From 5f63300cfa86be3a35d143f836c9fade957c9ede Mon Sep 17 00:00:00 2001 From: mwasiluk Date: Fri, 9 Sep 2016 00:25:29 +0200 Subject: [PATCH] toggling groups --- dist/odc-d3.js | 20 +++++++++++--------- dist/odc-d3.min.js | 6 +++--- dist/odc-d3.min.js.map | 2 +- src/histogram.js | 7 +++++-- src/scatterplot-matrix.js | 3 +-- src/scatterplot.js | 4 ++-- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/dist/odc-d3.js b/dist/odc-d3.js index 89a7040..edafdbd 100644 --- a/dist/odc-d3.js +++ b/dist/odc-d3.js @@ -4168,10 +4168,13 @@ var Histogram = exports.Histogram = function (_Chart) { if (colorValue && typeof colorValue === 'string' || colorValue instanceof String) { this.plot.color = colorValue; } else if (this.plot.colorCategory) { - var domain = Object.getOwnPropertyNames(d3.map(this.data, function (d) { - return _this3.config.groups.value.call(_this3.config, d); - })['_']); - self.plot.colorCategory.domain(domain); + if (this.config.groups) { + var domain = Object.getOwnPropertyNames(d3.map(this.data, function (d) { + return _this3.config.groups.value.call(_this3.config, d); + })['_']); + self.plot.colorCategory.domain(domain); + } + this.plot.color = function (d) { return self.plot.colorCategory(d.key); }; @@ -5318,7 +5321,6 @@ var ScatterPlotMatrix = exports.ScatterPlotMatrix = function (_Chart) { }); function plotSubplot(p) { - console.log('plotSubplot'); var plot = self.plot; plot.subplots.push(p); var cell = d3.select(this); @@ -5357,7 +5359,7 @@ var ScatterPlotMatrix = exports.ScatterPlotMatrix = function (_Chart) { var html = "(" + plot.x.value(d, subplot.x) + ", " + plot.y.value(d, subplot.y) + ")"; plot.tooltip.html(html).style("left", d3.event.pageX + 5 + "px").style("top", d3.event.pageY - 28 + "px"); - var group = self.config.groups.value(d); + var group = self.config.groups ? self.config.groups.value(d) : false; if (group || group === 0) { html += "
"; var label = self.config.groups.label; @@ -5554,7 +5556,7 @@ var ScatterPlotConfig = exports.ScatterPlotConfig = function (_ChartConfig) { _this.dot = { radius: 2, color: function color(d) { - return _this.groups.value(d, _this.groups.key); + return _this.groups ? _this.groups.value(d, _this.groups.key) : ''; }, // string or function returning color's value for color scale d3ColorCategory: 'category10' }; @@ -5787,7 +5789,7 @@ var ScatterPlot = exports.ScatterPlot = function (_Chart) { dots.on("mouseover", function (d) { plot.tooltip.transition().duration(200).style("opacity", .9); var html = "(" + plot.x.value(d) + ", " + plot.y.value(d) + ")"; - var group = self.config.groups.value(d, self.config.groups.key); + var group = self.config.groups ? self.config.groups.value(d, self.config.groups.key) : null; if (group || group === 0) { html += "
"; var label = self.config.groups.label; @@ -6643,4 +6645,4 @@ Utils.availableWidth = function (width, container, margin) { },{}]},{},[26])(26) }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJib3dlcl9jb21wb25lbnRzXFxkMy1sZWdlbmRcXG5vLWV4dGVuZC5qcyIsImJvd2VyX2NvbXBvbmVudHNcXGQzLWxlZ2VuZFxcc3JjXFxjb2xvci5qcyIsImJvd2VyX2NvbXBvbmVudHNcXGQzLWxlZ2VuZFxcc3JjXFxsZWdlbmQuanMiLCJib3dlcl9jb21wb25lbnRzXFxkMy1sZWdlbmRcXHNyY1xcc2l6ZS5qcyIsImJvd2VyX2NvbXBvbmVudHNcXGQzLWxlZ2VuZFxcc3JjXFxzeW1ib2wuanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxlcnJvcl9mdW5jdGlvbi5qcyIsImJvd2VyX2NvbXBvbmVudHNcXHNpbXBsZS1zdGF0aXN0aWNzXFxzcmNcXGxpbmVhcl9yZWdyZXNzaW9uLmpzIiwiYm93ZXJfY29tcG9uZW50c1xcc2ltcGxlLXN0YXRpc3RpY3NcXHNyY1xcbGluZWFyX3JlZ3Jlc3Npb25fbGluZS5qcyIsImJvd2VyX2NvbXBvbmVudHNcXHNpbXBsZS1zdGF0aXN0aWNzXFxzcmNcXG1lYW4uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzYW1wbGVfY29ycmVsYXRpb24uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzYW1wbGVfY292YXJpYW5jZS5qcyIsImJvd2VyX2NvbXBvbmVudHNcXHNpbXBsZS1zdGF0aXN0aWNzXFxzcmNcXHNhbXBsZV9zdGFuZGFyZF9kZXZpYXRpb24uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzYW1wbGVfdmFyaWFuY2UuanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzdGFuZGFyZF9kZXZpYXRpb24uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzdW0uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzdW1fbnRoX3Bvd2VyX2RldmlhdGlvbnMuanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFx2YXJpYW5jZS5qcyIsImJvd2VyX2NvbXBvbmVudHNcXHNpbXBsZS1zdGF0aXN0aWNzXFxzcmNcXHpfc2NvcmUuanMiLCJzcmNcXGJhci1jaGFydC5qcyIsInNyY1xcY2hhcnQuanMiLCJzcmNcXGNvcnJlbGF0aW9uLW1hdHJpeC5qcyIsInNyY1xcZDMtZXh0ZW5zaW9ucy5qcyIsInNyY1xcaGVhdG1hcC10aW1lc2VyaWVzLmpzIiwic3JjXFxoZWF0bWFwLmpzIiwic3JjXFxoaXN0b2dyYW0uanMiLCJzcmNcXGluZGV4LmpzIiwic3JjXFxsZWdlbmQuanMiLCJzcmNcXHJlZ3Jlc3Npb24uanMiLCJzcmNcXHNjYXR0ZXJwbG90LW1hdHJpeC5qcyIsInNyY1xcc2NhdHRlcnBsb3QuanMiLCJzcmNcXHN0YXRpc3RpY3MtZGlzdHJpYnV0aW9ucy5qcyIsInNyY1xcc3RhdGlzdGljcy11dGlscy5qcyIsInNyY1xcdXRpbHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztBQ0FBLE9BQU8sT0FBUCxHQUFpQjtBQUNmLFNBQU8sUUFBUSxhQUFSLENBRFE7QUFFZixRQUFNLFFBQVEsWUFBUixDQUZTO0FBR2YsVUFBUSxRQUFRLGNBQVI7QUFITyxDQUFqQjs7Ozs7QUNBQSxJQUFJLFNBQVMsUUFBUSxVQUFSLENBQWI7O0FBRUEsT0FBTyxPQUFQLEdBQWlCLFlBQVU7O0FBRXpCLE1BQUksUUFBUSxHQUFHLEtBQUgsQ0FBUyxNQUFULEVBQVo7QUFBQSxNQUNFLFFBQVEsTUFEVjtBQUFBLE1BRUUsYUFBYSxFQUZmO0FBQUEsTUFHRSxjQUFjLEVBSGhCO0FBQUEsTUFJRSxjQUFjLEVBSmhCO0FBQUEsTUFLRSxlQUFlLENBTGpCO0FBQUEsTUFNRSxRQUFRLENBQUMsQ0FBRCxDQU5WO0FBQUEsTUFPRSxTQUFTLEVBUFg7QUFBQSxNQVFFLGNBQWMsRUFSaEI7QUFBQSxNQVNFLFdBQVcsS0FUYjtBQUFBLE1BVUUsUUFBUSxFQVZWO0FBQUEsTUFXRSxjQUFjLEdBQUcsTUFBSCxDQUFVLE1BQVYsQ0FYaEI7QUFBQSxNQVlFLGNBQWMsRUFaaEI7QUFBQSxNQWFFLGFBQWEsUUFiZjtBQUFBLE1BY0UsaUJBQWlCLElBZG5CO0FBQUEsTUFlRSxTQUFTLFVBZlg7QUFBQSxNQWdCRSxZQUFZLEtBaEJkO0FBQUEsTUFpQkUsSUFqQkY7QUFBQSxNQWtCRSxtQkFBbUIsR0FBRyxRQUFILENBQVksVUFBWixFQUF3QixTQUF4QixFQUFtQyxXQUFuQyxDQWxCckI7O0FBb0JFLFdBQVMsTUFBVCxDQUFnQixHQUFoQixFQUFvQjs7QUFFbEIsUUFBSSxPQUFPLE9BQU8sV0FBUCxDQUFtQixLQUFuQixFQUEwQixTQUExQixFQUFxQyxLQUFyQyxFQUE0QyxNQUE1QyxFQUFvRCxXQUFwRCxFQUFpRSxjQUFqRSxDQUFYO0FBQUEsUUFDRSxVQUFVLElBQUksU0FBSixDQUFjLEdBQWQsRUFBbUIsSUFBbkIsQ0FBd0IsQ0FBQyxLQUFELENBQXhCLENBRFo7O0FBR0EsWUFBUSxLQUFSLEdBQWdCLE1BQWhCLENBQXVCLEdBQXZCLEVBQTRCLElBQTVCLENBQWlDLE9BQWpDLEVBQTBDLGNBQWMsYUFBeEQ7O0FBR0EsUUFBSSxPQUFPLFFBQVEsU0FBUixDQUFrQixNQUFNLFdBQU4sR0FBb0IsTUFBdEMsRUFBOEMsSUFBOUMsQ0FBbUQsS0FBSyxJQUF4RCxDQUFYO0FBQUEsUUFDRSxZQUFZLEtBQUssS0FBTCxHQUFhLE1BQWIsQ0FBb0IsR0FBcEIsRUFBeUIsT0FBekIsRUFBa0MsSUFBbEMsQ0FBdUMsT0FBdkMsRUFBZ0QsY0FBYyxNQUE5RCxFQUFzRSxLQUF0RSxDQUE0RSxTQUE1RSxFQUF1RixJQUF2RixDQURkO0FBQUEsUUFFRSxhQUFhLFVBQVUsTUFBVixDQUFpQixLQUFqQixFQUF3QixJQUF4QixDQUE2QixPQUE3QixFQUFzQyxjQUFjLFFBQXBELENBRmY7QUFBQSxRQUdFLFNBQVMsS0FBSyxNQUFMLENBQVksT0FBTyxXQUFQLEdBQXFCLE9BQXJCLEdBQStCLEtBQTNDLENBSFg7OztBQU1BLFdBQU8sWUFBUCxDQUFvQixTQUFwQixFQUErQixnQkFBL0I7O0FBRUEsU0FBSyxJQUFMLEdBQVksVUFBWixHQUF5QixLQUF6QixDQUErQixTQUEvQixFQUEwQyxDQUExQyxFQUE2QyxNQUE3Qzs7QUFFQSxXQUFPLGFBQVAsQ0FBcUIsS0FBckIsRUFBNEIsTUFBNUIsRUFBb0MsV0FBcEMsRUFBaUQsVUFBakQsRUFBNkQsV0FBN0QsRUFBMEUsSUFBMUU7O0FBRUEsV0FBTyxVQUFQLENBQWtCLE9BQWxCLEVBQTJCLFNBQTNCLEVBQXNDLEtBQUssTUFBM0MsRUFBbUQsV0FBbkQ7OztBQUdBLFFBQUksT0FBTyxLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQVg7QUFBQSxRQUNFLFlBQVksT0FBTyxDQUFQLEVBQVUsR0FBVixDQUFlLFVBQVMsQ0FBVCxFQUFXO0FBQUUsYUFBTyxFQUFFLE9BQUYsRUFBUDtBQUFxQixLQUFqRCxDQURkOzs7O0FBS0EsUUFBSSxDQUFDLFFBQUwsRUFBYztBQUNaLFVBQUksU0FBUyxNQUFiLEVBQW9CO0FBQ2xCLGVBQU8sS0FBUCxDQUFhLFFBQWIsRUFBdUIsS0FBSyxPQUE1QjtBQUNELE9BRkQsTUFFTztBQUNMLGVBQU8sS0FBUCxDQUFhLE1BQWIsRUFBcUIsS0FBSyxPQUExQjtBQUNEO0FBQ0YsS0FORCxNQU1PO0FBQ0wsYUFBTyxJQUFQLENBQVksT0FBWixFQUFxQixVQUFTLENBQVQsRUFBVztBQUFFLGVBQU8sY0FBYyxTQUFkLEdBQTBCLEtBQUssT0FBTCxDQUFhLENBQWIsQ0FBakM7QUFBbUQsT0FBckY7QUFDRDs7QUFFRCxRQUFJLFNBQUo7QUFBQSxRQUNBLFNBREE7QUFBQSxRQUVBLFlBQWEsY0FBYyxPQUFmLEdBQTBCLENBQTFCLEdBQStCLGNBQWMsUUFBZixHQUEyQixHQUEzQixHQUFpQyxDQUYzRTs7O0FBS0EsUUFBSSxXQUFXLFVBQWYsRUFBMEI7QUFDeEIsa0JBQVksbUJBQVMsQ0FBVCxFQUFXLENBQVgsRUFBYztBQUFFLGVBQU8sa0JBQW1CLEtBQUssVUFBVSxDQUFWLEVBQWEsTUFBYixHQUFzQixZQUEzQixDQUFuQixHQUErRCxHQUF0RTtBQUE0RSxPQUF4RztBQUNBLGtCQUFZLG1CQUFTLENBQVQsRUFBVyxDQUFYLEVBQWM7QUFBRSxlQUFPLGdCQUFnQixVQUFVLENBQVYsRUFBYSxLQUFiLEdBQXFCLFVBQVUsQ0FBVixFQUFhLENBQWxDLEdBQ2pELFdBRGlDLElBQ2xCLEdBRGtCLElBQ1gsVUFBVSxDQUFWLEVBQWEsQ0FBYixHQUFpQixVQUFVLENBQVYsRUFBYSxNQUFiLEdBQW9CLENBQXJDLEdBQXlDLENBRDlCLElBQ21DLEdBRDFDO0FBQ2dELE9BRDVFO0FBR0QsS0FMRCxNQUtPLElBQUksV0FBVyxZQUFmLEVBQTRCO0FBQ2pDLGtCQUFZLG1CQUFTLENBQVQsRUFBVyxDQUFYLEVBQWM7QUFBRSxlQUFPLGVBQWdCLEtBQUssVUFBVSxDQUFWLEVBQWEsS0FBYixHQUFxQixZQUExQixDQUFoQixHQUEyRCxLQUFsRTtBQUEwRSxPQUF0RztBQUNBLGtCQUFZLG1CQUFTLENBQVQsRUFBVyxDQUFYLEVBQWM7QUFBRSxlQUFPLGdCQUFnQixVQUFVLENBQVYsRUFBYSxLQUFiLEdBQW1CLFNBQW5CLEdBQWdDLFVBQVUsQ0FBVixFQUFhLENBQTdELElBQ2pDLEdBRGlDLElBQzFCLFVBQVUsQ0FBVixFQUFhLE1BQWIsR0FBc0IsVUFBVSxDQUFWLEVBQWEsQ0FBbkMsR0FBdUMsV0FBdkMsR0FBcUQsQ0FEM0IsSUFDZ0MsR0FEdkM7QUFDNkMsT0FEekU7QUFFRDs7QUFFRCxXQUFPLFlBQVAsQ0FBb0IsTUFBcEIsRUFBNEIsSUFBNUIsRUFBa0MsU0FBbEMsRUFBNkMsSUFBN0MsRUFBbUQsU0FBbkQsRUFBOEQsVUFBOUQ7QUFDQSxXQUFPLFFBQVAsQ0FBZ0IsR0FBaEIsRUFBcUIsT0FBckIsRUFBOEIsS0FBOUIsRUFBcUMsV0FBckM7O0FBRUEsU0FBSyxVQUFMLEdBQWtCLEtBQWxCLENBQXdCLFNBQXhCLEVBQW1DLENBQW5DO0FBRUQ7O0FBSUgsU0FBTyxLQUFQLEdBQWUsVUFBUyxDQUFULEVBQVk7QUFDekIsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLEtBQVA7QUFDdkIsWUFBUSxDQUFSO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxTQUFPLEtBQVAsR0FBZSxVQUFTLENBQVQsRUFBWTtBQUN6QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sS0FBUDtBQUN2QixRQUFJLEVBQUUsTUFBRixHQUFXLENBQVgsSUFBZ0IsS0FBSyxDQUF6QixFQUE0QjtBQUMxQixjQUFRLENBQVI7QUFDRDtBQUNELFdBQU8sTUFBUDtBQUNELEdBTkQ7O0FBUUEsU0FBTyxLQUFQLEdBQWUsVUFBUyxDQUFULEVBQVksQ0FBWixFQUFlO0FBQzVCLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxLQUFQO0FBQ3ZCLFFBQUksS0FBSyxNQUFMLElBQWUsS0FBSyxRQUFwQixJQUFnQyxLQUFLLE1BQXJDLElBQWdELEtBQUssTUFBTCxJQUFnQixPQUFPLENBQVAsS0FBYSxRQUFqRixFQUE2RjtBQUMzRixjQUFRLENBQVI7QUFDQSxhQUFPLENBQVA7QUFDRDtBQUNELFdBQU8sTUFBUDtBQUNELEdBUEQ7O0FBU0EsU0FBTyxVQUFQLEdBQW9CLFVBQVMsQ0FBVCxFQUFZO0FBQzlCLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxVQUFQO0FBQ3ZCLGlCQUFhLENBQUMsQ0FBZDtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxXQUFQLEdBQXFCLFVBQVMsQ0FBVCxFQUFZO0FBQy9CLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxXQUFQO0FBQ3ZCLGtCQUFjLENBQUMsQ0FBZjtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxXQUFQLEdBQXFCLFVBQVMsQ0FBVCxFQUFZO0FBQy9CLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxXQUFQO0FBQ3ZCLGtCQUFjLENBQUMsQ0FBZjtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxZQUFQLEdBQXNCLFVBQVMsQ0FBVCxFQUFZO0FBQ2hDLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxZQUFQO0FBQ3ZCLG1CQUFlLENBQUMsQ0FBaEI7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sTUFBUCxHQUFnQixVQUFTLENBQVQsRUFBWTtBQUMxQixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sTUFBUDtBQUN2QixhQUFTLENBQVQ7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sVUFBUCxHQUFvQixVQUFTLENBQVQsRUFBWTtBQUM5QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sVUFBUDtBQUN2QixRQUFJLEtBQUssT0FBTCxJQUFnQixLQUFLLEtBQXJCLElBQThCLEtBQUssUUFBdkMsRUFBaUQ7QUFDL0MsbUJBQWEsQ0FBYjtBQUNEO0FBQ0QsV0FBTyxNQUFQO0FBQ0QsR0FORDs7QUFRQSxTQUFPLFdBQVAsR0FBcUIsVUFBUyxDQUFULEVBQVk7QUFDL0IsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLFdBQVA7QUFDdkIsa0JBQWMsQ0FBZDtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxXQUFQLEdBQXFCLFVBQVMsQ0FBVCxFQUFZO0FBQy9CLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxXQUFQO0FBQ3ZCLGtCQUFjLENBQUMsQ0FBZjtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxjQUFQLEdBQXdCLFVBQVMsQ0FBVCxFQUFZO0FBQ2xDLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxjQUFQO0FBQ3ZCLHFCQUFpQixDQUFqQjtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxRQUFQLEdBQWtCLFVBQVMsQ0FBVCxFQUFZO0FBQzVCLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxRQUFQO0FBQ3ZCLFFBQUksTUFBTSxJQUFOLElBQWMsTUFBTSxLQUF4QixFQUE4QjtBQUM1QixpQkFBVyxDQUFYO0FBQ0Q7QUFDRCxXQUFPLE1BQVA7QUFDRCxHQU5EOztBQVFBLFNBQU8sTUFBUCxHQUFnQixVQUFTLENBQVQsRUFBVztBQUN6QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sTUFBUDtBQUN2QixRQUFJLEVBQUUsV0FBRixFQUFKO0FBQ0EsUUFBSSxLQUFLLFlBQUwsSUFBcUIsS0FBSyxVQUE5QixFQUEwQztBQUN4QyxlQUFTLENBQVQ7QUFDRDtBQUNELFdBQU8sTUFBUDtBQUNELEdBUEQ7O0FBU0EsU0FBTyxTQUFQLEdBQW1CLFVBQVMsQ0FBVCxFQUFZO0FBQzdCLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxTQUFQO0FBQ3ZCLGdCQUFZLENBQUMsQ0FBQyxDQUFkO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxTQUFPLFdBQVAsR0FBcUIsVUFBUyxDQUFULEVBQVk7QUFDL0IsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLFdBQVA7QUFDdkIsa0JBQWMsQ0FBZDtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxLQUFQLEdBQWUsVUFBUyxDQUFULEVBQVk7QUFDekIsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLEtBQVA7QUFDdkIsWUFBUSxDQUFSO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxLQUFHLE1BQUgsQ0FBVSxNQUFWLEVBQWtCLGdCQUFsQixFQUFvQyxJQUFwQzs7QUFFQSxTQUFPLE1BQVA7QUFFRCxDQTNNRDs7Ozs7QUNGQSxPQUFPLE9BQVAsR0FBaUI7O0FBRWYsZUFBYSxxQkFBVSxDQUFWLEVBQWE7QUFDeEIsV0FBTyxDQUFQO0FBQ0QsR0FKYzs7QUFNZixrQkFBZ0Isd0JBQVUsR0FBVixFQUFlLE1BQWYsRUFBdUI7O0FBRW5DLFFBQUcsT0FBTyxNQUFQLEtBQWtCLENBQXJCLEVBQXdCLE9BQU8sR0FBUDs7QUFFeEIsVUFBTyxHQUFELEdBQVEsR0FBUixHQUFjLEVBQXBCOztBQUVBLFFBQUksSUFBSSxPQUFPLE1BQWY7QUFDQSxXQUFPLElBQUksSUFBSSxNQUFmLEVBQXVCLEdBQXZCLEVBQTRCO0FBQzFCLGFBQU8sSUFBUCxDQUFZLElBQUksQ0FBSixDQUFaO0FBQ0Q7QUFDRCxXQUFPLE1BQVA7QUFDRCxHQWpCWTs7QUFtQmYsbUJBQWlCLHlCQUFVLEtBQVYsRUFBaUIsS0FBakIsRUFBd0IsV0FBeEIsRUFBcUM7QUFDcEQsUUFBSSxPQUFPLEVBQVg7O0FBRUEsUUFBSSxNQUFNLE1BQU4sR0FBZSxDQUFuQixFQUFxQjtBQUNuQixhQUFPLEtBQVA7QUFFRCxLQUhELE1BR087QUFDTCxVQUFJLFNBQVMsTUFBTSxNQUFOLEVBQWI7QUFBQSxVQUNBLFlBQVksQ0FBQyxPQUFPLE9BQU8sTUFBUCxHQUFnQixDQUF2QixJQUE0QixPQUFPLENBQVAsQ0FBN0IsS0FBeUMsUUFBUSxDQUFqRCxDQURaO0FBQUEsVUFFQSxJQUFJLENBRko7O0FBSUEsYUFBTyxJQUFJLEtBQVgsRUFBa0IsR0FBbEIsRUFBc0I7QUFDcEIsYUFBSyxJQUFMLENBQVUsT0FBTyxDQUFQLElBQVksSUFBRSxTQUF4QjtBQUNEO0FBQ0Y7O0FBRUQsUUFBSSxTQUFTLEtBQUssR0FBTCxDQUFTLFdBQVQsQ0FBYjs7QUFFQSxXQUFPLEVBQUMsTUFBTSxJQUFQO0FBQ0MsY0FBUSxNQURUO0FBRUMsZUFBUyxpQkFBUyxDQUFULEVBQVc7QUFBRSxlQUFPLE1BQU0sQ0FBTixDQUFQO0FBQWtCLE9BRnpDLEVBQVA7QUFHRCxHQXhDYzs7QUEwQ2Ysa0JBQWdCLHdCQUFVLEtBQVYsRUFBaUIsV0FBakIsRUFBOEIsY0FBOUIsRUFBOEM7QUFDNUQsUUFBSSxTQUFTLE1BQU0sS0FBTixHQUFjLEdBQWQsQ0FBa0IsVUFBUyxDQUFULEVBQVc7QUFDeEMsVUFBSSxTQUFTLE1BQU0sWUFBTixDQUFtQixDQUFuQixDQUFiO0FBQUEsVUFDQSxJQUFJLFlBQVksT0FBTyxDQUFQLENBQVosQ0FESjtBQUFBLFVBRUEsSUFBSSxZQUFZLE9BQU8sQ0FBUCxDQUFaLENBRko7Ozs7QUFNRSxhQUFPLFlBQVksT0FBTyxDQUFQLENBQVosSUFBeUIsR0FBekIsR0FBK0IsY0FBL0IsR0FBZ0QsR0FBaEQsR0FBc0QsWUFBWSxPQUFPLENBQVAsQ0FBWixDQUE3RDs7Ozs7QUFNSCxLQWJZLENBQWI7O0FBZUEsV0FBTyxFQUFDLE1BQU0sTUFBTSxLQUFOLEVBQVA7QUFDQyxjQUFRLE1BRFQ7QUFFQyxlQUFTLEtBQUs7QUFGZixLQUFQO0FBSUQsR0E5RGM7O0FBZ0VmLG9CQUFrQiwwQkFBVSxLQUFWLEVBQWlCO0FBQ2pDLFdBQU8sRUFBQyxNQUFNLE1BQU0sTUFBTixFQUFQO0FBQ0MsY0FBUSxNQUFNLE1BQU4sRUFEVDtBQUVDLGVBQVMsaUJBQVMsQ0FBVCxFQUFXO0FBQUUsZUFBTyxNQUFNLENBQU4sQ0FBUDtBQUFrQixPQUZ6QyxFQUFQO0FBR0QsR0FwRWM7O0FBc0VmLGlCQUFlLHVCQUFVLEtBQVYsRUFBaUIsTUFBakIsRUFBeUIsV0FBekIsRUFBc0MsVUFBdEMsRUFBa0QsV0FBbEQsRUFBK0QsSUFBL0QsRUFBcUU7QUFDbEYsUUFBSSxVQUFVLE1BQWQsRUFBcUI7QUFDakIsYUFBTyxJQUFQLENBQVksUUFBWixFQUFzQixXQUF0QixFQUFtQyxJQUFuQyxDQUF3QyxPQUF4QyxFQUFpRCxVQUFqRDtBQUVILEtBSEQsTUFHTyxJQUFJLFVBQVUsUUFBZCxFQUF3QjtBQUMzQixhQUFPLElBQVAsQ0FBWSxHQUFaLEVBQWlCLFdBQWpCLEU7QUFFSCxLQUhNLE1BR0EsSUFBSSxVQUFVLE1BQWQsRUFBc0I7QUFDekIsYUFBTyxJQUFQLENBQVksSUFBWixFQUFrQixDQUFsQixFQUFxQixJQUFyQixDQUEwQixJQUExQixFQUFnQyxVQUFoQyxFQUE0QyxJQUE1QyxDQUFpRCxJQUFqRCxFQUF1RCxDQUF2RCxFQUEwRCxJQUExRCxDQUErRCxJQUEvRCxFQUFxRSxDQUFyRTtBQUVILEtBSE0sTUFHQSxJQUFJLFVBQVUsTUFBZCxFQUFzQjtBQUMzQixhQUFPLElBQVAsQ0FBWSxHQUFaLEVBQWlCLElBQWpCO0FBQ0Q7QUFDRixHQW5GYzs7QUFxRmYsY0FBWSxvQkFBVSxHQUFWLEVBQWUsS0FBZixFQUFzQixNQUF0QixFQUE4QixXQUE5QixFQUEwQztBQUNwRCxVQUFNLE1BQU4sQ0FBYSxNQUFiLEVBQXFCLElBQXJCLENBQTBCLE9BQTFCLEVBQW1DLGNBQWMsT0FBakQ7QUFDQSxRQUFJLFNBQUosQ0FBYyxPQUFPLFdBQVAsR0FBcUIsV0FBbkMsRUFBZ0QsSUFBaEQsQ0FBcUQsTUFBckQsRUFBNkQsSUFBN0QsQ0FBa0UsS0FBSyxXQUF2RTtBQUNELEdBeEZjOztBQTBGZixlQUFhLHFCQUFVLEtBQVYsRUFBaUIsU0FBakIsRUFBNEIsS0FBNUIsRUFBbUMsTUFBbkMsRUFBMkMsV0FBM0MsRUFBd0QsY0FBeEQsRUFBdUU7QUFDbEYsUUFBSSxPQUFPLE1BQU0sS0FBTixHQUNILEtBQUssZUFBTCxDQUFxQixLQUFyQixFQUE0QixLQUE1QixFQUFtQyxXQUFuQyxDQURHLEdBQytDLE1BQU0sWUFBTixHQUNsRCxLQUFLLGNBQUwsQ0FBb0IsS0FBcEIsRUFBMkIsV0FBM0IsRUFBd0MsY0FBeEMsQ0FEa0QsR0FDUSxLQUFLLGdCQUFMLENBQXNCLEtBQXRCLENBRmxFOztBQUlBLFNBQUssTUFBTCxHQUFjLEtBQUssY0FBTCxDQUFvQixLQUFLLE1BQXpCLEVBQWlDLE1BQWpDLENBQWQ7O0FBRUEsUUFBSSxTQUFKLEVBQWU7QUFDYixXQUFLLE1BQUwsR0FBYyxLQUFLLFVBQUwsQ0FBZ0IsS0FBSyxNQUFyQixDQUFkO0FBQ0EsV0FBSyxJQUFMLEdBQVksS0FBSyxVQUFMLENBQWdCLEtBQUssSUFBckIsQ0FBWjtBQUNEOztBQUVELFdBQU8sSUFBUDtBQUNELEdBdkdjOztBQXlHZixjQUFZLG9CQUFTLEdBQVQsRUFBYztBQUN4QixRQUFJLFNBQVMsRUFBYjtBQUNBLFNBQUssSUFBSSxJQUFJLENBQVIsRUFBVyxJQUFJLElBQUksTUFBeEIsRUFBZ0MsSUFBSSxDQUFwQyxFQUF1QyxHQUF2QyxFQUE0QztBQUMxQyxhQUFPLENBQVAsSUFBWSxJQUFJLElBQUUsQ0FBRixHQUFJLENBQVIsQ0FBWjtBQUNEO0FBQ0QsV0FBTyxNQUFQO0FBQ0QsR0EvR2M7O0FBaUhmLGdCQUFjLHNCQUFVLE1BQVYsRUFBa0IsSUFBbEIsRUFBd0IsU0FBeEIsRUFBbUMsSUFBbkMsRUFBeUMsU0FBekMsRUFBb0QsVUFBcEQsRUFBZ0U7QUFDNUUsU0FBSyxJQUFMLENBQVUsV0FBVixFQUF1QixTQUF2QjtBQUNBLFNBQUssSUFBTCxDQUFVLFdBQVYsRUFBdUIsU0FBdkI7QUFDQSxRQUFJLFdBQVcsWUFBZixFQUE0QjtBQUMxQixXQUFLLEtBQUwsQ0FBVyxhQUFYLEVBQTBCLFVBQTFCO0FBQ0Q7QUFDRixHQXZIYzs7QUF5SGYsZ0JBQWMsc0JBQVMsS0FBVCxFQUFnQixVQUFoQixFQUEyQjtBQUN2QyxRQUFJLElBQUksSUFBUjs7QUFFRSxVQUFNLEVBQU4sQ0FBUyxrQkFBVCxFQUE2QixVQUFVLENBQVYsRUFBYTtBQUFFLFFBQUUsV0FBRixDQUFjLFVBQWQsRUFBMEIsQ0FBMUIsRUFBNkIsSUFBN0I7QUFBcUMsS0FBakYsRUFDSyxFQURMLENBQ1EsaUJBRFIsRUFDMkIsVUFBVSxDQUFWLEVBQWE7QUFBRSxRQUFFLFVBQUYsQ0FBYSxVQUFiLEVBQXlCLENBQXpCLEVBQTRCLElBQTVCO0FBQW9DLEtBRDlFLEVBRUssRUFGTCxDQUVRLGNBRlIsRUFFd0IsVUFBVSxDQUFWLEVBQWE7QUFBRSxRQUFFLFlBQUYsQ0FBZSxVQUFmLEVBQTJCLENBQTNCLEVBQThCLElBQTlCO0FBQXNDLEtBRjdFO0FBR0gsR0EvSGM7O0FBaUlmLGVBQWEscUJBQVMsY0FBVCxFQUF5QixDQUF6QixFQUE0QixHQUE1QixFQUFnQztBQUMzQyxtQkFBZSxRQUFmLENBQXdCLElBQXhCLENBQTZCLEdBQTdCLEVBQWtDLENBQWxDO0FBQ0QsR0FuSWM7O0FBcUlmLGNBQVksb0JBQVMsY0FBVCxFQUF5QixDQUF6QixFQUE0QixHQUE1QixFQUFnQztBQUMxQyxtQkFBZSxPQUFmLENBQXVCLElBQXZCLENBQTRCLEdBQTVCLEVBQWlDLENBQWpDO0FBQ0QsR0F2SWM7O0FBeUlmLGdCQUFjLHNCQUFTLGNBQVQsRUFBeUIsQ0FBekIsRUFBNEIsR0FBNUIsRUFBZ0M7QUFDNUMsbUJBQWUsU0FBZixDQUF5QixJQUF6QixDQUE4QixHQUE5QixFQUFtQyxDQUFuQztBQUNELEdBM0ljOztBQTZJZixZQUFVLGtCQUFTLEdBQVQsRUFBYyxRQUFkLEVBQXdCLEtBQXhCLEVBQStCLFdBQS9CLEVBQTJDO0FBQ25ELFFBQUksVUFBVSxFQUFkLEVBQWlCOztBQUVmLFVBQUksWUFBWSxJQUFJLFNBQUosQ0FBYyxVQUFVLFdBQVYsR0FBd0IsYUFBdEMsQ0FBaEI7O0FBRUEsZ0JBQVUsSUFBVixDQUFlLENBQUMsS0FBRCxDQUFmLEVBQ0csS0FESCxHQUVHLE1BRkgsQ0FFVSxNQUZWLEVBR0csSUFISCxDQUdRLE9BSFIsRUFHaUIsY0FBYyxhQUgvQjs7QUFLRSxVQUFJLFNBQUosQ0FBYyxVQUFVLFdBQVYsR0FBd0IsYUFBdEMsRUFDSyxJQURMLENBQ1UsS0FEVjs7QUFHRixVQUFJLFVBQVUsSUFBSSxNQUFKLENBQVcsTUFBTSxXQUFOLEdBQW9CLGFBQS9CLEVBQ1QsR0FEUyxDQUNMLFVBQVMsQ0FBVCxFQUFZO0FBQUUsZUFBTyxFQUFFLENBQUYsRUFBSyxPQUFMLEdBQWUsTUFBdEI7QUFBNkIsT0FEdEMsRUFDd0MsQ0FEeEMsQ0FBZDtBQUFBLFVBRUEsVUFBVSxDQUFDLFNBQVMsR0FBVCxDQUFhLFVBQVMsQ0FBVCxFQUFZO0FBQUUsZUFBTyxFQUFFLENBQUYsRUFBSyxPQUFMLEdBQWUsQ0FBdEI7QUFBd0IsT0FBbkQsRUFBcUQsQ0FBckQsQ0FGWDs7QUFJQSxlQUFTLElBQVQsQ0FBYyxXQUFkLEVBQTJCLGVBQWUsT0FBZixHQUF5QixHQUF6QixJQUFnQyxVQUFVLEVBQTFDLElBQWdELEdBQTNFO0FBRUQ7QUFDRjtBQWpLYyxDQUFqQjs7Ozs7QUNBQSxJQUFJLFNBQVMsUUFBUSxVQUFSLENBQWI7O0FBRUEsT0FBTyxPQUFQLEdBQWtCLFlBQVU7O0FBRTFCLE1BQUksUUFBUSxHQUFHLEtBQUgsQ0FBUyxNQUFULEVBQVo7QUFBQSxNQUNFLFFBQVEsTUFEVjtBQUFBLE1BRUUsYUFBYSxFQUZmO0FBQUEsTUFHRSxlQUFlLENBSGpCO0FBQUEsTUFJRSxRQUFRLENBQUMsQ0FBRCxDQUpWO0FBQUEsTUFLRSxTQUFTLEVBTFg7QUFBQSxNQU1FLFlBQVksS0FOZDtBQUFBLE1BT0UsY0FBYyxFQVBoQjtBQUFBLE1BUUUsUUFBUSxFQVJWO0FBQUEsTUFTRSxjQUFjLEdBQUcsTUFBSCxDQUFVLE1BQVYsQ0FUaEI7QUFBQSxNQVVFLGNBQWMsRUFWaEI7QUFBQSxNQVdFLGFBQWEsUUFYZjtBQUFBLE1BWUUsaUJBQWlCLElBWm5CO0FBQUEsTUFhRSxTQUFTLFVBYlg7QUFBQSxNQWNFLFlBQVksS0FkZDtBQUFBLE1BZUUsSUFmRjtBQUFBLE1BZ0JFLG1CQUFtQixHQUFHLFFBQUgsQ0FBWSxVQUFaLEVBQXdCLFNBQXhCLEVBQW1DLFdBQW5DLENBaEJyQjs7QUFrQkUsV0FBUyxNQUFULENBQWdCLEdBQWhCLEVBQW9COztBQUVsQixRQUFJLE9BQU8sT0FBTyxXQUFQLENBQW1CLEtBQW5CLEVBQTBCLFNBQTFCLEVBQXFDLEtBQXJDLEVBQTRDLE1BQTVDLEVBQW9ELFdBQXBELEVBQWlFLGNBQWpFLENBQVg7QUFBQSxRQUNFLFVBQVUsSUFBSSxTQUFKLENBQWMsR0FBZCxFQUFtQixJQUFuQixDQUF3QixDQUFDLEtBQUQsQ0FBeEIsQ0FEWjs7QUFHQSxZQUFRLEtBQVIsR0FBZ0IsTUFBaEIsQ0FBdUIsR0FBdkIsRUFBNEIsSUFBNUIsQ0FBaUMsT0FBakMsRUFBMEMsY0FBYyxhQUF4RDs7QUFHQSxRQUFJLE9BQU8sUUFBUSxTQUFSLENBQWtCLE1BQU0sV0FBTixHQUFvQixNQUF0QyxFQUE4QyxJQUE5QyxDQUFtRCxLQUFLLElBQXhELENBQVg7QUFBQSxRQUNFLFlBQVksS0FBSyxLQUFMLEdBQWEsTUFBYixDQUFvQixHQUFwQixFQUF5QixPQUF6QixFQUFrQyxJQUFsQyxDQUF1QyxPQUF2QyxFQUFnRCxjQUFjLE1BQTlELEVBQXNFLEtBQXRFLENBQTRFLFNBQTVFLEVBQXVGLElBQXZGLENBRGQ7QUFBQSxRQUVFLGFBQWEsVUFBVSxNQUFWLENBQWlCLEtBQWpCLEVBQXdCLElBQXhCLENBQTZCLE9BQTdCLEVBQXNDLGNBQWMsUUFBcEQsQ0FGZjtBQUFBLFFBR0UsU0FBUyxLQUFLLE1BQUwsQ0FBWSxPQUFPLFdBQVAsR0FBcUIsT0FBckIsR0FBK0IsS0FBM0MsQ0FIWDs7O0FBTUEsV0FBTyxZQUFQLENBQW9CLFNBQXBCLEVBQStCLGdCQUEvQjs7QUFFQSxTQUFLLElBQUwsR0FBWSxVQUFaLEdBQXlCLEtBQXpCLENBQStCLFNBQS9CLEVBQTBDLENBQTFDLEVBQTZDLE1BQTdDOzs7QUFHQSxRQUFJLFVBQVUsTUFBZCxFQUFxQjtBQUNuQixhQUFPLGFBQVAsQ0FBcUIsS0FBckIsRUFBNEIsTUFBNUIsRUFBb0MsQ0FBcEMsRUFBdUMsVUFBdkM7QUFDQSxhQUFPLElBQVAsQ0FBWSxjQUFaLEVBQTRCLEtBQUssT0FBakM7QUFDRCxLQUhELE1BR087QUFDTCxhQUFPLGFBQVAsQ0FBcUIsS0FBckIsRUFBNEIsTUFBNUIsRUFBb0MsS0FBSyxPQUF6QyxFQUFrRCxLQUFLLE9BQXZELEVBQWdFLEtBQUssT0FBckUsRUFBOEUsSUFBOUU7QUFDRDs7QUFFRCxXQUFPLFVBQVAsQ0FBa0IsT0FBbEIsRUFBMkIsU0FBM0IsRUFBc0MsS0FBSyxNQUEzQyxFQUFtRCxXQUFuRDs7O0FBR0EsUUFBSSxPQUFPLEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBWDtBQUFBLFFBQ0UsWUFBWSxPQUFPLENBQVAsRUFBVSxHQUFWLENBQ1YsVUFBUyxDQUFULEVBQVksQ0FBWixFQUFjO0FBQ1osVUFBSSxPQUFPLEVBQUUsT0FBRixFQUFYO0FBQ0EsVUFBSSxTQUFTLE1BQU0sS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFOLENBQWI7O0FBRUEsVUFBSSxVQUFVLE1BQVYsSUFBb0IsV0FBVyxZQUFuQyxFQUFpRDtBQUMvQyxhQUFLLE1BQUwsR0FBYyxLQUFLLE1BQUwsR0FBYyxNQUE1QjtBQUNELE9BRkQsTUFFTyxJQUFJLFVBQVUsTUFBVixJQUFvQixXQUFXLFVBQW5DLEVBQThDO0FBQ25ELGFBQUssS0FBTCxHQUFhLEtBQUssS0FBbEI7QUFDRDs7QUFFRCxhQUFPLElBQVA7QUFDSCxLQVpXLENBRGQ7O0FBZUEsUUFBSSxPQUFPLEdBQUcsR0FBSCxDQUFPLFNBQVAsRUFBa0IsVUFBUyxDQUFULEVBQVc7QUFBRSxhQUFPLEVBQUUsTUFBRixHQUFXLEVBQUUsQ0FBcEI7QUFBd0IsS0FBdkQsQ0FBWDtBQUFBLFFBQ0EsT0FBTyxHQUFHLEdBQUgsQ0FBTyxTQUFQLEVBQWtCLFVBQVMsQ0FBVCxFQUFXO0FBQUUsYUFBTyxFQUFFLEtBQUYsR0FBVSxFQUFFLENBQW5CO0FBQXVCLEtBQXRELENBRFA7O0FBR0EsUUFBSSxTQUFKO0FBQUEsUUFDQSxTQURBO0FBQUEsUUFFQSxZQUFhLGNBQWMsT0FBZixHQUEwQixDQUExQixHQUErQixjQUFjLFFBQWYsR0FBMkIsR0FBM0IsR0FBaUMsQ0FGM0U7OztBQUtBLFFBQUksV0FBVyxVQUFmLEVBQTBCOztBQUV4QixrQkFBWSxtQkFBUyxDQUFULEVBQVcsQ0FBWCxFQUFjO0FBQ3RCLFlBQUksU0FBUyxHQUFHLEdBQUgsQ0FBTyxVQUFVLEtBQVYsQ0FBZ0IsQ0FBaEIsRUFBbUIsSUFBSSxDQUF2QixDQUFQLEVBQW1DLFVBQVMsQ0FBVCxFQUFXO0FBQUUsaUJBQU8sRUFBRSxNQUFUO0FBQWtCLFNBQWxFLENBQWI7QUFDQSxlQUFPLG1CQUFtQixTQUFTLElBQUUsWUFBOUIsSUFBOEMsR0FBckQ7QUFBMkQsT0FGL0Q7O0FBSUEsa0JBQVksbUJBQVMsQ0FBVCxFQUFXLENBQVgsRUFBYztBQUFFLGVBQU8sZ0JBQWdCLE9BQU8sV0FBdkIsSUFBc0MsR0FBdEMsSUFDaEMsVUFBVSxDQUFWLEVBQWEsQ0FBYixHQUFpQixVQUFVLENBQVYsRUFBYSxNQUFiLEdBQW9CLENBQXJDLEdBQXlDLENBRFQsSUFDYyxHQURyQjtBQUMyQixPQUR2RDtBQUdELEtBVEQsTUFTTyxJQUFJLFdBQVcsWUFBZixFQUE0QjtBQUNqQyxrQkFBWSxtQkFBUyxDQUFULEVBQVcsQ0FBWCxFQUFjO0FBQ3RCLFlBQUksUUFBUSxHQUFHLEdBQUgsQ0FBTyxVQUFVLEtBQVYsQ0FBZ0IsQ0FBaEIsRUFBbUIsSUFBSSxDQUF2QixDQUFQLEVBQW1DLFVBQVMsQ0FBVCxFQUFXO0FBQUUsaUJBQU8sRUFBRSxLQUFUO0FBQWlCLFNBQWpFLENBQVo7QUFDQSxlQUFPLGdCQUFnQixRQUFRLElBQUUsWUFBMUIsSUFBMEMsS0FBakQ7QUFBeUQsT0FGN0Q7O0FBSUEsa0JBQVksbUJBQVMsQ0FBVCxFQUFXLENBQVgsRUFBYztBQUFFLGVBQU8sZ0JBQWdCLFVBQVUsQ0FBVixFQUFhLEtBQWIsR0FBbUIsU0FBbkIsR0FBZ0MsVUFBVSxDQUFWLEVBQWEsQ0FBN0QsSUFBa0UsR0FBbEUsSUFDNUIsT0FBTyxXQURxQixJQUNMLEdBREY7QUFDUSxPQURwQztBQUVEOztBQUVELFdBQU8sWUFBUCxDQUFvQixNQUFwQixFQUE0QixJQUE1QixFQUFrQyxTQUFsQyxFQUE2QyxJQUE3QyxFQUFtRCxTQUFuRCxFQUE4RCxVQUE5RDtBQUNBLFdBQU8sUUFBUCxDQUFnQixHQUFoQixFQUFxQixPQUFyQixFQUE4QixLQUE5QixFQUFxQyxXQUFyQzs7QUFFQSxTQUFLLFVBQUwsR0FBa0IsS0FBbEIsQ0FBd0IsU0FBeEIsRUFBbUMsQ0FBbkM7QUFFRDs7QUFFSCxTQUFPLEtBQVAsR0FBZSxVQUFTLENBQVQsRUFBWTtBQUN6QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sS0FBUDtBQUN2QixZQUFRLENBQVI7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sS0FBUCxHQUFlLFVBQVMsQ0FBVCxFQUFZO0FBQ3pCLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxLQUFQO0FBQ3ZCLFFBQUksRUFBRSxNQUFGLEdBQVcsQ0FBWCxJQUFnQixLQUFLLENBQXpCLEVBQTRCO0FBQzFCLGNBQVEsQ0FBUjtBQUNEO0FBQ0QsV0FBTyxNQUFQO0FBQ0QsR0FORDs7QUFTQSxTQUFPLEtBQVAsR0FBZSxVQUFTLENBQVQsRUFBWSxDQUFaLEVBQWU7QUFDNUIsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLEtBQVA7QUFDdkIsUUFBSSxLQUFLLE1BQUwsSUFBZSxLQUFLLFFBQXBCLElBQWdDLEtBQUssTUFBekMsRUFBaUQ7QUFDL0MsY0FBUSxDQUFSO0FBQ0EsYUFBTyxDQUFQO0FBQ0Q7QUFDRCxXQUFPLE1BQVA7QUFDRCxHQVBEOztBQVNBLFNBQU8sVUFBUCxHQUFvQixVQUFTLENBQVQsRUFBWTtBQUM5QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sVUFBUDtBQUN2QixpQkFBYSxDQUFDLENBQWQ7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sWUFBUCxHQUFzQixVQUFTLENBQVQsRUFBWTtBQUNoQyxRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sWUFBUDtBQUN2QixtQkFBZSxDQUFDLENBQWhCO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxTQUFPLE1BQVAsR0FBZ0IsVUFBUyxDQUFULEVBQVk7QUFDMUIsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLE1BQVA7QUFDdkIsYUFBUyxDQUFUO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxTQUFPLFVBQVAsR0FBb0IsVUFBUyxDQUFULEVBQVk7QUFDOUIsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLFVBQVA7QUFDdkIsUUFBSSxLQUFLLE9BQUwsSUFBZ0IsS0FBSyxLQUFyQixJQUE4QixLQUFLLFFBQXZDLEVBQWlEO0FBQy9DLG1CQUFhLENBQWI7QUFDRDtBQUNELFdBQU8sTUFBUDtBQUNELEdBTkQ7O0FBUUEsU0FBTyxXQUFQLEdBQXFCLFVBQVMsQ0FBVCxFQUFZO0FBQy9CLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxXQUFQO0FBQ3ZCLGtCQUFjLENBQWQ7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sV0FBUCxHQUFxQixVQUFTLENBQVQsRUFBWTtBQUMvQixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sV0FBUDtBQUN2QixrQkFBYyxDQUFDLENBQWY7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sY0FBUCxHQUF3QixVQUFTLENBQVQsRUFBWTtBQUNsQyxRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sY0FBUDtBQUN2QixxQkFBaUIsQ0FBakI7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sTUFBUCxHQUFnQixVQUFTLENBQVQsRUFBVztBQUN6QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sTUFBUDtBQUN2QixRQUFJLEVBQUUsV0FBRixFQUFKO0FBQ0EsUUFBSSxLQUFLLFlBQUwsSUFBcUIsS0FBSyxVQUE5QixFQUEwQztBQUN4QyxlQUFTLENBQVQ7QUFDRDtBQUNELFdBQU8sTUFBUDtBQUNELEdBUEQ7O0FBU0EsU0FBTyxTQUFQLEdBQW1CLFVBQVMsQ0FBVCxFQUFZO0FBQzdCLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxTQUFQO0FBQ3ZCLGdCQUFZLENBQUMsQ0FBQyxDQUFkO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxTQUFPLFdBQVAsR0FBcUIsVUFBUyxDQUFULEVBQVk7QUFDL0IsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLFdBQVA7QUFDdkIsa0JBQWMsQ0FBZDtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxLQUFQLEdBQWUsVUFBUyxDQUFULEVBQVk7QUFDekIsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLEtBQVA7QUFDdkIsWUFBUSxDQUFSO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxLQUFHLE1BQUgsQ0FBVSxNQUFWLEVBQWtCLGdCQUFsQixFQUFvQyxJQUFwQzs7QUFFQSxTQUFPLE1BQVA7QUFFRCxDQXBNRDs7Ozs7QUNGQSxJQUFJLFNBQVMsUUFBUSxVQUFSLENBQWI7O0FBRUEsT0FBTyxPQUFQLEdBQWlCLFlBQVU7O0FBRXpCLE1BQUksUUFBUSxHQUFHLEtBQUgsQ0FBUyxNQUFULEVBQVo7QUFBQSxNQUNFLFFBQVEsTUFEVjtBQUFBLE1BRUUsYUFBYSxFQUZmO0FBQUEsTUFHRSxjQUFjLEVBSGhCO0FBQUEsTUFJRSxjQUFjLEVBSmhCO0FBQUEsTUFLRSxlQUFlLENBTGpCO0FBQUEsTUFNRSxRQUFRLENBQUMsQ0FBRCxDQU5WO0FBQUEsTUFPRSxTQUFTLEVBUFg7QUFBQSxNQVFFLGNBQWMsRUFSaEI7QUFBQSxNQVNFLFdBQVcsS0FUYjtBQUFBLE1BVUUsUUFBUSxFQVZWO0FBQUEsTUFXRSxjQUFjLEdBQUcsTUFBSCxDQUFVLE1BQVYsQ0FYaEI7QUFBQSxNQVlFLGFBQWEsUUFaZjtBQUFBLE1BYUUsY0FBYyxFQWJoQjtBQUFBLE1BY0UsaUJBQWlCLElBZG5CO0FBQUEsTUFlRSxTQUFTLFVBZlg7QUFBQSxNQWdCRSxZQUFZLEtBaEJkO0FBQUEsTUFpQkUsbUJBQW1CLEdBQUcsUUFBSCxDQUFZLFVBQVosRUFBd0IsU0FBeEIsRUFBbUMsV0FBbkMsQ0FqQnJCOztBQW1CRSxXQUFTLE1BQVQsQ0FBZ0IsR0FBaEIsRUFBb0I7O0FBRWxCLFFBQUksT0FBTyxPQUFPLFdBQVAsQ0FBbUIsS0FBbkIsRUFBMEIsU0FBMUIsRUFBcUMsS0FBckMsRUFBNEMsTUFBNUMsRUFBb0QsV0FBcEQsRUFBaUUsY0FBakUsQ0FBWDtBQUFBLFFBQ0UsVUFBVSxJQUFJLFNBQUosQ0FBYyxHQUFkLEVBQW1CLElBQW5CLENBQXdCLENBQUMsS0FBRCxDQUF4QixDQURaOztBQUdBLFlBQVEsS0FBUixHQUFnQixNQUFoQixDQUF1QixHQUF2QixFQUE0QixJQUE1QixDQUFpQyxPQUFqQyxFQUEwQyxjQUFjLGFBQXhEOztBQUVBLFFBQUksT0FBTyxRQUFRLFNBQVIsQ0FBa0IsTUFBTSxXQUFOLEdBQW9CLE1BQXRDLEVBQThDLElBQTlDLENBQW1ELEtBQUssSUFBeEQsQ0FBWDtBQUFBLFFBQ0UsWUFBWSxLQUFLLEtBQUwsR0FBYSxNQUFiLENBQW9CLEdBQXBCLEVBQXlCLE9BQXpCLEVBQWtDLElBQWxDLENBQXVDLE9BQXZDLEVBQWdELGNBQWMsTUFBOUQsRUFBc0UsS0FBdEUsQ0FBNEUsU0FBNUUsRUFBdUYsSUFBdkYsQ0FEZDtBQUFBLFFBRUUsYUFBYSxVQUFVLE1BQVYsQ0FBaUIsS0FBakIsRUFBd0IsSUFBeEIsQ0FBNkIsT0FBN0IsRUFBc0MsY0FBYyxRQUFwRCxDQUZmO0FBQUEsUUFHRSxTQUFTLEtBQUssTUFBTCxDQUFZLE9BQU8sV0FBUCxHQUFxQixPQUFyQixHQUErQixLQUEzQyxDQUhYOzs7QUFNQSxXQUFPLFlBQVAsQ0FBb0IsU0FBcEIsRUFBK0IsZ0JBQS9COzs7QUFHQSxTQUFLLElBQUwsR0FBWSxVQUFaLEdBQXlCLEtBQXpCLENBQStCLFNBQS9CLEVBQTBDLENBQTFDLEVBQTZDLE1BQTdDOztBQUVBLFdBQU8sYUFBUCxDQUFxQixLQUFyQixFQUE0QixNQUE1QixFQUFvQyxXQUFwQyxFQUFpRCxVQUFqRCxFQUE2RCxXQUE3RCxFQUEwRSxLQUFLLE9BQS9FO0FBQ0EsV0FBTyxVQUFQLENBQWtCLE9BQWxCLEVBQTJCLFNBQTNCLEVBQXNDLEtBQUssTUFBM0MsRUFBbUQsV0FBbkQ7OztBQUdBLFFBQUksT0FBTyxLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQVg7QUFBQSxRQUNFLFlBQVksT0FBTyxDQUFQLEVBQVUsR0FBVixDQUFlLFVBQVMsQ0FBVCxFQUFXO0FBQUUsYUFBTyxFQUFFLE9BQUYsRUFBUDtBQUFxQixLQUFqRCxDQURkOztBQUdBLFFBQUksT0FBTyxHQUFHLEdBQUgsQ0FBTyxTQUFQLEVBQWtCLFVBQVMsQ0FBVCxFQUFXO0FBQUUsYUFBTyxFQUFFLE1BQVQ7QUFBa0IsS0FBakQsQ0FBWDtBQUFBLFFBQ0EsT0FBTyxHQUFHLEdBQUgsQ0FBTyxTQUFQLEVBQWtCLFVBQVMsQ0FBVCxFQUFXO0FBQUUsYUFBTyxFQUFFLEtBQVQ7QUFBaUIsS0FBaEQsQ0FEUDs7QUFHQSxRQUFJLFNBQUo7QUFBQSxRQUNBLFNBREE7QUFBQSxRQUVBLFlBQWEsY0FBYyxPQUFmLEdBQTBCLENBQTFCLEdBQStCLGNBQWMsUUFBZixHQUEyQixHQUEzQixHQUFpQyxDQUYzRTs7O0FBS0EsUUFBSSxXQUFXLFVBQWYsRUFBMEI7QUFDeEIsa0JBQVksbUJBQVMsQ0FBVCxFQUFXLENBQVgsRUFBYztBQUFFLGVBQU8sa0JBQW1CLEtBQUssT0FBTyxZQUFaLENBQW5CLEdBQWdELEdBQXZEO0FBQTZELE9BQXpGO0FBQ0Esa0JBQVksbUJBQVMsQ0FBVCxFQUFXLENBQVgsRUFBYztBQUFFLGVBQU8sZ0JBQWdCLE9BQU8sV0FBdkIsSUFBc0MsR0FBdEMsSUFDNUIsVUFBVSxDQUFWLEVBQWEsQ0FBYixHQUFpQixVQUFVLENBQVYsRUFBYSxNQUFiLEdBQW9CLENBQXJDLEdBQXlDLENBRGIsSUFDa0IsR0FEekI7QUFDK0IsT0FEM0Q7QUFHRCxLQUxELE1BS08sSUFBSSxXQUFXLFlBQWYsRUFBNEI7QUFDakMsa0JBQVksbUJBQVMsQ0FBVCxFQUFXLENBQVgsRUFBYztBQUFFLGVBQU8sZUFBZ0IsS0FBSyxPQUFPLFlBQVosQ0FBaEIsR0FBNkMsS0FBcEQ7QUFBNEQsT0FBeEY7QUFDQSxrQkFBWSxtQkFBUyxDQUFULEVBQVcsQ0FBWCxFQUFjO0FBQUUsZUFBTyxnQkFBZ0IsVUFBVSxDQUFWLEVBQWEsS0FBYixHQUFtQixTQUFuQixHQUFnQyxVQUFVLENBQVYsRUFBYSxDQUE3RCxJQUFrRSxHQUFsRSxJQUM1QixPQUFPLFdBRHFCLElBQ0wsR0FERjtBQUNRLE9BRHBDO0FBRUQ7O0FBRUQsV0FBTyxZQUFQLENBQW9CLE1BQXBCLEVBQTRCLElBQTVCLEVBQWtDLFNBQWxDLEVBQTZDLElBQTdDLEVBQW1ELFNBQW5ELEVBQThELFVBQTlEO0FBQ0EsV0FBTyxRQUFQLENBQWdCLEdBQWhCLEVBQXFCLE9BQXJCLEVBQThCLEtBQTlCLEVBQXFDLFdBQXJDO0FBQ0EsU0FBSyxVQUFMLEdBQWtCLEtBQWxCLENBQXdCLFNBQXhCLEVBQW1DLENBQW5DO0FBRUQ7O0FBR0gsU0FBTyxLQUFQLEdBQWUsVUFBUyxDQUFULEVBQVk7QUFDekIsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLEtBQVA7QUFDdkIsWUFBUSxDQUFSO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxTQUFPLEtBQVAsR0FBZSxVQUFTLENBQVQsRUFBWTtBQUN6QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sS0FBUDtBQUN2QixRQUFJLEVBQUUsTUFBRixHQUFXLENBQVgsSUFBZ0IsS0FBSyxDQUF6QixFQUE0QjtBQUMxQixjQUFRLENBQVI7QUFDRDtBQUNELFdBQU8sTUFBUDtBQUNELEdBTkQ7O0FBUUEsU0FBTyxZQUFQLEdBQXNCLFVBQVMsQ0FBVCxFQUFZO0FBQ2hDLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxZQUFQO0FBQ3ZCLG1CQUFlLENBQUMsQ0FBaEI7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sTUFBUCxHQUFnQixVQUFTLENBQVQsRUFBWTtBQUMxQixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sTUFBUDtBQUN2QixhQUFTLENBQVQ7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sVUFBUCxHQUFvQixVQUFTLENBQVQsRUFBWTtBQUM5QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sVUFBUDtBQUN2QixRQUFJLEtBQUssT0FBTCxJQUFnQixLQUFLLEtBQXJCLElBQThCLEtBQUssUUFBdkMsRUFBaUQ7QUFDL0MsbUJBQWEsQ0FBYjtBQUNEO0FBQ0QsV0FBTyxNQUFQO0FBQ0QsR0FORDs7QUFRQSxTQUFPLFdBQVAsR0FBcUIsVUFBUyxDQUFULEVBQVk7QUFDL0IsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLFdBQVA7QUFDdkIsa0JBQWMsQ0FBZDtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxXQUFQLEdBQXFCLFVBQVMsQ0FBVCxFQUFZO0FBQy9CLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxXQUFQO0FBQ3ZCLGtCQUFjLENBQUMsQ0FBZjtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxjQUFQLEdBQXdCLFVBQVMsQ0FBVCxFQUFZO0FBQ2xDLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxjQUFQO0FBQ3ZCLHFCQUFpQixDQUFqQjtBQUNBLFdBQU8sTUFBUDtBQUNELEdBSkQ7O0FBTUEsU0FBTyxNQUFQLEdBQWdCLFVBQVMsQ0FBVCxFQUFXO0FBQ3pCLFFBQUksQ0FBQyxVQUFVLE1BQWYsRUFBdUIsT0FBTyxNQUFQO0FBQ3ZCLFFBQUksRUFBRSxXQUFGLEVBQUo7QUFDQSxRQUFJLEtBQUssWUFBTCxJQUFxQixLQUFLLFVBQTlCLEVBQTBDO0FBQ3hDLGVBQVMsQ0FBVDtBQUNEO0FBQ0QsV0FBTyxNQUFQO0FBQ0QsR0FQRDs7QUFTQSxTQUFPLFNBQVAsR0FBbUIsVUFBUyxDQUFULEVBQVk7QUFDN0IsUUFBSSxDQUFDLFVBQVUsTUFBZixFQUF1QixPQUFPLFNBQVA7QUFDdkIsZ0JBQVksQ0FBQyxDQUFDLENBQWQ7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLFNBQU8sV0FBUCxHQUFxQixVQUFTLENBQVQsRUFBWTtBQUMvQixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sV0FBUDtBQUN2QixrQkFBYyxDQUFkO0FBQ0EsV0FBTyxNQUFQO0FBQ0QsR0FKRDs7QUFNQSxTQUFPLEtBQVAsR0FBZSxVQUFTLENBQVQsRUFBWTtBQUN6QixRQUFJLENBQUMsVUFBVSxNQUFmLEVBQXVCLE9BQU8sS0FBUDtBQUN2QixZQUFRLENBQVI7QUFDQSxXQUFPLE1BQVA7QUFDRCxHQUpEOztBQU1BLEtBQUcsTUFBSCxDQUFVLE1BQVYsRUFBa0IsZ0JBQWxCLEVBQW9DLElBQXBDOztBQUVBLFNBQU8sTUFBUDtBQUVELENBM0pEOzs7QUNGQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnQkEsU0FBUyxhQUFULENBQXVCLEMsY0FBdkIsRSxhQUFvRDtBQUNoRCxRQUFJLElBQUksS0FBSyxJQUFJLE1BQU0sS0FBSyxHQUFMLENBQVMsQ0FBVCxDQUFmLENBQVI7QUFDQSxRQUFJLE1BQU0sSUFBSSxLQUFLLEdBQUwsQ0FBUyxDQUFDLEtBQUssR0FBTCxDQUFTLENBQVQsRUFBWSxDQUFaLENBQUQsR0FDbkIsVUFEbUIsR0FFbkIsYUFBYSxDQUZNLEdBR25CLGFBQWEsS0FBSyxHQUFMLENBQVMsQ0FBVCxFQUFZLENBQVosQ0FITSxHQUluQixhQUFhLEtBQUssR0FBTCxDQUFTLENBQVQsRUFBWSxDQUFaLENBSk0sR0FLbkIsYUFBYSxLQUFLLEdBQUwsQ0FBUyxDQUFULEVBQVksQ0FBWixDQUxNLEdBTW5CLGFBQWEsS0FBSyxHQUFMLENBQVMsQ0FBVCxFQUFZLENBQVosQ0FOTSxHQU9uQixhQUFhLEtBQUssR0FBTCxDQUFTLENBQVQsRUFBWSxDQUFaLENBUE0sR0FRbkIsYUFBYSxLQUFLLEdBQUwsQ0FBUyxDQUFULEVBQVksQ0FBWixDQVJNLEdBU25CLGFBQWEsS0FBSyxHQUFMLENBQVMsQ0FBVCxFQUFZLENBQVosQ0FUTSxHQVVuQixhQUFhLEtBQUssR0FBTCxDQUFTLENBQVQsRUFBWSxDQUFaLENBVkgsQ0FBZDtBQVdBLFFBQUksS0FBSyxDQUFULEVBQVk7QUFDUixlQUFPLElBQUksR0FBWDtBQUNILEtBRkQsTUFFTztBQUNILGVBQU8sTUFBTSxDQUFiO0FBQ0g7QUFDSjs7QUFFRCxPQUFPLE9BQVAsR0FBaUIsYUFBakI7OztBQ3BDQTs7Ozs7Ozs7Ozs7Ozs7OztBQWVBLFNBQVMsZ0JBQVQsQ0FBMEIsSSw0QkFBMUIsRSwrQkFBMEY7O0FBRXRGLFFBQUksQ0FBSixFQUFPLENBQVA7Ozs7QUFJQSxRQUFJLGFBQWEsS0FBSyxNQUF0Qjs7OztBQUlBLFFBQUksZUFBZSxDQUFuQixFQUFzQjtBQUNsQixZQUFJLENBQUo7QUFDQSxZQUFJLEtBQUssQ0FBTCxFQUFRLENBQVIsQ0FBSjtBQUNILEtBSEQsTUFHTzs7O0FBR0gsWUFBSSxPQUFPLENBQVg7QUFBQSxZQUFjLE9BQU8sQ0FBckI7QUFBQSxZQUNJLFFBQVEsQ0FEWjtBQUFBLFlBQ2UsUUFBUSxDQUR2Qjs7OztBQUtBLFlBQUksS0FBSixFQUFXLENBQVgsRUFBYyxDQUFkOzs7Ozs7O0FBT0EsYUFBSyxJQUFJLElBQUksQ0FBYixFQUFnQixJQUFJLFVBQXBCLEVBQWdDLEdBQWhDLEVBQXFDO0FBQ2pDLG9CQUFRLEtBQUssQ0FBTCxDQUFSO0FBQ0EsZ0JBQUksTUFBTSxDQUFOLENBQUo7QUFDQSxnQkFBSSxNQUFNLENBQU4sQ0FBSjs7QUFFQSxvQkFBUSxDQUFSO0FBQ0Esb0JBQVEsQ0FBUjs7QUFFQSxxQkFBUyxJQUFJLENBQWI7QUFDQSxxQkFBUyxJQUFJLENBQWI7QUFDSDs7O0FBR0QsWUFBSSxDQUFFLGFBQWEsS0FBZCxHQUF3QixPQUFPLElBQWhDLEtBQ0UsYUFBYSxLQUFkLEdBQXdCLE9BQU8sSUFEaEMsQ0FBSjs7O0FBSUEsWUFBSyxPQUFPLFVBQVIsR0FBd0IsSUFBSSxJQUFMLEdBQWEsVUFBeEM7QUFDSDs7O0FBR0QsV0FBTztBQUNILFdBQUcsQ0FEQTtBQUVILFdBQUc7QUFGQSxLQUFQO0FBSUg7O0FBR0QsT0FBTyxPQUFQLEdBQWlCLGdCQUFqQjs7O0FDdkVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBLFNBQVMsb0JBQVQsQ0FBOEIsRSwrQkFBOUIsRSxlQUErRTs7OztBQUkzRSxXQUFPLFVBQVMsQ0FBVCxFQUFZO0FBQ2YsZUFBTyxHQUFHLENBQUgsR0FBUSxHQUFHLENBQUgsR0FBTyxDQUF0QjtBQUNILEtBRkQ7QUFHSDs7QUFFRCxPQUFPLE9BQVAsR0FBaUIsb0JBQWpCOzs7QUMzQkE7OztBQUdBLElBQUksTUFBTSxRQUFRLE9BQVIsQ0FBVjs7Ozs7Ozs7Ozs7Ozs7O0FBZUEsU0FBUyxJQUFULENBQWMsQyxxQkFBZCxFLFdBQWlEOztBQUU3QyxRQUFJLEVBQUUsTUFBRixLQUFhLENBQWpCLEVBQW9CO0FBQUUsZUFBTyxHQUFQO0FBQWE7O0FBRW5DLFdBQU8sSUFBSSxDQUFKLElBQVMsRUFBRSxNQUFsQjtBQUNIOztBQUVELE9BQU8sT0FBUCxHQUFpQixJQUFqQjs7O0FDekJBOzs7QUFHQSxJQUFJLG1CQUFtQixRQUFRLHFCQUFSLENBQXZCO0FBQ0EsSUFBSSwwQkFBMEIsUUFBUSw2QkFBUixDQUE5Qjs7Ozs7Ozs7Ozs7Ozs7QUFjQSxTQUFTLGlCQUFULENBQTJCLEMscUJBQTNCLEVBQWtELEMscUJBQWxELEUsV0FBb0Y7QUFDaEYsUUFBSSxNQUFNLGlCQUFpQixDQUFqQixFQUFvQixDQUFwQixDQUFWO0FBQUEsUUFDSSxPQUFPLHdCQUF3QixDQUF4QixDQURYO0FBQUEsUUFFSSxPQUFPLHdCQUF3QixDQUF4QixDQUZYOztBQUlBLFdBQU8sTUFBTSxJQUFOLEdBQWEsSUFBcEI7QUFDSDs7QUFFRCxPQUFPLE9BQVAsR0FBaUIsaUJBQWpCOzs7QUMxQkE7OztBQUdBLElBQUksT0FBTyxRQUFRLFFBQVIsQ0FBWDs7Ozs7Ozs7Ozs7Ozs7O0FBZUEsU0FBUyxnQkFBVCxDQUEwQixDLG1CQUExQixFQUFnRCxDLG1CQUFoRCxFLFdBQWlGOzs7QUFHN0UsUUFBSSxFQUFFLE1BQUYsSUFBWSxDQUFaLElBQWlCLEVBQUUsTUFBRixLQUFhLEVBQUUsTUFBcEMsRUFBNEM7QUFDeEMsZUFBTyxHQUFQO0FBQ0g7Ozs7OztBQU1ELFFBQUksUUFBUSxLQUFLLENBQUwsQ0FBWjtBQUFBLFFBQ0ksUUFBUSxLQUFLLENBQUwsQ0FEWjtBQUFBLFFBRUksTUFBTSxDQUZWOzs7Ozs7QUFRQSxTQUFLLElBQUksSUFBSSxDQUFiLEVBQWdCLElBQUksRUFBRSxNQUF0QixFQUE4QixHQUE5QixFQUFtQztBQUMvQixlQUFPLENBQUMsRUFBRSxDQUFGLElBQU8sS0FBUixLQUFrQixFQUFFLENBQUYsSUFBTyxLQUF6QixDQUFQO0FBQ0g7Ozs7O0FBS0QsUUFBSSxvQkFBb0IsRUFBRSxNQUFGLEdBQVcsQ0FBbkM7OztBQUdBLFdBQU8sTUFBTSxpQkFBYjtBQUNIOztBQUVELE9BQU8sT0FBUCxHQUFpQixnQkFBakI7OztBQ2xEQTs7O0FBR0EsSUFBSSxpQkFBaUIsUUFBUSxtQkFBUixDQUFyQjs7Ozs7Ozs7Ozs7O0FBWUEsU0FBUyx1QkFBVCxDQUFpQyxDLG1CQUFqQyxFLFdBQWlFOztBQUU3RCxNQUFJLGtCQUFrQixlQUFlLENBQWYsQ0FBdEI7QUFDQSxNQUFJLE1BQU0sZUFBTixDQUFKLEVBQTRCO0FBQUUsV0FBTyxHQUFQO0FBQWE7QUFDM0MsU0FBTyxLQUFLLElBQUwsQ0FBVSxlQUFWLENBQVA7QUFDSDs7QUFFRCxPQUFPLE9BQVAsR0FBaUIsdUJBQWpCOzs7QUN0QkE7OztBQUdBLElBQUksd0JBQXdCLFFBQVEsNEJBQVIsQ0FBNUI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtCQSxTQUFTLGNBQVQsQ0FBd0IsQyxxQkFBeEIsRSxXQUEyRDs7QUFFdkQsUUFBSSxFQUFFLE1BQUYsSUFBWSxDQUFoQixFQUFtQjtBQUFFLGVBQU8sR0FBUDtBQUFhOztBQUVsQyxRQUFJLDRCQUE0QixzQkFBc0IsQ0FBdEIsRUFBeUIsQ0FBekIsQ0FBaEM7Ozs7O0FBS0EsUUFBSSxvQkFBb0IsRUFBRSxNQUFGLEdBQVcsQ0FBbkM7OztBQUdBLFdBQU8sNEJBQTRCLGlCQUFuQztBQUNIOztBQUVELE9BQU8sT0FBUCxHQUFpQixjQUFqQjs7O0FDcENBOzs7QUFHQSxJQUFJLFdBQVcsUUFBUSxZQUFSLENBQWY7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtCQSxTQUFTLGlCQUFULENBQTJCLEMscUJBQTNCLEUsV0FBOEQ7O0FBRTFELE1BQUksSUFBSSxTQUFTLENBQVQsQ0FBUjtBQUNBLE1BQUksTUFBTSxDQUFOLENBQUosRUFBYztBQUFFLFdBQU8sQ0FBUDtBQUFXO0FBQzNCLFNBQU8sS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFQO0FBQ0g7O0FBRUQsT0FBTyxPQUFQLEdBQWlCLGlCQUFqQjs7O0FDNUJBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1CQSxTQUFTLEdBQVQsQ0FBYSxDLHFCQUFiLEUsYUFBaUQ7Ozs7QUFJN0MsUUFBSSxNQUFNLENBQVY7Ozs7O0FBS0EsUUFBSSxvQkFBb0IsQ0FBeEI7OztBQUdBLFFBQUkscUJBQUo7OztBQUdBLFFBQUksT0FBSjs7QUFFQSxTQUFLLElBQUksSUFBSSxDQUFiLEVBQWdCLElBQUksRUFBRSxNQUF0QixFQUE4QixHQUE5QixFQUFtQzs7QUFFL0IsZ0NBQXdCLEVBQUUsQ0FBRixJQUFPLGlCQUEvQjs7Ozs7QUFLQSxrQkFBVSxNQUFNLHFCQUFoQjs7Ozs7OztBQU9BLDRCQUFvQixVQUFVLEdBQVYsR0FBZ0IscUJBQXBDOzs7O0FBSUEsY0FBTSxPQUFOO0FBQ0g7O0FBRUQsV0FBTyxHQUFQO0FBQ0g7O0FBRUQsT0FBTyxPQUFQLEdBQWlCLEdBQWpCOzs7QUM1REE7OztBQUdBLElBQUksT0FBTyxRQUFRLFFBQVIsQ0FBWDs7Ozs7Ozs7Ozs7Ozs7OztBQWdCQSxTQUFTLHFCQUFULENBQStCLEMscUJBQS9CLEVBQXNELEMsY0FBdEQsRSxXQUFpRjtBQUM3RSxRQUFJLFlBQVksS0FBSyxDQUFMLENBQWhCO0FBQUEsUUFDSSxNQUFNLENBRFY7O0FBR0EsU0FBSyxJQUFJLElBQUksQ0FBYixFQUFnQixJQUFJLEVBQUUsTUFBdEIsRUFBOEIsR0FBOUIsRUFBbUM7QUFDL0IsZUFBTyxLQUFLLEdBQUwsQ0FBUyxFQUFFLENBQUYsSUFBTyxTQUFoQixFQUEyQixDQUEzQixDQUFQO0FBQ0g7O0FBRUQsV0FBTyxHQUFQO0FBQ0g7O0FBRUQsT0FBTyxPQUFQLEdBQWlCLHFCQUFqQjs7O0FDOUJBOzs7QUFHQSxJQUFJLHdCQUF3QixRQUFRLDRCQUFSLENBQTVCOzs7Ozs7Ozs7Ozs7Ozs7QUFlQSxTQUFTLFFBQVQsQ0FBa0IsQyxxQkFBbEIsRSxXQUFvRDs7QUFFaEQsUUFBSSxFQUFFLE1BQUYsS0FBYSxDQUFqQixFQUFvQjtBQUFFLGVBQU8sR0FBUDtBQUFhOzs7O0FBSW5DLFdBQU8sc0JBQXNCLENBQXRCLEVBQXlCLENBQXpCLElBQThCLEVBQUUsTUFBdkM7QUFDSDs7QUFFRCxPQUFPLE9BQVAsR0FBaUIsUUFBakI7OztBQzNCQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMEJBLFNBQVMsTUFBVCxDQUFnQixDLFlBQWhCLEVBQThCLEksWUFBOUIsRUFBK0MsaUIsWUFBL0MsRSxXQUF3RjtBQUNwRixTQUFPLENBQUMsSUFBSSxJQUFMLElBQWEsaUJBQXBCO0FBQ0g7O0FBRUQsT0FBTyxPQUFQLEdBQWlCLE1BQWpCOzs7Ozs7Ozs7Ozs7OztBQzlCQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7SUFFYSxjLFdBQUEsYzs7Ozs7QUFpQ1QsNEJBQVksTUFBWixFQUFtQjtBQUFBOztBQUFBOztBQUFBLGNBL0JuQixRQStCbUIsR0EvQlQsTUFBSyxjQUFMLEdBQW9CLFdBK0JYO0FBQUEsY0E5Qm5CLFVBOEJtQixHQTlCUixJQThCUTtBQUFBLGNBN0JuQixXQTZCbUIsR0E3Qk4sSUE2Qk07QUFBQSxjQTVCbkIsTUE0Qm1CLEdBNUJaO0FBQ0gsbUJBQU8sRUFESjtBQUVILG9CQUFRLEVBRkw7QUFHSCx3QkFBWTtBQUhULFNBNEJZO0FBQUEsY0F2Qm5CLENBdUJtQixHQXZCakIsRTtBQUNFLG1CQUFPLEVBRFQsRTtBQUVFLGlCQUFLLENBRlA7QUFHRSxtQkFBTyxlQUFDLENBQUQsRUFBSSxHQUFKO0FBQUEsdUJBQVksYUFBTSxRQUFOLENBQWUsQ0FBZixJQUFvQixDQUFwQixHQUF3QixFQUFFLEdBQUYsQ0FBcEM7QUFBQSxhQUhULEU7QUFJRSxtQkFBTyxTQUpUO0FBS0UsbUJBQU87QUFMVCxTQXVCaUI7QUFBQSxjQWhCbkIsQ0FnQm1CLEdBaEJqQixFO0FBQ0UsaUJBQUssQ0FEUDtBQUVFLG1CQUFPLGVBQUMsQ0FBRCxFQUFJLEdBQUo7QUFBQSx1QkFBWSxhQUFNLFFBQU4sQ0FBZSxDQUFmLElBQW9CLENBQXBCLEdBQXdCLEVBQUUsR0FBRixDQUFwQztBQUFBLGFBRlQsRTtBQUdFLG1CQUFPLEVBSFQsRTtBQUlFLG9CQUFRLE1BSlY7QUFLRSxtQkFBTztBQUxULFNBZ0JpQjtBQUFBLGNBVG5CLE1BU21CLEdBVFo7QUFDSCxpQkFBSyxDQURGO0FBRUgsbUJBQU8sZUFBQyxDQUFEO0FBQUEsdUJBQU8sRUFBRSxNQUFLLE1BQUwsQ0FBWSxHQUFkLENBQVA7QUFBQSxhQUZKLEU7QUFHSCxtQkFBTztBQUhKLFNBU1k7QUFBQSxjQUpuQixLQUltQixHQUpYLFNBSVc7QUFBQSxjQUhuQixlQUdtQixHQUhGLFlBR0U7QUFBQSxjQUZuQixVQUVtQixHQUZQLElBRU87O0FBRWYsWUFBSSxjQUFKOztBQUVBLFlBQUcsTUFBSCxFQUFVO0FBQ04seUJBQU0sVUFBTixRQUF1QixNQUF2QjtBQUNIOztBQU5jO0FBUWxCOzs7OztJQUdRLFEsV0FBQSxROzs7QUFDVCxzQkFBWSxtQkFBWixFQUFpQyxJQUFqQyxFQUF1QyxNQUF2QyxFQUErQztBQUFBOztBQUFBLDJGQUNyQyxtQkFEcUMsRUFDaEIsSUFEZ0IsRUFDVixJQUFJLGNBQUosQ0FBbUIsTUFBbkIsQ0FEVTtBQUU5Qzs7OztrQ0FFUyxNLEVBQU87QUFDYixpR0FBdUIsSUFBSSxjQUFKLENBQW1CLE1BQW5CLENBQXZCO0FBQ0g7OzttQ0FFUztBQUNOO0FBQ0EsZ0JBQUksT0FBSyxJQUFUOztBQUVBLGdCQUFJLE9BQU8sS0FBSyxNQUFoQjs7QUFFQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixHQUFZLEVBQVo7QUFDQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixHQUFZLEVBQVo7O0FBRUEsaUJBQUssSUFBTCxDQUFVLFVBQVYsR0FBdUIsS0FBSyxVQUE1QjtBQUNBLGdCQUFHLEtBQUssSUFBTCxDQUFVLFVBQWIsRUFBd0I7QUFDcEIscUJBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsS0FBakIsR0FBeUIsS0FBSyxNQUFMLENBQVksS0FBWixHQUFvQixLQUFLLE1BQUwsQ0FBWSxLQUFoQyxHQUFzQyxLQUFLLE1BQUwsQ0FBWSxNQUFaLEdBQW1CLENBQWxGO0FBQ0g7O0FBR0QsaUJBQUssZUFBTDtBQUNBLGlCQUFLLE1BQUw7QUFDQSxpQkFBSyxNQUFMO0FBQ0EsaUJBQUssZ0JBQUw7O0FBR0EsaUJBQUssWUFBTDs7QUFHQSxnQkFBRyxLQUFLLGVBQVIsRUFBd0I7QUFDcEIscUJBQUssSUFBTCxDQUFVLGFBQVYsR0FBMEIsR0FBRyxLQUFILENBQVMsS0FBSyxlQUFkLEdBQTFCO0FBQ0g7QUFDRCxnQkFBSSxhQUFhLEtBQUssS0FBdEI7QUFDQSxnQkFBSSxjQUFjLE9BQU8sVUFBUCxLQUFzQixRQUFwQyxJQUFnRCxzQkFBc0IsTUFBMUUsRUFBaUY7QUFDN0UscUJBQUssSUFBTCxDQUFVLEtBQVYsR0FBa0IsVUFBbEI7QUFDSCxhQUZELE1BRU0sSUFBRyxLQUFLLElBQUwsQ0FBVSxhQUFiLEVBQTJCO0FBQzdCLHFCQUFLLElBQUwsQ0FBVSxLQUFWLEdBQWtCO0FBQUEsMkJBQU0sS0FBSyxJQUFMLENBQVUsYUFBVixDQUF3QixFQUFFLEdBQTFCLENBQU47QUFBQSxpQkFBbEI7QUFDSDs7QUFFRCxtQkFBTyxJQUFQO0FBQ0g7OztpQ0FJTzs7QUFFSixnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxJQUFJLEtBQUssQ0FBYjtBQUNBLGdCQUFJLE9BQU8sS0FBSyxNQUFMLENBQVksQ0FBdkI7Ozs7Ozs7O0FBUUEsY0FBRSxLQUFGLEdBQVU7QUFBQSx1QkFBSyxLQUFLLEtBQUwsQ0FBVyxDQUFYLEVBQWMsS0FBSyxHQUFuQixDQUFMO0FBQUEsYUFBVjtBQUNBLGNBQUUsS0FBRixHQUFVLEdBQUcsS0FBSCxDQUFTLE9BQVQsR0FBbUIsZUFBbkIsQ0FBbUMsQ0FBQyxDQUFELEVBQUksS0FBSyxLQUFULENBQW5DLEVBQW9ELEdBQXBELENBQVY7QUFDQSxjQUFFLEdBQUYsR0FBUTtBQUFBLHVCQUFLLEVBQUUsS0FBRixDQUFRLEVBQUUsS0FBRixDQUFRLENBQVIsQ0FBUixDQUFMO0FBQUEsYUFBUjs7QUFFQSxjQUFFLElBQUYsR0FBUyxHQUFHLEdBQUgsQ0FBTyxJQUFQLEdBQWMsS0FBZCxDQUFvQixFQUFFLEtBQXRCLEVBQTZCLE1BQTdCLENBQW9DLEtBQUssTUFBekMsQ0FBVDs7QUFFQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxNQUFKO0FBQ0EsZ0JBQUcsQ0FBQyxLQUFLLE1BQUwsQ0FBWSxNQUFoQixFQUF1QjtBQUNuQix5QkFBUyxHQUFHLEdBQUgsQ0FBTyxJQUFQLEVBQWEsRUFBRSxLQUFmLEVBQXNCLElBQXRCLEVBQVQ7QUFDSCxhQUZELE1BRUs7QUFDRCx5QkFBUyxHQUFHLEdBQUgsQ0FBTyxLQUFLLENBQUwsRUFBUSxNQUFmLEVBQXVCLEVBQUUsS0FBekIsRUFBZ0MsSUFBaEMsRUFBVDtBQUNIOztBQUVELGlCQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsTUFBYixDQUFvQixNQUFwQjtBQUNBLG9CQUFRLEdBQVIsQ0FBWSxzQkFBWixFQUFvQyxLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsTUFBYixFQUFwQztBQUVIOzs7aUNBRVE7O0FBRUwsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsZ0JBQUksSUFBSSxLQUFLLENBQWI7QUFDQSxnQkFBSSxPQUFPLEtBQUssTUFBTCxDQUFZLENBQXZCO0FBQ0EsY0FBRSxLQUFGLEdBQVU7QUFBQSx1QkFBSyxLQUFLLEtBQUwsQ0FBVyxDQUFYLEVBQWMsS0FBSyxHQUFuQixDQUFMO0FBQUEsYUFBVjtBQUNBLGNBQUUsS0FBRixHQUFVLEdBQUcsS0FBSCxDQUFTLEtBQUssS0FBZCxJQUF1QixLQUF2QixDQUE2QixDQUFDLEtBQUssTUFBTixFQUFjLENBQWQsQ0FBN0IsQ0FBVjtBQUNBLGNBQUUsR0FBRixHQUFRO0FBQUEsdUJBQUssRUFBRSxLQUFGLENBQVEsRUFBRSxLQUFGLENBQVEsQ0FBUixDQUFSLENBQUw7QUFBQSxhQUFSOztBQUVBLGNBQUUsSUFBRixHQUFTLEdBQUcsR0FBSCxDQUFPLElBQVAsR0FBYyxLQUFkLENBQW9CLEVBQUUsS0FBdEIsRUFBNkIsTUFBN0IsQ0FBb0MsS0FBSyxNQUF6QyxDQUFUO0FBQ0EsZ0JBQUcsS0FBSyxLQUFSLEVBQWM7QUFDVixrQkFBRSxJQUFGLENBQU8sS0FBUCxDQUFhLEtBQUssS0FBbEI7QUFDSDtBQUNKOzs7dUNBRWM7QUFDWCxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxNQUFKO0FBQ0EsZ0JBQUksWUFBWSxHQUFHLEdBQUgsQ0FBTyxLQUFLLE1BQVosRUFBb0I7QUFBQSx1QkFBUyxHQUFHLEdBQUgsQ0FBTyxNQUFNLE1BQWIsRUFBcUI7QUFBQSwyQkFBSyxFQUFFLEVBQUYsR0FBTyxFQUFFLENBQWQ7QUFBQSxpQkFBckIsQ0FBVDtBQUFBLGFBQXBCLENBQWhCO0FBQ0EsZ0JBQUcsQ0FBQyxLQUFLLE1BQUwsQ0FBWSxNQUFoQixFQUF1QjtBQUNuQix5QkFBUyxDQUFDLEdBQUcsR0FBSCxDQUFPLElBQVAsRUFBYSxLQUFLLENBQUwsQ0FBTyxLQUFwQixDQUFELEVBQTZCLEdBQUcsR0FBSCxDQUFPLElBQVAsRUFBYSxLQUFLLENBQUwsQ0FBTyxLQUFwQixDQUE3QixDQUFUO0FBQ0gsYUFGRCxNQUVLOzs7QUFHRCxvQkFBSSxNQUFNLFNBQVY7QUFDQSx5QkFBUyxDQUFDLENBQUQsRUFBSSxHQUFKLENBQVQ7QUFDSDtBQUNELGlCQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsTUFBYixDQUFvQixNQUFwQjtBQUNBLG9CQUFRLEdBQVIsQ0FBWSxzQkFBWixFQUFvQyxLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsTUFBYixFQUFwQztBQUNIOzs7b0NBQ1U7QUFDUCxnQkFBSSxPQUFLLElBQVQ7QUFDQSxpQkFBSyxJQUFMLENBQVUsZUFBVixHQUE0QixLQUFLLE1BQUwsQ0FBWSxNQUF4QztBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFHLENBQUMsS0FBSyxJQUFMLENBQVUsZUFBZCxFQUErQjtBQUMzQixxQkFBSyxJQUFMLENBQVUsV0FBVixHQUF5QixDQUFDO0FBQ3RCLHlCQUFLLE1BRGlCO0FBRXRCLDRCQUFRLEtBQUssV0FBTCxDQUFpQixJQUFqQjtBQUZjLGlCQUFELENBQXpCO0FBSUgsYUFMRCxNQUtLOztBQUVELHFCQUFLLElBQUwsQ0FBVSxXQUFWLEdBQXlCLEtBQUssR0FBTCxDQUFTLGFBQUc7QUFDakMsMkJBQU07QUFDRiw2QkFBSyxFQUFFLEdBREw7QUFFRixnQ0FBUSxLQUFLLFdBQUwsQ0FBaUIsRUFBRSxNQUFuQjtBQUZOLHFCQUFOO0FBSUgsaUJBTHdCLENBQXpCO0FBT0g7QUFDSjs7OzJDQUNrQjtBQUNmLGdCQUFJLE9BQUssSUFBVDtBQUNBLGlCQUFLLFNBQUw7O0FBRUEsaUJBQUssSUFBTCxDQUFVLEtBQVYsR0FBa0IsR0FBRyxNQUFILENBQVUsS0FBVixHQUFrQixNQUFsQixDQUF5QjtBQUFBLHVCQUFHLEVBQUUsTUFBTDtBQUFBLGFBQXpCLENBQWxCO0FBQ0EsaUJBQUssSUFBTCxDQUFVLE1BQVYsR0FBbUIsS0FBSyxJQUFMLENBQVUsS0FBVixDQUFnQixLQUFLLElBQUwsQ0FBVSxXQUExQixDQUFuQjtBQUVIOzs7b0NBRVcsTSxFQUFPO0FBQ2YsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsbUJBQU8sT0FBTyxHQUFQLENBQVcsYUFBRztBQUNqQix1QkFBTztBQUNILHVCQUFHLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxDQUFiLENBREE7QUFFSCx1QkFBRyxLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsQ0FBYjtBQUZBLGlCQUFQO0FBSUgsYUFMTSxDQUFQO0FBTUg7OztvQ0FFVTtBQUNQLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLFdBQVcsS0FBSyxNQUFMLENBQVksQ0FBM0I7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBTCxDQUFVLGNBQVYsQ0FBeUIsT0FBSyxLQUFLLFdBQUwsQ0FBaUIsUUFBakIsQ0FBTCxHQUFnQyxHQUFoQyxHQUFvQyxLQUFLLFdBQUwsQ0FBaUIsTUFBakIsQ0FBcEMsSUFBOEQsS0FBSyxNQUFMLENBQVksTUFBWixHQUFxQixFQUFyQixHQUEwQixNQUFJLEtBQUssV0FBTCxDQUFpQixXQUFqQixDQUE1RixDQUF6QixFQUNOLElBRE0sQ0FDRCxXQURDLEVBQ1ksaUJBQWlCLEtBQUssTUFBdEIsR0FBK0IsR0FEM0MsQ0FBWDs7QUFHQSxnQkFBSSxRQUFRLElBQVo7QUFDQSxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxVQUFoQixFQUE0QjtBQUN4Qix3QkFBUSxLQUFLLFVBQUwsR0FBa0IsSUFBbEIsQ0FBdUIsWUFBdkIsQ0FBUjtBQUNIOztBQUVELGtCQUFNLElBQU4sQ0FBVyxLQUFLLENBQUwsQ0FBTyxJQUFsQjs7QUFFQSxpQkFBSyxjQUFMLENBQW9CLFVBQVEsS0FBSyxXQUFMLENBQWlCLE9BQWpCLENBQTVCLEVBQ0ssSUFETCxDQUNVLFdBRFYsRUFDdUIsZUFBZSxLQUFLLEtBQUwsR0FBVyxDQUExQixHQUE4QixHQUE5QixHQUFvQyxLQUFLLE1BQUwsQ0FBWSxNQUFoRCxHQUF5RCxHQURoRixDO0FBQUEsYUFFSyxJQUZMLENBRVUsSUFGVixFQUVnQixNQUZoQixFQUdLLEtBSEwsQ0FHVyxhQUhYLEVBRzBCLFFBSDFCLEVBSUssSUFKTCxDQUlVLFNBQVMsS0FKbkI7QUFLSDs7O29DQUVVO0FBQ1AsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsZ0JBQUksV0FBVyxLQUFLLE1BQUwsQ0FBWSxDQUEzQjtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFMLENBQVUsY0FBVixDQUF5QixPQUFLLEtBQUssV0FBTCxDQUFpQixRQUFqQixDQUFMLEdBQWdDLEdBQWhDLEdBQW9DLEtBQUssV0FBTCxDQUFpQixNQUFqQixDQUFwQyxJQUE4RCxLQUFLLE1BQUwsQ0FBWSxNQUFaLEdBQXFCLEVBQXJCLEdBQTBCLE1BQUksS0FBSyxXQUFMLENBQWlCLFdBQWpCLENBQTVGLENBQXpCLENBQVg7O0FBRUEsZ0JBQUksUUFBUSxJQUFaO0FBQ0EsZ0JBQUksS0FBSyxNQUFMLENBQVksVUFBaEIsRUFBNEI7QUFDeEIsd0JBQVEsS0FBSyxVQUFMLEdBQWtCLElBQWxCLENBQXVCLFlBQXZCLENBQVI7QUFDSDs7QUFFRCxrQkFBTSxJQUFOLENBQVcsS0FBSyxDQUFMLENBQU8sSUFBbEI7O0FBRUEsaUJBQUssY0FBTCxDQUFvQixVQUFRLEtBQUssV0FBTCxDQUFpQixPQUFqQixDQUE1QixFQUNLLElBREwsQ0FDVSxXQURWLEVBQ3VCLGVBQWMsQ0FBQyxLQUFLLE1BQUwsQ0FBWSxJQUEzQixHQUFpQyxHQUFqQyxHQUFzQyxLQUFLLE1BQUwsR0FBWSxDQUFsRCxHQUFxRCxjQUQ1RSxDO0FBQUEsYUFFSyxJQUZMLENBRVUsSUFGVixFQUVnQixLQUZoQixFQUdLLEtBSEwsQ0FHVyxhQUhYLEVBRzBCLFFBSDFCLEVBSUssSUFKTCxDQUlVLFNBQVMsS0FKbkI7QUFLSDs7O21DQUdVO0FBQ1AsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQWhCOztBQUVBLG9CQUFRLEdBQVIsQ0FBWSxLQUFLLE1BQWpCOztBQUVBLGdCQUFJLGFBQWEsS0FBSyxXQUFMLENBQWlCLE9BQWpCLENBQWpCOztBQUVBLGdCQUFJLFdBQVcsS0FBSyxXQUFMLENBQWlCLEtBQWpCLENBQWY7QUFDQSxnQkFBSSxRQUFRLEtBQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsTUFBSSxVQUF4QixFQUNQLElBRE8sQ0FDRixLQUFLLE1BREgsQ0FBWjs7QUFHQSxrQkFBTSxLQUFOLEdBQWMsTUFBZCxDQUFxQixHQUFyQixFQUNLLElBREwsQ0FDVSxPQURWLEVBQ21CLFVBRG5COztBQUdBLGdCQUFJLE1BQU0sTUFBTSxTQUFOLENBQWdCLE1BQUksUUFBcEIsRUFDTCxJQURLLENBQ0E7QUFBQSx1QkFBSyxFQUFFLE1BQVA7QUFBQSxhQURBLENBQVY7O0FBR0EsZ0JBQUksS0FBSixHQUFZLE1BQVosQ0FBbUIsR0FBbkIsRUFDSyxJQURMLENBQ1UsT0FEVixFQUNtQixRQURuQixFQUVLLE1BRkwsQ0FFWSxNQUZaLEVBR0ssSUFITCxDQUdVLEdBSFYsRUFHZSxDQUhmOztBQU1BLGdCQUFJLFVBQVUsSUFBSSxNQUFKLENBQVcsTUFBWCxDQUFkOztBQUVBLGdCQUFJLFdBQVcsT0FBZjtBQUNBLGdCQUFJLE9BQU8sR0FBWDtBQUNBLGdCQUFJLFNBQVMsS0FBYjtBQUNBLGdCQUFJLEtBQUssaUJBQUwsRUFBSixFQUE4QjtBQUMxQiwyQkFBVyxRQUFRLFVBQVIsRUFBWDtBQUNBLHVCQUFPLElBQUksVUFBSixFQUFQO0FBQ0EseUJBQVEsTUFBTSxVQUFOLEVBQVI7QUFDSDs7QUFFRCxnQkFBSSxVQUFVLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxNQUFiLEVBQWQ7QUFDQSxpQkFBSyxJQUFMLENBQVUsV0FBVixFQUF1QixVQUFTLENBQVQsRUFBWTtBQUFFLHVCQUFPLGVBQWUsS0FBSyxDQUFMLENBQU8sS0FBUCxDQUFhLEVBQUUsQ0FBZixDQUFmLEdBQW1DLEdBQW5DLEdBQTBDLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxFQUFFLEVBQUYsR0FBSyxFQUFFLENBQXBCLENBQTFDLEdBQXFFLEdBQTVFO0FBQWtGLGFBQXZIOztBQUVBLHFCQUNLLElBREwsQ0FDVSxPQURWLEVBQ29CLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxTQUFiLEVBRHBCLEVBRUssSUFGTCxDQUVVLFFBRlYsRUFFb0I7QUFBQSx1QkFBTyxLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsRUFBRSxFQUFmLElBQXNCLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxFQUFFLEVBQUYsR0FBTyxFQUFFLENBQVQsR0FBYSxRQUFRLENBQVIsQ0FBMUIsQ0FBN0I7QUFBQSxhQUZwQjs7QUFLQSxnQkFBRyxLQUFLLElBQUwsQ0FBVSxLQUFiLEVBQW1CO0FBQ2YsdUJBQ0ssSUFETCxDQUNVLE1BRFYsRUFDa0IsS0FBSyxJQUFMLENBQVUsS0FENUI7QUFFSDs7QUFFRCxnQkFBSSxLQUFLLE9BQVQsRUFBa0I7QUFDZCxvQkFBSSxFQUFKLENBQU8sV0FBUCxFQUFvQixhQUFLO0FBQ3JCLHlCQUFLLE9BQUwsQ0FBYSxVQUFiLEdBQ0ssUUFETCxDQUNjLEdBRGQsRUFFSyxLQUZMLENBRVcsU0FGWCxFQUVzQixFQUZ0QjtBQUdBLHlCQUFLLE9BQUwsQ0FBYSxJQUFiLENBQWtCLEVBQUUsQ0FBcEIsRUFDSyxLQURMLENBQ1csTUFEWCxFQUNvQixHQUFHLEtBQUgsQ0FBUyxLQUFULEdBQWlCLENBQWxCLEdBQXVCLElBRDFDLEVBRUssS0FGTCxDQUVXLEtBRlgsRUFFbUIsR0FBRyxLQUFILENBQVMsS0FBVCxHQUFpQixFQUFsQixHQUF3QixJQUYxQztBQUdILGlCQVBELEVBT0csRUFQSCxDQU9NLFVBUE4sRUFPa0IsYUFBSztBQUNuQix5QkFBSyxPQUFMLENBQWEsVUFBYixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsQ0FGdEI7QUFHSCxpQkFYRDtBQVlIO0FBQ0Qsa0JBQU0sSUFBTixHQUFhLE1BQWI7QUFDQSxnQkFBSSxJQUFKLEdBQVcsTUFBWDtBQUNIOzs7K0JBRU0sTyxFQUFRO0FBQ1gsdUZBQWEsT0FBYjtBQUNBLGlCQUFLLFNBQUw7QUFDQSxpQkFBSyxTQUFMOztBQUVBLGlCQUFLLFFBQUw7O0FBRUEsaUJBQUssWUFBTDtBQUNIOzs7dUNBR2M7QUFDWCxnQkFBSSxPQUFPLEtBQUssSUFBaEI7O0FBRUEsZ0JBQUksUUFBUSxLQUFLLGFBQWpCO0FBQ0EsZ0JBQUcsQ0FBQyxNQUFNLE1BQU4sRUFBRCxJQUFtQixNQUFNLE1BQU4sR0FBZSxNQUFmLEdBQXNCLENBQTVDLEVBQThDO0FBQzFDLHFCQUFLLFVBQUwsR0FBa0IsS0FBbEI7QUFDSDs7QUFFRCxnQkFBRyxDQUFDLEtBQUssVUFBVCxFQUFvQjtBQUNoQixvQkFBRyxLQUFLLE1BQUwsSUFBZSxLQUFLLE1BQUwsQ0FBWSxTQUE5QixFQUF3QztBQUNwQyx5QkFBSyxNQUFMLENBQVksU0FBWixDQUFzQixNQUF0QjtBQUNIO0FBQ0Q7QUFDSDs7QUFHRCxnQkFBSSxVQUFVLEtBQUssSUFBTCxDQUFVLEtBQVYsR0FBa0IsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixNQUFuRDtBQUNBLGdCQUFJLFVBQVUsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixNQUFqQzs7QUFFQSxpQkFBSyxNQUFMLEdBQWMsbUJBQVcsS0FBSyxHQUFoQixFQUFxQixLQUFLLElBQTFCLEVBQWdDLEtBQWhDLEVBQXVDLE9BQXZDLEVBQWdELE9BQWhELENBQWQ7O0FBRUEsZ0JBQUksZUFBZSxLQUFLLE1BQUwsQ0FBWSxLQUFaLEdBQ2QsVUFEYyxDQUNILEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBbUIsVUFEaEIsRUFFZCxNQUZjLENBRVAsVUFGTyxFQUdkLEtBSGMsQ0FHUixLQUhRLENBQW5COztBQUtBLGlCQUFLLE1BQUwsQ0FBWSxTQUFaLENBQ0ssSUFETCxDQUNVLFlBRFY7QUFFSDs7Ozs7Ozs7Ozs7Ozs7OztBQ3hWTDs7OztJQUdhLFcsV0FBQSxXLEdBY1QscUJBQVksTUFBWixFQUFvQjtBQUFBOztBQUFBLFNBYnBCLGNBYW9CLEdBYkgsTUFhRztBQUFBLFNBWnBCLFFBWW9CLEdBWlQsS0FBSyxjQUFMLEdBQXNCLGFBWWI7QUFBQSxTQVhwQixLQVdvQixHQVhaLFNBV1k7QUFBQSxTQVZwQixNQVVvQixHQVZYLFNBVVc7QUFBQSxTQVRwQixNQVNvQixHQVRYO0FBQ0wsY0FBTSxFQUREO0FBRUwsZUFBTyxFQUZGO0FBR0wsYUFBSyxFQUhBO0FBSUwsZ0JBQVE7QUFKSCxLQVNXO0FBQUEsU0FIcEIsV0FHb0IsR0FITixLQUdNO0FBQUEsU0FGcEIsVUFFb0IsR0FGUCxJQUVPOztBQUNoQixRQUFJLE1BQUosRUFBWTtBQUNSLHFCQUFNLFVBQU4sQ0FBaUIsSUFBakIsRUFBdUIsTUFBdkI7QUFDSDtBQUNKLEM7O0lBS1EsSyxXQUFBLEs7QUFlVCxtQkFBWSxJQUFaLEVBQWtCLElBQWxCLEVBQXdCLE1BQXhCLEVBQWdDO0FBQUE7O0FBQUEsYUFkaEMsS0FjZ0M7QUFBQSxhQVZoQyxJQVVnQyxHQVZ6QjtBQUNILG9CQUFRO0FBREwsU0FVeUI7QUFBQSxhQVBoQyxTQU9nQyxHQVBwQixFQU9vQjtBQUFBLGFBTmhDLE9BTWdDLEdBTnRCLEVBTXNCO0FBQUEsYUFMaEMsT0FLZ0MsR0FMdEIsRUFLc0I7QUFBQSxhQUhoQyxjQUdnQyxHQUhqQixLQUdpQjs7O0FBRTVCLGFBQUssV0FBTCxHQUFtQixnQkFBZ0IsS0FBbkM7O0FBRUEsYUFBSyxhQUFMLEdBQXFCLElBQXJCOztBQUVBLGFBQUssU0FBTCxDQUFlLE1BQWY7O0FBRUEsWUFBSSxJQUFKLEVBQVU7QUFDTixpQkFBSyxPQUFMLENBQWEsSUFBYjtBQUNIOztBQUVELGFBQUssSUFBTDtBQUNBLGFBQUssUUFBTDtBQUNIOzs7O2tDQUVTLE0sRUFBUTtBQUNkLGdCQUFJLENBQUMsTUFBTCxFQUFhO0FBQ1QscUJBQUssTUFBTCxHQUFjLElBQUksV0FBSixFQUFkO0FBQ0gsYUFGRCxNQUVPO0FBQ0gscUJBQUssTUFBTCxHQUFjLE1BQWQ7QUFDSDs7QUFFRCxtQkFBTyxJQUFQO0FBQ0g7OztnQ0FFTyxJLEVBQU07QUFDVixpQkFBSyxJQUFMLEdBQVksSUFBWjtBQUNBLG1CQUFPLElBQVA7QUFDSDs7OytCQUVNO0FBQ0gsZ0JBQUksT0FBTyxJQUFYOztBQUdBLGlCQUFLLFFBQUw7QUFDQSxpQkFBSyxPQUFMOztBQUVBLGlCQUFLLFdBQUw7QUFDQSxpQkFBSyxJQUFMO0FBQ0EsaUJBQUssY0FBTCxHQUFvQixJQUFwQjtBQUNBLG1CQUFPLElBQVA7QUFDSDs7O21DQUVTLENBRVQ7OztrQ0FFUztBQUNOLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLFNBQVMsS0FBSyxNQUFsQjs7QUFFQSxnQkFBSSxTQUFTLEtBQUssSUFBTCxDQUFVLE1BQXZCO0FBQ0EsZ0JBQUksUUFBUSxLQUFLLElBQUwsQ0FBVSxLQUFWLEdBQWtCLE9BQU8sSUFBekIsR0FBZ0MsT0FBTyxLQUFuRDtBQUNBLGdCQUFJLFNBQVMsS0FBSyxJQUFMLENBQVUsTUFBVixHQUFtQixPQUFPLEdBQTFCLEdBQWdDLE9BQU8sTUFBcEQ7QUFDQSxnQkFBSSxTQUFTLFFBQVEsTUFBckI7QUFDQSxnQkFBRyxDQUFDLEtBQUssV0FBVCxFQUFxQjtBQUNqQixvQkFBRyxDQUFDLEtBQUssY0FBVCxFQUF3QjtBQUNwQix1QkFBRyxNQUFILENBQVUsS0FBSyxhQUFmLEVBQThCLE1BQTlCLENBQXFDLEtBQXJDLEVBQTRDLE1BQTVDO0FBQ0g7QUFDRCxxQkFBSyxHQUFMLEdBQVcsR0FBRyxNQUFILENBQVUsS0FBSyxhQUFmLEVBQThCLGNBQTlCLENBQTZDLEtBQTdDLENBQVg7O0FBRUEscUJBQUssR0FBTCxDQUNLLElBREwsQ0FDVSxPQURWLEVBQ21CLEtBRG5CLEVBRUssSUFGTCxDQUVVLFFBRlYsRUFFb0IsTUFGcEIsRUFHSyxJQUhMLENBR1UsU0FIVixFQUdxQixTQUFTLEdBQVQsR0FBZSxLQUFmLEdBQXVCLEdBQXZCLEdBQTZCLE1BSGxELEVBSUssSUFKTCxDQUlVLHFCQUpWLEVBSWlDLGVBSmpDLEVBS0ssSUFMTCxDQUtVLE9BTFYsRUFLbUIsT0FBTyxRQUwxQjtBQU1BLHFCQUFLLElBQUwsR0FBWSxLQUFLLEdBQUwsQ0FBUyxjQUFULENBQXdCLGNBQXhCLENBQVo7QUFDSCxhQWJELE1BYUs7QUFDRCx3QkFBUSxHQUFSLENBQVksS0FBSyxhQUFqQjtBQUNBLHFCQUFLLEdBQUwsR0FBVyxLQUFLLGFBQUwsQ0FBbUIsR0FBOUI7QUFDQSxxQkFBSyxJQUFMLEdBQVksS0FBSyxHQUFMLENBQVMsY0FBVCxDQUF3QixrQkFBZ0IsT0FBTyxRQUEvQyxDQUFaO0FBQ0g7O0FBRUQsaUJBQUssSUFBTCxDQUFVLElBQVYsQ0FBZSxXQUFmLEVBQTRCLGVBQWUsT0FBTyxJQUF0QixHQUE2QixHQUE3QixHQUFtQyxPQUFPLEdBQTFDLEdBQWdELEdBQTVFOztBQUVBLGdCQUFJLENBQUMsT0FBTyxLQUFSLElBQWlCLE9BQU8sTUFBNUIsRUFBb0M7QUFDaEMsbUJBQUcsTUFBSCxDQUFVLE1BQVYsRUFDSyxFQURMLENBQ1EsUUFEUixFQUNrQixZQUFZOztBQUV6QixpQkFITDtBQUlIO0FBQ0o7OztzQ0FFWTtBQUNULGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLEtBQUssTUFBTCxDQUFZLFdBQWhCLEVBQTZCO0FBQ3pCLG9CQUFHLENBQUMsS0FBSyxXQUFULEVBQXNCO0FBQ2xCLHlCQUFLLElBQUwsQ0FBVSxPQUFWLEdBQW9CLEdBQUcsTUFBSCxDQUFVLE1BQVYsRUFBa0IsY0FBbEIsQ0FBaUMsU0FBTyxLQUFLLE1BQUwsQ0FBWSxjQUFuQixHQUFrQyxTQUFuRSxFQUNmLEtBRGUsQ0FDVCxTQURTLEVBQ0UsQ0FERixDQUFwQjtBQUVILGlCQUhELE1BR0s7QUFDRCx5QkFBSyxJQUFMLENBQVUsT0FBVixHQUFtQixLQUFLLGFBQUwsQ0FBbUIsSUFBbkIsQ0FBd0IsT0FBM0M7QUFDSDtBQUVKO0FBQ0o7OzttQ0FFVTtBQUNQLGdCQUFJLFNBQVMsS0FBSyxNQUFMLENBQVksTUFBekI7QUFDQSxpQkFBSyxJQUFMLEdBQVksS0FBSyxJQUFMLElBQWEsRUFBekI7QUFDQSxpQkFBSyxJQUFMLENBQVUsTUFBVixHQUFtQjtBQUNmLHFCQUFLLE9BQU8sR0FERztBQUVmLHdCQUFRLE9BQU8sTUFGQTtBQUdmLHNCQUFNLE9BQU8sSUFIRTtBQUlmLHVCQUFPLE9BQU87QUFKQyxhQUFuQjtBQU1IOzs7K0JBRU0sSSxFQUFNO0FBQ1QsZ0JBQUksSUFBSixFQUFVO0FBQ04scUJBQUssT0FBTCxDQUFhLElBQWI7QUFDSDtBQUNELGdCQUFJLFNBQUosRUFBZSxjQUFmO0FBQ0EsaUJBQUssSUFBSSxjQUFULElBQTJCLEtBQUssU0FBaEMsRUFBMkM7O0FBRXZDLGlDQUFpQixJQUFqQjs7QUFFQSxxQkFBSyxTQUFMLENBQWUsY0FBZixFQUErQixNQUEvQixDQUFzQyxjQUF0QztBQUNIO0FBQ0QsbUJBQU8sSUFBUDtBQUNIOzs7NkJBRUksSSxFQUFNO0FBQ1AsaUJBQUssTUFBTCxDQUFZLElBQVo7O0FBR0EsbUJBQU8sSUFBUDtBQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrQkFrQk0sYyxFQUFnQixLLEVBQU87QUFDMUIsZ0JBQUksVUFBVSxNQUFWLEtBQXFCLENBQXpCLEVBQTRCO0FBQ3hCLHVCQUFPLEtBQUssU0FBTCxDQUFlLGNBQWYsQ0FBUDtBQUNIOztBQUVELGlCQUFLLFNBQUwsQ0FBZSxjQUFmLElBQWlDLEtBQWpDO0FBQ0EsbUJBQU8sS0FBUDtBQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsyQkFtQkUsSSxFQUFNLFEsRUFBVSxPLEVBQVM7QUFDeEIsZ0JBQUksU0FBUyxLQUFLLE9BQUwsQ0FBYSxJQUFiLE1BQXVCLEtBQUssT0FBTCxDQUFhLElBQWIsSUFBcUIsRUFBNUMsQ0FBYjtBQUNBLG1CQUFPLElBQVAsQ0FBWTtBQUNSLDBCQUFVLFFBREY7QUFFUix5QkFBUyxXQUFXLElBRlo7QUFHUix3QkFBUTtBQUhBLGFBQVo7QUFLQSxtQkFBTyxJQUFQO0FBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzZCQW9CSSxJLEVBQU0sUSxFQUFVLE8sRUFBUztBQUMxQixnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLFNBQVAsSUFBTyxHQUFZO0FBQ25CLHFCQUFLLEdBQUwsQ0FBUyxJQUFULEVBQWUsSUFBZjtBQUNBLHlCQUFTLEtBQVQsQ0FBZSxJQUFmLEVBQXFCLFNBQXJCO0FBQ0gsYUFIRDtBQUlBLG1CQUFPLEtBQUssRUFBTCxDQUFRLElBQVIsRUFBYyxJQUFkLEVBQW9CLE9BQXBCLENBQVA7QUFDSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7NEJBc0JHLEksRUFBTSxRLEVBQVUsTyxFQUFTO0FBQ3pCLGdCQUFJLEtBQUosRUFBVyxDQUFYLEVBQWMsTUFBZCxFQUFzQixLQUF0QixFQUE2QixDQUE3QixFQUFnQyxDQUFoQzs7O0FBR0EsZ0JBQUksVUFBVSxNQUFWLEtBQXFCLENBQXpCLEVBQTRCO0FBQ3hCLHFCQUFLLElBQUwsSUFBYSxLQUFLLE9BQWxCLEVBQTJCO0FBQ3ZCLHlCQUFLLE9BQUwsQ0FBYSxJQUFiLEVBQW1CLE1BQW5CLEdBQTRCLENBQTVCO0FBQ0g7QUFDRCx1QkFBTyxJQUFQO0FBQ0g7OztBQUdELGdCQUFJLFVBQVUsTUFBVixLQUFxQixDQUF6QixFQUE0QjtBQUN4Qix5QkFBUyxLQUFLLE9BQUwsQ0FBYSxJQUFiLENBQVQ7QUFDQSxvQkFBSSxNQUFKLEVBQVk7QUFDUiwyQkFBTyxNQUFQLEdBQWdCLENBQWhCO0FBQ0g7QUFDRCx1QkFBTyxJQUFQO0FBQ0g7Ozs7QUFJRCxvQkFBUSxPQUFPLENBQUMsSUFBRCxDQUFQLEdBQWdCLE9BQU8sSUFBUCxDQUFZLEtBQUssT0FBakIsQ0FBeEI7QUFDQSxpQkFBSyxJQUFJLENBQVQsRUFBWSxJQUFJLE1BQU0sTUFBdEIsRUFBOEIsR0FBOUIsRUFBbUM7QUFDL0Isb0JBQUksTUFBTSxDQUFOLENBQUo7QUFDQSx5QkFBUyxLQUFLLE9BQUwsQ0FBYSxDQUFiLENBQVQ7QUFDQSxvQkFBSSxPQUFPLE1BQVg7QUFDQSx1QkFBTyxHQUFQLEVBQVk7QUFDUiw0QkFBUSxPQUFPLENBQVAsQ0FBUjtBQUNBLHdCQUFLLFlBQVksYUFBYSxNQUFNLFFBQWhDLElBQ0MsV0FBVyxZQUFZLE1BQU0sT0FEbEMsRUFDNEM7QUFDeEMsK0JBQU8sTUFBUCxDQUFjLENBQWQsRUFBaUIsQ0FBakI7QUFDSDtBQUNKO0FBQ0o7O0FBRUQsbUJBQU8sSUFBUDtBQUNIOzs7Ozs7Ozs7Ozs7Ozs7OztnQ0FjTyxJLEVBQU07QUFDVixnQkFBSSxPQUFPLE1BQU0sU0FBTixDQUFnQixLQUFoQixDQUFzQixJQUF0QixDQUEyQixTQUEzQixFQUFzQyxDQUF0QyxDQUFYO0FBQ0EsZ0JBQUksU0FBUyxLQUFLLE9BQUwsQ0FBYSxJQUFiLENBQWI7QUFDQSxnQkFBSSxDQUFKLEVBQU8sRUFBUDs7QUFFQSxnQkFBSSxXQUFXLFNBQWYsRUFBMEI7QUFDdEIscUJBQUssSUFBSSxDQUFULEVBQVksSUFBSSxPQUFPLE1BQXZCLEVBQStCLEdBQS9CLEVBQW9DO0FBQ2hDLHlCQUFLLE9BQU8sQ0FBUCxDQUFMO0FBQ0EsdUJBQUcsUUFBSCxDQUFZLEtBQVosQ0FBa0IsR0FBRyxPQUFyQixFQUE4QixJQUE5QjtBQUNIO0FBQ0o7O0FBRUQsbUJBQU8sSUFBUDtBQUNIOzs7MkNBQ2lCO0FBQ2QsZ0JBQUcsS0FBSyxXQUFSLEVBQW9CO0FBQ2hCLHVCQUFPLEtBQUssYUFBTCxDQUFtQixHQUExQjtBQUNIO0FBQ0QsbUJBQU8sR0FBRyxNQUFILENBQVUsS0FBSyxhQUFmLENBQVA7QUFDSDs7OytDQUVxQjs7QUFFbEIsbUJBQU8sS0FBSyxnQkFBTCxHQUF3QixJQUF4QixFQUFQO0FBQ0g7OztvQ0FFVyxLLEVBQU8sTSxFQUFPO0FBQ3RCLG1CQUFPLFNBQVEsR0FBUixHQUFhLEtBQUcsS0FBSyxNQUFMLENBQVksY0FBZixHQUE4QixLQUFsRDtBQUNIOzs7MENBQ2lCO0FBQ2QsaUJBQUssSUFBTCxDQUFVLEtBQVYsR0FBa0IsYUFBTSxjQUFOLENBQXFCLEtBQUssTUFBTCxDQUFZLEtBQWpDLEVBQXdDLEtBQUssZ0JBQUwsRUFBeEMsRUFBaUUsS0FBSyxJQUFMLENBQVUsTUFBM0UsQ0FBbEI7QUFDQSxpQkFBSyxJQUFMLENBQVUsTUFBVixHQUFtQixhQUFNLGVBQU4sQ0FBc0IsS0FBSyxNQUFMLENBQVksTUFBbEMsRUFBMEMsS0FBSyxnQkFBTCxFQUExQyxFQUFtRSxLQUFLLElBQUwsQ0FBVSxNQUE3RSxDQUFuQjtBQUNIOzs7NENBRWtCO0FBQ2YsbUJBQU8sS0FBSyxjQUFMLElBQXVCLEtBQUssTUFBTCxDQUFZLFVBQTFDO0FBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3JXTDs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7SUFFYSx1QixXQUFBLHVCOzs7OztBQW9DVCxxQ0FBWSxNQUFaLEVBQW9CO0FBQUE7O0FBQUE7O0FBQUEsY0FsQ3BCLFFBa0NvQixHQWxDVCxNQUFLLGNBQUwsR0FBb0Isb0JBa0NYO0FBQUEsY0FqQ3BCLE1BaUNvQixHQWpDWCxLQWlDVztBQUFBLGNBaENwQixXQWdDb0IsR0FoQ04sSUFnQ007QUFBQSxjQS9CcEIsVUErQm9CLEdBL0JQLElBK0JPO0FBQUEsY0E5QnBCLGVBOEJvQixHQTlCRixJQThCRTtBQUFBLGNBN0JwQixhQTZCb0IsR0E3QkosSUE2Qkk7QUFBQSxjQTVCcEIsYUE0Qm9CLEdBNUJKLElBNEJJO0FBQUEsY0EzQnBCLFNBMkJvQixHQTNCUjtBQUNSLG9CQUFRLFNBREE7QUFFUixrQkFBTSxFQUZFLEU7QUFHUixtQkFBTyxlQUFDLENBQUQsRUFBSSxXQUFKO0FBQUEsdUJBQW9CLEVBQUUsV0FBRixDQUFwQjtBQUFBLGFBSEMsRTtBQUlSLG1CQUFPO0FBSkMsU0EyQlE7QUFBQSxjQXJCcEIsV0FxQm9CLEdBckJOO0FBQ1YsbUJBQU8sUUFERztBQUVWLG9CQUFRLENBQUMsQ0FBQyxDQUFGLEVBQUssQ0FBQyxJQUFOLEVBQVksQ0FBQyxHQUFiLEVBQWtCLENBQWxCLEVBQXFCLEdBQXJCLEVBQTBCLElBQTFCLEVBQWdDLENBQWhDLENBRkU7QUFHVixtQkFBTyxDQUFDLFVBQUQsRUFBYSxNQUFiLEVBQXFCLGNBQXJCLEVBQXFDLE9BQXJDLEVBQThDLFdBQTlDLEVBQTJELFNBQTNELEVBQXNFLFNBQXRFLENBSEc7QUFJVixtQkFBTyxlQUFDLE9BQUQsRUFBVSxPQUFWO0FBQUEsdUJBQXNCLGlDQUFnQixpQkFBaEIsQ0FBa0MsT0FBbEMsRUFBMkMsT0FBM0MsQ0FBdEI7QUFBQTs7QUFKRyxTQXFCTTtBQUFBLGNBZHBCLElBY29CLEdBZGI7QUFDSCxtQkFBTyxTQURKLEU7QUFFSCxrQkFBTSxTQUZIO0FBR0gscUJBQVMsRUFITjtBQUlILHFCQUFTLEdBSk47QUFLSCxxQkFBUztBQUxOLFNBY2E7QUFBQSxjQVBwQixNQU9vQixHQVBYO0FBQ0wsa0JBQU0sRUFERDtBQUVMLG1CQUFPLEVBRkY7QUFHTCxpQkFBSyxFQUhBO0FBSUwsb0JBQVE7QUFKSCxTQU9XOztBQUVoQixZQUFJLE1BQUosRUFBWTtBQUNSLHlCQUFNLFVBQU4sUUFBdUIsTUFBdkI7QUFDSDtBQUplO0FBS25CLEs7Ozs7OztJQUdRLGlCLFdBQUEsaUI7OztBQUNULCtCQUFZLG1CQUFaLEVBQWlDLElBQWpDLEVBQXVDLE1BQXZDLEVBQStDO0FBQUE7O0FBQUEsb0dBQ3JDLG1CQURxQyxFQUNoQixJQURnQixFQUNWLElBQUksdUJBQUosQ0FBNEIsTUFBNUIsQ0FEVTtBQUU5Qzs7OztrQ0FFUyxNLEVBQVE7QUFDZCwwR0FBdUIsSUFBSSx1QkFBSixDQUE0QixNQUE1QixDQUF2QjtBQUVIOzs7bUNBRVU7QUFDUDtBQUNBLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLFNBQVMsS0FBSyxNQUFMLENBQVksTUFBekI7QUFDQSxnQkFBSSxPQUFPLEtBQUssTUFBaEI7O0FBRUEsaUJBQUssSUFBTCxDQUFVLENBQVYsR0FBYyxFQUFkO0FBQ0EsaUJBQUssSUFBTCxDQUFVLFdBQVYsR0FBd0I7QUFDcEIsd0JBQVEsU0FEWTtBQUVwQix1QkFBTyxTQUZhO0FBR3BCLHVCQUFPLEVBSGE7QUFJcEIsdUJBQU87QUFKYSxhQUF4Qjs7QUFRQSxpQkFBSyxjQUFMO0FBQ0EsZ0JBQUksUUFBUSxLQUFLLEtBQWpCO0FBQ0EsZ0JBQUksa0JBQWtCLEtBQUssb0JBQUwsRUFBdEI7QUFDQSxpQkFBSyxJQUFMLENBQVUsZUFBVixHQUE0QixlQUE1Qjs7QUFFQSxnQkFBSSxjQUFjLGdCQUFnQixxQkFBaEIsR0FBd0MsS0FBMUQ7QUFDQSxnQkFBSSxLQUFKLEVBQVc7O0FBRVAsb0JBQUksQ0FBQyxLQUFLLElBQUwsQ0FBVSxRQUFmLEVBQXlCO0FBQ3JCLHlCQUFLLElBQUwsQ0FBVSxRQUFWLEdBQXFCLEtBQUssR0FBTCxDQUFTLEtBQUssSUFBTCxDQUFVLE9BQW5CLEVBQTRCLEtBQUssR0FBTCxDQUFTLEtBQUssSUFBTCxDQUFVLE9BQW5CLEVBQTRCLENBQUMsUUFBUSxPQUFPLElBQWYsR0FBc0IsT0FBTyxLQUE5QixJQUF1QyxLQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLE1BQXZGLENBQTVCLENBQXJCO0FBQ0g7QUFFSixhQU5ELE1BTU87QUFDSCxxQkFBSyxJQUFMLENBQVUsUUFBVixHQUFxQixLQUFLLE1BQUwsQ0FBWSxJQUFaLENBQWlCLElBQXRDOztBQUVBLG9CQUFJLENBQUMsS0FBSyxJQUFMLENBQVUsUUFBZixFQUF5QjtBQUNyQix5QkFBSyxJQUFMLENBQVUsUUFBVixHQUFxQixLQUFLLEdBQUwsQ0FBUyxLQUFLLElBQUwsQ0FBVSxPQUFuQixFQUE0QixLQUFLLEdBQUwsQ0FBUyxLQUFLLElBQUwsQ0FBVSxPQUFuQixFQUE0QixDQUFDLGNBQWMsT0FBTyxJQUFyQixHQUE0QixPQUFPLEtBQXBDLElBQTZDLEtBQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsTUFBN0YsQ0FBNUIsQ0FBckI7QUFDSDs7QUFFRCx3QkFBUSxLQUFLLElBQUwsQ0FBVSxRQUFWLEdBQXFCLEtBQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsTUFBekMsR0FBa0QsT0FBTyxJQUF6RCxHQUFnRSxPQUFPLEtBQS9FO0FBRUg7O0FBRUQsZ0JBQUksU0FBUyxLQUFiO0FBQ0EsZ0JBQUksQ0FBQyxNQUFMLEVBQWE7QUFDVCx5QkFBUyxnQkFBZ0IscUJBQWhCLEdBQXdDLE1BQWpEO0FBQ0g7O0FBRUQsaUJBQUssSUFBTCxDQUFVLEtBQVYsR0FBa0IsUUFBUSxPQUFPLElBQWYsR0FBc0IsT0FBTyxLQUEvQztBQUNBLGlCQUFLLElBQUwsQ0FBVSxNQUFWLEdBQW1CLEtBQUssSUFBTCxDQUFVLEtBQTdCOztBQUVBLGlCQUFLLG9CQUFMO0FBQ0EsaUJBQUssc0JBQUw7QUFDQSxpQkFBSyxzQkFBTDs7QUFHQSxtQkFBTyxJQUFQO0FBQ0g7OzsrQ0FFc0I7O0FBRW5CLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLElBQUksS0FBSyxDQUFiO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLE1BQUwsQ0FBWSxTQUF2Qjs7Ozs7Ozs7QUFRQSxjQUFFLEtBQUYsR0FBVSxLQUFLLEtBQWY7QUFDQSxjQUFFLEtBQUYsR0FBVSxHQUFHLEtBQUgsQ0FBUyxLQUFLLEtBQWQsSUFBdUIsVUFBdkIsQ0FBa0MsQ0FBQyxLQUFLLEtBQU4sRUFBYSxDQUFiLENBQWxDLENBQVY7QUFDQSxjQUFFLEdBQUYsR0FBUTtBQUFBLHVCQUFLLEVBQUUsS0FBRixDQUFRLEVBQUUsS0FBRixDQUFRLENBQVIsQ0FBUixDQUFMO0FBQUEsYUFBUjtBQUVIOzs7aURBRXdCO0FBQ3JCLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLFdBQVcsS0FBSyxNQUFMLENBQVksV0FBM0I7O0FBRUEsaUJBQUssV0FBTCxDQUFpQixLQUFqQixDQUF1QixLQUF2QixHQUErQixHQUFHLEtBQUgsQ0FBUyxTQUFTLEtBQWxCLElBQTJCLE1BQTNCLENBQWtDLFNBQVMsTUFBM0MsRUFBbUQsS0FBbkQsQ0FBeUQsU0FBUyxLQUFsRSxDQUEvQjtBQUNBLGdCQUFJLFFBQVEsS0FBSyxXQUFMLENBQWlCLEtBQWpCLEdBQXlCLEVBQXJDOztBQUVBLGdCQUFJLFdBQVcsS0FBSyxNQUFMLENBQVksSUFBM0I7QUFDQSxrQkFBTSxJQUFOLEdBQWEsU0FBUyxLQUF0Qjs7QUFFQSxnQkFBSSxZQUFZLEtBQUssUUFBTCxHQUFnQixTQUFTLE9BQVQsR0FBbUIsQ0FBbkQ7QUFDQSxnQkFBSSxNQUFNLElBQU4sSUFBYyxRQUFsQixFQUE0QjtBQUN4QixvQkFBSSxZQUFZLFlBQVksQ0FBNUI7QUFDQSxzQkFBTSxXQUFOLEdBQW9CLEdBQUcsS0FBSCxDQUFTLE1BQVQsR0FBa0IsTUFBbEIsQ0FBeUIsQ0FBQyxDQUFELEVBQUksQ0FBSixDQUF6QixFQUFpQyxLQUFqQyxDQUF1QyxDQUFDLENBQUQsRUFBSSxTQUFKLENBQXZDLENBQXBCO0FBQ0Esc0JBQU0sTUFBTixHQUFlO0FBQUEsMkJBQUksTUFBTSxXQUFOLENBQWtCLEtBQUssR0FBTCxDQUFTLEVBQUUsS0FBWCxDQUFsQixDQUFKO0FBQUEsaUJBQWY7QUFDSCxhQUpELE1BSU8sSUFBSSxNQUFNLElBQU4sSUFBYyxTQUFsQixFQUE2QjtBQUNoQyxvQkFBSSxZQUFZLFlBQVksQ0FBNUI7QUFDQSxzQkFBTSxXQUFOLEdBQW9CLEdBQUcsS0FBSCxDQUFTLE1BQVQsR0FBa0IsTUFBbEIsQ0FBeUIsQ0FBQyxDQUFELEVBQUksQ0FBSixDQUF6QixFQUFpQyxLQUFqQyxDQUF1QyxDQUFDLFNBQUQsRUFBWSxDQUFaLENBQXZDLENBQXBCO0FBQ0Esc0JBQU0sT0FBTixHQUFnQjtBQUFBLDJCQUFJLE1BQU0sV0FBTixDQUFrQixLQUFLLEdBQUwsQ0FBUyxFQUFFLEtBQVgsQ0FBbEIsQ0FBSjtBQUFBLGlCQUFoQjtBQUNBLHNCQUFNLE9BQU4sR0FBZ0IsU0FBaEI7O0FBRUEsc0JBQU0sU0FBTixHQUFrQixhQUFLO0FBQ25CLHdCQUFJLEtBQUssQ0FBVCxFQUFZLE9BQU8sR0FBUDtBQUNaLHdCQUFJLElBQUksQ0FBUixFQUFXLE9BQU8sS0FBUDtBQUNYLDJCQUFPLElBQVA7QUFDSCxpQkFKRDtBQUtILGFBWE0sTUFXQSxJQUFJLE1BQU0sSUFBTixJQUFjLE1BQWxCLEVBQTBCO0FBQzdCLHNCQUFNLElBQU4sR0FBYSxTQUFiO0FBQ0g7QUFFSjs7O3lDQUdnQjs7QUFFYixnQkFBSSxnQkFBZ0IsS0FBSyxNQUFMLENBQVksU0FBaEM7O0FBRUEsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsaUJBQUssZ0JBQUwsR0FBd0IsRUFBeEI7QUFDQSxpQkFBSyxTQUFMLEdBQWlCLGNBQWMsSUFBL0I7QUFDQSxnQkFBSSxDQUFDLEtBQUssU0FBTixJQUFtQixDQUFDLEtBQUssU0FBTCxDQUFlLE1BQXZDLEVBQStDO0FBQzNDLHFCQUFLLFNBQUwsR0FBaUIsYUFBTSxjQUFOLENBQXFCLElBQXJCLEVBQTJCLEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBbUIsR0FBOUMsRUFBbUQsS0FBSyxNQUFMLENBQVksYUFBL0QsQ0FBakI7QUFDSDs7QUFFRCxpQkFBSyxNQUFMLEdBQWMsRUFBZDtBQUNBLGlCQUFLLGVBQUwsR0FBdUIsRUFBdkI7QUFDQSxpQkFBSyxTQUFMLENBQWUsT0FBZixDQUF1QixVQUFDLFdBQUQsRUFBYyxLQUFkLEVBQXdCO0FBQzNDLHFCQUFLLGdCQUFMLENBQXNCLFdBQXRCLElBQXFDLEdBQUcsTUFBSCxDQUFVLElBQVYsRUFBZ0IsVUFBQyxDQUFEO0FBQUEsMkJBQU8sY0FBYyxLQUFkLENBQW9CLENBQXBCLEVBQXVCLFdBQXZCLENBQVA7QUFBQSxpQkFBaEIsQ0FBckM7QUFDQSxvQkFBSSxRQUFRLFdBQVo7QUFDQSxvQkFBSSxjQUFjLE1BQWQsSUFBd0IsY0FBYyxNQUFkLENBQXFCLE1BQXJCLEdBQThCLEtBQTFELEVBQWlFOztBQUU3RCw0QkFBUSxjQUFjLE1BQWQsQ0FBcUIsS0FBckIsQ0FBUjtBQUNIO0FBQ0QscUJBQUssTUFBTCxDQUFZLElBQVosQ0FBaUIsS0FBakI7QUFDQSxxQkFBSyxlQUFMLENBQXFCLFdBQXJCLElBQW9DLEtBQXBDO0FBQ0gsYUFURDs7QUFXQSxvQkFBUSxHQUFSLENBQVksS0FBSyxlQUFqQjtBQUVIOzs7aURBR3dCO0FBQ3JCLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLFNBQVMsS0FBSyxJQUFMLENBQVUsV0FBVixDQUFzQixNQUF0QixHQUErQixFQUE1QztBQUNBLGdCQUFJLGNBQWMsS0FBSyxJQUFMLENBQVUsV0FBVixDQUFzQixNQUF0QixDQUE2QixLQUE3QixHQUFxQyxFQUF2RDtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjs7QUFFQSxnQkFBSSxtQkFBbUIsRUFBdkI7QUFDQSxpQkFBSyxTQUFMLENBQWUsT0FBZixDQUF1QixVQUFDLENBQUQsRUFBSSxDQUFKLEVBQVU7O0FBRTdCLGlDQUFpQixDQUFqQixJQUFzQixLQUFLLEdBQUwsQ0FBUztBQUFBLDJCQUFHLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxDQUFiLEVBQWdCLENBQWhCLENBQUg7QUFBQSxpQkFBVCxDQUF0QjtBQUNILGFBSEQ7O0FBS0EsaUJBQUssU0FBTCxDQUFlLE9BQWYsQ0FBdUIsVUFBQyxFQUFELEVBQUssQ0FBTCxFQUFXO0FBQzlCLG9CQUFJLE1BQU0sRUFBVjtBQUNBLHVCQUFPLElBQVAsQ0FBWSxHQUFaOztBQUVBLHFCQUFLLFNBQUwsQ0FBZSxPQUFmLENBQXVCLFVBQUMsRUFBRCxFQUFLLENBQUwsRUFBVztBQUM5Qix3QkFBSSxPQUFPLENBQVg7QUFDQSx3QkFBSSxNQUFNLEVBQVYsRUFBYztBQUNWLCtCQUFPLEtBQUssTUFBTCxDQUFZLFdBQVosQ0FBd0IsS0FBeEIsQ0FBOEIsaUJBQWlCLEVBQWpCLENBQTlCLEVBQW9ELGlCQUFpQixFQUFqQixDQUFwRCxDQUFQO0FBQ0g7QUFDRCx3QkFBSSxPQUFPO0FBQ1AsZ0NBQVEsRUFERDtBQUVQLGdDQUFRLEVBRkQ7QUFHUCw2QkFBSyxDQUhFO0FBSVAsNkJBQUssQ0FKRTtBQUtQLCtCQUFPO0FBTEEscUJBQVg7QUFPQSx3QkFBSSxJQUFKLENBQVMsSUFBVDs7QUFFQSxnQ0FBWSxJQUFaLENBQWlCLElBQWpCO0FBQ0gsaUJBZkQ7QUFpQkgsYUFyQkQ7QUFzQkg7OzsrQkFHTSxPLEVBQVM7QUFDWixnR0FBYSxPQUFiOztBQUVBLGlCQUFLLFdBQUw7QUFDQSxpQkFBSyxvQkFBTDs7QUFHQSxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxVQUFoQixFQUE0QjtBQUN4QixxQkFBSyxZQUFMO0FBQ0g7QUFDSjs7OytDQUVzQjtBQUNuQixpQkFBSyxJQUFMLENBQVUsVUFBVixHQUF1QixLQUFLLFdBQUwsQ0FBaUIsT0FBakIsQ0FBdkI7QUFDQSxpQkFBSyxXQUFMO0FBQ0EsaUJBQUssV0FBTDtBQUNIOzs7c0NBRWE7QUFDVixnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxhQUFhLEtBQUssVUFBdEI7QUFDQSxnQkFBSSxjQUFjLGFBQWEsSUFBL0I7O0FBRUEsZ0JBQUksU0FBUyxLQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLFVBQVUsV0FBOUIsRUFDUixJQURRLENBQ0gsS0FBSyxTQURGLEVBQ2EsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFRLENBQVI7QUFBQSxhQURiLENBQWI7O0FBR0EsbUJBQU8sS0FBUCxHQUFlLE1BQWYsQ0FBc0IsTUFBdEIsRUFBOEIsSUFBOUIsQ0FBbUMsT0FBbkMsRUFBNEMsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFVLGFBQWEsR0FBYixHQUFtQixXQUFuQixHQUFpQyxHQUFqQyxHQUF1QyxXQUF2QyxHQUFxRCxHQUFyRCxHQUEyRCxDQUFyRTtBQUFBLGFBQTVDOztBQUVBLG1CQUNLLElBREwsQ0FDVSxHQURWLEVBQ2UsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFVLElBQUksS0FBSyxRQUFULEdBQW9CLEtBQUssUUFBTCxHQUFnQixDQUE5QztBQUFBLGFBRGYsRUFFSyxJQUZMLENBRVUsR0FGVixFQUVlLEtBQUssTUFGcEIsRUFHSyxJQUhMLENBR1UsSUFIVixFQUdnQixDQUFDLENBSGpCLEVBSUssSUFKTCxDQUlVLElBSlYsRUFJZ0IsQ0FKaEIsRUFLSyxJQUxMLENBS1UsYUFMVixFQUt5QixLQUx6Qjs7O0FBQUEsYUFRSyxJQVJMLENBUVU7QUFBQSx1QkFBRyxLQUFLLGVBQUwsQ0FBcUIsQ0FBckIsQ0FBSDtBQUFBLGFBUlY7O0FBVUEsZ0JBQUksS0FBSyxNQUFMLENBQVksYUFBaEIsRUFBK0I7QUFDM0IsdUJBQU8sSUFBUCxDQUFZLFdBQVosRUFBeUIsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLDJCQUFVLGtCQUFrQixJQUFJLEtBQUssUUFBVCxHQUFvQixLQUFLLFFBQUwsR0FBZ0IsQ0FBdEQsSUFBNkQsSUFBN0QsR0FBb0UsS0FBSyxNQUF6RSxHQUFrRixHQUE1RjtBQUFBLGlCQUF6QjtBQUNIOztBQUVELGdCQUFJLFdBQVcsS0FBSyx1QkFBTCxFQUFmO0FBQ0EsbUJBQU8sSUFBUCxDQUFZLFVBQVUsS0FBVixFQUFpQjtBQUN6Qiw2QkFBTSwrQkFBTixDQUFzQyxHQUFHLE1BQUgsQ0FBVSxJQUFWLENBQXRDLEVBQXVELEtBQXZELEVBQThELFFBQTlELEVBQXdFLEtBQUssTUFBTCxDQUFZLFdBQVosR0FBMEIsS0FBSyxJQUFMLENBQVUsT0FBcEMsR0FBOEMsS0FBdEg7QUFDSCxhQUZEOztBQUlBLG1CQUFPLElBQVAsR0FBYyxNQUFkO0FBQ0g7OztzQ0FFYTtBQUNWLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLGFBQWEsS0FBSyxVQUF0QjtBQUNBLGdCQUFJLGNBQWMsS0FBSyxVQUFMLEdBQWtCLElBQXBDO0FBQ0EsZ0JBQUksU0FBUyxLQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLFVBQVUsV0FBOUIsRUFDUixJQURRLENBQ0gsS0FBSyxTQURGLENBQWI7O0FBR0EsbUJBQU8sS0FBUCxHQUFlLE1BQWYsQ0FBc0IsTUFBdEI7O0FBRUEsbUJBQ0ssSUFETCxDQUNVLEdBRFYsRUFDZSxDQURmLEVBRUssSUFGTCxDQUVVLEdBRlYsRUFFZSxVQUFDLENBQUQsRUFBSSxDQUFKO0FBQUEsdUJBQVUsSUFBSSxLQUFLLFFBQVQsR0FBb0IsS0FBSyxRQUFMLEdBQWdCLENBQTlDO0FBQUEsYUFGZixFQUdLLElBSEwsQ0FHVSxJQUhWLEVBR2dCLENBQUMsQ0FIakIsRUFJSyxJQUpMLENBSVUsYUFKVixFQUl5QixLQUp6QixFQUtLLElBTEwsQ0FLVSxPQUxWLEVBS21CLFVBQUMsQ0FBRCxFQUFJLENBQUo7QUFBQSx1QkFBVSxhQUFhLEdBQWIsR0FBbUIsV0FBbkIsR0FBaUMsR0FBakMsR0FBdUMsV0FBdkMsR0FBcUQsR0FBckQsR0FBMkQsQ0FBckU7QUFBQSxhQUxuQjs7QUFBQSxhQU9LLElBUEwsQ0FPVTtBQUFBLHVCQUFHLEtBQUssZUFBTCxDQUFxQixDQUFyQixDQUFIO0FBQUEsYUFQVjs7QUFTQSxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxhQUFoQixFQUErQjtBQUMzQix1QkFDSyxJQURMLENBQ1UsV0FEVixFQUN1QixVQUFDLENBQUQsRUFBSSxDQUFKO0FBQUEsMkJBQVUsaUJBQWlCLENBQWpCLEdBQXFCLElBQXJCLElBQTZCLElBQUksS0FBSyxRQUFULEdBQW9CLEtBQUssUUFBTCxHQUFnQixDQUFqRSxJQUFzRSxHQUFoRjtBQUFBLGlCQUR2QixFQUVLLElBRkwsQ0FFVSxhQUZWLEVBRXlCLEtBRnpCO0FBR0g7O0FBRUQsZ0JBQUksV0FBVyxLQUFLLHVCQUFMLEVBQWY7QUFDQSxtQkFBTyxJQUFQLENBQVksVUFBVSxLQUFWLEVBQWlCO0FBQ3pCLDZCQUFNLCtCQUFOLENBQXNDLEdBQUcsTUFBSCxDQUFVLElBQVYsQ0FBdEMsRUFBdUQsS0FBdkQsRUFBOEQsUUFBOUQsRUFBd0UsS0FBSyxNQUFMLENBQVksV0FBWixHQUEwQixLQUFLLElBQUwsQ0FBVSxPQUFwQyxHQUE4QyxLQUF0SDtBQUNILGFBRkQ7O0FBSUEsbUJBQU8sSUFBUCxHQUFjLE1BQWQ7QUFDSDs7O2tEQUV5QjtBQUN0QixnQkFBSSxXQUFXLEtBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsSUFBaEM7QUFDQSxnQkFBSSxDQUFDLEtBQUssTUFBTCxDQUFZLGFBQWpCLEVBQWdDO0FBQzVCLHVCQUFPLFFBQVA7QUFDSDs7QUFFRCx3QkFBWSxhQUFNLE1BQWxCO0FBQ0EsZ0JBQUksV0FBVyxFQUFmLEM7QUFDQSx3QkFBWSxXQUFXLENBQXZCOztBQUVBLG1CQUFPLFFBQVA7QUFDSDs7O2dEQUV1QixNLEVBQVE7QUFDNUIsZ0JBQUksQ0FBQyxLQUFLLE1BQUwsQ0FBWSxhQUFqQixFQUFnQztBQUM1Qix1QkFBTyxLQUFLLElBQUwsQ0FBVSxRQUFWLEdBQXFCLENBQTVCO0FBQ0g7QUFDRCxnQkFBSSxPQUFPLEtBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsTUFBNUI7QUFDQSxvQkFBUSxhQUFNLE1BQWQ7QUFDQSxnQkFBSSxXQUFXLEVBQWYsQztBQUNBLG9CQUFRLFdBQVcsQ0FBbkI7QUFDQSxtQkFBTyxJQUFQO0FBQ0g7OztzQ0FFYTs7QUFFVixnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxZQUFZLEtBQUssV0FBTCxDQUFpQixNQUFqQixDQUFoQjtBQUNBLGdCQUFJLFlBQVksS0FBSyxXQUFMLENBQWlCLEtBQWpCLENBQXVCLElBQXZDOztBQUVBLGdCQUFJLFFBQVEsS0FBSyxJQUFMLENBQVUsU0FBVixDQUFvQixPQUFPLFNBQTNCLEVBQ1AsSUFETyxDQUNGLEtBQUssV0FBTCxDQUFpQixNQUFqQixDQUF3QixLQUR0QixDQUFaOztBQUdBLGdCQUFJLGFBQWEsTUFBTSxLQUFOLEdBQWMsTUFBZCxDQUFxQixHQUFyQixFQUNaLE9BRFksQ0FDSixTQURJLEVBQ08sSUFEUCxDQUFqQjtBQUVBLGtCQUFNLElBQU4sQ0FBVyxXQUFYLEVBQXdCO0FBQUEsdUJBQUksZ0JBQWdCLEtBQUssUUFBTCxHQUFnQixFQUFFLEdBQWxCLEdBQXdCLEtBQUssUUFBTCxHQUFnQixDQUF4RCxJQUE2RCxHQUE3RCxJQUFvRSxLQUFLLFFBQUwsR0FBZ0IsRUFBRSxHQUFsQixHQUF3QixLQUFLLFFBQUwsR0FBZ0IsQ0FBNUcsSUFBaUgsR0FBckg7QUFBQSxhQUF4Qjs7QUFFQSxrQkFBTSxPQUFOLENBQWMsS0FBSyxNQUFMLENBQVksY0FBWixHQUE2QixZQUEzQyxFQUF5RCxDQUFDLENBQUMsS0FBSyxXQUFoRTs7QUFFQSxnQkFBSSxXQUFXLHVCQUF1QixTQUF2QixHQUFtQyxHQUFsRDs7QUFFQSxnQkFBSSxjQUFjLE1BQU0sU0FBTixDQUFnQixRQUFoQixDQUFsQjtBQUNBLHdCQUFZLE1BQVo7O0FBRUEsZ0JBQUksU0FBUyxNQUFNLGNBQU4sQ0FBcUIsWUFBWSxjQUFaLEdBQTZCLFNBQWxELENBQWI7O0FBRUEsZ0JBQUksS0FBSyxXQUFMLENBQWlCLEtBQWpCLENBQXVCLElBQXZCLElBQStCLFFBQW5DLEVBQTZDOztBQUV6Qyx1QkFDSyxJQURMLENBQ1UsR0FEVixFQUNlLEtBQUssV0FBTCxDQUFpQixLQUFqQixDQUF1QixNQUR0QyxFQUVLLElBRkwsQ0FFVSxJQUZWLEVBRWdCLENBRmhCLEVBR0ssSUFITCxDQUdVLElBSFYsRUFHZ0IsQ0FIaEI7QUFJSDs7QUFFRCxnQkFBSSxLQUFLLFdBQUwsQ0FBaUIsS0FBakIsQ0FBdUIsSUFBdkIsSUFBK0IsU0FBbkMsRUFBOEM7O0FBRTFDLHVCQUNLLElBREwsQ0FDVSxJQURWLEVBQ2dCLEtBQUssV0FBTCxDQUFpQixLQUFqQixDQUF1QixPQUR2QyxFQUVLLElBRkwsQ0FFVSxJQUZWLEVBRWdCLEtBQUssV0FBTCxDQUFpQixLQUFqQixDQUF1QixPQUZ2QyxFQUdLLElBSEwsQ0FHVSxJQUhWLEVBR2dCLENBSGhCLEVBSUssSUFKTCxDQUlVLElBSlYsRUFJZ0IsQ0FKaEIsRUFNSyxJQU5MLENBTVUsV0FOVixFQU11QjtBQUFBLDJCQUFJLFlBQVksS0FBSyxXQUFMLENBQWlCLEtBQWpCLENBQXVCLFNBQXZCLENBQWlDLEVBQUUsS0FBbkMsQ0FBWixHQUF3RCxHQUE1RDtBQUFBLGlCQU52QjtBQU9IOztBQUdELGdCQUFJLEtBQUssV0FBTCxDQUFpQixLQUFqQixDQUF1QixJQUF2QixJQUErQixNQUFuQyxFQUEyQztBQUN2Qyx1QkFDSyxJQURMLENBQ1UsT0FEVixFQUNtQixLQUFLLFdBQUwsQ0FBaUIsS0FBakIsQ0FBdUIsSUFEMUMsRUFFSyxJQUZMLENBRVUsUUFGVixFQUVvQixLQUFLLFdBQUwsQ0FBaUIsS0FBakIsQ0FBdUIsSUFGM0MsRUFHSyxJQUhMLENBR1UsR0FIVixFQUdlLENBQUMsS0FBSyxRQUFOLEdBQWlCLENBSGhDLEVBSUssSUFKTCxDQUlVLEdBSlYsRUFJZSxDQUFDLEtBQUssUUFBTixHQUFpQixDQUpoQztBQUtIO0FBQ0QsbUJBQU8sS0FBUCxDQUFhLE1BQWIsRUFBcUI7QUFBQSx1QkFBSSxLQUFLLFdBQUwsQ0FBaUIsS0FBakIsQ0FBdUIsS0FBdkIsQ0FBNkIsRUFBRSxLQUEvQixDQUFKO0FBQUEsYUFBckI7O0FBRUEsZ0JBQUkscUJBQXFCLEVBQXpCO0FBQ0EsZ0JBQUksb0JBQW9CLEVBQXhCOztBQUVBLGdCQUFJLEtBQUssT0FBVCxFQUFrQjs7QUFFZCxtQ0FBbUIsSUFBbkIsQ0FBd0IsYUFBSTtBQUN4Qix5QkFBSyxPQUFMLENBQWEsVUFBYixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsRUFGdEI7QUFHQSx3QkFBSSxPQUFPLEVBQUUsS0FBYjtBQUNBLHlCQUFLLE9BQUwsQ0FBYSxJQUFiLENBQWtCLElBQWxCLEVBQ0ssS0FETCxDQUNXLE1BRFgsRUFDb0IsR0FBRyxLQUFILENBQVMsS0FBVCxHQUFpQixDQUFsQixHQUF1QixJQUQxQyxFQUVLLEtBRkwsQ0FFVyxLQUZYLEVBRW1CLEdBQUcsS0FBSCxDQUFTLEtBQVQsR0FBaUIsRUFBbEIsR0FBd0IsSUFGMUM7QUFHSCxpQkFSRDs7QUFVQSxrQ0FBa0IsSUFBbEIsQ0FBdUIsYUFBSTtBQUN2Qix5QkFBSyxPQUFMLENBQWEsVUFBYixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsQ0FGdEI7QUFHSCxpQkFKRDtBQU9IOztBQUVELGdCQUFJLEtBQUssTUFBTCxDQUFZLGVBQWhCLEVBQWlDO0FBQzdCLG9CQUFJLGlCQUFpQixLQUFLLE1BQUwsQ0FBWSxjQUFaLEdBQTZCLFdBQWxEO0FBQ0Esb0JBQUksY0FBYyxTQUFkLFdBQWM7QUFBQSwyQkFBRyxLQUFLLFVBQUwsR0FBa0IsS0FBbEIsR0FBMEIsRUFBRSxHQUEvQjtBQUFBLGlCQUFsQjtBQUNBLG9CQUFJLGNBQWMsU0FBZCxXQUFjO0FBQUEsMkJBQUcsS0FBSyxVQUFMLEdBQWtCLEtBQWxCLEdBQTBCLEVBQUUsR0FBL0I7QUFBQSxpQkFBbEI7O0FBR0EsbUNBQW1CLElBQW5CLENBQXdCLGFBQUk7O0FBRXhCLHlCQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLFVBQVUsWUFBWSxDQUFaLENBQTlCLEVBQThDLE9BQTlDLENBQXNELGNBQXRELEVBQXNFLElBQXRFO0FBQ0EseUJBQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsVUFBVSxZQUFZLENBQVosQ0FBOUIsRUFBOEMsT0FBOUMsQ0FBc0QsY0FBdEQsRUFBc0UsSUFBdEU7QUFDSCxpQkFKRDtBQUtBLGtDQUFrQixJQUFsQixDQUF1QixhQUFJO0FBQ3ZCLHlCQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLFVBQVUsWUFBWSxDQUFaLENBQTlCLEVBQThDLE9BQTlDLENBQXNELGNBQXRELEVBQXNFLEtBQXRFO0FBQ0EseUJBQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsVUFBVSxZQUFZLENBQVosQ0FBOUIsRUFBOEMsT0FBOUMsQ0FBc0QsY0FBdEQsRUFBc0UsS0FBdEU7QUFDSCxpQkFIRDtBQUlIOztBQUdELGtCQUFNLEVBQU4sQ0FBUyxXQUFULEVBQXNCLGFBQUs7QUFDdkIsbUNBQW1CLE9BQW5CLENBQTJCO0FBQUEsMkJBQVUsU0FBUyxDQUFULENBQVY7QUFBQSxpQkFBM0I7QUFDSCxhQUZELEVBR0ssRUFITCxDQUdRLFVBSFIsRUFHb0IsYUFBSztBQUNqQixrQ0FBa0IsT0FBbEIsQ0FBMEI7QUFBQSwyQkFBVSxTQUFTLENBQVQsQ0FBVjtBQUFBLGlCQUExQjtBQUNILGFBTEw7O0FBT0Esa0JBQU0sRUFBTixDQUFTLE9BQVQsRUFBa0IsYUFBSTtBQUNsQixxQkFBSyxPQUFMLENBQWEsZUFBYixFQUE4QixDQUE5QjtBQUNILGFBRkQ7O0FBS0Esa0JBQU0sSUFBTixHQUFhLE1BQWI7QUFDSDs7O3VDQUdjOztBQUVYLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLFVBQVUsS0FBSyxJQUFMLENBQVUsS0FBVixHQUFrQixFQUFoQztBQUNBLGdCQUFJLFVBQVUsQ0FBZDtBQUNBLGdCQUFJLFdBQVcsRUFBZjtBQUNBLGdCQUFJLFlBQVksS0FBSyxJQUFMLENBQVUsTUFBVixHQUFtQixDQUFuQztBQUNBLGdCQUFJLFFBQVEsS0FBSyxXQUFMLENBQWlCLEtBQWpCLENBQXVCLEtBQW5DOztBQUVBLGlCQUFLLE1BQUwsR0FBYyxtQkFBVyxLQUFLLEdBQWhCLEVBQXFCLEtBQUssSUFBMUIsRUFBZ0MsS0FBaEMsRUFBdUMsT0FBdkMsRUFBZ0QsT0FBaEQsRUFBeUQsaUJBQXpELENBQTJFLFFBQTNFLEVBQXFGLFNBQXJGLENBQWQ7QUFHSDs7OzBDQUVpQixpQixFQUFtQixNLEVBQVE7QUFBQTs7QUFDekMsZ0JBQUksT0FBTyxJQUFYOztBQUVBLHFCQUFTLFVBQVUsRUFBbkI7O0FBR0EsZ0JBQUksb0JBQW9CO0FBQ3BCLHdCQUFRLEtBQUssSUFBTCxDQUFVLE1BQVYsR0FBbUIsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixHQUF0QyxHQUE0QyxLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLE1BRG5EO0FBRXBCLHVCQUFPLEtBQUssSUFBTCxDQUFVLE1BQVYsR0FBbUIsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixHQUF0QyxHQUE0QyxLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLE1BRmxEO0FBR3BCLHdCQUFRO0FBQ0oseUJBQUssS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixHQURwQjtBQUVKLDJCQUFPLEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBbUI7QUFGdEIsaUJBSFk7QUFPcEIsd0JBQVEsSUFQWTtBQVFwQiw0QkFBWTtBQVJRLGFBQXhCOztBQVdBLGlCQUFLLFdBQUwsR0FBbUIsSUFBbkI7O0FBRUEsZ0NBQW9CLGFBQU0sVUFBTixDQUFpQixpQkFBakIsRUFBb0MsTUFBcEMsQ0FBcEI7QUFDQSxpQkFBSyxNQUFMOztBQUVBLGlCQUFLLEVBQUwsQ0FBUSxlQUFSLEVBQXlCLGFBQUk7O0FBR3pCLGtDQUFrQixDQUFsQixHQUFzQjtBQUNsQix5QkFBSyxFQUFFLE1BRFc7QUFFbEIsMkJBQU8sS0FBSyxJQUFMLENBQVUsZUFBVixDQUEwQixFQUFFLE1BQTVCO0FBRlcsaUJBQXRCO0FBSUEsa0NBQWtCLENBQWxCLEdBQXNCO0FBQ2xCLHlCQUFLLEVBQUUsTUFEVztBQUVsQiwyQkFBTyxLQUFLLElBQUwsQ0FBVSxlQUFWLENBQTBCLEVBQUUsTUFBNUI7QUFGVyxpQkFBdEI7QUFJQSxvQkFBSSxLQUFLLFdBQUwsSUFBb0IsS0FBSyxXQUFMLEtBQXFCLElBQTdDLEVBQW1EO0FBQy9DLHlCQUFLLFdBQUwsQ0FBaUIsU0FBakIsQ0FBMkIsaUJBQTNCLEVBQThDLElBQTlDO0FBQ0gsaUJBRkQsTUFFTztBQUNILHlCQUFLLFdBQUwsR0FBbUIsNkJBQWdCLGlCQUFoQixFQUFtQyxLQUFLLElBQXhDLEVBQThDLGlCQUE5QyxDQUFuQjtBQUNBLDJCQUFLLE1BQUwsQ0FBWSxhQUFaLEVBQTJCLEtBQUssV0FBaEM7QUFDSDtBQUdKLGFBbkJEO0FBc0JIOzs7Ozs7Ozs7Ozs7Ozs7O0FDN2ZMOzs7O0lBR2EsWSxXQUFBLFk7Ozs7Ozs7aUNBRU07O0FBRVgsZUFBRyxTQUFILENBQWEsS0FBYixDQUFtQixTQUFuQixDQUE2QixjQUE3QixHQUNJLEdBQUcsU0FBSCxDQUFhLFNBQWIsQ0FBdUIsY0FBdkIsR0FBd0MsVUFBUyxRQUFULEVBQW1CLE1BQW5CLEVBQTJCO0FBQy9ELHVCQUFPLGFBQU0sY0FBTixDQUFxQixJQUFyQixFQUEyQixRQUEzQixFQUFxQyxNQUFyQyxDQUFQO0FBQ0gsYUFITDs7QUFNQSxlQUFHLFNBQUgsQ0FBYSxLQUFiLENBQW1CLFNBQW5CLENBQTZCLGNBQTdCLEdBQ0ksR0FBRyxTQUFILENBQWEsU0FBYixDQUF1QixjQUF2QixHQUF3QyxVQUFTLFFBQVQsRUFBbUI7QUFDdkQsdUJBQU8sYUFBTSxjQUFOLENBQXFCLElBQXJCLEVBQTJCLFFBQTNCLENBQVA7QUFDSCxhQUhMOztBQUtBLGVBQUcsU0FBSCxDQUFhLEtBQWIsQ0FBbUIsU0FBbkIsQ0FBNkIsY0FBN0IsR0FDSSxHQUFHLFNBQUgsQ0FBYSxTQUFiLENBQXVCLGNBQXZCLEdBQXdDLFVBQVMsUUFBVCxFQUFtQjtBQUN2RCx1QkFBTyxhQUFNLGNBQU4sQ0FBcUIsSUFBckIsRUFBMkIsUUFBM0IsQ0FBUDtBQUNILGFBSEw7O0FBS0EsZUFBRyxTQUFILENBQWEsS0FBYixDQUFtQixTQUFuQixDQUE2QixjQUE3QixHQUNJLEdBQUcsU0FBSCxDQUFhLFNBQWIsQ0FBdUIsY0FBdkIsR0FBd0MsVUFBUyxRQUFULEVBQW1CLE1BQW5CLEVBQTJCO0FBQy9ELHVCQUFPLGFBQU0sY0FBTixDQUFxQixJQUFyQixFQUEyQixRQUEzQixFQUFxQyxNQUFyQyxDQUFQO0FBQ0gsYUFITDtBQU9IOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM5Qkw7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0lBR2EsdUIsV0FBQSx1Qjs7O0FBdURULHFDQUFZLE1BQVosRUFBb0I7QUFBQTs7QUFBQTs7QUFBQSxjQXREcEIsQ0FzRG9CLEdBdERoQjtBQUNBLHlCQUFhLEtBRGIsRTtBQUVBLHNCQUFVLFNBRlYsRTtBQUdBLDBCQUFjLENBSGQ7QUFJQSxvQkFBUSxTQUpSLEU7QUFLQSwyQkFBZSxTQUxmLEU7QUFNQSwrQkFBbUIsQztBQUNmO0FBQ0ksc0JBQU0sTUFEVjtBQUVJLHlCQUFTLENBQUMsSUFBRDtBQUZiLGFBRGUsRUFLZjtBQUNJLHNCQUFNLE9BRFY7QUFFSSx5QkFBUyxDQUFDLE9BQUQ7QUFGYixhQUxlLEVBU2Y7QUFDSSxzQkFBTSxLQURWO0FBRUkseUJBQVMsQ0FBQyxVQUFEO0FBRmIsYUFUZSxFQWFmO0FBQ0ksc0JBQU0sTUFEVjtBQUVJLHlCQUFTLENBQUMsSUFBRCxFQUFPLGFBQVA7QUFGYixhQWJlLEVBaUJmO0FBQ0ksc0JBQU0sUUFEVjtBQUVJLHlCQUFTLENBQUMsT0FBRCxFQUFVLGdCQUFWO0FBRmIsYUFqQmUsRUFxQmY7QUFDSSxzQkFBTSxRQURWO0FBRUkseUJBQVMsQ0FBQyxVQUFELEVBQWEsbUJBQWI7QUFGYixhQXJCZSxDQU5uQjs7QUFpQ0EsNEJBQWdCLFNBQVMsY0FBVCxDQUF3QixDQUF4QixFQUEyQixDQUEzQixFQUE4QjtBQUMxQyx1QkFBTyxhQUFNLFFBQU4sQ0FBZSxDQUFmLElBQXFCLEVBQUUsYUFBRixDQUFnQixDQUFoQixDQUFyQixHQUEyQyxJQUFJLENBQXREO0FBQ0gsYUFuQ0Q7QUFvQ0EsdUJBQVc7QUFwQ1gsU0FzRGdCO0FBQUEsY0FoQnBCLENBZ0JvQixHQWhCaEI7QUFDQSx5QkFBYSxJO0FBRGIsU0FnQmdCO0FBQUEsY0FacEIsTUFZb0IsR0FaWDtBQUNMLHVCQUFXLG1CQUFVLENBQVYsRUFBYTtBQUNwQixvQkFBSSxTQUFTLEVBQWI7QUFDQSxvQkFBSSxJQUFJLE9BQUosSUFBZSxDQUFuQixFQUFzQjtBQUNsQiw2QkFBUyxJQUFUO0FBQ0Esd0JBQUksT0FBTyxJQUFJLE9BQVgsRUFBb0IsT0FBcEIsQ0FBNEIsQ0FBNUIsQ0FBSjtBQUNIO0FBQ0Qsb0JBQUksS0FBSyxLQUFLLFlBQUwsRUFBVDtBQUNBLHVCQUFPLEdBQUcsTUFBSCxDQUFVLENBQVYsSUFBZSxNQUF0QjtBQUNIO0FBVEksU0FZVzs7O0FBR2hCLFlBQUksTUFBSixFQUFZO0FBQ1IseUJBQU0sVUFBTixRQUF1QixNQUF2QjtBQUNIOztBQUxlO0FBT25COzs7OztJQUdRLGlCLFdBQUEsaUI7OztBQUNULCtCQUFZLG1CQUFaLEVBQWlDLElBQWpDLEVBQXVDLE1BQXZDLEVBQStDO0FBQUE7O0FBQUEsb0dBQ3JDLG1CQURxQyxFQUNoQixJQURnQixFQUNWLElBQUksdUJBQUosQ0FBNEIsTUFBNUIsQ0FEVTtBQUU5Qzs7OztrQ0FFUyxNLEVBQVE7QUFDZCwwR0FBdUIsSUFBSSx1QkFBSixDQUE0QixNQUE1QixDQUF2QjtBQUNIOzs7c0RBRzZCO0FBQUE7O0FBRTFCLGlCQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksVUFBWixHQUF5QixLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsTUFBdkM7QUFDQSxnQkFBRyxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsYUFBZCxJQUErQixDQUFDLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxVQUEvQyxFQUEwRDtBQUN0RCxxQkFBSyxlQUFMO0FBQ0g7O0FBR0Q7QUFDQSxnQkFBSSxDQUFDLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxXQUFuQixFQUFnQztBQUM1QjtBQUNIOztBQUVELGdCQUFJLE9BQU8sSUFBWDs7QUFFQSxpQkFBSyx5QkFBTDs7QUFFQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLFlBQVosR0FBMkIsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLFlBQWQsSUFBOEIsQ0FBekQ7O0FBRUEsaUJBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxVQUFaLEdBQXlCLEtBQUssYUFBTCxFQUF6Qjs7QUFJQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLFlBQVosQ0FBeUIsSUFBekIsQ0FBOEIsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLGNBQTVDOztBQUVBLGdCQUFJLE9BQU8sSUFBWDs7QUFFQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLFlBQVosQ0FBeUIsT0FBekIsQ0FBaUMsVUFBQyxDQUFELEVBQUksQ0FBSixFQUFTO0FBQ3RDLG9CQUFJLFVBQVUsT0FBSyxTQUFMLENBQWUsQ0FBZixDQUFkO0FBQ0Esb0JBQUksU0FBUyxJQUFiLEVBQW1CO0FBQ2YsMkJBQU8sT0FBUDtBQUNBO0FBQ0g7O0FBRUQsb0JBQUksT0FBTyxLQUFLLGlCQUFMLENBQXVCLElBQXZCLENBQVg7QUFDQSxvQkFBSSxVQUFVLEVBQWQ7QUFDQSxvQkFBSSxZQUFZLENBQWhCO0FBQ0EsdUJBQU8sS0FBSyxpQkFBTCxDQUF1QixJQUF2QixFQUE2QixPQUE3QixLQUF1QyxDQUE5QyxFQUFpRDtBQUM3QztBQUNBLHdCQUFJLFlBQVksR0FBaEIsRUFBcUI7QUFDakI7QUFDSDtBQUNELHdCQUFJLElBQUksRUFBUjtBQUNBLHdCQUFJLGFBQWEsS0FBSyxVQUFMLENBQWdCLElBQWhCLENBQWpCO0FBQ0Esc0JBQUUsT0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLEdBQWhCLElBQXVCLFVBQXZCOztBQUVBLHlCQUFLLFlBQUwsQ0FBa0IsQ0FBbEIsRUFBcUIsVUFBckIsRUFBaUMsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLE1BQTdDLEVBQXFELEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxNQUFuRTtBQUNBLDRCQUFRLElBQVIsQ0FBYSxJQUFiO0FBQ0EsMkJBQU8sS0FBSyxpQkFBTCxDQUF1QixJQUF2QixDQUFQO0FBQ0g7QUFDRCx1QkFBTyxPQUFQO0FBQ0gsYUF4QkQ7QUEwQkg7OztrQ0FFUyxDLEVBQUc7QUFDVCxnQkFBSSxTQUFTLEtBQUssYUFBTCxFQUFiO0FBQ0EsbUJBQU8sT0FBTyxLQUFQLENBQWEsQ0FBYixDQUFQO0FBQ0g7OzttQ0FFVSxJLEVBQUs7QUFDWixnQkFBSSxTQUFTLEtBQUssYUFBTCxFQUFiO0FBQ0EsbUJBQU8sT0FBTyxJQUFQLENBQVA7QUFDSDs7O3FDQUVZLEssRUFBTzs7QUFDaEIsZ0JBQUksS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLFNBQWxCLEVBQTZCLE9BQU8sS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLFNBQWQsQ0FBd0IsSUFBeEIsQ0FBNkIsS0FBSyxNQUFsQyxFQUEwQyxLQUExQyxDQUFQOztBQUU3QixnQkFBRyxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsYUFBakIsRUFBK0I7QUFDM0Isb0JBQUksT0FBTyxLQUFLLFNBQUwsQ0FBZSxLQUFmLENBQVg7QUFDQSx1QkFBTyxHQUFHLElBQUgsQ0FBUSxNQUFSLENBQWUsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLGFBQTdCLEVBQTRDLElBQTVDLENBQVA7QUFDSDs7QUFFRCxnQkFBRyxDQUFDLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxVQUFoQixFQUE0QixPQUFPLEtBQVA7O0FBRTVCLGdCQUFHLGFBQU0sTUFBTixDQUFhLEtBQWIsQ0FBSCxFQUF1QjtBQUNuQix1QkFBTyxLQUFLLFVBQUwsQ0FBZ0IsS0FBaEIsQ0FBUDtBQUNIOztBQUVELG1CQUFPLEtBQVA7QUFDSDs7OzBDQUVpQixDLEVBQUcsQyxFQUFFO0FBQ25CLG1CQUFPLElBQUUsQ0FBVDtBQUNIOzs7d0NBRWUsQyxFQUFHLEMsRUFBRztBQUNsQixnQkFBSSxTQUFTLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxVQUF6QjtBQUNBLG1CQUFPLE9BQU8sQ0FBUCxNQUFjLE9BQU8sQ0FBUCxDQUFyQjtBQUNIOzs7MENBRWlCLEMsRUFBRztBQUNqQixnQkFBSSxXQUFXLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxRQUEzQjtBQUNBLG1CQUFPLEdBQUcsSUFBSCxDQUFRLFFBQVIsRUFBa0IsTUFBbEIsQ0FBeUIsQ0FBekIsRUFBNEIsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLFlBQXhDLENBQVA7QUFDSDs7O21DQUVVO0FBQ1A7O0FBRUEsZ0JBQUksS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLFdBQWxCLEVBQStCO0FBQzNCLHFCQUFLLElBQUwsQ0FBVSxNQUFWLENBQWlCLE9BQWpCLENBQXlCLFVBQUMsR0FBRCxFQUFNLFFBQU4sRUFBbUI7QUFDeEMsd0JBQUksZUFBZSxTQUFuQjtBQUNBLHdCQUFJLE9BQUosQ0FBWSxVQUFDLElBQUQsRUFBTyxRQUFQLEVBQW9CO0FBQzVCLDRCQUFJLEtBQUssS0FBTCxLQUFlLFNBQWYsSUFBNEIsaUJBQWlCLFNBQWpELEVBQTREO0FBQ3hELGlDQUFLLEtBQUwsR0FBYSxZQUFiO0FBQ0EsaUNBQUssT0FBTCxHQUFlLElBQWY7QUFDSDtBQUNELHVDQUFlLEtBQUssS0FBcEI7QUFDSCxxQkFORDtBQU9ILGlCQVREO0FBVUg7QUFHSjs7OytCQUVNLE8sRUFBUztBQUNaLGdHQUFhLE9BQWI7QUFFSDs7O29EQUcyQjs7QUFFeEIsaUJBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxRQUFaLEdBQXVCLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxRQUFyQzs7QUFFQSxnQkFBRyxDQUFDLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxVQUFoQixFQUEyQjtBQUN2QixxQkFBSyxlQUFMO0FBQ0g7O0FBRUQsZ0JBQUcsQ0FBQyxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksUUFBYixJQUF5QixLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksVUFBeEMsRUFBbUQ7QUFDL0MscUJBQUssYUFBTDtBQUNIO0FBQ0o7OzswQ0FFaUI7QUFDZCxnQkFBSSxPQUFPLElBQVg7QUFDQSxpQkFBSSxJQUFJLElBQUUsQ0FBVixFQUFhLElBQUksS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLGlCQUFkLENBQWdDLE1BQWpELEVBQXlELEdBQXpELEVBQTZEO0FBQ3pELG9CQUFJLGlCQUFpQixLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsaUJBQWQsQ0FBZ0MsQ0FBaEMsQ0FBckI7QUFDQSxvQkFBSSxTQUFTLElBQWI7QUFDQSxvQkFBSSxjQUFjLGVBQWUsT0FBZixDQUF1QixJQUF2QixDQUE0QixhQUFHO0FBQzdDLDZCQUFTLENBQVQ7QUFDQSx3QkFBSSxTQUFTLEdBQUcsSUFBSCxDQUFRLE1BQVIsQ0FBZSxDQUFmLENBQWI7QUFDQSwyQkFBTyxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksWUFBWixDQUF5QixLQUF6QixDQUErQixhQUFHO0FBQ3JDLCtCQUFPLE9BQU8sS0FBUCxDQUFhLENBQWIsTUFBb0IsSUFBM0I7QUFDSCxxQkFGTSxDQUFQO0FBR0gsaUJBTmlCLENBQWxCO0FBT0Esb0JBQUcsV0FBSCxFQUFlO0FBQ1gseUJBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxVQUFaLEdBQXlCLE1BQXpCO0FBQ0EsNEJBQVEsR0FBUixDQUFZLG9CQUFaLEVBQWtDLE1BQWxDO0FBQ0Esd0JBQUcsQ0FBQyxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksUUFBaEIsRUFBeUI7QUFDckIsNkJBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxRQUFaLEdBQXVCLGVBQWUsSUFBdEM7QUFDQSxnQ0FBUSxHQUFSLENBQVksa0JBQVosRUFBZ0MsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLFFBQTVDO0FBQ0g7QUFDRDtBQUNIO0FBQ0o7QUFDSjs7O3dDQUVlO0FBQ1osZ0JBQUksT0FBTyxJQUFYO0FBQ0EsaUJBQUksSUFBSSxJQUFFLENBQVYsRUFBYSxJQUFJLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxpQkFBZCxDQUFnQyxNQUFqRCxFQUF5RCxHQUF6RCxFQUE4RDtBQUMxRCxvQkFBSSxpQkFBaUIsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLGlCQUFkLENBQWdDLENBQWhDLENBQXJCOztBQUVBLG9CQUFHLGVBQWUsT0FBZixDQUF1QixPQUF2QixDQUErQixLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksVUFBM0MsS0FBMEQsQ0FBN0QsRUFBK0Q7QUFDM0QseUJBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxRQUFaLEdBQXVCLGVBQWUsSUFBdEM7QUFDQSw0QkFBUSxHQUFSLENBQVksa0JBQVosRUFBZ0MsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLFFBQTVDO0FBQ0E7QUFDSDtBQUVKO0FBRUo7Ozt3Q0FHZTtBQUNaLGdCQUFHLENBQUMsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLFVBQWhCLEVBQTJCO0FBQ3ZCLHFCQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksVUFBWixHQUF5QixHQUFHLElBQUgsQ0FBUSxNQUFSLENBQWUsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLFVBQTNCLENBQXpCO0FBQ0g7QUFDRCxtQkFBTyxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksVUFBbkI7QUFDSDs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDcFFMOztBQUNBOztBQUNBOzs7Ozs7OztJQUdhLGEsV0FBQSxhOzs7OztBQWlGVCwyQkFBWSxNQUFaLEVBQW9CO0FBQUE7O0FBQUE7O0FBQUEsY0EvRXBCLFFBK0VvQixHQS9FVCxhQStFUztBQUFBLGNBOUVwQixXQThFb0IsR0E5RU4sSUE4RU07QUFBQSxjQTdFcEIsT0E2RW9CLEdBN0VWO0FBQ04sd0JBQVk7QUFETixTQTZFVTtBQUFBLGNBMUVwQixVQTBFb0IsR0ExRVAsSUEwRU87QUFBQSxjQXpFcEIsTUF5RW9CLEdBekVYO0FBQ0wsbUJBQU8sRUFERjtBQUVMLDBCQUFjLEtBRlQ7QUFHTCwyQkFBZSxTQUhWO0FBSUwsdUJBQVc7QUFBQSx1QkFBSyxNQUFLLE1BQUwsQ0FBWSxhQUFaLEtBQThCLFNBQTlCLEdBQTBDLENBQTFDLEdBQThDLE9BQU8sQ0FBUCxFQUFVLE9BQVYsQ0FBa0IsTUFBSyxNQUFMLENBQVksYUFBOUIsQ0FBbkQ7QUFBQTtBQUpOLFNBeUVXO0FBQUEsY0FuRXBCLGVBbUVvQixHQW5FRixJQW1FRTtBQUFBLGNBbEVwQixDQWtFb0IsR0FsRWhCLEU7QUFDQSxtQkFBTyxFQURQLEU7QUFFQSxpQkFBSyxDQUZMO0FBR0EsbUJBQU8sZUFBQyxDQUFEO0FBQUEsdUJBQU8sRUFBRSxNQUFLLENBQUwsQ0FBTyxHQUFULENBQVA7QUFBQSxhQUhQLEU7QUFJQSwwQkFBYyxJQUpkO0FBS0Esd0JBQVksS0FMWjtBQU1BLDRCQUFnQix3QkFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFTLGFBQU0sUUFBTixDQUFlLENBQWYsSUFBb0IsSUFBSSxDQUF4QixHQUE0QixFQUFFLGFBQUYsQ0FBZ0IsQ0FBaEIsQ0FBckM7QUFBQSxhQU5oQjtBQU9BLG9CQUFRO0FBQ0osc0JBQU0sRUFERjtBQUVKLHdCQUFRLEVBRko7QUFHSix1QkFBTyxlQUFDLENBQUQsRUFBSSxHQUFKO0FBQUEsMkJBQVksRUFBRSxHQUFGLENBQVo7QUFBQSxpQkFISDtBQUlKLHlCQUFTO0FBQ0wseUJBQUssRUFEQTtBQUVMLDRCQUFRO0FBRkg7QUFKTCxhQVBSO0FBZ0JBLHVCQUFXLFM7O0FBaEJYLFNBa0VnQjtBQUFBLGNBL0NwQixDQStDb0IsR0EvQ2hCLEU7QUFDQSxtQkFBTyxFQURQLEU7QUFFQSwwQkFBYyxJQUZkO0FBR0EsaUJBQUssQ0FITDtBQUlBLG1CQUFPLGVBQUMsQ0FBRDtBQUFBLHVCQUFPLEVBQUUsTUFBSyxDQUFMLENBQU8sR0FBVCxDQUFQO0FBQUEsYUFKUCxFO0FBS0Esd0JBQVksS0FMWjtBQU1BLDRCQUFnQix3QkFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFTLGFBQU0sUUFBTixDQUFlLENBQWYsSUFBb0IsSUFBSSxDQUF4QixHQUE0QixFQUFFLGFBQUYsQ0FBZ0IsQ0FBaEIsQ0FBckM7QUFBQSxhQU5oQjtBQU9BLG9CQUFRO0FBQ0osc0JBQU0sRUFERjtBQUVKLHdCQUFRLEVBRko7QUFHSix1QkFBTyxlQUFDLENBQUQsRUFBSSxHQUFKO0FBQUEsMkJBQVksRUFBRSxHQUFGLENBQVo7QUFBQSxpQkFISDtBQUlKLHlCQUFTO0FBQ0wsMEJBQU0sRUFERDtBQUVMLDJCQUFPO0FBRkY7QUFKTCxhQVBSO0FBZ0JBLHVCQUFXLFM7QUFoQlgsU0ErQ2dCO0FBQUEsY0E3QnBCLENBNkJvQixHQTdCaEI7QUFDQSxpQkFBSyxDQURMO0FBRUEsbUJBQU8sZUFBQyxDQUFEO0FBQUEsdUJBQU8sRUFBRSxNQUFLLENBQUwsQ0FBTyxHQUFULENBQVA7QUFBQSxhQUZQO0FBR0EsK0JBQW1CLDJCQUFDLENBQUQ7QUFBQSx1QkFBTyxNQUFNLElBQU4sSUFBYyxNQUFNLFNBQTNCO0FBQUEsYUFIbkI7O0FBS0EsMkJBQWUsU0FMZjtBQU1BLHVCQUFXO0FBQUEsdUJBQUssTUFBSyxDQUFMLENBQU8sYUFBUCxLQUF5QixTQUF6QixHQUFxQyxDQUFyQyxHQUF5QyxPQUFPLENBQVAsRUFBVSxPQUFWLENBQWtCLE1BQUssQ0FBTCxDQUFPLGFBQXpCLENBQTlDO0FBQUEsYTs7QUFOWCxTQTZCZ0I7QUFBQSxjQXBCcEIsS0FvQm9CLEdBcEJaO0FBQ0oseUJBQWEsT0FEVDtBQUVKLG1CQUFPLFFBRkg7QUFHSiwwQkFBYyxLQUhWO0FBSUosbUJBQU8sQ0FBQyxVQUFELEVBQWEsY0FBYixFQUE2QixRQUE3QixFQUF1QyxTQUF2QyxFQUFrRCxTQUFsRDtBQUpILFNBb0JZO0FBQUEsY0FkcEIsSUFjb0IsR0FkYjtBQUNILG1CQUFPLFNBREo7QUFFSCxvQkFBUSxTQUZMO0FBR0gscUJBQVMsRUFITjtBQUlILHFCQUFTLEdBSk47QUFLSCxxQkFBUztBQUxOLFNBY2E7QUFBQSxjQVBwQixNQU9vQixHQVBYO0FBQ0wsa0JBQU0sRUFERDtBQUVMLG1CQUFPLEVBRkY7QUFHTCxpQkFBSyxFQUhBO0FBSUwsb0JBQVE7QUFKSCxTQU9XOztBQUVoQixZQUFJLE1BQUosRUFBWTtBQUNSLHlCQUFNLFVBQU4sUUFBdUIsTUFBdkI7QUFDSDtBQUplO0FBS25COzs7Ozs7OztJQUlRLE8sV0FBQSxPOzs7QUFLVCxxQkFBWSxtQkFBWixFQUFpQyxJQUFqQyxFQUF1QyxNQUF2QyxFQUErQztBQUFBOztBQUFBLDBGQUNyQyxtQkFEcUMsRUFDaEIsSUFEZ0IsRUFDVixJQUFJLGFBQUosQ0FBa0IsTUFBbEIsQ0FEVTtBQUU5Qzs7OztrQ0FFUyxNLEVBQVE7QUFDZCxnR0FBdUIsSUFBSSxhQUFKLENBQWtCLE1BQWxCLENBQXZCO0FBRUg7OzttQ0FFVTtBQUNQO0FBQ0EsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksU0FBUyxLQUFLLE1BQUwsQ0FBWSxNQUF6QjtBQUNBLGdCQUFJLE9BQU8sS0FBSyxNQUFoQjs7QUFFQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixHQUFjLEVBQWQ7QUFDQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixHQUFjLEVBQWQ7QUFDQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixHQUFjO0FBQ1YsMEJBQVUsU0FEQTtBQUVWLHVCQUFPLFNBRkc7QUFHVix1QkFBTyxFQUhHO0FBSVYsdUJBQU87QUFKRyxhQUFkOztBQVFBLGlCQUFLLFdBQUw7QUFDQSxpQkFBSyxVQUFMOztBQUVBLGdCQUFJLGlCQUFpQixDQUFyQjtBQUNBLGlCQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksT0FBWixHQUFzQjtBQUNsQixxQkFBSyxDQURhO0FBRWxCLHdCQUFRO0FBRlUsYUFBdEI7QUFJQSxnQkFBSSxLQUFLLElBQUwsQ0FBVSxRQUFkLEVBQXdCO0FBQ3BCLG9CQUFJLFFBQVEsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLE1BQWQsQ0FBcUIsSUFBckIsQ0FBMEIsTUFBdEM7QUFDQSxvQkFBSSxpQkFBaUIsUUFBUyxjQUE5Qjs7QUFFQSxxQkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLE9BQVosQ0FBb0IsTUFBcEIsR0FBNkIsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLE1BQWQsQ0FBcUIsT0FBckIsQ0FBNkIsTUFBMUQ7QUFDQSxxQkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLE9BQVosQ0FBb0IsR0FBcEIsR0FBMEIsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLE1BQWQsQ0FBcUIsT0FBckIsQ0FBNkIsR0FBN0IsR0FBbUMsY0FBN0Q7QUFDQSxxQkFBSyxJQUFMLENBQVUsTUFBVixDQUFpQixHQUFqQixHQUF1QixLQUFLLE1BQUwsQ0FBWSxLQUFaLEdBQW9CLEtBQUssQ0FBTCxDQUFPLE1BQVAsQ0FBYyxPQUFkLENBQXNCLEdBQWpFO0FBQ0EscUJBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsTUFBakIsR0FBMEIsS0FBSyxNQUFMLENBQVksTUFBWixHQUFxQixLQUFLLENBQUwsQ0FBTyxNQUFQLENBQWMsT0FBZCxDQUFzQixNQUFyRTtBQUNIOztBQUdELGlCQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksT0FBWixHQUFzQjtBQUNsQixzQkFBTSxDQURZO0FBRWxCLHVCQUFPO0FBRlcsYUFBdEI7O0FBTUEsZ0JBQUksS0FBSyxJQUFMLENBQVUsUUFBZCxFQUF3QjtBQUNwQixvQkFBSSxTQUFRLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxNQUFkLENBQXFCLElBQXJCLENBQTBCLE1BQXRDO0FBQ0Esb0JBQUksa0JBQWlCLFNBQVMsY0FBOUI7QUFDQSxxQkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLE9BQVosQ0FBb0IsS0FBcEIsR0FBNEIsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLE1BQWQsQ0FBcUIsT0FBckIsQ0FBNkIsSUFBN0IsR0FBb0MsZUFBaEU7QUFDQSxxQkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLE9BQVosQ0FBb0IsSUFBcEIsR0FBMkIsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLE1BQWQsQ0FBcUIsT0FBckIsQ0FBNkIsSUFBeEQ7QUFDQSxxQkFBSyxJQUFMLENBQVUsTUFBVixDQUFpQixJQUFqQixHQUF3QixLQUFLLE1BQUwsQ0FBWSxJQUFaLEdBQW1CLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxPQUFaLENBQW9CLElBQS9EO0FBQ0EscUJBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsS0FBakIsR0FBeUIsS0FBSyxNQUFMLENBQVksS0FBWixHQUFvQixLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksT0FBWixDQUFvQixLQUFqRTtBQUNIO0FBQ0QsaUJBQUssSUFBTCxDQUFVLFVBQVYsR0FBdUIsS0FBSyxVQUE1QjtBQUNBLGdCQUFJLEtBQUssSUFBTCxDQUFVLFVBQWQsRUFBMEI7QUFDdEIscUJBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsS0FBakIsSUFBMEIsS0FBSyxNQUFMLENBQVksS0FBdEM7QUFDSDtBQUNELGlCQUFLLGVBQUw7QUFDQSxpQkFBSyxXQUFMOztBQUVBLG1CQUFPLElBQVA7QUFDSDs7O3NDQUVhO0FBQUE7O0FBQ1YsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksU0FBUyxLQUFLLE1BQWxCO0FBQ0EsZ0JBQUksSUFBSSxLQUFLLElBQUwsQ0FBVSxDQUFsQjtBQUNBLGdCQUFJLElBQUksS0FBSyxJQUFMLENBQVUsQ0FBbEI7QUFDQSxnQkFBSSxJQUFJLEtBQUssSUFBTCxDQUFVLENBQWxCOztBQUdBLGNBQUUsS0FBRixHQUFVO0FBQUEsdUJBQUssT0FBTyxDQUFQLENBQVMsS0FBVCxDQUFlLElBQWYsQ0FBb0IsTUFBcEIsRUFBNEIsQ0FBNUIsQ0FBTDtBQUFBLGFBQVY7QUFDQSxjQUFFLEtBQUYsR0FBVTtBQUFBLHVCQUFLLE9BQU8sQ0FBUCxDQUFTLEtBQVQsQ0FBZSxJQUFmLENBQW9CLE1BQXBCLEVBQTRCLENBQTVCLENBQUw7QUFBQSxhQUFWO0FBQ0EsY0FBRSxLQUFGLEdBQVU7QUFBQSx1QkFBSyxPQUFPLENBQVAsQ0FBUyxLQUFULENBQWUsSUFBZixDQUFvQixNQUFwQixFQUE0QixDQUE1QixDQUFMO0FBQUEsYUFBVjs7QUFFQSxjQUFFLFlBQUYsR0FBaUIsRUFBakI7QUFDQSxjQUFFLFlBQUYsR0FBaUIsRUFBakI7O0FBR0EsaUJBQUssSUFBTCxDQUFVLFFBQVYsR0FBcUIsQ0FBQyxDQUFDLE9BQU8sQ0FBUCxDQUFTLE1BQVQsQ0FBZ0IsSUFBaEIsQ0FBcUIsTUFBNUM7QUFDQSxpQkFBSyxJQUFMLENBQVUsUUFBVixHQUFxQixDQUFDLENBQUMsT0FBTyxDQUFQLENBQVMsTUFBVCxDQUFnQixJQUFoQixDQUFxQixNQUE1Qzs7QUFFQSxjQUFFLE1BQUYsR0FBVztBQUNQLHFCQUFLLFNBREU7QUFFUCx1QkFBTyxFQUZBO0FBR1Asd0JBQVEsRUFIRDtBQUlQLDBCQUFVLElBSkg7QUFLUCx1QkFBTyxDQUxBO0FBTVAsdUJBQU8sQ0FOQTtBQU9QLDJCQUFXO0FBUEosYUFBWDtBQVNBLGNBQUUsTUFBRixHQUFXO0FBQ1AscUJBQUssU0FERTtBQUVQLHVCQUFPLEVBRkE7QUFHUCx3QkFBUSxFQUhEO0FBSVAsMEJBQVUsSUFKSDtBQUtQLHVCQUFPLENBTEE7QUFNUCx1QkFBTyxDQU5BO0FBT1AsMkJBQVc7QUFQSixhQUFYOztBQVVBLGdCQUFJLFdBQVcsRUFBZjtBQUNBLGdCQUFJLE9BQU8sU0FBWDtBQUNBLGdCQUFJLE9BQU8sU0FBWDtBQUNBLGlCQUFLLElBQUwsQ0FBVSxPQUFWLENBQWtCLGFBQUk7O0FBRWxCLG9CQUFJLE9BQU8sRUFBRSxLQUFGLENBQVEsQ0FBUixDQUFYO0FBQ0Esb0JBQUksT0FBTyxFQUFFLEtBQUYsQ0FBUSxDQUFSLENBQVg7QUFDQSxvQkFBSSxVQUFVLEVBQUUsS0FBRixDQUFRLENBQVIsQ0FBZDtBQUNBLG9CQUFJLE9BQU8sT0FBTyxDQUFQLENBQVMsaUJBQVQsQ0FBMkIsT0FBM0IsSUFBc0MsU0FBdEMsR0FBa0QsV0FBVyxPQUFYLENBQTdEOztBQUdBLG9CQUFJLEVBQUUsWUFBRixDQUFlLE9BQWYsQ0FBdUIsSUFBdkIsTUFBaUMsQ0FBQyxDQUF0QyxFQUF5QztBQUNyQyxzQkFBRSxZQUFGLENBQWUsSUFBZixDQUFvQixJQUFwQjtBQUNIOztBQUVELG9CQUFJLEVBQUUsWUFBRixDQUFlLE9BQWYsQ0FBdUIsSUFBdkIsTUFBaUMsQ0FBQyxDQUF0QyxFQUF5QztBQUNyQyxzQkFBRSxZQUFGLENBQWUsSUFBZixDQUFvQixJQUFwQjtBQUNIOztBQUVELG9CQUFJLFNBQVMsRUFBRSxNQUFmO0FBQ0Esb0JBQUksS0FBSyxJQUFMLENBQVUsUUFBZCxFQUF3QjtBQUNwQiw2QkFBUyxPQUFLLFlBQUwsQ0FBa0IsQ0FBbEIsRUFBcUIsSUFBckIsRUFBMkIsRUFBRSxNQUE3QixFQUFxQyxPQUFPLENBQVAsQ0FBUyxNQUE5QyxDQUFUO0FBQ0g7QUFDRCxvQkFBSSxTQUFTLEVBQUUsTUFBZjtBQUNBLG9CQUFJLEtBQUssSUFBTCxDQUFVLFFBQWQsRUFBd0I7O0FBRXBCLDZCQUFTLE9BQUssWUFBTCxDQUFrQixDQUFsQixFQUFxQixJQUFyQixFQUEyQixFQUFFLE1BQTdCLEVBQXFDLE9BQU8sQ0FBUCxDQUFTLE1BQTlDLENBQVQ7QUFDSDs7QUFFRCxvQkFBSSxDQUFDLFNBQVMsT0FBTyxLQUFoQixDQUFMLEVBQTZCO0FBQ3pCLDZCQUFTLE9BQU8sS0FBaEIsSUFBeUIsRUFBekI7QUFDSDs7QUFFRCxvQkFBSSxDQUFDLFNBQVMsT0FBTyxLQUFoQixFQUF1QixPQUFPLEtBQTlCLENBQUwsRUFBMkM7QUFDdkMsNkJBQVMsT0FBTyxLQUFoQixFQUF1QixPQUFPLEtBQTlCLElBQXVDLEVBQXZDO0FBQ0g7QUFDRCxvQkFBSSxDQUFDLFNBQVMsT0FBTyxLQUFoQixFQUF1QixPQUFPLEtBQTlCLEVBQXFDLElBQXJDLENBQUwsRUFBaUQ7QUFDN0MsNkJBQVMsT0FBTyxLQUFoQixFQUF1QixPQUFPLEtBQTlCLEVBQXFDLElBQXJDLElBQTZDLEVBQTdDO0FBQ0g7QUFDRCx5QkFBUyxPQUFPLEtBQWhCLEVBQXVCLE9BQU8sS0FBOUIsRUFBcUMsSUFBckMsRUFBMkMsSUFBM0MsSUFBbUQsSUFBbkQ7O0FBR0Esb0JBQUksU0FBUyxTQUFULElBQXNCLE9BQU8sSUFBakMsRUFBdUM7QUFDbkMsMkJBQU8sSUFBUDtBQUNIO0FBQ0Qsb0JBQUksU0FBUyxTQUFULElBQXNCLE9BQU8sSUFBakMsRUFBdUM7QUFDbkMsMkJBQU8sSUFBUDtBQUNIO0FBQ0osYUE3Q0Q7QUE4Q0EsaUJBQUssSUFBTCxDQUFVLFFBQVYsR0FBcUIsUUFBckI7O0FBR0EsZ0JBQUksQ0FBQyxLQUFLLElBQUwsQ0FBVSxRQUFmLEVBQXlCO0FBQ3JCLGtCQUFFLE1BQUYsQ0FBUyxNQUFULEdBQWtCLEVBQUUsWUFBcEI7QUFDSDs7QUFFRCxnQkFBSSxDQUFDLEtBQUssSUFBTCxDQUFVLFFBQWYsRUFBeUI7QUFDckIsa0JBQUUsTUFBRixDQUFTLE1BQVQsR0FBa0IsRUFBRSxZQUFwQjtBQUNIOztBQUVELGlCQUFLLDJCQUFMOztBQUVBLGNBQUUsSUFBRixHQUFTLEVBQVQ7QUFDQSxjQUFFLGdCQUFGLEdBQXFCLENBQXJCO0FBQ0EsY0FBRSxhQUFGLEdBQWtCLEVBQWxCO0FBQ0EsaUJBQUssVUFBTCxDQUFnQixDQUFoQixFQUFtQixFQUFFLE1BQXJCLEVBQTZCLE9BQU8sQ0FBcEM7O0FBRUEsY0FBRSxJQUFGLEdBQVMsRUFBVDtBQUNBLGNBQUUsZ0JBQUYsR0FBcUIsQ0FBckI7QUFDQSxjQUFFLGFBQUYsR0FBa0IsRUFBbEI7QUFDQSxpQkFBSyxVQUFMLENBQWdCLENBQWhCLEVBQW1CLEVBQUUsTUFBckIsRUFBNkIsT0FBTyxDQUFwQzs7QUFFQSxjQUFFLEdBQUYsR0FBUSxJQUFSO0FBQ0EsY0FBRSxHQUFGLEdBQVEsSUFBUjtBQUVIOzs7c0RBRTZCLENBQzdCOzs7cUNBRVk7QUFDVCxnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxJQUFJLEtBQUssSUFBTCxDQUFVLENBQWxCO0FBQ0EsZ0JBQUksSUFBSSxLQUFLLElBQUwsQ0FBVSxDQUFsQjtBQUNBLGdCQUFJLElBQUksS0FBSyxJQUFMLENBQVUsQ0FBbEI7QUFDQSxnQkFBSSxXQUFXLEtBQUssSUFBTCxDQUFVLFFBQXpCOztBQUVBLGdCQUFJLGNBQWMsS0FBSyxJQUFMLENBQVUsS0FBVixHQUFrQixFQUFwQztBQUNBLGdCQUFJLFNBQVMsS0FBSyxJQUFMLENBQVUsTUFBVixHQUFtQixFQUFoQzs7QUFFQSxjQUFFLGFBQUYsQ0FBZ0IsT0FBaEIsQ0FBd0IsVUFBQyxFQUFELEVBQUssQ0FBTCxFQUFVO0FBQzlCLG9CQUFJLE1BQU0sRUFBVjtBQUNBLHVCQUFPLElBQVAsQ0FBWSxHQUFaOztBQUVBLGtCQUFFLGFBQUYsQ0FBZ0IsT0FBaEIsQ0FBd0IsVUFBQyxFQUFELEVBQUssQ0FBTCxFQUFXO0FBQy9CLHdCQUFJLE9BQU8sU0FBWDtBQUNBLHdCQUFJO0FBQ0EsK0JBQU8sU0FBUyxHQUFHLEtBQUgsQ0FBUyxLQUFsQixFQUF5QixHQUFHLEtBQUgsQ0FBUyxLQUFsQyxFQUF5QyxHQUFHLEdBQTVDLEVBQWlELEdBQUcsR0FBcEQsQ0FBUDtBQUNILHFCQUZELENBRUUsT0FBTyxDQUFQLEVBQVUsQ0FDWDs7QUFFRCx3QkFBSSxPQUFPO0FBQ1AsZ0NBQVEsRUFERDtBQUVQLGdDQUFRLEVBRkQ7QUFHUCw2QkFBSyxDQUhFO0FBSVAsNkJBQUssQ0FKRTtBQUtQLCtCQUFPO0FBTEEscUJBQVg7QUFPQSx3QkFBSSxJQUFKLENBQVMsSUFBVDs7QUFFQSxnQ0FBWSxJQUFaLENBQWlCLElBQWpCO0FBQ0gsaUJBakJEO0FBa0JILGFBdEJEO0FBd0JIOzs7cUNBRVksQyxFQUFHLE8sRUFBUyxTLEVBQVcsZ0IsRUFBa0I7O0FBRWxELGdCQUFJLFNBQVMsS0FBSyxNQUFsQjtBQUNBLGdCQUFJLGVBQWUsU0FBbkI7QUFDQSw2QkFBaUIsSUFBakIsQ0FBc0IsT0FBdEIsQ0FBOEIsVUFBQyxRQUFELEVBQVcsYUFBWCxFQUE2QjtBQUN2RCw2QkFBYSxHQUFiLEdBQW1CLFFBQW5COztBQUVBLG9CQUFJLENBQUMsYUFBYSxRQUFsQixFQUE0QjtBQUN4QixpQ0FBYSxRQUFiLEdBQXdCLEVBQXhCO0FBQ0g7O0FBRUQsb0JBQUksZ0JBQWdCLGlCQUFpQixLQUFqQixDQUF1QixJQUF2QixDQUE0QixNQUE1QixFQUFvQyxDQUFwQyxFQUF1QyxRQUF2QyxDQUFwQjs7QUFFQSxvQkFBSSxDQUFDLGFBQWEsUUFBYixDQUFzQixjQUF0QixDQUFxQyxhQUFyQyxDQUFMLEVBQTBEO0FBQ3RELDhCQUFVLFNBQVY7QUFDQSxpQ0FBYSxRQUFiLENBQXNCLGFBQXRCLElBQXVDO0FBQ25DLGdDQUFRLEVBRDJCO0FBRW5DLGtDQUFVLElBRnlCO0FBR25DLHVDQUFlLGFBSG9CO0FBSW5DLCtCQUFPLGFBQWEsS0FBYixHQUFxQixDQUpPO0FBS25DLCtCQUFPLFVBQVUsU0FMa0I7QUFNbkMsNkJBQUs7QUFOOEIscUJBQXZDO0FBUUg7O0FBRUQsK0JBQWUsYUFBYSxRQUFiLENBQXNCLGFBQXRCLENBQWY7QUFDSCxhQXRCRDs7QUF3QkEsZ0JBQUksYUFBYSxNQUFiLENBQW9CLE9BQXBCLENBQTRCLE9BQTVCLE1BQXlDLENBQUMsQ0FBOUMsRUFBaUQ7QUFDN0MsNkJBQWEsTUFBYixDQUFvQixJQUFwQixDQUF5QixPQUF6QjtBQUNIOztBQUVELG1CQUFPLFlBQVA7QUFDSDs7O21DQUVVLEksRUFBTSxLLEVBQU8sVSxFQUFZLEksRUFBTTtBQUN0QyxnQkFBSSxXQUFXLE1BQVgsQ0FBa0IsTUFBbEIsSUFBNEIsV0FBVyxNQUFYLENBQWtCLE1BQWxCLENBQXlCLE1BQXpCLEdBQWtDLE1BQU0sS0FBeEUsRUFBK0U7QUFDM0Usc0JBQU0sS0FBTixHQUFjLFdBQVcsTUFBWCxDQUFrQixNQUFsQixDQUF5QixNQUFNLEtBQS9CLENBQWQ7QUFDSCxhQUZELE1BRU87QUFDSCxzQkFBTSxLQUFOLEdBQWMsTUFBTSxHQUFwQjtBQUNIOztBQUVELGdCQUFJLENBQUMsSUFBTCxFQUFXO0FBQ1AsdUJBQU8sQ0FBQyxDQUFELENBQVA7QUFDSDtBQUNELGdCQUFJLEtBQUssTUFBTCxJQUFlLE1BQU0sS0FBekIsRUFBZ0M7QUFDNUIscUJBQUssSUFBTCxDQUFVLENBQVY7QUFDSDs7QUFFRCxrQkFBTSxjQUFOLEdBQXVCLE1BQU0sY0FBTixJQUF3QixDQUEvQztBQUNBLGtCQUFNLG9CQUFOLEdBQTZCLE1BQU0sb0JBQU4sSUFBOEIsQ0FBM0Q7O0FBRUEsa0JBQU0sSUFBTixHQUFhLEtBQUssS0FBTCxFQUFiO0FBQ0Esa0JBQU0sVUFBTixHQUFtQixLQUFLLEtBQUwsRUFBbkI7O0FBR0Esa0JBQU0sUUFBTixHQUFpQixRQUFRLGVBQVIsQ0FBd0IsTUFBTSxJQUE5QixDQUFqQjtBQUNBLGtCQUFNLGNBQU4sR0FBdUIsTUFBTSxRQUE3QjtBQUNBLGdCQUFJLE1BQU0sTUFBVixFQUFrQjtBQUNkLG9CQUFJLFdBQVcsVUFBZixFQUEyQjtBQUN2QiwwQkFBTSxNQUFOLENBQWEsSUFBYixDQUFrQixXQUFXLGNBQTdCO0FBQ0g7QUFDRCxzQkFBTSxNQUFOLENBQWEsT0FBYixDQUFxQjtBQUFBLDJCQUFHLEtBQUssYUFBTCxDQUFtQixJQUFuQixDQUF3QixFQUFDLEtBQUssQ0FBTixFQUFTLE9BQU8sS0FBaEIsRUFBeEIsQ0FBSDtBQUFBLGlCQUFyQjtBQUNBLHNCQUFNLG9CQUFOLEdBQTZCLEtBQUssZ0JBQWxDO0FBQ0EscUJBQUssZ0JBQUwsSUFBeUIsTUFBTSxNQUFOLENBQWEsTUFBdEM7QUFDQSxzQkFBTSxjQUFOLElBQXdCLE1BQU0sTUFBTixDQUFhLE1BQXJDO0FBQ0g7O0FBRUQsa0JBQU0sWUFBTixHQUFxQixFQUFyQjtBQUNBLGdCQUFJLE1BQU0sUUFBVixFQUFvQjtBQUNoQixvQkFBSSxnQkFBZ0IsQ0FBcEI7O0FBRUEscUJBQUssSUFBSSxTQUFULElBQXNCLE1BQU0sUUFBNUIsRUFBc0M7QUFDbEMsd0JBQUksTUFBTSxRQUFOLENBQWUsY0FBZixDQUE4QixTQUE5QixDQUFKLEVBQThDO0FBQzFDLDRCQUFJLFFBQVEsTUFBTSxRQUFOLENBQWUsU0FBZixDQUFaO0FBQ0EsOEJBQU0sWUFBTixDQUFtQixJQUFuQixDQUF3QixLQUF4QjtBQUNBOztBQUVBLDZCQUFLLFVBQUwsQ0FBZ0IsSUFBaEIsRUFBc0IsS0FBdEIsRUFBNkIsVUFBN0IsRUFBeUMsSUFBekM7QUFDQSw4QkFBTSxjQUFOLElBQXdCLE1BQU0sY0FBOUI7QUFDQSw2QkFBSyxNQUFNLEtBQVgsS0FBcUIsQ0FBckI7QUFDSDtBQUNKOztBQUVELG9CQUFJLFFBQVEsZ0JBQWdCLENBQTVCLEVBQStCO0FBQzNCLHlCQUFLLE1BQU0sS0FBWCxLQUFxQixDQUFyQjtBQUNIOztBQUVELHNCQUFNLFVBQU4sR0FBbUIsRUFBbkI7QUFDQSxxQkFBSyxPQUFMLENBQWEsVUFBQyxDQUFELEVBQUksQ0FBSixFQUFTO0FBQ2xCLDBCQUFNLFVBQU4sQ0FBaUIsSUFBakIsQ0FBc0IsS0FBSyxNQUFNLFVBQU4sQ0FBaUIsQ0FBakIsS0FBdUIsQ0FBNUIsQ0FBdEI7QUFDSCxpQkFGRDtBQUdBLHNCQUFNLGNBQU4sR0FBdUIsUUFBUSxlQUFSLENBQXdCLE1BQU0sVUFBOUIsQ0FBdkI7O0FBRUEsb0JBQUksS0FBSyxJQUFMLENBQVUsTUFBVixHQUFtQixLQUFLLE1BQTVCLEVBQW9DO0FBQ2hDLHlCQUFLLElBQUwsR0FBWSxJQUFaO0FBQ0g7QUFDSjtBQUVKOzs7Z0RBRXVCLE0sRUFBUTtBQUM1QixnQkFBSSxXQUFXLEtBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsSUFBaEM7QUFDQSxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsS0FBbEIsRUFBeUI7QUFDckIsNEJBQVksRUFBWjtBQUNIO0FBQ0QsZ0JBQUksVUFBVSxPQUFPLENBQXJCLEVBQXdCO0FBQ3BCLDRCQUFZLE9BQU8sQ0FBbkI7QUFDSDs7QUFFRCxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsWUFBbEIsRUFBZ0M7QUFDNUIsNEJBQVksYUFBTSxNQUFsQjtBQUNBLG9CQUFJLFdBQVcsRUFBZixDO0FBQ0EsNEJBQVcsV0FBUyxDQUFwQjtBQUNIOztBQUVELG1CQUFPLFFBQVA7QUFDSDs7O2dEQUV1QixNLEVBQVE7QUFDNUIsZ0JBQUksQ0FBQyxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsWUFBbkIsRUFBaUM7QUFDN0IsdUJBQU8sS0FBSyxJQUFMLENBQVUsU0FBVixHQUFzQixDQUE3QjtBQUNIO0FBQ0QsZ0JBQUksT0FBTyxLQUFLLElBQUwsQ0FBVSxNQUFWLENBQWlCLE1BQTVCO0FBQ0EsZ0JBQUksS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLEtBQWxCLEVBQXlCO0FBQ3JCLHdCQUFRLEVBQVI7QUFDSDtBQUNELGdCQUFJLFVBQVUsT0FBTyxDQUFyQixFQUF3QjtBQUNwQix3QkFBUSxPQUFPLENBQWY7QUFDSDs7QUFFRCxvQkFBUSxhQUFNLE1BQWQ7O0FBRUEsZ0JBQUksV0FBVyxFQUFmLEM7QUFDQSxvQkFBTyxXQUFTLENBQWhCOztBQUVBLG1CQUFPLElBQVA7QUFDSDs7OzBDQVlpQjs7QUFFZCxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxPQUFPLEtBQUssTUFBaEI7QUFDQSxnQkFBSSxTQUFTLEtBQUssTUFBbEI7QUFDQSxnQkFBSSxpQkFBaUIsYUFBTSxjQUFOLENBQXFCLEtBQUssTUFBTCxDQUFZLEtBQWpDLEVBQXdDLEtBQUssZ0JBQUwsRUFBeEMsRUFBaUUsS0FBSyxJQUFMLENBQVUsTUFBM0UsQ0FBckI7QUFDQSxnQkFBSSxrQkFBa0IsYUFBTSxlQUFOLENBQXNCLEtBQUssTUFBTCxDQUFZLE1BQWxDLEVBQTBDLEtBQUssZ0JBQUwsRUFBMUMsRUFBbUUsS0FBSyxJQUFMLENBQVUsTUFBN0UsQ0FBdEI7QUFDQSxnQkFBSSxRQUFRLGNBQVo7QUFDQSxnQkFBSSxTQUFTLGVBQWI7O0FBRUEsZ0JBQUksWUFBWSxRQUFRLGVBQVIsQ0FBd0IsS0FBSyxDQUFMLENBQU8sSUFBL0IsQ0FBaEI7O0FBR0EsZ0JBQUksb0JBQW9CLEtBQUssR0FBTCxDQUFTLEtBQUssSUFBTCxDQUFVLE9BQW5CLEVBQTRCLEtBQUssR0FBTCxDQUFTLEtBQUssSUFBTCxDQUFVLE9BQW5CLEVBQTRCLENBQUMsaUJBQWlCLFNBQWxCLElBQStCLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxnQkFBdkUsQ0FBNUIsQ0FBeEI7QUFDQSxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxLQUFoQixFQUF1Qjs7QUFFbkIsb0JBQUksQ0FBQyxLQUFLLE1BQUwsQ0FBWSxJQUFaLENBQWlCLEtBQXRCLEVBQTZCO0FBQ3pCLHlCQUFLLElBQUwsQ0FBVSxTQUFWLEdBQXNCLGlCQUF0QjtBQUNIO0FBRUosYUFORCxNQU1PO0FBQ0gscUJBQUssSUFBTCxDQUFVLFNBQVYsR0FBc0IsS0FBSyxNQUFMLENBQVksSUFBWixDQUFpQixLQUF2Qzs7QUFFQSxvQkFBSSxDQUFDLEtBQUssSUFBTCxDQUFVLFNBQWYsRUFBMEI7QUFDdEIseUJBQUssSUFBTCxDQUFVLFNBQVYsR0FBc0IsaUJBQXRCO0FBQ0g7QUFFSjtBQUNELG9CQUFRLEtBQUssSUFBTCxDQUFVLFNBQVYsR0FBc0IsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLGdCQUFsQyxHQUFxRCxPQUFPLElBQTVELEdBQW1FLE9BQU8sS0FBMUUsR0FBa0YsU0FBMUY7O0FBRUEsZ0JBQUksWUFBWSxRQUFRLGVBQVIsQ0FBd0IsS0FBSyxDQUFMLENBQU8sSUFBL0IsQ0FBaEI7QUFDQSxnQkFBSSxxQkFBcUIsS0FBSyxHQUFMLENBQVMsS0FBSyxJQUFMLENBQVUsT0FBbkIsRUFBNEIsS0FBSyxHQUFMLENBQVMsS0FBSyxJQUFMLENBQVUsT0FBbkIsRUFBNEIsQ0FBQyxrQkFBa0IsU0FBbkIsSUFBZ0MsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLGdCQUF4RSxDQUE1QixDQUF6QjtBQUNBLGdCQUFJLEtBQUssTUFBTCxDQUFZLE1BQWhCLEVBQXdCO0FBQ3BCLG9CQUFJLENBQUMsS0FBSyxNQUFMLENBQVksSUFBWixDQUFpQixNQUF0QixFQUE4QjtBQUMxQix5QkFBSyxJQUFMLENBQVUsVUFBVixHQUF1QixrQkFBdkI7QUFDSDtBQUNKLGFBSkQsTUFJTztBQUNILHFCQUFLLElBQUwsQ0FBVSxVQUFWLEdBQXVCLEtBQUssTUFBTCxDQUFZLElBQVosQ0FBaUIsTUFBeEM7O0FBRUEsb0JBQUksQ0FBQyxLQUFLLElBQUwsQ0FBVSxVQUFmLEVBQTJCO0FBQ3ZCLHlCQUFLLElBQUwsQ0FBVSxVQUFWLEdBQXVCLGtCQUF2QjtBQUNIO0FBRUo7O0FBRUQscUJBQVMsS0FBSyxJQUFMLENBQVUsVUFBVixHQUF1QixLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksZ0JBQW5DLEdBQXNELE9BQU8sR0FBN0QsR0FBbUUsT0FBTyxNQUExRSxHQUFtRixTQUE1Rjs7QUFHQSxpQkFBSyxJQUFMLENBQVUsS0FBVixHQUFrQixRQUFRLE9BQU8sSUFBZixHQUFzQixPQUFPLEtBQS9DO0FBQ0EsaUJBQUssSUFBTCxDQUFVLE1BQVYsR0FBbUIsU0FBUyxPQUFPLEdBQWhCLEdBQXNCLE9BQU8sTUFBaEQ7QUFDSDs7O3NDQUdhOztBQUVWLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLFNBQVMsS0FBSyxNQUFsQjtBQUNBLGdCQUFJLElBQUksS0FBSyxJQUFMLENBQVUsQ0FBbEI7QUFDQSxnQkFBSSxRQUFRLE9BQU8sS0FBUCxDQUFhLEtBQXpCO0FBQ0EsZ0JBQUksU0FBUyxFQUFFLEdBQUYsR0FBUSxFQUFFLEdBQXZCO0FBQ0EsZ0JBQUksS0FBSjtBQUNBLGNBQUUsTUFBRixHQUFXLEVBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQVAsQ0FBYSxLQUFiLElBQXNCLEtBQTFCLEVBQWlDO0FBQzdCLG9CQUFJLFdBQVcsRUFBZjtBQUNBLHNCQUFNLE9BQU4sQ0FBYyxVQUFDLENBQUQsRUFBSSxDQUFKLEVBQVM7QUFDbkIsd0JBQUksSUFBSSxFQUFFLEdBQUYsR0FBUyxTQUFTLEtBQUssR0FBTCxDQUFTLEVBQVQsRUFBYSxDQUFiLENBQTFCO0FBQ0Esc0JBQUUsTUFBRixDQUFTLElBQVQsQ0FBYyxDQUFkO0FBQ0gsaUJBSEQ7QUFJQSx3QkFBUSxHQUFHLEtBQUgsQ0FBUyxHQUFULEdBQWUsUUFBZixDQUF3QixRQUF4QixDQUFSO0FBQ0gsYUFQRCxNQU9PLElBQUksT0FBTyxLQUFQLENBQWEsS0FBYixJQUFzQixLQUExQixFQUFpQzs7QUFFcEMsc0JBQU0sT0FBTixDQUFjLFVBQUMsQ0FBRCxFQUFJLENBQUosRUFBUztBQUNuQix3QkFBSSxJQUFJLEVBQUUsR0FBRixHQUFTLFNBQVMsS0FBSyxHQUFMLENBQVMsRUFBVCxFQUFhLENBQWIsQ0FBMUI7QUFDQSxzQkFBRSxNQUFGLENBQVMsT0FBVCxDQUFpQixDQUFqQjtBQUVILGlCQUpEOztBQU1BLHdCQUFRLEdBQUcsS0FBSCxDQUFTLEdBQVQsRUFBUjtBQUNILGFBVE0sTUFTQTtBQUNILHNCQUFNLE9BQU4sQ0FBYyxVQUFDLENBQUQsRUFBSSxDQUFKLEVBQVM7QUFDbkIsd0JBQUksSUFBSSxFQUFFLEdBQUYsR0FBUyxVQUFVLEtBQUssTUFBTSxNQUFOLEdBQWUsQ0FBcEIsQ0FBVixDQUFqQjtBQUNBLHNCQUFFLE1BQUYsQ0FBUyxJQUFULENBQWMsQ0FBZDtBQUNILGlCQUhEO0FBSUEsd0JBQVEsR0FBRyxLQUFILENBQVMsT0FBTyxLQUFQLENBQWEsS0FBdEIsR0FBUjtBQUNIOztBQUdELGNBQUUsTUFBRixDQUFTLENBQVQsSUFBYyxFQUFFLEdBQWhCLEM7QUFDQSxjQUFFLE1BQUYsQ0FBUyxFQUFFLE1BQUYsQ0FBUyxNQUFULEdBQWtCLENBQTNCLElBQWdDLEVBQUUsR0FBbEMsQztBQUNBLG9CQUFRLEdBQVIsQ0FBWSxFQUFFLE1BQWQ7O0FBRUEsZ0JBQUksT0FBTyxLQUFQLENBQWEsWUFBakIsRUFBK0I7QUFDM0Isa0JBQUUsTUFBRixDQUFTLE9BQVQ7QUFDSDs7QUFFRCxnQkFBSSxPQUFPLEtBQUssSUFBaEI7O0FBRUEsb0JBQVEsR0FBUixDQUFZLEtBQVo7QUFDQSxpQkFBSyxDQUFMLENBQU8sS0FBUCxDQUFhLEtBQWIsR0FBcUIsTUFBTSxNQUFOLENBQWEsRUFBRSxNQUFmLEVBQXVCLEtBQXZCLENBQTZCLEtBQTdCLENBQXJCO0FBQ0EsZ0JBQUksUUFBUSxLQUFLLENBQUwsQ0FBTyxLQUFQLEdBQWUsRUFBM0I7O0FBRUEsZ0JBQUksV0FBVyxLQUFLLE1BQUwsQ0FBWSxJQUEzQjtBQUNBLGtCQUFNLElBQU4sR0FBYSxNQUFiOztBQUVBLGlCQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsS0FBYixHQUFxQixLQUFLLFNBQUwsR0FBaUIsU0FBUyxPQUFULEdBQW1CLENBQXpEO0FBQ0EsaUJBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxNQUFiLEdBQXNCLEtBQUssVUFBTCxHQUFrQixTQUFTLE9BQVQsR0FBbUIsQ0FBM0Q7QUFDSDs7OytCQUdNLE8sRUFBUztBQUNaLHNGQUFhLE9BQWI7QUFDQSxnQkFBSSxLQUFLLElBQUwsQ0FBVSxRQUFkLEVBQXdCO0FBQ3BCLHFCQUFLLFdBQUwsQ0FBaUIsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLE1BQTdCLEVBQXFDLEtBQUssSUFBMUM7QUFDSDtBQUNELGdCQUFJLEtBQUssSUFBTCxDQUFVLFFBQWQsRUFBd0I7QUFDcEIscUJBQUssV0FBTCxDQUFpQixLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksTUFBN0IsRUFBcUMsS0FBSyxJQUExQztBQUNIOztBQUVELGlCQUFLLFdBQUw7Ozs7QUFJQSxpQkFBSyxXQUFMO0FBQ0EsaUJBQUssV0FBTDs7QUFFQSxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxVQUFoQixFQUE0QjtBQUN4QixxQkFBSyxZQUFMO0FBQ0g7O0FBRUQsaUJBQUssZ0JBQUw7QUFDSDs7OzJDQUVrQjtBQUNmLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUdIOzs7c0NBR2E7QUFDVixnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxhQUFhLEtBQUssV0FBTCxDQUFpQixPQUFqQixDQUFqQjtBQUNBLGdCQUFJLGNBQWMsYUFBYSxJQUEvQjtBQUNBLGdCQUFJLGNBQWMsYUFBYSxJQUEvQjtBQUNBLGlCQUFLLFVBQUwsR0FBa0IsVUFBbEI7O0FBRUEsZ0JBQUksVUFBVTtBQUNWLG1CQUFHLENBRE87QUFFVixtQkFBRztBQUZPLGFBQWQ7QUFJQSxnQkFBSSxVQUFVLFFBQVEsY0FBUixDQUF1QixDQUF2QixDQUFkO0FBQ0EsZ0JBQUksS0FBSyxRQUFULEVBQW1CO0FBQ2Ysb0JBQUksVUFBVSxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsTUFBZCxDQUFxQixPQUFuQzs7QUFFQSx3QkFBUSxDQUFSLEdBQVksVUFBVSxDQUF0QjtBQUNBLHdCQUFRLENBQVIsR0FBWSxRQUFRLE1BQVIsR0FBaUIsVUFBVSxDQUEzQixHQUErQixDQUEzQztBQUNILGFBTEQsTUFLTyxJQUFJLEtBQUssUUFBVCxFQUFtQjtBQUN0Qix3QkFBUSxDQUFSLEdBQVksT0FBWjtBQUNIOztBQUdELGdCQUFJLFNBQVMsS0FBSyxJQUFMLENBQVUsU0FBVixDQUFvQixVQUFVLFdBQTlCLEVBQ1IsSUFEUSxDQUNILEtBQUssQ0FBTCxDQUFPLGFBREosRUFDbUIsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFRLENBQVI7QUFBQSxhQURuQixDQUFiOztBQUdBLG1CQUFPLEtBQVAsR0FBZSxNQUFmLENBQXNCLE1BQXRCLEVBQThCLElBQTlCLENBQW1DLE9BQW5DLEVBQTRDLFVBQUMsQ0FBRCxFQUFJLENBQUo7QUFBQSx1QkFBVSxhQUFhLEdBQWIsR0FBbUIsV0FBbkIsR0FBaUMsR0FBakMsR0FBdUMsV0FBdkMsR0FBcUQsR0FBckQsR0FBMkQsQ0FBckU7QUFBQSxhQUE1Qzs7QUFFQSxtQkFDSyxJQURMLENBQ1UsR0FEVixFQUNlLFVBQUMsQ0FBRCxFQUFJLENBQUo7QUFBQSx1QkFBVyxJQUFJLEtBQUssU0FBVCxHQUFxQixLQUFLLFNBQUwsR0FBaUIsQ0FBdkMsR0FBNkMsRUFBRSxLQUFGLENBQVEsUUFBckQsR0FBaUUsUUFBUSxDQUFuRjtBQUFBLGFBRGYsRUFFSyxJQUZMLENBRVUsR0FGVixFQUVlLEtBQUssTUFBTCxHQUFjLFFBQVEsQ0FGckMsRUFHSyxJQUhMLENBR1UsSUFIVixFQUdnQixFQUhoQixFQUtLLElBTEwsQ0FLVSxhQUxWLEVBS3lCLFFBTHpCLEVBTUssSUFOTCxDQU1VO0FBQUEsdUJBQUcsS0FBSyxZQUFMLENBQWtCLEVBQUUsR0FBcEIsQ0FBSDtBQUFBLGFBTlY7O0FBVUEsZ0JBQUksV0FBVyxLQUFLLHVCQUFMLENBQTZCLE9BQTdCLENBQWY7O0FBRUEsbUJBQU8sSUFBUCxDQUFZLFVBQVUsS0FBVixFQUFpQjtBQUN6QixvQkFBSSxPQUFPLEdBQUcsTUFBSCxDQUFVLElBQVYsQ0FBWDtBQUFBLG9CQUNJLE9BQU8sS0FBSyxZQUFMLENBQWtCLE1BQU0sR0FBeEIsQ0FEWDtBQUVBLDZCQUFNLCtCQUFOLENBQXNDLElBQXRDLEVBQTRDLElBQTVDLEVBQWtELFFBQWxELEVBQTRELEtBQUssTUFBTCxDQUFZLFdBQVosR0FBMEIsS0FBSyxJQUFMLENBQVUsT0FBcEMsR0FBOEMsS0FBMUc7QUFDSCxhQUpEOztBQU1BLGdCQUFJLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxZQUFsQixFQUFnQztBQUM1Qix1QkFBTyxJQUFQLENBQVksV0FBWixFQUF5QixVQUFDLENBQUQsRUFBSSxDQUFKO0FBQUEsMkJBQVUsa0JBQW1CLElBQUksS0FBSyxTQUFULEdBQXFCLEtBQUssU0FBTCxHQUFpQixDQUF2QyxHQUE0QyxFQUFFLEtBQUYsQ0FBUSxRQUFwRCxHQUErRCxRQUFRLENBQXpGLElBQStGLElBQS9GLElBQXdHLEtBQUssTUFBTCxHQUFjLFFBQVEsQ0FBOUgsSUFBbUksR0FBN0k7QUFBQSxpQkFBekIsRUFDSyxJQURMLENBQ1UsSUFEVixFQUNnQixDQUFDLENBRGpCLEVBRUssSUFGTCxDQUVVLElBRlYsRUFFZ0IsQ0FGaEIsRUFHSyxJQUhMLENBR1UsYUFIVixFQUd5QixLQUh6QjtBQUlIOztBQUdELG1CQUFPLElBQVAsR0FBYyxNQUFkOztBQUdBLGlCQUFLLElBQUwsQ0FBVSxjQUFWLENBQXlCLE9BQU8sS0FBSyxXQUFMLENBQWlCLFFBQWpCLENBQWhDLEVBQ0ssSUFETCxDQUNVLFdBRFYsRUFDdUIsZUFBZ0IsS0FBSyxLQUFMLEdBQWEsQ0FBN0IsR0FBa0MsR0FBbEMsSUFBeUMsS0FBSyxNQUFMLEdBQWMsS0FBSyxNQUFMLENBQVksTUFBbkUsSUFBNkUsR0FEcEcsRUFFSyxjQUZMLENBRW9CLFVBQVUsS0FBSyxXQUFMLENBQWlCLE9BQWpCLENBRjlCLEVBSUssSUFKTCxDQUlVLElBSlYsRUFJZ0IsUUFKaEIsRUFLSyxLQUxMLENBS1csYUFMWCxFQUswQixRQUwxQixFQU1LLElBTkwsQ0FNVSxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsS0FOeEI7QUFPSDs7O3NDQUVhO0FBQ1YsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsZ0JBQUksYUFBYSxLQUFLLFdBQUwsQ0FBaUIsT0FBakIsQ0FBakI7QUFDQSxnQkFBSSxjQUFjLGFBQWEsSUFBL0I7QUFDQSxpQkFBSyxVQUFMLEdBQWtCLFVBQWxCOztBQUdBLGdCQUFJLFNBQVMsS0FBSyxJQUFMLENBQVUsU0FBVixDQUFvQixVQUFVLFdBQTlCLEVBQ1IsSUFEUSxDQUNILEtBQUssQ0FBTCxDQUFPLGFBREosQ0FBYjs7QUFHQSxtQkFBTyxLQUFQLEdBQWUsTUFBZixDQUFzQixNQUF0Qjs7QUFFQSxnQkFBSSxVQUFVO0FBQ1YsbUJBQUcsQ0FETztBQUVWLG1CQUFHO0FBRk8sYUFBZDtBQUlBLGdCQUFJLEtBQUssUUFBVCxFQUFtQjtBQUNmLG9CQUFJLFVBQVUsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLE1BQWQsQ0FBcUIsT0FBbkM7QUFDQSxvQkFBSSxVQUFVLFFBQVEsY0FBUixDQUF1QixDQUF2QixDQUFkO0FBQ0Esd0JBQVEsQ0FBUixHQUFZLENBQUMsUUFBUSxJQUFyQjs7QUFFQSx3QkFBUSxDQUFSLEdBQVksVUFBVSxDQUF0QjtBQUNIO0FBQ0QsbUJBQ0ssSUFETCxDQUNVLEdBRFYsRUFDZSxRQUFRLENBRHZCLEVBRUssSUFGTCxDQUVVLEdBRlYsRUFFZSxVQUFDLENBQUQsRUFBSSxDQUFKO0FBQUEsdUJBQVcsSUFBSSxLQUFLLFVBQVQsR0FBc0IsS0FBSyxVQUFMLEdBQWtCLENBQXpDLEdBQThDLEVBQUUsS0FBRixDQUFRLFFBQXRELEdBQWlFLFFBQVEsQ0FBbkY7QUFBQSxhQUZmLEVBR0ssSUFITCxDQUdVLElBSFYsRUFHZ0IsQ0FBQyxDQUhqQixFQUlLLElBSkwsQ0FJVSxhQUpWLEVBSXlCLEtBSnpCLEVBS0ssSUFMTCxDQUtVLE9BTFYsRUFLbUIsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFVLGFBQWEsR0FBYixHQUFtQixXQUFuQixHQUFpQyxHQUFqQyxHQUF1QyxXQUF2QyxHQUFxRCxHQUFyRCxHQUEyRCxDQUFyRTtBQUFBLGFBTG5CLEVBT0ssSUFQTCxDQU9VLFVBQVUsQ0FBVixFQUFhO0FBQ2Ysb0JBQUksWUFBWSxLQUFLLFlBQUwsQ0FBa0IsRUFBRSxHQUFwQixDQUFoQjtBQUNBLHVCQUFPLFNBQVA7QUFDSCxhQVZMOztBQVlBLGdCQUFJLFdBQVcsS0FBSyx1QkFBTCxDQUE2QixPQUE3QixDQUFmOztBQUVBLG1CQUFPLElBQVAsQ0FBWSxVQUFVLEtBQVYsRUFBaUI7QUFDekIsb0JBQUksT0FBTyxHQUFHLE1BQUgsQ0FBVSxJQUFWLENBQVg7QUFBQSxvQkFDSSxPQUFPLEtBQUssWUFBTCxDQUFrQixNQUFNLEdBQXhCLENBRFg7QUFFQSw2QkFBTSwrQkFBTixDQUFzQyxJQUF0QyxFQUE0QyxJQUE1QyxFQUFrRCxRQUFsRCxFQUE0RCxLQUFLLE1BQUwsQ0FBWSxXQUFaLEdBQTBCLEtBQUssSUFBTCxDQUFVLE9BQXBDLEdBQThDLEtBQTFHO0FBQ0gsYUFKRDs7QUFNQSxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsWUFBbEIsRUFBZ0M7QUFDNUIsdUJBQ0ssSUFETCxDQUNVLFdBRFYsRUFDdUIsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLDJCQUFVLGlCQUFrQixRQUFRLENBQTFCLEdBQWlDLElBQWpDLElBQXlDLEVBQUUsS0FBRixDQUFRLFFBQVIsSUFBb0IsSUFBSSxLQUFLLFVBQVQsR0FBc0IsS0FBSyxVQUFMLEdBQWtCLENBQTVELElBQWlFLFFBQVEsQ0FBbEgsSUFBdUgsR0FBakk7QUFBQSxpQkFEdkIsRUFFSyxJQUZMLENBRVUsYUFGVixFQUV5QixLQUZ6Qjs7QUFJSCxhQUxELE1BS087QUFDSCx1QkFBTyxJQUFQLENBQVksbUJBQVosRUFBaUMsUUFBakM7QUFDSDs7QUFHRCxtQkFBTyxJQUFQLEdBQWMsTUFBZDs7QUFHQSxpQkFBSyxJQUFMLENBQVUsY0FBVixDQUF5QixPQUFPLEtBQUssV0FBTCxDQUFpQixRQUFqQixDQUFoQyxFQUNLLGNBREwsQ0FDb0IsVUFBVSxLQUFLLFdBQUwsQ0FBaUIsT0FBakIsQ0FEOUIsRUFFSyxJQUZMLENBRVUsV0FGVixFQUV1QixlQUFlLENBQUMsS0FBSyxNQUFMLENBQVksSUFBNUIsR0FBbUMsR0FBbkMsR0FBMEMsS0FBSyxNQUFMLEdBQWMsQ0FBeEQsR0FBNkQsY0FGcEYsRUFHSyxJQUhMLENBR1UsSUFIVixFQUdnQixLQUhoQixFQUlLLEtBSkwsQ0FJVyxhQUpYLEVBSTBCLFFBSjFCLEVBS0ssSUFMTCxDQUtVLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxLQUx4QjtBQU9IOzs7b0NBR1csVyxFQUFhLFMsRUFBVyxjLEVBQWdCOztBQUVoRCxnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7O0FBRUEsZ0JBQUksYUFBYSxLQUFLLFdBQUwsQ0FBaUIsT0FBakIsQ0FBakI7QUFDQSxnQkFBSSxjQUFjLGFBQWEsSUFBL0I7QUFDQSxnQkFBSSxTQUFTLFVBQVUsU0FBVixDQUFvQixPQUFPLFVBQVAsR0FBb0IsR0FBcEIsR0FBMEIsV0FBOUMsRUFDUixJQURRLENBQ0gsWUFBWSxZQURULENBQWI7O0FBR0EsZ0JBQUksb0JBQW9CLENBQXhCO0FBQ0EsZ0JBQUksaUJBQWlCLENBQXJCOztBQUVBLGdCQUFJLGVBQWUsT0FBTyxLQUFQLEdBQWUsTUFBZixDQUFzQixHQUF0QixDQUFuQjtBQUNBLHlCQUNLLE9BREwsQ0FDYSxVQURiLEVBQ3lCLElBRHpCLEVBRUssT0FGTCxDQUVhLFdBRmIsRUFFMEIsSUFGMUIsRUFHSyxNQUhMLENBR1ksTUFIWixFQUdvQixPQUhwQixDQUc0QixZQUg1QixFQUcwQyxJQUgxQzs7QUFLQSxnQkFBSSxrQkFBa0IsYUFBYSxjQUFiLENBQTRCLFNBQTVCLENBQXRCO0FBQ0EsNEJBQWdCLE1BQWhCLENBQXVCLE1BQXZCO0FBQ0EsNEJBQWdCLE1BQWhCLENBQXVCLE1BQXZCOztBQUVBLGdCQUFJLFVBQVUsUUFBUSxjQUFSLENBQXVCLFlBQVksS0FBbkMsQ0FBZDtBQUNBLGdCQUFJLFVBQVUsVUFBVSxDQUF4Qjs7QUFFQSxnQkFBSSxpQkFBaUIsUUFBUSxvQkFBN0I7QUFDQSxnQkFBSSxRQUFRLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxNQUFkLENBQXFCLElBQXJCLENBQTBCLE1BQTFCLEdBQW1DLFlBQVksS0FBM0Q7QUFDQSxnQkFBSSxVQUFVO0FBQ1Ysc0JBQU0sQ0FESTtBQUVWLHVCQUFPO0FBRkcsYUFBZDs7QUFLQSxnQkFBSSxDQUFDLGNBQUwsRUFBcUI7QUFDakIsd0JBQVEsS0FBUixHQUFnQixLQUFLLENBQUwsQ0FBTyxPQUFQLENBQWUsSUFBL0I7QUFDQSx3QkFBUSxJQUFSLEdBQWUsS0FBSyxDQUFMLENBQU8sT0FBUCxDQUFlLElBQTlCO0FBQ0EsaUNBQWlCLEtBQUssS0FBTCxHQUFhLE9BQWIsR0FBdUIsUUFBUSxJQUEvQixHQUFzQyxRQUFRLEtBQS9EO0FBQ0g7O0FBR0QsbUJBQ0ssSUFETCxDQUNVLFdBRFYsRUFDdUIsVUFBQyxDQUFELEVBQUksQ0FBSixFQUFVO0FBQ3pCLG9CQUFJLFlBQVksZ0JBQWdCLFVBQVUsUUFBUSxJQUFsQyxJQUEwQyxHQUExQyxJQUFrRCxLQUFLLFVBQUwsR0FBa0IsaUJBQW5CLEdBQXdDLElBQUksT0FBNUMsR0FBc0QsY0FBdEQsR0FBdUUsT0FBeEgsSUFBbUksR0FBbko7QUFDQSxrQ0FBbUIsRUFBRSxjQUFGLElBQW9CLENBQXZDO0FBQ0EscUNBQXFCLEVBQUUsY0FBRixJQUFvQixDQUF6QztBQUNBLHVCQUFPLFNBQVA7QUFDSCxhQU5MOztBQVNBLGdCQUFJLGFBQWEsaUJBQWlCLFVBQVUsQ0FBNUM7O0FBRUEsZ0JBQUksY0FBYyxPQUFPLFNBQVAsQ0FBaUIsU0FBakIsRUFDYixJQURhLENBQ1IsV0FEUSxFQUNLLFVBQUMsQ0FBRCxFQUFJLENBQUo7QUFBQSx1QkFBVSxnQkFBZ0IsYUFBYSxjQUE3QixJQUErQyxNQUF6RDtBQUFBLGFBREwsQ0FBbEI7O0FBR0EsZ0JBQUksWUFBWSxZQUFZLFNBQVosQ0FBc0IsTUFBdEIsRUFDWCxJQURXLENBQ04sT0FETSxFQUNHLGNBREgsRUFFWCxJQUZXLENBRU4sUUFGTSxFQUVJLGFBQUk7QUFDaEIsdUJBQU8sQ0FBQyxFQUFFLGNBQUYsSUFBb0IsQ0FBckIsSUFBMEIsS0FBSyxVQUFMLEdBQWtCLEVBQUUsY0FBOUMsR0FBK0QsVUFBVSxDQUFoRjtBQUNILGFBSlcsRUFLWCxJQUxXLENBS04sR0FMTSxFQUtELENBTEMsRUFNWCxJQU5XLENBTU4sR0FOTSxFQU1ELENBTkM7O0FBQUEsYUFRWCxJQVJXLENBUU4sY0FSTSxFQVFVLENBUlYsQ0FBaEI7O0FBVUEsaUJBQUssc0JBQUwsQ0FBNEIsV0FBNUIsRUFBeUMsU0FBekM7O0FBR0EsbUJBQU8sU0FBUCxDQUFpQixpQkFBakIsRUFDSyxJQURMLENBQ1UsT0FEVixFQUNtQjtBQUFBLHVCQUFJLDJCQUEyQixFQUFFLEtBQWpDO0FBQUEsYUFEbkIsRUFFSyxJQUZMLENBRVUsT0FGVixFQUVtQixVQUZuQixFQUdLLElBSEwsQ0FHVSxRQUhWLEVBR29CLGFBQUk7QUFDaEIsdUJBQU8sQ0FBQyxFQUFFLGNBQUYsSUFBb0IsQ0FBckIsSUFBMEIsS0FBSyxVQUFMLEdBQWtCLEVBQUUsY0FBOUMsR0FBK0QsVUFBVSxDQUFoRjtBQUNILGFBTEwsRUFNSyxJQU5MLENBTVUsR0FOVixFQU1lLENBTmYsRUFPSyxJQVBMLENBT1UsR0FQVixFQU9lLENBUGYsRUFRSyxJQVJMLENBUVUsTUFSVixFQVFrQixPQVJsQixFQVNLLElBVEwsQ0FTVSxjQVRWLEVBUzBCLENBVDFCLEVBVUssSUFWTCxDQVVVLGNBVlYsRUFVMEIsR0FWMUIsRUFXSyxJQVhMLENBV1UsUUFYVixFQVdvQixPQVhwQjs7QUFjQSxtQkFBTyxJQUFQLENBQVksVUFBVSxLQUFWLEVBQWlCOztBQUV6QixxQkFBSyxXQUFMLENBQWlCLElBQWpCLENBQXNCLElBQXRCLEVBQTRCLEtBQTVCLEVBQW1DLEdBQUcsTUFBSCxDQUFVLElBQVYsQ0FBbkMsRUFBb0QsYUFBYSxjQUFqRTtBQUNILGFBSEQ7QUFLSDs7O29DQUVXLFcsRUFBYSxTLEVBQVcsZSxFQUFpQjs7QUFFakQsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQWhCOztBQUVBLGdCQUFJLGFBQWEsS0FBSyxXQUFMLENBQWlCLE9BQWpCLENBQWpCO0FBQ0EsZ0JBQUksY0FBYyxhQUFhLElBQS9CO0FBQ0EsZ0JBQUksU0FBUyxVQUFVLFNBQVYsQ0FBb0IsT0FBTyxVQUFQLEdBQW9CLEdBQXBCLEdBQTBCLFdBQTlDLEVBQ1IsSUFEUSxDQUNILFlBQVksWUFEVCxDQUFiOztBQUdBLGdCQUFJLG9CQUFvQixDQUF4QjtBQUNBLGdCQUFJLGlCQUFpQixDQUFyQjs7QUFFQSxnQkFBSSxlQUFlLE9BQU8sS0FBUCxHQUFlLE1BQWYsQ0FBc0IsR0FBdEIsQ0FBbkI7QUFDQSx5QkFDSyxPQURMLENBQ2EsVUFEYixFQUN5QixJQUR6QixFQUVLLE9BRkwsQ0FFYSxXQUZiLEVBRTBCLElBRjFCLEVBR0ssTUFITCxDQUdZLE1BSFosRUFHb0IsT0FIcEIsQ0FHNEIsWUFINUIsRUFHMEMsSUFIMUM7O0FBS0EsZ0JBQUksa0JBQWtCLGFBQWEsY0FBYixDQUE0QixTQUE1QixDQUF0QjtBQUNBLDRCQUFnQixNQUFoQixDQUF1QixNQUF2QjtBQUNBLDRCQUFnQixNQUFoQixDQUF1QixNQUF2Qjs7QUFFQSxnQkFBSSxVQUFVLFFBQVEsY0FBUixDQUF1QixZQUFZLEtBQW5DLENBQWQ7QUFDQSxnQkFBSSxVQUFVLFVBQVUsQ0FBeEI7QUFDQSxnQkFBSSxrQkFBa0IsUUFBUSxvQkFBOUI7O0FBRUEsZ0JBQUksUUFBUSxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsTUFBZCxDQUFxQixJQUFyQixDQUEwQixNQUExQixHQUFtQyxZQUFZLEtBQTNEOztBQUVBLGdCQUFJLFVBQVU7QUFDVixxQkFBSyxDQURLO0FBRVYsd0JBQVE7QUFGRSxhQUFkOztBQUtBLGdCQUFJLENBQUMsZUFBTCxFQUFzQjtBQUNsQix3QkFBUSxNQUFSLEdBQWlCLEtBQUssQ0FBTCxDQUFPLE9BQVAsQ0FBZSxNQUFoQztBQUNBLHdCQUFRLEdBQVIsR0FBYyxLQUFLLENBQUwsQ0FBTyxPQUFQLENBQWUsR0FBN0I7QUFDQSxrQ0FBa0IsS0FBSyxNQUFMLEdBQWMsT0FBZCxHQUF3QixRQUFRLEdBQWhDLEdBQXNDLFFBQVEsTUFBaEU7QUFFSCxhQUxELE1BS087QUFDSCx3QkFBUSxHQUFSLEdBQWMsQ0FBQyxlQUFmO0FBQ0g7OztBQUdELG1CQUNLLElBREwsQ0FDVSxXQURWLEVBQ3VCLFVBQUMsQ0FBRCxFQUFJLENBQUosRUFBVTtBQUN6QixvQkFBSSxZQUFZLGdCQUFpQixLQUFLLFNBQUwsR0FBaUIsaUJBQWxCLEdBQXVDLElBQUksT0FBM0MsR0FBcUQsY0FBckQsR0FBc0UsT0FBdEYsSUFBaUcsSUFBakcsSUFBeUcsVUFBVSxRQUFRLEdBQTNILElBQWtJLEdBQWxKO0FBQ0Esa0NBQW1CLEVBQUUsY0FBRixJQUFvQixDQUF2QztBQUNBLHFDQUFxQixFQUFFLGNBQUYsSUFBb0IsQ0FBekM7QUFDQSx1QkFBTyxTQUFQO0FBQ0gsYUFOTDs7QUFRQSxnQkFBSSxjQUFjLGtCQUFrQixVQUFVLENBQTlDOztBQUVBLGdCQUFJLGNBQWMsT0FBTyxTQUFQLENBQWlCLFNBQWpCLEVBQ2IsSUFEYSxDQUNSLFdBRFEsRUFDSyxVQUFDLENBQUQsRUFBSSxDQUFKO0FBQUEsdUJBQVUsa0JBQW1CLENBQW5CLEdBQXdCLEdBQWxDO0FBQUEsYUFETCxDQUFsQjs7QUFJQSxnQkFBSSxZQUFZLFlBQVksU0FBWixDQUFzQixNQUF0QixFQUNYLElBRFcsQ0FDTixRQURNLEVBQ0ksZUFESixFQUVYLElBRlcsQ0FFTixPQUZNLEVBRUcsYUFBSTtBQUNmLHVCQUFPLENBQUMsRUFBRSxjQUFGLElBQW9CLENBQXJCLElBQTBCLEtBQUssU0FBTCxHQUFpQixFQUFFLGNBQTdDLEdBQThELFVBQVUsQ0FBL0U7QUFDSCxhQUpXLEVBS1gsSUFMVyxDQUtOLEdBTE0sRUFLRCxDQUxDLEVBTVgsSUFOVyxDQU1OLEdBTk0sRUFNRCxDQU5DOztBQUFBLGFBUVgsSUFSVyxDQVFOLGNBUk0sRUFRVSxDQVJWLENBQWhCOztBQVVBLGlCQUFLLHNCQUFMLENBQTRCLFdBQTVCLEVBQXlDLFNBQXpDOztBQUdBLG1CQUFPLFNBQVAsQ0FBaUIsaUJBQWpCLEVBQ0ssSUFETCxDQUNVLE9BRFYsRUFDbUI7QUFBQSx1QkFBSSwyQkFBMkIsRUFBRSxLQUFqQztBQUFBLGFBRG5CLEVBRUssSUFGTCxDQUVVLFFBRlYsRUFFb0IsV0FGcEIsRUFHSyxJQUhMLENBR1UsT0FIVixFQUdtQixhQUFJO0FBQ2YsdUJBQU8sQ0FBQyxFQUFFLGNBQUYsSUFBb0IsQ0FBckIsSUFBMEIsS0FBSyxTQUFMLEdBQWlCLEVBQUUsY0FBN0MsR0FBOEQsVUFBVSxDQUEvRTtBQUNILGFBTEwsRUFNSyxJQU5MLENBTVUsR0FOVixFQU1lLENBTmYsRUFPSyxJQVBMLENBT1UsR0FQVixFQU9lLENBUGYsRUFRSyxJQVJMLENBUVUsTUFSVixFQVFrQixPQVJsQixFQVNLLElBVEwsQ0FTVSxjQVRWLEVBUzBCLENBVDFCLEVBVUssSUFWTCxDQVVVLGNBVlYsRUFVMEIsR0FWMUIsRUFXSyxJQVhMLENBV1UsUUFYVixFQVdvQixPQVhwQjs7QUFhQSxtQkFBTyxJQUFQLENBQVksVUFBVSxLQUFWLEVBQWlCO0FBQ3pCLHFCQUFLLFdBQUwsQ0FBaUIsSUFBakIsQ0FBc0IsSUFBdEIsRUFBNEIsS0FBNUIsRUFBbUMsR0FBRyxNQUFILENBQVUsSUFBVixDQUFuQyxFQUFvRCxjQUFjLGVBQWxFO0FBQ0gsYUFGRDs7QUFJQSxtQkFBTyxJQUFQLEdBQWMsTUFBZDtBQUVIOzs7K0NBRXNCLFcsRUFBYSxTLEVBQVc7QUFDM0MsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUkscUJBQXFCLEVBQXpCO0FBQ0EsK0JBQW1CLElBQW5CLENBQXdCLFVBQVUsQ0FBVixFQUFhO0FBQ2pDLG1CQUFHLE1BQUgsQ0FBVSxJQUFWLEVBQWdCLE9BQWhCLENBQXdCLGFBQXhCLEVBQXVDLElBQXZDO0FBQ0EsbUJBQUcsTUFBSCxDQUFVLEtBQUssVUFBTCxDQUFnQixVQUExQixFQUFzQyxTQUF0QyxDQUFnRCxxQkFBcUIsRUFBRSxLQUF2RSxFQUE4RSxPQUE5RSxDQUFzRixhQUF0RixFQUFxRyxJQUFyRztBQUNILGFBSEQ7O0FBS0EsZ0JBQUksb0JBQW9CLEVBQXhCO0FBQ0EsOEJBQWtCLElBQWxCLENBQXVCLFVBQVUsQ0FBVixFQUFhO0FBQ2hDLG1CQUFHLE1BQUgsQ0FBVSxJQUFWLEVBQWdCLE9BQWhCLENBQXdCLGFBQXhCLEVBQXVDLEtBQXZDO0FBQ0EsbUJBQUcsTUFBSCxDQUFVLEtBQUssVUFBTCxDQUFnQixVQUExQixFQUFzQyxTQUF0QyxDQUFnRCxxQkFBcUIsRUFBRSxLQUF2RSxFQUE4RSxPQUE5RSxDQUFzRixhQUF0RixFQUFxRyxLQUFyRztBQUNILGFBSEQ7QUFJQSxnQkFBSSxLQUFLLE9BQVQsRUFBa0I7O0FBRWQsbUNBQW1CLElBQW5CLENBQXdCLGFBQUk7QUFDeEIseUJBQUssT0FBTCxDQUFhLFVBQWIsR0FDSyxRQURMLENBQ2MsR0FEZCxFQUVLLEtBRkwsQ0FFVyxTQUZYLEVBRXNCLEVBRnRCO0FBR0Esd0JBQUksT0FBTyxZQUFZLEtBQVosR0FBb0IsSUFBcEIsR0FBMkIsRUFBRSxhQUF4Qzs7QUFFQSx5QkFBSyxPQUFMLENBQWEsSUFBYixDQUFrQixJQUFsQixFQUNLLEtBREwsQ0FDVyxNQURYLEVBQ29CLEdBQUcsS0FBSCxDQUFTLEtBQVQsR0FBaUIsQ0FBbEIsR0FBdUIsSUFEMUMsRUFFSyxLQUZMLENBRVcsS0FGWCxFQUVtQixHQUFHLEtBQUgsQ0FBUyxLQUFULEdBQWlCLEVBQWxCLEdBQXdCLElBRjFDO0FBR0gsaUJBVEQ7O0FBV0Esa0NBQWtCLElBQWxCLENBQXVCLGFBQUk7QUFDdkIseUJBQUssT0FBTCxDQUFhLFVBQWIsR0FDSyxRQURMLENBQ2MsR0FEZCxFQUVLLEtBRkwsQ0FFVyxTQUZYLEVBRXNCLENBRnRCO0FBR0gsaUJBSkQ7QUFPSDtBQUNELHNCQUFVLEVBQVYsQ0FBYSxXQUFiLEVBQTBCLFVBQVUsQ0FBVixFQUFhO0FBQ25DLG9CQUFJLE9BQU8sSUFBWDtBQUNBLG1DQUFtQixPQUFuQixDQUEyQixVQUFVLFFBQVYsRUFBb0I7QUFDM0MsNkJBQVMsSUFBVCxDQUFjLElBQWQsRUFBb0IsQ0FBcEI7QUFDSCxpQkFGRDtBQUdILGFBTEQ7QUFNQSxzQkFBVSxFQUFWLENBQWEsVUFBYixFQUF5QixVQUFVLENBQVYsRUFBYTtBQUNsQyxvQkFBSSxPQUFPLElBQVg7QUFDQSxrQ0FBa0IsT0FBbEIsQ0FBMEIsVUFBVSxRQUFWLEVBQW9CO0FBQzFDLDZCQUFTLElBQVQsQ0FBYyxJQUFkLEVBQW9CLENBQXBCO0FBQ0gsaUJBRkQ7QUFHSCxhQUxEO0FBTUg7OztzQ0FFYTs7QUFFVixnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxxQkFBcUIsS0FBSyxXQUFMLENBQWlCLE9BQWpCLENBQXpCO0FBQ0EsZ0JBQUksVUFBVSxRQUFRLGNBQVIsQ0FBdUIsQ0FBdkIsQ0FBZDtBQUNBLGdCQUFJLFdBQVcsS0FBSyxDQUFMLENBQU8sTUFBUCxDQUFjLFlBQWQsQ0FBMkIsTUFBM0IsR0FBb0MsVUFBVSxDQUE5QyxHQUFrRCxDQUFqRTtBQUNBLGdCQUFJLFdBQVcsS0FBSyxDQUFMLENBQU8sTUFBUCxDQUFjLFlBQWQsQ0FBMkIsTUFBM0IsR0FBb0MsVUFBVSxDQUE5QyxHQUFrRCxDQUFqRTtBQUNBLGdCQUFJLGdCQUFnQixLQUFLLElBQUwsQ0FBVSxjQUFWLENBQXlCLE9BQU8sa0JBQWhDLENBQXBCO0FBQ0EsMEJBQWMsSUFBZCxDQUFtQixXQUFuQixFQUFnQyxlQUFlLFFBQWYsR0FBMEIsSUFBMUIsR0FBaUMsUUFBakMsR0FBNEMsR0FBNUU7O0FBRUEsZ0JBQUksWUFBWSxLQUFLLFdBQUwsQ0FBaUIsTUFBakIsQ0FBaEI7QUFDQSxnQkFBSSxZQUFZLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxJQUE3Qjs7QUFFQSxnQkFBSSxRQUFRLGNBQWMsU0FBZCxDQUF3QixPQUFPLFNBQS9CLEVBQ1AsSUFETyxDQUNGLEtBQUssSUFBTCxDQUFVLEtBRFIsQ0FBWjs7QUFHQSxnQkFBSSxhQUFhLE1BQU0sS0FBTixHQUFjLE1BQWQsQ0FBcUIsR0FBckIsRUFDWixPQURZLENBQ0osU0FESSxFQUNPLElBRFAsQ0FBakI7QUFFQSxrQkFBTSxJQUFOLENBQVcsV0FBWCxFQUF3QjtBQUFBLHVCQUFJLGdCQUFpQixLQUFLLFNBQUwsR0FBaUIsRUFBRSxHQUFuQixHQUF5QixLQUFLLFNBQUwsR0FBaUIsQ0FBM0MsR0FBZ0QsRUFBRSxNQUFGLENBQVMsS0FBVCxDQUFlLFFBQS9FLElBQTJGLEdBQTNGLElBQW1HLEtBQUssVUFBTCxHQUFrQixFQUFFLEdBQXBCLEdBQTBCLEtBQUssVUFBTCxHQUFrQixDQUE3QyxHQUFrRCxFQUFFLE1BQUYsQ0FBUyxLQUFULENBQWUsUUFBbkssSUFBK0ssR0FBbkw7QUFBQSxhQUF4Qjs7QUFFQSxnQkFBSSxTQUFTLE1BQU0sY0FBTixDQUFxQixZQUFZLGNBQVosR0FBNkIsU0FBbEQsQ0FBYjs7QUFFQSxtQkFDSyxJQURMLENBQ1UsT0FEVixFQUNtQixLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsS0FEaEMsRUFFSyxJQUZMLENBRVUsUUFGVixFQUVvQixLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsTUFGakMsRUFHSyxJQUhMLENBR1UsR0FIVixFQUdlLENBQUMsS0FBSyxTQUFOLEdBQWtCLENBSGpDLEVBSUssSUFKTCxDQUlVLEdBSlYsRUFJZSxDQUFDLEtBQUssVUFBTixHQUFtQixDQUpsQzs7QUFNQSxtQkFBTyxLQUFQLENBQWEsTUFBYixFQUFxQjtBQUFBLHVCQUFJLEVBQUUsS0FBRixLQUFZLFNBQVosR0FBd0IsS0FBSyxNQUFMLENBQVksS0FBWixDQUFrQixXQUExQyxHQUF3RCxLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsS0FBYixDQUFtQixFQUFFLEtBQXJCLENBQTVEO0FBQUEsYUFBckI7QUFDQSxtQkFBTyxJQUFQLENBQVksY0FBWixFQUE0QjtBQUFBLHVCQUFJLEVBQUUsS0FBRixLQUFZLFNBQVosR0FBd0IsQ0FBeEIsR0FBNEIsQ0FBaEM7QUFBQSxhQUE1Qjs7QUFFQSxnQkFBSSxxQkFBcUIsRUFBekI7QUFDQSxnQkFBSSxvQkFBb0IsRUFBeEI7O0FBRUEsZ0JBQUksS0FBSyxPQUFULEVBQWtCOztBQUVkLG1DQUFtQixJQUFuQixDQUF3QixhQUFJO0FBQ3hCLHlCQUFLLE9BQUwsQ0FBYSxVQUFiLEdBQ0ssUUFETCxDQUNjLEdBRGQsRUFFSyxLQUZMLENBRVcsU0FGWCxFQUVzQixFQUZ0QjtBQUdBLHdCQUFJLE9BQU8sRUFBRSxLQUFGLEtBQVksU0FBWixHQUF3QixLQUFLLE1BQUwsQ0FBWSxPQUFaLENBQW9CLFVBQTVDLEdBQXlELEtBQUssWUFBTCxDQUFrQixFQUFFLEtBQXBCLENBQXBFOztBQUVBLHlCQUFLLE9BQUwsQ0FBYSxJQUFiLENBQWtCLElBQWxCLEVBQ0ssS0FETCxDQUNXLE1BRFgsRUFDb0IsR0FBRyxLQUFILENBQVMsS0FBVCxHQUFpQixDQUFsQixHQUF1QixJQUQxQyxFQUVLLEtBRkwsQ0FFVyxLQUZYLEVBRW1CLEdBQUcsS0FBSCxDQUFTLEtBQVQsR0FBaUIsRUFBbEIsR0FBd0IsSUFGMUM7QUFHSCxpQkFURDs7QUFXQSxrQ0FBa0IsSUFBbEIsQ0FBdUIsYUFBSTtBQUN2Qix5QkFBSyxPQUFMLENBQWEsVUFBYixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsQ0FGdEI7QUFHSCxpQkFKRDtBQU9IOztBQUVELGdCQUFJLEtBQUssTUFBTCxDQUFZLGVBQWhCLEVBQWlDO0FBQzdCLG9CQUFJLGlCQUFpQixLQUFLLE1BQUwsQ0FBWSxjQUFaLEdBQTZCLFdBQWxEO0FBQ0Esb0JBQUksY0FBYyxTQUFkLFdBQWM7QUFBQSwyQkFBRyxLQUFLLFVBQUwsR0FBa0IsS0FBbEIsR0FBMEIsRUFBRSxHQUEvQjtBQUFBLGlCQUFsQjtBQUNBLG9CQUFJLGNBQWMsU0FBZCxXQUFjO0FBQUEsMkJBQUcsS0FBSyxVQUFMLEdBQWtCLEtBQWxCLEdBQTBCLEVBQUUsR0FBL0I7QUFBQSxpQkFBbEI7O0FBR0EsbUNBQW1CLElBQW5CLENBQXdCLGFBQUk7O0FBRXhCLHlCQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLFVBQVUsWUFBWSxDQUFaLENBQTlCLEVBQThDLE9BQTlDLENBQXNELGNBQXRELEVBQXNFLElBQXRFO0FBQ0EseUJBQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsVUFBVSxZQUFZLENBQVosQ0FBOUIsRUFBOEMsT0FBOUMsQ0FBc0QsY0FBdEQsRUFBc0UsSUFBdEU7QUFDSCxpQkFKRDtBQUtBLGtDQUFrQixJQUFsQixDQUF1QixhQUFJO0FBQ3ZCLHlCQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLFVBQVUsWUFBWSxDQUFaLENBQTlCLEVBQThDLE9BQTlDLENBQXNELGNBQXRELEVBQXNFLEtBQXRFO0FBQ0EseUJBQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsVUFBVSxZQUFZLENBQVosQ0FBOUIsRUFBOEMsT0FBOUMsQ0FBc0QsY0FBdEQsRUFBc0UsS0FBdEU7QUFDSCxpQkFIRDtBQUlIOztBQUdELGtCQUFNLEVBQU4sQ0FBUyxXQUFULEVBQXNCLGFBQUs7QUFDdkIsbUNBQW1CLE9BQW5CLENBQTJCO0FBQUEsMkJBQVUsU0FBUyxDQUFULENBQVY7QUFBQSxpQkFBM0I7QUFDSCxhQUZELEVBR0ssRUFITCxDQUdRLFVBSFIsRUFHb0IsYUFBSztBQUNqQixrQ0FBa0IsT0FBbEIsQ0FBMEI7QUFBQSwyQkFBVSxTQUFTLENBQVQsQ0FBVjtBQUFBLGlCQUExQjtBQUNILGFBTEw7O0FBT0Esa0JBQU0sRUFBTixDQUFTLE9BQVQsRUFBa0IsYUFBSTtBQUNsQixxQkFBSyxPQUFMLENBQWEsZUFBYixFQUE4QixDQUE5QjtBQUNILGFBRkQ7O0FBS0Esa0JBQU0sSUFBTixHQUFhLE1BQWI7QUFDSDs7O3FDQUVZLEssRUFBTztBQUNoQixnQkFBSSxDQUFDLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxTQUFuQixFQUE4QixPQUFPLEtBQVA7O0FBRTlCLG1CQUFPLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxTQUFkLENBQXdCLElBQXhCLENBQTZCLEtBQUssTUFBbEMsRUFBMEMsS0FBMUMsQ0FBUDtBQUNIOzs7cUNBRVksSyxFQUFPO0FBQ2hCLGdCQUFJLENBQUMsS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLFNBQW5CLEVBQThCLE9BQU8sS0FBUDs7QUFFOUIsbUJBQU8sS0FBSyxNQUFMLENBQVksQ0FBWixDQUFjLFNBQWQsQ0FBd0IsSUFBeEIsQ0FBNkIsS0FBSyxNQUFsQyxFQUEwQyxLQUExQyxDQUFQO0FBQ0g7OztxQ0FFWSxLLEVBQU87QUFDaEIsZ0JBQUksQ0FBQyxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsU0FBbkIsRUFBOEIsT0FBTyxLQUFQOztBQUU5QixtQkFBTyxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsU0FBZCxDQUF3QixJQUF4QixDQUE2QixLQUFLLE1BQWxDLEVBQTBDLEtBQTFDLENBQVA7QUFDSDs7OzBDQUVpQixLLEVBQU87QUFDckIsZ0JBQUksQ0FBQyxLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLFNBQXhCLEVBQW1DLE9BQU8sS0FBUDs7QUFFbkMsbUJBQU8sS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixTQUFuQixDQUE2QixJQUE3QixDQUFrQyxLQUFLLE1BQXZDLEVBQStDLEtBQS9DLENBQVA7QUFDSDs7O3VDQUVjO0FBQ1gsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsZ0JBQUksVUFBVSxLQUFLLElBQUwsQ0FBVSxLQUFWLEdBQWtCLEVBQWhDO0FBQ0EsZ0JBQUksVUFBVSxRQUFRLGNBQVIsQ0FBdUIsQ0FBdkIsQ0FBZDtBQUNBLGdCQUFJLEtBQUssSUFBTCxDQUFVLFFBQWQsRUFBd0I7QUFDcEIsMkJBQVcsVUFBVSxDQUFWLEdBQWMsS0FBSyxDQUFMLENBQU8sT0FBUCxDQUFlLEtBQXhDO0FBQ0gsYUFGRCxNQUVPLElBQUksS0FBSyxJQUFMLENBQVUsUUFBZCxFQUF3QjtBQUMzQiwyQkFBVyxPQUFYO0FBQ0g7QUFDRCxnQkFBSSxVQUFVLENBQWQ7QUFDQSxnQkFBSSxLQUFLLElBQUwsQ0FBVSxRQUFWLElBQXNCLEtBQUssSUFBTCxDQUFVLFFBQXBDLEVBQThDO0FBQzFDLDJCQUFXLFVBQVUsQ0FBckI7QUFDSDs7QUFFRCxnQkFBSSxXQUFXLEVBQWY7QUFDQSxnQkFBSSxZQUFZLEtBQUssSUFBTCxDQUFVLE1BQVYsR0FBbUIsQ0FBbkM7QUFDQSxnQkFBSSxRQUFRLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxLQUF6Qjs7QUFFQSxpQkFBSyxNQUFMLEdBQWMsbUJBQVcsS0FBSyxHQUFoQixFQUFxQixLQUFLLElBQTFCLEVBQWdDLEtBQWhDLEVBQXVDLE9BQXZDLEVBQWdELE9BQWhELEVBQXlEO0FBQUEsdUJBQUssS0FBSyxpQkFBTCxDQUF1QixDQUF2QixDQUFMO0FBQUEsYUFBekQsRUFBeUYsZUFBekYsQ0FBeUcsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixZQUE1SCxFQUEwSSxpQkFBMUksQ0FBNEosUUFBNUosRUFBc0ssU0FBdEssQ0FBZDtBQUNIOzs7dUNBdG9CcUIsUSxFQUFVO0FBQzVCLG1CQUFPLFFBQVEsZUFBUixJQUEyQixXQUFXLENBQXRDLENBQVA7QUFDSDs7O3dDQUVzQixJLEVBQU07QUFDekIsZ0JBQUksV0FBVyxDQUFmO0FBQ0EsaUJBQUssT0FBTCxDQUFhLFVBQUMsVUFBRCxFQUFhLFNBQWI7QUFBQSx1QkFBMEIsWUFBWSxhQUFhLFFBQVEsY0FBUixDQUF1QixTQUF2QixDQUFuRDtBQUFBLGFBQWI7QUFDQSxtQkFBTyxRQUFQO0FBQ0g7Ozs7OztBQXRYUSxPLENBRUYsZSxHQUFrQixFO0FBRmhCLE8sQ0FHRixvQixHQUF1QixDOzs7Ozs7Ozs7Ozs7OztBQ2xHbEM7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0lBRWEsZSxXQUFBLGU7Ozs7O0FBZ0NULDZCQUFZLE1BQVosRUFBbUI7QUFBQTs7QUFBQTs7QUFBQSxjQTlCbkIsUUE4Qm1CLEdBOUJULE1BQUssY0FBTCxHQUFvQixXQThCWDtBQUFBLGNBN0JuQixVQTZCbUIsR0E3QlIsSUE2QlE7QUFBQSxjQTVCbkIsV0E0Qm1CLEdBNUJOLElBNEJNO0FBQUEsY0EzQm5CLE1BMkJtQixHQTNCWjtBQUNILG1CQUFPLEVBREo7QUFFSCxvQkFBUSxFQUZMO0FBR0gsd0JBQVk7QUFIVCxTQTJCWTtBQUFBLGNBdEJuQixDQXNCbUIsR0F0QmpCLEU7QUFDRSxtQkFBTyxFQURULEU7QUFFRSxpQkFBSyxDQUZQO0FBR0UsbUJBQU8sZUFBQyxDQUFELEVBQUksR0FBSjtBQUFBLHVCQUFZLGFBQU0sUUFBTixDQUFlLENBQWYsSUFBb0IsQ0FBcEIsR0FBd0IsRUFBRSxHQUFGLENBQXBDO0FBQUEsYUFIVCxFO0FBSUUsbUJBQU8sUUFKVDtBQUtFLG1CQUFPO0FBTFQsU0FzQmlCO0FBQUEsY0FmbkIsQ0FlbUIsR0FmakIsRTtBQUNFLG1CQUFPLEVBRFQsRTtBQUVFLG9CQUFRLE1BRlY7QUFHRSxtQkFBTztBQUhULFNBZWlCO0FBQUEsY0FWbkIsU0FVbUIsR0FWVCxJQVVTO0FBQUEsY0FUbkIsTUFTbUIsR0FUWjtBQUNILGlCQUFLLENBREY7QUFFSCxtQkFBTyxlQUFDLENBQUQ7QUFBQSx1QkFBTyxFQUFFLE1BQUssTUFBTCxDQUFZLEdBQWQsQ0FBUDtBQUFBLGFBRkosRTtBQUdILG1CQUFPO0FBSEosU0FTWTtBQUFBLGNBSm5CLEtBSW1CLEdBSlgsU0FJVztBQUFBLGNBSG5CLGVBR21CLEdBSEYsWUFHRTtBQUFBLGNBRm5CLFVBRW1CLEdBRlAsSUFFTzs7QUFFZixZQUFJLGNBQUo7O0FBRUEsWUFBRyxNQUFILEVBQVU7QUFDTix5QkFBTSxVQUFOLFFBQXVCLE1BQXZCO0FBQ0g7O0FBTmM7QUFRbEI7Ozs7O0lBR1EsUyxXQUFBLFM7OztBQUNULHVCQUFZLG1CQUFaLEVBQWlDLElBQWpDLEVBQXVDLE1BQXZDLEVBQStDO0FBQUE7O0FBQUEsNEZBQ3JDLG1CQURxQyxFQUNoQixJQURnQixFQUNWLElBQUksZUFBSixDQUFvQixNQUFwQixDQURVO0FBRTlDOzs7O2tDQUVTLE0sRUFBTztBQUNiLGtHQUF1QixJQUFJLGVBQUosQ0FBb0IsTUFBcEIsQ0FBdkI7QUFDSDs7O21DQUVTO0FBQUE7O0FBQ047QUFDQSxnQkFBSSxPQUFLLElBQVQ7O0FBRUEsZ0JBQUksT0FBTyxLQUFLLE1BQWhCOztBQUVBLGlCQUFLLElBQUwsQ0FBVSxDQUFWLEdBQVksRUFBWjtBQUNBLGlCQUFLLElBQUwsQ0FBVSxDQUFWLEdBQVksRUFBWjtBQUNBLGlCQUFLLElBQUwsQ0FBVSxHQUFWLEdBQWM7QUFDVix1QkFBTyxJO0FBREcsYUFBZDs7QUFJQSxpQkFBSyxJQUFMLENBQVUsVUFBVixHQUF1QixLQUFLLFVBQTVCO0FBQ0EsZ0JBQUcsS0FBSyxJQUFMLENBQVUsVUFBYixFQUF3QjtBQUNwQixxQkFBSyxJQUFMLENBQVUsTUFBVixDQUFpQixLQUFqQixHQUF5QixLQUFLLE1BQUwsQ0FBWSxLQUFaLEdBQW9CLEtBQUssTUFBTCxDQUFZLEtBQWhDLEdBQXNDLEtBQUssTUFBTCxDQUFZLE1BQVosR0FBbUIsQ0FBbEY7QUFDSDs7QUFHRCxpQkFBSyxlQUFMOztBQUlBLGdCQUFHLEtBQUssZUFBUixFQUF3QjtBQUNwQixxQkFBSyxJQUFMLENBQVUsYUFBVixHQUEwQixHQUFHLEtBQUgsQ0FBUyxLQUFLLGVBQWQsR0FBMUI7QUFDSDtBQUNELGdCQUFJLGFBQWEsS0FBSyxLQUF0QjtBQUNBLGdCQUFJLGNBQWMsT0FBTyxVQUFQLEtBQXNCLFFBQXBDLElBQWdELHNCQUFzQixNQUExRSxFQUFpRjtBQUM3RSxxQkFBSyxJQUFMLENBQVUsS0FBVixHQUFrQixVQUFsQjtBQUNILGFBRkQsTUFFTSxJQUFHLEtBQUssSUFBTCxDQUFVLGFBQWIsRUFBMkI7QUFDN0Isb0JBQUksU0FBUyxPQUFPLG1CQUFQLENBQTJCLEdBQUcsR0FBSCxDQUFPLEtBQUssSUFBWixFQUFrQjtBQUFBLDJCQUFLLE9BQUssTUFBTCxDQUFZLE1BQVosQ0FBbUIsS0FBbkIsQ0FBeUIsSUFBekIsQ0FBOEIsT0FBSyxNQUFuQyxFQUEyQyxDQUEzQyxDQUFMO0FBQUEsaUJBQWxCLEVBQXNFLEdBQXRFLENBQTNCLENBQWI7QUFDQSxxQkFBSyxJQUFMLENBQVUsYUFBVixDQUF3QixNQUF4QixDQUErQixNQUEvQjtBQUNBLHFCQUFLLElBQUwsQ0FBVSxLQUFWLEdBQWtCO0FBQUEsMkJBQU0sS0FBSyxJQUFMLENBQVUsYUFBVixDQUF3QixFQUFFLEdBQTFCLENBQU47QUFBQSxpQkFBbEI7QUFDSDs7QUFFRCxpQkFBSyxJQUFMLENBQVUsSUFBVixHQUFpQixLQUFLLGFBQUwsRUFBakI7QUFDQSxpQkFBSyxNQUFMO0FBQ0EsaUJBQUssY0FBTDtBQUNBLGlCQUFLLGdCQUFMO0FBQ0EsaUJBQUssTUFBTDs7QUFFQSxtQkFBTyxJQUFQO0FBQ0g7OztpQ0FFTzs7QUFFSixnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxJQUFJLEtBQUssQ0FBYjtBQUNBLGdCQUFJLE9BQU8sS0FBSyxNQUFMLENBQVksQ0FBdkI7Ozs7Ozs7O0FBUUEsY0FBRSxLQUFGLEdBQVU7QUFBQSx1QkFBSyxLQUFLLEtBQUwsQ0FBVyxDQUFYLEVBQWMsS0FBSyxHQUFuQixDQUFMO0FBQUEsYUFBVjtBQUNBLGNBQUUsS0FBRixHQUFVLEdBQUcsS0FBSCxDQUFTLEtBQUssS0FBZCxJQUF1QixLQUF2QixDQUE2QixDQUFDLENBQUQsRUFBSSxLQUFLLEtBQVQsQ0FBN0IsQ0FBVjtBQUNBLGNBQUUsR0FBRixHQUFRO0FBQUEsdUJBQUssRUFBRSxLQUFGLENBQVEsRUFBRSxLQUFGLENBQVEsQ0FBUixDQUFSLENBQUw7QUFBQSxhQUFSOztBQUVBLGNBQUUsSUFBRixHQUFTLEdBQUcsR0FBSCxDQUFPLElBQVAsR0FBYyxLQUFkLENBQW9CLEVBQUUsS0FBdEIsRUFBNkIsTUFBN0IsQ0FBb0MsS0FBSyxNQUF6QyxDQUFUO0FBQ0EsZ0JBQUcsS0FBSyxLQUFSLEVBQWM7QUFDVixrQkFBRSxJQUFGLENBQU8sS0FBUCxDQUFhLEtBQUssS0FBbEI7QUFDSDtBQUNELGdCQUFJLE9BQU8sS0FBSyxJQUFMLENBQVUsSUFBckI7QUFDQSxpQkFBSyxDQUFMLENBQU8sS0FBUCxDQUFhLE1BQWIsQ0FBb0IsQ0FBQyxHQUFHLEdBQUgsQ0FBTyxJQUFQLEVBQWEsS0FBSyxDQUFMLENBQU8sS0FBcEIsQ0FBRCxFQUE2QixHQUFHLEdBQUgsQ0FBTyxJQUFQLEVBQWEsS0FBSyxDQUFMLENBQU8sS0FBcEIsQ0FBN0IsQ0FBcEI7QUFFSDs7O2lDQUVROztBQUVMLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLElBQUksS0FBSyxDQUFiO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLE1BQUwsQ0FBWSxDQUF2QjtBQUNBLGNBQUUsS0FBRixHQUFVLEdBQUcsS0FBSCxDQUFTLEtBQUssS0FBZCxJQUF1QixLQUF2QixDQUE2QixDQUFDLEtBQUssTUFBTixFQUFjLENBQWQsQ0FBN0IsQ0FBVjs7QUFFQSxjQUFFLElBQUYsR0FBUyxHQUFHLEdBQUgsQ0FBTyxJQUFQLEdBQWMsS0FBZCxDQUFvQixFQUFFLEtBQXRCLEVBQTZCLE1BQTdCLENBQW9DLEtBQUssTUFBekMsQ0FBVDs7QUFFQSxnQkFBSSxPQUFPLEtBQUssSUFBTCxDQUFVLElBQXJCO0FBQ0EsaUJBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxNQUFiLENBQW9CLENBQUMsQ0FBRCxFQUFJLEdBQUcsR0FBSCxDQUFPLEtBQUssYUFBWixFQUEyQjtBQUFBLHVCQUFHLEVBQUUsQ0FBTDtBQUFBLGFBQTNCLENBQUosQ0FBcEI7QUFDSDs7O3lDQUVnQjtBQUNiLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLElBQUksS0FBSyxDQUFiO0FBQ0EsZ0JBQUksSUFBSSxLQUFLLENBQWI7QUFDQSxnQkFBSSxRQUFRLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBYyxLQUFkLEdBQXNCLEVBQUUsS0FBRixDQUFRLEtBQVIsQ0FBYyxLQUFLLE1BQUwsQ0FBWSxDQUFaLENBQWMsS0FBNUIsQ0FBdEIsR0FBMkQsRUFBRSxLQUFGLENBQVEsS0FBUixFQUF2RTs7QUFFQSxpQkFBSyxTQUFMLEdBQWlCLEdBQUcsTUFBSCxDQUFVLFNBQVYsR0FBc0IsU0FBdEIsQ0FBZ0MsS0FBSyxNQUFMLENBQVksU0FBNUMsRUFDWixLQURZLENBQ04sRUFBRSxLQURJLEVBRVosSUFGWSxDQUVQLEtBRk8sQ0FBakI7QUFHQSxpQkFBSyxhQUFMLEdBQXFCLEtBQUssU0FBTCxDQUFlLEtBQUssSUFBTCxDQUFVLElBQXpCLENBQXJCO0FBRUg7OzsyQ0FFa0I7QUFBQTs7QUFDZixnQkFBSSxPQUFLLElBQVQ7QUFDQSxpQkFBSyxJQUFMLENBQVUsZUFBVixHQUE0QixLQUFLLE1BQUwsQ0FBWSxNQUFaLElBQXNCLEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBbUIsS0FBckU7O0FBRUEsaUJBQUssSUFBTCxDQUFVLEtBQVYsR0FBa0IsR0FBRyxNQUFILENBQVUsS0FBVixHQUFrQixNQUFsQixDQUF5QjtBQUFBLHVCQUFHLEVBQUUsYUFBTDtBQUFBLGFBQXpCLENBQWxCO0FBQ0EsaUJBQUssSUFBTCxDQUFVLFdBQVYsR0FBeUIsR0FBRyxJQUFILEdBQVUsR0FBVixDQUFjO0FBQUEsdUJBQUssT0FBSyxJQUFMLENBQVUsZUFBVixHQUE0QixPQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLEtBQW5CLENBQXlCLElBQXpCLENBQThCLE9BQUssTUFBbkMsRUFBMkMsQ0FBM0MsQ0FBNUIsR0FBNEUsTUFBakY7QUFBQSxhQUFkLEVBQXdHLE9BQXhHLENBQWdILEtBQUssSUFBTCxDQUFVLElBQTFILENBQXpCO0FBQ0EsaUJBQUssSUFBTCxDQUFVLFdBQVYsQ0FBc0IsT0FBdEIsQ0FBOEIsYUFBRztBQUM3QixrQkFBRSxhQUFGLEdBQWtCLE9BQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsU0FBcEIsQ0FBOEIsT0FBSyxNQUFMLENBQVksU0FBWixJQUF5QixPQUFLLElBQUwsQ0FBVSxlQUFqRSxFQUFrRixFQUFFLE1BQXBGLENBQWxCO0FBQ0Esb0JBQUcsQ0FBQyxPQUFLLE1BQUwsQ0FBWSxTQUFiLElBQTBCLE9BQUssSUFBTCxDQUFVLGVBQXZDLEVBQXVEO0FBQ25ELHNCQUFFLGFBQUYsQ0FBZ0IsT0FBaEIsQ0FBd0IsYUFBSztBQUN6QiwwQkFBRSxFQUFGLEdBQU8sRUFBRSxFQUFGLEdBQUssT0FBSyxJQUFMLENBQVUsSUFBVixDQUFlLE1BQTNCO0FBQ0EsMEJBQUUsQ0FBRixHQUFNLEVBQUUsQ0FBRixHQUFJLE9BQUssSUFBTCxDQUFVLElBQVYsQ0FBZSxNQUF6QjtBQUNILHFCQUhEO0FBSUg7QUFDSixhQVJEO0FBU0EsaUJBQUssSUFBTCxDQUFVLGlCQUFWLEdBQThCLEtBQUssSUFBTCxDQUFVLEtBQVYsQ0FBZ0IsS0FBSyxJQUFMLENBQVUsV0FBMUIsQ0FBOUI7QUFDSDs7O3dDQUVjO0FBQUE7O0FBQ1gsZ0JBQUcsQ0FBQyxLQUFLLGFBQVQsRUFBdUI7QUFDbkIsdUJBQU8sS0FBSyxJQUFaO0FBQ0g7O0FBRUQsbUJBQU8sS0FBSyxJQUFMLENBQVUsTUFBVixDQUFpQjtBQUFBLHVCQUFLLE9BQUssYUFBTCxDQUFtQixPQUFuQixDQUEyQixPQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLEtBQW5CLENBQXlCLElBQXpCLENBQThCLE9BQUssTUFBbkMsRUFBMkMsQ0FBM0MsQ0FBM0IsSUFBMEUsQ0FBQyxDQUFoRjtBQUFBLGFBQWpCLENBQVA7QUFDSDs7O29DQUVVO0FBQ1AsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsZ0JBQUksV0FBVyxLQUFLLE1BQUwsQ0FBWSxDQUEzQjtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFMLENBQVUsY0FBVixDQUF5QixPQUFLLEtBQUssV0FBTCxDQUFpQixRQUFqQixDQUFMLEdBQWdDLEdBQWhDLEdBQW9DLEtBQUssV0FBTCxDQUFpQixNQUFqQixDQUFwQyxJQUE4RCxLQUFLLE1BQUwsQ0FBWSxNQUFaLEdBQXFCLEVBQXJCLEdBQTBCLE1BQUksS0FBSyxXQUFMLENBQWlCLFdBQWpCLENBQTVGLENBQXpCLEVBQ04sSUFETSxDQUNELFdBREMsRUFDWSxpQkFBaUIsS0FBSyxNQUF0QixHQUErQixHQUQzQyxDQUFYOztBQUdBLGdCQUFJLFFBQVEsSUFBWjtBQUNBLGdCQUFJLEtBQUssTUFBTCxDQUFZLFVBQWhCLEVBQTRCO0FBQ3hCLHdCQUFRLEtBQUssVUFBTCxHQUFrQixJQUFsQixDQUF1QixZQUF2QixDQUFSO0FBQ0g7O0FBRUQsa0JBQU0sSUFBTixDQUFXLEtBQUssQ0FBTCxDQUFPLElBQWxCOztBQUVBLGlCQUFLLGNBQUwsQ0FBb0IsVUFBUSxLQUFLLFdBQUwsQ0FBaUIsT0FBakIsQ0FBNUIsRUFDSyxJQURMLENBQ1UsV0FEVixFQUN1QixlQUFlLEtBQUssS0FBTCxHQUFXLENBQTFCLEdBQThCLEdBQTlCLEdBQW9DLEtBQUssTUFBTCxDQUFZLE1BQWhELEdBQXlELEdBRGhGLEM7QUFBQSxhQUVLLElBRkwsQ0FFVSxJQUZWLEVBRWdCLE1BRmhCLEVBR0ssS0FITCxDQUdXLGFBSFgsRUFHMEIsUUFIMUIsRUFJSyxJQUpMLENBSVUsU0FBUyxLQUpuQjtBQUtIOzs7b0NBRVU7QUFDUCxnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxXQUFXLEtBQUssTUFBTCxDQUFZLENBQTNCO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQUwsQ0FBVSxjQUFWLENBQXlCLE9BQUssS0FBSyxXQUFMLENBQWlCLFFBQWpCLENBQUwsR0FBZ0MsR0FBaEMsR0FBb0MsS0FBSyxXQUFMLENBQWlCLE1BQWpCLENBQXBDLElBQThELEtBQUssTUFBTCxDQUFZLE1BQVosR0FBcUIsRUFBckIsR0FBMEIsTUFBSSxLQUFLLFdBQUwsQ0FBaUIsV0FBakIsQ0FBNUYsQ0FBekIsQ0FBWDs7QUFFQSxnQkFBSSxRQUFRLElBQVo7QUFDQSxnQkFBSSxLQUFLLE1BQUwsQ0FBWSxVQUFoQixFQUE0QjtBQUN4Qix3QkFBUSxLQUFLLFVBQUwsR0FBa0IsSUFBbEIsQ0FBdUIsWUFBdkIsQ0FBUjtBQUNIOztBQUVELGtCQUFNLElBQU4sQ0FBVyxLQUFLLENBQUwsQ0FBTyxJQUFsQjs7QUFFQSxpQkFBSyxjQUFMLENBQW9CLFVBQVEsS0FBSyxXQUFMLENBQWlCLE9BQWpCLENBQTVCLEVBQ0ssSUFETCxDQUNVLFdBRFYsRUFDdUIsZUFBYyxDQUFDLEtBQUssTUFBTCxDQUFZLElBQTNCLEdBQWlDLEdBQWpDLEdBQXNDLEtBQUssTUFBTCxHQUFZLENBQWxELEdBQXFELGNBRDVFLEM7QUFBQSxhQUVLLElBRkwsQ0FFVSxJQUZWLEVBRWdCLEtBRmhCLEVBR0ssS0FITCxDQUdXLGFBSFgsRUFHMEIsUUFIMUIsRUFJSyxJQUpMLENBSVUsU0FBUyxLQUpuQjtBQUtIOzs7d0NBR2U7QUFDWixnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7O0FBRUEsZ0JBQUksYUFBYSxLQUFLLFdBQUwsQ0FBaUIsT0FBakIsQ0FBakI7O0FBRUEsZ0JBQUksV0FBVyxLQUFLLFdBQUwsQ0FBaUIsS0FBakIsQ0FBZjtBQUNBLGdCQUFJLFFBQVEsS0FBSyxJQUFMLENBQVUsU0FBVixDQUFvQixNQUFJLFVBQXhCLEVBQ1AsSUFETyxDQUNGLEtBQUssaUJBREgsQ0FBWjs7QUFHQSxrQkFBTSxLQUFOLEdBQWMsTUFBZCxDQUFxQixHQUFyQixFQUNLLElBREwsQ0FDVSxPQURWLEVBQ21CLFVBRG5COztBQUdBLGdCQUFJLE1BQU0sTUFBTSxTQUFOLENBQWdCLE1BQUksUUFBcEIsRUFDTCxJQURLLENBQ0E7QUFBQSx1QkFBSyxFQUFFLGFBQVA7QUFBQSxhQURBLENBQVY7O0FBR0EsZ0JBQUksS0FBSixHQUFZLE1BQVosQ0FBbUIsR0FBbkIsRUFDSyxJQURMLENBQ1UsT0FEVixFQUNtQixRQURuQixFQUVLLE1BRkwsQ0FFWSxNQUZaLEVBR0ssSUFITCxDQUdVLEdBSFYsRUFHZSxDQUhmOztBQU1BLGdCQUFJLFVBQVUsSUFBSSxNQUFKLENBQVcsTUFBWCxDQUFkOztBQUVBLGdCQUFJLFdBQVcsT0FBZjtBQUNBLGdCQUFJLE9BQU8sR0FBWDtBQUNBLGdCQUFJLFNBQVMsS0FBYjtBQUNBLGdCQUFJLEtBQUssaUJBQUwsRUFBSixFQUE4QjtBQUMxQiwyQkFBVyxRQUFRLFVBQVIsRUFBWDtBQUNBLHVCQUFPLElBQUksVUFBSixFQUFQO0FBQ0EseUJBQVEsTUFBTSxVQUFOLEVBQVI7QUFDSDs7QUFFRCxpQkFBSyxJQUFMLENBQVUsV0FBVixFQUF1QixVQUFTLENBQVQsRUFBWTtBQUFFLHVCQUFPLGVBQWUsS0FBSyxDQUFMLENBQU8sS0FBUCxDQUFhLEVBQUUsQ0FBZixDQUFmLEdBQW1DLEdBQW5DLEdBQTBDLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxFQUFFLEVBQUYsR0FBTSxFQUFFLENBQXJCLENBQTFDLEdBQXFFLEdBQTVFO0FBQWtGLGFBQXZIOztBQUVBLGdCQUFJLEtBQUssS0FBSyxhQUFMLENBQW1CLE1BQW5CLEdBQTZCLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxLQUFLLGFBQUwsQ0FBbUIsQ0FBbkIsRUFBc0IsRUFBbkMsQ0FBN0IsR0FBc0UsQ0FBL0U7QUFDQSxxQkFDSyxJQURMLENBQ1UsT0FEVixFQUNvQixLQUFLLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxDQUFiLENBQUwsR0FBc0IsQ0FEMUMsRUFFSyxJQUZMLENBRVUsUUFGVixFQUVvQjtBQUFBLHVCQUFPLEtBQUssTUFBTCxHQUFjLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxFQUFFLENBQWYsQ0FBckI7QUFBQSxhQUZwQjs7QUFJQSxnQkFBRyxLQUFLLElBQUwsQ0FBVSxLQUFiLEVBQW1CO0FBQ2YsdUJBQ0ssSUFETCxDQUNVLE1BRFYsRUFDa0IsS0FBSyxJQUFMLENBQVUsS0FENUI7QUFFSDs7QUFFRCxnQkFBSSxLQUFLLE9BQVQsRUFBa0I7QUFDZCxvQkFBSSxFQUFKLENBQU8sV0FBUCxFQUFvQixhQUFLO0FBQ3JCLHlCQUFLLE9BQUwsQ0FBYSxVQUFiLEdBQ0ssUUFETCxDQUNjLEdBRGQsRUFFSyxLQUZMLENBRVcsU0FGWCxFQUVzQixFQUZ0QjtBQUdBLHlCQUFLLE9BQUwsQ0FBYSxJQUFiLENBQWtCLEVBQUUsQ0FBcEIsRUFDSyxLQURMLENBQ1csTUFEWCxFQUNvQixHQUFHLEtBQUgsQ0FBUyxLQUFULEdBQWlCLENBQWxCLEdBQXVCLElBRDFDLEVBRUssS0FGTCxDQUVXLEtBRlgsRUFFbUIsR0FBRyxLQUFILENBQVMsS0FBVCxHQUFpQixFQUFsQixHQUF3QixJQUYxQztBQUdILGlCQVBELEVBT0csRUFQSCxDQU9NLFVBUE4sRUFPa0IsYUFBSztBQUNuQix5QkFBSyxPQUFMLENBQWEsVUFBYixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsQ0FGdEI7QUFHSCxpQkFYRDtBQVlIO0FBQ0Qsa0JBQU0sSUFBTixHQUFhLE1BQWI7QUFDQSxnQkFBSSxJQUFKLEdBQVcsTUFBWDtBQUNIOzs7K0JBRU0sTyxFQUFRO0FBQ1gsd0ZBQWEsT0FBYjtBQUNBLGlCQUFLLFNBQUw7QUFDQSxpQkFBSyxTQUFMOztBQUVBLGlCQUFLLGFBQUw7O0FBRUEsaUJBQUssWUFBTDtBQUNIOzs7dUNBR2M7QUFBQTs7QUFDWCxnQkFBSSxPQUFPLEtBQUssSUFBaEI7O0FBRUEsZ0JBQUksUUFBUSxLQUFLLGFBQWpCO0FBQ0EsZ0JBQUcsQ0FBQyxNQUFNLE1BQU4sRUFBRCxJQUFtQixNQUFNLE1BQU4sR0FBZSxNQUFmLEdBQXNCLENBQTVDLEVBQThDO0FBQzFDLHFCQUFLLFVBQUwsR0FBa0IsS0FBbEI7QUFDSDs7QUFFRCxnQkFBRyxDQUFDLEtBQUssVUFBVCxFQUFvQjtBQUNoQixvQkFBRyxLQUFLLE1BQUwsSUFBZSxLQUFLLE1BQUwsQ0FBWSxTQUE5QixFQUF3QztBQUNwQyx5QkFBSyxNQUFMLENBQVksU0FBWixDQUFzQixNQUF0QjtBQUNIO0FBQ0Q7QUFDSDs7QUFHRCxnQkFBSSxVQUFVLEtBQUssSUFBTCxDQUFVLEtBQVYsR0FBa0IsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixNQUFuRDtBQUNBLGdCQUFJLFVBQVUsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixNQUFqQzs7QUFFQSxpQkFBSyxNQUFMLEdBQWMsbUJBQVcsS0FBSyxHQUFoQixFQUFxQixLQUFLLElBQTFCLEVBQWdDLEtBQWhDLEVBQXVDLE9BQXZDLEVBQWdELE9BQWhELENBQWQ7O0FBRUEsaUJBQUssV0FBTCxHQUFtQixLQUFLLE1BQUwsQ0FBWSxLQUFaLEdBQ2QsVUFEYyxDQUNILEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBbUIsVUFEaEIsRUFFZCxNQUZjLENBRVAsVUFGTyxFQUdkLEtBSGMsQ0FHUixLQUhRLENBQW5COztBQU1BLGlCQUFLLFdBQUwsQ0FBaUIsRUFBakIsQ0FBb0IsV0FBcEIsRUFBaUM7QUFBQSx1QkFBSSxPQUFLLGlCQUFMLENBQXVCLENBQXZCLENBQUo7QUFBQSxhQUFqQzs7QUFFQSxpQkFBSyxNQUFMLENBQVksU0FBWixDQUNLLElBREwsQ0FDVSxLQUFLLFdBRGY7QUFFSDs7OzBDQUVpQixTLEVBQVU7QUFDeEIsaUJBQUssbUJBQUwsQ0FBeUIsU0FBekI7O0FBRUEsZ0JBQUksYUFBYSxLQUFLLGFBQUwsQ0FBbUIsT0FBbkIsQ0FBMkIsU0FBM0IsSUFBc0MsQ0FBdkQ7QUFDQSxpQkFBSyxJQUFMLENBQVUsTUFBVixDQUFpQixTQUFqQixDQUEyQixTQUEzQixDQUFxQyxRQUFyQyxFQUErQyxJQUEvQyxDQUFvRCxVQUFTLElBQVQsRUFBYztBQUM5RCxvQkFBRyxRQUFRLFNBQVgsRUFBcUI7QUFDakIsdUJBQUcsTUFBSCxDQUFVLElBQVYsRUFBZ0IsT0FBaEIsQ0FBd0IsY0FBeEIsRUFBd0MsVUFBeEM7QUFDSDtBQUVKLGFBTEQ7O0FBT0EsaUJBQUssSUFBTDtBQUNIOzs7NENBRW1CLFMsRUFBVztBQUMzQixnQkFBSSxDQUFDLEtBQUssYUFBVixFQUF5QjtBQUNyQixxQkFBSyxhQUFMLEdBQXFCLEtBQUssSUFBTCxDQUFVLGFBQVYsQ0FBd0IsTUFBeEIsR0FBaUMsS0FBakMsRUFBckI7QUFDSDtBQUNELGdCQUFJLFFBQVEsS0FBSyxhQUFMLENBQW1CLE9BQW5CLENBQTJCLFNBQTNCLENBQVo7O0FBRUEsZ0JBQUksUUFBUSxDQUFaLEVBQWU7QUFDWCxxQkFBSyxhQUFMLENBQW1CLElBQW5CLENBQXdCLFNBQXhCO0FBQ0gsYUFGRCxNQUVPO0FBQ0gscUJBQUssYUFBTCxDQUFtQixNQUFuQixDQUEwQixLQUExQixFQUFpQyxDQUFqQztBQUNIO0FBQ0o7OztnQ0FJTyxJLEVBQUs7QUFDVCx5RkFBYyxJQUFkO0FBQ0EsaUJBQUssYUFBTCxHQUFxQixJQUFyQjtBQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O3dCQ2xXRyxXOzs7Ozs7d0JBQWEsaUI7Ozs7Ozs7Ozs4QkFDYixpQjs7Ozs7OzhCQUFtQix1Qjs7Ozs7Ozs7OzhCQUNuQixpQjs7Ozs7OzhCQUFtQix1Qjs7Ozs7Ozs7O3VCQUNuQixVOzs7Ozs7dUJBQVksZ0I7Ozs7Ozs7OztvQkFDWixPOzs7Ozs7b0JBQVMsYTs7Ozs7Ozs7OzhCQUNULGlCOzs7Ozs7OEJBQW1CLHVCOzs7Ozs7Ozs7c0JBQ25CLFM7Ozs7OztzQkFBVyxlOzs7Ozs7Ozs7cUJBQ1gsUTs7Ozs7O3FCQUFVLGM7Ozs7Ozs7Ozs0QkFDVixlOzs7Ozs7Ozs7bUJBQ0EsTTs7OztBQVpSOztBQUNBLDJCQUFhLE1BQWI7Ozs7Ozs7Ozs7OztBQ0RBOztBQUNBOzs7Ozs7Ozs7O0lBUWEsTSxXQUFBLE07QUFhVCxvQkFBWSxHQUFaLEVBQWlCLFlBQWpCLEVBQStCLEtBQS9CLEVBQXNDLE9BQXRDLEVBQStDLE9BQS9DLEVBQXdELFdBQXhELEVBQW9FO0FBQUE7O0FBQUEsYUFYcEUsY0FXb0UsR0FYckQsTUFXcUQ7QUFBQSxhQVZwRSxXQVVvRSxHQVZ4RCxLQUFLLGNBQUwsR0FBb0IsUUFVb0M7QUFBQSxhQVBwRSxLQU9vRTtBQUFBLGFBTnBFLElBTW9FO0FBQUEsYUFMcEUsTUFLb0U7QUFBQSxhQUZwRSxXQUVvRSxHQUZ0RCxTQUVzRDs7QUFDaEUsYUFBSyxLQUFMLEdBQVcsS0FBWDtBQUNBLGFBQUssR0FBTCxHQUFXLEdBQVg7QUFDQSxhQUFLLElBQUwsR0FBWSxhQUFNLElBQU4sRUFBWjtBQUNBLGFBQUssU0FBTCxHQUFrQixhQUFNLGNBQU4sQ0FBcUIsWUFBckIsRUFBbUMsT0FBSyxLQUFLLFdBQTdDLEVBQTBELEdBQTFELEVBQ2IsSUFEYSxDQUNSLFdBRFEsRUFDSyxlQUFhLE9BQWIsR0FBcUIsR0FBckIsR0FBeUIsT0FBekIsR0FBaUMsR0FEdEMsRUFFYixPQUZhLENBRUwsS0FBSyxXQUZBLEVBRWEsSUFGYixDQUFsQjs7QUFJQSxhQUFLLFdBQUwsR0FBbUIsV0FBbkI7QUFDSDs7OzswQ0FJaUIsUSxFQUFVLFMsRUFBVyxLLEVBQU07QUFDekMsZ0JBQUksYUFBYSxLQUFLLGNBQUwsR0FBb0IsaUJBQXBCLEdBQXNDLEdBQXRDLEdBQTBDLEtBQUssSUFBaEU7QUFDQSxnQkFBSSxRQUFPLEtBQUssS0FBaEI7QUFDQSxnQkFBSSxPQUFPLElBQVg7O0FBRUEsaUJBQUssY0FBTCxHQUFzQixhQUFNLGNBQU4sQ0FBcUIsS0FBSyxHQUExQixFQUErQixVQUEvQixFQUEyQyxLQUFLLEtBQUwsQ0FBVyxLQUFYLEVBQTNDLEVBQStELENBQS9ELEVBQWtFLEdBQWxFLEVBQXVFLENBQXZFLEVBQTBFLENBQTFFLENBQXRCOztBQUVBLGlCQUFLLFNBQUwsQ0FBZSxNQUFmLENBQXNCLE1BQXRCLEVBQ0ssSUFETCxDQUNVLE9BRFYsRUFDbUIsUUFEbkIsRUFFSyxJQUZMLENBRVUsUUFGVixFQUVvQixTQUZwQixFQUdLLElBSEwsQ0FHVSxHQUhWLEVBR2UsQ0FIZixFQUlLLElBSkwsQ0FJVSxHQUpWLEVBSWUsQ0FKZixFQUtLLEtBTEwsQ0FLVyxNQUxYLEVBS21CLFVBQVEsVUFBUixHQUFtQixHQUx0Qzs7QUFRQSxnQkFBSSxRQUFRLEtBQUssU0FBTCxDQUFlLFNBQWYsQ0FBeUIsTUFBekIsRUFDUCxJQURPLENBQ0QsTUFBTSxNQUFOLEVBREMsQ0FBWjtBQUVBLGdCQUFJLGNBQWEsTUFBTSxNQUFOLEdBQWUsTUFBZixHQUFzQixDQUF2QztBQUNBLGtCQUFNLEtBQU4sR0FBYyxNQUFkLENBQXFCLE1BQXJCOztBQUVBLGtCQUFNLElBQU4sQ0FBVyxHQUFYLEVBQWdCLFFBQWhCLEVBQ0ssSUFETCxDQUNVLEdBRFYsRUFDZ0IsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFXLFlBQVksSUFBRSxTQUFGLEdBQVksV0FBbkM7QUFBQSxhQURoQixFQUVLLElBRkwsQ0FFVSxJQUZWLEVBRWdCLENBRmhCOztBQUFBLGFBSUssSUFKTCxDQUlVLG9CQUpWLEVBSWdDLFFBSmhDLEVBS0ssSUFMTCxDQUtVO0FBQUEsdUJBQUksS0FBSyxXQUFMLEdBQW1CLEtBQUssV0FBTCxDQUFpQixDQUFqQixDQUFuQixHQUF5QyxDQUE3QztBQUFBLGFBTFY7QUFNQSxrQkFBTSxJQUFOLENBQVcsbUJBQVgsRUFBZ0MsUUFBaEM7QUFDQSxnQkFBRyxLQUFLLFlBQVIsRUFBcUI7QUFDakIsc0JBQ0ssSUFETCxDQUNVLFdBRFYsRUFDdUIsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLDJCQUFVLGlCQUFpQixRQUFqQixHQUE0QixJQUE1QixJQUFvQyxZQUFZLElBQUUsU0FBRixHQUFZLFdBQTVELElBQTRFLEdBQXRGO0FBQUEsaUJBRHZCLEVBRUssSUFGTCxDQUVVLGFBRlYsRUFFeUIsT0FGekIsRUFHSyxJQUhMLENBR1UsSUFIVixFQUdnQixDQUhoQixFQUlLLElBSkwsQ0FJVSxJQUpWLEVBSWdCLENBSmhCO0FBTUgsYUFQRCxNQU9LLENBRUo7O0FBRUQsa0JBQU0sSUFBTixHQUFhLE1BQWI7O0FBRUEsbUJBQU8sSUFBUDtBQUNIOzs7d0NBRWUsWSxFQUFjO0FBQzFCLGlCQUFLLFlBQUwsR0FBb0IsWUFBcEI7QUFDQSxtQkFBTyxJQUFQO0FBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2pGTDs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7SUFHYSxnQixXQUFBLGdCOzs7QUFVVCw4QkFBWSxNQUFaLEVBQW1CO0FBQUE7O0FBQUE7O0FBQUEsY0FSbkIsY0FRbUIsR0FSRixJQVFFO0FBQUEsY0FQbkIsZUFPbUIsR0FQRCxJQU9DO0FBQUEsY0FObkIsVUFNbUIsR0FOUjtBQUNQLG1CQUFPLElBREE7QUFFUCwyQkFBZSx1QkFBQyxnQkFBRCxFQUFtQixtQkFBbkI7QUFBQSx1QkFBMkMsaUNBQWdCLE1BQWhCLENBQXVCLGdCQUF2QixFQUF5QyxtQkFBekMsQ0FBM0M7QUFBQSxhQUZSO0FBR1AsMkJBQWUsUztBQUhSLFNBTVE7OztBQUdmLFlBQUcsTUFBSCxFQUFVO0FBQ04seUJBQU0sVUFBTixRQUF1QixNQUF2QjtBQUNIOztBQUxjO0FBT2xCOzs7OztJQUdRLFUsV0FBQSxVOzs7QUFDVCx3QkFBWSxtQkFBWixFQUFpQyxJQUFqQyxFQUF1QyxNQUF2QyxFQUErQztBQUFBOztBQUFBLDZGQUNyQyxtQkFEcUMsRUFDaEIsSUFEZ0IsRUFDVixJQUFJLGdCQUFKLENBQXFCLE1BQXJCLENBRFU7QUFFOUM7Ozs7a0NBRVMsTSxFQUFPO0FBQ2IsbUdBQXVCLElBQUksZ0JBQUosQ0FBcUIsTUFBckIsQ0FBdkI7QUFDSDs7O21DQUVTO0FBQ047QUFDQSxpQkFBSyxtQkFBTDtBQUNIOzs7OENBRW9COztBQUVqQixnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxrQkFBa0IsS0FBSyxNQUFMLENBQVksTUFBWixJQUFzQixLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLEtBQS9EOztBQUVBLGlCQUFLLElBQUwsQ0FBVSxXQUFWLEdBQXVCLEVBQXZCOztBQUdBLGdCQUFHLG1CQUFtQixLQUFLLE1BQUwsQ0FBWSxjQUFsQyxFQUFpRDtBQUM3QyxvQkFBSSxhQUFhLEtBQUssY0FBTCxDQUFvQixLQUFLLElBQUwsQ0FBVSxJQUE5QixFQUFvQyxLQUFwQyxDQUFqQjtBQUNBLHFCQUFLLElBQUwsQ0FBVSxXQUFWLENBQXNCLElBQXRCLENBQTJCLFVBQTNCO0FBQ0g7O0FBRUQsZ0JBQUcsS0FBSyxNQUFMLENBQVksZUFBZixFQUErQjtBQUMzQixxQkFBSyxtQkFBTDtBQUNIO0FBRUo7Ozs4Q0FFcUI7QUFDbEIsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksY0FBYyxFQUFsQjtBQUNBLGlCQUFLLElBQUwsQ0FBVSxJQUFWLENBQWUsT0FBZixDQUF3QixhQUFHO0FBQ3ZCLG9CQUFJLFdBQVcsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixLQUFuQixDQUF5QixDQUF6QixFQUE0QixLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLEdBQS9DLENBQWY7O0FBRUEsb0JBQUcsQ0FBQyxRQUFELElBQWEsYUFBVyxDQUEzQixFQUE2QjtBQUN6QjtBQUNIOztBQUVELG9CQUFHLENBQUMsWUFBWSxRQUFaLENBQUosRUFBMEI7QUFDdEIsZ0NBQVksUUFBWixJQUF3QixFQUF4QjtBQUNIO0FBQ0QsNEJBQVksUUFBWixFQUFzQixJQUF0QixDQUEyQixDQUEzQjtBQUNILGFBWEQ7O0FBYUEsaUJBQUksSUFBSSxHQUFSLElBQWUsV0FBZixFQUEyQjtBQUN2QixvQkFBSSxDQUFDLFlBQVksY0FBWixDQUEyQixHQUEzQixDQUFMLEVBQXNDO0FBQ2xDO0FBQ0g7O0FBRUQsb0JBQUksYUFBYSxLQUFLLGNBQUwsQ0FBb0IsWUFBWSxHQUFaLENBQXBCLEVBQXNDLEdBQXRDLENBQWpCO0FBQ0EscUJBQUssSUFBTCxDQUFVLFdBQVYsQ0FBc0IsSUFBdEIsQ0FBMkIsVUFBM0I7QUFDSDtBQUNKOzs7dUNBRWMsTSxFQUFRLFEsRUFBUztBQUM1QixnQkFBSSxPQUFPLElBQVg7O0FBRUEsZ0JBQUksU0FBUyxPQUFPLEdBQVAsQ0FBVyxhQUFHO0FBQ3ZCLHVCQUFPLENBQUMsV0FBVyxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksS0FBWixDQUFrQixDQUFsQixDQUFYLENBQUQsRUFBbUMsV0FBVyxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksS0FBWixDQUFrQixDQUFsQixDQUFYLENBQW5DLENBQVA7QUFDSCxhQUZZLENBQWI7Ozs7QUFNQSxnQkFBSSxtQkFBb0IsaUNBQWdCLGdCQUFoQixDQUFpQyxNQUFqQyxDQUF4QjtBQUNBLGdCQUFJLHVCQUF1QixpQ0FBZ0Isb0JBQWhCLENBQXFDLGdCQUFyQyxDQUEzQjs7QUFHQSxnQkFBSSxVQUFVLEdBQUcsTUFBSCxDQUFVLE1BQVYsRUFBa0I7QUFBQSx1QkFBRyxFQUFFLENBQUYsQ0FBSDtBQUFBLGFBQWxCLENBQWQ7O0FBR0EsZ0JBQUksYUFBYSxDQUNiO0FBQ0ksbUJBQUcsUUFBUSxDQUFSLENBRFA7QUFFSSxtQkFBRyxxQkFBcUIsUUFBUSxDQUFSLENBQXJCO0FBRlAsYUFEYSxFQUtiO0FBQ0ksbUJBQUcsUUFBUSxDQUFSLENBRFA7QUFFSSxtQkFBRyxxQkFBcUIsUUFBUSxDQUFSLENBQXJCO0FBRlAsYUFMYSxDQUFqQjs7QUFXQSxnQkFBSSxPQUFPLEdBQUcsR0FBSCxDQUFPLElBQVAsR0FDTixXQURNLENBQ00sT0FETixFQUVOLENBRk0sQ0FFSjtBQUFBLHVCQUFLLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxLQUFaLENBQWtCLEVBQUUsQ0FBcEIsQ0FBTDtBQUFBLGFBRkksRUFHTixDQUhNLENBR0o7QUFBQSx1QkFBSyxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksS0FBWixDQUFrQixFQUFFLENBQXBCLENBQUw7QUFBQSxhQUhJLENBQVg7O0FBTUEsZ0JBQUksUUFBUSxLQUFLLElBQUwsQ0FBVSxHQUFWLENBQWMsS0FBMUI7O0FBRUEsZ0JBQUksZUFBZSxPQUFuQjtBQUNBLGdCQUFHLGFBQU0sVUFBTixDQUFpQixLQUFqQixDQUFILEVBQTJCO0FBQ3ZCLG9CQUFHLE9BQU8sTUFBUCxJQUFpQixhQUFXLEtBQS9CLEVBQXFDO0FBQ2pDLDRCQUFRLE1BQU0sT0FBTyxDQUFQLENBQU4sQ0FBUjtBQUNILGlCQUZELE1BRUs7QUFDRCw0QkFBUSxZQUFSO0FBQ0g7QUFDSixhQU5ELE1BTU0sSUFBRyxDQUFDLEtBQUQsSUFBVSxhQUFXLEtBQXhCLEVBQThCO0FBQ2hDLHdCQUFRLFlBQVI7QUFDSDs7QUFHRCxnQkFBSSxhQUFhLEtBQUssaUJBQUwsQ0FBdUIsTUFBdkIsRUFBK0IsT0FBL0IsRUFBeUMsZ0JBQXpDLEVBQTBELG9CQUExRCxDQUFqQjtBQUNBLG1CQUFPO0FBQ0gsdUJBQU8sWUFBWSxLQURoQjtBQUVILHNCQUFNLElBRkg7QUFHSCw0QkFBWSxVQUhUO0FBSUgsdUJBQU8sS0FKSjtBQUtILDRCQUFZO0FBTFQsYUFBUDtBQU9IOzs7MENBRWlCLE0sRUFBUSxPLEVBQVMsZ0IsRUFBaUIsb0IsRUFBcUI7QUFDckUsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksUUFBUSxpQkFBaUIsQ0FBN0I7QUFDQSxnQkFBSSxJQUFJLE9BQU8sTUFBZjtBQUNBLGdCQUFJLG1CQUFtQixLQUFLLEdBQUwsQ0FBUyxDQUFULEVBQVksSUFBRSxDQUFkLENBQXZCOztBQUVBLGdCQUFJLFFBQVEsSUFBSSxLQUFLLE1BQUwsQ0FBWSxVQUFaLENBQXVCLEtBQXZDO0FBQ0EsZ0JBQUksc0JBQXVCLElBQUksUUFBTSxDQUFyQztBQUNBLGdCQUFJLGdCQUFnQixLQUFLLE1BQUwsQ0FBWSxVQUFaLENBQXVCLGFBQXZCLENBQXFDLGdCQUFyQyxFQUFzRCxtQkFBdEQsQ0FBcEI7O0FBRUEsZ0JBQUksVUFBVSxPQUFPLEdBQVAsQ0FBVztBQUFBLHVCQUFHLEVBQUUsQ0FBRixDQUFIO0FBQUEsYUFBWCxDQUFkO0FBQ0EsZ0JBQUksUUFBUSxpQ0FBZ0IsSUFBaEIsQ0FBcUIsT0FBckIsQ0FBWjtBQUNBLGdCQUFJLFNBQU8sQ0FBWDtBQUNBLGdCQUFJLE9BQUssQ0FBVDtBQUNBLGdCQUFJLFVBQVEsQ0FBWjtBQUNBLGdCQUFJLE9BQUssQ0FBVDtBQUNBLGdCQUFJLFVBQVEsQ0FBWjtBQUNBLG1CQUFPLE9BQVAsQ0FBZSxhQUFHO0FBQ2Qsb0JBQUksSUFBSSxFQUFFLENBQUYsQ0FBUjtBQUNBLG9CQUFJLElBQUksRUFBRSxDQUFGLENBQVI7O0FBRUEsMEJBQVUsSUFBRSxDQUFaO0FBQ0Esd0JBQU0sQ0FBTjtBQUNBLHdCQUFNLENBQU47QUFDQSwyQkFBVSxJQUFFLENBQVo7QUFDQSwyQkFBVSxJQUFFLENBQVo7QUFDSCxhQVREO0FBVUEsZ0JBQUksSUFBSSxpQkFBaUIsQ0FBekI7QUFDQSxnQkFBSSxJQUFJLGlCQUFpQixDQUF6Qjs7QUFFQSxnQkFBSSxNQUFNLEtBQUcsSUFBRSxDQUFMLEtBQVcsQ0FBQyxVQUFRLElBQUUsTUFBVixHQUFpQixJQUFFLElBQXBCLEtBQTJCLElBQUUsT0FBRixHQUFXLE9BQUssSUFBM0MsQ0FBWCxDQUFWLEM7QUFDQSxnQkFBSSxNQUFNLENBQUMsVUFBVSxJQUFFLE1BQVosR0FBbUIsSUFBRSxJQUF0QixLQUE2QixLQUFHLElBQUUsQ0FBTCxDQUE3QixDQUFWLEM7O0FBRUEsZ0JBQUksVUFBVSxTQUFWLE9BQVU7QUFBQSx1QkFBSSxLQUFLLElBQUwsQ0FBVSxNQUFNLEtBQUssR0FBTCxDQUFTLElBQUUsS0FBWCxFQUFpQixDQUFqQixJQUFvQixHQUFwQyxDQUFKO0FBQUEsYUFBZCxDO0FBQ0EsZ0JBQUksZ0JBQWlCLFNBQWpCLGFBQWlCO0FBQUEsdUJBQUksZ0JBQWUsUUFBUSxDQUFSLENBQW5CO0FBQUEsYUFBckI7Ozs7OztBQVFBLGdCQUFJLDZCQUE2QixTQUE3QiwwQkFBNkIsSUFBRztBQUNoQyxvQkFBSSxtQkFBbUIscUJBQXFCLENBQXJCLENBQXZCO0FBQ0Esb0JBQUksTUFBTSxjQUFjLENBQWQsQ0FBVjtBQUNBLG9CQUFJLFdBQVcsbUJBQW1CLEdBQWxDO0FBQ0Esb0JBQUksU0FBUyxtQkFBbUIsR0FBaEM7QUFDQSx1QkFBTztBQUNILHVCQUFHLENBREE7QUFFSCx3QkFBSSxRQUZEO0FBR0gsd0JBQUk7QUFIRCxpQkFBUDtBQU1ILGFBWEQ7O0FBYUEsZ0JBQUksVUFBVSxDQUFDLFFBQVEsQ0FBUixJQUFXLFFBQVEsQ0FBUixDQUFaLElBQXdCLENBQXRDOzs7QUFHQSxnQkFBSSx1QkFBdUIsQ0FBQyxRQUFRLENBQVIsQ0FBRCxFQUFhLE9BQWIsRUFBdUIsUUFBUSxDQUFSLENBQXZCLEVBQW1DLEdBQW5DLENBQXVDLDBCQUF2QyxDQUEzQjs7QUFFQSxnQkFBSSxZQUFZLFNBQVosU0FBWTtBQUFBLHVCQUFLLENBQUw7QUFBQSxhQUFoQjs7QUFFQSxnQkFBSSxpQkFBa0IsR0FBRyxHQUFILENBQU8sSUFBUCxHQUNyQixXQURxQixDQUNULFVBRFMsRUFFakIsQ0FGaUIsQ0FFZjtBQUFBLHVCQUFLLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxLQUFaLENBQWtCLEVBQUUsQ0FBcEIsQ0FBTDtBQUFBLGFBRmUsRUFHakIsRUFIaUIsQ0FHZDtBQUFBLHVCQUFLLFVBQVUsS0FBSyxJQUFMLENBQVUsQ0FBVixDQUFZLEtBQVosQ0FBa0IsRUFBRSxFQUFwQixDQUFWLENBQUw7QUFBQSxhQUhjLEVBSWpCLEVBSmlCLENBSWQ7QUFBQSx1QkFBSyxVQUFVLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxLQUFaLENBQWtCLEVBQUUsRUFBcEIsQ0FBVixDQUFMO0FBQUEsYUFKYyxDQUF0Qjs7QUFNQSxtQkFBTztBQUNILHNCQUFLLGNBREY7QUFFSCx3QkFBTztBQUZKLGFBQVA7QUFJSDs7OytCQUVNLE8sRUFBUTtBQUNYLHlGQUFhLE9BQWI7QUFDQSxpQkFBSyxxQkFBTDtBQUVIOzs7Z0RBRXVCO0FBQ3BCLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLDJCQUEyQixLQUFLLFdBQUwsQ0FBaUIsc0JBQWpCLENBQS9CO0FBQ0EsZ0JBQUksOEJBQThCLE9BQUssd0JBQXZDOztBQUVBLGdCQUFJLGFBQWEsS0FBSyxXQUFMLENBQWlCLE1BQWpCLENBQWpCOztBQUVBLGdCQUFJLHNCQUFzQixLQUFLLElBQUwsQ0FBVSxjQUFWLENBQXlCLDJCQUF6QixFQUFzRCxNQUFJLEtBQUssa0JBQS9ELENBQTFCO0FBQ0EsZ0JBQUksMEJBQTBCLG9CQUFvQixjQUFwQixDQUFtQyxVQUFuQyxFQUN6QixJQUR5QixDQUNwQixJQURvQixFQUNkLFVBRGMsQ0FBOUI7O0FBSUEsb0NBQXdCLGNBQXhCLENBQXVDLE1BQXZDLEVBQ0ssSUFETCxDQUNVLE9BRFYsRUFDbUIsS0FBSyxJQUFMLENBQVUsS0FEN0IsRUFFSyxJQUZMLENBRVUsUUFGVixFQUVvQixLQUFLLElBQUwsQ0FBVSxNQUY5QixFQUdLLElBSEwsQ0FHVSxHQUhWLEVBR2UsQ0FIZixFQUlLLElBSkwsQ0FJVSxHQUpWLEVBSWUsQ0FKZjs7QUFNQSxnQ0FBb0IsSUFBcEIsQ0FBeUIsV0FBekIsRUFBc0MsVUFBQyxDQUFELEVBQUcsQ0FBSDtBQUFBLHVCQUFTLFVBQVEsVUFBUixHQUFtQixHQUE1QjtBQUFBLGFBQXRDOztBQUVBLGdCQUFJLGtCQUFrQixLQUFLLFdBQUwsQ0FBaUIsWUFBakIsQ0FBdEI7QUFDQSxnQkFBSSxzQkFBc0IsS0FBSyxXQUFMLENBQWlCLFlBQWpCLENBQTFCO0FBQ0EsZ0JBQUkscUJBQXFCLE9BQUssZUFBOUI7QUFDQSxnQkFBSSxhQUFhLG9CQUFvQixTQUFwQixDQUE4QixrQkFBOUIsRUFDWixJQURZLENBQ1AsS0FBSyxJQUFMLENBQVUsV0FESCxFQUNnQixVQUFDLENBQUQsRUFBRyxDQUFIO0FBQUEsdUJBQVEsRUFBRSxLQUFWO0FBQUEsYUFEaEIsQ0FBakI7O0FBR0EsZ0JBQUksbUJBQW1CLFdBQVcsS0FBWCxHQUFtQixjQUFuQixDQUFrQyxrQkFBbEMsQ0FBdkI7QUFDQSxnQkFBSSxZQUFZLEtBQUssV0FBTCxDQUFpQixNQUFqQixDQUFoQjtBQUNBLDZCQUVLLE1BRkwsQ0FFWSxNQUZaLEVBR0ssSUFITCxDQUdVLE9BSFYsRUFHbUIsU0FIbkIsRUFJSyxJQUpMLENBSVUsaUJBSlYsRUFJNkIsaUJBSjdCOzs7OztBQVNBLGdCQUFJLE9BQU8sV0FBVyxNQUFYLENBQWtCLFVBQVEsU0FBMUIsRUFDTixLQURNLENBQ0EsUUFEQSxFQUNVO0FBQUEsdUJBQUssRUFBRSxLQUFQO0FBQUEsYUFEVixDQUFYOzs7Ozs7QUFRQSxnQkFBSSxRQUFRLElBQVo7QUFDQSxnQkFBSSxLQUFLLGlCQUFMLEVBQUosRUFBOEI7QUFDMUIsd0JBQVEsS0FBSyxVQUFMLEVBQVI7QUFDSDs7QUFFRCxrQkFBTSxJQUFOLENBQVcsR0FBWCxFQUFnQjtBQUFBLHVCQUFLLEVBQUUsSUFBRixDQUFPLEVBQUUsVUFBVCxDQUFMO0FBQUEsYUFBaEI7O0FBR0EsNkJBQ0ssTUFETCxDQUNZLE1BRFosRUFFSyxJQUZMLENBRVUsT0FGVixFQUVtQixtQkFGbkIsRUFHSyxJQUhMLENBR1UsaUJBSFYsRUFHNkIsaUJBSDdCLEVBSUssS0FKTCxDQUlXLFNBSlgsRUFJc0IsS0FKdEI7O0FBUUEsZ0JBQUksT0FBTyxXQUFXLE1BQVgsQ0FBa0IsVUFBUSxtQkFBMUIsQ0FBWDs7QUFFQSxnQkFBSSxRQUFRLElBQVo7QUFDQSxnQkFBSSxLQUFLLGlCQUFMLEVBQUosRUFBOEI7QUFDMUIsd0JBQVEsS0FBSyxVQUFMLEVBQVI7QUFDSDtBQUNELGtCQUFNLElBQU4sQ0FBVyxHQUFYLEVBQWdCO0FBQUEsdUJBQUssRUFBRSxVQUFGLENBQWEsSUFBYixDQUFrQixFQUFFLFVBQUYsQ0FBYSxNQUEvQixDQUFMO0FBQUEsYUFBaEI7QUFDQSxrQkFBTSxLQUFOLENBQVksTUFBWixFQUFvQjtBQUFBLHVCQUFLLEVBQUUsS0FBUDtBQUFBLGFBQXBCO0FBQ0EsdUJBQVcsSUFBWCxHQUFrQixNQUFsQjtBQUVIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNyU0w7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0lBRWEsdUIsV0FBQSx1Qjs7Ozs7OztBQTZCVCxxQ0FBWSxNQUFaLEVBQW1CO0FBQUE7O0FBQUE7O0FBQUEsY0EzQm5CLFFBMkJtQixHQTNCVCxNQUFLLGNBQUwsR0FBb0Isb0JBMkJYO0FBQUEsY0ExQm5CLElBMEJtQixHQTFCYixHQTBCYTtBQUFBLGNBekJuQixPQXlCbUIsR0F6QlYsRUF5QlU7QUFBQSxjQXhCbkIsS0F3Qm1CLEdBeEJaLElBd0JZO0FBQUEsY0F2Qm5CLE1BdUJtQixHQXZCWCxJQXVCVztBQUFBLGNBdEJuQixXQXNCbUIsR0F0Qk4sSUFzQk07QUFBQSxjQXJCbkIsS0FxQm1CLEdBckJaLFNBcUJZO0FBQUEsY0FwQm5CLENBb0JtQixHQXBCakIsRTtBQUNFLG9CQUFRLFFBRFY7QUFFRSxtQkFBTztBQUZULFNBb0JpQjtBQUFBLGNBaEJuQixDQWdCbUIsR0FoQmpCLEU7QUFDRSxvQkFBUSxNQURWO0FBRUUsbUJBQU87QUFGVCxTQWdCaUI7QUFBQSxjQVpuQixNQVltQixHQVpaO0FBQ0gsaUJBQUssU0FERixFO0FBRUgsMkJBQWUsS0FGWixFO0FBR0gsbUJBQU8sZUFBQyxDQUFELEVBQUksR0FBSjtBQUFBLHVCQUFZLEVBQUUsR0FBRixDQUFaO0FBQUEsYUFISixFO0FBSUgsbUJBQU87QUFKSixTQVlZO0FBQUEsY0FObkIsU0FNbUIsR0FOUjtBQUNQLG9CQUFRLEVBREQsRTtBQUVQLGtCQUFNLEVBRkMsRTtBQUdQLG1CQUFPLGVBQUMsQ0FBRCxFQUFJLFdBQUo7QUFBQSx1QkFBb0IsRUFBRSxXQUFGLENBQXBCO0FBQUEsYTtBQUhBLFNBTVE7O0FBRWYscUJBQU0sVUFBTixRQUF1QixNQUF2QjtBQUZlO0FBR2xCLEs7Ozs7Ozs7SUFLUSxpQixXQUFBLGlCOzs7QUFDVCwrQkFBWSxtQkFBWixFQUFpQyxJQUFqQyxFQUF1QyxNQUF2QyxFQUErQztBQUFBOztBQUFBLG9HQUNyQyxtQkFEcUMsRUFDaEIsSUFEZ0IsRUFDVixJQUFJLHVCQUFKLENBQTRCLE1BQTVCLENBRFU7QUFFOUM7Ozs7a0NBRVMsTSxFQUFRO0FBQ2QsMEdBQXVCLElBQUksdUJBQUosQ0FBNEIsTUFBNUIsQ0FBdkI7QUFFSDs7O21DQUVVO0FBQ1A7O0FBRUEsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksU0FBUyxLQUFLLElBQUwsQ0FBVSxNQUF2QjtBQUNBLGdCQUFJLE9BQU8sS0FBSyxNQUFoQjtBQUNBLGlCQUFLLElBQUwsQ0FBVSxDQUFWLEdBQVksRUFBWjtBQUNBLGlCQUFLLElBQUwsQ0FBVSxDQUFWLEdBQVksRUFBWjtBQUNBLGlCQUFLLElBQUwsQ0FBVSxHQUFWLEdBQWM7QUFDVix1QkFBTyxJO0FBREcsYUFBZDs7QUFLQSxpQkFBSyxJQUFMLENBQVUsVUFBVixHQUF1QixLQUFLLFVBQTVCO0FBQ0EsZ0JBQUcsS0FBSyxJQUFMLENBQVUsVUFBYixFQUF3QjtBQUNwQix1QkFBTyxLQUFQLEdBQWUsS0FBSyxNQUFMLENBQVksS0FBWixHQUFvQixLQUFLLE1BQUwsQ0FBWSxLQUFoQyxHQUFzQyxLQUFLLE1BQUwsQ0FBWSxNQUFaLEdBQW1CLENBQXhFO0FBQ0g7O0FBRUQsaUJBQUssV0FBTDs7QUFFQSxpQkFBSyxJQUFMLENBQVUsSUFBVixHQUFpQixLQUFLLGFBQUwsRUFBakI7QUFDQSxpQkFBSyxjQUFMOztBQUVBLGlCQUFLLElBQUwsQ0FBVSxJQUFWLEdBQWlCLEtBQUssSUFBdEI7O0FBR0EsZ0JBQUksUUFBUSxLQUFLLEtBQWpCO0FBQ0EsZ0JBQUkscUJBQXFCLEtBQUssb0JBQUwsR0FBNEIscUJBQTVCLEVBQXpCO0FBQ0EsZ0JBQUksQ0FBQyxLQUFMLEVBQVk7QUFDUixvQkFBSSxXQUFXLE9BQU8sSUFBUCxHQUFjLE9BQU8sS0FBckIsR0FBNkIsS0FBSyxJQUFMLENBQVUsU0FBVixDQUFvQixNQUFwQixHQUEyQixLQUFLLElBQUwsQ0FBVSxJQUFqRjtBQUNBLHdCQUFRLEtBQUssR0FBTCxDQUFTLG1CQUFtQixLQUE1QixFQUFtQyxRQUFuQyxDQUFSO0FBRUg7QUFDRCxnQkFBSSxTQUFTLEtBQWI7QUFDQSxnQkFBSSxDQUFDLE1BQUwsRUFBYTtBQUNULHlCQUFTLG1CQUFtQixNQUE1QjtBQUNIOztBQUVELGlCQUFLLElBQUwsQ0FBVSxLQUFWLEdBQWtCLFFBQVEsT0FBTyxJQUFmLEdBQXNCLE9BQU8sS0FBL0M7QUFDQSxpQkFBSyxJQUFMLENBQVUsTUFBVixHQUFtQixTQUFTLE9BQU8sR0FBaEIsR0FBc0IsT0FBTyxNQUFoRDs7QUFLQSxnQkFBRyxLQUFLLEtBQUwsS0FBYSxTQUFoQixFQUEwQjtBQUN0QixxQkFBSyxLQUFMLEdBQWEsS0FBSyxJQUFMLENBQVUsSUFBVixHQUFpQixFQUE5QjtBQUNIOztBQUlELGlCQUFLLE1BQUw7QUFDQSxpQkFBSyxNQUFMOztBQUVBLG1CQUFPLElBQVA7QUFFSDs7O3NDQUVhO0FBQ1YsZ0JBQUksT0FBSyxJQUFUO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLE1BQWhCO0FBQ0EsaUJBQUssSUFBTCxDQUFVLFVBQVYsR0FBdUI7QUFBQSx1QkFBSyxLQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLENBQWxCLEVBQXFCLEtBQUssTUFBTCxDQUFZLEdBQWpDLENBQUw7QUFBQSxhQUF2QjtBQUNBLGdCQUFHLEtBQUssR0FBTCxDQUFTLGVBQVosRUFBNEI7QUFDeEIscUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxhQUFkLEdBQThCLEdBQUcsS0FBSCxDQUFTLEtBQUssR0FBTCxDQUFTLGVBQWxCLEdBQTlCO0FBQ0g7QUFDRCxnQkFBSSxhQUFhLEtBQUssR0FBTCxDQUFTLEtBQTFCO0FBQ0EsZ0JBQUcsVUFBSCxFQUFjO0FBQ1YscUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxVQUFkLEdBQTJCLFVBQTNCOztBQUVBLG9CQUFJLE9BQU8sVUFBUCxLQUFzQixRQUF0QixJQUFrQyxzQkFBc0IsTUFBNUQsRUFBbUU7QUFDL0QseUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxLQUFkLEdBQXNCLFVBQXRCO0FBQ0gsaUJBRkQsTUFFTSxJQUFHLEtBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxhQUFqQixFQUErQjtBQUNqQyx3QkFBSSxTQUFTLE9BQU8sbUJBQVAsQ0FBMkIsR0FBRyxHQUFILENBQU8sS0FBSyxJQUFaLEVBQWtCO0FBQUEsK0JBQUssS0FBSyxJQUFMLENBQVUsR0FBVixDQUFjLFVBQWQsQ0FBeUIsSUFBekIsQ0FBOEIsSUFBOUIsRUFBbUMsQ0FBbkMsQ0FBTDtBQUFBLHFCQUFsQixFQUE4RCxHQUE5RCxDQUEzQixDQUFiO0FBQ0EseUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxhQUFkLENBQTRCLE1BQTVCLENBQW1DLE1BQW5DO0FBQ0EseUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxLQUFkLEdBQXNCO0FBQUEsK0JBQU0sS0FBSyxJQUFMLENBQVUsR0FBVixDQUFjLGFBQWQsQ0FBNEIsS0FBSyxJQUFMLENBQVUsR0FBVixDQUFjLFVBQWQsQ0FBeUIsSUFBekIsQ0FBOEIsSUFBOUIsRUFBbUMsQ0FBbkMsQ0FBNUIsQ0FBTjtBQUFBLHFCQUF0QjtBQUNIO0FBQ0o7QUFDSjs7O3dDQUVjO0FBQUE7O0FBQ1gsZ0JBQUcsQ0FBQyxLQUFLLGFBQVQsRUFBdUI7QUFDbkIsdUJBQU8sS0FBSyxJQUFaO0FBQ0g7O0FBRUQsZ0JBQUksU0FBUyxLQUFLLElBQUwsQ0FBVSxNQUFWLENBQWlCO0FBQUEsdUJBQUssT0FBSyxhQUFMLENBQW1CLE9BQW5CLENBQTJCLE9BQUssSUFBTCxDQUFVLFVBQVYsQ0FBcUIsQ0FBckIsQ0FBM0IsSUFBb0QsQ0FBQyxDQUExRDtBQUFBLGFBQWpCLENBQWI7QUFDQSxvQkFBUSxHQUFSLENBQVksT0FBTyxNQUFuQjtBQUNBLG1CQUFPLE1BQVA7QUFDSDs7O3lDQUVnQjtBQUNiLGdCQUFJLGdCQUFnQixLQUFLLE1BQUwsQ0FBWSxTQUFoQzs7QUFFQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxpQkFBSyxnQkFBTCxHQUF3QixFQUF4QjtBQUNBLGlCQUFLLFNBQUwsR0FBaUIsY0FBYyxJQUEvQjtBQUNBLGdCQUFHLENBQUMsS0FBSyxTQUFOLElBQW1CLENBQUMsS0FBSyxTQUFMLENBQWUsTUFBdEMsRUFBNkM7QUFDekMscUJBQUssU0FBTCxHQUFpQixhQUFNLGNBQU4sQ0FBcUIsSUFBckIsRUFBMkIsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixHQUE5QyxFQUFtRCxLQUFLLE1BQUwsQ0FBWSxhQUEvRCxDQUFqQjtBQUNIOztBQUVELGlCQUFLLE1BQUwsR0FBYyxFQUFkO0FBQ0EsaUJBQUssZUFBTCxHQUF1QixFQUF2QjtBQUNBLGlCQUFLLFNBQUwsQ0FBZSxPQUFmLENBQXVCLFVBQUMsV0FBRCxFQUFjLEtBQWQsRUFBd0I7QUFDM0MscUJBQUssZ0JBQUwsQ0FBc0IsV0FBdEIsSUFBcUMsR0FBRyxNQUFILENBQVUsSUFBVixFQUFnQixVQUFTLENBQVQsRUFBWTtBQUFFLDJCQUFPLGNBQWMsS0FBZCxDQUFvQixDQUFwQixFQUF1QixXQUF2QixDQUFQO0FBQTRDLGlCQUExRSxDQUFyQztBQUNBLG9CQUFJLFFBQVEsV0FBWjtBQUNBLG9CQUFHLGNBQWMsTUFBZCxJQUF3QixjQUFjLE1BQWQsQ0FBcUIsTUFBckIsR0FBNEIsS0FBdkQsRUFBNkQ7O0FBRXpELDRCQUFRLGNBQWMsTUFBZCxDQUFxQixLQUFyQixDQUFSO0FBQ0g7QUFDRCxxQkFBSyxNQUFMLENBQVksSUFBWixDQUFpQixLQUFqQjtBQUNBLHFCQUFLLGVBQUwsQ0FBcUIsV0FBckIsSUFBb0MsS0FBcEM7QUFDSCxhQVREOztBQVdBLG9CQUFRLEdBQVIsQ0FBWSxLQUFLLGVBQWpCOztBQUVBLGlCQUFLLFFBQUwsR0FBZ0IsRUFBaEI7QUFDSDs7O2lDQUVROztBQUVMLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLElBQUksS0FBSyxDQUFiO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLE1BQWhCOztBQUVBLGNBQUUsS0FBRixHQUFVLEtBQUssU0FBTCxDQUFlLEtBQXpCO0FBQ0EsY0FBRSxLQUFGLEdBQVUsR0FBRyxLQUFILENBQVMsS0FBSyxDQUFMLENBQU8sS0FBaEIsSUFBeUIsS0FBekIsQ0FBK0IsQ0FBQyxLQUFLLE9BQUwsR0FBZSxDQUFoQixFQUFtQixLQUFLLElBQUwsR0FBWSxLQUFLLE9BQUwsR0FBZSxDQUE5QyxDQUEvQixDQUFWO0FBQ0EsY0FBRSxHQUFGLEdBQVEsVUFBQyxDQUFELEVBQUksUUFBSjtBQUFBLHVCQUFpQixFQUFFLEtBQUYsQ0FBUSxFQUFFLEtBQUYsQ0FBUSxDQUFSLEVBQVcsUUFBWCxDQUFSLENBQWpCO0FBQUEsYUFBUjtBQUNBLGNBQUUsSUFBRixHQUFTLEdBQUcsR0FBSCxDQUFPLElBQVAsR0FBYyxLQUFkLENBQW9CLEVBQUUsS0FBdEIsRUFBNkIsTUFBN0IsQ0FBb0MsS0FBSyxDQUFMLENBQU8sTUFBM0MsRUFBbUQsS0FBbkQsQ0FBeUQsS0FBSyxLQUE5RCxDQUFUO0FBQ0EsY0FBRSxJQUFGLENBQU8sUUFBUCxDQUFnQixLQUFLLElBQUwsR0FBWSxLQUFLLFNBQUwsQ0FBZSxNQUEzQztBQUVIOzs7aUNBRVE7O0FBRUwsZ0JBQUksT0FBTyxLQUFLLElBQWhCO0FBQ0EsZ0JBQUksSUFBSSxLQUFLLENBQWI7QUFDQSxnQkFBSSxPQUFPLEtBQUssTUFBaEI7O0FBRUEsY0FBRSxLQUFGLEdBQVUsS0FBSyxTQUFMLENBQWUsS0FBekI7QUFDQSxjQUFFLEtBQUYsR0FBVSxHQUFHLEtBQUgsQ0FBUyxLQUFLLENBQUwsQ0FBTyxLQUFoQixJQUF5QixLQUF6QixDQUErQixDQUFFLEtBQUssSUFBTCxHQUFZLEtBQUssT0FBTCxHQUFlLENBQTdCLEVBQWdDLEtBQUssT0FBTCxHQUFlLENBQS9DLENBQS9CLENBQVY7QUFDQSxjQUFFLEdBQUYsR0FBUSxVQUFDLENBQUQsRUFBSSxRQUFKO0FBQUEsdUJBQWlCLEVBQUUsS0FBRixDQUFRLEVBQUUsS0FBRixDQUFRLENBQVIsRUFBVyxRQUFYLENBQVIsQ0FBakI7QUFBQSxhQUFSO0FBQ0EsY0FBRSxJQUFGLEdBQVEsR0FBRyxHQUFILENBQU8sSUFBUCxHQUFjLEtBQWQsQ0FBb0IsRUFBRSxLQUF0QixFQUE2QixNQUE3QixDQUFvQyxLQUFLLENBQUwsQ0FBTyxNQUEzQyxFQUFtRCxLQUFuRCxDQUF5RCxLQUFLLEtBQTlELENBQVI7QUFDQSxjQUFFLElBQUYsQ0FBTyxRQUFQLENBQWdCLENBQUMsS0FBSyxJQUFOLEdBQWEsS0FBSyxTQUFMLENBQWUsTUFBNUM7QUFDSDs7OytCQUVPLE8sRUFBUztBQUNiLGdHQUFhLE9BQWI7O0FBRUEsZ0JBQUksT0FBTSxJQUFWO0FBQ0EsZ0JBQUksSUFBSSxLQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLE1BQTVCO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLE1BQWhCOztBQUVBLGdCQUFJLFlBQVksS0FBSyxXQUFMLENBQWlCLE1BQWpCLENBQWhCO0FBQ0EsZ0JBQUksYUFBYSxZQUFVLElBQTNCO0FBQ0EsZ0JBQUksYUFBYSxZQUFVLElBQTNCOztBQUVBLGdCQUFJLGdCQUFnQixPQUFLLFVBQUwsR0FBZ0IsR0FBaEIsR0FBb0IsU0FBeEM7QUFDQSxnQkFBSSxnQkFBZ0IsT0FBSyxVQUFMLEdBQWdCLEdBQWhCLEdBQW9CLFNBQXhDOztBQUVBLGdCQUFJLGdCQUFnQixLQUFLLFdBQUwsQ0FBaUIsV0FBakIsQ0FBcEI7QUFDQSxpQkFBSyxJQUFMLENBQVUsU0FBVixDQUFvQixhQUFwQixFQUNLLElBREwsQ0FDVSxLQUFLLElBQUwsQ0FBVSxTQURwQixFQUVLLEtBRkwsR0FFYSxjQUZiLENBRTRCLGFBRjVCLEVBR0ssT0FITCxDQUdhLGFBSGIsRUFHNEIsQ0FBQyxLQUFLLE1BSGxDLEVBSUssSUFKTCxDQUlVLFdBSlYsRUFJdUIsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFVLGVBQWUsQ0FBQyxJQUFJLENBQUosR0FBUSxDQUFULElBQWMsS0FBSyxJQUFMLENBQVUsSUFBdkMsR0FBOEMsS0FBeEQ7QUFBQSxhQUp2QixFQUtLLElBTEwsQ0FLVSxVQUFTLENBQVQsRUFBWTtBQUFFLHFCQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksS0FBWixDQUFrQixNQUFsQixDQUF5QixLQUFLLElBQUwsQ0FBVSxnQkFBVixDQUEyQixDQUEzQixDQUF6QixFQUF5RCxHQUFHLE1BQUgsQ0FBVSxJQUFWLEVBQWdCLElBQWhCLENBQXFCLEtBQUssSUFBTCxDQUFVLENBQVYsQ0FBWSxJQUFqQztBQUF5QyxhQUwxSDs7QUFPQSxpQkFBSyxJQUFMLENBQVUsU0FBVixDQUFvQixhQUFwQixFQUNLLElBREwsQ0FDVSxLQUFLLElBQUwsQ0FBVSxTQURwQixFQUVLLEtBRkwsR0FFYSxjQUZiLENBRTRCLGFBRjVCLEVBR0ssT0FITCxDQUdhLGFBSGIsRUFHNEIsQ0FBQyxLQUFLLE1BSGxDLEVBSUssSUFKTCxDQUlVLFdBSlYsRUFJdUIsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLHVCQUFVLGlCQUFpQixJQUFJLEtBQUssSUFBTCxDQUFVLElBQS9CLEdBQXNDLEdBQWhEO0FBQUEsYUFKdkIsRUFLSyxJQUxMLENBS1UsVUFBUyxDQUFULEVBQVk7QUFBRSxxQkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLEtBQVosQ0FBa0IsTUFBbEIsQ0FBeUIsS0FBSyxJQUFMLENBQVUsZ0JBQVYsQ0FBMkIsQ0FBM0IsQ0FBekIsRUFBeUQsR0FBRyxNQUFILENBQVUsSUFBVixFQUFnQixJQUFoQixDQUFxQixLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksSUFBakM7QUFBeUMsYUFMMUg7O0FBT0EsZ0JBQUksWUFBYSxLQUFLLFdBQUwsQ0FBaUIsTUFBakIsQ0FBakI7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBTCxDQUFVLFNBQVYsQ0FBb0IsTUFBSSxTQUF4QixFQUNOLElBRE0sQ0FDRCxLQUFLLEtBQUwsQ0FBVyxLQUFYLENBQWlCLEtBQUssSUFBTCxDQUFVLFNBQTNCLEVBQXNDLEtBQUssSUFBTCxDQUFVLFNBQWhELENBREMsQ0FBWDs7QUFHQSxpQkFBSyxLQUFMLEdBQWEsY0FBYixDQUE0QixPQUFLLFNBQWpDLEVBQTRDLE1BQTVDLENBQW1EO0FBQUEsdUJBQUssRUFBRSxDQUFGLEtBQVEsRUFBRSxDQUFmO0FBQUEsYUFBbkQsRUFDSyxNQURMLENBQ1ksTUFEWjs7QUFHQSxpQkFBSyxJQUFMLENBQVUsV0FBVixFQUF1QjtBQUFBLHVCQUFLLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBTixHQUFVLENBQVgsSUFBZ0IsS0FBSyxJQUFMLENBQVUsSUFBekMsR0FBZ0QsR0FBaEQsR0FBc0QsRUFBRSxDQUFGLEdBQU0sS0FBSyxJQUFMLENBQVUsSUFBdEUsR0FBNkUsR0FBbEY7QUFBQSxhQUF2Qjs7QUFFQSxnQkFBRyxLQUFLLEtBQVIsRUFBYztBQUNWLHFCQUFLLFNBQUwsQ0FBZSxJQUFmO0FBQ0g7O0FBRUQsaUJBQUssSUFBTCxDQUFVLFdBQVY7OztBQUdBLGlCQUFLLE1BQUwsQ0FBWSxNQUFaLEVBQ0ssSUFETCxDQUNVLEdBRFYsRUFDZSxLQUFLLE9BRHBCLEVBRUssSUFGTCxDQUVVLEdBRlYsRUFFZSxLQUFLLE9BRnBCLEVBR0ssSUFITCxDQUdVLElBSFYsRUFHZ0IsT0FIaEIsRUFJSyxJQUpMLENBSVc7QUFBQSx1QkFBSyxLQUFLLElBQUwsQ0FBVSxlQUFWLENBQTBCLEVBQUUsQ0FBNUIsQ0FBTDtBQUFBLGFBSlg7O0FBU0EscUJBQVMsV0FBVCxDQUFxQixDQUFyQixFQUF3QjtBQUNwQix3QkFBUSxHQUFSLENBQVksYUFBWjtBQUNBLG9CQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLHFCQUFLLFFBQUwsQ0FBYyxJQUFkLENBQW1CLENBQW5CO0FBQ0Esb0JBQUksT0FBTyxHQUFHLE1BQUgsQ0FBVSxJQUFWLENBQVg7O0FBRUEscUJBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxNQUFiLENBQW9CLEtBQUssZ0JBQUwsQ0FBc0IsRUFBRSxDQUF4QixDQUFwQjtBQUNBLHFCQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsTUFBYixDQUFvQixLQUFLLGdCQUFMLENBQXNCLEVBQUUsQ0FBeEIsQ0FBcEI7O0FBRUEsb0JBQUksYUFBYyxLQUFLLFdBQUwsQ0FBaUIsT0FBakIsQ0FBbEI7QUFDQSxxQkFBSyxjQUFMLENBQW9CLFVBQVEsVUFBNUIsRUFDSyxJQURMLENBQ1UsT0FEVixFQUNtQixVQURuQixFQUVLLElBRkwsQ0FFVSxHQUZWLEVBRWUsS0FBSyxPQUFMLEdBQWUsQ0FGOUIsRUFHSyxJQUhMLENBR1UsR0FIVixFQUdlLEtBQUssT0FBTCxHQUFlLENBSDlCLEVBSUssSUFKTCxDQUlVLE9BSlYsRUFJbUIsS0FBSyxJQUFMLEdBQVksS0FBSyxPQUpwQyxFQUtLLElBTEwsQ0FLVSxRQUxWLEVBS29CLEtBQUssSUFBTCxHQUFZLEtBQUssT0FMckM7O0FBUUEsa0JBQUUsTUFBRixHQUFXLFlBQVc7O0FBRWxCLHdCQUFJLFVBQVUsSUFBZDtBQUNBLHdCQUFJLE9BQU8sS0FBSyxTQUFMLENBQWUsUUFBZixFQUNOLElBRE0sQ0FDRCxLQUFLLElBQUwsQ0FBVSxJQURULENBQVg7O0FBR0EseUJBQUssS0FBTCxHQUFhLE1BQWIsQ0FBb0IsUUFBcEI7O0FBRUEsd0JBQUksUUFBUSxJQUFaO0FBQ0Esd0JBQUksS0FBSyxpQkFBTCxFQUFKLEVBQThCO0FBQzFCLGdDQUFRLEtBQUssVUFBTCxFQUFSO0FBQ0g7O0FBRUQsMEJBQU0sSUFBTixDQUFXLElBQVgsRUFBaUIsVUFBQyxDQUFEO0FBQUEsK0JBQU8sS0FBSyxDQUFMLENBQU8sR0FBUCxDQUFXLENBQVgsRUFBYyxRQUFRLENBQXRCLENBQVA7QUFBQSxxQkFBakIsRUFDSyxJQURMLENBQ1UsSUFEVixFQUNnQixVQUFDLENBQUQ7QUFBQSwrQkFBTyxLQUFLLENBQUwsQ0FBTyxHQUFQLENBQVcsQ0FBWCxFQUFjLFFBQVEsQ0FBdEIsQ0FBUDtBQUFBLHFCQURoQixFQUVLLElBRkwsQ0FFVSxHQUZWLEVBRWUsS0FBSyxNQUFMLENBQVksR0FBWixDQUFnQixNQUYvQjs7QUFJQSx3QkFBSSxLQUFLLEdBQUwsQ0FBUyxLQUFiLEVBQW9CO0FBQ2hCLDhCQUFNLEtBQU4sQ0FBWSxNQUFaLEVBQW9CLEtBQUssR0FBTCxDQUFTLEtBQTdCO0FBQ0g7O0FBRUQsd0JBQUcsS0FBSyxPQUFSLEVBQWdCO0FBQ1osNkJBQUssRUFBTCxDQUFRLFdBQVIsRUFBcUIsVUFBQyxDQUFELEVBQU87QUFDeEIsaUNBQUssT0FBTCxDQUFhLFVBQWIsR0FDSyxRQURMLENBQ2MsR0FEZCxFQUVLLEtBRkwsQ0FFVyxTQUZYLEVBRXNCLEVBRnRCO0FBR0EsZ0NBQUksT0FBTyxNQUFNLEtBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxDQUFiLEVBQWdCLFFBQVEsQ0FBeEIsQ0FBTixHQUFtQyxJQUFuQyxHQUF5QyxLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsQ0FBYixFQUFnQixRQUFRLENBQXhCLENBQXpDLEdBQXNFLEdBQWpGO0FBQ0EsaUNBQUssT0FBTCxDQUFhLElBQWIsQ0FBa0IsSUFBbEIsRUFDSyxLQURMLENBQ1csTUFEWCxFQUNvQixHQUFHLEtBQUgsQ0FBUyxLQUFULEdBQWlCLENBQWxCLEdBQXVCLElBRDFDLEVBRUssS0FGTCxDQUVXLEtBRlgsRUFFbUIsR0FBRyxLQUFILENBQVMsS0FBVCxHQUFpQixFQUFsQixHQUF3QixJQUYxQzs7QUFJQSxnQ0FBSSxRQUFRLEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBbUIsS0FBbkIsQ0FBeUIsQ0FBekIsQ0FBWjtBQUNBLGdDQUFHLFNBQVMsVUFBUSxDQUFwQixFQUF1QjtBQUNuQix3Q0FBTSxPQUFOO0FBQ0Esb0NBQUksUUFBUSxLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLEtBQS9CO0FBQ0Esb0NBQUcsS0FBSCxFQUFTO0FBQ0wsNENBQU0sUUFBTSxJQUFaO0FBQ0g7QUFDRCx3Q0FBTSxLQUFOO0FBQ0g7QUFDRCxpQ0FBSyxPQUFMLENBQWEsSUFBYixDQUFrQixJQUFsQixFQUNLLEtBREwsQ0FDVyxNQURYLEVBQ29CLEdBQUcsS0FBSCxDQUFTLEtBQVQsR0FBaUIsQ0FBbEIsR0FBdUIsSUFEMUMsRUFFSyxLQUZMLENBRVcsS0FGWCxFQUVtQixHQUFHLEtBQUgsQ0FBUyxLQUFULEdBQWlCLEVBQWxCLEdBQXdCLElBRjFDO0FBR0gseUJBckJELEVBc0JLLEVBdEJMLENBc0JRLFVBdEJSLEVBc0JvQixVQUFDLENBQUQsRUFBTTtBQUNsQixpQ0FBSyxPQUFMLENBQWEsVUFBYixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsQ0FGdEI7QUFHSCx5QkExQkw7QUEyQkg7O0FBRUQseUJBQUssSUFBTCxHQUFZLE1BQVo7QUFDSCxpQkFwREQ7QUFxREEsa0JBQUUsTUFBRjtBQUVIOztBQUdELGlCQUFLLFlBQUw7QUFDSDs7O2tDQUVTLEksRUFBTTtBQUNaLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLFFBQVEsR0FBRyxHQUFILENBQU8sS0FBUCxHQUNQLENBRE8sQ0FDTCxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksS0FEUCxFQUVQLENBRk8sQ0FFTCxLQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksS0FGUCxFQUdQLEVBSE8sQ0FHSixZQUhJLEVBR1UsVUFIVixFQUlQLEVBSk8sQ0FJSixPQUpJLEVBSUssU0FKTCxFQUtQLEVBTE8sQ0FLSixVQUxJLEVBS1EsUUFMUixDQUFaOztBQU9BLGlCQUFLLE1BQUwsQ0FBWSxHQUFaLEVBQWlCLElBQWpCLENBQXNCLEtBQXRCOztBQUdBLGdCQUFJLFNBQUo7OztBQUdBLHFCQUFTLFVBQVQsQ0FBb0IsQ0FBcEIsRUFBdUI7QUFDbkIsb0JBQUksY0FBYyxJQUFsQixFQUF3QjtBQUNwQix1QkFBRyxNQUFILENBQVUsU0FBVixFQUFxQixJQUFyQixDQUEwQixNQUFNLEtBQU4sRUFBMUI7QUFDQSx5QkFBSyxJQUFMLENBQVUsQ0FBVixDQUFZLEtBQVosQ0FBa0IsTUFBbEIsQ0FBeUIsS0FBSyxJQUFMLENBQVUsZ0JBQVYsQ0FBMkIsRUFBRSxDQUE3QixDQUF6QjtBQUNBLHlCQUFLLElBQUwsQ0FBVSxDQUFWLENBQVksS0FBWixDQUFrQixNQUFsQixDQUF5QixLQUFLLElBQUwsQ0FBVSxnQkFBVixDQUEyQixFQUFFLENBQTdCLENBQXpCO0FBQ0EsZ0NBQVksSUFBWjtBQUNIO0FBQ0o7OztBQUdELHFCQUFTLFNBQVQsQ0FBbUIsQ0FBbkIsRUFBc0I7QUFDbEIsb0JBQUksSUFBSSxNQUFNLE1BQU4sRUFBUjtBQUNBLHFCQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLFFBQXBCLEVBQThCLE9BQTlCLENBQXNDLFFBQXRDLEVBQWdELFVBQVUsQ0FBVixFQUFhO0FBQ3pELDJCQUFPLEVBQUUsQ0FBRixFQUFLLENBQUwsSUFBVSxFQUFFLEVBQUUsQ0FBSixDQUFWLElBQW9CLEVBQUUsRUFBRSxDQUFKLElBQVMsRUFBRSxDQUFGLEVBQUssQ0FBTCxDQUE3QixJQUNBLEVBQUUsQ0FBRixFQUFLLENBQUwsSUFBVSxFQUFFLEVBQUUsQ0FBSixDQURWLElBQ29CLEVBQUUsRUFBRSxDQUFKLElBQVMsRUFBRSxDQUFGLEVBQUssQ0FBTCxDQURwQztBQUVILGlCQUhEO0FBSUg7O0FBRUQscUJBQVMsUUFBVCxHQUFvQjtBQUNoQixvQkFBSSxNQUFNLEtBQU4sRUFBSixFQUFtQixLQUFLLElBQUwsQ0FBVSxTQUFWLENBQW9CLFNBQXBCLEVBQStCLE9BQS9CLENBQXVDLFFBQXZDLEVBQWlELEtBQWpEO0FBQ3RCO0FBQ0o7Ozt1Q0FFYzs7QUFFWCxnQkFBSSxPQUFNLElBQVY7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7O0FBRUEsZ0JBQUksUUFBUSxLQUFLLEdBQUwsQ0FBUyxhQUFyQjs7QUFJQSxnQkFBRyxDQUFDLE1BQU0sTUFBTixFQUFELElBQW1CLE1BQU0sTUFBTixHQUFlLE1BQWYsR0FBc0IsQ0FBNUMsRUFBOEM7QUFDMUMscUJBQUssVUFBTCxHQUFrQixLQUFsQjtBQUNIOztBQUVELGdCQUFHLENBQUMsS0FBSyxVQUFULEVBQW9CO0FBQ2hCLG9CQUFHLEtBQUssTUFBTCxJQUFlLEtBQUssTUFBTCxDQUFZLFNBQTlCLEVBQXdDO0FBQ3BDLHlCQUFLLE1BQUwsQ0FBWSxTQUFaLENBQXNCLE1BQXRCO0FBQ0g7QUFDRDtBQUNIOztBQUdELGdCQUFJLFVBQVUsS0FBSyxJQUFMLENBQVUsS0FBVixHQUFrQixLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLE1BQW5EO0FBQ0EsZ0JBQUksVUFBVSxLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLE1BQWpDOztBQUVBLGlCQUFLLE1BQUwsR0FBYyxtQkFBVyxLQUFLLEdBQWhCLEVBQXFCLEtBQUssSUFBMUIsRUFBZ0MsS0FBaEMsRUFBdUMsT0FBdkMsRUFBZ0QsT0FBaEQsQ0FBZDs7QUFFQSxpQkFBSyxXQUFMLEdBQW1CLEtBQUssTUFBTCxDQUFZLEtBQVosR0FDZCxVQURjLENBQ0gsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixVQURoQixFQUVkLE1BRmMsQ0FFUCxVQUZPLEVBR2QsS0FIYyxDQUdSLEtBSFEsQ0FBbkI7O0FBTUEsaUJBQUssV0FBTCxDQUFpQixFQUFqQixDQUFvQixXQUFwQixFQUFpQztBQUFBLHVCQUFJLEtBQUssaUJBQUwsQ0FBdUIsQ0FBdkIsQ0FBSjtBQUFBLGFBQWpDOztBQUVBLGlCQUFLLE1BQUwsQ0FBWSxTQUFaLENBQ0ssSUFETCxDQUNVLEtBQUssV0FEZjtBQUVIOzs7MENBRWlCLFMsRUFBVTtBQUN4QixpQkFBSyxtQkFBTCxDQUF5QixTQUF6Qjs7QUFFQSxnQkFBSSxhQUFhLEtBQUssYUFBTCxDQUFtQixPQUFuQixDQUEyQixTQUEzQixJQUFzQyxDQUF2RDtBQUNBLGlCQUFLLElBQUwsQ0FBVSxNQUFWLENBQWlCLFNBQWpCLENBQTJCLFNBQTNCLENBQXFDLFFBQXJDLEVBQStDLElBQS9DLENBQW9ELFVBQVMsSUFBVCxFQUFjO0FBQzlELG9CQUFHLFFBQVEsU0FBWCxFQUFxQjtBQUNqQix1QkFBRyxNQUFILENBQVUsSUFBVixFQUFnQixPQUFoQixDQUF3QixjQUF4QixFQUF3QyxVQUF4QztBQUNIO0FBRUosYUFMRDs7QUFPQSxpQkFBSyxJQUFMO0FBQ0g7Ozs0Q0FFbUIsUyxFQUFXO0FBQzNCLGdCQUFJLENBQUMsS0FBSyxhQUFWLEVBQXlCO0FBQ3JCLHFCQUFLLGFBQUwsR0FBcUIsS0FBSyxJQUFMLENBQVUsR0FBVixDQUFjLGFBQWQsQ0FBNEIsTUFBNUIsR0FBcUMsS0FBckMsRUFBckI7QUFDSDtBQUNELGdCQUFJLFFBQVEsS0FBSyxhQUFMLENBQW1CLE9BQW5CLENBQTJCLFNBQTNCLENBQVo7O0FBRUEsZ0JBQUksUUFBUSxDQUFaLEVBQWU7QUFDWCxxQkFBSyxhQUFMLENBQW1CLElBQW5CLENBQXdCLFNBQXhCO0FBQ0gsYUFGRCxNQUVPO0FBQ0gscUJBQUssYUFBTCxDQUFtQixNQUFuQixDQUEwQixLQUExQixFQUFpQyxDQUFqQztBQUNIO0FBQ0o7OztnQ0FJTyxJLEVBQUs7QUFDVCxpR0FBYyxJQUFkO0FBQ0EsaUJBQUssYUFBTCxHQUFxQixJQUFyQjtBQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNyYkw7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0lBRWEsaUIsV0FBQSxpQjs7Ozs7QUFzQ1QsK0JBQVksTUFBWixFQUFtQjtBQUFBOztBQUFBOztBQUFBLGNBcENuQixRQW9DbUIsR0FwQ1QsTUFBSyxjQUFMLEdBQW9CLGFBb0NYO0FBQUEsY0FuQ25CLE1BbUNtQixHQW5DWCxLQW1DVztBQUFBLGNBbENuQixXQWtDbUIsR0FsQ04sSUFrQ007QUFBQSxjQWpDbkIsVUFpQ21CLEdBakNSLElBaUNRO0FBQUEsY0FoQ25CLE1BZ0NtQixHQWhDWjtBQUNILG1CQUFPLEVBREo7QUFFSCxvQkFBUSxFQUZMO0FBR0gsd0JBQVk7QUFIVCxTQWdDWTtBQUFBLGNBMUJuQixDQTBCbUIsR0ExQmpCLEU7QUFDRSxtQkFBTyxHQURULEU7QUFFRSxpQkFBSyxDQUZQO0FBR0UsbUJBQU8sZUFBQyxDQUFELEVBQUksR0FBSjtBQUFBLHVCQUFZLEVBQUUsR0FBRixDQUFaO0FBQUEsYUFIVCxFO0FBSUUsb0JBQVEsUUFKVjtBQUtFLG1CQUFPO0FBTFQsU0EwQmlCO0FBQUEsY0FuQm5CLENBbUJtQixHQW5CakIsRTtBQUNFLG1CQUFPLEdBRFQsRTtBQUVFLGlCQUFLLENBRlA7QUFHRSxtQkFBTyxlQUFDLENBQUQsRUFBSSxHQUFKO0FBQUEsdUJBQVksRUFBRSxHQUFGLENBQVo7QUFBQSxhQUhULEU7QUFJRSxvQkFBUSxNQUpWO0FBS0UsbUJBQU87QUFMVCxTQW1CaUI7QUFBQSxjQVpuQixNQVltQixHQVpaO0FBQ0gsaUJBQUssQ0FERjtBQUVILG1CQUFPLGVBQUMsQ0FBRCxFQUFJLEdBQUo7QUFBQSx1QkFBWSxFQUFFLEdBQUYsQ0FBWjtBQUFBLGFBRkosRTtBQUdILG1CQUFPO0FBSEosU0FZWTtBQUFBLGNBUG5CLEdBT21CLEdBUGI7QUFDRixvQkFBUSxDQUROO0FBRUYsbUJBQU87QUFBQSx1QkFBSyxNQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLENBQWxCLEVBQXFCLE1BQUssTUFBTCxDQUFZLEdBQWpDLENBQUw7QUFBQSxhQUZMLEU7QUFHRiw2QkFBaUI7QUFIZixTQU9hO0FBQUEsY0FGbkIsVUFFbUIsR0FGUCxJQUVPOzs7QUFLZixZQUFHLE1BQUgsRUFBVTtBQUNOLHlCQUFNLFVBQU4sUUFBdUIsTUFBdkI7QUFDSDs7QUFQYztBQVNsQixLOzs7Ozs7SUFHUSxXLFdBQUEsVzs7O0FBQ1QseUJBQVksbUJBQVosRUFBaUMsSUFBakMsRUFBdUMsTUFBdkMsRUFBK0M7QUFBQTs7QUFBQSw4RkFDckMsbUJBRHFDLEVBQ2hCLElBRGdCLEVBQ1YsSUFBSSxpQkFBSixDQUFzQixNQUF0QixDQURVO0FBRTlDOzs7O2tDQUVTLE0sRUFBTztBQUNiLG9HQUF1QixJQUFJLGlCQUFKLENBQXNCLE1BQXRCLENBQXZCO0FBQ0g7OzttQ0FFUztBQUNOO0FBQ0EsZ0JBQUksT0FBSyxJQUFUOztBQUVBLGdCQUFJLE9BQU8sS0FBSyxNQUFoQjs7QUFFQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixHQUFZLEVBQVo7QUFDQSxpQkFBSyxJQUFMLENBQVUsQ0FBVixHQUFZLEVBQVo7QUFDQSxpQkFBSyxJQUFMLENBQVUsR0FBVixHQUFjO0FBQ1YsdUJBQU8sSTtBQURHLGFBQWQ7O0FBS0EsaUJBQUssSUFBTCxDQUFVLFVBQVYsR0FBdUIsS0FBSyxVQUE1QjtBQUNBLGdCQUFHLEtBQUssSUFBTCxDQUFVLFVBQWIsRUFBd0I7QUFDcEIscUJBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsS0FBakIsR0FBeUIsS0FBSyxNQUFMLENBQVksS0FBWixHQUFvQixLQUFLLE1BQUwsQ0FBWSxLQUFoQyxHQUFzQyxLQUFLLE1BQUwsQ0FBWSxNQUFaLEdBQW1CLENBQWxGO0FBQ0g7O0FBR0QsaUJBQUssZUFBTDs7QUFHQSxpQkFBSyxXQUFMOztBQUVBLGlCQUFLLElBQUwsQ0FBVSxJQUFWLEdBQWlCLEtBQUssYUFBTCxFQUFqQjtBQUNBLGlCQUFLLE1BQUw7QUFDQSxpQkFBSyxNQUFMOztBQUlBLG1CQUFPLElBQVA7QUFDSDs7O3NDQUVhO0FBQ1YsZ0JBQUksT0FBSyxJQUFUO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLE1BQWhCO0FBQ0EsaUJBQUssSUFBTCxDQUFVLFVBQVYsR0FBdUI7QUFBQSx1QkFBSyxLQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLENBQWxCLEVBQXFCLEtBQUssTUFBTCxDQUFZLEdBQWpDLENBQUw7QUFBQSxhQUF2QjtBQUNBLGdCQUFHLEtBQUssR0FBTCxDQUFTLGVBQVosRUFBNEI7QUFDeEIscUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxhQUFkLEdBQThCLEdBQUcsS0FBSCxDQUFTLEtBQUssR0FBTCxDQUFTLGVBQWxCLEdBQTlCO0FBQ0g7QUFDRCxnQkFBSSxhQUFhLEtBQUssR0FBTCxDQUFTLEtBQTFCO0FBQ0EsZ0JBQUcsVUFBSCxFQUFjO0FBQ1YscUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxVQUFkLEdBQTJCLFVBQTNCOztBQUVBLG9CQUFJLE9BQU8sVUFBUCxLQUFzQixRQUF0QixJQUFrQyxzQkFBc0IsTUFBNUQsRUFBbUU7QUFDL0QseUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxLQUFkLEdBQXNCLFVBQXRCO0FBQ0gsaUJBRkQsTUFFTSxJQUFHLEtBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxhQUFqQixFQUErQjtBQUNqQyx3QkFBSSxTQUFTLE9BQU8sbUJBQVAsQ0FBMkIsR0FBRyxHQUFILENBQU8sS0FBSyxJQUFaLEVBQWtCO0FBQUEsK0JBQUssS0FBSyxJQUFMLENBQVUsR0FBVixDQUFjLFVBQWQsQ0FBeUIsSUFBekIsQ0FBOEIsSUFBOUIsRUFBbUMsQ0FBbkMsQ0FBTDtBQUFBLHFCQUFsQixFQUE4RCxHQUE5RCxDQUEzQixDQUFiO0FBQ0EseUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxhQUFkLENBQTRCLE1BQTVCLENBQW1DLE1BQW5DO0FBQ0EseUJBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxLQUFkLEdBQXNCO0FBQUEsK0JBQU0sS0FBSyxJQUFMLENBQVUsR0FBVixDQUFjLGFBQWQsQ0FBNEIsS0FBSyxJQUFMLENBQVUsR0FBVixDQUFjLFVBQWQsQ0FBeUIsSUFBekIsQ0FBOEIsSUFBOUIsRUFBbUMsQ0FBbkMsQ0FBNUIsQ0FBTjtBQUFBLHFCQUF0QjtBQUNIO0FBQ0o7QUFDSjs7O3dDQUVjO0FBQUE7O0FBQ1gsZ0JBQUcsQ0FBQyxLQUFLLGFBQVQsRUFBdUI7QUFDbkIsdUJBQU8sS0FBSyxJQUFaO0FBQ0g7O0FBRUQsbUJBQU8sS0FBSyxJQUFMLENBQVUsTUFBVixDQUFpQjtBQUFBLHVCQUFLLE9BQUssYUFBTCxDQUFtQixPQUFuQixDQUEyQixPQUFLLElBQUwsQ0FBVSxVQUFWLENBQXFCLENBQXJCLENBQTNCLElBQW9ELENBQUMsQ0FBMUQ7QUFBQSxhQUFqQixDQUFQO0FBQ0g7OztpQ0FFTzs7QUFFSixnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxJQUFJLEtBQUssQ0FBYjtBQUNBLGdCQUFJLE9BQU8sS0FBSyxNQUFMLENBQVksQ0FBdkI7Ozs7Ozs7O0FBUUEsY0FBRSxLQUFGLEdBQVU7QUFBQSx1QkFBSyxLQUFLLEtBQUwsQ0FBVyxDQUFYLEVBQWMsS0FBSyxHQUFuQixDQUFMO0FBQUEsYUFBVjtBQUNBLGNBQUUsS0FBRixHQUFVLEdBQUcsS0FBSCxDQUFTLEtBQUssS0FBZCxJQUF1QixLQUF2QixDQUE2QixDQUFDLENBQUQsRUFBSSxLQUFLLEtBQVQsQ0FBN0IsQ0FBVjtBQUNBLGNBQUUsR0FBRixHQUFRO0FBQUEsdUJBQUssRUFBRSxLQUFGLENBQVEsRUFBRSxLQUFGLENBQVEsQ0FBUixDQUFSLENBQUw7QUFBQSxhQUFSO0FBQ0EsY0FBRSxJQUFGLEdBQVMsR0FBRyxHQUFILENBQU8sSUFBUCxHQUFjLEtBQWQsQ0FBb0IsRUFBRSxLQUF0QixFQUE2QixNQUE3QixDQUFvQyxLQUFLLE1BQXpDLENBQVQ7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBTCxDQUFVLElBQXJCO0FBQ0EsaUJBQUssQ0FBTCxDQUFPLEtBQVAsQ0FBYSxNQUFiLENBQW9CLENBQUMsR0FBRyxHQUFILENBQU8sSUFBUCxFQUFhLEtBQUssQ0FBTCxDQUFPLEtBQXBCLElBQTJCLENBQTVCLEVBQStCLEdBQUcsR0FBSCxDQUFPLElBQVAsRUFBYSxLQUFLLENBQUwsQ0FBTyxLQUFwQixJQUEyQixDQUExRCxDQUFwQjtBQUNBLGdCQUFHLEtBQUssTUFBTCxDQUFZLE1BQWYsRUFBdUI7QUFDbkIsa0JBQUUsSUFBRixDQUFPLFFBQVAsQ0FBZ0IsQ0FBQyxLQUFLLE1BQXRCO0FBQ0g7QUFFSjs7O2lDQUVROztBQUVMLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLElBQUksS0FBSyxDQUFiO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLE1BQUwsQ0FBWSxDQUF2Qjs7Ozs7Ozs7QUFRQSxjQUFFLEtBQUYsR0FBVTtBQUFBLHVCQUFLLEtBQUssS0FBTCxDQUFXLENBQVgsRUFBYyxLQUFLLEdBQW5CLENBQUw7QUFBQSxhQUFWO0FBQ0EsY0FBRSxLQUFGLEdBQVUsR0FBRyxLQUFILENBQVMsS0FBSyxLQUFkLElBQXVCLEtBQXZCLENBQTZCLENBQUMsS0FBSyxNQUFOLEVBQWMsQ0FBZCxDQUE3QixDQUFWO0FBQ0EsY0FBRSxHQUFGLEdBQVE7QUFBQSx1QkFBSyxFQUFFLEtBQUYsQ0FBUSxFQUFFLEtBQUYsQ0FBUSxDQUFSLENBQVIsQ0FBTDtBQUFBLGFBQVI7QUFDQSxjQUFFLElBQUYsR0FBUyxHQUFHLEdBQUgsQ0FBTyxJQUFQLEdBQWMsS0FBZCxDQUFvQixFQUFFLEtBQXRCLEVBQTZCLE1BQTdCLENBQW9DLEtBQUssTUFBekMsQ0FBVDs7QUFFQSxnQkFBRyxLQUFLLE1BQUwsQ0FBWSxNQUFmLEVBQXNCO0FBQ2xCLGtCQUFFLElBQUYsQ0FBTyxRQUFQLENBQWdCLENBQUMsS0FBSyxLQUF0QjtBQUNIOztBQUdELGdCQUFJLE9BQU8sS0FBSyxJQUFMLENBQVUsSUFBckI7QUFDQSxpQkFBSyxDQUFMLENBQU8sS0FBUCxDQUFhLE1BQWIsQ0FBb0IsQ0FBQyxHQUFHLEdBQUgsQ0FBTyxJQUFQLEVBQWEsS0FBSyxDQUFMLENBQU8sS0FBcEIsSUFBMkIsQ0FBNUIsRUFBK0IsR0FBRyxHQUFILENBQU8sSUFBUCxFQUFhLEtBQUssQ0FBTCxDQUFPLEtBQXBCLElBQTJCLENBQTFELENBQXBCO0FBQ0g7OztvQ0FFVTtBQUNQLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLFdBQVcsS0FBSyxNQUFMLENBQVksQ0FBM0I7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBTCxDQUFVLGNBQVYsQ0FBeUIsT0FBSyxLQUFLLFdBQUwsQ0FBaUIsUUFBakIsQ0FBTCxHQUFnQyxHQUFoQyxHQUFvQyxLQUFLLFdBQUwsQ0FBaUIsTUFBakIsQ0FBcEMsSUFBOEQsS0FBSyxNQUFMLENBQVksTUFBWixHQUFxQixFQUFyQixHQUEwQixNQUFJLEtBQUssV0FBTCxDQUFpQixXQUFqQixDQUE1RixDQUF6QixFQUNOLElBRE0sQ0FDRCxXQURDLEVBQ1ksaUJBQWlCLEtBQUssTUFBdEIsR0FBK0IsR0FEM0MsQ0FBWDs7QUFHQSxnQkFBSSxRQUFRLElBQVo7QUFDQSxnQkFBSSxLQUFLLGlCQUFMLEVBQUosRUFBOEI7QUFDMUIsd0JBQVEsS0FBSyxVQUFMLEdBQWtCLElBQWxCLENBQXVCLFlBQXZCLENBQVI7QUFDSDs7QUFFRCxrQkFBTSxJQUFOLENBQVcsS0FBSyxDQUFMLENBQU8sSUFBbEI7O0FBRUEsaUJBQUssY0FBTCxDQUFvQixVQUFRLEtBQUssV0FBTCxDQUFpQixPQUFqQixDQUE1QixFQUNLLElBREwsQ0FDVSxXQURWLEVBQ3VCLGVBQWUsS0FBSyxLQUFMLEdBQVcsQ0FBMUIsR0FBOEIsR0FBOUIsR0FBb0MsS0FBSyxNQUFMLENBQVksTUFBaEQsR0FBeUQsR0FEaEYsQztBQUFBLGFBRUssSUFGTCxDQUVVLElBRlYsRUFFZ0IsTUFGaEIsRUFHSyxLQUhMLENBR1csYUFIWCxFQUcwQixRQUgxQixFQUlLLElBSkwsQ0FJVSxTQUFTLEtBSm5CO0FBS0g7OztvQ0FFVTtBQUNQLGdCQUFJLE9BQU8sSUFBWDtBQUNBLGdCQUFJLE9BQU8sS0FBSyxJQUFoQjtBQUNBLGdCQUFJLFdBQVcsS0FBSyxNQUFMLENBQVksQ0FBM0I7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBTCxDQUFVLGNBQVYsQ0FBeUIsT0FBSyxLQUFLLFdBQUwsQ0FBaUIsUUFBakIsQ0FBTCxHQUFnQyxHQUFoQyxHQUFvQyxLQUFLLFdBQUwsQ0FBaUIsTUFBakIsQ0FBcEMsSUFBOEQsS0FBSyxNQUFMLENBQVksTUFBWixHQUFxQixFQUFyQixHQUEwQixNQUFJLEtBQUssV0FBTCxDQUFpQixXQUFqQixDQUE1RixDQUF6QixDQUFYOztBQUVBLGdCQUFJLFFBQVEsSUFBWjtBQUNBLGdCQUFJLEtBQUssaUJBQUwsRUFBSixFQUE4QjtBQUMxQix3QkFBUSxLQUFLLFVBQUwsR0FBa0IsSUFBbEIsQ0FBdUIsWUFBdkIsQ0FBUjtBQUNIOztBQUVELGtCQUFNLElBQU4sQ0FBVyxLQUFLLENBQUwsQ0FBTyxJQUFsQjs7QUFFQSxpQkFBSyxjQUFMLENBQW9CLFVBQVEsS0FBSyxXQUFMLENBQWlCLE9BQWpCLENBQTVCLEVBQ0ssSUFETCxDQUNVLFdBRFYsRUFDdUIsZUFBYyxDQUFDLEtBQUssTUFBTCxDQUFZLElBQTNCLEdBQWlDLEdBQWpDLEdBQXNDLEtBQUssTUFBTCxHQUFZLENBQWxELEdBQXFELGNBRDVFLEM7QUFBQSxhQUVLLElBRkwsQ0FFVSxJQUZWLEVBRWdCLEtBRmhCLEVBR0ssS0FITCxDQUdXLGFBSFgsRUFHMEIsUUFIMUIsRUFJSyxJQUpMLENBSVUsU0FBUyxLQUpuQjtBQUtIOzs7K0JBRU0sTyxFQUFRO0FBQ1gsMEZBQWEsT0FBYjtBQUNBLGlCQUFLLFNBQUw7QUFDQSxpQkFBSyxTQUFMOztBQUVBLGlCQUFLLFVBQUw7O0FBRUEsaUJBQUssWUFBTDtBQUNIOzs7cUNBRVk7QUFDVCxnQkFBSSxPQUFPLElBQVg7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxPQUFPLEtBQUssSUFBaEI7QUFDQSxnQkFBSSxXQUFXLEtBQUssV0FBTCxDQUFpQixLQUFqQixDQUFmO0FBQ0EsaUJBQUssa0JBQUwsR0FBMEIsS0FBSyxXQUFMLENBQWlCLGdCQUFqQixDQUExQjs7QUFHQSxnQkFBSSxnQkFBZ0IsS0FBSyxJQUFMLENBQVUsY0FBVixDQUF5QixPQUFPLEtBQUssa0JBQXJDLENBQXBCOztBQUVBLGdCQUFJLE9BQU8sY0FBYyxTQUFkLENBQXdCLE1BQU0sUUFBOUIsRUFDTixJQURNLENBQ0QsSUFEQyxDQUFYOztBQUdBLGlCQUFLLEtBQUwsR0FBYSxNQUFiLENBQW9CLFFBQXBCLEVBQ0ssSUFETCxDQUNVLE9BRFYsRUFDbUIsUUFEbkI7O0FBR0EsZ0JBQUksUUFBUSxJQUFaO0FBQ0EsZ0JBQUksS0FBSyxpQkFBTCxFQUFKLEVBQThCO0FBQzFCLHdCQUFRLEtBQUssVUFBTCxFQUFSO0FBQ0g7O0FBRUQsa0JBQU0sSUFBTixDQUFXLEdBQVgsRUFBZ0IsS0FBSyxNQUFMLENBQVksR0FBWixDQUFnQixNQUFoQyxFQUNLLElBREwsQ0FDVSxJQURWLEVBQ2dCLEtBQUssQ0FBTCxDQUFPLEdBRHZCLEVBRUssSUFGTCxDQUVVLElBRlYsRUFFZ0IsS0FBSyxDQUFMLENBQU8sR0FGdkI7O0FBSUEsZ0JBQUksS0FBSyxPQUFULEVBQWtCO0FBQ2QscUJBQUssRUFBTCxDQUFRLFdBQVIsRUFBcUIsYUFBSztBQUN0Qix5QkFBSyxPQUFMLENBQWEsVUFBYixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsRUFGdEI7QUFHQSx3QkFBSSxPQUFPLE1BQU0sS0FBSyxDQUFMLENBQU8sS0FBUCxDQUFhLENBQWIsQ0FBTixHQUF3QixJQUF4QixHQUErQixLQUFLLENBQUwsQ0FBTyxLQUFQLENBQWEsQ0FBYixDQUEvQixHQUFpRCxHQUE1RDtBQUNBLHdCQUFJLFFBQVEsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixLQUFuQixDQUF5QixDQUF6QixFQUE0QixLQUFLLE1BQUwsQ0FBWSxNQUFaLENBQW1CLEdBQS9DLENBQVo7QUFDQSx3QkFBSSxTQUFTLFVBQVUsQ0FBdkIsRUFBMEI7QUFDdEIsZ0NBQVEsT0FBUjtBQUNBLDRCQUFJLFFBQVEsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixLQUEvQjtBQUNBLDRCQUFJLEtBQUosRUFBVztBQUNQLG9DQUFRLFFBQVEsSUFBaEI7QUFDSDtBQUNELGdDQUFRLEtBQVI7QUFDSDtBQUNELHlCQUFLLE9BQUwsQ0FBYSxJQUFiLENBQWtCLElBQWxCLEVBQ0ssS0FETCxDQUNXLE1BRFgsRUFDb0IsR0FBRyxLQUFILENBQVMsS0FBVCxHQUFpQixDQUFsQixHQUF1QixJQUQxQyxFQUVLLEtBRkwsQ0FFVyxLQUZYLEVBRW1CLEdBQUcsS0FBSCxDQUFTLEtBQVQsR0FBaUIsRUFBbEIsR0FBd0IsSUFGMUM7QUFHSCxpQkFqQkQsRUFrQkssRUFsQkwsQ0FrQlEsVUFsQlIsRUFrQm9CLGFBQUs7QUFDakIseUJBQUssT0FBTCxDQUFhLFVBQWIsR0FDSyxRQURMLENBQ2MsR0FEZCxFQUVLLEtBRkwsQ0FFVyxTQUZYLEVBRXNCLENBRnRCO0FBR0gsaUJBdEJMO0FBdUJIOztBQUVELGdCQUFJLEtBQUssR0FBTCxDQUFTLEtBQWIsRUFBb0I7QUFDaEIscUJBQUssS0FBTCxDQUFXLE1BQVgsRUFBbUIsS0FBSyxHQUFMLENBQVMsS0FBNUI7QUFDSDs7QUFFRCxpQkFBSyxJQUFMLEdBQVksTUFBWjtBQUNIOzs7dUNBRWM7O0FBRVgsZ0JBQUksT0FBTSxJQUFWO0FBQ0EsZ0JBQUksT0FBTyxLQUFLLElBQWhCOztBQUVBLGdCQUFJLFFBQVEsS0FBSyxHQUFMLENBQVMsYUFBckI7O0FBSUEsZ0JBQUcsQ0FBQyxNQUFNLE1BQU4sRUFBRCxJQUFtQixNQUFNLE1BQU4sR0FBZSxNQUFmLEdBQXNCLENBQTVDLEVBQThDO0FBQzFDLHFCQUFLLFVBQUwsR0FBa0IsS0FBbEI7QUFDSDs7QUFFRCxnQkFBRyxDQUFDLEtBQUssVUFBVCxFQUFvQjtBQUNoQixvQkFBRyxLQUFLLE1BQUwsSUFBZSxLQUFLLE1BQUwsQ0FBWSxTQUE5QixFQUF3QztBQUNwQyx5QkFBSyxNQUFMLENBQVksU0FBWixDQUFzQixNQUF0QjtBQUNIO0FBQ0Q7QUFDSDs7QUFHRCxnQkFBSSxVQUFVLEtBQUssSUFBTCxDQUFVLEtBQVYsR0FBa0IsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixNQUFuRDtBQUNBLGdCQUFJLFVBQVUsS0FBSyxNQUFMLENBQVksTUFBWixDQUFtQixNQUFqQzs7QUFFQSxpQkFBSyxNQUFMLEdBQWMsbUJBQVcsS0FBSyxHQUFoQixFQUFxQixLQUFLLElBQTFCLEVBQWdDLEtBQWhDLEVBQXVDLE9BQXZDLEVBQWdELE9BQWhELENBQWQ7O0FBRUEsaUJBQUssV0FBTCxHQUFtQixLQUFLLE1BQUwsQ0FBWSxLQUFaLEdBQ2QsVUFEYyxDQUNILEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBbUIsVUFEaEIsRUFFZCxNQUZjLENBRVAsVUFGTyxFQUdkLEtBSGMsQ0FHUixLQUhRLENBQW5COztBQU1BLGlCQUFLLFdBQUwsQ0FBaUIsRUFBakIsQ0FBb0IsV0FBcEIsRUFBaUM7QUFBQSx1QkFBSSxLQUFLLGlCQUFMLENBQXVCLENBQXZCLENBQUo7QUFBQSxhQUFqQzs7QUFFQSxpQkFBSyxNQUFMLENBQVksU0FBWixDQUNLLElBREwsQ0FDVSxLQUFLLFdBRGY7QUFFSDs7OzBDQUVpQixTLEVBQVU7QUFDeEIsaUJBQUssbUJBQUwsQ0FBeUIsU0FBekI7O0FBRUEsZ0JBQUksYUFBYSxLQUFLLGFBQUwsQ0FBbUIsT0FBbkIsQ0FBMkIsU0FBM0IsSUFBc0MsQ0FBdkQ7QUFDQSxpQkFBSyxJQUFMLENBQVUsTUFBVixDQUFpQixTQUFqQixDQUEyQixTQUEzQixDQUFxQyxRQUFyQyxFQUErQyxJQUEvQyxDQUFvRCxVQUFTLElBQVQsRUFBYztBQUM5RCxvQkFBRyxRQUFRLFNBQVgsRUFBcUI7QUFDakIsdUJBQUcsTUFBSCxDQUFVLElBQVYsRUFBZ0IsT0FBaEIsQ0FBd0IsY0FBeEIsRUFBd0MsVUFBeEM7QUFDSDtBQUVKLGFBTEQ7O0FBT0EsaUJBQUssSUFBTDtBQUNIOzs7NENBRW1CLFMsRUFBVztBQUMzQixnQkFBSSxDQUFDLEtBQUssYUFBVixFQUF5QjtBQUNyQixxQkFBSyxhQUFMLEdBQXFCLEtBQUssSUFBTCxDQUFVLEdBQVYsQ0FBYyxhQUFkLENBQTRCLE1BQTVCLEdBQXFDLEtBQXJDLEVBQXJCO0FBQ0g7QUFDRCxnQkFBSSxRQUFRLEtBQUssYUFBTCxDQUFtQixPQUFuQixDQUEyQixTQUEzQixDQUFaOztBQUVBLGdCQUFJLFFBQVEsQ0FBWixFQUFlO0FBQ1gscUJBQUssYUFBTCxDQUFtQixJQUFuQixDQUF3QixTQUF4QjtBQUNILGFBRkQsTUFFTztBQUNILHFCQUFLLGFBQUwsQ0FBbUIsTUFBbkIsQ0FBMEIsS0FBMUIsRUFBaUMsQ0FBakM7QUFDSDtBQUNKOzs7Z0NBSU8sSSxFQUFLO0FBQ1QsMkZBQWMsSUFBZDtBQUNBLGlCQUFLLGFBQUwsR0FBcUIsSUFBckI7QUFDSDs7Ozs7Ozs7Ozs7O1FDMVBXLE0sR0FBQSxNOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW5CaEIsSUFBSSxjQUFjLENBQWxCLEM7O0FBRUEsU0FBUyxXQUFULENBQXNCLEVBQXRCLEVBQTBCLEVBQTFCLEVBQThCO0FBQzdCLEtBQUksTUFBTSxDQUFOLElBQVcsS0FBSyxHQUFMLENBQVMsRUFBVCxJQUFlLEtBQUssR0FBTCxDQUFTLFFBQVEsRUFBUixDQUFULENBQWYsSUFBd0MsQ0FBdkQsRUFBMEQ7QUFDekQsUUFBTSxpQkFBTixDO0FBQ0E7QUFDRCxLQUFJLE1BQU0sQ0FBTixJQUFXLEtBQUssQ0FBcEIsRUFBdUI7QUFDdEIsUUFBTSxpQkFBTjtBQUNBO0FBQ0QsUUFBTyxpQkFBaUIsV0FBVyxLQUFHLENBQWQsRUFBaUIsS0FBRyxDQUFwQixDQUFqQixDQUFQO0FBQ0E7O0FBRUQsU0FBUyxNQUFULENBQWlCLEVBQWpCLEVBQXFCO0FBQ3BCLEtBQUksS0FBSyxDQUFMLElBQVUsTUFBTSxDQUFwQixFQUF1QjtBQUN0QixRQUFNLGlCQUFOO0FBQ0E7QUFDRCxRQUFPLGlCQUFpQixNQUFNLEtBQUcsQ0FBVCxDQUFqQixDQUFQO0FBQ0E7O0FBRU0sU0FBUyxNQUFULENBQWlCLEVBQWpCLEVBQXFCLEVBQXJCLEVBQXlCO0FBQy9CLEtBQUksTUFBTSxDQUFOLElBQVcsS0FBSyxHQUFMLENBQVMsRUFBVCxJQUFlLEtBQUssR0FBTCxDQUFTLFFBQVEsRUFBUixDQUFULENBQWYsSUFBd0MsQ0FBdkQsRUFBMEQ7QUFDekQsUUFBTSxpQkFBTjtBQUNBO0FBQ0QsS0FBSSxNQUFNLENBQU4sSUFBVyxNQUFNLENBQXJCLEVBQXdCO0FBQ3ZCLFFBQU0saUJBQU47QUFDQTtBQUNELFFBQU8saUJBQWlCLE1BQU0sS0FBRyxDQUFULEVBQVksS0FBRyxDQUFmLENBQWpCLENBQVA7QUFDQTs7QUFFRCxTQUFTLE1BQVQsQ0FBaUIsRUFBakIsRUFBcUIsRUFBckIsRUFBeUIsRUFBekIsRUFBNkI7QUFDNUIsS0FBSyxNQUFJLENBQUwsSUFBYSxLQUFLLEdBQUwsQ0FBUyxFQUFULElBQWMsS0FBSyxHQUFMLENBQVMsUUFBUSxFQUFSLENBQVQsQ0FBZixJQUF3QyxDQUF4RCxFQUE0RDtBQUMzRCxRQUFNLGlCQUFOLEM7QUFDQTtBQUNELEtBQUssTUFBSSxDQUFMLElBQWEsS0FBSyxHQUFMLENBQVMsRUFBVCxJQUFjLEtBQUssR0FBTCxDQUFTLFFBQVEsRUFBUixDQUFULENBQWYsSUFBd0MsQ0FBeEQsRUFBNEQ7QUFDM0QsUUFBTSxpQkFBTixDO0FBQ0E7QUFDRCxLQUFLLE1BQUksQ0FBTCxJQUFZLEtBQUcsQ0FBbkIsRUFBdUI7QUFDdEIsUUFBTSxpQkFBTjtBQUNBO0FBQ0QsUUFBTyxpQkFBaUIsTUFBTSxLQUFHLENBQVQsRUFBWSxLQUFHLENBQWYsRUFBa0IsS0FBRyxDQUFyQixDQUFqQixDQUFQO0FBQ0E7O0FBRUQsU0FBUyxLQUFULENBQWdCLEVBQWhCLEVBQW9CO0FBQ25CLFFBQU8saUJBQWlCLFVBQVUsS0FBRyxDQUFiLENBQWpCLENBQVA7QUFDQTs7QUFFRCxTQUFTLFVBQVQsQ0FBcUIsRUFBckIsRUFBd0IsRUFBeEIsRUFBNEI7QUFDM0IsS0FBSyxNQUFNLENBQVAsSUFBZSxLQUFLLEdBQUwsQ0FBUyxFQUFULElBQWdCLEtBQUssR0FBTCxDQUFTLFFBQVEsRUFBUixDQUFULENBQWpCLElBQTRDLENBQTlELEVBQWtFO0FBQ2pFLFFBQU0saUJBQU4sQztBQUNBO0FBQ0QsUUFBTyxpQkFBaUIsZUFBZSxLQUFHLENBQWxCLEVBQXFCLEtBQUcsQ0FBeEIsQ0FBakIsQ0FBUDtBQUNBOztBQUVELFNBQVMsS0FBVCxDQUFnQixFQUFoQixFQUFvQixFQUFwQixFQUF3QjtBQUN2QixLQUFLLE1BQU0sQ0FBUCxJQUFlLEtBQUssR0FBTCxDQUFTLEVBQVQsSUFBZSxLQUFLLEdBQUwsQ0FBUyxRQUFRLEVBQVIsQ0FBVCxDQUFoQixJQUF5QyxDQUEzRCxFQUErRDtBQUM5RCxRQUFNLGlCQUFOLEM7QUFDQTtBQUNELFFBQU8saUJBQWlCLFVBQVUsS0FBRyxDQUFiLEVBQWdCLEtBQUcsQ0FBbkIsQ0FBakIsQ0FBUDtBQUNBOztBQUVELFNBQVMsS0FBVCxDQUFnQixFQUFoQixFQUFvQixFQUFwQixFQUF3QixFQUF4QixFQUE0QjtBQUMzQixLQUFLLE1BQUksQ0FBTCxJQUFhLEtBQUssR0FBTCxDQUFTLEVBQVQsSUFBYyxLQUFLLEdBQUwsQ0FBUyxRQUFRLEVBQVIsQ0FBVCxDQUFmLElBQXdDLENBQXhELEVBQTREO0FBQzNELFFBQU0saUJBQU4sQztBQUNBO0FBQ0QsS0FBSyxNQUFJLENBQUwsSUFBYSxLQUFLLEdBQUwsQ0FBUyxFQUFULElBQWMsS0FBSyxHQUFMLENBQVMsUUFBUSxFQUFSLENBQVQsQ0FBZixJQUF3QyxDQUF4RCxFQUE0RDtBQUMzRCxRQUFNLGlCQUFOLEM7QUFDQTtBQUNELFFBQU8saUJBQWlCLFVBQVUsS0FBRyxDQUFiLEVBQWdCLEtBQUcsQ0FBbkIsRUFBc0IsS0FBRyxDQUF6QixDQUFqQixDQUFQO0FBQ0E7O0FBR0QsU0FBUyxTQUFULENBQW9CLEVBQXBCLEVBQXdCLEVBQXhCLEVBQTRCLEVBQTVCLEVBQWdDO0FBQy9CLEtBQUksRUFBSjs7QUFFQSxLQUFJLE1BQUksQ0FBUixFQUFXO0FBQ1YsT0FBRyxDQUFIO0FBQ0EsRUFGRCxNQUVPLElBQUksS0FBSyxDQUFMLElBQVUsQ0FBZCxFQUFpQjtBQUN2QixNQUFJLEtBQUssTUFBTSxLQUFLLEtBQUssRUFBaEIsQ0FBVDtBQUNBLE1BQUksS0FBSyxDQUFUO0FBQ0EsT0FBSyxJQUFJLEtBQUssS0FBSyxDQUFuQixFQUFzQixNQUFNLENBQTVCLEVBQStCLE1BQU0sQ0FBckMsRUFBd0M7QUFDdkMsUUFBSyxJQUFJLENBQUMsS0FBSyxFQUFMLEdBQVUsQ0FBWCxJQUFnQixFQUFoQixHQUFxQixFQUFyQixHQUEwQixFQUFuQztBQUNBO0FBQ0QsT0FBSyxJQUFJLEtBQUssR0FBTCxDQUFVLElBQUksRUFBZCxFQUFvQixLQUFLLENBQU4sR0FBVyxFQUE5QixDQUFUO0FBQ0EsRUFQTSxNQU9BLElBQUksS0FBSyxDQUFMLElBQVUsQ0FBZCxFQUFpQjtBQUN2QixNQUFJLEtBQUssS0FBSyxFQUFMLElBQVcsS0FBSyxLQUFLLEVBQXJCLENBQVQ7QUFDQSxNQUFJLEtBQUssQ0FBVDtBQUNBLE9BQUssSUFBSSxLQUFLLEtBQUssQ0FBbkIsRUFBc0IsTUFBTSxDQUE1QixFQUErQixNQUFNLENBQXJDLEVBQXdDO0FBQ3ZDLFFBQUssSUFBSSxDQUFDLEtBQUssRUFBTCxHQUFVLENBQVgsSUFBZ0IsRUFBaEIsR0FBcUIsRUFBckIsR0FBMEIsRUFBbkM7QUFDQTtBQUNELE9BQUssS0FBSyxHQUFMLENBQVUsSUFBSSxFQUFkLEVBQW9CLEtBQUssQ0FBekIsSUFBK0IsRUFBcEM7QUFDQSxFQVBNLE1BT0E7QUFDTixNQUFJLEtBQUssS0FBSyxLQUFMLENBQVcsS0FBSyxJQUFMLENBQVUsS0FBSyxFQUFMLEdBQVUsRUFBcEIsQ0FBWCxFQUFvQyxDQUFwQyxDQUFUO0FBQ0EsTUFBSSxLQUFLLEtBQUssR0FBTCxDQUFTLEtBQUssR0FBTCxDQUFTLEVBQVQsQ0FBVCxFQUF1QixDQUF2QixDQUFUO0FBQ0EsTUFBSSxLQUFNLE1BQU0sQ0FBUCxHQUFZLENBQVosR0FBZ0IsQ0FBekI7QUFDQSxPQUFLLElBQUksS0FBSyxLQUFLLENBQW5CLEVBQXNCLE1BQU0sQ0FBNUIsRUFBK0IsTUFBTSxDQUFyQyxFQUF3QztBQUN2QyxRQUFLLElBQUksQ0FBQyxLQUFLLEVBQUwsR0FBVSxDQUFYLElBQWdCLEVBQWhCLEdBQXFCLEVBQXJCLEdBQTBCLEVBQW5DO0FBQ0E7QUFDRCxNQUFJLEtBQUssS0FBSyxFQUFkO0FBQ0EsT0FBSyxJQUFJLEtBQUssQ0FBZCxFQUFpQixNQUFNLEtBQUssQ0FBNUIsRUFBK0IsTUFBTSxDQUFyQyxFQUF3QztBQUN2QyxTQUFNLENBQUMsS0FBSyxDQUFOLElBQVcsRUFBakI7QUFDQTtBQUNELE1BQUksTUFBTSxJQUFJLEVBQUosR0FBUyxLQUFLLEdBQUwsQ0FBUyxFQUFULENBQVQsR0FBd0IsS0FBSyxHQUFMLENBQVMsS0FBSyxHQUFMLENBQVMsRUFBVCxDQUFULEVBQXVCLEVBQXZCLENBQXhCLEdBQXFELEVBQS9EOztBQUVBLE9BQUssS0FBSyxHQUFMLENBQVMsS0FBSyxHQUFMLENBQVMsRUFBVCxDQUFULEVBQXVCLENBQXZCLENBQUw7QUFDQSxPQUFNLE1BQU0sQ0FBUCxHQUFZLENBQVosR0FBZ0IsQ0FBckI7QUFDQSxPQUFLLElBQUksS0FBSyxLQUFHLENBQWpCLEVBQW9CLE1BQU0sQ0FBMUIsRUFBNkIsTUFBTSxDQUFuQyxFQUFzQztBQUNyQyxRQUFLLElBQUksQ0FBQyxLQUFLLENBQU4sSUFBVyxFQUFYLEdBQWdCLEVBQWhCLEdBQXFCLEVBQTlCO0FBQ0E7QUFDRCxPQUFLLElBQUksQ0FBSixFQUFPLE1BQU0sQ0FBTixHQUFVLElBQUksRUFBSixHQUFTLEtBQUssRUFBeEIsR0FDVCxJQUFJLEtBQUssRUFBVCxHQUFjLEtBQUssR0FBTCxDQUFTLEVBQVQsQ0FBZCxHQUE2QixLQUFLLEdBQUwsQ0FBUyxFQUFULENBQTdCLEdBQTRDLEVBRDFDLENBQUw7QUFFQTtBQUNELFFBQU8sRUFBUDtBQUNBOztBQUdELFNBQVMsY0FBVCxDQUF5QixFQUF6QixFQUE0QixFQUE1QixFQUFnQztBQUMvQixLQUFJLEVBQUo7O0FBRUEsS0FBSSxNQUFNLENBQVYsRUFBYTtBQUNaLE9BQUssQ0FBTDtBQUNBLEVBRkQsTUFFTyxJQUFJLEtBQUssR0FBVCxFQUFjO0FBQ3BCLE9BQUssVUFBVSxDQUFDLEtBQUssR0FBTCxDQUFVLEtBQUssRUFBZixFQUFvQixJQUFFLENBQXRCLEtBQ1gsSUFBSSxJQUFFLENBQUYsR0FBSSxFQURHLENBQUQsSUFDSyxLQUFLLElBQUwsQ0FBVSxJQUFFLENBQUYsR0FBSSxFQUFkLENBRGYsQ0FBTDtBQUVBLEVBSE0sTUFHQSxJQUFJLEtBQUssR0FBVCxFQUFjO0FBQ3BCLE9BQUssQ0FBTDtBQUNBLEVBRk0sTUFFQTtBQUNOLE1BQUksRUFBSjtBQUNjLE1BQUksRUFBSjtBQUNBLE1BQUksR0FBSjtBQUNkLE1BQUssS0FBSyxDQUFOLElBQVksQ0FBaEIsRUFBbUI7QUFDbEIsUUFBSyxJQUFJLFVBQVUsS0FBSyxJQUFMLENBQVUsRUFBVixDQUFWLENBQVQ7QUFDQSxRQUFLLEtBQUssSUFBTCxDQUFVLElBQUUsS0FBSyxFQUFqQixJQUF1QixLQUFLLEdBQUwsQ0FBUyxDQUFDLEVBQUQsR0FBSSxDQUFiLENBQXZCLEdBQXlDLEtBQUssSUFBTCxDQUFVLEVBQVYsQ0FBOUM7QUFDQSxTQUFNLENBQU47QUFDQSxHQUpELE1BSU87QUFDTixRQUFLLEtBQUssS0FBSyxHQUFMLENBQVMsQ0FBQyxFQUFELEdBQUksQ0FBYixDQUFWO0FBQ0EsU0FBTSxDQUFOO0FBQ0E7O0FBRUQsT0FBSyxLQUFLLEdBQVYsRUFBZSxNQUFPLEtBQUcsQ0FBekIsRUFBNkIsTUFBTSxDQUFuQyxFQUFzQztBQUNyQyxTQUFNLEtBQUssRUFBWDtBQUNBLFNBQU0sRUFBTjtBQUNBO0FBQ0Q7QUFDRCxRQUFPLEVBQVA7QUFDQTs7QUFFRCxTQUFTLEtBQVQsQ0FBZ0IsRUFBaEIsRUFBb0I7QUFDbkIsS0FBSSxLQUFLLENBQUMsS0FBSyxHQUFMLENBQVMsSUFBSSxFQUFKLElBQVUsSUFBSSxFQUFkLENBQVQsQ0FBVjtBQUNBLEtBQUksS0FBSyxLQUFLLElBQUwsQ0FDUixNQUFNLGNBQ0YsTUFBTSxlQUNMLE1BQU0sQ0FBQyxjQUFELEdBQ04sTUFBSyxDQUFDLGNBQUQsR0FDSixNQUFNLGlCQUNOLE1BQU0sa0JBQ1AsTUFBTSxDQUFDLGFBQUQsR0FDSixNQUFNLGlCQUNQLE1BQU0sQ0FBQyxjQUFELEdBQ0osTUFBTSxrQkFDUCxLQUFJLGVBREgsQ0FERixDQURDLENBREYsQ0FEQyxDQURBLENBREQsQ0FEQSxDQURELENBREosQ0FEUSxDQUFUO0FBWUEsS0FBSSxLQUFHLEVBQVAsRUFDZSxLQUFLLENBQUMsRUFBTjtBQUNmLFFBQU8sRUFBUDtBQUNBOztBQUVELFNBQVMsU0FBVCxDQUFvQixFQUFwQixFQUF3QjtBQUN2QixLQUFJLEtBQUssQ0FBVCxDO0FBQ0EsS0FBSSxRQUFRLEtBQUssR0FBTCxDQUFTLEVBQVQsQ0FBWjs7QUFFQSxLQUFJLFFBQVEsR0FBWixFQUFpQjtBQUNoQixPQUFLLEtBQUssR0FBTCxDQUFVLElBQ2QsU0FBUyxhQUNMLFNBQVMsY0FDUixTQUFTLGNBQ1QsU0FBUyxjQUNWLFNBQVMsY0FDUCxRQUFRLFVBRFYsQ0FEQyxDQURBLENBREQsQ0FESixDQURJLEVBTTRCLENBQUMsRUFON0IsSUFNaUMsQ0FOdEM7QUFPQSxFQVJELE1BUU8sSUFBSSxTQUFTLEdBQWIsRUFBa0I7QUFDeEIsT0FBSyxJQUFJLEtBQUssRUFBZCxFQUFrQixNQUFNLENBQXhCLEVBQTJCLElBQTNCLEVBQWlDO0FBQ2hDLFFBQUssTUFBTSxRQUFRLEVBQWQsQ0FBTDtBQUNBO0FBQ0QsT0FBSyxLQUFLLEdBQUwsQ0FBUyxDQUFDLEVBQUQsR0FBTSxLQUFOLEdBQWMsS0FBdkIsSUFDRixLQUFLLElBQUwsQ0FBVSxJQUFJLEtBQUssRUFBbkIsQ0FERSxJQUN3QixRQUFRLEVBRGhDLENBQUw7QUFFQTs7QUFFRCxLQUFJLEtBQUcsQ0FBUCxFQUNRLEtBQUssSUFBSSxFQUFUO0FBQ1IsUUFBTyxFQUFQO0FBQ0E7O0FBR0QsU0FBUyxLQUFULENBQWdCLEVBQWhCLEVBQW9CLEVBQXBCLEVBQXdCOztBQUV2QixLQUFJLE1BQU0sQ0FBTixJQUFXLE1BQU0sQ0FBckIsRUFBd0I7QUFDdkIsUUFBTSxpQkFBTjtBQUNBOztBQUVELEtBQUksTUFBTSxHQUFWLEVBQWU7QUFDZCxTQUFPLENBQVA7QUFDQSxFQUZELE1BRU8sSUFBSSxLQUFLLEdBQVQsRUFBYztBQUNwQixTQUFPLENBQUUsTUFBTSxFQUFOLEVBQVUsSUFBSSxFQUFkLENBQVQ7QUFDQTs7QUFFRCxLQUFJLEtBQUssTUFBTSxFQUFOLENBQVQ7QUFDQSxLQUFJLE1BQU0sS0FBSyxHQUFMLENBQVMsRUFBVCxFQUFhLENBQWIsQ0FBVjs7QUFFQSxLQUFJLEtBQUssQ0FBQyxNQUFNLENBQVAsSUFBWSxDQUFyQjtBQUNBLEtBQUksS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFKLEdBQVUsRUFBWCxJQUFpQixHQUFqQixHQUF1QixDQUF4QixJQUE2QixFQUF0QztBQUNBLEtBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUosR0FBVSxFQUFYLElBQWlCLEdBQWpCLEdBQXVCLEVBQXhCLElBQThCLEdBQTlCLEdBQW9DLEVBQXJDLElBQTJDLEdBQXBEO0FBQ0EsS0FBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFMLEdBQVcsR0FBWixJQUFtQixHQUFuQixHQUF5QixJQUExQixJQUFrQyxHQUFsQyxHQUF3QyxJQUF6QyxJQUFpRCxHQUFqRCxHQUF1RCxHQUF4RCxJQUNKLEtBREw7QUFFQSxLQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBTCxHQUFXLEdBQVosSUFBbUIsR0FBbkIsR0FBeUIsR0FBMUIsSUFBaUMsR0FBakMsR0FBdUMsSUFBeEMsSUFBZ0QsR0FBaEQsR0FBc0QsR0FBdkQsSUFBOEQsR0FBOUQsR0FDTixLQURLLElBQ0ksTUFEYjs7QUFHQSxLQUFJLEtBQUssTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLEVBQVgsSUFBaUIsRUFBdkIsSUFBNkIsRUFBbkMsSUFBeUMsRUFBL0MsSUFBcUQsRUFBL0QsQ0FBVDs7QUFFQSxLQUFJLE1BQU0sS0FBSyxHQUFMLENBQVMsTUFBTSxFQUFOLENBQVQsRUFBb0IsQ0FBcEIsSUFBeUIsQ0FBbkMsRUFBc0M7QUFDckMsTUFBSSxNQUFKO0FBQ0EsS0FBRztBQUNGLE9BQUksTUFBTSxVQUFVLEVBQVYsRUFBYyxFQUFkLENBQVY7QUFDQSxPQUFJLE1BQU0sS0FBSyxDQUFmO0FBQ0EsT0FBSSxTQUFTLENBQUMsTUFBTSxFQUFQLElBQ1YsS0FBSyxHQUFMLENBQVMsQ0FBQyxNQUFNLEtBQUssR0FBTCxDQUFTLE9BQU8sS0FBSyxLQUFLLEVBQWpCLENBQVQsQ0FBTixHQUNULEtBQUssR0FBTCxDQUFTLEtBQUcsR0FBSCxHQUFPLENBQVAsR0FBUyxLQUFLLEVBQXZCLENBRFMsR0FDb0IsQ0FEcEIsR0FFVCxDQUFDLElBQUUsR0FBRixHQUFRLElBQUUsRUFBWCxJQUFpQixDQUZULElBRWMsQ0FGdkIsQ0FESDtBQUlBLFNBQU0sTUFBTjtBQUNBLFlBQVMsbUJBQW1CLE1BQW5CLEVBQTJCLEtBQUssR0FBTCxDQUFTLFFBQVEsTUFBTSxLQUFLLEdBQUwsQ0FBUyxFQUFULENBQU4sSUFBb0IsQ0FBNUIsQ0FBVCxDQUEzQixDQUFUO0FBQ0EsR0FURCxRQVNVLEVBQUQsSUFBUyxVQUFVLENBVDVCO0FBVUE7QUFDRCxRQUFPLEVBQVA7QUFDQTs7QUFFRCxTQUFTLFNBQVQsQ0FBb0IsRUFBcEIsRUFBd0IsRUFBeEIsRUFBNEI7O0FBRTNCLEtBQUksRUFBSjtBQUNPLEtBQUksRUFBSjtBQUNQLEtBQUksS0FBSyxLQUFLLEtBQUwsQ0FBVyxLQUFLLEtBQUssSUFBTCxDQUFVLEVBQVYsQ0FBaEIsRUFBK0IsQ0FBL0IsQ0FBVDtBQUNBLEtBQUksS0FBSyxLQUFLLEdBQUwsQ0FBUyxLQUFLLEdBQUwsQ0FBUyxFQUFULENBQVQsRUFBdUIsQ0FBdkIsQ0FBVDtBQUNBLEtBQUksS0FBSyxDQUFUOztBQUVBLE1BQUssSUFBSSxLQUFLLEtBQUcsQ0FBakIsRUFBb0IsTUFBTSxDQUExQixFQUE2QixNQUFNLENBQW5DLEVBQXNDO0FBQ3JDLE9BQUssSUFBSSxDQUFDLEtBQUcsQ0FBSixJQUFTLEVBQVQsR0FBYyxFQUFkLEdBQW1CLEVBQTVCO0FBQ0E7O0FBRUQsS0FBSSxLQUFLLENBQUwsSUFBVSxDQUFkLEVBQWlCO0FBQ2hCLE9BQUssS0FBSyxHQUFMLENBQVMsRUFBVCxJQUFhLENBQWxCO0FBQ0EsT0FBSyxFQUFMO0FBQ0EsRUFIRCxNQUdPO0FBQ04sT0FBTSxNQUFNLENBQVAsR0FBWSxDQUFaLEdBQWdCLEtBQUssR0FBTCxDQUFTLEVBQVQsSUFBYSxLQUFLLEdBQUwsQ0FBUyxFQUFULENBQWIsR0FBMEIsS0FBSyxFQUFwRDtBQUNBLE9BQUksS0FBSyxLQUFHLEtBQUssRUFBakI7QUFDQTtBQUNELFFBQU8sSUFBSSxDQUFKLEVBQU8sSUFBSSxFQUFKLEdBQVMsS0FBSyxFQUFyQixDQUFQO0FBQ0E7O0FBRUQsU0FBUyxLQUFULENBQWdCLEVBQWhCLEVBQW9CLEVBQXBCLEVBQXdCLEVBQXhCLEVBQTRCO0FBQzNCLEtBQUksRUFBSjs7QUFFQSxLQUFJLE1BQU0sQ0FBTixJQUFXLE1BQU0sQ0FBckIsRUFBd0I7QUFDdkIsUUFBTSxpQkFBTjtBQUNBOztBQUVELEtBQUksTUFBTSxDQUFWLEVBQWE7QUFDWixPQUFLLENBQUw7QUFDQSxFQUZELE1BRU8sSUFBSSxNQUFNLENBQVYsRUFBYTtBQUNuQixPQUFLLElBQUksS0FBSyxHQUFMLENBQVMsTUFBTSxFQUFOLEVBQVUsTUFBTSxLQUFLLENBQXJCLENBQVQsRUFBa0MsQ0FBbEMsQ0FBVDtBQUNBLEVBRk0sTUFFQSxJQUFJLE1BQU0sQ0FBVixFQUFhO0FBQ25CLE9BQUssS0FBSyxHQUFMLENBQVMsTUFBTSxFQUFOLEVBQVUsS0FBRyxDQUFiLENBQVQsRUFBMEIsQ0FBMUIsQ0FBTDtBQUNBLEVBRk0sTUFFQSxJQUFJLE1BQU0sQ0FBVixFQUFhO0FBQ25CLE1BQUksS0FBSyxXQUFXLEVBQVgsRUFBZSxJQUFJLEVBQW5CLENBQVQ7QUFDQSxNQUFJLEtBQUssS0FBSyxDQUFkO0FBQ0EsT0FBSyxLQUFLLEtBQUssRUFBTCxJQUFXLElBQ3BCLENBQUMsQ0FBQyxLQUFLLEVBQU4sSUFBWSxDQUFaLEdBQ0EsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFKLEdBQVMsS0FBSyxFQUFmLElBQXFCLEVBQXJCLEdBQTBCLE1BQU0sSUFBSSxFQUFKLEdBQVMsRUFBZixDQUEzQixJQUFpRCxFQUFqRCxHQUNBLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBSixHQUFTLEtBQUssRUFBZixJQUFxQixFQUFyQixHQUEwQixNQUFNLEtBQUssRUFBTCxHQUFVLEVBQWhCLENBQTNCLElBQWtELEVBQWxELEdBQ0UsS0FBSyxFQUFMLElBQVcsSUFBSSxFQUFKLEdBQVMsQ0FBcEIsQ0FESCxJQUVFLEVBRkYsR0FFSyxFQUhOLElBSUUsRUFMSCxJQU1FLEVBUE8sQ0FBTCxDQUFMO0FBUUEsRUFYTSxNQVdBLElBQUksS0FBSyxFQUFULEVBQWE7QUFDbkIsT0FBSyxJQUFJLE9BQU8sRUFBUCxFQUFXLEVBQVgsRUFBZSxJQUFJLEVBQW5CLENBQVQ7QUFDQSxFQUZNLE1BRUE7QUFDTixPQUFLLE9BQU8sRUFBUCxFQUFXLEVBQVgsRUFBZSxFQUFmLENBQUw7QUFDQTtBQUNELFFBQU8sRUFBUDtBQUNBOztBQUVELFNBQVMsTUFBVCxDQUFpQixFQUFqQixFQUFxQixFQUFyQixFQUF5QixFQUF6QixFQUE2QjtBQUM1QixLQUFJLEtBQUssV0FBVyxFQUFYLEVBQWUsRUFBZixDQUFUO0FBQ0EsS0FBSSxNQUFNLEtBQUssQ0FBZjtBQUNBLEtBQUksS0FBSyxLQUFLLEVBQUwsSUFDUCxJQUNBLENBQUMsQ0FBQyxLQUFLLEdBQU4sSUFBYSxDQUFiLEdBQ0EsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFKLEdBQVMsS0FBSyxHQUFmLElBQXNCLEVBQXRCLEdBQTJCLE9BQU8sSUFBSSxFQUFKLEdBQVMsRUFBaEIsQ0FBNUIsSUFBbUQsRUFBbkQsR0FDQSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUosR0FBUyxLQUFLLEdBQWYsSUFBc0IsRUFBdEIsR0FBMkIsT0FBTyxLQUFLLEVBQUwsR0FBVSxFQUFqQixDQUE1QixJQUFvRCxFQUFwRCxHQUNFLE1BQU0sR0FBTixJQUFhLElBQUksRUFBSixHQUFTLENBQXRCLENBREgsSUFDK0IsRUFEL0IsR0FDb0MsRUFGckMsSUFFMkMsRUFINUMsSUFHa0QsRUFMM0MsQ0FBVDtBQU1BLEtBQUksTUFBSjtBQUNBLElBQUc7QUFDRixNQUFJLEtBQUssS0FBSyxHQUFMLENBQ1IsQ0FBQyxDQUFDLEtBQUcsRUFBSixJQUFVLEtBQUssR0FBTCxDQUFTLENBQUMsS0FBRyxFQUFKLEtBQVcsS0FBSyxFQUFMLEdBQVUsRUFBckIsQ0FBVCxDQUFWLEdBQ0UsQ0FBQyxLQUFLLENBQU4sSUFBVyxLQUFLLEdBQUwsQ0FBUyxFQUFULENBRGIsR0FFRSxLQUFLLEdBQUwsQ0FBUyxLQUFLLEVBQUwsSUFBVyxLQUFHLEVBQWQsQ0FBVCxDQUZGLEdBR0UsS0FBSyxHQUFMLENBQVMsSUFBSSxLQUFLLEVBQWxCLENBSEYsR0FJRSxDQUFDLElBQUUsRUFBRixHQUFRLElBQUUsRUFBVixHQUFlLEtBQUcsS0FBRyxFQUFOLENBQWhCLElBQTJCLENBSjlCLElBS0UsQ0FOTSxDQUFUO0FBT0EsV0FBUyxDQUFDLFVBQVUsRUFBVixFQUFjLEVBQWQsRUFBa0IsRUFBbEIsSUFBd0IsRUFBekIsSUFBK0IsRUFBeEM7QUFDQSxRQUFNLE1BQU47QUFDQSxFQVZELFFBVVMsS0FBSyxHQUFMLENBQVMsTUFBVCxJQUFpQixJQVYxQjtBQVdBLFFBQU8sRUFBUDtBQUNBOztBQUVELFNBQVMsVUFBVCxDQUFxQixFQUFyQixFQUF5QixFQUF6QixFQUE2QjtBQUM1QixLQUFJLEVBQUo7O0FBRUEsS0FBSyxLQUFLLENBQU4sSUFBYSxNQUFNLENBQXZCLEVBQTJCO0FBQzFCLFFBQU0saUJBQU47QUFDQSxFQUZELE1BRU8sSUFBSSxNQUFNLENBQVYsRUFBWTtBQUNsQixPQUFLLENBQUw7QUFDQSxFQUZNLE1BRUEsSUFBSSxNQUFNLENBQVYsRUFBYTtBQUNuQixPQUFLLEtBQUssR0FBTCxDQUFTLE1BQU0sS0FBSyxDQUFYLENBQVQsRUFBd0IsQ0FBeEIsQ0FBTDtBQUNBLEVBRk0sTUFFQSxJQUFJLE1BQU0sQ0FBVixFQUFhO0FBQ25CLE9BQUssQ0FBQyxDQUFELEdBQUssS0FBSyxHQUFMLENBQVMsRUFBVCxDQUFWO0FBQ0EsRUFGTSxNQUVBO0FBQ04sTUFBSSxLQUFLLE1BQU0sRUFBTixDQUFUO0FBQ0EsTUFBSSxNQUFNLEtBQUssRUFBZjs7QUFFQSxPQUFLLElBQUksQ0FBSixFQUFPLEtBQUssS0FBSyxJQUFMLENBQVUsSUFBSSxFQUFkLElBQW9CLEVBQXpCLEdBQ1QsSUFBRSxDQUFGLElBQU8sTUFBTSxDQUFiLENBRFMsR0FFVCxNQUFNLE1BQU0sQ0FBWixJQUFpQixDQUFqQixHQUFxQixLQUFLLElBQUwsQ0FBVSxJQUFJLEVBQWQsQ0FGWixHQUdULElBQUUsR0FBRixHQUFRLEVBQVIsSUFBYyxPQUFPLElBQUcsR0FBSCxHQUFTLENBQWhCLElBQXFCLEVBQW5DLENBSEUsQ0FBTDs7QUFLQSxNQUFJLE1BQU0sR0FBVixFQUFlO0FBQ2QsT0FBSSxHQUFKO0FBQ3FCLE9BQUksR0FBSjtBQUNBLE9BQUksRUFBSjtBQUNyQixNQUFHO0FBQ0YsVUFBTSxFQUFOO0FBQ0EsUUFBSSxLQUFLLENBQVQsRUFBWTtBQUNYLFdBQU0sQ0FBTjtBQUNBLEtBRkQsTUFFTyxJQUFJLEtBQUcsR0FBUCxFQUFZO0FBQ2xCLFdBQU0sVUFBVSxDQUFDLEtBQUssR0FBTCxDQUFVLEtBQUssRUFBZixFQUFxQixJQUFFLENBQXZCLEtBQThCLElBQUksSUFBRSxDQUFGLEdBQUksRUFBdEMsQ0FBRCxJQUNiLEtBQUssSUFBTCxDQUFVLElBQUUsQ0FBRixHQUFJLEVBQWQsQ0FERyxDQUFOO0FBRUEsS0FITSxNQUdBLElBQUksS0FBRyxHQUFQLEVBQVk7QUFDbEIsV0FBTSxDQUFOO0FBQ0EsS0FGTSxNQUVBO0FBQ04sU0FBSSxHQUFKO0FBQ21DLFNBQUksRUFBSjtBQUNuQyxTQUFLLEtBQUssQ0FBTixJQUFZLENBQWhCLEVBQW1CO0FBQ2xCLFlBQU0sSUFBSSxVQUFVLEtBQUssSUFBTCxDQUFVLEVBQVYsQ0FBVixDQUFWO0FBQ0EsV0FBSyxLQUFLLElBQUwsQ0FBVSxJQUFFLEtBQUssRUFBakIsSUFBdUIsS0FBSyxHQUFMLENBQVMsQ0FBQyxFQUFELEdBQUksQ0FBYixDQUF2QixHQUF5QyxLQUFLLElBQUwsQ0FBVSxFQUFWLENBQTlDO0FBQ0EsWUFBTSxDQUFOO0FBQ0EsTUFKRCxNQUlPO0FBQ04sWUFBTSxLQUFLLEtBQUssR0FBTCxDQUFTLENBQUMsRUFBRCxHQUFJLENBQWIsQ0FBWDtBQUNBLFlBQU0sQ0FBTjtBQUNBOztBQUVELFVBQUssSUFBSSxLQUFLLEdBQWQsRUFBbUIsTUFBTSxLQUFHLENBQTVCLEVBQStCLE1BQU0sQ0FBckMsRUFBd0M7QUFDdkMsWUFBTSxLQUFLLEVBQVg7QUFDQSxhQUFPLEVBQVA7QUFDQTtBQUNEO0FBQ0QsU0FBSyxLQUFLLEdBQUwsQ0FBUyxDQUFDLENBQUMsS0FBRyxDQUFKLElBQVMsS0FBSyxHQUFMLENBQVMsS0FBRyxFQUFaLENBQVQsR0FBMkIsS0FBSyxHQUFMLENBQVMsSUFBRSxLQUFLLEVBQVAsR0FBVSxFQUFuQixDQUEzQixHQUNaLEVBRFksR0FDUCxFQURPLEdBQ0YsSUFBRSxFQUFGLEdBQUssQ0FESixJQUNTLENBRGxCLENBQUw7QUFFQSxVQUFNLENBQUMsTUFBTSxFQUFQLElBQWEsRUFBbkI7QUFDQSxTQUFLLG1CQUFtQixFQUFuQixFQUF1QixDQUF2QixDQUFMO0FBQ0EsSUE5QkQsUUE4QlUsS0FBSyxFQUFOLElBQWMsS0FBSyxHQUFMLENBQVMsTUFBTSxFQUFmLElBQXFCLElBOUI1QztBQStCQTtBQUNEO0FBQ0QsUUFBTyxFQUFQO0FBQ0E7O0FBRUQsU0FBUyxLQUFULENBQWdCLEVBQWhCLEVBQW9CO0FBQ25CLFFBQU8sS0FBSyxHQUFMLENBQVMsRUFBVCxJQUFlLEtBQUssR0FBTCxDQUFTLEVBQVQsQ0FBdEI7QUFDQTs7QUFFRCxTQUFTLEdBQVQsR0FBZ0I7QUFDZixLQUFJLE9BQU8sVUFBVSxDQUFWLENBQVg7QUFDQSxNQUFLLElBQUksS0FBSyxDQUFkLEVBQWlCLElBQUksVUFBVSxNQUEvQixFQUF1QyxHQUF2QyxFQUE0QztBQUM3QixNQUFJLE9BQU8sVUFBVSxFQUFWLENBQVgsRUFDUSxPQUFPLFVBQVUsRUFBVixDQUFQO0FBQ3RCO0FBQ0QsUUFBTyxJQUFQO0FBQ0E7O0FBRUQsU0FBUyxHQUFULEdBQWdCO0FBQ2YsS0FBSSxPQUFPLFVBQVUsQ0FBVixDQUFYO0FBQ0EsTUFBSyxJQUFJLEtBQUssQ0FBZCxFQUFpQixJQUFJLFVBQVUsTUFBL0IsRUFBdUMsR0FBdkMsRUFBNEM7QUFDN0IsTUFBSSxPQUFPLFVBQVUsRUFBVixDQUFYLEVBQ1EsT0FBTyxVQUFVLEVBQVYsQ0FBUDtBQUN0QjtBQUNELFFBQU8sSUFBUDtBQUNBOztBQUVELFNBQVMsU0FBVCxDQUFvQixFQUFwQixFQUF3QjtBQUN2QixRQUFPLEtBQUssR0FBTCxDQUFTLFFBQVEsTUFBTSxLQUFLLEdBQUwsQ0FBUyxFQUFULENBQU4sSUFBc0IsV0FBOUIsQ0FBVCxDQUFQO0FBQ0E7O0FBRUQsU0FBUyxnQkFBVCxDQUEyQixFQUEzQixFQUErQjtBQUM5QixLQUFJLEVBQUosRUFBUTtBQUNQLFNBQU8sbUJBQW1CLEVBQW5CLEVBQXVCLFVBQVUsRUFBVixDQUF2QixDQUFQO0FBQ0EsRUFGRCxNQUVPO0FBQ04sU0FBTyxHQUFQO0FBQ0E7QUFDRDs7QUFFRCxTQUFTLGtCQUFULENBQTZCLEVBQTdCLEVBQWlDLEVBQWpDLEVBQXFDO0FBQzdCLE1BQUssS0FBSyxLQUFLLEdBQUwsQ0FBUyxFQUFULEVBQWEsRUFBYixDQUFWO0FBQ0EsTUFBSyxLQUFLLEtBQUwsQ0FBVyxFQUFYLENBQUw7QUFDQSxRQUFPLEtBQUssS0FBSyxHQUFMLENBQVMsRUFBVCxFQUFhLEVBQWIsQ0FBWjtBQUNQOztBQUVELFNBQVMsT0FBVCxDQUFrQixFQUFsQixFQUFzQjtBQUNkLEtBQUksS0FBSyxDQUFULEVBQ1EsT0FBTyxLQUFLLEtBQUwsQ0FBVyxFQUFYLENBQVAsQ0FEUixLQUdRLE9BQU8sS0FBSyxJQUFMLENBQVUsRUFBVixDQUFQO0FBQ2Y7Ozs7O0FDcGZEOztBQUVBLElBQUksS0FBSyxPQUFPLE9BQVAsQ0FBZSxlQUFmLEdBQWdDLEVBQXpDO0FBQ0EsR0FBRyxpQkFBSCxHQUF1QixRQUFRLDhEQUFSLENBQXZCO0FBQ0EsR0FBRyxnQkFBSCxHQUFzQixRQUFRLDZEQUFSLENBQXRCO0FBQ0EsR0FBRyxvQkFBSCxHQUEwQixRQUFRLGtFQUFSLENBQTFCO0FBQ0EsR0FBRyxhQUFILEdBQW1CLFFBQVEsMERBQVIsQ0FBbkI7QUFDQSxHQUFHLGlCQUFILEdBQXVCLFFBQVEsOERBQVIsQ0FBdkI7QUFDQSxHQUFHLHVCQUFILEdBQTZCLFFBQVEscUVBQVIsQ0FBN0I7QUFDQSxHQUFHLFFBQUgsR0FBYyxRQUFRLG9EQUFSLENBQWQ7QUFDQSxHQUFHLElBQUgsR0FBVSxRQUFRLGdEQUFSLENBQVY7QUFDQSxHQUFHLE1BQUgsR0FBWSxRQUFRLG1EQUFSLENBQVo7QUFDQSxHQUFHLGFBQUgsR0FBa0I7QUFBQSxXQUFPLEtBQUssSUFBTCxDQUFVLEdBQUcsUUFBSCxDQUFZLEdBQVosS0FBa0IsSUFBSSxNQUFKLEdBQVcsQ0FBN0IsQ0FBVixDQUFQO0FBQUEsQ0FBbEI7O0FBR0EsR0FBRyxNQUFILEdBQVcsVUFBQyxnQkFBRCxFQUFtQixtQkFBbkIsRUFBMkM7O0FBQ2xELFdBQU8scUNBQU8sZ0JBQVAsRUFBeUIsbUJBQXpCLENBQVA7QUFDSCxDQUZEOzs7Ozs7Ozs7Ozs7Ozs7OztJQ2ZhLEssV0FBQSxLOzs7Ozs7Ozs7bUNBR1MsRyxFQUFLOztBQUVuQixnQkFBSSxRQUFRLElBQVo7QUFDQSxnQkFBSSxXQUFXLEVBQWY7O0FBR0EsZ0JBQUksQ0FBQyxHQUFELElBQVEsVUFBVSxNQUFWLEdBQW1CLENBQTNCLElBQWdDLE1BQU0sT0FBTixDQUFjLFVBQVUsQ0FBVixDQUFkLENBQXBDLEVBQWlFO0FBQzdELHNCQUFNLEVBQU47QUFDSDtBQUNELGtCQUFNLE9BQU8sRUFBYjs7QUFFQSxpQkFBSyxJQUFJLElBQUksQ0FBYixFQUFnQixJQUFJLFVBQVUsTUFBOUIsRUFBc0MsR0FBdEMsRUFBMkM7QUFDdkMsb0JBQUksU0FBUyxVQUFVLENBQVYsQ0FBYjtBQUNBLG9CQUFJLENBQUMsTUFBTCxFQUNJOztBQUVKLHFCQUFLLElBQUksR0FBVCxJQUFnQixNQUFoQixFQUF3QjtBQUNwQix3QkFBSSxDQUFDLE9BQU8sY0FBUCxDQUFzQixHQUF0QixDQUFMLEVBQWlDO0FBQzdCO0FBQ0g7QUFDRCx3QkFBSSxVQUFVLE1BQU0sT0FBTixDQUFjLElBQUksR0FBSixDQUFkLENBQWQ7QUFDQSx3QkFBSSxXQUFXLE1BQU0sUUFBTixDQUFlLElBQUksR0FBSixDQUFmLENBQWY7QUFDQSx3QkFBSSxTQUFTLE1BQU0sUUFBTixDQUFlLE9BQU8sR0FBUCxDQUFmLENBQWI7O0FBRUEsd0JBQUksWUFBWSxDQUFDLE9BQWIsSUFBd0IsTUFBNUIsRUFBb0M7QUFDaEMsOEJBQU0sVUFBTixDQUFpQixJQUFJLEdBQUosQ0FBakIsRUFBMkIsT0FBTyxHQUFQLENBQTNCO0FBQ0gscUJBRkQsTUFFTztBQUNILDRCQUFJLEdBQUosSUFBVyxPQUFPLEdBQVAsQ0FBWDtBQUNIO0FBQ0o7QUFDSjs7QUFFRCxtQkFBTyxHQUFQO0FBQ0g7OztrQ0FFZ0IsTSxFQUFRLE0sRUFBUTtBQUM3QixnQkFBSSxTQUFTLE9BQU8sTUFBUCxDQUFjLEVBQWQsRUFBa0IsTUFBbEIsQ0FBYjtBQUNBLGdCQUFJLE1BQU0sZ0JBQU4sQ0FBdUIsTUFBdkIsS0FBa0MsTUFBTSxnQkFBTixDQUF1QixNQUF2QixDQUF0QyxFQUFzRTtBQUNsRSx1QkFBTyxJQUFQLENBQVksTUFBWixFQUFvQixPQUFwQixDQUE0QixlQUFPO0FBQy9CLHdCQUFJLE1BQU0sZ0JBQU4sQ0FBdUIsT0FBTyxHQUFQLENBQXZCLENBQUosRUFBeUM7QUFDckMsNEJBQUksRUFBRSxPQUFPLE1BQVQsQ0FBSixFQUNJLE9BQU8sTUFBUCxDQUFjLE1BQWQsc0JBQXdCLEdBQXhCLEVBQThCLE9BQU8sR0FBUCxDQUE5QixHQURKLEtBR0ksT0FBTyxHQUFQLElBQWMsTUFBTSxTQUFOLENBQWdCLE9BQU8sR0FBUCxDQUFoQixFQUE2QixPQUFPLEdBQVAsQ0FBN0IsQ0FBZDtBQUNQLHFCQUxELE1BS087QUFDSCwrQkFBTyxNQUFQLENBQWMsTUFBZCxzQkFBd0IsR0FBeEIsRUFBOEIsT0FBTyxHQUFQLENBQTlCO0FBQ0g7QUFDSixpQkFURDtBQVVIO0FBQ0QsbUJBQU8sTUFBUDtBQUNIOzs7OEJBRVksQyxFQUFHLEMsRUFBRztBQUNmLGdCQUFJLElBQUksRUFBUjtBQUFBLGdCQUFZLElBQUksRUFBRSxNQUFsQjtBQUFBLGdCQUEwQixJQUFJLEVBQUUsTUFBaEM7QUFBQSxnQkFBd0MsQ0FBeEM7QUFBQSxnQkFBMkMsQ0FBM0M7QUFDQSxpQkFBSyxJQUFJLENBQUMsQ0FBVixFQUFhLEVBQUUsQ0FBRixHQUFNLENBQW5CO0FBQXVCLHFCQUFLLElBQUksQ0FBQyxDQUFWLEVBQWEsRUFBRSxDQUFGLEdBQU0sQ0FBbkI7QUFBdUIsc0JBQUUsSUFBRixDQUFPLEVBQUMsR0FBRyxFQUFFLENBQUYsQ0FBSixFQUFVLEdBQUcsQ0FBYixFQUFnQixHQUFHLEVBQUUsQ0FBRixDQUFuQixFQUF5QixHQUFHLENBQTVCLEVBQVA7QUFBdkI7QUFBdkIsYUFDQSxPQUFPLENBQVA7QUFDSDs7O3VDQUVxQixJLEVBQU0sUSxFQUFVLFksRUFBYztBQUNoRCxnQkFBSSxNQUFNLEVBQVY7QUFDQSxnQkFBSSxLQUFLLE1BQVQsRUFBaUI7QUFDYixvQkFBSSxJQUFJLEtBQUssQ0FBTCxDQUFSO0FBQ0Esb0JBQUksYUFBYSxLQUFqQixFQUF3QjtBQUNwQiwwQkFBTSxFQUFFLEdBQUYsQ0FBTSxVQUFVLENBQVYsRUFBYSxDQUFiLEVBQWdCO0FBQ3hCLCtCQUFPLENBQVA7QUFDSCxxQkFGSyxDQUFOO0FBR0gsaUJBSkQsTUFJTyxJQUFJLFFBQU8sQ0FBUCx5Q0FBTyxDQUFQLE9BQWEsUUFBakIsRUFBMkI7O0FBRTlCLHlCQUFLLElBQUksSUFBVCxJQUFpQixDQUFqQixFQUFvQjtBQUNoQiw0QkFBSSxDQUFDLEVBQUUsY0FBRixDQUFpQixJQUFqQixDQUFMLEVBQTZCOztBQUU3Qiw0QkFBSSxJQUFKLENBQVMsSUFBVDtBQUNIO0FBQ0o7QUFDSjtBQUNELGdCQUFJLENBQUMsWUFBTCxFQUFtQjtBQUNmLG9CQUFJLFFBQVEsSUFBSSxPQUFKLENBQVksUUFBWixDQUFaO0FBQ0Esb0JBQUksUUFBUSxDQUFDLENBQWIsRUFBZ0I7QUFDWix3QkFBSSxNQUFKLENBQVcsS0FBWCxFQUFrQixDQUFsQjtBQUNIO0FBQ0o7QUFDRCxtQkFBTyxHQUFQO0FBQ0g7Ozt5Q0FFdUIsSSxFQUFNO0FBQzFCLG1CQUFRLFFBQVEsUUFBTyxJQUFQLHlDQUFPLElBQVAsT0FBZ0IsUUFBeEIsSUFBb0MsQ0FBQyxNQUFNLE9BQU4sQ0FBYyxJQUFkLENBQXJDLElBQTRELFNBQVMsSUFBN0U7QUFDSDs7O2lDQUVlLEMsRUFBRztBQUNmLG1CQUFPLE1BQU0sSUFBTixJQUFjLFFBQU8sQ0FBUCx5Q0FBTyxDQUFQLE9BQWEsUUFBbEM7QUFDSDs7O2lDQUVlLEMsRUFBRztBQUNmLG1CQUFPLENBQUMsTUFBTSxDQUFOLENBQUQsSUFBYSxPQUFPLENBQVAsS0FBYSxRQUFqQztBQUNIOzs7bUNBRWlCLEMsRUFBRztBQUNqQixtQkFBTyxPQUFPLENBQVAsS0FBYSxVQUFwQjtBQUNIOzs7K0JBRWEsQyxFQUFFO0FBQ1osbUJBQU8sT0FBTyxTQUFQLENBQWlCLFFBQWpCLENBQTBCLElBQTFCLENBQStCLENBQS9CLE1BQXNDLGVBQTdDO0FBQ0g7OztpQ0FFZSxDLEVBQUU7QUFDZCxtQkFBTyxPQUFPLENBQVAsS0FBYSxRQUFiLElBQXlCLGFBQWEsTUFBN0M7QUFDSDs7OytDQUU2QixNLEVBQVEsUSxFQUFVLFMsRUFBVyxNLEVBQVE7QUFDL0QsZ0JBQUksZ0JBQWdCLFNBQVMsS0FBVCxDQUFlLFVBQWYsQ0FBcEI7QUFDQSxnQkFBSSxVQUFVLE9BQU8sU0FBUCxFQUFrQixjQUFjLEtBQWQsRUFBbEIsRUFBeUMsTUFBekMsQ0FBZCxDO0FBQ0EsbUJBQU8sY0FBYyxNQUFkLEdBQXVCLENBQTlCLEVBQWlDO0FBQzdCLG9CQUFJLG1CQUFtQixjQUFjLEtBQWQsRUFBdkI7QUFDQSxvQkFBSSxlQUFlLGNBQWMsS0FBZCxFQUFuQjtBQUNBLG9CQUFJLHFCQUFxQixHQUF6QixFQUE4QjtBQUMxQiw4QkFBVSxRQUFRLE9BQVIsQ0FBZ0IsWUFBaEIsRUFBOEIsSUFBOUIsQ0FBVjtBQUNILGlCQUZELE1BRU8sSUFBSSxxQkFBcUIsR0FBekIsRUFBOEI7QUFDakMsOEJBQVUsUUFBUSxJQUFSLENBQWEsSUFBYixFQUFtQixZQUFuQixDQUFWO0FBQ0g7QUFDSjtBQUNELG1CQUFPLE9BQVA7QUFDSDs7O3VDQUVxQixNLEVBQVEsUSxFQUFVLE0sRUFBUTtBQUM1QyxtQkFBTyxNQUFNLHNCQUFOLENBQTZCLE1BQTdCLEVBQXFDLFFBQXJDLEVBQStDLFFBQS9DLEVBQXlELE1BQXpELENBQVA7QUFDSDs7O3VDQUVxQixNLEVBQVEsUSxFQUFVO0FBQ3BDLG1CQUFPLE1BQU0sc0JBQU4sQ0FBNkIsTUFBN0IsRUFBcUMsUUFBckMsRUFBK0MsUUFBL0MsQ0FBUDtBQUNIOzs7dUNBRXFCLE0sRUFBUSxRLEVBQVUsTyxFQUFTO0FBQzdDLGdCQUFJLFlBQVksT0FBTyxNQUFQLENBQWMsUUFBZCxDQUFoQjtBQUNBLGdCQUFJLFVBQVUsS0FBVixFQUFKLEVBQXVCO0FBQ25CLG9CQUFJLE9BQUosRUFBYTtBQUNULDJCQUFPLE9BQU8sTUFBUCxDQUFjLE9BQWQsQ0FBUDtBQUNIO0FBQ0QsdUJBQU8sTUFBTSxjQUFOLENBQXFCLE1BQXJCLEVBQTZCLFFBQTdCLENBQVA7QUFFSDtBQUNELG1CQUFPLFNBQVA7QUFDSDs7O3VDQUVxQixNLEVBQVEsUSxFQUFVLE0sRUFBUTtBQUM1QyxnQkFBSSxZQUFZLE9BQU8sTUFBUCxDQUFjLFFBQWQsQ0FBaEI7QUFDQSxnQkFBSSxVQUFVLEtBQVYsRUFBSixFQUF1QjtBQUNuQix1QkFBTyxNQUFNLGNBQU4sQ0FBcUIsTUFBckIsRUFBNkIsUUFBN0IsRUFBdUMsTUFBdkMsQ0FBUDtBQUNIO0FBQ0QsbUJBQU8sU0FBUDtBQUNIOzs7dUNBRXFCLEcsRUFBSyxVLEVBQVksSyxFQUFPLEUsRUFBSSxFLEVBQUksRSxFQUFJLEUsRUFBSTtBQUMxRCxnQkFBSSxPQUFPLE1BQU0sY0FBTixDQUFxQixHQUFyQixFQUEwQixNQUExQixDQUFYO0FBQ0EsZ0JBQUksaUJBQWlCLEtBQUssTUFBTCxDQUFZLGdCQUFaLEVBQ2hCLElBRGdCLENBQ1gsSUFEVyxFQUNMLFVBREssQ0FBckI7O0FBR0EsMkJBQ0ssSUFETCxDQUNVLElBRFYsRUFDZ0IsS0FBSyxHQURyQixFQUVLLElBRkwsQ0FFVSxJQUZWLEVBRWdCLEtBQUssR0FGckIsRUFHSyxJQUhMLENBR1UsSUFIVixFQUdnQixLQUFLLEdBSHJCLEVBSUssSUFKTCxDQUlVLElBSlYsRUFJZ0IsS0FBSyxHQUpyQjs7O0FBT0EsZ0JBQUksUUFBUSxlQUFlLFNBQWYsQ0FBeUIsTUFBekIsRUFDUCxJQURPLENBQ0YsS0FERSxDQUFaOztBQUdBLGtCQUFNLEtBQU4sR0FBYyxNQUFkLENBQXFCLE1BQXJCOztBQUVBLGtCQUFNLElBQU4sQ0FBVyxRQUFYLEVBQXFCLFVBQUMsQ0FBRCxFQUFJLENBQUo7QUFBQSx1QkFBVSxLQUFLLE1BQU0sTUFBTixHQUFlLENBQXBCLENBQVY7QUFBQSxhQUFyQixFQUNLLElBREwsQ0FDVSxZQURWLEVBQ3dCO0FBQUEsdUJBQUssQ0FBTDtBQUFBLGFBRHhCOztBQUdBLGtCQUFNLElBQU4sR0FBYSxNQUFiO0FBQ0g7OzsrQkFrQmE7QUFDVixxQkFBUyxFQUFULEdBQWM7QUFDVix1QkFBTyxLQUFLLEtBQUwsQ0FBVyxDQUFDLElBQUksS0FBSyxNQUFMLEVBQUwsSUFBc0IsT0FBakMsRUFDRixRQURFLENBQ08sRUFEUCxFQUVGLFNBRkUsQ0FFUSxDQUZSLENBQVA7QUFHSDs7QUFFRCxtQkFBTyxPQUFPLElBQVAsR0FBYyxHQUFkLEdBQW9CLElBQXBCLEdBQTJCLEdBQTNCLEdBQWlDLElBQWpDLEdBQXdDLEdBQXhDLEdBQ0gsSUFERyxHQUNJLEdBREosR0FDVSxJQURWLEdBQ2lCLElBRGpCLEdBQ3dCLElBRC9CO0FBRUg7Ozs7Ozs4Q0FHNEIsUyxFQUFXLFUsRUFBWSxLLEVBQU07QUFDdEQsZ0JBQUksVUFBVSxVQUFVLElBQVYsRUFBZDtBQUNBLG9CQUFRLFdBQVIsR0FBb0IsVUFBcEI7O0FBRUEsZ0JBQUksU0FBUyxDQUFiO0FBQ0EsZ0JBQUksaUJBQWlCLENBQXJCOztBQUVBLGdCQUFJLFFBQVEscUJBQVIsS0FBZ0MsUUFBTSxNQUExQyxFQUFpRDtBQUM3QyxxQkFBSyxJQUFJLElBQUUsV0FBVyxNQUFYLEdBQWtCLENBQTdCLEVBQStCLElBQUUsQ0FBakMsRUFBbUMsS0FBRyxDQUF0QyxFQUF3QztBQUNwQyx3QkFBSSxRQUFRLGtCQUFSLENBQTJCLENBQTNCLEVBQTZCLENBQTdCLElBQWdDLGNBQWhDLElBQWdELFFBQU0sTUFBMUQsRUFBaUU7QUFDN0QsZ0NBQVEsV0FBUixHQUFvQixXQUFXLFNBQVgsQ0FBcUIsQ0FBckIsRUFBdUIsQ0FBdkIsSUFBMEIsS0FBOUM7QUFDQSwrQkFBTyxJQUFQO0FBQ0g7QUFDSjtBQUNELHdCQUFRLFdBQVIsR0FBb0IsS0FBcEIsQztBQUNBLHVCQUFPLElBQVA7QUFDSDtBQUNELG1CQUFPLEtBQVA7QUFDSDs7O3dEQUVzQyxTLEVBQVcsVSxFQUFZLEssRUFBTyxPLEVBQVE7QUFDekUsZ0JBQUksaUJBQWlCLE1BQU0scUJBQU4sQ0FBNEIsU0FBNUIsRUFBdUMsVUFBdkMsRUFBbUQsS0FBbkQsQ0FBckI7QUFDQSxnQkFBRyxrQkFBa0IsT0FBckIsRUFBNkI7QUFDekIsMEJBQVUsRUFBVixDQUFhLFdBQWIsRUFBMEIsVUFBVSxDQUFWLEVBQWE7QUFDbkMsNEJBQVEsVUFBUixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsRUFGdEI7QUFHQSw0QkFBUSxJQUFSLENBQWEsVUFBYixFQUNLLEtBREwsQ0FDVyxNQURYLEVBQ29CLEdBQUcsS0FBSCxDQUFTLEtBQVQsR0FBaUIsQ0FBbEIsR0FBdUIsSUFEMUMsRUFFSyxLQUZMLENBRVcsS0FGWCxFQUVtQixHQUFHLEtBQUgsQ0FBUyxLQUFULEdBQWlCLEVBQWxCLEdBQXdCLElBRjFDO0FBR0gsaUJBUEQ7O0FBU0EsMEJBQVUsRUFBVixDQUFhLFVBQWIsRUFBeUIsVUFBVSxDQUFWLEVBQWE7QUFDbEMsNEJBQVEsVUFBUixHQUNLLFFBREwsQ0FDYyxHQURkLEVBRUssS0FGTCxDQUVXLFNBRlgsRUFFc0IsQ0FGdEI7QUFHSCxpQkFKRDtBQUtIO0FBRUo7OztvQ0FFa0IsTyxFQUFRO0FBQ3ZCLG1CQUFPLE9BQU8sZ0JBQVAsQ0FBd0IsT0FBeEIsRUFBaUMsSUFBakMsRUFBdUMsZ0JBQXZDLENBQXdELFdBQXhELENBQVA7QUFDSDs7Ozs7O0FBeFBRLEssQ0FDRixNLEdBQVMsYTs7QUFEUCxLLENBaUxGLGMsR0FBaUIsVUFBVSxNQUFWLEVBQWtCLFNBQWxCLEVBQTZCO0FBQ2pELFdBQVEsVUFBVSxTQUFTLFVBQVUsS0FBVixDQUFnQixRQUFoQixDQUFULEVBQW9DLEVBQXBDLENBQVYsSUFBcUQsR0FBN0Q7QUFDSCxDOztBQW5MUSxLLENBcUxGLGEsR0FBZ0IsVUFBVSxLQUFWLEVBQWlCLFNBQWpCLEVBQTRCO0FBQy9DLFdBQVEsU0FBUyxTQUFTLFVBQVUsS0FBVixDQUFnQixPQUFoQixDQUFULEVBQW1DLEVBQW5DLENBQVQsSUFBbUQsR0FBM0Q7QUFDSCxDOztBQXZMUSxLLENBeUxGLGUsR0FBa0IsVUFBVSxNQUFWLEVBQWtCLFNBQWxCLEVBQTZCLE1BQTdCLEVBQXFDO0FBQzFELFdBQU8sS0FBSyxHQUFMLENBQVMsQ0FBVCxFQUFZLE1BQU0sY0FBTixDQUFxQixNQUFyQixFQUE2QixTQUE3QixJQUEwQyxPQUFPLEdBQWpELEdBQXVELE9BQU8sTUFBMUUsQ0FBUDtBQUNILEM7O0FBM0xRLEssQ0E2TEYsYyxHQUFpQixVQUFVLEtBQVYsRUFBaUIsU0FBakIsRUFBNEIsTUFBNUIsRUFBb0M7QUFDeEQsV0FBTyxLQUFLLEdBQUwsQ0FBUyxDQUFULEVBQVksTUFBTSxhQUFOLENBQW9CLEtBQXBCLEVBQTJCLFNBQTNCLElBQXdDLE9BQU8sSUFBL0MsR0FBc0QsT0FBTyxLQUF6RSxDQUFQO0FBQ0gsQyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJtb2R1bGUuZXhwb3J0cyA9IHtcclxuICBjb2xvcjogcmVxdWlyZSgnLi9zcmMvY29sb3InKSxcclxuICBzaXplOiByZXF1aXJlKCcuL3NyYy9zaXplJyksXHJcbiAgc3ltYm9sOiByZXF1aXJlKCcuL3NyYy9zeW1ib2wnKVxyXG59O1xyXG4iLCJ2YXIgaGVscGVyID0gcmVxdWlyZSgnLi9sZWdlbmQnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKXtcclxuXHJcbiAgdmFyIHNjYWxlID0gZDMuc2NhbGUubGluZWFyKCksXHJcbiAgICBzaGFwZSA9IFwicmVjdFwiLFxyXG4gICAgc2hhcGVXaWR0aCA9IDE1LFxyXG4gICAgc2hhcGVIZWlnaHQgPSAxNSxcclxuICAgIHNoYXBlUmFkaXVzID0gMTAsXHJcbiAgICBzaGFwZVBhZGRpbmcgPSAyLFxyXG4gICAgY2VsbHMgPSBbNV0sXHJcbiAgICBsYWJlbHMgPSBbXSxcclxuICAgIGNsYXNzUHJlZml4ID0gXCJcIixcclxuICAgIHVzZUNsYXNzID0gZmFsc2UsXHJcbiAgICB0aXRsZSA9IFwiXCIsXHJcbiAgICBsYWJlbEZvcm1hdCA9IGQzLmZvcm1hdChcIi4wMWZcIiksXHJcbiAgICBsYWJlbE9mZnNldCA9IDEwLFxyXG4gICAgbGFiZWxBbGlnbiA9IFwibWlkZGxlXCIsXHJcbiAgICBsYWJlbERlbGltaXRlciA9IFwidG9cIixcclxuICAgIG9yaWVudCA9IFwidmVydGljYWxcIixcclxuICAgIGFzY2VuZGluZyA9IGZhbHNlLFxyXG4gICAgcGF0aCxcclxuICAgIGxlZ2VuZERpc3BhdGNoZXIgPSBkMy5kaXNwYXRjaChcImNlbGxvdmVyXCIsIFwiY2VsbG91dFwiLCBcImNlbGxjbGlja1wiKTtcclxuXHJcbiAgICBmdW5jdGlvbiBsZWdlbmQoc3ZnKXtcclxuXHJcbiAgICAgIHZhciB0eXBlID0gaGVscGVyLmQzX2NhbGNUeXBlKHNjYWxlLCBhc2NlbmRpbmcsIGNlbGxzLCBsYWJlbHMsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlciksXHJcbiAgICAgICAgbGVnZW5kRyA9IHN2Zy5zZWxlY3RBbGwoJ2cnKS5kYXRhKFtzY2FsZV0pO1xyXG5cclxuICAgICAgbGVnZW5kRy5lbnRlcigpLmFwcGVuZCgnZycpLmF0dHIoJ2NsYXNzJywgY2xhc3NQcmVmaXggKyAnbGVnZW5kQ2VsbHMnKTtcclxuXHJcblxyXG4gICAgICB2YXIgY2VsbCA9IGxlZ2VuZEcuc2VsZWN0QWxsKFwiLlwiICsgY2xhc3NQcmVmaXggKyBcImNlbGxcIikuZGF0YSh0eXBlLmRhdGEpLFxyXG4gICAgICAgIGNlbGxFbnRlciA9IGNlbGwuZW50ZXIoKS5hcHBlbmQoXCJnXCIsIFwiLmNlbGxcIikuYXR0cihcImNsYXNzXCIsIGNsYXNzUHJlZml4ICsgXCJjZWxsXCIpLnN0eWxlKFwib3BhY2l0eVwiLCAxZS02KSxcclxuICAgICAgICBzaGFwZUVudGVyID0gY2VsbEVudGVyLmFwcGVuZChzaGFwZSkuYXR0cihcImNsYXNzXCIsIGNsYXNzUHJlZml4ICsgXCJzd2F0Y2hcIiksXHJcbiAgICAgICAgc2hhcGVzID0gY2VsbC5zZWxlY3QoXCJnLlwiICsgY2xhc3NQcmVmaXggKyBcImNlbGwgXCIgKyBzaGFwZSk7XHJcblxyXG4gICAgICAvL2FkZCBldmVudCBoYW5kbGVyc1xyXG4gICAgICBoZWxwZXIuZDNfYWRkRXZlbnRzKGNlbGxFbnRlciwgbGVnZW5kRGlzcGF0Y2hlcik7XHJcblxyXG4gICAgICBjZWxsLmV4aXQoKS50cmFuc2l0aW9uKCkuc3R5bGUoXCJvcGFjaXR5XCIsIDApLnJlbW92ZSgpO1xyXG5cclxuICAgICAgaGVscGVyLmQzX2RyYXdTaGFwZXMoc2hhcGUsIHNoYXBlcywgc2hhcGVIZWlnaHQsIHNoYXBlV2lkdGgsIHNoYXBlUmFkaXVzLCBwYXRoKTtcclxuXHJcbiAgICAgIGhlbHBlci5kM19hZGRUZXh0KGxlZ2VuZEcsIGNlbGxFbnRlciwgdHlwZS5sYWJlbHMsIGNsYXNzUHJlZml4KVxyXG5cclxuICAgICAgLy8gc2V0cyBwbGFjZW1lbnRcclxuICAgICAgdmFyIHRleHQgPSBjZWxsLnNlbGVjdChcInRleHRcIiksXHJcbiAgICAgICAgc2hhcGVTaXplID0gc2hhcGVzWzBdLm1hcCggZnVuY3Rpb24oZCl7IHJldHVybiBkLmdldEJCb3goKTsgfSk7XHJcblxyXG4gICAgICAvL3NldHMgc2NhbGVcclxuICAgICAgLy9ldmVyeXRoaW5nIGlzIGZpbGwgZXhjZXB0IGZvciBsaW5lIHdoaWNoIGlzIHN0cm9rZSxcclxuICAgICAgaWYgKCF1c2VDbGFzcyl7XHJcbiAgICAgICAgaWYgKHNoYXBlID09IFwibGluZVwiKXtcclxuICAgICAgICAgIHNoYXBlcy5zdHlsZShcInN0cm9rZVwiLCB0eXBlLmZlYXR1cmUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBzaGFwZXMuc3R5bGUoXCJmaWxsXCIsIHR5cGUuZmVhdHVyZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNoYXBlcy5hdHRyKFwiY2xhc3NcIiwgZnVuY3Rpb24oZCl7IHJldHVybiBjbGFzc1ByZWZpeCArIFwic3dhdGNoIFwiICsgdHlwZS5mZWF0dXJlKGQpOyB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGNlbGxUcmFucyxcclxuICAgICAgdGV4dFRyYW5zLFxyXG4gICAgICB0ZXh0QWxpZ24gPSAobGFiZWxBbGlnbiA9PSBcInN0YXJ0XCIpID8gMCA6IChsYWJlbEFsaWduID09IFwibWlkZGxlXCIpID8gMC41IDogMTtcclxuXHJcbiAgICAgIC8vcG9zaXRpb25zIGNlbGxzIGFuZCB0ZXh0XHJcbiAgICAgIGlmIChvcmllbnQgPT09IFwidmVydGljYWxcIil7XHJcbiAgICAgICAgY2VsbFRyYW5zID0gZnVuY3Rpb24oZCxpKSB7IHJldHVybiBcInRyYW5zbGF0ZSgwLCBcIiArIChpICogKHNoYXBlU2l6ZVtpXS5oZWlnaHQgKyBzaGFwZVBhZGRpbmcpKSArIFwiKVwiOyB9O1xyXG4gICAgICAgIHRleHRUcmFucyA9IGZ1bmN0aW9uKGQsaSkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyAoc2hhcGVTaXplW2ldLndpZHRoICsgc2hhcGVTaXplW2ldLnggK1xyXG4gICAgICAgICAgbGFiZWxPZmZzZXQpICsgXCIsXCIgKyAoc2hhcGVTaXplW2ldLnkgKyBzaGFwZVNpemVbaV0uaGVpZ2h0LzIgKyA1KSArIFwiKVwiOyB9O1xyXG5cclxuICAgICAgfSBlbHNlIGlmIChvcmllbnQgPT09IFwiaG9yaXpvbnRhbFwiKXtcclxuICAgICAgICBjZWxsVHJhbnMgPSBmdW5jdGlvbihkLGkpIHsgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgKGkgKiAoc2hhcGVTaXplW2ldLndpZHRoICsgc2hhcGVQYWRkaW5nKSkgKyBcIiwwKVwiOyB9XHJcbiAgICAgICAgdGV4dFRyYW5zID0gZnVuY3Rpb24oZCxpKSB7IHJldHVybiBcInRyYW5zbGF0ZShcIiArIChzaGFwZVNpemVbaV0ud2lkdGgqdGV4dEFsaWduICArIHNoYXBlU2l6ZVtpXS54KSArXHJcbiAgICAgICAgICBcIixcIiArIChzaGFwZVNpemVbaV0uaGVpZ2h0ICsgc2hhcGVTaXplW2ldLnkgKyBsYWJlbE9mZnNldCArIDgpICsgXCIpXCI7IH07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGhlbHBlci5kM19wbGFjZW1lbnQob3JpZW50LCBjZWxsLCBjZWxsVHJhbnMsIHRleHQsIHRleHRUcmFucywgbGFiZWxBbGlnbik7XHJcbiAgICAgIGhlbHBlci5kM190aXRsZShzdmcsIGxlZ2VuZEcsIHRpdGxlLCBjbGFzc1ByZWZpeCk7XHJcblxyXG4gICAgICBjZWxsLnRyYW5zaXRpb24oKS5zdHlsZShcIm9wYWNpdHlcIiwgMSk7XHJcblxyXG4gICAgfVxyXG5cclxuXHJcblxyXG4gIGxlZ2VuZC5zY2FsZSA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNjYWxlO1xyXG4gICAgc2NhbGUgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuY2VsbHMgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBjZWxscztcclxuICAgIGlmIChfLmxlbmd0aCA+IDEgfHwgXyA+PSAyICl7XHJcbiAgICAgIGNlbGxzID0gXztcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnNoYXBlID0gZnVuY3Rpb24oXywgZCkge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2hhcGU7XHJcbiAgICBpZiAoXyA9PSBcInJlY3RcIiB8fCBfID09IFwiY2lyY2xlXCIgfHwgXyA9PSBcImxpbmVcIiB8fCAoXyA9PSBcInBhdGhcIiAmJiAodHlwZW9mIGQgPT09ICdzdHJpbmcnKSkgKXtcclxuICAgICAgc2hhcGUgPSBfO1xyXG4gICAgICBwYXRoID0gZDtcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnNoYXBlV2lkdGggPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzaGFwZVdpZHRoO1xyXG4gICAgc2hhcGVXaWR0aCA9ICtfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuc2hhcGVIZWlnaHQgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzaGFwZUhlaWdodDtcclxuICAgIHNoYXBlSGVpZ2h0ID0gK187XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5zaGFwZVJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNoYXBlUmFkaXVzO1xyXG4gICAgc2hhcGVSYWRpdXMgPSArXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnNoYXBlUGFkZGluZyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNoYXBlUGFkZGluZztcclxuICAgIHNoYXBlUGFkZGluZyA9ICtfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxzID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGFiZWxzO1xyXG4gICAgbGFiZWxzID0gXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmxhYmVsQWxpZ24gPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbEFsaWduO1xyXG4gICAgaWYgKF8gPT0gXCJzdGFydFwiIHx8IF8gPT0gXCJlbmRcIiB8fCBfID09IFwibWlkZGxlXCIpIHtcclxuICAgICAgbGFiZWxBbGlnbiA9IF87XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbEZvcm1hdCA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsRm9ybWF0O1xyXG4gICAgbGFiZWxGb3JtYXQgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxPZmZzZXQgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbE9mZnNldDtcclxuICAgIGxhYmVsT2Zmc2V0ID0gK187XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbERlbGltaXRlciA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsRGVsaW1pdGVyO1xyXG4gICAgbGFiZWxEZWxpbWl0ZXIgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQudXNlQ2xhc3MgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB1c2VDbGFzcztcclxuICAgIGlmIChfID09PSB0cnVlIHx8IF8gPT09IGZhbHNlKXtcclxuICAgICAgdXNlQ2xhc3MgPSBfO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQub3JpZW50ID0gZnVuY3Rpb24oXyl7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBvcmllbnQ7XHJcbiAgICBfID0gXy50b0xvd2VyQ2FzZSgpO1xyXG4gICAgaWYgKF8gPT0gXCJob3Jpem9udGFsXCIgfHwgXyA9PSBcInZlcnRpY2FsXCIpIHtcclxuICAgICAgb3JpZW50ID0gXztcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmFzY2VuZGluZyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGFzY2VuZGluZztcclxuICAgIGFzY2VuZGluZyA9ICEhXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmNsYXNzUHJlZml4ID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2xhc3NQcmVmaXg7XHJcbiAgICBjbGFzc1ByZWZpeCA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC50aXRsZSA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRpdGxlO1xyXG4gICAgdGl0bGUgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBkMy5yZWJpbmQobGVnZW5kLCBsZWdlbmREaXNwYXRjaGVyLCBcIm9uXCIpO1xyXG5cclxuICByZXR1cm4gbGVnZW5kO1xyXG5cclxufTtcclxuIiwibW9kdWxlLmV4cG9ydHMgPSB7XHJcblxyXG4gIGQzX2lkZW50aXR5OiBmdW5jdGlvbiAoZCkge1xyXG4gICAgcmV0dXJuIGQ7XHJcbiAgfSxcclxuXHJcbiAgZDNfbWVyZ2VMYWJlbHM6IGZ1bmN0aW9uIChnZW4sIGxhYmVscykge1xyXG5cclxuICAgICAgaWYobGFiZWxzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGdlbjtcclxuXHJcbiAgICAgIGdlbiA9IChnZW4pID8gZ2VuIDogW107XHJcblxyXG4gICAgICB2YXIgaSA9IGxhYmVscy5sZW5ndGg7XHJcbiAgICAgIGZvciAoOyBpIDwgZ2VuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGFiZWxzLnB1c2goZ2VuW2ldKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gbGFiZWxzO1xyXG4gICAgfSxcclxuXHJcbiAgZDNfbGluZWFyTGVnZW5kOiBmdW5jdGlvbiAoc2NhbGUsIGNlbGxzLCBsYWJlbEZvcm1hdCkge1xyXG4gICAgdmFyIGRhdGEgPSBbXTtcclxuXHJcbiAgICBpZiAoY2VsbHMubGVuZ3RoID4gMSl7XHJcbiAgICAgIGRhdGEgPSBjZWxscztcclxuXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXIgZG9tYWluID0gc2NhbGUuZG9tYWluKCksXHJcbiAgICAgIGluY3JlbWVudCA9IChkb21haW5bZG9tYWluLmxlbmd0aCAtIDFdIC0gZG9tYWluWzBdKS8oY2VsbHMgLSAxKSxcclxuICAgICAgaSA9IDA7XHJcblxyXG4gICAgICBmb3IgKDsgaSA8IGNlbGxzOyBpKyspe1xyXG4gICAgICAgIGRhdGEucHVzaChkb21haW5bMF0gKyBpKmluY3JlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2YXIgbGFiZWxzID0gZGF0YS5tYXAobGFiZWxGb3JtYXQpO1xyXG5cclxuICAgIHJldHVybiB7ZGF0YTogZGF0YSxcclxuICAgICAgICAgICAgbGFiZWxzOiBsYWJlbHMsXHJcbiAgICAgICAgICAgIGZlYXR1cmU6IGZ1bmN0aW9uKGQpeyByZXR1cm4gc2NhbGUoZCk7IH19O1xyXG4gIH0sXHJcblxyXG4gIGQzX3F1YW50TGVnZW5kOiBmdW5jdGlvbiAoc2NhbGUsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlcikge1xyXG4gICAgdmFyIGxhYmVscyA9IHNjYWxlLnJhbmdlKCkubWFwKGZ1bmN0aW9uKGQpe1xyXG4gICAgICB2YXIgaW52ZXJ0ID0gc2NhbGUuaW52ZXJ0RXh0ZW50KGQpLFxyXG4gICAgICBhID0gbGFiZWxGb3JtYXQoaW52ZXJ0WzBdKSxcclxuICAgICAgYiA9IGxhYmVsRm9ybWF0KGludmVydFsxXSk7XHJcblxyXG4gICAgICAvLyBpZiAoKCAoYSkgJiYgKGEuaXNOYW4oKSkgJiYgYil7XHJcbiAgICAgIC8vICAgY29uc29sZS5sb2coXCJpbiBpbml0aWFsIHN0YXRlbWVudFwiKVxyXG4gICAgICAgIHJldHVybiBsYWJlbEZvcm1hdChpbnZlcnRbMF0pICsgXCIgXCIgKyBsYWJlbERlbGltaXRlciArIFwiIFwiICsgbGFiZWxGb3JtYXQoaW52ZXJ0WzFdKTtcclxuICAgICAgLy8gfSBlbHNlIGlmIChhIHx8IGIpIHtcclxuICAgICAgLy8gICBjb25zb2xlLmxvZygnaW4gZWxzZSBzdGF0ZW1lbnQnKVxyXG4gICAgICAvLyAgIHJldHVybiAoYSkgPyBhIDogYjtcclxuICAgICAgLy8gfVxyXG5cclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB7ZGF0YTogc2NhbGUucmFuZ2UoKSxcclxuICAgICAgICAgICAgbGFiZWxzOiBsYWJlbHMsXHJcbiAgICAgICAgICAgIGZlYXR1cmU6IHRoaXMuZDNfaWRlbnRpdHlcclxuICAgICAgICAgIH07XHJcbiAgfSxcclxuXHJcbiAgZDNfb3JkaW5hbExlZ2VuZDogZnVuY3Rpb24gKHNjYWxlKSB7XHJcbiAgICByZXR1cm4ge2RhdGE6IHNjYWxlLmRvbWFpbigpLFxyXG4gICAgICAgICAgICBsYWJlbHM6IHNjYWxlLmRvbWFpbigpLFxyXG4gICAgICAgICAgICBmZWF0dXJlOiBmdW5jdGlvbihkKXsgcmV0dXJuIHNjYWxlKGQpOyB9fTtcclxuICB9LFxyXG5cclxuICBkM19kcmF3U2hhcGVzOiBmdW5jdGlvbiAoc2hhcGUsIHNoYXBlcywgc2hhcGVIZWlnaHQsIHNoYXBlV2lkdGgsIHNoYXBlUmFkaXVzLCBwYXRoKSB7XHJcbiAgICBpZiAoc2hhcGUgPT09IFwicmVjdFwiKXtcclxuICAgICAgICBzaGFwZXMuYXR0cihcImhlaWdodFwiLCBzaGFwZUhlaWdodCkuYXR0cihcIndpZHRoXCIsIHNoYXBlV2lkdGgpO1xyXG5cclxuICAgIH0gZWxzZSBpZiAoc2hhcGUgPT09IFwiY2lyY2xlXCIpIHtcclxuICAgICAgICBzaGFwZXMuYXR0cihcInJcIiwgc2hhcGVSYWRpdXMpLy8uYXR0cihcImN4XCIsIHNoYXBlUmFkaXVzKS5hdHRyKFwiY3lcIiwgc2hhcGVSYWRpdXMpO1xyXG5cclxuICAgIH0gZWxzZSBpZiAoc2hhcGUgPT09IFwibGluZVwiKSB7XHJcbiAgICAgICAgc2hhcGVzLmF0dHIoXCJ4MVwiLCAwKS5hdHRyKFwieDJcIiwgc2hhcGVXaWR0aCkuYXR0cihcInkxXCIsIDApLmF0dHIoXCJ5MlwiLCAwKTtcclxuXHJcbiAgICB9IGVsc2UgaWYgKHNoYXBlID09PSBcInBhdGhcIikge1xyXG4gICAgICBzaGFwZXMuYXR0cihcImRcIiwgcGF0aCk7XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgZDNfYWRkVGV4dDogZnVuY3Rpb24gKHN2ZywgZW50ZXIsIGxhYmVscywgY2xhc3NQcmVmaXgpe1xyXG4gICAgZW50ZXIuYXBwZW5kKFwidGV4dFwiKS5hdHRyKFwiY2xhc3NcIiwgY2xhc3NQcmVmaXggKyBcImxhYmVsXCIpO1xyXG4gICAgc3ZnLnNlbGVjdEFsbChcImcuXCIgKyBjbGFzc1ByZWZpeCArIFwiY2VsbCB0ZXh0XCIpLmRhdGEobGFiZWxzKS50ZXh0KHRoaXMuZDNfaWRlbnRpdHkpO1xyXG4gIH0sXHJcblxyXG4gIGQzX2NhbGNUeXBlOiBmdW5jdGlvbiAoc2NhbGUsIGFzY2VuZGluZywgY2VsbHMsIGxhYmVscywgbGFiZWxGb3JtYXQsIGxhYmVsRGVsaW1pdGVyKXtcclxuICAgIHZhciB0eXBlID0gc2NhbGUudGlja3MgP1xyXG4gICAgICAgICAgICB0aGlzLmQzX2xpbmVhckxlZ2VuZChzY2FsZSwgY2VsbHMsIGxhYmVsRm9ybWF0KSA6IHNjYWxlLmludmVydEV4dGVudCA/XHJcbiAgICAgICAgICAgIHRoaXMuZDNfcXVhbnRMZWdlbmQoc2NhbGUsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlcikgOiB0aGlzLmQzX29yZGluYWxMZWdlbmQoc2NhbGUpO1xyXG5cclxuICAgIHR5cGUubGFiZWxzID0gdGhpcy5kM19tZXJnZUxhYmVscyh0eXBlLmxhYmVscywgbGFiZWxzKTtcclxuXHJcbiAgICBpZiAoYXNjZW5kaW5nKSB7XHJcbiAgICAgIHR5cGUubGFiZWxzID0gdGhpcy5kM19yZXZlcnNlKHR5cGUubGFiZWxzKTtcclxuICAgICAgdHlwZS5kYXRhID0gdGhpcy5kM19yZXZlcnNlKHR5cGUuZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHR5cGU7XHJcbiAgfSxcclxuXHJcbiAgZDNfcmV2ZXJzZTogZnVuY3Rpb24oYXJyKSB7XHJcbiAgICB2YXIgbWlycm9yID0gW107XHJcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGFyci5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgbWlycm9yW2ldID0gYXJyW2wtaS0xXTtcclxuICAgIH1cclxuICAgIHJldHVybiBtaXJyb3I7XHJcbiAgfSxcclxuXHJcbiAgZDNfcGxhY2VtZW50OiBmdW5jdGlvbiAob3JpZW50LCBjZWxsLCBjZWxsVHJhbnMsIHRleHQsIHRleHRUcmFucywgbGFiZWxBbGlnbikge1xyXG4gICAgY2VsbC5hdHRyKFwidHJhbnNmb3JtXCIsIGNlbGxUcmFucyk7XHJcbiAgICB0ZXh0LmF0dHIoXCJ0cmFuc2Zvcm1cIiwgdGV4dFRyYW5zKTtcclxuICAgIGlmIChvcmllbnQgPT09IFwiaG9yaXpvbnRhbFwiKXtcclxuICAgICAgdGV4dC5zdHlsZShcInRleHQtYW5jaG9yXCIsIGxhYmVsQWxpZ24pO1xyXG4gICAgfVxyXG4gIH0sXHJcblxyXG4gIGQzX2FkZEV2ZW50czogZnVuY3Rpb24oY2VsbHMsIGRpc3BhdGNoZXIpe1xyXG4gICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgY2VsbHMub24oXCJtb3VzZW92ZXIubGVnZW5kXCIsIGZ1bmN0aW9uIChkKSB7IF8uZDNfY2VsbE92ZXIoZGlzcGF0Y2hlciwgZCwgdGhpcyk7IH0pXHJcbiAgICAgICAgICAub24oXCJtb3VzZW91dC5sZWdlbmRcIiwgZnVuY3Rpb24gKGQpIHsgXy5kM19jZWxsT3V0KGRpc3BhdGNoZXIsIGQsIHRoaXMpOyB9KVxyXG4gICAgICAgICAgLm9uKFwiY2xpY2subGVnZW5kXCIsIGZ1bmN0aW9uIChkKSB7IF8uZDNfY2VsbENsaWNrKGRpc3BhdGNoZXIsIGQsIHRoaXMpOyB9KTtcclxuICB9LFxyXG5cclxuICBkM19jZWxsT3ZlcjogZnVuY3Rpb24oY2VsbERpc3BhdGNoZXIsIGQsIG9iail7XHJcbiAgICBjZWxsRGlzcGF0Y2hlci5jZWxsb3Zlci5jYWxsKG9iaiwgZCk7XHJcbiAgfSxcclxuXHJcbiAgZDNfY2VsbE91dDogZnVuY3Rpb24oY2VsbERpc3BhdGNoZXIsIGQsIG9iail7XHJcbiAgICBjZWxsRGlzcGF0Y2hlci5jZWxsb3V0LmNhbGwob2JqLCBkKTtcclxuICB9LFxyXG5cclxuICBkM19jZWxsQ2xpY2s6IGZ1bmN0aW9uKGNlbGxEaXNwYXRjaGVyLCBkLCBvYmope1xyXG4gICAgY2VsbERpc3BhdGNoZXIuY2VsbGNsaWNrLmNhbGwob2JqLCBkKTtcclxuICB9LFxyXG5cclxuICBkM190aXRsZTogZnVuY3Rpb24oc3ZnLCBjZWxsc1N2ZywgdGl0bGUsIGNsYXNzUHJlZml4KXtcclxuICAgIGlmICh0aXRsZSAhPT0gXCJcIil7XHJcblxyXG4gICAgICB2YXIgdGl0bGVUZXh0ID0gc3ZnLnNlbGVjdEFsbCgndGV4dC4nICsgY2xhc3NQcmVmaXggKyAnbGVnZW5kVGl0bGUnKTtcclxuXHJcbiAgICAgIHRpdGxlVGV4dC5kYXRhKFt0aXRsZV0pXHJcbiAgICAgICAgLmVudGVyKClcclxuICAgICAgICAuYXBwZW5kKCd0ZXh0JylcclxuICAgICAgICAuYXR0cignY2xhc3MnLCBjbGFzc1ByZWZpeCArICdsZWdlbmRUaXRsZScpO1xyXG5cclxuICAgICAgICBzdmcuc2VsZWN0QWxsKCd0ZXh0LicgKyBjbGFzc1ByZWZpeCArICdsZWdlbmRUaXRsZScpXHJcbiAgICAgICAgICAgIC50ZXh0KHRpdGxlKVxyXG5cclxuICAgICAgdmFyIHlPZmZzZXQgPSBzdmcuc2VsZWN0KCcuJyArIGNsYXNzUHJlZml4ICsgJ2xlZ2VuZFRpdGxlJylcclxuICAgICAgICAgIC5tYXAoZnVuY3Rpb24oZCkgeyByZXR1cm4gZFswXS5nZXRCQm94KCkuaGVpZ2h0fSlbMF0sXHJcbiAgICAgIHhPZmZzZXQgPSAtY2VsbHNTdmcubWFwKGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGRbMF0uZ2V0QkJveCgpLnh9KVswXTtcclxuXHJcbiAgICAgIGNlbGxzU3ZnLmF0dHIoJ3RyYW5zZm9ybScsICd0cmFuc2xhdGUoJyArIHhPZmZzZXQgKyAnLCcgKyAoeU9mZnNldCArIDEwKSArICcpJyk7XHJcblxyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCJ2YXIgaGVscGVyID0gcmVxdWlyZSgnLi9sZWdlbmQnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gIGZ1bmN0aW9uKCl7XHJcblxyXG4gIHZhciBzY2FsZSA9IGQzLnNjYWxlLmxpbmVhcigpLFxyXG4gICAgc2hhcGUgPSBcInJlY3RcIixcclxuICAgIHNoYXBlV2lkdGggPSAxNSxcclxuICAgIHNoYXBlUGFkZGluZyA9IDIsXHJcbiAgICBjZWxscyA9IFs1XSxcclxuICAgIGxhYmVscyA9IFtdLFxyXG4gICAgdXNlU3Ryb2tlID0gZmFsc2UsXHJcbiAgICBjbGFzc1ByZWZpeCA9IFwiXCIsXHJcbiAgICB0aXRsZSA9IFwiXCIsXHJcbiAgICBsYWJlbEZvcm1hdCA9IGQzLmZvcm1hdChcIi4wMWZcIiksXHJcbiAgICBsYWJlbE9mZnNldCA9IDEwLFxyXG4gICAgbGFiZWxBbGlnbiA9IFwibWlkZGxlXCIsXHJcbiAgICBsYWJlbERlbGltaXRlciA9IFwidG9cIixcclxuICAgIG9yaWVudCA9IFwidmVydGljYWxcIixcclxuICAgIGFzY2VuZGluZyA9IGZhbHNlLFxyXG4gICAgcGF0aCxcclxuICAgIGxlZ2VuZERpc3BhdGNoZXIgPSBkMy5kaXNwYXRjaChcImNlbGxvdmVyXCIsIFwiY2VsbG91dFwiLCBcImNlbGxjbGlja1wiKTtcclxuXHJcbiAgICBmdW5jdGlvbiBsZWdlbmQoc3ZnKXtcclxuXHJcbiAgICAgIHZhciB0eXBlID0gaGVscGVyLmQzX2NhbGNUeXBlKHNjYWxlLCBhc2NlbmRpbmcsIGNlbGxzLCBsYWJlbHMsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlciksXHJcbiAgICAgICAgbGVnZW5kRyA9IHN2Zy5zZWxlY3RBbGwoJ2cnKS5kYXRhKFtzY2FsZV0pO1xyXG5cclxuICAgICAgbGVnZW5kRy5lbnRlcigpLmFwcGVuZCgnZycpLmF0dHIoJ2NsYXNzJywgY2xhc3NQcmVmaXggKyAnbGVnZW5kQ2VsbHMnKTtcclxuXHJcblxyXG4gICAgICB2YXIgY2VsbCA9IGxlZ2VuZEcuc2VsZWN0QWxsKFwiLlwiICsgY2xhc3NQcmVmaXggKyBcImNlbGxcIikuZGF0YSh0eXBlLmRhdGEpLFxyXG4gICAgICAgIGNlbGxFbnRlciA9IGNlbGwuZW50ZXIoKS5hcHBlbmQoXCJnXCIsIFwiLmNlbGxcIikuYXR0cihcImNsYXNzXCIsIGNsYXNzUHJlZml4ICsgXCJjZWxsXCIpLnN0eWxlKFwib3BhY2l0eVwiLCAxZS02KSxcclxuICAgICAgICBzaGFwZUVudGVyID0gY2VsbEVudGVyLmFwcGVuZChzaGFwZSkuYXR0cihcImNsYXNzXCIsIGNsYXNzUHJlZml4ICsgXCJzd2F0Y2hcIiksXHJcbiAgICAgICAgc2hhcGVzID0gY2VsbC5zZWxlY3QoXCJnLlwiICsgY2xhc3NQcmVmaXggKyBcImNlbGwgXCIgKyBzaGFwZSk7XHJcblxyXG4gICAgICAvL2FkZCBldmVudCBoYW5kbGVyc1xyXG4gICAgICBoZWxwZXIuZDNfYWRkRXZlbnRzKGNlbGxFbnRlciwgbGVnZW5kRGlzcGF0Y2hlcik7XHJcblxyXG4gICAgICBjZWxsLmV4aXQoKS50cmFuc2l0aW9uKCkuc3R5bGUoXCJvcGFjaXR5XCIsIDApLnJlbW92ZSgpO1xyXG5cclxuICAgICAgLy9jcmVhdGVzIHNoYXBlXHJcbiAgICAgIGlmIChzaGFwZSA9PT0gXCJsaW5lXCIpe1xyXG4gICAgICAgIGhlbHBlci5kM19kcmF3U2hhcGVzKHNoYXBlLCBzaGFwZXMsIDAsIHNoYXBlV2lkdGgpO1xyXG4gICAgICAgIHNoYXBlcy5hdHRyKFwic3Ryb2tlLXdpZHRoXCIsIHR5cGUuZmVhdHVyZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaGVscGVyLmQzX2RyYXdTaGFwZXMoc2hhcGUsIHNoYXBlcywgdHlwZS5mZWF0dXJlLCB0eXBlLmZlYXR1cmUsIHR5cGUuZmVhdHVyZSwgcGF0aCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGhlbHBlci5kM19hZGRUZXh0KGxlZ2VuZEcsIGNlbGxFbnRlciwgdHlwZS5sYWJlbHMsIGNsYXNzUHJlZml4KVxyXG5cclxuICAgICAgLy9zZXRzIHBsYWNlbWVudFxyXG4gICAgICB2YXIgdGV4dCA9IGNlbGwuc2VsZWN0KFwidGV4dFwiKSxcclxuICAgICAgICBzaGFwZVNpemUgPSBzaGFwZXNbMF0ubWFwKFxyXG4gICAgICAgICAgZnVuY3Rpb24oZCwgaSl7XHJcbiAgICAgICAgICAgIHZhciBiYm94ID0gZC5nZXRCQm94KClcclxuICAgICAgICAgICAgdmFyIHN0cm9rZSA9IHNjYWxlKHR5cGUuZGF0YVtpXSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2hhcGUgPT09IFwibGluZVwiICYmIG9yaWVudCA9PT0gXCJob3Jpem9udGFsXCIpIHtcclxuICAgICAgICAgICAgICBiYm94LmhlaWdodCA9IGJib3guaGVpZ2h0ICsgc3Ryb2tlO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNoYXBlID09PSBcImxpbmVcIiAmJiBvcmllbnQgPT09IFwidmVydGljYWxcIil7XHJcbiAgICAgICAgICAgICAgYmJveC53aWR0aCA9IGJib3gud2lkdGg7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBiYm94O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgdmFyIG1heEggPSBkMy5tYXgoc2hhcGVTaXplLCBmdW5jdGlvbihkKXsgcmV0dXJuIGQuaGVpZ2h0ICsgZC55OyB9KSxcclxuICAgICAgbWF4VyA9IGQzLm1heChzaGFwZVNpemUsIGZ1bmN0aW9uKGQpeyByZXR1cm4gZC53aWR0aCArIGQueDsgfSk7XHJcblxyXG4gICAgICB2YXIgY2VsbFRyYW5zLFxyXG4gICAgICB0ZXh0VHJhbnMsXHJcbiAgICAgIHRleHRBbGlnbiA9IChsYWJlbEFsaWduID09IFwic3RhcnRcIikgPyAwIDogKGxhYmVsQWxpZ24gPT0gXCJtaWRkbGVcIikgPyAwLjUgOiAxO1xyXG5cclxuICAgICAgLy9wb3NpdGlvbnMgY2VsbHMgYW5kIHRleHRcclxuICAgICAgaWYgKG9yaWVudCA9PT0gXCJ2ZXJ0aWNhbFwiKXtcclxuXHJcbiAgICAgICAgY2VsbFRyYW5zID0gZnVuY3Rpb24oZCxpKSB7XHJcbiAgICAgICAgICAgIHZhciBoZWlnaHQgPSBkMy5zdW0oc2hhcGVTaXplLnNsaWNlKDAsIGkgKyAxICksIGZ1bmN0aW9uKGQpeyByZXR1cm4gZC5oZWlnaHQ7IH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gXCJ0cmFuc2xhdGUoMCwgXCIgKyAoaGVpZ2h0ICsgaSpzaGFwZVBhZGRpbmcpICsgXCIpXCI7IH07XHJcblxyXG4gICAgICAgIHRleHRUcmFucyA9IGZ1bmN0aW9uKGQsaSkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyAobWF4VyArIGxhYmVsT2Zmc2V0KSArIFwiLFwiICtcclxuICAgICAgICAgIChzaGFwZVNpemVbaV0ueSArIHNoYXBlU2l6ZVtpXS5oZWlnaHQvMiArIDUpICsgXCIpXCI7IH07XHJcblxyXG4gICAgICB9IGVsc2UgaWYgKG9yaWVudCA9PT0gXCJob3Jpem9udGFsXCIpe1xyXG4gICAgICAgIGNlbGxUcmFucyA9IGZ1bmN0aW9uKGQsaSkge1xyXG4gICAgICAgICAgICB2YXIgd2lkdGggPSBkMy5zdW0oc2hhcGVTaXplLnNsaWNlKDAsIGkgKyAxICksIGZ1bmN0aW9uKGQpeyByZXR1cm4gZC53aWR0aDsgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiBcInRyYW5zbGF0ZShcIiArICh3aWR0aCArIGkqc2hhcGVQYWRkaW5nKSArIFwiLDApXCI7IH07XHJcblxyXG4gICAgICAgIHRleHRUcmFucyA9IGZ1bmN0aW9uKGQsaSkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyAoc2hhcGVTaXplW2ldLndpZHRoKnRleHRBbGlnbiAgKyBzaGFwZVNpemVbaV0ueCkgKyBcIixcIiArXHJcbiAgICAgICAgICAgICAgKG1heEggKyBsYWJlbE9mZnNldCApICsgXCIpXCI7IH07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGhlbHBlci5kM19wbGFjZW1lbnQob3JpZW50LCBjZWxsLCBjZWxsVHJhbnMsIHRleHQsIHRleHRUcmFucywgbGFiZWxBbGlnbik7XHJcbiAgICAgIGhlbHBlci5kM190aXRsZShzdmcsIGxlZ2VuZEcsIHRpdGxlLCBjbGFzc1ByZWZpeCk7XHJcblxyXG4gICAgICBjZWxsLnRyYW5zaXRpb24oKS5zdHlsZShcIm9wYWNpdHlcIiwgMSk7XHJcblxyXG4gICAgfVxyXG5cclxuICBsZWdlbmQuc2NhbGUgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzY2FsZTtcclxuICAgIHNjYWxlID0gXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmNlbGxzID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2VsbHM7XHJcbiAgICBpZiAoXy5sZW5ndGggPiAxIHx8IF8gPj0gMiApe1xyXG4gICAgICBjZWxscyA9IF87XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG5cclxuICBsZWdlbmQuc2hhcGUgPSBmdW5jdGlvbihfLCBkKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzaGFwZTtcclxuICAgIGlmIChfID09IFwicmVjdFwiIHx8IF8gPT0gXCJjaXJjbGVcIiB8fCBfID09IFwibGluZVwiICl7XHJcbiAgICAgIHNoYXBlID0gXztcclxuICAgICAgcGF0aCA9IGQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5zaGFwZVdpZHRoID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2hhcGVXaWR0aDtcclxuICAgIHNoYXBlV2lkdGggPSArXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnNoYXBlUGFkZGluZyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNoYXBlUGFkZGluZztcclxuICAgIHNoYXBlUGFkZGluZyA9ICtfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxzID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGFiZWxzO1xyXG4gICAgbGFiZWxzID0gXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmxhYmVsQWxpZ24gPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbEFsaWduO1xyXG4gICAgaWYgKF8gPT0gXCJzdGFydFwiIHx8IF8gPT0gXCJlbmRcIiB8fCBfID09IFwibWlkZGxlXCIpIHtcclxuICAgICAgbGFiZWxBbGlnbiA9IF87XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbEZvcm1hdCA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsRm9ybWF0O1xyXG4gICAgbGFiZWxGb3JtYXQgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxPZmZzZXQgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbE9mZnNldDtcclxuICAgIGxhYmVsT2Zmc2V0ID0gK187XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbERlbGltaXRlciA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsRGVsaW1pdGVyO1xyXG4gICAgbGFiZWxEZWxpbWl0ZXIgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQub3JpZW50ID0gZnVuY3Rpb24oXyl7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBvcmllbnQ7XHJcbiAgICBfID0gXy50b0xvd2VyQ2FzZSgpO1xyXG4gICAgaWYgKF8gPT0gXCJob3Jpem9udGFsXCIgfHwgXyA9PSBcInZlcnRpY2FsXCIpIHtcclxuICAgICAgb3JpZW50ID0gXztcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmFzY2VuZGluZyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGFzY2VuZGluZztcclxuICAgIGFzY2VuZGluZyA9ICEhXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmNsYXNzUHJlZml4ID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2xhc3NQcmVmaXg7XHJcbiAgICBjbGFzc1ByZWZpeCA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC50aXRsZSA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRpdGxlO1xyXG4gICAgdGl0bGUgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBkMy5yZWJpbmQobGVnZW5kLCBsZWdlbmREaXNwYXRjaGVyLCBcIm9uXCIpO1xyXG5cclxuICByZXR1cm4gbGVnZW5kO1xyXG5cclxufTtcclxuIiwidmFyIGhlbHBlciA9IHJlcXVpcmUoJy4vbGVnZW5kJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCl7XHJcblxyXG4gIHZhciBzY2FsZSA9IGQzLnNjYWxlLmxpbmVhcigpLFxyXG4gICAgc2hhcGUgPSBcInBhdGhcIixcclxuICAgIHNoYXBlV2lkdGggPSAxNSxcclxuICAgIHNoYXBlSGVpZ2h0ID0gMTUsXHJcbiAgICBzaGFwZVJhZGl1cyA9IDEwLFxyXG4gICAgc2hhcGVQYWRkaW5nID0gNSxcclxuICAgIGNlbGxzID0gWzVdLFxyXG4gICAgbGFiZWxzID0gW10sXHJcbiAgICBjbGFzc1ByZWZpeCA9IFwiXCIsXHJcbiAgICB1c2VDbGFzcyA9IGZhbHNlLFxyXG4gICAgdGl0bGUgPSBcIlwiLFxyXG4gICAgbGFiZWxGb3JtYXQgPSBkMy5mb3JtYXQoXCIuMDFmXCIpLFxyXG4gICAgbGFiZWxBbGlnbiA9IFwibWlkZGxlXCIsXHJcbiAgICBsYWJlbE9mZnNldCA9IDEwLFxyXG4gICAgbGFiZWxEZWxpbWl0ZXIgPSBcInRvXCIsXHJcbiAgICBvcmllbnQgPSBcInZlcnRpY2FsXCIsXHJcbiAgICBhc2NlbmRpbmcgPSBmYWxzZSxcclxuICAgIGxlZ2VuZERpc3BhdGNoZXIgPSBkMy5kaXNwYXRjaChcImNlbGxvdmVyXCIsIFwiY2VsbG91dFwiLCBcImNlbGxjbGlja1wiKTtcclxuXHJcbiAgICBmdW5jdGlvbiBsZWdlbmQoc3ZnKXtcclxuXHJcbiAgICAgIHZhciB0eXBlID0gaGVscGVyLmQzX2NhbGNUeXBlKHNjYWxlLCBhc2NlbmRpbmcsIGNlbGxzLCBsYWJlbHMsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlciksXHJcbiAgICAgICAgbGVnZW5kRyA9IHN2Zy5zZWxlY3RBbGwoJ2cnKS5kYXRhKFtzY2FsZV0pO1xyXG5cclxuICAgICAgbGVnZW5kRy5lbnRlcigpLmFwcGVuZCgnZycpLmF0dHIoJ2NsYXNzJywgY2xhc3NQcmVmaXggKyAnbGVnZW5kQ2VsbHMnKTtcclxuXHJcbiAgICAgIHZhciBjZWxsID0gbGVnZW5kRy5zZWxlY3RBbGwoXCIuXCIgKyBjbGFzc1ByZWZpeCArIFwiY2VsbFwiKS5kYXRhKHR5cGUuZGF0YSksXHJcbiAgICAgICAgY2VsbEVudGVyID0gY2VsbC5lbnRlcigpLmFwcGVuZChcImdcIiwgXCIuY2VsbFwiKS5hdHRyKFwiY2xhc3NcIiwgY2xhc3NQcmVmaXggKyBcImNlbGxcIikuc3R5bGUoXCJvcGFjaXR5XCIsIDFlLTYpLFxyXG4gICAgICAgIHNoYXBlRW50ZXIgPSBjZWxsRW50ZXIuYXBwZW5kKHNoYXBlKS5hdHRyKFwiY2xhc3NcIiwgY2xhc3NQcmVmaXggKyBcInN3YXRjaFwiKSxcclxuICAgICAgICBzaGFwZXMgPSBjZWxsLnNlbGVjdChcImcuXCIgKyBjbGFzc1ByZWZpeCArIFwiY2VsbCBcIiArIHNoYXBlKTtcclxuXHJcbiAgICAgIC8vYWRkIGV2ZW50IGhhbmRsZXJzXHJcbiAgICAgIGhlbHBlci5kM19hZGRFdmVudHMoY2VsbEVudGVyLCBsZWdlbmREaXNwYXRjaGVyKTtcclxuXHJcbiAgICAgIC8vcmVtb3ZlIG9sZCBzaGFwZXNcclxuICAgICAgY2VsbC5leGl0KCkudHJhbnNpdGlvbigpLnN0eWxlKFwib3BhY2l0eVwiLCAwKS5yZW1vdmUoKTtcclxuXHJcbiAgICAgIGhlbHBlci5kM19kcmF3U2hhcGVzKHNoYXBlLCBzaGFwZXMsIHNoYXBlSGVpZ2h0LCBzaGFwZVdpZHRoLCBzaGFwZVJhZGl1cywgdHlwZS5mZWF0dXJlKTtcclxuICAgICAgaGVscGVyLmQzX2FkZFRleHQobGVnZW5kRywgY2VsbEVudGVyLCB0eXBlLmxhYmVscywgY2xhc3NQcmVmaXgpXHJcblxyXG4gICAgICAvLyBzZXRzIHBsYWNlbWVudFxyXG4gICAgICB2YXIgdGV4dCA9IGNlbGwuc2VsZWN0KFwidGV4dFwiKSxcclxuICAgICAgICBzaGFwZVNpemUgPSBzaGFwZXNbMF0ubWFwKCBmdW5jdGlvbihkKXsgcmV0dXJuIGQuZ2V0QkJveCgpOyB9KTtcclxuXHJcbiAgICAgIHZhciBtYXhIID0gZDMubWF4KHNoYXBlU2l6ZSwgZnVuY3Rpb24oZCl7IHJldHVybiBkLmhlaWdodDsgfSksXHJcbiAgICAgIG1heFcgPSBkMy5tYXgoc2hhcGVTaXplLCBmdW5jdGlvbihkKXsgcmV0dXJuIGQud2lkdGg7IH0pO1xyXG5cclxuICAgICAgdmFyIGNlbGxUcmFucyxcclxuICAgICAgdGV4dFRyYW5zLFxyXG4gICAgICB0ZXh0QWxpZ24gPSAobGFiZWxBbGlnbiA9PSBcInN0YXJ0XCIpID8gMCA6IChsYWJlbEFsaWduID09IFwibWlkZGxlXCIpID8gMC41IDogMTtcclxuXHJcbiAgICAgIC8vcG9zaXRpb25zIGNlbGxzIGFuZCB0ZXh0XHJcbiAgICAgIGlmIChvcmllbnQgPT09IFwidmVydGljYWxcIil7XHJcbiAgICAgICAgY2VsbFRyYW5zID0gZnVuY3Rpb24oZCxpKSB7IHJldHVybiBcInRyYW5zbGF0ZSgwLCBcIiArIChpICogKG1heEggKyBzaGFwZVBhZGRpbmcpKSArIFwiKVwiOyB9O1xyXG4gICAgICAgIHRleHRUcmFucyA9IGZ1bmN0aW9uKGQsaSkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyAobWF4VyArIGxhYmVsT2Zmc2V0KSArIFwiLFwiICtcclxuICAgICAgICAgICAgICAoc2hhcGVTaXplW2ldLnkgKyBzaGFwZVNpemVbaV0uaGVpZ2h0LzIgKyA1KSArIFwiKVwiOyB9O1xyXG5cclxuICAgICAgfSBlbHNlIGlmIChvcmllbnQgPT09IFwiaG9yaXpvbnRhbFwiKXtcclxuICAgICAgICBjZWxsVHJhbnMgPSBmdW5jdGlvbihkLGkpIHsgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgKGkgKiAobWF4VyArIHNoYXBlUGFkZGluZykpICsgXCIsMClcIjsgfTtcclxuICAgICAgICB0ZXh0VHJhbnMgPSBmdW5jdGlvbihkLGkpIHsgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgKHNoYXBlU2l6ZVtpXS53aWR0aCp0ZXh0QWxpZ24gICsgc2hhcGVTaXplW2ldLngpICsgXCIsXCIgK1xyXG4gICAgICAgICAgICAgIChtYXhIICsgbGFiZWxPZmZzZXQgKSArIFwiKVwiOyB9O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBoZWxwZXIuZDNfcGxhY2VtZW50KG9yaWVudCwgY2VsbCwgY2VsbFRyYW5zLCB0ZXh0LCB0ZXh0VHJhbnMsIGxhYmVsQWxpZ24pO1xyXG4gICAgICBoZWxwZXIuZDNfdGl0bGUoc3ZnLCBsZWdlbmRHLCB0aXRsZSwgY2xhc3NQcmVmaXgpO1xyXG4gICAgICBjZWxsLnRyYW5zaXRpb24oKS5zdHlsZShcIm9wYWNpdHlcIiwgMSk7XHJcblxyXG4gICAgfVxyXG5cclxuXHJcbiAgbGVnZW5kLnNjYWxlID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2NhbGU7XHJcbiAgICBzY2FsZSA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5jZWxscyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGNlbGxzO1xyXG4gICAgaWYgKF8ubGVuZ3RoID4gMSB8fCBfID49IDIgKXtcclxuICAgICAgY2VsbHMgPSBfO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuc2hhcGVQYWRkaW5nID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2hhcGVQYWRkaW5nO1xyXG4gICAgc2hhcGVQYWRkaW5nID0gK187XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbHMgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbHM7XHJcbiAgICBsYWJlbHMgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxBbGlnbiA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsQWxpZ247XHJcbiAgICBpZiAoXyA9PSBcInN0YXJ0XCIgfHwgXyA9PSBcImVuZFwiIHx8IF8gPT0gXCJtaWRkbGVcIikge1xyXG4gICAgICBsYWJlbEFsaWduID0gXztcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmxhYmVsRm9ybWF0ID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGFiZWxGb3JtYXQ7XHJcbiAgICBsYWJlbEZvcm1hdCA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbE9mZnNldCA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsT2Zmc2V0O1xyXG4gICAgbGFiZWxPZmZzZXQgPSArXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmxhYmVsRGVsaW1pdGVyID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGFiZWxEZWxpbWl0ZXI7XHJcbiAgICBsYWJlbERlbGltaXRlciA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5vcmllbnQgPSBmdW5jdGlvbihfKXtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIG9yaWVudDtcclxuICAgIF8gPSBfLnRvTG93ZXJDYXNlKCk7XHJcbiAgICBpZiAoXyA9PSBcImhvcml6b250YWxcIiB8fCBfID09IFwidmVydGljYWxcIikge1xyXG4gICAgICBvcmllbnQgPSBfO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuYXNjZW5kaW5nID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gYXNjZW5kaW5nO1xyXG4gICAgYXNjZW5kaW5nID0gISFfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuY2xhc3NQcmVmaXggPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBjbGFzc1ByZWZpeDtcclxuICAgIGNsYXNzUHJlZml4ID0gXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnRpdGxlID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGl0bGU7XHJcbiAgICB0aXRsZSA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGQzLnJlYmluZChsZWdlbmQsIGxlZ2VuZERpc3BhdGNoZXIsIFwib25cIik7XHJcblxyXG4gIHJldHVybiBsZWdlbmQ7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG4vKipcclxuICogKipbR2F1c3NpYW4gZXJyb3IgZnVuY3Rpb25dKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRXJyb3JfZnVuY3Rpb24pKipcclxuICpcclxuICogVGhlIGBlcnJvckZ1bmN0aW9uKHgvKHNkICogTWF0aC5zcXJ0KDIpKSlgIGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGEgdmFsdWUgaW4gYVxyXG4gKiBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGggc3RhbmRhcmQgZGV2aWF0aW9uIHNkIGlzIHdpdGhpbiB4IG9mIHRoZSBtZWFuLlxyXG4gKlxyXG4gKiBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYSBudW1lcmljYWwgYXBwcm94aW1hdGlvbiB0byB0aGUgZXhhY3QgdmFsdWUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IGlucHV0XHJcbiAqIEByZXR1cm4ge251bWJlcn0gZXJyb3IgZXN0aW1hdGlvblxyXG4gKiBAZXhhbXBsZVxyXG4gKiBlcnJvckZ1bmN0aW9uKDEpOyAvLz0gMC44NDI3XHJcbiAqL1xyXG5mdW5jdGlvbiBlcnJvckZ1bmN0aW9uKHgvKjogbnVtYmVyICovKS8qOiBudW1iZXIgKi8ge1xyXG4gICAgdmFyIHQgPSAxIC8gKDEgKyAwLjUgKiBNYXRoLmFicyh4KSk7XHJcbiAgICB2YXIgdGF1ID0gdCAqIE1hdGguZXhwKC1NYXRoLnBvdyh4LCAyKSAtXHJcbiAgICAgICAgMS4yNjU1MTIyMyArXHJcbiAgICAgICAgMS4wMDAwMjM2OCAqIHQgK1xyXG4gICAgICAgIDAuMzc0MDkxOTYgKiBNYXRoLnBvdyh0LCAyKSArXHJcbiAgICAgICAgMC4wOTY3ODQxOCAqIE1hdGgucG93KHQsIDMpIC1cclxuICAgICAgICAwLjE4NjI4ODA2ICogTWF0aC5wb3codCwgNCkgK1xyXG4gICAgICAgIDAuMjc4ODY4MDcgKiBNYXRoLnBvdyh0LCA1KSAtXHJcbiAgICAgICAgMS4xMzUyMDM5OCAqIE1hdGgucG93KHQsIDYpICtcclxuICAgICAgICAxLjQ4ODUxNTg3ICogTWF0aC5wb3codCwgNykgLVxyXG4gICAgICAgIDAuODIyMTUyMjMgKiBNYXRoLnBvdyh0LCA4KSArXHJcbiAgICAgICAgMC4xNzA4NzI3NyAqIE1hdGgucG93KHQsIDkpKTtcclxuICAgIGlmICh4ID49IDApIHtcclxuICAgICAgICByZXR1cm4gMSAtIHRhdTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHRhdSAtIDE7XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZXJyb3JGdW5jdGlvbjtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG4vKiBAZmxvdyAqL1xyXG5cclxuLyoqXHJcbiAqIFtTaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb25dKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU2ltcGxlX2xpbmVhcl9yZWdyZXNzaW9uKVxyXG4gKiBpcyBhIHNpbXBsZSB3YXkgdG8gZmluZCBhIGZpdHRlZCBsaW5lXHJcbiAqIGJldHdlZW4gYSBzZXQgb2YgY29vcmRpbmF0ZXMuIFRoaXMgYWxnb3JpdGhtIGZpbmRzIHRoZSBzbG9wZSBhbmQgeS1pbnRlcmNlcHQgb2YgYSByZWdyZXNzaW9uIGxpbmVcclxuICogdXNpbmcgdGhlIGxlYXN0IHN1bSBvZiBzcXVhcmVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBkYXRhIGFuIGFycmF5IG9mIHR3by1lbGVtZW50IG9mIGFycmF5cyxcclxuICogbGlrZSBgW1swLCAxXSwgWzIsIDNdXWBcclxuICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IGNvbnRhaW5pbmcgc2xvcGUgYW5kIGludGVyc2VjdCBvZiByZWdyZXNzaW9uIGxpbmVcclxuICogQGV4YW1wbGVcclxuICogbGluZWFyUmVncmVzc2lvbihbWzAsIDBdLCBbMSwgMV1dKTsgLy8geyBtOiAxLCBiOiAwIH1cclxuICovXHJcbmZ1bmN0aW9uIGxpbmVhclJlZ3Jlc3Npb24oZGF0YS8qOiBBcnJheTxBcnJheTxudW1iZXI+PiAqLykvKjogeyBtOiBudW1iZXIsIGI6IG51bWJlciB9ICovIHtcclxuXHJcbiAgICB2YXIgbSwgYjtcclxuXHJcbiAgICAvLyBTdG9yZSBkYXRhIGxlbmd0aCBpbiBhIGxvY2FsIHZhcmlhYmxlIHRvIHJlZHVjZVxyXG4gICAgLy8gcmVwZWF0ZWQgb2JqZWN0IHByb3BlcnR5IGxvb2t1cHNcclxuICAgIHZhciBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGg7XHJcblxyXG4gICAgLy9pZiB0aGVyZSdzIG9ubHkgb25lIHBvaW50LCBhcmJpdHJhcmlseSBjaG9vc2UgYSBzbG9wZSBvZiAwXHJcbiAgICAvL2FuZCBhIHktaW50ZXJjZXB0IG9mIHdoYXRldmVyIHRoZSB5IG9mIHRoZSBpbml0aWFsIHBvaW50IGlzXHJcbiAgICBpZiAoZGF0YUxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgIG0gPSAwO1xyXG4gICAgICAgIGIgPSBkYXRhWzBdWzFdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBJbml0aWFsaXplIG91ciBzdW1zIGFuZCBzY29wZSB0aGUgYG1gIGFuZCBgYmBcclxuICAgICAgICAvLyB2YXJpYWJsZXMgdGhhdCBkZWZpbmUgdGhlIGxpbmUuXHJcbiAgICAgICAgdmFyIHN1bVggPSAwLCBzdW1ZID0gMCxcclxuICAgICAgICAgICAgc3VtWFggPSAwLCBzdW1YWSA9IDA7XHJcblxyXG4gICAgICAgIC8vIFVzZSBsb2NhbCB2YXJpYWJsZXMgdG8gZ3JhYiBwb2ludCB2YWx1ZXNcclxuICAgICAgICAvLyB3aXRoIG1pbmltYWwgb2JqZWN0IHByb3BlcnR5IGxvb2t1cHNcclxuICAgICAgICB2YXIgcG9pbnQsIHgsIHk7XHJcblxyXG4gICAgICAgIC8vIEdhdGhlciB0aGUgc3VtIG9mIGFsbCB4IHZhbHVlcywgdGhlIHN1bSBvZiBhbGxcclxuICAgICAgICAvLyB5IHZhbHVlcywgYW5kIHRoZSBzdW0gb2YgeF4yIGFuZCAoeCp5KSBmb3IgZWFjaFxyXG4gICAgICAgIC8vIHZhbHVlLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gSW4gbWF0aCBub3RhdGlvbiwgdGhlc2Ugd291bGQgYmUgU1NfeCwgU1NfeSwgU1NfeHgsIGFuZCBTU194eVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHBvaW50ID0gZGF0YVtpXTtcclxuICAgICAgICAgICAgeCA9IHBvaW50WzBdO1xyXG4gICAgICAgICAgICB5ID0gcG9pbnRbMV07XHJcblxyXG4gICAgICAgICAgICBzdW1YICs9IHg7XHJcbiAgICAgICAgICAgIHN1bVkgKz0geTtcclxuXHJcbiAgICAgICAgICAgIHN1bVhYICs9IHggKiB4O1xyXG4gICAgICAgICAgICBzdW1YWSArPSB4ICogeTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGBtYCBpcyB0aGUgc2xvcGUgb2YgdGhlIHJlZ3Jlc3Npb24gbGluZVxyXG4gICAgICAgIG0gPSAoKGRhdGFMZW5ndGggKiBzdW1YWSkgLSAoc3VtWCAqIHN1bVkpKSAvXHJcbiAgICAgICAgICAgICgoZGF0YUxlbmd0aCAqIHN1bVhYKSAtIChzdW1YICogc3VtWCkpO1xyXG5cclxuICAgICAgICAvLyBgYmAgaXMgdGhlIHktaW50ZXJjZXB0IG9mIHRoZSBsaW5lLlxyXG4gICAgICAgIGIgPSAoc3VtWSAvIGRhdGFMZW5ndGgpIC0gKChtICogc3VtWCkgLyBkYXRhTGVuZ3RoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZXR1cm4gYm90aCB2YWx1ZXMgYXMgYW4gb2JqZWN0LlxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBtOiBtLFxyXG4gICAgICAgIGI6IGJcclxuICAgIH07XHJcbn1cclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGxpbmVhclJlZ3Jlc3Npb247XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbi8qKlxyXG4gKiBHaXZlbiB0aGUgb3V0cHV0IG9mIGBsaW5lYXJSZWdyZXNzaW9uYDogYW4gb2JqZWN0XHJcbiAqIHdpdGggYG1gIGFuZCBgYmAgdmFsdWVzIGluZGljYXRpbmcgc2xvcGUgYW5kIGludGVyY2VwdCxcclxuICogcmVzcGVjdGl2ZWx5LCBnZW5lcmF0ZSBhIGxpbmUgZnVuY3Rpb24gdGhhdCB0cmFuc2xhdGVzXHJcbiAqIHggdmFsdWVzIGludG8geSB2YWx1ZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYiBvYmplY3Qgd2l0aCBgbWAgYW5kIGBiYCBtZW1iZXJzLCByZXByZXNlbnRpbmdcclxuICogc2xvcGUgYW5kIGludGVyc2VjdCBvZiBkZXNpcmVkIGxpbmVcclxuICogQHJldHVybnMge0Z1bmN0aW9ufSBtZXRob2QgdGhhdCBjb21wdXRlcyB5LXZhbHVlIGF0IGFueSBnaXZlblxyXG4gKiB4LXZhbHVlIG9uIHRoZSBsaW5lLlxyXG4gKiBAZXhhbXBsZVxyXG4gKiB2YXIgbCA9IGxpbmVhclJlZ3Jlc3Npb25MaW5lKGxpbmVhclJlZ3Jlc3Npb24oW1swLCAwXSwgWzEsIDFdXSkpO1xyXG4gKiBsKDApIC8vPSAwXHJcbiAqIGwoMikgLy89IDJcclxuICovXHJcbmZ1bmN0aW9uIGxpbmVhclJlZ3Jlc3Npb25MaW5lKG1iLyo6IHsgYjogbnVtYmVyLCBtOiBudW1iZXIgfSovKS8qOiBGdW5jdGlvbiAqLyB7XHJcbiAgICAvLyBSZXR1cm4gYSBmdW5jdGlvbiB0aGF0IGNvbXB1dGVzIGEgYHlgIHZhbHVlIGZvciBlYWNoXHJcbiAgICAvLyB4IHZhbHVlIGl0IGlzIGdpdmVuLCBiYXNlZCBvbiB0aGUgdmFsdWVzIG9mIGBiYCBhbmQgYGFgXHJcbiAgICAvLyB0aGF0IHdlIGp1c3QgY29tcHV0ZWQuXHJcbiAgICByZXR1cm4gZnVuY3Rpb24oeCkge1xyXG4gICAgICAgIHJldHVybiBtYi5iICsgKG1iLm0gKiB4KTtcclxuICAgIH07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluZWFyUmVncmVzc2lvbkxpbmU7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbnZhciBzdW0gPSByZXF1aXJlKCcuL3N1bScpO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBtZWFuLCBfYWxzbyBrbm93biBhcyBhdmVyYWdlXyxcclxuICogaXMgdGhlIHN1bSBvZiBhbGwgdmFsdWVzIG92ZXIgdGhlIG51bWJlciBvZiB2YWx1ZXMuXHJcbiAqIFRoaXMgaXMgYSBbbWVhc3VyZSBvZiBjZW50cmFsIHRlbmRlbmN5XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9DZW50cmFsX3RlbmRlbmN5KTpcclxuICogYSBtZXRob2Qgb2YgZmluZGluZyBhIHR5cGljYWwgb3IgY2VudHJhbCB2YWx1ZSBvZiBhIHNldCBvZiBudW1iZXJzLlxyXG4gKlxyXG4gKiBUaGlzIHJ1bnMgb24gYE8obilgLCBsaW5lYXIgdGltZSBpbiByZXNwZWN0IHRvIHRoZSBhcnJheVxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHggaW5wdXQgdmFsdWVzXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IG1lYW5cclxuICogQGV4YW1wbGVcclxuICogY29uc29sZS5sb2cobWVhbihbMCwgMTBdKSk7IC8vIDVcclxuICovXHJcbmZ1bmN0aW9uIG1lYW4oeCAvKjogQXJyYXk8bnVtYmVyPiAqLykvKjpudW1iZXIqLyB7XHJcbiAgICAvLyBUaGUgbWVhbiBvZiBubyBudW1iZXJzIGlzIG51bGxcclxuICAgIGlmICh4Lmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gTmFOOyB9XHJcblxyXG4gICAgcmV0dXJuIHN1bSh4KSAvIHgubGVuZ3RoO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IG1lYW47XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbnZhciBzYW1wbGVDb3ZhcmlhbmNlID0gcmVxdWlyZSgnLi9zYW1wbGVfY292YXJpYW5jZScpO1xyXG52YXIgc2FtcGxlU3RhbmRhcmREZXZpYXRpb24gPSByZXF1aXJlKCcuL3NhbXBsZV9zdGFuZGFyZF9kZXZpYXRpb24nKTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgW2NvcnJlbGF0aW9uXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvcnJlbGF0aW9uX2FuZF9kZXBlbmRlbmNlKSBpc1xyXG4gKiBhIG1lYXN1cmUgb2YgaG93IGNvcnJlbGF0ZWQgdHdvIGRhdGFzZXRzIGFyZSwgYmV0d2VlbiAtMSBhbmQgMVxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHggZmlyc3QgaW5wdXRcclxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSB5IHNlY29uZCBpbnB1dFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBzYW1wbGUgY29ycmVsYXRpb25cclxuICogQGV4YW1wbGVcclxuICogdmFyIGEgPSBbMSwgMiwgMywgNCwgNSwgNl07XHJcbiAqIHZhciBiID0gWzIsIDIsIDMsIDQsIDUsIDYwXTtcclxuICogc2FtcGxlQ29ycmVsYXRpb24oYSwgYik7IC8vPSAwLjY5MVxyXG4gKi9cclxuZnVuY3Rpb24gc2FtcGxlQ29ycmVsYXRpb24oeC8qOiBBcnJheTxudW1iZXI+ICovLCB5Lyo6IEFycmF5PG51bWJlcj4gKi8pLyo6bnVtYmVyKi8ge1xyXG4gICAgdmFyIGNvdiA9IHNhbXBsZUNvdmFyaWFuY2UoeCwgeSksXHJcbiAgICAgICAgeHN0ZCA9IHNhbXBsZVN0YW5kYXJkRGV2aWF0aW9uKHgpLFxyXG4gICAgICAgIHlzdGQgPSBzYW1wbGVTdGFuZGFyZERldmlhdGlvbih5KTtcclxuXHJcbiAgICByZXR1cm4gY292IC8geHN0ZCAvIHlzdGQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2FtcGxlQ29ycmVsYXRpb247XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbnZhciBtZWFuID0gcmVxdWlyZSgnLi9tZWFuJyk7XHJcblxyXG4vKipcclxuICogW1NhbXBsZSBjb3ZhcmlhbmNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TYW1wbGVfbWVhbl9hbmRfc2FtcGxlQ292YXJpYW5jZSkgb2YgdHdvIGRhdGFzZXRzOlxyXG4gKiBob3cgbXVjaCBkbyB0aGUgdHdvIGRhdGFzZXRzIG1vdmUgdG9nZXRoZXI/XHJcbiAqIHggYW5kIHkgYXJlIHR3byBkYXRhc2V0cywgcmVwcmVzZW50ZWQgYXMgYXJyYXlzIG9mIG51bWJlcnMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBmaXJzdCBpbnB1dFxyXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHkgc2Vjb25kIGlucHV0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IHNhbXBsZSBjb3ZhcmlhbmNlXHJcbiAqIEBleGFtcGxlXHJcbiAqIHZhciB4ID0gWzEsIDIsIDMsIDQsIDUsIDZdO1xyXG4gKiB2YXIgeSA9IFs2LCA1LCA0LCAzLCAyLCAxXTtcclxuICogc2FtcGxlQ292YXJpYW5jZSh4LCB5KTsgLy89IC0zLjVcclxuICovXHJcbmZ1bmN0aW9uIHNhbXBsZUNvdmFyaWFuY2UoeCAvKjpBcnJheTxudW1iZXI+Ki8sIHkgLyo6QXJyYXk8bnVtYmVyPiovKS8qOm51bWJlciovIHtcclxuXHJcbiAgICAvLyBUaGUgdHdvIGRhdGFzZXRzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGggd2hpY2ggbXVzdCBiZSBtb3JlIHRoYW4gMVxyXG4gICAgaWYgKHgubGVuZ3RoIDw9IDEgfHwgeC5sZW5ndGggIT09IHkubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIE5hTjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBkZXRlcm1pbmUgdGhlIG1lYW4gb2YgZWFjaCBkYXRhc2V0IHNvIHRoYXQgd2UgY2FuIGp1ZGdlIGVhY2hcclxuICAgIC8vIHZhbHVlIG9mIHRoZSBkYXRhc2V0IGZhaXJseSBhcyB0aGUgZGlmZmVyZW5jZSBmcm9tIHRoZSBtZWFuLiB0aGlzXHJcbiAgICAvLyB3YXksIGlmIG9uZSBkYXRhc2V0IGlzIFsxLCAyLCAzXSBhbmQgWzIsIDMsIDRdLCB0aGVpciBjb3ZhcmlhbmNlXHJcbiAgICAvLyBkb2VzIG5vdCBzdWZmZXIgYmVjYXVzZSBvZiB0aGUgZGlmZmVyZW5jZSBpbiBhYnNvbHV0ZSB2YWx1ZXNcclxuICAgIHZhciB4bWVhbiA9IG1lYW4oeCksXHJcbiAgICAgICAgeW1lYW4gPSBtZWFuKHkpLFxyXG4gICAgICAgIHN1bSA9IDA7XHJcblxyXG4gICAgLy8gZm9yIGVhY2ggcGFpciBvZiB2YWx1ZXMsIHRoZSBjb3ZhcmlhbmNlIGluY3JlYXNlcyB3aGVuIHRoZWlyXHJcbiAgICAvLyBkaWZmZXJlbmNlIGZyb20gdGhlIG1lYW4gaXMgYXNzb2NpYXRlZCAtIGlmIGJvdGggYXJlIHdlbGwgYWJvdmVcclxuICAgIC8vIG9yIGlmIGJvdGggYXJlIHdlbGwgYmVsb3dcclxuICAgIC8vIHRoZSBtZWFuLCB0aGUgY292YXJpYW5jZSBpbmNyZWFzZXMgc2lnbmlmaWNhbnRseS5cclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHN1bSArPSAoeFtpXSAtIHhtZWFuKSAqICh5W2ldIC0geW1lYW4pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHRoaXMgaXMgQmVzc2VscycgQ29ycmVjdGlvbjogYW4gYWRqdXN0bWVudCBtYWRlIHRvIHNhbXBsZSBzdGF0aXN0aWNzXHJcbiAgICAvLyB0aGF0IGFsbG93cyBmb3IgdGhlIHJlZHVjZWQgZGVncmVlIG9mIGZyZWVkb20gZW50YWlsZWQgaW4gY2FsY3VsYXRpbmdcclxuICAgIC8vIHZhbHVlcyBmcm9tIHNhbXBsZXMgcmF0aGVyIHRoYW4gY29tcGxldGUgcG9wdWxhdGlvbnMuXHJcbiAgICB2YXIgYmVzc2Vsc0NvcnJlY3Rpb24gPSB4Lmxlbmd0aCAtIDE7XHJcblxyXG4gICAgLy8gdGhlIGNvdmFyaWFuY2UgaXMgd2VpZ2h0ZWQgYnkgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YXNldHMuXHJcbiAgICByZXR1cm4gc3VtIC8gYmVzc2Vsc0NvcnJlY3Rpb247XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2FtcGxlQ292YXJpYW5jZTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG4vKiBAZmxvdyAqL1xyXG5cclxudmFyIHNhbXBsZVZhcmlhbmNlID0gcmVxdWlyZSgnLi9zYW1wbGVfdmFyaWFuY2UnKTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgW3N0YW5kYXJkIGRldmlhdGlvbl0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdGFuZGFyZF9kZXZpYXRpb24pXHJcbiAqIGlzIHRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgdmFyaWFuY2UuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBpbnB1dCBhcnJheVxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBzYW1wbGUgc3RhbmRhcmQgZGV2aWF0aW9uXHJcbiAqIEBleGFtcGxlXHJcbiAqIHNzLnNhbXBsZVN0YW5kYXJkRGV2aWF0aW9uKFsyLCA0LCA0LCA0LCA1LCA1LCA3LCA5XSk7XHJcbiAqIC8vPSAyLjEzOFxyXG4gKi9cclxuZnVuY3Rpb24gc2FtcGxlU3RhbmRhcmREZXZpYXRpb24oeC8qOkFycmF5PG51bWJlcj4qLykvKjpudW1iZXIqLyB7XHJcbiAgICAvLyBUaGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIG5vIG51bWJlcnMgaXMgbnVsbFxyXG4gICAgdmFyIHNhbXBsZVZhcmlhbmNlWCA9IHNhbXBsZVZhcmlhbmNlKHgpO1xyXG4gICAgaWYgKGlzTmFOKHNhbXBsZVZhcmlhbmNlWCkpIHsgcmV0dXJuIE5hTjsgfVxyXG4gICAgcmV0dXJuIE1hdGguc3FydChzYW1wbGVWYXJpYW5jZVgpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNhbXBsZVN0YW5kYXJkRGV2aWF0aW9uO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG52YXIgc3VtTnRoUG93ZXJEZXZpYXRpb25zID0gcmVxdWlyZSgnLi9zdW1fbnRoX3Bvd2VyX2RldmlhdGlvbnMnKTtcclxuXHJcbi8qXHJcbiAqIFRoZSBbc2FtcGxlIHZhcmlhbmNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9WYXJpYW5jZSNTYW1wbGVfdmFyaWFuY2UpXHJcbiAqIGlzIHRoZSBzdW0gb2Ygc3F1YXJlZCBkZXZpYXRpb25zIGZyb20gdGhlIG1lYW4uIFRoZSBzYW1wbGUgdmFyaWFuY2VcclxuICogaXMgZGlzdGluZ3Vpc2hlZCBmcm9tIHRoZSB2YXJpYW5jZSBieSB0aGUgdXNhZ2Ugb2YgW0Jlc3NlbCdzIENvcnJlY3Rpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jlc3NlbCdzX2NvcnJlY3Rpb24pOlxyXG4gKiBpbnN0ZWFkIG9mIGRpdmlkaW5nIHRoZSBzdW0gb2Ygc3F1YXJlZCBkZXZpYXRpb25zIGJ5IHRoZSBsZW5ndGggb2YgdGhlIGlucHV0LFxyXG4gKiBpdCBpcyBkaXZpZGVkIGJ5IHRoZSBsZW5ndGggbWludXMgb25lLiBUaGlzIGNvcnJlY3RzIHRoZSBiaWFzIGluIGVzdGltYXRpbmdcclxuICogYSB2YWx1ZSBmcm9tIGEgc2V0IHRoYXQgeW91IGRvbid0IGtub3cgaWYgZnVsbC5cclxuICpcclxuICogUmVmZXJlbmNlczpcclxuICogKiBbV29sZnJhbSBNYXRoV29ybGQgb24gU2FtcGxlIFZhcmlhbmNlXShodHRwOi8vbWF0aHdvcmxkLndvbGZyYW0uY29tL1NhbXBsZVZhcmlhbmNlLmh0bWwpXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBpbnB1dCBhcnJheVxyXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHNhbXBsZSB2YXJpYW5jZVxyXG4gKiBAZXhhbXBsZVxyXG4gKiBzYW1wbGVWYXJpYW5jZShbMSwgMiwgMywgNCwgNV0pOyAvLz0gMi41XHJcbiAqL1xyXG5mdW5jdGlvbiBzYW1wbGVWYXJpYW5jZSh4IC8qOiBBcnJheTxudW1iZXI+ICovKS8qOm51bWJlciovIHtcclxuICAgIC8vIFRoZSB2YXJpYW5jZSBvZiBubyBudW1iZXJzIGlzIG51bGxcclxuICAgIGlmICh4Lmxlbmd0aCA8PSAxKSB7IHJldHVybiBOYU47IH1cclxuXHJcbiAgICB2YXIgc3VtU3F1YXJlZERldmlhdGlvbnNWYWx1ZSA9IHN1bU50aFBvd2VyRGV2aWF0aW9ucyh4LCAyKTtcclxuXHJcbiAgICAvLyB0aGlzIGlzIEJlc3NlbHMnIENvcnJlY3Rpb246IGFuIGFkanVzdG1lbnQgbWFkZSB0byBzYW1wbGUgc3RhdGlzdGljc1xyXG4gICAgLy8gdGhhdCBhbGxvd3MgZm9yIHRoZSByZWR1Y2VkIGRlZ3JlZSBvZiBmcmVlZG9tIGVudGFpbGVkIGluIGNhbGN1bGF0aW5nXHJcbiAgICAvLyB2YWx1ZXMgZnJvbSBzYW1wbGVzIHJhdGhlciB0aGFuIGNvbXBsZXRlIHBvcHVsYXRpb25zLlxyXG4gICAgdmFyIGJlc3NlbHNDb3JyZWN0aW9uID0geC5sZW5ndGggLSAxO1xyXG5cclxuICAgIC8vIEZpbmQgdGhlIG1lYW4gdmFsdWUgb2YgdGhhdCBsaXN0XHJcbiAgICByZXR1cm4gc3VtU3F1YXJlZERldmlhdGlvbnNWYWx1ZSAvIGJlc3NlbHNDb3JyZWN0aW9uO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNhbXBsZVZhcmlhbmNlO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG52YXIgdmFyaWFuY2UgPSByZXF1aXJlKCcuL3ZhcmlhbmNlJyk7XHJcblxyXG4vKipcclxuICogVGhlIFtzdGFuZGFyZCBkZXZpYXRpb25dKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3RhbmRhcmRfZGV2aWF0aW9uKVxyXG4gKiBpcyB0aGUgc3F1YXJlIHJvb3Qgb2YgdGhlIHZhcmlhbmNlLiBJdCdzIHVzZWZ1bCBmb3IgbWVhc3VyaW5nIHRoZSBhbW91bnRcclxuICogb2YgdmFyaWF0aW9uIG9yIGRpc3BlcnNpb24gaW4gYSBzZXQgb2YgdmFsdWVzLlxyXG4gKlxyXG4gKiBTdGFuZGFyZCBkZXZpYXRpb24gaXMgb25seSBhcHByb3ByaWF0ZSBmb3IgZnVsbC1wb3B1bGF0aW9uIGtub3dsZWRnZTogZm9yXHJcbiAqIHNhbXBsZXMgb2YgYSBwb3B1bGF0aW9uLCB7QGxpbmsgc2FtcGxlU3RhbmRhcmREZXZpYXRpb259IGlzXHJcbiAqIG1vcmUgYXBwcm9wcmlhdGUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBpbnB1dFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBzdGFuZGFyZCBkZXZpYXRpb25cclxuICogQGV4YW1wbGVcclxuICogdmFyIHNjb3JlcyA9IFsyLCA0LCA0LCA0LCA1LCA1LCA3LCA5XTtcclxuICogdmFyaWFuY2Uoc2NvcmVzKTsgLy89IDRcclxuICogc3RhbmRhcmREZXZpYXRpb24oc2NvcmVzKTsgLy89IDJcclxuICovXHJcbmZ1bmN0aW9uIHN0YW5kYXJkRGV2aWF0aW9uKHggLyo6IEFycmF5PG51bWJlcj4gKi8pLyo6bnVtYmVyKi8ge1xyXG4gICAgLy8gVGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBubyBudW1iZXJzIGlzIG51bGxcclxuICAgIHZhciB2ID0gdmFyaWFuY2UoeCk7XHJcbiAgICBpZiAoaXNOYU4odikpIHsgcmV0dXJuIDA7IH1cclxuICAgIHJldHVybiBNYXRoLnNxcnQodik7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3RhbmRhcmREZXZpYXRpb247XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbi8qKlxyXG4gKiBPdXIgZGVmYXVsdCBzdW0gaXMgdGhlIFtLYWhhbiBzdW1tYXRpb24gYWxnb3JpdGhtXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9LYWhhbl9zdW1tYXRpb25fYWxnb3JpdGhtKSBpc1xyXG4gKiBhIG1ldGhvZCBmb3IgY29tcHV0aW5nIHRoZSBzdW0gb2YgYSBsaXN0IG9mIG51bWJlcnMgd2hpbGUgY29ycmVjdGluZ1xyXG4gKiBmb3IgZmxvYXRpbmctcG9pbnQgZXJyb3JzLiBUcmFkaXRpb25hbGx5LCBzdW1zIGFyZSBjYWxjdWxhdGVkIGFzIG1hbnlcclxuICogc3VjY2Vzc2l2ZSBhZGRpdGlvbnMsIGVhY2ggb25lIHdpdGggaXRzIG93biBmbG9hdGluZy1wb2ludCByb3VuZG9mZi4gVGhlc2VcclxuICogbG9zc2VzIGluIHByZWNpc2lvbiBhZGQgdXAgYXMgdGhlIG51bWJlciBvZiBudW1iZXJzIGluY3JlYXNlcy4gVGhpcyBhbHRlcm5hdGl2ZVxyXG4gKiBhbGdvcml0aG0gaXMgbW9yZSBhY2N1cmF0ZSB0aGFuIHRoZSBzaW1wbGUgd2F5IG9mIGNhbGN1bGF0aW5nIHN1bXMgYnkgc2ltcGxlXHJcbiAqIGFkZGl0aW9uLlxyXG4gKlxyXG4gKiBUaGlzIHJ1bnMgb24gYE8obilgLCBsaW5lYXIgdGltZSBpbiByZXNwZWN0IHRvIHRoZSBhcnJheVxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHggaW5wdXRcclxuICogQHJldHVybiB7bnVtYmVyfSBzdW0gb2YgYWxsIGlucHV0IG51bWJlcnNcclxuICogQGV4YW1wbGVcclxuICogY29uc29sZS5sb2coc3VtKFsxLCAyLCAzXSkpOyAvLyA2XHJcbiAqL1xyXG5mdW5jdGlvbiBzdW0oeC8qOiBBcnJheTxudW1iZXI+ICovKS8qOiBudW1iZXIgKi8ge1xyXG5cclxuICAgIC8vIGxpa2UgdGhlIHRyYWRpdGlvbmFsIHN1bSBhbGdvcml0aG0sIHdlIGtlZXAgYSBydW5uaW5nXHJcbiAgICAvLyBjb3VudCBvZiB0aGUgY3VycmVudCBzdW0uXHJcbiAgICB2YXIgc3VtID0gMDtcclxuXHJcbiAgICAvLyBidXQgd2UgYWxzbyBrZWVwIHRocmVlIGV4dHJhIHZhcmlhYmxlcyBhcyBib29ra2VlcGluZzpcclxuICAgIC8vIG1vc3QgaW1wb3J0YW50bHksIGFuIGVycm9yIGNvcnJlY3Rpb24gdmFsdWUuIFRoaXMgd2lsbCBiZSBhIHZlcnlcclxuICAgIC8vIHNtYWxsIG51bWJlciB0aGF0IGlzIHRoZSBvcHBvc2l0ZSBvZiB0aGUgZmxvYXRpbmcgcG9pbnQgcHJlY2lzaW9uIGxvc3MuXHJcbiAgICB2YXIgZXJyb3JDb21wZW5zYXRpb24gPSAwO1xyXG5cclxuICAgIC8vIHRoaXMgd2lsbCBiZSBlYWNoIG51bWJlciBpbiB0aGUgbGlzdCBjb3JyZWN0ZWQgd2l0aCB0aGUgY29tcGVuc2F0aW9uIHZhbHVlLlxyXG4gICAgdmFyIGNvcnJlY3RlZEN1cnJlbnRWYWx1ZTtcclxuXHJcbiAgICAvLyBhbmQgdGhpcyB3aWxsIGJlIHRoZSBuZXh0IHN1bVxyXG4gICAgdmFyIG5leHRTdW07XHJcblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgLy8gZmlyc3QgY29ycmVjdCB0aGUgdmFsdWUgdGhhdCB3ZSdyZSBnb2luZyB0byBhZGQgdG8gdGhlIHN1bVxyXG4gICAgICAgIGNvcnJlY3RlZEN1cnJlbnRWYWx1ZSA9IHhbaV0gLSBlcnJvckNvbXBlbnNhdGlvbjtcclxuXHJcbiAgICAgICAgLy8gY29tcHV0ZSB0aGUgbmV4dCBzdW0uIHN1bSBpcyBsaWtlbHkgYSBtdWNoIGxhcmdlciBudW1iZXJcclxuICAgICAgICAvLyB0aGFuIGNvcnJlY3RlZEN1cnJlbnRWYWx1ZSwgc28gd2UnbGwgbG9zZSBwcmVjaXNpb24gaGVyZSxcclxuICAgICAgICAvLyBhbmQgbWVhc3VyZSBob3cgbXVjaCBwcmVjaXNpb24gaXMgbG9zdCBpbiB0aGUgbmV4dCBzdGVwXHJcbiAgICAgICAgbmV4dFN1bSA9IHN1bSArIGNvcnJlY3RlZEN1cnJlbnRWYWx1ZTtcclxuXHJcbiAgICAgICAgLy8gd2UgaW50ZW50aW9uYWxseSBkaWRuJ3QgYXNzaWduIHN1bSBpbW1lZGlhdGVseSwgYnV0IHN0b3JlZFxyXG4gICAgICAgIC8vIGl0IGZvciBub3cgc28gd2UgY2FuIGZpZ3VyZSBvdXQgdGhpczogaXMgKHN1bSArIG5leHRWYWx1ZSkgLSBuZXh0VmFsdWVcclxuICAgICAgICAvLyBub3QgZXF1YWwgdG8gMD8gaWRlYWxseSBpdCB3b3VsZCBiZSwgYnV0IGluIHByYWN0aWNlIGl0IHdvbid0OlxyXG4gICAgICAgIC8vIGl0IHdpbGwgYmUgc29tZSB2ZXJ5IHNtYWxsIG51bWJlci4gdGhhdCdzIHdoYXQgd2UgcmVjb3JkXHJcbiAgICAgICAgLy8gYXMgZXJyb3JDb21wZW5zYXRpb24uXHJcbiAgICAgICAgZXJyb3JDb21wZW5zYXRpb24gPSBuZXh0U3VtIC0gc3VtIC0gY29ycmVjdGVkQ3VycmVudFZhbHVlO1xyXG5cclxuICAgICAgICAvLyBub3cgdGhhdCB3ZSd2ZSBjb21wdXRlZCBob3cgbXVjaCB3ZSdsbCBjb3JyZWN0IGZvciBpbiB0aGUgbmV4dFxyXG4gICAgICAgIC8vIGxvb3AsIHN0YXJ0IHRyZWF0aW5nIHRoZSBuZXh0U3VtIGFzIHRoZSBjdXJyZW50IHN1bS5cclxuICAgICAgICBzdW0gPSBuZXh0U3VtO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzdW07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3VtO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG52YXIgbWVhbiA9IHJlcXVpcmUoJy4vbWVhbicpO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBzdW0gb2YgZGV2aWF0aW9ucyB0byB0aGUgTnRoIHBvd2VyLlxyXG4gKiBXaGVuIG49MiBpdCdzIHRoZSBzdW0gb2Ygc3F1YXJlZCBkZXZpYXRpb25zLlxyXG4gKiBXaGVuIG49MyBpdCdzIHRoZSBzdW0gb2YgY3ViZWQgZGV2aWF0aW9ucy5cclxuICpcclxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSB4XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBuIHBvd2VyXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IHN1bSBvZiBudGggcG93ZXIgZGV2aWF0aW9uc1xyXG4gKiBAZXhhbXBsZVxyXG4gKiB2YXIgaW5wdXQgPSBbMSwgMiwgM107XHJcbiAqIC8vIHNpbmNlIHRoZSB2YXJpYW5jZSBvZiBhIHNldCBpcyB0aGUgbWVhbiBzcXVhcmVkXHJcbiAqIC8vIGRldmlhdGlvbnMsIHdlIGNhbiBjYWxjdWxhdGUgdGhhdCB3aXRoIHN1bU50aFBvd2VyRGV2aWF0aW9uczpcclxuICogdmFyIHZhcmlhbmNlID0gc3VtTnRoUG93ZXJEZXZpYXRpb25zKGlucHV0KSAvIGlucHV0Lmxlbmd0aDtcclxuICovXHJcbmZ1bmN0aW9uIHN1bU50aFBvd2VyRGV2aWF0aW9ucyh4Lyo6IEFycmF5PG51bWJlcj4gKi8sIG4vKjogbnVtYmVyICovKS8qOm51bWJlciovIHtcclxuICAgIHZhciBtZWFuVmFsdWUgPSBtZWFuKHgpLFxyXG4gICAgICAgIHN1bSA9IDA7XHJcblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgc3VtICs9IE1hdGgucG93KHhbaV0gLSBtZWFuVmFsdWUsIG4pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzdW07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3VtTnRoUG93ZXJEZXZpYXRpb25zO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG52YXIgc3VtTnRoUG93ZXJEZXZpYXRpb25zID0gcmVxdWlyZSgnLi9zdW1fbnRoX3Bvd2VyX2RldmlhdGlvbnMnKTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgW3ZhcmlhbmNlXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1ZhcmlhbmNlKVxyXG4gKiBpcyB0aGUgc3VtIG9mIHNxdWFyZWQgZGV2aWF0aW9ucyBmcm9tIHRoZSBtZWFuLlxyXG4gKlxyXG4gKiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHZhcmlhbmNlLCBub3Qgc2FtcGxlIHZhcmlhbmNlOlxyXG4gKiBzZWUgdGhlIGBzYW1wbGVWYXJpYW5jZWAgbWV0aG9kIGlmIHlvdSB3YW50IGEgc2FtcGxlIG1lYXN1cmUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBhIHBvcHVsYXRpb25cclxuICogQHJldHVybnMge251bWJlcn0gdmFyaWFuY2U6IGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHplcm8uXHJcbiAqIHplcm8gaW5kaWNhdGVzIHRoYXQgYWxsIHZhbHVlcyBhcmUgaWRlbnRpY2FsLlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBzcy52YXJpYW5jZShbMSwgMiwgMywgNCwgNSwgNl0pOyAvLz0gMi45MTdcclxuICovXHJcbmZ1bmN0aW9uIHZhcmlhbmNlKHgvKjogQXJyYXk8bnVtYmVyPiAqLykvKjpudW1iZXIqLyB7XHJcbiAgICAvLyBUaGUgdmFyaWFuY2Ugb2Ygbm8gbnVtYmVycyBpcyBudWxsXHJcbiAgICBpZiAoeC5sZW5ndGggPT09IDApIHsgcmV0dXJuIE5hTjsgfVxyXG5cclxuICAgIC8vIEZpbmQgdGhlIG1lYW4gb2Ygc3F1YXJlZCBkZXZpYXRpb25zIGJldHdlZW4gdGhlXHJcbiAgICAvLyBtZWFuIHZhbHVlIGFuZCBlYWNoIHZhbHVlLlxyXG4gICAgcmV0dXJuIHN1bU50aFBvd2VyRGV2aWF0aW9ucyh4LCAyKSAvIHgubGVuZ3RoO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHZhcmlhbmNlO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG4vKipcclxuICogVGhlIFtaLVNjb3JlLCBvciBTdGFuZGFyZCBTY29yZV0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdGFuZGFyZF9zY29yZSkuXHJcbiAqXHJcbiAqIFRoZSBzdGFuZGFyZCBzY29yZSBpcyB0aGUgbnVtYmVyIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgYW4gb2JzZXJ2YXRpb25cclxuICogb3IgZGF0dW0gaXMgYWJvdmUgb3IgYmVsb3cgdGhlIG1lYW4uIFRodXMsIGEgcG9zaXRpdmUgc3RhbmRhcmQgc2NvcmVcclxuICogcmVwcmVzZW50cyBhIGRhdHVtIGFib3ZlIHRoZSBtZWFuLCB3aGlsZSBhIG5lZ2F0aXZlIHN0YW5kYXJkIHNjb3JlXHJcbiAqIHJlcHJlc2VudHMgYSBkYXR1bSBiZWxvdyB0aGUgbWVhbi4gSXQgaXMgYSBkaW1lbnNpb25sZXNzIHF1YW50aXR5XHJcbiAqIG9idGFpbmVkIGJ5IHN1YnRyYWN0aW5nIHRoZSBwb3B1bGF0aW9uIG1lYW4gZnJvbSBhbiBpbmRpdmlkdWFsIHJhd1xyXG4gKiBzY29yZSBhbmQgdGhlbiBkaXZpZGluZyB0aGUgZGlmZmVyZW5jZSBieSB0aGUgcG9wdWxhdGlvbiBzdGFuZGFyZFxyXG4gKiBkZXZpYXRpb24uXHJcbiAqXHJcbiAqIFRoZSB6LXNjb3JlIGlzIG9ubHkgZGVmaW5lZCBpZiBvbmUga25vd3MgdGhlIHBvcHVsYXRpb24gcGFyYW1ldGVycztcclxuICogaWYgb25lIG9ubHkgaGFzIGEgc2FtcGxlIHNldCwgdGhlbiB0aGUgYW5hbG9nb3VzIGNvbXB1dGF0aW9uIHdpdGhcclxuICogc2FtcGxlIG1lYW4gYW5kIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24geWllbGRzIHRoZVxyXG4gKiBTdHVkZW50J3MgdC1zdGF0aXN0aWMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB4XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBtZWFuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFuZGFyZERldmlhdGlvblxyXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHogc2NvcmVcclxuICogQGV4YW1wbGVcclxuICogc3MuelNjb3JlKDc4LCA4MCwgNSk7IC8vPSAtMC40XHJcbiAqL1xyXG5mdW5jdGlvbiB6U2NvcmUoeC8qOm51bWJlciovLCBtZWFuLyo6bnVtYmVyKi8sIHN0YW5kYXJkRGV2aWF0aW9uLyo6bnVtYmVyKi8pLyo6bnVtYmVyKi8ge1xyXG4gICAgcmV0dXJuICh4IC0gbWVhbikgLyBzdGFuZGFyZERldmlhdGlvbjtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB6U2NvcmU7XHJcbiIsImltcG9ydCB7Q2hhcnQsIENoYXJ0Q29uZmlnfSBmcm9tIFwiLi9jaGFydFwiO1xyXG5pbXBvcnQge1V0aWxzfSBmcm9tICcuL3V0aWxzJ1xyXG5pbXBvcnQge0xlZ2VuZH0gZnJvbSBcIi4vbGVnZW5kXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQmFyQ2hhcnRDb25maWcgZXh0ZW5kcyBDaGFydENvbmZpZ3tcclxuXHJcbiAgICBzdmdDbGFzcz0gdGhpcy5jc3NDbGFzc1ByZWZpeCsnYmFyLWNoYXJ0JztcclxuICAgIHNob3dMZWdlbmQ9dHJ1ZTtcclxuICAgIHNob3dUb29sdGlwID10cnVlO1xyXG4gICAgbGVnZW5kPXtcclxuICAgICAgICB3aWR0aDogODAsXHJcbiAgICAgICAgbWFyZ2luOiAxMCxcclxuICAgICAgICBzaGFwZVdpZHRoOiAyMFxyXG4gICAgfTtcclxuICAgIHg9ey8vIFggYXhpcyBjb25maWdcclxuICAgICAgICBsYWJlbDogJycsIC8vIGF4aXMgbGFiZWxcclxuICAgICAgICBrZXk6IDAsXHJcbiAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IFV0aWxzLmlzTnVtYmVyKGQpID8gZCA6IGRba2V5XSwgLy8geCB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgICAgIHNjYWxlOiBcIm9yZGluYWxcIixcclxuICAgICAgICB0aWNrczogdW5kZWZpbmVkLFxyXG4gICAgfTtcclxuICAgIHk9ey8vIFkgYXhpcyBjb25maWdcclxuICAgICAgICBrZXk6IDEsXHJcbiAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IFV0aWxzLmlzTnVtYmVyKGQpID8gZCA6IGRba2V5XSwgLy8geCB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgICAgIGxhYmVsOiAnJywgLy8gYXhpcyBsYWJlbCxcclxuICAgICAgICBvcmllbnQ6IFwibGVmdFwiLFxyXG4gICAgICAgIHNjYWxlOiBcImxpbmVhclwiXHJcbiAgICB9O1xyXG4gICAgZ3JvdXBzPXtcclxuICAgICAgICBrZXk6IDEsXHJcbiAgICAgICAgdmFsdWU6IChkKSA9PiBkW3RoaXMuZ3JvdXBzLmtleV0gLCAvLyBncm91cGluZyB2YWx1ZSBhY2Nlc3NvcixcclxuICAgICAgICBsYWJlbDogXCJcIlxyXG4gICAgfTtcclxuICAgIGNvbG9yID0gdW5kZWZpbmVkIC8vIHN0cmluZyBvciBmdW5jdGlvbiByZXR1cm5pbmcgY29sb3IncyB2YWx1ZSBmb3IgY29sb3Igc2NhbGVcclxuICAgIGQzQ29sb3JDYXRlZ29yeT0gJ2NhdGVnb3J5MTAnO1xyXG4gICAgdHJhbnNpdGlvbj0gdHJ1ZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pe1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdmFyIGNvbmZpZyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmKGN1c3RvbSl7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgQmFyQ2hhcnQgZXh0ZW5kcyBDaGFydHtcclxuICAgIGNvbnN0cnVjdG9yKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIGNvbmZpZykge1xyXG4gICAgICAgIHN1cGVyKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIG5ldyBCYXJDaGFydENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRDb25maWcoY29uZmlnKXtcclxuICAgICAgICByZXR1cm4gc3VwZXIuc2V0Q29uZmlnKG5ldyBCYXJDaGFydENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpe1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGY9dGhpcztcclxuXHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90Lng9e307XHJcbiAgICAgICAgdGhpcy5wbG90Lnk9e307XHJcblxyXG4gICAgICAgIHRoaXMucGxvdC5zaG93TGVnZW5kID0gY29uZi5zaG93TGVnZW5kO1xyXG4gICAgICAgIGlmKHRoaXMucGxvdC5zaG93TGVnZW5kKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lm1hcmdpbi5yaWdodCA9IGNvbmYubWFyZ2luLnJpZ2h0ICsgY29uZi5sZWdlbmQud2lkdGgrY29uZi5sZWdlbmQubWFyZ2luKjI7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgdGhpcy5jb21wdXRlUGxvdFNpemUoKTtcclxuICAgICAgICB0aGlzLnNldHVwWSgpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBYKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cEdyb3VwU3RhY2tzKCk7XHJcblxyXG5cclxuICAgICAgICB0aGlzLnNldHVwWURvbWFpbigpO1xyXG5cclxuXHJcbiAgICAgICAgaWYoY29uZi5kM0NvbG9yQ2F0ZWdvcnkpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuY29sb3JDYXRlZ29yeSA9IGQzLnNjYWxlW2NvbmYuZDNDb2xvckNhdGVnb3J5XSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgY29sb3JWYWx1ZSA9IGNvbmYuY29sb3I7XHJcbiAgICAgICAgaWYgKGNvbG9yVmFsdWUgJiYgdHlwZW9mIGNvbG9yVmFsdWUgPT09ICdzdHJpbmcnIHx8IGNvbG9yVmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuY29sb3IgPSBjb2xvclZhbHVlO1xyXG4gICAgICAgIH1lbHNlIGlmKHRoaXMucGxvdC5jb2xvckNhdGVnb3J5KXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmNvbG9yID0gZCA9PiAgc2VsZi5wbG90LmNvbG9yQ2F0ZWdvcnkoZC5rZXkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG5cclxuXHJcbiAgICBzZXR1cFgoKXtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIHggPSBwbG90Lng7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZy54O1xyXG5cclxuICAgICAgICAvKiAqXHJcbiAgICAgICAgICogdmFsdWUgYWNjZXNzb3IgLSByZXR1cm5zIHRoZSB2YWx1ZSB0byBlbmNvZGUgZm9yIGEgZ2l2ZW4gZGF0YSBvYmplY3QuXHJcbiAgICAgICAgICogc2NhbGUgLSBtYXBzIHZhbHVlIHRvIGEgdmlzdWFsIGRpc3BsYXkgZW5jb2RpbmcsIHN1Y2ggYXMgYSBwaXhlbCBwb3NpdGlvbi5cclxuICAgICAgICAgKiBtYXAgZnVuY3Rpb24gLSBtYXBzIGZyb20gZGF0YSB2YWx1ZSB0byBkaXNwbGF5IHZhbHVlXHJcbiAgICAgICAgICogYXhpcyAtIHNldHMgdXAgYXhpc1xyXG4gICAgICAgICAqKi9cclxuICAgICAgICB4LnZhbHVlID0gZCA9PiBjb25mLnZhbHVlKGQsIGNvbmYua2V5KTtcclxuICAgICAgICB4LnNjYWxlID0gZDMuc2NhbGUub3JkaW5hbCgpLnJhbmdlUm91bmRCYW5kcyhbMCwgcGxvdC53aWR0aF0sIC4wOCk7XHJcbiAgICAgICAgeC5tYXAgPSBkID0+IHguc2NhbGUoeC52YWx1ZShkKSk7XHJcblxyXG4gICAgICAgIHguYXhpcyA9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeC5zY2FsZSkub3JpZW50KGNvbmYub3JpZW50KTtcclxuXHJcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLmRhdGE7XHJcbiAgICAgICAgdmFyIGRvbWFpbjtcclxuICAgICAgICBpZighdGhpcy5jb25maWcuc2VyaWVzKXtcclxuICAgICAgICAgICAgZG9tYWluID0gZDMubWFwKGRhdGEsIHgudmFsdWUpLmtleXMoKTtcclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgZG9tYWluID0gZDMubWFwKGRhdGFbMF0udmFsdWVzLCB4LnZhbHVlKS5rZXlzKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwbG90Lnguc2NhbGUuZG9tYWluKGRvbWFpbik7XHJcbiAgICAgICAgY29uc29sZS5sb2coJyBwbG90Lnguc2NhbGUuZG9tYWluJywgcGxvdC54LnNjYWxlLmRvbWFpbigpKTtcclxuICAgICAgICBcclxuICAgIH07XHJcblxyXG4gICAgc2V0dXBZICgpe1xyXG5cclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgeSA9IHBsb3QueTtcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnLnk7XHJcbiAgICAgICAgeS52YWx1ZSA9IGQgPT4gY29uZi52YWx1ZShkLCBjb25mLmtleSk7XHJcbiAgICAgICAgeS5zY2FsZSA9IGQzLnNjYWxlW2NvbmYuc2NhbGVdKCkucmFuZ2UoW3Bsb3QuaGVpZ2h0LCAwXSk7XHJcbiAgICAgICAgeS5tYXAgPSBkID0+IHkuc2NhbGUoeS52YWx1ZShkKSk7XHJcblxyXG4gICAgICAgIHkuYXhpcyA9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeS5zY2FsZSkub3JpZW50KGNvbmYub3JpZW50KTtcclxuICAgICAgICBpZihjb25mLnRpY2tzKXtcclxuICAgICAgICAgICAgeS5heGlzLnRpY2tzKGNvbmYudGlja3MpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgc2V0dXBZRG9tYWluKCkge1xyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5kYXRhO1xyXG4gICAgICAgIHZhciBkb21haW47XHJcbiAgICAgICAgdmFyIHlTdGFja01heCA9IGQzLm1heChwbG90LmxheWVycywgbGF5ZXIgPT4gZDMubWF4KGxheWVyLnZhbHVlcywgZCA9PiBkLnkwICsgZC55KSk7XHJcbiAgICAgICAgaWYoIXRoaXMuY29uZmlnLnNlcmllcyl7XHJcbiAgICAgICAgICAgIGRvbWFpbiA9IFtkMy5taW4oZGF0YSwgcGxvdC55LnZhbHVlKSwgZDMubWF4KGRhdGEsIHBsb3QueS52YWx1ZSldO1xyXG4gICAgICAgIH1lbHNle1xyXG5cclxuICAgICAgICAgICAgLy8gdmFyIG1pbiA9IGQzLm1pbihkYXRhLCBzPT5kMy5taW4ocy52YWx1ZXMsIHBsb3QueS52YWx1ZSkpO1xyXG4gICAgICAgICAgICB2YXIgbWF4ID0geVN0YWNrTWF4O1xyXG4gICAgICAgICAgICBkb21haW4gPSBbMCwgbWF4XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcGxvdC55LnNjYWxlLmRvbWFpbihkb21haW4pO1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCcgcGxvdC55LnNjYWxlLmRvbWFpbicsIHBsb3QueS5zY2FsZS5kb21haW4oKSk7XHJcbiAgICB9XHJcbiAgICBncm91cERhdGEoKXtcclxuICAgICAgICB2YXIgc2VsZj10aGlzO1xyXG4gICAgICAgIHRoaXMucGxvdC5ncm91cGluZ0VuYWJsZWQgPSB0aGlzLmNvbmZpZy5zZXJpZXM7XHJcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLmRhdGE7XHJcbiAgICAgICAgaWYoIXRoaXMucGxvdC5ncm91cGluZ0VuYWJsZWQgKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lmdyb3VwZWREYXRhID0gIFt7XHJcbiAgICAgICAgICAgICAgICBrZXk6ICdyb290JyxcclxuICAgICAgICAgICAgICAgIHZhbHVlczogc2VsZi5tYXBUb1BvaW50cyhkYXRhKVxyXG4gICAgICAgICAgICB9XTtcclxuICAgICAgICB9ZWxzZXtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5ncm91cGVkRGF0YSA9ICBkYXRhLm1hcChzPT57XHJcbiAgICAgICAgICAgICAgICByZXR1cm57XHJcbiAgICAgICAgICAgICAgICAgICAga2V5OiBzLmtleSxcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IHNlbGYubWFwVG9Qb2ludHMocy52YWx1ZXMpXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzZXR1cEdyb3VwU3RhY2tzKCkge1xyXG4gICAgICAgIHZhciBzZWxmPXRoaXM7XHJcbiAgICAgICAgdGhpcy5ncm91cERhdGEoKTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnN0YWNrID0gZDMubGF5b3V0LnN0YWNrKCkudmFsdWVzKGQ9PmQudmFsdWVzKTtcclxuICAgICAgICB0aGlzLnBsb3QubGF5ZXJzID0gdGhpcy5wbG90LnN0YWNrKHRoaXMucGxvdC5ncm91cGVkRGF0YSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIG1hcFRvUG9pbnRzKHZhbHVlcyl7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5tYXAodj0+e1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgeDogcGxvdC54LnZhbHVlKHYpLFxyXG4gICAgICAgICAgICAgICAgeTogcGxvdC55LnZhbHVlKHYpLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICBkcmF3QXhpc1goKXtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGF4aXNDb25mID0gdGhpcy5jb25maWcueDtcclxuICAgICAgICB2YXIgYXhpcyA9IHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcy14JykrXCIuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcycpKyhzZWxmLmNvbmZpZy5ndWlkZXMgPyAnJyA6ICcuJytzZWxmLnByZWZpeENsYXNzKCduby1ndWlkZXMnKSkpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKDAsXCIgKyBwbG90LmhlaWdodCArIFwiKVwiKTtcclxuXHJcbiAgICAgICAgdmFyIGF4aXNUID0gYXhpcztcclxuICAgICAgICBpZiAoc2VsZi5jb25maWcudHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICBheGlzVCA9IGF4aXMudHJhbnNpdGlvbigpLmVhc2UoXCJzaW4taW4tb3V0XCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXhpc1QuY2FsbChwbG90LnguYXhpcyk7XHJcblxyXG4gICAgICAgIGF4aXMuc2VsZWN0T3JBcHBlbmQoXCJ0ZXh0LlwiK3NlbGYucHJlZml4Q2xhc3MoJ2xhYmVsJykpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiKyAocGxvdC53aWR0aC8yKSArXCIsXCIrIChwbG90Lm1hcmdpbi5ib3R0b20pICtcIilcIikgIC8vIHRleHQgaXMgZHJhd24gb2ZmIHRoZSBzY3JlZW4gdG9wIGxlZnQsIG1vdmUgZG93biBhbmQgb3V0IGFuZCByb3RhdGVcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIi0xZW1cIilcclxuICAgICAgICAgICAgLnN0eWxlKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIilcclxuICAgICAgICAgICAgLnRleHQoYXhpc0NvbmYubGFiZWwpO1xyXG4gICAgfTtcclxuXHJcbiAgICBkcmF3QXhpc1koKXtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGF4aXNDb25mID0gdGhpcy5jb25maWcueTtcclxuICAgICAgICB2YXIgYXhpcyA9IHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcy15JykrXCIuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcycpKyhzZWxmLmNvbmZpZy5ndWlkZXMgPyAnJyA6ICcuJytzZWxmLnByZWZpeENsYXNzKCduby1ndWlkZXMnKSkpO1xyXG5cclxuICAgICAgICB2YXIgYXhpc1QgPSBheGlzO1xyXG4gICAgICAgIGlmIChzZWxmLmNvbmZpZy50cmFuc2l0aW9uKSB7XHJcbiAgICAgICAgICAgIGF4aXNUID0gYXhpcy50cmFuc2l0aW9uKCkuZWFzZShcInNpbi1pbi1vdXRcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBheGlzVC5jYWxsKHBsb3QueS5heGlzKTtcclxuXHJcbiAgICAgICAgYXhpcy5zZWxlY3RPckFwcGVuZChcInRleHQuXCIrc2VsZi5wcmVmaXhDbGFzcygnbGFiZWwnKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIrIC1wbG90Lm1hcmdpbi5sZWZ0ICtcIixcIisocGxvdC5oZWlnaHQvMikrXCIpcm90YXRlKC05MClcIikgIC8vIHRleHQgaXMgZHJhd24gb2ZmIHRoZSBzY3JlZW4gdG9wIGxlZnQsIG1vdmUgZG93biBhbmQgb3V0IGFuZCByb3RhdGVcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIjFlbVwiKVxyXG4gICAgICAgICAgICAuc3R5bGUoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChheGlzQ29uZi5sYWJlbCk7XHJcbiAgICB9O1xyXG5cclxuXHJcbiAgICBkcmF3QmFycygpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKHBsb3QubGF5ZXJzKTtcclxuXHJcbiAgICAgICAgdmFyIGxheWVyQ2xhc3MgPSB0aGlzLnByZWZpeENsYXNzKFwibGF5ZXJcIik7XHJcblxyXG4gICAgICAgIHZhciBiYXJDbGFzcyA9IHRoaXMucHJlZml4Q2xhc3MoXCJiYXJcIik7XHJcbiAgICAgICAgdmFyIGxheWVyID0gc2VsZi5zdmdHLnNlbGVjdEFsbChcIi5cIitsYXllckNsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShwbG90LmxheWVycyk7XHJcblxyXG4gICAgICAgIGxheWVyLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGxheWVyQ2xhc3MpO1xyXG5cclxuICAgICAgICB2YXIgYmFyID0gbGF5ZXIuc2VsZWN0QWxsKFwiLlwiK2JhckNsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShkID0+IGQudmFsdWVzKTtcclxuXHJcbiAgICAgICAgYmFyLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGJhckNsYXNzKVxyXG4gICAgICAgICAgICAuYXBwZW5kKFwicmVjdFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMSk7XHJcblxyXG5cclxuICAgICAgICB2YXIgYmFyUmVjdCA9IGJhci5zZWxlY3QoXCJyZWN0XCIpO1xyXG5cclxuICAgICAgICB2YXIgYmFyUmVjdFQgPSBiYXJSZWN0O1xyXG4gICAgICAgIHZhciBiYXJUID0gYmFyO1xyXG4gICAgICAgIHZhciBsYXllclQgPSBsYXllcjtcclxuICAgICAgICBpZiAodGhpcy50cmFuc2l0aW9uRW5hYmxlZCgpKSB7XHJcbiAgICAgICAgICAgIGJhclJlY3RUID0gYmFyUmVjdC50cmFuc2l0aW9uKCk7XHJcbiAgICAgICAgICAgIGJhclQgPSBiYXIudHJhbnNpdGlvbigpO1xyXG4gICAgICAgICAgICBsYXllclQ9IGxheWVyLnRyYW5zaXRpb24oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciB5RG9tYWluID0gcGxvdC55LnNjYWxlLmRvbWFpbigpO1xyXG4gICAgICAgIGJhclQuYXR0cihcInRyYW5zZm9ybVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBcInRyYW5zbGF0ZShcIiArIHBsb3QueC5zY2FsZShkLngpICsgXCIsXCIgKyAocGxvdC55LnNjYWxlKGQueTArZC55ICkpICsgXCIpXCI7IH0pO1xyXG5cclxuICAgICAgICBiYXJSZWN0VFxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsICBwbG90Lnguc2NhbGUucmFuZ2VCYW5kKCkpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGQgPT4gICBwbG90Lnkuc2NhbGUoZC55MCApIC0gcGxvdC55LnNjYWxlKGQueTAgKyBkLnkgLSB5RG9tYWluWzBdKSk7XHJcblxyXG5cclxuICAgICAgICBpZih0aGlzLnBsb3QuY29sb3Ipe1xyXG4gICAgICAgICAgICBsYXllclRcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwiZmlsbFwiLCB0aGlzLnBsb3QuY29sb3IpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBsb3QudG9vbHRpcCkge1xyXG4gICAgICAgICAgICBiYXIub24oXCJtb3VzZW92ZXJcIiwgZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDIwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIC45KTtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGQueSlcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJsZWZ0XCIsIChkMy5ldmVudC5wYWdlWCArIDUpICsgXCJweFwiKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcInRvcFwiLCAoZDMuZXZlbnQucGFnZVkgLSAyOCkgKyBcInB4XCIpO1xyXG4gICAgICAgICAgICB9KS5vbihcIm1vdXNlb3V0XCIsIGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbig1MDApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxheWVyLmV4aXQoKS5yZW1vdmUoKTtcclxuICAgICAgICBiYXIuZXhpdCgpLnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZShuZXdEYXRhKXtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcbiAgICAgICAgdGhpcy5kcmF3QXhpc1goKTtcclxuICAgICAgICB0aGlzLmRyYXdBeGlzWSgpO1xyXG5cclxuICAgICAgICB0aGlzLmRyYXdCYXJzKCk7XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlTGVnZW5kKCk7XHJcbiAgICB9O1xyXG5cclxuXHJcbiAgICB1cGRhdGVMZWdlbmQoKSB7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcblxyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3QuY29sb3JDYXRlZ29yeTtcclxuICAgICAgICBpZighc2NhbGUuZG9tYWluKCkgfHwgc2NhbGUuZG9tYWluKCkubGVuZ3RoPDIpe1xyXG4gICAgICAgICAgICBwbG90LnNob3dMZWdlbmQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKCFwbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICBpZihwbG90LmxlZ2VuZCAmJiBwbG90LmxlZ2VuZC5jb250YWluZXIpe1xyXG4gICAgICAgICAgICAgICAgcGxvdC5sZWdlbmQuY29udGFpbmVyLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgbGVnZW5kWCA9IHRoaXMucGxvdC53aWR0aCArIHRoaXMuY29uZmlnLmxlZ2VuZC5tYXJnaW47XHJcbiAgICAgICAgdmFyIGxlZ2VuZFkgPSB0aGlzLmNvbmZpZy5sZWdlbmQubWFyZ2luO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZCA9IG5ldyBMZWdlbmQodGhpcy5zdmcsIHRoaXMuc3ZnRywgc2NhbGUsIGxlZ2VuZFgsIGxlZ2VuZFkpO1xyXG5cclxuICAgICAgICB2YXIgbGVnZW5kTGluZWFyID0gcGxvdC5sZWdlbmQuY29sb3IoKVxyXG4gICAgICAgICAgICAuc2hhcGVXaWR0aCh0aGlzLmNvbmZpZy5sZWdlbmQuc2hhcGVXaWR0aClcclxuICAgICAgICAgICAgLm9yaWVudCgndmVydGljYWwnKVxyXG4gICAgICAgICAgICAuc2NhbGUoc2NhbGUpO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZC5jb250YWluZXJcclxuICAgICAgICAgICAgLmNhbGwobGVnZW5kTGluZWFyKTtcclxuICAgIH1cclxuXHJcblxyXG59XHJcbiIsImltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIENoYXJ0Q29uZmlnIHtcclxuICAgIGNzc0NsYXNzUHJlZml4ID0gXCJvZGMtXCI7XHJcbiAgICBzdmdDbGFzcyA9IHRoaXMuY3NzQ2xhc3NQcmVmaXggKyAnbXctZDMtY2hhcnQnO1xyXG4gICAgd2lkdGggPSB1bmRlZmluZWQ7XHJcbiAgICBoZWlnaHQgPSB1bmRlZmluZWQ7XHJcbiAgICBtYXJnaW4gPSB7XHJcbiAgICAgICAgbGVmdDogNTAsXHJcbiAgICAgICAgcmlnaHQ6IDMwLFxyXG4gICAgICAgIHRvcDogMzAsXHJcbiAgICAgICAgYm90dG9tOiA1MFxyXG4gICAgfTtcclxuICAgIHNob3dUb29sdGlwID0gZmFsc2U7XHJcbiAgICB0cmFuc2l0aW9uID0gdHJ1ZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pIHtcclxuICAgICAgICBpZiAoY3VzdG9tKSB7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIENoYXJ0IHtcclxuICAgIHV0aWxzID0gVXRpbHM7XHJcbiAgICBiYXNlQ29udGFpbmVyO1xyXG4gICAgc3ZnO1xyXG4gICAgY29uZmlnO1xyXG4gICAgcGxvdCA9IHtcclxuICAgICAgICBtYXJnaW46IHt9XHJcbiAgICB9O1xyXG4gICAgX2F0dGFjaGVkID0ge307XHJcbiAgICBfbGF5ZXJzID0ge307XHJcbiAgICBfZXZlbnRzID0ge307XHJcbiAgICBfaXNBdHRhY2hlZDtcclxuICAgIF9pc0luaXRpYWxpemVkPWZhbHNlO1xyXG5cclxuXHJcbiAgICBjb25zdHJ1Y3RvcihiYXNlLCBkYXRhLCBjb25maWcpIHtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLl9pc0F0dGFjaGVkID0gYmFzZSBpbnN0YW5jZW9mIENoYXJ0O1xyXG5cclxuICAgICAgICB0aGlzLmJhc2VDb250YWluZXIgPSBiYXNlO1xyXG5cclxuICAgICAgICB0aGlzLnNldENvbmZpZyhjb25maWcpO1xyXG5cclxuICAgICAgICBpZiAoZGF0YSkge1xyXG4gICAgICAgICAgICB0aGlzLnNldERhdGEoZGF0YSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmluaXQoKTtcclxuICAgICAgICB0aGlzLnBvc3RJbml0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Q29uZmlnKGNvbmZpZykge1xyXG4gICAgICAgIGlmICghY29uZmlnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlnID0gbmV3IENoYXJ0Q29uZmlnKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBzZXREYXRhKGRhdGEpIHtcclxuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIGluaXQoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuXHJcbiAgICAgICAgc2VsZi5pbml0UGxvdCgpO1xyXG4gICAgICAgIHNlbGYuaW5pdFN2ZygpO1xyXG5cclxuICAgICAgICBzZWxmLmluaXRUb29sdGlwKCk7XHJcbiAgICAgICAgc2VsZi5kcmF3KCk7XHJcbiAgICAgICAgdGhpcy5faXNJbml0aWFsaXplZD10cnVlO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHBvc3RJbml0KCl7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXRTdmcoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdmFyIG1hcmdpbiA9IHNlbGYucGxvdC5tYXJnaW47XHJcbiAgICAgICAgdmFyIHdpZHRoID0gc2VsZi5wbG90LndpZHRoICsgbWFyZ2luLmxlZnQgKyBtYXJnaW4ucmlnaHQ7XHJcbiAgICAgICAgdmFyIGhlaWdodCA9IHNlbGYucGxvdC5oZWlnaHQgKyBtYXJnaW4udG9wICsgbWFyZ2luLmJvdHRvbTtcclxuICAgICAgICB2YXIgYXNwZWN0ID0gd2lkdGggLyBoZWlnaHQ7XHJcbiAgICAgICAgaWYoIXNlbGYuX2lzQXR0YWNoZWQpe1xyXG4gICAgICAgICAgICBpZighdGhpcy5faXNJbml0aWFsaXplZCl7XHJcbiAgICAgICAgICAgICAgICBkMy5zZWxlY3Qoc2VsZi5iYXNlQ29udGFpbmVyKS5zZWxlY3QoXCJzdmdcIikucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2VsZi5zdmcgPSBkMy5zZWxlY3Qoc2VsZi5iYXNlQ29udGFpbmVyKS5zZWxlY3RPckFwcGVuZChcInN2Z1wiKTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuc3ZnXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIHdpZHRoKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgaGVpZ2h0KVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ2aWV3Qm94XCIsIFwiMCAwIFwiICsgXCIgXCIgKyB3aWR0aCArIFwiIFwiICsgaGVpZ2h0KVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJwcmVzZXJ2ZUFzcGVjdFJhdGlvXCIsIFwieE1pZFlNaWQgbWVldFwiKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBjb25maWcuc3ZnQ2xhc3MpO1xyXG4gICAgICAgICAgICBzZWxmLnN2Z0cgPSBzZWxmLnN2Zy5zZWxlY3RPckFwcGVuZChcImcubWFpbi1ncm91cFwiKTtcclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coc2VsZi5iYXNlQ29udGFpbmVyKTtcclxuICAgICAgICAgICAgc2VsZi5zdmcgPSBzZWxmLmJhc2VDb250YWluZXIuc3ZnO1xyXG4gICAgICAgICAgICBzZWxmLnN2Z0cgPSBzZWxmLnN2Zy5zZWxlY3RPckFwcGVuZChcImcubWFpbi1ncm91cC5cIitjb25maWcuc3ZnQ2xhc3MpXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxmLnN2Z0cuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIG1hcmdpbi5sZWZ0ICsgXCIsXCIgKyBtYXJnaW4udG9wICsgXCIpXCIpO1xyXG5cclxuICAgICAgICBpZiAoIWNvbmZpZy53aWR0aCB8fCBjb25maWcuaGVpZ2h0KSB7XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdCh3aW5kb3cpXHJcbiAgICAgICAgICAgICAgICAub24oXCJyZXNpemVcIiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vVE9ETyBhZGQgcmVzcG9uc2l2ZW5lc3MgaWYgd2lkdGgvaGVpZ2h0IG5vdCBzcGVjaWZpZWRcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpbml0VG9vbHRpcCgpe1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICBpZiAoc2VsZi5jb25maWcuc2hvd1Rvb2x0aXApIHtcclxuICAgICAgICAgICAgaWYoIXNlbGYuX2lzQXR0YWNoZWQgKXtcclxuICAgICAgICAgICAgICAgIHNlbGYucGxvdC50b29sdGlwID0gZDMuc2VsZWN0KFwiYm9keVwiKS5zZWxlY3RPckFwcGVuZCgnZGl2Licrc2VsZi5jb25maWcuY3NzQ2xhc3NQcmVmaXgrJ3Rvb2x0aXAnKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XHJcbiAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgICAgc2VsZi5wbG90LnRvb2x0aXA9IHNlbGYuYmFzZUNvbnRhaW5lci5wbG90LnRvb2x0aXA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGluaXRQbG90KCkge1xyXG4gICAgICAgIHZhciBtYXJnaW4gPSB0aGlzLmNvbmZpZy5tYXJnaW47XHJcbiAgICAgICAgdGhpcy5wbG90ID0gdGhpcy5wbG90IHx8IHt9O1xyXG4gICAgICAgIHRoaXMucGxvdC5tYXJnaW4gPSB7XHJcbiAgICAgICAgICAgIHRvcDogbWFyZ2luLnRvcCxcclxuICAgICAgICAgICAgYm90dG9tOiBtYXJnaW4uYm90dG9tLFxyXG4gICAgICAgICAgICBsZWZ0OiBtYXJnaW4ubGVmdCxcclxuICAgICAgICAgICAgcmlnaHQ6IG1hcmdpbi5yaWdodFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlKGRhdGEpIHtcclxuICAgICAgICBpZiAoZGF0YSkge1xyXG4gICAgICAgICAgICB0aGlzLnNldERhdGEoZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBsYXllck5hbWUsIGF0dGFjaG1lbnREYXRhO1xyXG4gICAgICAgIGZvciAodmFyIGF0dGFjaG1lbnROYW1lIGluIHRoaXMuX2F0dGFjaGVkKSB7XHJcblxyXG4gICAgICAgICAgICBhdHRhY2htZW50RGF0YSA9IGRhdGE7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9hdHRhY2hlZFthdHRhY2htZW50TmFtZV0udXBkYXRlKGF0dGFjaG1lbnREYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgZHJhdyhkYXRhKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGUoZGF0YSk7XHJcblxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcblxyXG4gICAgLy9Cb3Jyb3dlZCBmcm9tIGQzLmNoYXJ0XHJcbiAgICAvKipcclxuICAgICAqIFJlZ2lzdGVyIG9yIHJldHJpZXZlIGFuIFwiYXR0YWNobWVudFwiIENoYXJ0LiBUaGUgXCJhdHRhY2htZW50XCIgY2hhcnQncyBgZHJhd2BcclxuICAgICAqIG1ldGhvZCB3aWxsIGJlIGludm9rZWQgd2hlbmV2ZXIgdGhlIGNvbnRhaW5pbmcgY2hhcnQncyBgZHJhd2AgbWV0aG9kIGlzXHJcbiAgICAgKiBpbnZva2VkLlxyXG4gICAgICpcclxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUgY2hhcnQtYXR0YWNoXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGF0dGFjaG1lbnROYW1lIE5hbWUgb2YgdGhlIGF0dGFjaG1lbnRcclxuICAgICAqIEBwYXJhbSB7Q2hhcnR9IFtjaGFydF0gQ2hhcnQgdG8gcmVnaXN0ZXIgYXMgYSBtaXggaW4gb2YgdGhpcyBjaGFydC4gV2hlblxyXG4gICAgICogICAgICAgIHVuc3BlY2lmaWVkLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgYXR0YWNobWVudCBwcmV2aW91c2x5XHJcbiAgICAgKiAgICAgICAgcmVnaXN0ZXJlZCB3aXRoIHRoZSBzcGVjaWZpZWQgYGF0dGFjaG1lbnROYW1lYCAoaWYgYW55KS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Q2hhcnR9IFJlZmVyZW5jZSB0byB0aGlzIGNoYXJ0IChjaGFpbmFibGUpLlxyXG4gICAgICovXHJcbiAgICBhdHRhY2goYXR0YWNobWVudE5hbWUsIGNoYXJ0KSB7XHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F0dGFjaGVkW2F0dGFjaG1lbnROYW1lXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2F0dGFjaGVkW2F0dGFjaG1lbnROYW1lXSA9IGNoYXJ0O1xyXG4gICAgICAgIHJldHVybiBjaGFydDtcclxuICAgIH07XHJcblxyXG4gICAgXHJcblxyXG4gICAgLy9Cb3Jyb3dlZCBmcm9tIGQzLmNoYXJ0XHJcbiAgICAvKipcclxuICAgICAqIFN1YnNjcmliZSBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGFuIGV2ZW50IHRyaWdnZXJlZCBvbiB0aGUgY2hhcnQuIFNlZSB7QGxpbmtcclxuICAgICAgICAqIENoYXJ0I29uY2V9IHRvIHN1YnNjcmliZSBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGFuIGV2ZW50IGZvciBvbmUgb2NjdXJlbmNlLlxyXG4gICAgICpcclxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUge3J1bm5hYmxlfSBjaGFydC1vblxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIE5hbWUgb2YgdGhlIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0NoYXJ0RXZlbnRIYW5kbGVyfSBjYWxsYmFjayBGdW5jdGlvbiB0byBiZSBpbnZva2VkIHdoZW4gdGhlIGV2ZW50XHJcbiAgICAgKiAgICAgICAgb2NjdXJzXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW2NvbnRleHRdIFZhbHVlIHRvIHNldCBhcyBgdGhpc2Agd2hlbiBpbnZva2luZyB0aGVcclxuICAgICAqICAgICAgICBgY2FsbGJhY2tgLiBEZWZhdWx0cyB0byB0aGUgY2hhcnQgaW5zdGFuY2UuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0NoYXJ0fSBBIHJlZmVyZW5jZSB0byB0aGlzIGNoYXJ0IChjaGFpbmFibGUpLlxyXG4gICAgICovXHJcbiAgICBvbihuYW1lLCBjYWxsYmFjaywgY29udGV4dCkge1xyXG4gICAgICAgIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNbbmFtZV0gfHwgKHRoaXMuX2V2ZW50c1tuYW1lXSA9IFtdKTtcclxuICAgICAgICBldmVudHMucHVzaCh7XHJcbiAgICAgICAgICAgIGNhbGxiYWNrOiBjYWxsYmFjayxcclxuICAgICAgICAgICAgY29udGV4dDogY29udGV4dCB8fCB0aGlzLFxyXG4gICAgICAgICAgICBfY2hhcnQ6IHRoaXNcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICAvL0JvcnJvd2VkIGZyb20gZDMuY2hhcnRcclxuICAgIC8qKlxyXG4gICAgICpcclxuICAgICAqIFN1YnNjcmliZSBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGFuIGV2ZW50IHRyaWdnZXJlZCBvbiB0aGUgY2hhcnQuIFRoaXNcclxuICAgICAqIGZ1bmN0aW9uIHdpbGwgYmUgaW52b2tlZCBhdCB0aGUgbmV4dCBvY2N1cmFuY2Ugb2YgdGhlIGV2ZW50IGFuZCBpbW1lZGlhdGVseVxyXG4gICAgICogdW5zdWJzY3JpYmVkLiBTZWUge0BsaW5rIENoYXJ0I29ufSB0byBzdWJzY3JpYmUgYSBjYWxsYmFjayBmdW5jdGlvbiB0byBhblxyXG4gICAgICogZXZlbnQgaW5kZWZpbml0ZWx5LlxyXG4gICAgICpcclxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUge3J1bm5hYmxlfSBjaGFydC1vbmNlXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgTmFtZSBvZiB0aGUgZXZlbnRcclxuICAgICAqIEBwYXJhbSB7Q2hhcnRFdmVudEhhbmRsZXJ9IGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGJlIGludm9rZWQgd2hlbiB0aGUgZXZlbnRcclxuICAgICAqICAgICAgICBvY2N1cnNcclxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dF0gVmFsdWUgdG8gc2V0IGFzIGB0aGlzYCB3aGVuIGludm9raW5nIHRoZVxyXG4gICAgICogICAgICAgIGBjYWxsYmFja2AuIERlZmF1bHRzIHRvIHRoZSBjaGFydCBpbnN0YW5jZVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtDaGFydH0gQSByZWZlcmVuY2UgdG8gdGhpcyBjaGFydCAoY2hhaW5hYmxlKVxyXG4gICAgICovXHJcbiAgICBvbmNlKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBvbmNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBzZWxmLm9mZihuYW1lLCBvbmNlKTtcclxuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9uKG5hbWUsIG9uY2UsIGNvbnRleHQpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvL0JvcnJvd2VkIGZyb20gZDMuY2hhcnRcclxuICAgIC8qKlxyXG4gICAgICogVW5zdWJzY3JpYmUgb25lIG9yIG1vcmUgY2FsbGJhY2sgZnVuY3Rpb25zIGZyb20gYW4gZXZlbnQgdHJpZ2dlcmVkIG9uIHRoZVxyXG4gICAgICogY2hhcnQuIFdoZW4gbm8gYXJndW1lbnRzIGFyZSBzcGVjaWZpZWQsICphbGwqIGhhbmRsZXJzIHdpbGwgYmUgdW5zdWJzY3JpYmVkLlxyXG4gICAgICogV2hlbiBvbmx5IGEgYG5hbWVgIGlzIHNwZWNpZmllZCwgYWxsIGhhbmRsZXJzIHN1YnNjcmliZWQgdG8gdGhhdCBldmVudCB3aWxsXHJcbiAgICAgKiBiZSB1bnN1YnNjcmliZWQuIFdoZW4gYSBgbmFtZWAgYW5kIGBjYWxsYmFja2AgYXJlIHNwZWNpZmllZCwgb25seSB0aGF0XHJcbiAgICAgKiBmdW5jdGlvbiB3aWxsIGJlIHVuc3Vic2NyaWJlZCBmcm9tIHRoYXQgZXZlbnQuIFdoZW4gYSBgbmFtZWAgYW5kIGBjb250ZXh0YFxyXG4gICAgICogYXJlIHNwZWNpZmllZCAoYnV0IGBjYWxsYmFja2AgaXMgb21pdHRlZCksIGFsbCBldmVudHMgYm91bmQgdG8gdGhlIGdpdmVuXHJcbiAgICAgKiBldmVudCB3aXRoIHRoZSBnaXZlbiBjb250ZXh0IHdpbGwgYmUgdW5zdWJzY3JpYmVkLlxyXG4gICAgICpcclxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUge3J1bm5hYmxlfSBjaGFydC1vZmZcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gW25hbWVdIE5hbWUgb2YgdGhlIGV2ZW50IHRvIGJlIHVuc3Vic2NyaWJlZFxyXG4gICAgICogQHBhcmFtIHtDaGFydEV2ZW50SGFuZGxlcn0gW2NhbGxiYWNrXSBGdW5jdGlvbiB0byBiZSB1bnN1YnNjcmliZWRcclxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dF0gQ29udGV4dHMgdG8gYmUgdW5zdWJzY3JpYmVcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Q2hhcnR9IEEgcmVmZXJlbmNlIHRvIHRoaXMgY2hhcnQgKGNoYWluYWJsZSkuXHJcbiAgICAgKi9cclxuXHJcbiAgICBvZmYobmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcclxuICAgICAgICB2YXIgbmFtZXMsIG4sIGV2ZW50cywgZXZlbnQsIGksIGo7XHJcblxyXG4gICAgICAgIC8vIHJlbW92ZSBhbGwgZXZlbnRzXHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZm9yIChuYW1lIGluIHRoaXMuX2V2ZW50cykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW25hbWVdLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyByZW1vdmUgYWxsIGV2ZW50cyBmb3IgYSBzcGVjaWZpYyBuYW1lXHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzW25hbWVdO1xyXG4gICAgICAgICAgICBpZiAoZXZlbnRzKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudHMubGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggd2hhdGV2ZXIgY29tYmluYXRpb24gb2YgbmFtZSwgY29udGV4dFxyXG4gICAgICAgIC8vIGFuZCBjYWxsYmFjay5cclxuICAgICAgICBuYW1lcyA9IG5hbWUgPyBbbmFtZV0gOiBPYmplY3Qua2V5cyh0aGlzLl9ldmVudHMpO1xyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBuID0gbmFtZXNbaV07XHJcbiAgICAgICAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuXTtcclxuICAgICAgICAgICAgaiA9IGV2ZW50cy5sZW5ndGg7XHJcbiAgICAgICAgICAgIHdoaWxlIChqLS0pIHtcclxuICAgICAgICAgICAgICAgIGV2ZW50ID0gZXZlbnRzW2pdO1xyXG4gICAgICAgICAgICAgICAgaWYgKChjYWxsYmFjayAmJiBjYWxsYmFjayA9PT0gZXZlbnQuY2FsbGJhY2spIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgKGNvbnRleHQgJiYgY29udGV4dCA9PT0gZXZlbnQuY29udGV4dCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudHMuc3BsaWNlKGosIDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy9Cb3Jyb3dlZCBmcm9tIGQzLmNoYXJ0XHJcbiAgICAvKipcclxuICAgICAqIFB1Ymxpc2ggYW4gZXZlbnQgb24gdGhpcyBjaGFydCB3aXRoIHRoZSBnaXZlbiBgbmFtZWAuXHJcbiAgICAgKlxyXG4gICAgICogQGV4dGVybmFsRXhhbXBsZSB7cnVubmFibGV9IGNoYXJ0LXRyaWdnZXJcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBOYW1lIG9mIHRoZSBldmVudCB0byBwdWJsaXNoXHJcbiAgICAgKiBAcGFyYW0gey4uLip9IGFyZ3VtZW50cyBWYWx1ZXMgd2l0aCB3aGljaCB0byBpbnZva2UgdGhlIHJlZ2lzdGVyZWRcclxuICAgICAqICAgICAgICBjYWxsYmFja3MuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0NoYXJ0fSBBIHJlZmVyZW5jZSB0byB0aGlzIGNoYXJ0IChjaGFpbmFibGUpLlxyXG4gICAgICovXHJcbiAgICB0cmlnZ2VyKG5hbWUpIHtcclxuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XHJcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuYW1lXTtcclxuICAgICAgICB2YXIgaSwgZXY7XHJcblxyXG4gICAgICAgIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBldiA9IGV2ZW50c1tpXTtcclxuICAgICAgICAgICAgICAgIGV2LmNhbGxiYWNrLmFwcGx5KGV2LmNvbnRleHQsIGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBnZXRCYXNlQ29udGFpbmVyKCl7XHJcbiAgICAgICAgaWYodGhpcy5faXNBdHRhY2hlZCl7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmJhc2VDb250YWluZXIuc3ZnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZDMuc2VsZWN0KHRoaXMuYmFzZUNvbnRhaW5lcik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0QmFzZUNvbnRhaW5lck5vZGUoKXtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QmFzZUNvbnRhaW5lcigpLm5vZGUoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcmVmaXhDbGFzcyhjbGF6eiwgYWRkRG90KXtcclxuICAgICAgICByZXR1cm4gYWRkRG90PyAnLic6ICcnK3RoaXMuY29uZmlnLmNzc0NsYXNzUHJlZml4K2NsYXp6O1xyXG4gICAgfVxyXG4gICAgY29tcHV0ZVBsb3RTaXplKCkge1xyXG4gICAgICAgIHRoaXMucGxvdC53aWR0aCA9IFV0aWxzLmF2YWlsYWJsZVdpZHRoKHRoaXMuY29uZmlnLndpZHRoLCB0aGlzLmdldEJhc2VDb250YWluZXIoKSwgdGhpcy5wbG90Lm1hcmdpbik7XHJcbiAgICAgICAgdGhpcy5wbG90LmhlaWdodCA9IFV0aWxzLmF2YWlsYWJsZUhlaWdodCh0aGlzLmNvbmZpZy5oZWlnaHQsIHRoaXMuZ2V0QmFzZUNvbnRhaW5lcigpLCB0aGlzLnBsb3QubWFyZ2luKTtcclxuICAgIH1cclxuXHJcbiAgICB0cmFuc2l0aW9uRW5hYmxlZCgpe1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pc0luaXRpYWxpemVkICYmIHRoaXMuY29uZmlnLnRyYW5zaXRpb247XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcbmltcG9ydCB7U3RhdGlzdGljc1V0aWxzfSBmcm9tICcuL3N0YXRpc3RpY3MtdXRpbHMnXHJcbmltcG9ydCB7TGVnZW5kfSBmcm9tICcuL2xlZ2VuZCdcclxuaW1wb3J0IHtTY2F0dGVyUGxvdH0gZnJvbSAnLi9zY2F0dGVycGxvdCdcclxuXHJcbmV4cG9ydCBjbGFzcyBDb3JyZWxhdGlvbk1hdHJpeENvbmZpZyBleHRlbmRzIENoYXJ0Q29uZmlnIHtcclxuXHJcbiAgICBzdmdDbGFzcyA9IHRoaXMuY3NzQ2xhc3NQcmVmaXgrJ2NvcnJlbGF0aW9uLW1hdHJpeCc7XHJcbiAgICBndWlkZXMgPSBmYWxzZTsgLy9zaG93IGF4aXMgZ3VpZGVzXHJcbiAgICBzaG93VG9vbHRpcCA9IHRydWU7IC8vc2hvdyB0b29sdGlwIG9uIGRvdCBob3ZlclxyXG4gICAgc2hvd0xlZ2VuZCA9IHRydWU7XHJcbiAgICBoaWdobGlnaHRMYWJlbHMgPSB0cnVlO1xyXG4gICAgcm90YXRlTGFiZWxzWCA9IHRydWU7XHJcbiAgICByb3RhdGVMYWJlbHNZID0gdHJ1ZTtcclxuICAgIHZhcmlhYmxlcyA9IHtcclxuICAgICAgICBsYWJlbHM6IHVuZGVmaW5lZCxcclxuICAgICAgICBrZXlzOiBbXSwgLy9vcHRpb25hbCBhcnJheSBvZiB2YXJpYWJsZSBrZXlzXHJcbiAgICAgICAgdmFsdWU6IChkLCB2YXJpYWJsZUtleSkgPT4gZFt2YXJpYWJsZUtleV0sIC8vIHZhcmlhYmxlIHZhbHVlIGFjY2Vzc29yXHJcbiAgICAgICAgc2NhbGU6IFwib3JkaW5hbFwiXHJcbiAgICB9O1xyXG4gICAgY29ycmVsYXRpb24gPSB7XHJcbiAgICAgICAgc2NhbGU6IFwibGluZWFyXCIsXHJcbiAgICAgICAgZG9tYWluOiBbLTEsIC0wLjc1LCAtMC41LCAwLCAwLjUsIDAuNzUsIDFdLFxyXG4gICAgICAgIHJhbmdlOiBbXCJkYXJrYmx1ZVwiLCBcImJsdWVcIiwgXCJsaWdodHNreWJsdWVcIiwgXCJ3aGl0ZVwiLCBcIm9yYW5nZXJlZFwiLCBcImNyaW1zb25cIiwgXCJkYXJrcmVkXCJdLFxyXG4gICAgICAgIHZhbHVlOiAoeFZhbHVlcywgeVZhbHVlcykgPT4gU3RhdGlzdGljc1V0aWxzLnNhbXBsZUNvcnJlbGF0aW9uKHhWYWx1ZXMsIHlWYWx1ZXMpXHJcblxyXG4gICAgfTtcclxuICAgIGNlbGwgPSB7XHJcbiAgICAgICAgc2hhcGU6IFwiZWxsaXBzZVwiLCAvL3Bvc3NpYmxlIHZhbHVlczogcmVjdCwgY2lyY2xlLCBlbGxpcHNlXHJcbiAgICAgICAgc2l6ZTogdW5kZWZpbmVkLFxyXG4gICAgICAgIHNpemVNaW46IDE1LFxyXG4gICAgICAgIHNpemVNYXg6IDI1MCxcclxuICAgICAgICBwYWRkaW5nOiAxXHJcbiAgICB9O1xyXG4gICAgbWFyZ2luID0ge1xyXG4gICAgICAgIGxlZnQ6IDYwLFxyXG4gICAgICAgIHJpZ2h0OiA1MCxcclxuICAgICAgICB0b3A6IDMwLFxyXG4gICAgICAgIGJvdHRvbTogNjBcclxuICAgIH07XHJcblxyXG4gICAgY29uc3RydWN0b3IoY3VzdG9tKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICBpZiAoY3VzdG9tKSB7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBDb3JyZWxhdGlvbk1hdHJpeCBleHRlbmRzIENoYXJ0IHtcclxuICAgIGNvbnN0cnVjdG9yKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIGNvbmZpZykge1xyXG4gICAgICAgIHN1cGVyKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIG5ldyBDb3JyZWxhdGlvbk1hdHJpeENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRDb25maWcoY29uZmlnKSB7XHJcbiAgICAgICAgcmV0dXJuIHN1cGVyLnNldENvbmZpZyhuZXcgQ29ycmVsYXRpb25NYXRyaXhDb25maWcoY29uZmlnKSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXRQbG90KCkge1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBtYXJnaW4gPSB0aGlzLmNvbmZpZy5tYXJnaW47XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnggPSB7fTtcclxuICAgICAgICB0aGlzLnBsb3QuY29ycmVsYXRpb24gPSB7XHJcbiAgICAgICAgICAgIG1hdHJpeDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjZWxsczogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjb2xvcjoge30sXHJcbiAgICAgICAgICAgIHNoYXBlOiB7fVxyXG4gICAgICAgIH07XHJcblxyXG5cclxuICAgICAgICB0aGlzLnNldHVwVmFyaWFibGVzKCk7XHJcbiAgICAgICAgdmFyIHdpZHRoID0gY29uZi53aWR0aDtcclxuICAgICAgICB2YXIgcGxhY2Vob2xkZXJOb2RlID0gdGhpcy5nZXRCYXNlQ29udGFpbmVyTm9kZSgpO1xyXG4gICAgICAgIHRoaXMucGxvdC5wbGFjZWhvbGRlck5vZGUgPSBwbGFjZWhvbGRlck5vZGU7XHJcblxyXG4gICAgICAgIHZhciBwYXJlbnRXaWR0aCA9IHBsYWNlaG9sZGVyTm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aDtcclxuICAgICAgICBpZiAod2lkdGgpIHtcclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5wbG90LmNlbGxTaXplKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuY2VsbFNpemUgPSBNYXRoLm1heChjb25mLmNlbGwuc2l6ZU1pbiwgTWF0aC5taW4oY29uZi5jZWxsLnNpemVNYXgsICh3aWR0aCAtIG1hcmdpbi5sZWZ0IC0gbWFyZ2luLnJpZ2h0KSAvIHRoaXMucGxvdC52YXJpYWJsZXMubGVuZ3RoKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmNlbGxTaXplID0gdGhpcy5jb25maWcuY2VsbC5zaXplO1xyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLnBsb3QuY2VsbFNpemUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxvdC5jZWxsU2l6ZSA9IE1hdGgubWF4KGNvbmYuY2VsbC5zaXplTWluLCBNYXRoLm1pbihjb25mLmNlbGwuc2l6ZU1heCwgKHBhcmVudFdpZHRoIC0gbWFyZ2luLmxlZnQgLSBtYXJnaW4ucmlnaHQpIC8gdGhpcy5wbG90LnZhcmlhYmxlcy5sZW5ndGgpKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgd2lkdGggPSB0aGlzLnBsb3QuY2VsbFNpemUgKiB0aGlzLnBsb3QudmFyaWFibGVzLmxlbmd0aCArIG1hcmdpbi5sZWZ0ICsgbWFyZ2luLnJpZ2h0O1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoZWlnaHQgPSB3aWR0aDtcclxuICAgICAgICBpZiAoIWhlaWdodCkge1xyXG4gICAgICAgICAgICBoZWlnaHQgPSBwbGFjZWhvbGRlck5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5wbG90LndpZHRoID0gd2lkdGggLSBtYXJnaW4ubGVmdCAtIG1hcmdpbi5yaWdodDtcclxuICAgICAgICB0aGlzLnBsb3QuaGVpZ2h0ID0gdGhpcy5wbG90LndpZHRoO1xyXG5cclxuICAgICAgICB0aGlzLnNldHVwVmFyaWFibGVzU2NhbGVzKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cENvcnJlbGF0aW9uU2NhbGVzKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cENvcnJlbGF0aW9uTWF0cml4KCk7XHJcblxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBzZXR1cFZhcmlhYmxlc1NjYWxlcygpIHtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIHggPSBwbG90Lng7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZy52YXJpYWJsZXM7XHJcblxyXG4gICAgICAgIC8qICpcclxuICAgICAgICAgKiB2YWx1ZSBhY2Nlc3NvciAtIHJldHVybnMgdGhlIHZhbHVlIHRvIGVuY29kZSBmb3IgYSBnaXZlbiBkYXRhIG9iamVjdC5cclxuICAgICAgICAgKiBzY2FsZSAtIG1hcHMgdmFsdWUgdG8gYSB2aXN1YWwgZGlzcGxheSBlbmNvZGluZywgc3VjaCBhcyBhIHBpeGVsIHBvc2l0aW9uLlxyXG4gICAgICAgICAqIG1hcCBmdW5jdGlvbiAtIG1hcHMgZnJvbSBkYXRhIHZhbHVlIHRvIGRpc3BsYXkgdmFsdWVcclxuICAgICAgICAgKiBheGlzIC0gc2V0cyB1cCBheGlzXHJcbiAgICAgICAgICoqL1xyXG4gICAgICAgIHgudmFsdWUgPSBjb25mLnZhbHVlO1xyXG4gICAgICAgIHguc2NhbGUgPSBkMy5zY2FsZVtjb25mLnNjYWxlXSgpLnJhbmdlQmFuZHMoW3Bsb3Qud2lkdGgsIDBdKTtcclxuICAgICAgICB4Lm1hcCA9IGQgPT4geC5zY2FsZSh4LnZhbHVlKGQpKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIHNldHVwQ29ycmVsYXRpb25TY2FsZXMoKSB7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIGNvcnJDb25mID0gdGhpcy5jb25maWcuY29ycmVsYXRpb247XHJcblxyXG4gICAgICAgIHBsb3QuY29ycmVsYXRpb24uY29sb3Iuc2NhbGUgPSBkMy5zY2FsZVtjb3JyQ29uZi5zY2FsZV0oKS5kb21haW4oY29yckNvbmYuZG9tYWluKS5yYW5nZShjb3JyQ29uZi5yYW5nZSk7XHJcbiAgICAgICAgdmFyIHNoYXBlID0gcGxvdC5jb3JyZWxhdGlvbi5zaGFwZSA9IHt9O1xyXG5cclxuICAgICAgICB2YXIgY2VsbENvbmYgPSB0aGlzLmNvbmZpZy5jZWxsO1xyXG4gICAgICAgIHNoYXBlLnR5cGUgPSBjZWxsQ29uZi5zaGFwZTtcclxuXHJcbiAgICAgICAgdmFyIHNoYXBlU2l6ZSA9IHBsb3QuY2VsbFNpemUgLSBjZWxsQ29uZi5wYWRkaW5nICogMjtcclxuICAgICAgICBpZiAoc2hhcGUudHlwZSA9PSAnY2lyY2xlJykge1xyXG4gICAgICAgICAgICB2YXIgcmFkaXVzTWF4ID0gc2hhcGVTaXplIC8gMjtcclxuICAgICAgICAgICAgc2hhcGUucmFkaXVzU2NhbGUgPSBkMy5zY2FsZS5saW5lYXIoKS5kb21haW4oWzAsIDFdKS5yYW5nZShbMiwgcmFkaXVzTWF4XSk7XHJcbiAgICAgICAgICAgIHNoYXBlLnJhZGl1cyA9IGM9PiBzaGFwZS5yYWRpdXNTY2FsZShNYXRoLmFicyhjLnZhbHVlKSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChzaGFwZS50eXBlID09ICdlbGxpcHNlJykge1xyXG4gICAgICAgICAgICB2YXIgcmFkaXVzTWF4ID0gc2hhcGVTaXplIC8gMjtcclxuICAgICAgICAgICAgc2hhcGUucmFkaXVzU2NhbGUgPSBkMy5zY2FsZS5saW5lYXIoKS5kb21haW4oWzAsIDFdKS5yYW5nZShbcmFkaXVzTWF4LCAyXSk7XHJcbiAgICAgICAgICAgIHNoYXBlLnJhZGl1c1ggPSBjPT4gc2hhcGUucmFkaXVzU2NhbGUoTWF0aC5hYnMoYy52YWx1ZSkpO1xyXG4gICAgICAgICAgICBzaGFwZS5yYWRpdXNZID0gcmFkaXVzTWF4O1xyXG5cclxuICAgICAgICAgICAgc2hhcGUucm90YXRlVmFsID0gdiA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodiA9PSAwKSByZXR1cm4gXCIwXCI7XHJcbiAgICAgICAgICAgICAgICBpZiAodiA8IDApIHJldHVybiBcIi00NVwiO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiNDVcIlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChzaGFwZS50eXBlID09ICdyZWN0Jykge1xyXG4gICAgICAgICAgICBzaGFwZS5zaXplID0gc2hhcGVTaXplO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG5cclxuICAgIHNldHVwVmFyaWFibGVzKCkge1xyXG5cclxuICAgICAgICB2YXIgdmFyaWFibGVzQ29uZiA9IHRoaXMuY29uZmlnLnZhcmlhYmxlcztcclxuXHJcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLmRhdGE7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgcGxvdC5kb21haW5CeVZhcmlhYmxlID0ge307XHJcbiAgICAgICAgcGxvdC52YXJpYWJsZXMgPSB2YXJpYWJsZXNDb25mLmtleXM7XHJcbiAgICAgICAgaWYgKCFwbG90LnZhcmlhYmxlcyB8fCAhcGxvdC52YXJpYWJsZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHBsb3QudmFyaWFibGVzID0gVXRpbHMuaW5mZXJWYXJpYWJsZXMoZGF0YSwgdGhpcy5jb25maWcuZ3JvdXBzLmtleSwgdGhpcy5jb25maWcuaW5jbHVkZUluUGxvdCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwbG90LmxhYmVscyA9IFtdO1xyXG4gICAgICAgIHBsb3QubGFiZWxCeVZhcmlhYmxlID0ge307XHJcbiAgICAgICAgcGxvdC52YXJpYWJsZXMuZm9yRWFjaCgodmFyaWFibGVLZXksIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgIHBsb3QuZG9tYWluQnlWYXJpYWJsZVt2YXJpYWJsZUtleV0gPSBkMy5leHRlbnQoZGF0YSwgKGQpID0+IHZhcmlhYmxlc0NvbmYudmFsdWUoZCwgdmFyaWFibGVLZXkpKTtcclxuICAgICAgICAgICAgdmFyIGxhYmVsID0gdmFyaWFibGVLZXk7XHJcbiAgICAgICAgICAgIGlmICh2YXJpYWJsZXNDb25mLmxhYmVscyAmJiB2YXJpYWJsZXNDb25mLmxhYmVscy5sZW5ndGggPiBpbmRleCkge1xyXG5cclxuICAgICAgICAgICAgICAgIGxhYmVsID0gdmFyaWFibGVzQ29uZi5sYWJlbHNbaW5kZXhdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBsb3QubGFiZWxzLnB1c2gobGFiZWwpO1xyXG4gICAgICAgICAgICBwbG90LmxhYmVsQnlWYXJpYWJsZVt2YXJpYWJsZUtleV0gPSBsYWJlbDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgY29uc29sZS5sb2cocGxvdC5sYWJlbEJ5VmFyaWFibGUpO1xyXG5cclxuICAgIH07XHJcblxyXG5cclxuICAgIHNldHVwQ29ycmVsYXRpb25NYXRyaXgoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5kYXRhO1xyXG4gICAgICAgIHZhciBtYXRyaXggPSB0aGlzLnBsb3QuY29ycmVsYXRpb24ubWF0cml4ID0gW107XHJcbiAgICAgICAgdmFyIG1hdHJpeENlbGxzID0gdGhpcy5wbG90LmNvcnJlbGF0aW9uLm1hdHJpeC5jZWxscyA9IFtdO1xyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG5cclxuICAgICAgICB2YXIgdmFyaWFibGVUb1ZhbHVlcyA9IHt9O1xyXG4gICAgICAgIHBsb3QudmFyaWFibGVzLmZvckVhY2goKHYsIGkpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhcmlhYmxlVG9WYWx1ZXNbdl0gPSBkYXRhLm1hcChkPT5wbG90LngudmFsdWUoZCwgdikpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBwbG90LnZhcmlhYmxlcy5mb3JFYWNoKCh2MSwgaSkgPT4ge1xyXG4gICAgICAgICAgICB2YXIgcm93ID0gW107XHJcbiAgICAgICAgICAgIG1hdHJpeC5wdXNoKHJvdyk7XHJcblxyXG4gICAgICAgICAgICBwbG90LnZhcmlhYmxlcy5mb3JFYWNoKCh2MiwgaikgPT4ge1xyXG4gICAgICAgICAgICAgICAgdmFyIGNvcnIgPSAxO1xyXG4gICAgICAgICAgICAgICAgaWYgKHYxICE9IHYyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29yciA9IHNlbGYuY29uZmlnLmNvcnJlbGF0aW9uLnZhbHVlKHZhcmlhYmxlVG9WYWx1ZXNbdjFdLCB2YXJpYWJsZVRvVmFsdWVzW3YyXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IHtcclxuICAgICAgICAgICAgICAgICAgICByb3dWYXI6IHYxLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbFZhcjogdjIsXHJcbiAgICAgICAgICAgICAgICAgICAgcm93OiBpLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbDogaixcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogY29yclxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHJvdy5wdXNoKGNlbGwpO1xyXG5cclxuICAgICAgICAgICAgICAgIG1hdHJpeENlbGxzLnB1c2goY2VsbCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgdXBkYXRlKG5ld0RhdGEpIHtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcbiAgICAgICAgLy8gdGhpcy51cGRhdGVcclxuICAgICAgICB0aGlzLnVwZGF0ZUNlbGxzKCk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVWYXJpYWJsZUxhYmVscygpO1xyXG5cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnNob3dMZWdlbmQpIHtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVMZWdlbmQoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHVwZGF0ZVZhcmlhYmxlTGFiZWxzKCkge1xyXG4gICAgICAgIHRoaXMucGxvdC5sYWJlbENsYXNzID0gdGhpcy5wcmVmaXhDbGFzcyhcImxhYmVsXCIpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQXhpc1goKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUF4aXNZKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlQXhpc1goKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBsYWJlbENsYXNzID0gcGxvdC5sYWJlbENsYXNzO1xyXG4gICAgICAgIHZhciBsYWJlbFhDbGFzcyA9IGxhYmVsQ2xhc3MgKyBcIi14XCI7XHJcblxyXG4gICAgICAgIHZhciBsYWJlbHMgPSBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwidGV4dC5cIiArIGxhYmVsWENsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShwbG90LnZhcmlhYmxlcywgKGQsIGkpPT5pKTtcclxuXHJcbiAgICAgICAgbGFiZWxzLmVudGVyKCkuYXBwZW5kKFwidGV4dFwiKS5hdHRyKFwiY2xhc3NcIiwgKGQsIGkpID0+IGxhYmVsQ2xhc3MgKyBcIiBcIiArIGxhYmVsWENsYXNzICsgXCIgXCIgKyBsYWJlbFhDbGFzcyArIFwiLVwiICsgaSk7XHJcblxyXG4gICAgICAgIGxhYmVsc1xyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgKGQsIGkpID0+IGkgKiBwbG90LmNlbGxTaXplICsgcGxvdC5jZWxsU2l6ZSAvIDIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCBwbG90LmhlaWdodClcclxuICAgICAgICAgICAgLmF0dHIoXCJkeFwiLCAtMilcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCA1KVxyXG4gICAgICAgICAgICAuYXR0cihcInRleHQtYW5jaG9yXCIsIFwiZW5kXCIpXHJcblxyXG4gICAgICAgICAgICAvLyAuYXR0cihcImRvbWluYW50LWJhc2VsaW5lXCIsIFwiaGFuZ2luZ1wiKVxyXG4gICAgICAgICAgICAudGV4dCh2PT5wbG90LmxhYmVsQnlWYXJpYWJsZVt2XSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5yb3RhdGVMYWJlbHNYKSB7XHJcbiAgICAgICAgICAgIGxhYmVscy5hdHRyKFwidHJhbnNmb3JtXCIsIChkLCBpKSA9PiBcInJvdGF0ZSgtNDUsIFwiICsgKGkgKiBwbG90LmNlbGxTaXplICsgcGxvdC5jZWxsU2l6ZSAvIDIgICkgKyBcIiwgXCIgKyBwbG90LmhlaWdodCArIFwiKVwiKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIG1heFdpZHRoID0gc2VsZi5jb21wdXRlWEF4aXNMYWJlbHNXaWR0aCgpO1xyXG4gICAgICAgIGxhYmVscy5lYWNoKGZ1bmN0aW9uIChsYWJlbCkge1xyXG4gICAgICAgICAgICBVdGlscy5wbGFjZVRleHRXaXRoRWxsaXBzaXNBbmRUb29sdGlwKGQzLnNlbGVjdCh0aGlzKSwgbGFiZWwsIG1heFdpZHRoLCBzZWxmLmNvbmZpZy5zaG93VG9vbHRpcCA/IHNlbGYucGxvdC50b29sdGlwIDogZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsYWJlbHMuZXhpdCgpLnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUF4aXNZKCkge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHNlbGYucGxvdDtcclxuICAgICAgICB2YXIgbGFiZWxDbGFzcyA9IHBsb3QubGFiZWxDbGFzcztcclxuICAgICAgICB2YXIgbGFiZWxZQ2xhc3MgPSBwbG90LmxhYmVsQ2xhc3MgKyBcIi15XCI7XHJcbiAgICAgICAgdmFyIGxhYmVscyA9IHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgbGFiZWxZQ2xhc3MpXHJcbiAgICAgICAgICAgIC5kYXRhKHBsb3QudmFyaWFibGVzKTtcclxuXHJcbiAgICAgICAgbGFiZWxzLmVudGVyKCkuYXBwZW5kKFwidGV4dFwiKTtcclxuXHJcbiAgICAgICAgbGFiZWxzXHJcbiAgICAgICAgICAgIC5hdHRyKFwieFwiLCAwKVxyXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgKGQsIGkpID0+IGkgKiBwbG90LmNlbGxTaXplICsgcGxvdC5jZWxsU2l6ZSAvIDIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZHhcIiwgLTIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJlbmRcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCAoZCwgaSkgPT4gbGFiZWxDbGFzcyArIFwiIFwiICsgbGFiZWxZQ2xhc3MgKyBcIiBcIiArIGxhYmVsWUNsYXNzICsgXCItXCIgKyBpKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcImRvbWluYW50LWJhc2VsaW5lXCIsIFwiaGFuZ2luZ1wiKVxyXG4gICAgICAgICAgICAudGV4dCh2PT5wbG90LmxhYmVsQnlWYXJpYWJsZVt2XSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5yb3RhdGVMYWJlbHNZKSB7XHJcbiAgICAgICAgICAgIGxhYmVsc1xyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwicm90YXRlKC00NSwgXCIgKyAwICsgXCIsIFwiICsgKGkgKiBwbG90LmNlbGxTaXplICsgcGxvdC5jZWxsU2l6ZSAvIDIpICsgXCIpXCIpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInRleHQtYW5jaG9yXCIsIFwiZW5kXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIG1heFdpZHRoID0gc2VsZi5jb21wdXRlWUF4aXNMYWJlbHNXaWR0aCgpO1xyXG4gICAgICAgIGxhYmVscy5lYWNoKGZ1bmN0aW9uIChsYWJlbCkge1xyXG4gICAgICAgICAgICBVdGlscy5wbGFjZVRleHRXaXRoRWxsaXBzaXNBbmRUb29sdGlwKGQzLnNlbGVjdCh0aGlzKSwgbGFiZWwsIG1heFdpZHRoLCBzZWxmLmNvbmZpZy5zaG93VG9vbHRpcCA/IHNlbGYucGxvdC50b29sdGlwIDogZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsYWJlbHMuZXhpdCgpLnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVZQXhpc0xhYmVsc1dpZHRoKCkge1xyXG4gICAgICAgIHZhciBtYXhXaWR0aCA9IHRoaXMucGxvdC5tYXJnaW4ubGVmdDtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnJvdGF0ZUxhYmVsc1kpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG1heFdpZHRoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbWF4V2lkdGggKj0gVXRpbHMuU1FSVF8yO1xyXG4gICAgICAgIHZhciBmb250U2l6ZSA9IDExOyAvL3RvZG8gY2hlY2sgYWN0dWFsIGZvbnQgc2l6ZVxyXG4gICAgICAgIG1heFdpZHRoIC09IGZvbnRTaXplIC8gMjtcclxuXHJcbiAgICAgICAgcmV0dXJuIG1heFdpZHRoO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVYQXhpc0xhYmVsc1dpZHRoKG9mZnNldCkge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcucm90YXRlTGFiZWxzWCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wbG90LmNlbGxTaXplIC0gMjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNpemUgPSB0aGlzLnBsb3QubWFyZ2luLmJvdHRvbTtcclxuICAgICAgICBzaXplICo9IFV0aWxzLlNRUlRfMjtcclxuICAgICAgICB2YXIgZm9udFNpemUgPSAxMTsgLy90b2RvIGNoZWNrIGFjdHVhbCBmb250IHNpemVcclxuICAgICAgICBzaXplIC09IGZvbnRTaXplIC8gMjtcclxuICAgICAgICByZXR1cm4gc2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVDZWxscygpIHtcclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBjZWxsQ2xhc3MgPSBzZWxmLnByZWZpeENsYXNzKFwiY2VsbFwiKTtcclxuICAgICAgICB2YXIgY2VsbFNoYXBlID0gcGxvdC5jb3JyZWxhdGlvbi5zaGFwZS50eXBlO1xyXG5cclxuICAgICAgICB2YXIgY2VsbHMgPSBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwiZy5cIiArIGNlbGxDbGFzcylcclxuICAgICAgICAgICAgLmRhdGEocGxvdC5jb3JyZWxhdGlvbi5tYXRyaXguY2VsbHMpO1xyXG5cclxuICAgICAgICB2YXIgY2VsbEVudGVyRyA9IGNlbGxzLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuY2xhc3NlZChjZWxsQ2xhc3MsIHRydWUpO1xyXG4gICAgICAgIGNlbGxzLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgYz0+IFwidHJhbnNsYXRlKFwiICsgKHBsb3QuY2VsbFNpemUgKiBjLmNvbCArIHBsb3QuY2VsbFNpemUgLyAyKSArIFwiLFwiICsgKHBsb3QuY2VsbFNpemUgKiBjLnJvdyArIHBsb3QuY2VsbFNpemUgLyAyKSArIFwiKVwiKTtcclxuXHJcbiAgICAgICAgY2VsbHMuY2xhc3NlZChzZWxmLmNvbmZpZy5jc3NDbGFzc1ByZWZpeCArIFwic2VsZWN0YWJsZVwiLCAhIXNlbGYuc2NhdHRlclBsb3QpO1xyXG5cclxuICAgICAgICB2YXIgc2VsZWN0b3IgPSBcIio6bm90KC5jZWxsLXNoYXBlLVwiICsgY2VsbFNoYXBlICsgXCIpXCI7XHJcblxyXG4gICAgICAgIHZhciB3cm9uZ1NoYXBlcyA9IGNlbGxzLnNlbGVjdEFsbChzZWxlY3Rvcik7XHJcbiAgICAgICAgd3JvbmdTaGFwZXMucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgIHZhciBzaGFwZXMgPSBjZWxscy5zZWxlY3RPckFwcGVuZChjZWxsU2hhcGUgKyBcIi5jZWxsLXNoYXBlLVwiICsgY2VsbFNoYXBlKTtcclxuXHJcbiAgICAgICAgaWYgKHBsb3QuY29ycmVsYXRpb24uc2hhcGUudHlwZSA9PSAnY2lyY2xlJykge1xyXG5cclxuICAgICAgICAgICAgc2hhcGVzXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInJcIiwgcGxvdC5jb3JyZWxhdGlvbi5zaGFwZS5yYWRpdXMpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImN4XCIsIDApXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImN5XCIsIDApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBsb3QuY29ycmVsYXRpb24uc2hhcGUudHlwZSA9PSAnZWxsaXBzZScpIHtcclxuICAgICAgICAgICAgLy8gY2VsbHMuYXR0cihcInRyYW5zZm9ybVwiLCBjPT4gXCJ0cmFuc2xhdGUoMzAwLDE1MCkgcm90YXRlKFwiK3Bsb3QuY29ycmVsYXRpb24uc2hhcGUucm90YXRlVmFsKGMudmFsdWUpK1wiKVwiKTtcclxuICAgICAgICAgICAgc2hhcGVzXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInJ4XCIsIHBsb3QuY29ycmVsYXRpb24uc2hhcGUucmFkaXVzWClcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwicnlcIiwgcGxvdC5jb3JyZWxhdGlvbi5zaGFwZS5yYWRpdXNZKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJjeFwiLCAwKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJjeVwiLCAwKVxyXG5cclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIGM9PiBcInJvdGF0ZShcIiArIHBsb3QuY29ycmVsYXRpb24uc2hhcGUucm90YXRlVmFsKGMudmFsdWUpICsgXCIpXCIpO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIGlmIChwbG90LmNvcnJlbGF0aW9uLnNoYXBlLnR5cGUgPT0gJ3JlY3QnKSB7XHJcbiAgICAgICAgICAgIHNoYXBlc1xyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBwbG90LmNvcnJlbGF0aW9uLnNoYXBlLnNpemUpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCBwbG90LmNvcnJlbGF0aW9uLnNoYXBlLnNpemUpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInhcIiwgLXBsb3QuY2VsbFNpemUgLyAyKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIC1wbG90LmNlbGxTaXplIC8gMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNoYXBlcy5zdHlsZShcImZpbGxcIiwgYz0+IHBsb3QuY29ycmVsYXRpb24uY29sb3Iuc2NhbGUoYy52YWx1ZSkpO1xyXG5cclxuICAgICAgICB2YXIgbW91c2VvdmVyQ2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgdmFyIG1vdXNlb3V0Q2FsbGJhY2tzID0gW107XHJcblxyXG4gICAgICAgIGlmIChwbG90LnRvb2x0aXApIHtcclxuXHJcbiAgICAgICAgICAgIG1vdXNlb3ZlckNhbGxiYWNrcy5wdXNoKGM9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDIwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIC45KTtcclxuICAgICAgICAgICAgICAgIHZhciBodG1sID0gYy52YWx1ZTtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGh0bWwpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwibGVmdFwiLCAoZDMuZXZlbnQucGFnZVggKyA1KSArIFwicHhcIilcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgKGQzLmV2ZW50LnBhZ2VZIC0gMjgpICsgXCJweFwiKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBtb3VzZW91dENhbGxiYWNrcy5wdXNoKGM9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDUwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIDApO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNlbGYuY29uZmlnLmhpZ2hsaWdodExhYmVscykge1xyXG4gICAgICAgICAgICB2YXIgaGlnaGxpZ2h0Q2xhc3MgPSBzZWxmLmNvbmZpZy5jc3NDbGFzc1ByZWZpeCArIFwiaGlnaGxpZ2h0XCI7XHJcbiAgICAgICAgICAgIHZhciB4TGFiZWxDbGFzcyA9IGM9PnBsb3QubGFiZWxDbGFzcyArIFwiLXgtXCIgKyBjLmNvbDtcclxuICAgICAgICAgICAgdmFyIHlMYWJlbENsYXNzID0gYz0+cGxvdC5sYWJlbENsYXNzICsgXCIteS1cIiArIGMucm93O1xyXG5cclxuXHJcbiAgICAgICAgICAgIG1vdXNlb3ZlckNhbGxiYWNrcy5wdXNoKGM9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgc2VsZi5zdmdHLnNlbGVjdEFsbChcInRleHQuXCIgKyB4TGFiZWxDbGFzcyhjKSkuY2xhc3NlZChoaWdobGlnaHRDbGFzcywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwidGV4dC5cIiArIHlMYWJlbENsYXNzKGMpKS5jbGFzc2VkKGhpZ2hsaWdodENsYXNzLCB0cnVlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG1vdXNlb3V0Q2FsbGJhY2tzLnB1c2goYz0+IHtcclxuICAgICAgICAgICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgeExhYmVsQ2xhc3MoYykpLmNsYXNzZWQoaGlnaGxpZ2h0Q2xhc3MsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgeUxhYmVsQ2xhc3MoYykpLmNsYXNzZWQoaGlnaGxpZ2h0Q2xhc3MsIGZhbHNlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgY2VsbHMub24oXCJtb3VzZW92ZXJcIiwgYyA9PiB7XHJcbiAgICAgICAgICAgIG1vdXNlb3ZlckNhbGxiYWNrcy5mb3JFYWNoKGNhbGxiYWNrPT5jYWxsYmFjayhjKSk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLm9uKFwibW91c2VvdXRcIiwgYyA9PiB7XHJcbiAgICAgICAgICAgICAgICBtb3VzZW91dENhbGxiYWNrcy5mb3JFYWNoKGNhbGxiYWNrPT5jYWxsYmFjayhjKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICBjZWxscy5vbihcImNsaWNrXCIsIGM9PiB7XHJcbiAgICAgICAgICAgIHNlbGYudHJpZ2dlcihcImNlbGwtc2VsZWN0ZWRcIiwgYyk7XHJcbiAgICAgICAgfSk7XHJcblxyXG5cclxuICAgICAgICBjZWxscy5leGl0KCkucmVtb3ZlKCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIHVwZGF0ZUxlZ2VuZCgpIHtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIGxlZ2VuZFggPSB0aGlzLnBsb3Qud2lkdGggKyAxMDtcclxuICAgICAgICB2YXIgbGVnZW5kWSA9IDA7XHJcbiAgICAgICAgdmFyIGJhcldpZHRoID0gMTA7XHJcbiAgICAgICAgdmFyIGJhckhlaWdodCA9IHRoaXMucGxvdC5oZWlnaHQgLSAyO1xyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3QuY29ycmVsYXRpb24uY29sb3Iuc2NhbGU7XHJcblxyXG4gICAgICAgIHBsb3QubGVnZW5kID0gbmV3IExlZ2VuZCh0aGlzLnN2ZywgdGhpcy5zdmdHLCBzY2FsZSwgbGVnZW5kWCwgbGVnZW5kWSkubGluZWFyR3JhZGllbnRCYXIoYmFyV2lkdGgsIGJhckhlaWdodCk7XHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBhdHRhY2hTY2F0dGVyUGxvdChjb250YWluZXJTZWxlY3RvciwgY29uZmlnKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICBjb25maWcgPSBjb25maWcgfHwge307XHJcblxyXG5cclxuICAgICAgICB2YXIgc2NhdHRlclBsb3RDb25maWcgPSB7XHJcbiAgICAgICAgICAgIGhlaWdodDogc2VsZi5wbG90LmhlaWdodCArIHNlbGYuY29uZmlnLm1hcmdpbi50b3AgKyBzZWxmLmNvbmZpZy5tYXJnaW4uYm90dG9tLFxyXG4gICAgICAgICAgICB3aWR0aDogc2VsZi5wbG90LmhlaWdodCArIHNlbGYuY29uZmlnLm1hcmdpbi50b3AgKyBzZWxmLmNvbmZpZy5tYXJnaW4uYm90dG9tLFxyXG4gICAgICAgICAgICBncm91cHM6IHtcclxuICAgICAgICAgICAgICAgIGtleTogc2VsZi5jb25maWcuZ3JvdXBzLmtleSxcclxuICAgICAgICAgICAgICAgIGxhYmVsOiBzZWxmLmNvbmZpZy5ncm91cHMubGFiZWxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZ3VpZGVzOiB0cnVlLFxyXG4gICAgICAgICAgICBzaG93TGVnZW5kOiBmYWxzZVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHNlbGYuc2NhdHRlclBsb3QgPSB0cnVlO1xyXG5cclxuICAgICAgICBzY2F0dGVyUGxvdENvbmZpZyA9IFV0aWxzLmRlZXBFeHRlbmQoc2NhdHRlclBsb3RDb25maWcsIGNvbmZpZyk7XHJcbiAgICAgICAgdGhpcy51cGRhdGUoKTtcclxuXHJcbiAgICAgICAgdGhpcy5vbihcImNlbGwtc2VsZWN0ZWRcIiwgYz0+IHtcclxuXHJcblxyXG4gICAgICAgICAgICBzY2F0dGVyUGxvdENvbmZpZy54ID0ge1xyXG4gICAgICAgICAgICAgICAga2V5OiBjLnJvd1ZhcixcclxuICAgICAgICAgICAgICAgIGxhYmVsOiBzZWxmLnBsb3QubGFiZWxCeVZhcmlhYmxlW2Mucm93VmFyXVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBzY2F0dGVyUGxvdENvbmZpZy55ID0ge1xyXG4gICAgICAgICAgICAgICAga2V5OiBjLmNvbFZhcixcclxuICAgICAgICAgICAgICAgIGxhYmVsOiBzZWxmLnBsb3QubGFiZWxCeVZhcmlhYmxlW2MuY29sVmFyXVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5zY2F0dGVyUGxvdCAmJiBzZWxmLnNjYXR0ZXJQbG90ICE9PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnNjYXR0ZXJQbG90LnNldENvbmZpZyhzY2F0dGVyUGxvdENvbmZpZykuaW5pdCgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5zY2F0dGVyUGxvdCA9IG5ldyBTY2F0dGVyUGxvdChjb250YWluZXJTZWxlY3Rvciwgc2VsZi5kYXRhLCBzY2F0dGVyUGxvdENvbmZpZyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmF0dGFjaChcIlNjYXR0ZXJQbG90XCIsIHNlbGYuc2NhdHRlclBsb3QpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIEQzRXh0ZW5zaW9uc3tcclxuXHJcbiAgICBzdGF0aWMgZXh0ZW5kKCl7XHJcblxyXG4gICAgICAgIGQzLnNlbGVjdGlvbi5lbnRlci5wcm90b3R5cGUuaW5zZXJ0U2VsZWN0b3IgPVxyXG4gICAgICAgICAgICBkMy5zZWxlY3Rpb24ucHJvdG90eXBlLmluc2VydFNlbGVjdG9yID0gZnVuY3Rpb24oc2VsZWN0b3IsIGJlZm9yZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzLmluc2VydFNlbGVjdG9yKHRoaXMsIHNlbGVjdG9yLCBiZWZvcmUpO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuXHJcbiAgICAgICAgZDMuc2VsZWN0aW9uLmVudGVyLnByb3RvdHlwZS5hcHBlbmRTZWxlY3RvciA9XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUuYXBwZW5kU2VsZWN0b3IgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzLmFwcGVuZFNlbGVjdG9yKHRoaXMsIHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgZDMuc2VsZWN0aW9uLmVudGVyLnByb3RvdHlwZS5zZWxlY3RPckFwcGVuZCA9XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUuc2VsZWN0T3JBcHBlbmQgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnNlbGVjdE9yQXBwZW5kKHRoaXMsIHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgZDMuc2VsZWN0aW9uLmVudGVyLnByb3RvdHlwZS5zZWxlY3RPckluc2VydCA9XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUuc2VsZWN0T3JJbnNlcnQgPSBmdW5jdGlvbihzZWxlY3RvciwgYmVmb3JlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRpbHMuc2VsZWN0T3JJbnNlcnQodGhpcywgc2VsZWN0b3IsIGJlZm9yZSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG5cclxuXHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7SGVhdG1hcCwgSGVhdG1hcENvbmZpZ30gZnJvbSBcIi4vaGVhdG1hcFwiO1xyXG5pbXBvcnQge1V0aWxzfSBmcm9tICcuL3V0aWxzJ1xyXG5pbXBvcnQge1N0YXRpc3RpY3NVdGlsc30gZnJvbSAnLi9zdGF0aXN0aWNzLXV0aWxzJ1xyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBIZWF0bWFwVGltZVNlcmllc0NvbmZpZyBleHRlbmRzIEhlYXRtYXBDb25maWcge1xyXG4gICAgeCA9IHtcclxuICAgICAgICBmaWxsTWlzc2luZzogZmFsc2UsIC8vIGZpbGwgbWlzc2luZyB2YWx1ZXMgdXNpbmcgaW50ZXJ2YWwgYW5kIGludGVydmFsU3RlcFxyXG4gICAgICAgIGludGVydmFsOiB1bmRlZmluZWQsIC8vdXNlZCBpbiBmaWxsaW5nIG1pc3NpbmcgdGlja3NcclxuICAgICAgICBpbnRlcnZhbFN0ZXA6IDEsXHJcbiAgICAgICAgZm9ybWF0OiB1bmRlZmluZWQsIC8vaW5wdXQgZGF0YSBkMyB0aW1lIGZvcm1hdFxyXG4gICAgICAgIGRpc3BsYXlGb3JtYXQ6IHVuZGVmaW5lZCwvL2QzIHRpbWUgZm9ybWF0IGZvciBkaXNwbGF5XHJcbiAgICAgICAgaW50ZXJ2YWxUb0Zvcm1hdHM6IFsgLy91c2VkIHRvIGd1ZXNzIGludGVydmFsIGFuZCBmb3JtYXRcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ3llYXInLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogW1wiJVlcIl1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ21vbnRoJyxcclxuICAgICAgICAgICAgICAgIGZvcm1hdHM6IFtcIiVZLSVtXCJdXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdkYXknLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogW1wiJVktJW0tJWRcIl1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ2hvdXInLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogWyclSCcsICclWS0lbS0lZCAlSCddXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdtaW51dGUnLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogWyclSDolTScsICclWS0lbS0lZCAlSDolTSddXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdzZWNvbmQnLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogWyclSDolTTolUycsICclWS0lbS0lZCAlSDolTTolUyddXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBdLFxyXG5cclxuICAgICAgICBzb3J0Q29tcGFyYXRvcjogZnVuY3Rpb24gc29ydENvbXBhcmF0b3IoYSwgYikge1xyXG4gICAgICAgICAgICByZXR1cm4gVXRpbHMuaXNTdHJpbmcoYSkgPyAgYS5sb2NhbGVDb21wYXJlKGIpIDogIGEgLSBiO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZm9ybWF0dGVyOiB1bmRlZmluZWRcclxuICAgIH07XHJcbiAgICB6ID0ge1xyXG4gICAgICAgIGZpbGxNaXNzaW5nOiB0cnVlIC8vIGZpaWxsIG1pc3NpbmcgdmFsdWVzIHdpdGggbmVhcmVzdCBwcmV2aW91cyB2YWx1ZVxyXG4gICAgfTtcclxuXHJcbiAgICBsZWdlbmQgPSB7XHJcbiAgICAgICAgZm9ybWF0dGVyOiBmdW5jdGlvbiAodikge1xyXG4gICAgICAgICAgICB2YXIgc3VmZml4ID0gXCJcIjtcclxuICAgICAgICAgICAgaWYgKHYgLyAxMDAwMDAwID49IDEpIHtcclxuICAgICAgICAgICAgICAgIHN1ZmZpeCA9IFwiIE1cIjtcclxuICAgICAgICAgICAgICAgIHYgPSBOdW1iZXIodiAvIDEwMDAwMDApLnRvRml4ZWQoMyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIG5mID0gSW50bC5OdW1iZXJGb3JtYXQoKTtcclxuICAgICAgICAgICAgcmV0dXJuIG5mLmZvcm1hdCh2KSArIHN1ZmZpeDtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGN1c3RvbSkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG4gICAgICAgIGlmIChjdXN0b20pIHtcclxuICAgICAgICAgICAgVXRpbHMuZGVlcEV4dGVuZCh0aGlzLCBjdXN0b20pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBIZWF0bWFwVGltZVNlcmllcyBleHRlbmRzIEhlYXRtYXAge1xyXG4gICAgY29uc3RydWN0b3IocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgY29uZmlnKSB7XHJcbiAgICAgICAgc3VwZXIocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgbmV3IEhlYXRtYXBUaW1lU2VyaWVzQ29uZmlnKGNvbmZpZykpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldENvbmZpZyhjb25maWcpIHtcclxuICAgICAgICByZXR1cm4gc3VwZXIuc2V0Q29uZmlnKG5ldyBIZWF0bWFwVGltZVNlcmllc0NvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgc2V0dXBWYWx1ZXNCZWZvcmVHcm91cHNTb3J0KCkge1xyXG5cclxuICAgICAgICB0aGlzLnBsb3QueC50aW1lRm9ybWF0ID0gdGhpcy5jb25maWcueC5mb3JtYXQ7XHJcbiAgICAgICAgaWYodGhpcy5jb25maWcueC5kaXNwbGF5Rm9ybWF0ICYmICF0aGlzLnBsb3QueC50aW1lRm9ybWF0KXtcclxuICAgICAgICAgICAgdGhpcy5ndWVzc1RpbWVGb3JtYXQoKTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBzdXBlci5zZXR1cFZhbHVlc0JlZm9yZUdyb3Vwc1NvcnQoKTtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnguZmlsbE1pc3NpbmcpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICB0aGlzLmluaXRUaW1lRm9ybWF0QW5kSW50ZXJ2YWwoKTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnguaW50ZXJ2YWxTdGVwID0gdGhpcy5jb25maWcueC5pbnRlcnZhbFN0ZXAgfHwgMTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LngudGltZVBhcnNlciA9IHRoaXMuZ2V0VGltZVBhcnNlcigpO1xyXG5cclxuXHJcblxyXG4gICAgICAgIHRoaXMucGxvdC54LnVuaXF1ZVZhbHVlcy5zb3J0KHRoaXMuY29uZmlnLnguc29ydENvbXBhcmF0b3IpO1xyXG5cclxuICAgICAgICB2YXIgcHJldiA9IG51bGw7XHJcblxyXG4gICAgICAgIHRoaXMucGxvdC54LnVuaXF1ZVZhbHVlcy5mb3JFYWNoKCh4LCBpKT0+IHtcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLnBhcnNlVGltZSh4KTtcclxuICAgICAgICAgICAgaWYgKHByZXYgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHByZXYgPSBjdXJyZW50O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIgbmV4dCA9IHNlbGYubmV4dFRpbWVUaWNrVmFsdWUocHJldik7XHJcbiAgICAgICAgICAgIHZhciBtaXNzaW5nID0gW107XHJcbiAgICAgICAgICAgIHZhciBpdGVyYXRpb24gPSAwO1xyXG4gICAgICAgICAgICB3aGlsZSAoc2VsZi5jb21wYXJlVGltZVZhbHVlcyhuZXh0LCBjdXJyZW50KTw9MCkge1xyXG4gICAgICAgICAgICAgICAgaXRlcmF0aW9uKys7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlcmF0aW9uID4gMTAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgZCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIHRpbWVTdHJpbmcgPSBzZWxmLmZvcm1hdFRpbWUobmV4dCk7XHJcbiAgICAgICAgICAgICAgICBkW3RoaXMuY29uZmlnLngua2V5XSA9IHRpbWVTdHJpbmc7XHJcblxyXG4gICAgICAgICAgICAgICAgc2VsZi51cGRhdGVHcm91cHMoZCwgdGltZVN0cmluZywgc2VsZi5wbG90LnguZ3JvdXBzLCBzZWxmLmNvbmZpZy54Lmdyb3Vwcyk7XHJcbiAgICAgICAgICAgICAgICBtaXNzaW5nLnB1c2gobmV4dCk7XHJcbiAgICAgICAgICAgICAgICBuZXh0ID0gc2VsZi5uZXh0VGltZVRpY2tWYWx1ZShuZXh0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwcmV2ID0gY3VycmVudDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcGFyc2VUaW1lKHgpIHtcclxuICAgICAgICB2YXIgcGFyc2VyID0gdGhpcy5nZXRUaW1lUGFyc2VyKCk7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlci5wYXJzZSh4KTtcclxuICAgIH1cclxuXHJcbiAgICBmb3JtYXRUaW1lKGRhdGUpe1xyXG4gICAgICAgIHZhciBwYXJzZXIgPSB0aGlzLmdldFRpbWVQYXJzZXIoKTtcclxuICAgICAgICByZXR1cm4gcGFyc2VyKGRhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGZvcm1hdFZhbHVlWCh2YWx1ZSkgeyAvL3VzZWQgb25seSBmb3IgZGlzcGxheVxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy54LmZvcm1hdHRlcikgcmV0dXJuIHRoaXMuY29uZmlnLnguZm9ybWF0dGVyLmNhbGwodGhpcy5jb25maWcsIHZhbHVlKTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5jb25maWcueC5kaXNwbGF5Rm9ybWF0KXtcclxuICAgICAgICAgICAgdmFyIGRhdGUgPSB0aGlzLnBhcnNlVGltZSh2YWx1ZSk7XHJcbiAgICAgICAgICAgIHJldHVybiBkMy50aW1lLmZvcm1hdCh0aGlzLmNvbmZpZy54LmRpc3BsYXlGb3JtYXQpKGRhdGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYoIXRoaXMucGxvdC54LnRpbWVGb3JtYXQpIHJldHVybiB2YWx1ZTtcclxuXHJcbiAgICAgICAgaWYoVXRpbHMuaXNEYXRlKHZhbHVlKSl7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdFRpbWUodmFsdWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXBhcmVUaW1lVmFsdWVzKGEsIGIpe1xyXG4gICAgICAgIHJldHVybiBhLWI7XHJcbiAgICB9XHJcblxyXG4gICAgdGltZVZhbHVlc0VxdWFsKGEsIGIpIHtcclxuICAgICAgICB2YXIgcGFyc2VyID0gdGhpcy5wbG90LngudGltZVBhcnNlcjtcclxuICAgICAgICByZXR1cm4gcGFyc2VyKGEpID09PSBwYXJzZXIoYik7XHJcbiAgICB9XHJcblxyXG4gICAgbmV4dFRpbWVUaWNrVmFsdWUodCkge1xyXG4gICAgICAgIHZhciBpbnRlcnZhbCA9IHRoaXMucGxvdC54LmludGVydmFsO1xyXG4gICAgICAgIHJldHVybiBkMy50aW1lW2ludGVydmFsXS5vZmZzZXQodCwgdGhpcy5wbG90LnguaW50ZXJ2YWxTdGVwKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpIHtcclxuICAgICAgICBzdXBlci5pbml0UGxvdCgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5jb25maWcuei5maWxsTWlzc2luZykge1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWF0cml4LmZvckVhY2goKHJvdywgcm93SW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciBwcmV2Um93VmFsdWUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICByb3cuZm9yRWFjaCgoY2VsbCwgY29sSW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbC52YWx1ZSA9PT0gdW5kZWZpbmVkICYmIHByZXZSb3dWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBwcmV2Um93VmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwubWlzc2luZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHByZXZSb3dWYWx1ZSA9IGNlbGwudmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlKG5ld0RhdGEpIHtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcblxyXG4gICAgfTtcclxuXHJcblxyXG4gICAgaW5pdFRpbWVGb3JtYXRBbmRJbnRlcnZhbCgpIHtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnguaW50ZXJ2YWwgPSB0aGlzLmNvbmZpZy54LmludGVydmFsO1xyXG5cclxuICAgICAgICBpZighdGhpcy5wbG90LngudGltZUZvcm1hdCl7XHJcbiAgICAgICAgICAgIHRoaXMuZ3Vlc3NUaW1lRm9ybWF0KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZighdGhpcy5wbG90LnguaW50ZXJ2YWwgJiYgdGhpcy5wbG90LngudGltZUZvcm1hdCl7XHJcbiAgICAgICAgICAgIHRoaXMuZ3Vlc3NJbnRlcnZhbCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBndWVzc1RpbWVGb3JtYXQoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIGZvcihsZXQgaT0wOyBpIDwgc2VsZi5jb25maWcueC5pbnRlcnZhbFRvRm9ybWF0cy5sZW5ndGg7IGkrKyl7XHJcbiAgICAgICAgICAgIGxldCBpbnRlcnZhbEZvcm1hdCA9IHNlbGYuY29uZmlnLnguaW50ZXJ2YWxUb0Zvcm1hdHNbaV07XHJcbiAgICAgICAgICAgIHZhciBmb3JtYXQgPSBudWxsO1xyXG4gICAgICAgICAgICB2YXIgZm9ybWF0TWF0Y2ggPSBpbnRlcnZhbEZvcm1hdC5mb3JtYXRzLnNvbWUoZj0+e1xyXG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gZjtcclxuICAgICAgICAgICAgICAgIHZhciBwYXJzZXIgPSBkMy50aW1lLmZvcm1hdChmKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnBsb3QueC51bmlxdWVWYWx1ZXMuZXZlcnkoeD0+e1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZXIucGFyc2UoeCkgIT09IG51bGxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgaWYoZm9ybWF0TWF0Y2gpe1xyXG4gICAgICAgICAgICAgICAgc2VsZi5wbG90LngudGltZUZvcm1hdCA9IGZvcm1hdDtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdHdWVzc2VkIHRpbWVGb3JtYXQnLCBmb3JtYXQpO1xyXG4gICAgICAgICAgICAgICAgaWYoIXNlbGYucGxvdC54LmludGVydmFsKXtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnBsb3QueC5pbnRlcnZhbCA9IGludGVydmFsRm9ybWF0Lm5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0d1ZXNzZWQgaW50ZXJ2YWwnLCBzZWxmLnBsb3QueC5pbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ3Vlc3NJbnRlcnZhbCgpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgZm9yKGxldCBpPTA7IGkgPCBzZWxmLmNvbmZpZy54LmludGVydmFsVG9Gb3JtYXRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBpbnRlcnZhbEZvcm1hdCA9IHNlbGYuY29uZmlnLnguaW50ZXJ2YWxUb0Zvcm1hdHNbaV07XHJcblxyXG4gICAgICAgICAgICBpZihpbnRlcnZhbEZvcm1hdC5mb3JtYXRzLmluZGV4T2Yoc2VsZi5wbG90LngudGltZUZvcm1hdCkgPj0gMCl7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnBsb3QueC5pbnRlcnZhbCA9IGludGVydmFsRm9ybWF0Lm5hbWU7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnR3Vlc3NlZCBpbnRlcnZhbCcsIHNlbGYucGxvdC54LmludGVydmFsKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuXHJcbiAgICBnZXRUaW1lUGFyc2VyKCkge1xyXG4gICAgICAgIGlmKCF0aGlzLnBsb3QueC50aW1lUGFyc2VyKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LngudGltZVBhcnNlciA9IGQzLnRpbWUuZm9ybWF0KHRoaXMucGxvdC54LnRpbWVGb3JtYXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5wbG90LngudGltZVBhcnNlcjtcclxuICAgIH1cclxufVxyXG5cclxuIiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcbmltcG9ydCB7TGVnZW5kfSBmcm9tICcuL2xlZ2VuZCdcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgSGVhdG1hcENvbmZpZyBleHRlbmRzIENoYXJ0Q29uZmlnIHtcclxuXHJcbiAgICBzdmdDbGFzcyA9ICdvZGMtaGVhdG1hcCc7XHJcbiAgICBzaG93VG9vbHRpcCA9IHRydWU7IC8vc2hvdyB0b29sdGlwIG9uIGRvdCBob3ZlclxyXG4gICAgdG9vbHRpcCA9IHtcclxuICAgICAgICBub0RhdGFUZXh0OiBcIk4vQVwiXHJcbiAgICB9O1xyXG4gICAgc2hvd0xlZ2VuZCA9IHRydWU7XHJcbiAgICBsZWdlbmQgPSB7XHJcbiAgICAgICAgd2lkdGg6IDMwLFxyXG4gICAgICAgIHJvdGF0ZUxhYmVsczogZmFsc2UsXHJcbiAgICAgICAgZGVjaW1hbFBsYWNlczogdW5kZWZpbmVkLFxyXG4gICAgICAgIGZvcm1hdHRlcjogdiA9PiB0aGlzLmxlZ2VuZC5kZWNpbWFsUGxhY2VzID09PSB1bmRlZmluZWQgPyB2IDogTnVtYmVyKHYpLnRvRml4ZWQodGhpcy5sZWdlbmQuZGVjaW1hbFBsYWNlcylcclxuICAgIH1cclxuICAgIGhpZ2hsaWdodExhYmVscyA9IHRydWU7XHJcbiAgICB4ID0gey8vIFggYXhpcyBjb25maWdcclxuICAgICAgICB0aXRsZTogJycsIC8vIGF4aXMgdGl0bGVcclxuICAgICAgICBrZXk6IDAsXHJcbiAgICAgICAgdmFsdWU6IChkKSA9PiBkW3RoaXMueC5rZXldLCAvLyB4IHZhbHVlIGFjY2Vzc29yXHJcbiAgICAgICAgcm90YXRlTGFiZWxzOiB0cnVlLFxyXG4gICAgICAgIHNvcnRMYWJlbHM6IGZhbHNlLFxyXG4gICAgICAgIHNvcnRDb21wYXJhdG9yOiAoYSwgYik9PiBVdGlscy5pc051bWJlcihhKSA/IGEgLSBiIDogYS5sb2NhbGVDb21wYXJlKGIpLFxyXG4gICAgICAgIGdyb3Vwczoge1xyXG4gICAgICAgICAgICBrZXlzOiBbXSxcclxuICAgICAgICAgICAgbGFiZWxzOiBbXSxcclxuICAgICAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IGRba2V5XSxcclxuICAgICAgICAgICAgb3ZlcmxhcDoge1xyXG4gICAgICAgICAgICAgICAgdG9wOiAyMCxcclxuICAgICAgICAgICAgICAgIGJvdHRvbTogMjBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZm9ybWF0dGVyOiB1bmRlZmluZWQgLy8gdmFsdWUgZm9ybWF0dGVyIGZ1bmN0aW9uXHJcblxyXG4gICAgfTtcclxuICAgIHkgPSB7Ly8gWSBheGlzIGNvbmZpZ1xyXG4gICAgICAgIHRpdGxlOiAnJywgLy8gYXhpcyB0aXRsZSxcclxuICAgICAgICByb3RhdGVMYWJlbHM6IHRydWUsXHJcbiAgICAgICAga2V5OiAxLFxyXG4gICAgICAgIHZhbHVlOiAoZCkgPT4gZFt0aGlzLnkua2V5XSwgLy8geSB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgICAgIHNvcnRMYWJlbHM6IGZhbHNlLFxyXG4gICAgICAgIHNvcnRDb21wYXJhdG9yOiAoYSwgYik9PiBVdGlscy5pc051bWJlcihiKSA/IGIgLSBhIDogYi5sb2NhbGVDb21wYXJlKGEpLFxyXG4gICAgICAgIGdyb3Vwczoge1xyXG4gICAgICAgICAgICBrZXlzOiBbXSxcclxuICAgICAgICAgICAgbGFiZWxzOiBbXSxcclxuICAgICAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IGRba2V5XSxcclxuICAgICAgICAgICAgb3ZlcmxhcDoge1xyXG4gICAgICAgICAgICAgICAgbGVmdDogMjAsXHJcbiAgICAgICAgICAgICAgICByaWdodDogMjBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZm9ybWF0dGVyOiB1bmRlZmluZWQvLyB2YWx1ZSBmb3JtYXR0ZXIgZnVuY3Rpb25cclxuICAgIH07XHJcbiAgICB6ID0ge1xyXG4gICAgICAgIGtleTogMixcclxuICAgICAgICB2YWx1ZTogKGQpID0+IGRbdGhpcy56LmtleV0sXHJcbiAgICAgICAgbm90QXZhaWxhYmxlVmFsdWU6ICh2KSA9PiB2ID09PSBudWxsIHx8IHYgPT09IHVuZGVmaW5lZCxcclxuXHJcbiAgICAgICAgZGVjaW1hbFBsYWNlczogdW5kZWZpbmVkLFxyXG4gICAgICAgIGZvcm1hdHRlcjogdiA9PiB0aGlzLnouZGVjaW1hbFBsYWNlcyA9PT0gdW5kZWZpbmVkID8gdiA6IE51bWJlcih2KS50b0ZpeGVkKHRoaXMuei5kZWNpbWFsUGxhY2VzKS8vIHZhbHVlIGZvcm1hdHRlciBmdW5jdGlvblxyXG5cclxuICAgIH07XHJcbiAgICBjb2xvciA9IHtcclxuICAgICAgICBub0RhdGFDb2xvcjogXCJ3aGl0ZVwiLFxyXG4gICAgICAgIHNjYWxlOiBcImxpbmVhclwiLFxyXG4gICAgICAgIHJldmVyc2VTY2FsZTogZmFsc2UsXHJcbiAgICAgICAgcmFuZ2U6IFtcImRhcmtibHVlXCIsIFwibGlnaHRza3libHVlXCIsIFwib3JhbmdlXCIsIFwiY3JpbXNvblwiLCBcImRhcmtyZWRcIl1cclxuICAgIH07XHJcbiAgICBjZWxsID0ge1xyXG4gICAgICAgIHdpZHRoOiB1bmRlZmluZWQsXHJcbiAgICAgICAgaGVpZ2h0OiB1bmRlZmluZWQsXHJcbiAgICAgICAgc2l6ZU1pbjogMTUsXHJcbiAgICAgICAgc2l6ZU1heDogMjUwLFxyXG4gICAgICAgIHBhZGRpbmc6IDBcclxuICAgIH07XHJcbiAgICBtYXJnaW4gPSB7XHJcbiAgICAgICAgbGVmdDogNjAsXHJcbiAgICAgICAgcmlnaHQ6IDUwLFxyXG4gICAgICAgIHRvcDogMzAsXHJcbiAgICAgICAgYm90dG9tOiA4MFxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIGlmIChjdXN0b20pIHtcclxuICAgICAgICAgICAgVXRpbHMuZGVlcEV4dGVuZCh0aGlzLCBjdXN0b20pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLy9UT0RPIHJlZmFjdG9yXHJcbmV4cG9ydCBjbGFzcyBIZWF0bWFwIGV4dGVuZHMgQ2hhcnQge1xyXG5cclxuICAgIHN0YXRpYyBtYXhHcm91cEdhcFNpemUgPSAyNDtcclxuICAgIHN0YXRpYyBncm91cFRpdGxlUmVjdEhlaWdodCA9IDY7XHJcblxyXG4gICAgY29uc3RydWN0b3IocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgY29uZmlnKSB7XHJcbiAgICAgICAgc3VwZXIocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgbmV3IEhlYXRtYXBDb25maWcoY29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Q29uZmlnKGNvbmZpZykge1xyXG4gICAgICAgIHJldHVybiBzdXBlci5zZXRDb25maWcobmV3IEhlYXRtYXBDb25maWcoY29uZmlnKSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXRQbG90KCkge1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBtYXJnaW4gPSB0aGlzLmNvbmZpZy5tYXJnaW47XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnggPSB7fTtcclxuICAgICAgICB0aGlzLnBsb3QueSA9IHt9O1xyXG4gICAgICAgIHRoaXMucGxvdC56ID0ge1xyXG4gICAgICAgICAgICBtYXRyaXhlczogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjZWxsczogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjb2xvcjoge30sXHJcbiAgICAgICAgICAgIHNoYXBlOiB7fVxyXG4gICAgICAgIH07XHJcblxyXG5cclxuICAgICAgICB0aGlzLnNldHVwVmFsdWVzKCk7XHJcbiAgICAgICAgdGhpcy5idWlsZENlbGxzKCk7XHJcblxyXG4gICAgICAgIHZhciB0aXRsZVJlY3RXaWR0aCA9IDY7XHJcbiAgICAgICAgdGhpcy5wbG90Lngub3ZlcmxhcCA9IHtcclxuICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICBib3R0b206IDBcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmICh0aGlzLnBsb3QuZ3JvdXBCeVgpIHtcclxuICAgICAgICAgICAgbGV0IGRlcHRoID0gc2VsZi5jb25maWcueC5ncm91cHMua2V5cy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxldCBhbGxUaXRsZXNXaWR0aCA9IGRlcHRoICogKHRpdGxlUmVjdFdpZHRoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucGxvdC54Lm92ZXJsYXAuYm90dG9tID0gc2VsZi5jb25maWcueC5ncm91cHMub3ZlcmxhcC5ib3R0b207XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC54Lm92ZXJsYXAudG9wID0gc2VsZi5jb25maWcueC5ncm91cHMub3ZlcmxhcC50b3AgKyBhbGxUaXRsZXNXaWR0aDtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lm1hcmdpbi50b3AgPSBjb25mLm1hcmdpbi5yaWdodCArIGNvbmYueC5ncm91cHMub3ZlcmxhcC50b3A7XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5tYXJnaW4uYm90dG9tID0gY29uZi5tYXJnaW4uYm90dG9tICsgY29uZi54Lmdyb3Vwcy5vdmVybGFwLmJvdHRvbTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB0aGlzLnBsb3QueS5vdmVybGFwID0ge1xyXG4gICAgICAgICAgICBsZWZ0OiAwLFxyXG4gICAgICAgICAgICByaWdodDogMFxyXG4gICAgICAgIH07XHJcblxyXG5cclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlZKSB7XHJcbiAgICAgICAgICAgIGxldCBkZXB0aCA9IHNlbGYuY29uZmlnLnkuZ3JvdXBzLmtleXMubGVuZ3RoO1xyXG4gICAgICAgICAgICBsZXQgYWxsVGl0bGVzV2lkdGggPSBkZXB0aCAqICh0aXRsZVJlY3RXaWR0aCk7XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC55Lm92ZXJsYXAucmlnaHQgPSBzZWxmLmNvbmZpZy55Lmdyb3Vwcy5vdmVybGFwLmxlZnQgKyBhbGxUaXRsZXNXaWR0aDtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lnkub3ZlcmxhcC5sZWZ0ID0gc2VsZi5jb25maWcueS5ncm91cHMub3ZlcmxhcC5sZWZ0O1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWFyZ2luLmxlZnQgPSBjb25mLm1hcmdpbi5sZWZ0ICsgdGhpcy5wbG90Lnkub3ZlcmxhcC5sZWZ0O1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWFyZ2luLnJpZ2h0ID0gY29uZi5tYXJnaW4ucmlnaHQgKyB0aGlzLnBsb3QueS5vdmVybGFwLnJpZ2h0O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnBsb3Quc2hvd0xlZ2VuZCA9IGNvbmYuc2hvd0xlZ2VuZDtcclxuICAgICAgICBpZiAodGhpcy5wbG90LnNob3dMZWdlbmQpIHtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lm1hcmdpbi5yaWdodCArPSBjb25mLmxlZ2VuZC53aWR0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5jb21wdXRlUGxvdFNpemUoKTtcclxuICAgICAgICB0aGlzLnNldHVwWlNjYWxlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHNldHVwVmFsdWVzKCkge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgY29uZmlnID0gc2VsZi5jb25maWc7XHJcbiAgICAgICAgdmFyIHggPSBzZWxmLnBsb3QueDtcclxuICAgICAgICB2YXIgeSA9IHNlbGYucGxvdC55O1xyXG4gICAgICAgIHZhciB6ID0gc2VsZi5wbG90Lno7XHJcblxyXG5cclxuICAgICAgICB4LnZhbHVlID0gZCA9PiBjb25maWcueC52YWx1ZS5jYWxsKGNvbmZpZywgZCk7XHJcbiAgICAgICAgeS52YWx1ZSA9IGQgPT4gY29uZmlnLnkudmFsdWUuY2FsbChjb25maWcsIGQpO1xyXG4gICAgICAgIHoudmFsdWUgPSBkID0+IGNvbmZpZy56LnZhbHVlLmNhbGwoY29uZmlnLCBkKTtcclxuXHJcbiAgICAgICAgeC51bmlxdWVWYWx1ZXMgPSBbXTtcclxuICAgICAgICB5LnVuaXF1ZVZhbHVlcyA9IFtdO1xyXG5cclxuXHJcbiAgICAgICAgc2VsZi5wbG90Lmdyb3VwQnlZID0gISFjb25maWcueS5ncm91cHMua2V5cy5sZW5ndGg7XHJcbiAgICAgICAgc2VsZi5wbG90Lmdyb3VwQnlYID0gISFjb25maWcueC5ncm91cHMua2V5cy5sZW5ndGg7XHJcblxyXG4gICAgICAgIHkuZ3JvdXBzID0ge1xyXG4gICAgICAgICAgICBrZXk6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgbGFiZWw6ICcnLFxyXG4gICAgICAgICAgICB2YWx1ZXM6IFtdLFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogbnVsbCxcclxuICAgICAgICAgICAgbGV2ZWw6IDAsXHJcbiAgICAgICAgICAgIGluZGV4OiAwLFxyXG4gICAgICAgICAgICBsYXN0SW5kZXg6IDBcclxuICAgICAgICB9O1xyXG4gICAgICAgIHguZ3JvdXBzID0ge1xyXG4gICAgICAgICAgICBrZXk6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgbGFiZWw6ICcnLFxyXG4gICAgICAgICAgICB2YWx1ZXM6IFtdLFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogbnVsbCxcclxuICAgICAgICAgICAgbGV2ZWw6IDAsXHJcbiAgICAgICAgICAgIGluZGV4OiAwLFxyXG4gICAgICAgICAgICBsYXN0SW5kZXg6IDBcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB2YXIgdmFsdWVNYXAgPSB7fTtcclxuICAgICAgICB2YXIgbWluWiA9IHVuZGVmaW5lZDtcclxuICAgICAgICB2YXIgbWF4WiA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLmRhdGEuZm9yRWFjaChkPT4ge1xyXG5cclxuICAgICAgICAgICAgdmFyIHhWYWwgPSB4LnZhbHVlKGQpO1xyXG4gICAgICAgICAgICB2YXIgeVZhbCA9IHkudmFsdWUoZCk7XHJcbiAgICAgICAgICAgIHZhciB6VmFsUmF3ID0gei52YWx1ZShkKTtcclxuICAgICAgICAgICAgdmFyIHpWYWwgPSBjb25maWcuei5ub3RBdmFpbGFibGVWYWx1ZSh6VmFsUmF3KSA/IHVuZGVmaW5lZCA6IHBhcnNlRmxvYXQoelZhbFJhdyk7XHJcblxyXG5cclxuICAgICAgICAgICAgaWYgKHgudW5pcXVlVmFsdWVzLmluZGV4T2YoeFZhbCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB4LnVuaXF1ZVZhbHVlcy5wdXNoKHhWYWwpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoeS51bmlxdWVWYWx1ZXMuaW5kZXhPZih5VmFsKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHkudW5pcXVlVmFsdWVzLnB1c2goeVZhbCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciBncm91cFkgPSB5Lmdyb3VwcztcclxuICAgICAgICAgICAgaWYgKHNlbGYucGxvdC5ncm91cEJ5WSkge1xyXG4gICAgICAgICAgICAgICAgZ3JvdXBZID0gdGhpcy51cGRhdGVHcm91cHMoZCwgeVZhbCwgeS5ncm91cHMsIGNvbmZpZy55Lmdyb3Vwcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGdyb3VwWCA9IHguZ3JvdXBzO1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5wbG90Lmdyb3VwQnlYKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgZ3JvdXBYID0gdGhpcy51cGRhdGVHcm91cHMoZCwgeFZhbCwgeC5ncm91cHMsIGNvbmZpZy54Lmdyb3Vwcyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghdmFsdWVNYXBbZ3JvdXBZLmluZGV4XSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWVNYXBbZ3JvdXBZLmluZGV4XSA9IHt9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXZhbHVlTWFwW2dyb3VwWS5pbmRleF1bZ3JvdXBYLmluZGV4XSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWVNYXBbZ3JvdXBZLmluZGV4XVtncm91cFguaW5kZXhdID0ge307XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCF2YWx1ZU1hcFtncm91cFkuaW5kZXhdW2dyb3VwWC5pbmRleF1beVZhbF0pIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlTWFwW2dyb3VwWS5pbmRleF1bZ3JvdXBYLmluZGV4XVt5VmFsXSA9IHt9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhbHVlTWFwW2dyb3VwWS5pbmRleF1bZ3JvdXBYLmluZGV4XVt5VmFsXVt4VmFsXSA9IHpWYWw7XHJcblxyXG5cclxuICAgICAgICAgICAgaWYgKG1pblogPT09IHVuZGVmaW5lZCB8fCB6VmFsIDwgbWluWikge1xyXG4gICAgICAgICAgICAgICAgbWluWiA9IHpWYWw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG1heFogPT09IHVuZGVmaW5lZCB8fCB6VmFsID4gbWF4Wikge1xyXG4gICAgICAgICAgICAgICAgbWF4WiA9IHpWYWw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBzZWxmLnBsb3QudmFsdWVNYXAgPSB2YWx1ZU1hcDtcclxuXHJcblxyXG4gICAgICAgIGlmICghc2VsZi5wbG90Lmdyb3VwQnlYKSB7XHJcbiAgICAgICAgICAgIHguZ3JvdXBzLnZhbHVlcyA9IHgudW5pcXVlVmFsdWVzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFzZWxmLnBsb3QuZ3JvdXBCeVkpIHtcclxuICAgICAgICAgICAgeS5ncm91cHMudmFsdWVzID0geS51bmlxdWVWYWx1ZXM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnNldHVwVmFsdWVzQmVmb3JlR3JvdXBzU29ydCgpO1xyXG5cclxuICAgICAgICB4LmdhcHMgPSBbXTtcclxuICAgICAgICB4LnRvdGFsVmFsdWVzQ291bnQgPSAwO1xyXG4gICAgICAgIHguYWxsVmFsdWVzTGlzdCA9IFtdO1xyXG4gICAgICAgIHRoaXMuc29ydEdyb3Vwcyh4LCB4Lmdyb3VwcywgY29uZmlnLngpO1xyXG5cclxuICAgICAgICB5LmdhcHMgPSBbXTtcclxuICAgICAgICB5LnRvdGFsVmFsdWVzQ291bnQgPSAwO1xyXG4gICAgICAgIHkuYWxsVmFsdWVzTGlzdCA9IFtdO1xyXG4gICAgICAgIHRoaXMuc29ydEdyb3Vwcyh5LCB5Lmdyb3VwcywgY29uZmlnLnkpO1xyXG5cclxuICAgICAgICB6Lm1pbiA9IG1pblo7XHJcbiAgICAgICAgei5tYXggPSBtYXhaO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBzZXR1cFZhbHVlc0JlZm9yZUdyb3Vwc1NvcnQoKSB7XHJcbiAgICB9XHJcblxyXG4gICAgYnVpbGRDZWxscygpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHggPSBzZWxmLnBsb3QueDtcclxuICAgICAgICB2YXIgeSA9IHNlbGYucGxvdC55O1xyXG4gICAgICAgIHZhciB6ID0gc2VsZi5wbG90Lno7XHJcbiAgICAgICAgdmFyIHZhbHVlTWFwID0gc2VsZi5wbG90LnZhbHVlTWFwO1xyXG5cclxuICAgICAgICB2YXIgbWF0cml4Q2VsbHMgPSBzZWxmLnBsb3QuY2VsbHMgPSBbXTtcclxuICAgICAgICB2YXIgbWF0cml4ID0gc2VsZi5wbG90Lm1hdHJpeCA9IFtdO1xyXG5cclxuICAgICAgICB5LmFsbFZhbHVlc0xpc3QuZm9yRWFjaCgodjEsIGkpPT4ge1xyXG4gICAgICAgICAgICB2YXIgcm93ID0gW107XHJcbiAgICAgICAgICAgIG1hdHJpeC5wdXNoKHJvdyk7XHJcblxyXG4gICAgICAgICAgICB4LmFsbFZhbHVlc0xpc3QuZm9yRWFjaCgodjIsIGopID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciB6VmFsID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICB6VmFsID0gdmFsdWVNYXBbdjEuZ3JvdXAuaW5kZXhdW3YyLmdyb3VwLmluZGV4XVt2MS52YWxdW3YyLnZhbF1cclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IHtcclxuICAgICAgICAgICAgICAgICAgICByb3dWYXI6IHYxLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbFZhcjogdjIsXHJcbiAgICAgICAgICAgICAgICAgICAgcm93OiBpLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbDogaixcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogelZhbFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHJvdy5wdXNoKGNlbGwpO1xyXG5cclxuICAgICAgICAgICAgICAgIG1hdHJpeENlbGxzLnB1c2goY2VsbCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVHcm91cHMoZCwgYXhpc1ZhbCwgcm9vdEdyb3VwLCBheGlzR3JvdXBzQ29uZmlnKSB7XHJcblxyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmNvbmZpZztcclxuICAgICAgICB2YXIgY3VycmVudEdyb3VwID0gcm9vdEdyb3VwO1xyXG4gICAgICAgIGF4aXNHcm91cHNDb25maWcua2V5cy5mb3JFYWNoKChncm91cEtleSwgZ3JvdXBLZXlJbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBjdXJyZW50R3JvdXAua2V5ID0gZ3JvdXBLZXk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWN1cnJlbnRHcm91cC5jaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudEdyb3VwLmNoaWxkcmVuID0ge307XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciBncm91cGluZ1ZhbHVlID0gYXhpc0dyb3Vwc0NvbmZpZy52YWx1ZS5jYWxsKGNvbmZpZywgZCwgZ3JvdXBLZXkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFjdXJyZW50R3JvdXAuY2hpbGRyZW4uaGFzT3duUHJvcGVydHkoZ3JvdXBpbmdWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIHJvb3RHcm91cC5sYXN0SW5kZXgrKztcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRHcm91cC5jaGlsZHJlbltncm91cGluZ1ZhbHVlXSA9IHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwaW5nVmFsdWU6IGdyb3VwaW5nVmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgbGV2ZWw6IGN1cnJlbnRHcm91cC5sZXZlbCArIDEsXHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHJvb3RHcm91cC5sYXN0SW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAga2V5OiBncm91cEtleVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjdXJyZW50R3JvdXAgPSBjdXJyZW50R3JvdXAuY2hpbGRyZW5bZ3JvdXBpbmdWYWx1ZV07XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGlmIChjdXJyZW50R3JvdXAudmFsdWVzLmluZGV4T2YoYXhpc1ZhbCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIGN1cnJlbnRHcm91cC52YWx1ZXMucHVzaChheGlzVmFsKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBjdXJyZW50R3JvdXA7XHJcbiAgICB9XHJcblxyXG4gICAgc29ydEdyb3VwcyhheGlzLCBncm91cCwgYXhpc0NvbmZpZywgZ2Fwcykge1xyXG4gICAgICAgIGlmIChheGlzQ29uZmlnLmdyb3Vwcy5sYWJlbHMgJiYgYXhpc0NvbmZpZy5ncm91cHMubGFiZWxzLmxlbmd0aCA+IGdyb3VwLmxldmVsKSB7XHJcbiAgICAgICAgICAgIGdyb3VwLmxhYmVsID0gYXhpc0NvbmZpZy5ncm91cHMubGFiZWxzW2dyb3VwLmxldmVsXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBncm91cC5sYWJlbCA9IGdyb3VwLmtleTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghZ2Fwcykge1xyXG4gICAgICAgICAgICBnYXBzID0gWzBdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZ2Fwcy5sZW5ndGggPD0gZ3JvdXAubGV2ZWwpIHtcclxuICAgICAgICAgICAgZ2Fwcy5wdXNoKDApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ3JvdXAuYWxsVmFsdWVzQ291bnQgPSBncm91cC5hbGxWYWx1ZXNDb3VudCB8fCAwO1xyXG4gICAgICAgIGdyb3VwLmFsbFZhbHVlc0JlZm9yZUNvdW50ID0gZ3JvdXAuYWxsVmFsdWVzQmVmb3JlQ291bnQgfHwgMDtcclxuXHJcbiAgICAgICAgZ3JvdXAuZ2FwcyA9IGdhcHMuc2xpY2UoKTtcclxuICAgICAgICBncm91cC5nYXBzQmVmb3JlID0gZ2Fwcy5zbGljZSgpO1xyXG5cclxuXHJcbiAgICAgICAgZ3JvdXAuZ2Fwc1NpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBzU2l6ZShncm91cC5nYXBzKTtcclxuICAgICAgICBncm91cC5nYXBzQmVmb3JlU2l6ZSA9IGdyb3VwLmdhcHNTaXplO1xyXG4gICAgICAgIGlmIChncm91cC52YWx1ZXMpIHtcclxuICAgICAgICAgICAgaWYgKGF4aXNDb25maWcuc29ydExhYmVscykge1xyXG4gICAgICAgICAgICAgICAgZ3JvdXAudmFsdWVzLnNvcnQoYXhpc0NvbmZpZy5zb3J0Q29tcGFyYXRvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZ3JvdXAudmFsdWVzLmZvckVhY2godj0+YXhpcy5hbGxWYWx1ZXNMaXN0LnB1c2goe3ZhbDogdiwgZ3JvdXA6IGdyb3VwfSkpO1xyXG4gICAgICAgICAgICBncm91cC5hbGxWYWx1ZXNCZWZvcmVDb3VudCA9IGF4aXMudG90YWxWYWx1ZXNDb3VudDtcclxuICAgICAgICAgICAgYXhpcy50b3RhbFZhbHVlc0NvdW50ICs9IGdyb3VwLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGdyb3VwLmFsbFZhbHVlc0NvdW50ICs9IGdyb3VwLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBncm91cC5jaGlsZHJlbkxpc3QgPSBbXTtcclxuICAgICAgICBpZiAoZ3JvdXAuY2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgdmFyIGNoaWxkcmVuQ291bnQgPSAwO1xyXG5cclxuICAgICAgICAgICAgZm9yICh2YXIgY2hpbGRQcm9wIGluIGdyb3VwLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ3JvdXAuY2hpbGRyZW4uaGFzT3duUHJvcGVydHkoY2hpbGRQcm9wKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IGdyb3VwLmNoaWxkcmVuW2NoaWxkUHJvcF07XHJcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAuY2hpbGRyZW5MaXN0LnB1c2goY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuQ291bnQrKztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3J0R3JvdXBzKGF4aXMsIGNoaWxkLCBheGlzQ29uZmlnLCBnYXBzKTtcclxuICAgICAgICAgICAgICAgICAgICBncm91cC5hbGxWYWx1ZXNDb3VudCArPSBjaGlsZC5hbGxWYWx1ZXNDb3VudDtcclxuICAgICAgICAgICAgICAgICAgICBnYXBzW2dyb3VwLmxldmVsXSArPSAxO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZ2FwcyAmJiBjaGlsZHJlbkNvdW50ID4gMSkge1xyXG4gICAgICAgICAgICAgICAgZ2Fwc1tncm91cC5sZXZlbF0gLT0gMTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZ3JvdXAuZ2Fwc0luc2lkZSA9IFtdO1xyXG4gICAgICAgICAgICBnYXBzLmZvckVhY2goKGQsIGkpPT4ge1xyXG4gICAgICAgICAgICAgICAgZ3JvdXAuZ2Fwc0luc2lkZS5wdXNoKGQgLSAoZ3JvdXAuZ2Fwc0JlZm9yZVtpXSB8fCAwKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBncm91cC5nYXBzSW5zaWRlU2l6ZSA9IEhlYXRtYXAuY29tcHV0ZUdhcHNTaXplKGdyb3VwLmdhcHNJbnNpZGUpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGF4aXMuZ2Fwcy5sZW5ndGggPCBnYXBzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgYXhpcy5nYXBzID0gZ2FwcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgY29tcHV0ZVlBeGlzTGFiZWxzV2lkdGgob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIG1heFdpZHRoID0gdGhpcy5wbG90Lm1hcmdpbi5sZWZ0O1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy55LnRpdGxlKSB7XHJcbiAgICAgICAgICAgIG1heFdpZHRoIC09IDE1O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAob2Zmc2V0ICYmIG9mZnNldC54KSB7XHJcbiAgICAgICAgICAgIG1heFdpZHRoICs9IG9mZnNldC54O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnkucm90YXRlTGFiZWxzKSB7XHJcbiAgICAgICAgICAgIG1heFdpZHRoICo9IFV0aWxzLlNRUlRfMjtcclxuICAgICAgICAgICAgdmFyIGZvbnRTaXplID0gMTE7IC8vdG9kbyBjaGVjayBhY3R1YWwgZm9udCBzaXplXHJcbiAgICAgICAgICAgIG1heFdpZHRoIC09Zm9udFNpemUvMjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBtYXhXaWR0aDtcclxuICAgIH1cclxuXHJcbiAgICBjb21wdXRlWEF4aXNMYWJlbHNXaWR0aChvZmZzZXQpIHtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLngucm90YXRlTGFiZWxzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBsb3QuY2VsbFdpZHRoIC0gMjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNpemUgPSB0aGlzLnBsb3QubWFyZ2luLmJvdHRvbTtcclxuICAgICAgICBpZiAodGhpcy5jb25maWcueC50aXRsZSkge1xyXG4gICAgICAgICAgICBzaXplIC09IDE1O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAob2Zmc2V0ICYmIG9mZnNldC55KSB7XHJcbiAgICAgICAgICAgIHNpemUgLT0gb2Zmc2V0Lnk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzaXplICo9IFV0aWxzLlNRUlRfMjtcclxuXHJcbiAgICAgICAgdmFyIGZvbnRTaXplID0gMTE7IC8vdG9kbyBjaGVjayBhY3R1YWwgZm9udCBzaXplXHJcbiAgICAgICAgc2l6ZSAtPWZvbnRTaXplLzI7XHJcblxyXG4gICAgICAgIHJldHVybiBzaXplO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBjb21wdXRlR2FwU2l6ZShnYXBMZXZlbCkge1xyXG4gICAgICAgIHJldHVybiBIZWF0bWFwLm1heEdyb3VwR2FwU2l6ZSAvIChnYXBMZXZlbCArIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBjb21wdXRlR2Fwc1NpemUoZ2Fwcykge1xyXG4gICAgICAgIHZhciBnYXBzU2l6ZSA9IDA7XHJcbiAgICAgICAgZ2Fwcy5mb3JFYWNoKChnYXBzTnVtYmVyLCBnYXBzTGV2ZWwpPT4gZ2Fwc1NpemUgKz0gZ2Fwc051bWJlciAqIEhlYXRtYXAuY29tcHV0ZUdhcFNpemUoZ2Fwc0xldmVsKSk7XHJcbiAgICAgICAgcmV0dXJuIGdhcHNTaXplO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVQbG90U2l6ZSgpIHtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuICAgICAgICB2YXIgbWFyZ2luID0gcGxvdC5tYXJnaW47XHJcbiAgICAgICAgdmFyIGF2YWlsYWJsZVdpZHRoID0gVXRpbHMuYXZhaWxhYmxlV2lkdGgodGhpcy5jb25maWcud2lkdGgsIHRoaXMuZ2V0QmFzZUNvbnRhaW5lcigpLCB0aGlzLnBsb3QubWFyZ2luKTtcclxuICAgICAgICB2YXIgYXZhaWxhYmxlSGVpZ2h0ID0gVXRpbHMuYXZhaWxhYmxlSGVpZ2h0KHRoaXMuY29uZmlnLmhlaWdodCwgdGhpcy5nZXRCYXNlQ29udGFpbmVyKCksIHRoaXMucGxvdC5tYXJnaW4pO1xyXG4gICAgICAgIHZhciB3aWR0aCA9IGF2YWlsYWJsZVdpZHRoO1xyXG4gICAgICAgIHZhciBoZWlnaHQgPSBhdmFpbGFibGVIZWlnaHQ7XHJcblxyXG4gICAgICAgIHZhciB4R2Fwc1NpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBzU2l6ZShwbG90LnguZ2Fwcyk7XHJcblxyXG5cclxuICAgICAgICB2YXIgY29tcHV0ZWRDZWxsV2lkdGggPSBNYXRoLm1heChjb25mLmNlbGwuc2l6ZU1pbiwgTWF0aC5taW4oY29uZi5jZWxsLnNpemVNYXgsIChhdmFpbGFibGVXaWR0aCAtIHhHYXBzU2l6ZSkgLyB0aGlzLnBsb3QueC50b3RhbFZhbHVlc0NvdW50KSk7XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLndpZHRoKSB7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmNlbGwud2lkdGgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxvdC5jZWxsV2lkdGggPSBjb21wdXRlZENlbGxXaWR0aDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuY2VsbFdpZHRoID0gdGhpcy5jb25maWcuY2VsbC53aWR0aDtcclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5wbG90LmNlbGxXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wbG90LmNlbGxXaWR0aCA9IGNvbXB1dGVkQ2VsbFdpZHRoO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICB3aWR0aCA9IHRoaXMucGxvdC5jZWxsV2lkdGggKiB0aGlzLnBsb3QueC50b3RhbFZhbHVlc0NvdW50ICsgbWFyZ2luLmxlZnQgKyBtYXJnaW4ucmlnaHQgKyB4R2Fwc1NpemU7XHJcblxyXG4gICAgICAgIHZhciB5R2Fwc1NpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBzU2l6ZShwbG90LnkuZ2Fwcyk7XHJcbiAgICAgICAgdmFyIGNvbXB1dGVkQ2VsbEhlaWdodCA9IE1hdGgubWF4KGNvbmYuY2VsbC5zaXplTWluLCBNYXRoLm1pbihjb25mLmNlbGwuc2l6ZU1heCwgKGF2YWlsYWJsZUhlaWdodCAtIHlHYXBzU2l6ZSkgLyB0aGlzLnBsb3QueS50b3RhbFZhbHVlc0NvdW50KSk7XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmhlaWdodCkge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmNlbGwuaGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuY2VsbEhlaWdodCA9IGNvbXB1dGVkQ2VsbEhlaWdodDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5jZWxsSGVpZ2h0ID0gdGhpcy5jb25maWcuY2VsbC5oZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMucGxvdC5jZWxsSGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuY2VsbEhlaWdodCA9IGNvbXB1dGVkQ2VsbEhlaWdodDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGhlaWdodCA9IHRoaXMucGxvdC5jZWxsSGVpZ2h0ICogdGhpcy5wbG90LnkudG90YWxWYWx1ZXNDb3VudCArIG1hcmdpbi50b3AgKyBtYXJnaW4uYm90dG9tICsgeUdhcHNTaXplO1xyXG5cclxuXHJcbiAgICAgICAgdGhpcy5wbG90LndpZHRoID0gd2lkdGggLSBtYXJnaW4ubGVmdCAtIG1hcmdpbi5yaWdodDtcclxuICAgICAgICB0aGlzLnBsb3QuaGVpZ2h0ID0gaGVpZ2h0IC0gbWFyZ2luLnRvcCAtIG1hcmdpbi5ib3R0b207XHJcbiAgICB9XHJcblxyXG5cclxuICAgIHNldHVwWlNjYWxlKCkge1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGNvbmZpZyA9IHNlbGYuY29uZmlnO1xyXG4gICAgICAgIHZhciB6ID0gc2VsZi5wbG90Lno7XHJcbiAgICAgICAgdmFyIHJhbmdlID0gY29uZmlnLmNvbG9yLnJhbmdlO1xyXG4gICAgICAgIHZhciBleHRlbnQgPSB6Lm1heCAtIHoubWluO1xyXG4gICAgICAgIHZhciBzY2FsZTtcclxuICAgICAgICB6LmRvbWFpbiA9IFtdO1xyXG4gICAgICAgIGlmIChjb25maWcuY29sb3Iuc2NhbGUgPT0gXCJwb3dcIikge1xyXG4gICAgICAgICAgICB2YXIgZXhwb25lbnQgPSAxMDtcclxuICAgICAgICAgICAgcmFuZ2UuZm9yRWFjaCgoYywgaSk9PiB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdiA9IHoubWF4IC0gKGV4dGVudCAvIE1hdGgucG93KDEwLCBpKSk7XHJcbiAgICAgICAgICAgICAgICB6LmRvbWFpbi5wdXNoKHYpXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBzY2FsZSA9IGQzLnNjYWxlLnBvdygpLmV4cG9uZW50KGV4cG9uZW50KTtcclxuICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5jb2xvci5zY2FsZSA9PSBcImxvZ1wiKSB7XHJcblxyXG4gICAgICAgICAgICByYW5nZS5mb3JFYWNoKChjLCBpKT0+IHtcclxuICAgICAgICAgICAgICAgIHZhciB2ID0gei5taW4gKyAoZXh0ZW50IC8gTWF0aC5wb3coMTAsIGkpKTtcclxuICAgICAgICAgICAgICAgIHouZG9tYWluLnVuc2hpZnQodilcclxuXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgc2NhbGUgPSBkMy5zY2FsZS5sb2coKVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJhbmdlLmZvckVhY2goKGMsIGkpPT4ge1xyXG4gICAgICAgICAgICAgICAgdmFyIHYgPSB6Lm1pbiArIChleHRlbnQgKiAoaSAvIChyYW5nZS5sZW5ndGggLSAxKSkpO1xyXG4gICAgICAgICAgICAgICAgei5kb21haW4ucHVzaCh2KVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgc2NhbGUgPSBkMy5zY2FsZVtjb25maWcuY29sb3Iuc2NhbGVdKCk7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgei5kb21haW5bMF0gPSB6Lm1pbjsgLy9yZW1vdmluZyB1bm5lY2Vzc2FyeSBmbG9hdGluZyBwb2ludHNcclxuICAgICAgICB6LmRvbWFpblt6LmRvbWFpbi5sZW5ndGggLSAxXSA9IHoubWF4OyAvL3JlbW92aW5nIHVubmVjZXNzYXJ5IGZsb2F0aW5nIHBvaW50c1xyXG4gICAgICAgIGNvbnNvbGUubG9nKHouZG9tYWluKTtcclxuXHJcbiAgICAgICAgaWYgKGNvbmZpZy5jb2xvci5yZXZlcnNlU2NhbGUpIHtcclxuICAgICAgICAgICAgei5kb21haW4ucmV2ZXJzZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKHJhbmdlKTtcclxuICAgICAgICBwbG90LnouY29sb3Iuc2NhbGUgPSBzY2FsZS5kb21haW4oei5kb21haW4pLnJhbmdlKHJhbmdlKTtcclxuICAgICAgICB2YXIgc2hhcGUgPSBwbG90Lnouc2hhcGUgPSB7fTtcclxuXHJcbiAgICAgICAgdmFyIGNlbGxDb25mID0gdGhpcy5jb25maWcuY2VsbDtcclxuICAgICAgICBzaGFwZS50eXBlID0gXCJyZWN0XCI7XHJcblxyXG4gICAgICAgIHBsb3Quei5zaGFwZS53aWR0aCA9IHBsb3QuY2VsbFdpZHRoIC0gY2VsbENvbmYucGFkZGluZyAqIDI7XHJcbiAgICAgICAgcGxvdC56LnNoYXBlLmhlaWdodCA9IHBsb3QuY2VsbEhlaWdodCAtIGNlbGxDb25mLnBhZGRpbmcgKiAyO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICB1cGRhdGUobmV3RGF0YSkge1xyXG4gICAgICAgIHN1cGVyLnVwZGF0ZShuZXdEYXRhKTtcclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlZKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhd0dyb3Vwc1kodGhpcy5wbG90LnkuZ3JvdXBzLCB0aGlzLnN2Z0cpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlYKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhd0dyb3Vwc1godGhpcy5wbG90LnguZ3JvdXBzLCB0aGlzLnN2Z0cpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGVDZWxscygpO1xyXG5cclxuICAgICAgICAvLyB0aGlzLnVwZGF0ZVZhcmlhYmxlTGFiZWxzKCk7XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlQXhpc1goKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUF4aXNZKCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5zaG93TGVnZW5kKSB7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTGVnZW5kKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUF4aXNUaXRsZXMoKTtcclxuICAgIH07XHJcblxyXG4gICAgdXBkYXRlQXhpc1RpdGxlcygpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcblxyXG5cclxuICAgIH1cclxuXHJcblxyXG4gICAgdXBkYXRlQXhpc1goKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBsYWJlbENsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImxhYmVsXCIpO1xyXG4gICAgICAgIHZhciBsYWJlbFhDbGFzcyA9IGxhYmVsQ2xhc3MgKyBcIi14XCI7XHJcbiAgICAgICAgdmFyIGxhYmVsWUNsYXNzID0gbGFiZWxDbGFzcyArIFwiLXlcIjtcclxuICAgICAgICBwbG90LmxhYmVsQ2xhc3MgPSBsYWJlbENsYXNzO1xyXG5cclxuICAgICAgICB2YXIgb2Zmc2V0WCA9IHtcclxuICAgICAgICAgICAgeDogMCxcclxuICAgICAgICAgICAgeTogMFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgbGV0IGdhcFNpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBTaXplKDApO1xyXG4gICAgICAgIGlmIChwbG90Lmdyb3VwQnlYKSB7XHJcbiAgICAgICAgICAgIGxldCBvdmVybGFwID0gc2VsZi5jb25maWcueC5ncm91cHMub3ZlcmxhcDtcclxuXHJcbiAgICAgICAgICAgIG9mZnNldFgueCA9IGdhcFNpemUgLyAyO1xyXG4gICAgICAgICAgICBvZmZzZXRYLnkgPSBvdmVybGFwLmJvdHRvbSArIGdhcFNpemUgLyAyICsgNjtcclxuICAgICAgICB9IGVsc2UgaWYgKHBsb3QuZ3JvdXBCeVkpIHtcclxuICAgICAgICAgICAgb2Zmc2V0WC55ID0gZ2FwU2l6ZTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgbGFiZWxzID0gc2VsZi5zdmdHLnNlbGVjdEFsbChcInRleHQuXCIgKyBsYWJlbFhDbGFzcylcclxuICAgICAgICAgICAgLmRhdGEocGxvdC54LmFsbFZhbHVlc0xpc3QsIChkLCBpKT0+aSk7XHJcblxyXG4gICAgICAgIGxhYmVscy5lbnRlcigpLmFwcGVuZChcInRleHRcIikuYXR0cihcImNsYXNzXCIsIChkLCBpKSA9PiBsYWJlbENsYXNzICsgXCIgXCIgKyBsYWJlbFhDbGFzcyArIFwiIFwiICsgbGFiZWxYQ2xhc3MgKyBcIi1cIiArIGkpO1xyXG5cclxuICAgICAgICBsYWJlbHNcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIChkLCBpKSA9PiAoaSAqIHBsb3QuY2VsbFdpZHRoICsgcGxvdC5jZWxsV2lkdGggLyAyKSArIChkLmdyb3VwLmdhcHNTaXplKSArIG9mZnNldFgueClcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIHBsb3QuaGVpZ2h0ICsgb2Zmc2V0WC55KVxyXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIDEwKVxyXG5cclxuICAgICAgICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChkPT5zZWxmLmZvcm1hdFZhbHVlWChkLnZhbCkpO1xyXG5cclxuXHJcblxyXG4gICAgICAgIHZhciBtYXhXaWR0aCA9IHNlbGYuY29tcHV0ZVhBeGlzTGFiZWxzV2lkdGgob2Zmc2V0WCk7XHJcblxyXG4gICAgICAgIGxhYmVscy5lYWNoKGZ1bmN0aW9uIChsYWJlbCkge1xyXG4gICAgICAgICAgICB2YXIgZWxlbSA9IGQzLnNlbGVjdCh0aGlzKSxcclxuICAgICAgICAgICAgICAgIHRleHQgPSBzZWxmLmZvcm1hdFZhbHVlWChsYWJlbC52YWwpO1xyXG4gICAgICAgICAgICBVdGlscy5wbGFjZVRleHRXaXRoRWxsaXBzaXNBbmRUb29sdGlwKGVsZW0sIHRleHQsIG1heFdpZHRoLCBzZWxmLmNvbmZpZy5zaG93VG9vbHRpcCA/IHNlbGYucGxvdC50b29sdGlwIDogZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAoc2VsZi5jb25maWcueC5yb3RhdGVMYWJlbHMpIHtcclxuICAgICAgICAgICAgbGFiZWxzLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwicm90YXRlKC00NSwgXCIgKyAoKGkgKiBwbG90LmNlbGxXaWR0aCArIHBsb3QuY2VsbFdpZHRoIC8gMikgKyBkLmdyb3VwLmdhcHNTaXplICsgb2Zmc2V0WC54ICkgKyBcIiwgXCIgKyAoIHBsb3QuaGVpZ2h0ICsgb2Zmc2V0WC55KSArIFwiKVwiKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJkeFwiLCAtMilcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwiZHlcIiwgOClcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJlbmRcIik7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgbGFiZWxzLmV4aXQoKS5yZW1vdmUoKTtcclxuXHJcblxyXG4gICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIgKyBzZWxmLnByZWZpeENsYXNzKCdheGlzLXgnKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAocGxvdC53aWR0aCAvIDIpICsgXCIsXCIgKyAocGxvdC5oZWlnaHQgKyBwbG90Lm1hcmdpbi5ib3R0b20pICsgXCIpXCIpXHJcbiAgICAgICAgICAgIC5zZWxlY3RPckFwcGVuZChcInRleHQuXCIgKyBzZWxmLnByZWZpeENsYXNzKCdsYWJlbCcpKVxyXG5cclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIi0wLjVlbVwiKVxyXG4gICAgICAgICAgICAuc3R5bGUoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChzZWxmLmNvbmZpZy54LnRpdGxlKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVBeGlzWSgpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGxhYmVsQ2xhc3MgPSBzZWxmLnByZWZpeENsYXNzKFwibGFiZWxcIik7XHJcbiAgICAgICAgdmFyIGxhYmVsWUNsYXNzID0gbGFiZWxDbGFzcyArIFwiLXlcIjtcclxuICAgICAgICBwbG90LmxhYmVsQ2xhc3MgPSBsYWJlbENsYXNzO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIGxhYmVscyA9IHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgbGFiZWxZQ2xhc3MpXHJcbiAgICAgICAgICAgIC5kYXRhKHBsb3QueS5hbGxWYWx1ZXNMaXN0KTtcclxuXHJcbiAgICAgICAgbGFiZWxzLmVudGVyKCkuYXBwZW5kKFwidGV4dFwiKTtcclxuXHJcbiAgICAgICAgdmFyIG9mZnNldFkgPSB7XHJcbiAgICAgICAgICAgIHg6IDAsXHJcbiAgICAgICAgICAgIHk6IDBcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmIChwbG90Lmdyb3VwQnlZKSB7XHJcbiAgICAgICAgICAgIGxldCBvdmVybGFwID0gc2VsZi5jb25maWcueS5ncm91cHMub3ZlcmxhcDtcclxuICAgICAgICAgICAgbGV0IGdhcFNpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBTaXplKDApO1xyXG4gICAgICAgICAgICBvZmZzZXRZLnggPSAtb3ZlcmxhcC5sZWZ0O1xyXG5cclxuICAgICAgICAgICAgb2Zmc2V0WS55ID0gZ2FwU2l6ZSAvIDI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxhYmVsc1xyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgb2Zmc2V0WS54KVxyXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgKGQsIGkpID0+IChpICogcGxvdC5jZWxsSGVpZ2h0ICsgcGxvdC5jZWxsSGVpZ2h0IC8gMikgKyBkLmdyb3VwLmdhcHNTaXplICsgb2Zmc2V0WS55KVxyXG4gICAgICAgICAgICAuYXR0cihcImR4XCIsIC0yKVxyXG4gICAgICAgICAgICAuYXR0cihcInRleHQtYW5jaG9yXCIsIFwiZW5kXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgKGQsIGkpID0+IGxhYmVsQ2xhc3MgKyBcIiBcIiArIGxhYmVsWUNsYXNzICsgXCIgXCIgKyBsYWJlbFlDbGFzcyArIFwiLVwiICsgaSlcclxuXHJcbiAgICAgICAgICAgIC50ZXh0KGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZm9ybWF0dGVkID0gc2VsZi5mb3JtYXRWYWx1ZVkoZC52YWwpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1hdHRlZFxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdmFyIG1heFdpZHRoID0gc2VsZi5jb21wdXRlWUF4aXNMYWJlbHNXaWR0aChvZmZzZXRZKTtcclxuXHJcbiAgICAgICAgbGFiZWxzLmVhY2goZnVuY3Rpb24gKGxhYmVsKSB7XHJcbiAgICAgICAgICAgIHZhciBlbGVtID0gZDMuc2VsZWN0KHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgdGV4dCA9IHNlbGYuZm9ybWF0VmFsdWVZKGxhYmVsLnZhbCk7XHJcbiAgICAgICAgICAgIFV0aWxzLnBsYWNlVGV4dFdpdGhFbGxpcHNpc0FuZFRvb2x0aXAoZWxlbSwgdGV4dCwgbWF4V2lkdGgsIHNlbGYuY29uZmlnLnNob3dUb29sdGlwID8gc2VsZi5wbG90LnRvb2x0aXAgOiBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGlmIChzZWxmLmNvbmZpZy55LnJvdGF0ZUxhYmVscykge1xyXG4gICAgICAgICAgICBsYWJlbHNcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIChkLCBpKSA9PiBcInJvdGF0ZSgtNDUsIFwiICsgKG9mZnNldFkueCAgKSArIFwiLCBcIiArIChkLmdyb3VwLmdhcHNTaXplICsgKGkgKiBwbG90LmNlbGxIZWlnaHQgKyBwbG90LmNlbGxIZWlnaHQgLyAyKSArIG9mZnNldFkueSkgKyBcIilcIilcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJlbmRcIik7XHJcbiAgICAgICAgICAgIC8vIC5hdHRyKFwiZHhcIiwgLTcpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGxhYmVscy5hdHRyKFwiZG9taW5hbnQtYmFzZWxpbmVcIiwgXCJtaWRkbGVcIilcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBsYWJlbHMuZXhpdCgpLnJlbW92ZSgpO1xyXG5cclxuXHJcbiAgICAgICAgc2VsZi5zdmdHLnNlbGVjdE9yQXBwZW5kKFwiZy5cIiArIHNlbGYucHJlZml4Q2xhc3MoJ2F4aXMteScpKVxyXG4gICAgICAgICAgICAuc2VsZWN0T3JBcHBlbmQoXCJ0ZXh0LlwiICsgc2VsZi5wcmVmaXhDbGFzcygnbGFiZWwnKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAtcGxvdC5tYXJnaW4ubGVmdCArIFwiLFwiICsgKHBsb3QuaGVpZ2h0IC8gMikgKyBcIilyb3RhdGUoLTkwKVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIFwiMWVtXCIpXHJcbiAgICAgICAgICAgIC5zdHlsZShcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpXHJcbiAgICAgICAgICAgIC50ZXh0KHNlbGYuY29uZmlnLnkudGl0bGUpO1xyXG5cclxuICAgIH1cclxuXHJcblxyXG4gICAgZHJhd0dyb3Vwc1kocGFyZW50R3JvdXAsIGNvbnRhaW5lciwgYXZhaWxhYmxlV2lkdGgpIHtcclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG5cclxuICAgICAgICB2YXIgZ3JvdXBDbGFzcyA9IHNlbGYucHJlZml4Q2xhc3MoXCJncm91cFwiKTtcclxuICAgICAgICB2YXIgZ3JvdXBZQ2xhc3MgPSBncm91cENsYXNzICsgXCIteVwiO1xyXG4gICAgICAgIHZhciBncm91cHMgPSBjb250YWluZXIuc2VsZWN0QWxsKFwiZy5cIiArIGdyb3VwQ2xhc3MgKyBcIi5cIiArIGdyb3VwWUNsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShwYXJlbnRHcm91cC5jaGlsZHJlbkxpc3QpO1xyXG5cclxuICAgICAgICB2YXIgdmFsdWVzQmVmb3JlQ291bnQgPSAwO1xyXG4gICAgICAgIHZhciBnYXBzQmVmb3JlU2l6ZSA9IDA7XHJcblxyXG4gICAgICAgIHZhciBncm91cHNFbnRlckcgPSBncm91cHMuZW50ZXIoKS5hcHBlbmQoXCJnXCIpO1xyXG4gICAgICAgIGdyb3Vwc0VudGVyR1xyXG4gICAgICAgICAgICAuY2xhc3NlZChncm91cENsYXNzLCB0cnVlKVxyXG4gICAgICAgICAgICAuY2xhc3NlZChncm91cFlDbGFzcywgdHJ1ZSlcclxuICAgICAgICAgICAgLmFwcGVuZChcInJlY3RcIikuY2xhc3NlZChcImdyb3VwLXJlY3RcIiwgdHJ1ZSk7XHJcblxyXG4gICAgICAgIHZhciB0aXRsZUdyb3VwRW50ZXIgPSBncm91cHNFbnRlckcuYXBwZW5kU2VsZWN0b3IoXCJnLnRpdGxlXCIpO1xyXG4gICAgICAgIHRpdGxlR3JvdXBFbnRlci5hcHBlbmQoXCJyZWN0XCIpO1xyXG4gICAgICAgIHRpdGxlR3JvdXBFbnRlci5hcHBlbmQoXCJ0ZXh0XCIpO1xyXG5cclxuICAgICAgICB2YXIgZ2FwU2l6ZSA9IEhlYXRtYXAuY29tcHV0ZUdhcFNpemUocGFyZW50R3JvdXAubGV2ZWwpO1xyXG4gICAgICAgIHZhciBwYWRkaW5nID0gZ2FwU2l6ZSAvIDQ7XHJcblxyXG4gICAgICAgIHZhciB0aXRsZVJlY3RXaWR0aCA9IEhlYXRtYXAuZ3JvdXBUaXRsZVJlY3RIZWlnaHQ7XHJcbiAgICAgICAgdmFyIGRlcHRoID0gc2VsZi5jb25maWcueS5ncm91cHMua2V5cy5sZW5ndGggLSBwYXJlbnRHcm91cC5sZXZlbDtcclxuICAgICAgICB2YXIgb3ZlcmxhcCA9IHtcclxuICAgICAgICAgICAgbGVmdDogMCxcclxuICAgICAgICAgICAgcmlnaHQ6IDBcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBpZiAoIWF2YWlsYWJsZVdpZHRoKSB7XHJcbiAgICAgICAgICAgIG92ZXJsYXAucmlnaHQgPSBwbG90Lnkub3ZlcmxhcC5sZWZ0O1xyXG4gICAgICAgICAgICBvdmVybGFwLmxlZnQgPSBwbG90Lnkub3ZlcmxhcC5sZWZ0O1xyXG4gICAgICAgICAgICBhdmFpbGFibGVXaWR0aCA9IHBsb3Qud2lkdGggKyBnYXBTaXplICsgb3ZlcmxhcC5sZWZ0ICsgb3ZlcmxhcC5yaWdodDtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBncm91cHNcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciB0cmFuc2xhdGUgPSBcInRyYW5zbGF0ZShcIiArIChwYWRkaW5nIC0gb3ZlcmxhcC5sZWZ0KSArIFwiLFwiICsgKChwbG90LmNlbGxIZWlnaHQgKiB2YWx1ZXNCZWZvcmVDb3VudCkgKyBpICogZ2FwU2l6ZSArIGdhcHNCZWZvcmVTaXplICsgcGFkZGluZykgKyBcIilcIjtcclxuICAgICAgICAgICAgICAgIGdhcHNCZWZvcmVTaXplICs9IChkLmdhcHNJbnNpZGVTaXplIHx8IDApO1xyXG4gICAgICAgICAgICAgICAgdmFsdWVzQmVmb3JlQ291bnQgKz0gZC5hbGxWYWx1ZXNDb3VudCB8fCAwO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zbGF0ZVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIHZhciBncm91cFdpZHRoID0gYXZhaWxhYmxlV2lkdGggLSBwYWRkaW5nICogMjtcclxuXHJcbiAgICAgICAgdmFyIHRpdGxlR3JvdXBzID0gZ3JvdXBzLnNlbGVjdEFsbChcImcudGl0bGVcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwidHJhbnNsYXRlKFwiICsgKGdyb3VwV2lkdGggLSB0aXRsZVJlY3RXaWR0aCkgKyBcIiwgMClcIik7XHJcblxyXG4gICAgICAgIHZhciB0aWxlUmVjdHMgPSB0aXRsZUdyb3Vwcy5zZWxlY3RBbGwoXCJyZWN0XCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgdGl0bGVSZWN0V2lkdGgpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGQ9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCkgKyBwbG90LmNlbGxIZWlnaHQgKiBkLmFsbFZhbHVlc0NvdW50ICsgcGFkZGluZyAqIDJcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCAwKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcImZpbGxcIiwgXCJsaWdodGdyZXlcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJzdHJva2Utd2lkdGhcIiwgMCk7XHJcblxyXG4gICAgICAgIHRoaXMuc2V0R3JvdXBNb3VzZUNhbGxiYWNrcyhwYXJlbnRHcm91cCwgdGlsZVJlY3RzKTtcclxuXHJcblxyXG4gICAgICAgIGdyb3Vwcy5zZWxlY3RBbGwoXCJyZWN0Lmdyb3VwLXJlY3RcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBkPT4gXCJncm91cC1yZWN0IGdyb3VwLXJlY3QtXCIgKyBkLmluZGV4KVxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGdyb3VwV2lkdGgpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGQ9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCkgKyBwbG90LmNlbGxIZWlnaHQgKiBkLmFsbFZhbHVlc0NvdW50ICsgcGFkZGluZyAqIDJcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCAwKVxyXG4gICAgICAgICAgICAuYXR0cihcImZpbGxcIiwgXCJ3aGl0ZVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImZpbGwtb3BhY2l0eVwiLCAwKVxyXG4gICAgICAgICAgICAuYXR0cihcInN0cm9rZS13aWR0aFwiLCAwLjUpXHJcbiAgICAgICAgICAgIC5hdHRyKFwic3Ryb2tlXCIsIFwiYmxhY2tcIilcclxuXHJcblxyXG4gICAgICAgIGdyb3Vwcy5lYWNoKGZ1bmN0aW9uIChncm91cCkge1xyXG5cclxuICAgICAgICAgICAgc2VsZi5kcmF3R3JvdXBzWS5jYWxsKHNlbGYsIGdyb3VwLCBkMy5zZWxlY3QodGhpcyksIGdyb3VwV2lkdGggLSB0aXRsZVJlY3RXaWR0aCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGRyYXdHcm91cHNYKHBhcmVudEdyb3VwLCBjb250YWluZXIsIGF2YWlsYWJsZUhlaWdodCkge1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcblxyXG4gICAgICAgIHZhciBncm91cENsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImdyb3VwXCIpO1xyXG4gICAgICAgIHZhciBncm91cFhDbGFzcyA9IGdyb3VwQ2xhc3MgKyBcIi14XCI7XHJcbiAgICAgICAgdmFyIGdyb3VwcyA9IGNvbnRhaW5lci5zZWxlY3RBbGwoXCJnLlwiICsgZ3JvdXBDbGFzcyArIFwiLlwiICsgZ3JvdXBYQ2xhc3MpXHJcbiAgICAgICAgICAgIC5kYXRhKHBhcmVudEdyb3VwLmNoaWxkcmVuTGlzdCk7XHJcblxyXG4gICAgICAgIHZhciB2YWx1ZXNCZWZvcmVDb3VudCA9IDA7XHJcbiAgICAgICAgdmFyIGdhcHNCZWZvcmVTaXplID0gMDtcclxuXHJcbiAgICAgICAgdmFyIGdyb3Vwc0VudGVyRyA9IGdyb3Vwcy5lbnRlcigpLmFwcGVuZChcImdcIik7XHJcbiAgICAgICAgZ3JvdXBzRW50ZXJHXHJcbiAgICAgICAgICAgIC5jbGFzc2VkKGdyb3VwQ2xhc3MsIHRydWUpXHJcbiAgICAgICAgICAgIC5jbGFzc2VkKGdyb3VwWENsYXNzLCB0cnVlKVxyXG4gICAgICAgICAgICAuYXBwZW5kKFwicmVjdFwiKS5jbGFzc2VkKFwiZ3JvdXAtcmVjdFwiLCB0cnVlKTtcclxuXHJcbiAgICAgICAgdmFyIHRpdGxlR3JvdXBFbnRlciA9IGdyb3Vwc0VudGVyRy5hcHBlbmRTZWxlY3RvcihcImcudGl0bGVcIik7XHJcbiAgICAgICAgdGl0bGVHcm91cEVudGVyLmFwcGVuZChcInJlY3RcIik7XHJcbiAgICAgICAgdGl0bGVHcm91cEVudGVyLmFwcGVuZChcInRleHRcIik7XHJcblxyXG4gICAgICAgIHZhciBnYXBTaXplID0gSGVhdG1hcC5jb21wdXRlR2FwU2l6ZShwYXJlbnRHcm91cC5sZXZlbCk7XHJcbiAgICAgICAgdmFyIHBhZGRpbmcgPSBnYXBTaXplIC8gNDtcclxuICAgICAgICB2YXIgdGl0bGVSZWN0SGVpZ2h0ID0gSGVhdG1hcC5ncm91cFRpdGxlUmVjdEhlaWdodDtcclxuXHJcbiAgICAgICAgdmFyIGRlcHRoID0gc2VsZi5jb25maWcueC5ncm91cHMua2V5cy5sZW5ndGggLSBwYXJlbnRHcm91cC5sZXZlbDtcclxuXHJcbiAgICAgICAgdmFyIG92ZXJsYXAgPSB7XHJcbiAgICAgICAgICAgIHRvcDogMCxcclxuICAgICAgICAgICAgYm90dG9tOiAwXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKCFhdmFpbGFibGVIZWlnaHQpIHtcclxuICAgICAgICAgICAgb3ZlcmxhcC5ib3R0b20gPSBwbG90Lngub3ZlcmxhcC5ib3R0b207XHJcbiAgICAgICAgICAgIG92ZXJsYXAudG9wID0gcGxvdC54Lm92ZXJsYXAudG9wO1xyXG4gICAgICAgICAgICBhdmFpbGFibGVIZWlnaHQgPSBwbG90LmhlaWdodCArIGdhcFNpemUgKyBvdmVybGFwLnRvcCArIG92ZXJsYXAuYm90dG9tO1xyXG5cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBvdmVybGFwLnRvcCA9IC10aXRsZVJlY3RIZWlnaHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCdwYXJlbnRHcm91cCcscGFyZW50R3JvdXAsICdnYXBTaXplJywgZ2FwU2l6ZSwgcGxvdC54Lm92ZXJsYXApO1xyXG5cclxuICAgICAgICBncm91cHNcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciB0cmFuc2xhdGUgPSBcInRyYW5zbGF0ZShcIiArICgocGxvdC5jZWxsV2lkdGggKiB2YWx1ZXNCZWZvcmVDb3VudCkgKyBpICogZ2FwU2l6ZSArIGdhcHNCZWZvcmVTaXplICsgcGFkZGluZykgKyBcIiwgXCIgKyAocGFkZGluZyAtIG92ZXJsYXAudG9wKSArIFwiKVwiO1xyXG4gICAgICAgICAgICAgICAgZ2Fwc0JlZm9yZVNpemUgKz0gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCk7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZXNCZWZvcmVDb3VudCArPSBkLmFsbFZhbHVlc0NvdW50IHx8IDA7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNsYXRlXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB2YXIgZ3JvdXBIZWlnaHQgPSBhdmFpbGFibGVIZWlnaHQgLSBwYWRkaW5nICogMjtcclxuXHJcbiAgICAgICAgdmFyIHRpdGxlR3JvdXBzID0gZ3JvdXBzLnNlbGVjdEFsbChcImcudGl0bGVcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwidHJhbnNsYXRlKDAsIFwiICsgKDApICsgXCIpXCIpO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIHRpbGVSZWN0cyA9IHRpdGxlR3JvdXBzLnNlbGVjdEFsbChcInJlY3RcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgdGl0bGVSZWN0SGVpZ2h0KVxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGQ9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCkgKyBwbG90LmNlbGxXaWR0aCAqIGQuYWxsVmFsdWVzQ291bnQgKyBwYWRkaW5nICogMlxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMClcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIDApXHJcbiAgICAgICAgICAgIC8vIC5hdHRyKFwiZmlsbFwiLCBcImxpZ2h0Z3JleVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcInN0cm9rZS13aWR0aFwiLCAwKTtcclxuXHJcbiAgICAgICAgdGhpcy5zZXRHcm91cE1vdXNlQ2FsbGJhY2tzKHBhcmVudEdyb3VwLCB0aWxlUmVjdHMpO1xyXG5cclxuXHJcbiAgICAgICAgZ3JvdXBzLnNlbGVjdEFsbChcInJlY3QuZ3JvdXAtcmVjdFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGQ9PiBcImdyb3VwLXJlY3QgZ3JvdXAtcmVjdC1cIiArIGQuaW5kZXgpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGdyb3VwSGVpZ2h0KVxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGQ9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCkgKyBwbG90LmNlbGxXaWR0aCAqIGQuYWxsVmFsdWVzQ291bnQgKyBwYWRkaW5nICogMlxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMClcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZmlsbFwiLCBcIndoaXRlXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZmlsbC1vcGFjaXR5XCIsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKFwic3Ryb2tlLXdpZHRoXCIsIDAuNSlcclxuICAgICAgICAgICAgLmF0dHIoXCJzdHJva2VcIiwgXCJibGFja1wiKTtcclxuXHJcbiAgICAgICAgZ3JvdXBzLmVhY2goZnVuY3Rpb24gKGdyb3VwKSB7XHJcbiAgICAgICAgICAgIHNlbGYuZHJhd0dyb3Vwc1guY2FsbChzZWxmLCBncm91cCwgZDMuc2VsZWN0KHRoaXMpLCBncm91cEhlaWdodCAtIHRpdGxlUmVjdEhlaWdodCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGdyb3Vwcy5leGl0KCkucmVtb3ZlKCk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHNldEdyb3VwTW91c2VDYWxsYmFja3MocGFyZW50R3JvdXAsIHRpbGVSZWN0cykge1xyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgbW91c2VvdmVyQ2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLnB1c2goZnVuY3Rpb24gKGQpIHtcclxuICAgICAgICAgICAgZDMuc2VsZWN0KHRoaXMpLmNsYXNzZWQoJ2hpZ2hsaWdodGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdCh0aGlzLnBhcmVudE5vZGUucGFyZW50Tm9kZSkuc2VsZWN0QWxsKFwicmVjdC5ncm91cC1yZWN0LVwiICsgZC5pbmRleCkuY2xhc3NlZCgnaGlnaGxpZ2h0ZWQnLCB0cnVlKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdmFyIG1vdXNlb3V0Q2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgbW91c2VvdXRDYWxsYmFja3MucHVzaChmdW5jdGlvbiAoZCkge1xyXG4gICAgICAgICAgICBkMy5zZWxlY3QodGhpcykuY2xhc3NlZCgnaGlnaGxpZ2h0ZWQnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdCh0aGlzLnBhcmVudE5vZGUucGFyZW50Tm9kZSkuc2VsZWN0QWxsKFwicmVjdC5ncm91cC1yZWN0LVwiICsgZC5pbmRleCkuY2xhc3NlZCgnaGlnaGxpZ2h0ZWQnLCBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHBsb3QudG9vbHRpcCkge1xyXG5cclxuICAgICAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLnB1c2goZD0+IHtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oMjAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgLjkpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGh0bWwgPSBwYXJlbnRHcm91cC5sYWJlbCArIFwiOiBcIiArIGQuZ3JvdXBpbmdWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAuaHRtbChodG1sKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcImxlZnRcIiwgKGQzLmV2ZW50LnBhZ2VYICsgNSkgKyBcInB4XCIpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwidG9wXCIsIChkMy5ldmVudC5wYWdlWSAtIDI4KSArIFwicHhcIik7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgbW91c2VvdXRDYWxsYmFja3MucHVzaChkPT4ge1xyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbig1MDApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG5cclxuICAgICAgICB9XHJcbiAgICAgICAgdGlsZVJlY3RzLm9uKFwibW91c2VvdmVyXCIsIGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLmZvckVhY2goZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKHNlbGYsIGQpXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRpbGVSZWN0cy5vbihcIm1vdXNlb3V0XCIsIGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgbW91c2VvdXRDYWxsYmFja3MuZm9yRWFjaChmdW5jdGlvbiAoY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoc2VsZiwgZClcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlQ2VsbHMoKSB7XHJcblxyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHNlbGYucGxvdDtcclxuICAgICAgICB2YXIgY2VsbENvbnRhaW5lckNsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImNlbGxzXCIpO1xyXG4gICAgICAgIHZhciBnYXBTaXplID0gSGVhdG1hcC5jb21wdXRlR2FwU2l6ZSgwKTtcclxuICAgICAgICB2YXIgcGFkZGluZ1ggPSBwbG90LnguZ3JvdXBzLmNoaWxkcmVuTGlzdC5sZW5ndGggPyBnYXBTaXplIC8gMiA6IDA7XHJcbiAgICAgICAgdmFyIHBhZGRpbmdZID0gcGxvdC55Lmdyb3Vwcy5jaGlsZHJlbkxpc3QubGVuZ3RoID8gZ2FwU2l6ZSAvIDIgOiAwO1xyXG4gICAgICAgIHZhciBjZWxsQ29udGFpbmVyID0gc2VsZi5zdmdHLnNlbGVjdE9yQXBwZW5kKFwiZy5cIiArIGNlbGxDb250YWluZXJDbGFzcyk7XHJcbiAgICAgICAgY2VsbENvbnRhaW5lci5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgcGFkZGluZ1ggKyBcIiwgXCIgKyBwYWRkaW5nWSArIFwiKVwiKTtcclxuXHJcbiAgICAgICAgdmFyIGNlbGxDbGFzcyA9IHNlbGYucHJlZml4Q2xhc3MoXCJjZWxsXCIpO1xyXG4gICAgICAgIHZhciBjZWxsU2hhcGUgPSBwbG90Lnouc2hhcGUudHlwZTtcclxuXHJcbiAgICAgICAgdmFyIGNlbGxzID0gY2VsbENvbnRhaW5lci5zZWxlY3RBbGwoXCJnLlwiICsgY2VsbENsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShzZWxmLnBsb3QuY2VsbHMpO1xyXG5cclxuICAgICAgICB2YXIgY2VsbEVudGVyRyA9IGNlbGxzLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuY2xhc3NlZChjZWxsQ2xhc3MsIHRydWUpO1xyXG4gICAgICAgIGNlbGxzLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgYz0+IFwidHJhbnNsYXRlKFwiICsgKChwbG90LmNlbGxXaWR0aCAqIGMuY29sICsgcGxvdC5jZWxsV2lkdGggLyAyKSArIGMuY29sVmFyLmdyb3VwLmdhcHNTaXplKSArIFwiLFwiICsgKChwbG90LmNlbGxIZWlnaHQgKiBjLnJvdyArIHBsb3QuY2VsbEhlaWdodCAvIDIpICsgYy5yb3dWYXIuZ3JvdXAuZ2Fwc1NpemUpICsgXCIpXCIpO1xyXG5cclxuICAgICAgICB2YXIgc2hhcGVzID0gY2VsbHMuc2VsZWN0T3JBcHBlbmQoY2VsbFNoYXBlICsgXCIuY2VsbC1zaGFwZS1cIiArIGNlbGxTaGFwZSk7XHJcblxyXG4gICAgICAgIHNoYXBlc1xyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIHBsb3Quei5zaGFwZS53aWR0aClcclxuICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgcGxvdC56LnNoYXBlLmhlaWdodClcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIC1wbG90LmNlbGxXaWR0aCAvIDIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCAtcGxvdC5jZWxsSGVpZ2h0IC8gMik7XHJcblxyXG4gICAgICAgIHNoYXBlcy5zdHlsZShcImZpbGxcIiwgYz0+IGMudmFsdWUgPT09IHVuZGVmaW5lZCA/IHNlbGYuY29uZmlnLmNvbG9yLm5vRGF0YUNvbG9yIDogcGxvdC56LmNvbG9yLnNjYWxlKGMudmFsdWUpKTtcclxuICAgICAgICBzaGFwZXMuYXR0cihcImZpbGwtb3BhY2l0eVwiLCBkPT4gZC52YWx1ZSA9PT0gdW5kZWZpbmVkID8gMCA6IDEpO1xyXG5cclxuICAgICAgICB2YXIgbW91c2VvdmVyQ2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgdmFyIG1vdXNlb3V0Q2FsbGJhY2tzID0gW107XHJcblxyXG4gICAgICAgIGlmIChwbG90LnRvb2x0aXApIHtcclxuXHJcbiAgICAgICAgICAgIG1vdXNlb3ZlckNhbGxiYWNrcy5wdXNoKGM9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDIwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIC45KTtcclxuICAgICAgICAgICAgICAgIHZhciBodG1sID0gYy52YWx1ZSA9PT0gdW5kZWZpbmVkID8gc2VsZi5jb25maWcudG9vbHRpcC5ub0RhdGFUZXh0IDogc2VsZi5mb3JtYXRWYWx1ZVooYy52YWx1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLmh0bWwoaHRtbClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJsZWZ0XCIsIChkMy5ldmVudC5wYWdlWCArIDUpICsgXCJweFwiKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcInRvcFwiLCAoZDMuZXZlbnQucGFnZVkgLSAyOCkgKyBcInB4XCIpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIG1vdXNlb3V0Q2FsbGJhY2tzLnB1c2goYz0+IHtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oNTAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc2VsZi5jb25maWcuaGlnaGxpZ2h0TGFiZWxzKSB7XHJcbiAgICAgICAgICAgIHZhciBoaWdobGlnaHRDbGFzcyA9IHNlbGYuY29uZmlnLmNzc0NsYXNzUHJlZml4ICsgXCJoaWdobGlnaHRcIjtcclxuICAgICAgICAgICAgdmFyIHhMYWJlbENsYXNzID0gYz0+cGxvdC5sYWJlbENsYXNzICsgXCIteC1cIiArIGMuY29sO1xyXG4gICAgICAgICAgICB2YXIgeUxhYmVsQ2xhc3MgPSBjPT5wbG90LmxhYmVsQ2xhc3MgKyBcIi15LVwiICsgYy5yb3c7XHJcblxyXG5cclxuICAgICAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLnB1c2goYz0+IHtcclxuXHJcbiAgICAgICAgICAgICAgICBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwidGV4dC5cIiArIHhMYWJlbENsYXNzKGMpKS5jbGFzc2VkKGhpZ2hsaWdodENsYXNzLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgeUxhYmVsQ2xhc3MoYykpLmNsYXNzZWQoaGlnaGxpZ2h0Q2xhc3MsIHRydWUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgbW91c2VvdXRDYWxsYmFja3MucHVzaChjPT4ge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5zdmdHLnNlbGVjdEFsbChcInRleHQuXCIgKyB4TGFiZWxDbGFzcyhjKSkuY2xhc3NlZChoaWdobGlnaHRDbGFzcywgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgc2VsZi5zdmdHLnNlbGVjdEFsbChcInRleHQuXCIgKyB5TGFiZWxDbGFzcyhjKSkuY2xhc3NlZChoaWdobGlnaHRDbGFzcywgZmFsc2UpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBjZWxscy5vbihcIm1vdXNlb3ZlclwiLCBjID0+IHtcclxuICAgICAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLmZvckVhY2goY2FsbGJhY2s9PmNhbGxiYWNrKGMpKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgICAgICAub24oXCJtb3VzZW91dFwiLCBjID0+IHtcclxuICAgICAgICAgICAgICAgIG1vdXNlb3V0Q2FsbGJhY2tzLmZvckVhY2goY2FsbGJhY2s9PmNhbGxiYWNrKGMpKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGNlbGxzLm9uKFwiY2xpY2tcIiwgYz0+IHtcclxuICAgICAgICAgICAgc2VsZi50cmlnZ2VyKFwiY2VsbC1zZWxlY3RlZFwiLCBjKTtcclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIGNlbGxzLmV4aXQoKS5yZW1vdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBmb3JtYXRWYWx1ZVgodmFsdWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnguZm9ybWF0dGVyKSByZXR1cm4gdmFsdWU7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy54LmZvcm1hdHRlci5jYWxsKHRoaXMuY29uZmlnLCB2YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9ybWF0VmFsdWVZKHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy55LmZvcm1hdHRlcikgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcueS5mb3JtYXR0ZXIuY2FsbCh0aGlzLmNvbmZpZywgdmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGZvcm1hdFZhbHVlWih2YWx1ZSkge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcuei5mb3JtYXR0ZXIpIHJldHVybiB2YWx1ZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnouZm9ybWF0dGVyLmNhbGwodGhpcy5jb25maWcsIHZhbHVlKTtcclxuICAgIH1cclxuXHJcbiAgICBmb3JtYXRMZWdlbmRWYWx1ZSh2YWx1ZSkge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcubGVnZW5kLmZvcm1hdHRlcikgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcubGVnZW5kLmZvcm1hdHRlci5jYWxsKHRoaXMuY29uZmlnLCB2YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlTGVnZW5kKCkge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgbGVnZW5kWCA9IHRoaXMucGxvdC53aWR0aCArIDEwO1xyXG4gICAgICAgIHZhciBnYXBTaXplID0gSGVhdG1hcC5jb21wdXRlR2FwU2l6ZSgwKTtcclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlZKSB7XHJcbiAgICAgICAgICAgIGxlZ2VuZFggKz0gZ2FwU2l6ZSAvIDIgKyBwbG90Lnkub3ZlcmxhcC5yaWdodDtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucGxvdC5ncm91cEJ5WCkge1xyXG4gICAgICAgICAgICBsZWdlbmRYICs9IGdhcFNpemU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBsZWdlbmRZID0gMDtcclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlYIHx8IHRoaXMucGxvdC5ncm91cEJ5WSkge1xyXG4gICAgICAgICAgICBsZWdlbmRZICs9IGdhcFNpemUgLyAyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGJhcldpZHRoID0gMTA7XHJcbiAgICAgICAgdmFyIGJhckhlaWdodCA9IHRoaXMucGxvdC5oZWlnaHQgLSAyO1xyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3Quei5jb2xvci5zY2FsZTtcclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmQgPSBuZXcgTGVnZW5kKHRoaXMuc3ZnLCB0aGlzLnN2Z0csIHNjYWxlLCBsZWdlbmRYLCBsZWdlbmRZLCB2ID0+IHNlbGYuZm9ybWF0TGVnZW5kVmFsdWUodikpLnNldFJvdGF0ZUxhYmVscyhzZWxmLmNvbmZpZy5sZWdlbmQucm90YXRlTGFiZWxzKS5saW5lYXJHcmFkaWVudEJhcihiYXJXaWR0aCwgYmFySGVpZ2h0KTtcclxuICAgIH1cclxuXHJcblxyXG59XHJcbiIsImltcG9ydCB7Q2hhcnQsIENoYXJ0Q29uZmlnfSBmcm9tIFwiLi9jaGFydFwiO1xyXG5pbXBvcnQge1V0aWxzfSBmcm9tICcuL3V0aWxzJ1xyXG5pbXBvcnQge0xlZ2VuZH0gZnJvbSBcIi4vbGVnZW5kXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgSGlzdG9ncmFtQ29uZmlnIGV4dGVuZHMgQ2hhcnRDb25maWd7XHJcblxyXG4gICAgc3ZnQ2xhc3M9IHRoaXMuY3NzQ2xhc3NQcmVmaXgrJ2hpc3RvZ3JhbSc7XHJcbiAgICBzaG93TGVnZW5kPXRydWU7XHJcbiAgICBzaG93VG9vbHRpcCA9dHJ1ZTtcclxuICAgIGxlZ2VuZD17XHJcbiAgICAgICAgd2lkdGg6IDgwLFxyXG4gICAgICAgIG1hcmdpbjogMTAsXHJcbiAgICAgICAgc2hhcGVXaWR0aDogMjBcclxuICAgIH07XHJcbiAgICB4PXsvLyBYIGF4aXMgY29uZmlnXHJcbiAgICAgICAgbGFiZWw6ICcnLCAvLyBheGlzIGxhYmVsXHJcbiAgICAgICAga2V5OiAwLFxyXG4gICAgICAgIHZhbHVlOiAoZCwga2V5KSA9PiBVdGlscy5pc051bWJlcihkKSA/IGQgOiBkW2tleV0sIC8vIHggdmFsdWUgYWNjZXNzb3JcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIixcclxuICAgICAgICB0aWNrczogdW5kZWZpbmVkLFxyXG4gICAgfTtcclxuICAgIHk9ey8vIFkgYXhpcyBjb25maWdcclxuICAgICAgICBsYWJlbDogJycsIC8vIGF4aXMgbGFiZWwsXHJcbiAgICAgICAgb3JpZW50OiBcImxlZnRcIixcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIlxyXG4gICAgfTtcclxuICAgIGZyZXF1ZW5jeT10cnVlO1xyXG4gICAgZ3JvdXBzPXtcclxuICAgICAgICBrZXk6IDEsXHJcbiAgICAgICAgdmFsdWU6IChkKSA9PiBkW3RoaXMuZ3JvdXBzLmtleV0gLCAvLyBncm91cGluZyB2YWx1ZSBhY2Nlc3NvcixcclxuICAgICAgICBsYWJlbDogXCJcIlxyXG4gICAgfTtcclxuICAgIGNvbG9yID0gdW5kZWZpbmVkIC8vIHN0cmluZyBvciBmdW5jdGlvbiByZXR1cm5pbmcgY29sb3IncyB2YWx1ZSBmb3IgY29sb3Igc2NhbGVcclxuICAgIGQzQ29sb3JDYXRlZ29yeT0gJ2NhdGVnb3J5MTAnO1xyXG4gICAgdHJhbnNpdGlvbj0gdHJ1ZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pe1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdmFyIGNvbmZpZyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmKGN1c3RvbSl7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgSGlzdG9ncmFtIGV4dGVuZHMgQ2hhcnR7XHJcbiAgICBjb25zdHJ1Y3RvcihwbGFjZWhvbGRlclNlbGVjdG9yLCBkYXRhLCBjb25maWcpIHtcclxuICAgICAgICBzdXBlcihwbGFjZWhvbGRlclNlbGVjdG9yLCBkYXRhLCBuZXcgSGlzdG9ncmFtQ29uZmlnKGNvbmZpZykpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldENvbmZpZyhjb25maWcpe1xyXG4gICAgICAgIHJldHVybiBzdXBlci5zZXRDb25maWcobmV3IEhpc3RvZ3JhbUNvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpe1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGY9dGhpcztcclxuXHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90Lng9e307XHJcbiAgICAgICAgdGhpcy5wbG90Lnk9e307XHJcbiAgICAgICAgdGhpcy5wbG90LmJhcj17XHJcbiAgICAgICAgICAgIGNvbG9yOiBudWxsLy9jb2xvciBzY2FsZSBtYXBwaW5nIGZ1bmN0aW9uXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnNob3dMZWdlbmQgPSBjb25mLnNob3dMZWdlbmQ7XHJcbiAgICAgICAgaWYodGhpcy5wbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWFyZ2luLnJpZ2h0ID0gY29uZi5tYXJnaW4ucmlnaHQgKyBjb25mLmxlZ2VuZC53aWR0aCtjb25mLmxlZ2VuZC5tYXJnaW4qMjtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB0aGlzLmNvbXB1dGVQbG90U2l6ZSgpO1xyXG5cclxuXHJcblxyXG4gICAgICAgIGlmKGNvbmYuZDNDb2xvckNhdGVnb3J5KXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmNvbG9yQ2F0ZWdvcnkgPSBkMy5zY2FsZVtjb25mLmQzQ29sb3JDYXRlZ29yeV0oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNvbG9yVmFsdWUgPSBjb25mLmNvbG9yO1xyXG4gICAgICAgIGlmIChjb2xvclZhbHVlICYmIHR5cGVvZiBjb2xvclZhbHVlID09PSAnc3RyaW5nJyB8fCBjb2xvclZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmNvbG9yID0gY29sb3JWYWx1ZTtcclxuICAgICAgICB9ZWxzZSBpZih0aGlzLnBsb3QuY29sb3JDYXRlZ29yeSl7XHJcbiAgICAgICAgICAgIHZhciBkb21haW4gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhkMy5tYXAodGhpcy5kYXRhLCBkID0+IHRoaXMuY29uZmlnLmdyb3Vwcy52YWx1ZS5jYWxsKHRoaXMuY29uZmlnLCBkKSlbJ18nXSk7XHJcbiAgICAgICAgICAgIHNlbGYucGxvdC5jb2xvckNhdGVnb3J5LmRvbWFpbihkb21haW4pO1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuY29sb3IgPSBkID0+ICBzZWxmLnBsb3QuY29sb3JDYXRlZ29yeShkLmtleSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnBsb3QuZGF0YSA9IHRoaXMuZ2V0RGF0YVRvUGxvdCgpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBYKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cEhpc3RvZ3JhbSgpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBHcm91cFN0YWNrcygpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBZKCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHNldHVwWCgpe1xyXG5cclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgeCA9IHBsb3QueDtcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnLng7XHJcblxyXG4gICAgICAgIC8qICpcclxuICAgICAgICAgKiB2YWx1ZSBhY2Nlc3NvciAtIHJldHVybnMgdGhlIHZhbHVlIHRvIGVuY29kZSBmb3IgYSBnaXZlbiBkYXRhIG9iamVjdC5cclxuICAgICAgICAgKiBzY2FsZSAtIG1hcHMgdmFsdWUgdG8gYSB2aXN1YWwgZGlzcGxheSBlbmNvZGluZywgc3VjaCBhcyBhIHBpeGVsIHBvc2l0aW9uLlxyXG4gICAgICAgICAqIG1hcCBmdW5jdGlvbiAtIG1hcHMgZnJvbSBkYXRhIHZhbHVlIHRvIGRpc3BsYXkgdmFsdWVcclxuICAgICAgICAgKiBheGlzIC0gc2V0cyB1cCBheGlzXHJcbiAgICAgICAgICoqL1xyXG4gICAgICAgIHgudmFsdWUgPSBkID0+IGNvbmYudmFsdWUoZCwgY29uZi5rZXkpO1xyXG4gICAgICAgIHguc2NhbGUgPSBkMy5zY2FsZVtjb25mLnNjYWxlXSgpLnJhbmdlKFswLCBwbG90LndpZHRoXSk7XHJcbiAgICAgICAgeC5tYXAgPSBkID0+IHguc2NhbGUoeC52YWx1ZShkKSk7XHJcblxyXG4gICAgICAgIHguYXhpcyA9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeC5zY2FsZSkub3JpZW50KGNvbmYub3JpZW50KTtcclxuICAgICAgICBpZihjb25mLnRpY2tzKXtcclxuICAgICAgICAgICAgeC5heGlzLnRpY2tzKGNvbmYudGlja3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgZGF0YSA9IHRoaXMucGxvdC5kYXRhO1xyXG4gICAgICAgIHBsb3QueC5zY2FsZS5kb21haW4oW2QzLm1pbihkYXRhLCBwbG90LngudmFsdWUpLCBkMy5tYXgoZGF0YSwgcGxvdC54LnZhbHVlKV0pO1xyXG4gICAgICAgIFxyXG4gICAgfTtcclxuXHJcbiAgICBzZXR1cFkgKCl7XHJcblxyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciB5ID0gcGxvdC55O1xyXG4gICAgICAgIHZhciBjb25mID0gdGhpcy5jb25maWcueTtcclxuICAgICAgICB5LnNjYWxlID0gZDMuc2NhbGVbY29uZi5zY2FsZV0oKS5yYW5nZShbcGxvdC5oZWlnaHQsIDBdKTtcclxuXHJcbiAgICAgICAgeS5heGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh5LnNjYWxlKS5vcmllbnQoY29uZi5vcmllbnQpO1xyXG5cclxuICAgICAgICB2YXIgZGF0YSA9IHRoaXMucGxvdC5kYXRhO1xyXG4gICAgICAgIHBsb3QueS5zY2FsZS5kb21haW4oWzAsIGQzLm1heChwbG90Lmhpc3RvZ3JhbUJpbnMsIGQ9PmQueSldKTtcclxuICAgIH07XHJcblxyXG4gICAgc2V0dXBIaXN0b2dyYW0oKSB7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIHggPSBwbG90Lng7XHJcbiAgICAgICAgdmFyIHkgPSBwbG90Lnk7XHJcbiAgICAgICAgdmFyIHRpY2tzID0gdGhpcy5jb25maWcueC50aWNrcyA/IHguc2NhbGUudGlja3ModGhpcy5jb25maWcueC50aWNrcykgOiB4LnNjYWxlLnRpY2tzKCk7XHJcblxyXG4gICAgICAgIHBsb3QuaGlzdG9ncmFtID0gZDMubGF5b3V0Lmhpc3RvZ3JhbSgpLmZyZXF1ZW5jeSh0aGlzLmNvbmZpZy5mcmVxdWVuY3kpXHJcbiAgICAgICAgICAgIC52YWx1ZSh4LnZhbHVlKVxyXG4gICAgICAgICAgICAuYmlucyh0aWNrcyk7XHJcbiAgICAgICAgcGxvdC5oaXN0b2dyYW1CaW5zID0gcGxvdC5oaXN0b2dyYW0odGhpcy5wbG90LmRhdGEpO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBzZXR1cEdyb3VwU3RhY2tzKCkge1xyXG4gICAgICAgIHZhciBzZWxmPXRoaXM7XHJcbiAgICAgICAgdGhpcy5wbG90Lmdyb3VwaW5nRW5hYmxlZCA9IHRoaXMuY29uZmlnLmdyb3VwcyAmJiB0aGlzLmNvbmZpZy5ncm91cHMudmFsdWU7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5wbG90LnN0YWNrID0gZDMubGF5b3V0LnN0YWNrKCkudmFsdWVzKGQ9PmQuaGlzdG9ncmFtQmlucyk7XHJcbiAgICAgICAgdGhpcy5wbG90Lmdyb3VwZWREYXRhID0gIGQzLm5lc3QoKS5rZXkoZCA9PiB0aGlzLnBsb3QuZ3JvdXBpbmdFbmFibGVkID8gdGhpcy5jb25maWcuZ3JvdXBzLnZhbHVlLmNhbGwodGhpcy5jb25maWcsIGQpIDogJ3Jvb3QnICkuZW50cmllcyh0aGlzLnBsb3QuZGF0YSk7XHJcbiAgICAgICAgdGhpcy5wbG90Lmdyb3VwZWREYXRhLmZvckVhY2goZD0+e1xyXG4gICAgICAgICAgICBkLmhpc3RvZ3JhbUJpbnMgPSB0aGlzLnBsb3QuaGlzdG9ncmFtLmZyZXF1ZW5jeSh0aGlzLmNvbmZpZy5mcmVxdWVuY3kgfHwgdGhpcy5wbG90Lmdyb3VwaW5nRW5hYmxlZCkoZC52YWx1ZXMpO1xyXG4gICAgICAgICAgICBpZighdGhpcy5jb25maWcuZnJlcXVlbmN5ICYmIHRoaXMucGxvdC5ncm91cGluZ0VuYWJsZWQpe1xyXG4gICAgICAgICAgICAgICAgZC5oaXN0b2dyYW1CaW5zLmZvckVhY2goYiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYi5keSA9IGIuZHkvdGhpcy5wbG90LmRhdGEubGVuZ3RoXHJcbiAgICAgICAgICAgICAgICAgICAgYi55ID0gYi55L3RoaXMucGxvdC5kYXRhLmxlbmd0aFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLnBsb3Quc3RhY2tlZEhpc3RvZ3JhbXMgPSB0aGlzLnBsb3Quc3RhY2sodGhpcy5wbG90Lmdyb3VwZWREYXRhKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXREYXRhVG9QbG90KCl7XHJcbiAgICAgICAgaWYoIXRoaXMuZW5hYmxlZEdyb3Vwcyl7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGE7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhLmZpbHRlcihkID0+IHRoaXMuZW5hYmxlZEdyb3Vwcy5pbmRleE9mKHRoaXMuY29uZmlnLmdyb3Vwcy52YWx1ZS5jYWxsKHRoaXMuY29uZmlnLCBkKSk+LTEpO1xyXG4gICAgfVxyXG5cclxuICAgIGRyYXdBeGlzWCgpe1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHNlbGYucGxvdDtcclxuICAgICAgICB2YXIgYXhpc0NvbmYgPSB0aGlzLmNvbmZpZy54O1xyXG4gICAgICAgIHZhciBheGlzID0gc2VsZi5zdmdHLnNlbGVjdE9yQXBwZW5kKFwiZy5cIitzZWxmLnByZWZpeENsYXNzKCdheGlzLXgnKStcIi5cIitzZWxmLnByZWZpeENsYXNzKCdheGlzJykrKHNlbGYuY29uZmlnLmd1aWRlcyA/ICcnIDogJy4nK3NlbGYucHJlZml4Q2xhc3MoJ25vLWd1aWRlcycpKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoMCxcIiArIHBsb3QuaGVpZ2h0ICsgXCIpXCIpO1xyXG5cclxuICAgICAgICB2YXIgYXhpc1QgPSBheGlzO1xyXG4gICAgICAgIGlmIChzZWxmLmNvbmZpZy50cmFuc2l0aW9uKSB7XHJcbiAgICAgICAgICAgIGF4aXNUID0gYXhpcy50cmFuc2l0aW9uKCkuZWFzZShcInNpbi1pbi1vdXRcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBheGlzVC5jYWxsKHBsb3QueC5heGlzKTtcclxuXHJcbiAgICAgICAgYXhpcy5zZWxlY3RPckFwcGVuZChcInRleHQuXCIrc2VsZi5wcmVmaXhDbGFzcygnbGFiZWwnKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIrIChwbG90LndpZHRoLzIpICtcIixcIisgKHBsb3QubWFyZ2luLmJvdHRvbSkgK1wiKVwiKSAgLy8gdGV4dCBpcyBkcmF3biBvZmYgdGhlIHNjcmVlbiB0b3AgbGVmdCwgbW92ZSBkb3duIGFuZCBvdXQgYW5kIHJvdGF0ZVxyXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIFwiLTFlbVwiKVxyXG4gICAgICAgICAgICAuc3R5bGUoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChheGlzQ29uZi5sYWJlbCk7XHJcbiAgICB9O1xyXG5cclxuICAgIGRyYXdBeGlzWSgpe1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHNlbGYucGxvdDtcclxuICAgICAgICB2YXIgYXhpc0NvbmYgPSB0aGlzLmNvbmZpZy55O1xyXG4gICAgICAgIHZhciBheGlzID0gc2VsZi5zdmdHLnNlbGVjdE9yQXBwZW5kKFwiZy5cIitzZWxmLnByZWZpeENsYXNzKCdheGlzLXknKStcIi5cIitzZWxmLnByZWZpeENsYXNzKCdheGlzJykrKHNlbGYuY29uZmlnLmd1aWRlcyA/ICcnIDogJy4nK3NlbGYucHJlZml4Q2xhc3MoJ25vLWd1aWRlcycpKSk7XHJcblxyXG4gICAgICAgIHZhciBheGlzVCA9IGF4aXM7XHJcbiAgICAgICAgaWYgKHNlbGYuY29uZmlnLnRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgYXhpc1QgPSBheGlzLnRyYW5zaXRpb24oKS5lYXNlKFwic2luLWluLW91dFwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGF4aXNULmNhbGwocGxvdC55LmF4aXMpO1xyXG5cclxuICAgICAgICBheGlzLnNlbGVjdE9yQXBwZW5kKFwidGV4dC5cIitzZWxmLnByZWZpeENsYXNzKCdsYWJlbCcpKVxyXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIisgLXBsb3QubWFyZ2luLmxlZnQgK1wiLFwiKyhwbG90LmhlaWdodC8yKStcIilyb3RhdGUoLTkwKVwiKSAgLy8gdGV4dCBpcyBkcmF3biBvZmYgdGhlIHNjcmVlbiB0b3AgbGVmdCwgbW92ZSBkb3duIGFuZCBvdXQgYW5kIHJvdGF0ZVxyXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIFwiMWVtXCIpXHJcbiAgICAgICAgICAgIC5zdHlsZShcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpXHJcbiAgICAgICAgICAgIC50ZXh0KGF4aXNDb25mLmxhYmVsKTtcclxuICAgIH07XHJcblxyXG5cclxuICAgIGRyYXdIaXN0b2dyYW0oKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIFxyXG4gICAgICAgIHZhciBsYXllckNsYXNzID0gdGhpcy5wcmVmaXhDbGFzcyhcImxheWVyXCIpO1xyXG5cclxuICAgICAgICB2YXIgYmFyQ2xhc3MgPSB0aGlzLnByZWZpeENsYXNzKFwiYmFyXCIpO1xyXG4gICAgICAgIHZhciBsYXllciA9IHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCIuXCIrbGF5ZXJDbGFzcylcclxuICAgICAgICAgICAgLmRhdGEocGxvdC5zdGFja2VkSGlzdG9ncmFtcyk7XHJcblxyXG4gICAgICAgIGxheWVyLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGxheWVyQ2xhc3MpO1xyXG5cclxuICAgICAgICB2YXIgYmFyID0gbGF5ZXIuc2VsZWN0QWxsKFwiLlwiK2JhckNsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShkID0+IGQuaGlzdG9ncmFtQmlucyk7XHJcblxyXG4gICAgICAgIGJhci5lbnRlcigpLmFwcGVuZChcImdcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBiYXJDbGFzcylcclxuICAgICAgICAgICAgLmFwcGVuZChcInJlY3RcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIDEpO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIGJhclJlY3QgPSBiYXIuc2VsZWN0KFwicmVjdFwiKTtcclxuXHJcbiAgICAgICAgdmFyIGJhclJlY3RUID0gYmFyUmVjdDtcclxuICAgICAgICB2YXIgYmFyVCA9IGJhcjtcclxuICAgICAgICB2YXIgbGF5ZXJUID0gbGF5ZXI7XHJcbiAgICAgICAgaWYgKHRoaXMudHJhbnNpdGlvbkVuYWJsZWQoKSkge1xyXG4gICAgICAgICAgICBiYXJSZWN0VCA9IGJhclJlY3QudHJhbnNpdGlvbigpO1xyXG4gICAgICAgICAgICBiYXJUID0gYmFyLnRyYW5zaXRpb24oKTtcclxuICAgICAgICAgICAgbGF5ZXJUPSBsYXllci50cmFuc2l0aW9uKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBiYXJULmF0dHIoXCJ0cmFuc2Zvcm1cIiwgZnVuY3Rpb24oZCkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyBwbG90Lnguc2NhbGUoZC54KSArIFwiLFwiICsgKHBsb3QueS5zY2FsZShkLnkwICtkLnkpKSArIFwiKVwiOyB9KTtcclxuXHJcbiAgICAgICAgdmFyIGR4ID0gcGxvdC5oaXN0b2dyYW1CaW5zLmxlbmd0aCA/ICBwbG90Lnguc2NhbGUocGxvdC5oaXN0b2dyYW1CaW5zWzBdLmR4KSA6IDA7XHJcbiAgICAgICAgYmFyUmVjdFRcclxuICAgICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCAgZHggLSBwbG90Lnguc2NhbGUoMCktIDEpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGQgPT4gICBwbG90LmhlaWdodCAtIHBsb3QueS5zY2FsZShkLnkpKTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5wbG90LmNvbG9yKXtcclxuICAgICAgICAgICAgbGF5ZXJUXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImZpbGxcIiwgdGhpcy5wbG90LmNvbG9yKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwbG90LnRvb2x0aXApIHtcclxuICAgICAgICAgICAgYmFyLm9uKFwibW91c2VvdmVyXCIsIGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbigyMDApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAuOSk7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAuaHRtbChkLnkpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwibGVmdFwiLCAoZDMuZXZlbnQucGFnZVggKyA1KSArIFwicHhcIilcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgKGQzLmV2ZW50LnBhZ2VZIC0gMjgpICsgXCJweFwiKTtcclxuICAgICAgICAgICAgfSkub24oXCJtb3VzZW91dFwiLCBkID0+IHtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oNTAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsYXllci5leGl0KCkucmVtb3ZlKCk7XHJcbiAgICAgICAgYmFyLmV4aXQoKS5yZW1vdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGUobmV3RGF0YSl7XHJcbiAgICAgICAgc3VwZXIudXBkYXRlKG5ld0RhdGEpO1xyXG4gICAgICAgIHRoaXMuZHJhd0F4aXNYKCk7XHJcbiAgICAgICAgdGhpcy5kcmF3QXhpc1koKTtcclxuXHJcbiAgICAgICAgdGhpcy5kcmF3SGlzdG9ncmFtKCk7XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlTGVnZW5kKCk7XHJcbiAgICB9O1xyXG5cclxuXHJcbiAgICB1cGRhdGVMZWdlbmQoKSB7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcblxyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3QuY29sb3JDYXRlZ29yeTtcclxuICAgICAgICBpZighc2NhbGUuZG9tYWluKCkgfHwgc2NhbGUuZG9tYWluKCkubGVuZ3RoPDIpe1xyXG4gICAgICAgICAgICBwbG90LnNob3dMZWdlbmQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKCFwbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICBpZihwbG90LmxlZ2VuZCAmJiBwbG90LmxlZ2VuZC5jb250YWluZXIpe1xyXG4gICAgICAgICAgICAgICAgcGxvdC5sZWdlbmQuY29udGFpbmVyLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgbGVnZW5kWCA9IHRoaXMucGxvdC53aWR0aCArIHRoaXMuY29uZmlnLmxlZ2VuZC5tYXJnaW47XHJcbiAgICAgICAgdmFyIGxlZ2VuZFkgPSB0aGlzLmNvbmZpZy5sZWdlbmQubWFyZ2luO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZCA9IG5ldyBMZWdlbmQodGhpcy5zdmcsIHRoaXMuc3ZnRywgc2NhbGUsIGxlZ2VuZFgsIGxlZ2VuZFkpO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZENvbG9yID0gcGxvdC5sZWdlbmQuY29sb3IoKVxyXG4gICAgICAgICAgICAuc2hhcGVXaWR0aCh0aGlzLmNvbmZpZy5sZWdlbmQuc2hhcGVXaWR0aClcclxuICAgICAgICAgICAgLm9yaWVudCgndmVydGljYWwnKVxyXG4gICAgICAgICAgICAuc2NhbGUoc2NhbGUpO1xyXG5cclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmRDb2xvci5vbignY2VsbGNsaWNrJywgYz0+IHRoaXMub25MZWdlbmRDZWxsQ2xpY2soYykpO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZC5jb250YWluZXJcclxuICAgICAgICAgICAgLmNhbGwocGxvdC5sZWdlbmRDb2xvcik7XHJcbiAgICB9XHJcblxyXG4gICAgb25MZWdlbmRDZWxsQ2xpY2soY2VsbFZhbHVlKXtcclxuICAgICAgICB0aGlzLnVwZGF0ZUVuYWJsZWRHcm91cHMoY2VsbFZhbHVlKTtcclxuXHJcbiAgICAgICAgdmFyIGlzRGlzYWJsZWQgPSB0aGlzLmVuYWJsZWRHcm91cHMuaW5kZXhPZihjZWxsVmFsdWUpPDA7XHJcbiAgICAgICAgdGhpcy5wbG90LmxlZ2VuZC5jb250YWluZXIuc2VsZWN0QWxsKFwiZy5jZWxsXCIpLmVhY2goZnVuY3Rpb24oY2VsbCl7XHJcbiAgICAgICAgICAgIGlmKGNlbGwgPT0gY2VsbFZhbHVlKXtcclxuICAgICAgICAgICAgICAgIGQzLnNlbGVjdCh0aGlzKS5jbGFzc2VkKFwib2RjLWRpc2FibGVkXCIsIGlzRGlzYWJsZWQpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmluaXQoKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVFbmFibGVkR3JvdXBzKGNlbGxWYWx1ZSkge1xyXG4gICAgICAgIGlmICghdGhpcy5lbmFibGVkR3JvdXBzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZW5hYmxlZEdyb3VwcyA9IHRoaXMucGxvdC5jb2xvckNhdGVnb3J5LmRvbWFpbigpLnNsaWNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBpbmRleCA9IHRoaXMuZW5hYmxlZEdyb3Vwcy5pbmRleE9mKGNlbGxWYWx1ZSk7XHJcblxyXG4gICAgICAgIGlmIChpbmRleCA8IDApIHtcclxuICAgICAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzLnB1c2goY2VsbFZhbHVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxuXHJcbiAgICBzZXREYXRhKGRhdGEpe1xyXG4gICAgICAgIHN1cGVyLnNldERhdGEoZGF0YSk7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzID0gbnVsbDtcclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQge0QzRXh0ZW5zaW9uc30gZnJvbSAnLi9kMy1leHRlbnNpb25zJ1xyXG5EM0V4dGVuc2lvbnMuZXh0ZW5kKCk7XHJcblxyXG5leHBvcnQge1NjYXR0ZXJQbG90LCBTY2F0dGVyUGxvdENvbmZpZ30gZnJvbSBcIi4vc2NhdHRlcnBsb3RcIjtcclxuZXhwb3J0IHtTY2F0dGVyUGxvdE1hdHJpeCwgU2NhdHRlclBsb3RNYXRyaXhDb25maWd9IGZyb20gXCIuL3NjYXR0ZXJwbG90LW1hdHJpeFwiO1xyXG5leHBvcnQge0NvcnJlbGF0aW9uTWF0cml4LCBDb3JyZWxhdGlvbk1hdHJpeENvbmZpZ30gZnJvbSAnLi9jb3JyZWxhdGlvbi1tYXRyaXgnXHJcbmV4cG9ydCB7UmVncmVzc2lvbiwgUmVncmVzc2lvbkNvbmZpZ30gZnJvbSAnLi9yZWdyZXNzaW9uJ1xyXG5leHBvcnQge0hlYXRtYXAsIEhlYXRtYXBDb25maWd9IGZyb20gJy4vaGVhdG1hcCdcclxuZXhwb3J0IHtIZWF0bWFwVGltZVNlcmllcywgSGVhdG1hcFRpbWVTZXJpZXNDb25maWd9IGZyb20gJy4vaGVhdG1hcC10aW1lc2VyaWVzJ1xyXG5leHBvcnQge0hpc3RvZ3JhbSwgSGlzdG9ncmFtQ29uZmlnfSBmcm9tICcuL2hpc3RvZ3JhbSdcclxuZXhwb3J0IHtCYXJDaGFydCwgQmFyQ2hhcnRDb25maWd9IGZyb20gJy4vYmFyLWNoYXJ0J1xyXG5leHBvcnQge1N0YXRpc3RpY3NVdGlsc30gZnJvbSAnLi9zdGF0aXN0aWNzLXV0aWxzJ1xyXG5leHBvcnQge0xlZ2VuZH0gZnJvbSAnLi9sZWdlbmQnXHJcblxyXG5cclxuXHJcblxyXG5cclxuIiwiaW1wb3J0IHtVdGlsc30gZnJvbSBcIi4vdXRpbHNcIjtcclxuaW1wb3J0IHtjb2xvciwgc2l6ZSwgc3ltYm9sfSBmcm9tIFwiLi4vYm93ZXJfY29tcG9uZW50cy9kMy1sZWdlbmQvbm8tZXh0ZW5kXCI7XHJcblxyXG4vKnZhciBkMyA9IHJlcXVpcmUoJy4uL2Jvd2VyX2NvbXBvbmVudHMvZDMnKTtcclxuKi9cclxuLy8gdmFyIGxlZ2VuZCA9IHJlcXVpcmUoJy4uL2Jvd2VyX2NvbXBvbmVudHMvZDMtbGVnZW5kL25vLWV4dGVuZCcpO1xyXG4vL1xyXG4vLyBtb2R1bGUuZXhwb3J0cy5sZWdlbmQgPSBsZWdlbmQ7XHJcblxyXG5leHBvcnQgY2xhc3MgTGVnZW5kIHtcclxuXHJcbiAgICBjc3NDbGFzc1ByZWZpeD1cIm9kYy1cIjtcclxuICAgIGxlZ2VuZENsYXNzPXRoaXMuY3NzQ2xhc3NQcmVmaXgrXCJsZWdlbmRcIjtcclxuICAgIGNvbnRhaW5lcjtcclxuICAgIHNjYWxlO1xyXG4gICAgY29sb3I9IGNvbG9yO1xyXG4gICAgc2l6ZSA9IHNpemU7XHJcbiAgICBzeW1ib2w9IHN5bWJvbDtcclxuICAgIGd1aWQ7XHJcblxyXG4gICAgbGFiZWxGb3JtYXQgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc3ZnLCBsZWdlbmRQYXJlbnQsIHNjYWxlLCBsZWdlbmRYLCBsZWdlbmRZLCBsYWJlbEZvcm1hdCl7XHJcbiAgICAgICAgdGhpcy5zY2FsZT1zY2FsZTtcclxuICAgICAgICB0aGlzLnN2ZyA9IHN2ZztcclxuICAgICAgICB0aGlzLmd1aWQgPSBVdGlscy5ndWlkKCk7XHJcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSAgVXRpbHMuc2VsZWN0T3JBcHBlbmQobGVnZW5kUGFyZW50LCBcImcuXCIrdGhpcy5sZWdlbmRDbGFzcywgXCJnXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiK2xlZ2VuZFgrXCIsXCIrbGVnZW5kWStcIilcIilcclxuICAgICAgICAgICAgLmNsYXNzZWQodGhpcy5sZWdlbmRDbGFzcywgdHJ1ZSk7XHJcblxyXG4gICAgICAgIHRoaXMubGFiZWxGb3JtYXQgPSBsYWJlbEZvcm1hdDtcclxuICAgIH1cclxuXHJcblxyXG5cclxuICAgIGxpbmVhckdyYWRpZW50QmFyKGJhcldpZHRoLCBiYXJIZWlnaHQsIHRpdGxlKXtcclxuICAgICAgICB2YXIgZ3JhZGllbnRJZCA9IHRoaXMuY3NzQ2xhc3NQcmVmaXgrXCJsaW5lYXItZ3JhZGllbnRcIitcIi1cIit0aGlzLmd1aWQ7XHJcbiAgICAgICAgdmFyIHNjYWxlPSB0aGlzLnNjYWxlO1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgICAgdGhpcy5saW5lYXJHcmFkaWVudCA9IFV0aWxzLmxpbmVhckdyYWRpZW50KHRoaXMuc3ZnLCBncmFkaWVudElkLCB0aGlzLnNjYWxlLnJhbmdlKCksIDAsIDEwMCwgMCwgMCk7XHJcblxyXG4gICAgICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZChcInJlY3RcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBiYXJXaWR0aClcclxuICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgYmFySGVpZ2h0KVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMClcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIDApXHJcbiAgICAgICAgICAgIC5zdHlsZShcImZpbGxcIiwgXCJ1cmwoI1wiK2dyYWRpZW50SWQrXCIpXCIpO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIHRpY2tzID0gdGhpcy5jb250YWluZXIuc2VsZWN0QWxsKFwidGV4dFwiKVxyXG4gICAgICAgICAgICAuZGF0YSggc2NhbGUuZG9tYWluKCkgKTtcclxuICAgICAgICB2YXIgdGlja3NOdW1iZXIgPXNjYWxlLmRvbWFpbigpLmxlbmd0aC0xO1xyXG4gICAgICAgIHRpY2tzLmVudGVyKCkuYXBwZW5kKFwidGV4dFwiKTtcclxuXHJcbiAgICAgICAgdGlja3MuYXR0cihcInhcIiwgYmFyV2lkdGgpXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCAgKGQsIGkpID0+ICBiYXJIZWlnaHQgLShpKmJhckhlaWdodC90aWNrc051bWJlcikpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZHhcIiwgMylcclxuICAgICAgICAgICAgLy8gLmF0dHIoXCJkeVwiLCAxKVxyXG4gICAgICAgICAgICAuYXR0cihcImFsaWdubWVudC1iYXNlbGluZVwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChkPT4gc2VsZi5sYWJlbEZvcm1hdCA/IHNlbGYubGFiZWxGb3JtYXQoZCkgOiBkKTtcclxuICAgICAgICB0aWNrcy5hdHRyKFwiZG9taW5hbnQtYmFzZWxpbmVcIiwgXCJtaWRkbGVcIilcclxuICAgICAgICBpZih0aGlzLnJvdGF0ZUxhYmVscyl7XHJcbiAgICAgICAgICAgIHRpY2tzXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCAoZCwgaSkgPT4gXCJyb3RhdGUoLTQ1LCBcIiArIGJhcldpZHRoICsgXCIsIFwiICsgKGJhckhlaWdodCAtKGkqYmFySGVpZ2h0L3RpY2tzTnVtYmVyKSkgKyBcIilcIilcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJzdGFydFwiKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJkeFwiLCA1KVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCA1KTtcclxuXHJcbiAgICAgICAgfWVsc2V7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGlja3MuZXhpdCgpLnJlbW92ZSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBzZXRSb3RhdGVMYWJlbHMocm90YXRlTGFiZWxzKSB7XHJcbiAgICAgICAgdGhpcy5yb3RhdGVMYWJlbHMgPSByb3RhdGVMYWJlbHM7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgXHJcbn0iLCJpbXBvcnQge0NoYXJ0LCBDaGFydENvbmZpZ30gZnJvbSBcIi4vY2hhcnRcIjtcclxuaW1wb3J0IHtTY2F0dGVyUGxvdCwgU2NhdHRlclBsb3RDb25maWd9IGZyb20gXCIuL3NjYXR0ZXJwbG90XCI7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcbmltcG9ydCB7U3RhdGlzdGljc1V0aWxzfSBmcm9tICcuL3N0YXRpc3RpY3MtdXRpbHMnXHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFJlZ3Jlc3Npb25Db25maWcgZXh0ZW5kcyBTY2F0dGVyUGxvdENvbmZpZ3tcclxuXHJcbiAgICBtYWluUmVncmVzc2lvbiA9IHRydWU7XHJcbiAgICBncm91cFJlZ3Jlc3Npb24gPSB0cnVlO1xyXG4gICAgY29uZmlkZW5jZT17XHJcbiAgICAgICAgbGV2ZWw6IDAuOTUsXHJcbiAgICAgICAgY3JpdGljYWxWYWx1ZTogKGRlZ3JlZXNPZkZyZWVkb20sIGNyaXRpY2FsUHJvYmFiaWxpdHkpID0+IFN0YXRpc3RpY3NVdGlscy50VmFsdWUoZGVncmVlc09mRnJlZWRvbSwgY3JpdGljYWxQcm9iYWJpbGl0eSksXHJcbiAgICAgICAgbWFyZ2luT2ZFcnJvcjogdW5kZWZpbmVkIC8vY3VzdG9tICBtYXJnaW4gT2YgRXJyb3IgZnVuY3Rpb24gKHgsIHBvaW50cylcclxuICAgIH07XHJcblxyXG4gICAgY29uc3RydWN0b3IoY3VzdG9tKXtcclxuICAgICAgICBzdXBlcigpO1xyXG5cclxuICAgICAgICBpZihjdXN0b20pe1xyXG4gICAgICAgICAgICBVdGlscy5kZWVwRXh0ZW5kKHRoaXMsIGN1c3RvbSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFJlZ3Jlc3Npb24gZXh0ZW5kcyBTY2F0dGVyUGxvdHtcclxuICAgIGNvbnN0cnVjdG9yKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIGNvbmZpZykge1xyXG4gICAgICAgIHN1cGVyKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIG5ldyBSZWdyZXNzaW9uQ29uZmlnKGNvbmZpZykpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldENvbmZpZyhjb25maWcpe1xyXG4gICAgICAgIHJldHVybiBzdXBlci5zZXRDb25maWcobmV3IFJlZ3Jlc3Npb25Db25maWcoY29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdFBsb3QoKXtcclxuICAgICAgICBzdXBlci5pbml0UGxvdCgpO1xyXG4gICAgICAgIHRoaXMuaW5pdFJlZ3Jlc3Npb25MaW5lcygpO1xyXG4gICAgfVxyXG5cclxuICAgIGluaXRSZWdyZXNzaW9uTGluZXMoKXtcclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBncm91cHNBdmFpbGFibGUgPSBzZWxmLmNvbmZpZy5ncm91cHMgJiYgc2VsZi5jb25maWcuZ3JvdXBzLnZhbHVlO1xyXG5cclxuICAgICAgICBzZWxmLnBsb3QucmVncmVzc2lvbnM9IFtdO1xyXG5cclxuXHJcbiAgICAgICAgaWYoZ3JvdXBzQXZhaWxhYmxlICYmIHNlbGYuY29uZmlnLm1haW5SZWdyZXNzaW9uKXtcclxuICAgICAgICAgICAgdmFyIHJlZ3Jlc3Npb24gPSB0aGlzLmluaXRSZWdyZXNzaW9uKHRoaXMucGxvdC5kYXRhLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIHNlbGYucGxvdC5yZWdyZXNzaW9ucy5wdXNoKHJlZ3Jlc3Npb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYoc2VsZi5jb25maWcuZ3JvdXBSZWdyZXNzaW9uKXtcclxuICAgICAgICAgICAgdGhpcy5pbml0R3JvdXBSZWdyZXNzaW9uKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH1cclxuXHJcbiAgICBpbml0R3JvdXBSZWdyZXNzaW9uKCkge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgZGF0YUJ5R3JvdXAgPSB7fTtcclxuICAgICAgICB0aGlzLnBsb3QuZGF0YS5mb3JFYWNoIChkPT57XHJcbiAgICAgICAgICAgIHZhciBncm91cFZhbCA9IHNlbGYuY29uZmlnLmdyb3Vwcy52YWx1ZShkLCBzZWxmLmNvbmZpZy5ncm91cHMua2V5KTtcclxuXHJcbiAgICAgICAgICAgIGlmKCFncm91cFZhbCAmJiBncm91cFZhbCE9PTApe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZighZGF0YUJ5R3JvdXBbZ3JvdXBWYWxdKXtcclxuICAgICAgICAgICAgICAgIGRhdGFCeUdyb3VwW2dyb3VwVmFsXSA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRhdGFCeUdyb3VwW2dyb3VwVmFsXS5wdXNoKGQpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBmb3IodmFyIGtleSBpbiBkYXRhQnlHcm91cCl7XHJcbiAgICAgICAgICAgIGlmICghZGF0YUJ5R3JvdXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciByZWdyZXNzaW9uID0gdGhpcy5pbml0UmVncmVzc2lvbihkYXRhQnlHcm91cFtrZXldLCBrZXkpO1xyXG4gICAgICAgICAgICBzZWxmLnBsb3QucmVncmVzc2lvbnMucHVzaChyZWdyZXNzaW9uKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdFJlZ3Jlc3Npb24odmFsdWVzLCBncm91cFZhbCl7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICB2YXIgcG9pbnRzID0gdmFsdWVzLm1hcChkPT57XHJcbiAgICAgICAgICAgIHJldHVybiBbcGFyc2VGbG9hdChzZWxmLnBsb3QueC52YWx1ZShkKSksIHBhcnNlRmxvYXQoc2VsZi5wbG90LnkudmFsdWUoZCkpXTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gcG9pbnRzLnNvcnQoKGEsYikgPT4gYVswXS1iWzBdKTtcclxuXHJcbiAgICAgICAgdmFyIGxpbmVhclJlZ3Jlc3Npb24gPSAgU3RhdGlzdGljc1V0aWxzLmxpbmVhclJlZ3Jlc3Npb24ocG9pbnRzKTtcclxuICAgICAgICB2YXIgbGluZWFyUmVncmVzc2lvbkxpbmUgPSBTdGF0aXN0aWNzVXRpbHMubGluZWFyUmVncmVzc2lvbkxpbmUobGluZWFyUmVncmVzc2lvbik7XHJcblxyXG5cclxuICAgICAgICB2YXIgZXh0ZW50WCA9IGQzLmV4dGVudChwb2ludHMsIGQ9PmRbMF0pO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIGxpbmVQb2ludHMgPSBbXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHg6IGV4dGVudFhbMF0sXHJcbiAgICAgICAgICAgICAgICB5OiBsaW5lYXJSZWdyZXNzaW9uTGluZShleHRlbnRYWzBdKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICB4OiBleHRlbnRYWzFdLFxyXG4gICAgICAgICAgICAgICAgeTogbGluZWFyUmVncmVzc2lvbkxpbmUoZXh0ZW50WFsxXSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIF07XHJcblxyXG4gICAgICAgIHZhciBsaW5lID0gZDMuc3ZnLmxpbmUoKVxyXG4gICAgICAgICAgICAuaW50ZXJwb2xhdGUoXCJiYXNpc1wiKVxyXG4gICAgICAgICAgICAueChkID0+IHNlbGYucGxvdC54LnNjYWxlKGQueCkpXHJcbiAgICAgICAgICAgIC55KGQgPT4gc2VsZi5wbG90Lnkuc2NhbGUoZC55KSk7XHJcbiAgICAgICAgXHJcblxyXG4gICAgICAgIHZhciBjb2xvciA9IHNlbGYucGxvdC5kb3QuY29sb3I7XHJcblxyXG4gICAgICAgIHZhciBkZWZhdWx0Q29sb3IgPSBcImJsYWNrXCI7XHJcbiAgICAgICAgaWYoVXRpbHMuaXNGdW5jdGlvbihjb2xvcikpe1xyXG4gICAgICAgICAgICBpZih2YWx1ZXMubGVuZ3RoICYmIGdyb3VwVmFsIT09ZmFsc2Upe1xyXG4gICAgICAgICAgICAgICAgY29sb3IgPSBjb2xvcih2YWx1ZXNbMF0pO1xyXG4gICAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgICAgIGNvbG9yID0gZGVmYXVsdENvbG9yO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfWVsc2UgaWYoIWNvbG9yICYmIGdyb3VwVmFsPT09ZmFsc2Upe1xyXG4gICAgICAgICAgICBjb2xvciA9IGRlZmF1bHRDb2xvcjtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgY29uZmlkZW5jZSA9IHRoaXMuY29tcHV0ZUNvbmZpZGVuY2UocG9pbnRzLCBleHRlbnRYLCAgbGluZWFyUmVncmVzc2lvbixsaW5lYXJSZWdyZXNzaW9uTGluZSk7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgZ3JvdXA6IGdyb3VwVmFsIHx8IGZhbHNlLFxyXG4gICAgICAgICAgICBsaW5lOiBsaW5lLFxyXG4gICAgICAgICAgICBsaW5lUG9pbnRzOiBsaW5lUG9pbnRzLFxyXG4gICAgICAgICAgICBjb2xvcjogY29sb3IsXHJcbiAgICAgICAgICAgIGNvbmZpZGVuY2U6IGNvbmZpZGVuY2VcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVDb25maWRlbmNlKHBvaW50cywgZXh0ZW50WCwgbGluZWFyUmVncmVzc2lvbixsaW5lYXJSZWdyZXNzaW9uTGluZSl7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBzbG9wZSA9IGxpbmVhclJlZ3Jlc3Npb24ubTtcclxuICAgICAgICB2YXIgbiA9IHBvaW50cy5sZW5ndGg7XHJcbiAgICAgICAgdmFyIGRlZ3JlZXNPZkZyZWVkb20gPSBNYXRoLm1heCgwLCBuLTIpO1xyXG5cclxuICAgICAgICB2YXIgYWxwaGEgPSAxIC0gc2VsZi5jb25maWcuY29uZmlkZW5jZS5sZXZlbDtcclxuICAgICAgICB2YXIgY3JpdGljYWxQcm9iYWJpbGl0eSAgPSAxIC0gYWxwaGEvMjtcclxuICAgICAgICB2YXIgY3JpdGljYWxWYWx1ZSA9IHNlbGYuY29uZmlnLmNvbmZpZGVuY2UuY3JpdGljYWxWYWx1ZShkZWdyZWVzT2ZGcmVlZG9tLGNyaXRpY2FsUHJvYmFiaWxpdHkpO1xyXG5cclxuICAgICAgICB2YXIgeFZhbHVlcyA9IHBvaW50cy5tYXAoZD0+ZFswXSk7XHJcbiAgICAgICAgdmFyIG1lYW5YID0gU3RhdGlzdGljc1V0aWxzLm1lYW4oeFZhbHVlcyk7XHJcbiAgICAgICAgdmFyIHhNeVN1bT0wO1xyXG4gICAgICAgIHZhciB4U3VtPTA7XHJcbiAgICAgICAgdmFyIHhQb3dTdW09MDtcclxuICAgICAgICB2YXIgeVN1bT0wO1xyXG4gICAgICAgIHZhciB5UG93U3VtPTA7XHJcbiAgICAgICAgcG9pbnRzLmZvckVhY2gocD0+e1xyXG4gICAgICAgICAgICB2YXIgeCA9IHBbMF07XHJcbiAgICAgICAgICAgIHZhciB5ID0gcFsxXTtcclxuXHJcbiAgICAgICAgICAgIHhNeVN1bSArPSB4Knk7XHJcbiAgICAgICAgICAgIHhTdW0rPXg7XHJcbiAgICAgICAgICAgIHlTdW0rPXk7XHJcbiAgICAgICAgICAgIHhQb3dTdW0rPSB4Kng7XHJcbiAgICAgICAgICAgIHlQb3dTdW0rPSB5Knk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIGEgPSBsaW5lYXJSZWdyZXNzaW9uLm07XHJcbiAgICAgICAgdmFyIGIgPSBsaW5lYXJSZWdyZXNzaW9uLmI7XHJcblxyXG4gICAgICAgIHZhciBTYTIgPSBuLyhuKzIpICogKCh5UG93U3VtLWEqeE15U3VtLWIqeVN1bSkvKG4qeFBvd1N1bS0oeFN1bSp4U3VtKSkpOyAvL1dhcmlhbmNqYSB3c3DDs8WCY3p5bm5pa2Ega2llcnVua293ZWdvIHJlZ3Jlc2ppIGxpbmlvd2VqIGFcclxuICAgICAgICB2YXIgU3kyID0gKHlQb3dTdW0gLSBhKnhNeVN1bS1iKnlTdW0pLyhuKihuLTIpKTsgLy9TYTIgLy9NZWFuIHkgdmFsdWUgdmFyaWFuY2VcclxuXHJcbiAgICAgICAgdmFyIGVycm9yRm4gPSB4PT4gTWF0aC5zcXJ0KFN5MiArIE1hdGgucG93KHgtbWVhblgsMikqU2EyKTsgLy9waWVyd2lhc3RlayBrd2FkcmF0b3d5IHogd2FyaWFuY2ppIGRvd29sbmVnbyBwdW5rdHUgcHJvc3RlalxyXG4gICAgICAgIHZhciBtYXJnaW5PZkVycm9yID0gIHg9PiBjcml0aWNhbFZhbHVlKiBlcnJvckZuKHgpO1xyXG5cclxuXHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ24nLCBuLCAnZGVncmVlc09mRnJlZWRvbScsIGRlZ3JlZXNPZkZyZWVkb20sICdjcml0aWNhbFByb2JhYmlsaXR5Jyxjcml0aWNhbFByb2JhYmlsaXR5KTtcclxuICAgICAgICAvLyB2YXIgY29uZmlkZW5jZURvd24gPSB4ID0+IGxpbmVhclJlZ3Jlc3Npb25MaW5lKHgpIC0gIG1hcmdpbk9mRXJyb3IoeCk7XHJcbiAgICAgICAgLy8gdmFyIGNvbmZpZGVuY2VVcCA9IHggPT4gbGluZWFyUmVncmVzc2lvbkxpbmUoeCkgKyAgbWFyZ2luT2ZFcnJvcih4KTtcclxuXHJcblxyXG4gICAgICAgIHZhciBjb21wdXRlQ29uZmlkZW5jZUFyZWFQb2ludCA9IHg9PntcclxuICAgICAgICAgICAgdmFyIGxpbmVhclJlZ3Jlc3Npb24gPSBsaW5lYXJSZWdyZXNzaW9uTGluZSh4KTtcclxuICAgICAgICAgICAgdmFyIG1vZSA9IG1hcmdpbk9mRXJyb3IoeCk7XHJcbiAgICAgICAgICAgIHZhciBjb25mRG93biA9IGxpbmVhclJlZ3Jlc3Npb24gLSBtb2U7XHJcbiAgICAgICAgICAgIHZhciBjb25mVXAgPSBsaW5lYXJSZWdyZXNzaW9uICsgbW9lO1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgeDogeCxcclxuICAgICAgICAgICAgICAgIHkwOiBjb25mRG93bixcclxuICAgICAgICAgICAgICAgIHkxOiBjb25mVXBcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB2YXIgY2VudGVyWCA9IChleHRlbnRYWzFdK2V4dGVudFhbMF0pLzI7XHJcblxyXG4gICAgICAgIC8vIHZhciBjb25maWRlbmNlQXJlYVBvaW50cyA9IFtleHRlbnRYWzBdLCBjZW50ZXJYLCAgZXh0ZW50WFsxXV0ubWFwKGNvbXB1dGVDb25maWRlbmNlQXJlYVBvaW50KTtcclxuICAgICAgICB2YXIgY29uZmlkZW5jZUFyZWFQb2ludHMgPSBbZXh0ZW50WFswXSwgY2VudGVyWCwgIGV4dGVudFhbMV1dLm1hcChjb21wdXRlQ29uZmlkZW5jZUFyZWFQb2ludCk7XHJcblxyXG4gICAgICAgIHZhciBmaXRJblBsb3QgPSB5ID0+IHk7XHJcblxyXG4gICAgICAgIHZhciBjb25maWRlbmNlQXJlYSA9ICBkMy5zdmcuYXJlYSgpXHJcbiAgICAgICAgLmludGVycG9sYXRlKFwibW9ub3RvbmVcIilcclxuICAgICAgICAgICAgLngoZCA9PiBzZWxmLnBsb3QueC5zY2FsZShkLngpKVxyXG4gICAgICAgICAgICAueTAoZCA9PiBmaXRJblBsb3Qoc2VsZi5wbG90Lnkuc2NhbGUoZC55MCkpKVxyXG4gICAgICAgICAgICAueTEoZCA9PiBmaXRJblBsb3Qoc2VsZi5wbG90Lnkuc2NhbGUoZC55MSkpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgYXJlYTpjb25maWRlbmNlQXJlYSxcclxuICAgICAgICAgICAgcG9pbnRzOmNvbmZpZGVuY2VBcmVhUG9pbnRzXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGUobmV3RGF0YSl7XHJcbiAgICAgICAgc3VwZXIudXBkYXRlKG5ld0RhdGEpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlUmVncmVzc2lvbkxpbmVzKCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICB1cGRhdGVSZWdyZXNzaW9uTGluZXMoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciByZWdyZXNzaW9uQ29udGFpbmVyQ2xhc3MgPSB0aGlzLnByZWZpeENsYXNzKFwicmVncmVzc2lvbi1jb250YWluZXJcIik7XHJcbiAgICAgICAgdmFyIHJlZ3Jlc3Npb25Db250YWluZXJTZWxlY3RvciA9IFwiZy5cIityZWdyZXNzaW9uQ29udGFpbmVyQ2xhc3M7XHJcblxyXG4gICAgICAgIHZhciBjbGlwUGF0aElkID0gc2VsZi5wcmVmaXhDbGFzcyhcImNsaXBcIik7XHJcblxyXG4gICAgICAgIHZhciByZWdyZXNzaW9uQ29udGFpbmVyID0gc2VsZi5zdmdHLnNlbGVjdE9ySW5zZXJ0KHJlZ3Jlc3Npb25Db250YWluZXJTZWxlY3RvciwgXCIuXCIrc2VsZi5kb3RzQ29udGFpbmVyQ2xhc3MpO1xyXG4gICAgICAgIHZhciByZWdyZXNzaW9uQ29udGFpbmVyQ2xpcCA9IHJlZ3Jlc3Npb25Db250YWluZXIuc2VsZWN0T3JBcHBlbmQoXCJjbGlwUGF0aFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImlkXCIsIGNsaXBQYXRoSWQpO1xyXG5cclxuXHJcbiAgICAgICAgcmVncmVzc2lvbkNvbnRhaW5lckNsaXAuc2VsZWN0T3JBcHBlbmQoJ3JlY3QnKVxyXG4gICAgICAgICAgICAuYXR0cignd2lkdGgnLCBzZWxmLnBsb3Qud2lkdGgpXHJcbiAgICAgICAgICAgIC5hdHRyKCdoZWlnaHQnLCBzZWxmLnBsb3QuaGVpZ2h0KVxyXG4gICAgICAgICAgICAuYXR0cigneCcsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKCd5JywgMCk7XHJcblxyXG4gICAgICAgIHJlZ3Jlc3Npb25Db250YWluZXIuYXR0cihcImNsaXAtcGF0aFwiLCAoZCxpKSA9PiBcInVybCgjXCIrY2xpcFBhdGhJZCtcIilcIik7XHJcblxyXG4gICAgICAgIHZhciByZWdyZXNzaW9uQ2xhc3MgPSB0aGlzLnByZWZpeENsYXNzKFwicmVncmVzc2lvblwiKTtcclxuICAgICAgICB2YXIgY29uZmlkZW5jZUFyZWFDbGFzcyA9IHNlbGYucHJlZml4Q2xhc3MoXCJjb25maWRlbmNlXCIpO1xyXG4gICAgICAgIHZhciByZWdyZXNzaW9uU2VsZWN0b3IgPSBcImcuXCIrcmVncmVzc2lvbkNsYXNzO1xyXG4gICAgICAgIHZhciByZWdyZXNzaW9uID0gcmVncmVzc2lvbkNvbnRhaW5lci5zZWxlY3RBbGwocmVncmVzc2lvblNlbGVjdG9yKVxyXG4gICAgICAgICAgICAuZGF0YShzZWxmLnBsb3QucmVncmVzc2lvbnMsIChkLGkpPT4gZC5ncm91cCk7XHJcblxyXG4gICAgICAgIHZhciByZWdyZXNzaW9uRW50ZXJHID0gcmVncmVzc2lvbi5lbnRlcigpLmluc2VydFNlbGVjdG9yKHJlZ3Jlc3Npb25TZWxlY3Rvcik7XHJcbiAgICAgICAgdmFyIGxpbmVDbGFzcyA9IHNlbGYucHJlZml4Q2xhc3MoXCJsaW5lXCIpO1xyXG4gICAgICAgIHJlZ3Jlc3Npb25FbnRlckdcclxuXHJcbiAgICAgICAgICAgIC5hcHBlbmQoXCJwYXRoXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgbGluZUNsYXNzKVxyXG4gICAgICAgICAgICAuYXR0cihcInNoYXBlLXJlbmRlcmluZ1wiLCBcIm9wdGltaXplUXVhbGl0eVwiKTtcclxuICAgICAgICAgICAgLy8gLmFwcGVuZChcImxpbmVcIilcclxuICAgICAgICAgICAgLy8gLmF0dHIoXCJjbGFzc1wiLCBcImxpbmVcIilcclxuICAgICAgICAgICAgLy8gLmF0dHIoXCJzaGFwZS1yZW5kZXJpbmdcIiwgXCJvcHRpbWl6ZVF1YWxpdHlcIik7XHJcblxyXG4gICAgICAgIHZhciBsaW5lID0gcmVncmVzc2lvbi5zZWxlY3QoXCJwYXRoLlwiK2xpbmVDbGFzcylcclxuICAgICAgICAgICAgLnN0eWxlKFwic3Ryb2tlXCIsIHIgPT4gci5jb2xvcik7XHJcbiAgICAgICAgLy8gLmF0dHIoXCJ4MVwiLCByPT4gc2VsZi5wbG90Lnguc2NhbGUoci5saW5lUG9pbnRzWzBdLngpKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcInkxXCIsIHI9PiBzZWxmLnBsb3QueS5zY2FsZShyLmxpbmVQb2ludHNbMF0ueSkpXHJcbiAgICAgICAgICAgIC8vIC5hdHRyKFwieDJcIiwgcj0+IHNlbGYucGxvdC54LnNjYWxlKHIubGluZVBvaW50c1sxXS54KSlcclxuICAgICAgICAgICAgLy8gLmF0dHIoXCJ5MlwiLCByPT4gc2VsZi5wbG90Lnkuc2NhbGUoci5saW5lUG9pbnRzWzFdLnkpKVxyXG5cclxuXHJcbiAgICAgICAgdmFyIGxpbmVUID0gbGluZTtcclxuICAgICAgICBpZiAoc2VsZi50cmFuc2l0aW9uRW5hYmxlZCgpKSB7XHJcbiAgICAgICAgICAgIGxpbmVUID0gbGluZS50cmFuc2l0aW9uKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsaW5lVC5hdHRyKFwiZFwiLCByID0+IHIubGluZShyLmxpbmVQb2ludHMpKVxyXG5cclxuXHJcbiAgICAgICAgcmVncmVzc2lvbkVudGVyR1xyXG4gICAgICAgICAgICAuYXBwZW5kKFwicGF0aFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGNvbmZpZGVuY2VBcmVhQ2xhc3MpXHJcbiAgICAgICAgICAgIC5hdHRyKFwic2hhcGUtcmVuZGVyaW5nXCIsIFwib3B0aW1pemVRdWFsaXR5XCIpXHJcbiAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgXCIwLjRcIik7XHJcblxyXG5cclxuXHJcbiAgICAgICAgdmFyIGFyZWEgPSByZWdyZXNzaW9uLnNlbGVjdChcInBhdGguXCIrY29uZmlkZW5jZUFyZWFDbGFzcyk7XHJcblxyXG4gICAgICAgIHZhciBhcmVhVCA9IGFyZWE7XHJcbiAgICAgICAgaWYgKHNlbGYudHJhbnNpdGlvbkVuYWJsZWQoKSkge1xyXG4gICAgICAgICAgICBhcmVhVCA9IGFyZWEudHJhbnNpdGlvbigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBhcmVhVC5hdHRyKFwiZFwiLCByID0+IHIuY29uZmlkZW5jZS5hcmVhKHIuY29uZmlkZW5jZS5wb2ludHMpKTtcclxuICAgICAgICBhcmVhVC5zdHlsZShcImZpbGxcIiwgciA9PiByLmNvbG9yKVxyXG4gICAgICAgIHJlZ3Jlc3Npb24uZXhpdCgpLnJlbW92ZSgpO1xyXG5cclxuICAgIH1cclxuXHJcblxyXG5cclxufVxyXG5cclxuIiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7U2NhdHRlclBsb3RDb25maWd9IGZyb20gXCIuL3NjYXR0ZXJwbG90XCI7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcbmltcG9ydCB7TGVnZW5kfSBmcm9tIFwiLi9sZWdlbmRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTY2F0dGVyUGxvdE1hdHJpeENvbmZpZyBleHRlbmRzIFNjYXR0ZXJQbG90Q29uZmlne1xyXG5cclxuICAgIHN2Z0NsYXNzPSB0aGlzLmNzc0NsYXNzUHJlZml4KydzY2F0dGVycGxvdC1tYXRyaXgnO1xyXG4gICAgc2l6ZT0gMjAwOyAvL3NjYXR0ZXIgcGxvdCBjZWxsIHNpemVcclxuICAgIHBhZGRpbmc9IDIwOyAvL3NjYXR0ZXIgcGxvdCBjZWxsIHBhZGRpbmdcclxuICAgIGJydXNoPSB0cnVlO1xyXG4gICAgZ3VpZGVzPSB0cnVlOyAvL3Nob3cgYXhpcyBndWlkZXNcclxuICAgIHNob3dUb29sdGlwPSB0cnVlOyAvL3Nob3cgdG9vbHRpcCBvbiBkb3QgaG92ZXJcclxuICAgIHRpY2tzPSB1bmRlZmluZWQ7IC8vdGlja3MgbnVtYmVyLCAoZGVmYXVsdDogY29tcHV0ZWQgdXNpbmcgY2VsbCBzaXplKVxyXG4gICAgeD17Ly8gWCBheGlzIGNvbmZpZ1xyXG4gICAgICAgIG9yaWVudDogXCJib3R0b21cIixcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIlxyXG4gICAgfTtcclxuICAgIHk9ey8vIFkgYXhpcyBjb25maWdcclxuICAgICAgICBvcmllbnQ6IFwibGVmdFwiLFxyXG4gICAgICAgIHNjYWxlOiBcImxpbmVhclwiXHJcbiAgICB9O1xyXG4gICAgZ3JvdXBzPXtcclxuICAgICAgICBrZXk6IHVuZGVmaW5lZCwgLy9vYmplY3QgcHJvcGVydHkgbmFtZSBvciBhcnJheSBpbmRleCB3aXRoIGdyb3VwaW5nIHZhcmlhYmxlXHJcbiAgICAgICAgaW5jbHVkZUluUGxvdDogZmFsc2UsIC8vaW5jbHVkZSBncm91cCBhcyB2YXJpYWJsZSBpbiBwbG90LCBib29sZWFuIChkZWZhdWx0OiBmYWxzZSlcclxuICAgICAgICB2YWx1ZTogKGQsIGtleSkgPT4gZFtrZXldLCAvLyBncm91cGluZyB2YWx1ZSBhY2Nlc3NvcixcclxuICAgICAgICBsYWJlbDogXCJcIlxyXG4gICAgfTtcclxuICAgIHZhcmlhYmxlcz0ge1xyXG4gICAgICAgIGxhYmVsczogW10sIC8vb3B0aW9uYWwgYXJyYXkgb2YgdmFyaWFibGUgbGFiZWxzIChmb3IgdGhlIGRpYWdvbmFsIG9mIHRoZSBwbG90KS5cclxuICAgICAgICBrZXlzOiBbXSwgLy9vcHRpb25hbCBhcnJheSBvZiB2YXJpYWJsZSBrZXlzXHJcbiAgICAgICAgdmFsdWU6IChkLCB2YXJpYWJsZUtleSkgPT4gZFt2YXJpYWJsZUtleV0gLy8gdmFyaWFibGUgdmFsdWUgYWNjZXNzb3JcclxuICAgIH07XHJcblxyXG4gICAgY29uc3RydWN0b3IoY3VzdG9tKXtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgIH1cclxuXHJcblxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgU2NhdHRlclBsb3RNYXRyaXggZXh0ZW5kcyBDaGFydCB7XHJcbiAgICBjb25zdHJ1Y3RvcihwbGFjZWhvbGRlclNlbGVjdG9yLCBkYXRhLCBjb25maWcpIHtcclxuICAgICAgICBzdXBlcihwbGFjZWhvbGRlclNlbGVjdG9yLCBkYXRhLCBuZXcgU2NhdHRlclBsb3RNYXRyaXhDb25maWcoY29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Q29uZmlnKGNvbmZpZykge1xyXG4gICAgICAgIHJldHVybiBzdXBlci5zZXRDb25maWcobmV3IFNjYXR0ZXJQbG90TWF0cml4Q29uZmlnKGNvbmZpZykpO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpIHtcclxuICAgICAgICBzdXBlci5pbml0UGxvdCgpO1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIG1hcmdpbiA9IHRoaXMucGxvdC5tYXJnaW47XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuICAgICAgICB0aGlzLnBsb3QueD17fTtcclxuICAgICAgICB0aGlzLnBsb3QueT17fTtcclxuICAgICAgICB0aGlzLnBsb3QuZG90PXtcclxuICAgICAgICAgICAgY29sb3I6IG51bGwvL2NvbG9yIHNjYWxlIG1hcHBpbmcgZnVuY3Rpb25cclxuICAgICAgICB9O1xyXG5cclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnNob3dMZWdlbmQgPSBjb25mLnNob3dMZWdlbmQ7XHJcbiAgICAgICAgaWYodGhpcy5wbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICBtYXJnaW4ucmlnaHQgPSBjb25mLm1hcmdpbi5yaWdodCArIGNvbmYubGVnZW5kLndpZHRoK2NvbmYubGVnZW5kLm1hcmdpbioyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5zZXR1cEdyb3VwcygpO1xyXG5cclxuICAgICAgICB0aGlzLnBsb3QuZGF0YSA9IHRoaXMuZ2V0RGF0YVRvUGxvdCgpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBWYXJpYWJsZXMoKTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnNpemUgPSBjb25mLnNpemU7XHJcblxyXG5cclxuICAgICAgICB2YXIgd2lkdGggPSBjb25mLndpZHRoO1xyXG4gICAgICAgIHZhciBib3VuZGluZ0NsaWVudFJlY3QgPSB0aGlzLmdldEJhc2VDb250YWluZXJOb2RlKCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgaWYgKCF3aWR0aCkge1xyXG4gICAgICAgICAgICB2YXIgbWF4V2lkdGggPSBtYXJnaW4ubGVmdCArIG1hcmdpbi5yaWdodCArIHRoaXMucGxvdC52YXJpYWJsZXMubGVuZ3RoKnRoaXMucGxvdC5zaXplO1xyXG4gICAgICAgICAgICB3aWR0aCA9IE1hdGgubWluKGJvdW5kaW5nQ2xpZW50UmVjdC53aWR0aCwgbWF4V2lkdGgpO1xyXG5cclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGhlaWdodCA9IHdpZHRoO1xyXG4gICAgICAgIGlmICghaGVpZ2h0KSB7XHJcbiAgICAgICAgICAgIGhlaWdodCA9IGJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnBsb3Qud2lkdGggPSB3aWR0aCAtIG1hcmdpbi5sZWZ0IC0gbWFyZ2luLnJpZ2h0O1xyXG4gICAgICAgIHRoaXMucGxvdC5oZWlnaHQgPSBoZWlnaHQgLSBtYXJnaW4udG9wIC0gbWFyZ2luLmJvdHRvbTtcclxuXHJcblxyXG5cclxuXHJcbiAgICAgICAgaWYoY29uZi50aWNrcz09PXVuZGVmaW5lZCl7XHJcbiAgICAgICAgICAgIGNvbmYudGlja3MgPSB0aGlzLnBsb3Quc2l6ZSAvIDQwO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG5cclxuICAgICAgICB0aGlzLnNldHVwWCgpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBZKCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgc2V0dXBHcm91cHMoKSB7XHJcbiAgICAgICAgdmFyIHNlbGY9dGhpcztcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnO1xyXG4gICAgICAgIHRoaXMucGxvdC5ncm91cFZhbHVlID0gZCA9PiBjb25mLmdyb3Vwcy52YWx1ZShkLCBjb25mLmdyb3Vwcy5rZXkpO1xyXG4gICAgICAgIGlmKGNvbmYuZG90LmQzQ29sb3JDYXRlZ29yeSl7XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5kb3QuY29sb3JDYXRlZ29yeSA9IGQzLnNjYWxlW2NvbmYuZG90LmQzQ29sb3JDYXRlZ29yeV0oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNvbG9yVmFsdWUgPSBjb25mLmRvdC5jb2xvcjtcclxuICAgICAgICBpZihjb2xvclZhbHVlKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmRvdC5jb2xvclZhbHVlID0gY29sb3JWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29sb3JWYWx1ZSA9PT0gJ3N0cmluZycgfHwgY29sb3JWYWx1ZSBpbnN0YW5jZW9mIFN0cmluZyl7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuZG90LmNvbG9yID0gY29sb3JWYWx1ZTtcclxuICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5wbG90LmRvdC5jb2xvckNhdGVnb3J5KXtcclxuICAgICAgICAgICAgICAgIHZhciBkb21haW4gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhkMy5tYXAodGhpcy5kYXRhLCBkID0+IHNlbGYucGxvdC5kb3QuY29sb3JWYWx1ZS5jYWxsKHNlbGYsZCkpWydfJ10pO1xyXG4gICAgICAgICAgICAgICAgc2VsZi5wbG90LmRvdC5jb2xvckNhdGVnb3J5LmRvbWFpbihkb21haW4pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wbG90LmRvdC5jb2xvciA9IGQgPT4gIHNlbGYucGxvdC5kb3QuY29sb3JDYXRlZ29yeShzZWxmLnBsb3QuZG90LmNvbG9yVmFsdWUuY2FsbChzZWxmLGQpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXREYXRhVG9QbG90KCl7XHJcbiAgICAgICAgaWYoIXRoaXMuZW5hYmxlZEdyb3Vwcyl7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGE7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgZmlsdGVyID0gdGhpcy5kYXRhLmZpbHRlcihkID0+IHRoaXMuZW5hYmxlZEdyb3Vwcy5pbmRleE9mKHRoaXMucGxvdC5ncm91cFZhbHVlKGQpKT4tMSk7XHJcbiAgICAgICAgY29uc29sZS5sb2coZmlsdGVyLmxlbmd0aCk7XHJcbiAgICAgICAgcmV0dXJuIGZpbHRlcjtcclxuICAgIH1cclxuXHJcbiAgICBzZXR1cFZhcmlhYmxlcygpIHtcclxuICAgICAgICB2YXIgdmFyaWFibGVzQ29uZiA9IHRoaXMuY29uZmlnLnZhcmlhYmxlcztcclxuXHJcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLmRhdGE7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgcGxvdC5kb21haW5CeVZhcmlhYmxlID0ge307XHJcbiAgICAgICAgcGxvdC52YXJpYWJsZXMgPSB2YXJpYWJsZXNDb25mLmtleXM7XHJcbiAgICAgICAgaWYoIXBsb3QudmFyaWFibGVzIHx8ICFwbG90LnZhcmlhYmxlcy5sZW5ndGgpe1xyXG4gICAgICAgICAgICBwbG90LnZhcmlhYmxlcyA9IFV0aWxzLmluZmVyVmFyaWFibGVzKGRhdGEsIHRoaXMuY29uZmlnLmdyb3Vwcy5rZXksIHRoaXMuY29uZmlnLmluY2x1ZGVJblBsb3QpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcGxvdC5sYWJlbHMgPSBbXTtcclxuICAgICAgICBwbG90LmxhYmVsQnlWYXJpYWJsZSA9IHt9O1xyXG4gICAgICAgIHBsb3QudmFyaWFibGVzLmZvckVhY2goKHZhcmlhYmxlS2V5LCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBwbG90LmRvbWFpbkJ5VmFyaWFibGVbdmFyaWFibGVLZXldID0gZDMuZXh0ZW50KGRhdGEsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHZhcmlhYmxlc0NvbmYudmFsdWUoZCwgdmFyaWFibGVLZXkpIH0pO1xyXG4gICAgICAgICAgICB2YXIgbGFiZWwgPSB2YXJpYWJsZUtleTtcclxuICAgICAgICAgICAgaWYodmFyaWFibGVzQ29uZi5sYWJlbHMgJiYgdmFyaWFibGVzQ29uZi5sYWJlbHMubGVuZ3RoPmluZGV4KXtcclxuXHJcbiAgICAgICAgICAgICAgICBsYWJlbCA9IHZhcmlhYmxlc0NvbmYubGFiZWxzW2luZGV4XTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwbG90LmxhYmVscy5wdXNoKGxhYmVsKTtcclxuICAgICAgICAgICAgcGxvdC5sYWJlbEJ5VmFyaWFibGVbdmFyaWFibGVLZXldID0gbGFiZWw7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKHBsb3QubGFiZWxCeVZhcmlhYmxlKTtcclxuXHJcbiAgICAgICAgcGxvdC5zdWJwbG90cyA9IFtdO1xyXG4gICAgfTtcclxuXHJcbiAgICBzZXR1cFgoKSB7XHJcblxyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciB4ID0gcGxvdC54O1xyXG4gICAgICAgIHZhciBjb25mID0gdGhpcy5jb25maWc7XHJcblxyXG4gICAgICAgIHgudmFsdWUgPSBjb25mLnZhcmlhYmxlcy52YWx1ZTtcclxuICAgICAgICB4LnNjYWxlID0gZDMuc2NhbGVbY29uZi54LnNjYWxlXSgpLnJhbmdlKFtjb25mLnBhZGRpbmcgLyAyLCBwbG90LnNpemUgLSBjb25mLnBhZGRpbmcgLyAyXSk7XHJcbiAgICAgICAgeC5tYXAgPSAoZCwgdmFyaWFibGUpID0+IHguc2NhbGUoeC52YWx1ZShkLCB2YXJpYWJsZSkpO1xyXG4gICAgICAgIHguYXhpcyA9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeC5zY2FsZSkub3JpZW50KGNvbmYueC5vcmllbnQpLnRpY2tzKGNvbmYudGlja3MpO1xyXG4gICAgICAgIHguYXhpcy50aWNrU2l6ZShwbG90LnNpemUgKiBwbG90LnZhcmlhYmxlcy5sZW5ndGgpO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgc2V0dXBZKCkge1xyXG5cclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgeSA9IHBsb3QueTtcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnO1xyXG5cclxuICAgICAgICB5LnZhbHVlID0gY29uZi52YXJpYWJsZXMudmFsdWU7XHJcbiAgICAgICAgeS5zY2FsZSA9IGQzLnNjYWxlW2NvbmYueS5zY2FsZV0oKS5yYW5nZShbIHBsb3Quc2l6ZSAtIGNvbmYucGFkZGluZyAvIDIsIGNvbmYucGFkZGluZyAvIDJdKTtcclxuICAgICAgICB5Lm1hcCA9IChkLCB2YXJpYWJsZSkgPT4geS5zY2FsZSh5LnZhbHVlKGQsIHZhcmlhYmxlKSk7XHJcbiAgICAgICAgeS5heGlzPSBkMy5zdmcuYXhpcygpLnNjYWxlKHkuc2NhbGUpLm9yaWVudChjb25mLnkub3JpZW50KS50aWNrcyhjb25mLnRpY2tzKTtcclxuICAgICAgICB5LmF4aXMudGlja1NpemUoLXBsb3Quc2l6ZSAqIHBsb3QudmFyaWFibGVzLmxlbmd0aCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHVwZGF0ZSggbmV3RGF0YSkge1xyXG4gICAgICAgIHN1cGVyLnVwZGF0ZShuZXdEYXRhKTtcclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPXRoaXM7XHJcbiAgICAgICAgdmFyIG4gPSBzZWxmLnBsb3QudmFyaWFibGVzLmxlbmd0aDtcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnO1xyXG5cclxuICAgICAgICB2YXIgYXhpc0NsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImF4aXNcIik7XHJcbiAgICAgICAgdmFyIGF4aXNYQ2xhc3MgPSBheGlzQ2xhc3MrXCIteFwiO1xyXG4gICAgICAgIHZhciBheGlzWUNsYXNzID0gYXhpc0NsYXNzK1wiLXlcIjtcclxuXHJcbiAgICAgICAgdmFyIHhBeGlzU2VsZWN0b3IgPSBcImcuXCIrYXhpc1hDbGFzcytcIi5cIitheGlzQ2xhc3M7XHJcbiAgICAgICAgdmFyIHlBeGlzU2VsZWN0b3IgPSBcImcuXCIrYXhpc1lDbGFzcytcIi5cIitheGlzQ2xhc3M7XHJcblxyXG4gICAgICAgIHZhciBub0d1aWRlc0NsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcIm5vLWd1aWRlc1wiKTtcclxuICAgICAgICBzZWxmLnN2Z0cuc2VsZWN0QWxsKHhBeGlzU2VsZWN0b3IpXHJcbiAgICAgICAgICAgIC5kYXRhKHNlbGYucGxvdC52YXJpYWJsZXMpXHJcbiAgICAgICAgICAgIC5lbnRlcigpLmFwcGVuZFNlbGVjdG9yKHhBeGlzU2VsZWN0b3IpXHJcbiAgICAgICAgICAgIC5jbGFzc2VkKG5vR3VpZGVzQ2xhc3MsICFjb25mLmd1aWRlcylcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwidHJhbnNsYXRlKFwiICsgKG4gLSBpIC0gMSkgKiBzZWxmLnBsb3Quc2l6ZSArIFwiLDApXCIpXHJcbiAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uKGQpIHsgc2VsZi5wbG90Lnguc2NhbGUuZG9tYWluKHNlbGYucGxvdC5kb21haW5CeVZhcmlhYmxlW2RdKTsgZDMuc2VsZWN0KHRoaXMpLmNhbGwoc2VsZi5wbG90LnguYXhpcyk7IH0pO1xyXG5cclxuICAgICAgICBzZWxmLnN2Z0cuc2VsZWN0QWxsKHlBeGlzU2VsZWN0b3IpXHJcbiAgICAgICAgICAgIC5kYXRhKHNlbGYucGxvdC52YXJpYWJsZXMpXHJcbiAgICAgICAgICAgIC5lbnRlcigpLmFwcGVuZFNlbGVjdG9yKHlBeGlzU2VsZWN0b3IpXHJcbiAgICAgICAgICAgIC5jbGFzc2VkKG5vR3VpZGVzQ2xhc3MsICFjb25mLmd1aWRlcylcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwidHJhbnNsYXRlKDAsXCIgKyBpICogc2VsZi5wbG90LnNpemUgKyBcIilcIilcclxuICAgICAgICAgICAgLmVhY2goZnVuY3Rpb24oZCkgeyBzZWxmLnBsb3QueS5zY2FsZS5kb21haW4oc2VsZi5wbG90LmRvbWFpbkJ5VmFyaWFibGVbZF0pOyBkMy5zZWxlY3QodGhpcykuY2FsbChzZWxmLnBsb3QueS5heGlzKTsgfSk7XHJcblxyXG4gICAgICAgIHZhciBjZWxsQ2xhc3MgPSAgc2VsZi5wcmVmaXhDbGFzcyhcImNlbGxcIik7XHJcbiAgICAgICAgdmFyIGNlbGwgPSBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwiLlwiK2NlbGxDbGFzcylcclxuICAgICAgICAgICAgLmRhdGEoc2VsZi51dGlscy5jcm9zcyhzZWxmLnBsb3QudmFyaWFibGVzLCBzZWxmLnBsb3QudmFyaWFibGVzKSk7XHJcblxyXG4gICAgICAgIGNlbGwuZW50ZXIoKS5hcHBlbmRTZWxlY3RvcihcImcuXCIrY2VsbENsYXNzKS5maWx0ZXIoZCA9PiBkLmkgPT09IGQuailcclxuICAgICAgICAgICAgLmFwcGVuZChcInRleHRcIik7XHJcblxyXG4gICAgICAgIGNlbGwuYXR0cihcInRyYW5zZm9ybVwiLCBkID0+IFwidHJhbnNsYXRlKFwiICsgKG4gLSBkLmkgLSAxKSAqIHNlbGYucGxvdC5zaXplICsgXCIsXCIgKyBkLmogKiBzZWxmLnBsb3Quc2l6ZSArIFwiKVwiKTtcclxuXHJcbiAgICAgICAgaWYoY29uZi5icnVzaCl7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhd0JydXNoKGNlbGwpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY2VsbC5lYWNoKHBsb3RTdWJwbG90KTtcclxuXHJcbiAgICAgICAgLy9MYWJlbHNcclxuICAgICAgICBjZWxsLnNlbGVjdChcInRleHRcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIGNvbmYucGFkZGluZylcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIGNvbmYucGFkZGluZylcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIi43MWVtXCIpXHJcbiAgICAgICAgICAgIC50ZXh0KCBkID0+IHNlbGYucGxvdC5sYWJlbEJ5VmFyaWFibGVbZC54XSk7XHJcblxyXG5cclxuXHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHBsb3RTdWJwbG90KHApIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ3Bsb3RTdWJwbG90Jyk7XHJcbiAgICAgICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgICAgICBwbG90LnN1YnBsb3RzLnB1c2gocCk7XHJcbiAgICAgICAgICAgIHZhciBjZWxsID0gZDMuc2VsZWN0KHRoaXMpO1xyXG5cclxuICAgICAgICAgICAgcGxvdC54LnNjYWxlLmRvbWFpbihwbG90LmRvbWFpbkJ5VmFyaWFibGVbcC54XSk7XHJcbiAgICAgICAgICAgIHBsb3QueS5zY2FsZS5kb21haW4ocGxvdC5kb21haW5CeVZhcmlhYmxlW3AueV0pO1xyXG5cclxuICAgICAgICAgICAgdmFyIGZyYW1lQ2xhc3MgPSAgc2VsZi5wcmVmaXhDbGFzcyhcImZyYW1lXCIpO1xyXG4gICAgICAgICAgICBjZWxsLnNlbGVjdE9yQXBwZW5kKFwicmVjdC5cIitmcmFtZUNsYXNzKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBmcmFtZUNsYXNzKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIGNvbmYucGFkZGluZyAvIDIpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInlcIiwgY29uZi5wYWRkaW5nIC8gMilcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgY29uZi5zaXplIC0gY29uZi5wYWRkaW5nKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgY29uZi5zaXplIC0gY29uZi5wYWRkaW5nKTtcclxuXHJcblxyXG4gICAgICAgICAgICBwLnVwZGF0ZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBzdWJwbG90ID0gdGhpcztcclxuICAgICAgICAgICAgICAgIHZhciBkb3RzID0gY2VsbC5zZWxlY3RBbGwoXCJjaXJjbGVcIilcclxuICAgICAgICAgICAgICAgICAgICAuZGF0YShzZWxmLnBsb3QuZGF0YSk7XHJcblxyXG4gICAgICAgICAgICAgICAgZG90cy5lbnRlcigpLmFwcGVuZChcImNpcmNsZVwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgZG90c1QgPSBkb3RzO1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYudHJhbnNpdGlvbkVuYWJsZWQoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRvdHNUID0gZG90cy50cmFuc2l0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZG90c1QuYXR0cihcImN4XCIsIChkKSA9PiBwbG90LngubWFwKGQsIHN1YnBsb3QueCkpXHJcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoXCJjeVwiLCAoZCkgPT4gcGxvdC55Lm1hcChkLCBzdWJwbG90LnkpKVxyXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKFwiclwiLCBzZWxmLmNvbmZpZy5kb3QucmFkaXVzKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAocGxvdC5kb3QuY29sb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBkb3RzVC5zdHlsZShcImZpbGxcIiwgcGxvdC5kb3QuY29sb3IpXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYocGxvdC50b29sdGlwKXtcclxuICAgICAgICAgICAgICAgICAgICBkb3RzLm9uKFwibW91c2VvdmVyXCIsIChkKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbigyMDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIC45KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGh0bWwgPSBcIihcIiArIHBsb3QueC52YWx1ZShkLCBzdWJwbG90LngpICsgXCIsIFwiICtwbG90LnkudmFsdWUoZCwgc3VicGxvdC55KSArIFwiKVwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAuaHRtbChodG1sKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwibGVmdFwiLCAoZDMuZXZlbnQucGFnZVggKyA1KSArIFwicHhcIilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdHlsZShcInRvcFwiLCAoZDMuZXZlbnQucGFnZVkgLSAyOCkgKyBcInB4XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGdyb3VwID0gc2VsZi5jb25maWcuZ3JvdXBzLnZhbHVlKGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihncm91cCB8fCBncm91cD09PTAgKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwrPVwiPGJyLz5cIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYWJlbCA9IHNlbGYuY29uZmlnLmdyb3Vwcy5sYWJlbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxhYmVsKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sKz1sYWJlbCtcIjogXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sKz1ncm91cFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGh0bWwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJsZWZ0XCIsIChkMy5ldmVudC5wYWdlWCArIDUpICsgXCJweFwiKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwidG9wXCIsIChkMy5ldmVudC5wYWdlWSAtIDI4KSArIFwicHhcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgLm9uKFwibW91c2VvdXRcIiwgKGQpPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbig1MDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZG90cy5leGl0KCkucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHAudXBkYXRlKCk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlTGVnZW5kKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIGRyYXdCcnVzaChjZWxsKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBicnVzaCA9IGQzLnN2Zy5icnVzaCgpXHJcbiAgICAgICAgICAgIC54KHNlbGYucGxvdC54LnNjYWxlKVxyXG4gICAgICAgICAgICAueShzZWxmLnBsb3QueS5zY2FsZSlcclxuICAgICAgICAgICAgLm9uKFwiYnJ1c2hzdGFydFwiLCBicnVzaHN0YXJ0KVxyXG4gICAgICAgICAgICAub24oXCJicnVzaFwiLCBicnVzaG1vdmUpXHJcbiAgICAgICAgICAgIC5vbihcImJydXNoZW5kXCIsIGJydXNoZW5kKTtcclxuXHJcbiAgICAgICAgY2VsbC5hcHBlbmQoXCJnXCIpLmNhbGwoYnJ1c2gpO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIGJydXNoQ2VsbDtcclxuXHJcbiAgICAgICAgLy8gQ2xlYXIgdGhlIHByZXZpb3VzbHktYWN0aXZlIGJydXNoLCBpZiBhbnkuXHJcbiAgICAgICAgZnVuY3Rpb24gYnJ1c2hzdGFydChwKSB7XHJcbiAgICAgICAgICAgIGlmIChicnVzaENlbGwgIT09IHRoaXMpIHtcclxuICAgICAgICAgICAgICAgIGQzLnNlbGVjdChicnVzaENlbGwpLmNhbGwoYnJ1c2guY2xlYXIoKSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnBsb3QueC5zY2FsZS5kb21haW4oc2VsZi5wbG90LmRvbWFpbkJ5VmFyaWFibGVbcC54XSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnBsb3QueS5zY2FsZS5kb21haW4oc2VsZi5wbG90LmRvbWFpbkJ5VmFyaWFibGVbcC55XSk7XHJcbiAgICAgICAgICAgICAgICBicnVzaENlbGwgPSB0aGlzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBIaWdobGlnaHQgdGhlIHNlbGVjdGVkIGNpcmNsZXMuXHJcbiAgICAgICAgZnVuY3Rpb24gYnJ1c2htb3ZlKHApIHtcclxuICAgICAgICAgICAgdmFyIGUgPSBicnVzaC5leHRlbnQoKTtcclxuICAgICAgICAgICAgc2VsZi5zdmdHLnNlbGVjdEFsbChcImNpcmNsZVwiKS5jbGFzc2VkKFwiaGlkZGVuXCIsIGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZVswXVswXSA+IGRbcC54XSB8fCBkW3AueF0gPiBlWzFdWzBdXHJcbiAgICAgICAgICAgICAgICAgICAgfHwgZVswXVsxXSA+IGRbcC55XSB8fCBkW3AueV0gPiBlWzFdWzFdO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gSWYgdGhlIGJydXNoIGlzIGVtcHR5LCBzZWxlY3QgYWxsIGNpcmNsZXMuXHJcbiAgICAgICAgZnVuY3Rpb24gYnJ1c2hlbmQoKSB7XHJcbiAgICAgICAgICAgIGlmIChicnVzaC5lbXB0eSgpKSBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwiLmhpZGRlblwiKS5jbGFzc2VkKFwiaGlkZGVuXCIsIGZhbHNlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHVwZGF0ZUxlZ2VuZCgpIHtcclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPXRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcblxyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3QuZG90LmNvbG9yQ2F0ZWdvcnk7XHJcblxyXG5cclxuXHJcbiAgICAgICAgaWYoIXNjYWxlLmRvbWFpbigpIHx8IHNjYWxlLmRvbWFpbigpLmxlbmd0aDwyKXtcclxuICAgICAgICAgICAgcGxvdC5zaG93TGVnZW5kID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZighcGxvdC5zaG93TGVnZW5kKXtcclxuICAgICAgICAgICAgaWYocGxvdC5sZWdlbmQgJiYgcGxvdC5sZWdlbmQuY29udGFpbmVyKXtcclxuICAgICAgICAgICAgICAgIHBsb3QubGVnZW5kLmNvbnRhaW5lci5yZW1vdmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgdmFyIGxlZ2VuZFggPSB0aGlzLnBsb3Qud2lkdGggKyB0aGlzLmNvbmZpZy5sZWdlbmQubWFyZ2luO1xyXG4gICAgICAgIHZhciBsZWdlbmRZID0gdGhpcy5jb25maWcubGVnZW5kLm1hcmdpbjtcclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmQgPSBuZXcgTGVnZW5kKHRoaXMuc3ZnLCB0aGlzLnN2Z0csIHNjYWxlLCBsZWdlbmRYLCBsZWdlbmRZKTtcclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmRDb2xvciA9IHBsb3QubGVnZW5kLmNvbG9yKClcclxuICAgICAgICAgICAgLnNoYXBlV2lkdGgodGhpcy5jb25maWcubGVnZW5kLnNoYXBlV2lkdGgpXHJcbiAgICAgICAgICAgIC5vcmllbnQoJ3ZlcnRpY2FsJylcclxuICAgICAgICAgICAgLnNjYWxlKHNjYWxlKTtcclxuXHJcblxyXG4gICAgICAgIHBsb3QubGVnZW5kQ29sb3Iub24oJ2NlbGxjbGljaycsIGM9PiBzZWxmLm9uTGVnZW5kQ2VsbENsaWNrKGMpKTtcclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmQuY29udGFpbmVyXHJcbiAgICAgICAgICAgIC5jYWxsKHBsb3QubGVnZW5kQ29sb3IpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uTGVnZW5kQ2VsbENsaWNrKGNlbGxWYWx1ZSl7XHJcbiAgICAgICAgdGhpcy51cGRhdGVFbmFibGVkR3JvdXBzKGNlbGxWYWx1ZSk7XHJcblxyXG4gICAgICAgIHZhciBpc0Rpc2FibGVkID0gdGhpcy5lbmFibGVkR3JvdXBzLmluZGV4T2YoY2VsbFZhbHVlKTwwO1xyXG4gICAgICAgIHRoaXMucGxvdC5sZWdlbmQuY29udGFpbmVyLnNlbGVjdEFsbChcImcuY2VsbFwiKS5lYWNoKGZ1bmN0aW9uKGNlbGwpe1xyXG4gICAgICAgICAgICBpZihjZWxsID09IGNlbGxWYWx1ZSl7XHJcbiAgICAgICAgICAgICAgICBkMy5zZWxlY3QodGhpcykuY2xhc3NlZChcIm9kYy1kaXNhYmxlZFwiLCBpc0Rpc2FibGVkKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5pbml0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlRW5hYmxlZEdyb3VwcyhjZWxsVmFsdWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZW5hYmxlZEdyb3Vwcykge1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMgPSB0aGlzLnBsb3QuZG90LmNvbG9yQ2F0ZWdvcnkuZG9tYWluKCkuc2xpY2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5lbmFibGVkR3JvdXBzLmluZGV4T2YoY2VsbFZhbHVlKTtcclxuXHJcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMucHVzaChjZWxsVmFsdWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZW5hYmxlZEdyb3Vwcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG5cclxuICAgIHNldERhdGEoZGF0YSl7XHJcbiAgICAgICAgc3VwZXIuc2V0RGF0YShkYXRhKTtcclxuICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMgPSBudWxsO1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcbmltcG9ydCB7TGVnZW5kfSBmcm9tIFwiLi9sZWdlbmRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTY2F0dGVyUGxvdENvbmZpZyBleHRlbmRzIENoYXJ0Q29uZmlne1xyXG5cclxuICAgIHN2Z0NsYXNzPSB0aGlzLmNzc0NsYXNzUHJlZml4KydzY2F0dGVycGxvdCc7XHJcbiAgICBndWlkZXM9IGZhbHNlOyAvL3Nob3cgYXhpcyBndWlkZXNcclxuICAgIHNob3dUb29sdGlwPSB0cnVlOyAvL3Nob3cgdG9vbHRpcCBvbiBkb3QgaG92ZXJcclxuICAgIHNob3dMZWdlbmQ9dHJ1ZTtcclxuICAgIGxlZ2VuZD17XHJcbiAgICAgICAgd2lkdGg6IDgwLFxyXG4gICAgICAgIG1hcmdpbjogMTAsXHJcbiAgICAgICAgc2hhcGVXaWR0aDogMjBcclxuICAgIH07XHJcblxyXG4gICAgeD17Ly8gWCBheGlzIGNvbmZpZ1xyXG4gICAgICAgIGxhYmVsOiAnWCcsIC8vIGF4aXMgbGFiZWxcclxuICAgICAgICBrZXk6IDAsXHJcbiAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IGRba2V5XSwgLy8geCB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgICAgIG9yaWVudDogXCJib3R0b21cIixcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIlxyXG4gICAgfTtcclxuICAgIHk9ey8vIFkgYXhpcyBjb25maWdcclxuICAgICAgICBsYWJlbDogJ1knLCAvLyBheGlzIGxhYmVsLFxyXG4gICAgICAgIGtleTogMSxcclxuICAgICAgICB2YWx1ZTogKGQsIGtleSkgPT4gZFtrZXldLCAvLyB5IHZhbHVlIGFjY2Vzc29yXHJcbiAgICAgICAgb3JpZW50OiBcImxlZnRcIixcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIlxyXG4gICAgfTtcclxuICAgIGdyb3Vwcz17XHJcbiAgICAgICAga2V5OiAyLFxyXG4gICAgICAgIHZhbHVlOiAoZCwga2V5KSA9PiBkW2tleV0gLCAvLyBncm91cGluZyB2YWx1ZSBhY2Nlc3NvcixcclxuICAgICAgICBsYWJlbDogXCJcIlxyXG4gICAgfTtcclxuICAgIGRvdCA9IHtcclxuICAgICAgICByYWRpdXM6IDIsXHJcbiAgICAgICAgY29sb3I6IGQgPT4gdGhpcy5ncm91cHMudmFsdWUoZCwgdGhpcy5ncm91cHMua2V5KSwgLy8gc3RyaW5nIG9yIGZ1bmN0aW9uIHJldHVybmluZyBjb2xvcidzIHZhbHVlIGZvciBjb2xvciBzY2FsZVxyXG4gICAgICAgIGQzQ29sb3JDYXRlZ29yeTogJ2NhdGVnb3J5MTAnXHJcbiAgICB9O1xyXG4gICAgdHJhbnNpdGlvbj0gdHJ1ZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pe1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG5cclxuXHJcbiAgICAgICAgaWYoY3VzdG9tKXtcclxuICAgICAgICAgICAgVXRpbHMuZGVlcEV4dGVuZCh0aGlzLCBjdXN0b20pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBTY2F0dGVyUGxvdCBleHRlbmRzIENoYXJ0e1xyXG4gICAgY29uc3RydWN0b3IocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgY29uZmlnKSB7XHJcbiAgICAgICAgc3VwZXIocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgbmV3IFNjYXR0ZXJQbG90Q29uZmlnKGNvbmZpZykpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldENvbmZpZyhjb25maWcpe1xyXG4gICAgICAgIHJldHVybiBzdXBlci5zZXRDb25maWcobmV3IFNjYXR0ZXJQbG90Q29uZmlnKGNvbmZpZykpO1xyXG4gICAgfVxyXG5cclxuICAgIGluaXRQbG90KCl7XHJcbiAgICAgICAgc3VwZXIuaW5pdFBsb3QoKTtcclxuICAgICAgICB2YXIgc2VsZj10aGlzO1xyXG5cclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnO1xyXG5cclxuICAgICAgICB0aGlzLnBsb3QueD17fTtcclxuICAgICAgICB0aGlzLnBsb3QueT17fTtcclxuICAgICAgICB0aGlzLnBsb3QuZG90PXtcclxuICAgICAgICAgICAgY29sb3I6IG51bGwvL2NvbG9yIHNjYWxlIG1hcHBpbmcgZnVuY3Rpb25cclxuICAgICAgICB9O1xyXG5cclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnNob3dMZWdlbmQgPSBjb25mLnNob3dMZWdlbmQ7XHJcbiAgICAgICAgaWYodGhpcy5wbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWFyZ2luLnJpZ2h0ID0gY29uZi5tYXJnaW4ucmlnaHQgKyBjb25mLmxlZ2VuZC53aWR0aCtjb25mLmxlZ2VuZC5tYXJnaW4qMjtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcblxyXG4gICAgICAgIHRoaXMuY29tcHV0ZVBsb3RTaXplKCk7XHJcblxyXG5cclxuICAgICAgICB0aGlzLnNldHVwR3JvdXBzKCk7XHJcblxyXG4gICAgICAgIHRoaXMucGxvdC5kYXRhID0gdGhpcy5nZXREYXRhVG9QbG90KCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cFgoKTtcclxuICAgICAgICB0aGlzLnNldHVwWSgpO1xyXG5cclxuXHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHNldHVwR3JvdXBzKCkge1xyXG4gICAgICAgIHZhciBzZWxmPXRoaXM7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuICAgICAgICB0aGlzLnBsb3QuZ3JvdXBWYWx1ZSA9IGQgPT4gY29uZi5ncm91cHMudmFsdWUoZCwgY29uZi5ncm91cHMua2V5KTtcclxuICAgICAgICBpZihjb25mLmRvdC5kM0NvbG9yQ2F0ZWdvcnkpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuZG90LmNvbG9yQ2F0ZWdvcnkgPSBkMy5zY2FsZVtjb25mLmRvdC5kM0NvbG9yQ2F0ZWdvcnldKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjb2xvclZhbHVlID0gY29uZi5kb3QuY29sb3I7XHJcbiAgICAgICAgaWYoY29sb3JWYWx1ZSl7XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5kb3QuY29sb3JWYWx1ZSA9IGNvbG9yVmFsdWU7XHJcblxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGNvbG9yVmFsdWUgPT09ICdzdHJpbmcnIHx8IGNvbG9yVmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wbG90LmRvdC5jb2xvciA9IGNvbG9yVmFsdWU7XHJcbiAgICAgICAgICAgIH1lbHNlIGlmKHRoaXMucGxvdC5kb3QuY29sb3JDYXRlZ29yeSl7XHJcbiAgICAgICAgICAgICAgICB2YXIgZG9tYWluID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZDMubWFwKHRoaXMuZGF0YSwgZCA9PiBzZWxmLnBsb3QuZG90LmNvbG9yVmFsdWUuY2FsbChzZWxmLGQpKVsnXyddKTtcclxuICAgICAgICAgICAgICAgIHNlbGYucGxvdC5kb3QuY29sb3JDYXRlZ29yeS5kb21haW4oZG9tYWluKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxvdC5kb3QuY29sb3IgPSBkID0+ICBzZWxmLnBsb3QuZG90LmNvbG9yQ2F0ZWdvcnkoc2VsZi5wbG90LmRvdC5jb2xvclZhbHVlLmNhbGwoc2VsZixkKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0RGF0YVRvUGxvdCgpe1xyXG4gICAgICAgIGlmKCF0aGlzLmVuYWJsZWRHcm91cHMpe1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRhO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5maWx0ZXIoZCA9PiB0aGlzLmVuYWJsZWRHcm91cHMuaW5kZXhPZih0aGlzLnBsb3QuZ3JvdXBWYWx1ZShkKSk+LTEpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldHVwWCgpe1xyXG5cclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgeCA9IHBsb3QueDtcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnLng7XHJcblxyXG4gICAgICAgIC8qICpcclxuICAgICAgICAgKiB2YWx1ZSBhY2Nlc3NvciAtIHJldHVybnMgdGhlIHZhbHVlIHRvIGVuY29kZSBmb3IgYSBnaXZlbiBkYXRhIG9iamVjdC5cclxuICAgICAgICAgKiBzY2FsZSAtIG1hcHMgdmFsdWUgdG8gYSB2aXN1YWwgZGlzcGxheSBlbmNvZGluZywgc3VjaCBhcyBhIHBpeGVsIHBvc2l0aW9uLlxyXG4gICAgICAgICAqIG1hcCBmdW5jdGlvbiAtIG1hcHMgZnJvbSBkYXRhIHZhbHVlIHRvIGRpc3BsYXkgdmFsdWVcclxuICAgICAgICAgKiBheGlzIC0gc2V0cyB1cCBheGlzXHJcbiAgICAgICAgICoqL1xyXG4gICAgICAgIHgudmFsdWUgPSBkID0+IGNvbmYudmFsdWUoZCwgY29uZi5rZXkpO1xyXG4gICAgICAgIHguc2NhbGUgPSBkMy5zY2FsZVtjb25mLnNjYWxlXSgpLnJhbmdlKFswLCBwbG90LndpZHRoXSk7XHJcbiAgICAgICAgeC5tYXAgPSBkID0+IHguc2NhbGUoeC52YWx1ZShkKSk7XHJcbiAgICAgICAgeC5heGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh4LnNjYWxlKS5vcmllbnQoY29uZi5vcmllbnQpO1xyXG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5wbG90LmRhdGE7XHJcbiAgICAgICAgcGxvdC54LnNjYWxlLmRvbWFpbihbZDMubWluKGRhdGEsIHBsb3QueC52YWx1ZSktMSwgZDMubWF4KGRhdGEsIHBsb3QueC52YWx1ZSkrMV0pO1xyXG4gICAgICAgIGlmKHRoaXMuY29uZmlnLmd1aWRlcykge1xyXG4gICAgICAgICAgICB4LmF4aXMudGlja1NpemUoLXBsb3QuaGVpZ2h0KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBzZXR1cFkgKCl7XHJcblxyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciB5ID0gcGxvdC55O1xyXG4gICAgICAgIHZhciBjb25mID0gdGhpcy5jb25maWcueTtcclxuXHJcbiAgICAgICAgLypcclxuICAgICAgICAgKiB2YWx1ZSBhY2Nlc3NvciAtIHJldHVybnMgdGhlIHZhbHVlIHRvIGVuY29kZSBmb3IgYSBnaXZlbiBkYXRhIG9iamVjdC5cclxuICAgICAgICAgKiBzY2FsZSAtIG1hcHMgdmFsdWUgdG8gYSB2aXN1YWwgZGlzcGxheSBlbmNvZGluZywgc3VjaCBhcyBhIHBpeGVsIHBvc2l0aW9uLlxyXG4gICAgICAgICAqIG1hcCBmdW5jdGlvbiAtIG1hcHMgZnJvbSBkYXRhIHZhbHVlIHRvIGRpc3BsYXkgdmFsdWVcclxuICAgICAgICAgKiBheGlzIC0gc2V0cyB1cCBheGlzXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgeS52YWx1ZSA9IGQgPT4gY29uZi52YWx1ZShkLCBjb25mLmtleSk7XHJcbiAgICAgICAgeS5zY2FsZSA9IGQzLnNjYWxlW2NvbmYuc2NhbGVdKCkucmFuZ2UoW3Bsb3QuaGVpZ2h0LCAwXSk7XHJcbiAgICAgICAgeS5tYXAgPSBkID0+IHkuc2NhbGUoeS52YWx1ZShkKSk7XHJcbiAgICAgICAgeS5heGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh5LnNjYWxlKS5vcmllbnQoY29uZi5vcmllbnQpO1xyXG5cclxuICAgICAgICBpZih0aGlzLmNvbmZpZy5ndWlkZXMpe1xyXG4gICAgICAgICAgICB5LmF4aXMudGlja1NpemUoLXBsb3Qud2lkdGgpO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5wbG90LmRhdGE7XHJcbiAgICAgICAgcGxvdC55LnNjYWxlLmRvbWFpbihbZDMubWluKGRhdGEsIHBsb3QueS52YWx1ZSktMSwgZDMubWF4KGRhdGEsIHBsb3QueS52YWx1ZSkrMV0pO1xyXG4gICAgfTtcclxuXHJcbiAgICBkcmF3QXhpc1goKXtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGF4aXNDb25mID0gdGhpcy5jb25maWcueDtcclxuICAgICAgICB2YXIgYXhpcyA9IHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcy14JykrXCIuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcycpKyhzZWxmLmNvbmZpZy5ndWlkZXMgPyAnJyA6ICcuJytzZWxmLnByZWZpeENsYXNzKCduby1ndWlkZXMnKSkpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKDAsXCIgKyBwbG90LmhlaWdodCArIFwiKVwiKTtcclxuICAgICAgICBcclxuICAgICAgICB2YXIgYXhpc1QgPSBheGlzO1xyXG4gICAgICAgIGlmIChzZWxmLnRyYW5zaXRpb25FbmFibGVkKCkpIHtcclxuICAgICAgICAgICAgYXhpc1QgPSBheGlzLnRyYW5zaXRpb24oKS5lYXNlKFwic2luLWluLW91dFwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGF4aXNULmNhbGwocGxvdC54LmF4aXMpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGF4aXMuc2VsZWN0T3JBcHBlbmQoXCJ0ZXh0LlwiK3NlbGYucHJlZml4Q2xhc3MoJ2xhYmVsJykpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiKyAocGxvdC53aWR0aC8yKSArXCIsXCIrIChwbG90Lm1hcmdpbi5ib3R0b20pICtcIilcIikgIC8vIHRleHQgaXMgZHJhd24gb2ZmIHRoZSBzY3JlZW4gdG9wIGxlZnQsIG1vdmUgZG93biBhbmQgb3V0IGFuZCByb3RhdGVcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIi0xZW1cIilcclxuICAgICAgICAgICAgLnN0eWxlKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIilcclxuICAgICAgICAgICAgLnRleHQoYXhpc0NvbmYubGFiZWwpO1xyXG4gICAgfTtcclxuXHJcbiAgICBkcmF3QXhpc1koKXtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGF4aXNDb25mID0gdGhpcy5jb25maWcueTtcclxuICAgICAgICB2YXIgYXhpcyA9IHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcy15JykrXCIuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcycpKyhzZWxmLmNvbmZpZy5ndWlkZXMgPyAnJyA6ICcuJytzZWxmLnByZWZpeENsYXNzKCduby1ndWlkZXMnKSkpO1xyXG5cclxuICAgICAgICB2YXIgYXhpc1QgPSBheGlzO1xyXG4gICAgICAgIGlmIChzZWxmLnRyYW5zaXRpb25FbmFibGVkKCkpIHtcclxuICAgICAgICAgICAgYXhpc1QgPSBheGlzLnRyYW5zaXRpb24oKS5lYXNlKFwic2luLWluLW91dFwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGF4aXNULmNhbGwocGxvdC55LmF4aXMpO1xyXG5cclxuICAgICAgICBheGlzLnNlbGVjdE9yQXBwZW5kKFwidGV4dC5cIitzZWxmLnByZWZpeENsYXNzKCdsYWJlbCcpKVxyXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIisgLXBsb3QubWFyZ2luLmxlZnQgK1wiLFwiKyhwbG90LmhlaWdodC8yKStcIilyb3RhdGUoLTkwKVwiKSAgLy8gdGV4dCBpcyBkcmF3biBvZmYgdGhlIHNjcmVlbiB0b3AgbGVmdCwgbW92ZSBkb3duIGFuZCBvdXQgYW5kIHJvdGF0ZVxyXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIFwiMWVtXCIpXHJcbiAgICAgICAgICAgIC5zdHlsZShcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpXHJcbiAgICAgICAgICAgIC50ZXh0KGF4aXNDb25mLmxhYmVsKTtcclxuICAgIH07XHJcblxyXG4gICAgdXBkYXRlKG5ld0RhdGEpe1xyXG4gICAgICAgIHN1cGVyLnVwZGF0ZShuZXdEYXRhKTtcclxuICAgICAgICB0aGlzLmRyYXdBeGlzWCgpO1xyXG4gICAgICAgIHRoaXMuZHJhd0F4aXNZKCk7XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlRG90cygpO1xyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUxlZ2VuZCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICB1cGRhdGVEb3RzKCkge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHNlbGYucGxvdDtcclxuICAgICAgICB2YXIgZGF0YSA9IHBsb3QuZGF0YTtcclxuICAgICAgICB2YXIgZG90Q2xhc3MgPSBzZWxmLnByZWZpeENsYXNzKCdkb3QnKTtcclxuICAgICAgICBzZWxmLmRvdHNDb250YWluZXJDbGFzcyA9IHNlbGYucHJlZml4Q2xhc3MoJ2RvdHMtY29udGFpbmVyJyk7XHJcblxyXG5cclxuICAgICAgICB2YXIgZG90c0NvbnRhaW5lciA9IHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIgKyBzZWxmLmRvdHNDb250YWluZXJDbGFzcyk7XHJcblxyXG4gICAgICAgIHZhciBkb3RzID0gZG90c0NvbnRhaW5lci5zZWxlY3RBbGwoJy4nICsgZG90Q2xhc3MpXHJcbiAgICAgICAgICAgIC5kYXRhKGRhdGEpO1xyXG5cclxuICAgICAgICBkb3RzLmVudGVyKCkuYXBwZW5kKFwiY2lyY2xlXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgZG90Q2xhc3MpO1xyXG5cclxuICAgICAgICB2YXIgZG90c1QgPSBkb3RzO1xyXG4gICAgICAgIGlmIChzZWxmLnRyYW5zaXRpb25FbmFibGVkKCkpIHtcclxuICAgICAgICAgICAgZG90c1QgPSBkb3RzLnRyYW5zaXRpb24oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGRvdHNULmF0dHIoXCJyXCIsIHNlbGYuY29uZmlnLmRvdC5yYWRpdXMpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiY3hcIiwgcGxvdC54Lm1hcClcclxuICAgICAgICAgICAgLmF0dHIoXCJjeVwiLCBwbG90LnkubWFwKTtcclxuXHJcbiAgICAgICAgaWYgKHBsb3QudG9vbHRpcCkge1xyXG4gICAgICAgICAgICBkb3RzLm9uKFwibW91c2VvdmVyXCIsIGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbigyMDApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAuOSk7XHJcbiAgICAgICAgICAgICAgICB2YXIgaHRtbCA9IFwiKFwiICsgcGxvdC54LnZhbHVlKGQpICsgXCIsIFwiICsgcGxvdC55LnZhbHVlKGQpICsgXCIpXCI7XHJcbiAgICAgICAgICAgICAgICB2YXIgZ3JvdXAgPSBzZWxmLmNvbmZpZy5ncm91cHMudmFsdWUoZCwgc2VsZi5jb25maWcuZ3JvdXBzLmtleSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ3JvdXAgfHwgZ3JvdXAgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBodG1sICs9IFwiPGJyLz5cIjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWwgPSBzZWxmLmNvbmZpZy5ncm91cHMubGFiZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gbGFiZWwgKyBcIjogXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gZ3JvdXBcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGh0bWwpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwibGVmdFwiLCAoZDMuZXZlbnQucGFnZVggKyA1KSArIFwicHhcIilcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgKGQzLmV2ZW50LnBhZ2VZIC0gMjgpICsgXCJweFwiKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIC5vbihcIm1vdXNlb3V0XCIsIGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDUwMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBsb3QuZG90LmNvbG9yKSB7XHJcbiAgICAgICAgICAgIGRvdHMuc3R5bGUoXCJmaWxsXCIsIHBsb3QuZG90LmNvbG9yKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZG90cy5leGl0KCkucmVtb3ZlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlTGVnZW5kKCkge1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9dGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuXHJcbiAgICAgICAgdmFyIHNjYWxlID0gcGxvdC5kb3QuY29sb3JDYXRlZ29yeTtcclxuXHJcblxyXG5cclxuICAgICAgICBpZighc2NhbGUuZG9tYWluKCkgfHwgc2NhbGUuZG9tYWluKCkubGVuZ3RoPDIpe1xyXG4gICAgICAgICAgICBwbG90LnNob3dMZWdlbmQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKCFwbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICBpZihwbG90LmxlZ2VuZCAmJiBwbG90LmxlZ2VuZC5jb250YWluZXIpe1xyXG4gICAgICAgICAgICAgICAgcGxvdC5sZWdlbmQuY29udGFpbmVyLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgbGVnZW5kWCA9IHRoaXMucGxvdC53aWR0aCArIHRoaXMuY29uZmlnLmxlZ2VuZC5tYXJnaW47XHJcbiAgICAgICAgdmFyIGxlZ2VuZFkgPSB0aGlzLmNvbmZpZy5sZWdlbmQubWFyZ2luO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZCA9IG5ldyBMZWdlbmQodGhpcy5zdmcsIHRoaXMuc3ZnRywgc2NhbGUsIGxlZ2VuZFgsIGxlZ2VuZFkpO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZENvbG9yID0gcGxvdC5sZWdlbmQuY29sb3IoKVxyXG4gICAgICAgICAgICAuc2hhcGVXaWR0aCh0aGlzLmNvbmZpZy5sZWdlbmQuc2hhcGVXaWR0aClcclxuICAgICAgICAgICAgLm9yaWVudCgndmVydGljYWwnKVxyXG4gICAgICAgICAgICAuc2NhbGUoc2NhbGUpO1xyXG5cclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmRDb2xvci5vbignY2VsbGNsaWNrJywgYz0+IHNlbGYub25MZWdlbmRDZWxsQ2xpY2soYykpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHBsb3QubGVnZW5kLmNvbnRhaW5lclxyXG4gICAgICAgICAgICAuY2FsbChwbG90LmxlZ2VuZENvbG9yKTtcclxuICAgIH1cclxuXHJcbiAgICBvbkxlZ2VuZENlbGxDbGljayhjZWxsVmFsdWUpe1xyXG4gICAgICAgIHRoaXMudXBkYXRlRW5hYmxlZEdyb3VwcyhjZWxsVmFsdWUpO1xyXG5cclxuICAgICAgICB2YXIgaXNEaXNhYmxlZCA9IHRoaXMuZW5hYmxlZEdyb3Vwcy5pbmRleE9mKGNlbGxWYWx1ZSk8MDtcclxuICAgICAgICB0aGlzLnBsb3QubGVnZW5kLmNvbnRhaW5lci5zZWxlY3RBbGwoXCJnLmNlbGxcIikuZWFjaChmdW5jdGlvbihjZWxsKXtcclxuICAgICAgICAgICAgaWYoY2VsbCA9PSBjZWxsVmFsdWUpe1xyXG4gICAgICAgICAgICAgICAgZDMuc2VsZWN0KHRoaXMpLmNsYXNzZWQoXCJvZGMtZGlzYWJsZWRcIiwgaXNEaXNhYmxlZCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuaW5pdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUVuYWJsZWRHcm91cHMoY2VsbFZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVuYWJsZWRHcm91cHMpIHtcclxuICAgICAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzID0gdGhpcy5wbG90LmRvdC5jb2xvckNhdGVnb3J5LmRvbWFpbigpLnNsaWNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBpbmRleCA9IHRoaXMuZW5hYmxlZEdyb3Vwcy5pbmRleE9mKGNlbGxWYWx1ZSk7XHJcblxyXG4gICAgICAgIGlmIChpbmRleCA8IDApIHtcclxuICAgICAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzLnB1c2goY2VsbFZhbHVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxuXHJcbiAgICBzZXREYXRhKGRhdGEpe1xyXG4gICAgICAgIHN1cGVyLnNldERhdGEoZGF0YSk7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzID0gbnVsbDtcclxuICAgIH1cclxufVxyXG4iLCIvKlxuICogaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vYmVucmFzbXVzZW4vMTI2MTk3N1xuICogTkFNRVxuICogXG4gKiBzdGF0aXN0aWNzLWRpc3RyaWJ1dGlvbnMuanMgLSBKYXZhU2NyaXB0IGxpYnJhcnkgZm9yIGNhbGN1bGF0aW5nXG4gKiAgIGNyaXRpY2FsIHZhbHVlcyBhbmQgdXBwZXIgcHJvYmFiaWxpdGllcyBvZiBjb21tb24gc3RhdGlzdGljYWxcbiAqICAgZGlzdHJpYnV0aW9uc1xuICogXG4gKiBTWU5PUFNJU1xuICogXG4gKiBcbiAqICAgLy8gQ2hpLXNxdWFyZWQtY3JpdCAoMiBkZWdyZWVzIG9mIGZyZWVkb20sIDk1dGggcGVyY2VudGlsZSA9IDAuMDUgbGV2ZWxcbiAqICAgY2hpc3FyZGlzdHIoMiwgLjA1KVxuICogICBcbiAqICAgLy8gdS1jcml0ICg5NXRoIHBlcmNlbnRpbGUgPSAwLjA1IGxldmVsKVxuICogICB1ZGlzdHIoLjA1KTtcbiAqICAgXG4gKiAgIC8vIHQtY3JpdCAoMSBkZWdyZWUgb2YgZnJlZWRvbSwgOTkuNXRoIHBlcmNlbnRpbGUgPSAwLjAwNSBsZXZlbCkgXG4gKiAgIHRkaXN0cigxLC4wMDUpO1xuICogICBcbiAqICAgLy8gRi1jcml0ICgxIGRlZ3JlZSBvZiBmcmVlZG9tIGluIG51bWVyYXRvciwgMyBkZWdyZWVzIG9mIGZyZWVkb20gXG4gKiAgIC8vICAgICAgICAgaW4gZGVub21pbmF0b3IsIDk5dGggcGVyY2VudGlsZSA9IDAuMDEgbGV2ZWwpXG4gKiAgIGZkaXN0cigxLDMsLjAxKTtcbiAqICAgXG4gKiAgIC8vIHVwcGVyIHByb2JhYmlsaXR5IG9mIHRoZSB1IGRpc3RyaWJ1dGlvbiAodSA9IC0wLjg1KTogUSh1KSA9IDEtRyh1KVxuICogICB1cHJvYigtMC44NSk7XG4gKiAgIFxuICogICAvLyB1cHBlciBwcm9iYWJpbGl0eSBvZiB0aGUgY2hpLXNxdWFyZSBkaXN0cmlidXRpb25cbiAqICAgLy8gKDMgZGVncmVlcyBvZiBmcmVlZG9tLCBjaGktc3F1YXJlZCA9IDYuMjUpOiBRID0gMS1HXG4gKiAgIGNoaXNxcnByb2IoMyw2LjI1KTtcbiAqICAgXG4gKiAgIC8vIHVwcGVyIHByb2JhYmlsaXR5IG9mIHRoZSB0IGRpc3RyaWJ1dGlvblxuICogICAvLyAoMyBkZWdyZWVzIG9mIGZyZWVkb20sIHQgPSA2LjI1MSk6IFEgPSAxLUdcbiAqICAgdHByb2IoMyw2LjI1MSk7XG4gKiAgIFxuICogICAvLyB1cHBlciBwcm9iYWJpbGl0eSBvZiB0aGUgRiBkaXN0cmlidXRpb25cbiAqICAgLy8gKDMgZGVncmVlcyBvZiBmcmVlZG9tIGluIG51bWVyYXRvciwgNSBkZWdyZWVzIG9mIGZyZWVkb20gaW5cbiAqICAgLy8gIGRlbm9taW5hdG9yLCBGID0gNi4yNSk6IFEgPSAxLUdcbiAqICAgZnByb2IoMyw1LC42MjUpO1xuICogXG4gKiBcbiAqICBERVNDUklQVElPTlxuICogXG4gKiBUaGlzIGxpYnJhcnkgY2FsY3VsYXRlcyBwZXJjZW50YWdlIHBvaW50cyAoNSBzaWduaWZpY2FudCBkaWdpdHMpIG9mIHRoZSB1XG4gKiAoc3RhbmRhcmQgbm9ybWFsKSBkaXN0cmlidXRpb24sIHRoZSBzdHVkZW50J3MgdCBkaXN0cmlidXRpb24sIHRoZVxuICogY2hpLXNxdWFyZSBkaXN0cmlidXRpb24gYW5kIHRoZSBGIGRpc3RyaWJ1dGlvbi4gSXQgY2FuIGFsc28gY2FsY3VsYXRlIHRoZVxuICogdXBwZXIgcHJvYmFiaWxpdHkgKDUgc2lnbmlmaWNhbnQgZGlnaXRzKSBvZiB0aGUgdSAoc3RhbmRhcmQgbm9ybWFsKSwgdGhlXG4gKiBjaGktc3F1YXJlLCB0aGUgdCBhbmQgdGhlIEYgZGlzdHJpYnV0aW9uLlxuICogXG4gKiBUaGVzZSBjcml0aWNhbCB2YWx1ZXMgYXJlIG5lZWRlZCB0byBwZXJmb3JtIHN0YXRpc3RpY2FsIHRlc3RzLCBsaWtlIHRoZSB1XG4gKiB0ZXN0LCB0aGUgdCB0ZXN0LCB0aGUgRiB0ZXN0IGFuZCB0aGUgY2hpLXNxdWFyZWQgdGVzdCwgYW5kIHRvIGNhbGN1bGF0ZVxuICogY29uZmlkZW5jZSBpbnRlcnZhbHMuXG4gKiBcbiAqIElmIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBtb3JlIHByZWNpc2UgYWxnb3JpdGhtcyB5b3UgY291bGQgbG9vayBhdDpcbiAqICAgU3RhdExpYjogaHR0cDovL2xpYi5zdGF0LmNtdS5lZHUvYXBzdGF0LyA7IFxuICogICBBcHBsaWVkIFN0YXRpc3RpY3MgQWxnb3JpdGhtcyBieSBHcmlmZml0aHMsIFAuIGFuZCBIaWxsLCBJLkQuXG4gKiAgICwgRWxsaXMgSG9yd29vZDogQ2hpY2hlc3RlciAoMTk4NSlcbiAqIFxuICogQlVHUyBcbiAqIFxuICogVGhpcyBwb3J0IHdhcyBwcm9kdWNlZCBmcm9tIHRoZSBQZXJsIG1vZHVsZSBTdGF0aXN0aWNzOjpEaXN0cmlidXRpb25zXG4gKiB0aGF0IGhhcyBoYWQgbm8gYnVnIHJlcG9ydHMgaW4gc2V2ZXJhbCB5ZWFycy4gIElmIHlvdSBmaW5kIGEgYnVnIHRoZW5cbiAqIHBsZWFzZSBkb3VibGUtY2hlY2sgdGhhdCBKYXZhU2NyaXB0IGRvZXMgbm90IHRoaW5nIHRoZSBudW1iZXJzIHlvdSBhcmVcbiAqIHBhc3NpbmcgaW4gYXJlIHN0cmluZ3MuICAoWW91IGNhbiBzdWJ0cmFjdCAwIGZyb20gdGhlbSBhcyB5b3UgcGFzcyB0aGVtXG4gKiBpbiBzbyB0aGF0IFwiNVwiIGlzIHByb3Blcmx5IHVuZGVyc3Rvb2QgdG8gYmUgNS4pICBJZiB5b3UgaGF2ZSBwYXNzZWQgaW4gYVxuICogbnVtYmVyIHRoZW4gcGxlYXNlIGNvbnRhY3QgdGhlIGF1dGhvclxuICogXG4gKiBBVVRIT1JcbiAqIFxuICogQmVuIFRpbGx5IDxidGlsbHlAZ21haWwuY29tPlxuICogXG4gKiBPcmlnaW5sIFBlcmwgdmVyc2lvbiBieSBNaWNoYWVsIEtvc3BhY2ggPG1pa2UucGVybEBnbXguYXQ+XG4gKiBcbiAqIE5pY2UgZm9ybWF0aW5nLCBzaW1wbGlmaWNhdGlvbiBhbmQgYnVnIHJlcGFpciBieSBNYXR0aGlhcyBUcmF1dG5lciBLcm9tYW5uXG4gKiA8bXRrQGlkLmNicy5kaz5cbiAqIFxuICogQ09QWVJJR0hUIFxuICogXG4gKiBDb3B5cmlnaHQgMjAwOCBCZW4gVGlsbHkuXG4gKiBcbiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0XG4gKiB1bmRlciB0aGUgc2FtZSB0ZXJtcyBhcyBQZXJsIGl0c2VsZi4gIFRoaXMgbWVhbnMgdW5kZXIgZWl0aGVyIHRoZSBQZXJsXG4gKiBBcnRpc3RpYyBMaWNlbnNlIG9yIHRoZSBHUEwgdjEgb3IgbGF0ZXIuXG4gKi9cblxudmFyIFNJR05JRklDQU5UID0gNTsgLy8gbnVtYmVyIG9mIHNpZ25pZmljYW50IGRpZ2l0cyB0byBiZSByZXR1cm5lZFxuXG5mdW5jdGlvbiBjaGlzcXJkaXN0ciAoJG4sICRwKSB7XG5cdGlmICgkbiA8PSAwIHx8IE1hdGguYWJzKCRuKSAtIE1hdGguYWJzKGludGVnZXIoJG4pKSAhPSAwKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIG46ICRuXFxuXCIpOyAvKiBkZWdyZWUgb2YgZnJlZWRvbSAqL1xuXHR9XG5cdGlmICgkcCA8PSAwIHx8ICRwID4gMSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBwOiAkcFxcblwiKTsgXG5cdH1cblx0cmV0dXJuIHByZWNpc2lvbl9zdHJpbmcoX3N1YmNoaXNxcigkbi0wLCAkcC0wKSk7XG59XG5cbmZ1bmN0aW9uIHVkaXN0ciAoJHApIHtcblx0aWYgKCRwID4gMSB8fCAkcCA8PSAwKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIHA6ICRwXFxuXCIpO1xuXHR9XG5cdHJldHVybiBwcmVjaXNpb25fc3RyaW5nKF9zdWJ1KCRwLTApKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRkaXN0ciAoJG4sICRwKSB7XG5cdGlmICgkbiA8PSAwIHx8IE1hdGguYWJzKCRuKSAtIE1hdGguYWJzKGludGVnZXIoJG4pKSAhPSAwKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIG46ICRuXFxuXCIpO1xuXHR9XG5cdGlmICgkcCA8PSAwIHx8ICRwID49IDEpIHtcblx0XHR0aHJvdyhcIkludmFsaWQgcDogJHBcXG5cIik7XG5cdH1cblx0cmV0dXJuIHByZWNpc2lvbl9zdHJpbmcoX3N1YnQoJG4tMCwgJHAtMCkpO1xufVxuXG5mdW5jdGlvbiBmZGlzdHIgKCRuLCAkbSwgJHApIHtcblx0aWYgKCgkbjw9MCkgfHwgKChNYXRoLmFicygkbiktKE1hdGguYWJzKGludGVnZXIoJG4pKSkpIT0wKSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBuOiAkblxcblwiKTsgLyogZmlyc3QgZGVncmVlIG9mIGZyZWVkb20gKi9cblx0fVxuXHRpZiAoKCRtPD0wKSB8fCAoKE1hdGguYWJzKCRtKS0oTWF0aC5hYnMoaW50ZWdlcigkbSkpKSkhPTApKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIG06ICRtXFxuXCIpOyAvKiBzZWNvbmQgZGVncmVlIG9mIGZyZWVkb20gKi9cblx0fVxuXHRpZiAoKCRwPD0wKSB8fCAoJHA+MSkpIHtcblx0XHR0aHJvdyhcIkludmFsaWQgcDogJHBcXG5cIik7XG5cdH1cblx0cmV0dXJuIHByZWNpc2lvbl9zdHJpbmcoX3N1YmYoJG4tMCwgJG0tMCwgJHAtMCkpO1xufVxuXG5mdW5jdGlvbiB1cHJvYiAoJHgpIHtcblx0cmV0dXJuIHByZWNpc2lvbl9zdHJpbmcoX3N1YnVwcm9iKCR4LTApKTtcbn1cblxuZnVuY3Rpb24gY2hpc3FycHJvYiAoJG4sJHgpIHtcblx0aWYgKCgkbiA8PSAwKSB8fCAoKE1hdGguYWJzKCRuKSAtIChNYXRoLmFicyhpbnRlZ2VyKCRuKSkpKSAhPSAwKSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBuOiAkblxcblwiKTsgLyogZGVncmVlIG9mIGZyZWVkb20gKi9cblx0fVxuXHRyZXR1cm4gcHJlY2lzaW9uX3N0cmluZyhfc3ViY2hpc3FycHJvYigkbi0wLCAkeC0wKSk7XG59XG5cbmZ1bmN0aW9uIHRwcm9iICgkbiwgJHgpIHtcblx0aWYgKCgkbiA8PSAwKSB8fCAoKE1hdGguYWJzKCRuKSAtIE1hdGguYWJzKGludGVnZXIoJG4pKSkgIT0wKSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBuOiAkblxcblwiKTsgLyogZGVncmVlIG9mIGZyZWVkb20gKi9cblx0fVxuXHRyZXR1cm4gcHJlY2lzaW9uX3N0cmluZyhfc3VidHByb2IoJG4tMCwgJHgtMCkpO1xufVxuXG5mdW5jdGlvbiBmcHJvYiAoJG4sICRtLCAkeCkge1xuXHRpZiAoKCRuPD0wKSB8fCAoKE1hdGguYWJzKCRuKS0oTWF0aC5hYnMoaW50ZWdlcigkbikpKSkhPTApKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIG46ICRuXFxuXCIpOyAvKiBmaXJzdCBkZWdyZWUgb2YgZnJlZWRvbSAqL1xuXHR9XG5cdGlmICgoJG08PTApIHx8ICgoTWF0aC5hYnMoJG0pLShNYXRoLmFicyhpbnRlZ2VyKCRtKSkpKSE9MCkpIHtcblx0XHR0aHJvdyhcIkludmFsaWQgbTogJG1cXG5cIik7IC8qIHNlY29uZCBkZWdyZWUgb2YgZnJlZWRvbSAqL1xuXHR9IFxuXHRyZXR1cm4gcHJlY2lzaW9uX3N0cmluZyhfc3ViZnByb2IoJG4tMCwgJG0tMCwgJHgtMCkpO1xufVxuXG5cbmZ1bmN0aW9uIF9zdWJmcHJvYiAoJG4sICRtLCAkeCkge1xuXHR2YXIgJHA7XG5cblx0aWYgKCR4PD0wKSB7XG5cdFx0JHA9MTtcblx0fSBlbHNlIGlmICgkbSAlIDIgPT0gMCkge1xuXHRcdHZhciAkeiA9ICRtIC8gKCRtICsgJG4gKiAkeCk7XG5cdFx0dmFyICRhID0gMTtcblx0XHRmb3IgKHZhciAkaSA9ICRtIC0gMjsgJGkgPj0gMjsgJGkgLT0gMikge1xuXHRcdFx0JGEgPSAxICsgKCRuICsgJGkgLSAyKSAvICRpICogJHogKiAkYTtcblx0XHR9XG5cdFx0JHAgPSAxIC0gTWF0aC5wb3coKDEgLSAkeiksICgkbiAvIDIpICogJGEpO1xuXHR9IGVsc2UgaWYgKCRuICUgMiA9PSAwKSB7XG5cdFx0dmFyICR6ID0gJG4gKiAkeCAvICgkbSArICRuICogJHgpO1xuXHRcdHZhciAkYSA9IDE7XG5cdFx0Zm9yICh2YXIgJGkgPSAkbiAtIDI7ICRpID49IDI7ICRpIC09IDIpIHtcblx0XHRcdCRhID0gMSArICgkbSArICRpIC0gMikgLyAkaSAqICR6ICogJGE7XG5cdFx0fVxuXHRcdCRwID0gTWF0aC5wb3coKDEgLSAkeiksICgkbSAvIDIpKSAqICRhO1xuXHR9IGVsc2Uge1xuXHRcdHZhciAkeSA9IE1hdGguYXRhbjIoTWF0aC5zcXJ0KCRuICogJHggLyAkbSksIDEpO1xuXHRcdHZhciAkeiA9IE1hdGgucG93KE1hdGguc2luKCR5KSwgMik7XG5cdFx0dmFyICRhID0gKCRuID09IDEpID8gMCA6IDE7XG5cdFx0Zm9yICh2YXIgJGkgPSAkbiAtIDI7ICRpID49IDM7ICRpIC09IDIpIHtcblx0XHRcdCRhID0gMSArICgkbSArICRpIC0gMikgLyAkaSAqICR6ICogJGE7XG5cdFx0fSBcblx0XHR2YXIgJGIgPSBNYXRoLlBJO1xuXHRcdGZvciAodmFyICRpID0gMjsgJGkgPD0gJG0gLSAxOyAkaSArPSAyKSB7XG5cdFx0XHQkYiAqPSAoJGkgLSAxKSAvICRpO1xuXHRcdH1cblx0XHR2YXIgJHAxID0gMiAvICRiICogTWF0aC5zaW4oJHkpICogTWF0aC5wb3coTWF0aC5jb3MoJHkpLCAkbSkgKiAkYTtcblxuXHRcdCR6ID0gTWF0aC5wb3coTWF0aC5jb3MoJHkpLCAyKTtcblx0XHQkYSA9ICgkbSA9PSAxKSA/IDAgOiAxO1xuXHRcdGZvciAodmFyICRpID0gJG0tMjsgJGkgPj0gMzsgJGkgLT0gMikge1xuXHRcdFx0JGEgPSAxICsgKCRpIC0gMSkgLyAkaSAqICR6ICogJGE7XG5cdFx0fVxuXHRcdCRwID0gbWF4KDAsICRwMSArIDEgLSAyICogJHkgLyBNYXRoLlBJXG5cdFx0XHQtIDIgLyBNYXRoLlBJICogTWF0aC5zaW4oJHkpICogTWF0aC5jb3MoJHkpICogJGEpO1xuXHR9XG5cdHJldHVybiAkcDtcbn1cblxuXG5mdW5jdGlvbiBfc3ViY2hpc3FycHJvYiAoJG4sJHgpIHtcblx0dmFyICRwO1xuXG5cdGlmICgkeCA8PSAwKSB7XG5cdFx0JHAgPSAxO1xuXHR9IGVsc2UgaWYgKCRuID4gMTAwKSB7XG5cdFx0JHAgPSBfc3VidXByb2IoKE1hdGgucG93KCgkeCAvICRuKSwgMS8zKVxuXHRcdFx0XHQtICgxIC0gMi85LyRuKSkgLyBNYXRoLnNxcnQoMi85LyRuKSk7XG5cdH0gZWxzZSBpZiAoJHggPiA0MDApIHtcblx0XHQkcCA9IDA7XG5cdH0gZWxzZSB7ICAgXG5cdFx0dmFyICRhO1xuICAgICAgICAgICAgICAgIHZhciAkaTtcbiAgICAgICAgICAgICAgICB2YXIgJGkxO1xuXHRcdGlmICgoJG4gJSAyKSAhPSAwKSB7XG5cdFx0XHQkcCA9IDIgKiBfc3VidXByb2IoTWF0aC5zcXJ0KCR4KSk7XG5cdFx0XHQkYSA9IE1hdGguc3FydCgyL01hdGguUEkpICogTWF0aC5leHAoLSR4LzIpIC8gTWF0aC5zcXJ0KCR4KTtcblx0XHRcdCRpMSA9IDE7XG5cdFx0fSBlbHNlIHtcblx0XHRcdCRwID0gJGEgPSBNYXRoLmV4cCgtJHgvMik7XG5cdFx0XHQkaTEgPSAyO1xuXHRcdH1cblxuXHRcdGZvciAoJGkgPSAkaTE7ICRpIDw9ICgkbi0yKTsgJGkgKz0gMikge1xuXHRcdFx0JGEgKj0gJHggLyAkaTtcblx0XHRcdCRwICs9ICRhO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gJHA7XG59XG5cbmZ1bmN0aW9uIF9zdWJ1ICgkcCkge1xuXHR2YXIgJHkgPSAtTWF0aC5sb2coNCAqICRwICogKDEgLSAkcCkpO1xuXHR2YXIgJHggPSBNYXRoLnNxcnQoXG5cdFx0JHkgKiAoMS41NzA3OTYyODhcblx0XHQgICsgJHkgKiAoLjAzNzA2OTg3OTA2XG5cdFx0ICBcdCsgJHkgKiAoLS44MzY0MzUzNTg5RS0zXG5cdFx0XHQgICsgJHkgKigtLjIyNTA5NDcxNzZFLTNcblx0XHRcdCAgXHQrICR5ICogKC42ODQxMjE4Mjk5RS01XG5cdFx0XHRcdCAgKyAkeSAqICgwLjU4MjQyMzg1MTVFLTVcblx0XHRcdFx0XHQrICR5ICogKC0uMTA0NTI3NDk3RS01XG5cdFx0XHRcdFx0ICArICR5ICogKC44MzYwOTM3MDE3RS03XG5cdFx0XHRcdFx0XHQrICR5ICogKC0uMzIzMTA4MTI3N0UtOFxuXHRcdFx0XHRcdFx0ICArICR5ICogKC4zNjU3NzYzMDM2RS0xMFxuXHRcdFx0XHRcdFx0XHQrICR5ICouNjkzNjIzMzk4MkUtMTIpKSkpKSkpKSkpKTtcblx0aWYgKCRwPi41KVxuICAgICAgICAgICAgICAgICR4ID0gLSR4O1xuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIF9zdWJ1cHJvYiAoJHgpIHtcblx0dmFyICRwID0gMDsgLyogaWYgKCRhYnN4ID4gMTAwKSAqL1xuXHR2YXIgJGFic3ggPSBNYXRoLmFicygkeCk7XG5cblx0aWYgKCRhYnN4IDwgMS45KSB7XG5cdFx0JHAgPSBNYXRoLnBvdygoMSArXG5cdFx0XHQkYWJzeCAqICguMDQ5ODY3MzQ3XG5cdFx0XHQgICsgJGFic3ggKiAoLjAyMTE0MTAwNjFcblx0XHRcdCAgXHQrICRhYnN4ICogKC4wMDMyNzc2MjYzXG5cdFx0XHRcdCAgKyAkYWJzeCAqICguMDAwMDM4MDAzNlxuXHRcdFx0XHRcdCsgJGFic3ggKiAoLjAwMDA0ODg5MDZcblx0XHRcdFx0XHQgICsgJGFic3ggKiAuMDAwMDA1MzgzKSkpKSkpLCAtMTYpLzI7XG5cdH0gZWxzZSBpZiAoJGFic3ggPD0gMTAwKSB7XG5cdFx0Zm9yICh2YXIgJGkgPSAxODsgJGkgPj0gMTsgJGktLSkge1xuXHRcdFx0JHAgPSAkaSAvICgkYWJzeCArICRwKTtcblx0XHR9XG5cdFx0JHAgPSBNYXRoLmV4cCgtLjUgKiAkYWJzeCAqICRhYnN4KSBcblx0XHRcdC8gTWF0aC5zcXJ0KDIgKiBNYXRoLlBJKSAvICgkYWJzeCArICRwKTtcblx0fVxuXG5cdGlmICgkeDwwKVxuICAgICAgICBcdCRwID0gMSAtICRwO1xuXHRyZXR1cm4gJHA7XG59XG5cbiAgIFxuZnVuY3Rpb24gX3N1YnQgKCRuLCAkcCkge1xuXG5cdGlmICgkcCA+PSAxIHx8ICRwIDw9IDApIHtcblx0XHR0aHJvdyhcIkludmFsaWQgcDogJHBcXG5cIik7XG5cdH1cblxuXHRpZiAoJHAgPT0gMC41KSB7XG5cdFx0cmV0dXJuIDA7XG5cdH0gZWxzZSBpZiAoJHAgPCAwLjUpIHtcblx0XHRyZXR1cm4gLSBfc3VidCgkbiwgMSAtICRwKTtcblx0fVxuXG5cdHZhciAkdSA9IF9zdWJ1KCRwKTtcblx0dmFyICR1MiA9IE1hdGgucG93KCR1LCAyKTtcblxuXHR2YXIgJGEgPSAoJHUyICsgMSkgLyA0O1xuXHR2YXIgJGIgPSAoKDUgKiAkdTIgKyAxNikgKiAkdTIgKyAzKSAvIDk2O1xuXHR2YXIgJGMgPSAoKCgzICogJHUyICsgMTkpICogJHUyICsgMTcpICogJHUyIC0gMTUpIC8gMzg0O1xuXHR2YXIgJGQgPSAoKCgoNzkgKiAkdTIgKyA3NzYpICogJHUyICsgMTQ4MikgKiAkdTIgLSAxOTIwKSAqICR1MiAtIDk0NSkgXG5cdFx0XHRcdC8gOTIxNjA7XG5cdHZhciAkZSA9ICgoKCgoMjcgKiAkdTIgKyAzMzkpICogJHUyICsgOTMwKSAqICR1MiAtIDE3ODIpICogJHUyIC0gNzY1KSAqICR1MlxuXHRcdFx0KyAxNzk1NSkgLyAzNjg2NDA7XG5cblx0dmFyICR4ID0gJHUgKiAoMSArICgkYSArICgkYiArICgkYyArICgkZCArICRlIC8gJG4pIC8gJG4pIC8gJG4pIC8gJG4pIC8gJG4pO1xuXG5cdGlmICgkbiA8PSBNYXRoLnBvdyhsb2cxMCgkcCksIDIpICsgMykge1xuXHRcdHZhciAkcm91bmQ7XG5cdFx0ZG8geyBcblx0XHRcdHZhciAkcDEgPSBfc3VidHByb2IoJG4sICR4KTtcblx0XHRcdHZhciAkbjEgPSAkbiArIDE7XG5cdFx0XHR2YXIgJGRlbHRhID0gKCRwMSAtICRwKSBcblx0XHRcdFx0LyBNYXRoLmV4cCgoJG4xICogTWF0aC5sb2coJG4xIC8gKCRuICsgJHggKiAkeCkpIFxuXHRcdFx0XHRcdCsgTWF0aC5sb2coJG4vJG4xLzIvTWF0aC5QSSkgLSAxIFxuXHRcdFx0XHRcdCsgKDEvJG4xIC0gMS8kbikgLyA2KSAvIDIpO1xuXHRcdFx0JHggKz0gJGRlbHRhO1xuXHRcdFx0JHJvdW5kID0gcm91bmRfdG9fcHJlY2lzaW9uKCRkZWx0YSwgTWF0aC5hYnMoaW50ZWdlcihsb2cxMChNYXRoLmFicygkeCkpLTQpKSk7XG5cdFx0fSB3aGlsZSAoKCR4KSAmJiAoJHJvdW5kICE9IDApKTtcblx0fVxuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIF9zdWJ0cHJvYiAoJG4sICR4KSB7XG5cblx0dmFyICRhO1xuICAgICAgICB2YXIgJGI7XG5cdHZhciAkdyA9IE1hdGguYXRhbjIoJHggLyBNYXRoLnNxcnQoJG4pLCAxKTtcblx0dmFyICR6ID0gTWF0aC5wb3coTWF0aC5jb3MoJHcpLCAyKTtcblx0dmFyICR5ID0gMTtcblxuXHRmb3IgKHZhciAkaSA9ICRuLTI7ICRpID49IDI7ICRpIC09IDIpIHtcblx0XHQkeSA9IDEgKyAoJGktMSkgLyAkaSAqICR6ICogJHk7XG5cdH0gXG5cblx0aWYgKCRuICUgMiA9PSAwKSB7XG5cdFx0JGEgPSBNYXRoLnNpbigkdykvMjtcblx0XHQkYiA9IC41O1xuXHR9IGVsc2Uge1xuXHRcdCRhID0gKCRuID09IDEpID8gMCA6IE1hdGguc2luKCR3KSpNYXRoLmNvcygkdykvTWF0aC5QSTtcblx0XHQkYj0gLjUgKyAkdy9NYXRoLlBJO1xuXHR9XG5cdHJldHVybiBtYXgoMCwgMSAtICRiIC0gJGEgKiAkeSk7XG59XG5cbmZ1bmN0aW9uIF9zdWJmICgkbiwgJG0sICRwKSB7XG5cdHZhciAkeDtcblxuXHRpZiAoJHAgPj0gMSB8fCAkcCA8PSAwKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIHA6ICRwXFxuXCIpO1xuXHR9XG5cblx0aWYgKCRwID09IDEpIHtcblx0XHQkeCA9IDA7XG5cdH0gZWxzZSBpZiAoJG0gPT0gMSkge1xuXHRcdCR4ID0gMSAvIE1hdGgucG93KF9zdWJ0KCRuLCAwLjUgLSAkcCAvIDIpLCAyKTtcblx0fSBlbHNlIGlmICgkbiA9PSAxKSB7XG5cdFx0JHggPSBNYXRoLnBvdyhfc3VidCgkbSwgJHAvMiksIDIpO1xuXHR9IGVsc2UgaWYgKCRtID09IDIpIHtcblx0XHR2YXIgJHUgPSBfc3ViY2hpc3FyKCRtLCAxIC0gJHApO1xuXHRcdHZhciAkYSA9ICRtIC0gMjtcblx0XHQkeCA9IDEgLyAoJHUgLyAkbSAqICgxICtcblx0XHRcdCgoJHUgLSAkYSkgLyAyICtcblx0XHRcdFx0KCgoNCAqICR1IC0gMTEgKiAkYSkgKiAkdSArICRhICogKDcgKiAkbSAtIDEwKSkgLyAyNCArXG5cdFx0XHRcdFx0KCgoMiAqICR1IC0gMTAgKiAkYSkgKiAkdSArICRhICogKDE3ICogJG0gLSAyNikpICogJHVcblx0XHRcdFx0XHRcdC0gJGEgKiAkYSAqICg5ICogJG0gLSA2KVxuXHRcdFx0XHRcdCkvNDgvJG5cblx0XHRcdFx0KS8kblxuXHRcdFx0KS8kbikpO1xuXHR9IGVsc2UgaWYgKCRuID4gJG0pIHtcblx0XHQkeCA9IDEgLyBfc3ViZjIoJG0sICRuLCAxIC0gJHApXG5cdH0gZWxzZSB7XG5cdFx0JHggPSBfc3ViZjIoJG4sICRtLCAkcClcblx0fVxuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIF9zdWJmMiAoJG4sICRtLCAkcCkge1xuXHR2YXIgJHUgPSBfc3ViY2hpc3FyKCRuLCAkcCk7XG5cdHZhciAkbjIgPSAkbiAtIDI7XG5cdHZhciAkeCA9ICR1IC8gJG4gKiBcblx0XHQoMSArIFxuXHRcdFx0KCgkdSAtICRuMikgLyAyICsgXG5cdFx0XHRcdCgoKDQgKiAkdSAtIDExICogJG4yKSAqICR1ICsgJG4yICogKDcgKiAkbiAtIDEwKSkgLyAyNCArIFxuXHRcdFx0XHRcdCgoKDIgKiAkdSAtIDEwICogJG4yKSAqICR1ICsgJG4yICogKDE3ICogJG4gLSAyNikpICogJHUgXG5cdFx0XHRcdFx0XHQtICRuMiAqICRuMiAqICg5ICogJG4gLSA2KSkgLyA0OCAvICRtKSAvICRtKSAvICRtKTtcblx0dmFyICRkZWx0YTtcblx0ZG8ge1xuXHRcdHZhciAkeiA9IE1hdGguZXhwKFxuXHRcdFx0KCgkbiskbSkgKiBNYXRoLmxvZygoJG4rJG0pIC8gKCRuICogJHggKyAkbSkpIFxuXHRcdFx0XHQrICgkbiAtIDIpICogTWF0aC5sb2coJHgpXG5cdFx0XHRcdCsgTWF0aC5sb2coJG4gKiAkbSAvICgkbiskbSkpXG5cdFx0XHRcdC0gTWF0aC5sb2coNCAqIE1hdGguUEkpXG5cdFx0XHRcdC0gKDEvJG4gICsgMS8kbSAtIDEvKCRuKyRtKSkvNlxuXHRcdFx0KS8yKTtcblx0XHQkZGVsdGEgPSAoX3N1YmZwcm9iKCRuLCAkbSwgJHgpIC0gJHApIC8gJHo7XG5cdFx0JHggKz0gJGRlbHRhO1xuXHR9IHdoaWxlIChNYXRoLmFicygkZGVsdGEpPjNlLTQpO1xuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIF9zdWJjaGlzcXIgKCRuLCAkcCkge1xuXHR2YXIgJHg7XG5cblx0aWYgKCgkcCA+IDEpIHx8ICgkcCA8PSAwKSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBwOiAkcFxcblwiKTtcblx0fSBlbHNlIGlmICgkcCA9PSAxKXtcblx0XHQkeCA9IDA7XG5cdH0gZWxzZSBpZiAoJG4gPT0gMSkge1xuXHRcdCR4ID0gTWF0aC5wb3coX3N1YnUoJHAgLyAyKSwgMik7XG5cdH0gZWxzZSBpZiAoJG4gPT0gMikge1xuXHRcdCR4ID0gLTIgKiBNYXRoLmxvZygkcCk7XG5cdH0gZWxzZSB7XG5cdFx0dmFyICR1ID0gX3N1YnUoJHApO1xuXHRcdHZhciAkdTIgPSAkdSAqICR1O1xuXG5cdFx0JHggPSBtYXgoMCwgJG4gKyBNYXRoLnNxcnQoMiAqICRuKSAqICR1IFxuXHRcdFx0KyAyLzMgKiAoJHUyIC0gMSlcblx0XHRcdCsgJHUgKiAoJHUyIC0gNykgLyA5IC8gTWF0aC5zcXJ0KDIgKiAkbilcblx0XHRcdC0gMi80MDUgLyAkbiAqICgkdTIgKiAoMyAqJHUyICsgNykgLSAxNikpO1xuXG5cdFx0aWYgKCRuIDw9IDEwMCkge1xuXHRcdFx0dmFyICR4MDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkcDE7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgJHo7XG5cdFx0XHRkbyB7XG5cdFx0XHRcdCR4MCA9ICR4O1xuXHRcdFx0XHRpZiAoJHggPCAwKSB7XG5cdFx0XHRcdFx0JHAxID0gMTtcblx0XHRcdFx0fSBlbHNlIGlmICgkbj4xMDApIHtcblx0XHRcdFx0XHQkcDEgPSBfc3VidXByb2IoKE1hdGgucG93KCgkeCAvICRuKSwgKDEvMykpIC0gKDEgLSAyLzkvJG4pKVxuXHRcdFx0XHRcdFx0LyBNYXRoLnNxcnQoMi85LyRuKSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoJHg+NDAwKSB7XG5cdFx0XHRcdFx0JHAxID0gMDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YXIgJGkwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyICRhO1xuXHRcdFx0XHRcdGlmICgoJG4gJSAyKSAhPSAwKSB7XG5cdFx0XHRcdFx0XHQkcDEgPSAyICogX3N1YnVwcm9iKE1hdGguc3FydCgkeCkpO1xuXHRcdFx0XHRcdFx0JGEgPSBNYXRoLnNxcnQoMi9NYXRoLlBJKSAqIE1hdGguZXhwKC0keC8yKSAvIE1hdGguc3FydCgkeCk7XG5cdFx0XHRcdFx0XHQkaTAgPSAxO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQkcDEgPSAkYSA9IE1hdGguZXhwKC0keC8yKTtcblx0XHRcdFx0XHRcdCRpMCA9IDI7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Zm9yICh2YXIgJGkgPSAkaTA7ICRpIDw9ICRuLTI7ICRpICs9IDIpIHtcblx0XHRcdFx0XHRcdCRhICo9ICR4IC8gJGk7XG5cdFx0XHRcdFx0XHQkcDEgKz0gJGE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdCR6ID0gTWF0aC5leHAoKCgkbi0xKSAqIE1hdGgubG9nKCR4LyRuKSAtIE1hdGgubG9nKDQqTWF0aC5QSSokeCkgXG5cdFx0XHRcdFx0KyAkbiAtICR4IC0gMS8kbi82KSAvIDIpO1xuXHRcdFx0XHQkeCArPSAoJHAxIC0gJHApIC8gJHo7XG5cdFx0XHRcdCR4ID0gcm91bmRfdG9fcHJlY2lzaW9uKCR4LCA1KTtcblx0XHRcdH0gd2hpbGUgKCgkbiA8IDMxKSAmJiAoTWF0aC5hYnMoJHgwIC0gJHgpID4gMWUtNCkpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIGxvZzEwICgkbikge1xuXHRyZXR1cm4gTWF0aC5sb2coJG4pIC8gTWF0aC5sb2coMTApO1xufVxuIFxuZnVuY3Rpb24gbWF4ICgpIHtcblx0dmFyICRtYXggPSBhcmd1bWVudHNbMF07XG5cdGZvciAodmFyICRpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICgkbWF4IDwgYXJndW1lbnRzWyRpXSlcbiAgICAgICAgICAgICAgICAgICAgICAgICRtYXggPSBhcmd1bWVudHNbJGldO1xuXHR9XHRcblx0cmV0dXJuICRtYXg7XG59XG5cbmZ1bmN0aW9uIG1pbiAoKSB7XG5cdHZhciAkbWluID0gYXJndW1lbnRzWzBdO1xuXHRmb3IgKHZhciAkaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoJG1pbiA+IGFyZ3VtZW50c1skaV0pXG4gICAgICAgICAgICAgICAgICAgICAgICAkbWluID0gYXJndW1lbnRzWyRpXTtcblx0fVxuXHRyZXR1cm4gJG1pbjtcbn1cblxuZnVuY3Rpb24gcHJlY2lzaW9uICgkeCkge1xuXHRyZXR1cm4gTWF0aC5hYnMoaW50ZWdlcihsb2cxMChNYXRoLmFicygkeCkpIC0gU0lHTklGSUNBTlQpKTtcbn1cblxuZnVuY3Rpb24gcHJlY2lzaW9uX3N0cmluZyAoJHgpIHtcblx0aWYgKCR4KSB7XG5cdFx0cmV0dXJuIHJvdW5kX3RvX3ByZWNpc2lvbigkeCwgcHJlY2lzaW9uKCR4KSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIFwiMFwiO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHJvdW5kX3RvX3ByZWNpc2lvbiAoJHgsICRwKSB7XG4gICAgICAgICR4ID0gJHggKiBNYXRoLnBvdygxMCwgJHApO1xuICAgICAgICAkeCA9IE1hdGgucm91bmQoJHgpO1xuICAgICAgICByZXR1cm4gJHggLyBNYXRoLnBvdygxMCwgJHApO1xufVxuXG5mdW5jdGlvbiBpbnRlZ2VyICgkaSkge1xuICAgICAgICBpZiAoJGkgPiAwKVxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKCRpKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwoJGkpO1xufSIsImltcG9ydCB7dGRpc3RyfSBmcm9tIFwiLi9zdGF0aXN0aWNzLWRpc3RyaWJ1dGlvbnNcIlxyXG5cclxudmFyIHN1ID0gbW9kdWxlLmV4cG9ydHMuU3RhdGlzdGljc1V0aWxzID17fTtcclxuc3Uuc2FtcGxlQ29ycmVsYXRpb24gPSByZXF1aXJlKCcuLi9ib3dlcl9jb21wb25lbnRzL3NpbXBsZS1zdGF0aXN0aWNzL3NyYy9zYW1wbGVfY29ycmVsYXRpb24nKTtcclxuc3UubGluZWFyUmVncmVzc2lvbiA9IHJlcXVpcmUoJy4uL2Jvd2VyX2NvbXBvbmVudHMvc2ltcGxlLXN0YXRpc3RpY3Mvc3JjL2xpbmVhcl9yZWdyZXNzaW9uJyk7XHJcbnN1LmxpbmVhclJlZ3Jlc3Npb25MaW5lID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9zaW1wbGUtc3RhdGlzdGljcy9zcmMvbGluZWFyX3JlZ3Jlc3Npb25fbGluZScpO1xyXG5zdS5lcnJvckZ1bmN0aW9uID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9zaW1wbGUtc3RhdGlzdGljcy9zcmMvZXJyb3JfZnVuY3Rpb24nKTtcclxuc3Uuc3RhbmRhcmREZXZpYXRpb24gPSByZXF1aXJlKCcuLi9ib3dlcl9jb21wb25lbnRzL3NpbXBsZS1zdGF0aXN0aWNzL3NyYy9zdGFuZGFyZF9kZXZpYXRpb24nKTtcclxuc3Uuc2FtcGxlU3RhbmRhcmREZXZpYXRpb24gPSByZXF1aXJlKCcuLi9ib3dlcl9jb21wb25lbnRzL3NpbXBsZS1zdGF0aXN0aWNzL3NyYy9zYW1wbGVfc3RhbmRhcmRfZGV2aWF0aW9uJyk7XHJcbnN1LnZhcmlhbmNlID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9zaW1wbGUtc3RhdGlzdGljcy9zcmMvdmFyaWFuY2UnKTtcclxuc3UubWVhbiA9IHJlcXVpcmUoJy4uL2Jvd2VyX2NvbXBvbmVudHMvc2ltcGxlLXN0YXRpc3RpY3Mvc3JjL21lYW4nKTtcclxuc3UuelNjb3JlID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9zaW1wbGUtc3RhdGlzdGljcy9zcmMvel9zY29yZScpO1xyXG5zdS5zdGFuZGFyZEVycm9yPSBhcnIgPT4gTWF0aC5zcXJ0KHN1LnZhcmlhbmNlKGFycikvKGFyci5sZW5ndGgtMSkpO1xyXG5cclxuXHJcbnN1LnRWYWx1ZT0gKGRlZ3JlZXNPZkZyZWVkb20sIGNyaXRpY2FsUHJvYmFiaWxpdHkpID0+IHsgLy9hcyBpbiBodHRwOi8vc3RhdHRyZWsuY29tL29ubGluZS1jYWxjdWxhdG9yL3QtZGlzdHJpYnV0aW9uLmFzcHhcclxuICAgIHJldHVybiB0ZGlzdHIoZGVncmVlc09mRnJlZWRvbSwgY3JpdGljYWxQcm9iYWJpbGl0eSk7XHJcbn07IiwiZXhwb3J0IGNsYXNzIFV0aWxzIHtcclxuICAgIHN0YXRpYyBTUVJUXzIgPSAxLjQxNDIxMzU2MjM3O1xyXG4gICAgLy8gdXNhZ2UgZXhhbXBsZSBkZWVwRXh0ZW5kKHt9LCBvYmpBLCBvYmpCKTsgPT4gc2hvdWxkIHdvcmsgc2ltaWxhciB0byAkLmV4dGVuZCh0cnVlLCB7fSwgb2JqQSwgb2JqQik7XHJcbiAgICBzdGF0aWMgZGVlcEV4dGVuZChvdXQpIHtcclxuXHJcbiAgICAgICAgdmFyIHV0aWxzID0gdGhpcztcclxuICAgICAgICB2YXIgZW1wdHlPdXQgPSB7fTtcclxuXHJcblxyXG4gICAgICAgIGlmICghb3V0ICYmIGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIEFycmF5LmlzQXJyYXkoYXJndW1lbnRzWzFdKSkge1xyXG4gICAgICAgICAgICBvdXQgPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgb3V0ID0gb3V0IHx8IHt9O1xyXG5cclxuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBpZiAoIXNvdXJjZSlcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzb3VyY2UuaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5KG91dFtrZXldKTtcclxuICAgICAgICAgICAgICAgIHZhciBpc09iamVjdCA9IHV0aWxzLmlzT2JqZWN0KG91dFtrZXldKTtcclxuICAgICAgICAgICAgICAgIHZhciBzcmNPYmogPSB1dGlscy5pc09iamVjdChzb3VyY2Vba2V5XSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0ICYmICFpc0FycmF5ICYmIHNyY09iaikge1xyXG4gICAgICAgICAgICAgICAgICAgIHV0aWxzLmRlZXBFeHRlbmQob3V0W2tleV0sIHNvdXJjZVtrZXldKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb3V0W2tleV0gPSBzb3VyY2Vba2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG91dDtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIG1lcmdlRGVlcCh0YXJnZXQsIHNvdXJjZSkge1xyXG4gICAgICAgIGxldCBvdXRwdXQgPSBPYmplY3QuYXNzaWduKHt9LCB0YXJnZXQpO1xyXG4gICAgICAgIGlmIChVdGlscy5pc09iamVjdE5vdEFycmF5KHRhcmdldCkgJiYgVXRpbHMuaXNPYmplY3ROb3RBcnJheShzb3VyY2UpKSB7XHJcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHNvdXJjZSkuZm9yRWFjaChrZXkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKFV0aWxzLmlzT2JqZWN0Tm90QXJyYXkoc291cmNlW2tleV0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoa2V5IGluIHRhcmdldCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ob3V0cHV0LCB7W2tleV06IHNvdXJjZVtrZXldfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRba2V5XSA9IFV0aWxzLm1lcmdlRGVlcCh0YXJnZXRba2V5XSwgc291cmNlW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKG91dHB1dCwge1trZXldOiBzb3VyY2Vba2V5XX0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG91dHB1dDtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgY3Jvc3MoYSwgYikge1xyXG4gICAgICAgIHZhciBjID0gW10sIG4gPSBhLmxlbmd0aCwgbSA9IGIubGVuZ3RoLCBpLCBqO1xyXG4gICAgICAgIGZvciAoaSA9IC0xOyArK2kgPCBuOykgZm9yIChqID0gLTE7ICsraiA8IG07KSBjLnB1c2goe3g6IGFbaV0sIGk6IGksIHk6IGJbal0sIGo6IGp9KTtcclxuICAgICAgICByZXR1cm4gYztcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGluZmVyVmFyaWFibGVzKGRhdGEsIGdyb3VwS2V5LCBpbmNsdWRlR3JvdXApIHtcclxuICAgICAgICB2YXIgcmVzID0gW107XHJcbiAgICAgICAgaWYgKGRhdGEubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHZhciBkID0gZGF0YVswXTtcclxuICAgICAgICAgICAgaWYgKGQgaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgcmVzID0gZC5tYXAoZnVuY3Rpb24gKHYsIGkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkID09PSAnb2JqZWN0Jykge1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZC5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJlcy5wdXNoKHByb3ApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghaW5jbHVkZUdyb3VwKSB7XHJcbiAgICAgICAgICAgIHZhciBpbmRleCA9IHJlcy5pbmRleE9mKGdyb3VwS2V5KTtcclxuICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIHJlcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXNcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGlzT2JqZWN0Tm90QXJyYXkoaXRlbSkge1xyXG4gICAgICAgIHJldHVybiAoaXRlbSAmJiB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkoaXRlbSkgJiYgaXRlbSAhPT0gbnVsbCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHN0YXRpYyBpc09iamVjdChhKSB7XHJcbiAgICAgICAgcmV0dXJuIGEgIT09IG51bGwgJiYgdHlwZW9mIGEgPT09ICdvYmplY3QnO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgaXNOdW1iZXIoYSkge1xyXG4gICAgICAgIHJldHVybiAhaXNOYU4oYSkgJiYgdHlwZW9mIGEgPT09ICdudW1iZXInO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgaXNGdW5jdGlvbihhKSB7XHJcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBhID09PSAnZnVuY3Rpb24nO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgaXNEYXRlKGEpe1xyXG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYSkgPT09ICdbb2JqZWN0IERhdGVdJ1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBpc1N0cmluZyhhKXtcclxuICAgICAgICByZXR1cm4gdHlwZW9mIGEgPT09ICdzdHJpbmcnIHx8IGEgaW5zdGFuY2VvZiBTdHJpbmdcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgaW5zZXJ0T3JBcHBlbmRTZWxlY3RvcihwYXJlbnQsIHNlbGVjdG9yLCBvcGVyYXRpb24sIGJlZm9yZSkge1xyXG4gICAgICAgIHZhciBzZWxlY3RvclBhcnRzID0gc2VsZWN0b3Iuc3BsaXQoLyhbXFwuXFwjXSkvKTtcclxuICAgICAgICB2YXIgZWxlbWVudCA9IHBhcmVudFtvcGVyYXRpb25dKHNlbGVjdG9yUGFydHMuc2hpZnQoKSwgYmVmb3JlKTsvL1wiOmZpcnN0LWNoaWxkXCJcclxuICAgICAgICB3aGlsZSAoc2VsZWN0b3JQYXJ0cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxlY3Rvck1vZGlmaWVyID0gc2VsZWN0b3JQYXJ0cy5zaGlmdCgpO1xyXG4gICAgICAgICAgICB2YXIgc2VsZWN0b3JJdGVtID0gc2VsZWN0b3JQYXJ0cy5zaGlmdCgpO1xyXG4gICAgICAgICAgICBpZiAoc2VsZWN0b3JNb2RpZmllciA9PT0gXCIuXCIpIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LmNsYXNzZWQoc2VsZWN0b3JJdGVtLCB0cnVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3Rvck1vZGlmaWVyID09PSBcIiNcIikge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQuYXR0cignaWQnLCBzZWxlY3Rvckl0ZW0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBlbGVtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBpbnNlcnRTZWxlY3RvcihwYXJlbnQsIHNlbGVjdG9yLCBiZWZvcmUpIHtcclxuICAgICAgICByZXR1cm4gVXRpbHMuaW5zZXJ0T3JBcHBlbmRTZWxlY3RvcihwYXJlbnQsIHNlbGVjdG9yLCBcImluc2VydFwiLCBiZWZvcmUpO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBhcHBlbmRTZWxlY3RvcihwYXJlbnQsIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgcmV0dXJuIFV0aWxzLmluc2VydE9yQXBwZW5kU2VsZWN0b3IocGFyZW50LCBzZWxlY3RvciwgXCJhcHBlbmRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIHNlbGVjdE9yQXBwZW5kKHBhcmVudCwgc2VsZWN0b3IsIGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgc2VsZWN0aW9uID0gcGFyZW50LnNlbGVjdChzZWxlY3Rvcik7XHJcbiAgICAgICAgaWYgKHNlbGVjdGlvbi5lbXB0eSgpKSB7XHJcbiAgICAgICAgICAgIGlmIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50LmFwcGVuZChlbGVtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gVXRpbHMuYXBwZW5kU2VsZWN0b3IocGFyZW50LCBzZWxlY3Rvcik7XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2VsZWN0aW9uO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgc2VsZWN0T3JJbnNlcnQocGFyZW50LCBzZWxlY3RvciwgYmVmb3JlKSB7XHJcbiAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHBhcmVudC5zZWxlY3Qoc2VsZWN0b3IpO1xyXG4gICAgICAgIGlmIChzZWxlY3Rpb24uZW1wdHkoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gVXRpbHMuaW5zZXJ0U2VsZWN0b3IocGFyZW50LCBzZWxlY3RvciwgYmVmb3JlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNlbGVjdGlvbjtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGxpbmVhckdyYWRpZW50KHN2ZywgZ3JhZGllbnRJZCwgcmFuZ2UsIHgxLCB5MSwgeDIsIHkyKSB7XHJcbiAgICAgICAgdmFyIGRlZnMgPSBVdGlscy5zZWxlY3RPckFwcGVuZChzdmcsIFwiZGVmc1wiKTtcclxuICAgICAgICB2YXIgbGluZWFyR3JhZGllbnQgPSBkZWZzLmFwcGVuZChcImxpbmVhckdyYWRpZW50XCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaWRcIiwgZ3JhZGllbnRJZCk7XHJcblxyXG4gICAgICAgIGxpbmVhckdyYWRpZW50XHJcbiAgICAgICAgICAgIC5hdHRyKFwieDFcIiwgeDEgKyBcIiVcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ5MVwiLCB5MSArIFwiJVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcIngyXCIsIHgyICsgXCIlXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwieTJcIiwgeTIgKyBcIiVcIik7XHJcblxyXG4gICAgICAgIC8vQXBwZW5kIG11bHRpcGxlIGNvbG9yIHN0b3BzIGJ5IHVzaW5nIEQzJ3MgZGF0YS9lbnRlciBzdGVwXHJcbiAgICAgICAgdmFyIHN0b3BzID0gbGluZWFyR3JhZGllbnQuc2VsZWN0QWxsKFwic3RvcFwiKVxyXG4gICAgICAgICAgICAuZGF0YShyYW5nZSk7XHJcblxyXG4gICAgICAgIHN0b3BzLmVudGVyKCkuYXBwZW5kKFwic3RvcFwiKTtcclxuXHJcbiAgICAgICAgc3RvcHMuYXR0cihcIm9mZnNldFwiLCAoZCwgaSkgPT4gaSAvIChyYW5nZS5sZW5ndGggLSAxKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJzdG9wLWNvbG9yXCIsIGQgPT4gZCk7XHJcblxyXG4gICAgICAgIHN0b3BzLmV4aXQoKS5yZW1vdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgc2FuaXRpemVIZWlnaHQgPSBmdW5jdGlvbiAoaGVpZ2h0LCBjb250YWluZXIpIHtcclxuICAgICAgICByZXR1cm4gKGhlaWdodCB8fCBwYXJzZUludChjb250YWluZXIuc3R5bGUoJ2hlaWdodCcpLCAxMCkgfHwgNDAwKTtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIHNhbml0aXplV2lkdGggPSBmdW5jdGlvbiAod2lkdGgsIGNvbnRhaW5lcikge1xyXG4gICAgICAgIHJldHVybiAod2lkdGggfHwgcGFyc2VJbnQoY29udGFpbmVyLnN0eWxlKCd3aWR0aCcpLCAxMCkgfHwgOTYwKTtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGF2YWlsYWJsZUhlaWdodCA9IGZ1bmN0aW9uIChoZWlnaHQsIGNvbnRhaW5lciwgbWFyZ2luKSB7XHJcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIFV0aWxzLnNhbml0aXplSGVpZ2h0KGhlaWdodCwgY29udGFpbmVyKSAtIG1hcmdpbi50b3AgLSBtYXJnaW4uYm90dG9tKTtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGF2YWlsYWJsZVdpZHRoID0gZnVuY3Rpb24gKHdpZHRoLCBjb250YWluZXIsIG1hcmdpbikge1xyXG4gICAgICAgIHJldHVybiBNYXRoLm1heCgwLCBVdGlscy5zYW5pdGl6ZVdpZHRoKHdpZHRoLCBjb250YWluZXIpIC0gbWFyZ2luLmxlZnQgLSBtYXJnaW4ucmlnaHQpO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgZ3VpZCgpIHtcclxuICAgICAgICBmdW5jdGlvbiBzNCgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKDEgKyBNYXRoLnJhbmRvbSgpKSAqIDB4MTAwMDApXHJcbiAgICAgICAgICAgICAgICAudG9TdHJpbmcoMTYpXHJcbiAgICAgICAgICAgICAgICAuc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHM0KCkgKyBzNCgpICsgJy0nICsgczQoKSArICctJyArIHM0KCkgKyAnLScgK1xyXG4gICAgICAgICAgICBzNCgpICsgJy0nICsgczQoKSArIHM0KCkgKyBzNCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vcGxhY2VzIHRleHRTdHJpbmcgaW4gdGV4dE9iaiwgYWRkcyBhbiBlbGxpcHNpcyBpZiB0ZXh0IGNhbid0IGZpdCBpbiB3aWR0aFxyXG4gICAgc3RhdGljIHBsYWNlVGV4dFdpdGhFbGxpcHNpcyh0ZXh0RDNPYmosIHRleHRTdHJpbmcsIHdpZHRoKXtcclxuICAgICAgICB2YXIgdGV4dE9iaiA9IHRleHREM09iai5ub2RlKCk7XHJcbiAgICAgICAgdGV4dE9iai50ZXh0Q29udGVudD10ZXh0U3RyaW5nO1xyXG5cclxuICAgICAgICB2YXIgbWFyZ2luID0gMDtcclxuICAgICAgICB2YXIgZWxsaXBzaXNMZW5ndGggPSA5O1xyXG4gICAgICAgIC8vZWxsaXBzaXMgaXMgbmVlZGVkXHJcbiAgICAgICAgaWYgKHRleHRPYmouZ2V0Q29tcHV0ZWRUZXh0TGVuZ3RoKCk+d2lkdGgrbWFyZ2luKXtcclxuICAgICAgICAgICAgZm9yICh2YXIgeD10ZXh0U3RyaW5nLmxlbmd0aC0zO3g+MDt4LT0xKXtcclxuICAgICAgICAgICAgICAgIGlmICh0ZXh0T2JqLmdldFN1YlN0cmluZ0xlbmd0aCgwLHgpK2VsbGlwc2lzTGVuZ3RoPD13aWR0aCttYXJnaW4pe1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHRPYmoudGV4dENvbnRlbnQ9dGV4dFN0cmluZy5zdWJzdHJpbmcoMCx4KStcIi4uLlwiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRleHRPYmoudGV4dENvbnRlbnQ9XCIuLi5cIjsgLy9jYW4ndCBwbGFjZSBhdCBhbGxcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgcGxhY2VUZXh0V2l0aEVsbGlwc2lzQW5kVG9vbHRpcCh0ZXh0RDNPYmosIHRleHRTdHJpbmcsIHdpZHRoLCB0b29sdGlwKXtcclxuICAgICAgICB2YXIgZWxsaXBzaXNQbGFjZWQgPSBVdGlscy5wbGFjZVRleHRXaXRoRWxsaXBzaXModGV4dEQzT2JqLCB0ZXh0U3RyaW5nLCB3aWR0aCk7XHJcbiAgICAgICAgaWYoZWxsaXBzaXNQbGFjZWQgJiYgdG9vbHRpcCl7XHJcbiAgICAgICAgICAgIHRleHREM09iai5vbihcIm1vdXNlb3ZlclwiLCBmdW5jdGlvbiAoZCkge1xyXG4gICAgICAgICAgICAgICAgdG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oMjAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgLjkpO1xyXG4gICAgICAgICAgICAgICAgdG9vbHRpcC5odG1sKHRleHRTdHJpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwibGVmdFwiLCAoZDMuZXZlbnQucGFnZVggKyA1KSArIFwicHhcIilcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgKGQzLmV2ZW50LnBhZ2VZIC0gMjgpICsgXCJweFwiKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0ZXh0RDNPYmoub24oXCJtb3VzZW91dFwiLCBmdW5jdGlvbiAoZCkge1xyXG4gICAgICAgICAgICAgICAgdG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oNTAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGdldEZvbnRTaXplKGVsZW1lbnQpe1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKFwiZm9udC1zaXplXCIpO1xyXG4gICAgfVxyXG59XHJcbiJdfQ== +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJib3dlcl9jb21wb25lbnRzXFxkMy1sZWdlbmRcXG5vLWV4dGVuZC5qcyIsImJvd2VyX2NvbXBvbmVudHNcXGQzLWxlZ2VuZFxcc3JjXFxjb2xvci5qcyIsImJvd2VyX2NvbXBvbmVudHNcXGQzLWxlZ2VuZFxcc3JjXFxsZWdlbmQuanMiLCJib3dlcl9jb21wb25lbnRzXFxkMy1sZWdlbmRcXHNyY1xcc2l6ZS5qcyIsImJvd2VyX2NvbXBvbmVudHNcXGQzLWxlZ2VuZFxcc3JjXFxzeW1ib2wuanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxlcnJvcl9mdW5jdGlvbi5qcyIsImJvd2VyX2NvbXBvbmVudHNcXHNpbXBsZS1zdGF0aXN0aWNzXFxzcmNcXGxpbmVhcl9yZWdyZXNzaW9uLmpzIiwiYm93ZXJfY29tcG9uZW50c1xcc2ltcGxlLXN0YXRpc3RpY3NcXHNyY1xcbGluZWFyX3JlZ3Jlc3Npb25fbGluZS5qcyIsImJvd2VyX2NvbXBvbmVudHNcXHNpbXBsZS1zdGF0aXN0aWNzXFxzcmNcXG1lYW4uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzYW1wbGVfY29ycmVsYXRpb24uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzYW1wbGVfY292YXJpYW5jZS5qcyIsImJvd2VyX2NvbXBvbmVudHNcXHNpbXBsZS1zdGF0aXN0aWNzXFxzcmNcXHNhbXBsZV9zdGFuZGFyZF9kZXZpYXRpb24uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzYW1wbGVfdmFyaWFuY2UuanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzdGFuZGFyZF9kZXZpYXRpb24uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzdW0uanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFxzdW1fbnRoX3Bvd2VyX2RldmlhdGlvbnMuanMiLCJib3dlcl9jb21wb25lbnRzXFxzaW1wbGUtc3RhdGlzdGljc1xcc3JjXFx2YXJpYW5jZS5qcyIsImJvd2VyX2NvbXBvbmVudHNcXHNpbXBsZS1zdGF0aXN0aWNzXFxzcmNcXHpfc2NvcmUuanMiLCJzcmNcXGJhci1jaGFydC5qcyIsInNyY1xcY2hhcnQuanMiLCJzcmNcXGNvcnJlbGF0aW9uLW1hdHJpeC5qcyIsInNyY1xcZDMtZXh0ZW5zaW9ucy5qcyIsInNyY1xcaGVhdG1hcC10aW1lc2VyaWVzLmpzIiwic3JjXFxoZWF0bWFwLmpzIiwic3JjXFxoaXN0b2dyYW0uanMiLCJzcmNcXGluZGV4LmpzIiwic3JjXFxsZWdlbmQuanMiLCJzcmNcXHJlZ3Jlc3Npb24uanMiLCJzcmNcXHNjYXR0ZXJwbG90LW1hdHJpeC5qcyIsInNyY1xcc2NhdHRlcnBsb3QuanMiLCJzcmNcXHN0YXRpc3RpY3MtZGlzdHJpYnV0aW9ucy5qcyIsInNyY1xcc3RhdGlzdGljcy11dGlscy5qcyIsInNyY1xcdXRpbHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztBQ0FBLE9BQU8sT0FBUCxHQUFpQjtBQUNmLFNBQU8sUUFBUSxhQUFSLENBRFE7QUFFZixRQUFNLFFBQVEsWUFBUixDQUZTO0FBR2YsVUFBUSxRQUFRLGNBQVI7QUFITyxDQUFqQjs7Ozs7QUNBQSxJQUFJLFNBQVMsUUFBUSxVQUFSLENBQWI7O0FBRUEsT0FBTyxPQUFQLEdBQWlCLFlBQVU7O0FBRXpCLE1BQUksUUFBUSxHQUFHLEtBQUgsQ0FBUyxNQUFULEVBQVo7QUFBQSxNQUNFLFFBQVEsTUFEVjtBQUFBLE1BRUUsYUFBYSxFQUZmO0FBQUEsTUFHRSxjQUFjLEVBSGhCO0FBQUEsTUFJRSxjQUFjLEVBSmhCO0FBQUEsTUFLRSxlQUFlLENBTGpCO0FBQUEsTUFNRSxRQUFRLENB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LEVBQTRCO0FBQy9DLFdBQVEsU0FBUyxTQUFTLFVBQVUsS0FBVixDQUFnQixPQUFoQixDQUFULEVBQW1DLEVBQW5DLENBQVQsSUFBbUQsR0FBM0Q7QUFDSCxDOztBQXZMUSxLLENBeUxGLGUsR0FBa0IsVUFBVSxNQUFWLEVBQWtCLFNBQWxCLEVBQTZCLE1BQTdCLEVBQXFDO0FBQzFELFdBQU8sS0FBSyxHQUFMLENBQVMsQ0FBVCxFQUFZLE1BQU0sY0FBTixDQUFxQixNQUFyQixFQUE2QixTQUE3QixJQUEwQyxPQUFPLEdBQWpELEdBQXVELE9BQU8sTUFBMUUsQ0FBUDtBQUNILEM7O0FBM0xRLEssQ0E2TEYsYyxHQUFpQixVQUFVLEtBQVYsRUFBaUIsU0FBakIsRUFBNEIsTUFBNUIsRUFBb0M7QUFDeEQsV0FBTyxLQUFLLEdBQUwsQ0FBUyxDQUFULEVBQVksTUFBTSxhQUFOLENBQW9CLEtBQXBCLEVBQTJCLFNBQTNCLElBQXdDLE9BQU8sSUFBL0MsR0FBc0QsT0FBTyxLQUF6RSxDQUFQO0FBQ0gsQyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJtb2R1bGUuZXhwb3J0cyA9IHtcclxuICBjb2xvcjogcmVxdWlyZSgnLi9zcmMvY29sb3InKSxcclxuICBzaXplOiByZXF1aXJlKCcuL3NyYy9zaXplJyksXHJcbiAgc3ltYm9sOiByZXF1aXJlKCcuL3NyYy9zeW1ib2wnKVxyXG59O1xyXG4iLCJ2YXIgaGVscGVyID0gcmVxdWlyZSgnLi9sZWdlbmQnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKXtcclxuXHJcbiAgdmFyIHNjYWxlID0gZDMuc2NhbGUubGluZWFyKCksXHJcbiAgICBzaGFwZSA9IFwicmVjdFwiLFxyXG4gICAgc2hhcGVXaWR0aCA9IDE1LFxyXG4gICAgc2hhcGVIZWlnaHQgPSAxNSxcclxuICAgIHNoYXBlUmFkaXVzID0gMTAsXHJcbiAgICBzaGFwZVBhZGRpbmcgPSAyLFxyXG4gICAgY2VsbHMgPSBbNV0sXHJcbiAgICBsYWJlbHMgPSBbXSxcclxuICAgIGNsYXNzUHJlZml4ID0gXCJcIixcclxuICAgIHVzZUNsYXNzID0gZmFsc2UsXHJcbiAgICB0aXRsZSA9IFwiXCIsXHJcbiAgICBsYWJlbEZvcm1hdCA9IGQzLmZvcm1hdChcIi4wMWZcIiksXHJcbiAgICBsYWJlbE9mZnNldCA9IDEwLFxyXG4gICAgbGFiZWxBbGlnbiA9IFwibWlkZGxlXCIsXHJcbiAgICBsYWJlbERlbGltaXRlciA9IFwidG9cIixcclxuICAgIG9yaWVudCA9IFwidmVydGljYWxcIixcclxuICAgIGFzY2VuZGluZyA9IGZhbHNlLFxyXG4gICAgcGF0aCxcclxuICAgIGxlZ2VuZERpc3BhdGNoZXIgPSBkMy5kaXNwYXRjaChcImNlbGxvdmVyXCIsIFwiY2VsbG91dFwiLCBcImNlbGxjbGlja1wiKTtcclxuXHJcbiAgICBmdW5jdGlvbiBsZWdlbmQoc3ZnKXtcclxuXHJcbiAgICAgIHZhciB0eXBlID0gaGVscGVyLmQzX2NhbGNUeXBlKHNjYWxlLCBhc2NlbmRpbmcsIGNlbGxzLCBsYWJlbHMsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlciksXHJcbiAgICAgICAgbGVnZW5kRyA9IHN2Zy5zZWxlY3RBbGwoJ2cnKS5kYXRhKFtzY2FsZV0pO1xyXG5cclxuICAgICAgbGVnZW5kRy5lbnRlcigpLmFwcGVuZCgnZycpLmF0dHIoJ2NsYXNzJywgY2xhc3NQcmVmaXggKyAnbGVnZW5kQ2VsbHMnKTtcclxuXHJcblxyXG4gICAgICB2YXIgY2VsbCA9IGxlZ2VuZEcuc2VsZWN0QWxsKFwiLlwiICsgY2xhc3NQcmVmaXggKyBcImNlbGxcIikuZGF0YSh0eXBlLmRhdGEpLFxyXG4gICAgICAgIGNlbGxFbnRlciA9IGNlbGwuZW50ZXIoKS5hcHBlbmQoXCJnXCIsIFwiLmNlbGxcIikuYXR0cihcImNsYXNzXCIsIGNsYXNzUHJlZml4ICsgXCJjZWxsXCIpLnN0eWxlKFwib3BhY2l0eVwiLCAxZS02KSxcclxuICAgICAgICBzaGFwZUVudGVyID0gY2VsbEVudGVyLmFwcGVuZChzaGFwZSkuYXR0cihcImNsYXNzXCIsIGNsYXNzUHJlZml4ICsgXCJzd2F0Y2hcIiksXHJcbiAgICAgICAgc2hhcGVzID0gY2VsbC5zZWxlY3QoXCJnLlwiICsgY2xhc3NQcmVmaXggKyBcImNlbGwgXCIgKyBzaGFwZSk7XHJcblxyXG4gICAgICAvL2FkZCBldmVudCBoYW5kbGVyc1xyXG4gICAgICBoZWxwZXIuZDNfYWRkRXZlbnRzKGNlbGxFbnRlciwgbGVnZW5kRGlzcGF0Y2hlcik7XHJcblxyXG4gICAgICBjZWxsLmV4aXQoKS50cmFuc2l0aW9uKCkuc3R5bGUoXCJvcGFjaXR5XCIsIDApLnJlbW92ZSgpO1xyXG5cclxuICAgICAgaGVscGVyLmQzX2RyYXdTaGFwZXMoc2hhcGUsIHNoYXBlcywgc2hhcGVIZWlnaHQsIHNoYXBlV2lkdGgsIHNoYXBlUmFkaXVzLCBwYXRoKTtcclxuXHJcbiAgICAgIGhlbHBlci5kM19hZGRUZXh0KGxlZ2VuZEcsIGNlbGxFbnRlciwgdHlwZS5sYWJlbHMsIGNsYXNzUHJlZml4KVxyXG5cclxuICAgICAgLy8gc2V0cyBwbGFjZW1lbnRcclxuICAgICAgdmFyIHRleHQgPSBjZWxsLnNlbGVjdChcInRleHRcIiksXHJcbiAgICAgICAgc2hhcGVTaXplID0gc2hhcGVzWzBdLm1hcCggZnVuY3Rpb24oZCl7IHJldHVybiBkLmdldEJCb3goKTsgfSk7XHJcblxyXG4gICAgICAvL3NldHMgc2NhbGVcclxuICAgICAgLy9ldmVyeXRoaW5nIGlzIGZpbGwgZXhjZXB0IGZvciBsaW5lIHdoaWNoIGlzIHN0cm9rZSxcclxuICAgICAgaWYgKCF1c2VDbGFzcyl7XHJcbiAgICAgICAgaWYgKHNoYXBlID09IFwibGluZVwiKXtcclxuICAgICAgICAgIHNoYXBlcy5zdHlsZShcInN0cm9rZVwiLCB0eXBlLmZlYXR1cmUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBzaGFwZXMuc3R5bGUoXCJmaWxsXCIsIHR5cGUuZmVhdHVyZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNoYXBlcy5hdHRyKFwiY2xhc3NcIiwgZnVuY3Rpb24oZCl7IHJldHVybiBjbGFzc1ByZWZpeCArIFwic3dhdGNoIFwiICsgdHlwZS5mZWF0dXJlKGQpOyB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGNlbGxUcmFucyxcclxuICAgICAgdGV4dFRyYW5zLFxyXG4gICAgICB0ZXh0QWxpZ24gPSAobGFiZWxBbGlnbiA9PSBcInN0YXJ0XCIpID8gMCA6IChsYWJlbEFsaWduID09IFwibWlkZGxlXCIpID8gMC41IDogMTtcclxuXHJcbiAgICAgIC8vcG9zaXRpb25zIGNlbGxzIGFuZCB0ZXh0XHJcbiAgICAgIGlmIChvcmllbnQgPT09IFwidmVydGljYWxcIil7XHJcbiAgICAgICAgY2VsbFRyYW5zID0gZnVuY3Rpb24oZCxpKSB7IHJldHVybiBcInRyYW5zbGF0ZSgwLCBcIiArIChpICogKHNoYXBlU2l6ZVtpXS5oZWlnaHQgKyBzaGFwZVBhZGRpbmcpKSArIFwiKVwiOyB9O1xyXG4gICAgICAgIHRleHRUcmFucyA9IGZ1bmN0aW9uKGQsaSkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyAoc2hhcGVTaXplW2ldLndpZHRoICsgc2hhcGVTaXplW2ldLnggK1xyXG4gICAgICAgICAgbGFiZWxPZmZzZXQpICsgXCIsXCIgKyAoc2hhcGVTaXplW2ldLnkgKyBzaGFwZVNpemVbaV0uaGVpZ2h0LzIgKyA1KSArIFwiKVwiOyB9O1xyXG5cclxuICAgICAgfSBlbHNlIGlmIChvcmllbnQgPT09IFwiaG9yaXpvbnRhbFwiKXtcclxuICAgICAgICBjZWxsVHJhbnMgPSBmdW5jdGlvbihkLGkpIHsgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgKGkgKiAoc2hhcGVTaXplW2ldLndpZHRoICsgc2hhcGVQYWRkaW5nKSkgKyBcIiwwKVwiOyB9XHJcbiAgICAgICAgdGV4dFRyYW5zID0gZnVuY3Rpb24oZCxpKSB7IHJldHVybiBcInRyYW5zbGF0ZShcIiArIChzaGFwZVNpemVbaV0ud2lkdGgqdGV4dEFsaWduICArIHNoYXBlU2l6ZVtpXS54KSArXHJcbiAgICAgICAgICBcIixcIiArIChzaGFwZVNpemVbaV0uaGVpZ2h0ICsgc2hhcGVTaXplW2ldLnkgKyBsYWJlbE9mZnNldCArIDgpICsgXCIpXCI7IH07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGhlbHBlci5kM19wbGFjZW1lbnQob3JpZW50LCBjZWxsLCBjZWxsVHJhbnMsIHRleHQsIHRleHRUcmFucywgbGFiZWxBbGlnbik7XHJcbiAgICAgIGhlbHBlci5kM190aXRsZShzdmcsIGxlZ2VuZEcsIHRpdGxlLCBjbGFzc1ByZWZpeCk7XHJcblxyXG4gICAgICBjZWxsLnRyYW5zaXRpb24oKS5zdHlsZShcIm9wYWNpdHlcIiwgMSk7XHJcblxyXG4gICAgfVxyXG5cclxuXHJcblxyXG4gIGxlZ2VuZC5zY2FsZSA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNjYWxlO1xyXG4gICAgc2NhbGUgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuY2VsbHMgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBjZWxscztcclxuICAgIGlmIChfLmxlbmd0aCA+IDEgfHwgXyA+PSAyICl7XHJcbiAgICAgIGNlbGxzID0gXztcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnNoYXBlID0gZnVuY3Rpb24oXywgZCkge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2hhcGU7XHJcbiAgICBpZiAoXyA9PSBcInJlY3RcIiB8fCBfID09IFwiY2lyY2xlXCIgfHwgXyA9PSBcImxpbmVcIiB8fCAoXyA9PSBcInBhdGhcIiAmJiAodHlwZW9mIGQgPT09ICdzdHJpbmcnKSkgKXtcclxuICAgICAgc2hhcGUgPSBfO1xyXG4gICAgICBwYXRoID0gZDtcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnNoYXBlV2lkdGggPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzaGFwZVdpZHRoO1xyXG4gICAgc2hhcGVXaWR0aCA9ICtfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuc2hhcGVIZWlnaHQgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzaGFwZUhlaWdodDtcclxuICAgIHNoYXBlSGVpZ2h0ID0gK187XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5zaGFwZVJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNoYXBlUmFkaXVzO1xyXG4gICAgc2hhcGVSYWRpdXMgPSArXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnNoYXBlUGFkZGluZyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNoYXBlUGFkZGluZztcclxuICAgIHNoYXBlUGFkZGluZyA9ICtfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxzID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGFiZWxzO1xyXG4gICAgbGFiZWxzID0gXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmxhYmVsQWxpZ24gPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbEFsaWduO1xyXG4gICAgaWYgKF8gPT0gXCJzdGFydFwiIHx8IF8gPT0gXCJlbmRcIiB8fCBfID09IFwibWlkZGxlXCIpIHtcclxuICAgICAgbGFiZWxBbGlnbiA9IF87XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbEZvcm1hdCA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsRm9ybWF0O1xyXG4gICAgbGFiZWxGb3JtYXQgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxPZmZzZXQgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbE9mZnNldDtcclxuICAgIGxhYmVsT2Zmc2V0ID0gK187XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbERlbGltaXRlciA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsRGVsaW1pdGVyO1xyXG4gICAgbGFiZWxEZWxpbWl0ZXIgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQudXNlQ2xhc3MgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB1c2VDbGFzcztcclxuICAgIGlmIChfID09PSB0cnVlIHx8IF8gPT09IGZhbHNlKXtcclxuICAgICAgdXNlQ2xhc3MgPSBfO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQub3JpZW50ID0gZnVuY3Rpb24oXyl7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBvcmllbnQ7XHJcbiAgICBfID0gXy50b0xvd2VyQ2FzZSgpO1xyXG4gICAgaWYgKF8gPT0gXCJob3Jpem9udGFsXCIgfHwgXyA9PSBcInZlcnRpY2FsXCIpIHtcclxuICAgICAgb3JpZW50ID0gXztcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmFzY2VuZGluZyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGFzY2VuZGluZztcclxuICAgIGFzY2VuZGluZyA9ICEhXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmNsYXNzUHJlZml4ID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2xhc3NQcmVmaXg7XHJcbiAgICBjbGFzc1ByZWZpeCA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC50aXRsZSA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRpdGxlO1xyXG4gICAgdGl0bGUgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBkMy5yZWJpbmQobGVnZW5kLCBsZWdlbmREaXNwYXRjaGVyLCBcIm9uXCIpO1xyXG5cclxuICByZXR1cm4gbGVnZW5kO1xyXG5cclxufTtcclxuIiwibW9kdWxlLmV4cG9ydHMgPSB7XHJcblxyXG4gIGQzX2lkZW50aXR5OiBmdW5jdGlvbiAoZCkge1xyXG4gICAgcmV0dXJuIGQ7XHJcbiAgfSxcclxuXHJcbiAgZDNfbWVyZ2VMYWJlbHM6IGZ1bmN0aW9uIChnZW4sIGxhYmVscykge1xyXG5cclxuICAgICAgaWYobGFiZWxzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGdlbjtcclxuXHJcbiAgICAgIGdlbiA9IChnZW4pID8gZ2VuIDogW107XHJcblxyXG4gICAgICB2YXIgaSA9IGxhYmVscy5sZW5ndGg7XHJcbiAgICAgIGZvciAoOyBpIDwgZ2VuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGFiZWxzLnB1c2goZ2VuW2ldKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gbGFiZWxzO1xyXG4gICAgfSxcclxuXHJcbiAgZDNfbGluZWFyTGVnZW5kOiBmdW5jdGlvbiAoc2NhbGUsIGNlbGxzLCBsYWJlbEZvcm1hdCkge1xyXG4gICAgdmFyIGRhdGEgPSBbXTtcclxuXHJcbiAgICBpZiAoY2VsbHMubGVuZ3RoID4gMSl7XHJcbiAgICAgIGRhdGEgPSBjZWxscztcclxuXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXIgZG9tYWluID0gc2NhbGUuZG9tYWluKCksXHJcbiAgICAgIGluY3JlbWVudCA9IChkb21haW5bZG9tYWluLmxlbmd0aCAtIDFdIC0gZG9tYWluWzBdKS8oY2VsbHMgLSAxKSxcclxuICAgICAgaSA9IDA7XHJcblxyXG4gICAgICBmb3IgKDsgaSA8IGNlbGxzOyBpKyspe1xyXG4gICAgICAgIGRhdGEucHVzaChkb21haW5bMF0gKyBpKmluY3JlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2YXIgbGFiZWxzID0gZGF0YS5tYXAobGFiZWxGb3JtYXQpO1xyXG5cclxuICAgIHJldHVybiB7ZGF0YTogZGF0YSxcclxuICAgICAgICAgICAgbGFiZWxzOiBsYWJlbHMsXHJcbiAgICAgICAgICAgIGZlYXR1cmU6IGZ1bmN0aW9uKGQpeyByZXR1cm4gc2NhbGUoZCk7IH19O1xyXG4gIH0sXHJcblxyXG4gIGQzX3F1YW50TGVnZW5kOiBmdW5jdGlvbiAoc2NhbGUsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlcikge1xyXG4gICAgdmFyIGxhYmVscyA9IHNjYWxlLnJhbmdlKCkubWFwKGZ1bmN0aW9uKGQpe1xyXG4gICAgICB2YXIgaW52ZXJ0ID0gc2NhbGUuaW52ZXJ0RXh0ZW50KGQpLFxyXG4gICAgICBhID0gbGFiZWxGb3JtYXQoaW52ZXJ0WzBdKSxcclxuICAgICAgYiA9IGxhYmVsRm9ybWF0KGludmVydFsxXSk7XHJcblxyXG4gICAgICAvLyBpZiAoKCAoYSkgJiYgKGEuaXNOYW4oKSkgJiYgYil7XHJcbiAgICAgIC8vICAgY29uc29sZS5sb2coXCJpbiBpbml0aWFsIHN0YXRlbWVudFwiKVxyXG4gICAgICAgIHJldHVybiBsYWJlbEZvcm1hdChpbnZlcnRbMF0pICsgXCIgXCIgKyBsYWJlbERlbGltaXRlciArIFwiIFwiICsgbGFiZWxGb3JtYXQoaW52ZXJ0WzFdKTtcclxuICAgICAgLy8gfSBlbHNlIGlmIChhIHx8IGIpIHtcclxuICAgICAgLy8gICBjb25zb2xlLmxvZygnaW4gZWxzZSBzdGF0ZW1lbnQnKVxyXG4gICAgICAvLyAgIHJldHVybiAoYSkgPyBhIDogYjtcclxuICAgICAgLy8gfVxyXG5cclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB7ZGF0YTogc2NhbGUucmFuZ2UoKSxcclxuICAgICAgICAgICAgbGFiZWxzOiBsYWJlbHMsXHJcbiAgICAgICAgICAgIGZlYXR1cmU6IHRoaXMuZDNfaWRlbnRpdHlcclxuICAgICAgICAgIH07XHJcbiAgfSxcclxuXHJcbiAgZDNfb3JkaW5hbExlZ2VuZDogZnVuY3Rpb24gKHNjYWxlKSB7XHJcbiAgICByZXR1cm4ge2RhdGE6IHNjYWxlLmRvbWFpbigpLFxyXG4gICAgICAgICAgICBsYWJlbHM6IHNjYWxlLmRvbWFpbigpLFxyXG4gICAgICAgICAgICBmZWF0dXJlOiBmdW5jdGlvbihkKXsgcmV0dXJuIHNjYWxlKGQpOyB9fTtcclxuICB9LFxyXG5cclxuICBkM19kcmF3U2hhcGVzOiBmdW5jdGlvbiAoc2hhcGUsIHNoYXBlcywgc2hhcGVIZWlnaHQsIHNoYXBlV2lkdGgsIHNoYXBlUmFkaXVzLCBwYXRoKSB7XHJcbiAgICBpZiAoc2hhcGUgPT09IFwicmVjdFwiKXtcclxuICAgICAgICBzaGFwZXMuYXR0cihcImhlaWdodFwiLCBzaGFwZUhlaWdodCkuYXR0cihcIndpZHRoXCIsIHNoYXBlV2lkdGgpO1xyXG5cclxuICAgIH0gZWxzZSBpZiAoc2hhcGUgPT09IFwiY2lyY2xlXCIpIHtcclxuICAgICAgICBzaGFwZXMuYXR0cihcInJcIiwgc2hhcGVSYWRpdXMpLy8uYXR0cihcImN4XCIsIHNoYXBlUmFkaXVzKS5hdHRyKFwiY3lcIiwgc2hhcGVSYWRpdXMpO1xyXG5cclxuICAgIH0gZWxzZSBpZiAoc2hhcGUgPT09IFwibGluZVwiKSB7XHJcbiAgICAgICAgc2hhcGVzLmF0dHIoXCJ4MVwiLCAwKS5hdHRyKFwieDJcIiwgc2hhcGVXaWR0aCkuYXR0cihcInkxXCIsIDApLmF0dHIoXCJ5MlwiLCAwKTtcclxuXHJcbiAgICB9IGVsc2UgaWYgKHNoYXBlID09PSBcInBhdGhcIikge1xyXG4gICAgICBzaGFwZXMuYXR0cihcImRcIiwgcGF0aCk7XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgZDNfYWRkVGV4dDogZnVuY3Rpb24gKHN2ZywgZW50ZXIsIGxhYmVscywgY2xhc3NQcmVmaXgpe1xyXG4gICAgZW50ZXIuYXBwZW5kKFwidGV4dFwiKS5hdHRyKFwiY2xhc3NcIiwgY2xhc3NQcmVmaXggKyBcImxhYmVsXCIpO1xyXG4gICAgc3ZnLnNlbGVjdEFsbChcImcuXCIgKyBjbGFzc1ByZWZpeCArIFwiY2VsbCB0ZXh0XCIpLmRhdGEobGFiZWxzKS50ZXh0KHRoaXMuZDNfaWRlbnRpdHkpO1xyXG4gIH0sXHJcblxyXG4gIGQzX2NhbGNUeXBlOiBmdW5jdGlvbiAoc2NhbGUsIGFzY2VuZGluZywgY2VsbHMsIGxhYmVscywgbGFiZWxGb3JtYXQsIGxhYmVsRGVsaW1pdGVyKXtcclxuICAgIHZhciB0eXBlID0gc2NhbGUudGlja3MgP1xyXG4gICAgICAgICAgICB0aGlzLmQzX2xpbmVhckxlZ2VuZChzY2FsZSwgY2VsbHMsIGxhYmVsRm9ybWF0KSA6IHNjYWxlLmludmVydEV4dGVudCA/XHJcbiAgICAgICAgICAgIHRoaXMuZDNfcXVhbnRMZWdlbmQoc2NhbGUsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlcikgOiB0aGlzLmQzX29yZGluYWxMZWdlbmQoc2NhbGUpO1xyXG5cclxuICAgIHR5cGUubGFiZWxzID0gdGhpcy5kM19tZXJnZUxhYmVscyh0eXBlLmxhYmVscywgbGFiZWxzKTtcclxuXHJcbiAgICBpZiAoYXNjZW5kaW5nKSB7XHJcbiAgICAgIHR5cGUubGFiZWxzID0gdGhpcy5kM19yZXZlcnNlKHR5cGUubGFiZWxzKTtcclxuICAgICAgdHlwZS5kYXRhID0gdGhpcy5kM19yZXZlcnNlKHR5cGUuZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHR5cGU7XHJcbiAgfSxcclxuXHJcbiAgZDNfcmV2ZXJzZTogZnVuY3Rpb24oYXJyKSB7XHJcbiAgICB2YXIgbWlycm9yID0gW107XHJcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGFyci5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgbWlycm9yW2ldID0gYXJyW2wtaS0xXTtcclxuICAgIH1cclxuICAgIHJldHVybiBtaXJyb3I7XHJcbiAgfSxcclxuXHJcbiAgZDNfcGxhY2VtZW50OiBmdW5jdGlvbiAob3JpZW50LCBjZWxsLCBjZWxsVHJhbnMsIHRleHQsIHRleHRUcmFucywgbGFiZWxBbGlnbikge1xyXG4gICAgY2VsbC5hdHRyKFwidHJhbnNmb3JtXCIsIGNlbGxUcmFucyk7XHJcbiAgICB0ZXh0LmF0dHIoXCJ0cmFuc2Zvcm1cIiwgdGV4dFRyYW5zKTtcclxuICAgIGlmIChvcmllbnQgPT09IFwiaG9yaXpvbnRhbFwiKXtcclxuICAgICAgdGV4dC5zdHlsZShcInRleHQtYW5jaG9yXCIsIGxhYmVsQWxpZ24pO1xyXG4gICAgfVxyXG4gIH0sXHJcblxyXG4gIGQzX2FkZEV2ZW50czogZnVuY3Rpb24oY2VsbHMsIGRpc3BhdGNoZXIpe1xyXG4gICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgY2VsbHMub24oXCJtb3VzZW92ZXIubGVnZW5kXCIsIGZ1bmN0aW9uIChkKSB7IF8uZDNfY2VsbE92ZXIoZGlzcGF0Y2hlciwgZCwgdGhpcyk7IH0pXHJcbiAgICAgICAgICAub24oXCJtb3VzZW91dC5sZWdlbmRcIiwgZnVuY3Rpb24gKGQpIHsgXy5kM19jZWxsT3V0KGRpc3BhdGNoZXIsIGQsIHRoaXMpOyB9KVxyXG4gICAgICAgICAgLm9uKFwiY2xpY2subGVnZW5kXCIsIGZ1bmN0aW9uIChkKSB7IF8uZDNfY2VsbENsaWNrKGRpc3BhdGNoZXIsIGQsIHRoaXMpOyB9KTtcclxuICB9LFxyXG5cclxuICBkM19jZWxsT3ZlcjogZnVuY3Rpb24oY2VsbERpc3BhdGNoZXIsIGQsIG9iail7XHJcbiAgICBjZWxsRGlzcGF0Y2hlci5jZWxsb3Zlci5jYWxsKG9iaiwgZCk7XHJcbiAgfSxcclxuXHJcbiAgZDNfY2VsbE91dDogZnVuY3Rpb24oY2VsbERpc3BhdGNoZXIsIGQsIG9iail7XHJcbiAgICBjZWxsRGlzcGF0Y2hlci5jZWxsb3V0LmNhbGwob2JqLCBkKTtcclxuICB9LFxyXG5cclxuICBkM19jZWxsQ2xpY2s6IGZ1bmN0aW9uKGNlbGxEaXNwYXRjaGVyLCBkLCBvYmope1xyXG4gICAgY2VsbERpc3BhdGNoZXIuY2VsbGNsaWNrLmNhbGwob2JqLCBkKTtcclxuICB9LFxyXG5cclxuICBkM190aXRsZTogZnVuY3Rpb24oc3ZnLCBjZWxsc1N2ZywgdGl0bGUsIGNsYXNzUHJlZml4KXtcclxuICAgIGlmICh0aXRsZSAhPT0gXCJcIil7XHJcblxyXG4gICAgICB2YXIgdGl0bGVUZXh0ID0gc3ZnLnNlbGVjdEFsbCgndGV4dC4nICsgY2xhc3NQcmVmaXggKyAnbGVnZW5kVGl0bGUnKTtcclxuXHJcbiAgICAgIHRpdGxlVGV4dC5kYXRhKFt0aXRsZV0pXHJcbiAgICAgICAgLmVudGVyKClcclxuICAgICAgICAuYXBwZW5kKCd0ZXh0JylcclxuICAgICAgICAuYXR0cignY2xhc3MnLCBjbGFzc1ByZWZpeCArICdsZWdlbmRUaXRsZScpO1xyXG5cclxuICAgICAgICBzdmcuc2VsZWN0QWxsKCd0ZXh0LicgKyBjbGFzc1ByZWZpeCArICdsZWdlbmRUaXRsZScpXHJcbiAgICAgICAgICAgIC50ZXh0KHRpdGxlKVxyXG5cclxuICAgICAgdmFyIHlPZmZzZXQgPSBzdmcuc2VsZWN0KCcuJyArIGNsYXNzUHJlZml4ICsgJ2xlZ2VuZFRpdGxlJylcclxuICAgICAgICAgIC5tYXAoZnVuY3Rpb24oZCkgeyByZXR1cm4gZFswXS5nZXRCQm94KCkuaGVpZ2h0fSlbMF0sXHJcbiAgICAgIHhPZmZzZXQgPSAtY2VsbHNTdmcubWFwKGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGRbMF0uZ2V0QkJveCgpLnh9KVswXTtcclxuXHJcbiAgICAgIGNlbGxzU3ZnLmF0dHIoJ3RyYW5zZm9ybScsICd0cmFuc2xhdGUoJyArIHhPZmZzZXQgKyAnLCcgKyAoeU9mZnNldCArIDEwKSArICcpJyk7XHJcblxyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCJ2YXIgaGVscGVyID0gcmVxdWlyZSgnLi9sZWdlbmQnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gIGZ1bmN0aW9uKCl7XHJcblxyXG4gIHZhciBzY2FsZSA9IGQzLnNjYWxlLmxpbmVhcigpLFxyXG4gICAgc2hhcGUgPSBcInJlY3RcIixcclxuICAgIHNoYXBlV2lkdGggPSAxNSxcclxuICAgIHNoYXBlUGFkZGluZyA9IDIsXHJcbiAgICBjZWxscyA9IFs1XSxcclxuICAgIGxhYmVscyA9IFtdLFxyXG4gICAgdXNlU3Ryb2tlID0gZmFsc2UsXHJcbiAgICBjbGFzc1ByZWZpeCA9IFwiXCIsXHJcbiAgICB0aXRsZSA9IFwiXCIsXHJcbiAgICBsYWJlbEZvcm1hdCA9IGQzLmZvcm1hdChcIi4wMWZcIiksXHJcbiAgICBsYWJlbE9mZnNldCA9IDEwLFxyXG4gICAgbGFiZWxBbGlnbiA9IFwibWlkZGxlXCIsXHJcbiAgICBsYWJlbERlbGltaXRlciA9IFwidG9cIixcclxuICAgIG9yaWVudCA9IFwidmVydGljYWxcIixcclxuICAgIGFzY2VuZGluZyA9IGZhbHNlLFxyXG4gICAgcGF0aCxcclxuICAgIGxlZ2VuZERpc3BhdGNoZXIgPSBkMy5kaXNwYXRjaChcImNlbGxvdmVyXCIsIFwiY2VsbG91dFwiLCBcImNlbGxjbGlja1wiKTtcclxuXHJcbiAgICBmdW5jdGlvbiBsZWdlbmQoc3ZnKXtcclxuXHJcbiAgICAgIHZhciB0eXBlID0gaGVscGVyLmQzX2NhbGNUeXBlKHNjYWxlLCBhc2NlbmRpbmcsIGNlbGxzLCBsYWJlbHMsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlciksXHJcbiAgICAgICAgbGVnZW5kRyA9IHN2Zy5zZWxlY3RBbGwoJ2cnKS5kYXRhKFtzY2FsZV0pO1xyXG5cclxuICAgICAgbGVnZW5kRy5lbnRlcigpLmFwcGVuZCgnZycpLmF0dHIoJ2NsYXNzJywgY2xhc3NQcmVmaXggKyAnbGVnZW5kQ2VsbHMnKTtcclxuXHJcblxyXG4gICAgICB2YXIgY2VsbCA9IGxlZ2VuZEcuc2VsZWN0QWxsKFwiLlwiICsgY2xhc3NQcmVmaXggKyBcImNlbGxcIikuZGF0YSh0eXBlLmRhdGEpLFxyXG4gICAgICAgIGNlbGxFbnRlciA9IGNlbGwuZW50ZXIoKS5hcHBlbmQoXCJnXCIsIFwiLmNlbGxcIikuYXR0cihcImNsYXNzXCIsIGNsYXNzUHJlZml4ICsgXCJjZWxsXCIpLnN0eWxlKFwib3BhY2l0eVwiLCAxZS02KSxcclxuICAgICAgICBzaGFwZUVudGVyID0gY2VsbEVudGVyLmFwcGVuZChzaGFwZSkuYXR0cihcImNsYXNzXCIsIGNsYXNzUHJlZml4ICsgXCJzd2F0Y2hcIiksXHJcbiAgICAgICAgc2hhcGVzID0gY2VsbC5zZWxlY3QoXCJnLlwiICsgY2xhc3NQcmVmaXggKyBcImNlbGwgXCIgKyBzaGFwZSk7XHJcblxyXG4gICAgICAvL2FkZCBldmVudCBoYW5kbGVyc1xyXG4gICAgICBoZWxwZXIuZDNfYWRkRXZlbnRzKGNlbGxFbnRlciwgbGVnZW5kRGlzcGF0Y2hlcik7XHJcblxyXG4gICAgICBjZWxsLmV4aXQoKS50cmFuc2l0aW9uKCkuc3R5bGUoXCJvcGFjaXR5XCIsIDApLnJlbW92ZSgpO1xyXG5cclxuICAgICAgLy9jcmVhdGVzIHNoYXBlXHJcbiAgICAgIGlmIChzaGFwZSA9PT0gXCJsaW5lXCIpe1xyXG4gICAgICAgIGhlbHBlci5kM19kcmF3U2hhcGVzKHNoYXBlLCBzaGFwZXMsIDAsIHNoYXBlV2lkdGgpO1xyXG4gICAgICAgIHNoYXBlcy5hdHRyKFwic3Ryb2tlLXdpZHRoXCIsIHR5cGUuZmVhdHVyZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaGVscGVyLmQzX2RyYXdTaGFwZXMoc2hhcGUsIHNoYXBlcywgdHlwZS5mZWF0dXJlLCB0eXBlLmZlYXR1cmUsIHR5cGUuZmVhdHVyZSwgcGF0aCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGhlbHBlci5kM19hZGRUZXh0KGxlZ2VuZEcsIGNlbGxFbnRlciwgdHlwZS5sYWJlbHMsIGNsYXNzUHJlZml4KVxyXG5cclxuICAgICAgLy9zZXRzIHBsYWNlbWVudFxyXG4gICAgICB2YXIgdGV4dCA9IGNlbGwuc2VsZWN0KFwidGV4dFwiKSxcclxuICAgICAgICBzaGFwZVNpemUgPSBzaGFwZXNbMF0ubWFwKFxyXG4gICAgICAgICAgZnVuY3Rpb24oZCwgaSl7XHJcbiAgICAgICAgICAgIHZhciBiYm94ID0gZC5nZXRCQm94KClcclxuICAgICAgICAgICAgdmFyIHN0cm9rZSA9IHNjYWxlKHR5cGUuZGF0YVtpXSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2hhcGUgPT09IFwibGluZVwiICYmIG9yaWVudCA9PT0gXCJob3Jpem9udGFsXCIpIHtcclxuICAgICAgICAgICAgICBiYm94LmhlaWdodCA9IGJib3guaGVpZ2h0ICsgc3Ryb2tlO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNoYXBlID09PSBcImxpbmVcIiAmJiBvcmllbnQgPT09IFwidmVydGljYWxcIil7XHJcbiAgICAgICAgICAgICAgYmJveC53aWR0aCA9IGJib3gud2lkdGg7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBiYm94O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgdmFyIG1heEggPSBkMy5tYXgoc2hhcGVTaXplLCBmdW5jdGlvbihkKXsgcmV0dXJuIGQuaGVpZ2h0ICsgZC55OyB9KSxcclxuICAgICAgbWF4VyA9IGQzLm1heChzaGFwZVNpemUsIGZ1bmN0aW9uKGQpeyByZXR1cm4gZC53aWR0aCArIGQueDsgfSk7XHJcblxyXG4gICAgICB2YXIgY2VsbFRyYW5zLFxyXG4gICAgICB0ZXh0VHJhbnMsXHJcbiAgICAgIHRleHRBbGlnbiA9IChsYWJlbEFsaWduID09IFwic3RhcnRcIikgPyAwIDogKGxhYmVsQWxpZ24gPT0gXCJtaWRkbGVcIikgPyAwLjUgOiAxO1xyXG5cclxuICAgICAgLy9wb3NpdGlvbnMgY2VsbHMgYW5kIHRleHRcclxuICAgICAgaWYgKG9yaWVudCA9PT0gXCJ2ZXJ0aWNhbFwiKXtcclxuXHJcbiAgICAgICAgY2VsbFRyYW5zID0gZnVuY3Rpb24oZCxpKSB7XHJcbiAgICAgICAgICAgIHZhciBoZWlnaHQgPSBkMy5zdW0oc2hhcGVTaXplLnNsaWNlKDAsIGkgKyAxICksIGZ1bmN0aW9uKGQpeyByZXR1cm4gZC5oZWlnaHQ7IH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gXCJ0cmFuc2xhdGUoMCwgXCIgKyAoaGVpZ2h0ICsgaSpzaGFwZVBhZGRpbmcpICsgXCIpXCI7IH07XHJcblxyXG4gICAgICAgIHRleHRUcmFucyA9IGZ1bmN0aW9uKGQsaSkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyAobWF4VyArIGxhYmVsT2Zmc2V0KSArIFwiLFwiICtcclxuICAgICAgICAgIChzaGFwZVNpemVbaV0ueSArIHNoYXBlU2l6ZVtpXS5oZWlnaHQvMiArIDUpICsgXCIpXCI7IH07XHJcblxyXG4gICAgICB9IGVsc2UgaWYgKG9yaWVudCA9PT0gXCJob3Jpem9udGFsXCIpe1xyXG4gICAgICAgIGNlbGxUcmFucyA9IGZ1bmN0aW9uKGQsaSkge1xyXG4gICAgICAgICAgICB2YXIgd2lkdGggPSBkMy5zdW0oc2hhcGVTaXplLnNsaWNlKDAsIGkgKyAxICksIGZ1bmN0aW9uKGQpeyByZXR1cm4gZC53aWR0aDsgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiBcInRyYW5zbGF0ZShcIiArICh3aWR0aCArIGkqc2hhcGVQYWRkaW5nKSArIFwiLDApXCI7IH07XHJcblxyXG4gICAgICAgIHRleHRUcmFucyA9IGZ1bmN0aW9uKGQsaSkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyAoc2hhcGVTaXplW2ldLndpZHRoKnRleHRBbGlnbiAgKyBzaGFwZVNpemVbaV0ueCkgKyBcIixcIiArXHJcbiAgICAgICAgICAgICAgKG1heEggKyBsYWJlbE9mZnNldCApICsgXCIpXCI7IH07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGhlbHBlci5kM19wbGFjZW1lbnQob3JpZW50LCBjZWxsLCBjZWxsVHJhbnMsIHRleHQsIHRleHRUcmFucywgbGFiZWxBbGlnbik7XHJcbiAgICAgIGhlbHBlci5kM190aXRsZShzdmcsIGxlZ2VuZEcsIHRpdGxlLCBjbGFzc1ByZWZpeCk7XHJcblxyXG4gICAgICBjZWxsLnRyYW5zaXRpb24oKS5zdHlsZShcIm9wYWNpdHlcIiwgMSk7XHJcblxyXG4gICAgfVxyXG5cclxuICBsZWdlbmQuc2NhbGUgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzY2FsZTtcclxuICAgIHNjYWxlID0gXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmNlbGxzID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2VsbHM7XHJcbiAgICBpZiAoXy5sZW5ndGggPiAxIHx8IF8gPj0gMiApe1xyXG4gICAgICBjZWxscyA9IF87XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG5cclxuICBsZWdlbmQuc2hhcGUgPSBmdW5jdGlvbihfLCBkKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzaGFwZTtcclxuICAgIGlmIChfID09IFwicmVjdFwiIHx8IF8gPT0gXCJjaXJjbGVcIiB8fCBfID09IFwibGluZVwiICl7XHJcbiAgICAgIHNoYXBlID0gXztcclxuICAgICAgcGF0aCA9IGQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5zaGFwZVdpZHRoID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2hhcGVXaWR0aDtcclxuICAgIHNoYXBlV2lkdGggPSArXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnNoYXBlUGFkZGluZyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNoYXBlUGFkZGluZztcclxuICAgIHNoYXBlUGFkZGluZyA9ICtfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxzID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGFiZWxzO1xyXG4gICAgbGFiZWxzID0gXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmxhYmVsQWxpZ24gPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbEFsaWduO1xyXG4gICAgaWYgKF8gPT0gXCJzdGFydFwiIHx8IF8gPT0gXCJlbmRcIiB8fCBfID09IFwibWlkZGxlXCIpIHtcclxuICAgICAgbGFiZWxBbGlnbiA9IF87XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbEZvcm1hdCA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsRm9ybWF0O1xyXG4gICAgbGFiZWxGb3JtYXQgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxPZmZzZXQgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbE9mZnNldDtcclxuICAgIGxhYmVsT2Zmc2V0ID0gK187XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbERlbGltaXRlciA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsRGVsaW1pdGVyO1xyXG4gICAgbGFiZWxEZWxpbWl0ZXIgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQub3JpZW50ID0gZnVuY3Rpb24oXyl7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBvcmllbnQ7XHJcbiAgICBfID0gXy50b0xvd2VyQ2FzZSgpO1xyXG4gICAgaWYgKF8gPT0gXCJob3Jpem9udGFsXCIgfHwgXyA9PSBcInZlcnRpY2FsXCIpIHtcclxuICAgICAgb3JpZW50ID0gXztcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmFzY2VuZGluZyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGFzY2VuZGluZztcclxuICAgIGFzY2VuZGluZyA9ICEhXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmNsYXNzUHJlZml4ID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2xhc3NQcmVmaXg7XHJcbiAgICBjbGFzc1ByZWZpeCA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC50aXRsZSA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRpdGxlO1xyXG4gICAgdGl0bGUgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBkMy5yZWJpbmQobGVnZW5kLCBsZWdlbmREaXNwYXRjaGVyLCBcIm9uXCIpO1xyXG5cclxuICByZXR1cm4gbGVnZW5kO1xyXG5cclxufTtcclxuIiwidmFyIGhlbHBlciA9IHJlcXVpcmUoJy4vbGVnZW5kJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCl7XHJcblxyXG4gIHZhciBzY2FsZSA9IGQzLnNjYWxlLmxpbmVhcigpLFxyXG4gICAgc2hhcGUgPSBcInBhdGhcIixcclxuICAgIHNoYXBlV2lkdGggPSAxNSxcclxuICAgIHNoYXBlSGVpZ2h0ID0gMTUsXHJcbiAgICBzaGFwZVJhZGl1cyA9IDEwLFxyXG4gICAgc2hhcGVQYWRkaW5nID0gNSxcclxuICAgIGNlbGxzID0gWzVdLFxyXG4gICAgbGFiZWxzID0gW10sXHJcbiAgICBjbGFzc1ByZWZpeCA9IFwiXCIsXHJcbiAgICB1c2VDbGFzcyA9IGZhbHNlLFxyXG4gICAgdGl0bGUgPSBcIlwiLFxyXG4gICAgbGFiZWxGb3JtYXQgPSBkMy5mb3JtYXQoXCIuMDFmXCIpLFxyXG4gICAgbGFiZWxBbGlnbiA9IFwibWlkZGxlXCIsXHJcbiAgICBsYWJlbE9mZnNldCA9IDEwLFxyXG4gICAgbGFiZWxEZWxpbWl0ZXIgPSBcInRvXCIsXHJcbiAgICBvcmllbnQgPSBcInZlcnRpY2FsXCIsXHJcbiAgICBhc2NlbmRpbmcgPSBmYWxzZSxcclxuICAgIGxlZ2VuZERpc3BhdGNoZXIgPSBkMy5kaXNwYXRjaChcImNlbGxvdmVyXCIsIFwiY2VsbG91dFwiLCBcImNlbGxjbGlja1wiKTtcclxuXHJcbiAgICBmdW5jdGlvbiBsZWdlbmQoc3ZnKXtcclxuXHJcbiAgICAgIHZhciB0eXBlID0gaGVscGVyLmQzX2NhbGNUeXBlKHNjYWxlLCBhc2NlbmRpbmcsIGNlbGxzLCBsYWJlbHMsIGxhYmVsRm9ybWF0LCBsYWJlbERlbGltaXRlciksXHJcbiAgICAgICAgbGVnZW5kRyA9IHN2Zy5zZWxlY3RBbGwoJ2cnKS5kYXRhKFtzY2FsZV0pO1xyXG5cclxuICAgICAgbGVnZW5kRy5lbnRlcigpLmFwcGVuZCgnZycpLmF0dHIoJ2NsYXNzJywgY2xhc3NQcmVmaXggKyAnbGVnZW5kQ2VsbHMnKTtcclxuXHJcbiAgICAgIHZhciBjZWxsID0gbGVnZW5kRy5zZWxlY3RBbGwoXCIuXCIgKyBjbGFzc1ByZWZpeCArIFwiY2VsbFwiKS5kYXRhKHR5cGUuZGF0YSksXHJcbiAgICAgICAgY2VsbEVudGVyID0gY2VsbC5lbnRlcigpLmFwcGVuZChcImdcIiwgXCIuY2VsbFwiKS5hdHRyKFwiY2xhc3NcIiwgY2xhc3NQcmVmaXggKyBcImNlbGxcIikuc3R5bGUoXCJvcGFjaXR5XCIsIDFlLTYpLFxyXG4gICAgICAgIHNoYXBlRW50ZXIgPSBjZWxsRW50ZXIuYXBwZW5kKHNoYXBlKS5hdHRyKFwiY2xhc3NcIiwgY2xhc3NQcmVmaXggKyBcInN3YXRjaFwiKSxcclxuICAgICAgICBzaGFwZXMgPSBjZWxsLnNlbGVjdChcImcuXCIgKyBjbGFzc1ByZWZpeCArIFwiY2VsbCBcIiArIHNoYXBlKTtcclxuXHJcbiAgICAgIC8vYWRkIGV2ZW50IGhhbmRsZXJzXHJcbiAgICAgIGhlbHBlci5kM19hZGRFdmVudHMoY2VsbEVudGVyLCBsZWdlbmREaXNwYXRjaGVyKTtcclxuXHJcbiAgICAgIC8vcmVtb3ZlIG9sZCBzaGFwZXNcclxuICAgICAgY2VsbC5leGl0KCkudHJhbnNpdGlvbigpLnN0eWxlKFwib3BhY2l0eVwiLCAwKS5yZW1vdmUoKTtcclxuXHJcbiAgICAgIGhlbHBlci5kM19kcmF3U2hhcGVzKHNoYXBlLCBzaGFwZXMsIHNoYXBlSGVpZ2h0LCBzaGFwZVdpZHRoLCBzaGFwZVJhZGl1cywgdHlwZS5mZWF0dXJlKTtcclxuICAgICAgaGVscGVyLmQzX2FkZFRleHQobGVnZW5kRywgY2VsbEVudGVyLCB0eXBlLmxhYmVscywgY2xhc3NQcmVmaXgpXHJcblxyXG4gICAgICAvLyBzZXRzIHBsYWNlbWVudFxyXG4gICAgICB2YXIgdGV4dCA9IGNlbGwuc2VsZWN0KFwidGV4dFwiKSxcclxuICAgICAgICBzaGFwZVNpemUgPSBzaGFwZXNbMF0ubWFwKCBmdW5jdGlvbihkKXsgcmV0dXJuIGQuZ2V0QkJveCgpOyB9KTtcclxuXHJcbiAgICAgIHZhciBtYXhIID0gZDMubWF4KHNoYXBlU2l6ZSwgZnVuY3Rpb24oZCl7IHJldHVybiBkLmhlaWdodDsgfSksXHJcbiAgICAgIG1heFcgPSBkMy5tYXgoc2hhcGVTaXplLCBmdW5jdGlvbihkKXsgcmV0dXJuIGQud2lkdGg7IH0pO1xyXG5cclxuICAgICAgdmFyIGNlbGxUcmFucyxcclxuICAgICAgdGV4dFRyYW5zLFxyXG4gICAgICB0ZXh0QWxpZ24gPSAobGFiZWxBbGlnbiA9PSBcInN0YXJ0XCIpID8gMCA6IChsYWJlbEFsaWduID09IFwibWlkZGxlXCIpID8gMC41IDogMTtcclxuXHJcbiAgICAgIC8vcG9zaXRpb25zIGNlbGxzIGFuZCB0ZXh0XHJcbiAgICAgIGlmIChvcmllbnQgPT09IFwidmVydGljYWxcIil7XHJcbiAgICAgICAgY2VsbFRyYW5zID0gZnVuY3Rpb24oZCxpKSB7IHJldHVybiBcInRyYW5zbGF0ZSgwLCBcIiArIChpICogKG1heEggKyBzaGFwZVBhZGRpbmcpKSArIFwiKVwiOyB9O1xyXG4gICAgICAgIHRleHRUcmFucyA9IGZ1bmN0aW9uKGQsaSkgeyByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyAobWF4VyArIGxhYmVsT2Zmc2V0KSArIFwiLFwiICtcclxuICAgICAgICAgICAgICAoc2hhcGVTaXplW2ldLnkgKyBzaGFwZVNpemVbaV0uaGVpZ2h0LzIgKyA1KSArIFwiKVwiOyB9O1xyXG5cclxuICAgICAgfSBlbHNlIGlmIChvcmllbnQgPT09IFwiaG9yaXpvbnRhbFwiKXtcclxuICAgICAgICBjZWxsVHJhbnMgPSBmdW5jdGlvbihkLGkpIHsgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgKGkgKiAobWF4VyArIHNoYXBlUGFkZGluZykpICsgXCIsMClcIjsgfTtcclxuICAgICAgICB0ZXh0VHJhbnMgPSBmdW5jdGlvbihkLGkpIHsgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgKHNoYXBlU2l6ZVtpXS53aWR0aCp0ZXh0QWxpZ24gICsgc2hhcGVTaXplW2ldLngpICsgXCIsXCIgK1xyXG4gICAgICAgICAgICAgIChtYXhIICsgbGFiZWxPZmZzZXQgKSArIFwiKVwiOyB9O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBoZWxwZXIuZDNfcGxhY2VtZW50KG9yaWVudCwgY2VsbCwgY2VsbFRyYW5zLCB0ZXh0LCB0ZXh0VHJhbnMsIGxhYmVsQWxpZ24pO1xyXG4gICAgICBoZWxwZXIuZDNfdGl0bGUoc3ZnLCBsZWdlbmRHLCB0aXRsZSwgY2xhc3NQcmVmaXgpO1xyXG4gICAgICBjZWxsLnRyYW5zaXRpb24oKS5zdHlsZShcIm9wYWNpdHlcIiwgMSk7XHJcblxyXG4gICAgfVxyXG5cclxuXHJcbiAgbGVnZW5kLnNjYWxlID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2NhbGU7XHJcbiAgICBzY2FsZSA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5jZWxscyA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGNlbGxzO1xyXG4gICAgaWYgKF8ubGVuZ3RoID4gMSB8fCBfID49IDIgKXtcclxuICAgICAgY2VsbHMgPSBfO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuc2hhcGVQYWRkaW5nID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2hhcGVQYWRkaW5nO1xyXG4gICAgc2hhcGVQYWRkaW5nID0gK187XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbHMgPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsYWJlbHM7XHJcbiAgICBsYWJlbHMgPSBfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQubGFiZWxBbGlnbiA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsQWxpZ247XHJcbiAgICBpZiAoXyA9PSBcInN0YXJ0XCIgfHwgXyA9PSBcImVuZFwiIHx8IF8gPT0gXCJtaWRkbGVcIikge1xyXG4gICAgICBsYWJlbEFsaWduID0gXztcclxuICAgIH1cclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmxhYmVsRm9ybWF0ID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGFiZWxGb3JtYXQ7XHJcbiAgICBsYWJlbEZvcm1hdCA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5sYWJlbE9mZnNldCA9IGZ1bmN0aW9uKF8pIHtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxhYmVsT2Zmc2V0O1xyXG4gICAgbGFiZWxPZmZzZXQgPSArXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLmxhYmVsRGVsaW1pdGVyID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGFiZWxEZWxpbWl0ZXI7XHJcbiAgICBsYWJlbERlbGltaXRlciA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGxlZ2VuZC5vcmllbnQgPSBmdW5jdGlvbihfKXtcclxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIG9yaWVudDtcclxuICAgIF8gPSBfLnRvTG93ZXJDYXNlKCk7XHJcbiAgICBpZiAoXyA9PSBcImhvcml6b250YWxcIiB8fCBfID09IFwidmVydGljYWxcIikge1xyXG4gICAgICBvcmllbnQgPSBfO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuYXNjZW5kaW5nID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gYXNjZW5kaW5nO1xyXG4gICAgYXNjZW5kaW5nID0gISFfO1xyXG4gICAgcmV0dXJuIGxlZ2VuZDtcclxuICB9O1xyXG5cclxuICBsZWdlbmQuY2xhc3NQcmVmaXggPSBmdW5jdGlvbihfKSB7XHJcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBjbGFzc1ByZWZpeDtcclxuICAgIGNsYXNzUHJlZml4ID0gXztcclxuICAgIHJldHVybiBsZWdlbmQ7XHJcbiAgfTtcclxuXHJcbiAgbGVnZW5kLnRpdGxlID0gZnVuY3Rpb24oXykge1xyXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGl0bGU7XHJcbiAgICB0aXRsZSA9IF87XHJcbiAgICByZXR1cm4gbGVnZW5kO1xyXG4gIH07XHJcblxyXG4gIGQzLnJlYmluZChsZWdlbmQsIGxlZ2VuZERpc3BhdGNoZXIsIFwib25cIik7XHJcblxyXG4gIHJldHVybiBsZWdlbmQ7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG4vKipcclxuICogKipbR2F1c3NpYW4gZXJyb3IgZnVuY3Rpb25dKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRXJyb3JfZnVuY3Rpb24pKipcclxuICpcclxuICogVGhlIGBlcnJvckZ1bmN0aW9uKHgvKHNkICogTWF0aC5zcXJ0KDIpKSlgIGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGEgdmFsdWUgaW4gYVxyXG4gKiBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGggc3RhbmRhcmQgZGV2aWF0aW9uIHNkIGlzIHdpdGhpbiB4IG9mIHRoZSBtZWFuLlxyXG4gKlxyXG4gKiBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYSBudW1lcmljYWwgYXBwcm94aW1hdGlvbiB0byB0aGUgZXhhY3QgdmFsdWUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IGlucHV0XHJcbiAqIEByZXR1cm4ge251bWJlcn0gZXJyb3IgZXN0aW1hdGlvblxyXG4gKiBAZXhhbXBsZVxyXG4gKiBlcnJvckZ1bmN0aW9uKDEpOyAvLz0gMC44NDI3XHJcbiAqL1xyXG5mdW5jdGlvbiBlcnJvckZ1bmN0aW9uKHgvKjogbnVtYmVyICovKS8qOiBudW1iZXIgKi8ge1xyXG4gICAgdmFyIHQgPSAxIC8gKDEgKyAwLjUgKiBNYXRoLmFicyh4KSk7XHJcbiAgICB2YXIgdGF1ID0gdCAqIE1hdGguZXhwKC1NYXRoLnBvdyh4LCAyKSAtXHJcbiAgICAgICAgMS4yNjU1MTIyMyArXHJcbiAgICAgICAgMS4wMDAwMjM2OCAqIHQgK1xyXG4gICAgICAgIDAuMzc0MDkxOTYgKiBNYXRoLnBvdyh0LCAyKSArXHJcbiAgICAgICAgMC4wOTY3ODQxOCAqIE1hdGgucG93KHQsIDMpIC1cclxuICAgICAgICAwLjE4NjI4ODA2ICogTWF0aC5wb3codCwgNCkgK1xyXG4gICAgICAgIDAuMjc4ODY4MDcgKiBNYXRoLnBvdyh0LCA1KSAtXHJcbiAgICAgICAgMS4xMzUyMDM5OCAqIE1hdGgucG93KHQsIDYpICtcclxuICAgICAgICAxLjQ4ODUxNTg3ICogTWF0aC5wb3codCwgNykgLVxyXG4gICAgICAgIDAuODIyMTUyMjMgKiBNYXRoLnBvdyh0LCA4KSArXHJcbiAgICAgICAgMC4xNzA4NzI3NyAqIE1hdGgucG93KHQsIDkpKTtcclxuICAgIGlmICh4ID49IDApIHtcclxuICAgICAgICByZXR1cm4gMSAtIHRhdTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHRhdSAtIDE7XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZXJyb3JGdW5jdGlvbjtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG4vKiBAZmxvdyAqL1xyXG5cclxuLyoqXHJcbiAqIFtTaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb25dKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU2ltcGxlX2xpbmVhcl9yZWdyZXNzaW9uKVxyXG4gKiBpcyBhIHNpbXBsZSB3YXkgdG8gZmluZCBhIGZpdHRlZCBsaW5lXHJcbiAqIGJldHdlZW4gYSBzZXQgb2YgY29vcmRpbmF0ZXMuIFRoaXMgYWxnb3JpdGhtIGZpbmRzIHRoZSBzbG9wZSBhbmQgeS1pbnRlcmNlcHQgb2YgYSByZWdyZXNzaW9uIGxpbmVcclxuICogdXNpbmcgdGhlIGxlYXN0IHN1bSBvZiBzcXVhcmVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBkYXRhIGFuIGFycmF5IG9mIHR3by1lbGVtZW50IG9mIGFycmF5cyxcclxuICogbGlrZSBgW1swLCAxXSwgWzIsIDNdXWBcclxuICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IGNvbnRhaW5pbmcgc2xvcGUgYW5kIGludGVyc2VjdCBvZiByZWdyZXNzaW9uIGxpbmVcclxuICogQGV4YW1wbGVcclxuICogbGluZWFyUmVncmVzc2lvbihbWzAsIDBdLCBbMSwgMV1dKTsgLy8geyBtOiAxLCBiOiAwIH1cclxuICovXHJcbmZ1bmN0aW9uIGxpbmVhclJlZ3Jlc3Npb24oZGF0YS8qOiBBcnJheTxBcnJheTxudW1iZXI+PiAqLykvKjogeyBtOiBudW1iZXIsIGI6IG51bWJlciB9ICovIHtcclxuXHJcbiAgICB2YXIgbSwgYjtcclxuXHJcbiAgICAvLyBTdG9yZSBkYXRhIGxlbmd0aCBpbiBhIGxvY2FsIHZhcmlhYmxlIHRvIHJlZHVjZVxyXG4gICAgLy8gcmVwZWF0ZWQgb2JqZWN0IHByb3BlcnR5IGxvb2t1cHNcclxuICAgIHZhciBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGg7XHJcblxyXG4gICAgLy9pZiB0aGVyZSdzIG9ubHkgb25lIHBvaW50LCBhcmJpdHJhcmlseSBjaG9vc2UgYSBzbG9wZSBvZiAwXHJcbiAgICAvL2FuZCBhIHktaW50ZXJjZXB0IG9mIHdoYXRldmVyIHRoZSB5IG9mIHRoZSBpbml0aWFsIHBvaW50IGlzXHJcbiAgICBpZiAoZGF0YUxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgIG0gPSAwO1xyXG4gICAgICAgIGIgPSBkYXRhWzBdWzFdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBJbml0aWFsaXplIG91ciBzdW1zIGFuZCBzY29wZSB0aGUgYG1gIGFuZCBgYmBcclxuICAgICAgICAvLyB2YXJpYWJsZXMgdGhhdCBkZWZpbmUgdGhlIGxpbmUuXHJcbiAgICAgICAgdmFyIHN1bVggPSAwLCBzdW1ZID0gMCxcclxuICAgICAgICAgICAgc3VtWFggPSAwLCBzdW1YWSA9IDA7XHJcblxyXG4gICAgICAgIC8vIFVzZSBsb2NhbCB2YXJpYWJsZXMgdG8gZ3JhYiBwb2ludCB2YWx1ZXNcclxuICAgICAgICAvLyB3aXRoIG1pbmltYWwgb2JqZWN0IHByb3BlcnR5IGxvb2t1cHNcclxuICAgICAgICB2YXIgcG9pbnQsIHgsIHk7XHJcblxyXG4gICAgICAgIC8vIEdhdGhlciB0aGUgc3VtIG9mIGFsbCB4IHZhbHVlcywgdGhlIHN1bSBvZiBhbGxcclxuICAgICAgICAvLyB5IHZhbHVlcywgYW5kIHRoZSBzdW0gb2YgeF4yIGFuZCAoeCp5KSBmb3IgZWFjaFxyXG4gICAgICAgIC8vIHZhbHVlLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gSW4gbWF0aCBub3RhdGlvbiwgdGhlc2Ugd291bGQgYmUgU1NfeCwgU1NfeSwgU1NfeHgsIGFuZCBTU194eVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHBvaW50ID0gZGF0YVtpXTtcclxuICAgICAgICAgICAgeCA9IHBvaW50WzBdO1xyXG4gICAgICAgICAgICB5ID0gcG9pbnRbMV07XHJcblxyXG4gICAgICAgICAgICBzdW1YICs9IHg7XHJcbiAgICAgICAgICAgIHN1bVkgKz0geTtcclxuXHJcbiAgICAgICAgICAgIHN1bVhYICs9IHggKiB4O1xyXG4gICAgICAgICAgICBzdW1YWSArPSB4ICogeTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGBtYCBpcyB0aGUgc2xvcGUgb2YgdGhlIHJlZ3Jlc3Npb24gbGluZVxyXG4gICAgICAgIG0gPSAoKGRhdGFMZW5ndGggKiBzdW1YWSkgLSAoc3VtWCAqIHN1bVkpKSAvXHJcbiAgICAgICAgICAgICgoZGF0YUxlbmd0aCAqIHN1bVhYKSAtIChzdW1YICogc3VtWCkpO1xyXG5cclxuICAgICAgICAvLyBgYmAgaXMgdGhlIHktaW50ZXJjZXB0IG9mIHRoZSBsaW5lLlxyXG4gICAgICAgIGIgPSAoc3VtWSAvIGRhdGFMZW5ndGgpIC0gKChtICogc3VtWCkgLyBkYXRhTGVuZ3RoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZXR1cm4gYm90aCB2YWx1ZXMgYXMgYW4gb2JqZWN0LlxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBtOiBtLFxyXG4gICAgICAgIGI6IGJcclxuICAgIH07XHJcbn1cclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGxpbmVhclJlZ3Jlc3Npb247XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbi8qKlxyXG4gKiBHaXZlbiB0aGUgb3V0cHV0IG9mIGBsaW5lYXJSZWdyZXNzaW9uYDogYW4gb2JqZWN0XHJcbiAqIHdpdGggYG1gIGFuZCBgYmAgdmFsdWVzIGluZGljYXRpbmcgc2xvcGUgYW5kIGludGVyY2VwdCxcclxuICogcmVzcGVjdGl2ZWx5LCBnZW5lcmF0ZSBhIGxpbmUgZnVuY3Rpb24gdGhhdCB0cmFuc2xhdGVzXHJcbiAqIHggdmFsdWVzIGludG8geSB2YWx1ZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYiBvYmplY3Qgd2l0aCBgbWAgYW5kIGBiYCBtZW1iZXJzLCByZXByZXNlbnRpbmdcclxuICogc2xvcGUgYW5kIGludGVyc2VjdCBvZiBkZXNpcmVkIGxpbmVcclxuICogQHJldHVybnMge0Z1bmN0aW9ufSBtZXRob2QgdGhhdCBjb21wdXRlcyB5LXZhbHVlIGF0IGFueSBnaXZlblxyXG4gKiB4LXZhbHVlIG9uIHRoZSBsaW5lLlxyXG4gKiBAZXhhbXBsZVxyXG4gKiB2YXIgbCA9IGxpbmVhclJlZ3Jlc3Npb25MaW5lKGxpbmVhclJlZ3Jlc3Npb24oW1swLCAwXSwgWzEsIDFdXSkpO1xyXG4gKiBsKDApIC8vPSAwXHJcbiAqIGwoMikgLy89IDJcclxuICovXHJcbmZ1bmN0aW9uIGxpbmVhclJlZ3Jlc3Npb25MaW5lKG1iLyo6IHsgYjogbnVtYmVyLCBtOiBudW1iZXIgfSovKS8qOiBGdW5jdGlvbiAqLyB7XHJcbiAgICAvLyBSZXR1cm4gYSBmdW5jdGlvbiB0aGF0IGNvbXB1dGVzIGEgYHlgIHZhbHVlIGZvciBlYWNoXHJcbiAgICAvLyB4IHZhbHVlIGl0IGlzIGdpdmVuLCBiYXNlZCBvbiB0aGUgdmFsdWVzIG9mIGBiYCBhbmQgYGFgXHJcbiAgICAvLyB0aGF0IHdlIGp1c3QgY29tcHV0ZWQuXHJcbiAgICByZXR1cm4gZnVuY3Rpb24oeCkge1xyXG4gICAgICAgIHJldHVybiBtYi5iICsgKG1iLm0gKiB4KTtcclxuICAgIH07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluZWFyUmVncmVzc2lvbkxpbmU7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbnZhciBzdW0gPSByZXF1aXJlKCcuL3N1bScpO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBtZWFuLCBfYWxzbyBrbm93biBhcyBhdmVyYWdlXyxcclxuICogaXMgdGhlIHN1bSBvZiBhbGwgdmFsdWVzIG92ZXIgdGhlIG51bWJlciBvZiB2YWx1ZXMuXHJcbiAqIFRoaXMgaXMgYSBbbWVhc3VyZSBvZiBjZW50cmFsIHRlbmRlbmN5XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9DZW50cmFsX3RlbmRlbmN5KTpcclxuICogYSBtZXRob2Qgb2YgZmluZGluZyBhIHR5cGljYWwgb3IgY2VudHJhbCB2YWx1ZSBvZiBhIHNldCBvZiBudW1iZXJzLlxyXG4gKlxyXG4gKiBUaGlzIHJ1bnMgb24gYE8obilgLCBsaW5lYXIgdGltZSBpbiByZXNwZWN0IHRvIHRoZSBhcnJheVxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHggaW5wdXQgdmFsdWVzXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IG1lYW5cclxuICogQGV4YW1wbGVcclxuICogY29uc29sZS5sb2cobWVhbihbMCwgMTBdKSk7IC8vIDVcclxuICovXHJcbmZ1bmN0aW9uIG1lYW4oeCAvKjogQXJyYXk8bnVtYmVyPiAqLykvKjpudW1iZXIqLyB7XHJcbiAgICAvLyBUaGUgbWVhbiBvZiBubyBudW1iZXJzIGlzIG51bGxcclxuICAgIGlmICh4Lmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gTmFOOyB9XHJcblxyXG4gICAgcmV0dXJuIHN1bSh4KSAvIHgubGVuZ3RoO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IG1lYW47XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbnZhciBzYW1wbGVDb3ZhcmlhbmNlID0gcmVxdWlyZSgnLi9zYW1wbGVfY292YXJpYW5jZScpO1xyXG52YXIgc2FtcGxlU3RhbmRhcmREZXZpYXRpb24gPSByZXF1aXJlKCcuL3NhbXBsZV9zdGFuZGFyZF9kZXZpYXRpb24nKTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgW2NvcnJlbGF0aW9uXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvcnJlbGF0aW9uX2FuZF9kZXBlbmRlbmNlKSBpc1xyXG4gKiBhIG1lYXN1cmUgb2YgaG93IGNvcnJlbGF0ZWQgdHdvIGRhdGFzZXRzIGFyZSwgYmV0d2VlbiAtMSBhbmQgMVxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHggZmlyc3QgaW5wdXRcclxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSB5IHNlY29uZCBpbnB1dFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBzYW1wbGUgY29ycmVsYXRpb25cclxuICogQGV4YW1wbGVcclxuICogdmFyIGEgPSBbMSwgMiwgMywgNCwgNSwgNl07XHJcbiAqIHZhciBiID0gWzIsIDIsIDMsIDQsIDUsIDYwXTtcclxuICogc2FtcGxlQ29ycmVsYXRpb24oYSwgYik7IC8vPSAwLjY5MVxyXG4gKi9cclxuZnVuY3Rpb24gc2FtcGxlQ29ycmVsYXRpb24oeC8qOiBBcnJheTxudW1iZXI+ICovLCB5Lyo6IEFycmF5PG51bWJlcj4gKi8pLyo6bnVtYmVyKi8ge1xyXG4gICAgdmFyIGNvdiA9IHNhbXBsZUNvdmFyaWFuY2UoeCwgeSksXHJcbiAgICAgICAgeHN0ZCA9IHNhbXBsZVN0YW5kYXJkRGV2aWF0aW9uKHgpLFxyXG4gICAgICAgIHlzdGQgPSBzYW1wbGVTdGFuZGFyZERldmlhdGlvbih5KTtcclxuXHJcbiAgICByZXR1cm4gY292IC8geHN0ZCAvIHlzdGQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2FtcGxlQ29ycmVsYXRpb247XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbnZhciBtZWFuID0gcmVxdWlyZSgnLi9tZWFuJyk7XHJcblxyXG4vKipcclxuICogW1NhbXBsZSBjb3ZhcmlhbmNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TYW1wbGVfbWVhbl9hbmRfc2FtcGxlQ292YXJpYW5jZSkgb2YgdHdvIGRhdGFzZXRzOlxyXG4gKiBob3cgbXVjaCBkbyB0aGUgdHdvIGRhdGFzZXRzIG1vdmUgdG9nZXRoZXI/XHJcbiAqIHggYW5kIHkgYXJlIHR3byBkYXRhc2V0cywgcmVwcmVzZW50ZWQgYXMgYXJyYXlzIG9mIG51bWJlcnMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBmaXJzdCBpbnB1dFxyXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHkgc2Vjb25kIGlucHV0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IHNhbXBsZSBjb3ZhcmlhbmNlXHJcbiAqIEBleGFtcGxlXHJcbiAqIHZhciB4ID0gWzEsIDIsIDMsIDQsIDUsIDZdO1xyXG4gKiB2YXIgeSA9IFs2LCA1LCA0LCAzLCAyLCAxXTtcclxuICogc2FtcGxlQ292YXJpYW5jZSh4LCB5KTsgLy89IC0zLjVcclxuICovXHJcbmZ1bmN0aW9uIHNhbXBsZUNvdmFyaWFuY2UoeCAvKjpBcnJheTxudW1iZXI+Ki8sIHkgLyo6QXJyYXk8bnVtYmVyPiovKS8qOm51bWJlciovIHtcclxuXHJcbiAgICAvLyBUaGUgdHdvIGRhdGFzZXRzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGggd2hpY2ggbXVzdCBiZSBtb3JlIHRoYW4gMVxyXG4gICAgaWYgKHgubGVuZ3RoIDw9IDEgfHwgeC5sZW5ndGggIT09IHkubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIE5hTjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBkZXRlcm1pbmUgdGhlIG1lYW4gb2YgZWFjaCBkYXRhc2V0IHNvIHRoYXQgd2UgY2FuIGp1ZGdlIGVhY2hcclxuICAgIC8vIHZhbHVlIG9mIHRoZSBkYXRhc2V0IGZhaXJseSBhcyB0aGUgZGlmZmVyZW5jZSBmcm9tIHRoZSBtZWFuLiB0aGlzXHJcbiAgICAvLyB3YXksIGlmIG9uZSBkYXRhc2V0IGlzIFsxLCAyLCAzXSBhbmQgWzIsIDMsIDRdLCB0aGVpciBjb3ZhcmlhbmNlXHJcbiAgICAvLyBkb2VzIG5vdCBzdWZmZXIgYmVjYXVzZSBvZiB0aGUgZGlmZmVyZW5jZSBpbiBhYnNvbHV0ZSB2YWx1ZXNcclxuICAgIHZhciB4bWVhbiA9IG1lYW4oeCksXHJcbiAgICAgICAgeW1lYW4gPSBtZWFuKHkpLFxyXG4gICAgICAgIHN1bSA9IDA7XHJcblxyXG4gICAgLy8gZm9yIGVhY2ggcGFpciBvZiB2YWx1ZXMsIHRoZSBjb3ZhcmlhbmNlIGluY3JlYXNlcyB3aGVuIHRoZWlyXHJcbiAgICAvLyBkaWZmZXJlbmNlIGZyb20gdGhlIG1lYW4gaXMgYXNzb2NpYXRlZCAtIGlmIGJvdGggYXJlIHdlbGwgYWJvdmVcclxuICAgIC8vIG9yIGlmIGJvdGggYXJlIHdlbGwgYmVsb3dcclxuICAgIC8vIHRoZSBtZWFuLCB0aGUgY292YXJpYW5jZSBpbmNyZWFzZXMgc2lnbmlmaWNhbnRseS5cclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHN1bSArPSAoeFtpXSAtIHhtZWFuKSAqICh5W2ldIC0geW1lYW4pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHRoaXMgaXMgQmVzc2VscycgQ29ycmVjdGlvbjogYW4gYWRqdXN0bWVudCBtYWRlIHRvIHNhbXBsZSBzdGF0aXN0aWNzXHJcbiAgICAvLyB0aGF0IGFsbG93cyBmb3IgdGhlIHJlZHVjZWQgZGVncmVlIG9mIGZyZWVkb20gZW50YWlsZWQgaW4gY2FsY3VsYXRpbmdcclxuICAgIC8vIHZhbHVlcyBmcm9tIHNhbXBsZXMgcmF0aGVyIHRoYW4gY29tcGxldGUgcG9wdWxhdGlvbnMuXHJcbiAgICB2YXIgYmVzc2Vsc0NvcnJlY3Rpb24gPSB4Lmxlbmd0aCAtIDE7XHJcblxyXG4gICAgLy8gdGhlIGNvdmFyaWFuY2UgaXMgd2VpZ2h0ZWQgYnkgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YXNldHMuXHJcbiAgICByZXR1cm4gc3VtIC8gYmVzc2Vsc0NvcnJlY3Rpb247XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2FtcGxlQ292YXJpYW5jZTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG4vKiBAZmxvdyAqL1xyXG5cclxudmFyIHNhbXBsZVZhcmlhbmNlID0gcmVxdWlyZSgnLi9zYW1wbGVfdmFyaWFuY2UnKTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgW3N0YW5kYXJkIGRldmlhdGlvbl0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdGFuZGFyZF9kZXZpYXRpb24pXHJcbiAqIGlzIHRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgdmFyaWFuY2UuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBpbnB1dCBhcnJheVxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBzYW1wbGUgc3RhbmRhcmQgZGV2aWF0aW9uXHJcbiAqIEBleGFtcGxlXHJcbiAqIHNzLnNhbXBsZVN0YW5kYXJkRGV2aWF0aW9uKFsyLCA0LCA0LCA0LCA1LCA1LCA3LCA5XSk7XHJcbiAqIC8vPSAyLjEzOFxyXG4gKi9cclxuZnVuY3Rpb24gc2FtcGxlU3RhbmRhcmREZXZpYXRpb24oeC8qOkFycmF5PG51bWJlcj4qLykvKjpudW1iZXIqLyB7XHJcbiAgICAvLyBUaGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIG5vIG51bWJlcnMgaXMgbnVsbFxyXG4gICAgdmFyIHNhbXBsZVZhcmlhbmNlWCA9IHNhbXBsZVZhcmlhbmNlKHgpO1xyXG4gICAgaWYgKGlzTmFOKHNhbXBsZVZhcmlhbmNlWCkpIHsgcmV0dXJuIE5hTjsgfVxyXG4gICAgcmV0dXJuIE1hdGguc3FydChzYW1wbGVWYXJpYW5jZVgpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNhbXBsZVN0YW5kYXJkRGV2aWF0aW9uO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG52YXIgc3VtTnRoUG93ZXJEZXZpYXRpb25zID0gcmVxdWlyZSgnLi9zdW1fbnRoX3Bvd2VyX2RldmlhdGlvbnMnKTtcclxuXHJcbi8qXHJcbiAqIFRoZSBbc2FtcGxlIHZhcmlhbmNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9WYXJpYW5jZSNTYW1wbGVfdmFyaWFuY2UpXHJcbiAqIGlzIHRoZSBzdW0gb2Ygc3F1YXJlZCBkZXZpYXRpb25zIGZyb20gdGhlIG1lYW4uIFRoZSBzYW1wbGUgdmFyaWFuY2VcclxuICogaXMgZGlzdGluZ3Vpc2hlZCBmcm9tIHRoZSB2YXJpYW5jZSBieSB0aGUgdXNhZ2Ugb2YgW0Jlc3NlbCdzIENvcnJlY3Rpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jlc3NlbCdzX2NvcnJlY3Rpb24pOlxyXG4gKiBpbnN0ZWFkIG9mIGRpdmlkaW5nIHRoZSBzdW0gb2Ygc3F1YXJlZCBkZXZpYXRpb25zIGJ5IHRoZSBsZW5ndGggb2YgdGhlIGlucHV0LFxyXG4gKiBpdCBpcyBkaXZpZGVkIGJ5IHRoZSBsZW5ndGggbWludXMgb25lLiBUaGlzIGNvcnJlY3RzIHRoZSBiaWFzIGluIGVzdGltYXRpbmdcclxuICogYSB2YWx1ZSBmcm9tIGEgc2V0IHRoYXQgeW91IGRvbid0IGtub3cgaWYgZnVsbC5cclxuICpcclxuICogUmVmZXJlbmNlczpcclxuICogKiBbV29sZnJhbSBNYXRoV29ybGQgb24gU2FtcGxlIFZhcmlhbmNlXShodHRwOi8vbWF0aHdvcmxkLndvbGZyYW0uY29tL1NhbXBsZVZhcmlhbmNlLmh0bWwpXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBpbnB1dCBhcnJheVxyXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHNhbXBsZSB2YXJpYW5jZVxyXG4gKiBAZXhhbXBsZVxyXG4gKiBzYW1wbGVWYXJpYW5jZShbMSwgMiwgMywgNCwgNV0pOyAvLz0gMi41XHJcbiAqL1xyXG5mdW5jdGlvbiBzYW1wbGVWYXJpYW5jZSh4IC8qOiBBcnJheTxudW1iZXI+ICovKS8qOm51bWJlciovIHtcclxuICAgIC8vIFRoZSB2YXJpYW5jZSBvZiBubyBudW1iZXJzIGlzIG51bGxcclxuICAgIGlmICh4Lmxlbmd0aCA8PSAxKSB7IHJldHVybiBOYU47IH1cclxuXHJcbiAgICB2YXIgc3VtU3F1YXJlZERldmlhdGlvbnNWYWx1ZSA9IHN1bU50aFBvd2VyRGV2aWF0aW9ucyh4LCAyKTtcclxuXHJcbiAgICAvLyB0aGlzIGlzIEJlc3NlbHMnIENvcnJlY3Rpb246IGFuIGFkanVzdG1lbnQgbWFkZSB0byBzYW1wbGUgc3RhdGlzdGljc1xyXG4gICAgLy8gdGhhdCBhbGxvd3MgZm9yIHRoZSByZWR1Y2VkIGRlZ3JlZSBvZiBmcmVlZG9tIGVudGFpbGVkIGluIGNhbGN1bGF0aW5nXHJcbiAgICAvLyB2YWx1ZXMgZnJvbSBzYW1wbGVzIHJhdGhlciB0aGFuIGNvbXBsZXRlIHBvcHVsYXRpb25zLlxyXG4gICAgdmFyIGJlc3NlbHNDb3JyZWN0aW9uID0geC5sZW5ndGggLSAxO1xyXG5cclxuICAgIC8vIEZpbmQgdGhlIG1lYW4gdmFsdWUgb2YgdGhhdCBsaXN0XHJcbiAgICByZXR1cm4gc3VtU3F1YXJlZERldmlhdGlvbnNWYWx1ZSAvIGJlc3NlbHNDb3JyZWN0aW9uO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNhbXBsZVZhcmlhbmNlO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG52YXIgdmFyaWFuY2UgPSByZXF1aXJlKCcuL3ZhcmlhbmNlJyk7XHJcblxyXG4vKipcclxuICogVGhlIFtzdGFuZGFyZCBkZXZpYXRpb25dKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3RhbmRhcmRfZGV2aWF0aW9uKVxyXG4gKiBpcyB0aGUgc3F1YXJlIHJvb3Qgb2YgdGhlIHZhcmlhbmNlLiBJdCdzIHVzZWZ1bCBmb3IgbWVhc3VyaW5nIHRoZSBhbW91bnRcclxuICogb2YgdmFyaWF0aW9uIG9yIGRpc3BlcnNpb24gaW4gYSBzZXQgb2YgdmFsdWVzLlxyXG4gKlxyXG4gKiBTdGFuZGFyZCBkZXZpYXRpb24gaXMgb25seSBhcHByb3ByaWF0ZSBmb3IgZnVsbC1wb3B1bGF0aW9uIGtub3dsZWRnZTogZm9yXHJcbiAqIHNhbXBsZXMgb2YgYSBwb3B1bGF0aW9uLCB7QGxpbmsgc2FtcGxlU3RhbmRhcmREZXZpYXRpb259IGlzXHJcbiAqIG1vcmUgYXBwcm9wcmlhdGUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBpbnB1dFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBzdGFuZGFyZCBkZXZpYXRpb25cclxuICogQGV4YW1wbGVcclxuICogdmFyIHNjb3JlcyA9IFsyLCA0LCA0LCA0LCA1LCA1LCA3LCA5XTtcclxuICogdmFyaWFuY2Uoc2NvcmVzKTsgLy89IDRcclxuICogc3RhbmRhcmREZXZpYXRpb24oc2NvcmVzKTsgLy89IDJcclxuICovXHJcbmZ1bmN0aW9uIHN0YW5kYXJkRGV2aWF0aW9uKHggLyo6IEFycmF5PG51bWJlcj4gKi8pLyo6bnVtYmVyKi8ge1xyXG4gICAgLy8gVGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBubyBudW1iZXJzIGlzIG51bGxcclxuICAgIHZhciB2ID0gdmFyaWFuY2UoeCk7XHJcbiAgICBpZiAoaXNOYU4odikpIHsgcmV0dXJuIDA7IH1cclxuICAgIHJldHVybiBNYXRoLnNxcnQodik7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3RhbmRhcmREZXZpYXRpb247XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuLyogQGZsb3cgKi9cclxuXHJcbi8qKlxyXG4gKiBPdXIgZGVmYXVsdCBzdW0gaXMgdGhlIFtLYWhhbiBzdW1tYXRpb24gYWxnb3JpdGhtXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9LYWhhbl9zdW1tYXRpb25fYWxnb3JpdGhtKSBpc1xyXG4gKiBhIG1ldGhvZCBmb3IgY29tcHV0aW5nIHRoZSBzdW0gb2YgYSBsaXN0IG9mIG51bWJlcnMgd2hpbGUgY29ycmVjdGluZ1xyXG4gKiBmb3IgZmxvYXRpbmctcG9pbnQgZXJyb3JzLiBUcmFkaXRpb25hbGx5LCBzdW1zIGFyZSBjYWxjdWxhdGVkIGFzIG1hbnlcclxuICogc3VjY2Vzc2l2ZSBhZGRpdGlvbnMsIGVhY2ggb25lIHdpdGggaXRzIG93biBmbG9hdGluZy1wb2ludCByb3VuZG9mZi4gVGhlc2VcclxuICogbG9zc2VzIGluIHByZWNpc2lvbiBhZGQgdXAgYXMgdGhlIG51bWJlciBvZiBudW1iZXJzIGluY3JlYXNlcy4gVGhpcyBhbHRlcm5hdGl2ZVxyXG4gKiBhbGdvcml0aG0gaXMgbW9yZSBhY2N1cmF0ZSB0aGFuIHRoZSBzaW1wbGUgd2F5IG9mIGNhbGN1bGF0aW5nIHN1bXMgYnkgc2ltcGxlXHJcbiAqIGFkZGl0aW9uLlxyXG4gKlxyXG4gKiBUaGlzIHJ1bnMgb24gYE8obilgLCBsaW5lYXIgdGltZSBpbiByZXNwZWN0IHRvIHRoZSBhcnJheVxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHggaW5wdXRcclxuICogQHJldHVybiB7bnVtYmVyfSBzdW0gb2YgYWxsIGlucHV0IG51bWJlcnNcclxuICogQGV4YW1wbGVcclxuICogY29uc29sZS5sb2coc3VtKFsxLCAyLCAzXSkpOyAvLyA2XHJcbiAqL1xyXG5mdW5jdGlvbiBzdW0oeC8qOiBBcnJheTxudW1iZXI+ICovKS8qOiBudW1iZXIgKi8ge1xyXG5cclxuICAgIC8vIGxpa2UgdGhlIHRyYWRpdGlvbmFsIHN1bSBhbGdvcml0aG0sIHdlIGtlZXAgYSBydW5uaW5nXHJcbiAgICAvLyBjb3VudCBvZiB0aGUgY3VycmVudCBzdW0uXHJcbiAgICB2YXIgc3VtID0gMDtcclxuXHJcbiAgICAvLyBidXQgd2UgYWxzbyBrZWVwIHRocmVlIGV4dHJhIHZhcmlhYmxlcyBhcyBib29ra2VlcGluZzpcclxuICAgIC8vIG1vc3QgaW1wb3J0YW50bHksIGFuIGVycm9yIGNvcnJlY3Rpb24gdmFsdWUuIFRoaXMgd2lsbCBiZSBhIHZlcnlcclxuICAgIC8vIHNtYWxsIG51bWJlciB0aGF0IGlzIHRoZSBvcHBvc2l0ZSBvZiB0aGUgZmxvYXRpbmcgcG9pbnQgcHJlY2lzaW9uIGxvc3MuXHJcbiAgICB2YXIgZXJyb3JDb21wZW5zYXRpb24gPSAwO1xyXG5cclxuICAgIC8vIHRoaXMgd2lsbCBiZSBlYWNoIG51bWJlciBpbiB0aGUgbGlzdCBjb3JyZWN0ZWQgd2l0aCB0aGUgY29tcGVuc2F0aW9uIHZhbHVlLlxyXG4gICAgdmFyIGNvcnJlY3RlZEN1cnJlbnRWYWx1ZTtcclxuXHJcbiAgICAvLyBhbmQgdGhpcyB3aWxsIGJlIHRoZSBuZXh0IHN1bVxyXG4gICAgdmFyIG5leHRTdW07XHJcblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgLy8gZmlyc3QgY29ycmVjdCB0aGUgdmFsdWUgdGhhdCB3ZSdyZSBnb2luZyB0byBhZGQgdG8gdGhlIHN1bVxyXG4gICAgICAgIGNvcnJlY3RlZEN1cnJlbnRWYWx1ZSA9IHhbaV0gLSBlcnJvckNvbXBlbnNhdGlvbjtcclxuXHJcbiAgICAgICAgLy8gY29tcHV0ZSB0aGUgbmV4dCBzdW0uIHN1bSBpcyBsaWtlbHkgYSBtdWNoIGxhcmdlciBudW1iZXJcclxuICAgICAgICAvLyB0aGFuIGNvcnJlY3RlZEN1cnJlbnRWYWx1ZSwgc28gd2UnbGwgbG9zZSBwcmVjaXNpb24gaGVyZSxcclxuICAgICAgICAvLyBhbmQgbWVhc3VyZSBob3cgbXVjaCBwcmVjaXNpb24gaXMgbG9zdCBpbiB0aGUgbmV4dCBzdGVwXHJcbiAgICAgICAgbmV4dFN1bSA9IHN1bSArIGNvcnJlY3RlZEN1cnJlbnRWYWx1ZTtcclxuXHJcbiAgICAgICAgLy8gd2UgaW50ZW50aW9uYWxseSBkaWRuJ3QgYXNzaWduIHN1bSBpbW1lZGlhdGVseSwgYnV0IHN0b3JlZFxyXG4gICAgICAgIC8vIGl0IGZvciBub3cgc28gd2UgY2FuIGZpZ3VyZSBvdXQgdGhpczogaXMgKHN1bSArIG5leHRWYWx1ZSkgLSBuZXh0VmFsdWVcclxuICAgICAgICAvLyBub3QgZXF1YWwgdG8gMD8gaWRlYWxseSBpdCB3b3VsZCBiZSwgYnV0IGluIHByYWN0aWNlIGl0IHdvbid0OlxyXG4gICAgICAgIC8vIGl0IHdpbGwgYmUgc29tZSB2ZXJ5IHNtYWxsIG51bWJlci4gdGhhdCdzIHdoYXQgd2UgcmVjb3JkXHJcbiAgICAgICAgLy8gYXMgZXJyb3JDb21wZW5zYXRpb24uXHJcbiAgICAgICAgZXJyb3JDb21wZW5zYXRpb24gPSBuZXh0U3VtIC0gc3VtIC0gY29ycmVjdGVkQ3VycmVudFZhbHVlO1xyXG5cclxuICAgICAgICAvLyBub3cgdGhhdCB3ZSd2ZSBjb21wdXRlZCBob3cgbXVjaCB3ZSdsbCBjb3JyZWN0IGZvciBpbiB0aGUgbmV4dFxyXG4gICAgICAgIC8vIGxvb3AsIHN0YXJ0IHRyZWF0aW5nIHRoZSBuZXh0U3VtIGFzIHRoZSBjdXJyZW50IHN1bS5cclxuICAgICAgICBzdW0gPSBuZXh0U3VtO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzdW07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3VtO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG52YXIgbWVhbiA9IHJlcXVpcmUoJy4vbWVhbicpO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBzdW0gb2YgZGV2aWF0aW9ucyB0byB0aGUgTnRoIHBvd2VyLlxyXG4gKiBXaGVuIG49MiBpdCdzIHRoZSBzdW0gb2Ygc3F1YXJlZCBkZXZpYXRpb25zLlxyXG4gKiBXaGVuIG49MyBpdCdzIHRoZSBzdW0gb2YgY3ViZWQgZGV2aWF0aW9ucy5cclxuICpcclxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSB4XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBuIHBvd2VyXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IHN1bSBvZiBudGggcG93ZXIgZGV2aWF0aW9uc1xyXG4gKiBAZXhhbXBsZVxyXG4gKiB2YXIgaW5wdXQgPSBbMSwgMiwgM107XHJcbiAqIC8vIHNpbmNlIHRoZSB2YXJpYW5jZSBvZiBhIHNldCBpcyB0aGUgbWVhbiBzcXVhcmVkXHJcbiAqIC8vIGRldmlhdGlvbnMsIHdlIGNhbiBjYWxjdWxhdGUgdGhhdCB3aXRoIHN1bU50aFBvd2VyRGV2aWF0aW9uczpcclxuICogdmFyIHZhcmlhbmNlID0gc3VtTnRoUG93ZXJEZXZpYXRpb25zKGlucHV0KSAvIGlucHV0Lmxlbmd0aDtcclxuICovXHJcbmZ1bmN0aW9uIHN1bU50aFBvd2VyRGV2aWF0aW9ucyh4Lyo6IEFycmF5PG51bWJlcj4gKi8sIG4vKjogbnVtYmVyICovKS8qOm51bWJlciovIHtcclxuICAgIHZhciBtZWFuVmFsdWUgPSBtZWFuKHgpLFxyXG4gICAgICAgIHN1bSA9IDA7XHJcblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgc3VtICs9IE1hdGgucG93KHhbaV0gLSBtZWFuVmFsdWUsIG4pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzdW07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3VtTnRoUG93ZXJEZXZpYXRpb25zO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG52YXIgc3VtTnRoUG93ZXJEZXZpYXRpb25zID0gcmVxdWlyZSgnLi9zdW1fbnRoX3Bvd2VyX2RldmlhdGlvbnMnKTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgW3ZhcmlhbmNlXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1ZhcmlhbmNlKVxyXG4gKiBpcyB0aGUgc3VtIG9mIHNxdWFyZWQgZGV2aWF0aW9ucyBmcm9tIHRoZSBtZWFuLlxyXG4gKlxyXG4gKiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHZhcmlhbmNlLCBub3Qgc2FtcGxlIHZhcmlhbmNlOlxyXG4gKiBzZWUgdGhlIGBzYW1wbGVWYXJpYW5jZWAgbWV0aG9kIGlmIHlvdSB3YW50IGEgc2FtcGxlIG1lYXN1cmUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geCBhIHBvcHVsYXRpb25cclxuICogQHJldHVybnMge251bWJlcn0gdmFyaWFuY2U6IGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHplcm8uXHJcbiAqIHplcm8gaW5kaWNhdGVzIHRoYXQgYWxsIHZhbHVlcyBhcmUgaWRlbnRpY2FsLlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBzcy52YXJpYW5jZShbMSwgMiwgMywgNCwgNSwgNl0pOyAvLz0gMi45MTdcclxuICovXHJcbmZ1bmN0aW9uIHZhcmlhbmNlKHgvKjogQXJyYXk8bnVtYmVyPiAqLykvKjpudW1iZXIqLyB7XHJcbiAgICAvLyBUaGUgdmFyaWFuY2Ugb2Ygbm8gbnVtYmVycyBpcyBudWxsXHJcbiAgICBpZiAoeC5sZW5ndGggPT09IDApIHsgcmV0dXJuIE5hTjsgfVxyXG5cclxuICAgIC8vIEZpbmQgdGhlIG1lYW4gb2Ygc3F1YXJlZCBkZXZpYXRpb25zIGJldHdlZW4gdGhlXHJcbiAgICAvLyBtZWFuIHZhbHVlIGFuZCBlYWNoIHZhbHVlLlxyXG4gICAgcmV0dXJuIHN1bU50aFBvd2VyRGV2aWF0aW9ucyh4LCAyKSAvIHgubGVuZ3RoO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHZhcmlhbmNlO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcbi8qIEBmbG93ICovXHJcblxyXG4vKipcclxuICogVGhlIFtaLVNjb3JlLCBvciBTdGFuZGFyZCBTY29yZV0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdGFuZGFyZF9zY29yZSkuXHJcbiAqXHJcbiAqIFRoZSBzdGFuZGFyZCBzY29yZSBpcyB0aGUgbnVtYmVyIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgYW4gb2JzZXJ2YXRpb25cclxuICogb3IgZGF0dW0gaXMgYWJvdmUgb3IgYmVsb3cgdGhlIG1lYW4uIFRodXMsIGEgcG9zaXRpdmUgc3RhbmRhcmQgc2NvcmVcclxuICogcmVwcmVzZW50cyBhIGRhdHVtIGFib3ZlIHRoZSBtZWFuLCB3aGlsZSBhIG5lZ2F0aXZlIHN0YW5kYXJkIHNjb3JlXHJcbiAqIHJlcHJlc2VudHMgYSBkYXR1bSBiZWxvdyB0aGUgbWVhbi4gSXQgaXMgYSBkaW1lbnNpb25sZXNzIHF1YW50aXR5XHJcbiAqIG9idGFpbmVkIGJ5IHN1YnRyYWN0aW5nIHRoZSBwb3B1bGF0aW9uIG1lYW4gZnJvbSBhbiBpbmRpdmlkdWFsIHJhd1xyXG4gKiBzY29yZSBhbmQgdGhlbiBkaXZpZGluZyB0aGUgZGlmZmVyZW5jZSBieSB0aGUgcG9wdWxhdGlvbiBzdGFuZGFyZFxyXG4gKiBkZXZpYXRpb24uXHJcbiAqXHJcbiAqIFRoZSB6LXNjb3JlIGlzIG9ubHkgZGVmaW5lZCBpZiBvbmUga25vd3MgdGhlIHBvcHVsYXRpb24gcGFyYW1ldGVycztcclxuICogaWYgb25lIG9ubHkgaGFzIGEgc2FtcGxlIHNldCwgdGhlbiB0aGUgYW5hbG9nb3VzIGNvbXB1dGF0aW9uIHdpdGhcclxuICogc2FtcGxlIG1lYW4gYW5kIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24geWllbGRzIHRoZVxyXG4gKiBTdHVkZW50J3MgdC1zdGF0aXN0aWMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB4XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBtZWFuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFuZGFyZERldmlhdGlvblxyXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHogc2NvcmVcclxuICogQGV4YW1wbGVcclxuICogc3MuelNjb3JlKDc4LCA4MCwgNSk7IC8vPSAtMC40XHJcbiAqL1xyXG5mdW5jdGlvbiB6U2NvcmUoeC8qOm51bWJlciovLCBtZWFuLyo6bnVtYmVyKi8sIHN0YW5kYXJkRGV2aWF0aW9uLyo6bnVtYmVyKi8pLyo6bnVtYmVyKi8ge1xyXG4gICAgcmV0dXJuICh4IC0gbWVhbikgLyBzdGFuZGFyZERldmlhdGlvbjtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB6U2NvcmU7XHJcbiIsImltcG9ydCB7Q2hhcnQsIENoYXJ0Q29uZmlnfSBmcm9tIFwiLi9jaGFydFwiO1xyXG5pbXBvcnQge1V0aWxzfSBmcm9tICcuL3V0aWxzJ1xyXG5pbXBvcnQge0xlZ2VuZH0gZnJvbSBcIi4vbGVnZW5kXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQmFyQ2hhcnRDb25maWcgZXh0ZW5kcyBDaGFydENvbmZpZ3tcclxuXHJcbiAgICBzdmdDbGFzcz0gdGhpcy5jc3NDbGFzc1ByZWZpeCsnYmFyLWNoYXJ0JztcclxuICAgIHNob3dMZWdlbmQ9dHJ1ZTtcclxuICAgIHNob3dUb29sdGlwID10cnVlO1xyXG4gICAgbGVnZW5kPXtcclxuICAgICAgICB3aWR0aDogODAsXHJcbiAgICAgICAgbWFyZ2luOiAxMCxcclxuICAgICAgICBzaGFwZVdpZHRoOiAyMFxyXG4gICAgfTtcclxuICAgIHg9ey8vIFggYXhpcyBjb25maWdcclxuICAgICAgICBsYWJlbDogJycsIC8vIGF4aXMgbGFiZWxcclxuICAgICAgICBrZXk6IDAsXHJcbiAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IFV0aWxzLmlzTnVtYmVyKGQpID8gZCA6IGRba2V5XSwgLy8geCB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgICAgIHNjYWxlOiBcIm9yZGluYWxcIixcclxuICAgICAgICB0aWNrczogdW5kZWZpbmVkLFxyXG4gICAgfTtcclxuICAgIHk9ey8vIFkgYXhpcyBjb25maWdcclxuICAgICAgICBrZXk6IDEsXHJcbiAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IFV0aWxzLmlzTnVtYmVyKGQpID8gZCA6IGRba2V5XSwgLy8geCB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgICAgIGxhYmVsOiAnJywgLy8gYXhpcyBsYWJlbCxcclxuICAgICAgICBvcmllbnQ6IFwibGVmdFwiLFxyXG4gICAgICAgIHNjYWxlOiBcImxpbmVhclwiXHJcbiAgICB9O1xyXG4gICAgZ3JvdXBzPXtcclxuICAgICAgICBrZXk6IDEsXHJcbiAgICAgICAgdmFsdWU6IChkKSA9PiBkW3RoaXMuZ3JvdXBzLmtleV0gLCAvLyBncm91cGluZyB2YWx1ZSBhY2Nlc3NvcixcclxuICAgICAgICBsYWJlbDogXCJcIlxyXG4gICAgfTtcclxuICAgIGNvbG9yID0gdW5kZWZpbmVkIC8vIHN0cmluZyBvciBmdW5jdGlvbiByZXR1cm5pbmcgY29sb3IncyB2YWx1ZSBmb3IgY29sb3Igc2NhbGVcclxuICAgIGQzQ29sb3JDYXRlZ29yeT0gJ2NhdGVnb3J5MTAnO1xyXG4gICAgdHJhbnNpdGlvbj0gdHJ1ZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pe1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdmFyIGNvbmZpZyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmKGN1c3RvbSl7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgQmFyQ2hhcnQgZXh0ZW5kcyBDaGFydHtcclxuICAgIGNvbnN0cnVjdG9yKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIGNvbmZpZykge1xyXG4gICAgICAgIHN1cGVyKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIG5ldyBCYXJDaGFydENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRDb25maWcoY29uZmlnKXtcclxuICAgICAgICByZXR1cm4gc3VwZXIuc2V0Q29uZmlnKG5ldyBCYXJDaGFydENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpe1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGY9dGhpcztcclxuXHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90Lng9e307XHJcbiAgICAgICAgdGhpcy5wbG90Lnk9e307XHJcblxyXG4gICAgICAgIHRoaXMucGxvdC5zaG93TGVnZW5kID0gY29uZi5zaG93TGVnZW5kO1xyXG4gICAgICAgIGlmKHRoaXMucGxvdC5zaG93TGVnZW5kKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lm1hcmdpbi5yaWdodCA9IGNvbmYubWFyZ2luLnJpZ2h0ICsgY29uZi5sZWdlbmQud2lkdGgrY29uZi5sZWdlbmQubWFyZ2luKjI7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgdGhpcy5jb21wdXRlUGxvdFNpemUoKTtcclxuICAgICAgICB0aGlzLnNldHVwWSgpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBYKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cEdyb3VwU3RhY2tzKCk7XHJcblxyXG5cclxuICAgICAgICB0aGlzLnNldHVwWURvbWFpbigpO1xyXG5cclxuXHJcbiAgICAgICAgaWYoY29uZi5kM0NvbG9yQ2F0ZWdvcnkpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuY29sb3JDYXRlZ29yeSA9IGQzLnNjYWxlW2NvbmYuZDNDb2xvckNhdGVnb3J5XSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgY29sb3JWYWx1ZSA9IGNvbmYuY29sb3I7XHJcbiAgICAgICAgaWYgKGNvbG9yVmFsdWUgJiYgdHlwZW9mIGNvbG9yVmFsdWUgPT09ICdzdHJpbmcnIHx8IGNvbG9yVmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuY29sb3IgPSBjb2xvclZhbHVlO1xyXG4gICAgICAgIH1lbHNlIGlmKHRoaXMucGxvdC5jb2xvckNhdGVnb3J5KXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmNvbG9yID0gZCA9PiAgc2VsZi5wbG90LmNvbG9yQ2F0ZWdvcnkoZC5rZXkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG5cclxuXHJcbiAgICBzZXR1cFgoKXtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIHggPSBwbG90Lng7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZy54O1xyXG5cclxuICAgICAgICAvKiAqXHJcbiAgICAgICAgICogdmFsdWUgYWNjZXNzb3IgLSByZXR1cm5zIHRoZSB2YWx1ZSB0byBlbmNvZGUgZm9yIGEgZ2l2ZW4gZGF0YSBvYmplY3QuXHJcbiAgICAgICAgICogc2NhbGUgLSBtYXBzIHZhbHVlIHRvIGEgdmlzdWFsIGRpc3BsYXkgZW5jb2RpbmcsIHN1Y2ggYXMgYSBwaXhlbCBwb3NpdGlvbi5cclxuICAgICAgICAgKiBtYXAgZnVuY3Rpb24gLSBtYXBzIGZyb20gZGF0YSB2YWx1ZSB0byBkaXNwbGF5IHZhbHVlXHJcbiAgICAgICAgICogYXhpcyAtIHNldHMgdXAgYXhpc1xyXG4gICAgICAgICAqKi9cclxuICAgICAgICB4LnZhbHVlID0gZCA9PiBjb25mLnZhbHVlKGQsIGNvbmYua2V5KTtcclxuICAgICAgICB4LnNjYWxlID0gZDMuc2NhbGUub3JkaW5hbCgpLnJhbmdlUm91bmRCYW5kcyhbMCwgcGxvdC53aWR0aF0sIC4wOCk7XHJcbiAgICAgICAgeC5tYXAgPSBkID0+IHguc2NhbGUoeC52YWx1ZShkKSk7XHJcblxyXG4gICAgICAgIHguYXhpcyA9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeC5zY2FsZSkub3JpZW50KGNvbmYub3JpZW50KTtcclxuXHJcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLmRhdGE7XHJcbiAgICAgICAgdmFyIGRvbWFpbjtcclxuICAgICAgICBpZighdGhpcy5jb25maWcuc2VyaWVzKXtcclxuICAgICAgICAgICAgZG9tYWluID0gZDMubWFwKGRhdGEsIHgudmFsdWUpLmtleXMoKTtcclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgZG9tYWluID0gZDMubWFwKGRhdGFbMF0udmFsdWVzLCB4LnZhbHVlKS5rZXlzKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwbG90Lnguc2NhbGUuZG9tYWluKGRvbWFpbik7XHJcbiAgICAgICAgY29uc29sZS5sb2coJyBwbG90Lnguc2NhbGUuZG9tYWluJywgcGxvdC54LnNjYWxlLmRvbWFpbigpKTtcclxuICAgICAgICBcclxuICAgIH07XHJcblxyXG4gICAgc2V0dXBZICgpe1xyXG5cclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgeSA9IHBsb3QueTtcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnLnk7XHJcbiAgICAgICAgeS52YWx1ZSA9IGQgPT4gY29uZi52YWx1ZShkLCBjb25mLmtleSk7XHJcbiAgICAgICAgeS5zY2FsZSA9IGQzLnNjYWxlW2NvbmYuc2NhbGVdKCkucmFuZ2UoW3Bsb3QuaGVpZ2h0LCAwXSk7XHJcbiAgICAgICAgeS5tYXAgPSBkID0+IHkuc2NhbGUoeS52YWx1ZShkKSk7XHJcblxyXG4gICAgICAgIHkuYXhpcyA9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeS5zY2FsZSkub3JpZW50KGNvbmYub3JpZW50KTtcclxuICAgICAgICBpZihjb25mLnRpY2tzKXtcclxuICAgICAgICAgICAgeS5heGlzLnRpY2tzKGNvbmYudGlja3MpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgc2V0dXBZRG9tYWluKCkge1xyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5kYXRhO1xyXG4gICAgICAgIHZhciBkb21haW47XHJcbiAgICAgICAgdmFyIHlTdGFja01heCA9IGQzLm1heChwbG90LmxheWVycywgbGF5ZXIgPT4gZDMubWF4KGxheWVyLnZhbHVlcywgZCA9PiBkLnkwICsgZC55KSk7XHJcbiAgICAgICAgaWYoIXRoaXMuY29uZmlnLnNlcmllcyl7XHJcbiAgICAgICAgICAgIGRvbWFpbiA9IFtkMy5taW4oZGF0YSwgcGxvdC55LnZhbHVlKSwgZDMubWF4KGRhdGEsIHBsb3QueS52YWx1ZSldO1xyXG4gICAgICAgIH1lbHNle1xyXG5cclxuICAgICAgICAgICAgLy8gdmFyIG1pbiA9IGQzLm1pbihkYXRhLCBzPT5kMy5taW4ocy52YWx1ZXMsIHBsb3QueS52YWx1ZSkpO1xyXG4gICAgICAgICAgICB2YXIgbWF4ID0geVN0YWNrTWF4O1xyXG4gICAgICAgICAgICBkb21haW4gPSBbMCwgbWF4XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcGxvdC55LnNjYWxlLmRvbWFpbihkb21haW4pO1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCcgcGxvdC55LnNjYWxlLmRvbWFpbicsIHBsb3QueS5zY2FsZS5kb21haW4oKSk7XHJcbiAgICB9XHJcbiAgICBncm91cERhdGEoKXtcclxuICAgICAgICB2YXIgc2VsZj10aGlzO1xyXG4gICAgICAgIHRoaXMucGxvdC5ncm91cGluZ0VuYWJsZWQgPSB0aGlzLmNvbmZpZy5zZXJpZXM7XHJcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLmRhdGE7XHJcbiAgICAgICAgaWYoIXRoaXMucGxvdC5ncm91cGluZ0VuYWJsZWQgKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lmdyb3VwZWREYXRhID0gIFt7XHJcbiAgICAgICAgICAgICAgICBrZXk6ICdyb290JyxcclxuICAgICAgICAgICAgICAgIHZhbHVlczogc2VsZi5tYXBUb1BvaW50cyhkYXRhKVxyXG4gICAgICAgICAgICB9XTtcclxuICAgICAgICB9ZWxzZXtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5ncm91cGVkRGF0YSA9ICBkYXRhLm1hcChzPT57XHJcbiAgICAgICAgICAgICAgICByZXR1cm57XHJcbiAgICAgICAgICAgICAgICAgICAga2V5OiBzLmtleSxcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IHNlbGYubWFwVG9Qb2ludHMocy52YWx1ZXMpXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzZXR1cEdyb3VwU3RhY2tzKCkge1xyXG4gICAgICAgIHZhciBzZWxmPXRoaXM7XHJcbiAgICAgICAgdGhpcy5ncm91cERhdGEoKTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnN0YWNrID0gZDMubGF5b3V0LnN0YWNrKCkudmFsdWVzKGQ9PmQudmFsdWVzKTtcclxuICAgICAgICB0aGlzLnBsb3QubGF5ZXJzID0gdGhpcy5wbG90LnN0YWNrKHRoaXMucGxvdC5ncm91cGVkRGF0YSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIG1hcFRvUG9pbnRzKHZhbHVlcyl7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5tYXAodj0+e1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgeDogcGxvdC54LnZhbHVlKHYpLFxyXG4gICAgICAgICAgICAgICAgeTogcGxvdC55LnZhbHVlKHYpLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICBkcmF3QXhpc1goKXtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGF4aXNDb25mID0gdGhpcy5jb25maWcueDtcclxuICAgICAgICB2YXIgYXhpcyA9IHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcy14JykrXCIuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcycpKyhzZWxmLmNvbmZpZy5ndWlkZXMgPyAnJyA6ICcuJytzZWxmLnByZWZpeENsYXNzKCduby1ndWlkZXMnKSkpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKDAsXCIgKyBwbG90LmhlaWdodCArIFwiKVwiKTtcclxuXHJcbiAgICAgICAgdmFyIGF4aXNUID0gYXhpcztcclxuICAgICAgICBpZiAoc2VsZi5jb25maWcudHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICBheGlzVCA9IGF4aXMudHJhbnNpdGlvbigpLmVhc2UoXCJzaW4taW4tb3V0XCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXhpc1QuY2FsbChwbG90LnguYXhpcyk7XHJcblxyXG4gICAgICAgIGF4aXMuc2VsZWN0T3JBcHBlbmQoXCJ0ZXh0LlwiK3NlbGYucHJlZml4Q2xhc3MoJ2xhYmVsJykpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiKyAocGxvdC53aWR0aC8yKSArXCIsXCIrIChwbG90Lm1hcmdpbi5ib3R0b20pICtcIilcIikgIC8vIHRleHQgaXMgZHJhd24gb2ZmIHRoZSBzY3JlZW4gdG9wIGxlZnQsIG1vdmUgZG93biBhbmQgb3V0IGFuZCByb3RhdGVcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIi0xZW1cIilcclxuICAgICAgICAgICAgLnN0eWxlKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIilcclxuICAgICAgICAgICAgLnRleHQoYXhpc0NvbmYubGFiZWwpO1xyXG4gICAgfTtcclxuXHJcbiAgICBkcmF3QXhpc1koKXtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGF4aXNDb25mID0gdGhpcy5jb25maWcueTtcclxuICAgICAgICB2YXIgYXhpcyA9IHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcy15JykrXCIuXCIrc2VsZi5wcmVmaXhDbGFzcygnYXhpcycpKyhzZWxmLmNvbmZpZy5ndWlkZXMgPyAnJyA6ICcuJytzZWxmLnByZWZpeENsYXNzKCduby1ndWlkZXMnKSkpO1xyXG5cclxuICAgICAgICB2YXIgYXhpc1QgPSBheGlzO1xyXG4gICAgICAgIGlmIChzZWxmLmNvbmZpZy50cmFuc2l0aW9uKSB7XHJcbiAgICAgICAgICAgIGF4aXNUID0gYXhpcy50cmFuc2l0aW9uKCkuZWFzZShcInNpbi1pbi1vdXRcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBheGlzVC5jYWxsKHBsb3QueS5heGlzKTtcclxuXHJcbiAgICAgICAgYXhpcy5zZWxlY3RPckFwcGVuZChcInRleHQuXCIrc2VsZi5wcmVmaXhDbGFzcygnbGFiZWwnKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIrIC1wbG90Lm1hcmdpbi5sZWZ0ICtcIixcIisocGxvdC5oZWlnaHQvMikrXCIpcm90YXRlKC05MClcIikgIC8vIHRleHQgaXMgZHJhd24gb2ZmIHRoZSBzY3JlZW4gdG9wIGxlZnQsIG1vdmUgZG93biBhbmQgb3V0IGFuZCByb3RhdGVcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIjFlbVwiKVxyXG4gICAgICAgICAgICAuc3R5bGUoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChheGlzQ29uZi5sYWJlbCk7XHJcbiAgICB9O1xyXG5cclxuXHJcbiAgICBkcmF3QmFycygpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKHBsb3QubGF5ZXJzKTtcclxuXHJcbiAgICAgICAgdmFyIGxheWVyQ2xhc3MgPSB0aGlzLnByZWZpeENsYXNzKFwibGF5ZXJcIik7XHJcblxyXG4gICAgICAgIHZhciBiYXJDbGFzcyA9IHRoaXMucHJlZml4Q2xhc3MoXCJiYXJcIik7XHJcbiAgICAgICAgdmFyIGxheWVyID0gc2VsZi5zdmdHLnNlbGVjdEFsbChcIi5cIitsYXllckNsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShwbG90LmxheWVycyk7XHJcblxyXG4gICAgICAgIGxheWVyLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGxheWVyQ2xhc3MpO1xyXG5cclxuICAgICAgICB2YXIgYmFyID0gbGF5ZXIuc2VsZWN0QWxsKFwiLlwiK2JhckNsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShkID0+IGQudmFsdWVzKTtcclxuXHJcbiAgICAgICAgYmFyLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGJhckNsYXNzKVxyXG4gICAgICAgICAgICAuYXBwZW5kKFwicmVjdFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMSk7XHJcblxyXG5cclxuICAgICAgICB2YXIgYmFyUmVjdCA9IGJhci5zZWxlY3QoXCJyZWN0XCIpO1xyXG5cclxuICAgICAgICB2YXIgYmFyUmVjdFQgPSBiYXJSZWN0O1xyXG4gICAgICAgIHZhciBiYXJUID0gYmFyO1xyXG4gICAgICAgIHZhciBsYXllclQgPSBsYXllcjtcclxuICAgICAgICBpZiAodGhpcy50cmFuc2l0aW9uRW5hYmxlZCgpKSB7XHJcbiAgICAgICAgICAgIGJhclJlY3RUID0gYmFyUmVjdC50cmFuc2l0aW9uKCk7XHJcbiAgICAgICAgICAgIGJhclQgPSBiYXIudHJhbnNpdGlvbigpO1xyXG4gICAgICAgICAgICBsYXllclQ9IGxheWVyLnRyYW5zaXRpb24oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciB5RG9tYWluID0gcGxvdC55LnNjYWxlLmRvbWFpbigpO1xyXG4gICAgICAgIGJhclQuYXR0cihcInRyYW5zZm9ybVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBcInRyYW5zbGF0ZShcIiArIHBsb3QueC5zY2FsZShkLngpICsgXCIsXCIgKyAocGxvdC55LnNjYWxlKGQueTArZC55ICkpICsgXCIpXCI7IH0pO1xyXG5cclxuICAgICAgICBiYXJSZWN0VFxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsICBwbG90Lnguc2NhbGUucmFuZ2VCYW5kKCkpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGQgPT4gICBwbG90Lnkuc2NhbGUoZC55MCApIC0gcGxvdC55LnNjYWxlKGQueTAgKyBkLnkgLSB5RG9tYWluWzBdKSk7XHJcblxyXG5cclxuICAgICAgICBpZih0aGlzLnBsb3QuY29sb3Ipe1xyXG4gICAgICAgICAgICBsYXllclRcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwiZmlsbFwiLCB0aGlzLnBsb3QuY29sb3IpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBsb3QudG9vbHRpcCkge1xyXG4gICAgICAgICAgICBiYXIub24oXCJtb3VzZW92ZXJcIiwgZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDIwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIC45KTtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGQueSlcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJsZWZ0XCIsIChkMy5ldmVudC5wYWdlWCArIDUpICsgXCJweFwiKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcInRvcFwiLCAoZDMuZXZlbnQucGFnZVkgLSAyOCkgKyBcInB4XCIpO1xyXG4gICAgICAgICAgICB9KS5vbihcIm1vdXNlb3V0XCIsIGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbig1MDApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxheWVyLmV4aXQoKS5yZW1vdmUoKTtcclxuICAgICAgICBiYXIuZXhpdCgpLnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZShuZXdEYXRhKXtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcbiAgICAgICAgdGhpcy5kcmF3QXhpc1goKTtcclxuICAgICAgICB0aGlzLmRyYXdBeGlzWSgpO1xyXG5cclxuICAgICAgICB0aGlzLmRyYXdCYXJzKCk7XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlTGVnZW5kKCk7XHJcbiAgICB9O1xyXG5cclxuXHJcbiAgICB1cGRhdGVMZWdlbmQoKSB7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcblxyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3QuY29sb3JDYXRlZ29yeTtcclxuICAgICAgICBpZighc2NhbGUuZG9tYWluKCkgfHwgc2NhbGUuZG9tYWluKCkubGVuZ3RoPDIpe1xyXG4gICAgICAgICAgICBwbG90LnNob3dMZWdlbmQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKCFwbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICBpZihwbG90LmxlZ2VuZCAmJiBwbG90LmxlZ2VuZC5jb250YWluZXIpe1xyXG4gICAgICAgICAgICAgICAgcGxvdC5sZWdlbmQuY29udGFpbmVyLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgbGVnZW5kWCA9IHRoaXMucGxvdC53aWR0aCArIHRoaXMuY29uZmlnLmxlZ2VuZC5tYXJnaW47XHJcbiAgICAgICAgdmFyIGxlZ2VuZFkgPSB0aGlzLmNvbmZpZy5sZWdlbmQubWFyZ2luO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZCA9IG5ldyBMZWdlbmQodGhpcy5zdmcsIHRoaXMuc3ZnRywgc2NhbGUsIGxlZ2VuZFgsIGxlZ2VuZFkpO1xyXG5cclxuICAgICAgICB2YXIgbGVnZW5kTGluZWFyID0gcGxvdC5sZWdlbmQuY29sb3IoKVxyXG4gICAgICAgICAgICAuc2hhcGVXaWR0aCh0aGlzLmNvbmZpZy5sZWdlbmQuc2hhcGVXaWR0aClcclxuICAgICAgICAgICAgLm9yaWVudCgndmVydGljYWwnKVxyXG4gICAgICAgICAgICAuc2NhbGUoc2NhbGUpO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZC5jb250YWluZXJcclxuICAgICAgICAgICAgLmNhbGwobGVnZW5kTGluZWFyKTtcclxuICAgIH1cclxuXHJcblxyXG59XHJcbiIsImltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIENoYXJ0Q29uZmlnIHtcclxuICAgIGNzc0NsYXNzUHJlZml4ID0gXCJvZGMtXCI7XHJcbiAgICBzdmdDbGFzcyA9IHRoaXMuY3NzQ2xhc3NQcmVmaXggKyAnbXctZDMtY2hhcnQnO1xyXG4gICAgd2lkdGggPSB1bmRlZmluZWQ7XHJcbiAgICBoZWlnaHQgPSB1bmRlZmluZWQ7XHJcbiAgICBtYXJnaW4gPSB7XHJcbiAgICAgICAgbGVmdDogNTAsXHJcbiAgICAgICAgcmlnaHQ6IDMwLFxyXG4gICAgICAgIHRvcDogMzAsXHJcbiAgICAgICAgYm90dG9tOiA1MFxyXG4gICAgfTtcclxuICAgIHNob3dUb29sdGlwID0gZmFsc2U7XHJcbiAgICB0cmFuc2l0aW9uID0gdHJ1ZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pIHtcclxuICAgICAgICBpZiAoY3VzdG9tKSB7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIENoYXJ0IHtcclxuICAgIHV0aWxzID0gVXRpbHM7XHJcbiAgICBiYXNlQ29udGFpbmVyO1xyXG4gICAgc3ZnO1xyXG4gICAgY29uZmlnO1xyXG4gICAgcGxvdCA9IHtcclxuICAgICAgICBtYXJnaW46IHt9XHJcbiAgICB9O1xyXG4gICAgX2F0dGFjaGVkID0ge307XHJcbiAgICBfbGF5ZXJzID0ge307XHJcbiAgICBfZXZlbnRzID0ge307XHJcbiAgICBfaXNBdHRhY2hlZDtcclxuICAgIF9pc0luaXRpYWxpemVkPWZhbHNlO1xyXG5cclxuXHJcbiAgICBjb25zdHJ1Y3RvcihiYXNlLCBkYXRhLCBjb25maWcpIHtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLl9pc0F0dGFjaGVkID0gYmFzZSBpbnN0YW5jZW9mIENoYXJ0O1xyXG5cclxuICAgICAgICB0aGlzLmJhc2VDb250YWluZXIgPSBiYXNlO1xyXG5cclxuICAgICAgICB0aGlzLnNldENvbmZpZyhjb25maWcpO1xyXG5cclxuICAgICAgICBpZiAoZGF0YSkge1xyXG4gICAgICAgICAgICB0aGlzLnNldERhdGEoZGF0YSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmluaXQoKTtcclxuICAgICAgICB0aGlzLnBvc3RJbml0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Q29uZmlnKGNvbmZpZykge1xyXG4gICAgICAgIGlmICghY29uZmlnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlnID0gbmV3IENoYXJ0Q29uZmlnKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBzZXREYXRhKGRhdGEpIHtcclxuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIGluaXQoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuXHJcbiAgICAgICAgc2VsZi5pbml0UGxvdCgpO1xyXG4gICAgICAgIHNlbGYuaW5pdFN2ZygpO1xyXG5cclxuICAgICAgICBzZWxmLmluaXRUb29sdGlwKCk7XHJcbiAgICAgICAgc2VsZi5kcmF3KCk7XHJcbiAgICAgICAgdGhpcy5faXNJbml0aWFsaXplZD10cnVlO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHBvc3RJbml0KCl7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXRTdmcoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdmFyIG1hcmdpbiA9IHNlbGYucGxvdC5tYXJnaW47XHJcbiAgICAgICAgdmFyIHdpZHRoID0gc2VsZi5wbG90LndpZHRoICsgbWFyZ2luLmxlZnQgKyBtYXJnaW4ucmlnaHQ7XHJcbiAgICAgICAgdmFyIGhlaWdodCA9IHNlbGYucGxvdC5oZWlnaHQgKyBtYXJnaW4udG9wICsgbWFyZ2luLmJvdHRvbTtcclxuICAgICAgICB2YXIgYXNwZWN0ID0gd2lkdGggLyBoZWlnaHQ7XHJcbiAgICAgICAgaWYoIXNlbGYuX2lzQXR0YWNoZWQpe1xyXG4gICAgICAgICAgICBpZighdGhpcy5faXNJbml0aWFsaXplZCl7XHJcbiAgICAgICAgICAgICAgICBkMy5zZWxlY3Qoc2VsZi5iYXNlQ29udGFpbmVyKS5zZWxlY3QoXCJzdmdcIikucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2VsZi5zdmcgPSBkMy5zZWxlY3Qoc2VsZi5iYXNlQ29udGFpbmVyKS5zZWxlY3RPckFwcGVuZChcInN2Z1wiKTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuc3ZnXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIHdpZHRoKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgaGVpZ2h0KVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ2aWV3Qm94XCIsIFwiMCAwIFwiICsgXCIgXCIgKyB3aWR0aCArIFwiIFwiICsgaGVpZ2h0KVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJwcmVzZXJ2ZUFzcGVjdFJhdGlvXCIsIFwieE1pZFlNaWQgbWVldFwiKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBjb25maWcuc3ZnQ2xhc3MpO1xyXG4gICAgICAgICAgICBzZWxmLnN2Z0cgPSBzZWxmLnN2Zy5zZWxlY3RPckFwcGVuZChcImcubWFpbi1ncm91cFwiKTtcclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coc2VsZi5iYXNlQ29udGFpbmVyKTtcclxuICAgICAgICAgICAgc2VsZi5zdmcgPSBzZWxmLmJhc2VDb250YWluZXIuc3ZnO1xyXG4gICAgICAgICAgICBzZWxmLnN2Z0cgPSBzZWxmLnN2Zy5zZWxlY3RPckFwcGVuZChcImcubWFpbi1ncm91cC5cIitjb25maWcuc3ZnQ2xhc3MpXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxmLnN2Z0cuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIG1hcmdpbi5sZWZ0ICsgXCIsXCIgKyBtYXJnaW4udG9wICsgXCIpXCIpO1xyXG5cclxuICAgICAgICBpZiAoIWNvbmZpZy53aWR0aCB8fCBjb25maWcuaGVpZ2h0KSB7XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdCh3aW5kb3cpXHJcbiAgICAgICAgICAgICAgICAub24oXCJyZXNpemVcIiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vVE9ETyBhZGQgcmVzcG9uc2l2ZW5lc3MgaWYgd2lkdGgvaGVpZ2h0IG5vdCBzcGVjaWZpZWRcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpbml0VG9vbHRpcCgpe1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICBpZiAoc2VsZi5jb25maWcuc2hvd1Rvb2x0aXApIHtcclxuICAgICAgICAgICAgaWYoIXNlbGYuX2lzQXR0YWNoZWQgKXtcclxuICAgICAgICAgICAgICAgIHNlbGYucGxvdC50b29sdGlwID0gZDMuc2VsZWN0KFwiYm9keVwiKS5zZWxlY3RPckFwcGVuZCgnZGl2Licrc2VsZi5jb25maWcuY3NzQ2xhc3NQcmVmaXgrJ3Rvb2x0aXAnKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XHJcbiAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgICAgc2VsZi5wbG90LnRvb2x0aXA9IHNlbGYuYmFzZUNvbnRhaW5lci5wbG90LnRvb2x0aXA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGluaXRQbG90KCkge1xyXG4gICAgICAgIHZhciBtYXJnaW4gPSB0aGlzLmNvbmZpZy5tYXJnaW47XHJcbiAgICAgICAgdGhpcy5wbG90ID0gdGhpcy5wbG90IHx8IHt9O1xyXG4gICAgICAgIHRoaXMucGxvdC5tYXJnaW4gPSB7XHJcbiAgICAgICAgICAgIHRvcDogbWFyZ2luLnRvcCxcclxuICAgICAgICAgICAgYm90dG9tOiBtYXJnaW4uYm90dG9tLFxyXG4gICAgICAgICAgICBsZWZ0OiBtYXJnaW4ubGVmdCxcclxuICAgICAgICAgICAgcmlnaHQ6IG1hcmdpbi5yaWdodFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlKGRhdGEpIHtcclxuICAgICAgICBpZiAoZGF0YSkge1xyXG4gICAgICAgICAgICB0aGlzLnNldERhdGEoZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBsYXllck5hbWUsIGF0dGFjaG1lbnREYXRhO1xyXG4gICAgICAgIGZvciAodmFyIGF0dGFjaG1lbnROYW1lIGluIHRoaXMuX2F0dGFjaGVkKSB7XHJcblxyXG4gICAgICAgICAgICBhdHRhY2htZW50RGF0YSA9IGRhdGE7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9hdHRhY2hlZFthdHRhY2htZW50TmFtZV0udXBkYXRlKGF0dGFjaG1lbnREYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgZHJhdyhkYXRhKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGUoZGF0YSk7XHJcblxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcblxyXG4gICAgLy9Cb3Jyb3dlZCBmcm9tIGQzLmNoYXJ0XHJcbiAgICAvKipcclxuICAgICAqIFJlZ2lzdGVyIG9yIHJldHJpZXZlIGFuIFwiYXR0YWNobWVudFwiIENoYXJ0LiBUaGUgXCJhdHRhY2htZW50XCIgY2hhcnQncyBgZHJhd2BcclxuICAgICAqIG1ldGhvZCB3aWxsIGJlIGludm9rZWQgd2hlbmV2ZXIgdGhlIGNvbnRhaW5pbmcgY2hhcnQncyBgZHJhd2AgbWV0aG9kIGlzXHJcbiAgICAgKiBpbnZva2VkLlxyXG4gICAgICpcclxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUgY2hhcnQtYXR0YWNoXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGF0dGFjaG1lbnROYW1lIE5hbWUgb2YgdGhlIGF0dGFjaG1lbnRcclxuICAgICAqIEBwYXJhbSB7Q2hhcnR9IFtjaGFydF0gQ2hhcnQgdG8gcmVnaXN0ZXIgYXMgYSBtaXggaW4gb2YgdGhpcyBjaGFydC4gV2hlblxyXG4gICAgICogICAgICAgIHVuc3BlY2lmaWVkLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgYXR0YWNobWVudCBwcmV2aW91c2x5XHJcbiAgICAgKiAgICAgICAgcmVnaXN0ZXJlZCB3aXRoIHRoZSBzcGVjaWZpZWQgYGF0dGFjaG1lbnROYW1lYCAoaWYgYW55KS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Q2hhcnR9IFJlZmVyZW5jZSB0byB0aGlzIGNoYXJ0IChjaGFpbmFibGUpLlxyXG4gICAgICovXHJcbiAgICBhdHRhY2goYXR0YWNobWVudE5hbWUsIGNoYXJ0KSB7XHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F0dGFjaGVkW2F0dGFjaG1lbnROYW1lXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2F0dGFjaGVkW2F0dGFjaG1lbnROYW1lXSA9IGNoYXJ0O1xyXG4gICAgICAgIHJldHVybiBjaGFydDtcclxuICAgIH07XHJcblxyXG4gICAgXHJcblxyXG4gICAgLy9Cb3Jyb3dlZCBmcm9tIGQzLmNoYXJ0XHJcbiAgICAvKipcclxuICAgICAqIFN1YnNjcmliZSBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGFuIGV2ZW50IHRyaWdnZXJlZCBvbiB0aGUgY2hhcnQuIFNlZSB7QGxpbmtcclxuICAgICAgICAqIENoYXJ0I29uY2V9IHRvIHN1YnNjcmliZSBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGFuIGV2ZW50IGZvciBvbmUgb2NjdXJlbmNlLlxyXG4gICAgICpcclxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUge3J1bm5hYmxlfSBjaGFydC1vblxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIE5hbWUgb2YgdGhlIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0NoYXJ0RXZlbnRIYW5kbGVyfSBjYWxsYmFjayBGdW5jdGlvbiB0byBiZSBpbnZva2VkIHdoZW4gdGhlIGV2ZW50XHJcbiAgICAgKiAgICAgICAgb2NjdXJzXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW2NvbnRleHRdIFZhbHVlIHRvIHNldCBhcyBgdGhpc2Agd2hlbiBpbnZva2luZyB0aGVcclxuICAgICAqICAgICAgICBgY2FsbGJhY2tgLiBEZWZhdWx0cyB0byB0aGUgY2hhcnQgaW5zdGFuY2UuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0NoYXJ0fSBBIHJlZmVyZW5jZSB0byB0aGlzIGNoYXJ0IChjaGFpbmFibGUpLlxyXG4gICAgICovXHJcbiAgICBvbihuYW1lLCBjYWxsYmFjaywgY29udGV4dCkge1xyXG4gICAgICAgIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNbbmFtZV0gfHwgKHRoaXMuX2V2ZW50c1tuYW1lXSA9IFtdKTtcclxuICAgICAgICBldmVudHMucHVzaCh7XHJcbiAgICAgICAgICAgIGNhbGxiYWNrOiBjYWxsYmFjayxcclxuICAgICAgICAgICAgY29udGV4dDogY29udGV4dCB8fCB0aGlzLFxyXG4gICAgICAgICAgICBfY2hhcnQ6IHRoaXNcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICAvL0JvcnJvd2VkIGZyb20gZDMuY2hhcnRcclxuICAgIC8qKlxyXG4gICAgICpcclxuICAgICAqIFN1YnNjcmliZSBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGFuIGV2ZW50IHRyaWdnZXJlZCBvbiB0aGUgY2hhcnQuIFRoaXNcclxuICAgICAqIGZ1bmN0aW9uIHdpbGwgYmUgaW52b2tlZCBhdCB0aGUgbmV4dCBvY2N1cmFuY2Ugb2YgdGhlIGV2ZW50IGFuZCBpbW1lZGlhdGVseVxyXG4gICAgICogdW5zdWJzY3JpYmVkLiBTZWUge0BsaW5rIENoYXJ0I29ufSB0byBzdWJzY3JpYmUgYSBjYWxsYmFjayBmdW5jdGlvbiB0byBhblxyXG4gICAgICogZXZlbnQgaW5kZWZpbml0ZWx5LlxyXG4gICAgICpcclxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUge3J1bm5hYmxlfSBjaGFydC1vbmNlXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgTmFtZSBvZiB0aGUgZXZlbnRcclxuICAgICAqIEBwYXJhbSB7Q2hhcnRFdmVudEhhbmRsZXJ9IGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGJlIGludm9rZWQgd2hlbiB0aGUgZXZlbnRcclxuICAgICAqICAgICAgICBvY2N1cnNcclxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dF0gVmFsdWUgdG8gc2V0IGFzIGB0aGlzYCB3aGVuIGludm9raW5nIHRoZVxyXG4gICAgICogICAgICAgIGBjYWxsYmFja2AuIERlZmF1bHRzIHRvIHRoZSBjaGFydCBpbnN0YW5jZVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtDaGFydH0gQSByZWZlcmVuY2UgdG8gdGhpcyBjaGFydCAoY2hhaW5hYmxlKVxyXG4gICAgICovXHJcbiAgICBvbmNlKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBvbmNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBzZWxmLm9mZihuYW1lLCBvbmNlKTtcclxuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9uKG5hbWUsIG9uY2UsIGNvbnRleHQpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvL0JvcnJvd2VkIGZyb20gZDMuY2hhcnRcclxuICAgIC8qKlxyXG4gICAgICogVW5zdWJzY3JpYmUgb25lIG9yIG1vcmUgY2FsbGJhY2sgZnVuY3Rpb25zIGZyb20gYW4gZXZlbnQgdHJpZ2dlcmVkIG9uIHRoZVxyXG4gICAgICogY2hhcnQuIFdoZW4gbm8gYXJndW1lbnRzIGFyZSBzcGVjaWZpZWQsICphbGwqIGhhbmRsZXJzIHdpbGwgYmUgdW5zdWJzY3JpYmVkLlxyXG4gICAgICogV2hlbiBvbmx5IGEgYG5hbWVgIGlzIHNwZWNpZmllZCwgYWxsIGhhbmRsZXJzIHN1YnNjcmliZWQgdG8gdGhhdCBldmVudCB3aWxsXHJcbiAgICAgKiBiZSB1bnN1YnNjcmliZWQuIFdoZW4gYSBgbmFtZWAgYW5kIGBjYWxsYmFja2AgYXJlIHNwZWNpZmllZCwgb25seSB0aGF0XHJcbiAgICAgKiBmdW5jdGlvbiB3aWxsIGJlIHVuc3Vic2NyaWJlZCBmcm9tIHRoYXQgZXZlbnQuIFdoZW4gYSBgbmFtZWAgYW5kIGBjb250ZXh0YFxyXG4gICAgICogYXJlIHNwZWNpZmllZCAoYnV0IGBjYWxsYmFja2AgaXMgb21pdHRlZCksIGFsbCBldmVudHMgYm91bmQgdG8gdGhlIGdpdmVuXHJcbiAgICAgKiBldmVudCB3aXRoIHRoZSBnaXZlbiBjb250ZXh0IHdpbGwgYmUgdW5zdWJzY3JpYmVkLlxyXG4gICAgICpcclxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUge3J1bm5hYmxlfSBjaGFydC1vZmZcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gW25hbWVdIE5hbWUgb2YgdGhlIGV2ZW50IHRvIGJlIHVuc3Vic2NyaWJlZFxyXG4gICAgICogQHBhcmFtIHtDaGFydEV2ZW50SGFuZGxlcn0gW2NhbGxiYWNrXSBGdW5jdGlvbiB0byBiZSB1bnN1YnNjcmliZWRcclxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dF0gQ29udGV4dHMgdG8gYmUgdW5zdWJzY3JpYmVcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Q2hhcnR9IEEgcmVmZXJlbmNlIHRvIHRoaXMgY2hhcnQgKGNoYWluYWJsZSkuXHJcbiAgICAgKi9cclxuXHJcbiAgICBvZmYobmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcclxuICAgICAgICB2YXIgbmFtZXMsIG4sIGV2ZW50cywgZXZlbnQsIGksIGo7XHJcblxyXG4gICAgICAgIC8vIHJlbW92ZSBhbGwgZXZlbnRzXHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZm9yIChuYW1lIGluIHRoaXMuX2V2ZW50cykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW25hbWVdLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyByZW1vdmUgYWxsIGV2ZW50cyBmb3IgYSBzcGVjaWZpYyBuYW1lXHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzW25hbWVdO1xyXG4gICAgICAgICAgICBpZiAoZXZlbnRzKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudHMubGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggd2hhdGV2ZXIgY29tYmluYXRpb24gb2YgbmFtZSwgY29udGV4dFxyXG4gICAgICAgIC8vIGFuZCBjYWxsYmFjay5cclxuICAgICAgICBuYW1lcyA9IG5hbWUgPyBbbmFtZV0gOiBPYmplY3Qua2V5cyh0aGlzLl9ldmVudHMpO1xyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBuID0gbmFtZXNbaV07XHJcbiAgICAgICAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuXTtcclxuICAgICAgICAgICAgaiA9IGV2ZW50cy5sZW5ndGg7XHJcbiAgICAgICAgICAgIHdoaWxlIChqLS0pIHtcclxuICAgICAgICAgICAgICAgIGV2ZW50ID0gZXZlbnRzW2pdO1xyXG4gICAgICAgICAgICAgICAgaWYgKChjYWxsYmFjayAmJiBjYWxsYmFjayA9PT0gZXZlbnQuY2FsbGJhY2spIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgKGNvbnRleHQgJiYgY29udGV4dCA9PT0gZXZlbnQuY29udGV4dCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudHMuc3BsaWNlKGosIDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy9Cb3Jyb3dlZCBmcm9tIGQzLmNoYXJ0XHJcbiAgICAvKipcclxuICAgICAqIFB1Ymxpc2ggYW4gZXZlbnQgb24gdGhpcyBjaGFydCB3aXRoIHRoZSBnaXZlbiBgbmFtZWAuXHJcbiAgICAgKlxyXG4gICAgICogQGV4dGVybmFsRXhhbXBsZSB7cnVubmFibGV9IGNoYXJ0LXRyaWdnZXJcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBOYW1lIG9mIHRoZSBldmVudCB0byBwdWJsaXNoXHJcbiAgICAgKiBAcGFyYW0gey4uLip9IGFyZ3VtZW50cyBWYWx1ZXMgd2l0aCB3aGljaCB0byBpbnZva2UgdGhlIHJlZ2lzdGVyZWRcclxuICAgICAqICAgICAgICBjYWxsYmFja3MuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0NoYXJ0fSBBIHJlZmVyZW5jZSB0byB0aGlzIGNoYXJ0IChjaGFpbmFibGUpLlxyXG4gICAgICovXHJcbiAgICB0cmlnZ2VyKG5hbWUpIHtcclxuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XHJcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuYW1lXTtcclxuICAgICAgICB2YXIgaSwgZXY7XHJcblxyXG4gICAgICAgIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBldiA9IGV2ZW50c1tpXTtcclxuICAgICAgICAgICAgICAgIGV2LmNhbGxiYWNrLmFwcGx5KGV2LmNvbnRleHQsIGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBnZXRCYXNlQ29udGFpbmVyKCl7XHJcbiAgICAgICAgaWYodGhpcy5faXNBdHRhY2hlZCl7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmJhc2VDb250YWluZXIuc3ZnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZDMuc2VsZWN0KHRoaXMuYmFzZUNvbnRhaW5lcik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0QmFzZUNvbnRhaW5lck5vZGUoKXtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QmFzZUNvbnRhaW5lcigpLm5vZGUoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcmVmaXhDbGFzcyhjbGF6eiwgYWRkRG90KXtcclxuICAgICAgICByZXR1cm4gYWRkRG90PyAnLic6ICcnK3RoaXMuY29uZmlnLmNzc0NsYXNzUHJlZml4K2NsYXp6O1xyXG4gICAgfVxyXG4gICAgY29tcHV0ZVBsb3RTaXplKCkge1xyXG4gICAgICAgIHRoaXMucGxvdC53aWR0aCA9IFV0aWxzLmF2YWlsYWJsZVdpZHRoKHRoaXMuY29uZmlnLndpZHRoLCB0aGlzLmdldEJhc2VDb250YWluZXIoKSwgdGhpcy5wbG90Lm1hcmdpbik7XHJcbiAgICAgICAgdGhpcy5wbG90LmhlaWdodCA9IFV0aWxzLmF2YWlsYWJsZUhlaWdodCh0aGlzLmNvbmZpZy5oZWlnaHQsIHRoaXMuZ2V0QmFzZUNvbnRhaW5lcigpLCB0aGlzLnBsb3QubWFyZ2luKTtcclxuICAgIH1cclxuXHJcbiAgICB0cmFuc2l0aW9uRW5hYmxlZCgpe1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pc0luaXRpYWxpemVkICYmIHRoaXMuY29uZmlnLnRyYW5zaXRpb247XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcbmltcG9ydCB7U3RhdGlzdGljc1V0aWxzfSBmcm9tICcuL3N0YXRpc3RpY3MtdXRpbHMnXHJcbmltcG9ydCB7TGVnZW5kfSBmcm9tICcuL2xlZ2VuZCdcclxuaW1wb3J0IHtTY2F0dGVyUGxvdH0gZnJvbSAnLi9zY2F0dGVycGxvdCdcclxuXHJcbmV4cG9ydCBjbGFzcyBDb3JyZWxhdGlvbk1hdHJpeENvbmZpZyBleHRlbmRzIENoYXJ0Q29uZmlnIHtcclxuXHJcbiAgICBzdmdDbGFzcyA9IHRoaXMuY3NzQ2xhc3NQcmVmaXgrJ2NvcnJlbGF0aW9uLW1hdHJpeCc7XHJcbiAgICBndWlkZXMgPSBmYWxzZTsgLy9zaG93IGF4aXMgZ3VpZGVzXHJcbiAgICBzaG93VG9vbHRpcCA9IHRydWU7IC8vc2hvdyB0b29sdGlwIG9uIGRvdCBob3ZlclxyXG4gICAgc2hvd0xlZ2VuZCA9IHRydWU7XHJcbiAgICBoaWdobGlnaHRMYWJlbHMgPSB0cnVlO1xyXG4gICAgcm90YXRlTGFiZWxzWCA9IHRydWU7XHJcbiAgICByb3RhdGVMYWJlbHNZID0gdHJ1ZTtcclxuICAgIHZhcmlhYmxlcyA9IHtcclxuICAgICAgICBsYWJlbHM6IHVuZGVmaW5lZCxcclxuICAgICAgICBrZXlzOiBbXSwgLy9vcHRpb25hbCBhcnJheSBvZiB2YXJpYWJsZSBrZXlzXHJcbiAgICAgICAgdmFsdWU6IChkLCB2YXJpYWJsZUtleSkgPT4gZFt2YXJpYWJsZUtleV0sIC8vIHZhcmlhYmxlIHZhbHVlIGFjY2Vzc29yXHJcbiAgICAgICAgc2NhbGU6IFwib3JkaW5hbFwiXHJcbiAgICB9O1xyXG4gICAgY29ycmVsYXRpb24gPSB7XHJcbiAgICAgICAgc2NhbGU6IFwibGluZWFyXCIsXHJcbiAgICAgICAgZG9tYWluOiBbLTEsIC0wLjc1LCAtMC41LCAwLCAwLjUsIDAuNzUsIDFdLFxyXG4gICAgICAgIHJhbmdlOiBbXCJkYXJrYmx1ZVwiLCBcImJsdWVcIiwgXCJsaWdodHNreWJsdWVcIiwgXCJ3aGl0ZVwiLCBcIm9yYW5nZXJlZFwiLCBcImNyaW1zb25cIiwgXCJkYXJrcmVkXCJdLFxyXG4gICAgICAgIHZhbHVlOiAoeFZhbHVlcywgeVZhbHVlcykgPT4gU3RhdGlzdGljc1V0aWxzLnNhbXBsZUNvcnJlbGF0aW9uKHhWYWx1ZXMsIHlWYWx1ZXMpXHJcblxyXG4gICAgfTtcclxuICAgIGNlbGwgPSB7XHJcbiAgICAgICAgc2hhcGU6IFwiZWxsaXBzZVwiLCAvL3Bvc3NpYmxlIHZhbHVlczogcmVjdCwgY2lyY2xlLCBlbGxpcHNlXHJcbiAgICAgICAgc2l6ZTogdW5kZWZpbmVkLFxyXG4gICAgICAgIHNpemVNaW46IDE1LFxyXG4gICAgICAgIHNpemVNYXg6IDI1MCxcclxuICAgICAgICBwYWRkaW5nOiAxXHJcbiAgICB9O1xyXG4gICAgbWFyZ2luID0ge1xyXG4gICAgICAgIGxlZnQ6IDYwLFxyXG4gICAgICAgIHJpZ2h0OiA1MCxcclxuICAgICAgICB0b3A6IDMwLFxyXG4gICAgICAgIGJvdHRvbTogNjBcclxuICAgIH07XHJcblxyXG4gICAgY29uc3RydWN0b3IoY3VzdG9tKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICBpZiAoY3VzdG9tKSB7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBDb3JyZWxhdGlvbk1hdHJpeCBleHRlbmRzIENoYXJ0IHtcclxuICAgIGNvbnN0cnVjdG9yKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIGNvbmZpZykge1xyXG4gICAgICAgIHN1cGVyKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIG5ldyBDb3JyZWxhdGlvbk1hdHJpeENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRDb25maWcoY29uZmlnKSB7XHJcbiAgICAgICAgcmV0dXJuIHN1cGVyLnNldENvbmZpZyhuZXcgQ29ycmVsYXRpb25NYXRyaXhDb25maWcoY29uZmlnKSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXRQbG90KCkge1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBtYXJnaW4gPSB0aGlzLmNvbmZpZy5tYXJnaW47XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnggPSB7fTtcclxuICAgICAgICB0aGlzLnBsb3QuY29ycmVsYXRpb24gPSB7XHJcbiAgICAgICAgICAgIG1hdHJpeDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjZWxsczogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjb2xvcjoge30sXHJcbiAgICAgICAgICAgIHNoYXBlOiB7fVxyXG4gICAgICAgIH07XHJcblxyXG5cclxuICAgICAgICB0aGlzLnNldHVwVmFyaWFibGVzKCk7XHJcbiAgICAgICAgdmFyIHdpZHRoID0gY29uZi53aWR0aDtcclxuICAgICAgICB2YXIgcGxhY2Vob2xkZXJOb2RlID0gdGhpcy5nZXRCYXNlQ29udGFpbmVyTm9kZSgpO1xyXG4gICAgICAgIHRoaXMucGxvdC5wbGFjZWhvbGRlck5vZGUgPSBwbGFjZWhvbGRlck5vZGU7XHJcblxyXG4gICAgICAgIHZhciBwYXJlbnRXaWR0aCA9IHBsYWNlaG9sZGVyTm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aDtcclxuICAgICAgICBpZiAod2lkdGgpIHtcclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5wbG90LmNlbGxTaXplKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuY2VsbFNpemUgPSBNYXRoLm1heChjb25mLmNlbGwuc2l6ZU1pbiwgTWF0aC5taW4oY29uZi5jZWxsLnNpemVNYXgsICh3aWR0aCAtIG1hcmdpbi5sZWZ0IC0gbWFyZ2luLnJpZ2h0KSAvIHRoaXMucGxvdC52YXJpYWJsZXMubGVuZ3RoKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmNlbGxTaXplID0gdGhpcy5jb25maWcuY2VsbC5zaXplO1xyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLnBsb3QuY2VsbFNpemUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxvdC5jZWxsU2l6ZSA9IE1hdGgubWF4KGNvbmYuY2VsbC5zaXplTWluLCBNYXRoLm1pbihjb25mLmNlbGwuc2l6ZU1heCwgKHBhcmVudFdpZHRoIC0gbWFyZ2luLmxlZnQgLSBtYXJnaW4ucmlnaHQpIC8gdGhpcy5wbG90LnZhcmlhYmxlcy5sZW5ndGgpKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgd2lkdGggPSB0aGlzLnBsb3QuY2VsbFNpemUgKiB0aGlzLnBsb3QudmFyaWFibGVzLmxlbmd0aCArIG1hcmdpbi5sZWZ0ICsgbWFyZ2luLnJpZ2h0O1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoZWlnaHQgPSB3aWR0aDtcclxuICAgICAgICBpZiAoIWhlaWdodCkge1xyXG4gICAgICAgICAgICBoZWlnaHQgPSBwbGFjZWhvbGRlck5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5wbG90LndpZHRoID0gd2lkdGggLSBtYXJnaW4ubGVmdCAtIG1hcmdpbi5yaWdodDtcclxuICAgICAgICB0aGlzLnBsb3QuaGVpZ2h0ID0gdGhpcy5wbG90LndpZHRoO1xyXG5cclxuICAgICAgICB0aGlzLnNldHVwVmFyaWFibGVzU2NhbGVzKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cENvcnJlbGF0aW9uU2NhbGVzKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cENvcnJlbGF0aW9uTWF0cml4KCk7XHJcblxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBzZXR1cFZhcmlhYmxlc1NjYWxlcygpIHtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIHggPSBwbG90Lng7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZy52YXJpYWJsZXM7XHJcblxyXG4gICAgICAgIC8qICpcclxuICAgICAgICAgKiB2YWx1ZSBhY2Nlc3NvciAtIHJldHVybnMgdGhlIHZhbHVlIHRvIGVuY29kZSBmb3IgYSBnaXZlbiBkYXRhIG9iamVjdC5cclxuICAgICAgICAgKiBzY2FsZSAtIG1hcHMgdmFsdWUgdG8gYSB2aXN1YWwgZGlzcGxheSBlbmNvZGluZywgc3VjaCBhcyBhIHBpeGVsIHBvc2l0aW9uLlxyXG4gICAgICAgICAqIG1hcCBmdW5jdGlvbiAtIG1hcHMgZnJvbSBkYXRhIHZhbHVlIHRvIGRpc3BsYXkgdmFsdWVcclxuICAgICAgICAgKiBheGlzIC0gc2V0cyB1cCBheGlzXHJcbiAgICAgICAgICoqL1xyXG4gICAgICAgIHgudmFsdWUgPSBjb25mLnZhbHVlO1xyXG4gICAgICAgIHguc2NhbGUgPSBkMy5zY2FsZVtjb25mLnNjYWxlXSgpLnJhbmdlQmFuZHMoW3Bsb3Qud2lkdGgsIDBdKTtcclxuICAgICAgICB4Lm1hcCA9IGQgPT4geC5zY2FsZSh4LnZhbHVlKGQpKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIHNldHVwQ29ycmVsYXRpb25TY2FsZXMoKSB7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIGNvcnJDb25mID0gdGhpcy5jb25maWcuY29ycmVsYXRpb247XHJcblxyXG4gICAgICAgIHBsb3QuY29ycmVsYXRpb24uY29sb3Iuc2NhbGUgPSBkMy5zY2FsZVtjb3JyQ29uZi5zY2FsZV0oKS5kb21haW4oY29yckNvbmYuZG9tYWluKS5yYW5nZShjb3JyQ29uZi5yYW5nZSk7XHJcbiAgICAgICAgdmFyIHNoYXBlID0gcGxvdC5jb3JyZWxhdGlvbi5zaGFwZSA9IHt9O1xyXG5cclxuICAgICAgICB2YXIgY2VsbENvbmYgPSB0aGlzLmNvbmZpZy5jZWxsO1xyXG4gICAgICAgIHNoYXBlLnR5cGUgPSBjZWxsQ29uZi5zaGFwZTtcclxuXHJcbiAgICAgICAgdmFyIHNoYXBlU2l6ZSA9IHBsb3QuY2VsbFNpemUgLSBjZWxsQ29uZi5wYWRkaW5nICogMjtcclxuICAgICAgICBpZiAoc2hhcGUudHlwZSA9PSAnY2lyY2xlJykge1xyXG4gICAgICAgICAgICB2YXIgcmFkaXVzTWF4ID0gc2hhcGVTaXplIC8gMjtcclxuICAgICAgICAgICAgc2hhcGUucmFkaXVzU2NhbGUgPSBkMy5zY2FsZS5saW5lYXIoKS5kb21haW4oWzAsIDFdKS5yYW5nZShbMiwgcmFkaXVzTWF4XSk7XHJcbiAgICAgICAgICAgIHNoYXBlLnJhZGl1cyA9IGM9PiBzaGFwZS5yYWRpdXNTY2FsZShNYXRoLmFicyhjLnZhbHVlKSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChzaGFwZS50eXBlID09ICdlbGxpcHNlJykge1xyXG4gICAgICAgICAgICB2YXIgcmFkaXVzTWF4ID0gc2hhcGVTaXplIC8gMjtcclxuICAgICAgICAgICAgc2hhcGUucmFkaXVzU2NhbGUgPSBkMy5zY2FsZS5saW5lYXIoKS5kb21haW4oWzAsIDFdKS5yYW5nZShbcmFkaXVzTWF4LCAyXSk7XHJcbiAgICAgICAgICAgIHNoYXBlLnJhZGl1c1ggPSBjPT4gc2hhcGUucmFkaXVzU2NhbGUoTWF0aC5hYnMoYy52YWx1ZSkpO1xyXG4gICAgICAgICAgICBzaGFwZS5yYWRpdXNZID0gcmFkaXVzTWF4O1xyXG5cclxuICAgICAgICAgICAgc2hhcGUucm90YXRlVmFsID0gdiA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodiA9PSAwKSByZXR1cm4gXCIwXCI7XHJcbiAgICAgICAgICAgICAgICBpZiAodiA8IDApIHJldHVybiBcIi00NVwiO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiNDVcIlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChzaGFwZS50eXBlID09ICdyZWN0Jykge1xyXG4gICAgICAgICAgICBzaGFwZS5zaXplID0gc2hhcGVTaXplO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG5cclxuICAgIHNldHVwVmFyaWFibGVzKCkge1xyXG5cclxuICAgICAgICB2YXIgdmFyaWFibGVzQ29uZiA9IHRoaXMuY29uZmlnLnZhcmlhYmxlcztcclxuXHJcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLmRhdGE7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgcGxvdC5kb21haW5CeVZhcmlhYmxlID0ge307XHJcbiAgICAgICAgcGxvdC52YXJpYWJsZXMgPSB2YXJpYWJsZXNDb25mLmtleXM7XHJcbiAgICAgICAgaWYgKCFwbG90LnZhcmlhYmxlcyB8fCAhcGxvdC52YXJpYWJsZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHBsb3QudmFyaWFibGVzID0gVXRpbHMuaW5mZXJWYXJpYWJsZXMoZGF0YSwgdGhpcy5jb25maWcuZ3JvdXBzLmtleSwgdGhpcy5jb25maWcuaW5jbHVkZUluUGxvdCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwbG90LmxhYmVscyA9IFtdO1xyXG4gICAgICAgIHBsb3QubGFiZWxCeVZhcmlhYmxlID0ge307XHJcbiAgICAgICAgcGxvdC52YXJpYWJsZXMuZm9yRWFjaCgodmFyaWFibGVLZXksIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgIHBsb3QuZG9tYWluQnlWYXJpYWJsZVt2YXJpYWJsZUtleV0gPSBkMy5leHRlbnQoZGF0YSwgKGQpID0+IHZhcmlhYmxlc0NvbmYudmFsdWUoZCwgdmFyaWFibGVLZXkpKTtcclxuICAgICAgICAgICAgdmFyIGxhYmVsID0gdmFyaWFibGVLZXk7XHJcbiAgICAgICAgICAgIGlmICh2YXJpYWJsZXNDb25mLmxhYmVscyAmJiB2YXJpYWJsZXNDb25mLmxhYmVscy5sZW5ndGggPiBpbmRleCkge1xyXG5cclxuICAgICAgICAgICAgICAgIGxhYmVsID0gdmFyaWFibGVzQ29uZi5sYWJlbHNbaW5kZXhdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBsb3QubGFiZWxzLnB1c2gobGFiZWwpO1xyXG4gICAgICAgICAgICBwbG90LmxhYmVsQnlWYXJpYWJsZVt2YXJpYWJsZUtleV0gPSBsYWJlbDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgY29uc29sZS5sb2cocGxvdC5sYWJlbEJ5VmFyaWFibGUpO1xyXG5cclxuICAgIH07XHJcblxyXG5cclxuICAgIHNldHVwQ29ycmVsYXRpb25NYXRyaXgoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5kYXRhO1xyXG4gICAgICAgIHZhciBtYXRyaXggPSB0aGlzLnBsb3QuY29ycmVsYXRpb24ubWF0cml4ID0gW107XHJcbiAgICAgICAgdmFyIG1hdHJpeENlbGxzID0gdGhpcy5wbG90LmNvcnJlbGF0aW9uLm1hdHJpeC5jZWxscyA9IFtdO1xyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG5cclxuICAgICAgICB2YXIgdmFyaWFibGVUb1ZhbHVlcyA9IHt9O1xyXG4gICAgICAgIHBsb3QudmFyaWFibGVzLmZvckVhY2goKHYsIGkpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhcmlhYmxlVG9WYWx1ZXNbdl0gPSBkYXRhLm1hcChkPT5wbG90LngudmFsdWUoZCwgdikpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBwbG90LnZhcmlhYmxlcy5mb3JFYWNoKCh2MSwgaSkgPT4ge1xyXG4gICAgICAgICAgICB2YXIgcm93ID0gW107XHJcbiAgICAgICAgICAgIG1hdHJpeC5wdXNoKHJvdyk7XHJcblxyXG4gICAgICAgICAgICBwbG90LnZhcmlhYmxlcy5mb3JFYWNoKCh2MiwgaikgPT4ge1xyXG4gICAgICAgICAgICAgICAgdmFyIGNvcnIgPSAxO1xyXG4gICAgICAgICAgICAgICAgaWYgKHYxICE9IHYyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29yciA9IHNlbGYuY29uZmlnLmNvcnJlbGF0aW9uLnZhbHVlKHZhcmlhYmxlVG9WYWx1ZXNbdjFdLCB2YXJpYWJsZVRvVmFsdWVzW3YyXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IHtcclxuICAgICAgICAgICAgICAgICAgICByb3dWYXI6IHYxLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbFZhcjogdjIsXHJcbiAgICAgICAgICAgICAgICAgICAgcm93OiBpLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbDogaixcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogY29yclxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHJvdy5wdXNoKGNlbGwpO1xyXG5cclxuICAgICAgICAgICAgICAgIG1hdHJpeENlbGxzLnB1c2goY2VsbCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgdXBkYXRlKG5ld0RhdGEpIHtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcbiAgICAgICAgLy8gdGhpcy51cGRhdGVcclxuICAgICAgICB0aGlzLnVwZGF0ZUNlbGxzKCk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVWYXJpYWJsZUxhYmVscygpO1xyXG5cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnNob3dMZWdlbmQpIHtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVMZWdlbmQoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHVwZGF0ZVZhcmlhYmxlTGFiZWxzKCkge1xyXG4gICAgICAgIHRoaXMucGxvdC5sYWJlbENsYXNzID0gdGhpcy5wcmVmaXhDbGFzcyhcImxhYmVsXCIpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQXhpc1goKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUF4aXNZKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlQXhpc1goKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBsYWJlbENsYXNzID0gcGxvdC5sYWJlbENsYXNzO1xyXG4gICAgICAgIHZhciBsYWJlbFhDbGFzcyA9IGxhYmVsQ2xhc3MgKyBcIi14XCI7XHJcblxyXG4gICAgICAgIHZhciBsYWJlbHMgPSBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwidGV4dC5cIiArIGxhYmVsWENsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShwbG90LnZhcmlhYmxlcywgKGQsIGkpPT5pKTtcclxuXHJcbiAgICAgICAgbGFiZWxzLmVudGVyKCkuYXBwZW5kKFwidGV4dFwiKS5hdHRyKFwiY2xhc3NcIiwgKGQsIGkpID0+IGxhYmVsQ2xhc3MgKyBcIiBcIiArIGxhYmVsWENsYXNzICsgXCIgXCIgKyBsYWJlbFhDbGFzcyArIFwiLVwiICsgaSk7XHJcblxyXG4gICAgICAgIGxhYmVsc1xyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgKGQsIGkpID0+IGkgKiBwbG90LmNlbGxTaXplICsgcGxvdC5jZWxsU2l6ZSAvIDIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCBwbG90LmhlaWdodClcclxuICAgICAgICAgICAgLmF0dHIoXCJkeFwiLCAtMilcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCA1KVxyXG4gICAgICAgICAgICAuYXR0cihcInRleHQtYW5jaG9yXCIsIFwiZW5kXCIpXHJcblxyXG4gICAgICAgICAgICAvLyAuYXR0cihcImRvbWluYW50LWJhc2VsaW5lXCIsIFwiaGFuZ2luZ1wiKVxyXG4gICAgICAgICAgICAudGV4dCh2PT5wbG90LmxhYmVsQnlWYXJpYWJsZVt2XSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5yb3RhdGVMYWJlbHNYKSB7XHJcbiAgICAgICAgICAgIGxhYmVscy5hdHRyKFwidHJhbnNmb3JtXCIsIChkLCBpKSA9PiBcInJvdGF0ZSgtNDUsIFwiICsgKGkgKiBwbG90LmNlbGxTaXplICsgcGxvdC5jZWxsU2l6ZSAvIDIgICkgKyBcIiwgXCIgKyBwbG90LmhlaWdodCArIFwiKVwiKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIG1heFdpZHRoID0gc2VsZi5jb21wdXRlWEF4aXNMYWJlbHNXaWR0aCgpO1xyXG4gICAgICAgIGxhYmVscy5lYWNoKGZ1bmN0aW9uIChsYWJlbCkge1xyXG4gICAgICAgICAgICBVdGlscy5wbGFjZVRleHRXaXRoRWxsaXBzaXNBbmRUb29sdGlwKGQzLnNlbGVjdCh0aGlzKSwgbGFiZWwsIG1heFdpZHRoLCBzZWxmLmNvbmZpZy5zaG93VG9vbHRpcCA/IHNlbGYucGxvdC50b29sdGlwIDogZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsYWJlbHMuZXhpdCgpLnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUF4aXNZKCkge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHNlbGYucGxvdDtcclxuICAgICAgICB2YXIgbGFiZWxDbGFzcyA9IHBsb3QubGFiZWxDbGFzcztcclxuICAgICAgICB2YXIgbGFiZWxZQ2xhc3MgPSBwbG90LmxhYmVsQ2xhc3MgKyBcIi15XCI7XHJcbiAgICAgICAgdmFyIGxhYmVscyA9IHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgbGFiZWxZQ2xhc3MpXHJcbiAgICAgICAgICAgIC5kYXRhKHBsb3QudmFyaWFibGVzKTtcclxuXHJcbiAgICAgICAgbGFiZWxzLmVudGVyKCkuYXBwZW5kKFwidGV4dFwiKTtcclxuXHJcbiAgICAgICAgbGFiZWxzXHJcbiAgICAgICAgICAgIC5hdHRyKFwieFwiLCAwKVxyXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgKGQsIGkpID0+IGkgKiBwbG90LmNlbGxTaXplICsgcGxvdC5jZWxsU2l6ZSAvIDIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZHhcIiwgLTIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJlbmRcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCAoZCwgaSkgPT4gbGFiZWxDbGFzcyArIFwiIFwiICsgbGFiZWxZQ2xhc3MgKyBcIiBcIiArIGxhYmVsWUNsYXNzICsgXCItXCIgKyBpKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcImRvbWluYW50LWJhc2VsaW5lXCIsIFwiaGFuZ2luZ1wiKVxyXG4gICAgICAgICAgICAudGV4dCh2PT5wbG90LmxhYmVsQnlWYXJpYWJsZVt2XSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5yb3RhdGVMYWJlbHNZKSB7XHJcbiAgICAgICAgICAgIGxhYmVsc1xyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwicm90YXRlKC00NSwgXCIgKyAwICsgXCIsIFwiICsgKGkgKiBwbG90LmNlbGxTaXplICsgcGxvdC5jZWxsU2l6ZSAvIDIpICsgXCIpXCIpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInRleHQtYW5jaG9yXCIsIFwiZW5kXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIG1heFdpZHRoID0gc2VsZi5jb21wdXRlWUF4aXNMYWJlbHNXaWR0aCgpO1xyXG4gICAgICAgIGxhYmVscy5lYWNoKGZ1bmN0aW9uIChsYWJlbCkge1xyXG4gICAgICAgICAgICBVdGlscy5wbGFjZVRleHRXaXRoRWxsaXBzaXNBbmRUb29sdGlwKGQzLnNlbGVjdCh0aGlzKSwgbGFiZWwsIG1heFdpZHRoLCBzZWxmLmNvbmZpZy5zaG93VG9vbHRpcCA/IHNlbGYucGxvdC50b29sdGlwIDogZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsYWJlbHMuZXhpdCgpLnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVZQXhpc0xhYmVsc1dpZHRoKCkge1xyXG4gICAgICAgIHZhciBtYXhXaWR0aCA9IHRoaXMucGxvdC5tYXJnaW4ubGVmdDtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnJvdGF0ZUxhYmVsc1kpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG1heFdpZHRoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbWF4V2lkdGggKj0gVXRpbHMuU1FSVF8yO1xyXG4gICAgICAgIHZhciBmb250U2l6ZSA9IDExOyAvL3RvZG8gY2hlY2sgYWN0dWFsIGZvbnQgc2l6ZVxyXG4gICAgICAgIG1heFdpZHRoIC09IGZvbnRTaXplIC8gMjtcclxuXHJcbiAgICAgICAgcmV0dXJuIG1heFdpZHRoO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVYQXhpc0xhYmVsc1dpZHRoKG9mZnNldCkge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcucm90YXRlTGFiZWxzWCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wbG90LmNlbGxTaXplIC0gMjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNpemUgPSB0aGlzLnBsb3QubWFyZ2luLmJvdHRvbTtcclxuICAgICAgICBzaXplICo9IFV0aWxzLlNRUlRfMjtcclxuICAgICAgICB2YXIgZm9udFNpemUgPSAxMTsgLy90b2RvIGNoZWNrIGFjdHVhbCBmb250IHNpemVcclxuICAgICAgICBzaXplIC09IGZvbnRTaXplIC8gMjtcclxuICAgICAgICByZXR1cm4gc2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVDZWxscygpIHtcclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBjZWxsQ2xhc3MgPSBzZWxmLnByZWZpeENsYXNzKFwiY2VsbFwiKTtcclxuICAgICAgICB2YXIgY2VsbFNoYXBlID0gcGxvdC5jb3JyZWxhdGlvbi5zaGFwZS50eXBlO1xyXG5cclxuICAgICAgICB2YXIgY2VsbHMgPSBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwiZy5cIiArIGNlbGxDbGFzcylcclxuICAgICAgICAgICAgLmRhdGEocGxvdC5jb3JyZWxhdGlvbi5tYXRyaXguY2VsbHMpO1xyXG5cclxuICAgICAgICB2YXIgY2VsbEVudGVyRyA9IGNlbGxzLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuY2xhc3NlZChjZWxsQ2xhc3MsIHRydWUpO1xyXG4gICAgICAgIGNlbGxzLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgYz0+IFwidHJhbnNsYXRlKFwiICsgKHBsb3QuY2VsbFNpemUgKiBjLmNvbCArIHBsb3QuY2VsbFNpemUgLyAyKSArIFwiLFwiICsgKHBsb3QuY2VsbFNpemUgKiBjLnJvdyArIHBsb3QuY2VsbFNpemUgLyAyKSArIFwiKVwiKTtcclxuXHJcbiAgICAgICAgY2VsbHMuY2xhc3NlZChzZWxmLmNvbmZpZy5jc3NDbGFzc1ByZWZpeCArIFwic2VsZWN0YWJsZVwiLCAhIXNlbGYuc2NhdHRlclBsb3QpO1xyXG5cclxuICAgICAgICB2YXIgc2VsZWN0b3IgPSBcIio6bm90KC5jZWxsLXNoYXBlLVwiICsgY2VsbFNoYXBlICsgXCIpXCI7XHJcblxyXG4gICAgICAgIHZhciB3cm9uZ1NoYXBlcyA9IGNlbGxzLnNlbGVjdEFsbChzZWxlY3Rvcik7XHJcbiAgICAgICAgd3JvbmdTaGFwZXMucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgIHZhciBzaGFwZXMgPSBjZWxscy5zZWxlY3RPckFwcGVuZChjZWxsU2hhcGUgKyBcIi5jZWxsLXNoYXBlLVwiICsgY2VsbFNoYXBlKTtcclxuXHJcbiAgICAgICAgaWYgKHBsb3QuY29ycmVsYXRpb24uc2hhcGUudHlwZSA9PSAnY2lyY2xlJykge1xyXG5cclxuICAgICAgICAgICAgc2hhcGVzXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInJcIiwgcGxvdC5jb3JyZWxhdGlvbi5zaGFwZS5yYWRpdXMpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImN4XCIsIDApXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImN5XCIsIDApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBsb3QuY29ycmVsYXRpb24uc2hhcGUudHlwZSA9PSAnZWxsaXBzZScpIHtcclxuICAgICAgICAgICAgLy8gY2VsbHMuYXR0cihcInRyYW5zZm9ybVwiLCBjPT4gXCJ0cmFuc2xhdGUoMzAwLDE1MCkgcm90YXRlKFwiK3Bsb3QuY29ycmVsYXRpb24uc2hhcGUucm90YXRlVmFsKGMudmFsdWUpK1wiKVwiKTtcclxuICAgICAgICAgICAgc2hhcGVzXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInJ4XCIsIHBsb3QuY29ycmVsYXRpb24uc2hhcGUucmFkaXVzWClcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwicnlcIiwgcGxvdC5jb3JyZWxhdGlvbi5zaGFwZS5yYWRpdXNZKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJjeFwiLCAwKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJjeVwiLCAwKVxyXG5cclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIGM9PiBcInJvdGF0ZShcIiArIHBsb3QuY29ycmVsYXRpb24uc2hhcGUucm90YXRlVmFsKGMudmFsdWUpICsgXCIpXCIpO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIGlmIChwbG90LmNvcnJlbGF0aW9uLnNoYXBlLnR5cGUgPT0gJ3JlY3QnKSB7XHJcbiAgICAgICAgICAgIHNoYXBlc1xyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBwbG90LmNvcnJlbGF0aW9uLnNoYXBlLnNpemUpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCBwbG90LmNvcnJlbGF0aW9uLnNoYXBlLnNpemUpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcInhcIiwgLXBsb3QuY2VsbFNpemUgLyAyKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIC1wbG90LmNlbGxTaXplIC8gMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNoYXBlcy5zdHlsZShcImZpbGxcIiwgYz0+IHBsb3QuY29ycmVsYXRpb24uY29sb3Iuc2NhbGUoYy52YWx1ZSkpO1xyXG5cclxuICAgICAgICB2YXIgbW91c2VvdmVyQ2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgdmFyIG1vdXNlb3V0Q2FsbGJhY2tzID0gW107XHJcblxyXG4gICAgICAgIGlmIChwbG90LnRvb2x0aXApIHtcclxuXHJcbiAgICAgICAgICAgIG1vdXNlb3ZlckNhbGxiYWNrcy5wdXNoKGM9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDIwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIC45KTtcclxuICAgICAgICAgICAgICAgIHZhciBodG1sID0gYy52YWx1ZTtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGh0bWwpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwibGVmdFwiLCAoZDMuZXZlbnQucGFnZVggKyA1KSArIFwicHhcIilcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgKGQzLmV2ZW50LnBhZ2VZIC0gMjgpICsgXCJweFwiKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBtb3VzZW91dENhbGxiYWNrcy5wdXNoKGM9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDUwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIDApO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNlbGYuY29uZmlnLmhpZ2hsaWdodExhYmVscykge1xyXG4gICAgICAgICAgICB2YXIgaGlnaGxpZ2h0Q2xhc3MgPSBzZWxmLmNvbmZpZy5jc3NDbGFzc1ByZWZpeCArIFwiaGlnaGxpZ2h0XCI7XHJcbiAgICAgICAgICAgIHZhciB4TGFiZWxDbGFzcyA9IGM9PnBsb3QubGFiZWxDbGFzcyArIFwiLXgtXCIgKyBjLmNvbDtcclxuICAgICAgICAgICAgdmFyIHlMYWJlbENsYXNzID0gYz0+cGxvdC5sYWJlbENsYXNzICsgXCIteS1cIiArIGMucm93O1xyXG5cclxuXHJcbiAgICAgICAgICAgIG1vdXNlb3ZlckNhbGxiYWNrcy5wdXNoKGM9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgc2VsZi5zdmdHLnNlbGVjdEFsbChcInRleHQuXCIgKyB4TGFiZWxDbGFzcyhjKSkuY2xhc3NlZChoaWdobGlnaHRDbGFzcywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwidGV4dC5cIiArIHlMYWJlbENsYXNzKGMpKS5jbGFzc2VkKGhpZ2hsaWdodENsYXNzLCB0cnVlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG1vdXNlb3V0Q2FsbGJhY2tzLnB1c2goYz0+IHtcclxuICAgICAgICAgICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgeExhYmVsQ2xhc3MoYykpLmNsYXNzZWQoaGlnaGxpZ2h0Q2xhc3MsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgeUxhYmVsQ2xhc3MoYykpLmNsYXNzZWQoaGlnaGxpZ2h0Q2xhc3MsIGZhbHNlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgY2VsbHMub24oXCJtb3VzZW92ZXJcIiwgYyA9PiB7XHJcbiAgICAgICAgICAgIG1vdXNlb3ZlckNhbGxiYWNrcy5mb3JFYWNoKGNhbGxiYWNrPT5jYWxsYmFjayhjKSk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLm9uKFwibW91c2VvdXRcIiwgYyA9PiB7XHJcbiAgICAgICAgICAgICAgICBtb3VzZW91dENhbGxiYWNrcy5mb3JFYWNoKGNhbGxiYWNrPT5jYWxsYmFjayhjKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICBjZWxscy5vbihcImNsaWNrXCIsIGM9PiB7XHJcbiAgICAgICAgICAgIHNlbGYudHJpZ2dlcihcImNlbGwtc2VsZWN0ZWRcIiwgYyk7XHJcbiAgICAgICAgfSk7XHJcblxyXG5cclxuICAgICAgICBjZWxscy5leGl0KCkucmVtb3ZlKCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIHVwZGF0ZUxlZ2VuZCgpIHtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIGxlZ2VuZFggPSB0aGlzLnBsb3Qud2lkdGggKyAxMDtcclxuICAgICAgICB2YXIgbGVnZW5kWSA9IDA7XHJcbiAgICAgICAgdmFyIGJhcldpZHRoID0gMTA7XHJcbiAgICAgICAgdmFyIGJhckhlaWdodCA9IHRoaXMucGxvdC5oZWlnaHQgLSAyO1xyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3QuY29ycmVsYXRpb24uY29sb3Iuc2NhbGU7XHJcblxyXG4gICAgICAgIHBsb3QubGVnZW5kID0gbmV3IExlZ2VuZCh0aGlzLnN2ZywgdGhpcy5zdmdHLCBzY2FsZSwgbGVnZW5kWCwgbGVnZW5kWSkubGluZWFyR3JhZGllbnRCYXIoYmFyV2lkdGgsIGJhckhlaWdodCk7XHJcblxyXG5cclxuICAgIH1cclxuXHJcbiAgICBhdHRhY2hTY2F0dGVyUGxvdChjb250YWluZXJTZWxlY3RvciwgY29uZmlnKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICBjb25maWcgPSBjb25maWcgfHwge307XHJcblxyXG5cclxuICAgICAgICB2YXIgc2NhdHRlclBsb3RDb25maWcgPSB7XHJcbiAgICAgICAgICAgIGhlaWdodDogc2VsZi5wbG90LmhlaWdodCArIHNlbGYuY29uZmlnLm1hcmdpbi50b3AgKyBzZWxmLmNvbmZpZy5tYXJnaW4uYm90dG9tLFxyXG4gICAgICAgICAgICB3aWR0aDogc2VsZi5wbG90LmhlaWdodCArIHNlbGYuY29uZmlnLm1hcmdpbi50b3AgKyBzZWxmLmNvbmZpZy5tYXJnaW4uYm90dG9tLFxyXG4gICAgICAgICAgICBncm91cHM6IHtcclxuICAgICAgICAgICAgICAgIGtleTogc2VsZi5jb25maWcuZ3JvdXBzLmtleSxcclxuICAgICAgICAgICAgICAgIGxhYmVsOiBzZWxmLmNvbmZpZy5ncm91cHMubGFiZWxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZ3VpZGVzOiB0cnVlLFxyXG4gICAgICAgICAgICBzaG93TGVnZW5kOiBmYWxzZVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHNlbGYuc2NhdHRlclBsb3QgPSB0cnVlO1xyXG5cclxuICAgICAgICBzY2F0dGVyUGxvdENvbmZpZyA9IFV0aWxzLmRlZXBFeHRlbmQoc2NhdHRlclBsb3RDb25maWcsIGNvbmZpZyk7XHJcbiAgICAgICAgdGhpcy51cGRhdGUoKTtcclxuXHJcbiAgICAgICAgdGhpcy5vbihcImNlbGwtc2VsZWN0ZWRcIiwgYz0+IHtcclxuXHJcblxyXG4gICAgICAgICAgICBzY2F0dGVyUGxvdENvbmZpZy54ID0ge1xyXG4gICAgICAgICAgICAgICAga2V5OiBjLnJvd1ZhcixcclxuICAgICAgICAgICAgICAgIGxhYmVsOiBzZWxmLnBsb3QubGFiZWxCeVZhcmlhYmxlW2Mucm93VmFyXVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBzY2F0dGVyUGxvdENvbmZpZy55ID0ge1xyXG4gICAgICAgICAgICAgICAga2V5OiBjLmNvbFZhcixcclxuICAgICAgICAgICAgICAgIGxhYmVsOiBzZWxmLnBsb3QubGFiZWxCeVZhcmlhYmxlW2MuY29sVmFyXVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5zY2F0dGVyUGxvdCAmJiBzZWxmLnNjYXR0ZXJQbG90ICE9PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnNjYXR0ZXJQbG90LnNldENvbmZpZyhzY2F0dGVyUGxvdENvbmZpZykuaW5pdCgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5zY2F0dGVyUGxvdCA9IG5ldyBTY2F0dGVyUGxvdChjb250YWluZXJTZWxlY3Rvciwgc2VsZi5kYXRhLCBzY2F0dGVyUGxvdENvbmZpZyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmF0dGFjaChcIlNjYXR0ZXJQbG90XCIsIHNlbGYuc2NhdHRlclBsb3QpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIEQzRXh0ZW5zaW9uc3tcclxuXHJcbiAgICBzdGF0aWMgZXh0ZW5kKCl7XHJcblxyXG4gICAgICAgIGQzLnNlbGVjdGlvbi5lbnRlci5wcm90b3R5cGUuaW5zZXJ0U2VsZWN0b3IgPVxyXG4gICAgICAgICAgICBkMy5zZWxlY3Rpb24ucHJvdG90eXBlLmluc2VydFNlbGVjdG9yID0gZnVuY3Rpb24oc2VsZWN0b3IsIGJlZm9yZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzLmluc2VydFNlbGVjdG9yKHRoaXMsIHNlbGVjdG9yLCBiZWZvcmUpO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuXHJcbiAgICAgICAgZDMuc2VsZWN0aW9uLmVudGVyLnByb3RvdHlwZS5hcHBlbmRTZWxlY3RvciA9XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUuYXBwZW5kU2VsZWN0b3IgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzLmFwcGVuZFNlbGVjdG9yKHRoaXMsIHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgZDMuc2VsZWN0aW9uLmVudGVyLnByb3RvdHlwZS5zZWxlY3RPckFwcGVuZCA9XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUuc2VsZWN0T3JBcHBlbmQgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnNlbGVjdE9yQXBwZW5kKHRoaXMsIHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgZDMuc2VsZWN0aW9uLmVudGVyLnByb3RvdHlwZS5zZWxlY3RPckluc2VydCA9XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUuc2VsZWN0T3JJbnNlcnQgPSBmdW5jdGlvbihzZWxlY3RvciwgYmVmb3JlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRpbHMuc2VsZWN0T3JJbnNlcnQodGhpcywgc2VsZWN0b3IsIGJlZm9yZSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG5cclxuXHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7SGVhdG1hcCwgSGVhdG1hcENvbmZpZ30gZnJvbSBcIi4vaGVhdG1hcFwiO1xyXG5pbXBvcnQge1V0aWxzfSBmcm9tICcuL3V0aWxzJ1xyXG5pbXBvcnQge1N0YXRpc3RpY3NVdGlsc30gZnJvbSAnLi9zdGF0aXN0aWNzLXV0aWxzJ1xyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBIZWF0bWFwVGltZVNlcmllc0NvbmZpZyBleHRlbmRzIEhlYXRtYXBDb25maWcge1xyXG4gICAgeCA9IHtcclxuICAgICAgICBmaWxsTWlzc2luZzogZmFsc2UsIC8vIGZpbGwgbWlzc2luZyB2YWx1ZXMgdXNpbmcgaW50ZXJ2YWwgYW5kIGludGVydmFsU3RlcFxyXG4gICAgICAgIGludGVydmFsOiB1bmRlZmluZWQsIC8vdXNlZCBpbiBmaWxsaW5nIG1pc3NpbmcgdGlja3NcclxuICAgICAgICBpbnRlcnZhbFN0ZXA6IDEsXHJcbiAgICAgICAgZm9ybWF0OiB1bmRlZmluZWQsIC8vaW5wdXQgZGF0YSBkMyB0aW1lIGZvcm1hdFxyXG4gICAgICAgIGRpc3BsYXlGb3JtYXQ6IHVuZGVmaW5lZCwvL2QzIHRpbWUgZm9ybWF0IGZvciBkaXNwbGF5XHJcbiAgICAgICAgaW50ZXJ2YWxUb0Zvcm1hdHM6IFsgLy91c2VkIHRvIGd1ZXNzIGludGVydmFsIGFuZCBmb3JtYXRcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ3llYXInLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogW1wiJVlcIl1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ21vbnRoJyxcclxuICAgICAgICAgICAgICAgIGZvcm1hdHM6IFtcIiVZLSVtXCJdXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdkYXknLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogW1wiJVktJW0tJWRcIl1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ2hvdXInLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogWyclSCcsICclWS0lbS0lZCAlSCddXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdtaW51dGUnLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogWyclSDolTScsICclWS0lbS0lZCAlSDolTSddXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdzZWNvbmQnLFxyXG4gICAgICAgICAgICAgICAgZm9ybWF0czogWyclSDolTTolUycsICclWS0lbS0lZCAlSDolTTolUyddXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBdLFxyXG5cclxuICAgICAgICBzb3J0Q29tcGFyYXRvcjogZnVuY3Rpb24gc29ydENvbXBhcmF0b3IoYSwgYikge1xyXG4gICAgICAgICAgICByZXR1cm4gVXRpbHMuaXNTdHJpbmcoYSkgPyAgYS5sb2NhbGVDb21wYXJlKGIpIDogIGEgLSBiO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZm9ybWF0dGVyOiB1bmRlZmluZWRcclxuICAgIH07XHJcbiAgICB6ID0ge1xyXG4gICAgICAgIGZpbGxNaXNzaW5nOiB0cnVlIC8vIGZpaWxsIG1pc3NpbmcgdmFsdWVzIHdpdGggbmVhcmVzdCBwcmV2aW91cyB2YWx1ZVxyXG4gICAgfTtcclxuXHJcbiAgICBsZWdlbmQgPSB7XHJcbiAgICAgICAgZm9ybWF0dGVyOiBmdW5jdGlvbiAodikge1xyXG4gICAgICAgICAgICB2YXIgc3VmZml4ID0gXCJcIjtcclxuICAgICAgICAgICAgaWYgKHYgLyAxMDAwMDAwID49IDEpIHtcclxuICAgICAgICAgICAgICAgIHN1ZmZpeCA9IFwiIE1cIjtcclxuICAgICAgICAgICAgICAgIHYgPSBOdW1iZXIodiAvIDEwMDAwMDApLnRvRml4ZWQoMyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIG5mID0gSW50bC5OdW1iZXJGb3JtYXQoKTtcclxuICAgICAgICAgICAgcmV0dXJuIG5mLmZvcm1hdCh2KSArIHN1ZmZpeDtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGN1c3RvbSkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG4gICAgICAgIGlmIChjdXN0b20pIHtcclxuICAgICAgICAgICAgVXRpbHMuZGVlcEV4dGVuZCh0aGlzLCBjdXN0b20pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBIZWF0bWFwVGltZVNlcmllcyBleHRlbmRzIEhlYXRtYXAge1xyXG4gICAgY29uc3RydWN0b3IocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgY29uZmlnKSB7XHJcbiAgICAgICAgc3VwZXIocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgbmV3IEhlYXRtYXBUaW1lU2VyaWVzQ29uZmlnKGNvbmZpZykpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldENvbmZpZyhjb25maWcpIHtcclxuICAgICAgICByZXR1cm4gc3VwZXIuc2V0Q29uZmlnKG5ldyBIZWF0bWFwVGltZVNlcmllc0NvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgc2V0dXBWYWx1ZXNCZWZvcmVHcm91cHNTb3J0KCkge1xyXG5cclxuICAgICAgICB0aGlzLnBsb3QueC50aW1lRm9ybWF0ID0gdGhpcy5jb25maWcueC5mb3JtYXQ7XHJcbiAgICAgICAgaWYodGhpcy5jb25maWcueC5kaXNwbGF5Rm9ybWF0ICYmICF0aGlzLnBsb3QueC50aW1lRm9ybWF0KXtcclxuICAgICAgICAgICAgdGhpcy5ndWVzc1RpbWVGb3JtYXQoKTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBzdXBlci5zZXR1cFZhbHVlc0JlZm9yZUdyb3Vwc1NvcnQoKTtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnguZmlsbE1pc3NpbmcpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICB0aGlzLmluaXRUaW1lRm9ybWF0QW5kSW50ZXJ2YWwoKTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnguaW50ZXJ2YWxTdGVwID0gdGhpcy5jb25maWcueC5pbnRlcnZhbFN0ZXAgfHwgMTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LngudGltZVBhcnNlciA9IHRoaXMuZ2V0VGltZVBhcnNlcigpO1xyXG5cclxuXHJcblxyXG4gICAgICAgIHRoaXMucGxvdC54LnVuaXF1ZVZhbHVlcy5zb3J0KHRoaXMuY29uZmlnLnguc29ydENvbXBhcmF0b3IpO1xyXG5cclxuICAgICAgICB2YXIgcHJldiA9IG51bGw7XHJcblxyXG4gICAgICAgIHRoaXMucGxvdC54LnVuaXF1ZVZhbHVlcy5mb3JFYWNoKCh4LCBpKT0+IHtcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLnBhcnNlVGltZSh4KTtcclxuICAgICAgICAgICAgaWYgKHByZXYgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHByZXYgPSBjdXJyZW50O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIgbmV4dCA9IHNlbGYubmV4dFRpbWVUaWNrVmFsdWUocHJldik7XHJcbiAgICAgICAgICAgIHZhciBtaXNzaW5nID0gW107XHJcbiAgICAgICAgICAgIHZhciBpdGVyYXRpb24gPSAwO1xyXG4gICAgICAgICAgICB3aGlsZSAoc2VsZi5jb21wYXJlVGltZVZhbHVlcyhuZXh0LCBjdXJyZW50KTw9MCkge1xyXG4gICAgICAgICAgICAgICAgaXRlcmF0aW9uKys7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlcmF0aW9uID4gMTAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgZCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIHRpbWVTdHJpbmcgPSBzZWxmLmZvcm1hdFRpbWUobmV4dCk7XHJcbiAgICAgICAgICAgICAgICBkW3RoaXMuY29uZmlnLngua2V5XSA9IHRpbWVTdHJpbmc7XHJcblxyXG4gICAgICAgICAgICAgICAgc2VsZi51cGRhdGVHcm91cHMoZCwgdGltZVN0cmluZywgc2VsZi5wbG90LnguZ3JvdXBzLCBzZWxmLmNvbmZpZy54Lmdyb3Vwcyk7XHJcbiAgICAgICAgICAgICAgICBtaXNzaW5nLnB1c2gobmV4dCk7XHJcbiAgICAgICAgICAgICAgICBuZXh0ID0gc2VsZi5uZXh0VGltZVRpY2tWYWx1ZShuZXh0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwcmV2ID0gY3VycmVudDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcGFyc2VUaW1lKHgpIHtcclxuICAgICAgICB2YXIgcGFyc2VyID0gdGhpcy5nZXRUaW1lUGFyc2VyKCk7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlci5wYXJzZSh4KTtcclxuICAgIH1cclxuXHJcbiAgICBmb3JtYXRUaW1lKGRhdGUpe1xyXG4gICAgICAgIHZhciBwYXJzZXIgPSB0aGlzLmdldFRpbWVQYXJzZXIoKTtcclxuICAgICAgICByZXR1cm4gcGFyc2VyKGRhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGZvcm1hdFZhbHVlWCh2YWx1ZSkgeyAvL3VzZWQgb25seSBmb3IgZGlzcGxheVxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy54LmZvcm1hdHRlcikgcmV0dXJuIHRoaXMuY29uZmlnLnguZm9ybWF0dGVyLmNhbGwodGhpcy5jb25maWcsIHZhbHVlKTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5jb25maWcueC5kaXNwbGF5Rm9ybWF0KXtcclxuICAgICAgICAgICAgdmFyIGRhdGUgPSB0aGlzLnBhcnNlVGltZSh2YWx1ZSk7XHJcbiAgICAgICAgICAgIHJldHVybiBkMy50aW1lLmZvcm1hdCh0aGlzLmNvbmZpZy54LmRpc3BsYXlGb3JtYXQpKGRhdGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYoIXRoaXMucGxvdC54LnRpbWVGb3JtYXQpIHJldHVybiB2YWx1ZTtcclxuXHJcbiAgICAgICAgaWYoVXRpbHMuaXNEYXRlKHZhbHVlKSl7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdFRpbWUodmFsdWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXBhcmVUaW1lVmFsdWVzKGEsIGIpe1xyXG4gICAgICAgIHJldHVybiBhLWI7XHJcbiAgICB9XHJcblxyXG4gICAgdGltZVZhbHVlc0VxdWFsKGEsIGIpIHtcclxuICAgICAgICB2YXIgcGFyc2VyID0gdGhpcy5wbG90LngudGltZVBhcnNlcjtcclxuICAgICAgICByZXR1cm4gcGFyc2VyKGEpID09PSBwYXJzZXIoYik7XHJcbiAgICB9XHJcblxyXG4gICAgbmV4dFRpbWVUaWNrVmFsdWUodCkge1xyXG4gICAgICAgIHZhciBpbnRlcnZhbCA9IHRoaXMucGxvdC54LmludGVydmFsO1xyXG4gICAgICAgIHJldHVybiBkMy50aW1lW2ludGVydmFsXS5vZmZzZXQodCwgdGhpcy5wbG90LnguaW50ZXJ2YWxTdGVwKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpIHtcclxuICAgICAgICBzdXBlci5pbml0UGxvdCgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5jb25maWcuei5maWxsTWlzc2luZykge1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWF0cml4LmZvckVhY2goKHJvdywgcm93SW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciBwcmV2Um93VmFsdWUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICByb3cuZm9yRWFjaCgoY2VsbCwgY29sSW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbC52YWx1ZSA9PT0gdW5kZWZpbmVkICYmIHByZXZSb3dWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBwcmV2Um93VmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwubWlzc2luZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHByZXZSb3dWYWx1ZSA9IGNlbGwudmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlKG5ld0RhdGEpIHtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcblxyXG4gICAgfTtcclxuXHJcblxyXG4gICAgaW5pdFRpbWVGb3JtYXRBbmRJbnRlcnZhbCgpIHtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnguaW50ZXJ2YWwgPSB0aGlzLmNvbmZpZy54LmludGVydmFsO1xyXG5cclxuICAgICAgICBpZighdGhpcy5wbG90LngudGltZUZvcm1hdCl7XHJcbiAgICAgICAgICAgIHRoaXMuZ3Vlc3NUaW1lRm9ybWF0KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZighdGhpcy5wbG90LnguaW50ZXJ2YWwgJiYgdGhpcy5wbG90LngudGltZUZvcm1hdCl7XHJcbiAgICAgICAgICAgIHRoaXMuZ3Vlc3NJbnRlcnZhbCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBndWVzc1RpbWVGb3JtYXQoKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIGZvcihsZXQgaT0wOyBpIDwgc2VsZi5jb25maWcueC5pbnRlcnZhbFRvRm9ybWF0cy5sZW5ndGg7IGkrKyl7XHJcbiAgICAgICAgICAgIGxldCBpbnRlcnZhbEZvcm1hdCA9IHNlbGYuY29uZmlnLnguaW50ZXJ2YWxUb0Zvcm1hdHNbaV07XHJcbiAgICAgICAgICAgIHZhciBmb3JtYXQgPSBudWxsO1xyXG4gICAgICAgICAgICB2YXIgZm9ybWF0TWF0Y2ggPSBpbnRlcnZhbEZvcm1hdC5mb3JtYXRzLnNvbWUoZj0+e1xyXG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gZjtcclxuICAgICAgICAgICAgICAgIHZhciBwYXJzZXIgPSBkMy50aW1lLmZvcm1hdChmKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnBsb3QueC51bmlxdWVWYWx1ZXMuZXZlcnkoeD0+e1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZXIucGFyc2UoeCkgIT09IG51bGxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgaWYoZm9ybWF0TWF0Y2gpe1xyXG4gICAgICAgICAgICAgICAgc2VsZi5wbG90LngudGltZUZvcm1hdCA9IGZvcm1hdDtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdHdWVzc2VkIHRpbWVGb3JtYXQnLCBmb3JtYXQpO1xyXG4gICAgICAgICAgICAgICAgaWYoIXNlbGYucGxvdC54LmludGVydmFsKXtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnBsb3QueC5pbnRlcnZhbCA9IGludGVydmFsRm9ybWF0Lm5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0d1ZXNzZWQgaW50ZXJ2YWwnLCBzZWxmLnBsb3QueC5pbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ3Vlc3NJbnRlcnZhbCgpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgZm9yKGxldCBpPTA7IGkgPCBzZWxmLmNvbmZpZy54LmludGVydmFsVG9Gb3JtYXRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBpbnRlcnZhbEZvcm1hdCA9IHNlbGYuY29uZmlnLnguaW50ZXJ2YWxUb0Zvcm1hdHNbaV07XHJcblxyXG4gICAgICAgICAgICBpZihpbnRlcnZhbEZvcm1hdC5mb3JtYXRzLmluZGV4T2Yoc2VsZi5wbG90LngudGltZUZvcm1hdCkgPj0gMCl7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnBsb3QueC5pbnRlcnZhbCA9IGludGVydmFsRm9ybWF0Lm5hbWU7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnR3Vlc3NlZCBpbnRlcnZhbCcsIHNlbGYucGxvdC54LmludGVydmFsKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuXHJcbiAgICBnZXRUaW1lUGFyc2VyKCkge1xyXG4gICAgICAgIGlmKCF0aGlzLnBsb3QueC50aW1lUGFyc2VyKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LngudGltZVBhcnNlciA9IGQzLnRpbWUuZm9ybWF0KHRoaXMucGxvdC54LnRpbWVGb3JtYXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5wbG90LngudGltZVBhcnNlcjtcclxuICAgIH1cclxufVxyXG5cclxuIiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcbmltcG9ydCB7TGVnZW5kfSBmcm9tICcuL2xlZ2VuZCdcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgSGVhdG1hcENvbmZpZyBleHRlbmRzIENoYXJ0Q29uZmlnIHtcclxuXHJcbiAgICBzdmdDbGFzcyA9ICdvZGMtaGVhdG1hcCc7XHJcbiAgICBzaG93VG9vbHRpcCA9IHRydWU7IC8vc2hvdyB0b29sdGlwIG9uIGRvdCBob3ZlclxyXG4gICAgdG9vbHRpcCA9IHtcclxuICAgICAgICBub0RhdGFUZXh0OiBcIk4vQVwiXHJcbiAgICB9O1xyXG4gICAgc2hvd0xlZ2VuZCA9IHRydWU7XHJcbiAgICBsZWdlbmQgPSB7XHJcbiAgICAgICAgd2lkdGg6IDMwLFxyXG4gICAgICAgIHJvdGF0ZUxhYmVsczogZmFsc2UsXHJcbiAgICAgICAgZGVjaW1hbFBsYWNlczogdW5kZWZpbmVkLFxyXG4gICAgICAgIGZvcm1hdHRlcjogdiA9PiB0aGlzLmxlZ2VuZC5kZWNpbWFsUGxhY2VzID09PSB1bmRlZmluZWQgPyB2IDogTnVtYmVyKHYpLnRvRml4ZWQodGhpcy5sZWdlbmQuZGVjaW1hbFBsYWNlcylcclxuICAgIH1cclxuICAgIGhpZ2hsaWdodExhYmVscyA9IHRydWU7XHJcbiAgICB4ID0gey8vIFggYXhpcyBjb25maWdcclxuICAgICAgICB0aXRsZTogJycsIC8vIGF4aXMgdGl0bGVcclxuICAgICAgICBrZXk6IDAsXHJcbiAgICAgICAgdmFsdWU6IChkKSA9PiBkW3RoaXMueC5rZXldLCAvLyB4IHZhbHVlIGFjY2Vzc29yXHJcbiAgICAgICAgcm90YXRlTGFiZWxzOiB0cnVlLFxyXG4gICAgICAgIHNvcnRMYWJlbHM6IGZhbHNlLFxyXG4gICAgICAgIHNvcnRDb21wYXJhdG9yOiAoYSwgYik9PiBVdGlscy5pc051bWJlcihhKSA/IGEgLSBiIDogYS5sb2NhbGVDb21wYXJlKGIpLFxyXG4gICAgICAgIGdyb3Vwczoge1xyXG4gICAgICAgICAgICBrZXlzOiBbXSxcclxuICAgICAgICAgICAgbGFiZWxzOiBbXSxcclxuICAgICAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IGRba2V5XSxcclxuICAgICAgICAgICAgb3ZlcmxhcDoge1xyXG4gICAgICAgICAgICAgICAgdG9wOiAyMCxcclxuICAgICAgICAgICAgICAgIGJvdHRvbTogMjBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZm9ybWF0dGVyOiB1bmRlZmluZWQgLy8gdmFsdWUgZm9ybWF0dGVyIGZ1bmN0aW9uXHJcblxyXG4gICAgfTtcclxuICAgIHkgPSB7Ly8gWSBheGlzIGNvbmZpZ1xyXG4gICAgICAgIHRpdGxlOiAnJywgLy8gYXhpcyB0aXRsZSxcclxuICAgICAgICByb3RhdGVMYWJlbHM6IHRydWUsXHJcbiAgICAgICAga2V5OiAxLFxyXG4gICAgICAgIHZhbHVlOiAoZCkgPT4gZFt0aGlzLnkua2V5XSwgLy8geSB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgICAgIHNvcnRMYWJlbHM6IGZhbHNlLFxyXG4gICAgICAgIHNvcnRDb21wYXJhdG9yOiAoYSwgYik9PiBVdGlscy5pc051bWJlcihiKSA/IGIgLSBhIDogYi5sb2NhbGVDb21wYXJlKGEpLFxyXG4gICAgICAgIGdyb3Vwczoge1xyXG4gICAgICAgICAgICBrZXlzOiBbXSxcclxuICAgICAgICAgICAgbGFiZWxzOiBbXSxcclxuICAgICAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IGRba2V5XSxcclxuICAgICAgICAgICAgb3ZlcmxhcDoge1xyXG4gICAgICAgICAgICAgICAgbGVmdDogMjAsXHJcbiAgICAgICAgICAgICAgICByaWdodDogMjBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZm9ybWF0dGVyOiB1bmRlZmluZWQvLyB2YWx1ZSBmb3JtYXR0ZXIgZnVuY3Rpb25cclxuICAgIH07XHJcbiAgICB6ID0ge1xyXG4gICAgICAgIGtleTogMixcclxuICAgICAgICB2YWx1ZTogKGQpID0+IGRbdGhpcy56LmtleV0sXHJcbiAgICAgICAgbm90QXZhaWxhYmxlVmFsdWU6ICh2KSA9PiB2ID09PSBudWxsIHx8IHYgPT09IHVuZGVmaW5lZCxcclxuXHJcbiAgICAgICAgZGVjaW1hbFBsYWNlczogdW5kZWZpbmVkLFxyXG4gICAgICAgIGZvcm1hdHRlcjogdiA9PiB0aGlzLnouZGVjaW1hbFBsYWNlcyA9PT0gdW5kZWZpbmVkID8gdiA6IE51bWJlcih2KS50b0ZpeGVkKHRoaXMuei5kZWNpbWFsUGxhY2VzKS8vIHZhbHVlIGZvcm1hdHRlciBmdW5jdGlvblxyXG5cclxuICAgIH07XHJcbiAgICBjb2xvciA9IHtcclxuICAgICAgICBub0RhdGFDb2xvcjogXCJ3aGl0ZVwiLFxyXG4gICAgICAgIHNjYWxlOiBcImxpbmVhclwiLFxyXG4gICAgICAgIHJldmVyc2VTY2FsZTogZmFsc2UsXHJcbiAgICAgICAgcmFuZ2U6IFtcImRhcmtibHVlXCIsIFwibGlnaHRza3libHVlXCIsIFwib3JhbmdlXCIsIFwiY3JpbXNvblwiLCBcImRhcmtyZWRcIl1cclxuICAgIH07XHJcbiAgICBjZWxsID0ge1xyXG4gICAgICAgIHdpZHRoOiB1bmRlZmluZWQsXHJcbiAgICAgICAgaGVpZ2h0OiB1bmRlZmluZWQsXHJcbiAgICAgICAgc2l6ZU1pbjogMTUsXHJcbiAgICAgICAgc2l6ZU1heDogMjUwLFxyXG4gICAgICAgIHBhZGRpbmc6IDBcclxuICAgIH07XHJcbiAgICBtYXJnaW4gPSB7XHJcbiAgICAgICAgbGVmdDogNjAsXHJcbiAgICAgICAgcmlnaHQ6IDUwLFxyXG4gICAgICAgIHRvcDogMzAsXHJcbiAgICAgICAgYm90dG9tOiA4MFxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIGlmIChjdXN0b20pIHtcclxuICAgICAgICAgICAgVXRpbHMuZGVlcEV4dGVuZCh0aGlzLCBjdXN0b20pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLy9UT0RPIHJlZmFjdG9yXHJcbmV4cG9ydCBjbGFzcyBIZWF0bWFwIGV4dGVuZHMgQ2hhcnQge1xyXG5cclxuICAgIHN0YXRpYyBtYXhHcm91cEdhcFNpemUgPSAyNDtcclxuICAgIHN0YXRpYyBncm91cFRpdGxlUmVjdEhlaWdodCA9IDY7XHJcblxyXG4gICAgY29uc3RydWN0b3IocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgY29uZmlnKSB7XHJcbiAgICAgICAgc3VwZXIocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgbmV3IEhlYXRtYXBDb25maWcoY29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Q29uZmlnKGNvbmZpZykge1xyXG4gICAgICAgIHJldHVybiBzdXBlci5zZXRDb25maWcobmV3IEhlYXRtYXBDb25maWcoY29uZmlnKSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXRQbG90KCkge1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBtYXJnaW4gPSB0aGlzLmNvbmZpZy5tYXJnaW47XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnggPSB7fTtcclxuICAgICAgICB0aGlzLnBsb3QueSA9IHt9O1xyXG4gICAgICAgIHRoaXMucGxvdC56ID0ge1xyXG4gICAgICAgICAgICBtYXRyaXhlczogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjZWxsczogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjb2xvcjoge30sXHJcbiAgICAgICAgICAgIHNoYXBlOiB7fVxyXG4gICAgICAgIH07XHJcblxyXG5cclxuICAgICAgICB0aGlzLnNldHVwVmFsdWVzKCk7XHJcbiAgICAgICAgdGhpcy5idWlsZENlbGxzKCk7XHJcblxyXG4gICAgICAgIHZhciB0aXRsZVJlY3RXaWR0aCA9IDY7XHJcbiAgICAgICAgdGhpcy5wbG90Lngub3ZlcmxhcCA9IHtcclxuICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICBib3R0b206IDBcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmICh0aGlzLnBsb3QuZ3JvdXBCeVgpIHtcclxuICAgICAgICAgICAgbGV0IGRlcHRoID0gc2VsZi5jb25maWcueC5ncm91cHMua2V5cy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxldCBhbGxUaXRsZXNXaWR0aCA9IGRlcHRoICogKHRpdGxlUmVjdFdpZHRoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucGxvdC54Lm92ZXJsYXAuYm90dG9tID0gc2VsZi5jb25maWcueC5ncm91cHMub3ZlcmxhcC5ib3R0b207XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC54Lm92ZXJsYXAudG9wID0gc2VsZi5jb25maWcueC5ncm91cHMub3ZlcmxhcC50b3AgKyBhbGxUaXRsZXNXaWR0aDtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lm1hcmdpbi50b3AgPSBjb25mLm1hcmdpbi5yaWdodCArIGNvbmYueC5ncm91cHMub3ZlcmxhcC50b3A7XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5tYXJnaW4uYm90dG9tID0gY29uZi5tYXJnaW4uYm90dG9tICsgY29uZi54Lmdyb3Vwcy5vdmVybGFwLmJvdHRvbTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB0aGlzLnBsb3QueS5vdmVybGFwID0ge1xyXG4gICAgICAgICAgICBsZWZ0OiAwLFxyXG4gICAgICAgICAgICByaWdodDogMFxyXG4gICAgICAgIH07XHJcblxyXG5cclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlZKSB7XHJcbiAgICAgICAgICAgIGxldCBkZXB0aCA9IHNlbGYuY29uZmlnLnkuZ3JvdXBzLmtleXMubGVuZ3RoO1xyXG4gICAgICAgICAgICBsZXQgYWxsVGl0bGVzV2lkdGggPSBkZXB0aCAqICh0aXRsZVJlY3RXaWR0aCk7XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC55Lm92ZXJsYXAucmlnaHQgPSBzZWxmLmNvbmZpZy55Lmdyb3Vwcy5vdmVybGFwLmxlZnQgKyBhbGxUaXRsZXNXaWR0aDtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lnkub3ZlcmxhcC5sZWZ0ID0gc2VsZi5jb25maWcueS5ncm91cHMub3ZlcmxhcC5sZWZ0O1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWFyZ2luLmxlZnQgPSBjb25mLm1hcmdpbi5sZWZ0ICsgdGhpcy5wbG90Lnkub3ZlcmxhcC5sZWZ0O1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWFyZ2luLnJpZ2h0ID0gY29uZi5tYXJnaW4ucmlnaHQgKyB0aGlzLnBsb3QueS5vdmVybGFwLnJpZ2h0O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnBsb3Quc2hvd0xlZ2VuZCA9IGNvbmYuc2hvd0xlZ2VuZDtcclxuICAgICAgICBpZiAodGhpcy5wbG90LnNob3dMZWdlbmQpIHtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lm1hcmdpbi5yaWdodCArPSBjb25mLmxlZ2VuZC53aWR0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5jb21wdXRlUGxvdFNpemUoKTtcclxuICAgICAgICB0aGlzLnNldHVwWlNjYWxlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHNldHVwVmFsdWVzKCkge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgY29uZmlnID0gc2VsZi5jb25maWc7XHJcbiAgICAgICAgdmFyIHggPSBzZWxmLnBsb3QueDtcclxuICAgICAgICB2YXIgeSA9IHNlbGYucGxvdC55O1xyXG4gICAgICAgIHZhciB6ID0gc2VsZi5wbG90Lno7XHJcblxyXG5cclxuICAgICAgICB4LnZhbHVlID0gZCA9PiBjb25maWcueC52YWx1ZS5jYWxsKGNvbmZpZywgZCk7XHJcbiAgICAgICAgeS52YWx1ZSA9IGQgPT4gY29uZmlnLnkudmFsdWUuY2FsbChjb25maWcsIGQpO1xyXG4gICAgICAgIHoudmFsdWUgPSBkID0+IGNvbmZpZy56LnZhbHVlLmNhbGwoY29uZmlnLCBkKTtcclxuXHJcbiAgICAgICAgeC51bmlxdWVWYWx1ZXMgPSBbXTtcclxuICAgICAgICB5LnVuaXF1ZVZhbHVlcyA9IFtdO1xyXG5cclxuXHJcbiAgICAgICAgc2VsZi5wbG90Lmdyb3VwQnlZID0gISFjb25maWcueS5ncm91cHMua2V5cy5sZW5ndGg7XHJcbiAgICAgICAgc2VsZi5wbG90Lmdyb3VwQnlYID0gISFjb25maWcueC5ncm91cHMua2V5cy5sZW5ndGg7XHJcblxyXG4gICAgICAgIHkuZ3JvdXBzID0ge1xyXG4gICAgICAgICAgICBrZXk6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgbGFiZWw6ICcnLFxyXG4gICAgICAgICAgICB2YWx1ZXM6IFtdLFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogbnVsbCxcclxuICAgICAgICAgICAgbGV2ZWw6IDAsXHJcbiAgICAgICAgICAgIGluZGV4OiAwLFxyXG4gICAgICAgICAgICBsYXN0SW5kZXg6IDBcclxuICAgICAgICB9O1xyXG4gICAgICAgIHguZ3JvdXBzID0ge1xyXG4gICAgICAgICAgICBrZXk6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgbGFiZWw6ICcnLFxyXG4gICAgICAgICAgICB2YWx1ZXM6IFtdLFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogbnVsbCxcclxuICAgICAgICAgICAgbGV2ZWw6IDAsXHJcbiAgICAgICAgICAgIGluZGV4OiAwLFxyXG4gICAgICAgICAgICBsYXN0SW5kZXg6IDBcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB2YXIgdmFsdWVNYXAgPSB7fTtcclxuICAgICAgICB2YXIgbWluWiA9IHVuZGVmaW5lZDtcclxuICAgICAgICB2YXIgbWF4WiA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLmRhdGEuZm9yRWFjaChkPT4ge1xyXG5cclxuICAgICAgICAgICAgdmFyIHhWYWwgPSB4LnZhbHVlKGQpO1xyXG4gICAgICAgICAgICB2YXIgeVZhbCA9IHkudmFsdWUoZCk7XHJcbiAgICAgICAgICAgIHZhciB6VmFsUmF3ID0gei52YWx1ZShkKTtcclxuICAgICAgICAgICAgdmFyIHpWYWwgPSBjb25maWcuei5ub3RBdmFpbGFibGVWYWx1ZSh6VmFsUmF3KSA/IHVuZGVmaW5lZCA6IHBhcnNlRmxvYXQoelZhbFJhdyk7XHJcblxyXG5cclxuICAgICAgICAgICAgaWYgKHgudW5pcXVlVmFsdWVzLmluZGV4T2YoeFZhbCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB4LnVuaXF1ZVZhbHVlcy5wdXNoKHhWYWwpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoeS51bmlxdWVWYWx1ZXMuaW5kZXhPZih5VmFsKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHkudW5pcXVlVmFsdWVzLnB1c2goeVZhbCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciBncm91cFkgPSB5Lmdyb3VwcztcclxuICAgICAgICAgICAgaWYgKHNlbGYucGxvdC5ncm91cEJ5WSkge1xyXG4gICAgICAgICAgICAgICAgZ3JvdXBZID0gdGhpcy51cGRhdGVHcm91cHMoZCwgeVZhbCwgeS5ncm91cHMsIGNvbmZpZy55Lmdyb3Vwcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGdyb3VwWCA9IHguZ3JvdXBzO1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5wbG90Lmdyb3VwQnlYKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgZ3JvdXBYID0gdGhpcy51cGRhdGVHcm91cHMoZCwgeFZhbCwgeC5ncm91cHMsIGNvbmZpZy54Lmdyb3Vwcyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghdmFsdWVNYXBbZ3JvdXBZLmluZGV4XSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWVNYXBbZ3JvdXBZLmluZGV4XSA9IHt9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXZhbHVlTWFwW2dyb3VwWS5pbmRleF1bZ3JvdXBYLmluZGV4XSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWVNYXBbZ3JvdXBZLmluZGV4XVtncm91cFguaW5kZXhdID0ge307XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCF2YWx1ZU1hcFtncm91cFkuaW5kZXhdW2dyb3VwWC5pbmRleF1beVZhbF0pIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlTWFwW2dyb3VwWS5pbmRleF1bZ3JvdXBYLmluZGV4XVt5VmFsXSA9IHt9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhbHVlTWFwW2dyb3VwWS5pbmRleF1bZ3JvdXBYLmluZGV4XVt5VmFsXVt4VmFsXSA9IHpWYWw7XHJcblxyXG5cclxuICAgICAgICAgICAgaWYgKG1pblogPT09IHVuZGVmaW5lZCB8fCB6VmFsIDwgbWluWikge1xyXG4gICAgICAgICAgICAgICAgbWluWiA9IHpWYWw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG1heFogPT09IHVuZGVmaW5lZCB8fCB6VmFsID4gbWF4Wikge1xyXG4gICAgICAgICAgICAgICAgbWF4WiA9IHpWYWw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBzZWxmLnBsb3QudmFsdWVNYXAgPSB2YWx1ZU1hcDtcclxuXHJcblxyXG4gICAgICAgIGlmICghc2VsZi5wbG90Lmdyb3VwQnlYKSB7XHJcbiAgICAgICAgICAgIHguZ3JvdXBzLnZhbHVlcyA9IHgudW5pcXVlVmFsdWVzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFzZWxmLnBsb3QuZ3JvdXBCeVkpIHtcclxuICAgICAgICAgICAgeS5ncm91cHMudmFsdWVzID0geS51bmlxdWVWYWx1ZXM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnNldHVwVmFsdWVzQmVmb3JlR3JvdXBzU29ydCgpO1xyXG5cclxuICAgICAgICB4LmdhcHMgPSBbXTtcclxuICAgICAgICB4LnRvdGFsVmFsdWVzQ291bnQgPSAwO1xyXG4gICAgICAgIHguYWxsVmFsdWVzTGlzdCA9IFtdO1xyXG4gICAgICAgIHRoaXMuc29ydEdyb3Vwcyh4LCB4Lmdyb3VwcywgY29uZmlnLngpO1xyXG5cclxuICAgICAgICB5LmdhcHMgPSBbXTtcclxuICAgICAgICB5LnRvdGFsVmFsdWVzQ291bnQgPSAwO1xyXG4gICAgICAgIHkuYWxsVmFsdWVzTGlzdCA9IFtdO1xyXG4gICAgICAgIHRoaXMuc29ydEdyb3Vwcyh5LCB5Lmdyb3VwcywgY29uZmlnLnkpO1xyXG5cclxuICAgICAgICB6Lm1pbiA9IG1pblo7XHJcbiAgICAgICAgei5tYXggPSBtYXhaO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBzZXR1cFZhbHVlc0JlZm9yZUdyb3Vwc1NvcnQoKSB7XHJcbiAgICB9XHJcblxyXG4gICAgYnVpbGRDZWxscygpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHggPSBzZWxmLnBsb3QueDtcclxuICAgICAgICB2YXIgeSA9IHNlbGYucGxvdC55O1xyXG4gICAgICAgIHZhciB6ID0gc2VsZi5wbG90Lno7XHJcbiAgICAgICAgdmFyIHZhbHVlTWFwID0gc2VsZi5wbG90LnZhbHVlTWFwO1xyXG5cclxuICAgICAgICB2YXIgbWF0cml4Q2VsbHMgPSBzZWxmLnBsb3QuY2VsbHMgPSBbXTtcclxuICAgICAgICB2YXIgbWF0cml4ID0gc2VsZi5wbG90Lm1hdHJpeCA9IFtdO1xyXG5cclxuICAgICAgICB5LmFsbFZhbHVlc0xpc3QuZm9yRWFjaCgodjEsIGkpPT4ge1xyXG4gICAgICAgICAgICB2YXIgcm93ID0gW107XHJcbiAgICAgICAgICAgIG1hdHJpeC5wdXNoKHJvdyk7XHJcblxyXG4gICAgICAgICAgICB4LmFsbFZhbHVlc0xpc3QuZm9yRWFjaCgodjIsIGopID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciB6VmFsID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICB6VmFsID0gdmFsdWVNYXBbdjEuZ3JvdXAuaW5kZXhdW3YyLmdyb3VwLmluZGV4XVt2MS52YWxdW3YyLnZhbF1cclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IHtcclxuICAgICAgICAgICAgICAgICAgICByb3dWYXI6IHYxLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbFZhcjogdjIsXHJcbiAgICAgICAgICAgICAgICAgICAgcm93OiBpLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbDogaixcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogelZhbFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHJvdy5wdXNoKGNlbGwpO1xyXG5cclxuICAgICAgICAgICAgICAgIG1hdHJpeENlbGxzLnB1c2goY2VsbCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVHcm91cHMoZCwgYXhpc1ZhbCwgcm9vdEdyb3VwLCBheGlzR3JvdXBzQ29uZmlnKSB7XHJcblxyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmNvbmZpZztcclxuICAgICAgICB2YXIgY3VycmVudEdyb3VwID0gcm9vdEdyb3VwO1xyXG4gICAgICAgIGF4aXNHcm91cHNDb25maWcua2V5cy5mb3JFYWNoKChncm91cEtleSwgZ3JvdXBLZXlJbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBjdXJyZW50R3JvdXAua2V5ID0gZ3JvdXBLZXk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWN1cnJlbnRHcm91cC5jaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudEdyb3VwLmNoaWxkcmVuID0ge307XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciBncm91cGluZ1ZhbHVlID0gYXhpc0dyb3Vwc0NvbmZpZy52YWx1ZS5jYWxsKGNvbmZpZywgZCwgZ3JvdXBLZXkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFjdXJyZW50R3JvdXAuY2hpbGRyZW4uaGFzT3duUHJvcGVydHkoZ3JvdXBpbmdWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIHJvb3RHcm91cC5sYXN0SW5kZXgrKztcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRHcm91cC5jaGlsZHJlbltncm91cGluZ1ZhbHVlXSA9IHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwaW5nVmFsdWU6IGdyb3VwaW5nVmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgbGV2ZWw6IGN1cnJlbnRHcm91cC5sZXZlbCArIDEsXHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHJvb3RHcm91cC5sYXN0SW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAga2V5OiBncm91cEtleVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjdXJyZW50R3JvdXAgPSBjdXJyZW50R3JvdXAuY2hpbGRyZW5bZ3JvdXBpbmdWYWx1ZV07XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGlmIChjdXJyZW50R3JvdXAudmFsdWVzLmluZGV4T2YoYXhpc1ZhbCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIGN1cnJlbnRHcm91cC52YWx1ZXMucHVzaChheGlzVmFsKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBjdXJyZW50R3JvdXA7XHJcbiAgICB9XHJcblxyXG4gICAgc29ydEdyb3VwcyhheGlzLCBncm91cCwgYXhpc0NvbmZpZywgZ2Fwcykge1xyXG4gICAgICAgIGlmIChheGlzQ29uZmlnLmdyb3Vwcy5sYWJlbHMgJiYgYXhpc0NvbmZpZy5ncm91cHMubGFiZWxzLmxlbmd0aCA+IGdyb3VwLmxldmVsKSB7XHJcbiAgICAgICAgICAgIGdyb3VwLmxhYmVsID0gYXhpc0NvbmZpZy5ncm91cHMubGFiZWxzW2dyb3VwLmxldmVsXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBncm91cC5sYWJlbCA9IGdyb3VwLmtleTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghZ2Fwcykge1xyXG4gICAgICAgICAgICBnYXBzID0gWzBdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZ2Fwcy5sZW5ndGggPD0gZ3JvdXAubGV2ZWwpIHtcclxuICAgICAgICAgICAgZ2Fwcy5wdXNoKDApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ3JvdXAuYWxsVmFsdWVzQ291bnQgPSBncm91cC5hbGxWYWx1ZXNDb3VudCB8fCAwO1xyXG4gICAgICAgIGdyb3VwLmFsbFZhbHVlc0JlZm9yZUNvdW50ID0gZ3JvdXAuYWxsVmFsdWVzQmVmb3JlQ291bnQgfHwgMDtcclxuXHJcbiAgICAgICAgZ3JvdXAuZ2FwcyA9IGdhcHMuc2xpY2UoKTtcclxuICAgICAgICBncm91cC5nYXBzQmVmb3JlID0gZ2Fwcy5zbGljZSgpO1xyXG5cclxuXHJcbiAgICAgICAgZ3JvdXAuZ2Fwc1NpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBzU2l6ZShncm91cC5nYXBzKTtcclxuICAgICAgICBncm91cC5nYXBzQmVmb3JlU2l6ZSA9IGdyb3VwLmdhcHNTaXplO1xyXG4gICAgICAgIGlmIChncm91cC52YWx1ZXMpIHtcclxuICAgICAgICAgICAgaWYgKGF4aXNDb25maWcuc29ydExhYmVscykge1xyXG4gICAgICAgICAgICAgICAgZ3JvdXAudmFsdWVzLnNvcnQoYXhpc0NvbmZpZy5zb3J0Q29tcGFyYXRvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZ3JvdXAudmFsdWVzLmZvckVhY2godj0+YXhpcy5hbGxWYWx1ZXNMaXN0LnB1c2goe3ZhbDogdiwgZ3JvdXA6IGdyb3VwfSkpO1xyXG4gICAgICAgICAgICBncm91cC5hbGxWYWx1ZXNCZWZvcmVDb3VudCA9IGF4aXMudG90YWxWYWx1ZXNDb3VudDtcclxuICAgICAgICAgICAgYXhpcy50b3RhbFZhbHVlc0NvdW50ICs9IGdyb3VwLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGdyb3VwLmFsbFZhbHVlc0NvdW50ICs9IGdyb3VwLnZhbHVlcy5sZW5ndGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBncm91cC5jaGlsZHJlbkxpc3QgPSBbXTtcclxuICAgICAgICBpZiAoZ3JvdXAuY2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgdmFyIGNoaWxkcmVuQ291bnQgPSAwO1xyXG5cclxuICAgICAgICAgICAgZm9yICh2YXIgY2hpbGRQcm9wIGluIGdyb3VwLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ3JvdXAuY2hpbGRyZW4uaGFzT3duUHJvcGVydHkoY2hpbGRQcm9wKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IGdyb3VwLmNoaWxkcmVuW2NoaWxkUHJvcF07XHJcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAuY2hpbGRyZW5MaXN0LnB1c2goY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuQ291bnQrKztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3J0R3JvdXBzKGF4aXMsIGNoaWxkLCBheGlzQ29uZmlnLCBnYXBzKTtcclxuICAgICAgICAgICAgICAgICAgICBncm91cC5hbGxWYWx1ZXNDb3VudCArPSBjaGlsZC5hbGxWYWx1ZXNDb3VudDtcclxuICAgICAgICAgICAgICAgICAgICBnYXBzW2dyb3VwLmxldmVsXSArPSAxO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZ2FwcyAmJiBjaGlsZHJlbkNvdW50ID4gMSkge1xyXG4gICAgICAgICAgICAgICAgZ2Fwc1tncm91cC5sZXZlbF0gLT0gMTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZ3JvdXAuZ2Fwc0luc2lkZSA9IFtdO1xyXG4gICAgICAgICAgICBnYXBzLmZvckVhY2goKGQsIGkpPT4ge1xyXG4gICAgICAgICAgICAgICAgZ3JvdXAuZ2Fwc0luc2lkZS5wdXNoKGQgLSAoZ3JvdXAuZ2Fwc0JlZm9yZVtpXSB8fCAwKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBncm91cC5nYXBzSW5zaWRlU2l6ZSA9IEhlYXRtYXAuY29tcHV0ZUdhcHNTaXplKGdyb3VwLmdhcHNJbnNpZGUpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGF4aXMuZ2Fwcy5sZW5ndGggPCBnYXBzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgYXhpcy5nYXBzID0gZ2FwcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgY29tcHV0ZVlBeGlzTGFiZWxzV2lkdGgob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIG1heFdpZHRoID0gdGhpcy5wbG90Lm1hcmdpbi5sZWZ0O1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy55LnRpdGxlKSB7XHJcbiAgICAgICAgICAgIG1heFdpZHRoIC09IDE1O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAob2Zmc2V0ICYmIG9mZnNldC54KSB7XHJcbiAgICAgICAgICAgIG1heFdpZHRoICs9IG9mZnNldC54O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnkucm90YXRlTGFiZWxzKSB7XHJcbiAgICAgICAgICAgIG1heFdpZHRoICo9IFV0aWxzLlNRUlRfMjtcclxuICAgICAgICAgICAgdmFyIGZvbnRTaXplID0gMTE7IC8vdG9kbyBjaGVjayBhY3R1YWwgZm9udCBzaXplXHJcbiAgICAgICAgICAgIG1heFdpZHRoIC09Zm9udFNpemUvMjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBtYXhXaWR0aDtcclxuICAgIH1cclxuXHJcbiAgICBjb21wdXRlWEF4aXNMYWJlbHNXaWR0aChvZmZzZXQpIHtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLngucm90YXRlTGFiZWxzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBsb3QuY2VsbFdpZHRoIC0gMjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNpemUgPSB0aGlzLnBsb3QubWFyZ2luLmJvdHRvbTtcclxuICAgICAgICBpZiAodGhpcy5jb25maWcueC50aXRsZSkge1xyXG4gICAgICAgICAgICBzaXplIC09IDE1O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAob2Zmc2V0ICYmIG9mZnNldC55KSB7XHJcbiAgICAgICAgICAgIHNpemUgLT0gb2Zmc2V0Lnk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzaXplICo9IFV0aWxzLlNRUlRfMjtcclxuXHJcbiAgICAgICAgdmFyIGZvbnRTaXplID0gMTE7IC8vdG9kbyBjaGVjayBhY3R1YWwgZm9udCBzaXplXHJcbiAgICAgICAgc2l6ZSAtPWZvbnRTaXplLzI7XHJcblxyXG4gICAgICAgIHJldHVybiBzaXplO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBjb21wdXRlR2FwU2l6ZShnYXBMZXZlbCkge1xyXG4gICAgICAgIHJldHVybiBIZWF0bWFwLm1heEdyb3VwR2FwU2l6ZSAvIChnYXBMZXZlbCArIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBjb21wdXRlR2Fwc1NpemUoZ2Fwcykge1xyXG4gICAgICAgIHZhciBnYXBzU2l6ZSA9IDA7XHJcbiAgICAgICAgZ2Fwcy5mb3JFYWNoKChnYXBzTnVtYmVyLCBnYXBzTGV2ZWwpPT4gZ2Fwc1NpemUgKz0gZ2Fwc051bWJlciAqIEhlYXRtYXAuY29tcHV0ZUdhcFNpemUoZ2Fwc0xldmVsKSk7XHJcbiAgICAgICAgcmV0dXJuIGdhcHNTaXplO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVQbG90U2l6ZSgpIHtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuICAgICAgICB2YXIgbWFyZ2luID0gcGxvdC5tYXJnaW47XHJcbiAgICAgICAgdmFyIGF2YWlsYWJsZVdpZHRoID0gVXRpbHMuYXZhaWxhYmxlV2lkdGgodGhpcy5jb25maWcud2lkdGgsIHRoaXMuZ2V0QmFzZUNvbnRhaW5lcigpLCB0aGlzLnBsb3QubWFyZ2luKTtcclxuICAgICAgICB2YXIgYXZhaWxhYmxlSGVpZ2h0ID0gVXRpbHMuYXZhaWxhYmxlSGVpZ2h0KHRoaXMuY29uZmlnLmhlaWdodCwgdGhpcy5nZXRCYXNlQ29udGFpbmVyKCksIHRoaXMucGxvdC5tYXJnaW4pO1xyXG4gICAgICAgIHZhciB3aWR0aCA9IGF2YWlsYWJsZVdpZHRoO1xyXG4gICAgICAgIHZhciBoZWlnaHQgPSBhdmFpbGFibGVIZWlnaHQ7XHJcblxyXG4gICAgICAgIHZhciB4R2Fwc1NpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBzU2l6ZShwbG90LnguZ2Fwcyk7XHJcblxyXG5cclxuICAgICAgICB2YXIgY29tcHV0ZWRDZWxsV2lkdGggPSBNYXRoLm1heChjb25mLmNlbGwuc2l6ZU1pbiwgTWF0aC5taW4oY29uZi5jZWxsLnNpemVNYXgsIChhdmFpbGFibGVXaWR0aCAtIHhHYXBzU2l6ZSkgLyB0aGlzLnBsb3QueC50b3RhbFZhbHVlc0NvdW50KSk7XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLndpZHRoKSB7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmNlbGwud2lkdGgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxvdC5jZWxsV2lkdGggPSBjb21wdXRlZENlbGxXaWR0aDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuY2VsbFdpZHRoID0gdGhpcy5jb25maWcuY2VsbC53aWR0aDtcclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5wbG90LmNlbGxXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wbG90LmNlbGxXaWR0aCA9IGNvbXB1dGVkQ2VsbFdpZHRoO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICB3aWR0aCA9IHRoaXMucGxvdC5jZWxsV2lkdGggKiB0aGlzLnBsb3QueC50b3RhbFZhbHVlc0NvdW50ICsgbWFyZ2luLmxlZnQgKyBtYXJnaW4ucmlnaHQgKyB4R2Fwc1NpemU7XHJcblxyXG4gICAgICAgIHZhciB5R2Fwc1NpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBzU2l6ZShwbG90LnkuZ2Fwcyk7XHJcbiAgICAgICAgdmFyIGNvbXB1dGVkQ2VsbEhlaWdodCA9IE1hdGgubWF4KGNvbmYuY2VsbC5zaXplTWluLCBNYXRoLm1pbihjb25mLmNlbGwuc2l6ZU1heCwgKGF2YWlsYWJsZUhlaWdodCAtIHlHYXBzU2l6ZSkgLyB0aGlzLnBsb3QueS50b3RhbFZhbHVlc0NvdW50KSk7XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmhlaWdodCkge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmNlbGwuaGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuY2VsbEhlaWdodCA9IGNvbXB1dGVkQ2VsbEhlaWdodDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5jZWxsSGVpZ2h0ID0gdGhpcy5jb25maWcuY2VsbC5oZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMucGxvdC5jZWxsSGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuY2VsbEhlaWdodCA9IGNvbXB1dGVkQ2VsbEhlaWdodDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGhlaWdodCA9IHRoaXMucGxvdC5jZWxsSGVpZ2h0ICogdGhpcy5wbG90LnkudG90YWxWYWx1ZXNDb3VudCArIG1hcmdpbi50b3AgKyBtYXJnaW4uYm90dG9tICsgeUdhcHNTaXplO1xyXG5cclxuXHJcbiAgICAgICAgdGhpcy5wbG90LndpZHRoID0gd2lkdGggLSBtYXJnaW4ubGVmdCAtIG1hcmdpbi5yaWdodDtcclxuICAgICAgICB0aGlzLnBsb3QuaGVpZ2h0ID0gaGVpZ2h0IC0gbWFyZ2luLnRvcCAtIG1hcmdpbi5ib3R0b207XHJcbiAgICB9XHJcblxyXG5cclxuICAgIHNldHVwWlNjYWxlKCkge1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGNvbmZpZyA9IHNlbGYuY29uZmlnO1xyXG4gICAgICAgIHZhciB6ID0gc2VsZi5wbG90Lno7XHJcbiAgICAgICAgdmFyIHJhbmdlID0gY29uZmlnLmNvbG9yLnJhbmdlO1xyXG4gICAgICAgIHZhciBleHRlbnQgPSB6Lm1heCAtIHoubWluO1xyXG4gICAgICAgIHZhciBzY2FsZTtcclxuICAgICAgICB6LmRvbWFpbiA9IFtdO1xyXG4gICAgICAgIGlmIChjb25maWcuY29sb3Iuc2NhbGUgPT0gXCJwb3dcIikge1xyXG4gICAgICAgICAgICB2YXIgZXhwb25lbnQgPSAxMDtcclxuICAgICAgICAgICAgcmFuZ2UuZm9yRWFjaCgoYywgaSk9PiB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdiA9IHoubWF4IC0gKGV4dGVudCAvIE1hdGgucG93KDEwLCBpKSk7XHJcbiAgICAgICAgICAgICAgICB6LmRvbWFpbi5wdXNoKHYpXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBzY2FsZSA9IGQzLnNjYWxlLnBvdygpLmV4cG9uZW50KGV4cG9uZW50KTtcclxuICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5jb2xvci5zY2FsZSA9PSBcImxvZ1wiKSB7XHJcblxyXG4gICAgICAgICAgICByYW5nZS5mb3JFYWNoKChjLCBpKT0+IHtcclxuICAgICAgICAgICAgICAgIHZhciB2ID0gei5taW4gKyAoZXh0ZW50IC8gTWF0aC5wb3coMTAsIGkpKTtcclxuICAgICAgICAgICAgICAgIHouZG9tYWluLnVuc2hpZnQodilcclxuXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgc2NhbGUgPSBkMy5zY2FsZS5sb2coKVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJhbmdlLmZvckVhY2goKGMsIGkpPT4ge1xyXG4gICAgICAgICAgICAgICAgdmFyIHYgPSB6Lm1pbiArIChleHRlbnQgKiAoaSAvIChyYW5nZS5sZW5ndGggLSAxKSkpO1xyXG4gICAgICAgICAgICAgICAgei5kb21haW4ucHVzaCh2KVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgc2NhbGUgPSBkMy5zY2FsZVtjb25maWcuY29sb3Iuc2NhbGVdKCk7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgei5kb21haW5bMF0gPSB6Lm1pbjsgLy9yZW1vdmluZyB1bm5lY2Vzc2FyeSBmbG9hdGluZyBwb2ludHNcclxuICAgICAgICB6LmRvbWFpblt6LmRvbWFpbi5sZW5ndGggLSAxXSA9IHoubWF4OyAvL3JlbW92aW5nIHVubmVjZXNzYXJ5IGZsb2F0aW5nIHBvaW50c1xyXG4gICAgICAgIGNvbnNvbGUubG9nKHouZG9tYWluKTtcclxuXHJcbiAgICAgICAgaWYgKGNvbmZpZy5jb2xvci5yZXZlcnNlU2NhbGUpIHtcclxuICAgICAgICAgICAgei5kb21haW4ucmV2ZXJzZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKHJhbmdlKTtcclxuICAgICAgICBwbG90LnouY29sb3Iuc2NhbGUgPSBzY2FsZS5kb21haW4oei5kb21haW4pLnJhbmdlKHJhbmdlKTtcclxuICAgICAgICB2YXIgc2hhcGUgPSBwbG90Lnouc2hhcGUgPSB7fTtcclxuXHJcbiAgICAgICAgdmFyIGNlbGxDb25mID0gdGhpcy5jb25maWcuY2VsbDtcclxuICAgICAgICBzaGFwZS50eXBlID0gXCJyZWN0XCI7XHJcblxyXG4gICAgICAgIHBsb3Quei5zaGFwZS53aWR0aCA9IHBsb3QuY2VsbFdpZHRoIC0gY2VsbENvbmYucGFkZGluZyAqIDI7XHJcbiAgICAgICAgcGxvdC56LnNoYXBlLmhlaWdodCA9IHBsb3QuY2VsbEhlaWdodCAtIGNlbGxDb25mLnBhZGRpbmcgKiAyO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICB1cGRhdGUobmV3RGF0YSkge1xyXG4gICAgICAgIHN1cGVyLnVwZGF0ZShuZXdEYXRhKTtcclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlZKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhd0dyb3Vwc1kodGhpcy5wbG90LnkuZ3JvdXBzLCB0aGlzLnN2Z0cpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlYKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhd0dyb3Vwc1godGhpcy5wbG90LnguZ3JvdXBzLCB0aGlzLnN2Z0cpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGVDZWxscygpO1xyXG5cclxuICAgICAgICAvLyB0aGlzLnVwZGF0ZVZhcmlhYmxlTGFiZWxzKCk7XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlQXhpc1goKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUF4aXNZKCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5zaG93TGVnZW5kKSB7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTGVnZW5kKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUF4aXNUaXRsZXMoKTtcclxuICAgIH07XHJcblxyXG4gICAgdXBkYXRlQXhpc1RpdGxlcygpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcblxyXG5cclxuICAgIH1cclxuXHJcblxyXG4gICAgdXBkYXRlQXhpc1goKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBsYWJlbENsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImxhYmVsXCIpO1xyXG4gICAgICAgIHZhciBsYWJlbFhDbGFzcyA9IGxhYmVsQ2xhc3MgKyBcIi14XCI7XHJcbiAgICAgICAgdmFyIGxhYmVsWUNsYXNzID0gbGFiZWxDbGFzcyArIFwiLXlcIjtcclxuICAgICAgICBwbG90LmxhYmVsQ2xhc3MgPSBsYWJlbENsYXNzO1xyXG5cclxuICAgICAgICB2YXIgb2Zmc2V0WCA9IHtcclxuICAgICAgICAgICAgeDogMCxcclxuICAgICAgICAgICAgeTogMFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgbGV0IGdhcFNpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBTaXplKDApO1xyXG4gICAgICAgIGlmIChwbG90Lmdyb3VwQnlYKSB7XHJcbiAgICAgICAgICAgIGxldCBvdmVybGFwID0gc2VsZi5jb25maWcueC5ncm91cHMub3ZlcmxhcDtcclxuXHJcbiAgICAgICAgICAgIG9mZnNldFgueCA9IGdhcFNpemUgLyAyO1xyXG4gICAgICAgICAgICBvZmZzZXRYLnkgPSBvdmVybGFwLmJvdHRvbSArIGdhcFNpemUgLyAyICsgNjtcclxuICAgICAgICB9IGVsc2UgaWYgKHBsb3QuZ3JvdXBCeVkpIHtcclxuICAgICAgICAgICAgb2Zmc2V0WC55ID0gZ2FwU2l6ZTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgbGFiZWxzID0gc2VsZi5zdmdHLnNlbGVjdEFsbChcInRleHQuXCIgKyBsYWJlbFhDbGFzcylcclxuICAgICAgICAgICAgLmRhdGEocGxvdC54LmFsbFZhbHVlc0xpc3QsIChkLCBpKT0+aSk7XHJcblxyXG4gICAgICAgIGxhYmVscy5lbnRlcigpLmFwcGVuZChcInRleHRcIikuYXR0cihcImNsYXNzXCIsIChkLCBpKSA9PiBsYWJlbENsYXNzICsgXCIgXCIgKyBsYWJlbFhDbGFzcyArIFwiIFwiICsgbGFiZWxYQ2xhc3MgKyBcIi1cIiArIGkpO1xyXG5cclxuICAgICAgICBsYWJlbHNcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIChkLCBpKSA9PiAoaSAqIHBsb3QuY2VsbFdpZHRoICsgcGxvdC5jZWxsV2lkdGggLyAyKSArIChkLmdyb3VwLmdhcHNTaXplKSArIG9mZnNldFgueClcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIHBsb3QuaGVpZ2h0ICsgb2Zmc2V0WC55KVxyXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIDEwKVxyXG5cclxuICAgICAgICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChkPT5zZWxmLmZvcm1hdFZhbHVlWChkLnZhbCkpO1xyXG5cclxuXHJcblxyXG4gICAgICAgIHZhciBtYXhXaWR0aCA9IHNlbGYuY29tcHV0ZVhBeGlzTGFiZWxzV2lkdGgob2Zmc2V0WCk7XHJcblxyXG4gICAgICAgIGxhYmVscy5lYWNoKGZ1bmN0aW9uIChsYWJlbCkge1xyXG4gICAgICAgICAgICB2YXIgZWxlbSA9IGQzLnNlbGVjdCh0aGlzKSxcclxuICAgICAgICAgICAgICAgIHRleHQgPSBzZWxmLmZvcm1hdFZhbHVlWChsYWJlbC52YWwpO1xyXG4gICAgICAgICAgICBVdGlscy5wbGFjZVRleHRXaXRoRWxsaXBzaXNBbmRUb29sdGlwKGVsZW0sIHRleHQsIG1heFdpZHRoLCBzZWxmLmNvbmZpZy5zaG93VG9vbHRpcCA/IHNlbGYucGxvdC50b29sdGlwIDogZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAoc2VsZi5jb25maWcueC5yb3RhdGVMYWJlbHMpIHtcclxuICAgICAgICAgICAgbGFiZWxzLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwicm90YXRlKC00NSwgXCIgKyAoKGkgKiBwbG90LmNlbGxXaWR0aCArIHBsb3QuY2VsbFdpZHRoIC8gMikgKyBkLmdyb3VwLmdhcHNTaXplICsgb2Zmc2V0WC54ICkgKyBcIiwgXCIgKyAoIHBsb3QuaGVpZ2h0ICsgb2Zmc2V0WC55KSArIFwiKVwiKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJkeFwiLCAtMilcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwiZHlcIiwgOClcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJlbmRcIik7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgbGFiZWxzLmV4aXQoKS5yZW1vdmUoKTtcclxuXHJcblxyXG4gICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RPckFwcGVuZChcImcuXCIgKyBzZWxmLnByZWZpeENsYXNzKCdheGlzLXgnKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAocGxvdC53aWR0aCAvIDIpICsgXCIsXCIgKyAocGxvdC5oZWlnaHQgKyBwbG90Lm1hcmdpbi5ib3R0b20pICsgXCIpXCIpXHJcbiAgICAgICAgICAgIC5zZWxlY3RPckFwcGVuZChcInRleHQuXCIgKyBzZWxmLnByZWZpeENsYXNzKCdsYWJlbCcpKVxyXG5cclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIi0wLjVlbVwiKVxyXG4gICAgICAgICAgICAuc3R5bGUoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChzZWxmLmNvbmZpZy54LnRpdGxlKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVBeGlzWSgpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGxhYmVsQ2xhc3MgPSBzZWxmLnByZWZpeENsYXNzKFwibGFiZWxcIik7XHJcbiAgICAgICAgdmFyIGxhYmVsWUNsYXNzID0gbGFiZWxDbGFzcyArIFwiLXlcIjtcclxuICAgICAgICBwbG90LmxhYmVsQ2xhc3MgPSBsYWJlbENsYXNzO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIGxhYmVscyA9IHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgbGFiZWxZQ2xhc3MpXHJcbiAgICAgICAgICAgIC5kYXRhKHBsb3QueS5hbGxWYWx1ZXNMaXN0KTtcclxuXHJcbiAgICAgICAgbGFiZWxzLmVudGVyKCkuYXBwZW5kKFwidGV4dFwiKTtcclxuXHJcbiAgICAgICAgdmFyIG9mZnNldFkgPSB7XHJcbiAgICAgICAgICAgIHg6IDAsXHJcbiAgICAgICAgICAgIHk6IDBcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmIChwbG90Lmdyb3VwQnlZKSB7XHJcbiAgICAgICAgICAgIGxldCBvdmVybGFwID0gc2VsZi5jb25maWcueS5ncm91cHMub3ZlcmxhcDtcclxuICAgICAgICAgICAgbGV0IGdhcFNpemUgPSBIZWF0bWFwLmNvbXB1dGVHYXBTaXplKDApO1xyXG4gICAgICAgICAgICBvZmZzZXRZLnggPSAtb3ZlcmxhcC5sZWZ0O1xyXG5cclxuICAgICAgICAgICAgb2Zmc2V0WS55ID0gZ2FwU2l6ZSAvIDI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxhYmVsc1xyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgb2Zmc2V0WS54KVxyXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgKGQsIGkpID0+IChpICogcGxvdC5jZWxsSGVpZ2h0ICsgcGxvdC5jZWxsSGVpZ2h0IC8gMikgKyBkLmdyb3VwLmdhcHNTaXplICsgb2Zmc2V0WS55KVxyXG4gICAgICAgICAgICAuYXR0cihcImR4XCIsIC0yKVxyXG4gICAgICAgICAgICAuYXR0cihcInRleHQtYW5jaG9yXCIsIFwiZW5kXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgKGQsIGkpID0+IGxhYmVsQ2xhc3MgKyBcIiBcIiArIGxhYmVsWUNsYXNzICsgXCIgXCIgKyBsYWJlbFlDbGFzcyArIFwiLVwiICsgaSlcclxuXHJcbiAgICAgICAgICAgIC50ZXh0KGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZm9ybWF0dGVkID0gc2VsZi5mb3JtYXRWYWx1ZVkoZC52YWwpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1hdHRlZFxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdmFyIG1heFdpZHRoID0gc2VsZi5jb21wdXRlWUF4aXNMYWJlbHNXaWR0aChvZmZzZXRZKTtcclxuXHJcbiAgICAgICAgbGFiZWxzLmVhY2goZnVuY3Rpb24gKGxhYmVsKSB7XHJcbiAgICAgICAgICAgIHZhciBlbGVtID0gZDMuc2VsZWN0KHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgdGV4dCA9IHNlbGYuZm9ybWF0VmFsdWVZKGxhYmVsLnZhbCk7XHJcbiAgICAgICAgICAgIFV0aWxzLnBsYWNlVGV4dFdpdGhFbGxpcHNpc0FuZFRvb2x0aXAoZWxlbSwgdGV4dCwgbWF4V2lkdGgsIHNlbGYuY29uZmlnLnNob3dUb29sdGlwID8gc2VsZi5wbG90LnRvb2x0aXAgOiBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGlmIChzZWxmLmNvbmZpZy55LnJvdGF0ZUxhYmVscykge1xyXG4gICAgICAgICAgICBsYWJlbHNcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIChkLCBpKSA9PiBcInJvdGF0ZSgtNDUsIFwiICsgKG9mZnNldFkueCAgKSArIFwiLCBcIiArIChkLmdyb3VwLmdhcHNTaXplICsgKGkgKiBwbG90LmNlbGxIZWlnaHQgKyBwbG90LmNlbGxIZWlnaHQgLyAyKSArIG9mZnNldFkueSkgKyBcIilcIilcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJlbmRcIik7XHJcbiAgICAgICAgICAgIC8vIC5hdHRyKFwiZHhcIiwgLTcpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGxhYmVscy5hdHRyKFwiZG9taW5hbnQtYmFzZWxpbmVcIiwgXCJtaWRkbGVcIilcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBsYWJlbHMuZXhpdCgpLnJlbW92ZSgpO1xyXG5cclxuXHJcbiAgICAgICAgc2VsZi5zdmdHLnNlbGVjdE9yQXBwZW5kKFwiZy5cIiArIHNlbGYucHJlZml4Q2xhc3MoJ2F4aXMteScpKVxyXG4gICAgICAgICAgICAuc2VsZWN0T3JBcHBlbmQoXCJ0ZXh0LlwiICsgc2VsZi5wcmVmaXhDbGFzcygnbGFiZWwnKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAtcGxvdC5tYXJnaW4ubGVmdCArIFwiLFwiICsgKHBsb3QuaGVpZ2h0IC8gMikgKyBcIilyb3RhdGUoLTkwKVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIFwiMWVtXCIpXHJcbiAgICAgICAgICAgIC5zdHlsZShcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpXHJcbiAgICAgICAgICAgIC50ZXh0KHNlbGYuY29uZmlnLnkudGl0bGUpO1xyXG5cclxuICAgIH1cclxuXHJcblxyXG4gICAgZHJhd0dyb3Vwc1kocGFyZW50R3JvdXAsIGNvbnRhaW5lciwgYXZhaWxhYmxlV2lkdGgpIHtcclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG5cclxuICAgICAgICB2YXIgZ3JvdXBDbGFzcyA9IHNlbGYucHJlZml4Q2xhc3MoXCJncm91cFwiKTtcclxuICAgICAgICB2YXIgZ3JvdXBZQ2xhc3MgPSBncm91cENsYXNzICsgXCIteVwiO1xyXG4gICAgICAgIHZhciBncm91cHMgPSBjb250YWluZXIuc2VsZWN0QWxsKFwiZy5cIiArIGdyb3VwQ2xhc3MgKyBcIi5cIiArIGdyb3VwWUNsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShwYXJlbnRHcm91cC5jaGlsZHJlbkxpc3QpO1xyXG5cclxuICAgICAgICB2YXIgdmFsdWVzQmVmb3JlQ291bnQgPSAwO1xyXG4gICAgICAgIHZhciBnYXBzQmVmb3JlU2l6ZSA9IDA7XHJcblxyXG4gICAgICAgIHZhciBncm91cHNFbnRlckcgPSBncm91cHMuZW50ZXIoKS5hcHBlbmQoXCJnXCIpO1xyXG4gICAgICAgIGdyb3Vwc0VudGVyR1xyXG4gICAgICAgICAgICAuY2xhc3NlZChncm91cENsYXNzLCB0cnVlKVxyXG4gICAgICAgICAgICAuY2xhc3NlZChncm91cFlDbGFzcywgdHJ1ZSlcclxuICAgICAgICAgICAgLmFwcGVuZChcInJlY3RcIikuY2xhc3NlZChcImdyb3VwLXJlY3RcIiwgdHJ1ZSk7XHJcblxyXG4gICAgICAgIHZhciB0aXRsZUdyb3VwRW50ZXIgPSBncm91cHNFbnRlckcuYXBwZW5kU2VsZWN0b3IoXCJnLnRpdGxlXCIpO1xyXG4gICAgICAgIHRpdGxlR3JvdXBFbnRlci5hcHBlbmQoXCJyZWN0XCIpO1xyXG4gICAgICAgIHRpdGxlR3JvdXBFbnRlci5hcHBlbmQoXCJ0ZXh0XCIpO1xyXG5cclxuICAgICAgICB2YXIgZ2FwU2l6ZSA9IEhlYXRtYXAuY29tcHV0ZUdhcFNpemUocGFyZW50R3JvdXAubGV2ZWwpO1xyXG4gICAgICAgIHZhciBwYWRkaW5nID0gZ2FwU2l6ZSAvIDQ7XHJcblxyXG4gICAgICAgIHZhciB0aXRsZVJlY3RXaWR0aCA9IEhlYXRtYXAuZ3JvdXBUaXRsZVJlY3RIZWlnaHQ7XHJcbiAgICAgICAgdmFyIGRlcHRoID0gc2VsZi5jb25maWcueS5ncm91cHMua2V5cy5sZW5ndGggLSBwYXJlbnRHcm91cC5sZXZlbDtcclxuICAgICAgICB2YXIgb3ZlcmxhcCA9IHtcclxuICAgICAgICAgICAgbGVmdDogMCxcclxuICAgICAgICAgICAgcmlnaHQ6IDBcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBpZiAoIWF2YWlsYWJsZVdpZHRoKSB7XHJcbiAgICAgICAgICAgIG92ZXJsYXAucmlnaHQgPSBwbG90Lnkub3ZlcmxhcC5sZWZ0O1xyXG4gICAgICAgICAgICBvdmVybGFwLmxlZnQgPSBwbG90Lnkub3ZlcmxhcC5sZWZ0O1xyXG4gICAgICAgICAgICBhdmFpbGFibGVXaWR0aCA9IHBsb3Qud2lkdGggKyBnYXBTaXplICsgb3ZlcmxhcC5sZWZ0ICsgb3ZlcmxhcC5yaWdodDtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBncm91cHNcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciB0cmFuc2xhdGUgPSBcInRyYW5zbGF0ZShcIiArIChwYWRkaW5nIC0gb3ZlcmxhcC5sZWZ0KSArIFwiLFwiICsgKChwbG90LmNlbGxIZWlnaHQgKiB2YWx1ZXNCZWZvcmVDb3VudCkgKyBpICogZ2FwU2l6ZSArIGdhcHNCZWZvcmVTaXplICsgcGFkZGluZykgKyBcIilcIjtcclxuICAgICAgICAgICAgICAgIGdhcHNCZWZvcmVTaXplICs9IChkLmdhcHNJbnNpZGVTaXplIHx8IDApO1xyXG4gICAgICAgICAgICAgICAgdmFsdWVzQmVmb3JlQ291bnQgKz0gZC5hbGxWYWx1ZXNDb3VudCB8fCAwO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zbGF0ZVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIHZhciBncm91cFdpZHRoID0gYXZhaWxhYmxlV2lkdGggLSBwYWRkaW5nICogMjtcclxuXHJcbiAgICAgICAgdmFyIHRpdGxlR3JvdXBzID0gZ3JvdXBzLnNlbGVjdEFsbChcImcudGl0bGVcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwidHJhbnNsYXRlKFwiICsgKGdyb3VwV2lkdGggLSB0aXRsZVJlY3RXaWR0aCkgKyBcIiwgMClcIik7XHJcblxyXG4gICAgICAgIHZhciB0aWxlUmVjdHMgPSB0aXRsZUdyb3Vwcy5zZWxlY3RBbGwoXCJyZWN0XCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgdGl0bGVSZWN0V2lkdGgpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGQ9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCkgKyBwbG90LmNlbGxIZWlnaHQgKiBkLmFsbFZhbHVlc0NvdW50ICsgcGFkZGluZyAqIDJcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCAwKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcImZpbGxcIiwgXCJsaWdodGdyZXlcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJzdHJva2Utd2lkdGhcIiwgMCk7XHJcblxyXG4gICAgICAgIHRoaXMuc2V0R3JvdXBNb3VzZUNhbGxiYWNrcyhwYXJlbnRHcm91cCwgdGlsZVJlY3RzKTtcclxuXHJcblxyXG4gICAgICAgIGdyb3Vwcy5zZWxlY3RBbGwoXCJyZWN0Lmdyb3VwLXJlY3RcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBkPT4gXCJncm91cC1yZWN0IGdyb3VwLXJlY3QtXCIgKyBkLmluZGV4KVxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGdyb3VwV2lkdGgpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGQ9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCkgKyBwbG90LmNlbGxIZWlnaHQgKiBkLmFsbFZhbHVlc0NvdW50ICsgcGFkZGluZyAqIDJcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCAwKVxyXG4gICAgICAgICAgICAuYXR0cihcImZpbGxcIiwgXCJ3aGl0ZVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImZpbGwtb3BhY2l0eVwiLCAwKVxyXG4gICAgICAgICAgICAuYXR0cihcInN0cm9rZS13aWR0aFwiLCAwLjUpXHJcbiAgICAgICAgICAgIC5hdHRyKFwic3Ryb2tlXCIsIFwiYmxhY2tcIilcclxuXHJcblxyXG4gICAgICAgIGdyb3Vwcy5lYWNoKGZ1bmN0aW9uIChncm91cCkge1xyXG5cclxuICAgICAgICAgICAgc2VsZi5kcmF3R3JvdXBzWS5jYWxsKHNlbGYsIGdyb3VwLCBkMy5zZWxlY3QodGhpcyksIGdyb3VwV2lkdGggLSB0aXRsZVJlY3RXaWR0aCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGRyYXdHcm91cHNYKHBhcmVudEdyb3VwLCBjb250YWluZXIsIGF2YWlsYWJsZUhlaWdodCkge1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcblxyXG4gICAgICAgIHZhciBncm91cENsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImdyb3VwXCIpO1xyXG4gICAgICAgIHZhciBncm91cFhDbGFzcyA9IGdyb3VwQ2xhc3MgKyBcIi14XCI7XHJcbiAgICAgICAgdmFyIGdyb3VwcyA9IGNvbnRhaW5lci5zZWxlY3RBbGwoXCJnLlwiICsgZ3JvdXBDbGFzcyArIFwiLlwiICsgZ3JvdXBYQ2xhc3MpXHJcbiAgICAgICAgICAgIC5kYXRhKHBhcmVudEdyb3VwLmNoaWxkcmVuTGlzdCk7XHJcblxyXG4gICAgICAgIHZhciB2YWx1ZXNCZWZvcmVDb3VudCA9IDA7XHJcbiAgICAgICAgdmFyIGdhcHNCZWZvcmVTaXplID0gMDtcclxuXHJcbiAgICAgICAgdmFyIGdyb3Vwc0VudGVyRyA9IGdyb3Vwcy5lbnRlcigpLmFwcGVuZChcImdcIik7XHJcbiAgICAgICAgZ3JvdXBzRW50ZXJHXHJcbiAgICAgICAgICAgIC5jbGFzc2VkKGdyb3VwQ2xhc3MsIHRydWUpXHJcbiAgICAgICAgICAgIC5jbGFzc2VkKGdyb3VwWENsYXNzLCB0cnVlKVxyXG4gICAgICAgICAgICAuYXBwZW5kKFwicmVjdFwiKS5jbGFzc2VkKFwiZ3JvdXAtcmVjdFwiLCB0cnVlKTtcclxuXHJcbiAgICAgICAgdmFyIHRpdGxlR3JvdXBFbnRlciA9IGdyb3Vwc0VudGVyRy5hcHBlbmRTZWxlY3RvcihcImcudGl0bGVcIik7XHJcbiAgICAgICAgdGl0bGVHcm91cEVudGVyLmFwcGVuZChcInJlY3RcIik7XHJcbiAgICAgICAgdGl0bGVHcm91cEVudGVyLmFwcGVuZChcInRleHRcIik7XHJcblxyXG4gICAgICAgIHZhciBnYXBTaXplID0gSGVhdG1hcC5jb21wdXRlR2FwU2l6ZShwYXJlbnRHcm91cC5sZXZlbCk7XHJcbiAgICAgICAgdmFyIHBhZGRpbmcgPSBnYXBTaXplIC8gNDtcclxuICAgICAgICB2YXIgdGl0bGVSZWN0SGVpZ2h0ID0gSGVhdG1hcC5ncm91cFRpdGxlUmVjdEhlaWdodDtcclxuXHJcbiAgICAgICAgdmFyIGRlcHRoID0gc2VsZi5jb25maWcueC5ncm91cHMua2V5cy5sZW5ndGggLSBwYXJlbnRHcm91cC5sZXZlbDtcclxuXHJcbiAgICAgICAgdmFyIG92ZXJsYXAgPSB7XHJcbiAgICAgICAgICAgIHRvcDogMCxcclxuICAgICAgICAgICAgYm90dG9tOiAwXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKCFhdmFpbGFibGVIZWlnaHQpIHtcclxuICAgICAgICAgICAgb3ZlcmxhcC5ib3R0b20gPSBwbG90Lngub3ZlcmxhcC5ib3R0b207XHJcbiAgICAgICAgICAgIG92ZXJsYXAudG9wID0gcGxvdC54Lm92ZXJsYXAudG9wO1xyXG4gICAgICAgICAgICBhdmFpbGFibGVIZWlnaHQgPSBwbG90LmhlaWdodCArIGdhcFNpemUgKyBvdmVybGFwLnRvcCArIG92ZXJsYXAuYm90dG9tO1xyXG5cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBvdmVybGFwLnRvcCA9IC10aXRsZVJlY3RIZWlnaHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCdwYXJlbnRHcm91cCcscGFyZW50R3JvdXAsICdnYXBTaXplJywgZ2FwU2l6ZSwgcGxvdC54Lm92ZXJsYXApO1xyXG5cclxuICAgICAgICBncm91cHNcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciB0cmFuc2xhdGUgPSBcInRyYW5zbGF0ZShcIiArICgocGxvdC5jZWxsV2lkdGggKiB2YWx1ZXNCZWZvcmVDb3VudCkgKyBpICogZ2FwU2l6ZSArIGdhcHNCZWZvcmVTaXplICsgcGFkZGluZykgKyBcIiwgXCIgKyAocGFkZGluZyAtIG92ZXJsYXAudG9wKSArIFwiKVwiO1xyXG4gICAgICAgICAgICAgICAgZ2Fwc0JlZm9yZVNpemUgKz0gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCk7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZXNCZWZvcmVDb3VudCArPSBkLmFsbFZhbHVlc0NvdW50IHx8IDA7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNsYXRlXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB2YXIgZ3JvdXBIZWlnaHQgPSBhdmFpbGFibGVIZWlnaHQgLSBwYWRkaW5nICogMjtcclxuXHJcbiAgICAgICAgdmFyIHRpdGxlR3JvdXBzID0gZ3JvdXBzLnNlbGVjdEFsbChcImcudGl0bGVcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IFwidHJhbnNsYXRlKDAsIFwiICsgKDApICsgXCIpXCIpO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIHRpbGVSZWN0cyA9IHRpdGxlR3JvdXBzLnNlbGVjdEFsbChcInJlY3RcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgdGl0bGVSZWN0SGVpZ2h0KVxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGQ9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCkgKyBwbG90LmNlbGxXaWR0aCAqIGQuYWxsVmFsdWVzQ291bnQgKyBwYWRkaW5nICogMlxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMClcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIDApXHJcbiAgICAgICAgICAgIC8vIC5hdHRyKFwiZmlsbFwiLCBcImxpZ2h0Z3JleVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcInN0cm9rZS13aWR0aFwiLCAwKTtcclxuXHJcbiAgICAgICAgdGhpcy5zZXRHcm91cE1vdXNlQ2FsbGJhY2tzKHBhcmVudEdyb3VwLCB0aWxlUmVjdHMpO1xyXG5cclxuXHJcbiAgICAgICAgZ3JvdXBzLnNlbGVjdEFsbChcInJlY3QuZ3JvdXAtcmVjdFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGQ9PiBcImdyb3VwLXJlY3QgZ3JvdXAtcmVjdC1cIiArIGQuaW5kZXgpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGdyb3VwSGVpZ2h0KVxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGQ9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGQuZ2Fwc0luc2lkZVNpemUgfHwgMCkgKyBwbG90LmNlbGxXaWR0aCAqIGQuYWxsVmFsdWVzQ291bnQgKyBwYWRkaW5nICogMlxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMClcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZmlsbFwiLCBcIndoaXRlXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZmlsbC1vcGFjaXR5XCIsIDApXHJcbiAgICAgICAgICAgIC5hdHRyKFwic3Ryb2tlLXdpZHRoXCIsIDAuNSlcclxuICAgICAgICAgICAgLmF0dHIoXCJzdHJva2VcIiwgXCJibGFja1wiKTtcclxuXHJcbiAgICAgICAgZ3JvdXBzLmVhY2goZnVuY3Rpb24gKGdyb3VwKSB7XHJcbiAgICAgICAgICAgIHNlbGYuZHJhd0dyb3Vwc1guY2FsbChzZWxmLCBncm91cCwgZDMuc2VsZWN0KHRoaXMpLCBncm91cEhlaWdodCAtIHRpdGxlUmVjdEhlaWdodCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGdyb3Vwcy5leGl0KCkucmVtb3ZlKCk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHNldEdyb3VwTW91c2VDYWxsYmFja3MocGFyZW50R3JvdXAsIHRpbGVSZWN0cykge1xyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgbW91c2VvdmVyQ2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLnB1c2goZnVuY3Rpb24gKGQpIHtcclxuICAgICAgICAgICAgZDMuc2VsZWN0KHRoaXMpLmNsYXNzZWQoJ2hpZ2hsaWdodGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdCh0aGlzLnBhcmVudE5vZGUucGFyZW50Tm9kZSkuc2VsZWN0QWxsKFwicmVjdC5ncm91cC1yZWN0LVwiICsgZC5pbmRleCkuY2xhc3NlZCgnaGlnaGxpZ2h0ZWQnLCB0cnVlKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdmFyIG1vdXNlb3V0Q2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgbW91c2VvdXRDYWxsYmFja3MucHVzaChmdW5jdGlvbiAoZCkge1xyXG4gICAgICAgICAgICBkMy5zZWxlY3QodGhpcykuY2xhc3NlZCgnaGlnaGxpZ2h0ZWQnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGQzLnNlbGVjdCh0aGlzLnBhcmVudE5vZGUucGFyZW50Tm9kZSkuc2VsZWN0QWxsKFwicmVjdC5ncm91cC1yZWN0LVwiICsgZC5pbmRleCkuY2xhc3NlZCgnaGlnaGxpZ2h0ZWQnLCBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHBsb3QudG9vbHRpcCkge1xyXG5cclxuICAgICAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLnB1c2goZD0+IHtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oMjAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgLjkpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGh0bWwgPSBwYXJlbnRHcm91cC5sYWJlbCArIFwiOiBcIiArIGQuZ3JvdXBpbmdWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAuaHRtbChodG1sKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcImxlZnRcIiwgKGQzLmV2ZW50LnBhZ2VYICsgNSkgKyBcInB4XCIpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwidG9wXCIsIChkMy5ldmVudC5wYWdlWSAtIDI4KSArIFwicHhcIik7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgbW91c2VvdXRDYWxsYmFja3MucHVzaChkPT4ge1xyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbig1MDApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG5cclxuICAgICAgICB9XHJcbiAgICAgICAgdGlsZVJlY3RzLm9uKFwibW91c2VvdmVyXCIsIGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLmZvckVhY2goZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKHNlbGYsIGQpXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRpbGVSZWN0cy5vbihcIm1vdXNlb3V0XCIsIGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgbW91c2VvdXRDYWxsYmFja3MuZm9yRWFjaChmdW5jdGlvbiAoY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoc2VsZiwgZClcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlQ2VsbHMoKSB7XHJcblxyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHNlbGYucGxvdDtcclxuICAgICAgICB2YXIgY2VsbENvbnRhaW5lckNsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImNlbGxzXCIpO1xyXG4gICAgICAgIHZhciBnYXBTaXplID0gSGVhdG1hcC5jb21wdXRlR2FwU2l6ZSgwKTtcclxuICAgICAgICB2YXIgcGFkZGluZ1ggPSBwbG90LnguZ3JvdXBzLmNoaWxkcmVuTGlzdC5sZW5ndGggPyBnYXBTaXplIC8gMiA6IDA7XHJcbiAgICAgICAgdmFyIHBhZGRpbmdZID0gcGxvdC55Lmdyb3Vwcy5jaGlsZHJlbkxpc3QubGVuZ3RoID8gZ2FwU2l6ZSAvIDIgOiAwO1xyXG4gICAgICAgIHZhciBjZWxsQ29udGFpbmVyID0gc2VsZi5zdmdHLnNlbGVjdE9yQXBwZW5kKFwiZy5cIiArIGNlbGxDb250YWluZXJDbGFzcyk7XHJcbiAgICAgICAgY2VsbENvbnRhaW5lci5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgcGFkZGluZ1ggKyBcIiwgXCIgKyBwYWRkaW5nWSArIFwiKVwiKTtcclxuXHJcbiAgICAgICAgdmFyIGNlbGxDbGFzcyA9IHNlbGYucHJlZml4Q2xhc3MoXCJjZWxsXCIpO1xyXG4gICAgICAgIHZhciBjZWxsU2hhcGUgPSBwbG90Lnouc2hhcGUudHlwZTtcclxuXHJcbiAgICAgICAgdmFyIGNlbGxzID0gY2VsbENvbnRhaW5lci5zZWxlY3RBbGwoXCJnLlwiICsgY2VsbENsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShzZWxmLnBsb3QuY2VsbHMpO1xyXG5cclxuICAgICAgICB2YXIgY2VsbEVudGVyRyA9IGNlbGxzLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuY2xhc3NlZChjZWxsQ2xhc3MsIHRydWUpO1xyXG4gICAgICAgIGNlbGxzLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgYz0+IFwidHJhbnNsYXRlKFwiICsgKChwbG90LmNlbGxXaWR0aCAqIGMuY29sICsgcGxvdC5jZWxsV2lkdGggLyAyKSArIGMuY29sVmFyLmdyb3VwLmdhcHNTaXplKSArIFwiLFwiICsgKChwbG90LmNlbGxIZWlnaHQgKiBjLnJvdyArIHBsb3QuY2VsbEhlaWdodCAvIDIpICsgYy5yb3dWYXIuZ3JvdXAuZ2Fwc1NpemUpICsgXCIpXCIpO1xyXG5cclxuICAgICAgICB2YXIgc2hhcGVzID0gY2VsbHMuc2VsZWN0T3JBcHBlbmQoY2VsbFNoYXBlICsgXCIuY2VsbC1zaGFwZS1cIiArIGNlbGxTaGFwZSk7XHJcblxyXG4gICAgICAgIHNoYXBlc1xyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIHBsb3Quei5zaGFwZS53aWR0aClcclxuICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgcGxvdC56LnNoYXBlLmhlaWdodClcclxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIC1wbG90LmNlbGxXaWR0aCAvIDIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCAtcGxvdC5jZWxsSGVpZ2h0IC8gMik7XHJcblxyXG4gICAgICAgIHNoYXBlcy5zdHlsZShcImZpbGxcIiwgYz0+IGMudmFsdWUgPT09IHVuZGVmaW5lZCA/IHNlbGYuY29uZmlnLmNvbG9yLm5vRGF0YUNvbG9yIDogcGxvdC56LmNvbG9yLnNjYWxlKGMudmFsdWUpKTtcclxuICAgICAgICBzaGFwZXMuYXR0cihcImZpbGwtb3BhY2l0eVwiLCBkPT4gZC52YWx1ZSA9PT0gdW5kZWZpbmVkID8gMCA6IDEpO1xyXG5cclxuICAgICAgICB2YXIgbW91c2VvdmVyQ2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgdmFyIG1vdXNlb3V0Q2FsbGJhY2tzID0gW107XHJcblxyXG4gICAgICAgIGlmIChwbG90LnRvb2x0aXApIHtcclxuXHJcbiAgICAgICAgICAgIG1vdXNlb3ZlckNhbGxiYWNrcy5wdXNoKGM9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDIwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIC45KTtcclxuICAgICAgICAgICAgICAgIHZhciBodG1sID0gYy52YWx1ZSA9PT0gdW5kZWZpbmVkID8gc2VsZi5jb25maWcudG9vbHRpcC5ub0RhdGFUZXh0IDogc2VsZi5mb3JtYXRWYWx1ZVooYy52YWx1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLmh0bWwoaHRtbClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJsZWZ0XCIsIChkMy5ldmVudC5wYWdlWCArIDUpICsgXCJweFwiKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcInRvcFwiLCAoZDMuZXZlbnQucGFnZVkgLSAyOCkgKyBcInB4XCIpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIG1vdXNlb3V0Q2FsbGJhY2tzLnB1c2goYz0+IHtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oNTAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc2VsZi5jb25maWcuaGlnaGxpZ2h0TGFiZWxzKSB7XHJcbiAgICAgICAgICAgIHZhciBoaWdobGlnaHRDbGFzcyA9IHNlbGYuY29uZmlnLmNzc0NsYXNzUHJlZml4ICsgXCJoaWdobGlnaHRcIjtcclxuICAgICAgICAgICAgdmFyIHhMYWJlbENsYXNzID0gYz0+cGxvdC5sYWJlbENsYXNzICsgXCIteC1cIiArIGMuY29sO1xyXG4gICAgICAgICAgICB2YXIgeUxhYmVsQ2xhc3MgPSBjPT5wbG90LmxhYmVsQ2xhc3MgKyBcIi15LVwiICsgYy5yb3c7XHJcblxyXG5cclxuICAgICAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLnB1c2goYz0+IHtcclxuXHJcbiAgICAgICAgICAgICAgICBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwidGV4dC5cIiArIHhMYWJlbENsYXNzKGMpKS5jbGFzc2VkKGhpZ2hsaWdodENsYXNzLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCJ0ZXh0LlwiICsgeUxhYmVsQ2xhc3MoYykpLmNsYXNzZWQoaGlnaGxpZ2h0Q2xhc3MsIHRydWUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgbW91c2VvdXRDYWxsYmFja3MucHVzaChjPT4ge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5zdmdHLnNlbGVjdEFsbChcInRleHQuXCIgKyB4TGFiZWxDbGFzcyhjKSkuY2xhc3NlZChoaWdobGlnaHRDbGFzcywgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgc2VsZi5zdmdHLnNlbGVjdEFsbChcInRleHQuXCIgKyB5TGFiZWxDbGFzcyhjKSkuY2xhc3NlZChoaWdobGlnaHRDbGFzcywgZmFsc2UpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBjZWxscy5vbihcIm1vdXNlb3ZlclwiLCBjID0+IHtcclxuICAgICAgICAgICAgbW91c2VvdmVyQ2FsbGJhY2tzLmZvckVhY2goY2FsbGJhY2s9PmNhbGxiYWNrKGMpKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgICAgICAub24oXCJtb3VzZW91dFwiLCBjID0+IHtcclxuICAgICAgICAgICAgICAgIG1vdXNlb3V0Q2FsbGJhY2tzLmZvckVhY2goY2FsbGJhY2s9PmNhbGxiYWNrKGMpKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGNlbGxzLm9uKFwiY2xpY2tcIiwgYz0+IHtcclxuICAgICAgICAgICAgc2VsZi50cmlnZ2VyKFwiY2VsbC1zZWxlY3RlZFwiLCBjKTtcclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIGNlbGxzLmV4aXQoKS5yZW1vdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBmb3JtYXRWYWx1ZVgodmFsdWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnguZm9ybWF0dGVyKSByZXR1cm4gdmFsdWU7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy54LmZvcm1hdHRlci5jYWxsKHRoaXMuY29uZmlnLCB2YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9ybWF0VmFsdWVZKHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy55LmZvcm1hdHRlcikgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcueS5mb3JtYXR0ZXIuY2FsbCh0aGlzLmNvbmZpZywgdmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGZvcm1hdFZhbHVlWih2YWx1ZSkge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcuei5mb3JtYXR0ZXIpIHJldHVybiB2YWx1ZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnouZm9ybWF0dGVyLmNhbGwodGhpcy5jb25maWcsIHZhbHVlKTtcclxuICAgIH1cclxuXHJcbiAgICBmb3JtYXRMZWdlbmRWYWx1ZSh2YWx1ZSkge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcubGVnZW5kLmZvcm1hdHRlcikgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcubGVnZW5kLmZvcm1hdHRlci5jYWxsKHRoaXMuY29uZmlnLCB2YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlTGVnZW5kKCkge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgbGVnZW5kWCA9IHRoaXMucGxvdC53aWR0aCArIDEwO1xyXG4gICAgICAgIHZhciBnYXBTaXplID0gSGVhdG1hcC5jb21wdXRlR2FwU2l6ZSgwKTtcclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlZKSB7XHJcbiAgICAgICAgICAgIGxlZ2VuZFggKz0gZ2FwU2l6ZSAvIDIgKyBwbG90Lnkub3ZlcmxhcC5yaWdodDtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucGxvdC5ncm91cEJ5WCkge1xyXG4gICAgICAgICAgICBsZWdlbmRYICs9IGdhcFNpemU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBsZWdlbmRZID0gMDtcclxuICAgICAgICBpZiAodGhpcy5wbG90Lmdyb3VwQnlYIHx8IHRoaXMucGxvdC5ncm91cEJ5WSkge1xyXG4gICAgICAgICAgICBsZWdlbmRZICs9IGdhcFNpemUgLyAyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGJhcldpZHRoID0gMTA7XHJcbiAgICAgICAgdmFyIGJhckhlaWdodCA9IHRoaXMucGxvdC5oZWlnaHQgLSAyO1xyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3Quei5jb2xvci5zY2FsZTtcclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmQgPSBuZXcgTGVnZW5kKHRoaXMuc3ZnLCB0aGlzLnN2Z0csIHNjYWxlLCBsZWdlbmRYLCBsZWdlbmRZLCB2ID0+IHNlbGYuZm9ybWF0TGVnZW5kVmFsdWUodikpLnNldFJvdGF0ZUxhYmVscyhzZWxmLmNvbmZpZy5sZWdlbmQucm90YXRlTGFiZWxzKS5saW5lYXJHcmFkaWVudEJhcihiYXJXaWR0aCwgYmFySGVpZ2h0KTtcclxuICAgIH1cclxuXHJcblxyXG59XHJcbiIsImltcG9ydCB7Q2hhcnQsIENoYXJ0Q29uZmlnfSBmcm9tIFwiLi9jaGFydFwiO1xyXG5pbXBvcnQge1V0aWxzfSBmcm9tICcuL3V0aWxzJ1xyXG5pbXBvcnQge0xlZ2VuZH0gZnJvbSBcIi4vbGVnZW5kXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgSGlzdG9ncmFtQ29uZmlnIGV4dGVuZHMgQ2hhcnRDb25maWd7XHJcblxyXG4gICAgc3ZnQ2xhc3M9IHRoaXMuY3NzQ2xhc3NQcmVmaXgrJ2hpc3RvZ3JhbSc7XHJcbiAgICBzaG93TGVnZW5kPXRydWU7XHJcbiAgICBzaG93VG9vbHRpcCA9dHJ1ZTtcclxuICAgIGxlZ2VuZD17XHJcbiAgICAgICAgd2lkdGg6IDgwLFxyXG4gICAgICAgIG1hcmdpbjogMTAsXHJcbiAgICAgICAgc2hhcGVXaWR0aDogMjBcclxuICAgIH07XHJcbiAgICB4PXsvLyBYIGF4aXMgY29uZmlnXHJcbiAgICAgICAgbGFiZWw6ICcnLCAvLyBheGlzIGxhYmVsXHJcbiAgICAgICAga2V5OiAwLFxyXG4gICAgICAgIHZhbHVlOiAoZCwga2V5KSA9PiBVdGlscy5pc051bWJlcihkKSA/IGQgOiBkW2tleV0sIC8vIHggdmFsdWUgYWNjZXNzb3JcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIixcclxuICAgICAgICB0aWNrczogdW5kZWZpbmVkLFxyXG4gICAgfTtcclxuICAgIHk9ey8vIFkgYXhpcyBjb25maWdcclxuICAgICAgICBsYWJlbDogJycsIC8vIGF4aXMgbGFiZWwsXHJcbiAgICAgICAgb3JpZW50OiBcImxlZnRcIixcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIlxyXG4gICAgfTtcclxuICAgIGZyZXF1ZW5jeT10cnVlO1xyXG4gICAgZ3JvdXBzPXtcclxuICAgICAgICBrZXk6IDEsXHJcbiAgICAgICAgdmFsdWU6IChkKSA9PiBkW3RoaXMuZ3JvdXBzLmtleV0gLCAvLyBncm91cGluZyB2YWx1ZSBhY2Nlc3NvcixcclxuICAgICAgICBsYWJlbDogXCJcIlxyXG4gICAgfTtcclxuICAgIGNvbG9yID0gdW5kZWZpbmVkIC8vIHN0cmluZyBvciBmdW5jdGlvbiByZXR1cm5pbmcgY29sb3IncyB2YWx1ZSBmb3IgY29sb3Igc2NhbGVcclxuICAgIGQzQ29sb3JDYXRlZ29yeT0gJ2NhdGVnb3J5MTAnO1xyXG4gICAgdHJhbnNpdGlvbj0gdHJ1ZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pe1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdmFyIGNvbmZpZyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmKGN1c3RvbSl7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgSGlzdG9ncmFtIGV4dGVuZHMgQ2hhcnR7XHJcbiAgICBjb25zdHJ1Y3RvcihwbGFjZWhvbGRlclNlbGVjdG9yLCBkYXRhLCBjb25maWcpIHtcclxuICAgICAgICBzdXBlcihwbGFjZWhvbGRlclNlbGVjdG9yLCBkYXRhLCBuZXcgSGlzdG9ncmFtQ29uZmlnKGNvbmZpZykpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldENvbmZpZyhjb25maWcpe1xyXG4gICAgICAgIHJldHVybiBzdXBlci5zZXRDb25maWcobmV3IEhpc3RvZ3JhbUNvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpe1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGY9dGhpcztcclxuXHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90Lng9e307XHJcbiAgICAgICAgdGhpcy5wbG90Lnk9e307XHJcbiAgICAgICAgdGhpcy5wbG90LmJhcj17XHJcbiAgICAgICAgICAgIGNvbG9yOiBudWxsLy9jb2xvciBzY2FsZSBtYXBwaW5nIGZ1bmN0aW9uXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdGhpcy5wbG90LnNob3dMZWdlbmQgPSBjb25mLnNob3dMZWdlbmQ7XHJcbiAgICAgICAgaWYodGhpcy5wbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QubWFyZ2luLnJpZ2h0ID0gY29uZi5tYXJnaW4ucmlnaHQgKyBjb25mLmxlZ2VuZC53aWR0aCtjb25mLmxlZ2VuZC5tYXJnaW4qMjtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB0aGlzLmNvbXB1dGVQbG90U2l6ZSgpO1xyXG5cclxuXHJcblxyXG4gICAgICAgIGlmKGNvbmYuZDNDb2xvckNhdGVnb3J5KXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmNvbG9yQ2F0ZWdvcnkgPSBkMy5zY2FsZVtjb25mLmQzQ29sb3JDYXRlZ29yeV0oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNvbG9yVmFsdWUgPSBjb25mLmNvbG9yO1xyXG4gICAgICAgIGlmIChjb2xvclZhbHVlICYmIHR5cGVvZiBjb2xvclZhbHVlID09PSAnc3RyaW5nJyB8fCBjb2xvclZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmNvbG9yID0gY29sb3JWYWx1ZTtcclxuICAgICAgICB9ZWxzZSBpZih0aGlzLnBsb3QuY29sb3JDYXRlZ29yeSl7XHJcbiAgICAgICAgICAgIGlmKHRoaXMuY29uZmlnLmdyb3Vwcyl7XHJcbiAgICAgICAgICAgICAgICB2YXIgZG9tYWluID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZDMubWFwKHRoaXMuZGF0YSwgZCA9PiB0aGlzLmNvbmZpZy5ncm91cHMudmFsdWUuY2FsbCh0aGlzLmNvbmZpZywgZCkpWydfJ10pO1xyXG4gICAgICAgICAgICAgICAgc2VsZi5wbG90LmNvbG9yQ2F0ZWdvcnkuZG9tYWluKGRvbWFpbik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMucGxvdC5jb2xvciA9IGQgPT4gIHNlbGYucGxvdC5jb2xvckNhdGVnb3J5KGQua2V5KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucGxvdC5kYXRhID0gdGhpcy5nZXREYXRhVG9QbG90KCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cFgoKTtcclxuICAgICAgICB0aGlzLnNldHVwSGlzdG9ncmFtKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cEdyb3VwU3RhY2tzKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cFkoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0dXBYKCl7XHJcblxyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciB4ID0gcGxvdC54O1xyXG4gICAgICAgIHZhciBjb25mID0gdGhpcy5jb25maWcueDtcclxuXHJcbiAgICAgICAgLyogKlxyXG4gICAgICAgICAqIHZhbHVlIGFjY2Vzc29yIC0gcmV0dXJucyB0aGUgdmFsdWUgdG8gZW5jb2RlIGZvciBhIGdpdmVuIGRhdGEgb2JqZWN0LlxyXG4gICAgICAgICAqIHNjYWxlIC0gbWFwcyB2YWx1ZSB0byBhIHZpc3VhbCBkaXNwbGF5IGVuY29kaW5nLCBzdWNoIGFzIGEgcGl4ZWwgcG9zaXRpb24uXHJcbiAgICAgICAgICogbWFwIGZ1bmN0aW9uIC0gbWFwcyBmcm9tIGRhdGEgdmFsdWUgdG8gZGlzcGxheSB2YWx1ZVxyXG4gICAgICAgICAqIGF4aXMgLSBzZXRzIHVwIGF4aXNcclxuICAgICAgICAgKiovXHJcbiAgICAgICAgeC52YWx1ZSA9IGQgPT4gY29uZi52YWx1ZShkLCBjb25mLmtleSk7XHJcbiAgICAgICAgeC5zY2FsZSA9IGQzLnNjYWxlW2NvbmYuc2NhbGVdKCkucmFuZ2UoWzAsIHBsb3Qud2lkdGhdKTtcclxuICAgICAgICB4Lm1hcCA9IGQgPT4geC5zY2FsZSh4LnZhbHVlKGQpKTtcclxuXHJcbiAgICAgICAgeC5heGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh4LnNjYWxlKS5vcmllbnQoY29uZi5vcmllbnQpO1xyXG4gICAgICAgIGlmKGNvbmYudGlja3Mpe1xyXG4gICAgICAgICAgICB4LmF4aXMudGlja3MoY29uZi50aWNrcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5wbG90LmRhdGE7XHJcbiAgICAgICAgcGxvdC54LnNjYWxlLmRvbWFpbihbZDMubWluKGRhdGEsIHBsb3QueC52YWx1ZSksIGQzLm1heChkYXRhLCBwbG90LngudmFsdWUpXSk7XHJcbiAgICAgICAgXHJcbiAgICB9O1xyXG5cclxuICAgIHNldHVwWSAoKXtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIHkgPSBwbG90Lnk7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZy55O1xyXG4gICAgICAgIHkuc2NhbGUgPSBkMy5zY2FsZVtjb25mLnNjYWxlXSgpLnJhbmdlKFtwbG90LmhlaWdodCwgMF0pO1xyXG5cclxuICAgICAgICB5LmF4aXMgPSBkMy5zdmcuYXhpcygpLnNjYWxlKHkuc2NhbGUpLm9yaWVudChjb25mLm9yaWVudCk7XHJcblxyXG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5wbG90LmRhdGE7XHJcbiAgICAgICAgcGxvdC55LnNjYWxlLmRvbWFpbihbMCwgZDMubWF4KHBsb3QuaGlzdG9ncmFtQmlucywgZD0+ZC55KV0pO1xyXG4gICAgfTtcclxuXHJcbiAgICBzZXR1cEhpc3RvZ3JhbSgpIHtcclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgeCA9IHBsb3QueDtcclxuICAgICAgICB2YXIgeSA9IHBsb3QueTtcclxuICAgICAgICB2YXIgdGlja3MgPSB0aGlzLmNvbmZpZy54LnRpY2tzID8geC5zY2FsZS50aWNrcyh0aGlzLmNvbmZpZy54LnRpY2tzKSA6IHguc2NhbGUudGlja3MoKTtcclxuXHJcbiAgICAgICAgcGxvdC5oaXN0b2dyYW0gPSBkMy5sYXlvdXQuaGlzdG9ncmFtKCkuZnJlcXVlbmN5KHRoaXMuY29uZmlnLmZyZXF1ZW5jeSlcclxuICAgICAgICAgICAgLnZhbHVlKHgudmFsdWUpXHJcbiAgICAgICAgICAgIC5iaW5zKHRpY2tzKTtcclxuICAgICAgICBwbG90Lmhpc3RvZ3JhbUJpbnMgPSBwbG90Lmhpc3RvZ3JhbSh0aGlzLnBsb3QuZGF0YSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHNldHVwR3JvdXBTdGFja3MoKSB7XHJcbiAgICAgICAgdmFyIHNlbGY9dGhpcztcclxuICAgICAgICB0aGlzLnBsb3QuZ3JvdXBpbmdFbmFibGVkID0gdGhpcy5jb25maWcuZ3JvdXBzICYmIHRoaXMuY29uZmlnLmdyb3Vwcy52YWx1ZTtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnBsb3Quc3RhY2sgPSBkMy5sYXlvdXQuc3RhY2soKS52YWx1ZXMoZD0+ZC5oaXN0b2dyYW1CaW5zKTtcclxuICAgICAgICB0aGlzLnBsb3QuZ3JvdXBlZERhdGEgPSAgZDMubmVzdCgpLmtleShkID0+IHRoaXMucGxvdC5ncm91cGluZ0VuYWJsZWQgPyB0aGlzLmNvbmZpZy5ncm91cHMudmFsdWUuY2FsbCh0aGlzLmNvbmZpZywgZCkgOiAncm9vdCcgKS5lbnRyaWVzKHRoaXMucGxvdC5kYXRhKTtcclxuICAgICAgICB0aGlzLnBsb3QuZ3JvdXBlZERhdGEuZm9yRWFjaChkPT57XHJcbiAgICAgICAgICAgIGQuaGlzdG9ncmFtQmlucyA9IHRoaXMucGxvdC5oaXN0b2dyYW0uZnJlcXVlbmN5KHRoaXMuY29uZmlnLmZyZXF1ZW5jeSB8fCB0aGlzLnBsb3QuZ3JvdXBpbmdFbmFibGVkKShkLnZhbHVlcyk7XHJcbiAgICAgICAgICAgIGlmKCF0aGlzLmNvbmZpZy5mcmVxdWVuY3kgJiYgdGhpcy5wbG90Lmdyb3VwaW5nRW5hYmxlZCl7XHJcbiAgICAgICAgICAgICAgICBkLmhpc3RvZ3JhbUJpbnMuZm9yRWFjaChiID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBiLmR5ID0gYi5keS90aGlzLnBsb3QuZGF0YS5sZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICBiLnkgPSBiLnkvdGhpcy5wbG90LmRhdGEubGVuZ3RoXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMucGxvdC5zdGFja2VkSGlzdG9ncmFtcyA9IHRoaXMucGxvdC5zdGFjayh0aGlzLnBsb3QuZ3JvdXBlZERhdGEpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldERhdGFUb1Bsb3QoKXtcclxuICAgICAgICBpZighdGhpcy5lbmFibGVkR3JvdXBzKXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEuZmlsdGVyKGQgPT4gdGhpcy5lbmFibGVkR3JvdXBzLmluZGV4T2YodGhpcy5jb25maWcuZ3JvdXBzLnZhbHVlLmNhbGwodGhpcy5jb25maWcsIGQpKT4tMSk7XHJcbiAgICB9XHJcblxyXG4gICAgZHJhd0F4aXNYKCl7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBheGlzQ29uZiA9IHRoaXMuY29uZmlnLng7XHJcbiAgICAgICAgdmFyIGF4aXMgPSBzZWxmLnN2Z0cuc2VsZWN0T3JBcHBlbmQoXCJnLlwiK3NlbGYucHJlZml4Q2xhc3MoJ2F4aXMteCcpK1wiLlwiK3NlbGYucHJlZml4Q2xhc3MoJ2F4aXMnKSsoc2VsZi5jb25maWcuZ3VpZGVzID8gJycgOiAnLicrc2VsZi5wcmVmaXhDbGFzcygnbm8tZ3VpZGVzJykpKVxyXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZSgwLFwiICsgcGxvdC5oZWlnaHQgKyBcIilcIik7XHJcblxyXG4gICAgICAgIHZhciBheGlzVCA9IGF4aXM7XHJcbiAgICAgICAgaWYgKHNlbGYuY29uZmlnLnRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgYXhpc1QgPSBheGlzLnRyYW5zaXRpb24oKS5lYXNlKFwic2luLWluLW91dFwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGF4aXNULmNhbGwocGxvdC54LmF4aXMpO1xyXG5cclxuICAgICAgICBheGlzLnNlbGVjdE9yQXBwZW5kKFwidGV4dC5cIitzZWxmLnByZWZpeENsYXNzKCdsYWJlbCcpKVxyXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIisgKHBsb3Qud2lkdGgvMikgK1wiLFwiKyAocGxvdC5tYXJnaW4uYm90dG9tKSArXCIpXCIpICAvLyB0ZXh0IGlzIGRyYXduIG9mZiB0aGUgc2NyZWVuIHRvcCBsZWZ0LCBtb3ZlIGRvd24gYW5kIG91dCBhbmQgcm90YXRlXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZHlcIiwgXCItMWVtXCIpXHJcbiAgICAgICAgICAgIC5zdHlsZShcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpXHJcbiAgICAgICAgICAgIC50ZXh0KGF4aXNDb25mLmxhYmVsKTtcclxuICAgIH07XHJcblxyXG4gICAgZHJhd0F4aXNZKCl7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBheGlzQ29uZiA9IHRoaXMuY29uZmlnLnk7XHJcbiAgICAgICAgdmFyIGF4aXMgPSBzZWxmLnN2Z0cuc2VsZWN0T3JBcHBlbmQoXCJnLlwiK3NlbGYucHJlZml4Q2xhc3MoJ2F4aXMteScpK1wiLlwiK3NlbGYucHJlZml4Q2xhc3MoJ2F4aXMnKSsoc2VsZi5jb25maWcuZ3VpZGVzID8gJycgOiAnLicrc2VsZi5wcmVmaXhDbGFzcygnbm8tZ3VpZGVzJykpKTtcclxuXHJcbiAgICAgICAgdmFyIGF4aXNUID0gYXhpcztcclxuICAgICAgICBpZiAoc2VsZi5jb25maWcudHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICBheGlzVCA9IGF4aXMudHJhbnNpdGlvbigpLmVhc2UoXCJzaW4taW4tb3V0XCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXhpc1QuY2FsbChwbG90LnkuYXhpcyk7XHJcblxyXG4gICAgICAgIGF4aXMuc2VsZWN0T3JBcHBlbmQoXCJ0ZXh0LlwiK3NlbGYucHJlZml4Q2xhc3MoJ2xhYmVsJykpXHJcbiAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiKyAtcGxvdC5tYXJnaW4ubGVmdCArXCIsXCIrKHBsb3QuaGVpZ2h0LzIpK1wiKXJvdGF0ZSgtOTApXCIpICAvLyB0ZXh0IGlzIGRyYXduIG9mZiB0aGUgc2NyZWVuIHRvcCBsZWZ0LCBtb3ZlIGRvd24gYW5kIG91dCBhbmQgcm90YXRlXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZHlcIiwgXCIxZW1cIilcclxuICAgICAgICAgICAgLnN0eWxlKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIilcclxuICAgICAgICAgICAgLnRleHQoYXhpc0NvbmYubGFiZWwpO1xyXG4gICAgfTtcclxuXHJcblxyXG4gICAgZHJhd0hpc3RvZ3JhbSgpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdmFyIGxheWVyQ2xhc3MgPSB0aGlzLnByZWZpeENsYXNzKFwibGF5ZXJcIik7XHJcblxyXG4gICAgICAgIHZhciBiYXJDbGFzcyA9IHRoaXMucHJlZml4Q2xhc3MoXCJiYXJcIik7XHJcbiAgICAgICAgdmFyIGxheWVyID0gc2VsZi5zdmdHLnNlbGVjdEFsbChcIi5cIitsYXllckNsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShwbG90LnN0YWNrZWRIaXN0b2dyYW1zKTtcclxuXHJcbiAgICAgICAgbGF5ZXIuZW50ZXIoKS5hcHBlbmQoXCJnXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgbGF5ZXJDbGFzcyk7XHJcblxyXG4gICAgICAgIHZhciBiYXIgPSBsYXllci5zZWxlY3RBbGwoXCIuXCIrYmFyQ2xhc3MpXHJcbiAgICAgICAgICAgIC5kYXRhKGQgPT4gZC5oaXN0b2dyYW1CaW5zKTtcclxuXHJcbiAgICAgICAgYmFyLmVudGVyKCkuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGJhckNsYXNzKVxyXG4gICAgICAgICAgICAuYXBwZW5kKFwicmVjdFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMSk7XHJcblxyXG5cclxuICAgICAgICB2YXIgYmFyUmVjdCA9IGJhci5zZWxlY3QoXCJyZWN0XCIpO1xyXG5cclxuICAgICAgICB2YXIgYmFyUmVjdFQgPSBiYXJSZWN0O1xyXG4gICAgICAgIHZhciBiYXJUID0gYmFyO1xyXG4gICAgICAgIHZhciBsYXllclQgPSBsYXllcjtcclxuICAgICAgICBpZiAodGhpcy50cmFuc2l0aW9uRW5hYmxlZCgpKSB7XHJcbiAgICAgICAgICAgIGJhclJlY3RUID0gYmFyUmVjdC50cmFuc2l0aW9uKCk7XHJcbiAgICAgICAgICAgIGJhclQgPSBiYXIudHJhbnNpdGlvbigpO1xyXG4gICAgICAgICAgICBsYXllclQ9IGxheWVyLnRyYW5zaXRpb24oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGJhclQuYXR0cihcInRyYW5zZm9ybVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBcInRyYW5zbGF0ZShcIiArIHBsb3QueC5zY2FsZShkLngpICsgXCIsXCIgKyAocGxvdC55LnNjYWxlKGQueTAgK2QueSkpICsgXCIpXCI7IH0pO1xyXG5cclxuICAgICAgICB2YXIgZHggPSBwbG90Lmhpc3RvZ3JhbUJpbnMubGVuZ3RoID8gIHBsb3QueC5zY2FsZShwbG90Lmhpc3RvZ3JhbUJpbnNbMF0uZHgpIDogMDtcclxuICAgICAgICBiYXJSZWN0VFxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsICBkeCAtIHBsb3QueC5zY2FsZSgwKS0gMSlcclxuICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgZCA9PiAgIHBsb3QuaGVpZ2h0IC0gcGxvdC55LnNjYWxlKGQueSkpO1xyXG5cclxuICAgICAgICBpZih0aGlzLnBsb3QuY29sb3Ipe1xyXG4gICAgICAgICAgICBsYXllclRcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwiZmlsbFwiLCB0aGlzLnBsb3QuY29sb3IpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBsb3QudG9vbHRpcCkge1xyXG4gICAgICAgICAgICBiYXIub24oXCJtb3VzZW92ZXJcIiwgZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDIwMClcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIC45KTtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGQueSlcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJsZWZ0XCIsIChkMy5ldmVudC5wYWdlWCArIDUpICsgXCJweFwiKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcInRvcFwiLCAoZDMuZXZlbnQucGFnZVkgLSAyOCkgKyBcInB4XCIpO1xyXG4gICAgICAgICAgICB9KS5vbihcIm1vdXNlb3V0XCIsIGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbig1MDApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxheWVyLmV4aXQoKS5yZW1vdmUoKTtcclxuICAgICAgICBiYXIuZXhpdCgpLnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZShuZXdEYXRhKXtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcbiAgICAgICAgdGhpcy5kcmF3QXhpc1goKTtcclxuICAgICAgICB0aGlzLmRyYXdBeGlzWSgpO1xyXG5cclxuICAgICAgICB0aGlzLmRyYXdIaXN0b2dyYW0oKTtcclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGVMZWdlbmQoKTtcclxuICAgIH07XHJcblxyXG5cclxuICAgIHVwZGF0ZUxlZ2VuZCgpIHtcclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuXHJcbiAgICAgICAgdmFyIHNjYWxlID0gcGxvdC5jb2xvckNhdGVnb3J5O1xyXG4gICAgICAgIGlmKCFzY2FsZS5kb21haW4oKSB8fCBzY2FsZS5kb21haW4oKS5sZW5ndGg8Mil7XHJcbiAgICAgICAgICAgIHBsb3Quc2hvd0xlZ2VuZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYoIXBsb3Quc2hvd0xlZ2VuZCl7XHJcbiAgICAgICAgICAgIGlmKHBsb3QubGVnZW5kICYmIHBsb3QubGVnZW5kLmNvbnRhaW5lcil7XHJcbiAgICAgICAgICAgICAgICBwbG90LmxlZ2VuZC5jb250YWluZXIucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIHZhciBsZWdlbmRYID0gdGhpcy5wbG90LndpZHRoICsgdGhpcy5jb25maWcubGVnZW5kLm1hcmdpbjtcclxuICAgICAgICB2YXIgbGVnZW5kWSA9IHRoaXMuY29uZmlnLmxlZ2VuZC5tYXJnaW47XHJcblxyXG4gICAgICAgIHBsb3QubGVnZW5kID0gbmV3IExlZ2VuZCh0aGlzLnN2ZywgdGhpcy5zdmdHLCBzY2FsZSwgbGVnZW5kWCwgbGVnZW5kWSk7XHJcblxyXG4gICAgICAgIHBsb3QubGVnZW5kQ29sb3IgPSBwbG90LmxlZ2VuZC5jb2xvcigpXHJcbiAgICAgICAgICAgIC5zaGFwZVdpZHRoKHRoaXMuY29uZmlnLmxlZ2VuZC5zaGFwZVdpZHRoKVxyXG4gICAgICAgICAgICAub3JpZW50KCd2ZXJ0aWNhbCcpXHJcbiAgICAgICAgICAgIC5zY2FsZShzY2FsZSk7XHJcblxyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZENvbG9yLm9uKCdjZWxsY2xpY2snLCBjPT4gdGhpcy5vbkxlZ2VuZENlbGxDbGljayhjKSk7XHJcblxyXG4gICAgICAgIHBsb3QubGVnZW5kLmNvbnRhaW5lclxyXG4gICAgICAgICAgICAuY2FsbChwbG90LmxlZ2VuZENvbG9yKTtcclxuICAgIH1cclxuXHJcbiAgICBvbkxlZ2VuZENlbGxDbGljayhjZWxsVmFsdWUpe1xyXG4gICAgICAgIHRoaXMudXBkYXRlRW5hYmxlZEdyb3VwcyhjZWxsVmFsdWUpO1xyXG5cclxuICAgICAgICB2YXIgaXNEaXNhYmxlZCA9IHRoaXMuZW5hYmxlZEdyb3Vwcy5pbmRleE9mKGNlbGxWYWx1ZSk8MDtcclxuICAgICAgICB0aGlzLnBsb3QubGVnZW5kLmNvbnRhaW5lci5zZWxlY3RBbGwoXCJnLmNlbGxcIikuZWFjaChmdW5jdGlvbihjZWxsKXtcclxuICAgICAgICAgICAgaWYoY2VsbCA9PSBjZWxsVmFsdWUpe1xyXG4gICAgICAgICAgICAgICAgZDMuc2VsZWN0KHRoaXMpLmNsYXNzZWQoXCJvZGMtZGlzYWJsZWRcIiwgaXNEaXNhYmxlZCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuaW5pdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUVuYWJsZWRHcm91cHMoY2VsbFZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVuYWJsZWRHcm91cHMpIHtcclxuICAgICAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzID0gdGhpcy5wbG90LmNvbG9yQ2F0ZWdvcnkuZG9tYWluKCkuc2xpY2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5lbmFibGVkR3JvdXBzLmluZGV4T2YoY2VsbFZhbHVlKTtcclxuXHJcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMucHVzaChjZWxsVmFsdWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZW5hYmxlZEdyb3Vwcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG5cclxuICAgIHNldERhdGEoZGF0YSl7XHJcbiAgICAgICAgc3VwZXIuc2V0RGF0YShkYXRhKTtcclxuICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMgPSBudWxsO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7RDNFeHRlbnNpb25zfSBmcm9tICcuL2QzLWV4dGVuc2lvbnMnXHJcbkQzRXh0ZW5zaW9ucy5leHRlbmQoKTtcclxuXHJcbmV4cG9ydCB7U2NhdHRlclBsb3QsIFNjYXR0ZXJQbG90Q29uZmlnfSBmcm9tIFwiLi9zY2F0dGVycGxvdFwiO1xyXG5leHBvcnQge1NjYXR0ZXJQbG90TWF0cml4LCBTY2F0dGVyUGxvdE1hdHJpeENvbmZpZ30gZnJvbSBcIi4vc2NhdHRlcnBsb3QtbWF0cml4XCI7XHJcbmV4cG9ydCB7Q29ycmVsYXRpb25NYXRyaXgsIENvcnJlbGF0aW9uTWF0cml4Q29uZmlnfSBmcm9tICcuL2NvcnJlbGF0aW9uLW1hdHJpeCdcclxuZXhwb3J0IHtSZWdyZXNzaW9uLCBSZWdyZXNzaW9uQ29uZmlnfSBmcm9tICcuL3JlZ3Jlc3Npb24nXHJcbmV4cG9ydCB7SGVhdG1hcCwgSGVhdG1hcENvbmZpZ30gZnJvbSAnLi9oZWF0bWFwJ1xyXG5leHBvcnQge0hlYXRtYXBUaW1lU2VyaWVzLCBIZWF0bWFwVGltZVNlcmllc0NvbmZpZ30gZnJvbSAnLi9oZWF0bWFwLXRpbWVzZXJpZXMnXHJcbmV4cG9ydCB7SGlzdG9ncmFtLCBIaXN0b2dyYW1Db25maWd9IGZyb20gJy4vaGlzdG9ncmFtJ1xyXG5leHBvcnQge0JhckNoYXJ0LCBCYXJDaGFydENvbmZpZ30gZnJvbSAnLi9iYXItY2hhcnQnXHJcbmV4cG9ydCB7U3RhdGlzdGljc1V0aWxzfSBmcm9tICcuL3N0YXRpc3RpY3MtdXRpbHMnXHJcbmV4cG9ydCB7TGVnZW5kfSBmcm9tICcuL2xlZ2VuZCdcclxuXHJcblxyXG5cclxuXHJcblxyXG4iLCJpbXBvcnQge1V0aWxzfSBmcm9tIFwiLi91dGlsc1wiO1xyXG5pbXBvcnQge2NvbG9yLCBzaXplLCBzeW1ib2x9IGZyb20gXCIuLi9ib3dlcl9jb21wb25lbnRzL2QzLWxlZ2VuZC9uby1leHRlbmRcIjtcclxuXHJcbi8qdmFyIGQzID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9kMycpO1xyXG4qL1xyXG4vLyB2YXIgbGVnZW5kID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9kMy1sZWdlbmQvbm8tZXh0ZW5kJyk7XHJcbi8vXHJcbi8vIG1vZHVsZS5leHBvcnRzLmxlZ2VuZCA9IGxlZ2VuZDtcclxuXHJcbmV4cG9ydCBjbGFzcyBMZWdlbmQge1xyXG5cclxuICAgIGNzc0NsYXNzUHJlZml4PVwib2RjLVwiO1xyXG4gICAgbGVnZW5kQ2xhc3M9dGhpcy5jc3NDbGFzc1ByZWZpeCtcImxlZ2VuZFwiO1xyXG4gICAgY29udGFpbmVyO1xyXG4gICAgc2NhbGU7XHJcbiAgICBjb2xvcj0gY29sb3I7XHJcbiAgICBzaXplID0gc2l6ZTtcclxuICAgIHN5bWJvbD0gc3ltYm9sO1xyXG4gICAgZ3VpZDtcclxuXHJcbiAgICBsYWJlbEZvcm1hdCA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihzdmcsIGxlZ2VuZFBhcmVudCwgc2NhbGUsIGxlZ2VuZFgsIGxlZ2VuZFksIGxhYmVsRm9ybWF0KXtcclxuICAgICAgICB0aGlzLnNjYWxlPXNjYWxlO1xyXG4gICAgICAgIHRoaXMuc3ZnID0gc3ZnO1xyXG4gICAgICAgIHRoaXMuZ3VpZCA9IFV0aWxzLmd1aWQoKTtcclxuICAgICAgICB0aGlzLmNvbnRhaW5lciA9ICBVdGlscy5zZWxlY3RPckFwcGVuZChsZWdlbmRQYXJlbnQsIFwiZy5cIit0aGlzLmxlZ2VuZENsYXNzLCBcImdcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIrbGVnZW5kWCtcIixcIitsZWdlbmRZK1wiKVwiKVxyXG4gICAgICAgICAgICAuY2xhc3NlZCh0aGlzLmxlZ2VuZENsYXNzLCB0cnVlKTtcclxuXHJcbiAgICAgICAgdGhpcy5sYWJlbEZvcm1hdCA9IGxhYmVsRm9ybWF0O1xyXG4gICAgfVxyXG5cclxuXHJcblxyXG4gICAgbGluZWFyR3JhZGllbnRCYXIoYmFyV2lkdGgsIGJhckhlaWdodCwgdGl0bGUpe1xyXG4gICAgICAgIHZhciBncmFkaWVudElkID0gdGhpcy5jc3NDbGFzc1ByZWZpeCtcImxpbmVhci1ncmFkaWVudFwiK1wiLVwiK3RoaXMuZ3VpZDtcclxuICAgICAgICB2YXIgc2NhbGU9IHRoaXMuc2NhbGU7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICB0aGlzLmxpbmVhckdyYWRpZW50ID0gVXRpbHMubGluZWFyR3JhZGllbnQodGhpcy5zdmcsIGdyYWRpZW50SWQsIHRoaXMuc2NhbGUucmFuZ2UoKSwgMCwgMTAwLCAwLCAwKTtcclxuXHJcbiAgICAgICAgdGhpcy5jb250YWluZXIuYXBwZW5kKFwicmVjdFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGJhcldpZHRoKVxyXG4gICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCBiYXJIZWlnaHQpXHJcbiAgICAgICAgICAgIC5hdHRyKFwieFwiLCAwKVxyXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgMClcclxuICAgICAgICAgICAgLnN0eWxlKFwiZmlsbFwiLCBcInVybCgjXCIrZ3JhZGllbnRJZCtcIilcIik7XHJcblxyXG5cclxuICAgICAgICB2YXIgdGlja3MgPSB0aGlzLmNvbnRhaW5lci5zZWxlY3RBbGwoXCJ0ZXh0XCIpXHJcbiAgICAgICAgICAgIC5kYXRhKCBzY2FsZS5kb21haW4oKSApO1xyXG4gICAgICAgIHZhciB0aWNrc051bWJlciA9c2NhbGUuZG9tYWluKCkubGVuZ3RoLTE7XHJcbiAgICAgICAgdGlja3MuZW50ZXIoKS5hcHBlbmQoXCJ0ZXh0XCIpO1xyXG5cclxuICAgICAgICB0aWNrcy5hdHRyKFwieFwiLCBiYXJXaWR0aClcclxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsICAoZCwgaSkgPT4gIGJhckhlaWdodCAtKGkqYmFySGVpZ2h0L3RpY2tzTnVtYmVyKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJkeFwiLCAzKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcImR5XCIsIDEpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiYWxpZ25tZW50LWJhc2VsaW5lXCIsIFwibWlkZGxlXCIpXHJcbiAgICAgICAgICAgIC50ZXh0KGQ9PiBzZWxmLmxhYmVsRm9ybWF0ID8gc2VsZi5sYWJlbEZvcm1hdChkKSA6IGQpO1xyXG4gICAgICAgIHRpY2tzLmF0dHIoXCJkb21pbmFudC1iYXNlbGluZVwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgIGlmKHRoaXMucm90YXRlTGFiZWxzKXtcclxuICAgICAgICAgICAgdGlja3NcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIChkLCBpKSA9PiBcInJvdGF0ZSgtNDUsIFwiICsgYmFyV2lkdGggKyBcIiwgXCIgKyAoYmFySGVpZ2h0IC0oaSpiYXJIZWlnaHQvdGlja3NOdW1iZXIpKSArIFwiKVwiKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBcInN0YXJ0XCIpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImR4XCIsIDUpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcImR5XCIsIDUpO1xyXG5cclxuICAgICAgICB9ZWxzZXtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aWNrcy5leGl0KCkucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHNldFJvdGF0ZUxhYmVscyhyb3RhdGVMYWJlbHMpIHtcclxuICAgICAgICB0aGlzLnJvdGF0ZUxhYmVscyA9IHJvdGF0ZUxhYmVscztcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBcclxufSIsImltcG9ydCB7Q2hhcnQsIENoYXJ0Q29uZmlnfSBmcm9tIFwiLi9jaGFydFwiO1xyXG5pbXBvcnQge1NjYXR0ZXJQbG90LCBTY2F0dGVyUGxvdENvbmZpZ30gZnJvbSBcIi4vc2NhdHRlcnBsb3RcIjtcclxuaW1wb3J0IHtVdGlsc30gZnJvbSAnLi91dGlscydcclxuaW1wb3J0IHtTdGF0aXN0aWNzVXRpbHN9IGZyb20gJy4vc3RhdGlzdGljcy11dGlscydcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgUmVncmVzc2lvbkNvbmZpZyBleHRlbmRzIFNjYXR0ZXJQbG90Q29uZmlne1xyXG5cclxuICAgIG1haW5SZWdyZXNzaW9uID0gdHJ1ZTtcclxuICAgIGdyb3VwUmVncmVzc2lvbiA9IHRydWU7XHJcbiAgICBjb25maWRlbmNlPXtcclxuICAgICAgICBsZXZlbDogMC45NSxcclxuICAgICAgICBjcml0aWNhbFZhbHVlOiAoZGVncmVlc09mRnJlZWRvbSwgY3JpdGljYWxQcm9iYWJpbGl0eSkgPT4gU3RhdGlzdGljc1V0aWxzLnRWYWx1ZShkZWdyZWVzT2ZGcmVlZG9tLCBjcml0aWNhbFByb2JhYmlsaXR5KSxcclxuICAgICAgICBtYXJnaW5PZkVycm9yOiB1bmRlZmluZWQgLy9jdXN0b20gIG1hcmdpbiBPZiBFcnJvciBmdW5jdGlvbiAoeCwgcG9pbnRzKVxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pe1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG4gICAgICAgIGlmKGN1c3RvbSl7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgUmVncmVzc2lvbiBleHRlbmRzIFNjYXR0ZXJQbG90e1xyXG4gICAgY29uc3RydWN0b3IocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgY29uZmlnKSB7XHJcbiAgICAgICAgc3VwZXIocGxhY2Vob2xkZXJTZWxlY3RvciwgZGF0YSwgbmV3IFJlZ3Jlc3Npb25Db25maWcoY29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Q29uZmlnKGNvbmZpZyl7XHJcbiAgICAgICAgcmV0dXJuIHN1cGVyLnNldENvbmZpZyhuZXcgUmVncmVzc2lvbkNvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpe1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdGhpcy5pbml0UmVncmVzc2lvbkxpbmVzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdFJlZ3Jlc3Npb25MaW5lcygpe1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGdyb3Vwc0F2YWlsYWJsZSA9IHNlbGYuY29uZmlnLmdyb3VwcyAmJiBzZWxmLmNvbmZpZy5ncm91cHMudmFsdWU7XHJcblxyXG4gICAgICAgIHNlbGYucGxvdC5yZWdyZXNzaW9ucz0gW107XHJcblxyXG5cclxuICAgICAgICBpZihncm91cHNBdmFpbGFibGUgJiYgc2VsZi5jb25maWcubWFpblJlZ3Jlc3Npb24pe1xyXG4gICAgICAgICAgICB2YXIgcmVncmVzc2lvbiA9IHRoaXMuaW5pdFJlZ3Jlc3Npb24odGhpcy5wbG90LmRhdGEsIGZhbHNlKTtcclxuICAgICAgICAgICAgc2VsZi5wbG90LnJlZ3Jlc3Npb25zLnB1c2gocmVncmVzc2lvbik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZihzZWxmLmNvbmZpZy5ncm91cFJlZ3Jlc3Npb24pe1xyXG4gICAgICAgICAgICB0aGlzLmluaXRHcm91cFJlZ3Jlc3Npb24oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXRHcm91cFJlZ3Jlc3Npb24oKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBkYXRhQnlHcm91cCA9IHt9O1xyXG4gICAgICAgIHRoaXMucGxvdC5kYXRhLmZvckVhY2ggKGQ9PntcclxuICAgICAgICAgICAgdmFyIGdyb3VwVmFsID0gc2VsZi5jb25maWcuZ3JvdXBzLnZhbHVlKGQsIHNlbGYuY29uZmlnLmdyb3Vwcy5rZXkpO1xyXG5cclxuICAgICAgICAgICAgaWYoIWdyb3VwVmFsICYmIGdyb3VwVmFsIT09MCl7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmKCFkYXRhQnlHcm91cFtncm91cFZhbF0pe1xyXG4gICAgICAgICAgICAgICAgZGF0YUJ5R3JvdXBbZ3JvdXBWYWxdID0gW107XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGF0YUJ5R3JvdXBbZ3JvdXBWYWxdLnB1c2goZCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGZvcih2YXIga2V5IGluIGRhdGFCeUdyb3VwKXtcclxuICAgICAgICAgICAgaWYgKCFkYXRhQnlHcm91cC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdmFyIHJlZ3Jlc3Npb24gPSB0aGlzLmluaXRSZWdyZXNzaW9uKGRhdGFCeUdyb3VwW2tleV0sIGtleSk7XHJcbiAgICAgICAgICAgIHNlbGYucGxvdC5yZWdyZXNzaW9ucy5wdXNoKHJlZ3Jlc3Npb24pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpbml0UmVncmVzc2lvbih2YWx1ZXMsIGdyb3VwVmFsKXtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgICAgIHZhciBwb2ludHMgPSB2YWx1ZXMubWFwKGQ9PntcclxuICAgICAgICAgICAgcmV0dXJuIFtwYXJzZUZsb2F0KHNlbGYucGxvdC54LnZhbHVlKGQpKSwgcGFyc2VGbG9hdChzZWxmLnBsb3QueS52YWx1ZShkKSldO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBwb2ludHMuc29ydCgoYSxiKSA9PiBhWzBdLWJbMF0pO1xyXG5cclxuICAgICAgICB2YXIgbGluZWFyUmVncmVzc2lvbiA9ICBTdGF0aXN0aWNzVXRpbHMubGluZWFyUmVncmVzc2lvbihwb2ludHMpO1xyXG4gICAgICAgIHZhciBsaW5lYXJSZWdyZXNzaW9uTGluZSA9IFN0YXRpc3RpY3NVdGlscy5saW5lYXJSZWdyZXNzaW9uTGluZShsaW5lYXJSZWdyZXNzaW9uKTtcclxuXHJcblxyXG4gICAgICAgIHZhciBleHRlbnRYID0gZDMuZXh0ZW50KHBvaW50cywgZD0+ZFswXSk7XHJcblxyXG5cclxuICAgICAgICB2YXIgbGluZVBvaW50cyA9IFtcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgeDogZXh0ZW50WFswXSxcclxuICAgICAgICAgICAgICAgIHk6IGxpbmVhclJlZ3Jlc3Npb25MaW5lKGV4dGVudFhbMF0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHg6IGV4dGVudFhbMV0sXHJcbiAgICAgICAgICAgICAgICB5OiBsaW5lYXJSZWdyZXNzaW9uTGluZShleHRlbnRYWzFdKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgXTtcclxuXHJcbiAgICAgICAgdmFyIGxpbmUgPSBkMy5zdmcubGluZSgpXHJcbiAgICAgICAgICAgIC5pbnRlcnBvbGF0ZShcImJhc2lzXCIpXHJcbiAgICAgICAgICAgIC54KGQgPT4gc2VsZi5wbG90Lnguc2NhbGUoZC54KSlcclxuICAgICAgICAgICAgLnkoZCA9PiBzZWxmLnBsb3QueS5zY2FsZShkLnkpKTtcclxuICAgICAgICBcclxuXHJcbiAgICAgICAgdmFyIGNvbG9yID0gc2VsZi5wbG90LmRvdC5jb2xvcjtcclxuXHJcbiAgICAgICAgdmFyIGRlZmF1bHRDb2xvciA9IFwiYmxhY2tcIjtcclxuICAgICAgICBpZihVdGlscy5pc0Z1bmN0aW9uKGNvbG9yKSl7XHJcbiAgICAgICAgICAgIGlmKHZhbHVlcy5sZW5ndGggJiYgZ3JvdXBWYWwhPT1mYWxzZSl7XHJcbiAgICAgICAgICAgICAgICBjb2xvciA9IGNvbG9yKHZhbHVlc1swXSk7XHJcbiAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgICAgY29sb3IgPSBkZWZhdWx0Q29sb3I7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9ZWxzZSBpZighY29sb3IgJiYgZ3JvdXBWYWw9PT1mYWxzZSl7XHJcbiAgICAgICAgICAgIGNvbG9yID0gZGVmYXVsdENvbG9yO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIHZhciBjb25maWRlbmNlID0gdGhpcy5jb21wdXRlQ29uZmlkZW5jZShwb2ludHMsIGV4dGVudFgsICBsaW5lYXJSZWdyZXNzaW9uLGxpbmVhclJlZ3Jlc3Npb25MaW5lKTtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBncm91cDogZ3JvdXBWYWwgfHwgZmFsc2UsXHJcbiAgICAgICAgICAgIGxpbmU6IGxpbmUsXHJcbiAgICAgICAgICAgIGxpbmVQb2ludHM6IGxpbmVQb2ludHMsXHJcbiAgICAgICAgICAgIGNvbG9yOiBjb2xvcixcclxuICAgICAgICAgICAgY29uZmlkZW5jZTogY29uZmlkZW5jZVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgY29tcHV0ZUNvbmZpZGVuY2UocG9pbnRzLCBleHRlbnRYLCBsaW5lYXJSZWdyZXNzaW9uLGxpbmVhclJlZ3Jlc3Npb25MaW5lKXtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHNsb3BlID0gbGluZWFyUmVncmVzc2lvbi5tO1xyXG4gICAgICAgIHZhciBuID0gcG9pbnRzLmxlbmd0aDtcclxuICAgICAgICB2YXIgZGVncmVlc09mRnJlZWRvbSA9IE1hdGgubWF4KDAsIG4tMik7XHJcblxyXG4gICAgICAgIHZhciBhbHBoYSA9IDEgLSBzZWxmLmNvbmZpZy5jb25maWRlbmNlLmxldmVsO1xyXG4gICAgICAgIHZhciBjcml0aWNhbFByb2JhYmlsaXR5ICA9IDEgLSBhbHBoYS8yO1xyXG4gICAgICAgIHZhciBjcml0aWNhbFZhbHVlID0gc2VsZi5jb25maWcuY29uZmlkZW5jZS5jcml0aWNhbFZhbHVlKGRlZ3JlZXNPZkZyZWVkb20sY3JpdGljYWxQcm9iYWJpbGl0eSk7XHJcblxyXG4gICAgICAgIHZhciB4VmFsdWVzID0gcG9pbnRzLm1hcChkPT5kWzBdKTtcclxuICAgICAgICB2YXIgbWVhblggPSBTdGF0aXN0aWNzVXRpbHMubWVhbih4VmFsdWVzKTtcclxuICAgICAgICB2YXIgeE15U3VtPTA7XHJcbiAgICAgICAgdmFyIHhTdW09MDtcclxuICAgICAgICB2YXIgeFBvd1N1bT0wO1xyXG4gICAgICAgIHZhciB5U3VtPTA7XHJcbiAgICAgICAgdmFyIHlQb3dTdW09MDtcclxuICAgICAgICBwb2ludHMuZm9yRWFjaChwPT57XHJcbiAgICAgICAgICAgIHZhciB4ID0gcFswXTtcclxuICAgICAgICAgICAgdmFyIHkgPSBwWzFdO1xyXG5cclxuICAgICAgICAgICAgeE15U3VtICs9IHgqeTtcclxuICAgICAgICAgICAgeFN1bSs9eDtcclxuICAgICAgICAgICAgeVN1bSs9eTtcclxuICAgICAgICAgICAgeFBvd1N1bSs9IHgqeDtcclxuICAgICAgICAgICAgeVBvd1N1bSs9IHkqeTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgYSA9IGxpbmVhclJlZ3Jlc3Npb24ubTtcclxuICAgICAgICB2YXIgYiA9IGxpbmVhclJlZ3Jlc3Npb24uYjtcclxuXHJcbiAgICAgICAgdmFyIFNhMiA9IG4vKG4rMikgKiAoKHlQb3dTdW0tYSp4TXlTdW0tYip5U3VtKS8obip4UG93U3VtLSh4U3VtKnhTdW0pKSk7IC8vV2FyaWFuY2phIHdzcMOzxYJjenlubmlrYSBraWVydW5rb3dlZ28gcmVncmVzamkgbGluaW93ZWogYVxyXG4gICAgICAgIHZhciBTeTIgPSAoeVBvd1N1bSAtIGEqeE15U3VtLWIqeVN1bSkvKG4qKG4tMikpOyAvL1NhMiAvL01lYW4geSB2YWx1ZSB2YXJpYW5jZVxyXG5cclxuICAgICAgICB2YXIgZXJyb3JGbiA9IHg9PiBNYXRoLnNxcnQoU3kyICsgTWF0aC5wb3coeC1tZWFuWCwyKSpTYTIpOyAvL3BpZXJ3aWFzdGVrIGt3YWRyYXRvd3kgeiB3YXJpYW5jamkgZG93b2xuZWdvIHB1bmt0dSBwcm9zdGVqXHJcbiAgICAgICAgdmFyIG1hcmdpbk9mRXJyb3IgPSAgeD0+IGNyaXRpY2FsVmFsdWUqIGVycm9yRm4oeCk7XHJcblxyXG5cclxuICAgICAgICAvLyBjb25zb2xlLmxvZygnbicsIG4sICdkZWdyZWVzT2ZGcmVlZG9tJywgZGVncmVlc09mRnJlZWRvbSwgJ2NyaXRpY2FsUHJvYmFiaWxpdHknLGNyaXRpY2FsUHJvYmFiaWxpdHkpO1xyXG4gICAgICAgIC8vIHZhciBjb25maWRlbmNlRG93biA9IHggPT4gbGluZWFyUmVncmVzc2lvbkxpbmUoeCkgLSAgbWFyZ2luT2ZFcnJvcih4KTtcclxuICAgICAgICAvLyB2YXIgY29uZmlkZW5jZVVwID0geCA9PiBsaW5lYXJSZWdyZXNzaW9uTGluZSh4KSArICBtYXJnaW5PZkVycm9yKHgpO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIGNvbXB1dGVDb25maWRlbmNlQXJlYVBvaW50ID0geD0+e1xyXG4gICAgICAgICAgICB2YXIgbGluZWFyUmVncmVzc2lvbiA9IGxpbmVhclJlZ3Jlc3Npb25MaW5lKHgpO1xyXG4gICAgICAgICAgICB2YXIgbW9lID0gbWFyZ2luT2ZFcnJvcih4KTtcclxuICAgICAgICAgICAgdmFyIGNvbmZEb3duID0gbGluZWFyUmVncmVzc2lvbiAtIG1vZTtcclxuICAgICAgICAgICAgdmFyIGNvbmZVcCA9IGxpbmVhclJlZ3Jlc3Npb24gKyBtb2U7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICB4OiB4LFxyXG4gICAgICAgICAgICAgICAgeTA6IGNvbmZEb3duLFxyXG4gICAgICAgICAgICAgICAgeTE6IGNvbmZVcFxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHZhciBjZW50ZXJYID0gKGV4dGVudFhbMV0rZXh0ZW50WFswXSkvMjtcclxuXHJcbiAgICAgICAgLy8gdmFyIGNvbmZpZGVuY2VBcmVhUG9pbnRzID0gW2V4dGVudFhbMF0sIGNlbnRlclgsICBleHRlbnRYWzFdXS5tYXAoY29tcHV0ZUNvbmZpZGVuY2VBcmVhUG9pbnQpO1xyXG4gICAgICAgIHZhciBjb25maWRlbmNlQXJlYVBvaW50cyA9IFtleHRlbnRYWzBdLCBjZW50ZXJYLCAgZXh0ZW50WFsxXV0ubWFwKGNvbXB1dGVDb25maWRlbmNlQXJlYVBvaW50KTtcclxuXHJcbiAgICAgICAgdmFyIGZpdEluUGxvdCA9IHkgPT4geTtcclxuXHJcbiAgICAgICAgdmFyIGNvbmZpZGVuY2VBcmVhID0gIGQzLnN2Zy5hcmVhKClcclxuICAgICAgICAuaW50ZXJwb2xhdGUoXCJtb25vdG9uZVwiKVxyXG4gICAgICAgICAgICAueChkID0+IHNlbGYucGxvdC54LnNjYWxlKGQueCkpXHJcbiAgICAgICAgICAgIC55MChkID0+IGZpdEluUGxvdChzZWxmLnBsb3QueS5zY2FsZShkLnkwKSkpXHJcbiAgICAgICAgICAgIC55MShkID0+IGZpdEluUGxvdChzZWxmLnBsb3QueS5zY2FsZShkLnkxKSkpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBhcmVhOmNvbmZpZGVuY2VBcmVhLFxyXG4gICAgICAgICAgICBwb2ludHM6Y29uZmlkZW5jZUFyZWFQb2ludHNcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZShuZXdEYXRhKXtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVSZWdyZXNzaW9uTGluZXMoKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIHVwZGF0ZVJlZ3Jlc3Npb25MaW5lcygpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHJlZ3Jlc3Npb25Db250YWluZXJDbGFzcyA9IHRoaXMucHJlZml4Q2xhc3MoXCJyZWdyZXNzaW9uLWNvbnRhaW5lclwiKTtcclxuICAgICAgICB2YXIgcmVncmVzc2lvbkNvbnRhaW5lclNlbGVjdG9yID0gXCJnLlwiK3JlZ3Jlc3Npb25Db250YWluZXJDbGFzcztcclxuXHJcbiAgICAgICAgdmFyIGNsaXBQYXRoSWQgPSBzZWxmLnByZWZpeENsYXNzKFwiY2xpcFwiKTtcclxuXHJcbiAgICAgICAgdmFyIHJlZ3Jlc3Npb25Db250YWluZXIgPSBzZWxmLnN2Z0cuc2VsZWN0T3JJbnNlcnQocmVncmVzc2lvbkNvbnRhaW5lclNlbGVjdG9yLCBcIi5cIitzZWxmLmRvdHNDb250YWluZXJDbGFzcyk7XHJcbiAgICAgICAgdmFyIHJlZ3Jlc3Npb25Db250YWluZXJDbGlwID0gcmVncmVzc2lvbkNvbnRhaW5lci5zZWxlY3RPckFwcGVuZChcImNsaXBQYXRoXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaWRcIiwgY2xpcFBhdGhJZCk7XHJcblxyXG5cclxuICAgICAgICByZWdyZXNzaW9uQ29udGFpbmVyQ2xpcC5zZWxlY3RPckFwcGVuZCgncmVjdCcpXHJcbiAgICAgICAgICAgIC5hdHRyKCd3aWR0aCcsIHNlbGYucGxvdC53aWR0aClcclxuICAgICAgICAgICAgLmF0dHIoJ2hlaWdodCcsIHNlbGYucGxvdC5oZWlnaHQpXHJcbiAgICAgICAgICAgIC5hdHRyKCd4JywgMClcclxuICAgICAgICAgICAgLmF0dHIoJ3knLCAwKTtcclxuXHJcbiAgICAgICAgcmVncmVzc2lvbkNvbnRhaW5lci5hdHRyKFwiY2xpcC1wYXRoXCIsIChkLGkpID0+IFwidXJsKCNcIitjbGlwUGF0aElkK1wiKVwiKTtcclxuXHJcbiAgICAgICAgdmFyIHJlZ3Jlc3Npb25DbGFzcyA9IHRoaXMucHJlZml4Q2xhc3MoXCJyZWdyZXNzaW9uXCIpO1xyXG4gICAgICAgIHZhciBjb25maWRlbmNlQXJlYUNsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImNvbmZpZGVuY2VcIik7XHJcbiAgICAgICAgdmFyIHJlZ3Jlc3Npb25TZWxlY3RvciA9IFwiZy5cIityZWdyZXNzaW9uQ2xhc3M7XHJcbiAgICAgICAgdmFyIHJlZ3Jlc3Npb24gPSByZWdyZXNzaW9uQ29udGFpbmVyLnNlbGVjdEFsbChyZWdyZXNzaW9uU2VsZWN0b3IpXHJcbiAgICAgICAgICAgIC5kYXRhKHNlbGYucGxvdC5yZWdyZXNzaW9ucywgKGQsaSk9PiBkLmdyb3VwKTtcclxuXHJcbiAgICAgICAgdmFyIHJlZ3Jlc3Npb25FbnRlckcgPSByZWdyZXNzaW9uLmVudGVyKCkuaW5zZXJ0U2VsZWN0b3IocmVncmVzc2lvblNlbGVjdG9yKTtcclxuICAgICAgICB2YXIgbGluZUNsYXNzID0gc2VsZi5wcmVmaXhDbGFzcyhcImxpbmVcIik7XHJcbiAgICAgICAgcmVncmVzc2lvbkVudGVyR1xyXG5cclxuICAgICAgICAgICAgLmFwcGVuZChcInBhdGhcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBsaW5lQ2xhc3MpXHJcbiAgICAgICAgICAgIC5hdHRyKFwic2hhcGUtcmVuZGVyaW5nXCIsIFwib3B0aW1pemVRdWFsaXR5XCIpO1xyXG4gICAgICAgICAgICAvLyAuYXBwZW5kKFwibGluZVwiKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcImNsYXNzXCIsIFwibGluZVwiKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcInNoYXBlLXJlbmRlcmluZ1wiLCBcIm9wdGltaXplUXVhbGl0eVwiKTtcclxuXHJcbiAgICAgICAgdmFyIGxpbmUgPSByZWdyZXNzaW9uLnNlbGVjdChcInBhdGguXCIrbGluZUNsYXNzKVxyXG4gICAgICAgICAgICAuc3R5bGUoXCJzdHJva2VcIiwgciA9PiByLmNvbG9yKTtcclxuICAgICAgICAvLyAuYXR0cihcIngxXCIsIHI9PiBzZWxmLnBsb3QueC5zY2FsZShyLmxpbmVQb2ludHNbMF0ueCkpXHJcbiAgICAgICAgICAgIC8vIC5hdHRyKFwieTFcIiwgcj0+IHNlbGYucGxvdC55LnNjYWxlKHIubGluZVBvaW50c1swXS55KSlcclxuICAgICAgICAgICAgLy8gLmF0dHIoXCJ4MlwiLCByPT4gc2VsZi5wbG90Lnguc2NhbGUoci5saW5lUG9pbnRzWzFdLngpKVxyXG4gICAgICAgICAgICAvLyAuYXR0cihcInkyXCIsIHI9PiBzZWxmLnBsb3QueS5zY2FsZShyLmxpbmVQb2ludHNbMV0ueSkpXHJcblxyXG5cclxuICAgICAgICB2YXIgbGluZVQgPSBsaW5lO1xyXG4gICAgICAgIGlmIChzZWxmLnRyYW5zaXRpb25FbmFibGVkKCkpIHtcclxuICAgICAgICAgICAgbGluZVQgPSBsaW5lLnRyYW5zaXRpb24oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxpbmVULmF0dHIoXCJkXCIsIHIgPT4gci5saW5lKHIubGluZVBvaW50cykpXHJcblxyXG5cclxuICAgICAgICByZWdyZXNzaW9uRW50ZXJHXHJcbiAgICAgICAgICAgIC5hcHBlbmQoXCJwYXRoXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgY29uZmlkZW5jZUFyZWFDbGFzcylcclxuICAgICAgICAgICAgLmF0dHIoXCJzaGFwZS1yZW5kZXJpbmdcIiwgXCJvcHRpbWl6ZVF1YWxpdHlcIilcclxuICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCBcIjAuNFwiKTtcclxuXHJcblxyXG5cclxuICAgICAgICB2YXIgYXJlYSA9IHJlZ3Jlc3Npb24uc2VsZWN0KFwicGF0aC5cIitjb25maWRlbmNlQXJlYUNsYXNzKTtcclxuXHJcbiAgICAgICAgdmFyIGFyZWFUID0gYXJlYTtcclxuICAgICAgICBpZiAoc2VsZi50cmFuc2l0aW9uRW5hYmxlZCgpKSB7XHJcbiAgICAgICAgICAgIGFyZWFUID0gYXJlYS50cmFuc2l0aW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGFyZWFULmF0dHIoXCJkXCIsIHIgPT4gci5jb25maWRlbmNlLmFyZWEoci5jb25maWRlbmNlLnBvaW50cykpO1xyXG4gICAgICAgIGFyZWFULnN0eWxlKFwiZmlsbFwiLCByID0+IHIuY29sb3IpXHJcbiAgICAgICAgcmVncmVzc2lvbi5leGl0KCkucmVtb3ZlKCk7XHJcblxyXG4gICAgfVxyXG5cclxuXHJcblxyXG59XHJcblxyXG4iLCJpbXBvcnQge0NoYXJ0LCBDaGFydENvbmZpZ30gZnJvbSBcIi4vY2hhcnRcIjtcclxuaW1wb3J0IHtTY2F0dGVyUGxvdENvbmZpZ30gZnJvbSBcIi4vc2NhdHRlcnBsb3RcIjtcclxuaW1wb3J0IHtVdGlsc30gZnJvbSAnLi91dGlscydcclxuaW1wb3J0IHtMZWdlbmR9IGZyb20gXCIuL2xlZ2VuZFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNjYXR0ZXJQbG90TWF0cml4Q29uZmlnIGV4dGVuZHMgU2NhdHRlclBsb3RDb25maWd7XHJcblxyXG4gICAgc3ZnQ2xhc3M9IHRoaXMuY3NzQ2xhc3NQcmVmaXgrJ3NjYXR0ZXJwbG90LW1hdHJpeCc7XHJcbiAgICBzaXplPSAyMDA7IC8vc2NhdHRlciBwbG90IGNlbGwgc2l6ZVxyXG4gICAgcGFkZGluZz0gMjA7IC8vc2NhdHRlciBwbG90IGNlbGwgcGFkZGluZ1xyXG4gICAgYnJ1c2g9IHRydWU7XHJcbiAgICBndWlkZXM9IHRydWU7IC8vc2hvdyBheGlzIGd1aWRlc1xyXG4gICAgc2hvd1Rvb2x0aXA9IHRydWU7IC8vc2hvdyB0b29sdGlwIG9uIGRvdCBob3ZlclxyXG4gICAgdGlja3M9IHVuZGVmaW5lZDsgLy90aWNrcyBudW1iZXIsIChkZWZhdWx0OiBjb21wdXRlZCB1c2luZyBjZWxsIHNpemUpXHJcbiAgICB4PXsvLyBYIGF4aXMgY29uZmlnXHJcbiAgICAgICAgb3JpZW50OiBcImJvdHRvbVwiLFxyXG4gICAgICAgIHNjYWxlOiBcImxpbmVhclwiXHJcbiAgICB9O1xyXG4gICAgeT17Ly8gWSBheGlzIGNvbmZpZ1xyXG4gICAgICAgIG9yaWVudDogXCJsZWZ0XCIsXHJcbiAgICAgICAgc2NhbGU6IFwibGluZWFyXCJcclxuICAgIH07XHJcbiAgICBncm91cHM9e1xyXG4gICAgICAgIGtleTogdW5kZWZpbmVkLCAvL29iamVjdCBwcm9wZXJ0eSBuYW1lIG9yIGFycmF5IGluZGV4IHdpdGggZ3JvdXBpbmcgdmFyaWFibGVcclxuICAgICAgICBpbmNsdWRlSW5QbG90OiBmYWxzZSwgLy9pbmNsdWRlIGdyb3VwIGFzIHZhcmlhYmxlIGluIHBsb3QsIGJvb2xlYW4gKGRlZmF1bHQ6IGZhbHNlKVxyXG4gICAgICAgIHZhbHVlOiAoZCwga2V5KSA9PiBkW2tleV0sIC8vIGdyb3VwaW5nIHZhbHVlIGFjY2Vzc29yLFxyXG4gICAgICAgIGxhYmVsOiBcIlwiXHJcbiAgICB9O1xyXG4gICAgdmFyaWFibGVzPSB7XHJcbiAgICAgICAgbGFiZWxzOiBbXSwgLy9vcHRpb25hbCBhcnJheSBvZiB2YXJpYWJsZSBsYWJlbHMgKGZvciB0aGUgZGlhZ29uYWwgb2YgdGhlIHBsb3QpLlxyXG4gICAgICAgIGtleXM6IFtdLCAvL29wdGlvbmFsIGFycmF5IG9mIHZhcmlhYmxlIGtleXNcclxuICAgICAgICB2YWx1ZTogKGQsIHZhcmlhYmxlS2V5KSA9PiBkW3ZhcmlhYmxlS2V5XSAvLyB2YXJpYWJsZSB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihjdXN0b20pe1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgVXRpbHMuZGVlcEV4dGVuZCh0aGlzLCBjdXN0b20pO1xyXG4gICAgfVxyXG5cclxuXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBTY2F0dGVyUGxvdE1hdHJpeCBleHRlbmRzIENoYXJ0IHtcclxuICAgIGNvbnN0cnVjdG9yKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIGNvbmZpZykge1xyXG4gICAgICAgIHN1cGVyKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIG5ldyBTY2F0dGVyUGxvdE1hdHJpeENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRDb25maWcoY29uZmlnKSB7XHJcbiAgICAgICAgcmV0dXJuIHN1cGVyLnNldENvbmZpZyhuZXcgU2NhdHRlclBsb3RNYXRyaXhDb25maWcoY29uZmlnKSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXRQbG90KCkge1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcblxyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgbWFyZ2luID0gdGhpcy5wbG90Lm1hcmdpbjtcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnO1xyXG4gICAgICAgIHRoaXMucGxvdC54PXt9O1xyXG4gICAgICAgIHRoaXMucGxvdC55PXt9O1xyXG4gICAgICAgIHRoaXMucGxvdC5kb3Q9e1xyXG4gICAgICAgICAgICBjb2xvcjogbnVsbC8vY29sb3Igc2NhbGUgbWFwcGluZyBmdW5jdGlvblxyXG4gICAgICAgIH07XHJcblxyXG5cclxuICAgICAgICB0aGlzLnBsb3Quc2hvd0xlZ2VuZCA9IGNvbmYuc2hvd0xlZ2VuZDtcclxuICAgICAgICBpZih0aGlzLnBsb3Quc2hvd0xlZ2VuZCl7XHJcbiAgICAgICAgICAgIG1hcmdpbi5yaWdodCA9IGNvbmYubWFyZ2luLnJpZ2h0ICsgY29uZi5sZWdlbmQud2lkdGgrY29uZi5sZWdlbmQubWFyZ2luKjI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnNldHVwR3JvdXBzKCk7XHJcblxyXG4gICAgICAgIHRoaXMucGxvdC5kYXRhID0gdGhpcy5nZXREYXRhVG9QbG90KCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cFZhcmlhYmxlcygpO1xyXG5cclxuICAgICAgICB0aGlzLnBsb3Quc2l6ZSA9IGNvbmYuc2l6ZTtcclxuXHJcblxyXG4gICAgICAgIHZhciB3aWR0aCA9IGNvbmYud2lkdGg7XHJcbiAgICAgICAgdmFyIGJvdW5kaW5nQ2xpZW50UmVjdCA9IHRoaXMuZ2V0QmFzZUNvbnRhaW5lck5vZGUoKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICBpZiAoIXdpZHRoKSB7XHJcbiAgICAgICAgICAgIHZhciBtYXhXaWR0aCA9IG1hcmdpbi5sZWZ0ICsgbWFyZ2luLnJpZ2h0ICsgdGhpcy5wbG90LnZhcmlhYmxlcy5sZW5ndGgqdGhpcy5wbG90LnNpemU7XHJcbiAgICAgICAgICAgIHdpZHRoID0gTWF0aC5taW4oYm91bmRpbmdDbGllbnRSZWN0LndpZHRoLCBtYXhXaWR0aCk7XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaGVpZ2h0ID0gd2lkdGg7XHJcbiAgICAgICAgaWYgKCFoZWlnaHQpIHtcclxuICAgICAgICAgICAgaGVpZ2h0ID0gYm91bmRpbmdDbGllbnRSZWN0LmhlaWdodDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucGxvdC53aWR0aCA9IHdpZHRoIC0gbWFyZ2luLmxlZnQgLSBtYXJnaW4ucmlnaHQ7XHJcbiAgICAgICAgdGhpcy5wbG90LmhlaWdodCA9IGhlaWdodCAtIG1hcmdpbi50b3AgLSBtYXJnaW4uYm90dG9tO1xyXG5cclxuXHJcblxyXG5cclxuICAgICAgICBpZihjb25mLnRpY2tzPT09dW5kZWZpbmVkKXtcclxuICAgICAgICAgICAgY29uZi50aWNrcyA9IHRoaXMucGxvdC5zaXplIC8gNDA7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcblxyXG4gICAgICAgIHRoaXMuc2V0dXBYKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cFkoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBzZXR1cEdyb3VwcygpIHtcclxuICAgICAgICB2YXIgc2VsZj10aGlzO1xyXG4gICAgICAgIHZhciBjb25mID0gdGhpcy5jb25maWc7XHJcbiAgICAgICAgdGhpcy5wbG90Lmdyb3VwVmFsdWUgPSBkID0+IGNvbmYuZ3JvdXBzLnZhbHVlKGQsIGNvbmYuZ3JvdXBzLmtleSk7XHJcbiAgICAgICAgaWYoY29uZi5kb3QuZDNDb2xvckNhdGVnb3J5KXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmRvdC5jb2xvckNhdGVnb3J5ID0gZDMuc2NhbGVbY29uZi5kb3QuZDNDb2xvckNhdGVnb3J5XSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgY29sb3JWYWx1ZSA9IGNvbmYuZG90LmNvbG9yO1xyXG4gICAgICAgIGlmKGNvbG9yVmFsdWUpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuZG90LmNvbG9yVmFsdWUgPSBjb2xvclZhbHVlO1xyXG5cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBjb2xvclZhbHVlID09PSAnc3RyaW5nJyB8fCBjb2xvclZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKXtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxvdC5kb3QuY29sb3IgPSBjb2xvclZhbHVlO1xyXG4gICAgICAgICAgICB9ZWxzZSBpZih0aGlzLnBsb3QuZG90LmNvbG9yQ2F0ZWdvcnkpe1xyXG4gICAgICAgICAgICAgICAgdmFyIGRvbWFpbiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGQzLm1hcCh0aGlzLmRhdGEsIGQgPT4gc2VsZi5wbG90LmRvdC5jb2xvclZhbHVlLmNhbGwoc2VsZixkKSlbJ18nXSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnBsb3QuZG90LmNvbG9yQ2F0ZWdvcnkuZG9tYWluKGRvbWFpbik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuZG90LmNvbG9yID0gZCA9PiAgc2VsZi5wbG90LmRvdC5jb2xvckNhdGVnb3J5KHNlbGYucGxvdC5kb3QuY29sb3JWYWx1ZS5jYWxsKHNlbGYsZCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldERhdGFUb1Bsb3QoKXtcclxuICAgICAgICBpZighdGhpcy5lbmFibGVkR3JvdXBzKXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBmaWx0ZXIgPSB0aGlzLmRhdGEuZmlsdGVyKGQgPT4gdGhpcy5lbmFibGVkR3JvdXBzLmluZGV4T2YodGhpcy5wbG90Lmdyb3VwVmFsdWUoZCkpPi0xKTtcclxuICAgICAgICBjb25zb2xlLmxvZyhmaWx0ZXIubGVuZ3RoKTtcclxuICAgICAgICByZXR1cm4gZmlsdGVyO1xyXG4gICAgfVxyXG5cclxuICAgIHNldHVwVmFyaWFibGVzKCkge1xyXG4gICAgICAgIHZhciB2YXJpYWJsZXNDb25mID0gdGhpcy5jb25maWcudmFyaWFibGVzO1xyXG5cclxuICAgICAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YTtcclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICBwbG90LmRvbWFpbkJ5VmFyaWFibGUgPSB7fTtcclxuICAgICAgICBwbG90LnZhcmlhYmxlcyA9IHZhcmlhYmxlc0NvbmYua2V5cztcclxuICAgICAgICBpZighcGxvdC52YXJpYWJsZXMgfHwgIXBsb3QudmFyaWFibGVzLmxlbmd0aCl7XHJcbiAgICAgICAgICAgIHBsb3QudmFyaWFibGVzID0gVXRpbHMuaW5mZXJWYXJpYWJsZXMoZGF0YSwgdGhpcy5jb25maWcuZ3JvdXBzLmtleSwgdGhpcy5jb25maWcuaW5jbHVkZUluUGxvdCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwbG90LmxhYmVscyA9IFtdO1xyXG4gICAgICAgIHBsb3QubGFiZWxCeVZhcmlhYmxlID0ge307XHJcbiAgICAgICAgcGxvdC52YXJpYWJsZXMuZm9yRWFjaCgodmFyaWFibGVLZXksIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgIHBsb3QuZG9tYWluQnlWYXJpYWJsZVt2YXJpYWJsZUtleV0gPSBkMy5leHRlbnQoZGF0YSwgZnVuY3Rpb24oZCkgeyByZXR1cm4gdmFyaWFibGVzQ29uZi52YWx1ZShkLCB2YXJpYWJsZUtleSkgfSk7XHJcbiAgICAgICAgICAgIHZhciBsYWJlbCA9IHZhcmlhYmxlS2V5O1xyXG4gICAgICAgICAgICBpZih2YXJpYWJsZXNDb25mLmxhYmVscyAmJiB2YXJpYWJsZXNDb25mLmxhYmVscy5sZW5ndGg+aW5kZXgpe1xyXG5cclxuICAgICAgICAgICAgICAgIGxhYmVsID0gdmFyaWFibGVzQ29uZi5sYWJlbHNbaW5kZXhdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBsb3QubGFiZWxzLnB1c2gobGFiZWwpO1xyXG4gICAgICAgICAgICBwbG90LmxhYmVsQnlWYXJpYWJsZVt2YXJpYWJsZUtleV0gPSBsYWJlbDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgY29uc29sZS5sb2cocGxvdC5sYWJlbEJ5VmFyaWFibGUpO1xyXG5cclxuICAgICAgICBwbG90LnN1YnBsb3RzID0gW107XHJcbiAgICB9O1xyXG5cclxuICAgIHNldHVwWCgpIHtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIHggPSBwbG90Lng7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgeC52YWx1ZSA9IGNvbmYudmFyaWFibGVzLnZhbHVlO1xyXG4gICAgICAgIHguc2NhbGUgPSBkMy5zY2FsZVtjb25mLnguc2NhbGVdKCkucmFuZ2UoW2NvbmYucGFkZGluZyAvIDIsIHBsb3Quc2l6ZSAtIGNvbmYucGFkZGluZyAvIDJdKTtcclxuICAgICAgICB4Lm1hcCA9IChkLCB2YXJpYWJsZSkgPT4geC5zY2FsZSh4LnZhbHVlKGQsIHZhcmlhYmxlKSk7XHJcbiAgICAgICAgeC5heGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh4LnNjYWxlKS5vcmllbnQoY29uZi54Lm9yaWVudCkudGlja3MoY29uZi50aWNrcyk7XHJcbiAgICAgICAgeC5heGlzLnRpY2tTaXplKHBsb3Quc2l6ZSAqIHBsb3QudmFyaWFibGVzLmxlbmd0aCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBzZXR1cFkoKSB7XHJcblxyXG4gICAgICAgIHZhciBwbG90ID0gdGhpcy5wbG90O1xyXG4gICAgICAgIHZhciB5ID0gcGxvdC55O1xyXG4gICAgICAgIHZhciBjb25mID0gdGhpcy5jb25maWc7XHJcblxyXG4gICAgICAgIHkudmFsdWUgPSBjb25mLnZhcmlhYmxlcy52YWx1ZTtcclxuICAgICAgICB5LnNjYWxlID0gZDMuc2NhbGVbY29uZi55LnNjYWxlXSgpLnJhbmdlKFsgcGxvdC5zaXplIC0gY29uZi5wYWRkaW5nIC8gMiwgY29uZi5wYWRkaW5nIC8gMl0pO1xyXG4gICAgICAgIHkubWFwID0gKGQsIHZhcmlhYmxlKSA9PiB5LnNjYWxlKHkudmFsdWUoZCwgdmFyaWFibGUpKTtcclxuICAgICAgICB5LmF4aXM9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeS5zY2FsZSkub3JpZW50KGNvbmYueS5vcmllbnQpLnRpY2tzKGNvbmYudGlja3MpO1xyXG4gICAgICAgIHkuYXhpcy50aWNrU2l6ZSgtcGxvdC5zaXplICogcGxvdC52YXJpYWJsZXMubGVuZ3RoKTtcclxuICAgIH07XHJcblxyXG4gICAgdXBkYXRlKCBuZXdEYXRhKSB7XHJcbiAgICAgICAgc3VwZXIudXBkYXRlKG5ld0RhdGEpO1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9dGhpcztcclxuICAgICAgICB2YXIgbiA9IHNlbGYucGxvdC52YXJpYWJsZXMubGVuZ3RoO1xyXG4gICAgICAgIHZhciBjb25mID0gdGhpcy5jb25maWc7XHJcblxyXG4gICAgICAgIHZhciBheGlzQ2xhc3MgPSBzZWxmLnByZWZpeENsYXNzKFwiYXhpc1wiKTtcclxuICAgICAgICB2YXIgYXhpc1hDbGFzcyA9IGF4aXNDbGFzcytcIi14XCI7XHJcbiAgICAgICAgdmFyIGF4aXNZQ2xhc3MgPSBheGlzQ2xhc3MrXCIteVwiO1xyXG5cclxuICAgICAgICB2YXIgeEF4aXNTZWxlY3RvciA9IFwiZy5cIitheGlzWENsYXNzK1wiLlwiK2F4aXNDbGFzcztcclxuICAgICAgICB2YXIgeUF4aXNTZWxlY3RvciA9IFwiZy5cIitheGlzWUNsYXNzK1wiLlwiK2F4aXNDbGFzcztcclxuXHJcbiAgICAgICAgdmFyIG5vR3VpZGVzQ2xhc3MgPSBzZWxmLnByZWZpeENsYXNzKFwibm8tZ3VpZGVzXCIpO1xyXG4gICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RBbGwoeEF4aXNTZWxlY3RvcilcclxuICAgICAgICAgICAgLmRhdGEoc2VsZi5wbG90LnZhcmlhYmxlcylcclxuICAgICAgICAgICAgLmVudGVyKCkuYXBwZW5kU2VsZWN0b3IoeEF4aXNTZWxlY3RvcilcclxuICAgICAgICAgICAgLmNsYXNzZWQobm9HdWlkZXNDbGFzcywgIWNvbmYuZ3VpZGVzKVxyXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCAoZCwgaSkgPT4gXCJ0cmFuc2xhdGUoXCIgKyAobiAtIGkgLSAxKSAqIHNlbGYucGxvdC5zaXplICsgXCIsMClcIilcclxuICAgICAgICAgICAgLmVhY2goZnVuY3Rpb24oZCkgeyBzZWxmLnBsb3QueC5zY2FsZS5kb21haW4oc2VsZi5wbG90LmRvbWFpbkJ5VmFyaWFibGVbZF0pOyBkMy5zZWxlY3QodGhpcykuY2FsbChzZWxmLnBsb3QueC5heGlzKTsgfSk7XHJcblxyXG4gICAgICAgIHNlbGYuc3ZnRy5zZWxlY3RBbGwoeUF4aXNTZWxlY3RvcilcclxuICAgICAgICAgICAgLmRhdGEoc2VsZi5wbG90LnZhcmlhYmxlcylcclxuICAgICAgICAgICAgLmVudGVyKCkuYXBwZW5kU2VsZWN0b3IoeUF4aXNTZWxlY3RvcilcclxuICAgICAgICAgICAgLmNsYXNzZWQobm9HdWlkZXNDbGFzcywgIWNvbmYuZ3VpZGVzKVxyXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCAoZCwgaSkgPT4gXCJ0cmFuc2xhdGUoMCxcIiArIGkgKiBzZWxmLnBsb3Quc2l6ZSArIFwiKVwiKVxyXG4gICAgICAgICAgICAuZWFjaChmdW5jdGlvbihkKSB7IHNlbGYucGxvdC55LnNjYWxlLmRvbWFpbihzZWxmLnBsb3QuZG9tYWluQnlWYXJpYWJsZVtkXSk7IGQzLnNlbGVjdCh0aGlzKS5jYWxsKHNlbGYucGxvdC55LmF4aXMpOyB9KTtcclxuXHJcbiAgICAgICAgdmFyIGNlbGxDbGFzcyA9ICBzZWxmLnByZWZpeENsYXNzKFwiY2VsbFwiKTtcclxuICAgICAgICB2YXIgY2VsbCA9IHNlbGYuc3ZnRy5zZWxlY3RBbGwoXCIuXCIrY2VsbENsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShzZWxmLnV0aWxzLmNyb3NzKHNlbGYucGxvdC52YXJpYWJsZXMsIHNlbGYucGxvdC52YXJpYWJsZXMpKTtcclxuXHJcbiAgICAgICAgY2VsbC5lbnRlcigpLmFwcGVuZFNlbGVjdG9yKFwiZy5cIitjZWxsQ2xhc3MpLmZpbHRlcihkID0+IGQuaSA9PT0gZC5qKVxyXG4gICAgICAgICAgICAuYXBwZW5kKFwidGV4dFwiKTtcclxuXHJcbiAgICAgICAgY2VsbC5hdHRyKFwidHJhbnNmb3JtXCIsIGQgPT4gXCJ0cmFuc2xhdGUoXCIgKyAobiAtIGQuaSAtIDEpICogc2VsZi5wbG90LnNpemUgKyBcIixcIiArIGQuaiAqIHNlbGYucGxvdC5zaXplICsgXCIpXCIpO1xyXG5cclxuICAgICAgICBpZihjb25mLmJydXNoKXtcclxuICAgICAgICAgICAgdGhpcy5kcmF3QnJ1c2goY2VsbCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjZWxsLmVhY2gocGxvdFN1YnBsb3QpO1xyXG5cclxuICAgICAgICAvL0xhYmVsc1xyXG4gICAgICAgIGNlbGwuc2VsZWN0KFwidGV4dFwiKVxyXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgY29uZi5wYWRkaW5nKVxyXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgY29uZi5wYWRkaW5nKVxyXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIFwiLjcxZW1cIilcclxuICAgICAgICAgICAgLnRleHQoIGQgPT4gc2VsZi5wbG90LmxhYmVsQnlWYXJpYWJsZVtkLnhdKTtcclxuXHJcblxyXG5cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcGxvdFN1YnBsb3QocCkge1xyXG4gICAgICAgICAgICB2YXIgcGxvdCA9IHNlbGYucGxvdDtcclxuICAgICAgICAgICAgcGxvdC5zdWJwbG90cy5wdXNoKHApO1xyXG4gICAgICAgICAgICB2YXIgY2VsbCA9IGQzLnNlbGVjdCh0aGlzKTtcclxuXHJcbiAgICAgICAgICAgIHBsb3QueC5zY2FsZS5kb21haW4ocGxvdC5kb21haW5CeVZhcmlhYmxlW3AueF0pO1xyXG4gICAgICAgICAgICBwbG90Lnkuc2NhbGUuZG9tYWluKHBsb3QuZG9tYWluQnlWYXJpYWJsZVtwLnldKTtcclxuXHJcbiAgICAgICAgICAgIHZhciBmcmFtZUNsYXNzID0gIHNlbGYucHJlZml4Q2xhc3MoXCJmcmFtZVwiKTtcclxuICAgICAgICAgICAgY2VsbC5zZWxlY3RPckFwcGVuZChcInJlY3QuXCIrZnJhbWVDbGFzcylcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgZnJhbWVDbGFzcylcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwieFwiLCBjb25mLnBhZGRpbmcgLyAyKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIGNvbmYucGFkZGluZyAvIDIpXHJcbiAgICAgICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGNvbmYuc2l6ZSAtIGNvbmYucGFkZGluZylcclxuICAgICAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGNvbmYuc2l6ZSAtIGNvbmYucGFkZGluZyk7XHJcblxyXG5cclxuICAgICAgICAgICAgcC51cGRhdGUgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgc3VicGxvdCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICB2YXIgZG90cyA9IGNlbGwuc2VsZWN0QWxsKFwiY2lyY2xlXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgLmRhdGEoc2VsZi5wbG90LmRhdGEpO1xyXG5cclxuICAgICAgICAgICAgICAgIGRvdHMuZW50ZXIoKS5hcHBlbmQoXCJjaXJjbGVcIik7XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIGRvdHNUID0gZG90cztcclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLnRyYW5zaXRpb25FbmFibGVkKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBkb3RzVCA9IGRvdHMudHJhbnNpdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGRvdHNULmF0dHIoXCJjeFwiLCAoZCkgPT4gcGxvdC54Lm1hcChkLCBzdWJwbG90LngpKVxyXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKFwiY3lcIiwgKGQpID0+IHBsb3QueS5tYXAoZCwgc3VicGxvdC55KSlcclxuICAgICAgICAgICAgICAgICAgICAuYXR0cihcInJcIiwgc2VsZi5jb25maWcuZG90LnJhZGl1cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHBsb3QuZG90LmNvbG9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZG90c1Quc3R5bGUoXCJmaWxsXCIsIHBsb3QuZG90LmNvbG9yKVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmKHBsb3QudG9vbHRpcCl7XHJcbiAgICAgICAgICAgICAgICAgICAgZG90cy5vbihcIm1vdXNlb3ZlclwiLCAoZCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbG90LnRvb2x0aXAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oMjAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAuOSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBodG1sID0gXCIoXCIgKyBwbG90LngudmFsdWUoZCwgc3VicGxvdC54KSArIFwiLCBcIiArcGxvdC55LnZhbHVlKGQsIHN1YnBsb3QueSkgKyBcIilcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLmh0bWwoaHRtbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdHlsZShcImxlZnRcIiwgKGQzLmV2ZW50LnBhZ2VYICsgNSkgKyBcInB4XCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgKGQzLmV2ZW50LnBhZ2VZIC0gMjgpICsgXCJweFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBncm91cCA9IHNlbGYuY29uZmlnLmdyb3VwcyA/IHNlbGYuY29uZmlnLmdyb3Vwcy52YWx1ZShkKSA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihncm91cCB8fCBncm91cD09PTAgKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwrPVwiPGJyLz5cIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYWJlbCA9IHNlbGYuY29uZmlnLmdyb3Vwcy5sYWJlbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxhYmVsKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sKz1sYWJlbCtcIjogXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sKz1ncm91cFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGh0bWwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJsZWZ0XCIsIChkMy5ldmVudC5wYWdlWCArIDUpICsgXCJweFwiKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwidG9wXCIsIChkMy5ldmVudC5wYWdlWSAtIDI4KSArIFwicHhcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgLm9uKFwibW91c2VvdXRcIiwgKGQpPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdC50b29sdGlwLnRyYW5zaXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbig1MDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZG90cy5leGl0KCkucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHAudXBkYXRlKCk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlTGVnZW5kKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIGRyYXdCcnVzaChjZWxsKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBicnVzaCA9IGQzLnN2Zy5icnVzaCgpXHJcbiAgICAgICAgICAgIC54KHNlbGYucGxvdC54LnNjYWxlKVxyXG4gICAgICAgICAgICAueShzZWxmLnBsb3QueS5zY2FsZSlcclxuICAgICAgICAgICAgLm9uKFwiYnJ1c2hzdGFydFwiLCBicnVzaHN0YXJ0KVxyXG4gICAgICAgICAgICAub24oXCJicnVzaFwiLCBicnVzaG1vdmUpXHJcbiAgICAgICAgICAgIC5vbihcImJydXNoZW5kXCIsIGJydXNoZW5kKTtcclxuXHJcbiAgICAgICAgY2VsbC5hcHBlbmQoXCJnXCIpLmNhbGwoYnJ1c2gpO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIGJydXNoQ2VsbDtcclxuXHJcbiAgICAgICAgLy8gQ2xlYXIgdGhlIHByZXZpb3VzbHktYWN0aXZlIGJydXNoLCBpZiBhbnkuXHJcbiAgICAgICAgZnVuY3Rpb24gYnJ1c2hzdGFydChwKSB7XHJcbiAgICAgICAgICAgIGlmIChicnVzaENlbGwgIT09IHRoaXMpIHtcclxuICAgICAgICAgICAgICAgIGQzLnNlbGVjdChicnVzaENlbGwpLmNhbGwoYnJ1c2guY2xlYXIoKSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnBsb3QueC5zY2FsZS5kb21haW4oc2VsZi5wbG90LmRvbWFpbkJ5VmFyaWFibGVbcC54XSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnBsb3QueS5zY2FsZS5kb21haW4oc2VsZi5wbG90LmRvbWFpbkJ5VmFyaWFibGVbcC55XSk7XHJcbiAgICAgICAgICAgICAgICBicnVzaENlbGwgPSB0aGlzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBIaWdobGlnaHQgdGhlIHNlbGVjdGVkIGNpcmNsZXMuXHJcbiAgICAgICAgZnVuY3Rpb24gYnJ1c2htb3ZlKHApIHtcclxuICAgICAgICAgICAgdmFyIGUgPSBicnVzaC5leHRlbnQoKTtcclxuICAgICAgICAgICAgc2VsZi5zdmdHLnNlbGVjdEFsbChcImNpcmNsZVwiKS5jbGFzc2VkKFwiaGlkZGVuXCIsIGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZVswXVswXSA+IGRbcC54XSB8fCBkW3AueF0gPiBlWzFdWzBdXHJcbiAgICAgICAgICAgICAgICAgICAgfHwgZVswXVsxXSA+IGRbcC55XSB8fCBkW3AueV0gPiBlWzFdWzFdO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gSWYgdGhlIGJydXNoIGlzIGVtcHR5LCBzZWxlY3QgYWxsIGNpcmNsZXMuXHJcbiAgICAgICAgZnVuY3Rpb24gYnJ1c2hlbmQoKSB7XHJcbiAgICAgICAgICAgIGlmIChicnVzaC5lbXB0eSgpKSBzZWxmLnN2Z0cuc2VsZWN0QWxsKFwiLmhpZGRlblwiKS5jbGFzc2VkKFwiaGlkZGVuXCIsIGZhbHNlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHVwZGF0ZUxlZ2VuZCgpIHtcclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPXRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcblxyXG4gICAgICAgIHZhciBzY2FsZSA9IHBsb3QuZG90LmNvbG9yQ2F0ZWdvcnk7XHJcblxyXG5cclxuXHJcbiAgICAgICAgaWYoIXNjYWxlLmRvbWFpbigpIHx8IHNjYWxlLmRvbWFpbigpLmxlbmd0aDwyKXtcclxuICAgICAgICAgICAgcGxvdC5zaG93TGVnZW5kID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZighcGxvdC5zaG93TGVnZW5kKXtcclxuICAgICAgICAgICAgaWYocGxvdC5sZWdlbmQgJiYgcGxvdC5sZWdlbmQuY29udGFpbmVyKXtcclxuICAgICAgICAgICAgICAgIHBsb3QubGVnZW5kLmNvbnRhaW5lci5yZW1vdmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgdmFyIGxlZ2VuZFggPSB0aGlzLnBsb3Qud2lkdGggKyB0aGlzLmNvbmZpZy5sZWdlbmQubWFyZ2luO1xyXG4gICAgICAgIHZhciBsZWdlbmRZID0gdGhpcy5jb25maWcubGVnZW5kLm1hcmdpbjtcclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmQgPSBuZXcgTGVnZW5kKHRoaXMuc3ZnLCB0aGlzLnN2Z0csIHNjYWxlLCBsZWdlbmRYLCBsZWdlbmRZKTtcclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmRDb2xvciA9IHBsb3QubGVnZW5kLmNvbG9yKClcclxuICAgICAgICAgICAgLnNoYXBlV2lkdGgodGhpcy5jb25maWcubGVnZW5kLnNoYXBlV2lkdGgpXHJcbiAgICAgICAgICAgIC5vcmllbnQoJ3ZlcnRpY2FsJylcclxuICAgICAgICAgICAgLnNjYWxlKHNjYWxlKTtcclxuXHJcblxyXG4gICAgICAgIHBsb3QubGVnZW5kQ29sb3Iub24oJ2NlbGxjbGljaycsIGM9PiBzZWxmLm9uTGVnZW5kQ2VsbENsaWNrKGMpKTtcclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmQuY29udGFpbmVyXHJcbiAgICAgICAgICAgIC5jYWxsKHBsb3QubGVnZW5kQ29sb3IpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uTGVnZW5kQ2VsbENsaWNrKGNlbGxWYWx1ZSl7XHJcbiAgICAgICAgdGhpcy51cGRhdGVFbmFibGVkR3JvdXBzKGNlbGxWYWx1ZSk7XHJcblxyXG4gICAgICAgIHZhciBpc0Rpc2FibGVkID0gdGhpcy5lbmFibGVkR3JvdXBzLmluZGV4T2YoY2VsbFZhbHVlKTwwO1xyXG4gICAgICAgIHRoaXMucGxvdC5sZWdlbmQuY29udGFpbmVyLnNlbGVjdEFsbChcImcuY2VsbFwiKS5lYWNoKGZ1bmN0aW9uKGNlbGwpe1xyXG4gICAgICAgICAgICBpZihjZWxsID09IGNlbGxWYWx1ZSl7XHJcbiAgICAgICAgICAgICAgICBkMy5zZWxlY3QodGhpcykuY2xhc3NlZChcIm9kYy1kaXNhYmxlZFwiLCBpc0Rpc2FibGVkKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5pbml0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlRW5hYmxlZEdyb3VwcyhjZWxsVmFsdWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZW5hYmxlZEdyb3Vwcykge1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMgPSB0aGlzLnBsb3QuZG90LmNvbG9yQ2F0ZWdvcnkuZG9tYWluKCkuc2xpY2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5lbmFibGVkR3JvdXBzLmluZGV4T2YoY2VsbFZhbHVlKTtcclxuXHJcbiAgICAgICAgaWYgKGluZGV4IDwgMCkge1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMucHVzaChjZWxsVmFsdWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZW5hYmxlZEdyb3Vwcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG5cclxuICAgIHNldERhdGEoZGF0YSl7XHJcbiAgICAgICAgc3VwZXIuc2V0RGF0YShkYXRhKTtcclxuICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMgPSBudWxsO1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHtDaGFydCwgQ2hhcnRDb25maWd9IGZyb20gXCIuL2NoYXJ0XCI7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4vdXRpbHMnXHJcbmltcG9ydCB7TGVnZW5kfSBmcm9tIFwiLi9sZWdlbmRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTY2F0dGVyUGxvdENvbmZpZyBleHRlbmRzIENoYXJ0Q29uZmlne1xyXG5cclxuICAgIHN2Z0NsYXNzPSB0aGlzLmNzc0NsYXNzUHJlZml4KydzY2F0dGVycGxvdCc7XHJcbiAgICBndWlkZXM9IGZhbHNlOyAvL3Nob3cgYXhpcyBndWlkZXNcclxuICAgIHNob3dUb29sdGlwPSB0cnVlOyAvL3Nob3cgdG9vbHRpcCBvbiBkb3QgaG92ZXJcclxuICAgIHNob3dMZWdlbmQ9dHJ1ZTtcclxuICAgIGxlZ2VuZD17XHJcbiAgICAgICAgd2lkdGg6IDgwLFxyXG4gICAgICAgIG1hcmdpbjogMTAsXHJcbiAgICAgICAgc2hhcGVXaWR0aDogMjBcclxuICAgIH07XHJcblxyXG4gICAgeD17Ly8gWCBheGlzIGNvbmZpZ1xyXG4gICAgICAgIGxhYmVsOiAnWCcsIC8vIGF4aXMgbGFiZWxcclxuICAgICAgICBrZXk6IDAsXHJcbiAgICAgICAgdmFsdWU6IChkLCBrZXkpID0+IGRba2V5XSwgLy8geCB2YWx1ZSBhY2Nlc3NvclxyXG4gICAgICAgIG9yaWVudDogXCJib3R0b21cIixcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIlxyXG4gICAgfTtcclxuICAgIHk9ey8vIFkgYXhpcyBjb25maWdcclxuICAgICAgICBsYWJlbDogJ1knLCAvLyBheGlzIGxhYmVsLFxyXG4gICAgICAgIGtleTogMSxcclxuICAgICAgICB2YWx1ZTogKGQsIGtleSkgPT4gZFtrZXldLCAvLyB5IHZhbHVlIGFjY2Vzc29yXHJcbiAgICAgICAgb3JpZW50OiBcImxlZnRcIixcclxuICAgICAgICBzY2FsZTogXCJsaW5lYXJcIlxyXG4gICAgfTtcclxuICAgIGdyb3Vwcz17XHJcbiAgICAgICAga2V5OiAyLFxyXG4gICAgICAgIHZhbHVlOiAoZCwga2V5KSA9PiBkW2tleV0gLCAvLyBncm91cGluZyB2YWx1ZSBhY2Nlc3NvcixcclxuICAgICAgICBsYWJlbDogXCJcIlxyXG4gICAgfTtcclxuICAgIGRvdCA9IHtcclxuICAgICAgICByYWRpdXM6IDIsXHJcbiAgICAgICAgY29sb3I6IGQgPT4gdGhpcy5ncm91cHMgPyB0aGlzLmdyb3Vwcy52YWx1ZShkLCB0aGlzLmdyb3Vwcy5rZXkpIDogJycsIC8vIHN0cmluZyBvciBmdW5jdGlvbiByZXR1cm5pbmcgY29sb3IncyB2YWx1ZSBmb3IgY29sb3Igc2NhbGVcclxuICAgICAgICBkM0NvbG9yQ2F0ZWdvcnk6ICdjYXRlZ29yeTEwJ1xyXG4gICAgfTtcclxuICAgIHRyYW5zaXRpb249IHRydWU7XHJcblxyXG4gICAgY29uc3RydWN0b3IoY3VzdG9tKXtcclxuICAgICAgICBzdXBlcigpO1xyXG5cclxuXHJcblxyXG4gICAgICAgIGlmKGN1c3RvbSl7XHJcbiAgICAgICAgICAgIFV0aWxzLmRlZXBFeHRlbmQodGhpcywgY3VzdG9tKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgU2NhdHRlclBsb3QgZXh0ZW5kcyBDaGFydHtcclxuICAgIGNvbnN0cnVjdG9yKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIGNvbmZpZykge1xyXG4gICAgICAgIHN1cGVyKHBsYWNlaG9sZGVyU2VsZWN0b3IsIGRhdGEsIG5ldyBTY2F0dGVyUGxvdENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRDb25maWcoY29uZmlnKXtcclxuICAgICAgICByZXR1cm4gc3VwZXIuc2V0Q29uZmlnKG5ldyBTY2F0dGVyUGxvdENvbmZpZyhjb25maWcpKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGxvdCgpe1xyXG4gICAgICAgIHN1cGVyLmluaXRQbG90KCk7XHJcbiAgICAgICAgdmFyIHNlbGY9dGhpcztcclxuXHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZztcclxuXHJcbiAgICAgICAgdGhpcy5wbG90Lng9e307XHJcbiAgICAgICAgdGhpcy5wbG90Lnk9e307XHJcbiAgICAgICAgdGhpcy5wbG90LmRvdD17XHJcbiAgICAgICAgICAgIGNvbG9yOiBudWxsLy9jb2xvciBzY2FsZSBtYXBwaW5nIGZ1bmN0aW9uXHJcbiAgICAgICAgfTtcclxuXHJcblxyXG4gICAgICAgIHRoaXMucGxvdC5zaG93TGVnZW5kID0gY29uZi5zaG93TGVnZW5kO1xyXG4gICAgICAgIGlmKHRoaXMucGxvdC5zaG93TGVnZW5kKXtcclxuICAgICAgICAgICAgdGhpcy5wbG90Lm1hcmdpbi5yaWdodCA9IGNvbmYubWFyZ2luLnJpZ2h0ICsgY29uZi5sZWdlbmQud2lkdGgrY29uZi5sZWdlbmQubWFyZ2luKjI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG5cclxuICAgICAgICB0aGlzLmNvbXB1dGVQbG90U2l6ZSgpO1xyXG5cclxuXHJcbiAgICAgICAgdGhpcy5zZXR1cEdyb3VwcygpO1xyXG5cclxuICAgICAgICB0aGlzLnBsb3QuZGF0YSA9IHRoaXMuZ2V0RGF0YVRvUGxvdCgpO1xyXG4gICAgICAgIHRoaXMuc2V0dXBYKCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cFkoKTtcclxuXHJcblxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBzZXR1cEdyb3VwcygpIHtcclxuICAgICAgICB2YXIgc2VsZj10aGlzO1xyXG4gICAgICAgIHZhciBjb25mID0gdGhpcy5jb25maWc7XHJcbiAgICAgICAgdGhpcy5wbG90Lmdyb3VwVmFsdWUgPSBkID0+IGNvbmYuZ3JvdXBzLnZhbHVlKGQsIGNvbmYuZ3JvdXBzLmtleSk7XHJcbiAgICAgICAgaWYoY29uZi5kb3QuZDNDb2xvckNhdGVnb3J5KXtcclxuICAgICAgICAgICAgdGhpcy5wbG90LmRvdC5jb2xvckNhdGVnb3J5ID0gZDMuc2NhbGVbY29uZi5kb3QuZDNDb2xvckNhdGVnb3J5XSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgY29sb3JWYWx1ZSA9IGNvbmYuZG90LmNvbG9yO1xyXG4gICAgICAgIGlmKGNvbG9yVmFsdWUpe1xyXG4gICAgICAgICAgICB0aGlzLnBsb3QuZG90LmNvbG9yVmFsdWUgPSBjb2xvclZhbHVlO1xyXG5cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBjb2xvclZhbHVlID09PSAnc3RyaW5nJyB8fCBjb2xvclZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKXtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxvdC5kb3QuY29sb3IgPSBjb2xvclZhbHVlO1xyXG4gICAgICAgICAgICB9ZWxzZSBpZih0aGlzLnBsb3QuZG90LmNvbG9yQ2F0ZWdvcnkpe1xyXG4gICAgICAgICAgICAgICAgdmFyIGRvbWFpbiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGQzLm1hcCh0aGlzLmRhdGEsIGQgPT4gc2VsZi5wbG90LmRvdC5jb2xvclZhbHVlLmNhbGwoc2VsZixkKSlbJ18nXSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnBsb3QuZG90LmNvbG9yQ2F0ZWdvcnkuZG9tYWluKGRvbWFpbik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3QuZG90LmNvbG9yID0gZCA9PiAgc2VsZi5wbG90LmRvdC5jb2xvckNhdGVnb3J5KHNlbGYucGxvdC5kb3QuY29sb3JWYWx1ZS5jYWxsKHNlbGYsZCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldERhdGFUb1Bsb3QoKXtcclxuICAgICAgICBpZighdGhpcy5lbmFibGVkR3JvdXBzKXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEuZmlsdGVyKGQgPT4gdGhpcy5lbmFibGVkR3JvdXBzLmluZGV4T2YodGhpcy5wbG90Lmdyb3VwVmFsdWUoZCkpPi0xKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXR1cFgoKXtcclxuXHJcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XHJcbiAgICAgICAgdmFyIHggPSBwbG90Lng7XHJcbiAgICAgICAgdmFyIGNvbmYgPSB0aGlzLmNvbmZpZy54O1xyXG5cclxuICAgICAgICAvKiAqXHJcbiAgICAgICAgICogdmFsdWUgYWNjZXNzb3IgLSByZXR1cm5zIHRoZSB2YWx1ZSB0byBlbmNvZGUgZm9yIGEgZ2l2ZW4gZGF0YSBvYmplY3QuXHJcbiAgICAgICAgICogc2NhbGUgLSBtYXBzIHZhbHVlIHRvIGEgdmlzdWFsIGRpc3BsYXkgZW5jb2RpbmcsIHN1Y2ggYXMgYSBwaXhlbCBwb3NpdGlvbi5cclxuICAgICAgICAgKiBtYXAgZnVuY3Rpb24gLSBtYXBzIGZyb20gZGF0YSB2YWx1ZSB0byBkaXNwbGF5IHZhbHVlXHJcbiAgICAgICAgICogYXhpcyAtIHNldHMgdXAgYXhpc1xyXG4gICAgICAgICAqKi9cclxuICAgICAgICB4LnZhbHVlID0gZCA9PiBjb25mLnZhbHVlKGQsIGNvbmYua2V5KTtcclxuICAgICAgICB4LnNjYWxlID0gZDMuc2NhbGVbY29uZi5zY2FsZV0oKS5yYW5nZShbMCwgcGxvdC53aWR0aF0pO1xyXG4gICAgICAgIHgubWFwID0gZCA9PiB4LnNjYWxlKHgudmFsdWUoZCkpO1xyXG4gICAgICAgIHguYXhpcyA9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeC5zY2FsZSkub3JpZW50KGNvbmYub3JpZW50KTtcclxuICAgICAgICB2YXIgZGF0YSA9IHRoaXMucGxvdC5kYXRhO1xyXG4gICAgICAgIHBsb3QueC5zY2FsZS5kb21haW4oW2QzLm1pbihkYXRhLCBwbG90LngudmFsdWUpLTEsIGQzLm1heChkYXRhLCBwbG90LngudmFsdWUpKzFdKTtcclxuICAgICAgICBpZih0aGlzLmNvbmZpZy5ndWlkZXMpIHtcclxuICAgICAgICAgICAgeC5heGlzLnRpY2tTaXplKC1wbG90LmhlaWdodCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgc2V0dXBZICgpe1xyXG5cclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuICAgICAgICB2YXIgeSA9IHBsb3QueTtcclxuICAgICAgICB2YXIgY29uZiA9IHRoaXMuY29uZmlnLnk7XHJcblxyXG4gICAgICAgIC8qXHJcbiAgICAgICAgICogdmFsdWUgYWNjZXNzb3IgLSByZXR1cm5zIHRoZSB2YWx1ZSB0byBlbmNvZGUgZm9yIGEgZ2l2ZW4gZGF0YSBvYmplY3QuXHJcbiAgICAgICAgICogc2NhbGUgLSBtYXBzIHZhbHVlIHRvIGEgdmlzdWFsIGRpc3BsYXkgZW5jb2RpbmcsIHN1Y2ggYXMgYSBwaXhlbCBwb3NpdGlvbi5cclxuICAgICAgICAgKiBtYXAgZnVuY3Rpb24gLSBtYXBzIGZyb20gZGF0YSB2YWx1ZSB0byBkaXNwbGF5IHZhbHVlXHJcbiAgICAgICAgICogYXhpcyAtIHNldHMgdXAgYXhpc1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHkudmFsdWUgPSBkID0+IGNvbmYudmFsdWUoZCwgY29uZi5rZXkpO1xyXG4gICAgICAgIHkuc2NhbGUgPSBkMy5zY2FsZVtjb25mLnNjYWxlXSgpLnJhbmdlKFtwbG90LmhlaWdodCwgMF0pO1xyXG4gICAgICAgIHkubWFwID0gZCA9PiB5LnNjYWxlKHkudmFsdWUoZCkpO1xyXG4gICAgICAgIHkuYXhpcyA9IGQzLnN2Zy5heGlzKCkuc2NhbGUoeS5zY2FsZSkub3JpZW50KGNvbmYub3JpZW50KTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5jb25maWcuZ3VpZGVzKXtcclxuICAgICAgICAgICAgeS5heGlzLnRpY2tTaXplKC1wbG90LndpZHRoKTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgZGF0YSA9IHRoaXMucGxvdC5kYXRhO1xyXG4gICAgICAgIHBsb3QueS5zY2FsZS5kb21haW4oW2QzLm1pbihkYXRhLCBwbG90LnkudmFsdWUpLTEsIGQzLm1heChkYXRhLCBwbG90LnkudmFsdWUpKzFdKTtcclxuICAgIH07XHJcblxyXG4gICAgZHJhd0F4aXNYKCl7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBheGlzQ29uZiA9IHRoaXMuY29uZmlnLng7XHJcbiAgICAgICAgdmFyIGF4aXMgPSBzZWxmLnN2Z0cuc2VsZWN0T3JBcHBlbmQoXCJnLlwiK3NlbGYucHJlZml4Q2xhc3MoJ2F4aXMteCcpK1wiLlwiK3NlbGYucHJlZml4Q2xhc3MoJ2F4aXMnKSsoc2VsZi5jb25maWcuZ3VpZGVzID8gJycgOiAnLicrc2VsZi5wcmVmaXhDbGFzcygnbm8tZ3VpZGVzJykpKVxyXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZSgwLFwiICsgcGxvdC5oZWlnaHQgKyBcIilcIik7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdmFyIGF4aXNUID0gYXhpcztcclxuICAgICAgICBpZiAoc2VsZi50cmFuc2l0aW9uRW5hYmxlZCgpKSB7XHJcbiAgICAgICAgICAgIGF4aXNUID0gYXhpcy50cmFuc2l0aW9uKCkuZWFzZShcInNpbi1pbi1vdXRcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBheGlzVC5jYWxsKHBsb3QueC5heGlzKTtcclxuICAgICAgICBcclxuICAgICAgICBheGlzLnNlbGVjdE9yQXBwZW5kKFwidGV4dC5cIitzZWxmLnByZWZpeENsYXNzKCdsYWJlbCcpKVxyXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIisgKHBsb3Qud2lkdGgvMikgK1wiLFwiKyAocGxvdC5tYXJnaW4uYm90dG9tKSArXCIpXCIpICAvLyB0ZXh0IGlzIGRyYXduIG9mZiB0aGUgc2NyZWVuIHRvcCBsZWZ0LCBtb3ZlIGRvd24gYW5kIG91dCBhbmQgcm90YXRlXHJcbiAgICAgICAgICAgIC5hdHRyKFwiZHlcIiwgXCItMWVtXCIpXHJcbiAgICAgICAgICAgIC5zdHlsZShcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpXHJcbiAgICAgICAgICAgIC50ZXh0KGF4aXNDb25mLmxhYmVsKTtcclxuICAgIH07XHJcblxyXG4gICAgZHJhd0F4aXNZKCl7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwbG90ID0gc2VsZi5wbG90O1xyXG4gICAgICAgIHZhciBheGlzQ29uZiA9IHRoaXMuY29uZmlnLnk7XHJcbiAgICAgICAgdmFyIGF4aXMgPSBzZWxmLnN2Z0cuc2VsZWN0T3JBcHBlbmQoXCJnLlwiK3NlbGYucHJlZml4Q2xhc3MoJ2F4aXMteScpK1wiLlwiK3NlbGYucHJlZml4Q2xhc3MoJ2F4aXMnKSsoc2VsZi5jb25maWcuZ3VpZGVzID8gJycgOiAnLicrc2VsZi5wcmVmaXhDbGFzcygnbm8tZ3VpZGVzJykpKTtcclxuXHJcbiAgICAgICAgdmFyIGF4aXNUID0gYXhpcztcclxuICAgICAgICBpZiAoc2VsZi50cmFuc2l0aW9uRW5hYmxlZCgpKSB7XHJcbiAgICAgICAgICAgIGF4aXNUID0gYXhpcy50cmFuc2l0aW9uKCkuZWFzZShcInNpbi1pbi1vdXRcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBheGlzVC5jYWxsKHBsb3QueS5heGlzKTtcclxuXHJcbiAgICAgICAgYXhpcy5zZWxlY3RPckFwcGVuZChcInRleHQuXCIrc2VsZi5wcmVmaXhDbGFzcygnbGFiZWwnKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIrIC1wbG90Lm1hcmdpbi5sZWZ0ICtcIixcIisocGxvdC5oZWlnaHQvMikrXCIpcm90YXRlKC05MClcIikgIC8vIHRleHQgaXMgZHJhd24gb2ZmIHRoZSBzY3JlZW4gdG9wIGxlZnQsIG1vdmUgZG93biBhbmQgb3V0IGFuZCByb3RhdGVcclxuICAgICAgICAgICAgLmF0dHIoXCJkeVwiLCBcIjFlbVwiKVxyXG4gICAgICAgICAgICAuc3R5bGUoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxyXG4gICAgICAgICAgICAudGV4dChheGlzQ29uZi5sYWJlbCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHVwZGF0ZShuZXdEYXRhKXtcclxuICAgICAgICBzdXBlci51cGRhdGUobmV3RGF0YSk7XHJcbiAgICAgICAgdGhpcy5kcmF3QXhpc1goKTtcclxuICAgICAgICB0aGlzLmRyYXdBeGlzWSgpO1xyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZURvdHMoKTtcclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGVMZWdlbmQoKTtcclxuICAgIH07XHJcblxyXG4gICAgdXBkYXRlRG90cygpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHBsb3QgPSBzZWxmLnBsb3Q7XHJcbiAgICAgICAgdmFyIGRhdGEgPSBwbG90LmRhdGE7XHJcbiAgICAgICAgdmFyIGRvdENsYXNzID0gc2VsZi5wcmVmaXhDbGFzcygnZG90Jyk7XHJcbiAgICAgICAgc2VsZi5kb3RzQ29udGFpbmVyQ2xhc3MgPSBzZWxmLnByZWZpeENsYXNzKCdkb3RzLWNvbnRhaW5lcicpO1xyXG5cclxuXHJcbiAgICAgICAgdmFyIGRvdHNDb250YWluZXIgPSBzZWxmLnN2Z0cuc2VsZWN0T3JBcHBlbmQoXCJnLlwiICsgc2VsZi5kb3RzQ29udGFpbmVyQ2xhc3MpO1xyXG5cclxuICAgICAgICB2YXIgZG90cyA9IGRvdHNDb250YWluZXIuc2VsZWN0QWxsKCcuJyArIGRvdENsYXNzKVxyXG4gICAgICAgICAgICAuZGF0YShkYXRhKTtcclxuXHJcbiAgICAgICAgZG90cy5lbnRlcigpLmFwcGVuZChcImNpcmNsZVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIGRvdENsYXNzKTtcclxuXHJcbiAgICAgICAgdmFyIGRvdHNUID0gZG90cztcclxuICAgICAgICBpZiAoc2VsZi50cmFuc2l0aW9uRW5hYmxlZCgpKSB7XHJcbiAgICAgICAgICAgIGRvdHNUID0gZG90cy50cmFuc2l0aW9uKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBkb3RzVC5hdHRyKFwiclwiLCBzZWxmLmNvbmZpZy5kb3QucmFkaXVzKVxyXG4gICAgICAgICAgICAuYXR0cihcImN4XCIsIHBsb3QueC5tYXApXHJcbiAgICAgICAgICAgIC5hdHRyKFwiY3lcIiwgcGxvdC55Lm1hcCk7XHJcblxyXG4gICAgICAgIGlmIChwbG90LnRvb2x0aXApIHtcclxuICAgICAgICAgICAgZG90cy5vbihcIm1vdXNlb3ZlclwiLCBkID0+IHtcclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oMjAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgLjkpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGh0bWwgPSBcIihcIiArIHBsb3QueC52YWx1ZShkKSArIFwiLCBcIiArIHBsb3QueS52YWx1ZShkKSArIFwiKVwiO1xyXG4gICAgICAgICAgICAgICAgdmFyIGdyb3VwID0gc2VsZi5jb25maWcuZ3JvdXBzID8gIHNlbGYuY29uZmlnLmdyb3Vwcy52YWx1ZShkLCBzZWxmLmNvbmZpZy5ncm91cHMua2V5KSA6IG51bGw7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ3JvdXAgfHwgZ3JvdXAgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBodG1sICs9IFwiPGJyLz5cIjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWwgPSBzZWxmLmNvbmZpZy5ncm91cHMubGFiZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gbGFiZWwgKyBcIjogXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gZ3JvdXBcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC5odG1sKGh0bWwpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwibGVmdFwiLCAoZDMuZXZlbnQucGFnZVggKyA1KSArIFwicHhcIilcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgKGQzLmV2ZW50LnBhZ2VZIC0gMjgpICsgXCJweFwiKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIC5vbihcIm1vdXNlb3V0XCIsIGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHBsb3QudG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKDUwMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBsb3QuZG90LmNvbG9yKSB7XHJcbiAgICAgICAgICAgIGRvdHMuc3R5bGUoXCJmaWxsXCIsIHBsb3QuZG90LmNvbG9yKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZG90cy5leGl0KCkucmVtb3ZlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlTGVnZW5kKCkge1xyXG5cclxuICAgICAgICB2YXIgc2VsZiA9dGhpcztcclxuICAgICAgICB2YXIgcGxvdCA9IHRoaXMucGxvdDtcclxuXHJcbiAgICAgICAgdmFyIHNjYWxlID0gcGxvdC5kb3QuY29sb3JDYXRlZ29yeTtcclxuXHJcblxyXG5cclxuICAgICAgICBpZighc2NhbGUuZG9tYWluKCkgfHwgc2NhbGUuZG9tYWluKCkubGVuZ3RoPDIpe1xyXG4gICAgICAgICAgICBwbG90LnNob3dMZWdlbmQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKCFwbG90LnNob3dMZWdlbmQpe1xyXG4gICAgICAgICAgICBpZihwbG90LmxlZ2VuZCAmJiBwbG90LmxlZ2VuZC5jb250YWluZXIpe1xyXG4gICAgICAgICAgICAgICAgcGxvdC5sZWdlbmQuY29udGFpbmVyLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICB2YXIgbGVnZW5kWCA9IHRoaXMucGxvdC53aWR0aCArIHRoaXMuY29uZmlnLmxlZ2VuZC5tYXJnaW47XHJcbiAgICAgICAgdmFyIGxlZ2VuZFkgPSB0aGlzLmNvbmZpZy5sZWdlbmQubWFyZ2luO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZCA9IG5ldyBMZWdlbmQodGhpcy5zdmcsIHRoaXMuc3ZnRywgc2NhbGUsIGxlZ2VuZFgsIGxlZ2VuZFkpO1xyXG5cclxuICAgICAgICBwbG90LmxlZ2VuZENvbG9yID0gcGxvdC5sZWdlbmQuY29sb3IoKVxyXG4gICAgICAgICAgICAuc2hhcGVXaWR0aCh0aGlzLmNvbmZpZy5sZWdlbmQuc2hhcGVXaWR0aClcclxuICAgICAgICAgICAgLm9yaWVudCgndmVydGljYWwnKVxyXG4gICAgICAgICAgICAuc2NhbGUoc2NhbGUpO1xyXG5cclxuXHJcbiAgICAgICAgcGxvdC5sZWdlbmRDb2xvci5vbignY2VsbGNsaWNrJywgYz0+IHNlbGYub25MZWdlbmRDZWxsQ2xpY2soYykpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHBsb3QubGVnZW5kLmNvbnRhaW5lclxyXG4gICAgICAgICAgICAuY2FsbChwbG90LmxlZ2VuZENvbG9yKTtcclxuICAgIH1cclxuXHJcbiAgICBvbkxlZ2VuZENlbGxDbGljayhjZWxsVmFsdWUpe1xyXG4gICAgICAgIHRoaXMudXBkYXRlRW5hYmxlZEdyb3VwcyhjZWxsVmFsdWUpO1xyXG5cclxuICAgICAgICB2YXIgaXNEaXNhYmxlZCA9IHRoaXMuZW5hYmxlZEdyb3Vwcy5pbmRleE9mKGNlbGxWYWx1ZSk8MDtcclxuICAgICAgICB0aGlzLnBsb3QubGVnZW5kLmNvbnRhaW5lci5zZWxlY3RBbGwoXCJnLmNlbGxcIikuZWFjaChmdW5jdGlvbihjZWxsKXtcclxuICAgICAgICAgICAgaWYoY2VsbCA9PSBjZWxsVmFsdWUpe1xyXG4gICAgICAgICAgICAgICAgZDMuc2VsZWN0KHRoaXMpLmNsYXNzZWQoXCJvZGMtZGlzYWJsZWRcIiwgaXNEaXNhYmxlZCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuaW5pdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUVuYWJsZWRHcm91cHMoY2VsbFZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVuYWJsZWRHcm91cHMpIHtcclxuICAgICAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzID0gdGhpcy5wbG90LmRvdC5jb2xvckNhdGVnb3J5LmRvbWFpbigpLnNsaWNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBpbmRleCA9IHRoaXMuZW5hYmxlZEdyb3Vwcy5pbmRleE9mKGNlbGxWYWx1ZSk7XHJcblxyXG4gICAgICAgIGlmIChpbmRleCA8IDApIHtcclxuICAgICAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzLnB1c2goY2VsbFZhbHVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRHcm91cHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxuXHJcbiAgICBzZXREYXRhKGRhdGEpe1xyXG4gICAgICAgIHN1cGVyLnNldERhdGEoZGF0YSk7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkR3JvdXBzID0gbnVsbDtcclxuICAgIH1cclxufVxyXG4iLCIvKlxuICogaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vYmVucmFzbXVzZW4vMTI2MTk3N1xuICogTkFNRVxuICogXG4gKiBzdGF0aXN0aWNzLWRpc3RyaWJ1dGlvbnMuanMgLSBKYXZhU2NyaXB0IGxpYnJhcnkgZm9yIGNhbGN1bGF0aW5nXG4gKiAgIGNyaXRpY2FsIHZhbHVlcyBhbmQgdXBwZXIgcHJvYmFiaWxpdGllcyBvZiBjb21tb24gc3RhdGlzdGljYWxcbiAqICAgZGlzdHJpYnV0aW9uc1xuICogXG4gKiBTWU5PUFNJU1xuICogXG4gKiBcbiAqICAgLy8gQ2hpLXNxdWFyZWQtY3JpdCAoMiBkZWdyZWVzIG9mIGZyZWVkb20sIDk1dGggcGVyY2VudGlsZSA9IDAuMDUgbGV2ZWxcbiAqICAgY2hpc3FyZGlzdHIoMiwgLjA1KVxuICogICBcbiAqICAgLy8gdS1jcml0ICg5NXRoIHBlcmNlbnRpbGUgPSAwLjA1IGxldmVsKVxuICogICB1ZGlzdHIoLjA1KTtcbiAqICAgXG4gKiAgIC8vIHQtY3JpdCAoMSBkZWdyZWUgb2YgZnJlZWRvbSwgOTkuNXRoIHBlcmNlbnRpbGUgPSAwLjAwNSBsZXZlbCkgXG4gKiAgIHRkaXN0cigxLC4wMDUpO1xuICogICBcbiAqICAgLy8gRi1jcml0ICgxIGRlZ3JlZSBvZiBmcmVlZG9tIGluIG51bWVyYXRvciwgMyBkZWdyZWVzIG9mIGZyZWVkb20gXG4gKiAgIC8vICAgICAgICAgaW4gZGVub21pbmF0b3IsIDk5dGggcGVyY2VudGlsZSA9IDAuMDEgbGV2ZWwpXG4gKiAgIGZkaXN0cigxLDMsLjAxKTtcbiAqICAgXG4gKiAgIC8vIHVwcGVyIHByb2JhYmlsaXR5IG9mIHRoZSB1IGRpc3RyaWJ1dGlvbiAodSA9IC0wLjg1KTogUSh1KSA9IDEtRyh1KVxuICogICB1cHJvYigtMC44NSk7XG4gKiAgIFxuICogICAvLyB1cHBlciBwcm9iYWJpbGl0eSBvZiB0aGUgY2hpLXNxdWFyZSBkaXN0cmlidXRpb25cbiAqICAgLy8gKDMgZGVncmVlcyBvZiBmcmVlZG9tLCBjaGktc3F1YXJlZCA9IDYuMjUpOiBRID0gMS1HXG4gKiAgIGNoaXNxcnByb2IoMyw2LjI1KTtcbiAqICAgXG4gKiAgIC8vIHVwcGVyIHByb2JhYmlsaXR5IG9mIHRoZSB0IGRpc3RyaWJ1dGlvblxuICogICAvLyAoMyBkZWdyZWVzIG9mIGZyZWVkb20sIHQgPSA2LjI1MSk6IFEgPSAxLUdcbiAqICAgdHByb2IoMyw2LjI1MSk7XG4gKiAgIFxuICogICAvLyB1cHBlciBwcm9iYWJpbGl0eSBvZiB0aGUgRiBkaXN0cmlidXRpb25cbiAqICAgLy8gKDMgZGVncmVlcyBvZiBmcmVlZG9tIGluIG51bWVyYXRvciwgNSBkZWdyZWVzIG9mIGZyZWVkb20gaW5cbiAqICAgLy8gIGRlbm9taW5hdG9yLCBGID0gNi4yNSk6IFEgPSAxLUdcbiAqICAgZnByb2IoMyw1LC42MjUpO1xuICogXG4gKiBcbiAqICBERVNDUklQVElPTlxuICogXG4gKiBUaGlzIGxpYnJhcnkgY2FsY3VsYXRlcyBwZXJjZW50YWdlIHBvaW50cyAoNSBzaWduaWZpY2FudCBkaWdpdHMpIG9mIHRoZSB1XG4gKiAoc3RhbmRhcmQgbm9ybWFsKSBkaXN0cmlidXRpb24sIHRoZSBzdHVkZW50J3MgdCBkaXN0cmlidXRpb24sIHRoZVxuICogY2hpLXNxdWFyZSBkaXN0cmlidXRpb24gYW5kIHRoZSBGIGRpc3RyaWJ1dGlvbi4gSXQgY2FuIGFsc28gY2FsY3VsYXRlIHRoZVxuICogdXBwZXIgcHJvYmFiaWxpdHkgKDUgc2lnbmlmaWNhbnQgZGlnaXRzKSBvZiB0aGUgdSAoc3RhbmRhcmQgbm9ybWFsKSwgdGhlXG4gKiBjaGktc3F1YXJlLCB0aGUgdCBhbmQgdGhlIEYgZGlzdHJpYnV0aW9uLlxuICogXG4gKiBUaGVzZSBjcml0aWNhbCB2YWx1ZXMgYXJlIG5lZWRlZCB0byBwZXJmb3JtIHN0YXRpc3RpY2FsIHRlc3RzLCBsaWtlIHRoZSB1XG4gKiB0ZXN0LCB0aGUgdCB0ZXN0LCB0aGUgRiB0ZXN0IGFuZCB0aGUgY2hpLXNxdWFyZWQgdGVzdCwgYW5kIHRvIGNhbGN1bGF0ZVxuICogY29uZmlkZW5jZSBpbnRlcnZhbHMuXG4gKiBcbiAqIElmIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBtb3JlIHByZWNpc2UgYWxnb3JpdGhtcyB5b3UgY291bGQgbG9vayBhdDpcbiAqICAgU3RhdExpYjogaHR0cDovL2xpYi5zdGF0LmNtdS5lZHUvYXBzdGF0LyA7IFxuICogICBBcHBsaWVkIFN0YXRpc3RpY3MgQWxnb3JpdGhtcyBieSBHcmlmZml0aHMsIFAuIGFuZCBIaWxsLCBJLkQuXG4gKiAgICwgRWxsaXMgSG9yd29vZDogQ2hpY2hlc3RlciAoMTk4NSlcbiAqIFxuICogQlVHUyBcbiAqIFxuICogVGhpcyBwb3J0IHdhcyBwcm9kdWNlZCBmcm9tIHRoZSBQZXJsIG1vZHVsZSBTdGF0aXN0aWNzOjpEaXN0cmlidXRpb25zXG4gKiB0aGF0IGhhcyBoYWQgbm8gYnVnIHJlcG9ydHMgaW4gc2V2ZXJhbCB5ZWFycy4gIElmIHlvdSBmaW5kIGEgYnVnIHRoZW5cbiAqIHBsZWFzZSBkb3VibGUtY2hlY2sgdGhhdCBKYXZhU2NyaXB0IGRvZXMgbm90IHRoaW5nIHRoZSBudW1iZXJzIHlvdSBhcmVcbiAqIHBhc3NpbmcgaW4gYXJlIHN0cmluZ3MuICAoWW91IGNhbiBzdWJ0cmFjdCAwIGZyb20gdGhlbSBhcyB5b3UgcGFzcyB0aGVtXG4gKiBpbiBzbyB0aGF0IFwiNVwiIGlzIHByb3Blcmx5IHVuZGVyc3Rvb2QgdG8gYmUgNS4pICBJZiB5b3UgaGF2ZSBwYXNzZWQgaW4gYVxuICogbnVtYmVyIHRoZW4gcGxlYXNlIGNvbnRhY3QgdGhlIGF1dGhvclxuICogXG4gKiBBVVRIT1JcbiAqIFxuICogQmVuIFRpbGx5IDxidGlsbHlAZ21haWwuY29tPlxuICogXG4gKiBPcmlnaW5sIFBlcmwgdmVyc2lvbiBieSBNaWNoYWVsIEtvc3BhY2ggPG1pa2UucGVybEBnbXguYXQ+XG4gKiBcbiAqIE5pY2UgZm9ybWF0aW5nLCBzaW1wbGlmaWNhdGlvbiBhbmQgYnVnIHJlcGFpciBieSBNYXR0aGlhcyBUcmF1dG5lciBLcm9tYW5uXG4gKiA8bXRrQGlkLmNicy5kaz5cbiAqIFxuICogQ09QWVJJR0hUIFxuICogXG4gKiBDb3B5cmlnaHQgMjAwOCBCZW4gVGlsbHkuXG4gKiBcbiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0XG4gKiB1bmRlciB0aGUgc2FtZSB0ZXJtcyBhcyBQZXJsIGl0c2VsZi4gIFRoaXMgbWVhbnMgdW5kZXIgZWl0aGVyIHRoZSBQZXJsXG4gKiBBcnRpc3RpYyBMaWNlbnNlIG9yIHRoZSBHUEwgdjEgb3IgbGF0ZXIuXG4gKi9cblxudmFyIFNJR05JRklDQU5UID0gNTsgLy8gbnVtYmVyIG9mIHNpZ25pZmljYW50IGRpZ2l0cyB0byBiZSByZXR1cm5lZFxuXG5mdW5jdGlvbiBjaGlzcXJkaXN0ciAoJG4sICRwKSB7XG5cdGlmICgkbiA8PSAwIHx8IE1hdGguYWJzKCRuKSAtIE1hdGguYWJzKGludGVnZXIoJG4pKSAhPSAwKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIG46ICRuXFxuXCIpOyAvKiBkZWdyZWUgb2YgZnJlZWRvbSAqL1xuXHR9XG5cdGlmICgkcCA8PSAwIHx8ICRwID4gMSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBwOiAkcFxcblwiKTsgXG5cdH1cblx0cmV0dXJuIHByZWNpc2lvbl9zdHJpbmcoX3N1YmNoaXNxcigkbi0wLCAkcC0wKSk7XG59XG5cbmZ1bmN0aW9uIHVkaXN0ciAoJHApIHtcblx0aWYgKCRwID4gMSB8fCAkcCA8PSAwKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIHA6ICRwXFxuXCIpO1xuXHR9XG5cdHJldHVybiBwcmVjaXNpb25fc3RyaW5nKF9zdWJ1KCRwLTApKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRkaXN0ciAoJG4sICRwKSB7XG5cdGlmICgkbiA8PSAwIHx8IE1hdGguYWJzKCRuKSAtIE1hdGguYWJzKGludGVnZXIoJG4pKSAhPSAwKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIG46ICRuXFxuXCIpO1xuXHR9XG5cdGlmICgkcCA8PSAwIHx8ICRwID49IDEpIHtcblx0XHR0aHJvdyhcIkludmFsaWQgcDogJHBcXG5cIik7XG5cdH1cblx0cmV0dXJuIHByZWNpc2lvbl9zdHJpbmcoX3N1YnQoJG4tMCwgJHAtMCkpO1xufVxuXG5mdW5jdGlvbiBmZGlzdHIgKCRuLCAkbSwgJHApIHtcblx0aWYgKCgkbjw9MCkgfHwgKChNYXRoLmFicygkbiktKE1hdGguYWJzKGludGVnZXIoJG4pKSkpIT0wKSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBuOiAkblxcblwiKTsgLyogZmlyc3QgZGVncmVlIG9mIGZyZWVkb20gKi9cblx0fVxuXHRpZiAoKCRtPD0wKSB8fCAoKE1hdGguYWJzKCRtKS0oTWF0aC5hYnMoaW50ZWdlcigkbSkpKSkhPTApKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIG06ICRtXFxuXCIpOyAvKiBzZWNvbmQgZGVncmVlIG9mIGZyZWVkb20gKi9cblx0fVxuXHRpZiAoKCRwPD0wKSB8fCAoJHA+MSkpIHtcblx0XHR0aHJvdyhcIkludmFsaWQgcDogJHBcXG5cIik7XG5cdH1cblx0cmV0dXJuIHByZWNpc2lvbl9zdHJpbmcoX3N1YmYoJG4tMCwgJG0tMCwgJHAtMCkpO1xufVxuXG5mdW5jdGlvbiB1cHJvYiAoJHgpIHtcblx0cmV0dXJuIHByZWNpc2lvbl9zdHJpbmcoX3N1YnVwcm9iKCR4LTApKTtcbn1cblxuZnVuY3Rpb24gY2hpc3FycHJvYiAoJG4sJHgpIHtcblx0aWYgKCgkbiA8PSAwKSB8fCAoKE1hdGguYWJzKCRuKSAtIChNYXRoLmFicyhpbnRlZ2VyKCRuKSkpKSAhPSAwKSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBuOiAkblxcblwiKTsgLyogZGVncmVlIG9mIGZyZWVkb20gKi9cblx0fVxuXHRyZXR1cm4gcHJlY2lzaW9uX3N0cmluZyhfc3ViY2hpc3FycHJvYigkbi0wLCAkeC0wKSk7XG59XG5cbmZ1bmN0aW9uIHRwcm9iICgkbiwgJHgpIHtcblx0aWYgKCgkbiA8PSAwKSB8fCAoKE1hdGguYWJzKCRuKSAtIE1hdGguYWJzKGludGVnZXIoJG4pKSkgIT0wKSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBuOiAkblxcblwiKTsgLyogZGVncmVlIG9mIGZyZWVkb20gKi9cblx0fVxuXHRyZXR1cm4gcHJlY2lzaW9uX3N0cmluZyhfc3VidHByb2IoJG4tMCwgJHgtMCkpO1xufVxuXG5mdW5jdGlvbiBmcHJvYiAoJG4sICRtLCAkeCkge1xuXHRpZiAoKCRuPD0wKSB8fCAoKE1hdGguYWJzKCRuKS0oTWF0aC5hYnMoaW50ZWdlcigkbikpKSkhPTApKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIG46ICRuXFxuXCIpOyAvKiBmaXJzdCBkZWdyZWUgb2YgZnJlZWRvbSAqL1xuXHR9XG5cdGlmICgoJG08PTApIHx8ICgoTWF0aC5hYnMoJG0pLShNYXRoLmFicyhpbnRlZ2VyKCRtKSkpKSE9MCkpIHtcblx0XHR0aHJvdyhcIkludmFsaWQgbTogJG1cXG5cIik7IC8qIHNlY29uZCBkZWdyZWUgb2YgZnJlZWRvbSAqL1xuXHR9IFxuXHRyZXR1cm4gcHJlY2lzaW9uX3N0cmluZyhfc3ViZnByb2IoJG4tMCwgJG0tMCwgJHgtMCkpO1xufVxuXG5cbmZ1bmN0aW9uIF9zdWJmcHJvYiAoJG4sICRtLCAkeCkge1xuXHR2YXIgJHA7XG5cblx0aWYgKCR4PD0wKSB7XG5cdFx0JHA9MTtcblx0fSBlbHNlIGlmICgkbSAlIDIgPT0gMCkge1xuXHRcdHZhciAkeiA9ICRtIC8gKCRtICsgJG4gKiAkeCk7XG5cdFx0dmFyICRhID0gMTtcblx0XHRmb3IgKHZhciAkaSA9ICRtIC0gMjsgJGkgPj0gMjsgJGkgLT0gMikge1xuXHRcdFx0JGEgPSAxICsgKCRuICsgJGkgLSAyKSAvICRpICogJHogKiAkYTtcblx0XHR9XG5cdFx0JHAgPSAxIC0gTWF0aC5wb3coKDEgLSAkeiksICgkbiAvIDIpICogJGEpO1xuXHR9IGVsc2UgaWYgKCRuICUgMiA9PSAwKSB7XG5cdFx0dmFyICR6ID0gJG4gKiAkeCAvICgkbSArICRuICogJHgpO1xuXHRcdHZhciAkYSA9IDE7XG5cdFx0Zm9yICh2YXIgJGkgPSAkbiAtIDI7ICRpID49IDI7ICRpIC09IDIpIHtcblx0XHRcdCRhID0gMSArICgkbSArICRpIC0gMikgLyAkaSAqICR6ICogJGE7XG5cdFx0fVxuXHRcdCRwID0gTWF0aC5wb3coKDEgLSAkeiksICgkbSAvIDIpKSAqICRhO1xuXHR9IGVsc2Uge1xuXHRcdHZhciAkeSA9IE1hdGguYXRhbjIoTWF0aC5zcXJ0KCRuICogJHggLyAkbSksIDEpO1xuXHRcdHZhciAkeiA9IE1hdGgucG93KE1hdGguc2luKCR5KSwgMik7XG5cdFx0dmFyICRhID0gKCRuID09IDEpID8gMCA6IDE7XG5cdFx0Zm9yICh2YXIgJGkgPSAkbiAtIDI7ICRpID49IDM7ICRpIC09IDIpIHtcblx0XHRcdCRhID0gMSArICgkbSArICRpIC0gMikgLyAkaSAqICR6ICogJGE7XG5cdFx0fSBcblx0XHR2YXIgJGIgPSBNYXRoLlBJO1xuXHRcdGZvciAodmFyICRpID0gMjsgJGkgPD0gJG0gLSAxOyAkaSArPSAyKSB7XG5cdFx0XHQkYiAqPSAoJGkgLSAxKSAvICRpO1xuXHRcdH1cblx0XHR2YXIgJHAxID0gMiAvICRiICogTWF0aC5zaW4oJHkpICogTWF0aC5wb3coTWF0aC5jb3MoJHkpLCAkbSkgKiAkYTtcblxuXHRcdCR6ID0gTWF0aC5wb3coTWF0aC5jb3MoJHkpLCAyKTtcblx0XHQkYSA9ICgkbSA9PSAxKSA/IDAgOiAxO1xuXHRcdGZvciAodmFyICRpID0gJG0tMjsgJGkgPj0gMzsgJGkgLT0gMikge1xuXHRcdFx0JGEgPSAxICsgKCRpIC0gMSkgLyAkaSAqICR6ICogJGE7XG5cdFx0fVxuXHRcdCRwID0gbWF4KDAsICRwMSArIDEgLSAyICogJHkgLyBNYXRoLlBJXG5cdFx0XHQtIDIgLyBNYXRoLlBJICogTWF0aC5zaW4oJHkpICogTWF0aC5jb3MoJHkpICogJGEpO1xuXHR9XG5cdHJldHVybiAkcDtcbn1cblxuXG5mdW5jdGlvbiBfc3ViY2hpc3FycHJvYiAoJG4sJHgpIHtcblx0dmFyICRwO1xuXG5cdGlmICgkeCA8PSAwKSB7XG5cdFx0JHAgPSAxO1xuXHR9IGVsc2UgaWYgKCRuID4gMTAwKSB7XG5cdFx0JHAgPSBfc3VidXByb2IoKE1hdGgucG93KCgkeCAvICRuKSwgMS8zKVxuXHRcdFx0XHQtICgxIC0gMi85LyRuKSkgLyBNYXRoLnNxcnQoMi85LyRuKSk7XG5cdH0gZWxzZSBpZiAoJHggPiA0MDApIHtcblx0XHQkcCA9IDA7XG5cdH0gZWxzZSB7ICAgXG5cdFx0dmFyICRhO1xuICAgICAgICAgICAgICAgIHZhciAkaTtcbiAgICAgICAgICAgICAgICB2YXIgJGkxO1xuXHRcdGlmICgoJG4gJSAyKSAhPSAwKSB7XG5cdFx0XHQkcCA9IDIgKiBfc3VidXByb2IoTWF0aC5zcXJ0KCR4KSk7XG5cdFx0XHQkYSA9IE1hdGguc3FydCgyL01hdGguUEkpICogTWF0aC5leHAoLSR4LzIpIC8gTWF0aC5zcXJ0KCR4KTtcblx0XHRcdCRpMSA9IDE7XG5cdFx0fSBlbHNlIHtcblx0XHRcdCRwID0gJGEgPSBNYXRoLmV4cCgtJHgvMik7XG5cdFx0XHQkaTEgPSAyO1xuXHRcdH1cblxuXHRcdGZvciAoJGkgPSAkaTE7ICRpIDw9ICgkbi0yKTsgJGkgKz0gMikge1xuXHRcdFx0JGEgKj0gJHggLyAkaTtcblx0XHRcdCRwICs9ICRhO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gJHA7XG59XG5cbmZ1bmN0aW9uIF9zdWJ1ICgkcCkge1xuXHR2YXIgJHkgPSAtTWF0aC5sb2coNCAqICRwICogKDEgLSAkcCkpO1xuXHR2YXIgJHggPSBNYXRoLnNxcnQoXG5cdFx0JHkgKiAoMS41NzA3OTYyODhcblx0XHQgICsgJHkgKiAoLjAzNzA2OTg3OTA2XG5cdFx0ICBcdCsgJHkgKiAoLS44MzY0MzUzNTg5RS0zXG5cdFx0XHQgICsgJHkgKigtLjIyNTA5NDcxNzZFLTNcblx0XHRcdCAgXHQrICR5ICogKC42ODQxMjE4Mjk5RS01XG5cdFx0XHRcdCAgKyAkeSAqICgwLjU4MjQyMzg1MTVFLTVcblx0XHRcdFx0XHQrICR5ICogKC0uMTA0NTI3NDk3RS01XG5cdFx0XHRcdFx0ICArICR5ICogKC44MzYwOTM3MDE3RS03XG5cdFx0XHRcdFx0XHQrICR5ICogKC0uMzIzMTA4MTI3N0UtOFxuXHRcdFx0XHRcdFx0ICArICR5ICogKC4zNjU3NzYzMDM2RS0xMFxuXHRcdFx0XHRcdFx0XHQrICR5ICouNjkzNjIzMzk4MkUtMTIpKSkpKSkpKSkpKTtcblx0aWYgKCRwPi41KVxuICAgICAgICAgICAgICAgICR4ID0gLSR4O1xuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIF9zdWJ1cHJvYiAoJHgpIHtcblx0dmFyICRwID0gMDsgLyogaWYgKCRhYnN4ID4gMTAwKSAqL1xuXHR2YXIgJGFic3ggPSBNYXRoLmFicygkeCk7XG5cblx0aWYgKCRhYnN4IDwgMS45KSB7XG5cdFx0JHAgPSBNYXRoLnBvdygoMSArXG5cdFx0XHQkYWJzeCAqICguMDQ5ODY3MzQ3XG5cdFx0XHQgICsgJGFic3ggKiAoLjAyMTE0MTAwNjFcblx0XHRcdCAgXHQrICRhYnN4ICogKC4wMDMyNzc2MjYzXG5cdFx0XHRcdCAgKyAkYWJzeCAqICguMDAwMDM4MDAzNlxuXHRcdFx0XHRcdCsgJGFic3ggKiAoLjAwMDA0ODg5MDZcblx0XHRcdFx0XHQgICsgJGFic3ggKiAuMDAwMDA1MzgzKSkpKSkpLCAtMTYpLzI7XG5cdH0gZWxzZSBpZiAoJGFic3ggPD0gMTAwKSB7XG5cdFx0Zm9yICh2YXIgJGkgPSAxODsgJGkgPj0gMTsgJGktLSkge1xuXHRcdFx0JHAgPSAkaSAvICgkYWJzeCArICRwKTtcblx0XHR9XG5cdFx0JHAgPSBNYXRoLmV4cCgtLjUgKiAkYWJzeCAqICRhYnN4KSBcblx0XHRcdC8gTWF0aC5zcXJ0KDIgKiBNYXRoLlBJKSAvICgkYWJzeCArICRwKTtcblx0fVxuXG5cdGlmICgkeDwwKVxuICAgICAgICBcdCRwID0gMSAtICRwO1xuXHRyZXR1cm4gJHA7XG59XG5cbiAgIFxuZnVuY3Rpb24gX3N1YnQgKCRuLCAkcCkge1xuXG5cdGlmICgkcCA+PSAxIHx8ICRwIDw9IDApIHtcblx0XHR0aHJvdyhcIkludmFsaWQgcDogJHBcXG5cIik7XG5cdH1cblxuXHRpZiAoJHAgPT0gMC41KSB7XG5cdFx0cmV0dXJuIDA7XG5cdH0gZWxzZSBpZiAoJHAgPCAwLjUpIHtcblx0XHRyZXR1cm4gLSBfc3VidCgkbiwgMSAtICRwKTtcblx0fVxuXG5cdHZhciAkdSA9IF9zdWJ1KCRwKTtcblx0dmFyICR1MiA9IE1hdGgucG93KCR1LCAyKTtcblxuXHR2YXIgJGEgPSAoJHUyICsgMSkgLyA0O1xuXHR2YXIgJGIgPSAoKDUgKiAkdTIgKyAxNikgKiAkdTIgKyAzKSAvIDk2O1xuXHR2YXIgJGMgPSAoKCgzICogJHUyICsgMTkpICogJHUyICsgMTcpICogJHUyIC0gMTUpIC8gMzg0O1xuXHR2YXIgJGQgPSAoKCgoNzkgKiAkdTIgKyA3NzYpICogJHUyICsgMTQ4MikgKiAkdTIgLSAxOTIwKSAqICR1MiAtIDk0NSkgXG5cdFx0XHRcdC8gOTIxNjA7XG5cdHZhciAkZSA9ICgoKCgoMjcgKiAkdTIgKyAzMzkpICogJHUyICsgOTMwKSAqICR1MiAtIDE3ODIpICogJHUyIC0gNzY1KSAqICR1MlxuXHRcdFx0KyAxNzk1NSkgLyAzNjg2NDA7XG5cblx0dmFyICR4ID0gJHUgKiAoMSArICgkYSArICgkYiArICgkYyArICgkZCArICRlIC8gJG4pIC8gJG4pIC8gJG4pIC8gJG4pIC8gJG4pO1xuXG5cdGlmICgkbiA8PSBNYXRoLnBvdyhsb2cxMCgkcCksIDIpICsgMykge1xuXHRcdHZhciAkcm91bmQ7XG5cdFx0ZG8geyBcblx0XHRcdHZhciAkcDEgPSBfc3VidHByb2IoJG4sICR4KTtcblx0XHRcdHZhciAkbjEgPSAkbiArIDE7XG5cdFx0XHR2YXIgJGRlbHRhID0gKCRwMSAtICRwKSBcblx0XHRcdFx0LyBNYXRoLmV4cCgoJG4xICogTWF0aC5sb2coJG4xIC8gKCRuICsgJHggKiAkeCkpIFxuXHRcdFx0XHRcdCsgTWF0aC5sb2coJG4vJG4xLzIvTWF0aC5QSSkgLSAxIFxuXHRcdFx0XHRcdCsgKDEvJG4xIC0gMS8kbikgLyA2KSAvIDIpO1xuXHRcdFx0JHggKz0gJGRlbHRhO1xuXHRcdFx0JHJvdW5kID0gcm91bmRfdG9fcHJlY2lzaW9uKCRkZWx0YSwgTWF0aC5hYnMoaW50ZWdlcihsb2cxMChNYXRoLmFicygkeCkpLTQpKSk7XG5cdFx0fSB3aGlsZSAoKCR4KSAmJiAoJHJvdW5kICE9IDApKTtcblx0fVxuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIF9zdWJ0cHJvYiAoJG4sICR4KSB7XG5cblx0dmFyICRhO1xuICAgICAgICB2YXIgJGI7XG5cdHZhciAkdyA9IE1hdGguYXRhbjIoJHggLyBNYXRoLnNxcnQoJG4pLCAxKTtcblx0dmFyICR6ID0gTWF0aC5wb3coTWF0aC5jb3MoJHcpLCAyKTtcblx0dmFyICR5ID0gMTtcblxuXHRmb3IgKHZhciAkaSA9ICRuLTI7ICRpID49IDI7ICRpIC09IDIpIHtcblx0XHQkeSA9IDEgKyAoJGktMSkgLyAkaSAqICR6ICogJHk7XG5cdH0gXG5cblx0aWYgKCRuICUgMiA9PSAwKSB7XG5cdFx0JGEgPSBNYXRoLnNpbigkdykvMjtcblx0XHQkYiA9IC41O1xuXHR9IGVsc2Uge1xuXHRcdCRhID0gKCRuID09IDEpID8gMCA6IE1hdGguc2luKCR3KSpNYXRoLmNvcygkdykvTWF0aC5QSTtcblx0XHQkYj0gLjUgKyAkdy9NYXRoLlBJO1xuXHR9XG5cdHJldHVybiBtYXgoMCwgMSAtICRiIC0gJGEgKiAkeSk7XG59XG5cbmZ1bmN0aW9uIF9zdWJmICgkbiwgJG0sICRwKSB7XG5cdHZhciAkeDtcblxuXHRpZiAoJHAgPj0gMSB8fCAkcCA8PSAwKSB7XG5cdFx0dGhyb3coXCJJbnZhbGlkIHA6ICRwXFxuXCIpO1xuXHR9XG5cblx0aWYgKCRwID09IDEpIHtcblx0XHQkeCA9IDA7XG5cdH0gZWxzZSBpZiAoJG0gPT0gMSkge1xuXHRcdCR4ID0gMSAvIE1hdGgucG93KF9zdWJ0KCRuLCAwLjUgLSAkcCAvIDIpLCAyKTtcblx0fSBlbHNlIGlmICgkbiA9PSAxKSB7XG5cdFx0JHggPSBNYXRoLnBvdyhfc3VidCgkbSwgJHAvMiksIDIpO1xuXHR9IGVsc2UgaWYgKCRtID09IDIpIHtcblx0XHR2YXIgJHUgPSBfc3ViY2hpc3FyKCRtLCAxIC0gJHApO1xuXHRcdHZhciAkYSA9ICRtIC0gMjtcblx0XHQkeCA9IDEgLyAoJHUgLyAkbSAqICgxICtcblx0XHRcdCgoJHUgLSAkYSkgLyAyICtcblx0XHRcdFx0KCgoNCAqICR1IC0gMTEgKiAkYSkgKiAkdSArICRhICogKDcgKiAkbSAtIDEwKSkgLyAyNCArXG5cdFx0XHRcdFx0KCgoMiAqICR1IC0gMTAgKiAkYSkgKiAkdSArICRhICogKDE3ICogJG0gLSAyNikpICogJHVcblx0XHRcdFx0XHRcdC0gJGEgKiAkYSAqICg5ICogJG0gLSA2KVxuXHRcdFx0XHRcdCkvNDgvJG5cblx0XHRcdFx0KS8kblxuXHRcdFx0KS8kbikpO1xuXHR9IGVsc2UgaWYgKCRuID4gJG0pIHtcblx0XHQkeCA9IDEgLyBfc3ViZjIoJG0sICRuLCAxIC0gJHApXG5cdH0gZWxzZSB7XG5cdFx0JHggPSBfc3ViZjIoJG4sICRtLCAkcClcblx0fVxuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIF9zdWJmMiAoJG4sICRtLCAkcCkge1xuXHR2YXIgJHUgPSBfc3ViY2hpc3FyKCRuLCAkcCk7XG5cdHZhciAkbjIgPSAkbiAtIDI7XG5cdHZhciAkeCA9ICR1IC8gJG4gKiBcblx0XHQoMSArIFxuXHRcdFx0KCgkdSAtICRuMikgLyAyICsgXG5cdFx0XHRcdCgoKDQgKiAkdSAtIDExICogJG4yKSAqICR1ICsgJG4yICogKDcgKiAkbiAtIDEwKSkgLyAyNCArIFxuXHRcdFx0XHRcdCgoKDIgKiAkdSAtIDEwICogJG4yKSAqICR1ICsgJG4yICogKDE3ICogJG4gLSAyNikpICogJHUgXG5cdFx0XHRcdFx0XHQtICRuMiAqICRuMiAqICg5ICogJG4gLSA2KSkgLyA0OCAvICRtKSAvICRtKSAvICRtKTtcblx0dmFyICRkZWx0YTtcblx0ZG8ge1xuXHRcdHZhciAkeiA9IE1hdGguZXhwKFxuXHRcdFx0KCgkbiskbSkgKiBNYXRoLmxvZygoJG4rJG0pIC8gKCRuICogJHggKyAkbSkpIFxuXHRcdFx0XHQrICgkbiAtIDIpICogTWF0aC5sb2coJHgpXG5cdFx0XHRcdCsgTWF0aC5sb2coJG4gKiAkbSAvICgkbiskbSkpXG5cdFx0XHRcdC0gTWF0aC5sb2coNCAqIE1hdGguUEkpXG5cdFx0XHRcdC0gKDEvJG4gICsgMS8kbSAtIDEvKCRuKyRtKSkvNlxuXHRcdFx0KS8yKTtcblx0XHQkZGVsdGEgPSAoX3N1YmZwcm9iKCRuLCAkbSwgJHgpIC0gJHApIC8gJHo7XG5cdFx0JHggKz0gJGRlbHRhO1xuXHR9IHdoaWxlIChNYXRoLmFicygkZGVsdGEpPjNlLTQpO1xuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIF9zdWJjaGlzcXIgKCRuLCAkcCkge1xuXHR2YXIgJHg7XG5cblx0aWYgKCgkcCA+IDEpIHx8ICgkcCA8PSAwKSkge1xuXHRcdHRocm93KFwiSW52YWxpZCBwOiAkcFxcblwiKTtcblx0fSBlbHNlIGlmICgkcCA9PSAxKXtcblx0XHQkeCA9IDA7XG5cdH0gZWxzZSBpZiAoJG4gPT0gMSkge1xuXHRcdCR4ID0gTWF0aC5wb3coX3N1YnUoJHAgLyAyKSwgMik7XG5cdH0gZWxzZSBpZiAoJG4gPT0gMikge1xuXHRcdCR4ID0gLTIgKiBNYXRoLmxvZygkcCk7XG5cdH0gZWxzZSB7XG5cdFx0dmFyICR1ID0gX3N1YnUoJHApO1xuXHRcdHZhciAkdTIgPSAkdSAqICR1O1xuXG5cdFx0JHggPSBtYXgoMCwgJG4gKyBNYXRoLnNxcnQoMiAqICRuKSAqICR1IFxuXHRcdFx0KyAyLzMgKiAoJHUyIC0gMSlcblx0XHRcdCsgJHUgKiAoJHUyIC0gNykgLyA5IC8gTWF0aC5zcXJ0KDIgKiAkbilcblx0XHRcdC0gMi80MDUgLyAkbiAqICgkdTIgKiAoMyAqJHUyICsgNykgLSAxNikpO1xuXG5cdFx0aWYgKCRuIDw9IDEwMCkge1xuXHRcdFx0dmFyICR4MDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkcDE7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgJHo7XG5cdFx0XHRkbyB7XG5cdFx0XHRcdCR4MCA9ICR4O1xuXHRcdFx0XHRpZiAoJHggPCAwKSB7XG5cdFx0XHRcdFx0JHAxID0gMTtcblx0XHRcdFx0fSBlbHNlIGlmICgkbj4xMDApIHtcblx0XHRcdFx0XHQkcDEgPSBfc3VidXByb2IoKE1hdGgucG93KCgkeCAvICRuKSwgKDEvMykpIC0gKDEgLSAyLzkvJG4pKVxuXHRcdFx0XHRcdFx0LyBNYXRoLnNxcnQoMi85LyRuKSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoJHg+NDAwKSB7XG5cdFx0XHRcdFx0JHAxID0gMDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YXIgJGkwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyICRhO1xuXHRcdFx0XHRcdGlmICgoJG4gJSAyKSAhPSAwKSB7XG5cdFx0XHRcdFx0XHQkcDEgPSAyICogX3N1YnVwcm9iKE1hdGguc3FydCgkeCkpO1xuXHRcdFx0XHRcdFx0JGEgPSBNYXRoLnNxcnQoMi9NYXRoLlBJKSAqIE1hdGguZXhwKC0keC8yKSAvIE1hdGguc3FydCgkeCk7XG5cdFx0XHRcdFx0XHQkaTAgPSAxO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQkcDEgPSAkYSA9IE1hdGguZXhwKC0keC8yKTtcblx0XHRcdFx0XHRcdCRpMCA9IDI7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Zm9yICh2YXIgJGkgPSAkaTA7ICRpIDw9ICRuLTI7ICRpICs9IDIpIHtcblx0XHRcdFx0XHRcdCRhICo9ICR4IC8gJGk7XG5cdFx0XHRcdFx0XHQkcDEgKz0gJGE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdCR6ID0gTWF0aC5leHAoKCgkbi0xKSAqIE1hdGgubG9nKCR4LyRuKSAtIE1hdGgubG9nKDQqTWF0aC5QSSokeCkgXG5cdFx0XHRcdFx0KyAkbiAtICR4IC0gMS8kbi82KSAvIDIpO1xuXHRcdFx0XHQkeCArPSAoJHAxIC0gJHApIC8gJHo7XG5cdFx0XHRcdCR4ID0gcm91bmRfdG9fcHJlY2lzaW9uKCR4LCA1KTtcblx0XHRcdH0gd2hpbGUgKCgkbiA8IDMxKSAmJiAoTWF0aC5hYnMoJHgwIC0gJHgpID4gMWUtNCkpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gJHg7XG59XG5cbmZ1bmN0aW9uIGxvZzEwICgkbikge1xuXHRyZXR1cm4gTWF0aC5sb2coJG4pIC8gTWF0aC5sb2coMTApO1xufVxuIFxuZnVuY3Rpb24gbWF4ICgpIHtcblx0dmFyICRtYXggPSBhcmd1bWVudHNbMF07XG5cdGZvciAodmFyICRpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICgkbWF4IDwgYXJndW1lbnRzWyRpXSlcbiAgICAgICAgICAgICAgICAgICAgICAgICRtYXggPSBhcmd1bWVudHNbJGldO1xuXHR9XHRcblx0cmV0dXJuICRtYXg7XG59XG5cbmZ1bmN0aW9uIG1pbiAoKSB7XG5cdHZhciAkbWluID0gYXJndW1lbnRzWzBdO1xuXHRmb3IgKHZhciAkaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoJG1pbiA+IGFyZ3VtZW50c1skaV0pXG4gICAgICAgICAgICAgICAgICAgICAgICAkbWluID0gYXJndW1lbnRzWyRpXTtcblx0fVxuXHRyZXR1cm4gJG1pbjtcbn1cblxuZnVuY3Rpb24gcHJlY2lzaW9uICgkeCkge1xuXHRyZXR1cm4gTWF0aC5hYnMoaW50ZWdlcihsb2cxMChNYXRoLmFicygkeCkpIC0gU0lHTklGSUNBTlQpKTtcbn1cblxuZnVuY3Rpb24gcHJlY2lzaW9uX3N0cmluZyAoJHgpIHtcblx0aWYgKCR4KSB7XG5cdFx0cmV0dXJuIHJvdW5kX3RvX3ByZWNpc2lvbigkeCwgcHJlY2lzaW9uKCR4KSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIFwiMFwiO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHJvdW5kX3RvX3ByZWNpc2lvbiAoJHgsICRwKSB7XG4gICAgICAgICR4ID0gJHggKiBNYXRoLnBvdygxMCwgJHApO1xuICAgICAgICAkeCA9IE1hdGgucm91bmQoJHgpO1xuICAgICAgICByZXR1cm4gJHggLyBNYXRoLnBvdygxMCwgJHApO1xufVxuXG5mdW5jdGlvbiBpbnRlZ2VyICgkaSkge1xuICAgICAgICBpZiAoJGkgPiAwKVxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKCRpKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwoJGkpO1xufSIsImltcG9ydCB7dGRpc3RyfSBmcm9tIFwiLi9zdGF0aXN0aWNzLWRpc3RyaWJ1dGlvbnNcIlxyXG5cclxudmFyIHN1ID0gbW9kdWxlLmV4cG9ydHMuU3RhdGlzdGljc1V0aWxzID17fTtcclxuc3Uuc2FtcGxlQ29ycmVsYXRpb24gPSByZXF1aXJlKCcuLi9ib3dlcl9jb21wb25lbnRzL3NpbXBsZS1zdGF0aXN0aWNzL3NyYy9zYW1wbGVfY29ycmVsYXRpb24nKTtcclxuc3UubGluZWFyUmVncmVzc2lvbiA9IHJlcXVpcmUoJy4uL2Jvd2VyX2NvbXBvbmVudHMvc2ltcGxlLXN0YXRpc3RpY3Mvc3JjL2xpbmVhcl9yZWdyZXNzaW9uJyk7XHJcbnN1LmxpbmVhclJlZ3Jlc3Npb25MaW5lID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9zaW1wbGUtc3RhdGlzdGljcy9zcmMvbGluZWFyX3JlZ3Jlc3Npb25fbGluZScpO1xyXG5zdS5lcnJvckZ1bmN0aW9uID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9zaW1wbGUtc3RhdGlzdGljcy9zcmMvZXJyb3JfZnVuY3Rpb24nKTtcclxuc3Uuc3RhbmRhcmREZXZpYXRpb24gPSByZXF1aXJlKCcuLi9ib3dlcl9jb21wb25lbnRzL3NpbXBsZS1zdGF0aXN0aWNzL3NyYy9zdGFuZGFyZF9kZXZpYXRpb24nKTtcclxuc3Uuc2FtcGxlU3RhbmRhcmREZXZpYXRpb24gPSByZXF1aXJlKCcuLi9ib3dlcl9jb21wb25lbnRzL3NpbXBsZS1zdGF0aXN0aWNzL3NyYy9zYW1wbGVfc3RhbmRhcmRfZGV2aWF0aW9uJyk7XHJcbnN1LnZhcmlhbmNlID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9zaW1wbGUtc3RhdGlzdGljcy9zcmMvdmFyaWFuY2UnKTtcclxuc3UubWVhbiA9IHJlcXVpcmUoJy4uL2Jvd2VyX2NvbXBvbmVudHMvc2ltcGxlLXN0YXRpc3RpY3Mvc3JjL21lYW4nKTtcclxuc3UuelNjb3JlID0gcmVxdWlyZSgnLi4vYm93ZXJfY29tcG9uZW50cy9zaW1wbGUtc3RhdGlzdGljcy9zcmMvel9zY29yZScpO1xyXG5zdS5zdGFuZGFyZEVycm9yPSBhcnIgPT4gTWF0aC5zcXJ0KHN1LnZhcmlhbmNlKGFycikvKGFyci5sZW5ndGgtMSkpO1xyXG5cclxuXHJcbnN1LnRWYWx1ZT0gKGRlZ3JlZXNPZkZyZWVkb20sIGNyaXRpY2FsUHJvYmFiaWxpdHkpID0+IHsgLy9hcyBpbiBodHRwOi8vc3RhdHRyZWsuY29tL29ubGluZS1jYWxjdWxhdG9yL3QtZGlzdHJpYnV0aW9uLmFzcHhcclxuICAgIHJldHVybiB0ZGlzdHIoZGVncmVlc09mRnJlZWRvbSwgY3JpdGljYWxQcm9iYWJpbGl0eSk7XHJcbn07IiwiZXhwb3J0IGNsYXNzIFV0aWxzIHtcclxuICAgIHN0YXRpYyBTUVJUXzIgPSAxLjQxNDIxMzU2MjM3O1xyXG4gICAgLy8gdXNhZ2UgZXhhbXBsZSBkZWVwRXh0ZW5kKHt9LCBvYmpBLCBvYmpCKTsgPT4gc2hvdWxkIHdvcmsgc2ltaWxhciB0byAkLmV4dGVuZCh0cnVlLCB7fSwgb2JqQSwgb2JqQik7XHJcbiAgICBzdGF0aWMgZGVlcEV4dGVuZChvdXQpIHtcclxuXHJcbiAgICAgICAgdmFyIHV0aWxzID0gdGhpcztcclxuICAgICAgICB2YXIgZW1wdHlPdXQgPSB7fTtcclxuXHJcblxyXG4gICAgICAgIGlmICghb3V0ICYmIGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIEFycmF5LmlzQXJyYXkoYXJndW1lbnRzWzFdKSkge1xyXG4gICAgICAgICAgICBvdXQgPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgb3V0ID0gb3V0IHx8IHt9O1xyXG5cclxuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBpZiAoIXNvdXJjZSlcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzb3VyY2UuaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5KG91dFtrZXldKTtcclxuICAgICAgICAgICAgICAgIHZhciBpc09iamVjdCA9IHV0aWxzLmlzT2JqZWN0KG91dFtrZXldKTtcclxuICAgICAgICAgICAgICAgIHZhciBzcmNPYmogPSB1dGlscy5pc09iamVjdChzb3VyY2Vba2V5XSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0ICYmICFpc0FycmF5ICYmIHNyY09iaikge1xyXG4gICAgICAgICAgICAgICAgICAgIHV0aWxzLmRlZXBFeHRlbmQob3V0W2tleV0sIHNvdXJjZVtrZXldKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb3V0W2tleV0gPSBzb3VyY2Vba2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG91dDtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIG1lcmdlRGVlcCh0YXJnZXQsIHNvdXJjZSkge1xyXG4gICAgICAgIGxldCBvdXRwdXQgPSBPYmplY3QuYXNzaWduKHt9LCB0YXJnZXQpO1xyXG4gICAgICAgIGlmIChVdGlscy5pc09iamVjdE5vdEFycmF5KHRhcmdldCkgJiYgVXRpbHMuaXNPYmplY3ROb3RBcnJheShzb3VyY2UpKSB7XHJcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHNvdXJjZSkuZm9yRWFjaChrZXkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKFV0aWxzLmlzT2JqZWN0Tm90QXJyYXkoc291cmNlW2tleV0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoa2V5IGluIHRhcmdldCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ob3V0cHV0LCB7W2tleV06IHNvdXJjZVtrZXldfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRba2V5XSA9IFV0aWxzLm1lcmdlRGVlcCh0YXJnZXRba2V5XSwgc291cmNlW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKG91dHB1dCwge1trZXldOiBzb3VyY2Vba2V5XX0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG91dHB1dDtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgY3Jvc3MoYSwgYikge1xyXG4gICAgICAgIHZhciBjID0gW10sIG4gPSBhLmxlbmd0aCwgbSA9IGIubGVuZ3RoLCBpLCBqO1xyXG4gICAgICAgIGZvciAoaSA9IC0xOyArK2kgPCBuOykgZm9yIChqID0gLTE7ICsraiA8IG07KSBjLnB1c2goe3g6IGFbaV0sIGk6IGksIHk6IGJbal0sIGo6IGp9KTtcclxuICAgICAgICByZXR1cm4gYztcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGluZmVyVmFyaWFibGVzKGRhdGEsIGdyb3VwS2V5LCBpbmNsdWRlR3JvdXApIHtcclxuICAgICAgICB2YXIgcmVzID0gW107XHJcbiAgICAgICAgaWYgKGRhdGEubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHZhciBkID0gZGF0YVswXTtcclxuICAgICAgICAgICAgaWYgKGQgaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgcmVzID0gZC5tYXAoZnVuY3Rpb24gKHYsIGkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkID09PSAnb2JqZWN0Jykge1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZC5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJlcy5wdXNoKHByb3ApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghaW5jbHVkZUdyb3VwKSB7XHJcbiAgICAgICAgICAgIHZhciBpbmRleCA9IHJlcy5pbmRleE9mKGdyb3VwS2V5KTtcclxuICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIHJlcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXNcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGlzT2JqZWN0Tm90QXJyYXkoaXRlbSkge1xyXG4gICAgICAgIHJldHVybiAoaXRlbSAmJiB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkoaXRlbSkgJiYgaXRlbSAhPT0gbnVsbCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHN0YXRpYyBpc09iamVjdChhKSB7XHJcbiAgICAgICAgcmV0dXJuIGEgIT09IG51bGwgJiYgdHlwZW9mIGEgPT09ICdvYmplY3QnO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgaXNOdW1iZXIoYSkge1xyXG4gICAgICAgIHJldHVybiAhaXNOYU4oYSkgJiYgdHlwZW9mIGEgPT09ICdudW1iZXInO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgaXNGdW5jdGlvbihhKSB7XHJcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBhID09PSAnZnVuY3Rpb24nO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgaXNEYXRlKGEpe1xyXG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYSkgPT09ICdbb2JqZWN0IERhdGVdJ1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBpc1N0cmluZyhhKXtcclxuICAgICAgICByZXR1cm4gdHlwZW9mIGEgPT09ICdzdHJpbmcnIHx8IGEgaW5zdGFuY2VvZiBTdHJpbmdcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgaW5zZXJ0T3JBcHBlbmRTZWxlY3RvcihwYXJlbnQsIHNlbGVjdG9yLCBvcGVyYXRpb24sIGJlZm9yZSkge1xyXG4gICAgICAgIHZhciBzZWxlY3RvclBhcnRzID0gc2VsZWN0b3Iuc3BsaXQoLyhbXFwuXFwjXSkvKTtcclxuICAgICAgICB2YXIgZWxlbWVudCA9IHBhcmVudFtvcGVyYXRpb25dKHNlbGVjdG9yUGFydHMuc2hpZnQoKSwgYmVmb3JlKTsvL1wiOmZpcnN0LWNoaWxkXCJcclxuICAgICAgICB3aGlsZSAoc2VsZWN0b3JQYXJ0cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxlY3Rvck1vZGlmaWVyID0gc2VsZWN0b3JQYXJ0cy5zaGlmdCgpO1xyXG4gICAgICAgICAgICB2YXIgc2VsZWN0b3JJdGVtID0gc2VsZWN0b3JQYXJ0cy5zaGlmdCgpO1xyXG4gICAgICAgICAgICBpZiAoc2VsZWN0b3JNb2RpZmllciA9PT0gXCIuXCIpIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LmNsYXNzZWQoc2VsZWN0b3JJdGVtLCB0cnVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3Rvck1vZGlmaWVyID09PSBcIiNcIikge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQuYXR0cignaWQnLCBzZWxlY3Rvckl0ZW0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBlbGVtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBpbnNlcnRTZWxlY3RvcihwYXJlbnQsIHNlbGVjdG9yLCBiZWZvcmUpIHtcclxuICAgICAgICByZXR1cm4gVXRpbHMuaW5zZXJ0T3JBcHBlbmRTZWxlY3RvcihwYXJlbnQsIHNlbGVjdG9yLCBcImluc2VydFwiLCBiZWZvcmUpO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBhcHBlbmRTZWxlY3RvcihwYXJlbnQsIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgcmV0dXJuIFV0aWxzLmluc2VydE9yQXBwZW5kU2VsZWN0b3IocGFyZW50LCBzZWxlY3RvciwgXCJhcHBlbmRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIHNlbGVjdE9yQXBwZW5kKHBhcmVudCwgc2VsZWN0b3IsIGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgc2VsZWN0aW9uID0gcGFyZW50LnNlbGVjdChzZWxlY3Rvcik7XHJcbiAgICAgICAgaWYgKHNlbGVjdGlvbi5lbXB0eSgpKSB7XHJcbiAgICAgICAgICAgIGlmIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50LmFwcGVuZChlbGVtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gVXRpbHMuYXBwZW5kU2VsZWN0b3IocGFyZW50LCBzZWxlY3Rvcik7XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2VsZWN0aW9uO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgc2VsZWN0T3JJbnNlcnQocGFyZW50LCBzZWxlY3RvciwgYmVmb3JlKSB7XHJcbiAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHBhcmVudC5zZWxlY3Qoc2VsZWN0b3IpO1xyXG4gICAgICAgIGlmIChzZWxlY3Rpb24uZW1wdHkoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gVXRpbHMuaW5zZXJ0U2VsZWN0b3IocGFyZW50LCBzZWxlY3RvciwgYmVmb3JlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNlbGVjdGlvbjtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGxpbmVhckdyYWRpZW50KHN2ZywgZ3JhZGllbnRJZCwgcmFuZ2UsIHgxLCB5MSwgeDIsIHkyKSB7XHJcbiAgICAgICAgdmFyIGRlZnMgPSBVdGlscy5zZWxlY3RPckFwcGVuZChzdmcsIFwiZGVmc1wiKTtcclxuICAgICAgICB2YXIgbGluZWFyR3JhZGllbnQgPSBkZWZzLmFwcGVuZChcImxpbmVhckdyYWRpZW50XCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwiaWRcIiwgZ3JhZGllbnRJZCk7XHJcblxyXG4gICAgICAgIGxpbmVhckdyYWRpZW50XHJcbiAgICAgICAgICAgIC5hdHRyKFwieDFcIiwgeDEgKyBcIiVcIilcclxuICAgICAgICAgICAgLmF0dHIoXCJ5MVwiLCB5MSArIFwiJVwiKVxyXG4gICAgICAgICAgICAuYXR0cihcIngyXCIsIHgyICsgXCIlXCIpXHJcbiAgICAgICAgICAgIC5hdHRyKFwieTJcIiwgeTIgKyBcIiVcIik7XHJcblxyXG4gICAgICAgIC8vQXBwZW5kIG11bHRpcGxlIGNvbG9yIHN0b3BzIGJ5IHVzaW5nIEQzJ3MgZGF0YS9lbnRlciBzdGVwXHJcbiAgICAgICAgdmFyIHN0b3BzID0gbGluZWFyR3JhZGllbnQuc2VsZWN0QWxsKFwic3RvcFwiKVxyXG4gICAgICAgICAgICAuZGF0YShyYW5nZSk7XHJcblxyXG4gICAgICAgIHN0b3BzLmVudGVyKCkuYXBwZW5kKFwic3RvcFwiKTtcclxuXHJcbiAgICAgICAgc3RvcHMuYXR0cihcIm9mZnNldFwiLCAoZCwgaSkgPT4gaSAvIChyYW5nZS5sZW5ndGggLSAxKSlcclxuICAgICAgICAgICAgLmF0dHIoXCJzdG9wLWNvbG9yXCIsIGQgPT4gZCk7XHJcblxyXG4gICAgICAgIHN0b3BzLmV4aXQoKS5yZW1vdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgc2FuaXRpemVIZWlnaHQgPSBmdW5jdGlvbiAoaGVpZ2h0LCBjb250YWluZXIpIHtcclxuICAgICAgICByZXR1cm4gKGhlaWdodCB8fCBwYXJzZUludChjb250YWluZXIuc3R5bGUoJ2hlaWdodCcpLCAxMCkgfHwgNDAwKTtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIHNhbml0aXplV2lkdGggPSBmdW5jdGlvbiAod2lkdGgsIGNvbnRhaW5lcikge1xyXG4gICAgICAgIHJldHVybiAod2lkdGggfHwgcGFyc2VJbnQoY29udGFpbmVyLnN0eWxlKCd3aWR0aCcpLCAxMCkgfHwgOTYwKTtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGF2YWlsYWJsZUhlaWdodCA9IGZ1bmN0aW9uIChoZWlnaHQsIGNvbnRhaW5lciwgbWFyZ2luKSB7XHJcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIFV0aWxzLnNhbml0aXplSGVpZ2h0KGhlaWdodCwgY29udGFpbmVyKSAtIG1hcmdpbi50b3AgLSBtYXJnaW4uYm90dG9tKTtcclxuICAgIH07XHJcblxyXG4gICAgc3RhdGljIGF2YWlsYWJsZVdpZHRoID0gZnVuY3Rpb24gKHdpZHRoLCBjb250YWluZXIsIG1hcmdpbikge1xyXG4gICAgICAgIHJldHVybiBNYXRoLm1heCgwLCBVdGlscy5zYW5pdGl6ZVdpZHRoKHdpZHRoLCBjb250YWluZXIpIC0gbWFyZ2luLmxlZnQgLSBtYXJnaW4ucmlnaHQpO1xyXG4gICAgfTtcclxuXHJcbiAgICBzdGF0aWMgZ3VpZCgpIHtcclxuICAgICAgICBmdW5jdGlvbiBzNCgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKDEgKyBNYXRoLnJhbmRvbSgpKSAqIDB4MTAwMDApXHJcbiAgICAgICAgICAgICAgICAudG9TdHJpbmcoMTYpXHJcbiAgICAgICAgICAgICAgICAuc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHM0KCkgKyBzNCgpICsgJy0nICsgczQoKSArICctJyArIHM0KCkgKyAnLScgK1xyXG4gICAgICAgICAgICBzNCgpICsgJy0nICsgczQoKSArIHM0KCkgKyBzNCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vcGxhY2VzIHRleHRTdHJpbmcgaW4gdGV4dE9iaiwgYWRkcyBhbiBlbGxpcHNpcyBpZiB0ZXh0IGNhbid0IGZpdCBpbiB3aWR0aFxyXG4gICAgc3RhdGljIHBsYWNlVGV4dFdpdGhFbGxpcHNpcyh0ZXh0RDNPYmosIHRleHRTdHJpbmcsIHdpZHRoKXtcclxuICAgICAgICB2YXIgdGV4dE9iaiA9IHRleHREM09iai5ub2RlKCk7XHJcbiAgICAgICAgdGV4dE9iai50ZXh0Q29udGVudD10ZXh0U3RyaW5nO1xyXG5cclxuICAgICAgICB2YXIgbWFyZ2luID0gMDtcclxuICAgICAgICB2YXIgZWxsaXBzaXNMZW5ndGggPSA5O1xyXG4gICAgICAgIC8vZWxsaXBzaXMgaXMgbmVlZGVkXHJcbiAgICAgICAgaWYgKHRleHRPYmouZ2V0Q29tcHV0ZWRUZXh0TGVuZ3RoKCk+d2lkdGgrbWFyZ2luKXtcclxuICAgICAgICAgICAgZm9yICh2YXIgeD10ZXh0U3RyaW5nLmxlbmd0aC0zO3g+MDt4LT0xKXtcclxuICAgICAgICAgICAgICAgIGlmICh0ZXh0T2JqLmdldFN1YlN0cmluZ0xlbmd0aCgwLHgpK2VsbGlwc2lzTGVuZ3RoPD13aWR0aCttYXJnaW4pe1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHRPYmoudGV4dENvbnRlbnQ9dGV4dFN0cmluZy5zdWJzdHJpbmcoMCx4KStcIi4uLlwiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRleHRPYmoudGV4dENvbnRlbnQ9XCIuLi5cIjsgLy9jYW4ndCBwbGFjZSBhdCBhbGxcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgcGxhY2VUZXh0V2l0aEVsbGlwc2lzQW5kVG9vbHRpcCh0ZXh0RDNPYmosIHRleHRTdHJpbmcsIHdpZHRoLCB0b29sdGlwKXtcclxuICAgICAgICB2YXIgZWxsaXBzaXNQbGFjZWQgPSBVdGlscy5wbGFjZVRleHRXaXRoRWxsaXBzaXModGV4dEQzT2JqLCB0ZXh0U3RyaW5nLCB3aWR0aCk7XHJcbiAgICAgICAgaWYoZWxsaXBzaXNQbGFjZWQgJiYgdG9vbHRpcCl7XHJcbiAgICAgICAgICAgIHRleHREM09iai5vbihcIm1vdXNlb3ZlclwiLCBmdW5jdGlvbiAoZCkge1xyXG4gICAgICAgICAgICAgICAgdG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oMjAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgLjkpO1xyXG4gICAgICAgICAgICAgICAgdG9vbHRpcC5odG1sKHRleHRTdHJpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKFwibGVmdFwiLCAoZDMuZXZlbnQucGFnZVggKyA1KSArIFwicHhcIilcclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJ0b3BcIiwgKGQzLmV2ZW50LnBhZ2VZIC0gMjgpICsgXCJweFwiKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0ZXh0RDNPYmoub24oXCJtb3VzZW91dFwiLCBmdW5jdGlvbiAoZCkge1xyXG4gICAgICAgICAgICAgICAgdG9vbHRpcC50cmFuc2l0aW9uKClcclxuICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oNTAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGdldEZvbnRTaXplKGVsZW1lbnQpe1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50LCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKFwiZm9udC1zaXplXCIpO1xyXG4gICAgfVxyXG59XHJcbiJdfQ== diff --git a/dist/odc-d3.min.js b/dist/odc-d3.min.js index 6c4f514..c4d2fef 100644 --- a/dist/odc-d3.min.js +++ b/dist/odc-d3.min.js @@ -1,5 +1,5 @@ !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.ODCD3=t()}}(function(){return function t(e,i,n){function r(a,l){if(!i[a]){if(!e[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(o)return o(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var u=i[a]={exports:{}};e[a][0].call(u.exports,function(t){var i=e[a][1][t];return r(i?i:t)},u,u.exports,t,e,i,n)}return i[a].exports}for(var o="function"==typeof require&&require,a=0;a1||e>=2)&&(c=e),t):c},t.shape=function(i,n){return arguments.length?(("rect"==i||"circle"==i||"line"==i||"path"==i&&"string"==typeof n)&&(r=i,e=n),t):r},t.shapeWidth=function(e){return arguments.length?(o=+e,t):o},t.shapeHeight=function(e){return arguments.length?(a=+e,t):a},t.shapeRadius=function(e){return arguments.length?(l=+e,t):l},t.shapePadding=function(e){return arguments.length?(s=+e,t):s},t.labels=function(e){return arguments.length?(u=e,t):u},t.labelAlign=function(e){return arguments.length?("start"!=e&&"end"!=e&&"middle"!=e||(v=e),t):v},t.labelFormat=function(e){return arguments.length?(d=e,t):d},t.labelOffset=function(e){return arguments.length?(g=+e,t):g},t.labelDelimiter=function(e){return arguments.length?(y=e,t):y},t.useClass=function(e){return arguments.length?(e!==!0&&e!==!1||(h=e),t):h},t.orient=function(e){return arguments.length?(e=e.toLowerCase(),"horizontal"!=e&&"vertical"!=e||(m=e),t):m},t.ascending=function(e){return arguments.length?(b=!!e,t):b},t.classPrefix=function(e){return arguments.length?(p=e,t):p},t.title=function(e){return arguments.length?(f=e,t):f},d3.rebind(t,x,"on"),t}},{"./legend":3}],3:[function(t,e,i){"use strict";e.exports={d3_identity:function(t){return t},d3_mergeLabels:function(t,e){if(0===e.length)return t;t=t?t:[];for(var i=e.length;i1)n=e;else for(var r=t.domain(),o=(r[r.length-1]-r[0])/(e-1),a=0;a1||e>=2)&&(l=e),t):l},t.shape=function(i,n){return arguments.length?("rect"!=i&&"circle"!=i&&"line"!=i||(r=i,e=n),t):r},t.shapeWidth=function(e){return arguments.length?(o=+e,t):o},t.shapePadding=function(e){return arguments.length?(a=+e,t):a},t.labels=function(e){return arguments.length?(s=e,t):s},t.labelAlign=function(e){return arguments.length?("start"!=e&&"end"!=e&&"middle"!=e||(f=e),t):f},t.labelFormat=function(e){return arguments.length?(p=e,t):p},t.labelOffset=function(e){return arguments.length?(h=+e,t):h},t.labelDelimiter=function(e){return arguments.length?(d=e,t):d},t.orient=function(e){return arguments.length?(e=e.toLowerCase(),"horizontal"!=e&&"vertical"!=e||(g=e),t):g},t.ascending=function(e){return arguments.length?(v=!!e,t):v},t.classPrefix=function(e){return arguments.length?(c=e,t):c},t.title=function(e){return arguments.length?(u=e,t):u},d3.rebind(t,y,"on"),t}},{"./legend":3}],5:[function(t,e,i){"use strict";var n=t("./legend");e.exports=function(){function t(t){var b=n.d3_calcType(e,y,s,c,h,g),x=t.selectAll("g").data([e]);x.enter().append("g").attr("class",u+"legendCells");var C=x.selectAll("."+u+"cell").data(b.data),w=C.enter().append("g",".cell").attr("class",u+"cell").style("opacity",1e-6),k=(w.append(i).attr("class",u+"swatch"),C.select("g."+u+"cell "+i));n.d3_addEvents(w,m),C.exit().transition().style("opacity",0).remove(),n.d3_drawShapes(i,k,o,r,a,b.feature),n.d3_addText(x,w,b.labels,u);var O,P,_=C.select("text"),S=k[0].map(function(t){return t.getBBox()}),j=d3.max(S,function(t){return t.height}),z=d3.max(S,function(t){return t.width}),A="start"==f?0:"middle"==f?.5:1;"vertical"===v?(O=function(t,e){return"translate(0, "+e*(j+l)+")"},P=function(t,e){return"translate("+(z+d)+","+(S[e].y+S[e].height/2+5)+")"}):"horizontal"===v&&(O=function(t,e){return"translate("+e*(z+l)+",0)"},P=function(t,e){return"translate("+(S[e].width*A+S[e].x)+","+(j+d)+")"}),n.d3_placement(v,C,O,_,P,f),n.d3_title(t,x,p,u),C.transition().style("opacity",1)}var e=d3.scale.linear(),i="path",r=15,o=15,a=10,l=5,s=[5],c=[],u="",p="",h=d3.format(".01f"),f="middle",d=10,g="to",v="vertical",y=!1,m=d3.dispatch("cellover","cellout","cellclick");return t.scale=function(i){return arguments.length?(e=i,t):e},t.cells=function(e){return arguments.length?((e.length>1||e>=2)&&(s=e),t):s},t.shapePadding=function(e){return arguments.length?(l=+e,t):l},t.labels=function(e){return arguments.length?(c=e,t):c},t.labelAlign=function(e){return arguments.length?("start"!=e&&"end"!=e&&"middle"!=e||(f=e),t):f},t.labelFormat=function(e){return arguments.length?(h=e,t):h},t.labelOffset=function(e){return arguments.length?(d=+e,t):d},t.labelDelimiter=function(e){return arguments.length?(g=e,t):g},t.orient=function(e){return arguments.length?(e=e.toLowerCase(),"horizontal"!=e&&"vertical"!=e||(v=e),t):v},t.ascending=function(e){return arguments.length?(y=!!e,t):y},t.classPrefix=function(e){return arguments.length?(u=e,t):u},t.title=function(e){return arguments.length?(p=e,t):p},d3.rebind(t,m,"on"),t}},{"./legend":3}],6:[function(t,e,i){"use strict";function n(t){var e=1/(1+.5*Math.abs(t)),i=e*Math.exp(-Math.pow(t,2)-1.26551223+1.00002368*e+.37409196*Math.pow(e,2)+.09678418*Math.pow(e,3)-.18628806*Math.pow(e,4)+.27886807*Math.pow(e,5)-1.13520398*Math.pow(e,6)+1.48851587*Math.pow(e,7)-.82215223*Math.pow(e,8)+.17087277*Math.pow(e,9));return t>=0?1-i:i-1}e.exports=n},{}],7:[function(t,e,i){"use strict";function n(t){var e,i,n=t.length;if(1===n)e=0,i=t[0][1];else{for(var r,o,a,l=0,s=0,c=0,u=0,p=0;pr&&(o=t.labels[r]),i.labels.push(o),i.labelByVariable[n]=o})}},{key:"setupCorrelationMatrix",value:function(){var t=this,e=this.data,i=this.plot.correlation.matrix=[],n=this.plot.correlation.matrix.cells=[],r=this.plot,o={};r.variables.forEach(function(t,i){o[t]=e.map(function(e){return r.x.value(e,t)})}),r.variables.forEach(function(e,a){var l=[];i.push(l),r.variables.forEach(function(i,r){var s=1;e!=i&&(s=t.config.correlation.value(o[e],o[i]));var c={rowVar:e,colVar:i,row:a,col:r,value:s};l.push(c),n.push(c)})})}},{key:"update",value:function(t){l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t),this.updateCells(),this.updateVariableLabels(),this.config.showLegend&&this.updateLegend()}},{key:"updateVariableLabels",value:function(){this.plot.labelClass=this.prefixClass("label"),this.updateAxisX(),this.updateAxisY()}},{key:"updateAxisX",value:function(){var t=this,e=t.plot,i=e.labelClass,n=i+"-x",r=t.svgG.selectAll("text."+n).data(e.variables,function(t,e){return e});r.enter().append("text").attr("class",function(t,e){return i+" "+n+" "+n+"-"+e}),r.attr("x",function(t,i){return i*e.cellSize+e.cellSize/2}).attr("y",e.height).attr("dx",-2).attr("dy",5).attr("text-anchor","end").text(function(t){return e.labelByVariable[t]}),this.config.rotateLabelsX&&r.attr("transform",function(t,i){return"rotate(-45, "+(i*e.cellSize+e.cellSize/2)+", "+e.height+")"});var o=t.computeXAxisLabelsWidth();r.each(function(e){c.Utils.placeTextWithEllipsisAndTooltip(d3.select(this),e,o,!!t.config.showTooltip&&t.plot.tooltip)}),r.exit().remove()}},{key:"updateAxisY",value:function(){var t=this,e=t.plot,i=e.labelClass,n=e.labelClass+"-y",r=t.svgG.selectAll("text."+n).data(e.variables);r.enter().append("text"),r.attr("x",0).attr("y",function(t,i){return i*e.cellSize+e.cellSize/2}).attr("dx",-2).attr("text-anchor","end").attr("class",function(t,e){return i+" "+n+" "+n+"-"+e}).text(function(t){return e.labelByVariable[t]}),this.config.rotateLabelsY&&r.attr("transform",function(t,i){return"rotate(-45, 0, "+(i*e.cellSize+e.cellSize/2)+")"}).attr("text-anchor","end");var o=t.computeYAxisLabelsWidth();r.each(function(e){c.Utils.placeTextWithEllipsisAndTooltip(d3.select(this),e,o,!!t.config.showTooltip&&t.plot.tooltip)}),r.exit().remove()}},{key:"computeYAxisLabelsWidth",value:function(){var t=this.plot.margin.left;if(!this.config.rotateLabelsY)return t;t*=c.Utils.SQRT_2;var e=11;return t-=e/2}},{key:"computeXAxisLabelsWidth",value:function(t){if(!this.config.rotateLabelsX)return this.plot.cellSize-2;var e=this.plot.margin.bottom;e*=c.Utils.SQRT_2;var i=11;return e-=i/2}},{key:"updateCells",value:function(){var t=this,e=t.plot,i=t.prefixClass("cell"),n=e.correlation.shape.type,r=t.svgG.selectAll("g."+i).data(e.correlation.matrix.cells);r.enter().append("g").classed(i,!0);r.attr("transform",function(t){return"translate("+(e.cellSize*t.col+e.cellSize/2)+","+(e.cellSize*t.row+e.cellSize/2)+")"}),r.classed(t.config.cssClassPrefix+"selectable",!!t.scatterPlot);var o="*:not(.cell-shape-"+n+")",a=r.selectAll(o);a.remove();var l=r.selectOrAppend(n+".cell-shape-"+n);"circle"==e.correlation.shape.type&&l.attr("r",e.correlation.shape.radius).attr("cx",0).attr("cy",0),"ellipse"==e.correlation.shape.type&&l.attr("rx",e.correlation.shape.radiusX).attr("ry",e.correlation.shape.radiusY).attr("cx",0).attr("cy",0).attr("transform",function(t){return"rotate("+e.correlation.shape.rotateVal(t.value)+")"; -}),"rect"==e.correlation.shape.type&&l.attr("width",e.correlation.shape.size).attr("height",e.correlation.shape.size).attr("x",-e.cellSize/2).attr("y",-e.cellSize/2),l.style("fill",function(t){return e.correlation.color.scale(t.value)});var s=[],c=[];if(e.tooltip&&(s.push(function(t){e.tooltip.transition().duration(200).style("opacity",.9);var i=t.value;e.tooltip.html(i).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}),c.push(function(t){e.tooltip.transition().duration(500).style("opacity",0)})),t.config.highlightLabels){var u=t.config.cssClassPrefix+"highlight",p=function(t){return e.labelClass+"-x-"+t.col},h=function(t){return e.labelClass+"-y-"+t.row};s.push(function(e){t.svgG.selectAll("text."+p(e)).classed(u,!0),t.svgG.selectAll("text."+h(e)).classed(u,!0)}),c.push(function(e){t.svgG.selectAll("text."+p(e)).classed(u,!1),t.svgG.selectAll("text."+h(e)).classed(u,!1)})}r.on("mouseover",function(t){s.forEach(function(e){return e(t)})}).on("mouseout",function(t){c.forEach(function(e){return e(t)})}),r.on("click",function(e){t.trigger("cell-selected",e)}),r.exit().remove()}},{key:"updateLegend",value:function(){var t=this.plot,e=this.plot.width+10,i=0,n=10,r=this.plot.height-2,o=t.correlation.color.scale;t.legend=new p.Legend(this.svg,this.svgG,o,e,i).linearGradientBar(n,r)}},{key:"attachScatterPlot",value:function(t,e){var i=this,n=this;e=e||{};var r={height:n.plot.height+n.config.margin.top+n.config.margin.bottom,width:n.plot.height+n.config.margin.top+n.config.margin.bottom,groups:{key:n.config.groups.key,label:n.config.groups.label},guides:!0,showLegend:!1};n.scatterPlot=!0,r=c.Utils.deepExtend(r,e),this.update(),this.on("cell-selected",function(e){r.x={key:e.rowVar,label:n.plot.labelByVariable[e.rowVar]},r.y={key:e.colVar,label:n.plot.labelByVariable[e.colVar]},n.scatterPlot&&n.scatterPlot!==!0?n.scatterPlot.setConfig(r).init():(n.scatterPlot=new h.ScatterPlot(t,n.data,r),i.attach("ScatterPlot",n.scatterPlot))})}}]),e}(s.Chart)},{"./chart":20,"./legend":27,"./scatterplot":30,"./statistics-utils":32,"./utils":33}],22:[function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0}),i.D3Extensions=void 0;var r=function(){function t(t,e){for(var i=0;i=1&&(e=" M",t=Number(t/1e6).toFixed(3));var i=Intl.NumberFormat();return i.format(t)+e}},t&&c.Utils.deepExtend(i,t),i}return o(e,t),e}(s.HeatmapConfig));i.HeatmapTimeSeries=function(t){function e(t,i,o){return n(this,e),r(this,Object.getPrototypeOf(e).call(this,t,i,new u(o)))}return o(e,t),a(e,[{key:"setConfig",value:function(t){return l(Object.getPrototypeOf(e.prototype),"setConfig",this).call(this,new u(t))}},{key:"setupValuesBeforeGroupsSort",value:function(){var t=this;if(this.plot.x.timeFormat=this.config.x.format,this.config.x.displayFormat&&!this.plot.x.timeFormat&&this.guessTimeFormat(),l(Object.getPrototypeOf(e.prototype),"setupValuesBeforeGroupsSort",this).call(this),this.config.x.fillMissing){var i=this;this.initTimeFormatAndInterval(),this.plot.x.intervalStep=this.config.x.intervalStep||1,this.plot.x.timeParser=this.getTimeParser(),this.plot.x.uniqueValues.sort(this.config.x.sortComparator);var n=null;this.plot.x.uniqueValues.forEach(function(e,r){var o=t.parseTime(e);if(null===n)return void(n=o);for(var a=i.nextTimeTickValue(n),l=[],s=0;i.compareTimeValues(a,o)<=0&&(s++,!(s>100));){var c={},u=i.formatTime(a);c[t.config.x.key]=u,i.updateGroups(c,u,i.plot.x.groups,i.config.x.groups),l.push(a),a=i.nextTimeTickValue(a)}n=o})}}},{key:"parseTime",value:function(t){var e=this.getTimeParser();return e.parse(t)}},{key:"formatTime",value:function(t){var e=this.getTimeParser();return e(t)}},{key:"formatValueX",value:function(t){if(this.config.x.formatter)return this.config.x.formatter.call(this.config,t);if(this.config.x.displayFormat){var e=this.parseTime(t);return d3.time.format(this.config.x.displayFormat)(e)}return this.plot.x.timeFormat&&c.Utils.isDate(t)?this.formatTime(t):t}},{key:"compareTimeValues",value:function(t,e){return t-e}},{key:"timeValuesEqual",value:function(t,e){var i=this.plot.x.timeParser;return i(t)===i(e)}},{key:"nextTimeTickValue",value:function(t){var e=this.plot.x.interval;return d3.time[e].offset(t,this.plot.x.intervalStep)}},{key:"initPlot",value:function(){l(Object.getPrototypeOf(e.prototype),"initPlot",this).call(this),this.config.z.fillMissing&&this.plot.matrix.forEach(function(t,e){var i=void 0;t.forEach(function(t,e){void 0===t.value&&void 0!==i&&(t.value=i,t.missing=!0),i=t.value})})}},{key:"update",value:function(t){l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t)}},{key:"initTimeFormatAndInterval",value:function(){this.plot.x.interval=this.config.x.interval,this.plot.x.timeFormat||this.guessTimeFormat(),!this.plot.x.interval&&this.plot.x.timeFormat&&this.guessInterval()}},{key:"guessTimeFormat",value:function(){for(var t=this,e=0;e=0)return void(t.plot.x.interval=i.name)}}},{key:"getTimeParser",value:function(){return this.plot.x.timeParser||(this.plot.x.timeParser=d3.time.format(this.plot.x.timeFormat)),this.plot.x.timeParser}}]),e}(s.Heatmap)},{"./chart":20,"./heatmap":24,"./statistics-utils":32,"./utils":33}],24:[function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(i,"__esModule",{value:!0}),i.Heatmap=i.HeatmapConfig=void 0;var a=function(){function t(t,e){for(var i=0;is)&&(s=f)}),e.plot.valueMap=a,e.plot.groupByX||(n.groups.values=n.uniqueValues),e.plot.groupByY||(r.groups.values=r.uniqueValues),this.setupValuesBeforeGroupsSort(),n.gaps=[],n.totalValuesCount=0,n.allValuesList=[],this.sortGroups(n,n.groups,i.x),r.gaps=[],r.totalValuesCount=0,r.allValuesList=[],this.sortGroups(r,r.groups,i.y),o.min=l,o.max=s}},{key:"setupValuesBeforeGroupsSort",value:function(){}},{key:"buildCells",value:function(){var t=this,e=t.plot.x,i=t.plot.y,n=(t.plot.z,t.plot.valueMap),r=t.plot.cells=[],o=t.plot.matrix=[];i.allValuesList.forEach(function(t,i){var a=[];o.push(a),e.allValuesList.forEach(function(e,o){var l=void 0;try{l=n[t.group.index][e.group.index][t.val][e.val]}catch(s){}var c={rowVar:t,colVar:e,row:i,col:o,value:l};a.push(c),r.push(c)})})}},{key:"updateGroups",value:function(t,e,i,n){var r=this.config,o=i;return n.keys.forEach(function(e,a){o.key=e,o.children||(o.children={});var l=n.value.call(r,t,e);o.children.hasOwnProperty(l)||(i.lastIndex++,o.children[l]={values:[],children:null,groupingValue:l,level:o.level+1,index:i.lastIndex,key:e}),o=o.children[l]}),o.values.indexOf(e)===-1&&o.values.push(e),o}},{key:"sortGroups",value:function(t,i,n,r){if(n.groups.labels&&n.groups.labels.length>i.level?i.label=n.groups.labels[i.level]:i.label=i.key,r||(r=[0]),r.length<=i.level&&r.push(0),i.allValuesCount=i.allValuesCount||0,i.allValuesBeforeCount=i.allValuesBeforeCount||0,i.gaps=r.slice(),i.gapsBefore=r.slice(),i.gapsSize=e.computeGapsSize(i.gaps),i.gapsBeforeSize=i.gapsSize,i.values&&(n.sortLabels&&i.values.sort(n.sortComparator),i.values.forEach(function(e){return t.allValuesList.push({val:e,group:i})}),i.allValuesBeforeCount=t.totalValuesCount,t.totalValuesCount+=i.values.length,i.allValuesCount+=i.values.length),i.childrenList=[],i.children){var o=0;for(var a in i.children)if(i.children.hasOwnProperty(a)){var l=i.children[a];i.childrenList.push(l),o++,this.sortGroups(t,l,n,r),i.allValuesCount+=l.allValuesCount,r[i.level]+=1}r&&o>1&&(r[i.level]-=1),i.gapsInside=[],r.forEach(function(t,e){i.gapsInside.push(t-(i.gapsBefore[e]||0))}),i.gapsInsideSize=e.computeGapsSize(i.gapsInside),t.gaps.length-1}):this.data}},{key:"drawAxisX",value:function(){var t=this,e=t.plot,i=this.config.x,n=t.svgG.selectOrAppend("g."+t.prefixClass("axis-x")+"."+t.prefixClass("axis")+(t.config.guides?"":"."+t.prefixClass("no-guides"))).attr("transform","translate(0,"+e.height+")"),r=n;t.config.transition&&(r=n.transition().ease("sin-in-out")),r.call(e.x.axis),n.selectOrAppend("text."+t.prefixClass("label")).attr("transform","translate("+e.width/2+","+e.margin.bottom+")").attr("dy","-1em").style("text-anchor","middle").text(i.label)}},{key:"drawAxisY",value:function(){var t=this,e=t.plot,i=this.config.y,n=t.svgG.selectOrAppend("g."+t.prefixClass("axis-y")+"."+t.prefixClass("axis")+(t.config.guides?"":"."+t.prefixClass("no-guides"))),r=n;t.config.transition&&(r=n.transition().ease("sin-in-out")),r.call(e.y.axis),n.selectOrAppend("text."+t.prefixClass("label")).attr("transform","translate("+-e.margin.left+","+e.height/2+")rotate(-90)").attr("dy","1em").style("text-anchor","middle").text(i.label)}},{key:"drawHistogram",value:function(){var t=this,e=t.plot,i=this.prefixClass("layer"),n=this.prefixClass("bar"),r=t.svgG.selectAll("."+i).data(e.stackedHistograms);r.enter().append("g").attr("class",i);var o=r.selectAll("."+n).data(function(t){return t.histogramBins});o.enter().append("g").attr("class",n).append("rect").attr("x",1);var a=o.select("rect"),l=a,s=o,c=r;this.transitionEnabled()&&(l=a.transition(),s=o.transition(),c=r.transition()),s.attr("transform",function(t){return"translate("+e.x.scale(t.x)+","+e.y.scale(t.y0+t.y)+")"});var u=e.histogramBins.length?e.x.scale(e.histogramBins[0].dx):0;l.attr("width",u-e.x.scale(0)-1).attr("height",function(t){return e.height-e.y.scale(t.y)}),this.plot.color&&c.attr("fill",this.plot.color),e.tooltip&&o.on("mouseover",function(t){e.tooltip.transition().duration(200).style("opacity",.9),e.tooltip.html(t.y).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){e.tooltip.transition().duration(500).style("opacity",0)}),r.exit().remove(),o.exit().remove()}},{key:"update",value:function(t){l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t),this.drawAxisX(),this.drawAxisY(),this.drawHistogram(),this.updateLegend()}},{key:"updateLegend",value:function(){var t=this,e=this.plot,i=e.colorCategory;if((!i.domain()||i.domain().length<2)&&(e.showLegend=!1),!e.showLegend)return void(e.legend&&e.legend.container&&e.legend.container.remove());var n=this.plot.width+this.config.legend.margin,r=this.config.legend.margin;e.legend=new u.Legend(this.svg,this.svgG,i,n,r),e.legendColor=e.legend.color().shapeWidth(this.config.legend.shapeWidth).orient("vertical").scale(i),e.legendColor.on("cellclick",function(e){return t.onLegendCellClick(e)}),e.legend.container.call(e.legendColor)}},{key:"onLegendCellClick",value:function(t){this.updateEnabledGroups(t);var e=this.enabledGroups.indexOf(t)<0;this.plot.legend.container.selectAll("g.cell").each(function(i){i==t&&d3.select(this).classed("odc-disabled",e)}),this.init()}},{key:"updateEnabledGroups",value:function(t){this.enabledGroups||(this.enabledGroups=this.plot.colorCategory.domain().slice());var e=this.enabledGroups.indexOf(t);e<0?this.enabledGroups.push(t):this.enabledGroups.splice(e,1)}},{key:"setData",value:function(t){l(Object.getPrototypeOf(e.prototype),"setData",this).call(this,t),this.enabledGroups=null}}]),e}(s.Chart)},{"./chart":20,"./legend":27,"./utils":33}],26:[function(t,e,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.Legend=i.StatisticsUtils=i.BarChartConfig=i.BarChart=i.HistogramConfig=i.Histogram=i.HeatmapTimeSeriesConfig=i.HeatmapTimeSeries=i.HeatmapConfig=i.Heatmap=i.RegressionConfig=i.Regression=i.CorrelationMatrixConfig=i.CorrelationMatrix=i.ScatterPlotMatrixConfig=i.ScatterPlotMatrix=i.ScatterPlotConfig=i.ScatterPlot=void 0;var n=t("./scatterplot");Object.defineProperty(i,"ScatterPlot",{enumerable:!0,get:function(){return n.ScatterPlot}}),Object.defineProperty(i,"ScatterPlotConfig",{enumerable:!0,get:function(){return n.ScatterPlotConfig}});var r=t("./scatterplot-matrix");Object.defineProperty(i,"ScatterPlotMatrix",{enumerable:!0,get:function(){return r.ScatterPlotMatrix}}),Object.defineProperty(i,"ScatterPlotMatrixConfig",{enumerable:!0,get:function(){return r.ScatterPlotMatrixConfig}});var o=t("./correlation-matrix");Object.defineProperty(i,"CorrelationMatrix",{enumerable:!0,get:function(){return o.CorrelationMatrix}}),Object.defineProperty(i,"CorrelationMatrixConfig",{enumerable:!0,get:function(){return o.CorrelationMatrixConfig}});var a=t("./regression");Object.defineProperty(i,"Regression",{enumerable:!0,get:function(){return a.Regression}}),Object.defineProperty(i,"RegressionConfig",{enumerable:!0,get:function(){return a.RegressionConfig}});var l=t("./heatmap");Object.defineProperty(i,"Heatmap",{enumerable:!0,get:function(){return l.Heatmap}}),Object.defineProperty(i,"HeatmapConfig",{enumerable:!0,get:function(){return l.HeatmapConfig}});var s=t("./heatmap-timeseries");Object.defineProperty(i,"HeatmapTimeSeries",{enumerable:!0,get:function(){return s.HeatmapTimeSeries}}),Object.defineProperty(i,"HeatmapTimeSeriesConfig",{enumerable:!0,get:function(){return s.HeatmapTimeSeriesConfig}});var c=t("./histogram");Object.defineProperty(i,"Histogram",{enumerable:!0,get:function(){return c.Histogram}}),Object.defineProperty(i,"HistogramConfig",{enumerable:!0,get:function(){return c.HistogramConfig}});var u=t("./bar-chart");Object.defineProperty(i,"BarChart",{enumerable:!0,get:function(){return u.BarChart}}),Object.defineProperty(i,"BarChartConfig",{enumerable:!0,get:function(){return u.BarChartConfig}});var p=t("./statistics-utils");Object.defineProperty(i,"StatisticsUtils",{enumerable:!0,get:function(){return p.StatisticsUtils}});var h=t("./legend");Object.defineProperty(i,"Legend",{enumerable:!0,get:function(){return h.Legend}});var f=t("./d3-extensions");f.D3Extensions.extend()},{"./bar-chart":19,"./correlation-matrix":21,"./d3-extensions":22,"./heatmap":24,"./heatmap-timeseries":23,"./histogram":25,"./legend":27,"./regression":28,"./scatterplot":30,"./scatterplot-matrix":29,"./statistics-utils":32}],27:[function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0}),i.Legend=void 0;var r=function(){function t(t,e){for(var i=0;i-1});return e}},{key:"setupVariables",value:function(){var t=this.config.variables,e=this.data,i=this.plot;i.domainByVariable={},i.variables=t.keys,i.variables&&i.variables.length||(i.variables=u.Utils.inferVariables(e,this.config.groups.key,this.config.includeInPlot)),i.labels=[],i.labelByVariable={},i.variables.forEach(function(n,r){i.domainByVariable[n]=d3.extent(e,function(e){return t.value(e,n)});var o=n;t.labels&&t.labels.length>r&&(o=t.labels[r]),i.labels.push(o),i.labelByVariable[n]=o}),i.subplots=[]}},{key:"setupX",value:function(){var t=this.plot,e=t.x,i=this.config;e.value=i.variables.value,e.scale=d3.scale[i.x.scale]().range([i.padding/2,t.size-i.padding/2]),e.map=function(t,i){return e.scale(e.value(t,i))},e.axis=d3.svg.axis().scale(e.scale).orient(i.x.orient).ticks(i.ticks),e.axis.tickSize(t.size*t.variables.length)}},{key:"setupY",value:function(){var t=this.plot,e=t.y,i=this.config;e.value=i.variables.value,e.scale=d3.scale[i.y.scale]().range([t.size-i.padding/2,i.padding/2]),e.map=function(t,i){return e.scale(e.value(t,i))},e.axis=d3.svg.axis().scale(e.scale).orient(i.y.orient).ticks(i.ticks),e.axis.tickSize(-t.size*t.variables.length)}},{key:"update",value:function(t){function i(t){var e=n.plot;e.subplots.push(t);var i=d3.select(this);e.x.scale.domain(e.domainByVariable[t.x]),e.y.scale.domain(e.domainByVariable[t.y]);var r=n.prefixClass("frame");i.selectOrAppend("rect."+r).attr("class",r).attr("x",o.padding/2).attr("y",o.padding/2).attr("width",o.size-o.padding).attr("height",o.size-o.padding),t.update=function(){var t=this,r=i.selectAll("circle").data(n.plot.data);r.enter().append("circle");var o=r;n.transitionEnabled()&&(o=r.transition()),o.attr("cx",function(i){return e.x.map(i,t.x)}).attr("cy",function(i){return e.y.map(i,t.y)}).attr("r",n.config.dot.radius),e.dot.color&&o.style("fill",e.dot.color),e.tooltip&&r.on("mouseover",function(i){e.tooltip.transition().duration(200).style("opacity",.9);var r="("+e.x.value(i,t.x)+", "+e.y.value(i,t.y)+")";e.tooltip.html(r).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px");var o=n.config.groups.value(i);if(o||0===o){r+="
";var a=n.config.groups.label;a&&(r+=a+": "),r+=o}e.tooltip.html(r).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){e.tooltip.transition().duration(500).style("opacity",0)}),r.exit().remove()},t.update()}l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t);var n=this,r=n.plot.variables.length,o=this.config,a=n.prefixClass("axis"),s=a+"-x",c=a+"-y",u="g."+s+"."+a,p="g."+c+"."+a,h=n.prefixClass("no-guides");n.svgG.selectAll(u).data(n.plot.variables).enter().appendSelector(u).classed(h,!o.guides).attr("transform",function(t,e){return"translate("+(r-e-1)*n.plot.size+",0)"}).each(function(t){n.plot.x.scale.domain(n.plot.domainByVariable[t]),d3.select(this).call(n.plot.x.axis)}),n.svgG.selectAll(p).data(n.plot.variables).enter().appendSelector(p).classed(h,!o.guides).attr("transform",function(t,e){return"translate(0,"+e*n.plot.size+")"}).each(function(t){n.plot.y.scale.domain(n.plot.domainByVariable[t]),d3.select(this).call(n.plot.y.axis)});var f=n.prefixClass("cell"),d=n.svgG.selectAll("."+f).data(n.utils.cross(n.plot.variables,n.plot.variables));d.enter().appendSelector("g."+f).filter(function(t){return t.i===t.j}).append("text"),d.attr("transform",function(t){return"translate("+(r-t.i-1)*n.plot.size+","+t.j*n.plot.size+")"}),o.brush&&this.drawBrush(d),d.each(i),d.select("text").attr("x",o.padding).attr("y",o.padding).attr("dy",".71em").text(function(t){return n.plot.labelByVariable[t.x]}),this.updateLegend()}},{key:"drawBrush",value:function(t){function e(t){a!==this&&(d3.select(a).call(o.clear()),r.plot.x.scale.domain(r.plot.domainByVariable[t.x]),r.plot.y.scale.domain(r.plot.domainByVariable[t.y]),a=this)}function i(t){var e=o.extent();r.svgG.selectAll("circle").classed("hidden",function(i){return e[0][0]>i[t.x]||i[t.x]>e[1][0]||e[0][1]>i[t.y]||i[t.y]>e[1][1]})}function n(){o.empty()&&r.svgG.selectAll(".hidden").classed("hidden",!1)}var r=this,o=d3.svg.brush().x(r.plot.x.scale).y(r.plot.y.scale).on("brushstart",e).on("brush",i).on("brushend",n);t.append("g").call(o);var a}},{key:"updateLegend",value:function(){var t=this,e=this.plot,i=e.dot.colorCategory;if((!i.domain()||i.domain().length<2)&&(e.showLegend=!1),!e.showLegend)return void(e.legend&&e.legend.container&&e.legend.container.remove());var n=this.plot.width+this.config.legend.margin,r=this.config.legend.margin;e.legend=new p.Legend(this.svg,this.svgG,i,n,r),e.legendColor=e.legend.color().shapeWidth(this.config.legend.shapeWidth).orient("vertical").scale(i),e.legendColor.on("cellclick",function(e){return t.onLegendCellClick(e)}),e.legend.container.call(e.legendColor)}},{key:"onLegendCellClick",value:function(t){this.updateEnabledGroups(t);var e=this.enabledGroups.indexOf(t)<0;this.plot.legend.container.selectAll("g.cell").each(function(i){i==t&&d3.select(this).classed("odc-disabled",e)}),this.init()}},{key:"updateEnabledGroups",value:function(t){this.enabledGroups||(this.enabledGroups=this.plot.dot.colorCategory.domain().slice());var e=this.enabledGroups.indexOf(t);e<0?this.enabledGroups.push(t):this.enabledGroups.splice(e,1)}},{key:"setData",value:function(t){l(Object.getPrototypeOf(e.prototype),"setData",this).call(this,t),this.enabledGroups=null}}]),e}(s.Chart)},{"./chart":20,"./legend":27,"./scatterplot":30,"./utils":33}],30:[function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(i,"__esModule",{value:!0}),i.ScatterPlot=i.ScatterPlotConfig=void 0;var a=function(){function t(t,e){for(var i=0;i-1}):this.data}},{key:"setupX",value:function(){var t=this.plot,e=t.x,i=this.config.x;e.value=function(t){return i.value(t,i.key)},e.scale=d3.scale[i.scale]().range([0,t.width]),e.map=function(t){return e.scale(e.value(t))},e.axis=d3.svg.axis().scale(e.scale).orient(i.orient);var n=this.plot.data;t.x.scale.domain([d3.min(n,t.x.value)-1,d3.max(n,t.x.value)+1]),this.config.guides&&e.axis.tickSize(-t.height)}},{key:"setupY",value:function(){var t=this.plot,e=t.y,i=this.config.y;e.value=function(t){return i.value(t,i.key)},e.scale=d3.scale[i.scale]().range([t.height,0]),e.map=function(t){return e.scale(e.value(t))},e.axis=d3.svg.axis().scale(e.scale).orient(i.orient),this.config.guides&&e.axis.tickSize(-t.width);var n=this.plot.data;t.y.scale.domain([d3.min(n,t.y.value)-1,d3.max(n,t.y.value)+1])}},{key:"drawAxisX",value:function(){var t=this,e=t.plot,i=this.config.x,n=t.svgG.selectOrAppend("g."+t.prefixClass("axis-x")+"."+t.prefixClass("axis")+(t.config.guides?"":"."+t.prefixClass("no-guides"))).attr("transform","translate(0,"+e.height+")"),r=n;t.transitionEnabled()&&(r=n.transition().ease("sin-in-out")),r.call(e.x.axis),n.selectOrAppend("text."+t.prefixClass("label")).attr("transform","translate("+e.width/2+","+e.margin.bottom+")").attr("dy","-1em").style("text-anchor","middle").text(i.label)}},{key:"drawAxisY",value:function(){var t=this,e=t.plot,i=this.config.y,n=t.svgG.selectOrAppend("g."+t.prefixClass("axis-y")+"."+t.prefixClass("axis")+(t.config.guides?"":"."+t.prefixClass("no-guides"))),r=n;t.transitionEnabled()&&(r=n.transition().ease("sin-in-out")),r.call(e.y.axis),n.selectOrAppend("text."+t.prefixClass("label")).attr("transform","translate("+-e.margin.left+","+e.height/2+")rotate(-90)").attr("dy","1em").style("text-anchor","middle").text(i.label)}},{key:"update",value:function(t){l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t),this.drawAxisX(),this.drawAxisY(),this.updateDots(),this.updateLegend()}},{key:"updateDots",value:function(){var t=this,e=t.plot,i=e.data,n=t.prefixClass("dot");t.dotsContainerClass=t.prefixClass("dots-container");var r=t.svgG.selectOrAppend("g."+t.dotsContainerClass),o=r.selectAll("."+n).data(i);o.enter().append("circle").attr("class",n);var a=o;t.transitionEnabled()&&(a=o.transition()),a.attr("r",t.config.dot.radius).attr("cx",e.x.map).attr("cy",e.y.map),e.tooltip&&o.on("mouseover",function(i){e.tooltip.transition().duration(200).style("opacity",.9);var n="("+e.x.value(i)+", "+e.y.value(i)+")",r=t.config.groups.value(i,t.config.groups.key);if(r||0===r){n+="
";var o=t.config.groups.label;o&&(n+=o+": "),n+=r}e.tooltip.html(n).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){e.tooltip.transition().duration(500).style("opacity",0)}),e.dot.color&&o.style("fill",e.dot.color),o.exit().remove()}},{key:"updateLegend",value:function(){var t=this,e=this.plot,i=e.dot.colorCategory;if((!i.domain()||i.domain().length<2)&&(e.showLegend=!1),!e.showLegend)return void(e.legend&&e.legend.container&&e.legend.container.remove());var n=this.plot.width+this.config.legend.margin,r=this.config.legend.margin;e.legend=new u.Legend(this.svg,this.svgG,i,n,r),e.legendColor=e.legend.color().shapeWidth(this.config.legend.shapeWidth).orient("vertical").scale(i),e.legendColor.on("cellclick",function(e){return t.onLegendCellClick(e)}),e.legend.container.call(e.legendColor)}},{key:"onLegendCellClick",value:function(t){this.updateEnabledGroups(t);var e=this.enabledGroups.indexOf(t)<0;this.plot.legend.container.selectAll("g.cell").each(function(i){i==t&&d3.select(this).classed("odc-disabled",e)}),this.init()}},{key:"updateEnabledGroups",value:function(t){this.enabledGroups||(this.enabledGroups=this.plot.dot.colorCategory.domain().slice());var e=this.enabledGroups.indexOf(t);e<0?this.enabledGroups.push(t):this.enabledGroups.splice(e,1)}},{key:"setData",value:function(t){l(Object.getPrototypeOf(e.prototype),"setData",this).call(this,t),this.enabledGroups=null}}]),e}(s.Chart)},{"./chart":20,"./legend":27,"./utils":33}],31:[function(t,e,n){"use strict";function r(t,e){if(t<=0||Math.abs(t)-Math.abs(f(t))!=0)throw"Invalid n: $n\n";if(e<=0||e>=1)throw"Invalid p: $p\n";return p(a(t-0,e-0))}function o(t){var e=-Math.log(4*t*(1-t)),i=Math.sqrt(e*(1.570796288+e*(.03706987906+e*(-.0008364353589+e*(-.0002250947176+e*(6841218299e-15+e*(5824238515e-15+e*(-104527497e-14+e*(8.360937017e-8+e*(-3.231081277e-9+e*(3.657763036e-11+6.936233982e-13*e)))))))))));return t>.5&&(i=-i),i}function a(t,e){if(e>=1||e<=0)throw"Invalid p: $p\n";if(.5==e)return 0;if(e<.5)return-a(t,1-e);var i=o(e),n=Math.pow(i,2),r=(n+1)/4,c=((5*n+16)*n+3)/96,u=(((3*n+19)*n+17)*n-15)/384,p=((((79*n+776)*n+1482)*n-1920)*n-945)/92160,d=(((((27*n+339)*n+930)*n-1782)*n-765)*n+17955)/368640,g=i*(1+(r+(c+(u+(p+d/t)/t)/t)/t)/t);if(t<=Math.pow(s(e),2)+3){var v;do{var y=l(t,g),m=t+1,b=(y-e)/Math.exp((m*Math.log(m/(t+g*g))+Math.log(t/m/2/Math.PI)-1+(1/m-1/t)/6)/2);g+=b,v=h(b,Math.abs(f(s(Math.abs(g))-4)))}while(g&&0!=v)}return g}function l(t,e){for(var i,n,r=Math.atan2(e/Math.sqrt(t),1),o=Math.pow(Math.cos(r),2),a=1,l=t-2;l>=2;l-=2)a=1+(l-1)/l*o*a;return t%2==0?(i=Math.sin(r)/2,n=.5):(i=1==t?0:Math.sin(r)*Math.cos(r)/Math.PI,n=.5+r/Math.PI),c(0,1-n-i*a)}function s(t){return Math.log(t)/Math.log(10)}function c(){for(var t=arguments[0],e=0;i0?Math.floor(t):Math.ceil(t)}Object.defineProperty(n,"__esModule",{value:!0}),n.tdistr=r;var d=5},{}],32:[function(t,e,i){"use strict";var n=t("./statistics-distributions"),r=e.exports.StatisticsUtils={};r.sampleCorrelation=t("../bower_components/simple-statistics/src/sample_correlation"),r.linearRegression=t("../bower_components/simple-statistics/src/linear_regression"), -r.linearRegressionLine=t("../bower_components/simple-statistics/src/linear_regression_line"),r.errorFunction=t("../bower_components/simple-statistics/src/error_function"),r.standardDeviation=t("../bower_components/simple-statistics/src/standard_deviation"),r.sampleStandardDeviation=t("../bower_components/simple-statistics/src/sample_standard_deviation"),r.variance=t("../bower_components/simple-statistics/src/variance"),r.mean=t("../bower_components/simple-statistics/src/mean"),r.zScore=t("../bower_components/simple-statistics/src/z_score"),r.standardError=function(t){return Math.sqrt(r.variance(t)/(t.length-1))},r.tValue=function(t,e){return(0,n.tdistr)(t,e)}},{"../bower_components/simple-statistics/src/error_function":6,"../bower_components/simple-statistics/src/linear_regression":7,"../bower_components/simple-statistics/src/linear_regression_line":8,"../bower_components/simple-statistics/src/mean":9,"../bower_components/simple-statistics/src/sample_correlation":10,"../bower_components/simple-statistics/src/sample_standard_deviation":12,"../bower_components/simple-statistics/src/standard_deviation":14,"../bower_components/simple-statistics/src/variance":17,"../bower_components/simple-statistics/src/z_score":18,"./statistics-distributions":31}],33:[function(t,e,i){"use strict";function n(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0});var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},a=function(){function t(t,e){for(var i=0;i1&&Array.isArray(arguments[1])&&(t=[]),t=t||{};for(var i=1;i-1&&n.splice(l,1)}return n}},{key:"isObjectNotArray",value:function(t){return t&&"object"===("undefined"==typeof t?"undefined":o(t))&&!Array.isArray(t)&&null!==t}},{key:"isObject",value:function(t){return null!==t&&"object"===("undefined"==typeof t?"undefined":o(t))}},{key:"isNumber",value:function(t){return!isNaN(t)&&"number"==typeof t}},{key:"isFunction",value:function(t){return"function"==typeof t}},{key:"isDate",value:function(t){return"[object Date]"===Object.prototype.toString.call(t)}},{key:"isString",value:function(t){return"string"==typeof t||t instanceof String}},{key:"insertOrAppendSelector",value:function(t,e,i,n){for(var r=e.split(/([\.\#])/),o=t[i](r.shift(),n);r.length>1;){var a=r.shift(),l=r.shift();"."===a?o=o.classed(l,!0):"#"===a&&(o=o.attr("id",l))}return o}},{key:"insertSelector",value:function(e,i,n){return t.insertOrAppendSelector(e,i,"insert",n)}},{key:"appendSelector",value:function(e,i){return t.insertOrAppendSelector(e,i,"append")}},{key:"selectOrAppend",value:function(e,i,n){var r=e.select(i);return r.empty()?n?e.append(n):t.appendSelector(e,i):r}},{key:"selectOrInsert",value:function(e,i,n){var r=e.select(i);return r.empty()?t.insertSelector(e,i,n):r}},{key:"linearGradient",value:function e(i,n,r,o,a,l,s){var c=t.selectOrAppend(i,"defs"),e=c.append("linearGradient").attr("id",n);e.attr("x1",o+"%").attr("y1",a+"%").attr("x2",l+"%").attr("y2",s+"%");var u=e.selectAll("stop").data(r);u.enter().append("stop"),u.attr("offset",function(t,e){return e/(r.length-1)}).attr("stop-color",function(t){return t}),u.exit().remove()}},{key:"guid",value:function(){function t(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()}},{key:"placeTextWithEllipsis",value:function(t,e,i){var n=t.node();n.textContent=e;var r=0,o=9;if(n.getComputedTextLength()>i+r){for(var a=e.length-3;a>0;a-=1)if(n.getSubStringLength(0,a)+o<=i+r)return n.textContent=e.substring(0,a)+"...",!0;return n.textContent="...",!0}return!1}},{key:"placeTextWithEllipsisAndTooltip",value:function(e,i,n,r){var o=t.placeTextWithEllipsis(e,i,n);o&&r&&(e.on("mouseover",function(t){r.transition().duration(200).style("opacity",.9),r.html(i).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}),e.on("mouseout",function(t){r.transition().duration(500).style("opacity",0)}))}},{key:"getFontSize",value:function(t){return window.getComputedStyle(t,null).getPropertyValue("font-size")}}]),t}();l.SQRT_2=1.41421356237,l.sanitizeHeight=function(t,e){return t||parseInt(e.style("height"),10)||400},l.sanitizeWidth=function(t,e){return t||parseInt(e.style("width"),10)||960},l.availableHeight=function(t,e,i){return Math.max(0,l.sanitizeHeight(t,e)-i.top-i.bottom)},l.availableWidth=function(t,e,i){return Math.max(0,l.sanitizeWidth(t,e)-i.left-i.right)}},{}]},{},[26])(26)}); +}),"rect"==e.correlation.shape.type&&l.attr("width",e.correlation.shape.size).attr("height",e.correlation.shape.size).attr("x",-e.cellSize/2).attr("y",-e.cellSize/2),l.style("fill",function(t){return e.correlation.color.scale(t.value)});var s=[],c=[];if(e.tooltip&&(s.push(function(t){e.tooltip.transition().duration(200).style("opacity",.9);var i=t.value;e.tooltip.html(i).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}),c.push(function(t){e.tooltip.transition().duration(500).style("opacity",0)})),t.config.highlightLabels){var u=t.config.cssClassPrefix+"highlight",p=function(t){return e.labelClass+"-x-"+t.col},h=function(t){return e.labelClass+"-y-"+t.row};s.push(function(e){t.svgG.selectAll("text."+p(e)).classed(u,!0),t.svgG.selectAll("text."+h(e)).classed(u,!0)}),c.push(function(e){t.svgG.selectAll("text."+p(e)).classed(u,!1),t.svgG.selectAll("text."+h(e)).classed(u,!1)})}r.on("mouseover",function(t){s.forEach(function(e){return e(t)})}).on("mouseout",function(t){c.forEach(function(e){return e(t)})}),r.on("click",function(e){t.trigger("cell-selected",e)}),r.exit().remove()}},{key:"updateLegend",value:function(){var t=this.plot,e=this.plot.width+10,i=0,n=10,r=this.plot.height-2,o=t.correlation.color.scale;t.legend=new p.Legend(this.svg,this.svgG,o,e,i).linearGradientBar(n,r)}},{key:"attachScatterPlot",value:function(t,e){var i=this,n=this;e=e||{};var r={height:n.plot.height+n.config.margin.top+n.config.margin.bottom,width:n.plot.height+n.config.margin.top+n.config.margin.bottom,groups:{key:n.config.groups.key,label:n.config.groups.label},guides:!0,showLegend:!1};n.scatterPlot=!0,r=c.Utils.deepExtend(r,e),this.update(),this.on("cell-selected",function(e){r.x={key:e.rowVar,label:n.plot.labelByVariable[e.rowVar]},r.y={key:e.colVar,label:n.plot.labelByVariable[e.colVar]},n.scatterPlot&&n.scatterPlot!==!0?n.scatterPlot.setConfig(r).init():(n.scatterPlot=new h.ScatterPlot(t,n.data,r),i.attach("ScatterPlot",n.scatterPlot))})}}]),e}(s.Chart)},{"./chart":20,"./legend":27,"./scatterplot":30,"./statistics-utils":32,"./utils":33}],22:[function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0}),i.D3Extensions=void 0;var r=function(){function t(t,e){for(var i=0;i=1&&(e=" M",t=Number(t/1e6).toFixed(3));var i=Intl.NumberFormat();return i.format(t)+e}},t&&c.Utils.deepExtend(i,t),i}return o(e,t),e}(s.HeatmapConfig));i.HeatmapTimeSeries=function(t){function e(t,i,o){return n(this,e),r(this,Object.getPrototypeOf(e).call(this,t,i,new u(o)))}return o(e,t),a(e,[{key:"setConfig",value:function(t){return l(Object.getPrototypeOf(e.prototype),"setConfig",this).call(this,new u(t))}},{key:"setupValuesBeforeGroupsSort",value:function(){var t=this;if(this.plot.x.timeFormat=this.config.x.format,this.config.x.displayFormat&&!this.plot.x.timeFormat&&this.guessTimeFormat(),l(Object.getPrototypeOf(e.prototype),"setupValuesBeforeGroupsSort",this).call(this),this.config.x.fillMissing){var i=this;this.initTimeFormatAndInterval(),this.plot.x.intervalStep=this.config.x.intervalStep||1,this.plot.x.timeParser=this.getTimeParser(),this.plot.x.uniqueValues.sort(this.config.x.sortComparator);var n=null;this.plot.x.uniqueValues.forEach(function(e,r){var o=t.parseTime(e);if(null===n)return void(n=o);for(var a=i.nextTimeTickValue(n),l=[],s=0;i.compareTimeValues(a,o)<=0&&(s++,!(s>100));){var c={},u=i.formatTime(a);c[t.config.x.key]=u,i.updateGroups(c,u,i.plot.x.groups,i.config.x.groups),l.push(a),a=i.nextTimeTickValue(a)}n=o})}}},{key:"parseTime",value:function(t){var e=this.getTimeParser();return e.parse(t)}},{key:"formatTime",value:function(t){var e=this.getTimeParser();return e(t)}},{key:"formatValueX",value:function(t){if(this.config.x.formatter)return this.config.x.formatter.call(this.config,t);if(this.config.x.displayFormat){var e=this.parseTime(t);return d3.time.format(this.config.x.displayFormat)(e)}return this.plot.x.timeFormat&&c.Utils.isDate(t)?this.formatTime(t):t}},{key:"compareTimeValues",value:function(t,e){return t-e}},{key:"timeValuesEqual",value:function(t,e){var i=this.plot.x.timeParser;return i(t)===i(e)}},{key:"nextTimeTickValue",value:function(t){var e=this.plot.x.interval;return d3.time[e].offset(t,this.plot.x.intervalStep)}},{key:"initPlot",value:function(){l(Object.getPrototypeOf(e.prototype),"initPlot",this).call(this),this.config.z.fillMissing&&this.plot.matrix.forEach(function(t,e){var i=void 0;t.forEach(function(t,e){void 0===t.value&&void 0!==i&&(t.value=i,t.missing=!0),i=t.value})})}},{key:"update",value:function(t){l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t)}},{key:"initTimeFormatAndInterval",value:function(){this.plot.x.interval=this.config.x.interval,this.plot.x.timeFormat||this.guessTimeFormat(),!this.plot.x.interval&&this.plot.x.timeFormat&&this.guessInterval()}},{key:"guessTimeFormat",value:function(){for(var t=this,e=0;e=0)return void(t.plot.x.interval=i.name)}}},{key:"getTimeParser",value:function(){return this.plot.x.timeParser||(this.plot.x.timeParser=d3.time.format(this.plot.x.timeFormat)),this.plot.x.timeParser}}]),e}(s.Heatmap)},{"./chart":20,"./heatmap":24,"./statistics-utils":32,"./utils":33}],24:[function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(i,"__esModule",{value:!0}),i.Heatmap=i.HeatmapConfig=void 0;var a=function(){function t(t,e){for(var i=0;is)&&(s=f)}),e.plot.valueMap=a,e.plot.groupByX||(n.groups.values=n.uniqueValues),e.plot.groupByY||(r.groups.values=r.uniqueValues),this.setupValuesBeforeGroupsSort(),n.gaps=[],n.totalValuesCount=0,n.allValuesList=[],this.sortGroups(n,n.groups,i.x),r.gaps=[],r.totalValuesCount=0,r.allValuesList=[],this.sortGroups(r,r.groups,i.y),o.min=l,o.max=s}},{key:"setupValuesBeforeGroupsSort",value:function(){}},{key:"buildCells",value:function(){var t=this,e=t.plot.x,i=t.plot.y,n=(t.plot.z,t.plot.valueMap),r=t.plot.cells=[],o=t.plot.matrix=[];i.allValuesList.forEach(function(t,i){var a=[];o.push(a),e.allValuesList.forEach(function(e,o){var l=void 0;try{l=n[t.group.index][e.group.index][t.val][e.val]}catch(s){}var c={rowVar:t,colVar:e,row:i,col:o,value:l};a.push(c),r.push(c)})})}},{key:"updateGroups",value:function(t,e,i,n){var r=this.config,o=i;return n.keys.forEach(function(e,a){o.key=e,o.children||(o.children={});var l=n.value.call(r,t,e);o.children.hasOwnProperty(l)||(i.lastIndex++,o.children[l]={values:[],children:null,groupingValue:l,level:o.level+1,index:i.lastIndex,key:e}),o=o.children[l]}),o.values.indexOf(e)===-1&&o.values.push(e),o}},{key:"sortGroups",value:function(t,i,n,r){if(n.groups.labels&&n.groups.labels.length>i.level?i.label=n.groups.labels[i.level]:i.label=i.key,r||(r=[0]),r.length<=i.level&&r.push(0),i.allValuesCount=i.allValuesCount||0,i.allValuesBeforeCount=i.allValuesBeforeCount||0,i.gaps=r.slice(),i.gapsBefore=r.slice(),i.gapsSize=e.computeGapsSize(i.gaps),i.gapsBeforeSize=i.gapsSize,i.values&&(n.sortLabels&&i.values.sort(n.sortComparator),i.values.forEach(function(e){return t.allValuesList.push({val:e,group:i})}),i.allValuesBeforeCount=t.totalValuesCount,t.totalValuesCount+=i.values.length,i.allValuesCount+=i.values.length),i.childrenList=[],i.children){var o=0;for(var a in i.children)if(i.children.hasOwnProperty(a)){var l=i.children[a];i.childrenList.push(l),o++,this.sortGroups(t,l,n,r),i.allValuesCount+=l.allValuesCount,r[i.level]+=1}r&&o>1&&(r[i.level]-=1),i.gapsInside=[],r.forEach(function(t,e){i.gapsInside.push(t-(i.gapsBefore[e]||0))}),i.gapsInsideSize=e.computeGapsSize(i.gapsInside),t.gaps.length-1}):this.data}},{key:"drawAxisX",value:function(){var t=this,e=t.plot,i=this.config.x,n=t.svgG.selectOrAppend("g."+t.prefixClass("axis-x")+"."+t.prefixClass("axis")+(t.config.guides?"":"."+t.prefixClass("no-guides"))).attr("transform","translate(0,"+e.height+")"),r=n;t.config.transition&&(r=n.transition().ease("sin-in-out")),r.call(e.x.axis),n.selectOrAppend("text."+t.prefixClass("label")).attr("transform","translate("+e.width/2+","+e.margin.bottom+")").attr("dy","-1em").style("text-anchor","middle").text(i.label)}},{key:"drawAxisY",value:function(){var t=this,e=t.plot,i=this.config.y,n=t.svgG.selectOrAppend("g."+t.prefixClass("axis-y")+"."+t.prefixClass("axis")+(t.config.guides?"":"."+t.prefixClass("no-guides"))),r=n;t.config.transition&&(r=n.transition().ease("sin-in-out")),r.call(e.y.axis),n.selectOrAppend("text."+t.prefixClass("label")).attr("transform","translate("+-e.margin.left+","+e.height/2+")rotate(-90)").attr("dy","1em").style("text-anchor","middle").text(i.label)}},{key:"drawHistogram",value:function(){var t=this,e=t.plot,i=this.prefixClass("layer"),n=this.prefixClass("bar"),r=t.svgG.selectAll("."+i).data(e.stackedHistograms);r.enter().append("g").attr("class",i);var o=r.selectAll("."+n).data(function(t){return t.histogramBins});o.enter().append("g").attr("class",n).append("rect").attr("x",1);var a=o.select("rect"),l=a,s=o,c=r;this.transitionEnabled()&&(l=a.transition(),s=o.transition(),c=r.transition()),s.attr("transform",function(t){return"translate("+e.x.scale(t.x)+","+e.y.scale(t.y0+t.y)+")"});var u=e.histogramBins.length?e.x.scale(e.histogramBins[0].dx):0;l.attr("width",u-e.x.scale(0)-1).attr("height",function(t){return e.height-e.y.scale(t.y)}),this.plot.color&&c.attr("fill",this.plot.color),e.tooltip&&o.on("mouseover",function(t){e.tooltip.transition().duration(200).style("opacity",.9),e.tooltip.html(t.y).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){e.tooltip.transition().duration(500).style("opacity",0)}),r.exit().remove(),o.exit().remove()}},{key:"update",value:function(t){l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t),this.drawAxisX(),this.drawAxisY(),this.drawHistogram(),this.updateLegend()}},{key:"updateLegend",value:function(){var t=this,e=this.plot,i=e.colorCategory;if((!i.domain()||i.domain().length<2)&&(e.showLegend=!1),!e.showLegend)return void(e.legend&&e.legend.container&&e.legend.container.remove());var n=this.plot.width+this.config.legend.margin,r=this.config.legend.margin;e.legend=new u.Legend(this.svg,this.svgG,i,n,r),e.legendColor=e.legend.color().shapeWidth(this.config.legend.shapeWidth).orient("vertical").scale(i),e.legendColor.on("cellclick",function(e){return t.onLegendCellClick(e)}),e.legend.container.call(e.legendColor)}},{key:"onLegendCellClick",value:function(t){this.updateEnabledGroups(t);var e=this.enabledGroups.indexOf(t)<0;this.plot.legend.container.selectAll("g.cell").each(function(i){i==t&&d3.select(this).classed("odc-disabled",e)}),this.init()}},{key:"updateEnabledGroups",value:function(t){this.enabledGroups||(this.enabledGroups=this.plot.colorCategory.domain().slice());var e=this.enabledGroups.indexOf(t);e<0?this.enabledGroups.push(t):this.enabledGroups.splice(e,1)}},{key:"setData",value:function(t){l(Object.getPrototypeOf(e.prototype),"setData",this).call(this,t),this.enabledGroups=null}}]),e}(s.Chart)},{"./chart":20,"./legend":27,"./utils":33}],26:[function(t,e,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.Legend=i.StatisticsUtils=i.BarChartConfig=i.BarChart=i.HistogramConfig=i.Histogram=i.HeatmapTimeSeriesConfig=i.HeatmapTimeSeries=i.HeatmapConfig=i.Heatmap=i.RegressionConfig=i.Regression=i.CorrelationMatrixConfig=i.CorrelationMatrix=i.ScatterPlotMatrixConfig=i.ScatterPlotMatrix=i.ScatterPlotConfig=i.ScatterPlot=void 0;var n=t("./scatterplot");Object.defineProperty(i,"ScatterPlot",{enumerable:!0,get:function(){return n.ScatterPlot}}),Object.defineProperty(i,"ScatterPlotConfig",{enumerable:!0,get:function(){return n.ScatterPlotConfig}});var r=t("./scatterplot-matrix");Object.defineProperty(i,"ScatterPlotMatrix",{enumerable:!0,get:function(){return r.ScatterPlotMatrix}}),Object.defineProperty(i,"ScatterPlotMatrixConfig",{enumerable:!0,get:function(){return r.ScatterPlotMatrixConfig}});var o=t("./correlation-matrix");Object.defineProperty(i,"CorrelationMatrix",{enumerable:!0,get:function(){return o.CorrelationMatrix}}),Object.defineProperty(i,"CorrelationMatrixConfig",{enumerable:!0,get:function(){return o.CorrelationMatrixConfig}});var a=t("./regression");Object.defineProperty(i,"Regression",{enumerable:!0,get:function(){return a.Regression}}),Object.defineProperty(i,"RegressionConfig",{enumerable:!0,get:function(){return a.RegressionConfig}});var l=t("./heatmap");Object.defineProperty(i,"Heatmap",{enumerable:!0,get:function(){return l.Heatmap}}),Object.defineProperty(i,"HeatmapConfig",{enumerable:!0,get:function(){return l.HeatmapConfig}});var s=t("./heatmap-timeseries");Object.defineProperty(i,"HeatmapTimeSeries",{enumerable:!0,get:function(){return s.HeatmapTimeSeries}}),Object.defineProperty(i,"HeatmapTimeSeriesConfig",{enumerable:!0,get:function(){return s.HeatmapTimeSeriesConfig}});var c=t("./histogram");Object.defineProperty(i,"Histogram",{enumerable:!0,get:function(){return c.Histogram}}),Object.defineProperty(i,"HistogramConfig",{enumerable:!0,get:function(){return c.HistogramConfig}});var u=t("./bar-chart");Object.defineProperty(i,"BarChart",{enumerable:!0,get:function(){return u.BarChart}}),Object.defineProperty(i,"BarChartConfig",{enumerable:!0,get:function(){return u.BarChartConfig}});var p=t("./statistics-utils");Object.defineProperty(i,"StatisticsUtils",{enumerable:!0,get:function(){return p.StatisticsUtils}});var h=t("./legend");Object.defineProperty(i,"Legend",{enumerable:!0,get:function(){return h.Legend}});var f=t("./d3-extensions");f.D3Extensions.extend()},{"./bar-chart":19,"./correlation-matrix":21,"./d3-extensions":22,"./heatmap":24,"./heatmap-timeseries":23,"./histogram":25,"./legend":27,"./regression":28,"./scatterplot":30,"./scatterplot-matrix":29,"./statistics-utils":32}],27:[function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0}),i.Legend=void 0;var r=function(){function t(t,e){for(var i=0;i-1});return e}},{key:"setupVariables",value:function(){var t=this.config.variables,e=this.data,i=this.plot;i.domainByVariable={},i.variables=t.keys,i.variables&&i.variables.length||(i.variables=u.Utils.inferVariables(e,this.config.groups.key,this.config.includeInPlot)),i.labels=[],i.labelByVariable={},i.variables.forEach(function(n,r){i.domainByVariable[n]=d3.extent(e,function(e){return t.value(e,n)});var o=n;t.labels&&t.labels.length>r&&(o=t.labels[r]),i.labels.push(o),i.labelByVariable[n]=o}),i.subplots=[]}},{key:"setupX",value:function(){var t=this.plot,e=t.x,i=this.config;e.value=i.variables.value,e.scale=d3.scale[i.x.scale]().range([i.padding/2,t.size-i.padding/2]),e.map=function(t,i){return e.scale(e.value(t,i))},e.axis=d3.svg.axis().scale(e.scale).orient(i.x.orient).ticks(i.ticks),e.axis.tickSize(t.size*t.variables.length)}},{key:"setupY",value:function(){var t=this.plot,e=t.y,i=this.config;e.value=i.variables.value,e.scale=d3.scale[i.y.scale]().range([t.size-i.padding/2,i.padding/2]),e.map=function(t,i){return e.scale(e.value(t,i))},e.axis=d3.svg.axis().scale(e.scale).orient(i.y.orient).ticks(i.ticks),e.axis.tickSize(-t.size*t.variables.length)}},{key:"update",value:function(t){function i(t){var e=n.plot;e.subplots.push(t);var i=d3.select(this);e.x.scale.domain(e.domainByVariable[t.x]),e.y.scale.domain(e.domainByVariable[t.y]);var r=n.prefixClass("frame");i.selectOrAppend("rect."+r).attr("class",r).attr("x",o.padding/2).attr("y",o.padding/2).attr("width",o.size-o.padding).attr("height",o.size-o.padding),t.update=function(){var t=this,r=i.selectAll("circle").data(n.plot.data);r.enter().append("circle");var o=r;n.transitionEnabled()&&(o=r.transition()),o.attr("cx",function(i){return e.x.map(i,t.x)}).attr("cy",function(i){return e.y.map(i,t.y)}).attr("r",n.config.dot.radius),e.dot.color&&o.style("fill",e.dot.color),e.tooltip&&r.on("mouseover",function(i){e.tooltip.transition().duration(200).style("opacity",.9);var r="("+e.x.value(i,t.x)+", "+e.y.value(i,t.y)+")";e.tooltip.html(r).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px");var o=!!n.config.groups&&n.config.groups.value(i);if(o||0===o){r+="
";var a=n.config.groups.label;a&&(r+=a+": "),r+=o}e.tooltip.html(r).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){e.tooltip.transition().duration(500).style("opacity",0)}),r.exit().remove()},t.update()}l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t);var n=this,r=n.plot.variables.length,o=this.config,a=n.prefixClass("axis"),s=a+"-x",c=a+"-y",u="g."+s+"."+a,p="g."+c+"."+a,h=n.prefixClass("no-guides");n.svgG.selectAll(u).data(n.plot.variables).enter().appendSelector(u).classed(h,!o.guides).attr("transform",function(t,e){return"translate("+(r-e-1)*n.plot.size+",0)"}).each(function(t){n.plot.x.scale.domain(n.plot.domainByVariable[t]),d3.select(this).call(n.plot.x.axis)}),n.svgG.selectAll(p).data(n.plot.variables).enter().appendSelector(p).classed(h,!o.guides).attr("transform",function(t,e){return"translate(0,"+e*n.plot.size+")"}).each(function(t){n.plot.y.scale.domain(n.plot.domainByVariable[t]),d3.select(this).call(n.plot.y.axis)});var f=n.prefixClass("cell"),d=n.svgG.selectAll("."+f).data(n.utils.cross(n.plot.variables,n.plot.variables));d.enter().appendSelector("g."+f).filter(function(t){return t.i===t.j}).append("text"),d.attr("transform",function(t){return"translate("+(r-t.i-1)*n.plot.size+","+t.j*n.plot.size+")"}),o.brush&&this.drawBrush(d),d.each(i),d.select("text").attr("x",o.padding).attr("y",o.padding).attr("dy",".71em").text(function(t){return n.plot.labelByVariable[t.x]}),this.updateLegend()}},{key:"drawBrush",value:function(t){function e(t){a!==this&&(d3.select(a).call(o.clear()),r.plot.x.scale.domain(r.plot.domainByVariable[t.x]),r.plot.y.scale.domain(r.plot.domainByVariable[t.y]),a=this)}function i(t){var e=o.extent();r.svgG.selectAll("circle").classed("hidden",function(i){return e[0][0]>i[t.x]||i[t.x]>e[1][0]||e[0][1]>i[t.y]||i[t.y]>e[1][1]})}function n(){o.empty()&&r.svgG.selectAll(".hidden").classed("hidden",!1)}var r=this,o=d3.svg.brush().x(r.plot.x.scale).y(r.plot.y.scale).on("brushstart",e).on("brush",i).on("brushend",n);t.append("g").call(o);var a}},{key:"updateLegend",value:function(){var t=this,e=this.plot,i=e.dot.colorCategory;if((!i.domain()||i.domain().length<2)&&(e.showLegend=!1),!e.showLegend)return void(e.legend&&e.legend.container&&e.legend.container.remove());var n=this.plot.width+this.config.legend.margin,r=this.config.legend.margin;e.legend=new p.Legend(this.svg,this.svgG,i,n,r),e.legendColor=e.legend.color().shapeWidth(this.config.legend.shapeWidth).orient("vertical").scale(i),e.legendColor.on("cellclick",function(e){return t.onLegendCellClick(e)}),e.legend.container.call(e.legendColor)}},{key:"onLegendCellClick",value:function(t){this.updateEnabledGroups(t);var e=this.enabledGroups.indexOf(t)<0;this.plot.legend.container.selectAll("g.cell").each(function(i){i==t&&d3.select(this).classed("odc-disabled",e)}),this.init()}},{key:"updateEnabledGroups",value:function(t){this.enabledGroups||(this.enabledGroups=this.plot.dot.colorCategory.domain().slice());var e=this.enabledGroups.indexOf(t);e<0?this.enabledGroups.push(t):this.enabledGroups.splice(e,1)}},{key:"setData",value:function(t){l(Object.getPrototypeOf(e.prototype),"setData",this).call(this,t),this.enabledGroups=null}}]),e}(s.Chart)},{"./chart":20,"./legend":27,"./scatterplot":30,"./utils":33}],30:[function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(i,"__esModule",{value:!0}),i.ScatterPlot=i.ScatterPlotConfig=void 0;var a=function(){function t(t,e){for(var i=0;i-1}):this.data}},{key:"setupX",value:function(){var t=this.plot,e=t.x,i=this.config.x;e.value=function(t){return i.value(t,i.key)},e.scale=d3.scale[i.scale]().range([0,t.width]),e.map=function(t){return e.scale(e.value(t))},e.axis=d3.svg.axis().scale(e.scale).orient(i.orient);var n=this.plot.data;t.x.scale.domain([d3.min(n,t.x.value)-1,d3.max(n,t.x.value)+1]),this.config.guides&&e.axis.tickSize(-t.height)}},{key:"setupY",value:function(){var t=this.plot,e=t.y,i=this.config.y;e.value=function(t){return i.value(t,i.key)},e.scale=d3.scale[i.scale]().range([t.height,0]),e.map=function(t){return e.scale(e.value(t))},e.axis=d3.svg.axis().scale(e.scale).orient(i.orient),this.config.guides&&e.axis.tickSize(-t.width);var n=this.plot.data;t.y.scale.domain([d3.min(n,t.y.value)-1,d3.max(n,t.y.value)+1])}},{key:"drawAxisX",value:function(){var t=this,e=t.plot,i=this.config.x,n=t.svgG.selectOrAppend("g."+t.prefixClass("axis-x")+"."+t.prefixClass("axis")+(t.config.guides?"":"."+t.prefixClass("no-guides"))).attr("transform","translate(0,"+e.height+")"),r=n;t.transitionEnabled()&&(r=n.transition().ease("sin-in-out")),r.call(e.x.axis),n.selectOrAppend("text."+t.prefixClass("label")).attr("transform","translate("+e.width/2+","+e.margin.bottom+")").attr("dy","-1em").style("text-anchor","middle").text(i.label)}},{key:"drawAxisY",value:function(){var t=this,e=t.plot,i=this.config.y,n=t.svgG.selectOrAppend("g."+t.prefixClass("axis-y")+"."+t.prefixClass("axis")+(t.config.guides?"":"."+t.prefixClass("no-guides"))),r=n;t.transitionEnabled()&&(r=n.transition().ease("sin-in-out")),r.call(e.y.axis),n.selectOrAppend("text."+t.prefixClass("label")).attr("transform","translate("+-e.margin.left+","+e.height/2+")rotate(-90)").attr("dy","1em").style("text-anchor","middle").text(i.label)}},{key:"update",value:function(t){l(Object.getPrototypeOf(e.prototype),"update",this).call(this,t),this.drawAxisX(),this.drawAxisY(),this.updateDots(),this.updateLegend()}},{key:"updateDots",value:function(){var t=this,e=t.plot,i=e.data,n=t.prefixClass("dot");t.dotsContainerClass=t.prefixClass("dots-container");var r=t.svgG.selectOrAppend("g."+t.dotsContainerClass),o=r.selectAll("."+n).data(i);o.enter().append("circle").attr("class",n);var a=o;t.transitionEnabled()&&(a=o.transition()),a.attr("r",t.config.dot.radius).attr("cx",e.x.map).attr("cy",e.y.map),e.tooltip&&o.on("mouseover",function(i){e.tooltip.transition().duration(200).style("opacity",.9);var n="("+e.x.value(i)+", "+e.y.value(i)+")",r=t.config.groups?t.config.groups.value(i,t.config.groups.key):null;if(r||0===r){n+="
";var o=t.config.groups.label;o&&(n+=o+": "),n+=r}e.tooltip.html(n).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){e.tooltip.transition().duration(500).style("opacity",0)}),e.dot.color&&o.style("fill",e.dot.color),o.exit().remove()}},{key:"updateLegend",value:function(){var t=this,e=this.plot,i=e.dot.colorCategory;if((!i.domain()||i.domain().length<2)&&(e.showLegend=!1),!e.showLegend)return void(e.legend&&e.legend.container&&e.legend.container.remove());var n=this.plot.width+this.config.legend.margin,r=this.config.legend.margin;e.legend=new u.Legend(this.svg,this.svgG,i,n,r),e.legendColor=e.legend.color().shapeWidth(this.config.legend.shapeWidth).orient("vertical").scale(i),e.legendColor.on("cellclick",function(e){return t.onLegendCellClick(e)}),e.legend.container.call(e.legendColor)}},{key:"onLegendCellClick",value:function(t){this.updateEnabledGroups(t);var e=this.enabledGroups.indexOf(t)<0;this.plot.legend.container.selectAll("g.cell").each(function(i){i==t&&d3.select(this).classed("odc-disabled",e)}),this.init()}},{key:"updateEnabledGroups",value:function(t){this.enabledGroups||(this.enabledGroups=this.plot.dot.colorCategory.domain().slice());var e=this.enabledGroups.indexOf(t);e<0?this.enabledGroups.push(t):this.enabledGroups.splice(e,1)}},{key:"setData",value:function(t){l(Object.getPrototypeOf(e.prototype),"setData",this).call(this,t),this.enabledGroups=null}}]),e}(s.Chart)},{"./chart":20,"./legend":27,"./utils":33}],31:[function(t,e,n){"use strict";function r(t,e){if(t<=0||Math.abs(t)-Math.abs(f(t))!=0)throw"Invalid n: $n\n";if(e<=0||e>=1)throw"Invalid p: $p\n";return p(a(t-0,e-0))}function o(t){var e=-Math.log(4*t*(1-t)),i=Math.sqrt(e*(1.570796288+e*(.03706987906+e*(-.0008364353589+e*(-.0002250947176+e*(6841218299e-15+e*(5824238515e-15+e*(-104527497e-14+e*(8.360937017e-8+e*(-3.231081277e-9+e*(3.657763036e-11+6.936233982e-13*e)))))))))));return t>.5&&(i=-i),i}function a(t,e){if(e>=1||e<=0)throw"Invalid p: $p\n";if(.5==e)return 0;if(e<.5)return-a(t,1-e);var i=o(e),n=Math.pow(i,2),r=(n+1)/4,c=((5*n+16)*n+3)/96,u=(((3*n+19)*n+17)*n-15)/384,p=((((79*n+776)*n+1482)*n-1920)*n-945)/92160,d=(((((27*n+339)*n+930)*n-1782)*n-765)*n+17955)/368640,g=i*(1+(r+(c+(u+(p+d/t)/t)/t)/t)/t);if(t<=Math.pow(s(e),2)+3){var v;do{var y=l(t,g),m=t+1,b=(y-e)/Math.exp((m*Math.log(m/(t+g*g))+Math.log(t/m/2/Math.PI)-1+(1/m-1/t)/6)/2);g+=b,v=h(b,Math.abs(f(s(Math.abs(g))-4)))}while(g&&0!=v)}return g}function l(t,e){for(var i,n,r=Math.atan2(e/Math.sqrt(t),1),o=Math.pow(Math.cos(r),2),a=1,l=t-2;l>=2;l-=2)a=1+(l-1)/l*o*a;return t%2==0?(i=Math.sin(r)/2,n=.5):(i=1==t?0:Math.sin(r)*Math.cos(r)/Math.PI,n=.5+r/Math.PI),c(0,1-n-i*a)}function s(t){return Math.log(t)/Math.log(10)}function c(){for(var t=arguments[0],e=0;i0?Math.floor(t):Math.ceil(t)}Object.defineProperty(n,"__esModule",{value:!0}),n.tdistr=r;var d=5},{}],32:[function(t,e,i){"use strict";var n=t("./statistics-distributions"),r=e.exports.StatisticsUtils={}; +r.sampleCorrelation=t("../bower_components/simple-statistics/src/sample_correlation"),r.linearRegression=t("../bower_components/simple-statistics/src/linear_regression"),r.linearRegressionLine=t("../bower_components/simple-statistics/src/linear_regression_line"),r.errorFunction=t("../bower_components/simple-statistics/src/error_function"),r.standardDeviation=t("../bower_components/simple-statistics/src/standard_deviation"),r.sampleStandardDeviation=t("../bower_components/simple-statistics/src/sample_standard_deviation"),r.variance=t("../bower_components/simple-statistics/src/variance"),r.mean=t("../bower_components/simple-statistics/src/mean"),r.zScore=t("../bower_components/simple-statistics/src/z_score"),r.standardError=function(t){return Math.sqrt(r.variance(t)/(t.length-1))},r.tValue=function(t,e){return(0,n.tdistr)(t,e)}},{"../bower_components/simple-statistics/src/error_function":6,"../bower_components/simple-statistics/src/linear_regression":7,"../bower_components/simple-statistics/src/linear_regression_line":8,"../bower_components/simple-statistics/src/mean":9,"../bower_components/simple-statistics/src/sample_correlation":10,"../bower_components/simple-statistics/src/sample_standard_deviation":12,"../bower_components/simple-statistics/src/standard_deviation":14,"../bower_components/simple-statistics/src/variance":17,"../bower_components/simple-statistics/src/z_score":18,"./statistics-distributions":31}],33:[function(t,e,i){"use strict";function n(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0});var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},a=function(){function t(t,e){for(var i=0;i1&&Array.isArray(arguments[1])&&(t=[]),t=t||{};for(var i=1;i-1&&n.splice(l,1)}return n}},{key:"isObjectNotArray",value:function(t){return t&&"object"===("undefined"==typeof t?"undefined":o(t))&&!Array.isArray(t)&&null!==t}},{key:"isObject",value:function(t){return null!==t&&"object"===("undefined"==typeof t?"undefined":o(t))}},{key:"isNumber",value:function(t){return!isNaN(t)&&"number"==typeof t}},{key:"isFunction",value:function(t){return"function"==typeof t}},{key:"isDate",value:function(t){return"[object Date]"===Object.prototype.toString.call(t)}},{key:"isString",value:function(t){return"string"==typeof t||t instanceof String}},{key:"insertOrAppendSelector",value:function(t,e,i,n){for(var r=e.split(/([\.\#])/),o=t[i](r.shift(),n);r.length>1;){var a=r.shift(),l=r.shift();"."===a?o=o.classed(l,!0):"#"===a&&(o=o.attr("id",l))}return o}},{key:"insertSelector",value:function(e,i,n){return t.insertOrAppendSelector(e,i,"insert",n)}},{key:"appendSelector",value:function(e,i){return t.insertOrAppendSelector(e,i,"append")}},{key:"selectOrAppend",value:function(e,i,n){var r=e.select(i);return r.empty()?n?e.append(n):t.appendSelector(e,i):r}},{key:"selectOrInsert",value:function(e,i,n){var r=e.select(i);return r.empty()?t.insertSelector(e,i,n):r}},{key:"linearGradient",value:function e(i,n,r,o,a,l,s){var c=t.selectOrAppend(i,"defs"),e=c.append("linearGradient").attr("id",n);e.attr("x1",o+"%").attr("y1",a+"%").attr("x2",l+"%").attr("y2",s+"%");var u=e.selectAll("stop").data(r);u.enter().append("stop"),u.attr("offset",function(t,e){return e/(r.length-1)}).attr("stop-color",function(t){return t}),u.exit().remove()}},{key:"guid",value:function(){function t(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()}},{key:"placeTextWithEllipsis",value:function(t,e,i){var n=t.node();n.textContent=e;var r=0,o=9;if(n.getComputedTextLength()>i+r){for(var a=e.length-3;a>0;a-=1)if(n.getSubStringLength(0,a)+o<=i+r)return n.textContent=e.substring(0,a)+"...",!0;return n.textContent="...",!0}return!1}},{key:"placeTextWithEllipsisAndTooltip",value:function(e,i,n,r){var o=t.placeTextWithEllipsis(e,i,n);o&&r&&(e.on("mouseover",function(t){r.transition().duration(200).style("opacity",.9),r.html(i).style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}),e.on("mouseout",function(t){r.transition().duration(500).style("opacity",0)}))}},{key:"getFontSize",value:function(t){return window.getComputedStyle(t,null).getPropertyValue("font-size")}}]),t}();l.SQRT_2=1.41421356237,l.sanitizeHeight=function(t,e){return t||parseInt(e.style("height"),10)||400},l.sanitizeWidth=function(t,e){return t||parseInt(e.style("width"),10)||960},l.availableHeight=function(t,e,i){return Math.max(0,l.sanitizeHeight(t,e)-i.top-i.bottom)},l.availableWidth=function(t,e,i){return Math.max(0,l.sanitizeWidth(t,e)-i.left-i.right)}},{}]},{},[26])(26)}); //# sourceMappingURL=odc-d3.min.js.map diff --git a/dist/odc-d3.min.js.map b/dist/odc-d3.min.js.map index 6b7c2d0..6bb916e 100644 --- a/dist/odc-d3.min.js.map +++ b/dist/odc-d3.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","odc-d3.js","bower_components/d3-legend/no-extend.js","bower_components/d3-legend/src/color.js","bower_components/d3-legend/src/legend.js","bower_components/d3-legend/src/size.js","bower_components/d3-legend/src/symbol.js","bower_components/simple-statistics/src/error_function.js","bower_components/simple-statistics/src/linear_regression.js","bower_components/simple-statistics/src/linear_regression_line.js","bower_components/simple-statistics/src/mean.js","bower_components/simple-statistics/src/sample_correlation.js","bower_components/simple-statistics/src/sample_covariance.js","bower_components/simple-statistics/src/sample_standard_deviation.js","bower_components/simple-statistics/src/sample_variance.js","bower_components/simple-statistics/src/standard_deviation.js","bower_components/simple-statistics/src/sum.js","bower_components/simple-statistics/src/sum_nth_power_deviations.js","bower_components/simple-statistics/src/variance.js","bower_components/simple-statistics/src/z_score.js","src/bar-chart.js","src/chart.js","src/correlation-matrix.js","src/d3-extensions.js","src/heatmap-timeseries.js","src/heatmap.js","src/histogram.js","src/index.js","src/legend.js","src/regression.js","src/scatterplot-matrix.js","src/scatterplot.js","src/statistics-distributions.js","src/statistics-utils.js","src/utils.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","ODCD3","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","color","size","symbol","./src/color","./src/size","./src/symbol","2","helper","legend","svg","type","d3_calcType","scale","ascending","cells","labels","labelFormat","labelDelimiter","legendG","selectAll","data","enter","append","attr","classPrefix","cell","cellEnter","style","shapes","shape","select","d3_addEvents","legendDispatcher","exit","transition","remove","d3_drawShapes","shapeHeight","shapeWidth","shapeRadius","path","d3_addText","text","shapeSize","map","d","getBBox","useClass","feature","cellTrans","textTrans","textAlign","labelAlign","orient","height","shapePadding","width","x","labelOffset","y","d3_placement","d3_title","title","d3","linear","format","dispatch","_","arguments","toLowerCase","rebind","./legend","3","d3_identity","d3_mergeLabels","gen","push","d3_linearLegend","domain","increment","d3_quantLegend","range","invert","invertExtent","d3_ordinalLegend","ticks","d3_reverse","arr","mirror","dispatcher","on","d3_cellOver","d3_cellOut","d3_cellClick","cellDispatcher","obj","cellover","cellout","cellclick","cellsSvg","titleText","yOffset","xOffset","4","bbox","stroke","maxH","max","maxW","sum","slice","5","6","errorFunction","Math","abs","tau","exp","pow","7","linearRegression","m","b","dataLength","point","sumX","sumY","sumXX","sumXY","8","linearRegressionLine","mb","9","mean","NaN","./sum","10","sampleCorrelation","cov","sampleCovariance","xstd","sampleStandardDeviation","ystd","./sample_covariance","./sample_standard_deviation","11","xmean","ymean","besselsCorrection","./mean","12","sampleVarianceX","sampleVariance","isNaN","sqrt","./sample_variance","13","sumSquaredDeviationsValue","sumNthPowerDeviations","./sum_nth_power_deviations","14","standardDeviation","v","variance","./variance","15","correctedCurrentValue","nextSum","errorCompensation","16","meanValue","17","18","zScore","19","_classCallCheck","instance","Constructor","TypeError","_possibleConstructorReturn","ReferenceError","_inherits","subClass","superClass","prototype","Object","create","constructor","value","enumerable","writable","configurable","setPrototypeOf","__proto__","defineProperty","BarChart","BarChartConfig","undefined","_createClass","defineProperties","target","props","descriptor","key","protoProps","staticProps","_get","get","object","property","receiver","Function","desc","getOwnPropertyDescriptor","parent","getPrototypeOf","getter","_chart","_utils","_legend","_ChartConfig","custom","_this","svgClass","cssClassPrefix","showLegend","showTooltip","margin","label","Utils","isNumber","groups","d3ColorCategory","deepExtend","ChartConfig","_Chart","placeholderSelector","config","conf","plot","right","computePlotSize","setupY","setupX","setupGroupStacks","setupYDomain","colorCategory","colorValue","String","ordinal","rangeRoundBands","axis","series","values","keys","yStackMax","layers","layer","y0","min","groupingEnabled","groupedData","mapToPoints","groupData","stack","layout","axisConf","svgG","selectOrAppend","prefixClass","guides","axisT","ease","bottom","left","layerClass","barClass","bar","barRect","barRectT","barT","layerT","transitionEnabled","yDomain","rangeBand","tooltip","duration","html","event","pageX","pageY","newData","drawAxisX","drawAxisY","drawBars","updateLegend","container","legendX","legendY","Legend","legendLinear","Chart","./chart","./utils","20","top","base","utils","_attached","_layers","_events","_isInitialized","_isAttached","baseContainer","setConfig","setData","init","postInit","initPlot","initSvg","initTooltip","draw","attachmentData","attachmentName","update","chart","name","callback","context","events","once","off","apply","names","j","splice","ev","args","Array","getBaseContainer","node","clazz","addDot","availableWidth","availableHeight","21","CorrelationMatrix","CorrelationMatrixConfig","_statisticsUtils","_scatterplot","highlightLabels","rotateLabelsX","rotateLabelsY","variables","variableKey","correlation","xValues","yValues","StatisticsUtils","sizeMin","sizeMax","padding","matrix","setupVariables","placeholderNode","getBaseContainerNode","parentWidth","getBoundingClientRect","cellSize","setupVariablesScales","setupCorrelationScales","setupCorrelationMatrix","rangeBands","corrConf","cellConf","radiusMax","radiusScale","radius","c","radiusX","radiusY","rotateVal","variablesConf","domainByVariable","inferVariables","includeInPlot","labelByVariable","forEach","index","extent","matrixCells","variableToValues","v1","row","v2","corr","rowVar","colVar","col","updateCells","updateVariableLabels","labelClass","updateAxisX","updateAxisY","labelXClass","maxWidth","computeXAxisLabelsWidth","each","placeTextWithEllipsisAndTooltip","labelYClass","computeYAxisLabelsWidth","SQRT_2","fontSize","offset","cellClass","cellShape","classed","scatterPlot","selector","wrongShapes","mouseoverCallbacks","mouseoutCallbacks","highlightClass","xLabelClass","yLabelClass","trigger","barWidth","barHeight","linearGradientBar","containerSelector","_this3","scatterPlotConfig","ScatterPlot","attach","./scatterplot","./statistics-utils","22","D3Extensions","selection","insertSelector","before","appendSelector","selectOrInsert","23","HeatmapTimeSeries","HeatmapTimeSeriesConfig","_heatmap","_HeatmapConfig","fillMissing","interval","intervalStep","displayFormat","intervalToFormats","formats","sortComparator","isString","localeCompare","formatter","z","suffix","Number","toFixed","nf","Intl","NumberFormat","HeatmapConfig","_Heatmap","timeFormat","guessTimeFormat","initTimeFormatAndInterval","timeParser","getTimeParser","uniqueValues","sort","prev","current","parseTime","next","nextTimeTickValue","missing","iteration","compareTimeValues","timeString","formatTime","updateGroups","parser","parse","date","time","isDate","rowIndex","prevRowValue","colIndex","guessInterval","intervalFormat","formatMatch","some","every","indexOf","Heatmap","./heatmap","24","noDataText","rotateLabels","decimalPlaces","sortLabels","overlap","notAvailableValue","noDataColor","reverseScale","matrixes","setupValues","buildCells","titleRectWidth","groupByX","depth","allTitlesWidth","groupByY","_depth","_allTitlesWidth","setupZScale","children","level","lastIndex","valueMap","minZ","maxZ","xVal","yVal","zValRaw","zVal","parseFloat","groupY","groupX","setupValuesBeforeGroupsSort","gaps","totalValuesCount","allValuesList","sortGroups","group","val","axisVal","rootGroup","axisGroupsConfig","currentGroup","groupKey","groupKeyIndex","groupingValue","hasOwnProperty","axisConfig","allValuesCount","allValuesBeforeCount","gapsBefore","gapsSize","computeGapsSize","gapsBeforeSize","childrenList","childrenCount","childProp","child","gapsInside","gapsInsideSize","cellWidth","xGapsSize","computedCellWidth","yGapsSize","computedCellHeight","cellHeight","exponent","unshift","log","reverse","drawGroupsY","drawGroupsX","updateAxisTitles","offsetX","gapSize","computeGapSize","formatValueX","elem","offsetY","formatted","formatValueY","parentGroup","groupClass","groupYClass","valuesBeforeCount","groupsEnterG","titleGroupEnter","groupTitleRectHeight","translate","groupWidth","titleGroups","tileRects","setGroupMouseCallbacks","groupXClass","titleRectHeight","groupHeight","parentNode","cellContainerClass","paddingX","paddingY","cellContainer","formatValueZ","formatLegendValue","setRotateLabels","gapLevel","maxGroupGapSize","gapsNumber","gapsLevel","25","Histogram","HistogramConfig","frequency","getOwnPropertyNames","getDataToPlot","setupHistogram","histogramBins","histogram","bins","_this4","nest","entries","dy","stackedHistograms","_this5","enabledGroups","filter","dx","drawHistogram","_this6","legendColor","onLegendCellClick","cellValue","updateEnabledGroups","isDisabled","26","RegressionConfig","Regression","ScatterPlotMatrixConfig","ScatterPlotMatrix","ScatterPlotConfig","_scatterplotMatrix","_correlationMatrix","_regression","_heatmapTimeseries","_histogram","_barChart","_d3Extensions","extend","./bar-chart","./correlation-matrix","./d3-extensions","./heatmap-timeseries","./histogram","./regression","./scatterplot-matrix","27","_noExtend","legendParent","legendClass","guid","gradientId","linearGradient","ticksNumber","../bower_components/d3-legend/no-extend","28","_ScatterPlotConfig","mainRegression","groupRegression","confidence","criticalValue","degreesOfFreedom","criticalProbability","tValue","marginOfError","_ScatterPlot","initRegressionLines","groupsAvailable","regressions","regression","initRegression","initGroupRegression","dataByGroup","groupVal","points","extentX","linePoints","line","interpolate","dot","defaultColor","isFunction","computeConfidence","alpha","meanX","xMySum","xSum","xPowSum","ySum","yPowSum","p","Sa2","Sy2","errorFn","computeConfidenceAreaPoint","moe","confDown","confUp","y1","centerX","confidenceAreaPoints","fitInPlot","confidenceArea","area","updateRegressionLines","regressionContainerClass","regressionContainerSelector","clipPathId","regressionContainer","dotsContainerClass","regressionContainerClip","regressionClass","confidenceAreaClass","regressionSelector","regressionEnterG","lineClass","lineT","areaT","29","brush","setupGroups","boundingClientRect","groupValue","subplots","variable","tickSize","plotSubplot","frameClass","subplot","dots","dotsT","axisClass","axisXClass","axisYClass","xAxisSelector","yAxisSelector","noGuidesClass","cross","drawBrush","brushstart","brushCell","clear","brushmove","brushend","empty","30","updateDots","dotClass","dotsContainer","31","tdistr","$n","$p","integer","precision_string","_subt","_subu","$y","$x","$u","$u2","$a","$b","$c","$d","$e","log10","$round","$p1","_subtprob","$n1","$delta","PI","round_to_precision","$w","atan2","$z","cos","$i","sin","$max","precision","SIGNIFICANT","round","floor","ceil","32","_statisticsDistributions","su","standardError","../bower_components/simple-statistics/src/error_function","../bower_components/simple-statistics/src/linear_regression","../bower_components/simple-statistics/src/linear_regression_line","../bower_components/simple-statistics/src/mean","../bower_components/simple-statistics/src/sample_correlation","../bower_components/simple-statistics/src/sample_standard_deviation","../bower_components/simple-statistics/src/standard_deviation","../bower_components/simple-statistics/src/variance","../bower_components/simple-statistics/src/z_score","./statistics-distributions","33","_defineProperty","_typeof","Symbol","iterator","out","isArray","source","isObject","srcObj","output","assign","isObjectNotArray","mergeDeep","includeGroup","res","prop","item","toString","operation","selectorParts","split","element","shift","selectorModifier","selectorItem","insertOrAppendSelector","x1","x2","y2","defs","stops","s4","random","substring","textD3Obj","textString","textObj","textContent","ellipsisLength","getComputedTextLength","getSubStringLength","ellipsisPlaced","placeTextWithEllipsis","getComputedStyle","getPropertyValue","sanitizeHeight","parseInt","sanitizeWidth"],"mappings":"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","file":"odc-d3.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 1 || _ >= 2) {\n cells = _;\n }\n return legend;\n };\n\n legend.shape = function (_, d) {\n if (!arguments.length) return shape;\n if (_ == \"rect\" || _ == \"circle\" || _ == \"line\" || _ == \"path\" && typeof d === 'string') {\n shape = _;\n path = d;\n }\n return legend;\n };\n\n legend.shapeWidth = function (_) {\n if (!arguments.length) return shapeWidth;\n shapeWidth = +_;\n return legend;\n };\n\n legend.shapeHeight = function (_) {\n if (!arguments.length) return shapeHeight;\n shapeHeight = +_;\n return legend;\n };\n\n legend.shapeRadius = function (_) {\n if (!arguments.length) return shapeRadius;\n shapeRadius = +_;\n return legend;\n };\n\n legend.shapePadding = function (_) {\n if (!arguments.length) return shapePadding;\n shapePadding = +_;\n return legend;\n };\n\n legend.labels = function (_) {\n if (!arguments.length) return labels;\n labels = _;\n return legend;\n };\n\n legend.labelAlign = function (_) {\n if (!arguments.length) return labelAlign;\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\n labelAlign = _;\n }\n return legend;\n };\n\n legend.labelFormat = function (_) {\n if (!arguments.length) return labelFormat;\n labelFormat = _;\n return legend;\n };\n\n legend.labelOffset = function (_) {\n if (!arguments.length) return labelOffset;\n labelOffset = +_;\n return legend;\n };\n\n legend.labelDelimiter = function (_) {\n if (!arguments.length) return labelDelimiter;\n labelDelimiter = _;\n return legend;\n };\n\n legend.useClass = function (_) {\n if (!arguments.length) return useClass;\n if (_ === true || _ === false) {\n useClass = _;\n }\n return legend;\n };\n\n legend.orient = function (_) {\n if (!arguments.length) return orient;\n _ = _.toLowerCase();\n if (_ == \"horizontal\" || _ == \"vertical\") {\n orient = _;\n }\n return legend;\n };\n\n legend.ascending = function (_) {\n if (!arguments.length) return ascending;\n ascending = !!_;\n return legend;\n };\n\n legend.classPrefix = function (_) {\n if (!arguments.length) return classPrefix;\n classPrefix = _;\n return legend;\n };\n\n legend.title = function (_) {\n if (!arguments.length) return title;\n title = _;\n return legend;\n };\n\n d3.rebind(legend, legendDispatcher, \"on\");\n\n return legend;\n};\n\n},{\"./legend\":3}],3:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = {\n\n d3_identity: function d3_identity(d) {\n return d;\n },\n\n d3_mergeLabels: function d3_mergeLabels(gen, labels) {\n\n if (labels.length === 0) return gen;\n\n gen = gen ? gen : [];\n\n var i = labels.length;\n for (; i < gen.length; i++) {\n labels.push(gen[i]);\n }\n return labels;\n },\n\n d3_linearLegend: function d3_linearLegend(scale, cells, labelFormat) {\n var data = [];\n\n if (cells.length > 1) {\n data = cells;\n } else {\n var domain = scale.domain(),\n increment = (domain[domain.length - 1] - domain[0]) / (cells - 1),\n i = 0;\n\n for (; i < cells; i++) {\n data.push(domain[0] + i * increment);\n }\n }\n\n var labels = data.map(labelFormat);\n\n return { data: data,\n labels: labels,\n feature: function feature(d) {\n return scale(d);\n } };\n },\n\n d3_quantLegend: function d3_quantLegend(scale, labelFormat, labelDelimiter) {\n var labels = scale.range().map(function (d) {\n var invert = scale.invertExtent(d),\n a = labelFormat(invert[0]),\n b = labelFormat(invert[1]);\n\n // if (( (a) && (a.isNan()) && b){\n // console.log(\"in initial statement\")\n return labelFormat(invert[0]) + \" \" + labelDelimiter + \" \" + labelFormat(invert[1]);\n // } else if (a || b) {\n // console.log('in else statement')\n // return (a) ? a : b;\n // }\n });\n\n return { data: scale.range(),\n labels: labels,\n feature: this.d3_identity\n };\n },\n\n d3_ordinalLegend: function d3_ordinalLegend(scale) {\n return { data: scale.domain(),\n labels: scale.domain(),\n feature: function feature(d) {\n return scale(d);\n } };\n },\n\n d3_drawShapes: function d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path) {\n if (shape === \"rect\") {\n shapes.attr(\"height\", shapeHeight).attr(\"width\", shapeWidth);\n } else if (shape === \"circle\") {\n shapes.attr(\"r\", shapeRadius); //.attr(\"cx\", shapeRadius).attr(\"cy\", shapeRadius);\n } else if (shape === \"line\") {\n shapes.attr(\"x1\", 0).attr(\"x2\", shapeWidth).attr(\"y1\", 0).attr(\"y2\", 0);\n } else if (shape === \"path\") {\n shapes.attr(\"d\", path);\n }\n },\n\n d3_addText: function d3_addText(svg, enter, labels, classPrefix) {\n enter.append(\"text\").attr(\"class\", classPrefix + \"label\");\n svg.selectAll(\"g.\" + classPrefix + \"cell text\").data(labels).text(this.d3_identity);\n },\n\n d3_calcType: function d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter) {\n var type = scale.ticks ? this.d3_linearLegend(scale, cells, labelFormat) : scale.invertExtent ? this.d3_quantLegend(scale, labelFormat, labelDelimiter) : this.d3_ordinalLegend(scale);\n\n type.labels = this.d3_mergeLabels(type.labels, labels);\n\n if (ascending) {\n type.labels = this.d3_reverse(type.labels);\n type.data = this.d3_reverse(type.data);\n }\n\n return type;\n },\n\n d3_reverse: function d3_reverse(arr) {\n var mirror = [];\n for (var i = 0, l = arr.length; i < l; i++) {\n mirror[i] = arr[l - i - 1];\n }\n return mirror;\n },\n\n d3_placement: function d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign) {\n cell.attr(\"transform\", cellTrans);\n text.attr(\"transform\", textTrans);\n if (orient === \"horizontal\") {\n text.style(\"text-anchor\", labelAlign);\n }\n },\n\n d3_addEvents: function d3_addEvents(cells, dispatcher) {\n var _ = this;\n\n cells.on(\"mouseover.legend\", function (d) {\n _.d3_cellOver(dispatcher, d, this);\n }).on(\"mouseout.legend\", function (d) {\n _.d3_cellOut(dispatcher, d, this);\n }).on(\"click.legend\", function (d) {\n _.d3_cellClick(dispatcher, d, this);\n });\n },\n\n d3_cellOver: function d3_cellOver(cellDispatcher, d, obj) {\n cellDispatcher.cellover.call(obj, d);\n },\n\n d3_cellOut: function d3_cellOut(cellDispatcher, d, obj) {\n cellDispatcher.cellout.call(obj, d);\n },\n\n d3_cellClick: function d3_cellClick(cellDispatcher, d, obj) {\n cellDispatcher.cellclick.call(obj, d);\n },\n\n d3_title: function d3_title(svg, cellsSvg, title, classPrefix) {\n if (title !== \"\") {\n\n var titleText = svg.selectAll('text.' + classPrefix + 'legendTitle');\n\n titleText.data([title]).enter().append('text').attr('class', classPrefix + 'legendTitle');\n\n svg.selectAll('text.' + classPrefix + 'legendTitle').text(title);\n\n var yOffset = svg.select('.' + classPrefix + 'legendTitle').map(function (d) {\n return d[0].getBBox().height;\n })[0],\n xOffset = -cellsSvg.map(function (d) {\n return d[0].getBBox().x;\n })[0];\n\n cellsSvg.attr('transform', 'translate(' + xOffset + ',' + (yOffset + 10) + ')');\n }\n }\n};\n\n},{}],4:[function(require,module,exports){\n\"use strict\";\n\nvar helper = require('./legend');\n\nmodule.exports = function () {\n\n var scale = d3.scale.linear(),\n shape = \"rect\",\n shapeWidth = 15,\n shapePadding = 2,\n cells = [5],\n labels = [],\n useStroke = false,\n classPrefix = \"\",\n title = \"\",\n labelFormat = d3.format(\".01f\"),\n labelOffset = 10,\n labelAlign = \"middle\",\n labelDelimiter = \"to\",\n orient = \"vertical\",\n ascending = false,\n path,\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\n\n function legend(svg) {\n\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\n legendG = svg.selectAll('g').data([scale]);\n\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\n\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\n\n //add event handlers\n helper.d3_addEvents(cellEnter, legendDispatcher);\n\n cell.exit().transition().style(\"opacity\", 0).remove();\n\n //creates shape\n if (shape === \"line\") {\n helper.d3_drawShapes(shape, shapes, 0, shapeWidth);\n shapes.attr(\"stroke-width\", type.feature);\n } else {\n helper.d3_drawShapes(shape, shapes, type.feature, type.feature, type.feature, path);\n }\n\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix);\n\n //sets placement\n var text = cell.select(\"text\"),\n shapeSize = shapes[0].map(function (d, i) {\n var bbox = d.getBBox();\n var stroke = scale(type.data[i]);\n\n if (shape === \"line\" && orient === \"horizontal\") {\n bbox.height = bbox.height + stroke;\n } else if (shape === \"line\" && orient === \"vertical\") {\n bbox.width = bbox.width;\n }\n\n return bbox;\n });\n\n var maxH = d3.max(shapeSize, function (d) {\n return d.height + d.y;\n }),\n maxW = d3.max(shapeSize, function (d) {\n return d.width + d.x;\n });\n\n var cellTrans,\n textTrans,\n textAlign = labelAlign == \"start\" ? 0 : labelAlign == \"middle\" ? 0.5 : 1;\n\n //positions cells and text\n if (orient === \"vertical\") {\n\n cellTrans = function cellTrans(d, i) {\n var height = d3.sum(shapeSize.slice(0, i + 1), function (d) {\n return d.height;\n });\n return \"translate(0, \" + (height + i * shapePadding) + \")\";\n };\n\n textTrans = function textTrans(d, i) {\n return \"translate(\" + (maxW + labelOffset) + \",\" + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + \")\";\n };\n } else if (orient === \"horizontal\") {\n cellTrans = function cellTrans(d, i) {\n var width = d3.sum(shapeSize.slice(0, i + 1), function (d) {\n return d.width;\n });\n return \"translate(\" + (width + i * shapePadding) + \",0)\";\n };\n\n textTrans = function textTrans(d, i) {\n return \"translate(\" + (shapeSize[i].width * textAlign + shapeSize[i].x) + \",\" + (maxH + labelOffset) + \")\";\n };\n }\n\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\n helper.d3_title(svg, legendG, title, classPrefix);\n\n cell.transition().style(\"opacity\", 1);\n }\n\n legend.scale = function (_) {\n if (!arguments.length) return scale;\n scale = _;\n return legend;\n };\n\n legend.cells = function (_) {\n if (!arguments.length) return cells;\n if (_.length > 1 || _ >= 2) {\n cells = _;\n }\n return legend;\n };\n\n legend.shape = function (_, d) {\n if (!arguments.length) return shape;\n if (_ == \"rect\" || _ == \"circle\" || _ == \"line\") {\n shape = _;\n path = d;\n }\n return legend;\n };\n\n legend.shapeWidth = function (_) {\n if (!arguments.length) return shapeWidth;\n shapeWidth = +_;\n return legend;\n };\n\n legend.shapePadding = function (_) {\n if (!arguments.length) return shapePadding;\n shapePadding = +_;\n return legend;\n };\n\n legend.labels = function (_) {\n if (!arguments.length) return labels;\n labels = _;\n return legend;\n };\n\n legend.labelAlign = function (_) {\n if (!arguments.length) return labelAlign;\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\n labelAlign = _;\n }\n return legend;\n };\n\n legend.labelFormat = function (_) {\n if (!arguments.length) return labelFormat;\n labelFormat = _;\n return legend;\n };\n\n legend.labelOffset = function (_) {\n if (!arguments.length) return labelOffset;\n labelOffset = +_;\n return legend;\n };\n\n legend.labelDelimiter = function (_) {\n if (!arguments.length) return labelDelimiter;\n labelDelimiter = _;\n return legend;\n };\n\n legend.orient = function (_) {\n if (!arguments.length) return orient;\n _ = _.toLowerCase();\n if (_ == \"horizontal\" || _ == \"vertical\") {\n orient = _;\n }\n return legend;\n };\n\n legend.ascending = function (_) {\n if (!arguments.length) return ascending;\n ascending = !!_;\n return legend;\n };\n\n legend.classPrefix = function (_) {\n if (!arguments.length) return classPrefix;\n classPrefix = _;\n return legend;\n };\n\n legend.title = function (_) {\n if (!arguments.length) return title;\n title = _;\n return legend;\n };\n\n d3.rebind(legend, legendDispatcher, \"on\");\n\n return legend;\n};\n\n},{\"./legend\":3}],5:[function(require,module,exports){\n\"use strict\";\n\nvar helper = require('./legend');\n\nmodule.exports = function () {\n\n var scale = d3.scale.linear(),\n shape = \"path\",\n shapeWidth = 15,\n shapeHeight = 15,\n shapeRadius = 10,\n shapePadding = 5,\n cells = [5],\n labels = [],\n classPrefix = \"\",\n useClass = false,\n title = \"\",\n labelFormat = d3.format(\".01f\"),\n labelAlign = \"middle\",\n labelOffset = 10,\n labelDelimiter = \"to\",\n orient = \"vertical\",\n ascending = false,\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\n\n function legend(svg) {\n\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\n legendG = svg.selectAll('g').data([scale]);\n\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\n\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\n\n //add event handlers\n helper.d3_addEvents(cellEnter, legendDispatcher);\n\n //remove old shapes\n cell.exit().transition().style(\"opacity\", 0).remove();\n\n helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, type.feature);\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix);\n\n // sets placement\n var text = cell.select(\"text\"),\n shapeSize = shapes[0].map(function (d) {\n return d.getBBox();\n });\n\n var maxH = d3.max(shapeSize, function (d) {\n return d.height;\n }),\n maxW = d3.max(shapeSize, function (d) {\n return d.width;\n });\n\n var cellTrans,\n textTrans,\n textAlign = labelAlign == \"start\" ? 0 : labelAlign == \"middle\" ? 0.5 : 1;\n\n //positions cells and text\n if (orient === \"vertical\") {\n cellTrans = function cellTrans(d, i) {\n return \"translate(0, \" + i * (maxH + shapePadding) + \")\";\n };\n textTrans = function textTrans(d, i) {\n return \"translate(\" + (maxW + labelOffset) + \",\" + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + \")\";\n };\n } else if (orient === \"horizontal\") {\n cellTrans = function cellTrans(d, i) {\n return \"translate(\" + i * (maxW + shapePadding) + \",0)\";\n };\n textTrans = function textTrans(d, i) {\n return \"translate(\" + (shapeSize[i].width * textAlign + shapeSize[i].x) + \",\" + (maxH + labelOffset) + \")\";\n };\n }\n\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\n helper.d3_title(svg, legendG, title, classPrefix);\n cell.transition().style(\"opacity\", 1);\n }\n\n legend.scale = function (_) {\n if (!arguments.length) return scale;\n scale = _;\n return legend;\n };\n\n legend.cells = function (_) {\n if (!arguments.length) return cells;\n if (_.length > 1 || _ >= 2) {\n cells = _;\n }\n return legend;\n };\n\n legend.shapePadding = function (_) {\n if (!arguments.length) return shapePadding;\n shapePadding = +_;\n return legend;\n };\n\n legend.labels = function (_) {\n if (!arguments.length) return labels;\n labels = _;\n return legend;\n };\n\n legend.labelAlign = function (_) {\n if (!arguments.length) return labelAlign;\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\n labelAlign = _;\n }\n return legend;\n };\n\n legend.labelFormat = function (_) {\n if (!arguments.length) return labelFormat;\n labelFormat = _;\n return legend;\n };\n\n legend.labelOffset = function (_) {\n if (!arguments.length) return labelOffset;\n labelOffset = +_;\n return legend;\n };\n\n legend.labelDelimiter = function (_) {\n if (!arguments.length) return labelDelimiter;\n labelDelimiter = _;\n return legend;\n };\n\n legend.orient = function (_) {\n if (!arguments.length) return orient;\n _ = _.toLowerCase();\n if (_ == \"horizontal\" || _ == \"vertical\") {\n orient = _;\n }\n return legend;\n };\n\n legend.ascending = function (_) {\n if (!arguments.length) return ascending;\n ascending = !!_;\n return legend;\n };\n\n legend.classPrefix = function (_) {\n if (!arguments.length) return classPrefix;\n classPrefix = _;\n return legend;\n };\n\n legend.title = function (_) {\n if (!arguments.length) return title;\n title = _;\n return legend;\n };\n\n d3.rebind(legend, legendDispatcher, \"on\");\n\n return legend;\n};\n\n},{\"./legend\":3}],6:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * **[Gaussian error function](http://en.wikipedia.org/wiki/Error_function)**\r\n *\r\n * The `errorFunction(x/(sd * Math.sqrt(2)))` is the probability that a value in a\r\n * normal distribution with standard deviation sd is within x of the mean.\r\n *\r\n * This function returns a numerical approximation to the exact value.\r\n *\r\n * @param {number} x input\r\n * @return {number} error estimation\r\n * @example\r\n * errorFunction(1); //= 0.8427\r\n */\n\nfunction errorFunction(x /*: number */) /*: number */{\n var t = 1 / (1 + 0.5 * Math.abs(x));\n var tau = t * Math.exp(-Math.pow(x, 2) - 1.26551223 + 1.00002368 * t + 0.37409196 * Math.pow(t, 2) + 0.09678418 * Math.pow(t, 3) - 0.18628806 * Math.pow(t, 4) + 0.27886807 * Math.pow(t, 5) - 1.13520398 * Math.pow(t, 6) + 1.48851587 * Math.pow(t, 7) - 0.82215223 * Math.pow(t, 8) + 0.17087277 * Math.pow(t, 9));\n if (x >= 0) {\n return 1 - tau;\n } else {\n return tau - 1;\n }\n}\n\nmodule.exports = errorFunction;\n\n},{}],7:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * [Simple linear regression](http://en.wikipedia.org/wiki/Simple_linear_regression)\r\n * is a simple way to find a fitted line\r\n * between a set of coordinates. This algorithm finds the slope and y-intercept of a regression line\r\n * using the least sum of squares.\r\n *\r\n * @param {Array>} data an array of two-element of arrays,\r\n * like `[[0, 1], [2, 3]]`\r\n * @returns {Object} object containing slope and intersect of regression line\r\n * @example\r\n * linearRegression([[0, 0], [1, 1]]); // { m: 1, b: 0 }\r\n */\n\nfunction linearRegression(data /*: Array> */) /*: { m: number, b: number } */{\n\n var m, b;\n\n // Store data length in a local variable to reduce\n // repeated object property lookups\n var dataLength = data.length;\n\n //if there's only one point, arbitrarily choose a slope of 0\n //and a y-intercept of whatever the y of the initial point is\n if (dataLength === 1) {\n m = 0;\n b = data[0][1];\n } else {\n // Initialize our sums and scope the `m` and `b`\n // variables that define the line.\n var sumX = 0,\n sumY = 0,\n sumXX = 0,\n sumXY = 0;\n\n // Use local variables to grab point values\n // with minimal object property lookups\n var point, x, y;\n\n // Gather the sum of all x values, the sum of all\n // y values, and the sum of x^2 and (x*y) for each\n // value.\n //\n // In math notation, these would be SS_x, SS_y, SS_xx, and SS_xy\n for (var i = 0; i < dataLength; i++) {\n point = data[i];\n x = point[0];\n y = point[1];\n\n sumX += x;\n sumY += y;\n\n sumXX += x * x;\n sumXY += x * y;\n }\n\n // `m` is the slope of the regression line\n m = (dataLength * sumXY - sumX * sumY) / (dataLength * sumXX - sumX * sumX);\n\n // `b` is the y-intercept of the line.\n b = sumY / dataLength - m * sumX / dataLength;\n }\n\n // Return both values as an object.\n return {\n m: m,\n b: b\n };\n}\n\nmodule.exports = linearRegression;\n\n},{}],8:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * Given the output of `linearRegression`: an object\r\n * with `m` and `b` values indicating slope and intercept,\r\n * respectively, generate a line function that translates\r\n * x values into y values.\r\n *\r\n * @param {Object} mb object with `m` and `b` members, representing\r\n * slope and intersect of desired line\r\n * @returns {Function} method that computes y-value at any given\r\n * x-value on the line.\r\n * @example\r\n * var l = linearRegressionLine(linearRegression([[0, 0], [1, 1]]));\r\n * l(0) //= 0\r\n * l(2) //= 2\r\n */\n\nfunction linearRegressionLine(mb /*: { b: number, m: number }*/) /*: Function */{\n // Return a function that computes a `y` value for each\n // x value it is given, based on the values of `b` and `a`\n // that we just computed.\n return function (x) {\n return mb.b + mb.m * x;\n };\n}\n\nmodule.exports = linearRegressionLine;\n\n},{}],9:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sum = require('./sum');\n\n/**\r\n * The mean, _also known as average_,\r\n * is the sum of all values over the number of values.\r\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\r\n * a method of finding a typical or central value of a set of numbers.\r\n *\r\n * This runs on `O(n)`, linear time in respect to the array\r\n *\r\n * @param {Array} x input values\r\n * @returns {number} mean\r\n * @example\r\n * console.log(mean([0, 10])); // 5\r\n */\nfunction mean(x /*: Array */) /*:number*/{\n // The mean of no numbers is null\n if (x.length === 0) {\n return NaN;\n }\n\n return sum(x) / x.length;\n}\n\nmodule.exports = mean;\n\n},{\"./sum\":15}],10:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sampleCovariance = require('./sample_covariance');\nvar sampleStandardDeviation = require('./sample_standard_deviation');\n\n/**\r\n * The [correlation](http://en.wikipedia.org/wiki/Correlation_and_dependence) is\r\n * a measure of how correlated two datasets are, between -1 and 1\r\n *\r\n * @param {Array} x first input\r\n * @param {Array} y second input\r\n * @returns {number} sample correlation\r\n * @example\r\n * var a = [1, 2, 3, 4, 5, 6];\r\n * var b = [2, 2, 3, 4, 5, 60];\r\n * sampleCorrelation(a, b); //= 0.691\r\n */\nfunction sampleCorrelation(x /*: Array */, y /*: Array */) /*:number*/{\n var cov = sampleCovariance(x, y),\n xstd = sampleStandardDeviation(x),\n ystd = sampleStandardDeviation(y);\n\n return cov / xstd / ystd;\n}\n\nmodule.exports = sampleCorrelation;\n\n},{\"./sample_covariance\":11,\"./sample_standard_deviation\":12}],11:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar mean = require('./mean');\n\n/**\r\n * [Sample covariance](https://en.wikipedia.org/wiki/Sample_mean_and_sampleCovariance) of two datasets:\r\n * how much do the two datasets move together?\r\n * x and y are two datasets, represented as arrays of numbers.\r\n *\r\n * @param {Array} x first input\r\n * @param {Array} y second input\r\n * @returns {number} sample covariance\r\n * @example\r\n * var x = [1, 2, 3, 4, 5, 6];\r\n * var y = [6, 5, 4, 3, 2, 1];\r\n * sampleCovariance(x, y); //= -3.5\r\n */\nfunction sampleCovariance(x /*:Array*/, y /*:Array*/) /*:number*/{\n\n // The two datasets must have the same length which must be more than 1\n if (x.length <= 1 || x.length !== y.length) {\n return NaN;\n }\n\n // determine the mean of each dataset so that we can judge each\n // value of the dataset fairly as the difference from the mean. this\n // way, if one dataset is [1, 2, 3] and [2, 3, 4], their covariance\n // does not suffer because of the difference in absolute values\n var xmean = mean(x),\n ymean = mean(y),\n sum = 0;\n\n // for each pair of values, the covariance increases when their\n // difference from the mean is associated - if both are well above\n // or if both are well below\n // the mean, the covariance increases significantly.\n for (var i = 0; i < x.length; i++) {\n sum += (x[i] - xmean) * (y[i] - ymean);\n }\n\n // this is Bessels' Correction: an adjustment made to sample statistics\n // that allows for the reduced degree of freedom entailed in calculating\n // values from samples rather than complete populations.\n var besselsCorrection = x.length - 1;\n\n // the covariance is weighted by the length of the datasets.\n return sum / besselsCorrection;\n}\n\nmodule.exports = sampleCovariance;\n\n},{\"./mean\":9}],12:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sampleVariance = require('./sample_variance');\n\n/**\r\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\r\n * is the square root of the variance.\r\n *\r\n * @param {Array} x input array\r\n * @returns {number} sample standard deviation\r\n * @example\r\n * ss.sampleStandardDeviation([2, 4, 4, 4, 5, 5, 7, 9]);\r\n * //= 2.138\r\n */\nfunction sampleStandardDeviation(x /*:Array*/) /*:number*/{\n // The standard deviation of no numbers is null\n var sampleVarianceX = sampleVariance(x);\n if (isNaN(sampleVarianceX)) {\n return NaN;\n }\n return Math.sqrt(sampleVarianceX);\n}\n\nmodule.exports = sampleStandardDeviation;\n\n},{\"./sample_variance\":13}],13:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sumNthPowerDeviations = require('./sum_nth_power_deviations');\n\n/*\r\n * The [sample variance](https://en.wikipedia.org/wiki/Variance#Sample_variance)\r\n * is the sum of squared deviations from the mean. The sample variance\r\n * is distinguished from the variance by the usage of [Bessel's Correction](https://en.wikipedia.org/wiki/Bessel's_correction):\r\n * instead of dividing the sum of squared deviations by the length of the input,\r\n * it is divided by the length minus one. This corrects the bias in estimating\r\n * a value from a set that you don't know if full.\r\n *\r\n * References:\r\n * * [Wolfram MathWorld on Sample Variance](http://mathworld.wolfram.com/SampleVariance.html)\r\n *\r\n * @param {Array} x input array\r\n * @return {number} sample variance\r\n * @example\r\n * sampleVariance([1, 2, 3, 4, 5]); //= 2.5\r\n */\nfunction sampleVariance(x /*: Array */) /*:number*/{\n // The variance of no numbers is null\n if (x.length <= 1) {\n return NaN;\n }\n\n var sumSquaredDeviationsValue = sumNthPowerDeviations(x, 2);\n\n // this is Bessels' Correction: an adjustment made to sample statistics\n // that allows for the reduced degree of freedom entailed in calculating\n // values from samples rather than complete populations.\n var besselsCorrection = x.length - 1;\n\n // Find the mean value of that list\n return sumSquaredDeviationsValue / besselsCorrection;\n}\n\nmodule.exports = sampleVariance;\n\n},{\"./sum_nth_power_deviations\":16}],14:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar variance = require('./variance');\n\n/**\r\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\r\n * is the square root of the variance. It's useful for measuring the amount\r\n * of variation or dispersion in a set of values.\r\n *\r\n * Standard deviation is only appropriate for full-population knowledge: for\r\n * samples of a population, {@link sampleStandardDeviation} is\r\n * more appropriate.\r\n *\r\n * @param {Array} x input\r\n * @returns {number} standard deviation\r\n * @example\r\n * var scores = [2, 4, 4, 4, 5, 5, 7, 9];\r\n * variance(scores); //= 4\r\n * standardDeviation(scores); //= 2\r\n */\nfunction standardDeviation(x /*: Array */) /*:number*/{\n // The standard deviation of no numbers is null\n var v = variance(x);\n if (isNaN(v)) {\n return 0;\n }\n return Math.sqrt(v);\n}\n\nmodule.exports = standardDeviation;\n\n},{\"./variance\":17}],15:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * Our default sum is the [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) is\r\n * a method for computing the sum of a list of numbers while correcting\r\n * for floating-point errors. Traditionally, sums are calculated as many\r\n * successive additions, each one with its own floating-point roundoff. These\r\n * losses in precision add up as the number of numbers increases. This alternative\r\n * algorithm is more accurate than the simple way of calculating sums by simple\r\n * addition.\r\n *\r\n * This runs on `O(n)`, linear time in respect to the array\r\n *\r\n * @param {Array} x input\r\n * @return {number} sum of all input numbers\r\n * @example\r\n * console.log(sum([1, 2, 3])); // 6\r\n */\n\nfunction sum(x /*: Array */) /*: number */{\n\n // like the traditional sum algorithm, we keep a running\n // count of the current sum.\n var sum = 0;\n\n // but we also keep three extra variables as bookkeeping:\n // most importantly, an error correction value. This will be a very\n // small number that is the opposite of the floating point precision loss.\n var errorCompensation = 0;\n\n // this will be each number in the list corrected with the compensation value.\n var correctedCurrentValue;\n\n // and this will be the next sum\n var nextSum;\n\n for (var i = 0; i < x.length; i++) {\n // first correct the value that we're going to add to the sum\n correctedCurrentValue = x[i] - errorCompensation;\n\n // compute the next sum. sum is likely a much larger number\n // than correctedCurrentValue, so we'll lose precision here,\n // and measure how much precision is lost in the next step\n nextSum = sum + correctedCurrentValue;\n\n // we intentionally didn't assign sum immediately, but stored\n // it for now so we can figure out this: is (sum + nextValue) - nextValue\n // not equal to 0? ideally it would be, but in practice it won't:\n // it will be some very small number. that's what we record\n // as errorCompensation.\n errorCompensation = nextSum - sum - correctedCurrentValue;\n\n // now that we've computed how much we'll correct for in the next\n // loop, start treating the nextSum as the current sum.\n sum = nextSum;\n }\n\n return sum;\n}\n\nmodule.exports = sum;\n\n},{}],16:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar mean = require('./mean');\n\n/**\r\n * The sum of deviations to the Nth power.\r\n * When n=2 it's the sum of squared deviations.\r\n * When n=3 it's the sum of cubed deviations.\r\n *\r\n * @param {Array} x\r\n * @param {number} n power\r\n * @returns {number} sum of nth power deviations\r\n * @example\r\n * var input = [1, 2, 3];\r\n * // since the variance of a set is the mean squared\r\n * // deviations, we can calculate that with sumNthPowerDeviations:\r\n * var variance = sumNthPowerDeviations(input) / input.length;\r\n */\nfunction sumNthPowerDeviations(x /*: Array */, n /*: number */) /*:number*/{\n var meanValue = mean(x),\n sum = 0;\n\n for (var i = 0; i < x.length; i++) {\n sum += Math.pow(x[i] - meanValue, n);\n }\n\n return sum;\n}\n\nmodule.exports = sumNthPowerDeviations;\n\n},{\"./mean\":9}],17:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sumNthPowerDeviations = require('./sum_nth_power_deviations');\n\n/**\r\n * The [variance](http://en.wikipedia.org/wiki/Variance)\r\n * is the sum of squared deviations from the mean.\r\n *\r\n * This is an implementation of variance, not sample variance:\r\n * see the `sampleVariance` method if you want a sample measure.\r\n *\r\n * @param {Array} x a population\r\n * @returns {number} variance: a value greater than or equal to zero.\r\n * zero indicates that all values are identical.\r\n * @example\r\n * ss.variance([1, 2, 3, 4, 5, 6]); //= 2.917\r\n */\nfunction variance(x /*: Array */) /*:number*/{\n // The variance of no numbers is null\n if (x.length === 0) {\n return NaN;\n }\n\n // Find the mean of squared deviations between the\n // mean value and each value.\n return sumNthPowerDeviations(x, 2) / x.length;\n}\n\nmodule.exports = variance;\n\n},{\"./sum_nth_power_deviations\":16}],18:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * The [Z-Score, or Standard Score](http://en.wikipedia.org/wiki/Standard_score).\r\n *\r\n * The standard score is the number of standard deviations an observation\r\n * or datum is above or below the mean. Thus, a positive standard score\r\n * represents a datum above the mean, while a negative standard score\r\n * represents a datum below the mean. It is a dimensionless quantity\r\n * obtained by subtracting the population mean from an individual raw\r\n * score and then dividing the difference by the population standard\r\n * deviation.\r\n *\r\n * The z-score is only defined if one knows the population parameters;\r\n * if one only has a sample set, then the analogous computation with\r\n * sample mean and sample standard deviation yields the\r\n * Student's t-statistic.\r\n *\r\n * @param {number} x\r\n * @param {number} mean\r\n * @param {number} standardDeviation\r\n * @return {number} z score\r\n * @example\r\n * ss.zScore(78, 80, 5); //= -0.4\r\n */\n\nfunction zScore(x /*:number*/, mean /*:number*/, standardDeviation /*:number*/) /*:number*/{\n return (x - mean) / standardDeviation;\n}\n\nmodule.exports = zScore;\n\n},{}],19:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.BarChart = exports.BarChartConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _utils = require(\"./utils\");\n\nvar _legend = require(\"./legend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar BarChartConfig = exports.BarChartConfig = function (_ChartConfig) {\n _inherits(BarChartConfig, _ChartConfig);\n\n // string or function returning color's value for color scale\n\n function BarChartConfig(custom) {\n _classCallCheck(this, BarChartConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(BarChartConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'bar-chart';\n _this.showLegend = true;\n _this.showTooltip = true;\n _this.legend = {\n width: 80,\n margin: 10,\n shapeWidth: 20\n };\n _this.x = { // X axis config\n label: '', // axis label\n key: 0,\n value: function value(d, key) {\n return _utils.Utils.isNumber(d) ? d : d[key];\n }, // x value accessor\n scale: \"ordinal\",\n ticks: undefined\n };\n _this.y = { // Y axis config\n key: 1,\n value: function value(d, key) {\n return _utils.Utils.isNumber(d) ? d : d[key];\n }, // x value accessor\n label: '', // axis label,\n orient: \"left\",\n scale: \"linear\"\n };\n _this.groups = {\n key: 1,\n value: function value(d) {\n return d[_this.groups.key];\n }, // grouping value accessor,\n label: \"\"\n };\n _this.color = undefined;\n _this.d3ColorCategory = 'category10';\n _this.transition = true;\n\n var config = _this;\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n }\n\n return BarChartConfig;\n}(_chart.ChartConfig);\n\nvar BarChart = exports.BarChart = function (_Chart) {\n _inherits(BarChart, _Chart);\n\n function BarChart(placeholderSelector, data, config) {\n _classCallCheck(this, BarChart);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(BarChart).call(this, placeholderSelector, data, new BarChartConfig(config)));\n }\n\n _createClass(BarChart, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(BarChart.prototype), \"setConfig\", this).call(this, new BarChartConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(BarChart.prototype), \"initPlot\", this).call(this);\n var self = this;\n\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.y = {};\n\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n this.plot.margin.right = conf.margin.right + conf.legend.width + conf.legend.margin * 2;\n }\n\n this.computePlotSize();\n this.setupY();\n this.setupX();\n this.setupGroupStacks();\n\n this.setupYDomain();\n\n if (conf.d3ColorCategory) {\n this.plot.colorCategory = d3.scale[conf.d3ColorCategory]();\n }\n var colorValue = conf.color;\n if (colorValue && typeof colorValue === 'string' || colorValue instanceof String) {\n this.plot.color = colorValue;\n } else if (this.plot.colorCategory) {\n this.plot.color = function (d) {\n return self.plot.colorCategory(d.key);\n };\n }\n\n return this;\n }\n }, {\n key: \"setupX\",\n value: function setupX() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config.x;\n\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\n x.value = function (d) {\n return conf.value(d, conf.key);\n };\n x.scale = d3.scale.ordinal().rangeRoundBands([0, plot.width], .08);\n x.map = function (d) {\n return x.scale(x.value(d));\n };\n\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\n\n var data = this.data;\n var domain;\n if (!this.config.series) {\n domain = d3.map(data, x.value).keys();\n } else {\n domain = d3.map(data[0].values, x.value).keys();\n }\n\n plot.x.scale.domain(domain);\n void 0;\n }\n }, {\n key: \"setupY\",\n value: function setupY() {\n\n var plot = this.plot;\n var y = plot.y;\n var conf = this.config.y;\n y.value = function (d) {\n return conf.value(d, conf.key);\n };\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\n y.map = function (d) {\n return y.scale(y.value(d));\n };\n\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\n if (conf.ticks) {\n y.axis.ticks(conf.ticks);\n }\n }\n }, {\n key: \"setupYDomain\",\n value: function setupYDomain() {\n var plot = this.plot;\n var data = this.data;\n var domain;\n var yStackMax = d3.max(plot.layers, function (layer) {\n return d3.max(layer.values, function (d) {\n return d.y0 + d.y;\n });\n });\n if (!this.config.series) {\n domain = [d3.min(data, plot.y.value), d3.max(data, plot.y.value)];\n } else {\n\n // var min = d3.min(data, s=>d3.min(s.values, plot.y.value));\n var max = yStackMax;\n domain = [0, max];\n }\n plot.y.scale.domain(domain);\n void 0;\n }\n }, {\n key: \"groupData\",\n value: function groupData() {\n var self = this;\n this.plot.groupingEnabled = this.config.series;\n var data = this.data;\n if (!this.plot.groupingEnabled) {\n this.plot.groupedData = [{\n key: 'root',\n values: self.mapToPoints(data)\n }];\n } else {\n\n this.plot.groupedData = data.map(function (s) {\n return {\n key: s.key,\n values: self.mapToPoints(s.values)\n };\n });\n }\n }\n }, {\n key: \"setupGroupStacks\",\n value: function setupGroupStacks() {\n var self = this;\n this.groupData();\n\n this.plot.stack = d3.layout.stack().values(function (d) {\n return d.values;\n });\n this.plot.layers = this.plot.stack(this.plot.groupedData);\n }\n }, {\n key: \"mapToPoints\",\n value: function mapToPoints(values) {\n var plot = this.plot;\n return values.map(function (v) {\n return {\n x: plot.x.value(v),\n y: plot.y.value(v)\n };\n });\n }\n }, {\n key: \"drawAxisX\",\n value: function drawAxisX() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.x;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides'))).attr(\"transform\", \"translate(0,\" + plot.height + \")\");\n\n var axisT = axis;\n if (self.config.transition) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.x.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + plot.width / 2 + \",\" + plot.margin.bottom + \")\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"-1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawAxisY\",\n value: function drawAxisY() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.y;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides')));\n\n var axisT = axis;\n if (self.config.transition) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.y.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + plot.height / 2 + \")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawBars\",\n value: function drawBars() {\n var self = this;\n var plot = self.plot;\n\n void 0;\n\n var layerClass = this.prefixClass(\"layer\");\n\n var barClass = this.prefixClass(\"bar\");\n var layer = self.svgG.selectAll(\".\" + layerClass).data(plot.layers);\n\n layer.enter().append(\"g\").attr(\"class\", layerClass);\n\n var bar = layer.selectAll(\".\" + barClass).data(function (d) {\n return d.values;\n });\n\n bar.enter().append(\"g\").attr(\"class\", barClass).append(\"rect\").attr(\"x\", 1);\n\n var barRect = bar.select(\"rect\");\n\n var barRectT = barRect;\n var barT = bar;\n var layerT = layer;\n if (this.transitionEnabled()) {\n barRectT = barRect.transition();\n barT = bar.transition();\n layerT = layer.transition();\n }\n\n var yDomain = plot.y.scale.domain();\n barT.attr(\"transform\", function (d) {\n return \"translate(\" + plot.x.scale(d.x) + \",\" + plot.y.scale(d.y0 + d.y) + \")\";\n });\n\n barRectT.attr(\"width\", plot.x.scale.rangeBand()).attr(\"height\", function (d) {\n return plot.y.scale(d.y0) - plot.y.scale(d.y0 + d.y - yDomain[0]);\n });\n\n if (this.plot.color) {\n layerT.attr(\"fill\", this.plot.color);\n }\n\n if (plot.tooltip) {\n bar.on(\"mouseover\", function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n plot.tooltip.html(d.y).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n }).on(\"mouseout\", function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n layer.exit().remove();\n bar.exit().remove();\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(BarChart.prototype), \"update\", this).call(this, newData);\n this.drawAxisX();\n this.drawAxisY();\n\n this.drawBars();\n\n this.updateLegend();\n }\n }, {\n key: \"updateLegend\",\n value: function updateLegend() {\n var plot = this.plot;\n\n var scale = plot.colorCategory;\n if (!scale.domain() || scale.domain().length < 2) {\n plot.showLegend = false;\n }\n\n if (!plot.showLegend) {\n if (plot.legend && plot.legend.container) {\n plot.legend.container.remove();\n }\n return;\n }\n\n var legendX = this.plot.width + this.config.legend.margin;\n var legendY = this.config.legend.margin;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY);\n\n var legendLinear = plot.legend.color().shapeWidth(this.config.legend.shapeWidth).orient('vertical').scale(scale);\n\n plot.legend.container.call(legendLinear);\n }\n }]);\n\n return BarChart;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./utils\":33}],20:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Chart = exports.ChartConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _utils = require('./utils');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar ChartConfig = exports.ChartConfig = function ChartConfig(custom) {\n _classCallCheck(this, ChartConfig);\n\n this.cssClassPrefix = \"odc-\";\n this.svgClass = this.cssClassPrefix + 'mw-d3-chart';\n this.width = undefined;\n this.height = undefined;\n this.margin = {\n left: 50,\n right: 30,\n top: 30,\n bottom: 50\n };\n this.showTooltip = false;\n this.transition = true;\n\n if (custom) {\n _utils.Utils.deepExtend(this, custom);\n }\n};\n\nvar Chart = exports.Chart = function () {\n function Chart(base, data, config) {\n _classCallCheck(this, Chart);\n\n this.utils = _utils.Utils;\n this.plot = {\n margin: {}\n };\n this._attached = {};\n this._layers = {};\n this._events = {};\n this._isInitialized = false;\n\n\n this._isAttached = base instanceof Chart;\n\n this.baseContainer = base;\n\n this.setConfig(config);\n\n if (data) {\n this.setData(data);\n }\n\n this.init();\n this.postInit();\n }\n\n _createClass(Chart, [{\n key: 'setConfig',\n value: function setConfig(config) {\n if (!config) {\n this.config = new ChartConfig();\n } else {\n this.config = config;\n }\n\n return this;\n }\n }, {\n key: 'setData',\n value: function setData(data) {\n this.data = data;\n return this;\n }\n }, {\n key: 'init',\n value: function init() {\n var self = this;\n\n self.initPlot();\n self.initSvg();\n\n self.initTooltip();\n self.draw();\n this._isInitialized = true;\n return this;\n }\n }, {\n key: 'postInit',\n value: function postInit() {}\n }, {\n key: 'initSvg',\n value: function initSvg() {\n var self = this;\n var config = this.config;\n\n var margin = self.plot.margin;\n var width = self.plot.width + margin.left + margin.right;\n var height = self.plot.height + margin.top + margin.bottom;\n var aspect = width / height;\n if (!self._isAttached) {\n if (!this._isInitialized) {\n d3.select(self.baseContainer).select(\"svg\").remove();\n }\n self.svg = d3.select(self.baseContainer).selectOrAppend(\"svg\");\n\n self.svg.attr(\"width\", width).attr(\"height\", height).attr(\"viewBox\", \"0 0 \" + \" \" + width + \" \" + height).attr(\"preserveAspectRatio\", \"xMidYMid meet\").attr(\"class\", config.svgClass);\n self.svgG = self.svg.selectOrAppend(\"g.main-group\");\n } else {\n void 0;\n self.svg = self.baseContainer.svg;\n self.svgG = self.svg.selectOrAppend(\"g.main-group.\" + config.svgClass);\n }\n\n self.svgG.attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");\n\n if (!config.width || config.height) {\n d3.select(window).on(\"resize\", function () {\n //TODO add responsiveness if width/height not specified\n });\n }\n }\n }, {\n key: 'initTooltip',\n value: function initTooltip() {\n var self = this;\n if (self.config.showTooltip) {\n if (!self._isAttached) {\n self.plot.tooltip = d3.select(\"body\").selectOrAppend('div.' + self.config.cssClassPrefix + 'tooltip').style(\"opacity\", 0);\n } else {\n self.plot.tooltip = self.baseContainer.plot.tooltip;\n }\n }\n }\n }, {\n key: 'initPlot',\n value: function initPlot() {\n var margin = this.config.margin;\n this.plot = this.plot || {};\n this.plot.margin = {\n top: margin.top,\n bottom: margin.bottom,\n left: margin.left,\n right: margin.right\n };\n }\n }, {\n key: 'update',\n value: function update(data) {\n if (data) {\n this.setData(data);\n }\n var layerName, attachmentData;\n for (var attachmentName in this._attached) {\n\n attachmentData = data;\n\n this._attached[attachmentName].update(attachmentData);\n }\n return this;\n }\n }, {\n key: 'draw',\n value: function draw(data) {\n this.update(data);\n\n return this;\n }\n\n //Borrowed from d3.chart\n /**\r\n * Register or retrieve an \"attachment\" Chart. The \"attachment\" chart's `draw`\r\n * method will be invoked whenever the containing chart's `draw` method is\r\n * invoked.\r\n *\r\n * @externalExample chart-attach\r\n *\r\n * @param {String} attachmentName Name of the attachment\r\n * @param {Chart} [chart] Chart to register as a mix in of this chart. When\r\n * unspecified, this method will return the attachment previously\r\n * registered with the specified `attachmentName` (if any).\r\n *\r\n * @returns {Chart} Reference to this chart (chainable).\r\n */\n\n }, {\n key: 'attach',\n value: function attach(attachmentName, chart) {\n if (arguments.length === 1) {\n return this._attached[attachmentName];\n }\n\n this._attached[attachmentName] = chart;\n return chart;\n }\n }, {\n key: 'on',\n\n\n //Borrowed from d3.chart\n /**\r\n * Subscribe a callback function to an event triggered on the chart. See {@link\r\n * Chart#once} to subscribe a callback function to an event for one occurence.\r\n *\r\n * @externalExample {runnable} chart-on\r\n *\r\n * @param {String} name Name of the event\r\n * @param {ChartEventHandler} callback Function to be invoked when the event\r\n * occurs\r\n * @param {Object} [context] Value to set as `this` when invoking the\r\n * `callback`. Defaults to the chart instance.\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\n value: function on(name, callback, context) {\n var events = this._events[name] || (this._events[name] = []);\n events.push({\n callback: callback,\n context: context || this,\n _chart: this\n });\n return this;\n }\n\n //Borrowed from d3.chart\n /**\r\n *\r\n * Subscribe a callback function to an event triggered on the chart. This\r\n * function will be invoked at the next occurance of the event and immediately\r\n * unsubscribed. See {@link Chart#on} to subscribe a callback function to an\r\n * event indefinitely.\r\n *\r\n * @externalExample {runnable} chart-once\r\n *\r\n * @param {String} name Name of the event\r\n * @param {ChartEventHandler} callback Function to be invoked when the event\r\n * occurs\r\n * @param {Object} [context] Value to set as `this` when invoking the\r\n * `callback`. Defaults to the chart instance\r\n *\r\n * @returns {Chart} A reference to this chart (chainable)\r\n */\n\n }, {\n key: 'once',\n value: function once(name, callback, context) {\n var self = this;\n var once = function once() {\n self.off(name, once);\n callback.apply(this, arguments);\n };\n return this.on(name, once, context);\n }\n\n //Borrowed from d3.chart\n /**\r\n * Unsubscribe one or more callback functions from an event triggered on the\r\n * chart. When no arguments are specified, *all* handlers will be unsubscribed.\r\n * When only a `name` is specified, all handlers subscribed to that event will\r\n * be unsubscribed. When a `name` and `callback` are specified, only that\r\n * function will be unsubscribed from that event. When a `name` and `context`\r\n * are specified (but `callback` is omitted), all events bound to the given\r\n * event with the given context will be unsubscribed.\r\n *\r\n * @externalExample {runnable} chart-off\r\n *\r\n * @param {String} [name] Name of the event to be unsubscribed\r\n * @param {ChartEventHandler} [callback] Function to be unsubscribed\r\n * @param {Object} [context] Contexts to be unsubscribe\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\n\n }, {\n key: 'off',\n value: function off(name, callback, context) {\n var names, n, events, event, i, j;\n\n // remove all events\n if (arguments.length === 0) {\n for (name in this._events) {\n this._events[name].length = 0;\n }\n return this;\n }\n\n // remove all events for a specific name\n if (arguments.length === 1) {\n events = this._events[name];\n if (events) {\n events.length = 0;\n }\n return this;\n }\n\n // remove all events that match whatever combination of name, context\n // and callback.\n names = name ? [name] : Object.keys(this._events);\n for (i = 0; i < names.length; i++) {\n n = names[i];\n events = this._events[n];\n j = events.length;\n while (j--) {\n event = events[j];\n if (callback && callback === event.callback || context && context === event.context) {\n events.splice(j, 1);\n }\n }\n }\n\n return this;\n }\n }, {\n key: 'trigger',\n\n\n //Borrowed from d3.chart\n /**\r\n * Publish an event on this chart with the given `name`.\r\n *\r\n * @externalExample {runnable} chart-trigger\r\n *\r\n * @param {String} name Name of the event to publish\r\n * @param {...*} arguments Values with which to invoke the registered\r\n * callbacks.\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\n value: function trigger(name) {\n var args = Array.prototype.slice.call(arguments, 1);\n var events = this._events[name];\n var i, ev;\n\n if (events !== undefined) {\n for (i = 0; i < events.length; i++) {\n ev = events[i];\n ev.callback.apply(ev.context, args);\n }\n }\n\n return this;\n }\n }, {\n key: 'getBaseContainer',\n value: function getBaseContainer() {\n if (this._isAttached) {\n return this.baseContainer.svg;\n }\n return d3.select(this.baseContainer);\n }\n }, {\n key: 'getBaseContainerNode',\n value: function getBaseContainerNode() {\n\n return this.getBaseContainer().node();\n }\n }, {\n key: 'prefixClass',\n value: function prefixClass(clazz, addDot) {\n return addDot ? '.' : '' + this.config.cssClassPrefix + clazz;\n }\n }, {\n key: 'computePlotSize',\n value: function computePlotSize() {\n this.plot.width = _utils.Utils.availableWidth(this.config.width, this.getBaseContainer(), this.plot.margin);\n this.plot.height = _utils.Utils.availableHeight(this.config.height, this.getBaseContainer(), this.plot.margin);\n }\n }, {\n key: 'transitionEnabled',\n value: function transitionEnabled() {\n return this._isInitialized && this.config.transition;\n }\n }]);\n\n return Chart;\n}();\n\n},{\"./utils\":33}],21:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.CorrelationMatrix = exports.CorrelationMatrixConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require('./chart');\n\nvar _utils = require('./utils');\n\nvar _statisticsUtils = require('./statistics-utils');\n\nvar _legend = require('./legend');\n\nvar _scatterplot = require('./scatterplot');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar CorrelationMatrixConfig = exports.CorrelationMatrixConfig = function (_ChartConfig) {\n _inherits(CorrelationMatrixConfig, _ChartConfig);\n\n //show tooltip on dot hover\n\n function CorrelationMatrixConfig(custom) {\n _classCallCheck(this, CorrelationMatrixConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(CorrelationMatrixConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'correlation-matrix';\n _this.guides = false;\n _this.showTooltip = true;\n _this.showLegend = true;\n _this.highlightLabels = true;\n _this.rotateLabelsX = true;\n _this.rotateLabelsY = true;\n _this.variables = {\n labels: undefined,\n keys: [], //optional array of variable keys\n value: function value(d, variableKey) {\n return d[variableKey];\n }, // variable value accessor\n scale: \"ordinal\"\n };\n _this.correlation = {\n scale: \"linear\",\n domain: [-1, -0.75, -0.5, 0, 0.5, 0.75, 1],\n range: [\"darkblue\", \"blue\", \"lightskyblue\", \"white\", \"orangered\", \"crimson\", \"darkred\"],\n value: function value(xValues, yValues) {\n return _statisticsUtils.StatisticsUtils.sampleCorrelation(xValues, yValues);\n }\n\n };\n _this.cell = {\n shape: \"ellipse\", //possible values: rect, circle, ellipse\n size: undefined,\n sizeMin: 15,\n sizeMax: 250,\n padding: 1\n };\n _this.margin = {\n left: 60,\n right: 50,\n top: 30,\n bottom: 60\n };\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n return _this;\n } //show axis guides\n\n\n return CorrelationMatrixConfig;\n}(_chart.ChartConfig);\n\nvar CorrelationMatrix = exports.CorrelationMatrix = function (_Chart) {\n _inherits(CorrelationMatrix, _Chart);\n\n function CorrelationMatrix(placeholderSelector, data, config) {\n _classCallCheck(this, CorrelationMatrix);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(CorrelationMatrix).call(this, placeholderSelector, data, new CorrelationMatrixConfig(config)));\n }\n\n _createClass(CorrelationMatrix, [{\n key: 'setConfig',\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(CorrelationMatrix.prototype), 'setConfig', this).call(this, new CorrelationMatrixConfig(config));\n }\n }, {\n key: 'initPlot',\n value: function initPlot() {\n _get(Object.getPrototypeOf(CorrelationMatrix.prototype), 'initPlot', this).call(this);\n var self = this;\n var margin = this.config.margin;\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.correlation = {\n matrix: undefined,\n cells: undefined,\n color: {},\n shape: {}\n };\n\n this.setupVariables();\n var width = conf.width;\n var placeholderNode = this.getBaseContainerNode();\n this.plot.placeholderNode = placeholderNode;\n\n var parentWidth = placeholderNode.getBoundingClientRect().width;\n if (width) {\n\n if (!this.plot.cellSize) {\n this.plot.cellSize = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (width - margin.left - margin.right) / this.plot.variables.length));\n }\n } else {\n this.plot.cellSize = this.config.cell.size;\n\n if (!this.plot.cellSize) {\n this.plot.cellSize = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (parentWidth - margin.left - margin.right) / this.plot.variables.length));\n }\n\n width = this.plot.cellSize * this.plot.variables.length + margin.left + margin.right;\n }\n\n var height = width;\n if (!height) {\n height = placeholderNode.getBoundingClientRect().height;\n }\n\n this.plot.width = width - margin.left - margin.right;\n this.plot.height = this.plot.width;\n\n this.setupVariablesScales();\n this.setupCorrelationScales();\n this.setupCorrelationMatrix();\n\n return this;\n }\n }, {\n key: 'setupVariablesScales',\n value: function setupVariablesScales() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config.variables;\n\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\n x.value = conf.value;\n x.scale = d3.scale[conf.scale]().rangeBands([plot.width, 0]);\n x.map = function (d) {\n return x.scale(x.value(d));\n };\n }\n }, {\n key: 'setupCorrelationScales',\n value: function setupCorrelationScales() {\n var plot = this.plot;\n var corrConf = this.config.correlation;\n\n plot.correlation.color.scale = d3.scale[corrConf.scale]().domain(corrConf.domain).range(corrConf.range);\n var shape = plot.correlation.shape = {};\n\n var cellConf = this.config.cell;\n shape.type = cellConf.shape;\n\n var shapeSize = plot.cellSize - cellConf.padding * 2;\n if (shape.type == 'circle') {\n var radiusMax = shapeSize / 2;\n shape.radiusScale = d3.scale.linear().domain([0, 1]).range([2, radiusMax]);\n shape.radius = function (c) {\n return shape.radiusScale(Math.abs(c.value));\n };\n } else if (shape.type == 'ellipse') {\n var radiusMax = shapeSize / 2;\n shape.radiusScale = d3.scale.linear().domain([0, 1]).range([radiusMax, 2]);\n shape.radiusX = function (c) {\n return shape.radiusScale(Math.abs(c.value));\n };\n shape.radiusY = radiusMax;\n\n shape.rotateVal = function (v) {\n if (v == 0) return \"0\";\n if (v < 0) return \"-45\";\n return \"45\";\n };\n } else if (shape.type == 'rect') {\n shape.size = shapeSize;\n }\n }\n }, {\n key: 'setupVariables',\n value: function setupVariables() {\n\n var variablesConf = this.config.variables;\n\n var data = this.data;\n var plot = this.plot;\n plot.domainByVariable = {};\n plot.variables = variablesConf.keys;\n if (!plot.variables || !plot.variables.length) {\n plot.variables = _utils.Utils.inferVariables(data, this.config.groups.key, this.config.includeInPlot);\n }\n\n plot.labels = [];\n plot.labelByVariable = {};\n plot.variables.forEach(function (variableKey, index) {\n plot.domainByVariable[variableKey] = d3.extent(data, function (d) {\n return variablesConf.value(d, variableKey);\n });\n var label = variableKey;\n if (variablesConf.labels && variablesConf.labels.length > index) {\n\n label = variablesConf.labels[index];\n }\n plot.labels.push(label);\n plot.labelByVariable[variableKey] = label;\n });\n\n void 0;\n }\n }, {\n key: 'setupCorrelationMatrix',\n value: function setupCorrelationMatrix() {\n var self = this;\n var data = this.data;\n var matrix = this.plot.correlation.matrix = [];\n var matrixCells = this.plot.correlation.matrix.cells = [];\n var plot = this.plot;\n\n var variableToValues = {};\n plot.variables.forEach(function (v, i) {\n\n variableToValues[v] = data.map(function (d) {\n return plot.x.value(d, v);\n });\n });\n\n plot.variables.forEach(function (v1, i) {\n var row = [];\n matrix.push(row);\n\n plot.variables.forEach(function (v2, j) {\n var corr = 1;\n if (v1 != v2) {\n corr = self.config.correlation.value(variableToValues[v1], variableToValues[v2]);\n }\n var cell = {\n rowVar: v1,\n colVar: v2,\n row: i,\n col: j,\n value: corr\n };\n row.push(cell);\n\n matrixCells.push(cell);\n });\n });\n }\n }, {\n key: 'update',\n value: function update(newData) {\n _get(Object.getPrototypeOf(CorrelationMatrix.prototype), 'update', this).call(this, newData);\n // this.update\n this.updateCells();\n this.updateVariableLabels();\n\n if (this.config.showLegend) {\n this.updateLegend();\n }\n }\n }, {\n key: 'updateVariableLabels',\n value: function updateVariableLabels() {\n this.plot.labelClass = this.prefixClass(\"label\");\n this.updateAxisX();\n this.updateAxisY();\n }\n }, {\n key: 'updateAxisX',\n value: function updateAxisX() {\n var self = this;\n var plot = self.plot;\n var labelClass = plot.labelClass;\n var labelXClass = labelClass + \"-x\";\n\n var labels = self.svgG.selectAll(\"text.\" + labelXClass).data(plot.variables, function (d, i) {\n return i;\n });\n\n labels.enter().append(\"text\").attr(\"class\", function (d, i) {\n return labelClass + \" \" + labelXClass + \" \" + labelXClass + \"-\" + i;\n });\n\n labels.attr(\"x\", function (d, i) {\n return i * plot.cellSize + plot.cellSize / 2;\n }).attr(\"y\", plot.height).attr(\"dx\", -2).attr(\"dy\", 5).attr(\"text-anchor\", \"end\")\n\n // .attr(\"dominant-baseline\", \"hanging\")\n .text(function (v) {\n return plot.labelByVariable[v];\n });\n\n if (this.config.rotateLabelsX) {\n labels.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + (i * plot.cellSize + plot.cellSize / 2) + \", \" + plot.height + \")\";\n });\n }\n\n var maxWidth = self.computeXAxisLabelsWidth();\n labels.each(function (label) {\n _utils.Utils.placeTextWithEllipsisAndTooltip(d3.select(this), label, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\n });\n\n labels.exit().remove();\n }\n }, {\n key: 'updateAxisY',\n value: function updateAxisY() {\n var self = this;\n var plot = self.plot;\n var labelClass = plot.labelClass;\n var labelYClass = plot.labelClass + \"-y\";\n var labels = self.svgG.selectAll(\"text.\" + labelYClass).data(plot.variables);\n\n labels.enter().append(\"text\");\n\n labels.attr(\"x\", 0).attr(\"y\", function (d, i) {\n return i * plot.cellSize + plot.cellSize / 2;\n }).attr(\"dx\", -2).attr(\"text-anchor\", \"end\").attr(\"class\", function (d, i) {\n return labelClass + \" \" + labelYClass + \" \" + labelYClass + \"-\" + i;\n })\n // .attr(\"dominant-baseline\", \"hanging\")\n .text(function (v) {\n return plot.labelByVariable[v];\n });\n\n if (this.config.rotateLabelsY) {\n labels.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + 0 + \", \" + (i * plot.cellSize + plot.cellSize / 2) + \")\";\n }).attr(\"text-anchor\", \"end\");\n }\n\n var maxWidth = self.computeYAxisLabelsWidth();\n labels.each(function (label) {\n _utils.Utils.placeTextWithEllipsisAndTooltip(d3.select(this), label, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\n });\n\n labels.exit().remove();\n }\n }, {\n key: 'computeYAxisLabelsWidth',\n value: function computeYAxisLabelsWidth() {\n var maxWidth = this.plot.margin.left;\n if (!this.config.rotateLabelsY) {\n return maxWidth;\n }\n\n maxWidth *= _utils.Utils.SQRT_2;\n var fontSize = 11; //todo check actual font size\n maxWidth -= fontSize / 2;\n\n return maxWidth;\n }\n }, {\n key: 'computeXAxisLabelsWidth',\n value: function computeXAxisLabelsWidth(offset) {\n if (!this.config.rotateLabelsX) {\n return this.plot.cellSize - 2;\n }\n var size = this.plot.margin.bottom;\n size *= _utils.Utils.SQRT_2;\n var fontSize = 11; //todo check actual font size\n size -= fontSize / 2;\n return size;\n }\n }, {\n key: 'updateCells',\n value: function updateCells() {\n\n var self = this;\n var plot = self.plot;\n var cellClass = self.prefixClass(\"cell\");\n var cellShape = plot.correlation.shape.type;\n\n var cells = self.svgG.selectAll(\"g.\" + cellClass).data(plot.correlation.matrix.cells);\n\n var cellEnterG = cells.enter().append(\"g\").classed(cellClass, true);\n cells.attr(\"transform\", function (c) {\n return \"translate(\" + (plot.cellSize * c.col + plot.cellSize / 2) + \",\" + (plot.cellSize * c.row + plot.cellSize / 2) + \")\";\n });\n\n cells.classed(self.config.cssClassPrefix + \"selectable\", !!self.scatterPlot);\n\n var selector = \"*:not(.cell-shape-\" + cellShape + \")\";\n\n var wrongShapes = cells.selectAll(selector);\n wrongShapes.remove();\n\n var shapes = cells.selectOrAppend(cellShape + \".cell-shape-\" + cellShape);\n\n if (plot.correlation.shape.type == 'circle') {\n\n shapes.attr(\"r\", plot.correlation.shape.radius).attr(\"cx\", 0).attr(\"cy\", 0);\n }\n\n if (plot.correlation.shape.type == 'ellipse') {\n // cells.attr(\"transform\", c=> \"translate(300,150) rotate(\"+plot.correlation.shape.rotateVal(c.value)+\")\");\n shapes.attr(\"rx\", plot.correlation.shape.radiusX).attr(\"ry\", plot.correlation.shape.radiusY).attr(\"cx\", 0).attr(\"cy\", 0).attr(\"transform\", function (c) {\n return \"rotate(\" + plot.correlation.shape.rotateVal(c.value) + \")\";\n });\n }\n\n if (plot.correlation.shape.type == 'rect') {\n shapes.attr(\"width\", plot.correlation.shape.size).attr(\"height\", plot.correlation.shape.size).attr(\"x\", -plot.cellSize / 2).attr(\"y\", -plot.cellSize / 2);\n }\n shapes.style(\"fill\", function (c) {\n return plot.correlation.color.scale(c.value);\n });\n\n var mouseoverCallbacks = [];\n var mouseoutCallbacks = [];\n\n if (plot.tooltip) {\n\n mouseoverCallbacks.push(function (c) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = c.value;\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n });\n\n mouseoutCallbacks.push(function (c) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n\n if (self.config.highlightLabels) {\n var highlightClass = self.config.cssClassPrefix + \"highlight\";\n var xLabelClass = function xLabelClass(c) {\n return plot.labelClass + \"-x-\" + c.col;\n };\n var yLabelClass = function yLabelClass(c) {\n return plot.labelClass + \"-y-\" + c.row;\n };\n\n mouseoverCallbacks.push(function (c) {\n\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, true);\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, true);\n });\n mouseoutCallbacks.push(function (c) {\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, false);\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, false);\n });\n }\n\n cells.on(\"mouseover\", function (c) {\n mouseoverCallbacks.forEach(function (callback) {\n return callback(c);\n });\n }).on(\"mouseout\", function (c) {\n mouseoutCallbacks.forEach(function (callback) {\n return callback(c);\n });\n });\n\n cells.on(\"click\", function (c) {\n self.trigger(\"cell-selected\", c);\n });\n\n cells.exit().remove();\n }\n }, {\n key: 'updateLegend',\n value: function updateLegend() {\n\n var plot = this.plot;\n var legendX = this.plot.width + 10;\n var legendY = 0;\n var barWidth = 10;\n var barHeight = this.plot.height - 2;\n var scale = plot.correlation.color.scale;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY).linearGradientBar(barWidth, barHeight);\n }\n }, {\n key: 'attachScatterPlot',\n value: function attachScatterPlot(containerSelector, config) {\n var _this3 = this;\n\n var self = this;\n\n config = config || {};\n\n var scatterPlotConfig = {\n height: self.plot.height + self.config.margin.top + self.config.margin.bottom,\n width: self.plot.height + self.config.margin.top + self.config.margin.bottom,\n groups: {\n key: self.config.groups.key,\n label: self.config.groups.label\n },\n guides: true,\n showLegend: false\n };\n\n self.scatterPlot = true;\n\n scatterPlotConfig = _utils.Utils.deepExtend(scatterPlotConfig, config);\n this.update();\n\n this.on(\"cell-selected\", function (c) {\n\n scatterPlotConfig.x = {\n key: c.rowVar,\n label: self.plot.labelByVariable[c.rowVar]\n };\n scatterPlotConfig.y = {\n key: c.colVar,\n label: self.plot.labelByVariable[c.colVar]\n };\n if (self.scatterPlot && self.scatterPlot !== true) {\n self.scatterPlot.setConfig(scatterPlotConfig).init();\n } else {\n self.scatterPlot = new _scatterplot.ScatterPlot(containerSelector, self.data, scatterPlotConfig);\n _this3.attach(\"ScatterPlot\", self.scatterPlot);\n }\n });\n }\n }]);\n\n return CorrelationMatrix;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./scatterplot\":30,\"./statistics-utils\":32,\"./utils\":33}],22:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.D3Extensions = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _utils = require('./utils');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar D3Extensions = exports.D3Extensions = function () {\n function D3Extensions() {\n _classCallCheck(this, D3Extensions);\n }\n\n _createClass(D3Extensions, null, [{\n key: 'extend',\n value: function extend() {\n\n d3.selection.enter.prototype.insertSelector = d3.selection.prototype.insertSelector = function (selector, before) {\n return _utils.Utils.insertSelector(this, selector, before);\n };\n\n d3.selection.enter.prototype.appendSelector = d3.selection.prototype.appendSelector = function (selector) {\n return _utils.Utils.appendSelector(this, selector);\n };\n\n d3.selection.enter.prototype.selectOrAppend = d3.selection.prototype.selectOrAppend = function (selector) {\n return _utils.Utils.selectOrAppend(this, selector);\n };\n\n d3.selection.enter.prototype.selectOrInsert = d3.selection.prototype.selectOrInsert = function (selector, before) {\n return _utils.Utils.selectOrInsert(this, selector, before);\n };\n }\n }]);\n\n return D3Extensions;\n}();\n\n},{\"./utils\":33}],23:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.HeatmapTimeSeries = exports.HeatmapTimeSeriesConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _heatmap = require(\"./heatmap\");\n\nvar _utils = require(\"./utils\");\n\nvar _statisticsUtils = require(\"./statistics-utils\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar HeatmapTimeSeriesConfig = exports.HeatmapTimeSeriesConfig = function (_HeatmapConfig) {\n _inherits(HeatmapTimeSeriesConfig, _HeatmapConfig);\n\n function HeatmapTimeSeriesConfig(custom) {\n _classCallCheck(this, HeatmapTimeSeriesConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(HeatmapTimeSeriesConfig).call(this));\n\n _this.x = {\n fillMissing: false, // fill missing values using interval and intervalStep\n interval: undefined, //used in filling missing ticks\n intervalStep: 1,\n format: undefined, //input data d3 time format\n displayFormat: undefined, //d3 time format for display\n intervalToFormats: [//used to guess interval and format\n {\n name: 'year',\n formats: [\"%Y\"]\n }, {\n name: 'month',\n formats: [\"%Y-%m\"]\n }, {\n name: 'day',\n formats: [\"%Y-%m-%d\"]\n }, {\n name: 'hour',\n formats: ['%H', '%Y-%m-%d %H']\n }, {\n name: 'minute',\n formats: ['%H:%M', '%Y-%m-%d %H:%M']\n }, {\n name: 'second',\n formats: ['%H:%M:%S', '%Y-%m-%d %H:%M:%S']\n }],\n\n sortComparator: function sortComparator(a, b) {\n return _utils.Utils.isString(a) ? a.localeCompare(b) : a - b;\n },\n formatter: undefined\n };\n _this.z = {\n fillMissing: true // fiill missing values with nearest previous value\n };\n _this.legend = {\n formatter: function formatter(v) {\n var suffix = \"\";\n if (v / 1000000 >= 1) {\n suffix = \" M\";\n v = Number(v / 1000000).toFixed(3);\n }\n var nf = Intl.NumberFormat();\n return nf.format(v) + suffix;\n }\n };\n\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n }\n\n return HeatmapTimeSeriesConfig;\n}(_heatmap.HeatmapConfig);\n\nvar HeatmapTimeSeries = exports.HeatmapTimeSeries = function (_Heatmap) {\n _inherits(HeatmapTimeSeries, _Heatmap);\n\n function HeatmapTimeSeries(placeholderSelector, data, config) {\n _classCallCheck(this, HeatmapTimeSeries);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(HeatmapTimeSeries).call(this, placeholderSelector, data, new HeatmapTimeSeriesConfig(config)));\n }\n\n _createClass(HeatmapTimeSeries, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(HeatmapTimeSeries.prototype), \"setConfig\", this).call(this, new HeatmapTimeSeriesConfig(config));\n }\n }, {\n key: \"setupValuesBeforeGroupsSort\",\n value: function setupValuesBeforeGroupsSort() {\n var _this3 = this;\n\n this.plot.x.timeFormat = this.config.x.format;\n if (this.config.x.displayFormat && !this.plot.x.timeFormat) {\n this.guessTimeFormat();\n }\n\n _get(Object.getPrototypeOf(HeatmapTimeSeries.prototype), \"setupValuesBeforeGroupsSort\", this).call(this);\n if (!this.config.x.fillMissing) {\n return;\n }\n\n var self = this;\n\n this.initTimeFormatAndInterval();\n\n this.plot.x.intervalStep = this.config.x.intervalStep || 1;\n\n this.plot.x.timeParser = this.getTimeParser();\n\n this.plot.x.uniqueValues.sort(this.config.x.sortComparator);\n\n var prev = null;\n\n this.plot.x.uniqueValues.forEach(function (x, i) {\n var current = _this3.parseTime(x);\n if (prev === null) {\n prev = current;\n return;\n }\n\n var next = self.nextTimeTickValue(prev);\n var missing = [];\n var iteration = 0;\n while (self.compareTimeValues(next, current) <= 0) {\n iteration++;\n if (iteration > 100) {\n break;\n }\n var d = {};\n var timeString = self.formatTime(next);\n d[_this3.config.x.key] = timeString;\n\n self.updateGroups(d, timeString, self.plot.x.groups, self.config.x.groups);\n missing.push(next);\n next = self.nextTimeTickValue(next);\n }\n prev = current;\n });\n }\n }, {\n key: \"parseTime\",\n value: function parseTime(x) {\n var parser = this.getTimeParser();\n return parser.parse(x);\n }\n }, {\n key: \"formatTime\",\n value: function formatTime(date) {\n var parser = this.getTimeParser();\n return parser(date);\n }\n }, {\n key: \"formatValueX\",\n value: function formatValueX(value) {\n //used only for display\n if (this.config.x.formatter) return this.config.x.formatter.call(this.config, value);\n\n if (this.config.x.displayFormat) {\n var date = this.parseTime(value);\n return d3.time.format(this.config.x.displayFormat)(date);\n }\n\n if (!this.plot.x.timeFormat) return value;\n\n if (_utils.Utils.isDate(value)) {\n return this.formatTime(value);\n }\n\n return value;\n }\n }, {\n key: \"compareTimeValues\",\n value: function compareTimeValues(a, b) {\n return a - b;\n }\n }, {\n key: \"timeValuesEqual\",\n value: function timeValuesEqual(a, b) {\n var parser = this.plot.x.timeParser;\n return parser(a) === parser(b);\n }\n }, {\n key: \"nextTimeTickValue\",\n value: function nextTimeTickValue(t) {\n var interval = this.plot.x.interval;\n return d3.time[interval].offset(t, this.plot.x.intervalStep);\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(HeatmapTimeSeries.prototype), \"initPlot\", this).call(this);\n\n if (this.config.z.fillMissing) {\n this.plot.matrix.forEach(function (row, rowIndex) {\n var prevRowValue = undefined;\n row.forEach(function (cell, colIndex) {\n if (cell.value === undefined && prevRowValue !== undefined) {\n cell.value = prevRowValue;\n cell.missing = true;\n }\n prevRowValue = cell.value;\n });\n });\n }\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(HeatmapTimeSeries.prototype), \"update\", this).call(this, newData);\n }\n }, {\n key: \"initTimeFormatAndInterval\",\n value: function initTimeFormatAndInterval() {\n\n this.plot.x.interval = this.config.x.interval;\n\n if (!this.plot.x.timeFormat) {\n this.guessTimeFormat();\n }\n\n if (!this.plot.x.interval && this.plot.x.timeFormat) {\n this.guessInterval();\n }\n }\n }, {\n key: \"guessTimeFormat\",\n value: function guessTimeFormat() {\n var self = this;\n for (var i = 0; i < self.config.x.intervalToFormats.length; i++) {\n var intervalFormat = self.config.x.intervalToFormats[i];\n var format = null;\n var formatMatch = intervalFormat.formats.some(function (f) {\n format = f;\n var parser = d3.time.format(f);\n return self.plot.x.uniqueValues.every(function (x) {\n return parser.parse(x) !== null;\n });\n });\n if (formatMatch) {\n self.plot.x.timeFormat = format;\n void 0;\n if (!self.plot.x.interval) {\n self.plot.x.interval = intervalFormat.name;\n void 0;\n }\n return;\n }\n }\n }\n }, {\n key: \"guessInterval\",\n value: function guessInterval() {\n var self = this;\n for (var i = 0; i < self.config.x.intervalToFormats.length; i++) {\n var intervalFormat = self.config.x.intervalToFormats[i];\n\n if (intervalFormat.formats.indexOf(self.plot.x.timeFormat) >= 0) {\n self.plot.x.interval = intervalFormat.name;\n void 0;\n return;\n }\n }\n }\n }, {\n key: \"getTimeParser\",\n value: function getTimeParser() {\n if (!this.plot.x.timeParser) {\n this.plot.x.timeParser = d3.time.format(this.plot.x.timeFormat);\n }\n return this.plot.x.timeParser;\n }\n }]);\n\n return HeatmapTimeSeries;\n}(_heatmap.Heatmap);\n\n},{\"./chart\":20,\"./heatmap\":24,\"./statistics-utils\":32,\"./utils\":33}],24:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Heatmap = exports.HeatmapConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require('./chart');\n\nvar _utils = require('./utils');\n\nvar _legend = require('./legend');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar HeatmapConfig = exports.HeatmapConfig = function (_ChartConfig) {\n _inherits(HeatmapConfig, _ChartConfig);\n\n //show tooltip on dot hover\n\n function HeatmapConfig(custom) {\n _classCallCheck(this, HeatmapConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(HeatmapConfig).call(this));\n\n _this.svgClass = 'odc-heatmap';\n _this.showTooltip = true;\n _this.tooltip = {\n noDataText: \"N/A\"\n };\n _this.showLegend = true;\n _this.legend = {\n width: 30,\n rotateLabels: false,\n decimalPlaces: undefined,\n formatter: function formatter(v) {\n return _this.legend.decimalPlaces === undefined ? v : Number(v).toFixed(_this.legend.decimalPlaces);\n }\n };\n _this.highlightLabels = true;\n _this.x = { // X axis config\n title: '', // axis title\n key: 0,\n value: function value(d) {\n return d[_this.x.key];\n }, // x value accessor\n rotateLabels: true,\n sortLabels: false,\n sortComparator: function sortComparator(a, b) {\n return _utils.Utils.isNumber(a) ? a - b : a.localeCompare(b);\n },\n groups: {\n keys: [],\n labels: [],\n value: function value(d, key) {\n return d[key];\n },\n overlap: {\n top: 20,\n bottom: 20\n }\n },\n formatter: undefined // value formatter function\n\n };\n _this.y = { // Y axis config\n title: '', // axis title,\n rotateLabels: true,\n key: 1,\n value: function value(d) {\n return d[_this.y.key];\n }, // y value accessor\n sortLabels: false,\n sortComparator: function sortComparator(a, b) {\n return _utils.Utils.isNumber(b) ? b - a : b.localeCompare(a);\n },\n groups: {\n keys: [],\n labels: [],\n value: function value(d, key) {\n return d[key];\n },\n overlap: {\n left: 20,\n right: 20\n }\n },\n formatter: undefined // value formatter function\n };\n _this.z = {\n key: 2,\n value: function value(d) {\n return d[_this.z.key];\n },\n notAvailableValue: function notAvailableValue(v) {\n return v === null || v === undefined;\n },\n\n decimalPlaces: undefined,\n formatter: function formatter(v) {\n return _this.z.decimalPlaces === undefined ? v : Number(v).toFixed(_this.z.decimalPlaces);\n } // value formatter function\n\n };\n _this.color = {\n noDataColor: \"white\",\n scale: \"linear\",\n reverseScale: false,\n range: [\"darkblue\", \"lightskyblue\", \"orange\", \"crimson\", \"darkred\"]\n };\n _this.cell = {\n width: undefined,\n height: undefined,\n sizeMin: 15,\n sizeMax: 250,\n padding: 0\n };\n _this.margin = {\n left: 60,\n right: 50,\n top: 30,\n bottom: 80\n };\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n return _this;\n }\n\n return HeatmapConfig;\n}(_chart.ChartConfig);\n\n//TODO refactor\n\n\nvar Heatmap = exports.Heatmap = function (_Chart) {\n _inherits(Heatmap, _Chart);\n\n function Heatmap(placeholderSelector, data, config) {\n _classCallCheck(this, Heatmap);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(Heatmap).call(this, placeholderSelector, data, new HeatmapConfig(config)));\n }\n\n _createClass(Heatmap, [{\n key: 'setConfig',\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(Heatmap.prototype), 'setConfig', this).call(this, new HeatmapConfig(config));\n }\n }, {\n key: 'initPlot',\n value: function initPlot() {\n _get(Object.getPrototypeOf(Heatmap.prototype), 'initPlot', this).call(this);\n var self = this;\n var margin = this.config.margin;\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.y = {};\n this.plot.z = {\n matrixes: undefined,\n cells: undefined,\n color: {},\n shape: {}\n };\n\n this.setupValues();\n this.buildCells();\n\n var titleRectWidth = 6;\n this.plot.x.overlap = {\n top: 0,\n bottom: 0\n };\n if (this.plot.groupByX) {\n var depth = self.config.x.groups.keys.length;\n var allTitlesWidth = depth * titleRectWidth;\n\n this.plot.x.overlap.bottom = self.config.x.groups.overlap.bottom;\n this.plot.x.overlap.top = self.config.x.groups.overlap.top + allTitlesWidth;\n this.plot.margin.top = conf.margin.right + conf.x.groups.overlap.top;\n this.plot.margin.bottom = conf.margin.bottom + conf.x.groups.overlap.bottom;\n }\n\n this.plot.y.overlap = {\n left: 0,\n right: 0\n };\n\n if (this.plot.groupByY) {\n var _depth = self.config.y.groups.keys.length;\n var _allTitlesWidth = _depth * titleRectWidth;\n this.plot.y.overlap.right = self.config.y.groups.overlap.left + _allTitlesWidth;\n this.plot.y.overlap.left = self.config.y.groups.overlap.left;\n this.plot.margin.left = conf.margin.left + this.plot.y.overlap.left;\n this.plot.margin.right = conf.margin.right + this.plot.y.overlap.right;\n }\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n this.plot.margin.right += conf.legend.width;\n }\n this.computePlotSize();\n this.setupZScale();\n\n return this;\n }\n }, {\n key: 'setupValues',\n value: function setupValues() {\n var _this3 = this;\n\n var self = this;\n var config = self.config;\n var x = self.plot.x;\n var y = self.plot.y;\n var z = self.plot.z;\n\n x.value = function (d) {\n return config.x.value.call(config, d);\n };\n y.value = function (d) {\n return config.y.value.call(config, d);\n };\n z.value = function (d) {\n return config.z.value.call(config, d);\n };\n\n x.uniqueValues = [];\n y.uniqueValues = [];\n\n self.plot.groupByY = !!config.y.groups.keys.length;\n self.plot.groupByX = !!config.x.groups.keys.length;\n\n y.groups = {\n key: undefined,\n label: '',\n values: [],\n children: null,\n level: 0,\n index: 0,\n lastIndex: 0\n };\n x.groups = {\n key: undefined,\n label: '',\n values: [],\n children: null,\n level: 0,\n index: 0,\n lastIndex: 0\n };\n\n var valueMap = {};\n var minZ = undefined;\n var maxZ = undefined;\n this.data.forEach(function (d) {\n\n var xVal = x.value(d);\n var yVal = y.value(d);\n var zValRaw = z.value(d);\n var zVal = config.z.notAvailableValue(zValRaw) ? undefined : parseFloat(zValRaw);\n\n if (x.uniqueValues.indexOf(xVal) === -1) {\n x.uniqueValues.push(xVal);\n }\n\n if (y.uniqueValues.indexOf(yVal) === -1) {\n y.uniqueValues.push(yVal);\n }\n\n var groupY = y.groups;\n if (self.plot.groupByY) {\n groupY = _this3.updateGroups(d, yVal, y.groups, config.y.groups);\n }\n var groupX = x.groups;\n if (self.plot.groupByX) {\n\n groupX = _this3.updateGroups(d, xVal, x.groups, config.x.groups);\n }\n\n if (!valueMap[groupY.index]) {\n valueMap[groupY.index] = {};\n }\n\n if (!valueMap[groupY.index][groupX.index]) {\n valueMap[groupY.index][groupX.index] = {};\n }\n if (!valueMap[groupY.index][groupX.index][yVal]) {\n valueMap[groupY.index][groupX.index][yVal] = {};\n }\n valueMap[groupY.index][groupX.index][yVal][xVal] = zVal;\n\n if (minZ === undefined || zVal < minZ) {\n minZ = zVal;\n }\n if (maxZ === undefined || zVal > maxZ) {\n maxZ = zVal;\n }\n });\n self.plot.valueMap = valueMap;\n\n if (!self.plot.groupByX) {\n x.groups.values = x.uniqueValues;\n }\n\n if (!self.plot.groupByY) {\n y.groups.values = y.uniqueValues;\n }\n\n this.setupValuesBeforeGroupsSort();\n\n x.gaps = [];\n x.totalValuesCount = 0;\n x.allValuesList = [];\n this.sortGroups(x, x.groups, config.x);\n\n y.gaps = [];\n y.totalValuesCount = 0;\n y.allValuesList = [];\n this.sortGroups(y, y.groups, config.y);\n\n z.min = minZ;\n z.max = maxZ;\n }\n }, {\n key: 'setupValuesBeforeGroupsSort',\n value: function setupValuesBeforeGroupsSort() {}\n }, {\n key: 'buildCells',\n value: function buildCells() {\n var self = this;\n var x = self.plot.x;\n var y = self.plot.y;\n var z = self.plot.z;\n var valueMap = self.plot.valueMap;\n\n var matrixCells = self.plot.cells = [];\n var matrix = self.plot.matrix = [];\n\n y.allValuesList.forEach(function (v1, i) {\n var row = [];\n matrix.push(row);\n\n x.allValuesList.forEach(function (v2, j) {\n var zVal = undefined;\n try {\n zVal = valueMap[v1.group.index][v2.group.index][v1.val][v2.val];\n } catch (e) {}\n\n var cell = {\n rowVar: v1,\n colVar: v2,\n row: i,\n col: j,\n value: zVal\n };\n row.push(cell);\n\n matrixCells.push(cell);\n });\n });\n }\n }, {\n key: 'updateGroups',\n value: function updateGroups(d, axisVal, rootGroup, axisGroupsConfig) {\n\n var config = this.config;\n var currentGroup = rootGroup;\n axisGroupsConfig.keys.forEach(function (groupKey, groupKeyIndex) {\n currentGroup.key = groupKey;\n\n if (!currentGroup.children) {\n currentGroup.children = {};\n }\n\n var groupingValue = axisGroupsConfig.value.call(config, d, groupKey);\n\n if (!currentGroup.children.hasOwnProperty(groupingValue)) {\n rootGroup.lastIndex++;\n currentGroup.children[groupingValue] = {\n values: [],\n children: null,\n groupingValue: groupingValue,\n level: currentGroup.level + 1,\n index: rootGroup.lastIndex,\n key: groupKey\n };\n }\n\n currentGroup = currentGroup.children[groupingValue];\n });\n\n if (currentGroup.values.indexOf(axisVal) === -1) {\n currentGroup.values.push(axisVal);\n }\n\n return currentGroup;\n }\n }, {\n key: 'sortGroups',\n value: function sortGroups(axis, group, axisConfig, gaps) {\n if (axisConfig.groups.labels && axisConfig.groups.labels.length > group.level) {\n group.label = axisConfig.groups.labels[group.level];\n } else {\n group.label = group.key;\n }\n\n if (!gaps) {\n gaps = [0];\n }\n if (gaps.length <= group.level) {\n gaps.push(0);\n }\n\n group.allValuesCount = group.allValuesCount || 0;\n group.allValuesBeforeCount = group.allValuesBeforeCount || 0;\n\n group.gaps = gaps.slice();\n group.gapsBefore = gaps.slice();\n\n group.gapsSize = Heatmap.computeGapsSize(group.gaps);\n group.gapsBeforeSize = group.gapsSize;\n if (group.values) {\n if (axisConfig.sortLabels) {\n group.values.sort(axisConfig.sortComparator);\n }\n group.values.forEach(function (v) {\n return axis.allValuesList.push({ val: v, group: group });\n });\n group.allValuesBeforeCount = axis.totalValuesCount;\n axis.totalValuesCount += group.values.length;\n group.allValuesCount += group.values.length;\n }\n\n group.childrenList = [];\n if (group.children) {\n var childrenCount = 0;\n\n for (var childProp in group.children) {\n if (group.children.hasOwnProperty(childProp)) {\n var child = group.children[childProp];\n group.childrenList.push(child);\n childrenCount++;\n\n this.sortGroups(axis, child, axisConfig, gaps);\n group.allValuesCount += child.allValuesCount;\n gaps[group.level] += 1;\n }\n }\n\n if (gaps && childrenCount > 1) {\n gaps[group.level] -= 1;\n }\n\n group.gapsInside = [];\n gaps.forEach(function (d, i) {\n group.gapsInside.push(d - (group.gapsBefore[i] || 0));\n });\n group.gapsInsideSize = Heatmap.computeGapsSize(group.gapsInside);\n\n if (axis.gaps.length < gaps.length) {\n axis.gaps = gaps;\n }\n }\n }\n }, {\n key: 'computeYAxisLabelsWidth',\n value: function computeYAxisLabelsWidth(offset) {\n var maxWidth = this.plot.margin.left;\n if (this.config.y.title) {\n maxWidth -= 15;\n }\n if (offset && offset.x) {\n maxWidth += offset.x;\n }\n\n if (this.config.y.rotateLabels) {\n maxWidth *= _utils.Utils.SQRT_2;\n var fontSize = 11; //todo check actual font size\n maxWidth -= fontSize / 2;\n }\n\n return maxWidth;\n }\n }, {\n key: 'computeXAxisLabelsWidth',\n value: function computeXAxisLabelsWidth(offset) {\n if (!this.config.x.rotateLabels) {\n return this.plot.cellWidth - 2;\n }\n var size = this.plot.margin.bottom;\n if (this.config.x.title) {\n size -= 15;\n }\n if (offset && offset.y) {\n size -= offset.y;\n }\n\n size *= _utils.Utils.SQRT_2;\n\n var fontSize = 11; //todo check actual font size\n size -= fontSize / 2;\n\n return size;\n }\n }, {\n key: 'computePlotSize',\n value: function computePlotSize() {\n\n var plot = this.plot;\n var conf = this.config;\n var margin = plot.margin;\n var availableWidth = _utils.Utils.availableWidth(this.config.width, this.getBaseContainer(), this.plot.margin);\n var availableHeight = _utils.Utils.availableHeight(this.config.height, this.getBaseContainer(), this.plot.margin);\n var width = availableWidth;\n var height = availableHeight;\n\n var xGapsSize = Heatmap.computeGapsSize(plot.x.gaps);\n\n var computedCellWidth = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (availableWidth - xGapsSize) / this.plot.x.totalValuesCount));\n if (this.config.width) {\n\n if (!this.config.cell.width) {\n this.plot.cellWidth = computedCellWidth;\n }\n } else {\n this.plot.cellWidth = this.config.cell.width;\n\n if (!this.plot.cellWidth) {\n this.plot.cellWidth = computedCellWidth;\n }\n }\n width = this.plot.cellWidth * this.plot.x.totalValuesCount + margin.left + margin.right + xGapsSize;\n\n var yGapsSize = Heatmap.computeGapsSize(plot.y.gaps);\n var computedCellHeight = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (availableHeight - yGapsSize) / this.plot.y.totalValuesCount));\n if (this.config.height) {\n if (!this.config.cell.height) {\n this.plot.cellHeight = computedCellHeight;\n }\n } else {\n this.plot.cellHeight = this.config.cell.height;\n\n if (!this.plot.cellHeight) {\n this.plot.cellHeight = computedCellHeight;\n }\n }\n\n height = this.plot.cellHeight * this.plot.y.totalValuesCount + margin.top + margin.bottom + yGapsSize;\n\n this.plot.width = width - margin.left - margin.right;\n this.plot.height = height - margin.top - margin.bottom;\n }\n }, {\n key: 'setupZScale',\n value: function setupZScale() {\n\n var self = this;\n var config = self.config;\n var z = self.plot.z;\n var range = config.color.range;\n var extent = z.max - z.min;\n var scale;\n z.domain = [];\n if (config.color.scale == \"pow\") {\n var exponent = 10;\n range.forEach(function (c, i) {\n var v = z.max - extent / Math.pow(10, i);\n z.domain.push(v);\n });\n scale = d3.scale.pow().exponent(exponent);\n } else if (config.color.scale == \"log\") {\n\n range.forEach(function (c, i) {\n var v = z.min + extent / Math.pow(10, i);\n z.domain.unshift(v);\n });\n\n scale = d3.scale.log();\n } else {\n range.forEach(function (c, i) {\n var v = z.min + extent * (i / (range.length - 1));\n z.domain.push(v);\n });\n scale = d3.scale[config.color.scale]();\n }\n\n z.domain[0] = z.min; //removing unnecessary floating points\n z.domain[z.domain.length - 1] = z.max; //removing unnecessary floating points\n void 0;\n\n if (config.color.reverseScale) {\n z.domain.reverse();\n }\n\n var plot = this.plot;\n\n void 0;\n plot.z.color.scale = scale.domain(z.domain).range(range);\n var shape = plot.z.shape = {};\n\n var cellConf = this.config.cell;\n shape.type = \"rect\";\n\n plot.z.shape.width = plot.cellWidth - cellConf.padding * 2;\n plot.z.shape.height = plot.cellHeight - cellConf.padding * 2;\n }\n }, {\n key: 'update',\n value: function update(newData) {\n _get(Object.getPrototypeOf(Heatmap.prototype), 'update', this).call(this, newData);\n if (this.plot.groupByY) {\n this.drawGroupsY(this.plot.y.groups, this.svgG);\n }\n if (this.plot.groupByX) {\n this.drawGroupsX(this.plot.x.groups, this.svgG);\n }\n\n this.updateCells();\n\n // this.updateVariableLabels();\n\n this.updateAxisX();\n this.updateAxisY();\n\n if (this.config.showLegend) {\n this.updateLegend();\n }\n\n this.updateAxisTitles();\n }\n }, {\n key: 'updateAxisTitles',\n value: function updateAxisTitles() {\n var self = this;\n var plot = self.plot;\n }\n }, {\n key: 'updateAxisX',\n value: function updateAxisX() {\n var self = this;\n var plot = self.plot;\n var labelClass = self.prefixClass(\"label\");\n var labelXClass = labelClass + \"-x\";\n var labelYClass = labelClass + \"-y\";\n plot.labelClass = labelClass;\n\n var offsetX = {\n x: 0,\n y: 0\n };\n var gapSize = Heatmap.computeGapSize(0);\n if (plot.groupByX) {\n var overlap = self.config.x.groups.overlap;\n\n offsetX.x = gapSize / 2;\n offsetX.y = overlap.bottom + gapSize / 2 + 6;\n } else if (plot.groupByY) {\n offsetX.y = gapSize;\n }\n\n var labels = self.svgG.selectAll(\"text.\" + labelXClass).data(plot.x.allValuesList, function (d, i) {\n return i;\n });\n\n labels.enter().append(\"text\").attr(\"class\", function (d, i) {\n return labelClass + \" \" + labelXClass + \" \" + labelXClass + \"-\" + i;\n });\n\n labels.attr(\"x\", function (d, i) {\n return i * plot.cellWidth + plot.cellWidth / 2 + d.group.gapsSize + offsetX.x;\n }).attr(\"y\", plot.height + offsetX.y).attr(\"dy\", 10).attr(\"text-anchor\", \"middle\").text(function (d) {\n return self.formatValueX(d.val);\n });\n\n var maxWidth = self.computeXAxisLabelsWidth(offsetX);\n\n labels.each(function (label) {\n var elem = d3.select(this),\n text = self.formatValueX(label.val);\n _utils.Utils.placeTextWithEllipsisAndTooltip(elem, text, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\n });\n\n if (self.config.x.rotateLabels) {\n labels.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + (i * plot.cellWidth + plot.cellWidth / 2 + d.group.gapsSize + offsetX.x) + \", \" + (plot.height + offsetX.y) + \")\";\n }).attr(\"dx\", -2).attr(\"dy\", 8).attr(\"text-anchor\", \"end\");\n }\n\n labels.exit().remove();\n\n self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x')).attr(\"transform\", \"translate(\" + plot.width / 2 + \",\" + (plot.height + plot.margin.bottom) + \")\").selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"dy\", \"-0.5em\").style(\"text-anchor\", \"middle\").text(self.config.x.title);\n }\n }, {\n key: 'updateAxisY',\n value: function updateAxisY() {\n var self = this;\n var plot = self.plot;\n var labelClass = self.prefixClass(\"label\");\n var labelYClass = labelClass + \"-y\";\n plot.labelClass = labelClass;\n\n var labels = self.svgG.selectAll(\"text.\" + labelYClass).data(plot.y.allValuesList);\n\n labels.enter().append(\"text\");\n\n var offsetY = {\n x: 0,\n y: 0\n };\n if (plot.groupByY) {\n var overlap = self.config.y.groups.overlap;\n var gapSize = Heatmap.computeGapSize(0);\n offsetY.x = -overlap.left;\n\n offsetY.y = gapSize / 2;\n }\n labels.attr(\"x\", offsetY.x).attr(\"y\", function (d, i) {\n return i * plot.cellHeight + plot.cellHeight / 2 + d.group.gapsSize + offsetY.y;\n }).attr(\"dx\", -2).attr(\"text-anchor\", \"end\").attr(\"class\", function (d, i) {\n return labelClass + \" \" + labelYClass + \" \" + labelYClass + \"-\" + i;\n }).text(function (d) {\n var formatted = self.formatValueY(d.val);\n return formatted;\n });\n\n var maxWidth = self.computeYAxisLabelsWidth(offsetY);\n\n labels.each(function (label) {\n var elem = d3.select(this),\n text = self.formatValueY(label.val);\n _utils.Utils.placeTextWithEllipsisAndTooltip(elem, text, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\n });\n\n if (self.config.y.rotateLabels) {\n labels.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + offsetY.x + \", \" + (d.group.gapsSize + (i * plot.cellHeight + plot.cellHeight / 2) + offsetY.y) + \")\";\n }).attr(\"text-anchor\", \"end\");\n // .attr(\"dx\", -7);\n } else {\n labels.attr(\"dominant-baseline\", \"middle\");\n }\n\n labels.exit().remove();\n\n self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y')).selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + plot.height / 2 + \")rotate(-90)\").attr(\"dy\", \"1em\").style(\"text-anchor\", \"middle\").text(self.config.y.title);\n }\n }, {\n key: 'drawGroupsY',\n value: function drawGroupsY(parentGroup, container, availableWidth) {\n\n var self = this;\n var plot = self.plot;\n\n var groupClass = self.prefixClass(\"group\");\n var groupYClass = groupClass + \"-y\";\n var groups = container.selectAll(\"g.\" + groupClass + \".\" + groupYClass).data(parentGroup.childrenList);\n\n var valuesBeforeCount = 0;\n var gapsBeforeSize = 0;\n\n var groupsEnterG = groups.enter().append(\"g\");\n groupsEnterG.classed(groupClass, true).classed(groupYClass, true).append(\"rect\").classed(\"group-rect\", true);\n\n var titleGroupEnter = groupsEnterG.appendSelector(\"g.title\");\n titleGroupEnter.append(\"rect\");\n titleGroupEnter.append(\"text\");\n\n var gapSize = Heatmap.computeGapSize(parentGroup.level);\n var padding = gapSize / 4;\n\n var titleRectWidth = Heatmap.groupTitleRectHeight;\n var depth = self.config.y.groups.keys.length - parentGroup.level;\n var overlap = {\n left: 0,\n right: 0\n };\n\n if (!availableWidth) {\n overlap.right = plot.y.overlap.left;\n overlap.left = plot.y.overlap.left;\n availableWidth = plot.width + gapSize + overlap.left + overlap.right;\n }\n\n groups.attr(\"transform\", function (d, i) {\n var translate = \"translate(\" + (padding - overlap.left) + \",\" + (plot.cellHeight * valuesBeforeCount + i * gapSize + gapsBeforeSize + padding) + \")\";\n gapsBeforeSize += d.gapsInsideSize || 0;\n valuesBeforeCount += d.allValuesCount || 0;\n return translate;\n });\n\n var groupWidth = availableWidth - padding * 2;\n\n var titleGroups = groups.selectAll(\"g.title\").attr(\"transform\", function (d, i) {\n return \"translate(\" + (groupWidth - titleRectWidth) + \", 0)\";\n });\n\n var tileRects = titleGroups.selectAll(\"rect\").attr(\"width\", titleRectWidth).attr(\"height\", function (d) {\n return (d.gapsInsideSize || 0) + plot.cellHeight * d.allValuesCount + padding * 2;\n }).attr(\"x\", 0).attr(\"y\", 0)\n // .attr(\"fill\", \"lightgrey\")\n .attr(\"stroke-width\", 0);\n\n this.setGroupMouseCallbacks(parentGroup, tileRects);\n\n groups.selectAll(\"rect.group-rect\").attr(\"class\", function (d) {\n return \"group-rect group-rect-\" + d.index;\n }).attr(\"width\", groupWidth).attr(\"height\", function (d) {\n return (d.gapsInsideSize || 0) + plot.cellHeight * d.allValuesCount + padding * 2;\n }).attr(\"x\", 0).attr(\"y\", 0).attr(\"fill\", \"white\").attr(\"fill-opacity\", 0).attr(\"stroke-width\", 0.5).attr(\"stroke\", \"black\");\n\n groups.each(function (group) {\n\n self.drawGroupsY.call(self, group, d3.select(this), groupWidth - titleRectWidth);\n });\n }\n }, {\n key: 'drawGroupsX',\n value: function drawGroupsX(parentGroup, container, availableHeight) {\n\n var self = this;\n var plot = self.plot;\n\n var groupClass = self.prefixClass(\"group\");\n var groupXClass = groupClass + \"-x\";\n var groups = container.selectAll(\"g.\" + groupClass + \".\" + groupXClass).data(parentGroup.childrenList);\n\n var valuesBeforeCount = 0;\n var gapsBeforeSize = 0;\n\n var groupsEnterG = groups.enter().append(\"g\");\n groupsEnterG.classed(groupClass, true).classed(groupXClass, true).append(\"rect\").classed(\"group-rect\", true);\n\n var titleGroupEnter = groupsEnterG.appendSelector(\"g.title\");\n titleGroupEnter.append(\"rect\");\n titleGroupEnter.append(\"text\");\n\n var gapSize = Heatmap.computeGapSize(parentGroup.level);\n var padding = gapSize / 4;\n var titleRectHeight = Heatmap.groupTitleRectHeight;\n\n var depth = self.config.x.groups.keys.length - parentGroup.level;\n\n var overlap = {\n top: 0,\n bottom: 0\n };\n\n if (!availableHeight) {\n overlap.bottom = plot.x.overlap.bottom;\n overlap.top = plot.x.overlap.top;\n availableHeight = plot.height + gapSize + overlap.top + overlap.bottom;\n } else {\n overlap.top = -titleRectHeight;\n }\n // console.log('parentGroup',parentGroup, 'gapSize', gapSize, plot.x.overlap);\n\n groups.attr(\"transform\", function (d, i) {\n var translate = \"translate(\" + (plot.cellWidth * valuesBeforeCount + i * gapSize + gapsBeforeSize + padding) + \", \" + (padding - overlap.top) + \")\";\n gapsBeforeSize += d.gapsInsideSize || 0;\n valuesBeforeCount += d.allValuesCount || 0;\n return translate;\n });\n\n var groupHeight = availableHeight - padding * 2;\n\n var titleGroups = groups.selectAll(\"g.title\").attr(\"transform\", function (d, i) {\n return \"translate(0, \" + 0 + \")\";\n });\n\n var tileRects = titleGroups.selectAll(\"rect\").attr(\"height\", titleRectHeight).attr(\"width\", function (d) {\n return (d.gapsInsideSize || 0) + plot.cellWidth * d.allValuesCount + padding * 2;\n }).attr(\"x\", 0).attr(\"y\", 0)\n // .attr(\"fill\", \"lightgrey\")\n .attr(\"stroke-width\", 0);\n\n this.setGroupMouseCallbacks(parentGroup, tileRects);\n\n groups.selectAll(\"rect.group-rect\").attr(\"class\", function (d) {\n return \"group-rect group-rect-\" + d.index;\n }).attr(\"height\", groupHeight).attr(\"width\", function (d) {\n return (d.gapsInsideSize || 0) + plot.cellWidth * d.allValuesCount + padding * 2;\n }).attr(\"x\", 0).attr(\"y\", 0).attr(\"fill\", \"white\").attr(\"fill-opacity\", 0).attr(\"stroke-width\", 0.5).attr(\"stroke\", \"black\");\n\n groups.each(function (group) {\n self.drawGroupsX.call(self, group, d3.select(this), groupHeight - titleRectHeight);\n });\n\n groups.exit().remove();\n }\n }, {\n key: 'setGroupMouseCallbacks',\n value: function setGroupMouseCallbacks(parentGroup, tileRects) {\n var plot = this.plot;\n var self = this;\n var mouseoverCallbacks = [];\n mouseoverCallbacks.push(function (d) {\n d3.select(this).classed('highlighted', true);\n d3.select(this.parentNode.parentNode).selectAll(\"rect.group-rect-\" + d.index).classed('highlighted', true);\n });\n\n var mouseoutCallbacks = [];\n mouseoutCallbacks.push(function (d) {\n d3.select(this).classed('highlighted', false);\n d3.select(this.parentNode.parentNode).selectAll(\"rect.group-rect-\" + d.index).classed('highlighted', false);\n });\n if (plot.tooltip) {\n\n mouseoverCallbacks.push(function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = parentGroup.label + \": \" + d.groupingValue;\n\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n });\n\n mouseoutCallbacks.push(function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n tileRects.on(\"mouseover\", function (d) {\n var self = this;\n mouseoverCallbacks.forEach(function (callback) {\n callback.call(self, d);\n });\n });\n tileRects.on(\"mouseout\", function (d) {\n var self = this;\n mouseoutCallbacks.forEach(function (callback) {\n callback.call(self, d);\n });\n });\n }\n }, {\n key: 'updateCells',\n value: function updateCells() {\n\n var self = this;\n var plot = self.plot;\n var cellContainerClass = self.prefixClass(\"cells\");\n var gapSize = Heatmap.computeGapSize(0);\n var paddingX = plot.x.groups.childrenList.length ? gapSize / 2 : 0;\n var paddingY = plot.y.groups.childrenList.length ? gapSize / 2 : 0;\n var cellContainer = self.svgG.selectOrAppend(\"g.\" + cellContainerClass);\n cellContainer.attr(\"transform\", \"translate(\" + paddingX + \", \" + paddingY + \")\");\n\n var cellClass = self.prefixClass(\"cell\");\n var cellShape = plot.z.shape.type;\n\n var cells = cellContainer.selectAll(\"g.\" + cellClass).data(self.plot.cells);\n\n var cellEnterG = cells.enter().append(\"g\").classed(cellClass, true);\n cells.attr(\"transform\", function (c) {\n return \"translate(\" + (plot.cellWidth * c.col + plot.cellWidth / 2 + c.colVar.group.gapsSize) + \",\" + (plot.cellHeight * c.row + plot.cellHeight / 2 + c.rowVar.group.gapsSize) + \")\";\n });\n\n var shapes = cells.selectOrAppend(cellShape + \".cell-shape-\" + cellShape);\n\n shapes.attr(\"width\", plot.z.shape.width).attr(\"height\", plot.z.shape.height).attr(\"x\", -plot.cellWidth / 2).attr(\"y\", -plot.cellHeight / 2);\n\n shapes.style(\"fill\", function (c) {\n return c.value === undefined ? self.config.color.noDataColor : plot.z.color.scale(c.value);\n });\n shapes.attr(\"fill-opacity\", function (d) {\n return d.value === undefined ? 0 : 1;\n });\n\n var mouseoverCallbacks = [];\n var mouseoutCallbacks = [];\n\n if (plot.tooltip) {\n\n mouseoverCallbacks.push(function (c) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = c.value === undefined ? self.config.tooltip.noDataText : self.formatValueZ(c.value);\n\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n });\n\n mouseoutCallbacks.push(function (c) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n\n if (self.config.highlightLabels) {\n var highlightClass = self.config.cssClassPrefix + \"highlight\";\n var xLabelClass = function xLabelClass(c) {\n return plot.labelClass + \"-x-\" + c.col;\n };\n var yLabelClass = function yLabelClass(c) {\n return plot.labelClass + \"-y-\" + c.row;\n };\n\n mouseoverCallbacks.push(function (c) {\n\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, true);\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, true);\n });\n mouseoutCallbacks.push(function (c) {\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, false);\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, false);\n });\n }\n\n cells.on(\"mouseover\", function (c) {\n mouseoverCallbacks.forEach(function (callback) {\n return callback(c);\n });\n }).on(\"mouseout\", function (c) {\n mouseoutCallbacks.forEach(function (callback) {\n return callback(c);\n });\n });\n\n cells.on(\"click\", function (c) {\n self.trigger(\"cell-selected\", c);\n });\n\n cells.exit().remove();\n }\n }, {\n key: 'formatValueX',\n value: function formatValueX(value) {\n if (!this.config.x.formatter) return value;\n\n return this.config.x.formatter.call(this.config, value);\n }\n }, {\n key: 'formatValueY',\n value: function formatValueY(value) {\n if (!this.config.y.formatter) return value;\n\n return this.config.y.formatter.call(this.config, value);\n }\n }, {\n key: 'formatValueZ',\n value: function formatValueZ(value) {\n if (!this.config.z.formatter) return value;\n\n return this.config.z.formatter.call(this.config, value);\n }\n }, {\n key: 'formatLegendValue',\n value: function formatLegendValue(value) {\n if (!this.config.legend.formatter) return value;\n\n return this.config.legend.formatter.call(this.config, value);\n }\n }, {\n key: 'updateLegend',\n value: function updateLegend() {\n var self = this;\n var plot = this.plot;\n var legendX = this.plot.width + 10;\n var gapSize = Heatmap.computeGapSize(0);\n if (this.plot.groupByY) {\n legendX += gapSize / 2 + plot.y.overlap.right;\n } else if (this.plot.groupByX) {\n legendX += gapSize;\n }\n var legendY = 0;\n if (this.plot.groupByX || this.plot.groupByY) {\n legendY += gapSize / 2;\n }\n\n var barWidth = 10;\n var barHeight = this.plot.height - 2;\n var scale = plot.z.color.scale;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY, function (v) {\n return self.formatLegendValue(v);\n }).setRotateLabels(self.config.legend.rotateLabels).linearGradientBar(barWidth, barHeight);\n }\n }], [{\n key: 'computeGapSize',\n value: function computeGapSize(gapLevel) {\n return Heatmap.maxGroupGapSize / (gapLevel + 1);\n }\n }, {\n key: 'computeGapsSize',\n value: function computeGapsSize(gaps) {\n var gapsSize = 0;\n gaps.forEach(function (gapsNumber, gapsLevel) {\n return gapsSize += gapsNumber * Heatmap.computeGapSize(gapsLevel);\n });\n return gapsSize;\n }\n }]);\n\n return Heatmap;\n}(_chart.Chart);\n\nHeatmap.maxGroupGapSize = 24;\nHeatmap.groupTitleRectHeight = 6;\n\n},{\"./chart\":20,\"./legend\":27,\"./utils\":33}],25:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Histogram = exports.HistogramConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _utils = require(\"./utils\");\n\nvar _legend = require(\"./legend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar HistogramConfig = exports.HistogramConfig = function (_ChartConfig) {\n _inherits(HistogramConfig, _ChartConfig);\n\n // string or function returning color's value for color scale\n\n function HistogramConfig(custom) {\n _classCallCheck(this, HistogramConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(HistogramConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'histogram';\n _this.showLegend = true;\n _this.showTooltip = true;\n _this.legend = {\n width: 80,\n margin: 10,\n shapeWidth: 20\n };\n _this.x = { // X axis config\n label: '', // axis label\n key: 0,\n value: function value(d, key) {\n return _utils.Utils.isNumber(d) ? d : d[key];\n }, // x value accessor\n scale: \"linear\",\n ticks: undefined\n };\n _this.y = { // Y axis config\n label: '', // axis label,\n orient: \"left\",\n scale: \"linear\"\n };\n _this.frequency = true;\n _this.groups = {\n key: 1,\n value: function value(d) {\n return d[_this.groups.key];\n }, // grouping value accessor,\n label: \"\"\n };\n _this.color = undefined;\n _this.d3ColorCategory = 'category10';\n _this.transition = true;\n\n var config = _this;\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n }\n\n return HistogramConfig;\n}(_chart.ChartConfig);\n\nvar Histogram = exports.Histogram = function (_Chart) {\n _inherits(Histogram, _Chart);\n\n function Histogram(placeholderSelector, data, config) {\n _classCallCheck(this, Histogram);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(Histogram).call(this, placeholderSelector, data, new HistogramConfig(config)));\n }\n\n _createClass(Histogram, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(Histogram.prototype), \"setConfig\", this).call(this, new HistogramConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n var _this3 = this;\n\n _get(Object.getPrototypeOf(Histogram.prototype), \"initPlot\", this).call(this);\n var self = this;\n\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.y = {};\n this.plot.bar = {\n color: null //color scale mapping function\n };\n\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n this.plot.margin.right = conf.margin.right + conf.legend.width + conf.legend.margin * 2;\n }\n\n this.computePlotSize();\n\n if (conf.d3ColorCategory) {\n this.plot.colorCategory = d3.scale[conf.d3ColorCategory]();\n }\n var colorValue = conf.color;\n if (colorValue && typeof colorValue === 'string' || colorValue instanceof String) {\n this.plot.color = colorValue;\n } else if (this.plot.colorCategory) {\n var domain = Object.getOwnPropertyNames(d3.map(this.data, function (d) {\n return _this3.config.groups.value.call(_this3.config, d);\n })['_']);\n self.plot.colorCategory.domain(domain);\n this.plot.color = function (d) {\n return self.plot.colorCategory(d.key);\n };\n }\n\n this.plot.data = this.getDataToPlot();\n this.setupX();\n this.setupHistogram();\n this.setupGroupStacks();\n this.setupY();\n\n return this;\n }\n }, {\n key: \"setupX\",\n value: function setupX() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config.x;\n\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\n x.value = function (d) {\n return conf.value(d, conf.key);\n };\n x.scale = d3.scale[conf.scale]().range([0, plot.width]);\n x.map = function (d) {\n return x.scale(x.value(d));\n };\n\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\n if (conf.ticks) {\n x.axis.ticks(conf.ticks);\n }\n var data = this.plot.data;\n plot.x.scale.domain([d3.min(data, plot.x.value), d3.max(data, plot.x.value)]);\n }\n }, {\n key: \"setupY\",\n value: function setupY() {\n\n var plot = this.plot;\n var y = plot.y;\n var conf = this.config.y;\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\n\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\n\n var data = this.plot.data;\n plot.y.scale.domain([0, d3.max(plot.histogramBins, function (d) {\n return d.y;\n })]);\n }\n }, {\n key: \"setupHistogram\",\n value: function setupHistogram() {\n var plot = this.plot;\n var x = plot.x;\n var y = plot.y;\n var ticks = this.config.x.ticks ? x.scale.ticks(this.config.x.ticks) : x.scale.ticks();\n\n plot.histogram = d3.layout.histogram().frequency(this.config.frequency).value(x.value).bins(ticks);\n plot.histogramBins = plot.histogram(this.plot.data);\n }\n }, {\n key: \"setupGroupStacks\",\n value: function setupGroupStacks() {\n var _this4 = this;\n\n var self = this;\n this.plot.groupingEnabled = this.config.groups && this.config.groups.value;\n\n this.plot.stack = d3.layout.stack().values(function (d) {\n return d.histogramBins;\n });\n this.plot.groupedData = d3.nest().key(function (d) {\n return _this4.plot.groupingEnabled ? _this4.config.groups.value.call(_this4.config, d) : 'root';\n }).entries(this.plot.data);\n this.plot.groupedData.forEach(function (d) {\n d.histogramBins = _this4.plot.histogram.frequency(_this4.config.frequency || _this4.plot.groupingEnabled)(d.values);\n if (!_this4.config.frequency && _this4.plot.groupingEnabled) {\n d.histogramBins.forEach(function (b) {\n b.dy = b.dy / _this4.plot.data.length;\n b.y = b.y / _this4.plot.data.length;\n });\n }\n });\n this.plot.stackedHistograms = this.plot.stack(this.plot.groupedData);\n }\n }, {\n key: \"getDataToPlot\",\n value: function getDataToPlot() {\n var _this5 = this;\n\n if (!this.enabledGroups) {\n return this.data;\n }\n\n return this.data.filter(function (d) {\n return _this5.enabledGroups.indexOf(_this5.config.groups.value.call(_this5.config, d)) > -1;\n });\n }\n }, {\n key: \"drawAxisX\",\n value: function drawAxisX() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.x;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides'))).attr(\"transform\", \"translate(0,\" + plot.height + \")\");\n\n var axisT = axis;\n if (self.config.transition) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.x.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + plot.width / 2 + \",\" + plot.margin.bottom + \")\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"-1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawAxisY\",\n value: function drawAxisY() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.y;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides')));\n\n var axisT = axis;\n if (self.config.transition) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.y.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + plot.height / 2 + \")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawHistogram\",\n value: function drawHistogram() {\n var self = this;\n var plot = self.plot;\n\n var layerClass = this.prefixClass(\"layer\");\n\n var barClass = this.prefixClass(\"bar\");\n var layer = self.svgG.selectAll(\".\" + layerClass).data(plot.stackedHistograms);\n\n layer.enter().append(\"g\").attr(\"class\", layerClass);\n\n var bar = layer.selectAll(\".\" + barClass).data(function (d) {\n return d.histogramBins;\n });\n\n bar.enter().append(\"g\").attr(\"class\", barClass).append(\"rect\").attr(\"x\", 1);\n\n var barRect = bar.select(\"rect\");\n\n var barRectT = barRect;\n var barT = bar;\n var layerT = layer;\n if (this.transitionEnabled()) {\n barRectT = barRect.transition();\n barT = bar.transition();\n layerT = layer.transition();\n }\n\n barT.attr(\"transform\", function (d) {\n return \"translate(\" + plot.x.scale(d.x) + \",\" + plot.y.scale(d.y0 + d.y) + \")\";\n });\n\n var dx = plot.histogramBins.length ? plot.x.scale(plot.histogramBins[0].dx) : 0;\n barRectT.attr(\"width\", dx - plot.x.scale(0) - 1).attr(\"height\", function (d) {\n return plot.height - plot.y.scale(d.y);\n });\n\n if (this.plot.color) {\n layerT.attr(\"fill\", this.plot.color);\n }\n\n if (plot.tooltip) {\n bar.on(\"mouseover\", function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n plot.tooltip.html(d.y).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n }).on(\"mouseout\", function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n layer.exit().remove();\n bar.exit().remove();\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(Histogram.prototype), \"update\", this).call(this, newData);\n this.drawAxisX();\n this.drawAxisY();\n\n this.drawHistogram();\n\n this.updateLegend();\n }\n }, {\n key: \"updateLegend\",\n value: function updateLegend() {\n var _this6 = this;\n\n var plot = this.plot;\n\n var scale = plot.colorCategory;\n if (!scale.domain() || scale.domain().length < 2) {\n plot.showLegend = false;\n }\n\n if (!plot.showLegend) {\n if (plot.legend && plot.legend.container) {\n plot.legend.container.remove();\n }\n return;\n }\n\n var legendX = this.plot.width + this.config.legend.margin;\n var legendY = this.config.legend.margin;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY);\n\n plot.legendColor = plot.legend.color().shapeWidth(this.config.legend.shapeWidth).orient('vertical').scale(scale);\n\n plot.legendColor.on('cellclick', function (c) {\n return _this6.onLegendCellClick(c);\n });\n\n plot.legend.container.call(plot.legendColor);\n }\n }, {\n key: \"onLegendCellClick\",\n value: function onLegendCellClick(cellValue) {\n this.updateEnabledGroups(cellValue);\n\n var isDisabled = this.enabledGroups.indexOf(cellValue) < 0;\n this.plot.legend.container.selectAll(\"g.cell\").each(function (cell) {\n if (cell == cellValue) {\n d3.select(this).classed(\"odc-disabled\", isDisabled);\n }\n });\n\n this.init();\n }\n }, {\n key: \"updateEnabledGroups\",\n value: function updateEnabledGroups(cellValue) {\n if (!this.enabledGroups) {\n this.enabledGroups = this.plot.colorCategory.domain().slice();\n }\n var index = this.enabledGroups.indexOf(cellValue);\n\n if (index < 0) {\n this.enabledGroups.push(cellValue);\n } else {\n this.enabledGroups.splice(index, 1);\n }\n }\n }, {\n key: \"setData\",\n value: function setData(data) {\n _get(Object.getPrototypeOf(Histogram.prototype), \"setData\", this).call(this, data);\n this.enabledGroups = null;\n }\n }]);\n\n return Histogram;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./utils\":33}],26:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Legend = exports.StatisticsUtils = exports.BarChartConfig = exports.BarChart = exports.HistogramConfig = exports.Histogram = exports.HeatmapTimeSeriesConfig = exports.HeatmapTimeSeries = exports.HeatmapConfig = exports.Heatmap = exports.RegressionConfig = exports.Regression = exports.CorrelationMatrixConfig = exports.CorrelationMatrix = exports.ScatterPlotMatrixConfig = exports.ScatterPlotMatrix = exports.ScatterPlotConfig = exports.ScatterPlot = undefined;\n\nvar _scatterplot = require(\"./scatterplot\");\n\nObject.defineProperty(exports, \"ScatterPlot\", {\n enumerable: true,\n get: function get() {\n return _scatterplot.ScatterPlot;\n }\n});\nObject.defineProperty(exports, \"ScatterPlotConfig\", {\n enumerable: true,\n get: function get() {\n return _scatterplot.ScatterPlotConfig;\n }\n});\n\nvar _scatterplotMatrix = require(\"./scatterplot-matrix\");\n\nObject.defineProperty(exports, \"ScatterPlotMatrix\", {\n enumerable: true,\n get: function get() {\n return _scatterplotMatrix.ScatterPlotMatrix;\n }\n});\nObject.defineProperty(exports, \"ScatterPlotMatrixConfig\", {\n enumerable: true,\n get: function get() {\n return _scatterplotMatrix.ScatterPlotMatrixConfig;\n }\n});\n\nvar _correlationMatrix = require(\"./correlation-matrix\");\n\nObject.defineProperty(exports, \"CorrelationMatrix\", {\n enumerable: true,\n get: function get() {\n return _correlationMatrix.CorrelationMatrix;\n }\n});\nObject.defineProperty(exports, \"CorrelationMatrixConfig\", {\n enumerable: true,\n get: function get() {\n return _correlationMatrix.CorrelationMatrixConfig;\n }\n});\n\nvar _regression = require(\"./regression\");\n\nObject.defineProperty(exports, \"Regression\", {\n enumerable: true,\n get: function get() {\n return _regression.Regression;\n }\n});\nObject.defineProperty(exports, \"RegressionConfig\", {\n enumerable: true,\n get: function get() {\n return _regression.RegressionConfig;\n }\n});\n\nvar _heatmap = require(\"./heatmap\");\n\nObject.defineProperty(exports, \"Heatmap\", {\n enumerable: true,\n get: function get() {\n return _heatmap.Heatmap;\n }\n});\nObject.defineProperty(exports, \"HeatmapConfig\", {\n enumerable: true,\n get: function get() {\n return _heatmap.HeatmapConfig;\n }\n});\n\nvar _heatmapTimeseries = require(\"./heatmap-timeseries\");\n\nObject.defineProperty(exports, \"HeatmapTimeSeries\", {\n enumerable: true,\n get: function get() {\n return _heatmapTimeseries.HeatmapTimeSeries;\n }\n});\nObject.defineProperty(exports, \"HeatmapTimeSeriesConfig\", {\n enumerable: true,\n get: function get() {\n return _heatmapTimeseries.HeatmapTimeSeriesConfig;\n }\n});\n\nvar _histogram = require(\"./histogram\");\n\nObject.defineProperty(exports, \"Histogram\", {\n enumerable: true,\n get: function get() {\n return _histogram.Histogram;\n }\n});\nObject.defineProperty(exports, \"HistogramConfig\", {\n enumerable: true,\n get: function get() {\n return _histogram.HistogramConfig;\n }\n});\n\nvar _barChart = require(\"./bar-chart\");\n\nObject.defineProperty(exports, \"BarChart\", {\n enumerable: true,\n get: function get() {\n return _barChart.BarChart;\n }\n});\nObject.defineProperty(exports, \"BarChartConfig\", {\n enumerable: true,\n get: function get() {\n return _barChart.BarChartConfig;\n }\n});\n\nvar _statisticsUtils = require(\"./statistics-utils\");\n\nObject.defineProperty(exports, \"StatisticsUtils\", {\n enumerable: true,\n get: function get() {\n return _statisticsUtils.StatisticsUtils;\n }\n});\n\nvar _legend = require(\"./legend\");\n\nObject.defineProperty(exports, \"Legend\", {\n enumerable: true,\n get: function get() {\n return _legend.Legend;\n }\n});\n\nvar _d3Extensions = require(\"./d3-extensions\");\n\n_d3Extensions.D3Extensions.extend();\n\n},{\"./bar-chart\":19,\"./correlation-matrix\":21,\"./d3-extensions\":22,\"./heatmap\":24,\"./heatmap-timeseries\":23,\"./histogram\":25,\"./legend\":27,\"./regression\":28,\"./scatterplot\":30,\"./scatterplot-matrix\":29,\"./statistics-utils\":32}],27:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Legend = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _utils = require(\"./utils\");\n\nvar _noExtend = require(\"../bower_components/d3-legend/no-extend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*var d3 = require('../bower_components/d3');\r\n*/\n// var legend = require('../bower_components/d3-legend/no-extend');\n//\n// module.exports.legend = legend;\n\nvar Legend = exports.Legend = function () {\n function Legend(svg, legendParent, scale, legendX, legendY, labelFormat) {\n _classCallCheck(this, Legend);\n\n this.cssClassPrefix = \"odc-\";\n this.legendClass = this.cssClassPrefix + \"legend\";\n this.color = _noExtend.color;\n this.size = _noExtend.size;\n this.symbol = _noExtend.symbol;\n this.labelFormat = undefined;\n\n this.scale = scale;\n this.svg = svg;\n this.guid = _utils.Utils.guid();\n this.container = _utils.Utils.selectOrAppend(legendParent, \"g.\" + this.legendClass, \"g\").attr(\"transform\", \"translate(\" + legendX + \",\" + legendY + \")\").classed(this.legendClass, true);\n\n this.labelFormat = labelFormat;\n }\n\n _createClass(Legend, [{\n key: \"linearGradientBar\",\n value: function linearGradientBar(barWidth, barHeight, title) {\n var gradientId = this.cssClassPrefix + \"linear-gradient\" + \"-\" + this.guid;\n var scale = this.scale;\n var self = this;\n\n this.linearGradient = _utils.Utils.linearGradient(this.svg, gradientId, this.scale.range(), 0, 100, 0, 0);\n\n this.container.append(\"rect\").attr(\"width\", barWidth).attr(\"height\", barHeight).attr(\"x\", 0).attr(\"y\", 0).style(\"fill\", \"url(#\" + gradientId + \")\");\n\n var ticks = this.container.selectAll(\"text\").data(scale.domain());\n var ticksNumber = scale.domain().length - 1;\n ticks.enter().append(\"text\");\n\n ticks.attr(\"x\", barWidth).attr(\"y\", function (d, i) {\n return barHeight - i * barHeight / ticksNumber;\n }).attr(\"dx\", 3)\n // .attr(\"dy\", 1)\n .attr(\"alignment-baseline\", \"middle\").text(function (d) {\n return self.labelFormat ? self.labelFormat(d) : d;\n });\n ticks.attr(\"dominant-baseline\", \"middle\");\n if (this.rotateLabels) {\n ticks.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + barWidth + \", \" + (barHeight - i * barHeight / ticksNumber) + \")\";\n }).attr(\"text-anchor\", \"start\").attr(\"dx\", 5).attr(\"dy\", 5);\n } else {}\n\n ticks.exit().remove();\n\n return this;\n }\n }, {\n key: \"setRotateLabels\",\n value: function setRotateLabels(rotateLabels) {\n this.rotateLabels = rotateLabels;\n return this;\n }\n }]);\n\n return Legend;\n}();\n\n},{\"../bower_components/d3-legend/no-extend\":1,\"./utils\":33}],28:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Regression = exports.RegressionConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _scatterplot = require(\"./scatterplot\");\n\nvar _utils = require(\"./utils\");\n\nvar _statisticsUtils = require(\"./statistics-utils\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar RegressionConfig = exports.RegressionConfig = function (_ScatterPlotConfig) {\n _inherits(RegressionConfig, _ScatterPlotConfig);\n\n function RegressionConfig(custom) {\n _classCallCheck(this, RegressionConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(RegressionConfig).call(this));\n\n _this.mainRegression = true;\n _this.groupRegression = true;\n _this.confidence = {\n level: 0.95,\n criticalValue: function criticalValue(degreesOfFreedom, criticalProbability) {\n return _statisticsUtils.StatisticsUtils.tValue(degreesOfFreedom, criticalProbability);\n },\n marginOfError: undefined //custom margin Of Error function (x, points)\n };\n\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n }\n\n return RegressionConfig;\n}(_scatterplot.ScatterPlotConfig);\n\nvar Regression = exports.Regression = function (_ScatterPlot) {\n _inherits(Regression, _ScatterPlot);\n\n function Regression(placeholderSelector, data, config) {\n _classCallCheck(this, Regression);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(Regression).call(this, placeholderSelector, data, new RegressionConfig(config)));\n }\n\n _createClass(Regression, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(Regression.prototype), \"setConfig\", this).call(this, new RegressionConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(Regression.prototype), \"initPlot\", this).call(this);\n this.initRegressionLines();\n }\n }, {\n key: \"initRegressionLines\",\n value: function initRegressionLines() {\n\n var self = this;\n var groupsAvailable = self.config.groups && self.config.groups.value;\n\n self.plot.regressions = [];\n\n if (groupsAvailable && self.config.mainRegression) {\n var regression = this.initRegression(this.plot.data, false);\n self.plot.regressions.push(regression);\n }\n\n if (self.config.groupRegression) {\n this.initGroupRegression();\n }\n }\n }, {\n key: \"initGroupRegression\",\n value: function initGroupRegression() {\n var self = this;\n var dataByGroup = {};\n this.plot.data.forEach(function (d) {\n var groupVal = self.config.groups.value(d, self.config.groups.key);\n\n if (!groupVal && groupVal !== 0) {\n return;\n }\n\n if (!dataByGroup[groupVal]) {\n dataByGroup[groupVal] = [];\n }\n dataByGroup[groupVal].push(d);\n });\n\n for (var key in dataByGroup) {\n if (!dataByGroup.hasOwnProperty(key)) {\n continue;\n }\n\n var regression = this.initRegression(dataByGroup[key], key);\n self.plot.regressions.push(regression);\n }\n }\n }, {\n key: \"initRegression\",\n value: function initRegression(values, groupVal) {\n var self = this;\n\n var points = values.map(function (d) {\n return [parseFloat(self.plot.x.value(d)), parseFloat(self.plot.y.value(d))];\n });\n\n // points.sort((a,b) => a[0]-b[0]);\n\n var linearRegression = _statisticsUtils.StatisticsUtils.linearRegression(points);\n var linearRegressionLine = _statisticsUtils.StatisticsUtils.linearRegressionLine(linearRegression);\n\n var extentX = d3.extent(points, function (d) {\n return d[0];\n });\n\n var linePoints = [{\n x: extentX[0],\n y: linearRegressionLine(extentX[0])\n }, {\n x: extentX[1],\n y: linearRegressionLine(extentX[1])\n }];\n\n var line = d3.svg.line().interpolate(\"basis\").x(function (d) {\n return self.plot.x.scale(d.x);\n }).y(function (d) {\n return self.plot.y.scale(d.y);\n });\n\n var color = self.plot.dot.color;\n\n var defaultColor = \"black\";\n if (_utils.Utils.isFunction(color)) {\n if (values.length && groupVal !== false) {\n color = color(values[0]);\n } else {\n color = defaultColor;\n }\n } else if (!color && groupVal === false) {\n color = defaultColor;\n }\n\n var confidence = this.computeConfidence(points, extentX, linearRegression, linearRegressionLine);\n return {\n group: groupVal || false,\n line: line,\n linePoints: linePoints,\n color: color,\n confidence: confidence\n };\n }\n }, {\n key: \"computeConfidence\",\n value: function computeConfidence(points, extentX, linearRegression, linearRegressionLine) {\n var self = this;\n var slope = linearRegression.m;\n var n = points.length;\n var degreesOfFreedom = Math.max(0, n - 2);\n\n var alpha = 1 - self.config.confidence.level;\n var criticalProbability = 1 - alpha / 2;\n var criticalValue = self.config.confidence.criticalValue(degreesOfFreedom, criticalProbability);\n\n var xValues = points.map(function (d) {\n return d[0];\n });\n var meanX = _statisticsUtils.StatisticsUtils.mean(xValues);\n var xMySum = 0;\n var xSum = 0;\n var xPowSum = 0;\n var ySum = 0;\n var yPowSum = 0;\n points.forEach(function (p) {\n var x = p[0];\n var y = p[1];\n\n xMySum += x * y;\n xSum += x;\n ySum += y;\n xPowSum += x * x;\n yPowSum += y * y;\n });\n var a = linearRegression.m;\n var b = linearRegression.b;\n\n var Sa2 = n / (n + 2) * ((yPowSum - a * xMySum - b * ySum) / (n * xPowSum - xSum * xSum)); //Wariancja współczynnika kierunkowego regresji liniowej a\n var Sy2 = (yPowSum - a * xMySum - b * ySum) / (n * (n - 2)); //Sa2 //Mean y value variance\n\n var errorFn = function errorFn(x) {\n return Math.sqrt(Sy2 + Math.pow(x - meanX, 2) * Sa2);\n }; //pierwiastek kwadratowy z wariancji dowolnego punktu prostej\n var marginOfError = function marginOfError(x) {\n return criticalValue * errorFn(x);\n };\n\n // console.log('n', n, 'degreesOfFreedom', degreesOfFreedom, 'criticalProbability',criticalProbability);\n // var confidenceDown = x => linearRegressionLine(x) - marginOfError(x);\n // var confidenceUp = x => linearRegressionLine(x) + marginOfError(x);\n\n var computeConfidenceAreaPoint = function computeConfidenceAreaPoint(x) {\n var linearRegression = linearRegressionLine(x);\n var moe = marginOfError(x);\n var confDown = linearRegression - moe;\n var confUp = linearRegression + moe;\n return {\n x: x,\n y0: confDown,\n y1: confUp\n };\n };\n\n var centerX = (extentX[1] + extentX[0]) / 2;\n\n // var confidenceAreaPoints = [extentX[0], centerX, extentX[1]].map(computeConfidenceAreaPoint);\n var confidenceAreaPoints = [extentX[0], centerX, extentX[1]].map(computeConfidenceAreaPoint);\n\n var fitInPlot = function fitInPlot(y) {\n return y;\n };\n\n var confidenceArea = d3.svg.area().interpolate(\"monotone\").x(function (d) {\n return self.plot.x.scale(d.x);\n }).y0(function (d) {\n return fitInPlot(self.plot.y.scale(d.y0));\n }).y1(function (d) {\n return fitInPlot(self.plot.y.scale(d.y1));\n });\n\n return {\n area: confidenceArea,\n points: confidenceAreaPoints\n };\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(Regression.prototype), \"update\", this).call(this, newData);\n this.updateRegressionLines();\n }\n }, {\n key: \"updateRegressionLines\",\n value: function updateRegressionLines() {\n var self = this;\n var regressionContainerClass = this.prefixClass(\"regression-container\");\n var regressionContainerSelector = \"g.\" + regressionContainerClass;\n\n var clipPathId = self.prefixClass(\"clip\");\n\n var regressionContainer = self.svgG.selectOrInsert(regressionContainerSelector, \".\" + self.dotsContainerClass);\n var regressionContainerClip = regressionContainer.selectOrAppend(\"clipPath\").attr(\"id\", clipPathId);\n\n regressionContainerClip.selectOrAppend('rect').attr('width', self.plot.width).attr('height', self.plot.height).attr('x', 0).attr('y', 0);\n\n regressionContainer.attr(\"clip-path\", function (d, i) {\n return \"url(#\" + clipPathId + \")\";\n });\n\n var regressionClass = this.prefixClass(\"regression\");\n var confidenceAreaClass = self.prefixClass(\"confidence\");\n var regressionSelector = \"g.\" + regressionClass;\n var regression = regressionContainer.selectAll(regressionSelector).data(self.plot.regressions, function (d, i) {\n return d.group;\n });\n\n var regressionEnterG = regression.enter().insertSelector(regressionSelector);\n var lineClass = self.prefixClass(\"line\");\n regressionEnterG.append(\"path\").attr(\"class\", lineClass).attr(\"shape-rendering\", \"optimizeQuality\");\n // .append(\"line\")\n // .attr(\"class\", \"line\")\n // .attr(\"shape-rendering\", \"optimizeQuality\");\n\n var line = regression.select(\"path.\" + lineClass).style(\"stroke\", function (r) {\n return r.color;\n });\n // .attr(\"x1\", r=> self.plot.x.scale(r.linePoints[0].x))\n // .attr(\"y1\", r=> self.plot.y.scale(r.linePoints[0].y))\n // .attr(\"x2\", r=> self.plot.x.scale(r.linePoints[1].x))\n // .attr(\"y2\", r=> self.plot.y.scale(r.linePoints[1].y))\n\n var lineT = line;\n if (self.transitionEnabled()) {\n lineT = line.transition();\n }\n\n lineT.attr(\"d\", function (r) {\n return r.line(r.linePoints);\n });\n\n regressionEnterG.append(\"path\").attr(\"class\", confidenceAreaClass).attr(\"shape-rendering\", \"optimizeQuality\").style(\"opacity\", \"0.4\");\n\n var area = regression.select(\"path.\" + confidenceAreaClass);\n\n var areaT = area;\n if (self.transitionEnabled()) {\n areaT = area.transition();\n }\n areaT.attr(\"d\", function (r) {\n return r.confidence.area(r.confidence.points);\n });\n areaT.style(\"fill\", function (r) {\n return r.color;\n });\n regression.exit().remove();\n }\n }]);\n\n return Regression;\n}(_scatterplot.ScatterPlot);\n\n},{\"./chart\":20,\"./scatterplot\":30,\"./statistics-utils\":32,\"./utils\":33}],29:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ScatterPlotMatrix = exports.ScatterPlotMatrixConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _scatterplot = require(\"./scatterplot\");\n\nvar _utils = require(\"./utils\");\n\nvar _legend = require(\"./legend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar ScatterPlotMatrixConfig = exports.ScatterPlotMatrixConfig = function (_ScatterPlotConfig) {\n _inherits(ScatterPlotMatrixConfig, _ScatterPlotConfig);\n\n //ticks number, (default: computed using cell size)\n //show axis guides\n //scatter plot cell padding\n\n function ScatterPlotMatrixConfig(custom) {\n _classCallCheck(this, ScatterPlotMatrixConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ScatterPlotMatrixConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'scatterplot-matrix';\n _this.size = 200;\n _this.padding = 20;\n _this.brush = true;\n _this.guides = true;\n _this.showTooltip = true;\n _this.ticks = undefined;\n _this.x = { // X axis config\n orient: \"bottom\",\n scale: \"linear\"\n };\n _this.y = { // Y axis config\n orient: \"left\",\n scale: \"linear\"\n };\n _this.groups = {\n key: undefined, //object property name or array index with grouping variable\n includeInPlot: false, //include group as variable in plot, boolean (default: false)\n value: function value(d, key) {\n return d[key];\n }, // grouping value accessor,\n label: \"\"\n };\n _this.variables = {\n labels: [], //optional array of variable labels (for the diagonal of the plot).\n keys: [], //optional array of variable keys\n value: function value(d, variableKey) {\n return d[variableKey];\n } // variable value accessor\n };\n\n _utils.Utils.deepExtend(_this, custom);\n return _this;\n } //show tooltip on dot hover\n //scatter plot cell size\n\n\n return ScatterPlotMatrixConfig;\n}(_scatterplot.ScatterPlotConfig);\n\nvar ScatterPlotMatrix = exports.ScatterPlotMatrix = function (_Chart) {\n _inherits(ScatterPlotMatrix, _Chart);\n\n function ScatterPlotMatrix(placeholderSelector, data, config) {\n _classCallCheck(this, ScatterPlotMatrix);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(ScatterPlotMatrix).call(this, placeholderSelector, data, new ScatterPlotMatrixConfig(config)));\n }\n\n _createClass(ScatterPlotMatrix, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(ScatterPlotMatrix.prototype), \"setConfig\", this).call(this, new ScatterPlotMatrixConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(ScatterPlotMatrix.prototype), \"initPlot\", this).call(this);\n\n var self = this;\n var margin = this.plot.margin;\n var conf = this.config;\n this.plot.x = {};\n this.plot.y = {};\n this.plot.dot = {\n color: null //color scale mapping function\n };\n\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n margin.right = conf.margin.right + conf.legend.width + conf.legend.margin * 2;\n }\n\n this.setupGroups();\n\n this.plot.data = this.getDataToPlot();\n this.setupVariables();\n\n this.plot.size = conf.size;\n\n var width = conf.width;\n var boundingClientRect = this.getBaseContainerNode().getBoundingClientRect();\n if (!width) {\n var maxWidth = margin.left + margin.right + this.plot.variables.length * this.plot.size;\n width = Math.min(boundingClientRect.width, maxWidth);\n }\n var height = width;\n if (!height) {\n height = boundingClientRect.height;\n }\n\n this.plot.width = width - margin.left - margin.right;\n this.plot.height = height - margin.top - margin.bottom;\n\n if (conf.ticks === undefined) {\n conf.ticks = this.plot.size / 40;\n }\n\n this.setupX();\n this.setupY();\n\n return this;\n }\n }, {\n key: \"setupGroups\",\n value: function setupGroups() {\n var self = this;\n var conf = this.config;\n this.plot.groupValue = function (d) {\n return conf.groups.value(d, conf.groups.key);\n };\n if (conf.dot.d3ColorCategory) {\n this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();\n }\n var colorValue = conf.dot.color;\n if (colorValue) {\n this.plot.dot.colorValue = colorValue;\n\n if (typeof colorValue === 'string' || colorValue instanceof String) {\n this.plot.dot.color = colorValue;\n } else if (this.plot.dot.colorCategory) {\n var domain = Object.getOwnPropertyNames(d3.map(this.data, function (d) {\n return self.plot.dot.colorValue.call(self, d);\n })['_']);\n self.plot.dot.colorCategory.domain(domain);\n this.plot.dot.color = function (d) {\n return self.plot.dot.colorCategory(self.plot.dot.colorValue.call(self, d));\n };\n }\n }\n }\n }, {\n key: \"getDataToPlot\",\n value: function getDataToPlot() {\n var _this3 = this;\n\n if (!this.enabledGroups) {\n return this.data;\n }\n\n var filter = this.data.filter(function (d) {\n return _this3.enabledGroups.indexOf(_this3.plot.groupValue(d)) > -1;\n });\n void 0;\n return filter;\n }\n }, {\n key: \"setupVariables\",\n value: function setupVariables() {\n var variablesConf = this.config.variables;\n\n var data = this.data;\n var plot = this.plot;\n plot.domainByVariable = {};\n plot.variables = variablesConf.keys;\n if (!plot.variables || !plot.variables.length) {\n plot.variables = _utils.Utils.inferVariables(data, this.config.groups.key, this.config.includeInPlot);\n }\n\n plot.labels = [];\n plot.labelByVariable = {};\n plot.variables.forEach(function (variableKey, index) {\n plot.domainByVariable[variableKey] = d3.extent(data, function (d) {\n return variablesConf.value(d, variableKey);\n });\n var label = variableKey;\n if (variablesConf.labels && variablesConf.labels.length > index) {\n\n label = variablesConf.labels[index];\n }\n plot.labels.push(label);\n plot.labelByVariable[variableKey] = label;\n });\n\n void 0;\n\n plot.subplots = [];\n }\n }, {\n key: \"setupX\",\n value: function setupX() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config;\n\n x.value = conf.variables.value;\n x.scale = d3.scale[conf.x.scale]().range([conf.padding / 2, plot.size - conf.padding / 2]);\n x.map = function (d, variable) {\n return x.scale(x.value(d, variable));\n };\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.x.orient).ticks(conf.ticks);\n x.axis.tickSize(plot.size * plot.variables.length);\n }\n }, {\n key: \"setupY\",\n value: function setupY() {\n\n var plot = this.plot;\n var y = plot.y;\n var conf = this.config;\n\n y.value = conf.variables.value;\n y.scale = d3.scale[conf.y.scale]().range([plot.size - conf.padding / 2, conf.padding / 2]);\n y.map = function (d, variable) {\n return y.scale(y.value(d, variable));\n };\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.y.orient).ticks(conf.ticks);\n y.axis.tickSize(-plot.size * plot.variables.length);\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(ScatterPlotMatrix.prototype), \"update\", this).call(this, newData);\n\n var self = this;\n var n = self.plot.variables.length;\n var conf = this.config;\n\n var axisClass = self.prefixClass(\"axis\");\n var axisXClass = axisClass + \"-x\";\n var axisYClass = axisClass + \"-y\";\n\n var xAxisSelector = \"g.\" + axisXClass + \".\" + axisClass;\n var yAxisSelector = \"g.\" + axisYClass + \".\" + axisClass;\n\n var noGuidesClass = self.prefixClass(\"no-guides\");\n self.svgG.selectAll(xAxisSelector).data(self.plot.variables).enter().appendSelector(xAxisSelector).classed(noGuidesClass, !conf.guides).attr(\"transform\", function (d, i) {\n return \"translate(\" + (n - i - 1) * self.plot.size + \",0)\";\n }).each(function (d) {\n self.plot.x.scale.domain(self.plot.domainByVariable[d]);d3.select(this).call(self.plot.x.axis);\n });\n\n self.svgG.selectAll(yAxisSelector).data(self.plot.variables).enter().appendSelector(yAxisSelector).classed(noGuidesClass, !conf.guides).attr(\"transform\", function (d, i) {\n return \"translate(0,\" + i * self.plot.size + \")\";\n }).each(function (d) {\n self.plot.y.scale.domain(self.plot.domainByVariable[d]);d3.select(this).call(self.plot.y.axis);\n });\n\n var cellClass = self.prefixClass(\"cell\");\n var cell = self.svgG.selectAll(\".\" + cellClass).data(self.utils.cross(self.plot.variables, self.plot.variables));\n\n cell.enter().appendSelector(\"g.\" + cellClass).filter(function (d) {\n return d.i === d.j;\n }).append(\"text\");\n\n cell.attr(\"transform\", function (d) {\n return \"translate(\" + (n - d.i - 1) * self.plot.size + \",\" + d.j * self.plot.size + \")\";\n });\n\n if (conf.brush) {\n this.drawBrush(cell);\n }\n\n cell.each(plotSubplot);\n\n //Labels\n cell.select(\"text\").attr(\"x\", conf.padding).attr(\"y\", conf.padding).attr(\"dy\", \".71em\").text(function (d) {\n return self.plot.labelByVariable[d.x];\n });\n\n function plotSubplot(p) {\n void 0;\n var plot = self.plot;\n plot.subplots.push(p);\n var cell = d3.select(this);\n\n plot.x.scale.domain(plot.domainByVariable[p.x]);\n plot.y.scale.domain(plot.domainByVariable[p.y]);\n\n var frameClass = self.prefixClass(\"frame\");\n cell.selectOrAppend(\"rect.\" + frameClass).attr(\"class\", frameClass).attr(\"x\", conf.padding / 2).attr(\"y\", conf.padding / 2).attr(\"width\", conf.size - conf.padding).attr(\"height\", conf.size - conf.padding);\n\n p.update = function () {\n\n var subplot = this;\n var dots = cell.selectAll(\"circle\").data(self.plot.data);\n\n dots.enter().append(\"circle\");\n\n var dotsT = dots;\n if (self.transitionEnabled()) {\n dotsT = dots.transition();\n }\n\n dotsT.attr(\"cx\", function (d) {\n return plot.x.map(d, subplot.x);\n }).attr(\"cy\", function (d) {\n return plot.y.map(d, subplot.y);\n }).attr(\"r\", self.config.dot.radius);\n\n if (plot.dot.color) {\n dotsT.style(\"fill\", plot.dot.color);\n }\n\n if (plot.tooltip) {\n dots.on(\"mouseover\", function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = \"(\" + plot.x.value(d, subplot.x) + \", \" + plot.y.value(d, subplot.y) + \")\";\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n\n var group = self.config.groups.value(d);\n if (group || group === 0) {\n html += \"
\";\n var label = self.config.groups.label;\n if (label) {\n html += label + \": \";\n }\n html += group;\n }\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n }).on(\"mouseout\", function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n\n dots.exit().remove();\n };\n p.update();\n }\n\n this.updateLegend();\n }\n }, {\n key: \"drawBrush\",\n value: function drawBrush(cell) {\n var self = this;\n var brush = d3.svg.brush().x(self.plot.x.scale).y(self.plot.y.scale).on(\"brushstart\", brushstart).on(\"brush\", brushmove).on(\"brushend\", brushend);\n\n cell.append(\"g\").call(brush);\n\n var brushCell;\n\n // Clear the previously-active brush, if any.\n function brushstart(p) {\n if (brushCell !== this) {\n d3.select(brushCell).call(brush.clear());\n self.plot.x.scale.domain(self.plot.domainByVariable[p.x]);\n self.plot.y.scale.domain(self.plot.domainByVariable[p.y]);\n brushCell = this;\n }\n }\n\n // Highlight the selected circles.\n function brushmove(p) {\n var e = brush.extent();\n self.svgG.selectAll(\"circle\").classed(\"hidden\", function (d) {\n return e[0][0] > d[p.x] || d[p.x] > e[1][0] || e[0][1] > d[p.y] || d[p.y] > e[1][1];\n });\n }\n // If the brush is empty, select all circles.\n function brushend() {\n if (brush.empty()) self.svgG.selectAll(\".hidden\").classed(\"hidden\", false);\n }\n }\n }, {\n key: \"updateLegend\",\n value: function updateLegend() {\n\n var self = this;\n var plot = this.plot;\n\n var scale = plot.dot.colorCategory;\n\n if (!scale.domain() || scale.domain().length < 2) {\n plot.showLegend = false;\n }\n\n if (!plot.showLegend) {\n if (plot.legend && plot.legend.container) {\n plot.legend.container.remove();\n }\n return;\n }\n\n var legendX = this.plot.width + this.config.legend.margin;\n var legendY = this.config.legend.margin;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY);\n\n plot.legendColor = plot.legend.color().shapeWidth(this.config.legend.shapeWidth).orient('vertical').scale(scale);\n\n plot.legendColor.on('cellclick', function (c) {\n return self.onLegendCellClick(c);\n });\n\n plot.legend.container.call(plot.legendColor);\n }\n }, {\n key: \"onLegendCellClick\",\n value: function onLegendCellClick(cellValue) {\n this.updateEnabledGroups(cellValue);\n\n var isDisabled = this.enabledGroups.indexOf(cellValue) < 0;\n this.plot.legend.container.selectAll(\"g.cell\").each(function (cell) {\n if (cell == cellValue) {\n d3.select(this).classed(\"odc-disabled\", isDisabled);\n }\n });\n\n this.init();\n }\n }, {\n key: \"updateEnabledGroups\",\n value: function updateEnabledGroups(cellValue) {\n if (!this.enabledGroups) {\n this.enabledGroups = this.plot.dot.colorCategory.domain().slice();\n }\n var index = this.enabledGroups.indexOf(cellValue);\n\n if (index < 0) {\n this.enabledGroups.push(cellValue);\n } else {\n this.enabledGroups.splice(index, 1);\n }\n }\n }, {\n key: \"setData\",\n value: function setData(data) {\n _get(Object.getPrototypeOf(ScatterPlotMatrix.prototype), \"setData\", this).call(this, data);\n this.enabledGroups = null;\n }\n }]);\n\n return ScatterPlotMatrix;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./scatterplot\":30,\"./utils\":33}],30:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ScatterPlot = exports.ScatterPlotConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _utils = require(\"./utils\");\n\nvar _legend = require(\"./legend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar ScatterPlotConfig = exports.ScatterPlotConfig = function (_ChartConfig) {\n _inherits(ScatterPlotConfig, _ChartConfig);\n\n //show axis guides\n\n function ScatterPlotConfig(custom) {\n _classCallCheck(this, ScatterPlotConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ScatterPlotConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'scatterplot';\n _this.guides = false;\n _this.showTooltip = true;\n _this.showLegend = true;\n _this.legend = {\n width: 80,\n margin: 10,\n shapeWidth: 20\n };\n _this.x = { // X axis config\n label: 'X', // axis label\n key: 0,\n value: function value(d, key) {\n return d[key];\n }, // x value accessor\n orient: \"bottom\",\n scale: \"linear\"\n };\n _this.y = { // Y axis config\n label: 'Y', // axis label,\n key: 1,\n value: function value(d, key) {\n return d[key];\n }, // y value accessor\n orient: \"left\",\n scale: \"linear\"\n };\n _this.groups = {\n key: 2,\n value: function value(d, key) {\n return d[key];\n }, // grouping value accessor,\n label: \"\"\n };\n _this.dot = {\n radius: 2,\n color: function color(d) {\n return _this.groups.value(d, _this.groups.key);\n }, // string or function returning color's value for color scale\n d3ColorCategory: 'category10'\n };\n _this.transition = true;\n\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n } //show tooltip on dot hover\n\n\n return ScatterPlotConfig;\n}(_chart.ChartConfig);\n\nvar ScatterPlot = exports.ScatterPlot = function (_Chart) {\n _inherits(ScatterPlot, _Chart);\n\n function ScatterPlot(placeholderSelector, data, config) {\n _classCallCheck(this, ScatterPlot);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(ScatterPlot).call(this, placeholderSelector, data, new ScatterPlotConfig(config)));\n }\n\n _createClass(ScatterPlot, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(ScatterPlot.prototype), \"setConfig\", this).call(this, new ScatterPlotConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(ScatterPlot.prototype), \"initPlot\", this).call(this);\n var self = this;\n\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.y = {};\n this.plot.dot = {\n color: null //color scale mapping function\n };\n\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n this.plot.margin.right = conf.margin.right + conf.legend.width + conf.legend.margin * 2;\n }\n\n this.computePlotSize();\n\n this.setupGroups();\n\n this.plot.data = this.getDataToPlot();\n this.setupX();\n this.setupY();\n\n return this;\n }\n }, {\n key: \"setupGroups\",\n value: function setupGroups() {\n var self = this;\n var conf = this.config;\n this.plot.groupValue = function (d) {\n return conf.groups.value(d, conf.groups.key);\n };\n if (conf.dot.d3ColorCategory) {\n this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();\n }\n var colorValue = conf.dot.color;\n if (colorValue) {\n this.plot.dot.colorValue = colorValue;\n\n if (typeof colorValue === 'string' || colorValue instanceof String) {\n this.plot.dot.color = colorValue;\n } else if (this.plot.dot.colorCategory) {\n var domain = Object.getOwnPropertyNames(d3.map(this.data, function (d) {\n return self.plot.dot.colorValue.call(self, d);\n })['_']);\n self.plot.dot.colorCategory.domain(domain);\n this.plot.dot.color = function (d) {\n return self.plot.dot.colorCategory(self.plot.dot.colorValue.call(self, d));\n };\n }\n }\n }\n }, {\n key: \"getDataToPlot\",\n value: function getDataToPlot() {\n var _this3 = this;\n\n if (!this.enabledGroups) {\n return this.data;\n }\n\n return this.data.filter(function (d) {\n return _this3.enabledGroups.indexOf(_this3.plot.groupValue(d)) > -1;\n });\n }\n }, {\n key: \"setupX\",\n value: function setupX() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config.x;\n\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\n x.value = function (d) {\n return conf.value(d, conf.key);\n };\n x.scale = d3.scale[conf.scale]().range([0, plot.width]);\n x.map = function (d) {\n return x.scale(x.value(d));\n };\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\n var data = this.plot.data;\n plot.x.scale.domain([d3.min(data, plot.x.value) - 1, d3.max(data, plot.x.value) + 1]);\n if (this.config.guides) {\n x.axis.tickSize(-plot.height);\n }\n }\n }, {\n key: \"setupY\",\n value: function setupY() {\n\n var plot = this.plot;\n var y = plot.y;\n var conf = this.config.y;\n\n /*\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n */\n y.value = function (d) {\n return conf.value(d, conf.key);\n };\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\n y.map = function (d) {\n return y.scale(y.value(d));\n };\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\n\n if (this.config.guides) {\n y.axis.tickSize(-plot.width);\n }\n\n var data = this.plot.data;\n plot.y.scale.domain([d3.min(data, plot.y.value) - 1, d3.max(data, plot.y.value) + 1]);\n }\n }, {\n key: \"drawAxisX\",\n value: function drawAxisX() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.x;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides'))).attr(\"transform\", \"translate(0,\" + plot.height + \")\");\n\n var axisT = axis;\n if (self.transitionEnabled()) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.x.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + plot.width / 2 + \",\" + plot.margin.bottom + \")\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"-1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawAxisY\",\n value: function drawAxisY() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.y;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides')));\n\n var axisT = axis;\n if (self.transitionEnabled()) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.y.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + plot.height / 2 + \")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(ScatterPlot.prototype), \"update\", this).call(this, newData);\n this.drawAxisX();\n this.drawAxisY();\n\n this.updateDots();\n\n this.updateLegend();\n }\n }, {\n key: \"updateDots\",\n value: function updateDots() {\n var self = this;\n var plot = self.plot;\n var data = plot.data;\n var dotClass = self.prefixClass('dot');\n self.dotsContainerClass = self.prefixClass('dots-container');\n\n var dotsContainer = self.svgG.selectOrAppend(\"g.\" + self.dotsContainerClass);\n\n var dots = dotsContainer.selectAll('.' + dotClass).data(data);\n\n dots.enter().append(\"circle\").attr(\"class\", dotClass);\n\n var dotsT = dots;\n if (self.transitionEnabled()) {\n dotsT = dots.transition();\n }\n\n dotsT.attr(\"r\", self.config.dot.radius).attr(\"cx\", plot.x.map).attr(\"cy\", plot.y.map);\n\n if (plot.tooltip) {\n dots.on(\"mouseover\", function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = \"(\" + plot.x.value(d) + \", \" + plot.y.value(d) + \")\";\n var group = self.config.groups.value(d, self.config.groups.key);\n if (group || group === 0) {\n html += \"
\";\n var label = self.config.groups.label;\n if (label) {\n html += label + \": \";\n }\n html += group;\n }\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n }).on(\"mouseout\", function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n\n if (plot.dot.color) {\n dots.style(\"fill\", plot.dot.color);\n }\n\n dots.exit().remove();\n }\n }, {\n key: \"updateLegend\",\n value: function updateLegend() {\n\n var self = this;\n var plot = this.plot;\n\n var scale = plot.dot.colorCategory;\n\n if (!scale.domain() || scale.domain().length < 2) {\n plot.showLegend = false;\n }\n\n if (!plot.showLegend) {\n if (plot.legend && plot.legend.container) {\n plot.legend.container.remove();\n }\n return;\n }\n\n var legendX = this.plot.width + this.config.legend.margin;\n var legendY = this.config.legend.margin;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY);\n\n plot.legendColor = plot.legend.color().shapeWidth(this.config.legend.shapeWidth).orient('vertical').scale(scale);\n\n plot.legendColor.on('cellclick', function (c) {\n return self.onLegendCellClick(c);\n });\n\n plot.legend.container.call(plot.legendColor);\n }\n }, {\n key: \"onLegendCellClick\",\n value: function onLegendCellClick(cellValue) {\n this.updateEnabledGroups(cellValue);\n\n var isDisabled = this.enabledGroups.indexOf(cellValue) < 0;\n this.plot.legend.container.selectAll(\"g.cell\").each(function (cell) {\n if (cell == cellValue) {\n d3.select(this).classed(\"odc-disabled\", isDisabled);\n }\n });\n\n this.init();\n }\n }, {\n key: \"updateEnabledGroups\",\n value: function updateEnabledGroups(cellValue) {\n if (!this.enabledGroups) {\n this.enabledGroups = this.plot.dot.colorCategory.domain().slice();\n }\n var index = this.enabledGroups.indexOf(cellValue);\n\n if (index < 0) {\n this.enabledGroups.push(cellValue);\n } else {\n this.enabledGroups.splice(index, 1);\n }\n }\n }, {\n key: \"setData\",\n value: function setData(data) {\n _get(Object.getPrototypeOf(ScatterPlot.prototype), \"setData\", this).call(this, data);\n this.enabledGroups = null;\n }\n }]);\n\n return ScatterPlot;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./utils\":33}],31:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports.tdistr = tdistr;\n/*\n * https://gist.github.com/benrasmusen/1261977\n * NAME\n * \n * statistics-distributions.js - JavaScript library for calculating\n * critical values and upper probabilities of common statistical\n * distributions\n * \n * SYNOPSIS\n * \n * \n * // Chi-squared-crit (2 degrees of freedom, 95th percentile = 0.05 level\n * chisqrdistr(2, .05)\n * \n * // u-crit (95th percentile = 0.05 level)\n * udistr(.05);\n * \n * // t-crit (1 degree of freedom, 99.5th percentile = 0.005 level) \n * tdistr(1,.005);\n * \n * // F-crit (1 degree of freedom in numerator, 3 degrees of freedom \n * // in denominator, 99th percentile = 0.01 level)\n * fdistr(1,3,.01);\n * \n * // upper probability of the u distribution (u = -0.85): Q(u) = 1-G(u)\n * uprob(-0.85);\n * \n * // upper probability of the chi-square distribution\n * // (3 degrees of freedom, chi-squared = 6.25): Q = 1-G\n * chisqrprob(3,6.25);\n * \n * // upper probability of the t distribution\n * // (3 degrees of freedom, t = 6.251): Q = 1-G\n * tprob(3,6.251);\n * \n * // upper probability of the F distribution\n * // (3 degrees of freedom in numerator, 5 degrees of freedom in\n * // denominator, F = 6.25): Q = 1-G\n * fprob(3,5,.625);\n * \n * \n * DESCRIPTION\n * \n * This library calculates percentage points (5 significant digits) of the u\n * (standard normal) distribution, the student's t distribution, the\n * chi-square distribution and the F distribution. It can also calculate the\n * upper probability (5 significant digits) of the u (standard normal), the\n * chi-square, the t and the F distribution.\n * \n * These critical values are needed to perform statistical tests, like the u\n * test, the t test, the F test and the chi-squared test, and to calculate\n * confidence intervals.\n * \n * If you are interested in more precise algorithms you could look at:\n * StatLib: http://lib.stat.cmu.edu/apstat/ ; \n * Applied Statistics Algorithms by Griffiths, P. and Hill, I.D.\n * , Ellis Horwood: Chichester (1985)\n * \n * BUGS \n * \n * This port was produced from the Perl module Statistics::Distributions\n * that has had no bug reports in several years. If you find a bug then\n * please double-check that JavaScript does not thing the numbers you are\n * passing in are strings. (You can subtract 0 from them as you pass them\n * in so that \"5\" is properly understood to be 5.) If you have passed in a\n * number then please contact the author\n * \n * AUTHOR\n * \n * Ben Tilly \n * \n * Originl Perl version by Michael Kospach \n * \n * Nice formating, simplification and bug repair by Matthias Trautner Kromann\n * \n * \n * COPYRIGHT \n * \n * Copyright 2008 Ben Tilly.\n * \n * This library is free software; you can redistribute it and/or modify it\n * under the same terms as Perl itself. This means under either the Perl\n * Artistic License or the GPL v1 or later.\n */\n\nvar SIGNIFICANT = 5; // number of significant digits to be returned\n\nfunction chisqrdistr($n, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* degree of freedom */\n\t}\n\tif ($p <= 0 || $p > 1) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\treturn precision_string(_subchisqr($n - 0, $p - 0));\n}\n\nfunction udistr($p) {\n\tif ($p > 1 || $p <= 0) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\treturn precision_string(_subu($p - 0));\n}\n\nfunction tdistr($n, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\";\n\t}\n\tif ($p <= 0 || $p >= 1) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\treturn precision_string(_subt($n - 0, $p - 0));\n}\n\nfunction fdistr($n, $m, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* first degree of freedom */\n\t}\n\tif ($m <= 0 || Math.abs($m) - Math.abs(integer($m)) != 0) {\n\t\tthrow \"Invalid m: $m\\n\"; /* second degree of freedom */\n\t}\n\tif ($p <= 0 || $p > 1) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\treturn precision_string(_subf($n - 0, $m - 0, $p - 0));\n}\n\nfunction uprob($x) {\n\treturn precision_string(_subuprob($x - 0));\n}\n\nfunction chisqrprob($n, $x) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* degree of freedom */\n\t}\n\treturn precision_string(_subchisqrprob($n - 0, $x - 0));\n}\n\nfunction tprob($n, $x) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* degree of freedom */\n\t}\n\treturn precision_string(_subtprob($n - 0, $x - 0));\n}\n\nfunction fprob($n, $m, $x) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* first degree of freedom */\n\t}\n\tif ($m <= 0 || Math.abs($m) - Math.abs(integer($m)) != 0) {\n\t\tthrow \"Invalid m: $m\\n\"; /* second degree of freedom */\n\t}\n\treturn precision_string(_subfprob($n - 0, $m - 0, $x - 0));\n}\n\nfunction _subfprob($n, $m, $x) {\n\tvar $p;\n\n\tif ($x <= 0) {\n\t\t$p = 1;\n\t} else if ($m % 2 == 0) {\n\t\tvar $z = $m / ($m + $n * $x);\n\t\tvar $a = 1;\n\t\tfor (var $i = $m - 2; $i >= 2; $i -= 2) {\n\t\t\t$a = 1 + ($n + $i - 2) / $i * $z * $a;\n\t\t}\n\t\t$p = 1 - Math.pow(1 - $z, $n / 2 * $a);\n\t} else if ($n % 2 == 0) {\n\t\tvar $z = $n * $x / ($m + $n * $x);\n\t\tvar $a = 1;\n\t\tfor (var $i = $n - 2; $i >= 2; $i -= 2) {\n\t\t\t$a = 1 + ($m + $i - 2) / $i * $z * $a;\n\t\t}\n\t\t$p = Math.pow(1 - $z, $m / 2) * $a;\n\t} else {\n\t\tvar $y = Math.atan2(Math.sqrt($n * $x / $m), 1);\n\t\tvar $z = Math.pow(Math.sin($y), 2);\n\t\tvar $a = $n == 1 ? 0 : 1;\n\t\tfor (var $i = $n - 2; $i >= 3; $i -= 2) {\n\t\t\t$a = 1 + ($m + $i - 2) / $i * $z * $a;\n\t\t}\n\t\tvar $b = Math.PI;\n\t\tfor (var $i = 2; $i <= $m - 1; $i += 2) {\n\t\t\t$b *= ($i - 1) / $i;\n\t\t}\n\t\tvar $p1 = 2 / $b * Math.sin($y) * Math.pow(Math.cos($y), $m) * $a;\n\n\t\t$z = Math.pow(Math.cos($y), 2);\n\t\t$a = $m == 1 ? 0 : 1;\n\t\tfor (var $i = $m - 2; $i >= 3; $i -= 2) {\n\t\t\t$a = 1 + ($i - 1) / $i * $z * $a;\n\t\t}\n\t\t$p = max(0, $p1 + 1 - 2 * $y / Math.PI - 2 / Math.PI * Math.sin($y) * Math.cos($y) * $a);\n\t}\n\treturn $p;\n}\n\nfunction _subchisqrprob($n, $x) {\n\tvar $p;\n\n\tif ($x <= 0) {\n\t\t$p = 1;\n\t} else if ($n > 100) {\n\t\t$p = _subuprob((Math.pow($x / $n, 1 / 3) - (1 - 2 / 9 / $n)) / Math.sqrt(2 / 9 / $n));\n\t} else if ($x > 400) {\n\t\t$p = 0;\n\t} else {\n\t\tvar $a;\n\t\tvar $i;\n\t\tvar $i1;\n\t\tif ($n % 2 != 0) {\n\t\t\t$p = 2 * _subuprob(Math.sqrt($x));\n\t\t\t$a = Math.sqrt(2 / Math.PI) * Math.exp(-$x / 2) / Math.sqrt($x);\n\t\t\t$i1 = 1;\n\t\t} else {\n\t\t\t$p = $a = Math.exp(-$x / 2);\n\t\t\t$i1 = 2;\n\t\t}\n\n\t\tfor ($i = $i1; $i <= $n - 2; $i += 2) {\n\t\t\t$a *= $x / $i;\n\t\t\t$p += $a;\n\t\t}\n\t}\n\treturn $p;\n}\n\nfunction _subu($p) {\n\tvar $y = -Math.log(4 * $p * (1 - $p));\n\tvar $x = Math.sqrt($y * (1.570796288 + $y * (.03706987906 + $y * (-.8364353589E-3 + $y * (-.2250947176E-3 + $y * (.6841218299E-5 + $y * (0.5824238515E-5 + $y * (-.104527497E-5 + $y * (.8360937017E-7 + $y * (-.3231081277E-8 + $y * (.3657763036E-10 + $y * .6936233982E-12)))))))))));\n\tif ($p > .5) $x = -$x;\n\treturn $x;\n}\n\nfunction _subuprob($x) {\n\tvar $p = 0; /* if ($absx > 100) */\n\tvar $absx = Math.abs($x);\n\n\tif ($absx < 1.9) {\n\t\t$p = Math.pow(1 + $absx * (.049867347 + $absx * (.0211410061 + $absx * (.0032776263 + $absx * (.0000380036 + $absx * (.0000488906 + $absx * .000005383))))), -16) / 2;\n\t} else if ($absx <= 100) {\n\t\tfor (var $i = 18; $i >= 1; $i--) {\n\t\t\t$p = $i / ($absx + $p);\n\t\t}\n\t\t$p = Math.exp(-.5 * $absx * $absx) / Math.sqrt(2 * Math.PI) / ($absx + $p);\n\t}\n\n\tif ($x < 0) $p = 1 - $p;\n\treturn $p;\n}\n\nfunction _subt($n, $p) {\n\n\tif ($p >= 1 || $p <= 0) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\n\tif ($p == 0.5) {\n\t\treturn 0;\n\t} else if ($p < 0.5) {\n\t\treturn -_subt($n, 1 - $p);\n\t}\n\n\tvar $u = _subu($p);\n\tvar $u2 = Math.pow($u, 2);\n\n\tvar $a = ($u2 + 1) / 4;\n\tvar $b = ((5 * $u2 + 16) * $u2 + 3) / 96;\n\tvar $c = (((3 * $u2 + 19) * $u2 + 17) * $u2 - 15) / 384;\n\tvar $d = ((((79 * $u2 + 776) * $u2 + 1482) * $u2 - 1920) * $u2 - 945) / 92160;\n\tvar $e = (((((27 * $u2 + 339) * $u2 + 930) * $u2 - 1782) * $u2 - 765) * $u2 + 17955) / 368640;\n\n\tvar $x = $u * (1 + ($a + ($b + ($c + ($d + $e / $n) / $n) / $n) / $n) / $n);\n\n\tif ($n <= Math.pow(log10($p), 2) + 3) {\n\t\tvar $round;\n\t\tdo {\n\t\t\tvar $p1 = _subtprob($n, $x);\n\t\t\tvar $n1 = $n + 1;\n\t\t\tvar $delta = ($p1 - $p) / Math.exp(($n1 * Math.log($n1 / ($n + $x * $x)) + Math.log($n / $n1 / 2 / Math.PI) - 1 + (1 / $n1 - 1 / $n) / 6) / 2);\n\t\t\t$x += $delta;\n\t\t\t$round = round_to_precision($delta, Math.abs(integer(log10(Math.abs($x)) - 4)));\n\t\t} while ($x && $round != 0);\n\t}\n\treturn $x;\n}\n\nfunction _subtprob($n, $x) {\n\n\tvar $a;\n\tvar $b;\n\tvar $w = Math.atan2($x / Math.sqrt($n), 1);\n\tvar $z = Math.pow(Math.cos($w), 2);\n\tvar $y = 1;\n\n\tfor (var $i = $n - 2; $i >= 2; $i -= 2) {\n\t\t$y = 1 + ($i - 1) / $i * $z * $y;\n\t}\n\n\tif ($n % 2 == 0) {\n\t\t$a = Math.sin($w) / 2;\n\t\t$b = .5;\n\t} else {\n\t\t$a = $n == 1 ? 0 : Math.sin($w) * Math.cos($w) / Math.PI;\n\t\t$b = .5 + $w / Math.PI;\n\t}\n\treturn max(0, 1 - $b - $a * $y);\n}\n\nfunction _subf($n, $m, $p) {\n\tvar $x;\n\n\tif ($p >= 1 || $p <= 0) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\n\tif ($p == 1) {\n\t\t$x = 0;\n\t} else if ($m == 1) {\n\t\t$x = 1 / Math.pow(_subt($n, 0.5 - $p / 2), 2);\n\t} else if ($n == 1) {\n\t\t$x = Math.pow(_subt($m, $p / 2), 2);\n\t} else if ($m == 2) {\n\t\tvar $u = _subchisqr($m, 1 - $p);\n\t\tvar $a = $m - 2;\n\t\t$x = 1 / ($u / $m * (1 + (($u - $a) / 2 + (((4 * $u - 11 * $a) * $u + $a * (7 * $m - 10)) / 24 + (((2 * $u - 10 * $a) * $u + $a * (17 * $m - 26)) * $u - $a * $a * (9 * $m - 6)) / 48 / $n) / $n) / $n));\n\t} else if ($n > $m) {\n\t\t$x = 1 / _subf2($m, $n, 1 - $p);\n\t} else {\n\t\t$x = _subf2($n, $m, $p);\n\t}\n\treturn $x;\n}\n\nfunction _subf2($n, $m, $p) {\n\tvar $u = _subchisqr($n, $p);\n\tvar $n2 = $n - 2;\n\tvar $x = $u / $n * (1 + (($u - $n2) / 2 + (((4 * $u - 11 * $n2) * $u + $n2 * (7 * $n - 10)) / 24 + (((2 * $u - 10 * $n2) * $u + $n2 * (17 * $n - 26)) * $u - $n2 * $n2 * (9 * $n - 6)) / 48 / $m) / $m) / $m);\n\tvar $delta;\n\tdo {\n\t\tvar $z = Math.exp((($n + $m) * Math.log(($n + $m) / ($n * $x + $m)) + ($n - 2) * Math.log($x) + Math.log($n * $m / ($n + $m)) - Math.log(4 * Math.PI) - (1 / $n + 1 / $m - 1 / ($n + $m)) / 6) / 2);\n\t\t$delta = (_subfprob($n, $m, $x) - $p) / $z;\n\t\t$x += $delta;\n\t} while (Math.abs($delta) > 3e-4);\n\treturn $x;\n}\n\nfunction _subchisqr($n, $p) {\n\tvar $x;\n\n\tif ($p > 1 || $p <= 0) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t} else if ($p == 1) {\n\t\t$x = 0;\n\t} else if ($n == 1) {\n\t\t$x = Math.pow(_subu($p / 2), 2);\n\t} else if ($n == 2) {\n\t\t$x = -2 * Math.log($p);\n\t} else {\n\t\tvar $u = _subu($p);\n\t\tvar $u2 = $u * $u;\n\n\t\t$x = max(0, $n + Math.sqrt(2 * $n) * $u + 2 / 3 * ($u2 - 1) + $u * ($u2 - 7) / 9 / Math.sqrt(2 * $n) - 2 / 405 / $n * ($u2 * (3 * $u2 + 7) - 16));\n\n\t\tif ($n <= 100) {\n\t\t\tvar $x0;\n\t\t\tvar $p1;\n\t\t\tvar $z;\n\t\t\tdo {\n\t\t\t\t$x0 = $x;\n\t\t\t\tif ($x < 0) {\n\t\t\t\t\t$p1 = 1;\n\t\t\t\t} else if ($n > 100) {\n\t\t\t\t\t$p1 = _subuprob((Math.pow($x / $n, 1 / 3) - (1 - 2 / 9 / $n)) / Math.sqrt(2 / 9 / $n));\n\t\t\t\t} else if ($x > 400) {\n\t\t\t\t\t$p1 = 0;\n\t\t\t\t} else {\n\t\t\t\t\tvar $i0;\n\t\t\t\t\tvar $a;\n\t\t\t\t\tif ($n % 2 != 0) {\n\t\t\t\t\t\t$p1 = 2 * _subuprob(Math.sqrt($x));\n\t\t\t\t\t\t$a = Math.sqrt(2 / Math.PI) * Math.exp(-$x / 2) / Math.sqrt($x);\n\t\t\t\t\t\t$i0 = 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$p1 = $a = Math.exp(-$x / 2);\n\t\t\t\t\t\t$i0 = 2;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (var $i = $i0; $i <= $n - 2; $i += 2) {\n\t\t\t\t\t\t$a *= $x / $i;\n\t\t\t\t\t\t$p1 += $a;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$z = Math.exp((($n - 1) * Math.log($x / $n) - Math.log(4 * Math.PI * $x) + $n - $x - 1 / $n / 6) / 2);\n\t\t\t\t$x += ($p1 - $p) / $z;\n\t\t\t\t$x = round_to_precision($x, 5);\n\t\t\t} while ($n < 31 && Math.abs($x0 - $x) > 1e-4);\n\t\t}\n\t}\n\treturn $x;\n}\n\nfunction log10($n) {\n\treturn Math.log($n) / Math.log(10);\n}\n\nfunction max() {\n\tvar $max = arguments[0];\n\tfor (var $i = 0; i < arguments.length; i++) {\n\t\tif ($max < arguments[$i]) $max = arguments[$i];\n\t}\n\treturn $max;\n}\n\nfunction min() {\n\tvar $min = arguments[0];\n\tfor (var $i = 0; i < arguments.length; i++) {\n\t\tif ($min > arguments[$i]) $min = arguments[$i];\n\t}\n\treturn $min;\n}\n\nfunction precision($x) {\n\treturn Math.abs(integer(log10(Math.abs($x)) - SIGNIFICANT));\n}\n\nfunction precision_string($x) {\n\tif ($x) {\n\t\treturn round_to_precision($x, precision($x));\n\t} else {\n\t\treturn \"0\";\n\t}\n}\n\nfunction round_to_precision($x, $p) {\n\t$x = $x * Math.pow(10, $p);\n\t$x = Math.round($x);\n\treturn $x / Math.pow(10, $p);\n}\n\nfunction integer($i) {\n\tif ($i > 0) return Math.floor($i);else return Math.ceil($i);\n}\n\n},{}],32:[function(require,module,exports){\n'use strict';\n\nvar _statisticsDistributions = require('./statistics-distributions');\n\nvar su = module.exports.StatisticsUtils = {};\nsu.sampleCorrelation = require('../bower_components/simple-statistics/src/sample_correlation');\nsu.linearRegression = require('../bower_components/simple-statistics/src/linear_regression');\nsu.linearRegressionLine = require('../bower_components/simple-statistics/src/linear_regression_line');\nsu.errorFunction = require('../bower_components/simple-statistics/src/error_function');\nsu.standardDeviation = require('../bower_components/simple-statistics/src/standard_deviation');\nsu.sampleStandardDeviation = require('../bower_components/simple-statistics/src/sample_standard_deviation');\nsu.variance = require('../bower_components/simple-statistics/src/variance');\nsu.mean = require('../bower_components/simple-statistics/src/mean');\nsu.zScore = require('../bower_components/simple-statistics/src/z_score');\nsu.standardError = function (arr) {\n return Math.sqrt(su.variance(arr) / (arr.length - 1));\n};\n\nsu.tValue = function (degreesOfFreedom, criticalProbability) {\n //as in http://stattrek.com/online-calculator/t-distribution.aspx\n return (0, _statisticsDistributions.tdistr)(degreesOfFreedom, criticalProbability);\n};\n\n},{\"../bower_components/simple-statistics/src/error_function\":6,\"../bower_components/simple-statistics/src/linear_regression\":7,\"../bower_components/simple-statistics/src/linear_regression_line\":8,\"../bower_components/simple-statistics/src/mean\":9,\"../bower_components/simple-statistics/src/sample_correlation\":10,\"../bower_components/simple-statistics/src/sample_standard_deviation\":12,\"../bower_components/simple-statistics/src/standard_deviation\":14,\"../bower_components/simple-statistics/src/variance\":17,\"../bower_components/simple-statistics/src/z_score\":18,\"./statistics-distributions\":31}],33:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\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\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Utils = exports.Utils = function () {\n function Utils() {\n _classCallCheck(this, Utils);\n }\n\n _createClass(Utils, null, [{\n key: 'deepExtend',\n\n // usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB);\n value: function deepExtend(out) {\n\n var utils = this;\n var emptyOut = {};\n\n if (!out && arguments.length > 1 && Array.isArray(arguments[1])) {\n out = [];\n }\n out = out || {};\n\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n if (!source) continue;\n\n for (var key in source) {\n if (!source.hasOwnProperty(key)) {\n continue;\n }\n var isArray = Array.isArray(out[key]);\n var isObject = utils.isObject(out[key]);\n var srcObj = utils.isObject(source[key]);\n\n if (isObject && !isArray && srcObj) {\n utils.deepExtend(out[key], source[key]);\n } else {\n out[key] = source[key];\n }\n }\n }\n\n return out;\n }\n }, {\n key: 'mergeDeep',\n value: function mergeDeep(target, source) {\n var output = Object.assign({}, target);\n if (Utils.isObjectNotArray(target) && Utils.isObjectNotArray(source)) {\n Object.keys(source).forEach(function (key) {\n if (Utils.isObjectNotArray(source[key])) {\n if (!(key in target)) Object.assign(output, _defineProperty({}, key, source[key]));else output[key] = Utils.mergeDeep(target[key], source[key]);\n } else {\n Object.assign(output, _defineProperty({}, key, source[key]));\n }\n });\n }\n return output;\n }\n }, {\n key: 'cross',\n value: function cross(a, b) {\n var c = [],\n n = a.length,\n m = b.length,\n i,\n j;\n for (i = -1; ++i < n;) {\n for (j = -1; ++j < m;) {\n c.push({ x: a[i], i: i, y: b[j], j: j });\n }\n }return c;\n }\n }, {\n key: 'inferVariables',\n value: function inferVariables(data, groupKey, includeGroup) {\n var res = [];\n if (data.length) {\n var d = data[0];\n if (d instanceof Array) {\n res = d.map(function (v, i) {\n return i;\n });\n } else if ((typeof d === 'undefined' ? 'undefined' : _typeof(d)) === 'object') {\n\n for (var prop in d) {\n if (!d.hasOwnProperty(prop)) continue;\n\n res.push(prop);\n }\n }\n }\n if (!includeGroup) {\n var index = res.indexOf(groupKey);\n if (index > -1) {\n res.splice(index, 1);\n }\n }\n return res;\n }\n }, {\n key: 'isObjectNotArray',\n value: function isObjectNotArray(item) {\n return item && (typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object' && !Array.isArray(item) && item !== null;\n }\n }, {\n key: 'isObject',\n value: function isObject(a) {\n return a !== null && (typeof a === 'undefined' ? 'undefined' : _typeof(a)) === 'object';\n }\n }, {\n key: 'isNumber',\n value: function isNumber(a) {\n return !isNaN(a) && typeof a === 'number';\n }\n }, {\n key: 'isFunction',\n value: function isFunction(a) {\n return typeof a === 'function';\n }\n }, {\n key: 'isDate',\n value: function isDate(a) {\n return Object.prototype.toString.call(a) === '[object Date]';\n }\n }, {\n key: 'isString',\n value: function isString(a) {\n return typeof a === 'string' || a instanceof String;\n }\n }, {\n key: 'insertOrAppendSelector',\n value: function insertOrAppendSelector(parent, selector, operation, before) {\n var selectorParts = selector.split(/([\\.\\#])/);\n var element = parent[operation](selectorParts.shift(), before); //\":first-child\"\n while (selectorParts.length > 1) {\n var selectorModifier = selectorParts.shift();\n var selectorItem = selectorParts.shift();\n if (selectorModifier === \".\") {\n element = element.classed(selectorItem, true);\n } else if (selectorModifier === \"#\") {\n element = element.attr('id', selectorItem);\n }\n }\n return element;\n }\n }, {\n key: 'insertSelector',\n value: function insertSelector(parent, selector, before) {\n return Utils.insertOrAppendSelector(parent, selector, \"insert\", before);\n }\n }, {\n key: 'appendSelector',\n value: function appendSelector(parent, selector) {\n return Utils.insertOrAppendSelector(parent, selector, \"append\");\n }\n }, {\n key: 'selectOrAppend',\n value: function selectOrAppend(parent, selector, element) {\n var selection = parent.select(selector);\n if (selection.empty()) {\n if (element) {\n return parent.append(element);\n }\n return Utils.appendSelector(parent, selector);\n }\n return selection;\n }\n }, {\n key: 'selectOrInsert',\n value: function selectOrInsert(parent, selector, before) {\n var selection = parent.select(selector);\n if (selection.empty()) {\n return Utils.insertSelector(parent, selector, before);\n }\n return selection;\n }\n }, {\n key: 'linearGradient',\n value: function linearGradient(svg, gradientId, range, x1, y1, x2, y2) {\n var defs = Utils.selectOrAppend(svg, \"defs\");\n var linearGradient = defs.append(\"linearGradient\").attr(\"id\", gradientId);\n\n linearGradient.attr(\"x1\", x1 + \"%\").attr(\"y1\", y1 + \"%\").attr(\"x2\", x2 + \"%\").attr(\"y2\", y2 + \"%\");\n\n //Append multiple color stops by using D3's data/enter step\n var stops = linearGradient.selectAll(\"stop\").data(range);\n\n stops.enter().append(\"stop\");\n\n stops.attr(\"offset\", function (d, i) {\n return i / (range.length - 1);\n }).attr(\"stop-color\", function (d) {\n return d;\n });\n\n stops.exit().remove();\n }\n }, {\n key: 'guid',\n value: function guid() {\n function s4() {\n return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);\n }\n\n return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\n }\n\n //places textString in textObj, adds an ellipsis if text can't fit in width\n\n }, {\n key: 'placeTextWithEllipsis',\n value: function placeTextWithEllipsis(textD3Obj, textString, width) {\n var textObj = textD3Obj.node();\n textObj.textContent = textString;\n\n var margin = 0;\n var ellipsisLength = 9;\n //ellipsis is needed\n if (textObj.getComputedTextLength() > width + margin) {\n for (var x = textString.length - 3; x > 0; x -= 1) {\n if (textObj.getSubStringLength(0, x) + ellipsisLength <= width + margin) {\n textObj.textContent = textString.substring(0, x) + \"...\";\n return true;\n }\n }\n textObj.textContent = \"...\"; //can't place at all\n return true;\n }\n return false;\n }\n }, {\n key: 'placeTextWithEllipsisAndTooltip',\n value: function placeTextWithEllipsisAndTooltip(textD3Obj, textString, width, tooltip) {\n var ellipsisPlaced = Utils.placeTextWithEllipsis(textD3Obj, textString, width);\n if (ellipsisPlaced && tooltip) {\n textD3Obj.on(\"mouseover\", function (d) {\n tooltip.transition().duration(200).style(\"opacity\", .9);\n tooltip.html(textString).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n });\n\n textD3Obj.on(\"mouseout\", function (d) {\n tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n }\n }, {\n key: 'getFontSize',\n value: function getFontSize(element) {\n return window.getComputedStyle(element, null).getPropertyValue(\"font-size\");\n }\n }]);\n\n return Utils;\n}();\n\nUtils.SQRT_2 = 1.41421356237;\n\nUtils.sanitizeHeight = function (height, container) {\n return height || parseInt(container.style('height'), 10) || 400;\n};\n\nUtils.sanitizeWidth = function (width, container) {\n return width || parseInt(container.style('width'), 10) || 960;\n};\n\nUtils.availableHeight = function (height, container, margin) {\n return Math.max(0, Utils.sanitizeHeight(height, container) - margin.top - margin.bottom);\n};\n\nUtils.availableWidth = function (width, container, margin) {\n return Math.max(0, Utils.sanitizeWidth(width, container) - margin.left - margin.right);\n};\n\n},{}]},{},[26])(26)\n});\n\n","module.exports = {\r\n color: require('./src/color'),\r\n size: require('./src/size'),\r\n symbol: require('./src/symbol')\r\n};\r\n","var helper = require('./legend');\r\n\r\nmodule.exports = function(){\r\n\r\n var scale = d3.scale.linear(),\r\n shape = \"rect\",\r\n shapeWidth = 15,\r\n shapeHeight = 15,\r\n shapeRadius = 10,\r\n shapePadding = 2,\r\n cells = [5],\r\n labels = [],\r\n classPrefix = \"\",\r\n useClass = false,\r\n title = \"\",\r\n labelFormat = d3.format(\".01f\"),\r\n labelOffset = 10,\r\n labelAlign = \"middle\",\r\n labelDelimiter = \"to\",\r\n orient = \"vertical\",\r\n ascending = false,\r\n path,\r\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\r\n\r\n function legend(svg){\r\n\r\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\r\n legendG = svg.selectAll('g').data([scale]);\r\n\r\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\r\n\r\n\r\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\r\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\r\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\r\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\r\n\r\n //add event handlers\r\n helper.d3_addEvents(cellEnter, legendDispatcher);\r\n\r\n cell.exit().transition().style(\"opacity\", 0).remove();\r\n\r\n helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path);\r\n\r\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix)\r\n\r\n // sets placement\r\n var text = cell.select(\"text\"),\r\n shapeSize = shapes[0].map( function(d){ return d.getBBox(); });\r\n\r\n //sets scale\r\n //everything is fill except for line which is stroke,\r\n if (!useClass){\r\n if (shape == \"line\"){\r\n shapes.style(\"stroke\", type.feature);\r\n } else {\r\n shapes.style(\"fill\", type.feature);\r\n }\r\n } else {\r\n shapes.attr(\"class\", function(d){ return classPrefix + \"swatch \" + type.feature(d); });\r\n }\r\n\r\n var cellTrans,\r\n textTrans,\r\n textAlign = (labelAlign == \"start\") ? 0 : (labelAlign == \"middle\") ? 0.5 : 1;\r\n\r\n //positions cells and text\r\n if (orient === \"vertical\"){\r\n cellTrans = function(d,i) { return \"translate(0, \" + (i * (shapeSize[i].height + shapePadding)) + \")\"; };\r\n textTrans = function(d,i) { return \"translate(\" + (shapeSize[i].width + shapeSize[i].x +\r\n labelOffset) + \",\" + (shapeSize[i].y + shapeSize[i].height/2 + 5) + \")\"; };\r\n\r\n } else if (orient === \"horizontal\"){\r\n cellTrans = function(d,i) { return \"translate(\" + (i * (shapeSize[i].width + shapePadding)) + \",0)\"; }\r\n textTrans = function(d,i) { return \"translate(\" + (shapeSize[i].width*textAlign + shapeSize[i].x) +\r\n \",\" + (shapeSize[i].height + shapeSize[i].y + labelOffset + 8) + \")\"; };\r\n }\r\n\r\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\r\n helper.d3_title(svg, legendG, title, classPrefix);\r\n\r\n cell.transition().style(\"opacity\", 1);\r\n\r\n }\r\n\r\n\r\n\r\n legend.scale = function(_) {\r\n if (!arguments.length) return scale;\r\n scale = _;\r\n return legend;\r\n };\r\n\r\n legend.cells = function(_) {\r\n if (!arguments.length) return cells;\r\n if (_.length > 1 || _ >= 2 ){\r\n cells = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.shape = function(_, d) {\r\n if (!arguments.length) return shape;\r\n if (_ == \"rect\" || _ == \"circle\" || _ == \"line\" || (_ == \"path\" && (typeof d === 'string')) ){\r\n shape = _;\r\n path = d;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.shapeWidth = function(_) {\r\n if (!arguments.length) return shapeWidth;\r\n shapeWidth = +_;\r\n return legend;\r\n };\r\n\r\n legend.shapeHeight = function(_) {\r\n if (!arguments.length) return shapeHeight;\r\n shapeHeight = +_;\r\n return legend;\r\n };\r\n\r\n legend.shapeRadius = function(_) {\r\n if (!arguments.length) return shapeRadius;\r\n shapeRadius = +_;\r\n return legend;\r\n };\r\n\r\n legend.shapePadding = function(_) {\r\n if (!arguments.length) return shapePadding;\r\n shapePadding = +_;\r\n return legend;\r\n };\r\n\r\n legend.labels = function(_) {\r\n if (!arguments.length) return labels;\r\n labels = _;\r\n return legend;\r\n };\r\n\r\n legend.labelAlign = function(_) {\r\n if (!arguments.length) return labelAlign;\r\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\r\n labelAlign = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.labelFormat = function(_) {\r\n if (!arguments.length) return labelFormat;\r\n labelFormat = _;\r\n return legend;\r\n };\r\n\r\n legend.labelOffset = function(_) {\r\n if (!arguments.length) return labelOffset;\r\n labelOffset = +_;\r\n return legend;\r\n };\r\n\r\n legend.labelDelimiter = function(_) {\r\n if (!arguments.length) return labelDelimiter;\r\n labelDelimiter = _;\r\n return legend;\r\n };\r\n\r\n legend.useClass = function(_) {\r\n if (!arguments.length) return useClass;\r\n if (_ === true || _ === false){\r\n useClass = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.orient = function(_){\r\n if (!arguments.length) return orient;\r\n _ = _.toLowerCase();\r\n if (_ == \"horizontal\" || _ == \"vertical\") {\r\n orient = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.ascending = function(_) {\r\n if (!arguments.length) return ascending;\r\n ascending = !!_;\r\n return legend;\r\n };\r\n\r\n legend.classPrefix = function(_) {\r\n if (!arguments.length) return classPrefix;\r\n classPrefix = _;\r\n return legend;\r\n };\r\n\r\n legend.title = function(_) {\r\n if (!arguments.length) return title;\r\n title = _;\r\n return legend;\r\n };\r\n\r\n d3.rebind(legend, legendDispatcher, \"on\");\r\n\r\n return legend;\r\n\r\n};\r\n","module.exports = {\r\n\r\n d3_identity: function (d) {\r\n return d;\r\n },\r\n\r\n d3_mergeLabels: function (gen, labels) {\r\n\r\n if(labels.length === 0) return gen;\r\n\r\n gen = (gen) ? gen : [];\r\n\r\n var i = labels.length;\r\n for (; i < gen.length; i++) {\r\n labels.push(gen[i]);\r\n }\r\n return labels;\r\n },\r\n\r\n d3_linearLegend: function (scale, cells, labelFormat) {\r\n var data = [];\r\n\r\n if (cells.length > 1){\r\n data = cells;\r\n\r\n } else {\r\n var domain = scale.domain(),\r\n increment = (domain[domain.length - 1] - domain[0])/(cells - 1),\r\n i = 0;\r\n\r\n for (; i < cells; i++){\r\n data.push(domain[0] + i*increment);\r\n }\r\n }\r\n\r\n var labels = data.map(labelFormat);\r\n\r\n return {data: data,\r\n labels: labels,\r\n feature: function(d){ return scale(d); }};\r\n },\r\n\r\n d3_quantLegend: function (scale, labelFormat, labelDelimiter) {\r\n var labels = scale.range().map(function(d){\r\n var invert = scale.invertExtent(d),\r\n a = labelFormat(invert[0]),\r\n b = labelFormat(invert[1]);\r\n\r\n // if (( (a) && (a.isNan()) && b){\r\n // console.log(\"in initial statement\")\r\n return labelFormat(invert[0]) + \" \" + labelDelimiter + \" \" + labelFormat(invert[1]);\r\n // } else if (a || b) {\r\n // console.log('in else statement')\r\n // return (a) ? a : b;\r\n // }\r\n\r\n });\r\n\r\n return {data: scale.range(),\r\n labels: labels,\r\n feature: this.d3_identity\r\n };\r\n },\r\n\r\n d3_ordinalLegend: function (scale) {\r\n return {data: scale.domain(),\r\n labels: scale.domain(),\r\n feature: function(d){ return scale(d); }};\r\n },\r\n\r\n d3_drawShapes: function (shape, shapes, shapeHeight, shapeWidth, shapeRadius, path) {\r\n if (shape === \"rect\"){\r\n shapes.attr(\"height\", shapeHeight).attr(\"width\", shapeWidth);\r\n\r\n } else if (shape === \"circle\") {\r\n shapes.attr(\"r\", shapeRadius)//.attr(\"cx\", shapeRadius).attr(\"cy\", shapeRadius);\r\n\r\n } else if (shape === \"line\") {\r\n shapes.attr(\"x1\", 0).attr(\"x2\", shapeWidth).attr(\"y1\", 0).attr(\"y2\", 0);\r\n\r\n } else if (shape === \"path\") {\r\n shapes.attr(\"d\", path);\r\n }\r\n },\r\n\r\n d3_addText: function (svg, enter, labels, classPrefix){\r\n enter.append(\"text\").attr(\"class\", classPrefix + \"label\");\r\n svg.selectAll(\"g.\" + classPrefix + \"cell text\").data(labels).text(this.d3_identity);\r\n },\r\n\r\n d3_calcType: function (scale, ascending, cells, labels, labelFormat, labelDelimiter){\r\n var type = scale.ticks ?\r\n this.d3_linearLegend(scale, cells, labelFormat) : scale.invertExtent ?\r\n this.d3_quantLegend(scale, labelFormat, labelDelimiter) : this.d3_ordinalLegend(scale);\r\n\r\n type.labels = this.d3_mergeLabels(type.labels, labels);\r\n\r\n if (ascending) {\r\n type.labels = this.d3_reverse(type.labels);\r\n type.data = this.d3_reverse(type.data);\r\n }\r\n\r\n return type;\r\n },\r\n\r\n d3_reverse: function(arr) {\r\n var mirror = [];\r\n for (var i = 0, l = arr.length; i < l; i++) {\r\n mirror[i] = arr[l-i-1];\r\n }\r\n return mirror;\r\n },\r\n\r\n d3_placement: function (orient, cell, cellTrans, text, textTrans, labelAlign) {\r\n cell.attr(\"transform\", cellTrans);\r\n text.attr(\"transform\", textTrans);\r\n if (orient === \"horizontal\"){\r\n text.style(\"text-anchor\", labelAlign);\r\n }\r\n },\r\n\r\n d3_addEvents: function(cells, dispatcher){\r\n var _ = this;\r\n\r\n cells.on(\"mouseover.legend\", function (d) { _.d3_cellOver(dispatcher, d, this); })\r\n .on(\"mouseout.legend\", function (d) { _.d3_cellOut(dispatcher, d, this); })\r\n .on(\"click.legend\", function (d) { _.d3_cellClick(dispatcher, d, this); });\r\n },\r\n\r\n d3_cellOver: function(cellDispatcher, d, obj){\r\n cellDispatcher.cellover.call(obj, d);\r\n },\r\n\r\n d3_cellOut: function(cellDispatcher, d, obj){\r\n cellDispatcher.cellout.call(obj, d);\r\n },\r\n\r\n d3_cellClick: function(cellDispatcher, d, obj){\r\n cellDispatcher.cellclick.call(obj, d);\r\n },\r\n\r\n d3_title: function(svg, cellsSvg, title, classPrefix){\r\n if (title !== \"\"){\r\n\r\n var titleText = svg.selectAll('text.' + classPrefix + 'legendTitle');\r\n\r\n titleText.data([title])\r\n .enter()\r\n .append('text')\r\n .attr('class', classPrefix + 'legendTitle');\r\n\r\n svg.selectAll('text.' + classPrefix + 'legendTitle')\r\n .text(title)\r\n\r\n var yOffset = svg.select('.' + classPrefix + 'legendTitle')\r\n .map(function(d) { return d[0].getBBox().height})[0],\r\n xOffset = -cellsSvg.map(function(d) { return d[0].getBBox().x})[0];\r\n\r\n cellsSvg.attr('transform', 'translate(' + xOffset + ',' + (yOffset + 10) + ')');\r\n\r\n }\r\n }\r\n}\r\n","var helper = require('./legend');\r\n\r\nmodule.exports = function(){\r\n\r\n var scale = d3.scale.linear(),\r\n shape = \"rect\",\r\n shapeWidth = 15,\r\n shapePadding = 2,\r\n cells = [5],\r\n labels = [],\r\n useStroke = false,\r\n classPrefix = \"\",\r\n title = \"\",\r\n labelFormat = d3.format(\".01f\"),\r\n labelOffset = 10,\r\n labelAlign = \"middle\",\r\n labelDelimiter = \"to\",\r\n orient = \"vertical\",\r\n ascending = false,\r\n path,\r\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\r\n\r\n function legend(svg){\r\n\r\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\r\n legendG = svg.selectAll('g').data([scale]);\r\n\r\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\r\n\r\n\r\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\r\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\r\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\r\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\r\n\r\n //add event handlers\r\n helper.d3_addEvents(cellEnter, legendDispatcher);\r\n\r\n cell.exit().transition().style(\"opacity\", 0).remove();\r\n\r\n //creates shape\r\n if (shape === \"line\"){\r\n helper.d3_drawShapes(shape, shapes, 0, shapeWidth);\r\n shapes.attr(\"stroke-width\", type.feature);\r\n } else {\r\n helper.d3_drawShapes(shape, shapes, type.feature, type.feature, type.feature, path);\r\n }\r\n\r\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix)\r\n\r\n //sets placement\r\n var text = cell.select(\"text\"),\r\n shapeSize = shapes[0].map(\r\n function(d, i){\r\n var bbox = d.getBBox()\r\n var stroke = scale(type.data[i]);\r\n\r\n if (shape === \"line\" && orient === \"horizontal\") {\r\n bbox.height = bbox.height + stroke;\r\n } else if (shape === \"line\" && orient === \"vertical\"){\r\n bbox.width = bbox.width;\r\n }\r\n\r\n return bbox;\r\n });\r\n\r\n var maxH = d3.max(shapeSize, function(d){ return d.height + d.y; }),\r\n maxW = d3.max(shapeSize, function(d){ return d.width + d.x; });\r\n\r\n var cellTrans,\r\n textTrans,\r\n textAlign = (labelAlign == \"start\") ? 0 : (labelAlign == \"middle\") ? 0.5 : 1;\r\n\r\n //positions cells and text\r\n if (orient === \"vertical\"){\r\n\r\n cellTrans = function(d,i) {\r\n var height = d3.sum(shapeSize.slice(0, i + 1 ), function(d){ return d.height; });\r\n return \"translate(0, \" + (height + i*shapePadding) + \")\"; };\r\n\r\n textTrans = function(d,i) { return \"translate(\" + (maxW + labelOffset) + \",\" +\r\n (shapeSize[i].y + shapeSize[i].height/2 + 5) + \")\"; };\r\n\r\n } else if (orient === \"horizontal\"){\r\n cellTrans = function(d,i) {\r\n var width = d3.sum(shapeSize.slice(0, i + 1 ), function(d){ return d.width; });\r\n return \"translate(\" + (width + i*shapePadding) + \",0)\"; };\r\n\r\n textTrans = function(d,i) { return \"translate(\" + (shapeSize[i].width*textAlign + shapeSize[i].x) + \",\" +\r\n (maxH + labelOffset ) + \")\"; };\r\n }\r\n\r\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\r\n helper.d3_title(svg, legendG, title, classPrefix);\r\n\r\n cell.transition().style(\"opacity\", 1);\r\n\r\n }\r\n\r\n legend.scale = function(_) {\r\n if (!arguments.length) return scale;\r\n scale = _;\r\n return legend;\r\n };\r\n\r\n legend.cells = function(_) {\r\n if (!arguments.length) return cells;\r\n if (_.length > 1 || _ >= 2 ){\r\n cells = _;\r\n }\r\n return legend;\r\n };\r\n\r\n\r\n legend.shape = function(_, d) {\r\n if (!arguments.length) return shape;\r\n if (_ == \"rect\" || _ == \"circle\" || _ == \"line\" ){\r\n shape = _;\r\n path = d;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.shapeWidth = function(_) {\r\n if (!arguments.length) return shapeWidth;\r\n shapeWidth = +_;\r\n return legend;\r\n };\r\n\r\n legend.shapePadding = function(_) {\r\n if (!arguments.length) return shapePadding;\r\n shapePadding = +_;\r\n return legend;\r\n };\r\n\r\n legend.labels = function(_) {\r\n if (!arguments.length) return labels;\r\n labels = _;\r\n return legend;\r\n };\r\n\r\n legend.labelAlign = function(_) {\r\n if (!arguments.length) return labelAlign;\r\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\r\n labelAlign = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.labelFormat = function(_) {\r\n if (!arguments.length) return labelFormat;\r\n labelFormat = _;\r\n return legend;\r\n };\r\n\r\n legend.labelOffset = function(_) {\r\n if (!arguments.length) return labelOffset;\r\n labelOffset = +_;\r\n return legend;\r\n };\r\n\r\n legend.labelDelimiter = function(_) {\r\n if (!arguments.length) return labelDelimiter;\r\n labelDelimiter = _;\r\n return legend;\r\n };\r\n\r\n legend.orient = function(_){\r\n if (!arguments.length) return orient;\r\n _ = _.toLowerCase();\r\n if (_ == \"horizontal\" || _ == \"vertical\") {\r\n orient = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.ascending = function(_) {\r\n if (!arguments.length) return ascending;\r\n ascending = !!_;\r\n return legend;\r\n };\r\n\r\n legend.classPrefix = function(_) {\r\n if (!arguments.length) return classPrefix;\r\n classPrefix = _;\r\n return legend;\r\n };\r\n\r\n legend.title = function(_) {\r\n if (!arguments.length) return title;\r\n title = _;\r\n return legend;\r\n };\r\n\r\n d3.rebind(legend, legendDispatcher, \"on\");\r\n\r\n return legend;\r\n\r\n};\r\n","var helper = require('./legend');\r\n\r\nmodule.exports = function(){\r\n\r\n var scale = d3.scale.linear(),\r\n shape = \"path\",\r\n shapeWidth = 15,\r\n shapeHeight = 15,\r\n shapeRadius = 10,\r\n shapePadding = 5,\r\n cells = [5],\r\n labels = [],\r\n classPrefix = \"\",\r\n useClass = false,\r\n title = \"\",\r\n labelFormat = d3.format(\".01f\"),\r\n labelAlign = \"middle\",\r\n labelOffset = 10,\r\n labelDelimiter = \"to\",\r\n orient = \"vertical\",\r\n ascending = false,\r\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\r\n\r\n function legend(svg){\r\n\r\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\r\n legendG = svg.selectAll('g').data([scale]);\r\n\r\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\r\n\r\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\r\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\r\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\r\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\r\n\r\n //add event handlers\r\n helper.d3_addEvents(cellEnter, legendDispatcher);\r\n\r\n //remove old shapes\r\n cell.exit().transition().style(\"opacity\", 0).remove();\r\n\r\n helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, type.feature);\r\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix)\r\n\r\n // sets placement\r\n var text = cell.select(\"text\"),\r\n shapeSize = shapes[0].map( function(d){ return d.getBBox(); });\r\n\r\n var maxH = d3.max(shapeSize, function(d){ return d.height; }),\r\n maxW = d3.max(shapeSize, function(d){ return d.width; });\r\n\r\n var cellTrans,\r\n textTrans,\r\n textAlign = (labelAlign == \"start\") ? 0 : (labelAlign == \"middle\") ? 0.5 : 1;\r\n\r\n //positions cells and text\r\n if (orient === \"vertical\"){\r\n cellTrans = function(d,i) { return \"translate(0, \" + (i * (maxH + shapePadding)) + \")\"; };\r\n textTrans = function(d,i) { return \"translate(\" + (maxW + labelOffset) + \",\" +\r\n (shapeSize[i].y + shapeSize[i].height/2 + 5) + \")\"; };\r\n\r\n } else if (orient === \"horizontal\"){\r\n cellTrans = function(d,i) { return \"translate(\" + (i * (maxW + shapePadding)) + \",0)\"; };\r\n textTrans = function(d,i) { return \"translate(\" + (shapeSize[i].width*textAlign + shapeSize[i].x) + \",\" +\r\n (maxH + labelOffset ) + \")\"; };\r\n }\r\n\r\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\r\n helper.d3_title(svg, legendG, title, classPrefix);\r\n cell.transition().style(\"opacity\", 1);\r\n\r\n }\r\n\r\n\r\n legend.scale = function(_) {\r\n if (!arguments.length) return scale;\r\n scale = _;\r\n return legend;\r\n };\r\n\r\n legend.cells = function(_) {\r\n if (!arguments.length) return cells;\r\n if (_.length > 1 || _ >= 2 ){\r\n cells = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.shapePadding = function(_) {\r\n if (!arguments.length) return shapePadding;\r\n shapePadding = +_;\r\n return legend;\r\n };\r\n\r\n legend.labels = function(_) {\r\n if (!arguments.length) return labels;\r\n labels = _;\r\n return legend;\r\n };\r\n\r\n legend.labelAlign = function(_) {\r\n if (!arguments.length) return labelAlign;\r\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\r\n labelAlign = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.labelFormat = function(_) {\r\n if (!arguments.length) return labelFormat;\r\n labelFormat = _;\r\n return legend;\r\n };\r\n\r\n legend.labelOffset = function(_) {\r\n if (!arguments.length) return labelOffset;\r\n labelOffset = +_;\r\n return legend;\r\n };\r\n\r\n legend.labelDelimiter = function(_) {\r\n if (!arguments.length) return labelDelimiter;\r\n labelDelimiter = _;\r\n return legend;\r\n };\r\n\r\n legend.orient = function(_){\r\n if (!arguments.length) return orient;\r\n _ = _.toLowerCase();\r\n if (_ == \"horizontal\" || _ == \"vertical\") {\r\n orient = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.ascending = function(_) {\r\n if (!arguments.length) return ascending;\r\n ascending = !!_;\r\n return legend;\r\n };\r\n\r\n legend.classPrefix = function(_) {\r\n if (!arguments.length) return classPrefix;\r\n classPrefix = _;\r\n return legend;\r\n };\r\n\r\n legend.title = function(_) {\r\n if (!arguments.length) return title;\r\n title = _;\r\n return legend;\r\n };\r\n\r\n d3.rebind(legend, legendDispatcher, \"on\");\r\n\r\n return legend;\r\n\r\n};\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * **[Gaussian error function](http://en.wikipedia.org/wiki/Error_function)**\r\n *\r\n * The `errorFunction(x/(sd * Math.sqrt(2)))` is the probability that a value in a\r\n * normal distribution with standard deviation sd is within x of the mean.\r\n *\r\n * This function returns a numerical approximation to the exact value.\r\n *\r\n * @param {number} x input\r\n * @return {number} error estimation\r\n * @example\r\n * errorFunction(1); //= 0.8427\r\n */\r\nfunction errorFunction(x/*: number */)/*: number */ {\r\n var t = 1 / (1 + 0.5 * Math.abs(x));\r\n var tau = t * Math.exp(-Math.pow(x, 2) -\r\n 1.26551223 +\r\n 1.00002368 * t +\r\n 0.37409196 * Math.pow(t, 2) +\r\n 0.09678418 * Math.pow(t, 3) -\r\n 0.18628806 * Math.pow(t, 4) +\r\n 0.27886807 * Math.pow(t, 5) -\r\n 1.13520398 * Math.pow(t, 6) +\r\n 1.48851587 * Math.pow(t, 7) -\r\n 0.82215223 * Math.pow(t, 8) +\r\n 0.17087277 * Math.pow(t, 9));\r\n if (x >= 0) {\r\n return 1 - tau;\r\n } else {\r\n return tau - 1;\r\n }\r\n}\r\n\r\nmodule.exports = errorFunction;\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * [Simple linear regression](http://en.wikipedia.org/wiki/Simple_linear_regression)\r\n * is a simple way to find a fitted line\r\n * between a set of coordinates. This algorithm finds the slope and y-intercept of a regression line\r\n * using the least sum of squares.\r\n *\r\n * @param {Array>} data an array of two-element of arrays,\r\n * like `[[0, 1], [2, 3]]`\r\n * @returns {Object} object containing slope and intersect of regression line\r\n * @example\r\n * linearRegression([[0, 0], [1, 1]]); // { m: 1, b: 0 }\r\n */\r\nfunction linearRegression(data/*: Array> */)/*: { m: number, b: number } */ {\r\n\r\n var m, b;\r\n\r\n // Store data length in a local variable to reduce\r\n // repeated object property lookups\r\n var dataLength = data.length;\r\n\r\n //if there's only one point, arbitrarily choose a slope of 0\r\n //and a y-intercept of whatever the y of the initial point is\r\n if (dataLength === 1) {\r\n m = 0;\r\n b = data[0][1];\r\n } else {\r\n // Initialize our sums and scope the `m` and `b`\r\n // variables that define the line.\r\n var sumX = 0, sumY = 0,\r\n sumXX = 0, sumXY = 0;\r\n\r\n // Use local variables to grab point values\r\n // with minimal object property lookups\r\n var point, x, y;\r\n\r\n // Gather the sum of all x values, the sum of all\r\n // y values, and the sum of x^2 and (x*y) for each\r\n // value.\r\n //\r\n // In math notation, these would be SS_x, SS_y, SS_xx, and SS_xy\r\n for (var i = 0; i < dataLength; i++) {\r\n point = data[i];\r\n x = point[0];\r\n y = point[1];\r\n\r\n sumX += x;\r\n sumY += y;\r\n\r\n sumXX += x * x;\r\n sumXY += x * y;\r\n }\r\n\r\n // `m` is the slope of the regression line\r\n m = ((dataLength * sumXY) - (sumX * sumY)) /\r\n ((dataLength * sumXX) - (sumX * sumX));\r\n\r\n // `b` is the y-intercept of the line.\r\n b = (sumY / dataLength) - ((m * sumX) / dataLength);\r\n }\r\n\r\n // Return both values as an object.\r\n return {\r\n m: m,\r\n b: b\r\n };\r\n}\r\n\r\n\r\nmodule.exports = linearRegression;\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * Given the output of `linearRegression`: an object\r\n * with `m` and `b` values indicating slope and intercept,\r\n * respectively, generate a line function that translates\r\n * x values into y values.\r\n *\r\n * @param {Object} mb object with `m` and `b` members, representing\r\n * slope and intersect of desired line\r\n * @returns {Function} method that computes y-value at any given\r\n * x-value on the line.\r\n * @example\r\n * var l = linearRegressionLine(linearRegression([[0, 0], [1, 1]]));\r\n * l(0) //= 0\r\n * l(2) //= 2\r\n */\r\nfunction linearRegressionLine(mb/*: { b: number, m: number }*/)/*: Function */ {\r\n // Return a function that computes a `y` value for each\r\n // x value it is given, based on the values of `b` and `a`\r\n // that we just computed.\r\n return function(x) {\r\n return mb.b + (mb.m * x);\r\n };\r\n}\r\n\r\nmodule.exports = linearRegressionLine;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sum = require('./sum');\r\n\r\n/**\r\n * The mean, _also known as average_,\r\n * is the sum of all values over the number of values.\r\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\r\n * a method of finding a typical or central value of a set of numbers.\r\n *\r\n * This runs on `O(n)`, linear time in respect to the array\r\n *\r\n * @param {Array} x input values\r\n * @returns {number} mean\r\n * @example\r\n * console.log(mean([0, 10])); // 5\r\n */\r\nfunction mean(x /*: Array */)/*:number*/ {\r\n // The mean of no numbers is null\r\n if (x.length === 0) { return NaN; }\r\n\r\n return sum(x) / x.length;\r\n}\r\n\r\nmodule.exports = mean;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sampleCovariance = require('./sample_covariance');\r\nvar sampleStandardDeviation = require('./sample_standard_deviation');\r\n\r\n/**\r\n * The [correlation](http://en.wikipedia.org/wiki/Correlation_and_dependence) is\r\n * a measure of how correlated two datasets are, between -1 and 1\r\n *\r\n * @param {Array} x first input\r\n * @param {Array} y second input\r\n * @returns {number} sample correlation\r\n * @example\r\n * var a = [1, 2, 3, 4, 5, 6];\r\n * var b = [2, 2, 3, 4, 5, 60];\r\n * sampleCorrelation(a, b); //= 0.691\r\n */\r\nfunction sampleCorrelation(x/*: Array */, y/*: Array */)/*:number*/ {\r\n var cov = sampleCovariance(x, y),\r\n xstd = sampleStandardDeviation(x),\r\n ystd = sampleStandardDeviation(y);\r\n\r\n return cov / xstd / ystd;\r\n}\r\n\r\nmodule.exports = sampleCorrelation;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar mean = require('./mean');\r\n\r\n/**\r\n * [Sample covariance](https://en.wikipedia.org/wiki/Sample_mean_and_sampleCovariance) of two datasets:\r\n * how much do the two datasets move together?\r\n * x and y are two datasets, represented as arrays of numbers.\r\n *\r\n * @param {Array} x first input\r\n * @param {Array} y second input\r\n * @returns {number} sample covariance\r\n * @example\r\n * var x = [1, 2, 3, 4, 5, 6];\r\n * var y = [6, 5, 4, 3, 2, 1];\r\n * sampleCovariance(x, y); //= -3.5\r\n */\r\nfunction sampleCovariance(x /*:Array*/, y /*:Array*/)/*:number*/ {\r\n\r\n // The two datasets must have the same length which must be more than 1\r\n if (x.length <= 1 || x.length !== y.length) {\r\n return NaN;\r\n }\r\n\r\n // determine the mean of each dataset so that we can judge each\r\n // value of the dataset fairly as the difference from the mean. this\r\n // way, if one dataset is [1, 2, 3] and [2, 3, 4], their covariance\r\n // does not suffer because of the difference in absolute values\r\n var xmean = mean(x),\r\n ymean = mean(y),\r\n sum = 0;\r\n\r\n // for each pair of values, the covariance increases when their\r\n // difference from the mean is associated - if both are well above\r\n // or if both are well below\r\n // the mean, the covariance increases significantly.\r\n for (var i = 0; i < x.length; i++) {\r\n sum += (x[i] - xmean) * (y[i] - ymean);\r\n }\r\n\r\n // this is Bessels' Correction: an adjustment made to sample statistics\r\n // that allows for the reduced degree of freedom entailed in calculating\r\n // values from samples rather than complete populations.\r\n var besselsCorrection = x.length - 1;\r\n\r\n // the covariance is weighted by the length of the datasets.\r\n return sum / besselsCorrection;\r\n}\r\n\r\nmodule.exports = sampleCovariance;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sampleVariance = require('./sample_variance');\r\n\r\n/**\r\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\r\n * is the square root of the variance.\r\n *\r\n * @param {Array} x input array\r\n * @returns {number} sample standard deviation\r\n * @example\r\n * ss.sampleStandardDeviation([2, 4, 4, 4, 5, 5, 7, 9]);\r\n * //= 2.138\r\n */\r\nfunction sampleStandardDeviation(x/*:Array*/)/*:number*/ {\r\n // The standard deviation of no numbers is null\r\n var sampleVarianceX = sampleVariance(x);\r\n if (isNaN(sampleVarianceX)) { return NaN; }\r\n return Math.sqrt(sampleVarianceX);\r\n}\r\n\r\nmodule.exports = sampleStandardDeviation;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sumNthPowerDeviations = require('./sum_nth_power_deviations');\r\n\r\n/*\r\n * The [sample variance](https://en.wikipedia.org/wiki/Variance#Sample_variance)\r\n * is the sum of squared deviations from the mean. The sample variance\r\n * is distinguished from the variance by the usage of [Bessel's Correction](https://en.wikipedia.org/wiki/Bessel's_correction):\r\n * instead of dividing the sum of squared deviations by the length of the input,\r\n * it is divided by the length minus one. This corrects the bias in estimating\r\n * a value from a set that you don't know if full.\r\n *\r\n * References:\r\n * * [Wolfram MathWorld on Sample Variance](http://mathworld.wolfram.com/SampleVariance.html)\r\n *\r\n * @param {Array} x input array\r\n * @return {number} sample variance\r\n * @example\r\n * sampleVariance([1, 2, 3, 4, 5]); //= 2.5\r\n */\r\nfunction sampleVariance(x /*: Array */)/*:number*/ {\r\n // The variance of no numbers is null\r\n if (x.length <= 1) { return NaN; }\r\n\r\n var sumSquaredDeviationsValue = sumNthPowerDeviations(x, 2);\r\n\r\n // this is Bessels' Correction: an adjustment made to sample statistics\r\n // that allows for the reduced degree of freedom entailed in calculating\r\n // values from samples rather than complete populations.\r\n var besselsCorrection = x.length - 1;\r\n\r\n // Find the mean value of that list\r\n return sumSquaredDeviationsValue / besselsCorrection;\r\n}\r\n\r\nmodule.exports = sampleVariance;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar variance = require('./variance');\r\n\r\n/**\r\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\r\n * is the square root of the variance. It's useful for measuring the amount\r\n * of variation or dispersion in a set of values.\r\n *\r\n * Standard deviation is only appropriate for full-population knowledge: for\r\n * samples of a population, {@link sampleStandardDeviation} is\r\n * more appropriate.\r\n *\r\n * @param {Array} x input\r\n * @returns {number} standard deviation\r\n * @example\r\n * var scores = [2, 4, 4, 4, 5, 5, 7, 9];\r\n * variance(scores); //= 4\r\n * standardDeviation(scores); //= 2\r\n */\r\nfunction standardDeviation(x /*: Array */)/*:number*/ {\r\n // The standard deviation of no numbers is null\r\n var v = variance(x);\r\n if (isNaN(v)) { return 0; }\r\n return Math.sqrt(v);\r\n}\r\n\r\nmodule.exports = standardDeviation;\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * Our default sum is the [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) is\r\n * a method for computing the sum of a list of numbers while correcting\r\n * for floating-point errors. Traditionally, sums are calculated as many\r\n * successive additions, each one with its own floating-point roundoff. These\r\n * losses in precision add up as the number of numbers increases. This alternative\r\n * algorithm is more accurate than the simple way of calculating sums by simple\r\n * addition.\r\n *\r\n * This runs on `O(n)`, linear time in respect to the array\r\n *\r\n * @param {Array} x input\r\n * @return {number} sum of all input numbers\r\n * @example\r\n * console.log(sum([1, 2, 3])); // 6\r\n */\r\nfunction sum(x/*: Array */)/*: number */ {\r\n\r\n // like the traditional sum algorithm, we keep a running\r\n // count of the current sum.\r\n var sum = 0;\r\n\r\n // but we also keep three extra variables as bookkeeping:\r\n // most importantly, an error correction value. This will be a very\r\n // small number that is the opposite of the floating point precision loss.\r\n var errorCompensation = 0;\r\n\r\n // this will be each number in the list corrected with the compensation value.\r\n var correctedCurrentValue;\r\n\r\n // and this will be the next sum\r\n var nextSum;\r\n\r\n for (var i = 0; i < x.length; i++) {\r\n // first correct the value that we're going to add to the sum\r\n correctedCurrentValue = x[i] - errorCompensation;\r\n\r\n // compute the next sum. sum is likely a much larger number\r\n // than correctedCurrentValue, so we'll lose precision here,\r\n // and measure how much precision is lost in the next step\r\n nextSum = sum + correctedCurrentValue;\r\n\r\n // we intentionally didn't assign sum immediately, but stored\r\n // it for now so we can figure out this: is (sum + nextValue) - nextValue\r\n // not equal to 0? ideally it would be, but in practice it won't:\r\n // it will be some very small number. that's what we record\r\n // as errorCompensation.\r\n errorCompensation = nextSum - sum - correctedCurrentValue;\r\n\r\n // now that we've computed how much we'll correct for in the next\r\n // loop, start treating the nextSum as the current sum.\r\n sum = nextSum;\r\n }\r\n\r\n return sum;\r\n}\r\n\r\nmodule.exports = sum;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar mean = require('./mean');\r\n\r\n/**\r\n * The sum of deviations to the Nth power.\r\n * When n=2 it's the sum of squared deviations.\r\n * When n=3 it's the sum of cubed deviations.\r\n *\r\n * @param {Array} x\r\n * @param {number} n power\r\n * @returns {number} sum of nth power deviations\r\n * @example\r\n * var input = [1, 2, 3];\r\n * // since the variance of a set is the mean squared\r\n * // deviations, we can calculate that with sumNthPowerDeviations:\r\n * var variance = sumNthPowerDeviations(input) / input.length;\r\n */\r\nfunction sumNthPowerDeviations(x/*: Array */, n/*: number */)/*:number*/ {\r\n var meanValue = mean(x),\r\n sum = 0;\r\n\r\n for (var i = 0; i < x.length; i++) {\r\n sum += Math.pow(x[i] - meanValue, n);\r\n }\r\n\r\n return sum;\r\n}\r\n\r\nmodule.exports = sumNthPowerDeviations;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sumNthPowerDeviations = require('./sum_nth_power_deviations');\r\n\r\n/**\r\n * The [variance](http://en.wikipedia.org/wiki/Variance)\r\n * is the sum of squared deviations from the mean.\r\n *\r\n * This is an implementation of variance, not sample variance:\r\n * see the `sampleVariance` method if you want a sample measure.\r\n *\r\n * @param {Array} x a population\r\n * @returns {number} variance: a value greater than or equal to zero.\r\n * zero indicates that all values are identical.\r\n * @example\r\n * ss.variance([1, 2, 3, 4, 5, 6]); //= 2.917\r\n */\r\nfunction variance(x/*: Array */)/*:number*/ {\r\n // The variance of no numbers is null\r\n if (x.length === 0) { return NaN; }\r\n\r\n // Find the mean of squared deviations between the\r\n // mean value and each value.\r\n return sumNthPowerDeviations(x, 2) / x.length;\r\n}\r\n\r\nmodule.exports = variance;\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * The [Z-Score, or Standard Score](http://en.wikipedia.org/wiki/Standard_score).\r\n *\r\n * The standard score is the number of standard deviations an observation\r\n * or datum is above or below the mean. Thus, a positive standard score\r\n * represents a datum above the mean, while a negative standard score\r\n * represents a datum below the mean. It is a dimensionless quantity\r\n * obtained by subtracting the population mean from an individual raw\r\n * score and then dividing the difference by the population standard\r\n * deviation.\r\n *\r\n * The z-score is only defined if one knows the population parameters;\r\n * if one only has a sample set, then the analogous computation with\r\n * sample mean and sample standard deviation yields the\r\n * Student's t-statistic.\r\n *\r\n * @param {number} x\r\n * @param {number} mean\r\n * @param {number} standardDeviation\r\n * @return {number} z score\r\n * @example\r\n * ss.zScore(78, 80, 5); //= -0.4\r\n */\r\nfunction zScore(x/*:number*/, mean/*:number*/, standardDeviation/*:number*/)/*:number*/ {\r\n return (x - mean) / standardDeviation;\r\n}\r\n\r\nmodule.exports = zScore;\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from \"./legend\";\r\n\r\nexport class BarChartConfig extends ChartConfig{\r\n\r\n svgClass= this.cssClassPrefix+'bar-chart';\r\n showLegend=true;\r\n showTooltip =true;\r\n legend={\r\n width: 80,\r\n margin: 10,\r\n shapeWidth: 20\r\n };\r\n x={// X axis config\r\n label: '', // axis label\r\n key: 0,\r\n value: (d, key) => Utils.isNumber(d) ? d : d[key], // x value accessor\r\n scale: \"ordinal\",\r\n ticks: undefined,\r\n };\r\n y={// Y axis config\r\n key: 1,\r\n value: (d, key) => Utils.isNumber(d) ? d : d[key], // x value accessor\r\n label: '', // axis label,\r\n orient: \"left\",\r\n scale: \"linear\"\r\n };\r\n groups={\r\n key: 1,\r\n value: (d) => d[this.groups.key] , // grouping value accessor,\r\n label: \"\"\r\n };\r\n color = undefined // string or function returning color's value for color scale\r\n d3ColorCategory= 'category10';\r\n transition= true;\r\n\r\n constructor(custom){\r\n super();\r\n var config = this;\r\n\r\n if(custom){\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class BarChart extends Chart{\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new BarChartConfig(config));\r\n }\r\n\r\n setConfig(config){\r\n return super.setConfig(new BarChartConfig(config));\r\n }\r\n\r\n initPlot(){\r\n super.initPlot();\r\n var self=this;\r\n\r\n var conf = this.config;\r\n\r\n this.plot.x={};\r\n this.plot.y={};\r\n\r\n this.plot.showLegend = conf.showLegend;\r\n if(this.plot.showLegend){\r\n this.plot.margin.right = conf.margin.right + conf.legend.width+conf.legend.margin*2;\r\n }\r\n\r\n\r\n this.computePlotSize();\r\n this.setupY();\r\n this.setupX();\r\n this.setupGroupStacks();\r\n\r\n\r\n this.setupYDomain();\r\n\r\n\r\n if(conf.d3ColorCategory){\r\n this.plot.colorCategory = d3.scale[conf.d3ColorCategory]();\r\n }\r\n var colorValue = conf.color;\r\n if (colorValue && typeof colorValue === 'string' || colorValue instanceof String){\r\n this.plot.color = colorValue;\r\n }else if(this.plot.colorCategory){\r\n this.plot.color = d => self.plot.colorCategory(d.key);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n\r\n\r\n setupX(){\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config.x;\r\n\r\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\r\n x.value = d => conf.value(d, conf.key);\r\n x.scale = d3.scale.ordinal().rangeRoundBands([0, plot.width], .08);\r\n x.map = d => x.scale(x.value(d));\r\n\r\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\r\n\r\n var data = this.data;\r\n var domain;\r\n if(!this.config.series){\r\n domain = d3.map(data, x.value).keys();\r\n }else{\r\n domain = d3.map(data[0].values, x.value).keys();\r\n }\r\n\r\n plot.x.scale.domain(domain);\r\n console.log(' plot.x.scale.domain', plot.x.scale.domain());\r\n \r\n };\r\n\r\n setupY (){\r\n\r\n var plot = this.plot;\r\n var y = plot.y;\r\n var conf = this.config.y;\r\n y.value = d => conf.value(d, conf.key);\r\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\r\n y.map = d => y.scale(y.value(d));\r\n\r\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\r\n if(conf.ticks){\r\n y.axis.ticks(conf.ticks);\r\n }\r\n };\r\n\r\n setupYDomain() {\r\n var plot = this.plot;\r\n var data = this.data;\r\n var domain;\r\n var yStackMax = d3.max(plot.layers, layer => d3.max(layer.values, d => d.y0 + d.y));\r\n if(!this.config.series){\r\n domain = [d3.min(data, plot.y.value), d3.max(data, plot.y.value)];\r\n }else{\r\n\r\n // var min = d3.min(data, s=>d3.min(s.values, plot.y.value));\r\n var max = yStackMax;\r\n domain = [0, max];\r\n }\r\n plot.y.scale.domain(domain);\r\n console.log(' plot.y.scale.domain', plot.y.scale.domain());\r\n }\r\n groupData(){\r\n var self=this;\r\n this.plot.groupingEnabled = this.config.series;\r\n var data = this.data;\r\n if(!this.plot.groupingEnabled ){\r\n this.plot.groupedData = [{\r\n key: 'root',\r\n values: self.mapToPoints(data)\r\n }];\r\n }else{\r\n\r\n this.plot.groupedData = data.map(s=>{\r\n return{\r\n key: s.key,\r\n values: self.mapToPoints(s.values)\r\n }\r\n });\r\n\r\n }\r\n }\r\n setupGroupStacks() {\r\n var self=this;\r\n this.groupData();\r\n\r\n this.plot.stack = d3.layout.stack().values(d=>d.values);\r\n this.plot.layers = this.plot.stack(this.plot.groupedData);\r\n\r\n }\r\n\r\n mapToPoints(values){\r\n var plot = this.plot;\r\n return values.map(v=>{\r\n return {\r\n x: plot.x.value(v),\r\n y: plot.y.value(v),\r\n }\r\n })\r\n }\r\n\r\n drawAxisX(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.x;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-x')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')))\r\n .attr(\"transform\", \"translate(0,\" + plot.height + \")\");\r\n\r\n var axisT = axis;\r\n if (self.config.transition) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.x.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ (plot.width/2) +\",\"+ (plot.margin.bottom) +\")\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"-1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n drawAxisY(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.y;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-y')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')));\r\n\r\n var axisT = axis;\r\n if (self.config.transition) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.y.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ -plot.margin.left +\",\"+(plot.height/2)+\")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n\r\n drawBars() {\r\n var self = this;\r\n var plot = self.plot;\r\n\r\n console.log(plot.layers);\r\n\r\n var layerClass = this.prefixClass(\"layer\");\r\n\r\n var barClass = this.prefixClass(\"bar\");\r\n var layer = self.svgG.selectAll(\".\"+layerClass)\r\n .data(plot.layers);\r\n\r\n layer.enter().append(\"g\")\r\n .attr(\"class\", layerClass);\r\n\r\n var bar = layer.selectAll(\".\"+barClass)\r\n .data(d => d.values);\r\n\r\n bar.enter().append(\"g\")\r\n .attr(\"class\", barClass)\r\n .append(\"rect\")\r\n .attr(\"x\", 1);\r\n\r\n\r\n var barRect = bar.select(\"rect\");\r\n\r\n var barRectT = barRect;\r\n var barT = bar;\r\n var layerT = layer;\r\n if (this.transitionEnabled()) {\r\n barRectT = barRect.transition();\r\n barT = bar.transition();\r\n layerT= layer.transition();\r\n }\r\n\r\n var yDomain = plot.y.scale.domain();\r\n barT.attr(\"transform\", function(d) { return \"translate(\" + plot.x.scale(d.x) + \",\" + (plot.y.scale(d.y0+d.y )) + \")\"; });\r\n\r\n barRectT\r\n .attr(\"width\", plot.x.scale.rangeBand())\r\n .attr(\"height\", d => plot.y.scale(d.y0 ) - plot.y.scale(d.y0 + d.y - yDomain[0]));\r\n\r\n\r\n if(this.plot.color){\r\n layerT\r\n .attr(\"fill\", this.plot.color);\r\n }\r\n\r\n if (plot.tooltip) {\r\n bar.on(\"mouseover\", d => {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n plot.tooltip.html(d.y)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n }).on(\"mouseout\", d => {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n layer.exit().remove();\r\n bar.exit().remove();\r\n }\r\n\r\n update(newData){\r\n super.update(newData);\r\n this.drawAxisX();\r\n this.drawAxisY();\r\n\r\n this.drawBars();\r\n\r\n this.updateLegend();\r\n };\r\n\r\n\r\n updateLegend() {\r\n var plot = this.plot;\r\n\r\n var scale = plot.colorCategory;\r\n if(!scale.domain() || scale.domain().length<2){\r\n plot.showLegend = false;\r\n }\r\n\r\n if(!plot.showLegend){\r\n if(plot.legend && plot.legend.container){\r\n plot.legend.container.remove();\r\n }\r\n return;\r\n }\r\n\r\n\r\n var legendX = this.plot.width + this.config.legend.margin;\r\n var legendY = this.config.legend.margin;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY);\r\n\r\n var legendLinear = plot.legend.color()\r\n .shapeWidth(this.config.legend.shapeWidth)\r\n .orient('vertical')\r\n .scale(scale);\r\n\r\n plot.legend.container\r\n .call(legendLinear);\r\n }\r\n\r\n\r\n}\r\n","import {Utils} from './utils'\r\n\r\n\r\nexport class ChartConfig {\r\n cssClassPrefix = \"odc-\";\r\n svgClass = this.cssClassPrefix + 'mw-d3-chart';\r\n width = undefined;\r\n height = undefined;\r\n margin = {\r\n left: 50,\r\n right: 30,\r\n top: 30,\r\n bottom: 50\r\n };\r\n showTooltip = false;\r\n transition = true;\r\n\r\n constructor(custom) {\r\n if (custom) {\r\n Utils.deepExtend(this, custom);\r\n }\r\n }\r\n\r\n\r\n}\r\n\r\nexport class Chart {\r\n utils = Utils;\r\n baseContainer;\r\n svg;\r\n config;\r\n plot = {\r\n margin: {}\r\n };\r\n _attached = {};\r\n _layers = {};\r\n _events = {};\r\n _isAttached;\r\n _isInitialized=false;\r\n\r\n\r\n constructor(base, data, config) {\r\n \r\n this._isAttached = base instanceof Chart;\r\n\r\n this.baseContainer = base;\r\n\r\n this.setConfig(config);\r\n\r\n if (data) {\r\n this.setData(data);\r\n }\r\n\r\n this.init();\r\n this.postInit();\r\n }\r\n\r\n setConfig(config) {\r\n if (!config) {\r\n this.config = new ChartConfig();\r\n } else {\r\n this.config = config;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n setData(data) {\r\n this.data = data;\r\n return this;\r\n }\r\n\r\n init() {\r\n var self = this;\r\n\r\n\r\n self.initPlot();\r\n self.initSvg();\r\n\r\n self.initTooltip();\r\n self.draw();\r\n this._isInitialized=true;\r\n return this;\r\n }\r\n\r\n postInit(){\r\n\r\n }\r\n\r\n initSvg() {\r\n var self = this;\r\n var config = this.config;\r\n\r\n var margin = self.plot.margin;\r\n var width = self.plot.width + margin.left + margin.right;\r\n var height = self.plot.height + margin.top + margin.bottom;\r\n var aspect = width / height;\r\n if(!self._isAttached){\r\n if(!this._isInitialized){\r\n d3.select(self.baseContainer).select(\"svg\").remove();\r\n }\r\n self.svg = d3.select(self.baseContainer).selectOrAppend(\"svg\");\r\n\r\n self.svg\r\n .attr(\"width\", width)\r\n .attr(\"height\", height)\r\n .attr(\"viewBox\", \"0 0 \" + \" \" + width + \" \" + height)\r\n .attr(\"preserveAspectRatio\", \"xMidYMid meet\")\r\n .attr(\"class\", config.svgClass);\r\n self.svgG = self.svg.selectOrAppend(\"g.main-group\");\r\n }else{\r\n console.log(self.baseContainer);\r\n self.svg = self.baseContainer.svg;\r\n self.svgG = self.svg.selectOrAppend(\"g.main-group.\"+config.svgClass)\r\n }\r\n\r\n self.svgG.attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");\r\n\r\n if (!config.width || config.height) {\r\n d3.select(window)\r\n .on(\"resize\", function () {\r\n //TODO add responsiveness if width/height not specified\r\n });\r\n }\r\n }\r\n\r\n initTooltip(){\r\n var self = this;\r\n if (self.config.showTooltip) {\r\n if(!self._isAttached ){\r\n self.plot.tooltip = d3.select(\"body\").selectOrAppend('div.'+self.config.cssClassPrefix+'tooltip')\r\n .style(\"opacity\", 0);\r\n }else{\r\n self.plot.tooltip= self.baseContainer.plot.tooltip;\r\n }\r\n\r\n }\r\n }\r\n\r\n initPlot() {\r\n var margin = this.config.margin;\r\n this.plot = this.plot || {};\r\n this.plot.margin = {\r\n top: margin.top,\r\n bottom: margin.bottom,\r\n left: margin.left,\r\n right: margin.right\r\n };\r\n }\r\n\r\n update(data) {\r\n if (data) {\r\n this.setData(data);\r\n }\r\n var layerName, attachmentData;\r\n for (var attachmentName in this._attached) {\r\n\r\n attachmentData = data;\r\n\r\n this._attached[attachmentName].update(attachmentData);\r\n }\r\n return this;\r\n }\r\n\r\n draw(data) {\r\n this.update(data);\r\n\r\n\r\n return this;\r\n }\r\n\r\n\r\n //Borrowed from d3.chart\r\n /**\r\n * Register or retrieve an \"attachment\" Chart. The \"attachment\" chart's `draw`\r\n * method will be invoked whenever the containing chart's `draw` method is\r\n * invoked.\r\n *\r\n * @externalExample chart-attach\r\n *\r\n * @param {String} attachmentName Name of the attachment\r\n * @param {Chart} [chart] Chart to register as a mix in of this chart. When\r\n * unspecified, this method will return the attachment previously\r\n * registered with the specified `attachmentName` (if any).\r\n *\r\n * @returns {Chart} Reference to this chart (chainable).\r\n */\r\n attach(attachmentName, chart) {\r\n if (arguments.length === 1) {\r\n return this._attached[attachmentName];\r\n }\r\n\r\n this._attached[attachmentName] = chart;\r\n return chart;\r\n };\r\n\r\n \r\n\r\n //Borrowed from d3.chart\r\n /**\r\n * Subscribe a callback function to an event triggered on the chart. See {@link\r\n * Chart#once} to subscribe a callback function to an event for one occurence.\r\n *\r\n * @externalExample {runnable} chart-on\r\n *\r\n * @param {String} name Name of the event\r\n * @param {ChartEventHandler} callback Function to be invoked when the event\r\n * occurs\r\n * @param {Object} [context] Value to set as `this` when invoking the\r\n * `callback`. Defaults to the chart instance.\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\r\n on(name, callback, context) {\r\n var events = this._events[name] || (this._events[name] = []);\r\n events.push({\r\n callback: callback,\r\n context: context || this,\r\n _chart: this\r\n });\r\n return this;\r\n }\r\n\r\n //Borrowed from d3.chart\r\n /**\r\n *\r\n * Subscribe a callback function to an event triggered on the chart. This\r\n * function will be invoked at the next occurance of the event and immediately\r\n * unsubscribed. See {@link Chart#on} to subscribe a callback function to an\r\n * event indefinitely.\r\n *\r\n * @externalExample {runnable} chart-once\r\n *\r\n * @param {String} name Name of the event\r\n * @param {ChartEventHandler} callback Function to be invoked when the event\r\n * occurs\r\n * @param {Object} [context] Value to set as `this` when invoking the\r\n * `callback`. Defaults to the chart instance\r\n *\r\n * @returns {Chart} A reference to this chart (chainable)\r\n */\r\n once(name, callback, context) {\r\n var self = this;\r\n var once = function () {\r\n self.off(name, once);\r\n callback.apply(this, arguments);\r\n };\r\n return this.on(name, once, context);\r\n }\r\n\r\n\r\n //Borrowed from d3.chart\r\n /**\r\n * Unsubscribe one or more callback functions from an event triggered on the\r\n * chart. When no arguments are specified, *all* handlers will be unsubscribed.\r\n * When only a `name` is specified, all handlers subscribed to that event will\r\n * be unsubscribed. When a `name` and `callback` are specified, only that\r\n * function will be unsubscribed from that event. When a `name` and `context`\r\n * are specified (but `callback` is omitted), all events bound to the given\r\n * event with the given context will be unsubscribed.\r\n *\r\n * @externalExample {runnable} chart-off\r\n *\r\n * @param {String} [name] Name of the event to be unsubscribed\r\n * @param {ChartEventHandler} [callback] Function to be unsubscribed\r\n * @param {Object} [context] Contexts to be unsubscribe\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\r\n\r\n off(name, callback, context) {\r\n var names, n, events, event, i, j;\r\n\r\n // remove all events\r\n if (arguments.length === 0) {\r\n for (name in this._events) {\r\n this._events[name].length = 0;\r\n }\r\n return this;\r\n }\r\n\r\n // remove all events for a specific name\r\n if (arguments.length === 1) {\r\n events = this._events[name];\r\n if (events) {\r\n events.length = 0;\r\n }\r\n return this;\r\n }\r\n\r\n // remove all events that match whatever combination of name, context\r\n // and callback.\r\n names = name ? [name] : Object.keys(this._events);\r\n for (i = 0; i < names.length; i++) {\r\n n = names[i];\r\n events = this._events[n];\r\n j = events.length;\r\n while (j--) {\r\n event = events[j];\r\n if ((callback && callback === event.callback) ||\r\n (context && context === event.context)) {\r\n events.splice(j, 1);\r\n }\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n\r\n //Borrowed from d3.chart\r\n /**\r\n * Publish an event on this chart with the given `name`.\r\n *\r\n * @externalExample {runnable} chart-trigger\r\n *\r\n * @param {String} name Name of the event to publish\r\n * @param {...*} arguments Values with which to invoke the registered\r\n * callbacks.\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\r\n trigger(name) {\r\n var args = Array.prototype.slice.call(arguments, 1);\r\n var events = this._events[name];\r\n var i, ev;\r\n\r\n if (events !== undefined) {\r\n for (i = 0; i < events.length; i++) {\r\n ev = events[i];\r\n ev.callback.apply(ev.context, args);\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n getBaseContainer(){\r\n if(this._isAttached){\r\n return this.baseContainer.svg;\r\n }\r\n return d3.select(this.baseContainer);\r\n }\r\n\r\n getBaseContainerNode(){\r\n\r\n return this.getBaseContainer().node();\r\n }\r\n\r\n prefixClass(clazz, addDot){\r\n return addDot? '.': ''+this.config.cssClassPrefix+clazz;\r\n }\r\n computePlotSize() {\r\n this.plot.width = Utils.availableWidth(this.config.width, this.getBaseContainer(), this.plot.margin);\r\n this.plot.height = Utils.availableHeight(this.config.height, this.getBaseContainer(), this.plot.margin);\r\n }\r\n\r\n transitionEnabled(){\r\n return this._isInitialized && this.config.transition;\r\n }\r\n}\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {StatisticsUtils} from './statistics-utils'\r\nimport {Legend} from './legend'\r\nimport {ScatterPlot} from './scatterplot'\r\n\r\nexport class CorrelationMatrixConfig extends ChartConfig {\r\n\r\n svgClass = this.cssClassPrefix+'correlation-matrix';\r\n guides = false; //show axis guides\r\n showTooltip = true; //show tooltip on dot hover\r\n showLegend = true;\r\n highlightLabels = true;\r\n rotateLabelsX = true;\r\n rotateLabelsY = true;\r\n variables = {\r\n labels: undefined,\r\n keys: [], //optional array of variable keys\r\n value: (d, variableKey) => d[variableKey], // variable value accessor\r\n scale: \"ordinal\"\r\n };\r\n correlation = {\r\n scale: \"linear\",\r\n domain: [-1, -0.75, -0.5, 0, 0.5, 0.75, 1],\r\n range: [\"darkblue\", \"blue\", \"lightskyblue\", \"white\", \"orangered\", \"crimson\", \"darkred\"],\r\n value: (xValues, yValues) => StatisticsUtils.sampleCorrelation(xValues, yValues)\r\n\r\n };\r\n cell = {\r\n shape: \"ellipse\", //possible values: rect, circle, ellipse\r\n size: undefined,\r\n sizeMin: 15,\r\n sizeMax: 250,\r\n padding: 1\r\n };\r\n margin = {\r\n left: 60,\r\n right: 50,\r\n top: 30,\r\n bottom: 60\r\n };\r\n\r\n constructor(custom) {\r\n super();\r\n if (custom) {\r\n Utils.deepExtend(this, custom);\r\n }\r\n }\r\n}\r\n\r\nexport class CorrelationMatrix extends Chart {\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new CorrelationMatrixConfig(config));\r\n }\r\n\r\n setConfig(config) {\r\n return super.setConfig(new CorrelationMatrixConfig(config));\r\n\r\n }\r\n\r\n initPlot() {\r\n super.initPlot();\r\n var self = this;\r\n var margin = this.config.margin;\r\n var conf = this.config;\r\n\r\n this.plot.x = {};\r\n this.plot.correlation = {\r\n matrix: undefined,\r\n cells: undefined,\r\n color: {},\r\n shape: {}\r\n };\r\n\r\n\r\n this.setupVariables();\r\n var width = conf.width;\r\n var placeholderNode = this.getBaseContainerNode();\r\n this.plot.placeholderNode = placeholderNode;\r\n\r\n var parentWidth = placeholderNode.getBoundingClientRect().width;\r\n if (width) {\r\n\r\n if (!this.plot.cellSize) {\r\n this.plot.cellSize = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (width - margin.left - margin.right) / this.plot.variables.length));\r\n }\r\n\r\n } else {\r\n this.plot.cellSize = this.config.cell.size;\r\n\r\n if (!this.plot.cellSize) {\r\n this.plot.cellSize = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (parentWidth - margin.left - margin.right) / this.plot.variables.length));\r\n }\r\n\r\n width = this.plot.cellSize * this.plot.variables.length + margin.left + margin.right;\r\n\r\n }\r\n\r\n var height = width;\r\n if (!height) {\r\n height = placeholderNode.getBoundingClientRect().height;\r\n }\r\n\r\n this.plot.width = width - margin.left - margin.right;\r\n this.plot.height = this.plot.width;\r\n\r\n this.setupVariablesScales();\r\n this.setupCorrelationScales();\r\n this.setupCorrelationMatrix();\r\n\r\n\r\n return this;\r\n }\r\n\r\n setupVariablesScales() {\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config.variables;\r\n\r\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\r\n x.value = conf.value;\r\n x.scale = d3.scale[conf.scale]().rangeBands([plot.width, 0]);\r\n x.map = d => x.scale(x.value(d));\r\n\r\n };\r\n\r\n setupCorrelationScales() {\r\n var plot = this.plot;\r\n var corrConf = this.config.correlation;\r\n\r\n plot.correlation.color.scale = d3.scale[corrConf.scale]().domain(corrConf.domain).range(corrConf.range);\r\n var shape = plot.correlation.shape = {};\r\n\r\n var cellConf = this.config.cell;\r\n shape.type = cellConf.shape;\r\n\r\n var shapeSize = plot.cellSize - cellConf.padding * 2;\r\n if (shape.type == 'circle') {\r\n var radiusMax = shapeSize / 2;\r\n shape.radiusScale = d3.scale.linear().domain([0, 1]).range([2, radiusMax]);\r\n shape.radius = c=> shape.radiusScale(Math.abs(c.value));\r\n } else if (shape.type == 'ellipse') {\r\n var radiusMax = shapeSize / 2;\r\n shape.radiusScale = d3.scale.linear().domain([0, 1]).range([radiusMax, 2]);\r\n shape.radiusX = c=> shape.radiusScale(Math.abs(c.value));\r\n shape.radiusY = radiusMax;\r\n\r\n shape.rotateVal = v => {\r\n if (v == 0) return \"0\";\r\n if (v < 0) return \"-45\";\r\n return \"45\"\r\n }\r\n } else if (shape.type == 'rect') {\r\n shape.size = shapeSize;\r\n }\r\n\r\n }\r\n\r\n\r\n setupVariables() {\r\n\r\n var variablesConf = this.config.variables;\r\n\r\n var data = this.data;\r\n var plot = this.plot;\r\n plot.domainByVariable = {};\r\n plot.variables = variablesConf.keys;\r\n if (!plot.variables || !plot.variables.length) {\r\n plot.variables = Utils.inferVariables(data, this.config.groups.key, this.config.includeInPlot);\r\n }\r\n\r\n plot.labels = [];\r\n plot.labelByVariable = {};\r\n plot.variables.forEach((variableKey, index) => {\r\n plot.domainByVariable[variableKey] = d3.extent(data, (d) => variablesConf.value(d, variableKey));\r\n var label = variableKey;\r\n if (variablesConf.labels && variablesConf.labels.length > index) {\r\n\r\n label = variablesConf.labels[index];\r\n }\r\n plot.labels.push(label);\r\n plot.labelByVariable[variableKey] = label;\r\n });\r\n\r\n console.log(plot.labelByVariable);\r\n\r\n };\r\n\r\n\r\n setupCorrelationMatrix() {\r\n var self = this;\r\n var data = this.data;\r\n var matrix = this.plot.correlation.matrix = [];\r\n var matrixCells = this.plot.correlation.matrix.cells = [];\r\n var plot = this.plot;\r\n\r\n var variableToValues = {};\r\n plot.variables.forEach((v, i) => {\r\n\r\n variableToValues[v] = data.map(d=>plot.x.value(d, v));\r\n });\r\n\r\n plot.variables.forEach((v1, i) => {\r\n var row = [];\r\n matrix.push(row);\r\n\r\n plot.variables.forEach((v2, j) => {\r\n var corr = 1;\r\n if (v1 != v2) {\r\n corr = self.config.correlation.value(variableToValues[v1], variableToValues[v2]);\r\n }\r\n var cell = {\r\n rowVar: v1,\r\n colVar: v2,\r\n row: i,\r\n col: j,\r\n value: corr\r\n };\r\n row.push(cell);\r\n\r\n matrixCells.push(cell);\r\n });\r\n\r\n });\r\n }\r\n\r\n\r\n update(newData) {\r\n super.update(newData);\r\n // this.update\r\n this.updateCells();\r\n this.updateVariableLabels();\r\n\r\n\r\n if (this.config.showLegend) {\r\n this.updateLegend();\r\n }\r\n };\r\n\r\n updateVariableLabels() {\r\n this.plot.labelClass = this.prefixClass(\"label\");\r\n this.updateAxisX();\r\n this.updateAxisY();\r\n }\r\n\r\n updateAxisX() {\r\n var self = this;\r\n var plot = self.plot;\r\n var labelClass = plot.labelClass;\r\n var labelXClass = labelClass + \"-x\";\r\n\r\n var labels = self.svgG.selectAll(\"text.\" + labelXClass)\r\n .data(plot.variables, (d, i)=>i);\r\n\r\n labels.enter().append(\"text\").attr(\"class\", (d, i) => labelClass + \" \" + labelXClass + \" \" + labelXClass + \"-\" + i);\r\n\r\n labels\r\n .attr(\"x\", (d, i) => i * plot.cellSize + plot.cellSize / 2)\r\n .attr(\"y\", plot.height)\r\n .attr(\"dx\", -2)\r\n .attr(\"dy\", 5)\r\n .attr(\"text-anchor\", \"end\")\r\n\r\n // .attr(\"dominant-baseline\", \"hanging\")\r\n .text(v=>plot.labelByVariable[v]);\r\n\r\n if (this.config.rotateLabelsX) {\r\n labels.attr(\"transform\", (d, i) => \"rotate(-45, \" + (i * plot.cellSize + plot.cellSize / 2 ) + \", \" + plot.height + \")\")\r\n }\r\n\r\n var maxWidth = self.computeXAxisLabelsWidth();\r\n labels.each(function (label) {\r\n Utils.placeTextWithEllipsisAndTooltip(d3.select(this), label, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\r\n });\r\n\r\n labels.exit().remove();\r\n }\r\n\r\n updateAxisY() {\r\n var self = this;\r\n var plot = self.plot;\r\n var labelClass = plot.labelClass;\r\n var labelYClass = plot.labelClass + \"-y\";\r\n var labels = self.svgG.selectAll(\"text.\" + labelYClass)\r\n .data(plot.variables);\r\n\r\n labels.enter().append(\"text\");\r\n\r\n labels\r\n .attr(\"x\", 0)\r\n .attr(\"y\", (d, i) => i * plot.cellSize + plot.cellSize / 2)\r\n .attr(\"dx\", -2)\r\n .attr(\"text-anchor\", \"end\")\r\n .attr(\"class\", (d, i) => labelClass + \" \" + labelYClass + \" \" + labelYClass + \"-\" + i)\r\n // .attr(\"dominant-baseline\", \"hanging\")\r\n .text(v=>plot.labelByVariable[v]);\r\n\r\n if (this.config.rotateLabelsY) {\r\n labels\r\n .attr(\"transform\", (d, i) => \"rotate(-45, \" + 0 + \", \" + (i * plot.cellSize + plot.cellSize / 2) + \")\")\r\n .attr(\"text-anchor\", \"end\");\r\n }\r\n\r\n var maxWidth = self.computeYAxisLabelsWidth();\r\n labels.each(function (label) {\r\n Utils.placeTextWithEllipsisAndTooltip(d3.select(this), label, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\r\n });\r\n\r\n labels.exit().remove();\r\n }\r\n\r\n computeYAxisLabelsWidth() {\r\n var maxWidth = this.plot.margin.left;\r\n if (!this.config.rotateLabelsY) {\r\n return maxWidth;\r\n }\r\n\r\n maxWidth *= Utils.SQRT_2;\r\n var fontSize = 11; //todo check actual font size\r\n maxWidth -= fontSize / 2;\r\n\r\n return maxWidth;\r\n }\r\n\r\n computeXAxisLabelsWidth(offset) {\r\n if (!this.config.rotateLabelsX) {\r\n return this.plot.cellSize - 2;\r\n }\r\n var size = this.plot.margin.bottom;\r\n size *= Utils.SQRT_2;\r\n var fontSize = 11; //todo check actual font size\r\n size -= fontSize / 2;\r\n return size;\r\n }\r\n\r\n updateCells() {\r\n\r\n var self = this;\r\n var plot = self.plot;\r\n var cellClass = self.prefixClass(\"cell\");\r\n var cellShape = plot.correlation.shape.type;\r\n\r\n var cells = self.svgG.selectAll(\"g.\" + cellClass)\r\n .data(plot.correlation.matrix.cells);\r\n\r\n var cellEnterG = cells.enter().append(\"g\")\r\n .classed(cellClass, true);\r\n cells.attr(\"transform\", c=> \"translate(\" + (plot.cellSize * c.col + plot.cellSize / 2) + \",\" + (plot.cellSize * c.row + plot.cellSize / 2) + \")\");\r\n\r\n cells.classed(self.config.cssClassPrefix + \"selectable\", !!self.scatterPlot);\r\n\r\n var selector = \"*:not(.cell-shape-\" + cellShape + \")\";\r\n\r\n var wrongShapes = cells.selectAll(selector);\r\n wrongShapes.remove();\r\n\r\n var shapes = cells.selectOrAppend(cellShape + \".cell-shape-\" + cellShape);\r\n\r\n if (plot.correlation.shape.type == 'circle') {\r\n\r\n shapes\r\n .attr(\"r\", plot.correlation.shape.radius)\r\n .attr(\"cx\", 0)\r\n .attr(\"cy\", 0);\r\n }\r\n\r\n if (plot.correlation.shape.type == 'ellipse') {\r\n // cells.attr(\"transform\", c=> \"translate(300,150) rotate(\"+plot.correlation.shape.rotateVal(c.value)+\")\");\r\n shapes\r\n .attr(\"rx\", plot.correlation.shape.radiusX)\r\n .attr(\"ry\", plot.correlation.shape.radiusY)\r\n .attr(\"cx\", 0)\r\n .attr(\"cy\", 0)\r\n\r\n .attr(\"transform\", c=> \"rotate(\" + plot.correlation.shape.rotateVal(c.value) + \")\");\r\n }\r\n\r\n\r\n if (plot.correlation.shape.type == 'rect') {\r\n shapes\r\n .attr(\"width\", plot.correlation.shape.size)\r\n .attr(\"height\", plot.correlation.shape.size)\r\n .attr(\"x\", -plot.cellSize / 2)\r\n .attr(\"y\", -plot.cellSize / 2);\r\n }\r\n shapes.style(\"fill\", c=> plot.correlation.color.scale(c.value));\r\n\r\n var mouseoverCallbacks = [];\r\n var mouseoutCallbacks = [];\r\n\r\n if (plot.tooltip) {\r\n\r\n mouseoverCallbacks.push(c=> {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = c.value;\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n });\r\n\r\n mouseoutCallbacks.push(c=> {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n\r\n\r\n }\r\n\r\n if (self.config.highlightLabels) {\r\n var highlightClass = self.config.cssClassPrefix + \"highlight\";\r\n var xLabelClass = c=>plot.labelClass + \"-x-\" + c.col;\r\n var yLabelClass = c=>plot.labelClass + \"-y-\" + c.row;\r\n\r\n\r\n mouseoverCallbacks.push(c=> {\r\n\r\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, true);\r\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, true);\r\n });\r\n mouseoutCallbacks.push(c=> {\r\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, false);\r\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, false);\r\n });\r\n }\r\n\r\n\r\n cells.on(\"mouseover\", c => {\r\n mouseoverCallbacks.forEach(callback=>callback(c));\r\n })\r\n .on(\"mouseout\", c => {\r\n mouseoutCallbacks.forEach(callback=>callback(c));\r\n });\r\n\r\n cells.on(\"click\", c=> {\r\n self.trigger(\"cell-selected\", c);\r\n });\r\n\r\n\r\n cells.exit().remove();\r\n }\r\n\r\n\r\n updateLegend() {\r\n\r\n var plot = this.plot;\r\n var legendX = this.plot.width + 10;\r\n var legendY = 0;\r\n var barWidth = 10;\r\n var barHeight = this.plot.height - 2;\r\n var scale = plot.correlation.color.scale;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY).linearGradientBar(barWidth, barHeight);\r\n\r\n\r\n }\r\n\r\n attachScatterPlot(containerSelector, config) {\r\n var self = this;\r\n\r\n config = config || {};\r\n\r\n\r\n var scatterPlotConfig = {\r\n height: self.plot.height + self.config.margin.top + self.config.margin.bottom,\r\n width: self.plot.height + self.config.margin.top + self.config.margin.bottom,\r\n groups: {\r\n key: self.config.groups.key,\r\n label: self.config.groups.label\r\n },\r\n guides: true,\r\n showLegend: false\r\n };\r\n\r\n self.scatterPlot = true;\r\n\r\n scatterPlotConfig = Utils.deepExtend(scatterPlotConfig, config);\r\n this.update();\r\n\r\n this.on(\"cell-selected\", c=> {\r\n\r\n\r\n scatterPlotConfig.x = {\r\n key: c.rowVar,\r\n label: self.plot.labelByVariable[c.rowVar]\r\n };\r\n scatterPlotConfig.y = {\r\n key: c.colVar,\r\n label: self.plot.labelByVariable[c.colVar]\r\n };\r\n if (self.scatterPlot && self.scatterPlot !== true) {\r\n self.scatterPlot.setConfig(scatterPlotConfig).init();\r\n } else {\r\n self.scatterPlot = new ScatterPlot(containerSelector, self.data, scatterPlotConfig);\r\n this.attach(\"ScatterPlot\", self.scatterPlot);\r\n }\r\n\r\n\r\n });\r\n\r\n\r\n }\r\n}\r\n","import {Utils} from './utils'\r\n\r\n\r\nexport class D3Extensions{\r\n\r\n static extend(){\r\n\r\n d3.selection.enter.prototype.insertSelector =\r\n d3.selection.prototype.insertSelector = function(selector, before) {\r\n return Utils.insertSelector(this, selector, before);\r\n };\r\n\r\n\r\n d3.selection.enter.prototype.appendSelector =\r\n d3.selection.prototype.appendSelector = function(selector) {\r\n return Utils.appendSelector(this, selector);\r\n };\r\n\r\n d3.selection.enter.prototype.selectOrAppend =\r\n d3.selection.prototype.selectOrAppend = function(selector) {\r\n return Utils.selectOrAppend(this, selector);\r\n };\r\n\r\n d3.selection.enter.prototype.selectOrInsert =\r\n d3.selection.prototype.selectOrInsert = function(selector, before) {\r\n return Utils.selectOrInsert(this, selector, before);\r\n };\r\n\r\n\r\n\r\n }\r\n}\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Heatmap, HeatmapConfig} from \"./heatmap\";\r\nimport {Utils} from './utils'\r\nimport {StatisticsUtils} from './statistics-utils'\r\n\r\n\r\nexport class HeatmapTimeSeriesConfig extends HeatmapConfig {\r\n x = {\r\n fillMissing: false, // fill missing values using interval and intervalStep\r\n interval: undefined, //used in filling missing ticks\r\n intervalStep: 1,\r\n format: undefined, //input data d3 time format\r\n displayFormat: undefined,//d3 time format for display\r\n intervalToFormats: [ //used to guess interval and format\r\n {\r\n name: 'year',\r\n formats: [\"%Y\"]\r\n },\r\n {\r\n name: 'month',\r\n formats: [\"%Y-%m\"]\r\n },\r\n {\r\n name: 'day',\r\n formats: [\"%Y-%m-%d\"]\r\n },\r\n {\r\n name: 'hour',\r\n formats: ['%H', '%Y-%m-%d %H']\r\n },\r\n {\r\n name: 'minute',\r\n formats: ['%H:%M', '%Y-%m-%d %H:%M']\r\n },\r\n {\r\n name: 'second',\r\n formats: ['%H:%M:%S', '%Y-%m-%d %H:%M:%S']\r\n }\r\n ],\r\n\r\n sortComparator: function sortComparator(a, b) {\r\n return Utils.isString(a) ? a.localeCompare(b) : a - b;\r\n },\r\n formatter: undefined\r\n };\r\n z = {\r\n fillMissing: true // fiill missing values with nearest previous value\r\n };\r\n\r\n legend = {\r\n formatter: function (v) {\r\n var suffix = \"\";\r\n if (v / 1000000 >= 1) {\r\n suffix = \" M\";\r\n v = Number(v / 1000000).toFixed(3);\r\n }\r\n var nf = Intl.NumberFormat();\r\n return nf.format(v) + suffix;\r\n }\r\n };\r\n\r\n constructor(custom) {\r\n super();\r\n\r\n if (custom) {\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class HeatmapTimeSeries extends Heatmap {\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new HeatmapTimeSeriesConfig(config));\r\n }\r\n\r\n setConfig(config) {\r\n return super.setConfig(new HeatmapTimeSeriesConfig(config));\r\n }\r\n\r\n\r\n setupValuesBeforeGroupsSort() {\r\n\r\n this.plot.x.timeFormat = this.config.x.format;\r\n if(this.config.x.displayFormat && !this.plot.x.timeFormat){\r\n this.guessTimeFormat();\r\n }\r\n\r\n\r\n super.setupValuesBeforeGroupsSort();\r\n if (!this.config.x.fillMissing) {\r\n return;\r\n }\r\n\r\n var self = this;\r\n\r\n this.initTimeFormatAndInterval();\r\n\r\n this.plot.x.intervalStep = this.config.x.intervalStep || 1;\r\n\r\n this.plot.x.timeParser = this.getTimeParser();\r\n\r\n\r\n\r\n this.plot.x.uniqueValues.sort(this.config.x.sortComparator);\r\n\r\n var prev = null;\r\n\r\n this.plot.x.uniqueValues.forEach((x, i)=> {\r\n var current = this.parseTime(x);\r\n if (prev === null) {\r\n prev = current;\r\n return;\r\n }\r\n\r\n var next = self.nextTimeTickValue(prev);\r\n var missing = [];\r\n var iteration = 0;\r\n while (self.compareTimeValues(next, current)<=0) {\r\n iteration++;\r\n if (iteration > 100) {\r\n break;\r\n }\r\n var d = {};\r\n var timeString = self.formatTime(next);\r\n d[this.config.x.key] = timeString;\r\n\r\n self.updateGroups(d, timeString, self.plot.x.groups, self.config.x.groups);\r\n missing.push(next);\r\n next = self.nextTimeTickValue(next);\r\n }\r\n prev = current;\r\n });\r\n\r\n }\r\n\r\n parseTime(x) {\r\n var parser = this.getTimeParser();\r\n return parser.parse(x);\r\n }\r\n\r\n formatTime(date){\r\n var parser = this.getTimeParser();\r\n return parser(date);\r\n }\r\n\r\n formatValueX(value) { //used only for display\r\n if (this.config.x.formatter) return this.config.x.formatter.call(this.config, value);\r\n\r\n if(this.config.x.displayFormat){\r\n var date = this.parseTime(value);\r\n return d3.time.format(this.config.x.displayFormat)(date);\r\n }\r\n\r\n if(!this.plot.x.timeFormat) return value;\r\n\r\n if(Utils.isDate(value)){\r\n return this.formatTime(value);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n compareTimeValues(a, b){\r\n return a-b;\r\n }\r\n\r\n timeValuesEqual(a, b) {\r\n var parser = this.plot.x.timeParser;\r\n return parser(a) === parser(b);\r\n }\r\n\r\n nextTimeTickValue(t) {\r\n var interval = this.plot.x.interval;\r\n return d3.time[interval].offset(t, this.plot.x.intervalStep);\r\n }\r\n\r\n initPlot() {\r\n super.initPlot();\r\n\r\n if (this.config.z.fillMissing) {\r\n this.plot.matrix.forEach((row, rowIndex) => {\r\n var prevRowValue = undefined;\r\n row.forEach((cell, colIndex) => {\r\n if (cell.value === undefined && prevRowValue !== undefined) {\r\n cell.value = prevRowValue;\r\n cell.missing = true;\r\n }\r\n prevRowValue = cell.value;\r\n });\r\n });\r\n }\r\n\r\n\r\n }\r\n\r\n update(newData) {\r\n super.update(newData);\r\n\r\n };\r\n\r\n\r\n initTimeFormatAndInterval() {\r\n\r\n this.plot.x.interval = this.config.x.interval;\r\n\r\n if(!this.plot.x.timeFormat){\r\n this.guessTimeFormat();\r\n }\r\n\r\n if(!this.plot.x.interval && this.plot.x.timeFormat){\r\n this.guessInterval();\r\n }\r\n }\r\n\r\n guessTimeFormat() {\r\n var self = this;\r\n for(let i=0; i < self.config.x.intervalToFormats.length; i++){\r\n let intervalFormat = self.config.x.intervalToFormats[i];\r\n var format = null;\r\n var formatMatch = intervalFormat.formats.some(f=>{\r\n format = f;\r\n var parser = d3.time.format(f);\r\n return self.plot.x.uniqueValues.every(x=>{\r\n return parser.parse(x) !== null\r\n });\r\n });\r\n if(formatMatch){\r\n self.plot.x.timeFormat = format;\r\n console.log('Guessed timeFormat', format);\r\n if(!self.plot.x.interval){\r\n self.plot.x.interval = intervalFormat.name;\r\n console.log('Guessed interval', self.plot.x.interval);\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n\r\n guessInterval() {\r\n var self = this;\r\n for(let i=0; i < self.config.x.intervalToFormats.length; i++) {\r\n let intervalFormat = self.config.x.intervalToFormats[i];\r\n\r\n if(intervalFormat.formats.indexOf(self.plot.x.timeFormat) >= 0){\r\n self.plot.x.interval = intervalFormat.name;\r\n console.log('Guessed interval', self.plot.x.interval);\r\n return;\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n\r\n getTimeParser() {\r\n if(!this.plot.x.timeParser){\r\n this.plot.x.timeParser = d3.time.format(this.plot.x.timeFormat);\r\n }\r\n return this.plot.x.timeParser;\r\n }\r\n}\r\n\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from './legend'\r\n\r\n\r\nexport class HeatmapConfig extends ChartConfig {\r\n\r\n svgClass = 'odc-heatmap';\r\n showTooltip = true; //show tooltip on dot hover\r\n tooltip = {\r\n noDataText: \"N/A\"\r\n };\r\n showLegend = true;\r\n legend = {\r\n width: 30,\r\n rotateLabels: false,\r\n decimalPlaces: undefined,\r\n formatter: v => this.legend.decimalPlaces === undefined ? v : Number(v).toFixed(this.legend.decimalPlaces)\r\n }\r\n highlightLabels = true;\r\n x = {// X axis config\r\n title: '', // axis title\r\n key: 0,\r\n value: (d) => d[this.x.key], // x value accessor\r\n rotateLabels: true,\r\n sortLabels: false,\r\n sortComparator: (a, b)=> Utils.isNumber(a) ? a - b : a.localeCompare(b),\r\n groups: {\r\n keys: [],\r\n labels: [],\r\n value: (d, key) => d[key],\r\n overlap: {\r\n top: 20,\r\n bottom: 20\r\n }\r\n },\r\n formatter: undefined // value formatter function\r\n\r\n };\r\n y = {// Y axis config\r\n title: '', // axis title,\r\n rotateLabels: true,\r\n key: 1,\r\n value: (d) => d[this.y.key], // y value accessor\r\n sortLabels: false,\r\n sortComparator: (a, b)=> Utils.isNumber(b) ? b - a : b.localeCompare(a),\r\n groups: {\r\n keys: [],\r\n labels: [],\r\n value: (d, key) => d[key],\r\n overlap: {\r\n left: 20,\r\n right: 20\r\n }\r\n },\r\n formatter: undefined// value formatter function\r\n };\r\n z = {\r\n key: 2,\r\n value: (d) => d[this.z.key],\r\n notAvailableValue: (v) => v === null || v === undefined,\r\n\r\n decimalPlaces: undefined,\r\n formatter: v => this.z.decimalPlaces === undefined ? v : Number(v).toFixed(this.z.decimalPlaces)// value formatter function\r\n\r\n };\r\n color = {\r\n noDataColor: \"white\",\r\n scale: \"linear\",\r\n reverseScale: false,\r\n range: [\"darkblue\", \"lightskyblue\", \"orange\", \"crimson\", \"darkred\"]\r\n };\r\n cell = {\r\n width: undefined,\r\n height: undefined,\r\n sizeMin: 15,\r\n sizeMax: 250,\r\n padding: 0\r\n };\r\n margin = {\r\n left: 60,\r\n right: 50,\r\n top: 30,\r\n bottom: 80\r\n };\r\n\r\n constructor(custom) {\r\n super();\r\n if (custom) {\r\n Utils.deepExtend(this, custom);\r\n }\r\n }\r\n}\r\n\r\n//TODO refactor\r\nexport class Heatmap extends Chart {\r\n\r\n static maxGroupGapSize = 24;\r\n static groupTitleRectHeight = 6;\r\n\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new HeatmapConfig(config));\r\n }\r\n\r\n setConfig(config) {\r\n return super.setConfig(new HeatmapConfig(config));\r\n\r\n }\r\n\r\n initPlot() {\r\n super.initPlot();\r\n var self = this;\r\n var margin = this.config.margin;\r\n var conf = this.config;\r\n\r\n this.plot.x = {};\r\n this.plot.y = {};\r\n this.plot.z = {\r\n matrixes: undefined,\r\n cells: undefined,\r\n color: {},\r\n shape: {}\r\n };\r\n\r\n\r\n this.setupValues();\r\n this.buildCells();\r\n\r\n var titleRectWidth = 6;\r\n this.plot.x.overlap = {\r\n top: 0,\r\n bottom: 0\r\n };\r\n if (this.plot.groupByX) {\r\n let depth = self.config.x.groups.keys.length;\r\n let allTitlesWidth = depth * (titleRectWidth);\r\n\r\n this.plot.x.overlap.bottom = self.config.x.groups.overlap.bottom;\r\n this.plot.x.overlap.top = self.config.x.groups.overlap.top + allTitlesWidth;\r\n this.plot.margin.top = conf.margin.right + conf.x.groups.overlap.top;\r\n this.plot.margin.bottom = conf.margin.bottom + conf.x.groups.overlap.bottom;\r\n }\r\n\r\n\r\n this.plot.y.overlap = {\r\n left: 0,\r\n right: 0\r\n };\r\n\r\n\r\n if (this.plot.groupByY) {\r\n let depth = self.config.y.groups.keys.length;\r\n let allTitlesWidth = depth * (titleRectWidth);\r\n this.plot.y.overlap.right = self.config.y.groups.overlap.left + allTitlesWidth;\r\n this.plot.y.overlap.left = self.config.y.groups.overlap.left;\r\n this.plot.margin.left = conf.margin.left + this.plot.y.overlap.left;\r\n this.plot.margin.right = conf.margin.right + this.plot.y.overlap.right;\r\n }\r\n this.plot.showLegend = conf.showLegend;\r\n if (this.plot.showLegend) {\r\n this.plot.margin.right += conf.legend.width;\r\n }\r\n this.computePlotSize();\r\n this.setupZScale();\r\n\r\n return this;\r\n }\r\n\r\n setupValues() {\r\n var self = this;\r\n var config = self.config;\r\n var x = self.plot.x;\r\n var y = self.plot.y;\r\n var z = self.plot.z;\r\n\r\n\r\n x.value = d => config.x.value.call(config, d);\r\n y.value = d => config.y.value.call(config, d);\r\n z.value = d => config.z.value.call(config, d);\r\n\r\n x.uniqueValues = [];\r\n y.uniqueValues = [];\r\n\r\n\r\n self.plot.groupByY = !!config.y.groups.keys.length;\r\n self.plot.groupByX = !!config.x.groups.keys.length;\r\n\r\n y.groups = {\r\n key: undefined,\r\n label: '',\r\n values: [],\r\n children: null,\r\n level: 0,\r\n index: 0,\r\n lastIndex: 0\r\n };\r\n x.groups = {\r\n key: undefined,\r\n label: '',\r\n values: [],\r\n children: null,\r\n level: 0,\r\n index: 0,\r\n lastIndex: 0\r\n };\r\n\r\n var valueMap = {};\r\n var minZ = undefined;\r\n var maxZ = undefined;\r\n this.data.forEach(d=> {\r\n\r\n var xVal = x.value(d);\r\n var yVal = y.value(d);\r\n var zValRaw = z.value(d);\r\n var zVal = config.z.notAvailableValue(zValRaw) ? undefined : parseFloat(zValRaw);\r\n\r\n\r\n if (x.uniqueValues.indexOf(xVal) === -1) {\r\n x.uniqueValues.push(xVal);\r\n }\r\n\r\n if (y.uniqueValues.indexOf(yVal) === -1) {\r\n y.uniqueValues.push(yVal);\r\n }\r\n\r\n var groupY = y.groups;\r\n if (self.plot.groupByY) {\r\n groupY = this.updateGroups(d, yVal, y.groups, config.y.groups);\r\n }\r\n var groupX = x.groups;\r\n if (self.plot.groupByX) {\r\n\r\n groupX = this.updateGroups(d, xVal, x.groups, config.x.groups);\r\n }\r\n\r\n if (!valueMap[groupY.index]) {\r\n valueMap[groupY.index] = {};\r\n }\r\n\r\n if (!valueMap[groupY.index][groupX.index]) {\r\n valueMap[groupY.index][groupX.index] = {};\r\n }\r\n if (!valueMap[groupY.index][groupX.index][yVal]) {\r\n valueMap[groupY.index][groupX.index][yVal] = {};\r\n }\r\n valueMap[groupY.index][groupX.index][yVal][xVal] = zVal;\r\n\r\n\r\n if (minZ === undefined || zVal < minZ) {\r\n minZ = zVal;\r\n }\r\n if (maxZ === undefined || zVal > maxZ) {\r\n maxZ = zVal;\r\n }\r\n });\r\n self.plot.valueMap = valueMap;\r\n\r\n\r\n if (!self.plot.groupByX) {\r\n x.groups.values = x.uniqueValues;\r\n }\r\n\r\n if (!self.plot.groupByY) {\r\n y.groups.values = y.uniqueValues;\r\n }\r\n\r\n this.setupValuesBeforeGroupsSort();\r\n\r\n x.gaps = [];\r\n x.totalValuesCount = 0;\r\n x.allValuesList = [];\r\n this.sortGroups(x, x.groups, config.x);\r\n\r\n y.gaps = [];\r\n y.totalValuesCount = 0;\r\n y.allValuesList = [];\r\n this.sortGroups(y, y.groups, config.y);\r\n\r\n z.min = minZ;\r\n z.max = maxZ;\r\n\r\n }\r\n\r\n setupValuesBeforeGroupsSort() {\r\n }\r\n\r\n buildCells() {\r\n var self = this;\r\n var x = self.plot.x;\r\n var y = self.plot.y;\r\n var z = self.plot.z;\r\n var valueMap = self.plot.valueMap;\r\n\r\n var matrixCells = self.plot.cells = [];\r\n var matrix = self.plot.matrix = [];\r\n\r\n y.allValuesList.forEach((v1, i)=> {\r\n var row = [];\r\n matrix.push(row);\r\n\r\n x.allValuesList.forEach((v2, j) => {\r\n var zVal = undefined;\r\n try {\r\n zVal = valueMap[v1.group.index][v2.group.index][v1.val][v2.val]\r\n } catch (e) {\r\n }\r\n\r\n var cell = {\r\n rowVar: v1,\r\n colVar: v2,\r\n row: i,\r\n col: j,\r\n value: zVal\r\n };\r\n row.push(cell);\r\n\r\n matrixCells.push(cell);\r\n });\r\n });\r\n\r\n }\r\n\r\n updateGroups(d, axisVal, rootGroup, axisGroupsConfig) {\r\n\r\n var config = this.config;\r\n var currentGroup = rootGroup;\r\n axisGroupsConfig.keys.forEach((groupKey, groupKeyIndex) => {\r\n currentGroup.key = groupKey;\r\n\r\n if (!currentGroup.children) {\r\n currentGroup.children = {};\r\n }\r\n\r\n var groupingValue = axisGroupsConfig.value.call(config, d, groupKey);\r\n\r\n if (!currentGroup.children.hasOwnProperty(groupingValue)) {\r\n rootGroup.lastIndex++;\r\n currentGroup.children[groupingValue] = {\r\n values: [],\r\n children: null,\r\n groupingValue: groupingValue,\r\n level: currentGroup.level + 1,\r\n index: rootGroup.lastIndex,\r\n key: groupKey\r\n }\r\n }\r\n\r\n currentGroup = currentGroup.children[groupingValue];\r\n });\r\n\r\n if (currentGroup.values.indexOf(axisVal) === -1) {\r\n currentGroup.values.push(axisVal);\r\n }\r\n\r\n return currentGroup;\r\n }\r\n\r\n sortGroups(axis, group, axisConfig, gaps) {\r\n if (axisConfig.groups.labels && axisConfig.groups.labels.length > group.level) {\r\n group.label = axisConfig.groups.labels[group.level];\r\n } else {\r\n group.label = group.key;\r\n }\r\n\r\n if (!gaps) {\r\n gaps = [0];\r\n }\r\n if (gaps.length <= group.level) {\r\n gaps.push(0);\r\n }\r\n\r\n group.allValuesCount = group.allValuesCount || 0;\r\n group.allValuesBeforeCount = group.allValuesBeforeCount || 0;\r\n\r\n group.gaps = gaps.slice();\r\n group.gapsBefore = gaps.slice();\r\n\r\n\r\n group.gapsSize = Heatmap.computeGapsSize(group.gaps);\r\n group.gapsBeforeSize = group.gapsSize;\r\n if (group.values) {\r\n if (axisConfig.sortLabels) {\r\n group.values.sort(axisConfig.sortComparator);\r\n }\r\n group.values.forEach(v=>axis.allValuesList.push({val: v, group: group}));\r\n group.allValuesBeforeCount = axis.totalValuesCount;\r\n axis.totalValuesCount += group.values.length;\r\n group.allValuesCount += group.values.length;\r\n }\r\n\r\n group.childrenList = [];\r\n if (group.children) {\r\n var childrenCount = 0;\r\n\r\n for (var childProp in group.children) {\r\n if (group.children.hasOwnProperty(childProp)) {\r\n var child = group.children[childProp];\r\n group.childrenList.push(child);\r\n childrenCount++;\r\n\r\n this.sortGroups(axis, child, axisConfig, gaps);\r\n group.allValuesCount += child.allValuesCount;\r\n gaps[group.level] += 1;\r\n }\r\n }\r\n\r\n if (gaps && childrenCount > 1) {\r\n gaps[group.level] -= 1;\r\n }\r\n\r\n group.gapsInside = [];\r\n gaps.forEach((d, i)=> {\r\n group.gapsInside.push(d - (group.gapsBefore[i] || 0));\r\n });\r\n group.gapsInsideSize = Heatmap.computeGapsSize(group.gapsInside);\r\n\r\n if (axis.gaps.length < gaps.length) {\r\n axis.gaps = gaps;\r\n }\r\n }\r\n\r\n }\r\n\r\n computeYAxisLabelsWidth(offset) {\r\n var maxWidth = this.plot.margin.left;\r\n if (this.config.y.title) {\r\n maxWidth -= 15;\r\n }\r\n if (offset && offset.x) {\r\n maxWidth += offset.x;\r\n }\r\n\r\n if (this.config.y.rotateLabels) {\r\n maxWidth *= Utils.SQRT_2;\r\n var fontSize = 11; //todo check actual font size\r\n maxWidth -=fontSize/2;\r\n }\r\n\r\n return maxWidth;\r\n }\r\n\r\n computeXAxisLabelsWidth(offset) {\r\n if (!this.config.x.rotateLabels) {\r\n return this.plot.cellWidth - 2;\r\n }\r\n var size = this.plot.margin.bottom;\r\n if (this.config.x.title) {\r\n size -= 15;\r\n }\r\n if (offset && offset.y) {\r\n size -= offset.y;\r\n }\r\n\r\n size *= Utils.SQRT_2;\r\n\r\n var fontSize = 11; //todo check actual font size\r\n size -=fontSize/2;\r\n\r\n return size;\r\n }\r\n\r\n static computeGapSize(gapLevel) {\r\n return Heatmap.maxGroupGapSize / (gapLevel + 1);\r\n }\r\n\r\n static computeGapsSize(gaps) {\r\n var gapsSize = 0;\r\n gaps.forEach((gapsNumber, gapsLevel)=> gapsSize += gapsNumber * Heatmap.computeGapSize(gapsLevel));\r\n return gapsSize;\r\n }\r\n\r\n computePlotSize() {\r\n\r\n var plot = this.plot;\r\n var conf = this.config;\r\n var margin = plot.margin;\r\n var availableWidth = Utils.availableWidth(this.config.width, this.getBaseContainer(), this.plot.margin);\r\n var availableHeight = Utils.availableHeight(this.config.height, this.getBaseContainer(), this.plot.margin);\r\n var width = availableWidth;\r\n var height = availableHeight;\r\n\r\n var xGapsSize = Heatmap.computeGapsSize(plot.x.gaps);\r\n\r\n\r\n var computedCellWidth = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (availableWidth - xGapsSize) / this.plot.x.totalValuesCount));\r\n if (this.config.width) {\r\n\r\n if (!this.config.cell.width) {\r\n this.plot.cellWidth = computedCellWidth;\r\n }\r\n\r\n } else {\r\n this.plot.cellWidth = this.config.cell.width;\r\n\r\n if (!this.plot.cellWidth) {\r\n this.plot.cellWidth = computedCellWidth;\r\n }\r\n\r\n }\r\n width = this.plot.cellWidth * this.plot.x.totalValuesCount + margin.left + margin.right + xGapsSize;\r\n\r\n var yGapsSize = Heatmap.computeGapsSize(plot.y.gaps);\r\n var computedCellHeight = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (availableHeight - yGapsSize) / this.plot.y.totalValuesCount));\r\n if (this.config.height) {\r\n if (!this.config.cell.height) {\r\n this.plot.cellHeight = computedCellHeight;\r\n }\r\n } else {\r\n this.plot.cellHeight = this.config.cell.height;\r\n\r\n if (!this.plot.cellHeight) {\r\n this.plot.cellHeight = computedCellHeight;\r\n }\r\n\r\n }\r\n\r\n height = this.plot.cellHeight * this.plot.y.totalValuesCount + margin.top + margin.bottom + yGapsSize;\r\n\r\n\r\n this.plot.width = width - margin.left - margin.right;\r\n this.plot.height = height - margin.top - margin.bottom;\r\n }\r\n\r\n\r\n setupZScale() {\r\n\r\n var self = this;\r\n var config = self.config;\r\n var z = self.plot.z;\r\n var range = config.color.range;\r\n var extent = z.max - z.min;\r\n var scale;\r\n z.domain = [];\r\n if (config.color.scale == \"pow\") {\r\n var exponent = 10;\r\n range.forEach((c, i)=> {\r\n var v = z.max - (extent / Math.pow(10, i));\r\n z.domain.push(v)\r\n });\r\n scale = d3.scale.pow().exponent(exponent);\r\n } else if (config.color.scale == \"log\") {\r\n\r\n range.forEach((c, i)=> {\r\n var v = z.min + (extent / Math.pow(10, i));\r\n z.domain.unshift(v)\r\n\r\n });\r\n\r\n scale = d3.scale.log()\r\n } else {\r\n range.forEach((c, i)=> {\r\n var v = z.min + (extent * (i / (range.length - 1)));\r\n z.domain.push(v)\r\n });\r\n scale = d3.scale[config.color.scale]();\r\n }\r\n\r\n\r\n z.domain[0] = z.min; //removing unnecessary floating points\r\n z.domain[z.domain.length - 1] = z.max; //removing unnecessary floating points\r\n console.log(z.domain);\r\n\r\n if (config.color.reverseScale) {\r\n z.domain.reverse();\r\n }\r\n\r\n var plot = this.plot;\r\n\r\n console.log(range);\r\n plot.z.color.scale = scale.domain(z.domain).range(range);\r\n var shape = plot.z.shape = {};\r\n\r\n var cellConf = this.config.cell;\r\n shape.type = \"rect\";\r\n\r\n plot.z.shape.width = plot.cellWidth - cellConf.padding * 2;\r\n plot.z.shape.height = plot.cellHeight - cellConf.padding * 2;\r\n }\r\n\r\n\r\n update(newData) {\r\n super.update(newData);\r\n if (this.plot.groupByY) {\r\n this.drawGroupsY(this.plot.y.groups, this.svgG);\r\n }\r\n if (this.plot.groupByX) {\r\n this.drawGroupsX(this.plot.x.groups, this.svgG);\r\n }\r\n\r\n this.updateCells();\r\n\r\n // this.updateVariableLabels();\r\n\r\n this.updateAxisX();\r\n this.updateAxisY();\r\n\r\n if (this.config.showLegend) {\r\n this.updateLegend();\r\n }\r\n\r\n this.updateAxisTitles();\r\n };\r\n\r\n updateAxisTitles() {\r\n var self = this;\r\n var plot = self.plot;\r\n\r\n\r\n }\r\n\r\n\r\n updateAxisX() {\r\n var self = this;\r\n var plot = self.plot;\r\n var labelClass = self.prefixClass(\"label\");\r\n var labelXClass = labelClass + \"-x\";\r\n var labelYClass = labelClass + \"-y\";\r\n plot.labelClass = labelClass;\r\n\r\n var offsetX = {\r\n x: 0,\r\n y: 0\r\n };\r\n let gapSize = Heatmap.computeGapSize(0);\r\n if (plot.groupByX) {\r\n let overlap = self.config.x.groups.overlap;\r\n\r\n offsetX.x = gapSize / 2;\r\n offsetX.y = overlap.bottom + gapSize / 2 + 6;\r\n } else if (plot.groupByY) {\r\n offsetX.y = gapSize;\r\n }\r\n\r\n\r\n var labels = self.svgG.selectAll(\"text.\" + labelXClass)\r\n .data(plot.x.allValuesList, (d, i)=>i);\r\n\r\n labels.enter().append(\"text\").attr(\"class\", (d, i) => labelClass + \" \" + labelXClass + \" \" + labelXClass + \"-\" + i);\r\n\r\n labels\r\n .attr(\"x\", (d, i) => (i * plot.cellWidth + plot.cellWidth / 2) + (d.group.gapsSize) + offsetX.x)\r\n .attr(\"y\", plot.height + offsetX.y)\r\n .attr(\"dy\", 10)\r\n\r\n .attr(\"text-anchor\", \"middle\")\r\n .text(d=>self.formatValueX(d.val));\r\n\r\n\r\n\r\n var maxWidth = self.computeXAxisLabelsWidth(offsetX);\r\n\r\n labels.each(function (label) {\r\n var elem = d3.select(this),\r\n text = self.formatValueX(label.val);\r\n Utils.placeTextWithEllipsisAndTooltip(elem, text, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\r\n });\r\n\r\n if (self.config.x.rotateLabels) {\r\n labels.attr(\"transform\", (d, i) => \"rotate(-45, \" + ((i * plot.cellWidth + plot.cellWidth / 2) + d.group.gapsSize + offsetX.x ) + \", \" + ( plot.height + offsetX.y) + \")\")\r\n .attr(\"dx\", -2)\r\n .attr(\"dy\", 8)\r\n .attr(\"text-anchor\", \"end\");\r\n }\r\n\r\n\r\n labels.exit().remove();\r\n\r\n\r\n self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x'))\r\n .attr(\"transform\", \"translate(\" + (plot.width / 2) + \",\" + (plot.height + plot.margin.bottom) + \")\")\r\n .selectOrAppend(\"text.\" + self.prefixClass('label'))\r\n\r\n .attr(\"dy\", \"-0.5em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(self.config.x.title);\r\n }\r\n\r\n updateAxisY() {\r\n var self = this;\r\n var plot = self.plot;\r\n var labelClass = self.prefixClass(\"label\");\r\n var labelYClass = labelClass + \"-y\";\r\n plot.labelClass = labelClass;\r\n\r\n\r\n var labels = self.svgG.selectAll(\"text.\" + labelYClass)\r\n .data(plot.y.allValuesList);\r\n\r\n labels.enter().append(\"text\");\r\n\r\n var offsetY = {\r\n x: 0,\r\n y: 0\r\n };\r\n if (plot.groupByY) {\r\n let overlap = self.config.y.groups.overlap;\r\n let gapSize = Heatmap.computeGapSize(0);\r\n offsetY.x = -overlap.left;\r\n\r\n offsetY.y = gapSize / 2;\r\n }\r\n labels\r\n .attr(\"x\", offsetY.x)\r\n .attr(\"y\", (d, i) => (i * plot.cellHeight + plot.cellHeight / 2) + d.group.gapsSize + offsetY.y)\r\n .attr(\"dx\", -2)\r\n .attr(\"text-anchor\", \"end\")\r\n .attr(\"class\", (d, i) => labelClass + \" \" + labelYClass + \" \" + labelYClass + \"-\" + i)\r\n\r\n .text(function (d) {\r\n var formatted = self.formatValueY(d.val);\r\n return formatted\r\n });\r\n\r\n var maxWidth = self.computeYAxisLabelsWidth(offsetY);\r\n\r\n labels.each(function (label) {\r\n var elem = d3.select(this),\r\n text = self.formatValueY(label.val);\r\n Utils.placeTextWithEllipsisAndTooltip(elem, text, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\r\n });\r\n\r\n if (self.config.y.rotateLabels) {\r\n labels\r\n .attr(\"transform\", (d, i) => \"rotate(-45, \" + (offsetY.x ) + \", \" + (d.group.gapsSize + (i * plot.cellHeight + plot.cellHeight / 2) + offsetY.y) + \")\")\r\n .attr(\"text-anchor\", \"end\");\r\n // .attr(\"dx\", -7);\r\n } else {\r\n labels.attr(\"dominant-baseline\", \"middle\")\r\n }\r\n\r\n\r\n labels.exit().remove();\r\n\r\n\r\n self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y'))\r\n .selectOrAppend(\"text.\" + self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + (plot.height / 2) + \")rotate(-90)\")\r\n .attr(\"dy\", \"1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(self.config.y.title);\r\n\r\n }\r\n\r\n\r\n drawGroupsY(parentGroup, container, availableWidth) {\r\n\r\n var self = this;\r\n var plot = self.plot;\r\n\r\n var groupClass = self.prefixClass(\"group\");\r\n var groupYClass = groupClass + \"-y\";\r\n var groups = container.selectAll(\"g.\" + groupClass + \".\" + groupYClass)\r\n .data(parentGroup.childrenList);\r\n\r\n var valuesBeforeCount = 0;\r\n var gapsBeforeSize = 0;\r\n\r\n var groupsEnterG = groups.enter().append(\"g\");\r\n groupsEnterG\r\n .classed(groupClass, true)\r\n .classed(groupYClass, true)\r\n .append(\"rect\").classed(\"group-rect\", true);\r\n\r\n var titleGroupEnter = groupsEnterG.appendSelector(\"g.title\");\r\n titleGroupEnter.append(\"rect\");\r\n titleGroupEnter.append(\"text\");\r\n\r\n var gapSize = Heatmap.computeGapSize(parentGroup.level);\r\n var padding = gapSize / 4;\r\n\r\n var titleRectWidth = Heatmap.groupTitleRectHeight;\r\n var depth = self.config.y.groups.keys.length - parentGroup.level;\r\n var overlap = {\r\n left: 0,\r\n right: 0\r\n };\r\n\r\n if (!availableWidth) {\r\n overlap.right = plot.y.overlap.left;\r\n overlap.left = plot.y.overlap.left;\r\n availableWidth = plot.width + gapSize + overlap.left + overlap.right;\r\n }\r\n\r\n\r\n groups\r\n .attr(\"transform\", (d, i) => {\r\n var translate = \"translate(\" + (padding - overlap.left) + \",\" + ((plot.cellHeight * valuesBeforeCount) + i * gapSize + gapsBeforeSize + padding) + \")\";\r\n gapsBeforeSize += (d.gapsInsideSize || 0);\r\n valuesBeforeCount += d.allValuesCount || 0;\r\n return translate\r\n });\r\n\r\n\r\n var groupWidth = availableWidth - padding * 2;\r\n\r\n var titleGroups = groups.selectAll(\"g.title\")\r\n .attr(\"transform\", (d, i) => \"translate(\" + (groupWidth - titleRectWidth) + \", 0)\");\r\n\r\n var tileRects = titleGroups.selectAll(\"rect\")\r\n .attr(\"width\", titleRectWidth)\r\n .attr(\"height\", d=> {\r\n return (d.gapsInsideSize || 0) + plot.cellHeight * d.allValuesCount + padding * 2\r\n })\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n // .attr(\"fill\", \"lightgrey\")\r\n .attr(\"stroke-width\", 0);\r\n\r\n this.setGroupMouseCallbacks(parentGroup, tileRects);\r\n\r\n\r\n groups.selectAll(\"rect.group-rect\")\r\n .attr(\"class\", d=> \"group-rect group-rect-\" + d.index)\r\n .attr(\"width\", groupWidth)\r\n .attr(\"height\", d=> {\r\n return (d.gapsInsideSize || 0) + plot.cellHeight * d.allValuesCount + padding * 2\r\n })\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n .attr(\"fill\", \"white\")\r\n .attr(\"fill-opacity\", 0)\r\n .attr(\"stroke-width\", 0.5)\r\n .attr(\"stroke\", \"black\")\r\n\r\n\r\n groups.each(function (group) {\r\n\r\n self.drawGroupsY.call(self, group, d3.select(this), groupWidth - titleRectWidth);\r\n });\r\n\r\n }\r\n\r\n drawGroupsX(parentGroup, container, availableHeight) {\r\n\r\n var self = this;\r\n var plot = self.plot;\r\n\r\n var groupClass = self.prefixClass(\"group\");\r\n var groupXClass = groupClass + \"-x\";\r\n var groups = container.selectAll(\"g.\" + groupClass + \".\" + groupXClass)\r\n .data(parentGroup.childrenList);\r\n\r\n var valuesBeforeCount = 0;\r\n var gapsBeforeSize = 0;\r\n\r\n var groupsEnterG = groups.enter().append(\"g\");\r\n groupsEnterG\r\n .classed(groupClass, true)\r\n .classed(groupXClass, true)\r\n .append(\"rect\").classed(\"group-rect\", true);\r\n\r\n var titleGroupEnter = groupsEnterG.appendSelector(\"g.title\");\r\n titleGroupEnter.append(\"rect\");\r\n titleGroupEnter.append(\"text\");\r\n\r\n var gapSize = Heatmap.computeGapSize(parentGroup.level);\r\n var padding = gapSize / 4;\r\n var titleRectHeight = Heatmap.groupTitleRectHeight;\r\n\r\n var depth = self.config.x.groups.keys.length - parentGroup.level;\r\n\r\n var overlap = {\r\n top: 0,\r\n bottom: 0\r\n };\r\n\r\n if (!availableHeight) {\r\n overlap.bottom = plot.x.overlap.bottom;\r\n overlap.top = plot.x.overlap.top;\r\n availableHeight = plot.height + gapSize + overlap.top + overlap.bottom;\r\n\r\n } else {\r\n overlap.top = -titleRectHeight;\r\n }\r\n // console.log('parentGroup',parentGroup, 'gapSize', gapSize, plot.x.overlap);\r\n\r\n groups\r\n .attr(\"transform\", (d, i) => {\r\n var translate = \"translate(\" + ((plot.cellWidth * valuesBeforeCount) + i * gapSize + gapsBeforeSize + padding) + \", \" + (padding - overlap.top) + \")\";\r\n gapsBeforeSize += (d.gapsInsideSize || 0);\r\n valuesBeforeCount += d.allValuesCount || 0;\r\n return translate\r\n });\r\n\r\n var groupHeight = availableHeight - padding * 2;\r\n\r\n var titleGroups = groups.selectAll(\"g.title\")\r\n .attr(\"transform\", (d, i) => \"translate(0, \" + (0) + \")\");\r\n\r\n\r\n var tileRects = titleGroups.selectAll(\"rect\")\r\n .attr(\"height\", titleRectHeight)\r\n .attr(\"width\", d=> {\r\n return (d.gapsInsideSize || 0) + plot.cellWidth * d.allValuesCount + padding * 2\r\n })\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n // .attr(\"fill\", \"lightgrey\")\r\n .attr(\"stroke-width\", 0);\r\n\r\n this.setGroupMouseCallbacks(parentGroup, tileRects);\r\n\r\n\r\n groups.selectAll(\"rect.group-rect\")\r\n .attr(\"class\", d=> \"group-rect group-rect-\" + d.index)\r\n .attr(\"height\", groupHeight)\r\n .attr(\"width\", d=> {\r\n return (d.gapsInsideSize || 0) + plot.cellWidth * d.allValuesCount + padding * 2\r\n })\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n .attr(\"fill\", \"white\")\r\n .attr(\"fill-opacity\", 0)\r\n .attr(\"stroke-width\", 0.5)\r\n .attr(\"stroke\", \"black\");\r\n\r\n groups.each(function (group) {\r\n self.drawGroupsX.call(self, group, d3.select(this), groupHeight - titleRectHeight);\r\n });\r\n\r\n groups.exit().remove();\r\n\r\n }\r\n\r\n setGroupMouseCallbacks(parentGroup, tileRects) {\r\n var plot = this.plot;\r\n var self = this;\r\n var mouseoverCallbacks = [];\r\n mouseoverCallbacks.push(function (d) {\r\n d3.select(this).classed('highlighted', true);\r\n d3.select(this.parentNode.parentNode).selectAll(\"rect.group-rect-\" + d.index).classed('highlighted', true);\r\n });\r\n\r\n var mouseoutCallbacks = [];\r\n mouseoutCallbacks.push(function (d) {\r\n d3.select(this).classed('highlighted', false);\r\n d3.select(this.parentNode.parentNode).selectAll(\"rect.group-rect-\" + d.index).classed('highlighted', false);\r\n });\r\n if (plot.tooltip) {\r\n\r\n mouseoverCallbacks.push(d=> {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = parentGroup.label + \": \" + d.groupingValue;\r\n\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n });\r\n\r\n mouseoutCallbacks.push(d=> {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n\r\n\r\n }\r\n tileRects.on(\"mouseover\", function (d) {\r\n var self = this;\r\n mouseoverCallbacks.forEach(function (callback) {\r\n callback.call(self, d)\r\n });\r\n });\r\n tileRects.on(\"mouseout\", function (d) {\r\n var self = this;\r\n mouseoutCallbacks.forEach(function (callback) {\r\n callback.call(self, d)\r\n });\r\n });\r\n }\r\n\r\n updateCells() {\r\n\r\n var self = this;\r\n var plot = self.plot;\r\n var cellContainerClass = self.prefixClass(\"cells\");\r\n var gapSize = Heatmap.computeGapSize(0);\r\n var paddingX = plot.x.groups.childrenList.length ? gapSize / 2 : 0;\r\n var paddingY = plot.y.groups.childrenList.length ? gapSize / 2 : 0;\r\n var cellContainer = self.svgG.selectOrAppend(\"g.\" + cellContainerClass);\r\n cellContainer.attr(\"transform\", \"translate(\" + paddingX + \", \" + paddingY + \")\");\r\n\r\n var cellClass = self.prefixClass(\"cell\");\r\n var cellShape = plot.z.shape.type;\r\n\r\n var cells = cellContainer.selectAll(\"g.\" + cellClass)\r\n .data(self.plot.cells);\r\n\r\n var cellEnterG = cells.enter().append(\"g\")\r\n .classed(cellClass, true);\r\n cells.attr(\"transform\", c=> \"translate(\" + ((plot.cellWidth * c.col + plot.cellWidth / 2) + c.colVar.group.gapsSize) + \",\" + ((plot.cellHeight * c.row + plot.cellHeight / 2) + c.rowVar.group.gapsSize) + \")\");\r\n\r\n var shapes = cells.selectOrAppend(cellShape + \".cell-shape-\" + cellShape);\r\n\r\n shapes\r\n .attr(\"width\", plot.z.shape.width)\r\n .attr(\"height\", plot.z.shape.height)\r\n .attr(\"x\", -plot.cellWidth / 2)\r\n .attr(\"y\", -plot.cellHeight / 2);\r\n\r\n shapes.style(\"fill\", c=> c.value === undefined ? self.config.color.noDataColor : plot.z.color.scale(c.value));\r\n shapes.attr(\"fill-opacity\", d=> d.value === undefined ? 0 : 1);\r\n\r\n var mouseoverCallbacks = [];\r\n var mouseoutCallbacks = [];\r\n\r\n if (plot.tooltip) {\r\n\r\n mouseoverCallbacks.push(c=> {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = c.value === undefined ? self.config.tooltip.noDataText : self.formatValueZ(c.value);\r\n\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n });\r\n\r\n mouseoutCallbacks.push(c=> {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n\r\n\r\n }\r\n\r\n if (self.config.highlightLabels) {\r\n var highlightClass = self.config.cssClassPrefix + \"highlight\";\r\n var xLabelClass = c=>plot.labelClass + \"-x-\" + c.col;\r\n var yLabelClass = c=>plot.labelClass + \"-y-\" + c.row;\r\n\r\n\r\n mouseoverCallbacks.push(c=> {\r\n\r\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, true);\r\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, true);\r\n });\r\n mouseoutCallbacks.push(c=> {\r\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, false);\r\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, false);\r\n });\r\n }\r\n\r\n\r\n cells.on(\"mouseover\", c => {\r\n mouseoverCallbacks.forEach(callback=>callback(c));\r\n })\r\n .on(\"mouseout\", c => {\r\n mouseoutCallbacks.forEach(callback=>callback(c));\r\n });\r\n\r\n cells.on(\"click\", c=> {\r\n self.trigger(\"cell-selected\", c);\r\n });\r\n\r\n\r\n cells.exit().remove();\r\n }\r\n\r\n formatValueX(value) {\r\n if (!this.config.x.formatter) return value;\r\n\r\n return this.config.x.formatter.call(this.config, value);\r\n }\r\n\r\n formatValueY(value) {\r\n if (!this.config.y.formatter) return value;\r\n\r\n return this.config.y.formatter.call(this.config, value);\r\n }\r\n\r\n formatValueZ(value) {\r\n if (!this.config.z.formatter) return value;\r\n\r\n return this.config.z.formatter.call(this.config, value);\r\n }\r\n\r\n formatLegendValue(value) {\r\n if (!this.config.legend.formatter) return value;\r\n\r\n return this.config.legend.formatter.call(this.config, value);\r\n }\r\n\r\n updateLegend() {\r\n var self = this;\r\n var plot = this.plot;\r\n var legendX = this.plot.width + 10;\r\n var gapSize = Heatmap.computeGapSize(0);\r\n if (this.plot.groupByY) {\r\n legendX += gapSize / 2 + plot.y.overlap.right;\r\n } else if (this.plot.groupByX) {\r\n legendX += gapSize;\r\n }\r\n var legendY = 0;\r\n if (this.plot.groupByX || this.plot.groupByY) {\r\n legendY += gapSize / 2;\r\n }\r\n\r\n var barWidth = 10;\r\n var barHeight = this.plot.height - 2;\r\n var scale = plot.z.color.scale;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY, v => self.formatLegendValue(v)).setRotateLabels(self.config.legend.rotateLabels).linearGradientBar(barWidth, barHeight);\r\n }\r\n\r\n\r\n}\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from \"./legend\";\r\n\r\nexport class HistogramConfig extends ChartConfig{\r\n\r\n svgClass= this.cssClassPrefix+'histogram';\r\n showLegend=true;\r\n showTooltip =true;\r\n legend={\r\n width: 80,\r\n margin: 10,\r\n shapeWidth: 20\r\n };\r\n x={// X axis config\r\n label: '', // axis label\r\n key: 0,\r\n value: (d, key) => Utils.isNumber(d) ? d : d[key], // x value accessor\r\n scale: \"linear\",\r\n ticks: undefined,\r\n };\r\n y={// Y axis config\r\n label: '', // axis label,\r\n orient: \"left\",\r\n scale: \"linear\"\r\n };\r\n frequency=true;\r\n groups={\r\n key: 1,\r\n value: (d) => d[this.groups.key] , // grouping value accessor,\r\n label: \"\"\r\n };\r\n color = undefined // string or function returning color's value for color scale\r\n d3ColorCategory= 'category10';\r\n transition= true;\r\n\r\n constructor(custom){\r\n super();\r\n var config = this;\r\n\r\n if(custom){\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class Histogram extends Chart{\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new HistogramConfig(config));\r\n }\r\n\r\n setConfig(config){\r\n return super.setConfig(new HistogramConfig(config));\r\n }\r\n\r\n initPlot(){\r\n super.initPlot();\r\n var self=this;\r\n\r\n var conf = this.config;\r\n\r\n this.plot.x={};\r\n this.plot.y={};\r\n this.plot.bar={\r\n color: null//color scale mapping function\r\n };\r\n\r\n this.plot.showLegend = conf.showLegend;\r\n if(this.plot.showLegend){\r\n this.plot.margin.right = conf.margin.right + conf.legend.width+conf.legend.margin*2;\r\n }\r\n\r\n\r\n this.computePlotSize();\r\n\r\n\r\n\r\n if(conf.d3ColorCategory){\r\n this.plot.colorCategory = d3.scale[conf.d3ColorCategory]();\r\n }\r\n var colorValue = conf.color;\r\n if (colorValue && typeof colorValue === 'string' || colorValue instanceof String){\r\n this.plot.color = colorValue;\r\n }else if(this.plot.colorCategory){\r\n var domain = Object.getOwnPropertyNames(d3.map(this.data, d => this.config.groups.value.call(this.config, d))['_']);\r\n self.plot.colorCategory.domain(domain);\r\n this.plot.color = d => self.plot.colorCategory(d.key);\r\n }\r\n\r\n this.plot.data = this.getDataToPlot();\r\n this.setupX();\r\n this.setupHistogram();\r\n this.setupGroupStacks();\r\n this.setupY();\r\n\r\n return this;\r\n }\r\n\r\n setupX(){\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config.x;\r\n\r\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\r\n x.value = d => conf.value(d, conf.key);\r\n x.scale = d3.scale[conf.scale]().range([0, plot.width]);\r\n x.map = d => x.scale(x.value(d));\r\n\r\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\r\n if(conf.ticks){\r\n x.axis.ticks(conf.ticks);\r\n }\r\n var data = this.plot.data;\r\n plot.x.scale.domain([d3.min(data, plot.x.value), d3.max(data, plot.x.value)]);\r\n \r\n };\r\n\r\n setupY (){\r\n\r\n var plot = this.plot;\r\n var y = plot.y;\r\n var conf = this.config.y;\r\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\r\n\r\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\r\n\r\n var data = this.plot.data;\r\n plot.y.scale.domain([0, d3.max(plot.histogramBins, d=>d.y)]);\r\n };\r\n\r\n setupHistogram() {\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var y = plot.y;\r\n var ticks = this.config.x.ticks ? x.scale.ticks(this.config.x.ticks) : x.scale.ticks();\r\n\r\n plot.histogram = d3.layout.histogram().frequency(this.config.frequency)\r\n .value(x.value)\r\n .bins(ticks);\r\n plot.histogramBins = plot.histogram(this.plot.data);\r\n\r\n }\r\n\r\n setupGroupStacks() {\r\n var self=this;\r\n this.plot.groupingEnabled = this.config.groups && this.config.groups.value;\r\n \r\n this.plot.stack = d3.layout.stack().values(d=>d.histogramBins);\r\n this.plot.groupedData = d3.nest().key(d => this.plot.groupingEnabled ? this.config.groups.value.call(this.config, d) : 'root' ).entries(this.plot.data);\r\n this.plot.groupedData.forEach(d=>{\r\n d.histogramBins = this.plot.histogram.frequency(this.config.frequency || this.plot.groupingEnabled)(d.values);\r\n if(!this.config.frequency && this.plot.groupingEnabled){\r\n d.histogramBins.forEach(b => {\r\n b.dy = b.dy/this.plot.data.length\r\n b.y = b.y/this.plot.data.length\r\n });\r\n }\r\n });\r\n this.plot.stackedHistograms = this.plot.stack(this.plot.groupedData);\r\n }\r\n\r\n getDataToPlot(){\r\n if(!this.enabledGroups){\r\n return this.data;\r\n }\r\n\r\n return this.data.filter(d => this.enabledGroups.indexOf(this.config.groups.value.call(this.config, d))>-1);\r\n }\r\n\r\n drawAxisX(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.x;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-x')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')))\r\n .attr(\"transform\", \"translate(0,\" + plot.height + \")\");\r\n\r\n var axisT = axis;\r\n if (self.config.transition) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.x.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ (plot.width/2) +\",\"+ (plot.margin.bottom) +\")\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"-1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n drawAxisY(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.y;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-y')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')));\r\n\r\n var axisT = axis;\r\n if (self.config.transition) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.y.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ -plot.margin.left +\",\"+(plot.height/2)+\")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n\r\n drawHistogram() {\r\n var self = this;\r\n var plot = self.plot;\r\n \r\n var layerClass = this.prefixClass(\"layer\");\r\n\r\n var barClass = this.prefixClass(\"bar\");\r\n var layer = self.svgG.selectAll(\".\"+layerClass)\r\n .data(plot.stackedHistograms);\r\n\r\n layer.enter().append(\"g\")\r\n .attr(\"class\", layerClass);\r\n\r\n var bar = layer.selectAll(\".\"+barClass)\r\n .data(d => d.histogramBins);\r\n\r\n bar.enter().append(\"g\")\r\n .attr(\"class\", barClass)\r\n .append(\"rect\")\r\n .attr(\"x\", 1);\r\n\r\n\r\n var barRect = bar.select(\"rect\");\r\n\r\n var barRectT = barRect;\r\n var barT = bar;\r\n var layerT = layer;\r\n if (this.transitionEnabled()) {\r\n barRectT = barRect.transition();\r\n barT = bar.transition();\r\n layerT= layer.transition();\r\n }\r\n\r\n barT.attr(\"transform\", function(d) { return \"translate(\" + plot.x.scale(d.x) + \",\" + (plot.y.scale(d.y0 +d.y)) + \")\"; });\r\n\r\n var dx = plot.histogramBins.length ? plot.x.scale(plot.histogramBins[0].dx) : 0;\r\n barRectT\r\n .attr(\"width\", dx - plot.x.scale(0)- 1)\r\n .attr(\"height\", d => plot.height - plot.y.scale(d.y));\r\n\r\n if(this.plot.color){\r\n layerT\r\n .attr(\"fill\", this.plot.color);\r\n }\r\n\r\n if (plot.tooltip) {\r\n bar.on(\"mouseover\", d => {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n plot.tooltip.html(d.y)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n }).on(\"mouseout\", d => {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n layer.exit().remove();\r\n bar.exit().remove();\r\n }\r\n\r\n update(newData){\r\n super.update(newData);\r\n this.drawAxisX();\r\n this.drawAxisY();\r\n\r\n this.drawHistogram();\r\n\r\n this.updateLegend();\r\n };\r\n\r\n\r\n updateLegend() {\r\n var plot = this.plot;\r\n\r\n var scale = plot.colorCategory;\r\n if(!scale.domain() || scale.domain().length<2){\r\n plot.showLegend = false;\r\n }\r\n\r\n if(!plot.showLegend){\r\n if(plot.legend && plot.legend.container){\r\n plot.legend.container.remove();\r\n }\r\n return;\r\n }\r\n\r\n\r\n var legendX = this.plot.width + this.config.legend.margin;\r\n var legendY = this.config.legend.margin;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY);\r\n\r\n plot.legendColor = plot.legend.color()\r\n .shapeWidth(this.config.legend.shapeWidth)\r\n .orient('vertical')\r\n .scale(scale);\r\n\r\n\r\n plot.legendColor.on('cellclick', c=> this.onLegendCellClick(c));\r\n\r\n plot.legend.container\r\n .call(plot.legendColor);\r\n }\r\n\r\n onLegendCellClick(cellValue){\r\n this.updateEnabledGroups(cellValue);\r\n\r\n var isDisabled = this.enabledGroups.indexOf(cellValue)<0;\r\n this.plot.legend.container.selectAll(\"g.cell\").each(function(cell){\r\n if(cell == cellValue){\r\n d3.select(this).classed(\"odc-disabled\", isDisabled);\r\n }\r\n\r\n });\r\n\r\n this.init();\r\n }\r\n\r\n updateEnabledGroups(cellValue) {\r\n if (!this.enabledGroups) {\r\n this.enabledGroups = this.plot.colorCategory.domain().slice();\r\n }\r\n var index = this.enabledGroups.indexOf(cellValue);\r\n\r\n if (index < 0) {\r\n this.enabledGroups.push(cellValue);\r\n } else {\r\n this.enabledGroups.splice(index, 1);\r\n }\r\n }\r\n\r\n\r\n\r\n setData(data){\r\n super.setData(data);\r\n this.enabledGroups = null;\r\n }\r\n}\r\n","import {D3Extensions} from './d3-extensions'\r\nD3Extensions.extend();\r\n\r\nexport {ScatterPlot, ScatterPlotConfig} from \"./scatterplot\";\r\nexport {ScatterPlotMatrix, ScatterPlotMatrixConfig} from \"./scatterplot-matrix\";\r\nexport {CorrelationMatrix, CorrelationMatrixConfig} from './correlation-matrix'\r\nexport {Regression, RegressionConfig} from './regression'\r\nexport {Heatmap, HeatmapConfig} from './heatmap'\r\nexport {HeatmapTimeSeries, HeatmapTimeSeriesConfig} from './heatmap-timeseries'\r\nexport {Histogram, HistogramConfig} from './histogram'\r\nexport {BarChart, BarChartConfig} from './bar-chart'\r\nexport {StatisticsUtils} from './statistics-utils'\r\nexport {Legend} from './legend'\r\n\r\n\r\n\r\n\r\n\r\n","import {Utils} from \"./utils\";\r\nimport {color, size, symbol} from \"../bower_components/d3-legend/no-extend\";\r\n\r\n/*var d3 = require('../bower_components/d3');\r\n*/\r\n// var legend = require('../bower_components/d3-legend/no-extend');\r\n//\r\n// module.exports.legend = legend;\r\n\r\nexport class Legend {\r\n\r\n cssClassPrefix=\"odc-\";\r\n legendClass=this.cssClassPrefix+\"legend\";\r\n container;\r\n scale;\r\n color= color;\r\n size = size;\r\n symbol= symbol;\r\n guid;\r\n\r\n labelFormat = undefined;\r\n\r\n constructor(svg, legendParent, scale, legendX, legendY, labelFormat){\r\n this.scale=scale;\r\n this.svg = svg;\r\n this.guid = Utils.guid();\r\n this.container = Utils.selectOrAppend(legendParent, \"g.\"+this.legendClass, \"g\")\r\n .attr(\"transform\", \"translate(\"+legendX+\",\"+legendY+\")\")\r\n .classed(this.legendClass, true);\r\n\r\n this.labelFormat = labelFormat;\r\n }\r\n\r\n\r\n\r\n linearGradientBar(barWidth, barHeight, title){\r\n var gradientId = this.cssClassPrefix+\"linear-gradient\"+\"-\"+this.guid;\r\n var scale= this.scale;\r\n var self = this;\r\n\r\n this.linearGradient = Utils.linearGradient(this.svg, gradientId, this.scale.range(), 0, 100, 0, 0);\r\n\r\n this.container.append(\"rect\")\r\n .attr(\"width\", barWidth)\r\n .attr(\"height\", barHeight)\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n .style(\"fill\", \"url(#\"+gradientId+\")\");\r\n\r\n\r\n var ticks = this.container.selectAll(\"text\")\r\n .data( scale.domain() );\r\n var ticksNumber =scale.domain().length-1;\r\n ticks.enter().append(\"text\");\r\n\r\n ticks.attr(\"x\", barWidth)\r\n .attr(\"y\", (d, i) => barHeight -(i*barHeight/ticksNumber))\r\n .attr(\"dx\", 3)\r\n // .attr(\"dy\", 1)\r\n .attr(\"alignment-baseline\", \"middle\")\r\n .text(d=> self.labelFormat ? self.labelFormat(d) : d);\r\n ticks.attr(\"dominant-baseline\", \"middle\")\r\n if(this.rotateLabels){\r\n ticks\r\n .attr(\"transform\", (d, i) => \"rotate(-45, \" + barWidth + \", \" + (barHeight -(i*barHeight/ticksNumber)) + \")\")\r\n .attr(\"text-anchor\", \"start\")\r\n .attr(\"dx\", 5)\r\n .attr(\"dy\", 5);\r\n\r\n }else{\r\n\r\n }\r\n\r\n ticks.exit().remove();\r\n\r\n return this;\r\n }\r\n\r\n setRotateLabels(rotateLabels) {\r\n this.rotateLabels = rotateLabels;\r\n return this;\r\n }\r\n\r\n \r\n}","import {Chart, ChartConfig} from \"./chart\";\r\nimport {ScatterPlot, ScatterPlotConfig} from \"./scatterplot\";\r\nimport {Utils} from './utils'\r\nimport {StatisticsUtils} from './statistics-utils'\r\n\r\n\r\nexport class RegressionConfig extends ScatterPlotConfig{\r\n\r\n mainRegression = true;\r\n groupRegression = true;\r\n confidence={\r\n level: 0.95,\r\n criticalValue: (degreesOfFreedom, criticalProbability) => StatisticsUtils.tValue(degreesOfFreedom, criticalProbability),\r\n marginOfError: undefined //custom margin Of Error function (x, points)\r\n };\r\n\r\n constructor(custom){\r\n super();\r\n\r\n if(custom){\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class Regression extends ScatterPlot{\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new RegressionConfig(config));\r\n }\r\n\r\n setConfig(config){\r\n return super.setConfig(new RegressionConfig(config));\r\n }\r\n\r\n initPlot(){\r\n super.initPlot();\r\n this.initRegressionLines();\r\n }\r\n\r\n initRegressionLines(){\r\n\r\n var self = this;\r\n var groupsAvailable = self.config.groups && self.config.groups.value;\r\n\r\n self.plot.regressions= [];\r\n\r\n\r\n if(groupsAvailable && self.config.mainRegression){\r\n var regression = this.initRegression(this.plot.data, false);\r\n self.plot.regressions.push(regression);\r\n }\r\n\r\n if(self.config.groupRegression){\r\n this.initGroupRegression();\r\n }\r\n\r\n }\r\n\r\n initGroupRegression() {\r\n var self = this;\r\n var dataByGroup = {};\r\n this.plot.data.forEach (d=>{\r\n var groupVal = self.config.groups.value(d, self.config.groups.key);\r\n\r\n if(!groupVal && groupVal!==0){\r\n return;\r\n }\r\n\r\n if(!dataByGroup[groupVal]){\r\n dataByGroup[groupVal] = [];\r\n }\r\n dataByGroup[groupVal].push(d);\r\n });\r\n\r\n for(var key in dataByGroup){\r\n if (!dataByGroup.hasOwnProperty(key)) {\r\n continue;\r\n }\r\n\r\n var regression = this.initRegression(dataByGroup[key], key);\r\n self.plot.regressions.push(regression);\r\n }\r\n }\r\n\r\n initRegression(values, groupVal){\r\n var self = this;\r\n\r\n var points = values.map(d=>{\r\n return [parseFloat(self.plot.x.value(d)), parseFloat(self.plot.y.value(d))];\r\n });\r\n\r\n // points.sort((a,b) => a[0]-b[0]);\r\n\r\n var linearRegression = StatisticsUtils.linearRegression(points);\r\n var linearRegressionLine = StatisticsUtils.linearRegressionLine(linearRegression);\r\n\r\n\r\n var extentX = d3.extent(points, d=>d[0]);\r\n\r\n\r\n var linePoints = [\r\n {\r\n x: extentX[0],\r\n y: linearRegressionLine(extentX[0])\r\n },\r\n {\r\n x: extentX[1],\r\n y: linearRegressionLine(extentX[1])\r\n }\r\n ];\r\n\r\n var line = d3.svg.line()\r\n .interpolate(\"basis\")\r\n .x(d => self.plot.x.scale(d.x))\r\n .y(d => self.plot.y.scale(d.y));\r\n \r\n\r\n var color = self.plot.dot.color;\r\n\r\n var defaultColor = \"black\";\r\n if(Utils.isFunction(color)){\r\n if(values.length && groupVal!==false){\r\n color = color(values[0]);\r\n }else{\r\n color = defaultColor;\r\n }\r\n }else if(!color && groupVal===false){\r\n color = defaultColor;\r\n }\r\n\r\n\r\n var confidence = this.computeConfidence(points, extentX, linearRegression,linearRegressionLine);\r\n return {\r\n group: groupVal || false,\r\n line: line,\r\n linePoints: linePoints,\r\n color: color,\r\n confidence: confidence\r\n };\r\n }\r\n\r\n computeConfidence(points, extentX, linearRegression,linearRegressionLine){\r\n var self = this;\r\n var slope = linearRegression.m;\r\n var n = points.length;\r\n var degreesOfFreedom = Math.max(0, n-2);\r\n\r\n var alpha = 1 - self.config.confidence.level;\r\n var criticalProbability = 1 - alpha/2;\r\n var criticalValue = self.config.confidence.criticalValue(degreesOfFreedom,criticalProbability);\r\n\r\n var xValues = points.map(d=>d[0]);\r\n var meanX = StatisticsUtils.mean(xValues);\r\n var xMySum=0;\r\n var xSum=0;\r\n var xPowSum=0;\r\n var ySum=0;\r\n var yPowSum=0;\r\n points.forEach(p=>{\r\n var x = p[0];\r\n var y = p[1];\r\n\r\n xMySum += x*y;\r\n xSum+=x;\r\n ySum+=y;\r\n xPowSum+= x*x;\r\n yPowSum+= y*y;\r\n });\r\n var a = linearRegression.m;\r\n var b = linearRegression.b;\r\n\r\n var Sa2 = n/(n+2) * ((yPowSum-a*xMySum-b*ySum)/(n*xPowSum-(xSum*xSum))); //Wariancja współczynnika kierunkowego regresji liniowej a\r\n var Sy2 = (yPowSum - a*xMySum-b*ySum)/(n*(n-2)); //Sa2 //Mean y value variance\r\n\r\n var errorFn = x=> Math.sqrt(Sy2 + Math.pow(x-meanX,2)*Sa2); //pierwiastek kwadratowy z wariancji dowolnego punktu prostej\r\n var marginOfError = x=> criticalValue* errorFn(x);\r\n\r\n\r\n // console.log('n', n, 'degreesOfFreedom', degreesOfFreedom, 'criticalProbability',criticalProbability);\r\n // var confidenceDown = x => linearRegressionLine(x) - marginOfError(x);\r\n // var confidenceUp = x => linearRegressionLine(x) + marginOfError(x);\r\n\r\n\r\n var computeConfidenceAreaPoint = x=>{\r\n var linearRegression = linearRegressionLine(x);\r\n var moe = marginOfError(x);\r\n var confDown = linearRegression - moe;\r\n var confUp = linearRegression + moe;\r\n return {\r\n x: x,\r\n y0: confDown,\r\n y1: confUp\r\n }\r\n\r\n };\r\n\r\n var centerX = (extentX[1]+extentX[0])/2;\r\n\r\n // var confidenceAreaPoints = [extentX[0], centerX, extentX[1]].map(computeConfidenceAreaPoint);\r\n var confidenceAreaPoints = [extentX[0], centerX, extentX[1]].map(computeConfidenceAreaPoint);\r\n\r\n var fitInPlot = y => y;\r\n\r\n var confidenceArea = d3.svg.area()\r\n .interpolate(\"monotone\")\r\n .x(d => self.plot.x.scale(d.x))\r\n .y0(d => fitInPlot(self.plot.y.scale(d.y0)))\r\n .y1(d => fitInPlot(self.plot.y.scale(d.y1)));\r\n\r\n return {\r\n area:confidenceArea,\r\n points:confidenceAreaPoints\r\n };\r\n }\r\n\r\n update(newData){\r\n super.update(newData);\r\n this.updateRegressionLines();\r\n\r\n };\r\n\r\n updateRegressionLines() {\r\n var self = this;\r\n var regressionContainerClass = this.prefixClass(\"regression-container\");\r\n var regressionContainerSelector = \"g.\"+regressionContainerClass;\r\n\r\n var clipPathId = self.prefixClass(\"clip\");\r\n\r\n var regressionContainer = self.svgG.selectOrInsert(regressionContainerSelector, \".\"+self.dotsContainerClass);\r\n var regressionContainerClip = regressionContainer.selectOrAppend(\"clipPath\")\r\n .attr(\"id\", clipPathId);\r\n\r\n\r\n regressionContainerClip.selectOrAppend('rect')\r\n .attr('width', self.plot.width)\r\n .attr('height', self.plot.height)\r\n .attr('x', 0)\r\n .attr('y', 0);\r\n\r\n regressionContainer.attr(\"clip-path\", (d,i) => \"url(#\"+clipPathId+\")\");\r\n\r\n var regressionClass = this.prefixClass(\"regression\");\r\n var confidenceAreaClass = self.prefixClass(\"confidence\");\r\n var regressionSelector = \"g.\"+regressionClass;\r\n var regression = regressionContainer.selectAll(regressionSelector)\r\n .data(self.plot.regressions, (d,i)=> d.group);\r\n\r\n var regressionEnterG = regression.enter().insertSelector(regressionSelector);\r\n var lineClass = self.prefixClass(\"line\");\r\n regressionEnterG\r\n\r\n .append(\"path\")\r\n .attr(\"class\", lineClass)\r\n .attr(\"shape-rendering\", \"optimizeQuality\");\r\n // .append(\"line\")\r\n // .attr(\"class\", \"line\")\r\n // .attr(\"shape-rendering\", \"optimizeQuality\");\r\n\r\n var line = regression.select(\"path.\"+lineClass)\r\n .style(\"stroke\", r => r.color);\r\n // .attr(\"x1\", r=> self.plot.x.scale(r.linePoints[0].x))\r\n // .attr(\"y1\", r=> self.plot.y.scale(r.linePoints[0].y))\r\n // .attr(\"x2\", r=> self.plot.x.scale(r.linePoints[1].x))\r\n // .attr(\"y2\", r=> self.plot.y.scale(r.linePoints[1].y))\r\n\r\n\r\n var lineT = line;\r\n if (self.transitionEnabled()) {\r\n lineT = line.transition();\r\n }\r\n\r\n lineT.attr(\"d\", r => r.line(r.linePoints))\r\n\r\n\r\n regressionEnterG\r\n .append(\"path\")\r\n .attr(\"class\", confidenceAreaClass)\r\n .attr(\"shape-rendering\", \"optimizeQuality\")\r\n .style(\"opacity\", \"0.4\");\r\n\r\n\r\n\r\n var area = regression.select(\"path.\"+confidenceAreaClass);\r\n\r\n var areaT = area;\r\n if (self.transitionEnabled()) {\r\n areaT = area.transition();\r\n }\r\n areaT.attr(\"d\", r => r.confidence.area(r.confidence.points));\r\n areaT.style(\"fill\", r => r.color)\r\n regression.exit().remove();\r\n\r\n }\r\n\r\n\r\n\r\n}\r\n\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {ScatterPlotConfig} from \"./scatterplot\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from \"./legend\";\r\n\r\nexport class ScatterPlotMatrixConfig extends ScatterPlotConfig{\r\n\r\n svgClass= this.cssClassPrefix+'scatterplot-matrix';\r\n size= 200; //scatter plot cell size\r\n padding= 20; //scatter plot cell padding\r\n brush= true;\r\n guides= true; //show axis guides\r\n showTooltip= true; //show tooltip on dot hover\r\n ticks= undefined; //ticks number, (default: computed using cell size)\r\n x={// X axis config\r\n orient: \"bottom\",\r\n scale: \"linear\"\r\n };\r\n y={// Y axis config\r\n orient: \"left\",\r\n scale: \"linear\"\r\n };\r\n groups={\r\n key: undefined, //object property name or array index with grouping variable\r\n includeInPlot: false, //include group as variable in plot, boolean (default: false)\r\n value: (d, key) => d[key], // grouping value accessor,\r\n label: \"\"\r\n };\r\n variables= {\r\n labels: [], //optional array of variable labels (for the diagonal of the plot).\r\n keys: [], //optional array of variable keys\r\n value: (d, variableKey) => d[variableKey] // variable value accessor\r\n };\r\n\r\n constructor(custom){\r\n super();\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n\r\n}\r\n\r\nexport class ScatterPlotMatrix extends Chart {\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new ScatterPlotMatrixConfig(config));\r\n }\r\n\r\n setConfig(config) {\r\n return super.setConfig(new ScatterPlotMatrixConfig(config));\r\n\r\n }\r\n\r\n initPlot() {\r\n super.initPlot();\r\n\r\n var self = this;\r\n var margin = this.plot.margin;\r\n var conf = this.config;\r\n this.plot.x={};\r\n this.plot.y={};\r\n this.plot.dot={\r\n color: null//color scale mapping function\r\n };\r\n\r\n\r\n this.plot.showLegend = conf.showLegend;\r\n if(this.plot.showLegend){\r\n margin.right = conf.margin.right + conf.legend.width+conf.legend.margin*2;\r\n }\r\n\r\n this.setupGroups();\r\n\r\n this.plot.data = this.getDataToPlot();\r\n this.setupVariables();\r\n\r\n this.plot.size = conf.size;\r\n\r\n\r\n var width = conf.width;\r\n var boundingClientRect = this.getBaseContainerNode().getBoundingClientRect();\r\n if (!width) {\r\n var maxWidth = margin.left + margin.right + this.plot.variables.length*this.plot.size;\r\n width = Math.min(boundingClientRect.width, maxWidth);\r\n\r\n }\r\n var height = width;\r\n if (!height) {\r\n height = boundingClientRect.height;\r\n }\r\n\r\n this.plot.width = width - margin.left - margin.right;\r\n this.plot.height = height - margin.top - margin.bottom;\r\n\r\n\r\n\r\n\r\n if(conf.ticks===undefined){\r\n conf.ticks = this.plot.size / 40;\r\n }\r\n\r\n\r\n\r\n this.setupX();\r\n this.setupY();\r\n\r\n return this;\r\n\r\n };\r\n\r\n setupGroups() {\r\n var self=this;\r\n var conf = this.config;\r\n this.plot.groupValue = d => conf.groups.value(d, conf.groups.key);\r\n if(conf.dot.d3ColorCategory){\r\n this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();\r\n }\r\n var colorValue = conf.dot.color;\r\n if(colorValue){\r\n this.plot.dot.colorValue = colorValue;\r\n\r\n if (typeof colorValue === 'string' || colorValue instanceof String){\r\n this.plot.dot.color = colorValue;\r\n }else if(this.plot.dot.colorCategory){\r\n var domain = Object.getOwnPropertyNames(d3.map(this.data, d => self.plot.dot.colorValue.call(self,d))['_']);\r\n self.plot.dot.colorCategory.domain(domain);\r\n this.plot.dot.color = d => self.plot.dot.colorCategory(self.plot.dot.colorValue.call(self,d));\r\n }\r\n }\r\n }\r\n\r\n getDataToPlot(){\r\n if(!this.enabledGroups){\r\n return this.data;\r\n }\r\n\r\n var filter = this.data.filter(d => this.enabledGroups.indexOf(this.plot.groupValue(d))>-1);\r\n console.log(filter.length);\r\n return filter;\r\n }\r\n\r\n setupVariables() {\r\n var variablesConf = this.config.variables;\r\n\r\n var data = this.data;\r\n var plot = this.plot;\r\n plot.domainByVariable = {};\r\n plot.variables = variablesConf.keys;\r\n if(!plot.variables || !plot.variables.length){\r\n plot.variables = Utils.inferVariables(data, this.config.groups.key, this.config.includeInPlot);\r\n }\r\n\r\n plot.labels = [];\r\n plot.labelByVariable = {};\r\n plot.variables.forEach((variableKey, index) => {\r\n plot.domainByVariable[variableKey] = d3.extent(data, function(d) { return variablesConf.value(d, variableKey) });\r\n var label = variableKey;\r\n if(variablesConf.labels && variablesConf.labels.length>index){\r\n\r\n label = variablesConf.labels[index];\r\n }\r\n plot.labels.push(label);\r\n plot.labelByVariable[variableKey] = label;\r\n });\r\n\r\n console.log(plot.labelByVariable);\r\n\r\n plot.subplots = [];\r\n };\r\n\r\n setupX() {\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config;\r\n\r\n x.value = conf.variables.value;\r\n x.scale = d3.scale[conf.x.scale]().range([conf.padding / 2, plot.size - conf.padding / 2]);\r\n x.map = (d, variable) => x.scale(x.value(d, variable));\r\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.x.orient).ticks(conf.ticks);\r\n x.axis.tickSize(plot.size * plot.variables.length);\r\n\r\n };\r\n\r\n setupY() {\r\n\r\n var plot = this.plot;\r\n var y = plot.y;\r\n var conf = this.config;\r\n\r\n y.value = conf.variables.value;\r\n y.scale = d3.scale[conf.y.scale]().range([ plot.size - conf.padding / 2, conf.padding / 2]);\r\n y.map = (d, variable) => y.scale(y.value(d, variable));\r\n y.axis= d3.svg.axis().scale(y.scale).orient(conf.y.orient).ticks(conf.ticks);\r\n y.axis.tickSize(-plot.size * plot.variables.length);\r\n };\r\n\r\n update( newData) {\r\n super.update(newData);\r\n\r\n var self =this;\r\n var n = self.plot.variables.length;\r\n var conf = this.config;\r\n\r\n var axisClass = self.prefixClass(\"axis\");\r\n var axisXClass = axisClass+\"-x\";\r\n var axisYClass = axisClass+\"-y\";\r\n\r\n var xAxisSelector = \"g.\"+axisXClass+\".\"+axisClass;\r\n var yAxisSelector = \"g.\"+axisYClass+\".\"+axisClass;\r\n\r\n var noGuidesClass = self.prefixClass(\"no-guides\");\r\n self.svgG.selectAll(xAxisSelector)\r\n .data(self.plot.variables)\r\n .enter().appendSelector(xAxisSelector)\r\n .classed(noGuidesClass, !conf.guides)\r\n .attr(\"transform\", (d, i) => \"translate(\" + (n - i - 1) * self.plot.size + \",0)\")\r\n .each(function(d) { self.plot.x.scale.domain(self.plot.domainByVariable[d]); d3.select(this).call(self.plot.x.axis); });\r\n\r\n self.svgG.selectAll(yAxisSelector)\r\n .data(self.plot.variables)\r\n .enter().appendSelector(yAxisSelector)\r\n .classed(noGuidesClass, !conf.guides)\r\n .attr(\"transform\", (d, i) => \"translate(0,\" + i * self.plot.size + \")\")\r\n .each(function(d) { self.plot.y.scale.domain(self.plot.domainByVariable[d]); d3.select(this).call(self.plot.y.axis); });\r\n\r\n var cellClass = self.prefixClass(\"cell\");\r\n var cell = self.svgG.selectAll(\".\"+cellClass)\r\n .data(self.utils.cross(self.plot.variables, self.plot.variables));\r\n\r\n cell.enter().appendSelector(\"g.\"+cellClass).filter(d => d.i === d.j)\r\n .append(\"text\");\r\n\r\n cell.attr(\"transform\", d => \"translate(\" + (n - d.i - 1) * self.plot.size + \",\" + d.j * self.plot.size + \")\");\r\n\r\n if(conf.brush){\r\n this.drawBrush(cell);\r\n }\r\n\r\n cell.each(plotSubplot);\r\n\r\n //Labels\r\n cell.select(\"text\")\r\n .attr(\"x\", conf.padding)\r\n .attr(\"y\", conf.padding)\r\n .attr(\"dy\", \".71em\")\r\n .text( d => self.plot.labelByVariable[d.x]);\r\n\r\n\r\n\r\n\r\n function plotSubplot(p) {\r\n console.log('plotSubplot');\r\n var plot = self.plot;\r\n plot.subplots.push(p);\r\n var cell = d3.select(this);\r\n\r\n plot.x.scale.domain(plot.domainByVariable[p.x]);\r\n plot.y.scale.domain(plot.domainByVariable[p.y]);\r\n\r\n var frameClass = self.prefixClass(\"frame\");\r\n cell.selectOrAppend(\"rect.\"+frameClass)\r\n .attr(\"class\", frameClass)\r\n .attr(\"x\", conf.padding / 2)\r\n .attr(\"y\", conf.padding / 2)\r\n .attr(\"width\", conf.size - conf.padding)\r\n .attr(\"height\", conf.size - conf.padding);\r\n\r\n\r\n p.update = function() {\r\n\r\n var subplot = this;\r\n var dots = cell.selectAll(\"circle\")\r\n .data(self.plot.data);\r\n\r\n dots.enter().append(\"circle\");\r\n\r\n var dotsT = dots;\r\n if (self.transitionEnabled()) {\r\n dotsT = dots.transition();\r\n }\r\n\r\n dotsT.attr(\"cx\", (d) => plot.x.map(d, subplot.x))\r\n .attr(\"cy\", (d) => plot.y.map(d, subplot.y))\r\n .attr(\"r\", self.config.dot.radius);\r\n\r\n if (plot.dot.color) {\r\n dotsT.style(\"fill\", plot.dot.color)\r\n }\r\n\r\n if(plot.tooltip){\r\n dots.on(\"mouseover\", (d) => {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = \"(\" + plot.x.value(d, subplot.x) + \", \" +plot.y.value(d, subplot.y) + \")\";\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n\r\n var group = self.config.groups.value(d);\r\n if(group || group===0 ){\r\n html+=\"
\";\r\n var label = self.config.groups.label;\r\n if(label){\r\n html+=label+\": \";\r\n }\r\n html+=group\r\n }\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n })\r\n .on(\"mouseout\", (d)=> {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n\r\n dots.exit().remove();\r\n };\r\n p.update();\r\n\r\n }\r\n\r\n\r\n this.updateLegend();\r\n };\r\n\r\n drawBrush(cell) {\r\n var self = this;\r\n var brush = d3.svg.brush()\r\n .x(self.plot.x.scale)\r\n .y(self.plot.y.scale)\r\n .on(\"brushstart\", brushstart)\r\n .on(\"brush\", brushmove)\r\n .on(\"brushend\", brushend);\r\n\r\n cell.append(\"g\").call(brush);\r\n\r\n\r\n var brushCell;\r\n\r\n // Clear the previously-active brush, if any.\r\n function brushstart(p) {\r\n if (brushCell !== this) {\r\n d3.select(brushCell).call(brush.clear());\r\n self.plot.x.scale.domain(self.plot.domainByVariable[p.x]);\r\n self.plot.y.scale.domain(self.plot.domainByVariable[p.y]);\r\n brushCell = this;\r\n }\r\n }\r\n\r\n // Highlight the selected circles.\r\n function brushmove(p) {\r\n var e = brush.extent();\r\n self.svgG.selectAll(\"circle\").classed(\"hidden\", function (d) {\r\n return e[0][0] > d[p.x] || d[p.x] > e[1][0]\r\n || e[0][1] > d[p.y] || d[p.y] > e[1][1];\r\n });\r\n }\r\n // If the brush is empty, select all circles.\r\n function brushend() {\r\n if (brush.empty()) self.svgG.selectAll(\".hidden\").classed(\"hidden\", false);\r\n }\r\n };\r\n\r\n updateLegend() {\r\n\r\n var self =this;\r\n var plot = this.plot;\r\n\r\n var scale = plot.dot.colorCategory;\r\n\r\n\r\n\r\n if(!scale.domain() || scale.domain().length<2){\r\n plot.showLegend = false;\r\n }\r\n\r\n if(!plot.showLegend){\r\n if(plot.legend && plot.legend.container){\r\n plot.legend.container.remove();\r\n }\r\n return;\r\n }\r\n\r\n\r\n var legendX = this.plot.width + this.config.legend.margin;\r\n var legendY = this.config.legend.margin;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY);\r\n\r\n plot.legendColor = plot.legend.color()\r\n .shapeWidth(this.config.legend.shapeWidth)\r\n .orient('vertical')\r\n .scale(scale);\r\n\r\n\r\n plot.legendColor.on('cellclick', c=> self.onLegendCellClick(c));\r\n\r\n plot.legend.container\r\n .call(plot.legendColor);\r\n }\r\n\r\n onLegendCellClick(cellValue){\r\n this.updateEnabledGroups(cellValue);\r\n\r\n var isDisabled = this.enabledGroups.indexOf(cellValue)<0;\r\n this.plot.legend.container.selectAll(\"g.cell\").each(function(cell){\r\n if(cell == cellValue){\r\n d3.select(this).classed(\"odc-disabled\", isDisabled);\r\n }\r\n\r\n });\r\n\r\n this.init();\r\n }\r\n\r\n updateEnabledGroups(cellValue) {\r\n if (!this.enabledGroups) {\r\n this.enabledGroups = this.plot.dot.colorCategory.domain().slice();\r\n }\r\n var index = this.enabledGroups.indexOf(cellValue);\r\n\r\n if (index < 0) {\r\n this.enabledGroups.push(cellValue);\r\n } else {\r\n this.enabledGroups.splice(index, 1);\r\n }\r\n }\r\n\r\n\r\n\r\n setData(data){\r\n super.setData(data);\r\n this.enabledGroups = null;\r\n }\r\n}","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from \"./legend\";\r\n\r\nexport class ScatterPlotConfig extends ChartConfig{\r\n\r\n svgClass= this.cssClassPrefix+'scatterplot';\r\n guides= false; //show axis guides\r\n showTooltip= true; //show tooltip on dot hover\r\n showLegend=true;\r\n legend={\r\n width: 80,\r\n margin: 10,\r\n shapeWidth: 20\r\n };\r\n\r\n x={// X axis config\r\n label: 'X', // axis label\r\n key: 0,\r\n value: (d, key) => d[key], // x value accessor\r\n orient: \"bottom\",\r\n scale: \"linear\"\r\n };\r\n y={// Y axis config\r\n label: 'Y', // axis label,\r\n key: 1,\r\n value: (d, key) => d[key], // y value accessor\r\n orient: \"left\",\r\n scale: \"linear\"\r\n };\r\n groups={\r\n key: 2,\r\n value: (d, key) => d[key] , // grouping value accessor,\r\n label: \"\"\r\n };\r\n dot = {\r\n radius: 2,\r\n color: d => this.groups.value(d, this.groups.key), // string or function returning color's value for color scale\r\n d3ColorCategory: 'category10'\r\n };\r\n transition= true;\r\n\r\n constructor(custom){\r\n super();\r\n\r\n\r\n\r\n if(custom){\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class ScatterPlot extends Chart{\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new ScatterPlotConfig(config));\r\n }\r\n\r\n setConfig(config){\r\n return super.setConfig(new ScatterPlotConfig(config));\r\n }\r\n\r\n initPlot(){\r\n super.initPlot();\r\n var self=this;\r\n\r\n var conf = this.config;\r\n\r\n this.plot.x={};\r\n this.plot.y={};\r\n this.plot.dot={\r\n color: null//color scale mapping function\r\n };\r\n\r\n\r\n this.plot.showLegend = conf.showLegend;\r\n if(this.plot.showLegend){\r\n this.plot.margin.right = conf.margin.right + conf.legend.width+conf.legend.margin*2;\r\n }\r\n \r\n\r\n this.computePlotSize();\r\n\r\n\r\n this.setupGroups();\r\n\r\n this.plot.data = this.getDataToPlot();\r\n this.setupX();\r\n this.setupY();\r\n\r\n\r\n\r\n return this;\r\n }\r\n\r\n setupGroups() {\r\n var self=this;\r\n var conf = this.config;\r\n this.plot.groupValue = d => conf.groups.value(d, conf.groups.key);\r\n if(conf.dot.d3ColorCategory){\r\n this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();\r\n }\r\n var colorValue = conf.dot.color;\r\n if(colorValue){\r\n this.plot.dot.colorValue = colorValue;\r\n\r\n if (typeof colorValue === 'string' || colorValue instanceof String){\r\n this.plot.dot.color = colorValue;\r\n }else if(this.plot.dot.colorCategory){\r\n var domain = Object.getOwnPropertyNames(d3.map(this.data, d => self.plot.dot.colorValue.call(self,d))['_']);\r\n self.plot.dot.colorCategory.domain(domain);\r\n this.plot.dot.color = d => self.plot.dot.colorCategory(self.plot.dot.colorValue.call(self,d));\r\n }\r\n }\r\n }\r\n\r\n getDataToPlot(){\r\n if(!this.enabledGroups){\r\n return this.data;\r\n }\r\n\r\n return this.data.filter(d => this.enabledGroups.indexOf(this.plot.groupValue(d))>-1);\r\n }\r\n\r\n setupX(){\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config.x;\r\n\r\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\r\n x.value = d => conf.value(d, conf.key);\r\n x.scale = d3.scale[conf.scale]().range([0, plot.width]);\r\n x.map = d => x.scale(x.value(d));\r\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\r\n var data = this.plot.data;\r\n plot.x.scale.domain([d3.min(data, plot.x.value)-1, d3.max(data, plot.x.value)+1]);\r\n if(this.config.guides) {\r\n x.axis.tickSize(-plot.height);\r\n }\r\n\r\n };\r\n\r\n setupY (){\r\n\r\n var plot = this.plot;\r\n var y = plot.y;\r\n var conf = this.config.y;\r\n\r\n /*\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n */\r\n y.value = d => conf.value(d, conf.key);\r\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\r\n y.map = d => y.scale(y.value(d));\r\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\r\n\r\n if(this.config.guides){\r\n y.axis.tickSize(-plot.width);\r\n }\r\n\r\n\r\n var data = this.plot.data;\r\n plot.y.scale.domain([d3.min(data, plot.y.value)-1, d3.max(data, plot.y.value)+1]);\r\n };\r\n\r\n drawAxisX(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.x;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-x')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')))\r\n .attr(\"transform\", \"translate(0,\" + plot.height + \")\");\r\n \r\n var axisT = axis;\r\n if (self.transitionEnabled()) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.x.axis);\r\n \r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ (plot.width/2) +\",\"+ (plot.margin.bottom) +\")\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"-1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n drawAxisY(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.y;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-y')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')));\r\n\r\n var axisT = axis;\r\n if (self.transitionEnabled()) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.y.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ -plot.margin.left +\",\"+(plot.height/2)+\")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n update(newData){\r\n super.update(newData);\r\n this.drawAxisX();\r\n this.drawAxisY();\r\n\r\n this.updateDots();\r\n\r\n this.updateLegend();\r\n };\r\n\r\n updateDots() {\r\n var self = this;\r\n var plot = self.plot;\r\n var data = plot.data;\r\n var dotClass = self.prefixClass('dot');\r\n self.dotsContainerClass = self.prefixClass('dots-container');\r\n\r\n\r\n var dotsContainer = self.svgG.selectOrAppend(\"g.\" + self.dotsContainerClass);\r\n\r\n var dots = dotsContainer.selectAll('.' + dotClass)\r\n .data(data);\r\n\r\n dots.enter().append(\"circle\")\r\n .attr(\"class\", dotClass);\r\n\r\n var dotsT = dots;\r\n if (self.transitionEnabled()) {\r\n dotsT = dots.transition();\r\n }\r\n\r\n dotsT.attr(\"r\", self.config.dot.radius)\r\n .attr(\"cx\", plot.x.map)\r\n .attr(\"cy\", plot.y.map);\r\n\r\n if (plot.tooltip) {\r\n dots.on(\"mouseover\", d => {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = \"(\" + plot.x.value(d) + \", \" + plot.y.value(d) + \")\";\r\n var group = self.config.groups.value(d, self.config.groups.key);\r\n if (group || group === 0) {\r\n html += \"
\";\r\n var label = self.config.groups.label;\r\n if (label) {\r\n html += label + \": \";\r\n }\r\n html += group\r\n }\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n })\r\n .on(\"mouseout\", d => {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n\r\n if (plot.dot.color) {\r\n dots.style(\"fill\", plot.dot.color)\r\n }\r\n\r\n dots.exit().remove();\r\n }\r\n\r\n updateLegend() {\r\n\r\n var self =this;\r\n var plot = this.plot;\r\n\r\n var scale = plot.dot.colorCategory;\r\n\r\n\r\n\r\n if(!scale.domain() || scale.domain().length<2){\r\n plot.showLegend = false;\r\n }\r\n\r\n if(!plot.showLegend){\r\n if(plot.legend && plot.legend.container){\r\n plot.legend.container.remove();\r\n }\r\n return;\r\n }\r\n\r\n\r\n var legendX = this.plot.width + this.config.legend.margin;\r\n var legendY = this.config.legend.margin;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY);\r\n\r\n plot.legendColor = plot.legend.color()\r\n .shapeWidth(this.config.legend.shapeWidth)\r\n .orient('vertical')\r\n .scale(scale);\r\n\r\n\r\n plot.legendColor.on('cellclick', c=> self.onLegendCellClick(c));\r\n \r\n plot.legend.container\r\n .call(plot.legendColor);\r\n }\r\n\r\n onLegendCellClick(cellValue){\r\n this.updateEnabledGroups(cellValue);\r\n\r\n var isDisabled = this.enabledGroups.indexOf(cellValue)<0;\r\n this.plot.legend.container.selectAll(\"g.cell\").each(function(cell){\r\n if(cell == cellValue){\r\n d3.select(this).classed(\"odc-disabled\", isDisabled);\r\n }\r\n\r\n });\r\n\r\n this.init();\r\n }\r\n\r\n updateEnabledGroups(cellValue) {\r\n if (!this.enabledGroups) {\r\n this.enabledGroups = this.plot.dot.colorCategory.domain().slice();\r\n }\r\n var index = this.enabledGroups.indexOf(cellValue);\r\n\r\n if (index < 0) {\r\n this.enabledGroups.push(cellValue);\r\n } else {\r\n this.enabledGroups.splice(index, 1);\r\n }\r\n }\r\n\r\n\r\n\r\n setData(data){\r\n super.setData(data);\r\n this.enabledGroups = null;\r\n }\r\n}\r\n","/*\n * https://gist.github.com/benrasmusen/1261977\n * NAME\n * \n * statistics-distributions.js - JavaScript library for calculating\n * critical values and upper probabilities of common statistical\n * distributions\n * \n * SYNOPSIS\n * \n * \n * // Chi-squared-crit (2 degrees of freedom, 95th percentile = 0.05 level\n * chisqrdistr(2, .05)\n * \n * // u-crit (95th percentile = 0.05 level)\n * udistr(.05);\n * \n * // t-crit (1 degree of freedom, 99.5th percentile = 0.005 level) \n * tdistr(1,.005);\n * \n * // F-crit (1 degree of freedom in numerator, 3 degrees of freedom \n * // in denominator, 99th percentile = 0.01 level)\n * fdistr(1,3,.01);\n * \n * // upper probability of the u distribution (u = -0.85): Q(u) = 1-G(u)\n * uprob(-0.85);\n * \n * // upper probability of the chi-square distribution\n * // (3 degrees of freedom, chi-squared = 6.25): Q = 1-G\n * chisqrprob(3,6.25);\n * \n * // upper probability of the t distribution\n * // (3 degrees of freedom, t = 6.251): Q = 1-G\n * tprob(3,6.251);\n * \n * // upper probability of the F distribution\n * // (3 degrees of freedom in numerator, 5 degrees of freedom in\n * // denominator, F = 6.25): Q = 1-G\n * fprob(3,5,.625);\n * \n * \n * DESCRIPTION\n * \n * This library calculates percentage points (5 significant digits) of the u\n * (standard normal) distribution, the student's t distribution, the\n * chi-square distribution and the F distribution. It can also calculate the\n * upper probability (5 significant digits) of the u (standard normal), the\n * chi-square, the t and the F distribution.\n * \n * These critical values are needed to perform statistical tests, like the u\n * test, the t test, the F test and the chi-squared test, and to calculate\n * confidence intervals.\n * \n * If you are interested in more precise algorithms you could look at:\n * StatLib: http://lib.stat.cmu.edu/apstat/ ; \n * Applied Statistics Algorithms by Griffiths, P. and Hill, I.D.\n * , Ellis Horwood: Chichester (1985)\n * \n * BUGS \n * \n * This port was produced from the Perl module Statistics::Distributions\n * that has had no bug reports in several years. If you find a bug then\n * please double-check that JavaScript does not thing the numbers you are\n * passing in are strings. (You can subtract 0 from them as you pass them\n * in so that \"5\" is properly understood to be 5.) If you have passed in a\n * number then please contact the author\n * \n * AUTHOR\n * \n * Ben Tilly \n * \n * Originl Perl version by Michael Kospach \n * \n * Nice formating, simplification and bug repair by Matthias Trautner Kromann\n * \n * \n * COPYRIGHT \n * \n * Copyright 2008 Ben Tilly.\n * \n * This library is free software; you can redistribute it and/or modify it\n * under the same terms as Perl itself. This means under either the Perl\n * Artistic License or the GPL v1 or later.\n */\n\nvar SIGNIFICANT = 5; // number of significant digits to be returned\n\nfunction chisqrdistr ($n, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* degree of freedom */\n\t}\n\tif ($p <= 0 || $p > 1) {\n\t\tthrow(\"Invalid p: $p\\n\"); \n\t}\n\treturn precision_string(_subchisqr($n-0, $p-0));\n}\n\nfunction udistr ($p) {\n\tif ($p > 1 || $p <= 0) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\treturn precision_string(_subu($p-0));\n}\n\nexport function tdistr ($n, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow(\"Invalid n: $n\\n\");\n\t}\n\tif ($p <= 0 || $p >= 1) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\treturn precision_string(_subt($n-0, $p-0));\n}\n\nfunction fdistr ($n, $m, $p) {\n\tif (($n<=0) || ((Math.abs($n)-(Math.abs(integer($n))))!=0)) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* first degree of freedom */\n\t}\n\tif (($m<=0) || ((Math.abs($m)-(Math.abs(integer($m))))!=0)) {\n\t\tthrow(\"Invalid m: $m\\n\"); /* second degree of freedom */\n\t}\n\tif (($p<=0) || ($p>1)) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\treturn precision_string(_subf($n-0, $m-0, $p-0));\n}\n\nfunction uprob ($x) {\n\treturn precision_string(_subuprob($x-0));\n}\n\nfunction chisqrprob ($n,$x) {\n\tif (($n <= 0) || ((Math.abs($n) - (Math.abs(integer($n)))) != 0)) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* degree of freedom */\n\t}\n\treturn precision_string(_subchisqrprob($n-0, $x-0));\n}\n\nfunction tprob ($n, $x) {\n\tif (($n <= 0) || ((Math.abs($n) - Math.abs(integer($n))) !=0)) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* degree of freedom */\n\t}\n\treturn precision_string(_subtprob($n-0, $x-0));\n}\n\nfunction fprob ($n, $m, $x) {\n\tif (($n<=0) || ((Math.abs($n)-(Math.abs(integer($n))))!=0)) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* first degree of freedom */\n\t}\n\tif (($m<=0) || ((Math.abs($m)-(Math.abs(integer($m))))!=0)) {\n\t\tthrow(\"Invalid m: $m\\n\"); /* second degree of freedom */\n\t} \n\treturn precision_string(_subfprob($n-0, $m-0, $x-0));\n}\n\n\nfunction _subfprob ($n, $m, $x) {\n\tvar $p;\n\n\tif ($x<=0) {\n\t\t$p=1;\n\t} else if ($m % 2 == 0) {\n\t\tvar $z = $m / ($m + $n * $x);\n\t\tvar $a = 1;\n\t\tfor (var $i = $m - 2; $i >= 2; $i -= 2) {\n\t\t\t$a = 1 + ($n + $i - 2) / $i * $z * $a;\n\t\t}\n\t\t$p = 1 - Math.pow((1 - $z), ($n / 2) * $a);\n\t} else if ($n % 2 == 0) {\n\t\tvar $z = $n * $x / ($m + $n * $x);\n\t\tvar $a = 1;\n\t\tfor (var $i = $n - 2; $i >= 2; $i -= 2) {\n\t\t\t$a = 1 + ($m + $i - 2) / $i * $z * $a;\n\t\t}\n\t\t$p = Math.pow((1 - $z), ($m / 2)) * $a;\n\t} else {\n\t\tvar $y = Math.atan2(Math.sqrt($n * $x / $m), 1);\n\t\tvar $z = Math.pow(Math.sin($y), 2);\n\t\tvar $a = ($n == 1) ? 0 : 1;\n\t\tfor (var $i = $n - 2; $i >= 3; $i -= 2) {\n\t\t\t$a = 1 + ($m + $i - 2) / $i * $z * $a;\n\t\t} \n\t\tvar $b = Math.PI;\n\t\tfor (var $i = 2; $i <= $m - 1; $i += 2) {\n\t\t\t$b *= ($i - 1) / $i;\n\t\t}\n\t\tvar $p1 = 2 / $b * Math.sin($y) * Math.pow(Math.cos($y), $m) * $a;\n\n\t\t$z = Math.pow(Math.cos($y), 2);\n\t\t$a = ($m == 1) ? 0 : 1;\n\t\tfor (var $i = $m-2; $i >= 3; $i -= 2) {\n\t\t\t$a = 1 + ($i - 1) / $i * $z * $a;\n\t\t}\n\t\t$p = max(0, $p1 + 1 - 2 * $y / Math.PI\n\t\t\t- 2 / Math.PI * Math.sin($y) * Math.cos($y) * $a);\n\t}\n\treturn $p;\n}\n\n\nfunction _subchisqrprob ($n,$x) {\n\tvar $p;\n\n\tif ($x <= 0) {\n\t\t$p = 1;\n\t} else if ($n > 100) {\n\t\t$p = _subuprob((Math.pow(($x / $n), 1/3)\n\t\t\t\t- (1 - 2/9/$n)) / Math.sqrt(2/9/$n));\n\t} else if ($x > 400) {\n\t\t$p = 0;\n\t} else { \n\t\tvar $a;\n var $i;\n var $i1;\n\t\tif (($n % 2) != 0) {\n\t\t\t$p = 2 * _subuprob(Math.sqrt($x));\n\t\t\t$a = Math.sqrt(2/Math.PI) * Math.exp(-$x/2) / Math.sqrt($x);\n\t\t\t$i1 = 1;\n\t\t} else {\n\t\t\t$p = $a = Math.exp(-$x/2);\n\t\t\t$i1 = 2;\n\t\t}\n\n\t\tfor ($i = $i1; $i <= ($n-2); $i += 2) {\n\t\t\t$a *= $x / $i;\n\t\t\t$p += $a;\n\t\t}\n\t}\n\treturn $p;\n}\n\nfunction _subu ($p) {\n\tvar $y = -Math.log(4 * $p * (1 - $p));\n\tvar $x = Math.sqrt(\n\t\t$y * (1.570796288\n\t\t + $y * (.03706987906\n\t\t \t+ $y * (-.8364353589E-3\n\t\t\t + $y *(-.2250947176E-3\n\t\t\t \t+ $y * (.6841218299E-5\n\t\t\t\t + $y * (0.5824238515E-5\n\t\t\t\t\t+ $y * (-.104527497E-5\n\t\t\t\t\t + $y * (.8360937017E-7\n\t\t\t\t\t\t+ $y * (-.3231081277E-8\n\t\t\t\t\t\t + $y * (.3657763036E-10\n\t\t\t\t\t\t\t+ $y *.6936233982E-12)))))))))));\n\tif ($p>.5)\n $x = -$x;\n\treturn $x;\n}\n\nfunction _subuprob ($x) {\n\tvar $p = 0; /* if ($absx > 100) */\n\tvar $absx = Math.abs($x);\n\n\tif ($absx < 1.9) {\n\t\t$p = Math.pow((1 +\n\t\t\t$absx * (.049867347\n\t\t\t + $absx * (.0211410061\n\t\t\t \t+ $absx * (.0032776263\n\t\t\t\t + $absx * (.0000380036\n\t\t\t\t\t+ $absx * (.0000488906\n\t\t\t\t\t + $absx * .000005383)))))), -16)/2;\n\t} else if ($absx <= 100) {\n\t\tfor (var $i = 18; $i >= 1; $i--) {\n\t\t\t$p = $i / ($absx + $p);\n\t\t}\n\t\t$p = Math.exp(-.5 * $absx * $absx) \n\t\t\t/ Math.sqrt(2 * Math.PI) / ($absx + $p);\n\t}\n\n\tif ($x<0)\n \t$p = 1 - $p;\n\treturn $p;\n}\n\n \nfunction _subt ($n, $p) {\n\n\tif ($p >= 1 || $p <= 0) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\n\tif ($p == 0.5) {\n\t\treturn 0;\n\t} else if ($p < 0.5) {\n\t\treturn - _subt($n, 1 - $p);\n\t}\n\n\tvar $u = _subu($p);\n\tvar $u2 = Math.pow($u, 2);\n\n\tvar $a = ($u2 + 1) / 4;\n\tvar $b = ((5 * $u2 + 16) * $u2 + 3) / 96;\n\tvar $c = (((3 * $u2 + 19) * $u2 + 17) * $u2 - 15) / 384;\n\tvar $d = ((((79 * $u2 + 776) * $u2 + 1482) * $u2 - 1920) * $u2 - 945) \n\t\t\t\t/ 92160;\n\tvar $e = (((((27 * $u2 + 339) * $u2 + 930) * $u2 - 1782) * $u2 - 765) * $u2\n\t\t\t+ 17955) / 368640;\n\n\tvar $x = $u * (1 + ($a + ($b + ($c + ($d + $e / $n) / $n) / $n) / $n) / $n);\n\n\tif ($n <= Math.pow(log10($p), 2) + 3) {\n\t\tvar $round;\n\t\tdo { \n\t\t\tvar $p1 = _subtprob($n, $x);\n\t\t\tvar $n1 = $n + 1;\n\t\t\tvar $delta = ($p1 - $p) \n\t\t\t\t/ Math.exp(($n1 * Math.log($n1 / ($n + $x * $x)) \n\t\t\t\t\t+ Math.log($n/$n1/2/Math.PI) - 1 \n\t\t\t\t\t+ (1/$n1 - 1/$n) / 6) / 2);\n\t\t\t$x += $delta;\n\t\t\t$round = round_to_precision($delta, Math.abs(integer(log10(Math.abs($x))-4)));\n\t\t} while (($x) && ($round != 0));\n\t}\n\treturn $x;\n}\n\nfunction _subtprob ($n, $x) {\n\n\tvar $a;\n var $b;\n\tvar $w = Math.atan2($x / Math.sqrt($n), 1);\n\tvar $z = Math.pow(Math.cos($w), 2);\n\tvar $y = 1;\n\n\tfor (var $i = $n-2; $i >= 2; $i -= 2) {\n\t\t$y = 1 + ($i-1) / $i * $z * $y;\n\t} \n\n\tif ($n % 2 == 0) {\n\t\t$a = Math.sin($w)/2;\n\t\t$b = .5;\n\t} else {\n\t\t$a = ($n == 1) ? 0 : Math.sin($w)*Math.cos($w)/Math.PI;\n\t\t$b= .5 + $w/Math.PI;\n\t}\n\treturn max(0, 1 - $b - $a * $y);\n}\n\nfunction _subf ($n, $m, $p) {\n\tvar $x;\n\n\tif ($p >= 1 || $p <= 0) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\n\tif ($p == 1) {\n\t\t$x = 0;\n\t} else if ($m == 1) {\n\t\t$x = 1 / Math.pow(_subt($n, 0.5 - $p / 2), 2);\n\t} else if ($n == 1) {\n\t\t$x = Math.pow(_subt($m, $p/2), 2);\n\t} else if ($m == 2) {\n\t\tvar $u = _subchisqr($m, 1 - $p);\n\t\tvar $a = $m - 2;\n\t\t$x = 1 / ($u / $m * (1 +\n\t\t\t(($u - $a) / 2 +\n\t\t\t\t(((4 * $u - 11 * $a) * $u + $a * (7 * $m - 10)) / 24 +\n\t\t\t\t\t(((2 * $u - 10 * $a) * $u + $a * (17 * $m - 26)) * $u\n\t\t\t\t\t\t- $a * $a * (9 * $m - 6)\n\t\t\t\t\t)/48/$n\n\t\t\t\t)/$n\n\t\t\t)/$n));\n\t} else if ($n > $m) {\n\t\t$x = 1 / _subf2($m, $n, 1 - $p)\n\t} else {\n\t\t$x = _subf2($n, $m, $p)\n\t}\n\treturn $x;\n}\n\nfunction _subf2 ($n, $m, $p) {\n\tvar $u = _subchisqr($n, $p);\n\tvar $n2 = $n - 2;\n\tvar $x = $u / $n * \n\t\t(1 + \n\t\t\t(($u - $n2) / 2 + \n\t\t\t\t(((4 * $u - 11 * $n2) * $u + $n2 * (7 * $n - 10)) / 24 + \n\t\t\t\t\t(((2 * $u - 10 * $n2) * $u + $n2 * (17 * $n - 26)) * $u \n\t\t\t\t\t\t- $n2 * $n2 * (9 * $n - 6)) / 48 / $m) / $m) / $m);\n\tvar $delta;\n\tdo {\n\t\tvar $z = Math.exp(\n\t\t\t(($n+$m) * Math.log(($n+$m) / ($n * $x + $m)) \n\t\t\t\t+ ($n - 2) * Math.log($x)\n\t\t\t\t+ Math.log($n * $m / ($n+$m))\n\t\t\t\t- Math.log(4 * Math.PI)\n\t\t\t\t- (1/$n + 1/$m - 1/($n+$m))/6\n\t\t\t)/2);\n\t\t$delta = (_subfprob($n, $m, $x) - $p) / $z;\n\t\t$x += $delta;\n\t} while (Math.abs($delta)>3e-4);\n\treturn $x;\n}\n\nfunction _subchisqr ($n, $p) {\n\tvar $x;\n\n\tif (($p > 1) || ($p <= 0)) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t} else if ($p == 1){\n\t\t$x = 0;\n\t} else if ($n == 1) {\n\t\t$x = Math.pow(_subu($p / 2), 2);\n\t} else if ($n == 2) {\n\t\t$x = -2 * Math.log($p);\n\t} else {\n\t\tvar $u = _subu($p);\n\t\tvar $u2 = $u * $u;\n\n\t\t$x = max(0, $n + Math.sqrt(2 * $n) * $u \n\t\t\t+ 2/3 * ($u2 - 1)\n\t\t\t+ $u * ($u2 - 7) / 9 / Math.sqrt(2 * $n)\n\t\t\t- 2/405 / $n * ($u2 * (3 *$u2 + 7) - 16));\n\n\t\tif ($n <= 100) {\n\t\t\tvar $x0;\n var $p1;\n var $z;\n\t\t\tdo {\n\t\t\t\t$x0 = $x;\n\t\t\t\tif ($x < 0) {\n\t\t\t\t\t$p1 = 1;\n\t\t\t\t} else if ($n>100) {\n\t\t\t\t\t$p1 = _subuprob((Math.pow(($x / $n), (1/3)) - (1 - 2/9/$n))\n\t\t\t\t\t\t/ Math.sqrt(2/9/$n));\n\t\t\t\t} else if ($x>400) {\n\t\t\t\t\t$p1 = 0;\n\t\t\t\t} else {\n\t\t\t\t\tvar $i0\n var $a;\n\t\t\t\t\tif (($n % 2) != 0) {\n\t\t\t\t\t\t$p1 = 2 * _subuprob(Math.sqrt($x));\n\t\t\t\t\t\t$a = Math.sqrt(2/Math.PI) * Math.exp(-$x/2) / Math.sqrt($x);\n\t\t\t\t\t\t$i0 = 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$p1 = $a = Math.exp(-$x/2);\n\t\t\t\t\t\t$i0 = 2;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (var $i = $i0; $i <= $n-2; $i += 2) {\n\t\t\t\t\t\t$a *= $x / $i;\n\t\t\t\t\t\t$p1 += $a;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$z = Math.exp((($n-1) * Math.log($x/$n) - Math.log(4*Math.PI*$x) \n\t\t\t\t\t+ $n - $x - 1/$n/6) / 2);\n\t\t\t\t$x += ($p1 - $p) / $z;\n\t\t\t\t$x = round_to_precision($x, 5);\n\t\t\t} while (($n < 31) && (Math.abs($x0 - $x) > 1e-4));\n\t\t}\n\t}\n\treturn $x;\n}\n\nfunction log10 ($n) {\n\treturn Math.log($n) / Math.log(10);\n}\n \nfunction max () {\n\tvar $max = arguments[0];\n\tfor (var $i = 0; i < arguments.length; i++) {\n if ($max < arguments[$i])\n $max = arguments[$i];\n\t}\t\n\treturn $max;\n}\n\nfunction min () {\n\tvar $min = arguments[0];\n\tfor (var $i = 0; i < arguments.length; i++) {\n if ($min > arguments[$i])\n $min = arguments[$i];\n\t}\n\treturn $min;\n}\n\nfunction precision ($x) {\n\treturn Math.abs(integer(log10(Math.abs($x)) - SIGNIFICANT));\n}\n\nfunction precision_string ($x) {\n\tif ($x) {\n\t\treturn round_to_precision($x, precision($x));\n\t} else {\n\t\treturn \"0\";\n\t}\n}\n\nfunction round_to_precision ($x, $p) {\n $x = $x * Math.pow(10, $p);\n $x = Math.round($x);\n return $x / Math.pow(10, $p);\n}\n\nfunction integer ($i) {\n if ($i > 0)\n return Math.floor($i);\n else\n return Math.ceil($i);\n}","import {tdistr} from \"./statistics-distributions\"\r\n\r\nvar su = module.exports.StatisticsUtils ={};\r\nsu.sampleCorrelation = require('../bower_components/simple-statistics/src/sample_correlation');\r\nsu.linearRegression = require('../bower_components/simple-statistics/src/linear_regression');\r\nsu.linearRegressionLine = require('../bower_components/simple-statistics/src/linear_regression_line');\r\nsu.errorFunction = require('../bower_components/simple-statistics/src/error_function');\r\nsu.standardDeviation = require('../bower_components/simple-statistics/src/standard_deviation');\r\nsu.sampleStandardDeviation = require('../bower_components/simple-statistics/src/sample_standard_deviation');\r\nsu.variance = require('../bower_components/simple-statistics/src/variance');\r\nsu.mean = require('../bower_components/simple-statistics/src/mean');\r\nsu.zScore = require('../bower_components/simple-statistics/src/z_score');\r\nsu.standardError= arr => Math.sqrt(su.variance(arr)/(arr.length-1));\r\n\r\n\r\nsu.tValue= (degreesOfFreedom, criticalProbability) => { //as in http://stattrek.com/online-calculator/t-distribution.aspx\r\n return tdistr(degreesOfFreedom, criticalProbability);\r\n};","export class Utils {\r\n static SQRT_2 = 1.41421356237;\r\n // usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB);\r\n static deepExtend(out) {\r\n\r\n var utils = this;\r\n var emptyOut = {};\r\n\r\n\r\n if (!out && arguments.length > 1 && Array.isArray(arguments[1])) {\r\n out = [];\r\n }\r\n out = out || {};\r\n\r\n for (var i = 1; i < arguments.length; i++) {\r\n var source = arguments[i];\r\n if (!source)\r\n continue;\r\n\r\n for (var key in source) {\r\n if (!source.hasOwnProperty(key)) {\r\n continue;\r\n }\r\n var isArray = Array.isArray(out[key]);\r\n var isObject = utils.isObject(out[key]);\r\n var srcObj = utils.isObject(source[key]);\r\n\r\n if (isObject && !isArray && srcObj) {\r\n utils.deepExtend(out[key], source[key]);\r\n } else {\r\n out[key] = source[key];\r\n }\r\n }\r\n }\r\n\r\n return out;\r\n };\r\n\r\n static mergeDeep(target, source) {\r\n let output = Object.assign({}, target);\r\n if (Utils.isObjectNotArray(target) && Utils.isObjectNotArray(source)) {\r\n Object.keys(source).forEach(key => {\r\n if (Utils.isObjectNotArray(source[key])) {\r\n if (!(key in target))\r\n Object.assign(output, {[key]: source[key]});\r\n else\r\n output[key] = Utils.mergeDeep(target[key], source[key]);\r\n } else {\r\n Object.assign(output, {[key]: source[key]});\r\n }\r\n });\r\n }\r\n return output;\r\n }\r\n\r\n static cross(a, b) {\r\n var c = [], n = a.length, m = b.length, i, j;\r\n for (i = -1; ++i < n;) for (j = -1; ++j < m;) c.push({x: a[i], i: i, y: b[j], j: j});\r\n return c;\r\n };\r\n\r\n static inferVariables(data, groupKey, includeGroup) {\r\n var res = [];\r\n if (data.length) {\r\n var d = data[0];\r\n if (d instanceof Array) {\r\n res = d.map(function (v, i) {\r\n return i;\r\n });\r\n } else if (typeof d === 'object') {\r\n\r\n for (var prop in d) {\r\n if (!d.hasOwnProperty(prop)) continue;\r\n\r\n res.push(prop);\r\n }\r\n }\r\n }\r\n if (!includeGroup) {\r\n var index = res.indexOf(groupKey);\r\n if (index > -1) {\r\n res.splice(index, 1);\r\n }\r\n }\r\n return res\r\n };\r\n\r\n static isObjectNotArray(item) {\r\n return (item && typeof item === 'object' && !Array.isArray(item) && item !== null);\r\n };\r\n\r\n static isObject(a) {\r\n return a !== null && typeof a === 'object';\r\n };\r\n\r\n static isNumber(a) {\r\n return !isNaN(a) && typeof a === 'number';\r\n };\r\n\r\n static isFunction(a) {\r\n return typeof a === 'function';\r\n };\r\n\r\n static isDate(a){\r\n return Object.prototype.toString.call(a) === '[object Date]'\r\n }\r\n\r\n static isString(a){\r\n return typeof a === 'string' || a instanceof String\r\n }\r\n\r\n static insertOrAppendSelector(parent, selector, operation, before) {\r\n var selectorParts = selector.split(/([\\.\\#])/);\r\n var element = parent[operation](selectorParts.shift(), before);//\":first-child\"\r\n while (selectorParts.length > 1) {\r\n var selectorModifier = selectorParts.shift();\r\n var selectorItem = selectorParts.shift();\r\n if (selectorModifier === \".\") {\r\n element = element.classed(selectorItem, true);\r\n } else if (selectorModifier === \"#\") {\r\n element = element.attr('id', selectorItem);\r\n }\r\n }\r\n return element;\r\n }\r\n\r\n static insertSelector(parent, selector, before) {\r\n return Utils.insertOrAppendSelector(parent, selector, \"insert\", before);\r\n }\r\n\r\n static appendSelector(parent, selector) {\r\n return Utils.insertOrAppendSelector(parent, selector, \"append\");\r\n }\r\n\r\n static selectOrAppend(parent, selector, element) {\r\n var selection = parent.select(selector);\r\n if (selection.empty()) {\r\n if (element) {\r\n return parent.append(element);\r\n }\r\n return Utils.appendSelector(parent, selector);\r\n\r\n }\r\n return selection;\r\n };\r\n\r\n static selectOrInsert(parent, selector, before) {\r\n var selection = parent.select(selector);\r\n if (selection.empty()) {\r\n return Utils.insertSelector(parent, selector, before);\r\n }\r\n return selection;\r\n };\r\n\r\n static linearGradient(svg, gradientId, range, x1, y1, x2, y2) {\r\n var defs = Utils.selectOrAppend(svg, \"defs\");\r\n var linearGradient = defs.append(\"linearGradient\")\r\n .attr(\"id\", gradientId);\r\n\r\n linearGradient\r\n .attr(\"x1\", x1 + \"%\")\r\n .attr(\"y1\", y1 + \"%\")\r\n .attr(\"x2\", x2 + \"%\")\r\n .attr(\"y2\", y2 + \"%\");\r\n\r\n //Append multiple color stops by using D3's data/enter step\r\n var stops = linearGradient.selectAll(\"stop\")\r\n .data(range);\r\n\r\n stops.enter().append(\"stop\");\r\n\r\n stops.attr(\"offset\", (d, i) => i / (range.length - 1))\r\n .attr(\"stop-color\", d => d);\r\n\r\n stops.exit().remove();\r\n }\r\n\r\n static sanitizeHeight = function (height, container) {\r\n return (height || parseInt(container.style('height'), 10) || 400);\r\n };\r\n\r\n static sanitizeWidth = function (width, container) {\r\n return (width || parseInt(container.style('width'), 10) || 960);\r\n };\r\n\r\n static availableHeight = function (height, container, margin) {\r\n return Math.max(0, Utils.sanitizeHeight(height, container) - margin.top - margin.bottom);\r\n };\r\n\r\n static availableWidth = function (width, container, margin) {\r\n return Math.max(0, Utils.sanitizeWidth(width, container) - margin.left - margin.right);\r\n };\r\n\r\n static guid() {\r\n function s4() {\r\n return Math.floor((1 + Math.random()) * 0x10000)\r\n .toString(16)\r\n .substring(1);\r\n }\r\n\r\n return s4() + s4() + '-' + s4() + '-' + s4() + '-' +\r\n s4() + '-' + s4() + s4() + s4();\r\n }\r\n\r\n //places textString in textObj, adds an ellipsis if text can't fit in width\r\n static placeTextWithEllipsis(textD3Obj, textString, width){\r\n var textObj = textD3Obj.node();\r\n textObj.textContent=textString;\r\n\r\n var margin = 0;\r\n var ellipsisLength = 9;\r\n //ellipsis is needed\r\n if (textObj.getComputedTextLength()>width+margin){\r\n for (var x=textString.length-3;x>0;x-=1){\r\n if (textObj.getSubStringLength(0,x)+ellipsisLength<=width+margin){\r\n textObj.textContent=textString.substring(0,x)+\"...\";\r\n return true;\r\n }\r\n }\r\n textObj.textContent=\"...\"; //can't place at all\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n static placeTextWithEllipsisAndTooltip(textD3Obj, textString, width, tooltip){\r\n var ellipsisPlaced = Utils.placeTextWithEllipsis(textD3Obj, textString, width);\r\n if(ellipsisPlaced && tooltip){\r\n textD3Obj.on(\"mouseover\", function (d) {\r\n tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n tooltip.html(textString)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n });\r\n\r\n textD3Obj.on(\"mouseout\", function (d) {\r\n tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n\r\n }\r\n\r\n static getFontSize(element){\r\n return window.getComputedStyle(element, null).getPropertyValue(\"font-size\");\r\n }\r\n}\r\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","odc-d3.js","bower_components/d3-legend/no-extend.js","bower_components/d3-legend/src/color.js","bower_components/d3-legend/src/legend.js","bower_components/d3-legend/src/size.js","bower_components/d3-legend/src/symbol.js","bower_components/simple-statistics/src/error_function.js","bower_components/simple-statistics/src/linear_regression.js","bower_components/simple-statistics/src/linear_regression_line.js","bower_components/simple-statistics/src/mean.js","bower_components/simple-statistics/src/sample_correlation.js","bower_components/simple-statistics/src/sample_covariance.js","bower_components/simple-statistics/src/sample_standard_deviation.js","bower_components/simple-statistics/src/sample_variance.js","bower_components/simple-statistics/src/standard_deviation.js","bower_components/simple-statistics/src/sum.js","bower_components/simple-statistics/src/sum_nth_power_deviations.js","bower_components/simple-statistics/src/variance.js","bower_components/simple-statistics/src/z_score.js","src/bar-chart.js","src/chart.js","src/correlation-matrix.js","src/d3-extensions.js","src/heatmap-timeseries.js","src/heatmap.js","src/histogram.js","src/index.js","src/legend.js","src/regression.js","src/scatterplot-matrix.js","src/scatterplot.js","src/statistics-distributions.js","src/statistics-utils.js","src/utils.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","ODCD3","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","color","size","symbol","./src/color","./src/size","./src/symbol","2","helper","legend","svg","type","d3_calcType","scale","ascending","cells","labels","labelFormat","labelDelimiter","legendG","selectAll","data","enter","append","attr","classPrefix","cell","cellEnter","style","shapes","shape","select","d3_addEvents","legendDispatcher","exit","transition","remove","d3_drawShapes","shapeHeight","shapeWidth","shapeRadius","path","d3_addText","text","shapeSize","map","d","getBBox","useClass","feature","cellTrans","textTrans","textAlign","labelAlign","orient","height","shapePadding","width","x","labelOffset","y","d3_placement","d3_title","title","d3","linear","format","dispatch","_","arguments","toLowerCase","rebind","./legend","3","d3_identity","d3_mergeLabels","gen","push","d3_linearLegend","domain","increment","d3_quantLegend","range","invert","invertExtent","d3_ordinalLegend","ticks","d3_reverse","arr","mirror","dispatcher","on","d3_cellOver","d3_cellOut","d3_cellClick","cellDispatcher","obj","cellover","cellout","cellclick","cellsSvg","titleText","yOffset","xOffset","4","bbox","stroke","maxH","max","maxW","sum","slice","5","6","errorFunction","Math","abs","tau","exp","pow","7","linearRegression","m","b","dataLength","point","sumX","sumY","sumXX","sumXY","8","linearRegressionLine","mb","9","mean","NaN","./sum","10","sampleCorrelation","cov","sampleCovariance","xstd","sampleStandardDeviation","ystd","./sample_covariance","./sample_standard_deviation","11","xmean","ymean","besselsCorrection","./mean","12","sampleVarianceX","sampleVariance","isNaN","sqrt","./sample_variance","13","sumSquaredDeviationsValue","sumNthPowerDeviations","./sum_nth_power_deviations","14","standardDeviation","v","variance","./variance","15","correctedCurrentValue","nextSum","errorCompensation","16","meanValue","17","18","zScore","19","_classCallCheck","instance","Constructor","TypeError","_possibleConstructorReturn","ReferenceError","_inherits","subClass","superClass","prototype","Object","create","constructor","value","enumerable","writable","configurable","setPrototypeOf","__proto__","defineProperty","BarChart","BarChartConfig","undefined","_createClass","defineProperties","target","props","descriptor","key","protoProps","staticProps","_get","get","object","property","receiver","Function","desc","getOwnPropertyDescriptor","parent","getPrototypeOf","getter","_chart","_utils","_legend","_ChartConfig","custom","_this","svgClass","cssClassPrefix","showLegend","showTooltip","margin","label","Utils","isNumber","groups","d3ColorCategory","deepExtend","ChartConfig","_Chart","placeholderSelector","config","conf","plot","right","computePlotSize","setupY","setupX","setupGroupStacks","setupYDomain","colorCategory","colorValue","String","ordinal","rangeRoundBands","axis","series","values","keys","yStackMax","layers","layer","y0","min","groupingEnabled","groupedData","mapToPoints","groupData","stack","layout","axisConf","svgG","selectOrAppend","prefixClass","guides","axisT","ease","bottom","left","layerClass","barClass","bar","barRect","barRectT","barT","layerT","transitionEnabled","yDomain","rangeBand","tooltip","duration","html","event","pageX","pageY","newData","drawAxisX","drawAxisY","drawBars","updateLegend","container","legendX","legendY","Legend","legendLinear","Chart","./chart","./utils","20","top","base","utils","_attached","_layers","_events","_isInitialized","_isAttached","baseContainer","setConfig","setData","init","postInit","initPlot","initSvg","initTooltip","draw","attachmentData","attachmentName","update","chart","name","callback","context","events","once","off","apply","names","j","splice","ev","args","Array","getBaseContainer","node","clazz","addDot","availableWidth","availableHeight","21","CorrelationMatrix","CorrelationMatrixConfig","_statisticsUtils","_scatterplot","highlightLabels","rotateLabelsX","rotateLabelsY","variables","variableKey","correlation","xValues","yValues","StatisticsUtils","sizeMin","sizeMax","padding","matrix","setupVariables","placeholderNode","getBaseContainerNode","parentWidth","getBoundingClientRect","cellSize","setupVariablesScales","setupCorrelationScales","setupCorrelationMatrix","rangeBands","corrConf","cellConf","radiusMax","radiusScale","radius","c","radiusX","radiusY","rotateVal","variablesConf","domainByVariable","inferVariables","includeInPlot","labelByVariable","forEach","index","extent","matrixCells","variableToValues","v1","row","v2","corr","rowVar","colVar","col","updateCells","updateVariableLabels","labelClass","updateAxisX","updateAxisY","labelXClass","maxWidth","computeXAxisLabelsWidth","each","placeTextWithEllipsisAndTooltip","labelYClass","computeYAxisLabelsWidth","SQRT_2","fontSize","offset","cellClass","cellShape","classed","scatterPlot","selector","wrongShapes","mouseoverCallbacks","mouseoutCallbacks","highlightClass","xLabelClass","yLabelClass","trigger","barWidth","barHeight","linearGradientBar","containerSelector","_this3","scatterPlotConfig","ScatterPlot","attach","./scatterplot","./statistics-utils","22","D3Extensions","selection","insertSelector","before","appendSelector","selectOrInsert","23","HeatmapTimeSeries","HeatmapTimeSeriesConfig","_heatmap","_HeatmapConfig","fillMissing","interval","intervalStep","displayFormat","intervalToFormats","formats","sortComparator","isString","localeCompare","formatter","z","suffix","Number","toFixed","nf","Intl","NumberFormat","HeatmapConfig","_Heatmap","timeFormat","guessTimeFormat","initTimeFormatAndInterval","timeParser","getTimeParser","uniqueValues","sort","prev","current","parseTime","next","nextTimeTickValue","missing","iteration","compareTimeValues","timeString","formatTime","updateGroups","parser","parse","date","time","isDate","rowIndex","prevRowValue","colIndex","guessInterval","intervalFormat","formatMatch","some","every","indexOf","Heatmap","./heatmap","24","noDataText","rotateLabels","decimalPlaces","sortLabels","overlap","notAvailableValue","noDataColor","reverseScale","matrixes","setupValues","buildCells","titleRectWidth","groupByX","depth","allTitlesWidth","groupByY","_depth","_allTitlesWidth","setupZScale","children","level","lastIndex","valueMap","minZ","maxZ","xVal","yVal","zValRaw","zVal","parseFloat","groupY","groupX","setupValuesBeforeGroupsSort","gaps","totalValuesCount","allValuesList","sortGroups","group","val","axisVal","rootGroup","axisGroupsConfig","currentGroup","groupKey","groupKeyIndex","groupingValue","hasOwnProperty","axisConfig","allValuesCount","allValuesBeforeCount","gapsBefore","gapsSize","computeGapsSize","gapsBeforeSize","childrenList","childrenCount","childProp","child","gapsInside","gapsInsideSize","cellWidth","xGapsSize","computedCellWidth","yGapsSize","computedCellHeight","cellHeight","exponent","unshift","log","reverse","drawGroupsY","drawGroupsX","updateAxisTitles","offsetX","gapSize","computeGapSize","formatValueX","elem","offsetY","formatted","formatValueY","parentGroup","groupClass","groupYClass","valuesBeforeCount","groupsEnterG","titleGroupEnter","groupTitleRectHeight","translate","groupWidth","titleGroups","tileRects","setGroupMouseCallbacks","groupXClass","titleRectHeight","groupHeight","parentNode","cellContainerClass","paddingX","paddingY","cellContainer","formatValueZ","formatLegendValue","setRotateLabels","gapLevel","maxGroupGapSize","gapsNumber","gapsLevel","25","Histogram","HistogramConfig","frequency","getOwnPropertyNames","getDataToPlot","setupHistogram","histogramBins","histogram","bins","_this4","nest","entries","dy","stackedHistograms","_this5","enabledGroups","filter","dx","drawHistogram","_this6","legendColor","onLegendCellClick","cellValue","updateEnabledGroups","isDisabled","26","RegressionConfig","Regression","ScatterPlotMatrixConfig","ScatterPlotMatrix","ScatterPlotConfig","_scatterplotMatrix","_correlationMatrix","_regression","_heatmapTimeseries","_histogram","_barChart","_d3Extensions","extend","./bar-chart","./correlation-matrix","./d3-extensions","./heatmap-timeseries","./histogram","./regression","./scatterplot-matrix","27","_noExtend","legendParent","legendClass","guid","gradientId","linearGradient","ticksNumber","../bower_components/d3-legend/no-extend","28","_ScatterPlotConfig","mainRegression","groupRegression","confidence","criticalValue","degreesOfFreedom","criticalProbability","tValue","marginOfError","_ScatterPlot","initRegressionLines","groupsAvailable","regressions","regression","initRegression","initGroupRegression","dataByGroup","groupVal","points","extentX","linePoints","line","interpolate","dot","defaultColor","isFunction","computeConfidence","alpha","meanX","xMySum","xSum","xPowSum","ySum","yPowSum","p","Sa2","Sy2","errorFn","computeConfidenceAreaPoint","moe","confDown","confUp","y1","centerX","confidenceAreaPoints","fitInPlot","confidenceArea","area","updateRegressionLines","regressionContainerClass","regressionContainerSelector","clipPathId","regressionContainer","dotsContainerClass","regressionContainerClip","regressionClass","confidenceAreaClass","regressionSelector","regressionEnterG","lineClass","lineT","areaT","29","brush","setupGroups","boundingClientRect","groupValue","subplots","variable","tickSize","plotSubplot","frameClass","subplot","dots","dotsT","axisClass","axisXClass","axisYClass","xAxisSelector","yAxisSelector","noGuidesClass","cross","drawBrush","brushstart","brushCell","clear","brushmove","brushend","empty","30","updateDots","dotClass","dotsContainer","31","tdistr","$n","$p","integer","precision_string","_subt","_subu","$y","$x","$u","$u2","$a","$b","$c","$d","$e","log10","$round","$p1","_subtprob","$n1","$delta","PI","round_to_precision","$w","atan2","$z","cos","$i","sin","$max","precision","SIGNIFICANT","round","floor","ceil","32","_statisticsDistributions","su","standardError","../bower_components/simple-statistics/src/error_function","../bower_components/simple-statistics/src/linear_regression","../bower_components/simple-statistics/src/linear_regression_line","../bower_components/simple-statistics/src/mean","../bower_components/simple-statistics/src/sample_correlation","../bower_components/simple-statistics/src/sample_standard_deviation","../bower_components/simple-statistics/src/standard_deviation","../bower_components/simple-statistics/src/variance","../bower_components/simple-statistics/src/z_score","./statistics-distributions","33","_defineProperty","_typeof","Symbol","iterator","out","isArray","source","isObject","srcObj","output","assign","isObjectNotArray","mergeDeep","includeGroup","res","prop","item","toString","operation","selectorParts","split","element","shift","selectorModifier","selectorItem","insertOrAppendSelector","x1","x2","y2","defs","stops","s4","random","substring","textD3Obj","textString","textObj","textContent","ellipsisLength","getComputedTextLength","getSubStringLength","ellipsisPlaced","placeTextWithEllipsis","getComputedStyle","getPropertyValue","sanitizeHeight","parseInt","sanitizeWidth"],"mappings":"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","file":"odc-d3.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 1 || _ >= 2) {\n cells = _;\n }\n return legend;\n };\n\n legend.shape = function (_, d) {\n if (!arguments.length) return shape;\n if (_ == \"rect\" || _ == \"circle\" || _ == \"line\" || _ == \"path\" && typeof d === 'string') {\n shape = _;\n path = d;\n }\n return legend;\n };\n\n legend.shapeWidth = function (_) {\n if (!arguments.length) return shapeWidth;\n shapeWidth = +_;\n return legend;\n };\n\n legend.shapeHeight = function (_) {\n if (!arguments.length) return shapeHeight;\n shapeHeight = +_;\n return legend;\n };\n\n legend.shapeRadius = function (_) {\n if (!arguments.length) return shapeRadius;\n shapeRadius = +_;\n return legend;\n };\n\n legend.shapePadding = function (_) {\n if (!arguments.length) return shapePadding;\n shapePadding = +_;\n return legend;\n };\n\n legend.labels = function (_) {\n if (!arguments.length) return labels;\n labels = _;\n return legend;\n };\n\n legend.labelAlign = function (_) {\n if (!arguments.length) return labelAlign;\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\n labelAlign = _;\n }\n return legend;\n };\n\n legend.labelFormat = function (_) {\n if (!arguments.length) return labelFormat;\n labelFormat = _;\n return legend;\n };\n\n legend.labelOffset = function (_) {\n if (!arguments.length) return labelOffset;\n labelOffset = +_;\n return legend;\n };\n\n legend.labelDelimiter = function (_) {\n if (!arguments.length) return labelDelimiter;\n labelDelimiter = _;\n return legend;\n };\n\n legend.useClass = function (_) {\n if (!arguments.length) return useClass;\n if (_ === true || _ === false) {\n useClass = _;\n }\n return legend;\n };\n\n legend.orient = function (_) {\n if (!arguments.length) return orient;\n _ = _.toLowerCase();\n if (_ == \"horizontal\" || _ == \"vertical\") {\n orient = _;\n }\n return legend;\n };\n\n legend.ascending = function (_) {\n if (!arguments.length) return ascending;\n ascending = !!_;\n return legend;\n };\n\n legend.classPrefix = function (_) {\n if (!arguments.length) return classPrefix;\n classPrefix = _;\n return legend;\n };\n\n legend.title = function (_) {\n if (!arguments.length) return title;\n title = _;\n return legend;\n };\n\n d3.rebind(legend, legendDispatcher, \"on\");\n\n return legend;\n};\n\n},{\"./legend\":3}],3:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = {\n\n d3_identity: function d3_identity(d) {\n return d;\n },\n\n d3_mergeLabels: function d3_mergeLabels(gen, labels) {\n\n if (labels.length === 0) return gen;\n\n gen = gen ? gen : [];\n\n var i = labels.length;\n for (; i < gen.length; i++) {\n labels.push(gen[i]);\n }\n return labels;\n },\n\n d3_linearLegend: function d3_linearLegend(scale, cells, labelFormat) {\n var data = [];\n\n if (cells.length > 1) {\n data = cells;\n } else {\n var domain = scale.domain(),\n increment = (domain[domain.length - 1] - domain[0]) / (cells - 1),\n i = 0;\n\n for (; i < cells; i++) {\n data.push(domain[0] + i * increment);\n }\n }\n\n var labels = data.map(labelFormat);\n\n return { data: data,\n labels: labels,\n feature: function feature(d) {\n return scale(d);\n } };\n },\n\n d3_quantLegend: function d3_quantLegend(scale, labelFormat, labelDelimiter) {\n var labels = scale.range().map(function (d) {\n var invert = scale.invertExtent(d),\n a = labelFormat(invert[0]),\n b = labelFormat(invert[1]);\n\n // if (( (a) && (a.isNan()) && b){\n // console.log(\"in initial statement\")\n return labelFormat(invert[0]) + \" \" + labelDelimiter + \" \" + labelFormat(invert[1]);\n // } else if (a || b) {\n // console.log('in else statement')\n // return (a) ? a : b;\n // }\n });\n\n return { data: scale.range(),\n labels: labels,\n feature: this.d3_identity\n };\n },\n\n d3_ordinalLegend: function d3_ordinalLegend(scale) {\n return { data: scale.domain(),\n labels: scale.domain(),\n feature: function feature(d) {\n return scale(d);\n } };\n },\n\n d3_drawShapes: function d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path) {\n if (shape === \"rect\") {\n shapes.attr(\"height\", shapeHeight).attr(\"width\", shapeWidth);\n } else if (shape === \"circle\") {\n shapes.attr(\"r\", shapeRadius); //.attr(\"cx\", shapeRadius).attr(\"cy\", shapeRadius);\n } else if (shape === \"line\") {\n shapes.attr(\"x1\", 0).attr(\"x2\", shapeWidth).attr(\"y1\", 0).attr(\"y2\", 0);\n } else if (shape === \"path\") {\n shapes.attr(\"d\", path);\n }\n },\n\n d3_addText: function d3_addText(svg, enter, labels, classPrefix) {\n enter.append(\"text\").attr(\"class\", classPrefix + \"label\");\n svg.selectAll(\"g.\" + classPrefix + \"cell text\").data(labels).text(this.d3_identity);\n },\n\n d3_calcType: function d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter) {\n var type = scale.ticks ? this.d3_linearLegend(scale, cells, labelFormat) : scale.invertExtent ? this.d3_quantLegend(scale, labelFormat, labelDelimiter) : this.d3_ordinalLegend(scale);\n\n type.labels = this.d3_mergeLabels(type.labels, labels);\n\n if (ascending) {\n type.labels = this.d3_reverse(type.labels);\n type.data = this.d3_reverse(type.data);\n }\n\n return type;\n },\n\n d3_reverse: function d3_reverse(arr) {\n var mirror = [];\n for (var i = 0, l = arr.length; i < l; i++) {\n mirror[i] = arr[l - i - 1];\n }\n return mirror;\n },\n\n d3_placement: function d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign) {\n cell.attr(\"transform\", cellTrans);\n text.attr(\"transform\", textTrans);\n if (orient === \"horizontal\") {\n text.style(\"text-anchor\", labelAlign);\n }\n },\n\n d3_addEvents: function d3_addEvents(cells, dispatcher) {\n var _ = this;\n\n cells.on(\"mouseover.legend\", function (d) {\n _.d3_cellOver(dispatcher, d, this);\n }).on(\"mouseout.legend\", function (d) {\n _.d3_cellOut(dispatcher, d, this);\n }).on(\"click.legend\", function (d) {\n _.d3_cellClick(dispatcher, d, this);\n });\n },\n\n d3_cellOver: function d3_cellOver(cellDispatcher, d, obj) {\n cellDispatcher.cellover.call(obj, d);\n },\n\n d3_cellOut: function d3_cellOut(cellDispatcher, d, obj) {\n cellDispatcher.cellout.call(obj, d);\n },\n\n d3_cellClick: function d3_cellClick(cellDispatcher, d, obj) {\n cellDispatcher.cellclick.call(obj, d);\n },\n\n d3_title: function d3_title(svg, cellsSvg, title, classPrefix) {\n if (title !== \"\") {\n\n var titleText = svg.selectAll('text.' + classPrefix + 'legendTitle');\n\n titleText.data([title]).enter().append('text').attr('class', classPrefix + 'legendTitle');\n\n svg.selectAll('text.' + classPrefix + 'legendTitle').text(title);\n\n var yOffset = svg.select('.' + classPrefix + 'legendTitle').map(function (d) {\n return d[0].getBBox().height;\n })[0],\n xOffset = -cellsSvg.map(function (d) {\n return d[0].getBBox().x;\n })[0];\n\n cellsSvg.attr('transform', 'translate(' + xOffset + ',' + (yOffset + 10) + ')');\n }\n }\n};\n\n},{}],4:[function(require,module,exports){\n\"use strict\";\n\nvar helper = require('./legend');\n\nmodule.exports = function () {\n\n var scale = d3.scale.linear(),\n shape = \"rect\",\n shapeWidth = 15,\n shapePadding = 2,\n cells = [5],\n labels = [],\n useStroke = false,\n classPrefix = \"\",\n title = \"\",\n labelFormat = d3.format(\".01f\"),\n labelOffset = 10,\n labelAlign = \"middle\",\n labelDelimiter = \"to\",\n orient = \"vertical\",\n ascending = false,\n path,\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\n\n function legend(svg) {\n\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\n legendG = svg.selectAll('g').data([scale]);\n\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\n\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\n\n //add event handlers\n helper.d3_addEvents(cellEnter, legendDispatcher);\n\n cell.exit().transition().style(\"opacity\", 0).remove();\n\n //creates shape\n if (shape === \"line\") {\n helper.d3_drawShapes(shape, shapes, 0, shapeWidth);\n shapes.attr(\"stroke-width\", type.feature);\n } else {\n helper.d3_drawShapes(shape, shapes, type.feature, type.feature, type.feature, path);\n }\n\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix);\n\n //sets placement\n var text = cell.select(\"text\"),\n shapeSize = shapes[0].map(function (d, i) {\n var bbox = d.getBBox();\n var stroke = scale(type.data[i]);\n\n if (shape === \"line\" && orient === \"horizontal\") {\n bbox.height = bbox.height + stroke;\n } else if (shape === \"line\" && orient === \"vertical\") {\n bbox.width = bbox.width;\n }\n\n return bbox;\n });\n\n var maxH = d3.max(shapeSize, function (d) {\n return d.height + d.y;\n }),\n maxW = d3.max(shapeSize, function (d) {\n return d.width + d.x;\n });\n\n var cellTrans,\n textTrans,\n textAlign = labelAlign == \"start\" ? 0 : labelAlign == \"middle\" ? 0.5 : 1;\n\n //positions cells and text\n if (orient === \"vertical\") {\n\n cellTrans = function cellTrans(d, i) {\n var height = d3.sum(shapeSize.slice(0, i + 1), function (d) {\n return d.height;\n });\n return \"translate(0, \" + (height + i * shapePadding) + \")\";\n };\n\n textTrans = function textTrans(d, i) {\n return \"translate(\" + (maxW + labelOffset) + \",\" + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + \")\";\n };\n } else if (orient === \"horizontal\") {\n cellTrans = function cellTrans(d, i) {\n var width = d3.sum(shapeSize.slice(0, i + 1), function (d) {\n return d.width;\n });\n return \"translate(\" + (width + i * shapePadding) + \",0)\";\n };\n\n textTrans = function textTrans(d, i) {\n return \"translate(\" + (shapeSize[i].width * textAlign + shapeSize[i].x) + \",\" + (maxH + labelOffset) + \")\";\n };\n }\n\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\n helper.d3_title(svg, legendG, title, classPrefix);\n\n cell.transition().style(\"opacity\", 1);\n }\n\n legend.scale = function (_) {\n if (!arguments.length) return scale;\n scale = _;\n return legend;\n };\n\n legend.cells = function (_) {\n if (!arguments.length) return cells;\n if (_.length > 1 || _ >= 2) {\n cells = _;\n }\n return legend;\n };\n\n legend.shape = function (_, d) {\n if (!arguments.length) return shape;\n if (_ == \"rect\" || _ == \"circle\" || _ == \"line\") {\n shape = _;\n path = d;\n }\n return legend;\n };\n\n legend.shapeWidth = function (_) {\n if (!arguments.length) return shapeWidth;\n shapeWidth = +_;\n return legend;\n };\n\n legend.shapePadding = function (_) {\n if (!arguments.length) return shapePadding;\n shapePadding = +_;\n return legend;\n };\n\n legend.labels = function (_) {\n if (!arguments.length) return labels;\n labels = _;\n return legend;\n };\n\n legend.labelAlign = function (_) {\n if (!arguments.length) return labelAlign;\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\n labelAlign = _;\n }\n return legend;\n };\n\n legend.labelFormat = function (_) {\n if (!arguments.length) return labelFormat;\n labelFormat = _;\n return legend;\n };\n\n legend.labelOffset = function (_) {\n if (!arguments.length) return labelOffset;\n labelOffset = +_;\n return legend;\n };\n\n legend.labelDelimiter = function (_) {\n if (!arguments.length) return labelDelimiter;\n labelDelimiter = _;\n return legend;\n };\n\n legend.orient = function (_) {\n if (!arguments.length) return orient;\n _ = _.toLowerCase();\n if (_ == \"horizontal\" || _ == \"vertical\") {\n orient = _;\n }\n return legend;\n };\n\n legend.ascending = function (_) {\n if (!arguments.length) return ascending;\n ascending = !!_;\n return legend;\n };\n\n legend.classPrefix = function (_) {\n if (!arguments.length) return classPrefix;\n classPrefix = _;\n return legend;\n };\n\n legend.title = function (_) {\n if (!arguments.length) return title;\n title = _;\n return legend;\n };\n\n d3.rebind(legend, legendDispatcher, \"on\");\n\n return legend;\n};\n\n},{\"./legend\":3}],5:[function(require,module,exports){\n\"use strict\";\n\nvar helper = require('./legend');\n\nmodule.exports = function () {\n\n var scale = d3.scale.linear(),\n shape = \"path\",\n shapeWidth = 15,\n shapeHeight = 15,\n shapeRadius = 10,\n shapePadding = 5,\n cells = [5],\n labels = [],\n classPrefix = \"\",\n useClass = false,\n title = \"\",\n labelFormat = d3.format(\".01f\"),\n labelAlign = \"middle\",\n labelOffset = 10,\n labelDelimiter = \"to\",\n orient = \"vertical\",\n ascending = false,\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\n\n function legend(svg) {\n\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\n legendG = svg.selectAll('g').data([scale]);\n\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\n\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\n\n //add event handlers\n helper.d3_addEvents(cellEnter, legendDispatcher);\n\n //remove old shapes\n cell.exit().transition().style(\"opacity\", 0).remove();\n\n helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, type.feature);\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix);\n\n // sets placement\n var text = cell.select(\"text\"),\n shapeSize = shapes[0].map(function (d) {\n return d.getBBox();\n });\n\n var maxH = d3.max(shapeSize, function (d) {\n return d.height;\n }),\n maxW = d3.max(shapeSize, function (d) {\n return d.width;\n });\n\n var cellTrans,\n textTrans,\n textAlign = labelAlign == \"start\" ? 0 : labelAlign == \"middle\" ? 0.5 : 1;\n\n //positions cells and text\n if (orient === \"vertical\") {\n cellTrans = function cellTrans(d, i) {\n return \"translate(0, \" + i * (maxH + shapePadding) + \")\";\n };\n textTrans = function textTrans(d, i) {\n return \"translate(\" + (maxW + labelOffset) + \",\" + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + \")\";\n };\n } else if (orient === \"horizontal\") {\n cellTrans = function cellTrans(d, i) {\n return \"translate(\" + i * (maxW + shapePadding) + \",0)\";\n };\n textTrans = function textTrans(d, i) {\n return \"translate(\" + (shapeSize[i].width * textAlign + shapeSize[i].x) + \",\" + (maxH + labelOffset) + \")\";\n };\n }\n\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\n helper.d3_title(svg, legendG, title, classPrefix);\n cell.transition().style(\"opacity\", 1);\n }\n\n legend.scale = function (_) {\n if (!arguments.length) return scale;\n scale = _;\n return legend;\n };\n\n legend.cells = function (_) {\n if (!arguments.length) return cells;\n if (_.length > 1 || _ >= 2) {\n cells = _;\n }\n return legend;\n };\n\n legend.shapePadding = function (_) {\n if (!arguments.length) return shapePadding;\n shapePadding = +_;\n return legend;\n };\n\n legend.labels = function (_) {\n if (!arguments.length) return labels;\n labels = _;\n return legend;\n };\n\n legend.labelAlign = function (_) {\n if (!arguments.length) return labelAlign;\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\n labelAlign = _;\n }\n return legend;\n };\n\n legend.labelFormat = function (_) {\n if (!arguments.length) return labelFormat;\n labelFormat = _;\n return legend;\n };\n\n legend.labelOffset = function (_) {\n if (!arguments.length) return labelOffset;\n labelOffset = +_;\n return legend;\n };\n\n legend.labelDelimiter = function (_) {\n if (!arguments.length) return labelDelimiter;\n labelDelimiter = _;\n return legend;\n };\n\n legend.orient = function (_) {\n if (!arguments.length) return orient;\n _ = _.toLowerCase();\n if (_ == \"horizontal\" || _ == \"vertical\") {\n orient = _;\n }\n return legend;\n };\n\n legend.ascending = function (_) {\n if (!arguments.length) return ascending;\n ascending = !!_;\n return legend;\n };\n\n legend.classPrefix = function (_) {\n if (!arguments.length) return classPrefix;\n classPrefix = _;\n return legend;\n };\n\n legend.title = function (_) {\n if (!arguments.length) return title;\n title = _;\n return legend;\n };\n\n d3.rebind(legend, legendDispatcher, \"on\");\n\n return legend;\n};\n\n},{\"./legend\":3}],6:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * **[Gaussian error function](http://en.wikipedia.org/wiki/Error_function)**\r\n *\r\n * The `errorFunction(x/(sd * Math.sqrt(2)))` is the probability that a value in a\r\n * normal distribution with standard deviation sd is within x of the mean.\r\n *\r\n * This function returns a numerical approximation to the exact value.\r\n *\r\n * @param {number} x input\r\n * @return {number} error estimation\r\n * @example\r\n * errorFunction(1); //= 0.8427\r\n */\n\nfunction errorFunction(x /*: number */) /*: number */{\n var t = 1 / (1 + 0.5 * Math.abs(x));\n var tau = t * Math.exp(-Math.pow(x, 2) - 1.26551223 + 1.00002368 * t + 0.37409196 * Math.pow(t, 2) + 0.09678418 * Math.pow(t, 3) - 0.18628806 * Math.pow(t, 4) + 0.27886807 * Math.pow(t, 5) - 1.13520398 * Math.pow(t, 6) + 1.48851587 * Math.pow(t, 7) - 0.82215223 * Math.pow(t, 8) + 0.17087277 * Math.pow(t, 9));\n if (x >= 0) {\n return 1 - tau;\n } else {\n return tau - 1;\n }\n}\n\nmodule.exports = errorFunction;\n\n},{}],7:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * [Simple linear regression](http://en.wikipedia.org/wiki/Simple_linear_regression)\r\n * is a simple way to find a fitted line\r\n * between a set of coordinates. This algorithm finds the slope and y-intercept of a regression line\r\n * using the least sum of squares.\r\n *\r\n * @param {Array>} data an array of two-element of arrays,\r\n * like `[[0, 1], [2, 3]]`\r\n * @returns {Object} object containing slope and intersect of regression line\r\n * @example\r\n * linearRegression([[0, 0], [1, 1]]); // { m: 1, b: 0 }\r\n */\n\nfunction linearRegression(data /*: Array> */) /*: { m: number, b: number } */{\n\n var m, b;\n\n // Store data length in a local variable to reduce\n // repeated object property lookups\n var dataLength = data.length;\n\n //if there's only one point, arbitrarily choose a slope of 0\n //and a y-intercept of whatever the y of the initial point is\n if (dataLength === 1) {\n m = 0;\n b = data[0][1];\n } else {\n // Initialize our sums and scope the `m` and `b`\n // variables that define the line.\n var sumX = 0,\n sumY = 0,\n sumXX = 0,\n sumXY = 0;\n\n // Use local variables to grab point values\n // with minimal object property lookups\n var point, x, y;\n\n // Gather the sum of all x values, the sum of all\n // y values, and the sum of x^2 and (x*y) for each\n // value.\n //\n // In math notation, these would be SS_x, SS_y, SS_xx, and SS_xy\n for (var i = 0; i < dataLength; i++) {\n point = data[i];\n x = point[0];\n y = point[1];\n\n sumX += x;\n sumY += y;\n\n sumXX += x * x;\n sumXY += x * y;\n }\n\n // `m` is the slope of the regression line\n m = (dataLength * sumXY - sumX * sumY) / (dataLength * sumXX - sumX * sumX);\n\n // `b` is the y-intercept of the line.\n b = sumY / dataLength - m * sumX / dataLength;\n }\n\n // Return both values as an object.\n return {\n m: m,\n b: b\n };\n}\n\nmodule.exports = linearRegression;\n\n},{}],8:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * Given the output of `linearRegression`: an object\r\n * with `m` and `b` values indicating slope and intercept,\r\n * respectively, generate a line function that translates\r\n * x values into y values.\r\n *\r\n * @param {Object} mb object with `m` and `b` members, representing\r\n * slope and intersect of desired line\r\n * @returns {Function} method that computes y-value at any given\r\n * x-value on the line.\r\n * @example\r\n * var l = linearRegressionLine(linearRegression([[0, 0], [1, 1]]));\r\n * l(0) //= 0\r\n * l(2) //= 2\r\n */\n\nfunction linearRegressionLine(mb /*: { b: number, m: number }*/) /*: Function */{\n // Return a function that computes a `y` value for each\n // x value it is given, based on the values of `b` and `a`\n // that we just computed.\n return function (x) {\n return mb.b + mb.m * x;\n };\n}\n\nmodule.exports = linearRegressionLine;\n\n},{}],9:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sum = require('./sum');\n\n/**\r\n * The mean, _also known as average_,\r\n * is the sum of all values over the number of values.\r\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\r\n * a method of finding a typical or central value of a set of numbers.\r\n *\r\n * This runs on `O(n)`, linear time in respect to the array\r\n *\r\n * @param {Array} x input values\r\n * @returns {number} mean\r\n * @example\r\n * console.log(mean([0, 10])); // 5\r\n */\nfunction mean(x /*: Array */) /*:number*/{\n // The mean of no numbers is null\n if (x.length === 0) {\n return NaN;\n }\n\n return sum(x) / x.length;\n}\n\nmodule.exports = mean;\n\n},{\"./sum\":15}],10:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sampleCovariance = require('./sample_covariance');\nvar sampleStandardDeviation = require('./sample_standard_deviation');\n\n/**\r\n * The [correlation](http://en.wikipedia.org/wiki/Correlation_and_dependence) is\r\n * a measure of how correlated two datasets are, between -1 and 1\r\n *\r\n * @param {Array} x first input\r\n * @param {Array} y second input\r\n * @returns {number} sample correlation\r\n * @example\r\n * var a = [1, 2, 3, 4, 5, 6];\r\n * var b = [2, 2, 3, 4, 5, 60];\r\n * sampleCorrelation(a, b); //= 0.691\r\n */\nfunction sampleCorrelation(x /*: Array */, y /*: Array */) /*:number*/{\n var cov = sampleCovariance(x, y),\n xstd = sampleStandardDeviation(x),\n ystd = sampleStandardDeviation(y);\n\n return cov / xstd / ystd;\n}\n\nmodule.exports = sampleCorrelation;\n\n},{\"./sample_covariance\":11,\"./sample_standard_deviation\":12}],11:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar mean = require('./mean');\n\n/**\r\n * [Sample covariance](https://en.wikipedia.org/wiki/Sample_mean_and_sampleCovariance) of two datasets:\r\n * how much do the two datasets move together?\r\n * x and y are two datasets, represented as arrays of numbers.\r\n *\r\n * @param {Array} x first input\r\n * @param {Array} y second input\r\n * @returns {number} sample covariance\r\n * @example\r\n * var x = [1, 2, 3, 4, 5, 6];\r\n * var y = [6, 5, 4, 3, 2, 1];\r\n * sampleCovariance(x, y); //= -3.5\r\n */\nfunction sampleCovariance(x /*:Array*/, y /*:Array*/) /*:number*/{\n\n // The two datasets must have the same length which must be more than 1\n if (x.length <= 1 || x.length !== y.length) {\n return NaN;\n }\n\n // determine the mean of each dataset so that we can judge each\n // value of the dataset fairly as the difference from the mean. this\n // way, if one dataset is [1, 2, 3] and [2, 3, 4], their covariance\n // does not suffer because of the difference in absolute values\n var xmean = mean(x),\n ymean = mean(y),\n sum = 0;\n\n // for each pair of values, the covariance increases when their\n // difference from the mean is associated - if both are well above\n // or if both are well below\n // the mean, the covariance increases significantly.\n for (var i = 0; i < x.length; i++) {\n sum += (x[i] - xmean) * (y[i] - ymean);\n }\n\n // this is Bessels' Correction: an adjustment made to sample statistics\n // that allows for the reduced degree of freedom entailed in calculating\n // values from samples rather than complete populations.\n var besselsCorrection = x.length - 1;\n\n // the covariance is weighted by the length of the datasets.\n return sum / besselsCorrection;\n}\n\nmodule.exports = sampleCovariance;\n\n},{\"./mean\":9}],12:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sampleVariance = require('./sample_variance');\n\n/**\r\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\r\n * is the square root of the variance.\r\n *\r\n * @param {Array} x input array\r\n * @returns {number} sample standard deviation\r\n * @example\r\n * ss.sampleStandardDeviation([2, 4, 4, 4, 5, 5, 7, 9]);\r\n * //= 2.138\r\n */\nfunction sampleStandardDeviation(x /*:Array*/) /*:number*/{\n // The standard deviation of no numbers is null\n var sampleVarianceX = sampleVariance(x);\n if (isNaN(sampleVarianceX)) {\n return NaN;\n }\n return Math.sqrt(sampleVarianceX);\n}\n\nmodule.exports = sampleStandardDeviation;\n\n},{\"./sample_variance\":13}],13:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sumNthPowerDeviations = require('./sum_nth_power_deviations');\n\n/*\r\n * The [sample variance](https://en.wikipedia.org/wiki/Variance#Sample_variance)\r\n * is the sum of squared deviations from the mean. The sample variance\r\n * is distinguished from the variance by the usage of [Bessel's Correction](https://en.wikipedia.org/wiki/Bessel's_correction):\r\n * instead of dividing the sum of squared deviations by the length of the input,\r\n * it is divided by the length minus one. This corrects the bias in estimating\r\n * a value from a set that you don't know if full.\r\n *\r\n * References:\r\n * * [Wolfram MathWorld on Sample Variance](http://mathworld.wolfram.com/SampleVariance.html)\r\n *\r\n * @param {Array} x input array\r\n * @return {number} sample variance\r\n * @example\r\n * sampleVariance([1, 2, 3, 4, 5]); //= 2.5\r\n */\nfunction sampleVariance(x /*: Array */) /*:number*/{\n // The variance of no numbers is null\n if (x.length <= 1) {\n return NaN;\n }\n\n var sumSquaredDeviationsValue = sumNthPowerDeviations(x, 2);\n\n // this is Bessels' Correction: an adjustment made to sample statistics\n // that allows for the reduced degree of freedom entailed in calculating\n // values from samples rather than complete populations.\n var besselsCorrection = x.length - 1;\n\n // Find the mean value of that list\n return sumSquaredDeviationsValue / besselsCorrection;\n}\n\nmodule.exports = sampleVariance;\n\n},{\"./sum_nth_power_deviations\":16}],14:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar variance = require('./variance');\n\n/**\r\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\r\n * is the square root of the variance. It's useful for measuring the amount\r\n * of variation or dispersion in a set of values.\r\n *\r\n * Standard deviation is only appropriate for full-population knowledge: for\r\n * samples of a population, {@link sampleStandardDeviation} is\r\n * more appropriate.\r\n *\r\n * @param {Array} x input\r\n * @returns {number} standard deviation\r\n * @example\r\n * var scores = [2, 4, 4, 4, 5, 5, 7, 9];\r\n * variance(scores); //= 4\r\n * standardDeviation(scores); //= 2\r\n */\nfunction standardDeviation(x /*: Array */) /*:number*/{\n // The standard deviation of no numbers is null\n var v = variance(x);\n if (isNaN(v)) {\n return 0;\n }\n return Math.sqrt(v);\n}\n\nmodule.exports = standardDeviation;\n\n},{\"./variance\":17}],15:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * Our default sum is the [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) is\r\n * a method for computing the sum of a list of numbers while correcting\r\n * for floating-point errors. Traditionally, sums are calculated as many\r\n * successive additions, each one with its own floating-point roundoff. These\r\n * losses in precision add up as the number of numbers increases. This alternative\r\n * algorithm is more accurate than the simple way of calculating sums by simple\r\n * addition.\r\n *\r\n * This runs on `O(n)`, linear time in respect to the array\r\n *\r\n * @param {Array} x input\r\n * @return {number} sum of all input numbers\r\n * @example\r\n * console.log(sum([1, 2, 3])); // 6\r\n */\n\nfunction sum(x /*: Array */) /*: number */{\n\n // like the traditional sum algorithm, we keep a running\n // count of the current sum.\n var sum = 0;\n\n // but we also keep three extra variables as bookkeeping:\n // most importantly, an error correction value. This will be a very\n // small number that is the opposite of the floating point precision loss.\n var errorCompensation = 0;\n\n // this will be each number in the list corrected with the compensation value.\n var correctedCurrentValue;\n\n // and this will be the next sum\n var nextSum;\n\n for (var i = 0; i < x.length; i++) {\n // first correct the value that we're going to add to the sum\n correctedCurrentValue = x[i] - errorCompensation;\n\n // compute the next sum. sum is likely a much larger number\n // than correctedCurrentValue, so we'll lose precision here,\n // and measure how much precision is lost in the next step\n nextSum = sum + correctedCurrentValue;\n\n // we intentionally didn't assign sum immediately, but stored\n // it for now so we can figure out this: is (sum + nextValue) - nextValue\n // not equal to 0? ideally it would be, but in practice it won't:\n // it will be some very small number. that's what we record\n // as errorCompensation.\n errorCompensation = nextSum - sum - correctedCurrentValue;\n\n // now that we've computed how much we'll correct for in the next\n // loop, start treating the nextSum as the current sum.\n sum = nextSum;\n }\n\n return sum;\n}\n\nmodule.exports = sum;\n\n},{}],16:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar mean = require('./mean');\n\n/**\r\n * The sum of deviations to the Nth power.\r\n * When n=2 it's the sum of squared deviations.\r\n * When n=3 it's the sum of cubed deviations.\r\n *\r\n * @param {Array} x\r\n * @param {number} n power\r\n * @returns {number} sum of nth power deviations\r\n * @example\r\n * var input = [1, 2, 3];\r\n * // since the variance of a set is the mean squared\r\n * // deviations, we can calculate that with sumNthPowerDeviations:\r\n * var variance = sumNthPowerDeviations(input) / input.length;\r\n */\nfunction sumNthPowerDeviations(x /*: Array */, n /*: number */) /*:number*/{\n var meanValue = mean(x),\n sum = 0;\n\n for (var i = 0; i < x.length; i++) {\n sum += Math.pow(x[i] - meanValue, n);\n }\n\n return sum;\n}\n\nmodule.exports = sumNthPowerDeviations;\n\n},{\"./mean\":9}],17:[function(require,module,exports){\n'use strict';\n/* @flow */\n\nvar sumNthPowerDeviations = require('./sum_nth_power_deviations');\n\n/**\r\n * The [variance](http://en.wikipedia.org/wiki/Variance)\r\n * is the sum of squared deviations from the mean.\r\n *\r\n * This is an implementation of variance, not sample variance:\r\n * see the `sampleVariance` method if you want a sample measure.\r\n *\r\n * @param {Array} x a population\r\n * @returns {number} variance: a value greater than or equal to zero.\r\n * zero indicates that all values are identical.\r\n * @example\r\n * ss.variance([1, 2, 3, 4, 5, 6]); //= 2.917\r\n */\nfunction variance(x /*: Array */) /*:number*/{\n // The variance of no numbers is null\n if (x.length === 0) {\n return NaN;\n }\n\n // Find the mean of squared deviations between the\n // mean value and each value.\n return sumNthPowerDeviations(x, 2) / x.length;\n}\n\nmodule.exports = variance;\n\n},{\"./sum_nth_power_deviations\":16}],18:[function(require,module,exports){\n'use strict';\n/* @flow */\n\n/**\r\n * The [Z-Score, or Standard Score](http://en.wikipedia.org/wiki/Standard_score).\r\n *\r\n * The standard score is the number of standard deviations an observation\r\n * or datum is above or below the mean. Thus, a positive standard score\r\n * represents a datum above the mean, while a negative standard score\r\n * represents a datum below the mean. It is a dimensionless quantity\r\n * obtained by subtracting the population mean from an individual raw\r\n * score and then dividing the difference by the population standard\r\n * deviation.\r\n *\r\n * The z-score is only defined if one knows the population parameters;\r\n * if one only has a sample set, then the analogous computation with\r\n * sample mean and sample standard deviation yields the\r\n * Student's t-statistic.\r\n *\r\n * @param {number} x\r\n * @param {number} mean\r\n * @param {number} standardDeviation\r\n * @return {number} z score\r\n * @example\r\n * ss.zScore(78, 80, 5); //= -0.4\r\n */\n\nfunction zScore(x /*:number*/, mean /*:number*/, standardDeviation /*:number*/) /*:number*/{\n return (x - mean) / standardDeviation;\n}\n\nmodule.exports = zScore;\n\n},{}],19:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.BarChart = exports.BarChartConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _utils = require(\"./utils\");\n\nvar _legend = require(\"./legend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar BarChartConfig = exports.BarChartConfig = function (_ChartConfig) {\n _inherits(BarChartConfig, _ChartConfig);\n\n // string or function returning color's value for color scale\n\n function BarChartConfig(custom) {\n _classCallCheck(this, BarChartConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(BarChartConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'bar-chart';\n _this.showLegend = true;\n _this.showTooltip = true;\n _this.legend = {\n width: 80,\n margin: 10,\n shapeWidth: 20\n };\n _this.x = { // X axis config\n label: '', // axis label\n key: 0,\n value: function value(d, key) {\n return _utils.Utils.isNumber(d) ? d : d[key];\n }, // x value accessor\n scale: \"ordinal\",\n ticks: undefined\n };\n _this.y = { // Y axis config\n key: 1,\n value: function value(d, key) {\n return _utils.Utils.isNumber(d) ? d : d[key];\n }, // x value accessor\n label: '', // axis label,\n orient: \"left\",\n scale: \"linear\"\n };\n _this.groups = {\n key: 1,\n value: function value(d) {\n return d[_this.groups.key];\n }, // grouping value accessor,\n label: \"\"\n };\n _this.color = undefined;\n _this.d3ColorCategory = 'category10';\n _this.transition = true;\n\n var config = _this;\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n }\n\n return BarChartConfig;\n}(_chart.ChartConfig);\n\nvar BarChart = exports.BarChart = function (_Chart) {\n _inherits(BarChart, _Chart);\n\n function BarChart(placeholderSelector, data, config) {\n _classCallCheck(this, BarChart);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(BarChart).call(this, placeholderSelector, data, new BarChartConfig(config)));\n }\n\n _createClass(BarChart, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(BarChart.prototype), \"setConfig\", this).call(this, new BarChartConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(BarChart.prototype), \"initPlot\", this).call(this);\n var self = this;\n\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.y = {};\n\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n this.plot.margin.right = conf.margin.right + conf.legend.width + conf.legend.margin * 2;\n }\n\n this.computePlotSize();\n this.setupY();\n this.setupX();\n this.setupGroupStacks();\n\n this.setupYDomain();\n\n if (conf.d3ColorCategory) {\n this.plot.colorCategory = d3.scale[conf.d3ColorCategory]();\n }\n var colorValue = conf.color;\n if (colorValue && typeof colorValue === 'string' || colorValue instanceof String) {\n this.plot.color = colorValue;\n } else if (this.plot.colorCategory) {\n this.plot.color = function (d) {\n return self.plot.colorCategory(d.key);\n };\n }\n\n return this;\n }\n }, {\n key: \"setupX\",\n value: function setupX() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config.x;\n\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\n x.value = function (d) {\n return conf.value(d, conf.key);\n };\n x.scale = d3.scale.ordinal().rangeRoundBands([0, plot.width], .08);\n x.map = function (d) {\n return x.scale(x.value(d));\n };\n\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\n\n var data = this.data;\n var domain;\n if (!this.config.series) {\n domain = d3.map(data, x.value).keys();\n } else {\n domain = d3.map(data[0].values, x.value).keys();\n }\n\n plot.x.scale.domain(domain);\n void 0;\n }\n }, {\n key: \"setupY\",\n value: function setupY() {\n\n var plot = this.plot;\n var y = plot.y;\n var conf = this.config.y;\n y.value = function (d) {\n return conf.value(d, conf.key);\n };\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\n y.map = function (d) {\n return y.scale(y.value(d));\n };\n\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\n if (conf.ticks) {\n y.axis.ticks(conf.ticks);\n }\n }\n }, {\n key: \"setupYDomain\",\n value: function setupYDomain() {\n var plot = this.plot;\n var data = this.data;\n var domain;\n var yStackMax = d3.max(plot.layers, function (layer) {\n return d3.max(layer.values, function (d) {\n return d.y0 + d.y;\n });\n });\n if (!this.config.series) {\n domain = [d3.min(data, plot.y.value), d3.max(data, plot.y.value)];\n } else {\n\n // var min = d3.min(data, s=>d3.min(s.values, plot.y.value));\n var max = yStackMax;\n domain = [0, max];\n }\n plot.y.scale.domain(domain);\n void 0;\n }\n }, {\n key: \"groupData\",\n value: function groupData() {\n var self = this;\n this.plot.groupingEnabled = this.config.series;\n var data = this.data;\n if (!this.plot.groupingEnabled) {\n this.plot.groupedData = [{\n key: 'root',\n values: self.mapToPoints(data)\n }];\n } else {\n\n this.plot.groupedData = data.map(function (s) {\n return {\n key: s.key,\n values: self.mapToPoints(s.values)\n };\n });\n }\n }\n }, {\n key: \"setupGroupStacks\",\n value: function setupGroupStacks() {\n var self = this;\n this.groupData();\n\n this.plot.stack = d3.layout.stack().values(function (d) {\n return d.values;\n });\n this.plot.layers = this.plot.stack(this.plot.groupedData);\n }\n }, {\n key: \"mapToPoints\",\n value: function mapToPoints(values) {\n var plot = this.plot;\n return values.map(function (v) {\n return {\n x: plot.x.value(v),\n y: plot.y.value(v)\n };\n });\n }\n }, {\n key: \"drawAxisX\",\n value: function drawAxisX() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.x;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides'))).attr(\"transform\", \"translate(0,\" + plot.height + \")\");\n\n var axisT = axis;\n if (self.config.transition) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.x.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + plot.width / 2 + \",\" + plot.margin.bottom + \")\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"-1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawAxisY\",\n value: function drawAxisY() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.y;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides')));\n\n var axisT = axis;\n if (self.config.transition) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.y.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + plot.height / 2 + \")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawBars\",\n value: function drawBars() {\n var self = this;\n var plot = self.plot;\n\n void 0;\n\n var layerClass = this.prefixClass(\"layer\");\n\n var barClass = this.prefixClass(\"bar\");\n var layer = self.svgG.selectAll(\".\" + layerClass).data(plot.layers);\n\n layer.enter().append(\"g\").attr(\"class\", layerClass);\n\n var bar = layer.selectAll(\".\" + barClass).data(function (d) {\n return d.values;\n });\n\n bar.enter().append(\"g\").attr(\"class\", barClass).append(\"rect\").attr(\"x\", 1);\n\n var barRect = bar.select(\"rect\");\n\n var barRectT = barRect;\n var barT = bar;\n var layerT = layer;\n if (this.transitionEnabled()) {\n barRectT = barRect.transition();\n barT = bar.transition();\n layerT = layer.transition();\n }\n\n var yDomain = plot.y.scale.domain();\n barT.attr(\"transform\", function (d) {\n return \"translate(\" + plot.x.scale(d.x) + \",\" + plot.y.scale(d.y0 + d.y) + \")\";\n });\n\n barRectT.attr(\"width\", plot.x.scale.rangeBand()).attr(\"height\", function (d) {\n return plot.y.scale(d.y0) - plot.y.scale(d.y0 + d.y - yDomain[0]);\n });\n\n if (this.plot.color) {\n layerT.attr(\"fill\", this.plot.color);\n }\n\n if (plot.tooltip) {\n bar.on(\"mouseover\", function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n plot.tooltip.html(d.y).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n }).on(\"mouseout\", function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n layer.exit().remove();\n bar.exit().remove();\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(BarChart.prototype), \"update\", this).call(this, newData);\n this.drawAxisX();\n this.drawAxisY();\n\n this.drawBars();\n\n this.updateLegend();\n }\n }, {\n key: \"updateLegend\",\n value: function updateLegend() {\n var plot = this.plot;\n\n var scale = plot.colorCategory;\n if (!scale.domain() || scale.domain().length < 2) {\n plot.showLegend = false;\n }\n\n if (!plot.showLegend) {\n if (plot.legend && plot.legend.container) {\n plot.legend.container.remove();\n }\n return;\n }\n\n var legendX = this.plot.width + this.config.legend.margin;\n var legendY = this.config.legend.margin;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY);\n\n var legendLinear = plot.legend.color().shapeWidth(this.config.legend.shapeWidth).orient('vertical').scale(scale);\n\n plot.legend.container.call(legendLinear);\n }\n }]);\n\n return BarChart;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./utils\":33}],20:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Chart = exports.ChartConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _utils = require('./utils');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar ChartConfig = exports.ChartConfig = function ChartConfig(custom) {\n _classCallCheck(this, ChartConfig);\n\n this.cssClassPrefix = \"odc-\";\n this.svgClass = this.cssClassPrefix + 'mw-d3-chart';\n this.width = undefined;\n this.height = undefined;\n this.margin = {\n left: 50,\n right: 30,\n top: 30,\n bottom: 50\n };\n this.showTooltip = false;\n this.transition = true;\n\n if (custom) {\n _utils.Utils.deepExtend(this, custom);\n }\n};\n\nvar Chart = exports.Chart = function () {\n function Chart(base, data, config) {\n _classCallCheck(this, Chart);\n\n this.utils = _utils.Utils;\n this.plot = {\n margin: {}\n };\n this._attached = {};\n this._layers = {};\n this._events = {};\n this._isInitialized = false;\n\n\n this._isAttached = base instanceof Chart;\n\n this.baseContainer = base;\n\n this.setConfig(config);\n\n if (data) {\n this.setData(data);\n }\n\n this.init();\n this.postInit();\n }\n\n _createClass(Chart, [{\n key: 'setConfig',\n value: function setConfig(config) {\n if (!config) {\n this.config = new ChartConfig();\n } else {\n this.config = config;\n }\n\n return this;\n }\n }, {\n key: 'setData',\n value: function setData(data) {\n this.data = data;\n return this;\n }\n }, {\n key: 'init',\n value: function init() {\n var self = this;\n\n self.initPlot();\n self.initSvg();\n\n self.initTooltip();\n self.draw();\n this._isInitialized = true;\n return this;\n }\n }, {\n key: 'postInit',\n value: function postInit() {}\n }, {\n key: 'initSvg',\n value: function initSvg() {\n var self = this;\n var config = this.config;\n\n var margin = self.plot.margin;\n var width = self.plot.width + margin.left + margin.right;\n var height = self.plot.height + margin.top + margin.bottom;\n var aspect = width / height;\n if (!self._isAttached) {\n if (!this._isInitialized) {\n d3.select(self.baseContainer).select(\"svg\").remove();\n }\n self.svg = d3.select(self.baseContainer).selectOrAppend(\"svg\");\n\n self.svg.attr(\"width\", width).attr(\"height\", height).attr(\"viewBox\", \"0 0 \" + \" \" + width + \" \" + height).attr(\"preserveAspectRatio\", \"xMidYMid meet\").attr(\"class\", config.svgClass);\n self.svgG = self.svg.selectOrAppend(\"g.main-group\");\n } else {\n void 0;\n self.svg = self.baseContainer.svg;\n self.svgG = self.svg.selectOrAppend(\"g.main-group.\" + config.svgClass);\n }\n\n self.svgG.attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");\n\n if (!config.width || config.height) {\n d3.select(window).on(\"resize\", function () {\n //TODO add responsiveness if width/height not specified\n });\n }\n }\n }, {\n key: 'initTooltip',\n value: function initTooltip() {\n var self = this;\n if (self.config.showTooltip) {\n if (!self._isAttached) {\n self.plot.tooltip = d3.select(\"body\").selectOrAppend('div.' + self.config.cssClassPrefix + 'tooltip').style(\"opacity\", 0);\n } else {\n self.plot.tooltip = self.baseContainer.plot.tooltip;\n }\n }\n }\n }, {\n key: 'initPlot',\n value: function initPlot() {\n var margin = this.config.margin;\n this.plot = this.plot || {};\n this.plot.margin = {\n top: margin.top,\n bottom: margin.bottom,\n left: margin.left,\n right: margin.right\n };\n }\n }, {\n key: 'update',\n value: function update(data) {\n if (data) {\n this.setData(data);\n }\n var layerName, attachmentData;\n for (var attachmentName in this._attached) {\n\n attachmentData = data;\n\n this._attached[attachmentName].update(attachmentData);\n }\n return this;\n }\n }, {\n key: 'draw',\n value: function draw(data) {\n this.update(data);\n\n return this;\n }\n\n //Borrowed from d3.chart\n /**\r\n * Register or retrieve an \"attachment\" Chart. The \"attachment\" chart's `draw`\r\n * method will be invoked whenever the containing chart's `draw` method is\r\n * invoked.\r\n *\r\n * @externalExample chart-attach\r\n *\r\n * @param {String} attachmentName Name of the attachment\r\n * @param {Chart} [chart] Chart to register as a mix in of this chart. When\r\n * unspecified, this method will return the attachment previously\r\n * registered with the specified `attachmentName` (if any).\r\n *\r\n * @returns {Chart} Reference to this chart (chainable).\r\n */\n\n }, {\n key: 'attach',\n value: function attach(attachmentName, chart) {\n if (arguments.length === 1) {\n return this._attached[attachmentName];\n }\n\n this._attached[attachmentName] = chart;\n return chart;\n }\n }, {\n key: 'on',\n\n\n //Borrowed from d3.chart\n /**\r\n * Subscribe a callback function to an event triggered on the chart. See {@link\r\n * Chart#once} to subscribe a callback function to an event for one occurence.\r\n *\r\n * @externalExample {runnable} chart-on\r\n *\r\n * @param {String} name Name of the event\r\n * @param {ChartEventHandler} callback Function to be invoked when the event\r\n * occurs\r\n * @param {Object} [context] Value to set as `this` when invoking the\r\n * `callback`. Defaults to the chart instance.\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\n value: function on(name, callback, context) {\n var events = this._events[name] || (this._events[name] = []);\n events.push({\n callback: callback,\n context: context || this,\n _chart: this\n });\n return this;\n }\n\n //Borrowed from d3.chart\n /**\r\n *\r\n * Subscribe a callback function to an event triggered on the chart. This\r\n * function will be invoked at the next occurance of the event and immediately\r\n * unsubscribed. See {@link Chart#on} to subscribe a callback function to an\r\n * event indefinitely.\r\n *\r\n * @externalExample {runnable} chart-once\r\n *\r\n * @param {String} name Name of the event\r\n * @param {ChartEventHandler} callback Function to be invoked when the event\r\n * occurs\r\n * @param {Object} [context] Value to set as `this` when invoking the\r\n * `callback`. Defaults to the chart instance\r\n *\r\n * @returns {Chart} A reference to this chart (chainable)\r\n */\n\n }, {\n key: 'once',\n value: function once(name, callback, context) {\n var self = this;\n var once = function once() {\n self.off(name, once);\n callback.apply(this, arguments);\n };\n return this.on(name, once, context);\n }\n\n //Borrowed from d3.chart\n /**\r\n * Unsubscribe one or more callback functions from an event triggered on the\r\n * chart. When no arguments are specified, *all* handlers will be unsubscribed.\r\n * When only a `name` is specified, all handlers subscribed to that event will\r\n * be unsubscribed. When a `name` and `callback` are specified, only that\r\n * function will be unsubscribed from that event. When a `name` and `context`\r\n * are specified (but `callback` is omitted), all events bound to the given\r\n * event with the given context will be unsubscribed.\r\n *\r\n * @externalExample {runnable} chart-off\r\n *\r\n * @param {String} [name] Name of the event to be unsubscribed\r\n * @param {ChartEventHandler} [callback] Function to be unsubscribed\r\n * @param {Object} [context] Contexts to be unsubscribe\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\n\n }, {\n key: 'off',\n value: function off(name, callback, context) {\n var names, n, events, event, i, j;\n\n // remove all events\n if (arguments.length === 0) {\n for (name in this._events) {\n this._events[name].length = 0;\n }\n return this;\n }\n\n // remove all events for a specific name\n if (arguments.length === 1) {\n events = this._events[name];\n if (events) {\n events.length = 0;\n }\n return this;\n }\n\n // remove all events that match whatever combination of name, context\n // and callback.\n names = name ? [name] : Object.keys(this._events);\n for (i = 0; i < names.length; i++) {\n n = names[i];\n events = this._events[n];\n j = events.length;\n while (j--) {\n event = events[j];\n if (callback && callback === event.callback || context && context === event.context) {\n events.splice(j, 1);\n }\n }\n }\n\n return this;\n }\n }, {\n key: 'trigger',\n\n\n //Borrowed from d3.chart\n /**\r\n * Publish an event on this chart with the given `name`.\r\n *\r\n * @externalExample {runnable} chart-trigger\r\n *\r\n * @param {String} name Name of the event to publish\r\n * @param {...*} arguments Values with which to invoke the registered\r\n * callbacks.\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\n value: function trigger(name) {\n var args = Array.prototype.slice.call(arguments, 1);\n var events = this._events[name];\n var i, ev;\n\n if (events !== undefined) {\n for (i = 0; i < events.length; i++) {\n ev = events[i];\n ev.callback.apply(ev.context, args);\n }\n }\n\n return this;\n }\n }, {\n key: 'getBaseContainer',\n value: function getBaseContainer() {\n if (this._isAttached) {\n return this.baseContainer.svg;\n }\n return d3.select(this.baseContainer);\n }\n }, {\n key: 'getBaseContainerNode',\n value: function getBaseContainerNode() {\n\n return this.getBaseContainer().node();\n }\n }, {\n key: 'prefixClass',\n value: function prefixClass(clazz, addDot) {\n return addDot ? '.' : '' + this.config.cssClassPrefix + clazz;\n }\n }, {\n key: 'computePlotSize',\n value: function computePlotSize() {\n this.plot.width = _utils.Utils.availableWidth(this.config.width, this.getBaseContainer(), this.plot.margin);\n this.plot.height = _utils.Utils.availableHeight(this.config.height, this.getBaseContainer(), this.plot.margin);\n }\n }, {\n key: 'transitionEnabled',\n value: function transitionEnabled() {\n return this._isInitialized && this.config.transition;\n }\n }]);\n\n return Chart;\n}();\n\n},{\"./utils\":33}],21:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.CorrelationMatrix = exports.CorrelationMatrixConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require('./chart');\n\nvar _utils = require('./utils');\n\nvar _statisticsUtils = require('./statistics-utils');\n\nvar _legend = require('./legend');\n\nvar _scatterplot = require('./scatterplot');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar CorrelationMatrixConfig = exports.CorrelationMatrixConfig = function (_ChartConfig) {\n _inherits(CorrelationMatrixConfig, _ChartConfig);\n\n //show tooltip on dot hover\n\n function CorrelationMatrixConfig(custom) {\n _classCallCheck(this, CorrelationMatrixConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(CorrelationMatrixConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'correlation-matrix';\n _this.guides = false;\n _this.showTooltip = true;\n _this.showLegend = true;\n _this.highlightLabels = true;\n _this.rotateLabelsX = true;\n _this.rotateLabelsY = true;\n _this.variables = {\n labels: undefined,\n keys: [], //optional array of variable keys\n value: function value(d, variableKey) {\n return d[variableKey];\n }, // variable value accessor\n scale: \"ordinal\"\n };\n _this.correlation = {\n scale: \"linear\",\n domain: [-1, -0.75, -0.5, 0, 0.5, 0.75, 1],\n range: [\"darkblue\", \"blue\", \"lightskyblue\", \"white\", \"orangered\", \"crimson\", \"darkred\"],\n value: function value(xValues, yValues) {\n return _statisticsUtils.StatisticsUtils.sampleCorrelation(xValues, yValues);\n }\n\n };\n _this.cell = {\n shape: \"ellipse\", //possible values: rect, circle, ellipse\n size: undefined,\n sizeMin: 15,\n sizeMax: 250,\n padding: 1\n };\n _this.margin = {\n left: 60,\n right: 50,\n top: 30,\n bottom: 60\n };\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n return _this;\n } //show axis guides\n\n\n return CorrelationMatrixConfig;\n}(_chart.ChartConfig);\n\nvar CorrelationMatrix = exports.CorrelationMatrix = function (_Chart) {\n _inherits(CorrelationMatrix, _Chart);\n\n function CorrelationMatrix(placeholderSelector, data, config) {\n _classCallCheck(this, CorrelationMatrix);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(CorrelationMatrix).call(this, placeholderSelector, data, new CorrelationMatrixConfig(config)));\n }\n\n _createClass(CorrelationMatrix, [{\n key: 'setConfig',\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(CorrelationMatrix.prototype), 'setConfig', this).call(this, new CorrelationMatrixConfig(config));\n }\n }, {\n key: 'initPlot',\n value: function initPlot() {\n _get(Object.getPrototypeOf(CorrelationMatrix.prototype), 'initPlot', this).call(this);\n var self = this;\n var margin = this.config.margin;\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.correlation = {\n matrix: undefined,\n cells: undefined,\n color: {},\n shape: {}\n };\n\n this.setupVariables();\n var width = conf.width;\n var placeholderNode = this.getBaseContainerNode();\n this.plot.placeholderNode = placeholderNode;\n\n var parentWidth = placeholderNode.getBoundingClientRect().width;\n if (width) {\n\n if (!this.plot.cellSize) {\n this.plot.cellSize = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (width - margin.left - margin.right) / this.plot.variables.length));\n }\n } else {\n this.plot.cellSize = this.config.cell.size;\n\n if (!this.plot.cellSize) {\n this.plot.cellSize = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (parentWidth - margin.left - margin.right) / this.plot.variables.length));\n }\n\n width = this.plot.cellSize * this.plot.variables.length + margin.left + margin.right;\n }\n\n var height = width;\n if (!height) {\n height = placeholderNode.getBoundingClientRect().height;\n }\n\n this.plot.width = width - margin.left - margin.right;\n this.plot.height = this.plot.width;\n\n this.setupVariablesScales();\n this.setupCorrelationScales();\n this.setupCorrelationMatrix();\n\n return this;\n }\n }, {\n key: 'setupVariablesScales',\n value: function setupVariablesScales() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config.variables;\n\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\n x.value = conf.value;\n x.scale = d3.scale[conf.scale]().rangeBands([plot.width, 0]);\n x.map = function (d) {\n return x.scale(x.value(d));\n };\n }\n }, {\n key: 'setupCorrelationScales',\n value: function setupCorrelationScales() {\n var plot = this.plot;\n var corrConf = this.config.correlation;\n\n plot.correlation.color.scale = d3.scale[corrConf.scale]().domain(corrConf.domain).range(corrConf.range);\n var shape = plot.correlation.shape = {};\n\n var cellConf = this.config.cell;\n shape.type = cellConf.shape;\n\n var shapeSize = plot.cellSize - cellConf.padding * 2;\n if (shape.type == 'circle') {\n var radiusMax = shapeSize / 2;\n shape.radiusScale = d3.scale.linear().domain([0, 1]).range([2, radiusMax]);\n shape.radius = function (c) {\n return shape.radiusScale(Math.abs(c.value));\n };\n } else if (shape.type == 'ellipse') {\n var radiusMax = shapeSize / 2;\n shape.radiusScale = d3.scale.linear().domain([0, 1]).range([radiusMax, 2]);\n shape.radiusX = function (c) {\n return shape.radiusScale(Math.abs(c.value));\n };\n shape.radiusY = radiusMax;\n\n shape.rotateVal = function (v) {\n if (v == 0) return \"0\";\n if (v < 0) return \"-45\";\n return \"45\";\n };\n } else if (shape.type == 'rect') {\n shape.size = shapeSize;\n }\n }\n }, {\n key: 'setupVariables',\n value: function setupVariables() {\n\n var variablesConf = this.config.variables;\n\n var data = this.data;\n var plot = this.plot;\n plot.domainByVariable = {};\n plot.variables = variablesConf.keys;\n if (!plot.variables || !plot.variables.length) {\n plot.variables = _utils.Utils.inferVariables(data, this.config.groups.key, this.config.includeInPlot);\n }\n\n plot.labels = [];\n plot.labelByVariable = {};\n plot.variables.forEach(function (variableKey, index) {\n plot.domainByVariable[variableKey] = d3.extent(data, function (d) {\n return variablesConf.value(d, variableKey);\n });\n var label = variableKey;\n if (variablesConf.labels && variablesConf.labels.length > index) {\n\n label = variablesConf.labels[index];\n }\n plot.labels.push(label);\n plot.labelByVariable[variableKey] = label;\n });\n\n void 0;\n }\n }, {\n key: 'setupCorrelationMatrix',\n value: function setupCorrelationMatrix() {\n var self = this;\n var data = this.data;\n var matrix = this.plot.correlation.matrix = [];\n var matrixCells = this.plot.correlation.matrix.cells = [];\n var plot = this.plot;\n\n var variableToValues = {};\n plot.variables.forEach(function (v, i) {\n\n variableToValues[v] = data.map(function (d) {\n return plot.x.value(d, v);\n });\n });\n\n plot.variables.forEach(function (v1, i) {\n var row = [];\n matrix.push(row);\n\n plot.variables.forEach(function (v2, j) {\n var corr = 1;\n if (v1 != v2) {\n corr = self.config.correlation.value(variableToValues[v1], variableToValues[v2]);\n }\n var cell = {\n rowVar: v1,\n colVar: v2,\n row: i,\n col: j,\n value: corr\n };\n row.push(cell);\n\n matrixCells.push(cell);\n });\n });\n }\n }, {\n key: 'update',\n value: function update(newData) {\n _get(Object.getPrototypeOf(CorrelationMatrix.prototype), 'update', this).call(this, newData);\n // this.update\n this.updateCells();\n this.updateVariableLabels();\n\n if (this.config.showLegend) {\n this.updateLegend();\n }\n }\n }, {\n key: 'updateVariableLabels',\n value: function updateVariableLabels() {\n this.plot.labelClass = this.prefixClass(\"label\");\n this.updateAxisX();\n this.updateAxisY();\n }\n }, {\n key: 'updateAxisX',\n value: function updateAxisX() {\n var self = this;\n var plot = self.plot;\n var labelClass = plot.labelClass;\n var labelXClass = labelClass + \"-x\";\n\n var labels = self.svgG.selectAll(\"text.\" + labelXClass).data(plot.variables, function (d, i) {\n return i;\n });\n\n labels.enter().append(\"text\").attr(\"class\", function (d, i) {\n return labelClass + \" \" + labelXClass + \" \" + labelXClass + \"-\" + i;\n });\n\n labels.attr(\"x\", function (d, i) {\n return i * plot.cellSize + plot.cellSize / 2;\n }).attr(\"y\", plot.height).attr(\"dx\", -2).attr(\"dy\", 5).attr(\"text-anchor\", \"end\")\n\n // .attr(\"dominant-baseline\", \"hanging\")\n .text(function (v) {\n return plot.labelByVariable[v];\n });\n\n if (this.config.rotateLabelsX) {\n labels.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + (i * plot.cellSize + plot.cellSize / 2) + \", \" + plot.height + \")\";\n });\n }\n\n var maxWidth = self.computeXAxisLabelsWidth();\n labels.each(function (label) {\n _utils.Utils.placeTextWithEllipsisAndTooltip(d3.select(this), label, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\n });\n\n labels.exit().remove();\n }\n }, {\n key: 'updateAxisY',\n value: function updateAxisY() {\n var self = this;\n var plot = self.plot;\n var labelClass = plot.labelClass;\n var labelYClass = plot.labelClass + \"-y\";\n var labels = self.svgG.selectAll(\"text.\" + labelYClass).data(plot.variables);\n\n labels.enter().append(\"text\");\n\n labels.attr(\"x\", 0).attr(\"y\", function (d, i) {\n return i * plot.cellSize + plot.cellSize / 2;\n }).attr(\"dx\", -2).attr(\"text-anchor\", \"end\").attr(\"class\", function (d, i) {\n return labelClass + \" \" + labelYClass + \" \" + labelYClass + \"-\" + i;\n })\n // .attr(\"dominant-baseline\", \"hanging\")\n .text(function (v) {\n return plot.labelByVariable[v];\n });\n\n if (this.config.rotateLabelsY) {\n labels.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + 0 + \", \" + (i * plot.cellSize + plot.cellSize / 2) + \")\";\n }).attr(\"text-anchor\", \"end\");\n }\n\n var maxWidth = self.computeYAxisLabelsWidth();\n labels.each(function (label) {\n _utils.Utils.placeTextWithEllipsisAndTooltip(d3.select(this), label, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\n });\n\n labels.exit().remove();\n }\n }, {\n key: 'computeYAxisLabelsWidth',\n value: function computeYAxisLabelsWidth() {\n var maxWidth = this.plot.margin.left;\n if (!this.config.rotateLabelsY) {\n return maxWidth;\n }\n\n maxWidth *= _utils.Utils.SQRT_2;\n var fontSize = 11; //todo check actual font size\n maxWidth -= fontSize / 2;\n\n return maxWidth;\n }\n }, {\n key: 'computeXAxisLabelsWidth',\n value: function computeXAxisLabelsWidth(offset) {\n if (!this.config.rotateLabelsX) {\n return this.plot.cellSize - 2;\n }\n var size = this.plot.margin.bottom;\n size *= _utils.Utils.SQRT_2;\n var fontSize = 11; //todo check actual font size\n size -= fontSize / 2;\n return size;\n }\n }, {\n key: 'updateCells',\n value: function updateCells() {\n\n var self = this;\n var plot = self.plot;\n var cellClass = self.prefixClass(\"cell\");\n var cellShape = plot.correlation.shape.type;\n\n var cells = self.svgG.selectAll(\"g.\" + cellClass).data(plot.correlation.matrix.cells);\n\n var cellEnterG = cells.enter().append(\"g\").classed(cellClass, true);\n cells.attr(\"transform\", function (c) {\n return \"translate(\" + (plot.cellSize * c.col + plot.cellSize / 2) + \",\" + (plot.cellSize * c.row + plot.cellSize / 2) + \")\";\n });\n\n cells.classed(self.config.cssClassPrefix + \"selectable\", !!self.scatterPlot);\n\n var selector = \"*:not(.cell-shape-\" + cellShape + \")\";\n\n var wrongShapes = cells.selectAll(selector);\n wrongShapes.remove();\n\n var shapes = cells.selectOrAppend(cellShape + \".cell-shape-\" + cellShape);\n\n if (plot.correlation.shape.type == 'circle') {\n\n shapes.attr(\"r\", plot.correlation.shape.radius).attr(\"cx\", 0).attr(\"cy\", 0);\n }\n\n if (plot.correlation.shape.type == 'ellipse') {\n // cells.attr(\"transform\", c=> \"translate(300,150) rotate(\"+plot.correlation.shape.rotateVal(c.value)+\")\");\n shapes.attr(\"rx\", plot.correlation.shape.radiusX).attr(\"ry\", plot.correlation.shape.radiusY).attr(\"cx\", 0).attr(\"cy\", 0).attr(\"transform\", function (c) {\n return \"rotate(\" + plot.correlation.shape.rotateVal(c.value) + \")\";\n });\n }\n\n if (plot.correlation.shape.type == 'rect') {\n shapes.attr(\"width\", plot.correlation.shape.size).attr(\"height\", plot.correlation.shape.size).attr(\"x\", -plot.cellSize / 2).attr(\"y\", -plot.cellSize / 2);\n }\n shapes.style(\"fill\", function (c) {\n return plot.correlation.color.scale(c.value);\n });\n\n var mouseoverCallbacks = [];\n var mouseoutCallbacks = [];\n\n if (plot.tooltip) {\n\n mouseoverCallbacks.push(function (c) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = c.value;\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n });\n\n mouseoutCallbacks.push(function (c) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n\n if (self.config.highlightLabels) {\n var highlightClass = self.config.cssClassPrefix + \"highlight\";\n var xLabelClass = function xLabelClass(c) {\n return plot.labelClass + \"-x-\" + c.col;\n };\n var yLabelClass = function yLabelClass(c) {\n return plot.labelClass + \"-y-\" + c.row;\n };\n\n mouseoverCallbacks.push(function (c) {\n\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, true);\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, true);\n });\n mouseoutCallbacks.push(function (c) {\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, false);\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, false);\n });\n }\n\n cells.on(\"mouseover\", function (c) {\n mouseoverCallbacks.forEach(function (callback) {\n return callback(c);\n });\n }).on(\"mouseout\", function (c) {\n mouseoutCallbacks.forEach(function (callback) {\n return callback(c);\n });\n });\n\n cells.on(\"click\", function (c) {\n self.trigger(\"cell-selected\", c);\n });\n\n cells.exit().remove();\n }\n }, {\n key: 'updateLegend',\n value: function updateLegend() {\n\n var plot = this.plot;\n var legendX = this.plot.width + 10;\n var legendY = 0;\n var barWidth = 10;\n var barHeight = this.plot.height - 2;\n var scale = plot.correlation.color.scale;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY).linearGradientBar(barWidth, barHeight);\n }\n }, {\n key: 'attachScatterPlot',\n value: function attachScatterPlot(containerSelector, config) {\n var _this3 = this;\n\n var self = this;\n\n config = config || {};\n\n var scatterPlotConfig = {\n height: self.plot.height + self.config.margin.top + self.config.margin.bottom,\n width: self.plot.height + self.config.margin.top + self.config.margin.bottom,\n groups: {\n key: self.config.groups.key,\n label: self.config.groups.label\n },\n guides: true,\n showLegend: false\n };\n\n self.scatterPlot = true;\n\n scatterPlotConfig = _utils.Utils.deepExtend(scatterPlotConfig, config);\n this.update();\n\n this.on(\"cell-selected\", function (c) {\n\n scatterPlotConfig.x = {\n key: c.rowVar,\n label: self.plot.labelByVariable[c.rowVar]\n };\n scatterPlotConfig.y = {\n key: c.colVar,\n label: self.plot.labelByVariable[c.colVar]\n };\n if (self.scatterPlot && self.scatterPlot !== true) {\n self.scatterPlot.setConfig(scatterPlotConfig).init();\n } else {\n self.scatterPlot = new _scatterplot.ScatterPlot(containerSelector, self.data, scatterPlotConfig);\n _this3.attach(\"ScatterPlot\", self.scatterPlot);\n }\n });\n }\n }]);\n\n return CorrelationMatrix;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./scatterplot\":30,\"./statistics-utils\":32,\"./utils\":33}],22:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.D3Extensions = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _utils = require('./utils');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar D3Extensions = exports.D3Extensions = function () {\n function D3Extensions() {\n _classCallCheck(this, D3Extensions);\n }\n\n _createClass(D3Extensions, null, [{\n key: 'extend',\n value: function extend() {\n\n d3.selection.enter.prototype.insertSelector = d3.selection.prototype.insertSelector = function (selector, before) {\n return _utils.Utils.insertSelector(this, selector, before);\n };\n\n d3.selection.enter.prototype.appendSelector = d3.selection.prototype.appendSelector = function (selector) {\n return _utils.Utils.appendSelector(this, selector);\n };\n\n d3.selection.enter.prototype.selectOrAppend = d3.selection.prototype.selectOrAppend = function (selector) {\n return _utils.Utils.selectOrAppend(this, selector);\n };\n\n d3.selection.enter.prototype.selectOrInsert = d3.selection.prototype.selectOrInsert = function (selector, before) {\n return _utils.Utils.selectOrInsert(this, selector, before);\n };\n }\n }]);\n\n return D3Extensions;\n}();\n\n},{\"./utils\":33}],23:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.HeatmapTimeSeries = exports.HeatmapTimeSeriesConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _heatmap = require(\"./heatmap\");\n\nvar _utils = require(\"./utils\");\n\nvar _statisticsUtils = require(\"./statistics-utils\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar HeatmapTimeSeriesConfig = exports.HeatmapTimeSeriesConfig = function (_HeatmapConfig) {\n _inherits(HeatmapTimeSeriesConfig, _HeatmapConfig);\n\n function HeatmapTimeSeriesConfig(custom) {\n _classCallCheck(this, HeatmapTimeSeriesConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(HeatmapTimeSeriesConfig).call(this));\n\n _this.x = {\n fillMissing: false, // fill missing values using interval and intervalStep\n interval: undefined, //used in filling missing ticks\n intervalStep: 1,\n format: undefined, //input data d3 time format\n displayFormat: undefined, //d3 time format for display\n intervalToFormats: [//used to guess interval and format\n {\n name: 'year',\n formats: [\"%Y\"]\n }, {\n name: 'month',\n formats: [\"%Y-%m\"]\n }, {\n name: 'day',\n formats: [\"%Y-%m-%d\"]\n }, {\n name: 'hour',\n formats: ['%H', '%Y-%m-%d %H']\n }, {\n name: 'minute',\n formats: ['%H:%M', '%Y-%m-%d %H:%M']\n }, {\n name: 'second',\n formats: ['%H:%M:%S', '%Y-%m-%d %H:%M:%S']\n }],\n\n sortComparator: function sortComparator(a, b) {\n return _utils.Utils.isString(a) ? a.localeCompare(b) : a - b;\n },\n formatter: undefined\n };\n _this.z = {\n fillMissing: true // fiill missing values with nearest previous value\n };\n _this.legend = {\n formatter: function formatter(v) {\n var suffix = \"\";\n if (v / 1000000 >= 1) {\n suffix = \" M\";\n v = Number(v / 1000000).toFixed(3);\n }\n var nf = Intl.NumberFormat();\n return nf.format(v) + suffix;\n }\n };\n\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n }\n\n return HeatmapTimeSeriesConfig;\n}(_heatmap.HeatmapConfig);\n\nvar HeatmapTimeSeries = exports.HeatmapTimeSeries = function (_Heatmap) {\n _inherits(HeatmapTimeSeries, _Heatmap);\n\n function HeatmapTimeSeries(placeholderSelector, data, config) {\n _classCallCheck(this, HeatmapTimeSeries);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(HeatmapTimeSeries).call(this, placeholderSelector, data, new HeatmapTimeSeriesConfig(config)));\n }\n\n _createClass(HeatmapTimeSeries, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(HeatmapTimeSeries.prototype), \"setConfig\", this).call(this, new HeatmapTimeSeriesConfig(config));\n }\n }, {\n key: \"setupValuesBeforeGroupsSort\",\n value: function setupValuesBeforeGroupsSort() {\n var _this3 = this;\n\n this.plot.x.timeFormat = this.config.x.format;\n if (this.config.x.displayFormat && !this.plot.x.timeFormat) {\n this.guessTimeFormat();\n }\n\n _get(Object.getPrototypeOf(HeatmapTimeSeries.prototype), \"setupValuesBeforeGroupsSort\", this).call(this);\n if (!this.config.x.fillMissing) {\n return;\n }\n\n var self = this;\n\n this.initTimeFormatAndInterval();\n\n this.plot.x.intervalStep = this.config.x.intervalStep || 1;\n\n this.plot.x.timeParser = this.getTimeParser();\n\n this.plot.x.uniqueValues.sort(this.config.x.sortComparator);\n\n var prev = null;\n\n this.plot.x.uniqueValues.forEach(function (x, i) {\n var current = _this3.parseTime(x);\n if (prev === null) {\n prev = current;\n return;\n }\n\n var next = self.nextTimeTickValue(prev);\n var missing = [];\n var iteration = 0;\n while (self.compareTimeValues(next, current) <= 0) {\n iteration++;\n if (iteration > 100) {\n break;\n }\n var d = {};\n var timeString = self.formatTime(next);\n d[_this3.config.x.key] = timeString;\n\n self.updateGroups(d, timeString, self.plot.x.groups, self.config.x.groups);\n missing.push(next);\n next = self.nextTimeTickValue(next);\n }\n prev = current;\n });\n }\n }, {\n key: \"parseTime\",\n value: function parseTime(x) {\n var parser = this.getTimeParser();\n return parser.parse(x);\n }\n }, {\n key: \"formatTime\",\n value: function formatTime(date) {\n var parser = this.getTimeParser();\n return parser(date);\n }\n }, {\n key: \"formatValueX\",\n value: function formatValueX(value) {\n //used only for display\n if (this.config.x.formatter) return this.config.x.formatter.call(this.config, value);\n\n if (this.config.x.displayFormat) {\n var date = this.parseTime(value);\n return d3.time.format(this.config.x.displayFormat)(date);\n }\n\n if (!this.plot.x.timeFormat) return value;\n\n if (_utils.Utils.isDate(value)) {\n return this.formatTime(value);\n }\n\n return value;\n }\n }, {\n key: \"compareTimeValues\",\n value: function compareTimeValues(a, b) {\n return a - b;\n }\n }, {\n key: \"timeValuesEqual\",\n value: function timeValuesEqual(a, b) {\n var parser = this.plot.x.timeParser;\n return parser(a) === parser(b);\n }\n }, {\n key: \"nextTimeTickValue\",\n value: function nextTimeTickValue(t) {\n var interval = this.plot.x.interval;\n return d3.time[interval].offset(t, this.plot.x.intervalStep);\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(HeatmapTimeSeries.prototype), \"initPlot\", this).call(this);\n\n if (this.config.z.fillMissing) {\n this.plot.matrix.forEach(function (row, rowIndex) {\n var prevRowValue = undefined;\n row.forEach(function (cell, colIndex) {\n if (cell.value === undefined && prevRowValue !== undefined) {\n cell.value = prevRowValue;\n cell.missing = true;\n }\n prevRowValue = cell.value;\n });\n });\n }\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(HeatmapTimeSeries.prototype), \"update\", this).call(this, newData);\n }\n }, {\n key: \"initTimeFormatAndInterval\",\n value: function initTimeFormatAndInterval() {\n\n this.plot.x.interval = this.config.x.interval;\n\n if (!this.plot.x.timeFormat) {\n this.guessTimeFormat();\n }\n\n if (!this.plot.x.interval && this.plot.x.timeFormat) {\n this.guessInterval();\n }\n }\n }, {\n key: \"guessTimeFormat\",\n value: function guessTimeFormat() {\n var self = this;\n for (var i = 0; i < self.config.x.intervalToFormats.length; i++) {\n var intervalFormat = self.config.x.intervalToFormats[i];\n var format = null;\n var formatMatch = intervalFormat.formats.some(function (f) {\n format = f;\n var parser = d3.time.format(f);\n return self.plot.x.uniqueValues.every(function (x) {\n return parser.parse(x) !== null;\n });\n });\n if (formatMatch) {\n self.plot.x.timeFormat = format;\n void 0;\n if (!self.plot.x.interval) {\n self.plot.x.interval = intervalFormat.name;\n void 0;\n }\n return;\n }\n }\n }\n }, {\n key: \"guessInterval\",\n value: function guessInterval() {\n var self = this;\n for (var i = 0; i < self.config.x.intervalToFormats.length; i++) {\n var intervalFormat = self.config.x.intervalToFormats[i];\n\n if (intervalFormat.formats.indexOf(self.plot.x.timeFormat) >= 0) {\n self.plot.x.interval = intervalFormat.name;\n void 0;\n return;\n }\n }\n }\n }, {\n key: \"getTimeParser\",\n value: function getTimeParser() {\n if (!this.plot.x.timeParser) {\n this.plot.x.timeParser = d3.time.format(this.plot.x.timeFormat);\n }\n return this.plot.x.timeParser;\n }\n }]);\n\n return HeatmapTimeSeries;\n}(_heatmap.Heatmap);\n\n},{\"./chart\":20,\"./heatmap\":24,\"./statistics-utils\":32,\"./utils\":33}],24:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Heatmap = exports.HeatmapConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require('./chart');\n\nvar _utils = require('./utils');\n\nvar _legend = require('./legend');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar HeatmapConfig = exports.HeatmapConfig = function (_ChartConfig) {\n _inherits(HeatmapConfig, _ChartConfig);\n\n //show tooltip on dot hover\n\n function HeatmapConfig(custom) {\n _classCallCheck(this, HeatmapConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(HeatmapConfig).call(this));\n\n _this.svgClass = 'odc-heatmap';\n _this.showTooltip = true;\n _this.tooltip = {\n noDataText: \"N/A\"\n };\n _this.showLegend = true;\n _this.legend = {\n width: 30,\n rotateLabels: false,\n decimalPlaces: undefined,\n formatter: function formatter(v) {\n return _this.legend.decimalPlaces === undefined ? v : Number(v).toFixed(_this.legend.decimalPlaces);\n }\n };\n _this.highlightLabels = true;\n _this.x = { // X axis config\n title: '', // axis title\n key: 0,\n value: function value(d) {\n return d[_this.x.key];\n }, // x value accessor\n rotateLabels: true,\n sortLabels: false,\n sortComparator: function sortComparator(a, b) {\n return _utils.Utils.isNumber(a) ? a - b : a.localeCompare(b);\n },\n groups: {\n keys: [],\n labels: [],\n value: function value(d, key) {\n return d[key];\n },\n overlap: {\n top: 20,\n bottom: 20\n }\n },\n formatter: undefined // value formatter function\n\n };\n _this.y = { // Y axis config\n title: '', // axis title,\n rotateLabels: true,\n key: 1,\n value: function value(d) {\n return d[_this.y.key];\n }, // y value accessor\n sortLabels: false,\n sortComparator: function sortComparator(a, b) {\n return _utils.Utils.isNumber(b) ? b - a : b.localeCompare(a);\n },\n groups: {\n keys: [],\n labels: [],\n value: function value(d, key) {\n return d[key];\n },\n overlap: {\n left: 20,\n right: 20\n }\n },\n formatter: undefined // value formatter function\n };\n _this.z = {\n key: 2,\n value: function value(d) {\n return d[_this.z.key];\n },\n notAvailableValue: function notAvailableValue(v) {\n return v === null || v === undefined;\n },\n\n decimalPlaces: undefined,\n formatter: function formatter(v) {\n return _this.z.decimalPlaces === undefined ? v : Number(v).toFixed(_this.z.decimalPlaces);\n } // value formatter function\n\n };\n _this.color = {\n noDataColor: \"white\",\n scale: \"linear\",\n reverseScale: false,\n range: [\"darkblue\", \"lightskyblue\", \"orange\", \"crimson\", \"darkred\"]\n };\n _this.cell = {\n width: undefined,\n height: undefined,\n sizeMin: 15,\n sizeMax: 250,\n padding: 0\n };\n _this.margin = {\n left: 60,\n right: 50,\n top: 30,\n bottom: 80\n };\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n return _this;\n }\n\n return HeatmapConfig;\n}(_chart.ChartConfig);\n\n//TODO refactor\n\n\nvar Heatmap = exports.Heatmap = function (_Chart) {\n _inherits(Heatmap, _Chart);\n\n function Heatmap(placeholderSelector, data, config) {\n _classCallCheck(this, Heatmap);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(Heatmap).call(this, placeholderSelector, data, new HeatmapConfig(config)));\n }\n\n _createClass(Heatmap, [{\n key: 'setConfig',\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(Heatmap.prototype), 'setConfig', this).call(this, new HeatmapConfig(config));\n }\n }, {\n key: 'initPlot',\n value: function initPlot() {\n _get(Object.getPrototypeOf(Heatmap.prototype), 'initPlot', this).call(this);\n var self = this;\n var margin = this.config.margin;\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.y = {};\n this.plot.z = {\n matrixes: undefined,\n cells: undefined,\n color: {},\n shape: {}\n };\n\n this.setupValues();\n this.buildCells();\n\n var titleRectWidth = 6;\n this.plot.x.overlap = {\n top: 0,\n bottom: 0\n };\n if (this.plot.groupByX) {\n var depth = self.config.x.groups.keys.length;\n var allTitlesWidth = depth * titleRectWidth;\n\n this.plot.x.overlap.bottom = self.config.x.groups.overlap.bottom;\n this.plot.x.overlap.top = self.config.x.groups.overlap.top + allTitlesWidth;\n this.plot.margin.top = conf.margin.right + conf.x.groups.overlap.top;\n this.plot.margin.bottom = conf.margin.bottom + conf.x.groups.overlap.bottom;\n }\n\n this.plot.y.overlap = {\n left: 0,\n right: 0\n };\n\n if (this.plot.groupByY) {\n var _depth = self.config.y.groups.keys.length;\n var _allTitlesWidth = _depth * titleRectWidth;\n this.plot.y.overlap.right = self.config.y.groups.overlap.left + _allTitlesWidth;\n this.plot.y.overlap.left = self.config.y.groups.overlap.left;\n this.plot.margin.left = conf.margin.left + this.plot.y.overlap.left;\n this.plot.margin.right = conf.margin.right + this.plot.y.overlap.right;\n }\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n this.plot.margin.right += conf.legend.width;\n }\n this.computePlotSize();\n this.setupZScale();\n\n return this;\n }\n }, {\n key: 'setupValues',\n value: function setupValues() {\n var _this3 = this;\n\n var self = this;\n var config = self.config;\n var x = self.plot.x;\n var y = self.plot.y;\n var z = self.plot.z;\n\n x.value = function (d) {\n return config.x.value.call(config, d);\n };\n y.value = function (d) {\n return config.y.value.call(config, d);\n };\n z.value = function (d) {\n return config.z.value.call(config, d);\n };\n\n x.uniqueValues = [];\n y.uniqueValues = [];\n\n self.plot.groupByY = !!config.y.groups.keys.length;\n self.plot.groupByX = !!config.x.groups.keys.length;\n\n y.groups = {\n key: undefined,\n label: '',\n values: [],\n children: null,\n level: 0,\n index: 0,\n lastIndex: 0\n };\n x.groups = {\n key: undefined,\n label: '',\n values: [],\n children: null,\n level: 0,\n index: 0,\n lastIndex: 0\n };\n\n var valueMap = {};\n var minZ = undefined;\n var maxZ = undefined;\n this.data.forEach(function (d) {\n\n var xVal = x.value(d);\n var yVal = y.value(d);\n var zValRaw = z.value(d);\n var zVal = config.z.notAvailableValue(zValRaw) ? undefined : parseFloat(zValRaw);\n\n if (x.uniqueValues.indexOf(xVal) === -1) {\n x.uniqueValues.push(xVal);\n }\n\n if (y.uniqueValues.indexOf(yVal) === -1) {\n y.uniqueValues.push(yVal);\n }\n\n var groupY = y.groups;\n if (self.plot.groupByY) {\n groupY = _this3.updateGroups(d, yVal, y.groups, config.y.groups);\n }\n var groupX = x.groups;\n if (self.plot.groupByX) {\n\n groupX = _this3.updateGroups(d, xVal, x.groups, config.x.groups);\n }\n\n if (!valueMap[groupY.index]) {\n valueMap[groupY.index] = {};\n }\n\n if (!valueMap[groupY.index][groupX.index]) {\n valueMap[groupY.index][groupX.index] = {};\n }\n if (!valueMap[groupY.index][groupX.index][yVal]) {\n valueMap[groupY.index][groupX.index][yVal] = {};\n }\n valueMap[groupY.index][groupX.index][yVal][xVal] = zVal;\n\n if (minZ === undefined || zVal < minZ) {\n minZ = zVal;\n }\n if (maxZ === undefined || zVal > maxZ) {\n maxZ = zVal;\n }\n });\n self.plot.valueMap = valueMap;\n\n if (!self.plot.groupByX) {\n x.groups.values = x.uniqueValues;\n }\n\n if (!self.plot.groupByY) {\n y.groups.values = y.uniqueValues;\n }\n\n this.setupValuesBeforeGroupsSort();\n\n x.gaps = [];\n x.totalValuesCount = 0;\n x.allValuesList = [];\n this.sortGroups(x, x.groups, config.x);\n\n y.gaps = [];\n y.totalValuesCount = 0;\n y.allValuesList = [];\n this.sortGroups(y, y.groups, config.y);\n\n z.min = minZ;\n z.max = maxZ;\n }\n }, {\n key: 'setupValuesBeforeGroupsSort',\n value: function setupValuesBeforeGroupsSort() {}\n }, {\n key: 'buildCells',\n value: function buildCells() {\n var self = this;\n var x = self.plot.x;\n var y = self.plot.y;\n var z = self.plot.z;\n var valueMap = self.plot.valueMap;\n\n var matrixCells = self.plot.cells = [];\n var matrix = self.plot.matrix = [];\n\n y.allValuesList.forEach(function (v1, i) {\n var row = [];\n matrix.push(row);\n\n x.allValuesList.forEach(function (v2, j) {\n var zVal = undefined;\n try {\n zVal = valueMap[v1.group.index][v2.group.index][v1.val][v2.val];\n } catch (e) {}\n\n var cell = {\n rowVar: v1,\n colVar: v2,\n row: i,\n col: j,\n value: zVal\n };\n row.push(cell);\n\n matrixCells.push(cell);\n });\n });\n }\n }, {\n key: 'updateGroups',\n value: function updateGroups(d, axisVal, rootGroup, axisGroupsConfig) {\n\n var config = this.config;\n var currentGroup = rootGroup;\n axisGroupsConfig.keys.forEach(function (groupKey, groupKeyIndex) {\n currentGroup.key = groupKey;\n\n if (!currentGroup.children) {\n currentGroup.children = {};\n }\n\n var groupingValue = axisGroupsConfig.value.call(config, d, groupKey);\n\n if (!currentGroup.children.hasOwnProperty(groupingValue)) {\n rootGroup.lastIndex++;\n currentGroup.children[groupingValue] = {\n values: [],\n children: null,\n groupingValue: groupingValue,\n level: currentGroup.level + 1,\n index: rootGroup.lastIndex,\n key: groupKey\n };\n }\n\n currentGroup = currentGroup.children[groupingValue];\n });\n\n if (currentGroup.values.indexOf(axisVal) === -1) {\n currentGroup.values.push(axisVal);\n }\n\n return currentGroup;\n }\n }, {\n key: 'sortGroups',\n value: function sortGroups(axis, group, axisConfig, gaps) {\n if (axisConfig.groups.labels && axisConfig.groups.labels.length > group.level) {\n group.label = axisConfig.groups.labels[group.level];\n } else {\n group.label = group.key;\n }\n\n if (!gaps) {\n gaps = [0];\n }\n if (gaps.length <= group.level) {\n gaps.push(0);\n }\n\n group.allValuesCount = group.allValuesCount || 0;\n group.allValuesBeforeCount = group.allValuesBeforeCount || 0;\n\n group.gaps = gaps.slice();\n group.gapsBefore = gaps.slice();\n\n group.gapsSize = Heatmap.computeGapsSize(group.gaps);\n group.gapsBeforeSize = group.gapsSize;\n if (group.values) {\n if (axisConfig.sortLabels) {\n group.values.sort(axisConfig.sortComparator);\n }\n group.values.forEach(function (v) {\n return axis.allValuesList.push({ val: v, group: group });\n });\n group.allValuesBeforeCount = axis.totalValuesCount;\n axis.totalValuesCount += group.values.length;\n group.allValuesCount += group.values.length;\n }\n\n group.childrenList = [];\n if (group.children) {\n var childrenCount = 0;\n\n for (var childProp in group.children) {\n if (group.children.hasOwnProperty(childProp)) {\n var child = group.children[childProp];\n group.childrenList.push(child);\n childrenCount++;\n\n this.sortGroups(axis, child, axisConfig, gaps);\n group.allValuesCount += child.allValuesCount;\n gaps[group.level] += 1;\n }\n }\n\n if (gaps && childrenCount > 1) {\n gaps[group.level] -= 1;\n }\n\n group.gapsInside = [];\n gaps.forEach(function (d, i) {\n group.gapsInside.push(d - (group.gapsBefore[i] || 0));\n });\n group.gapsInsideSize = Heatmap.computeGapsSize(group.gapsInside);\n\n if (axis.gaps.length < gaps.length) {\n axis.gaps = gaps;\n }\n }\n }\n }, {\n key: 'computeYAxisLabelsWidth',\n value: function computeYAxisLabelsWidth(offset) {\n var maxWidth = this.plot.margin.left;\n if (this.config.y.title) {\n maxWidth -= 15;\n }\n if (offset && offset.x) {\n maxWidth += offset.x;\n }\n\n if (this.config.y.rotateLabels) {\n maxWidth *= _utils.Utils.SQRT_2;\n var fontSize = 11; //todo check actual font size\n maxWidth -= fontSize / 2;\n }\n\n return maxWidth;\n }\n }, {\n key: 'computeXAxisLabelsWidth',\n value: function computeXAxisLabelsWidth(offset) {\n if (!this.config.x.rotateLabels) {\n return this.plot.cellWidth - 2;\n }\n var size = this.plot.margin.bottom;\n if (this.config.x.title) {\n size -= 15;\n }\n if (offset && offset.y) {\n size -= offset.y;\n }\n\n size *= _utils.Utils.SQRT_2;\n\n var fontSize = 11; //todo check actual font size\n size -= fontSize / 2;\n\n return size;\n }\n }, {\n key: 'computePlotSize',\n value: function computePlotSize() {\n\n var plot = this.plot;\n var conf = this.config;\n var margin = plot.margin;\n var availableWidth = _utils.Utils.availableWidth(this.config.width, this.getBaseContainer(), this.plot.margin);\n var availableHeight = _utils.Utils.availableHeight(this.config.height, this.getBaseContainer(), this.plot.margin);\n var width = availableWidth;\n var height = availableHeight;\n\n var xGapsSize = Heatmap.computeGapsSize(plot.x.gaps);\n\n var computedCellWidth = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (availableWidth - xGapsSize) / this.plot.x.totalValuesCount));\n if (this.config.width) {\n\n if (!this.config.cell.width) {\n this.plot.cellWidth = computedCellWidth;\n }\n } else {\n this.plot.cellWidth = this.config.cell.width;\n\n if (!this.plot.cellWidth) {\n this.plot.cellWidth = computedCellWidth;\n }\n }\n width = this.plot.cellWidth * this.plot.x.totalValuesCount + margin.left + margin.right + xGapsSize;\n\n var yGapsSize = Heatmap.computeGapsSize(plot.y.gaps);\n var computedCellHeight = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (availableHeight - yGapsSize) / this.plot.y.totalValuesCount));\n if (this.config.height) {\n if (!this.config.cell.height) {\n this.plot.cellHeight = computedCellHeight;\n }\n } else {\n this.plot.cellHeight = this.config.cell.height;\n\n if (!this.plot.cellHeight) {\n this.plot.cellHeight = computedCellHeight;\n }\n }\n\n height = this.plot.cellHeight * this.plot.y.totalValuesCount + margin.top + margin.bottom + yGapsSize;\n\n this.plot.width = width - margin.left - margin.right;\n this.plot.height = height - margin.top - margin.bottom;\n }\n }, {\n key: 'setupZScale',\n value: function setupZScale() {\n\n var self = this;\n var config = self.config;\n var z = self.plot.z;\n var range = config.color.range;\n var extent = z.max - z.min;\n var scale;\n z.domain = [];\n if (config.color.scale == \"pow\") {\n var exponent = 10;\n range.forEach(function (c, i) {\n var v = z.max - extent / Math.pow(10, i);\n z.domain.push(v);\n });\n scale = d3.scale.pow().exponent(exponent);\n } else if (config.color.scale == \"log\") {\n\n range.forEach(function (c, i) {\n var v = z.min + extent / Math.pow(10, i);\n z.domain.unshift(v);\n });\n\n scale = d3.scale.log();\n } else {\n range.forEach(function (c, i) {\n var v = z.min + extent * (i / (range.length - 1));\n z.domain.push(v);\n });\n scale = d3.scale[config.color.scale]();\n }\n\n z.domain[0] = z.min; //removing unnecessary floating points\n z.domain[z.domain.length - 1] = z.max; //removing unnecessary floating points\n void 0;\n\n if (config.color.reverseScale) {\n z.domain.reverse();\n }\n\n var plot = this.plot;\n\n void 0;\n plot.z.color.scale = scale.domain(z.domain).range(range);\n var shape = plot.z.shape = {};\n\n var cellConf = this.config.cell;\n shape.type = \"rect\";\n\n plot.z.shape.width = plot.cellWidth - cellConf.padding * 2;\n plot.z.shape.height = plot.cellHeight - cellConf.padding * 2;\n }\n }, {\n key: 'update',\n value: function update(newData) {\n _get(Object.getPrototypeOf(Heatmap.prototype), 'update', this).call(this, newData);\n if (this.plot.groupByY) {\n this.drawGroupsY(this.plot.y.groups, this.svgG);\n }\n if (this.plot.groupByX) {\n this.drawGroupsX(this.plot.x.groups, this.svgG);\n }\n\n this.updateCells();\n\n // this.updateVariableLabels();\n\n this.updateAxisX();\n this.updateAxisY();\n\n if (this.config.showLegend) {\n this.updateLegend();\n }\n\n this.updateAxisTitles();\n }\n }, {\n key: 'updateAxisTitles',\n value: function updateAxisTitles() {\n var self = this;\n var plot = self.plot;\n }\n }, {\n key: 'updateAxisX',\n value: function updateAxisX() {\n var self = this;\n var plot = self.plot;\n var labelClass = self.prefixClass(\"label\");\n var labelXClass = labelClass + \"-x\";\n var labelYClass = labelClass + \"-y\";\n plot.labelClass = labelClass;\n\n var offsetX = {\n x: 0,\n y: 0\n };\n var gapSize = Heatmap.computeGapSize(0);\n if (plot.groupByX) {\n var overlap = self.config.x.groups.overlap;\n\n offsetX.x = gapSize / 2;\n offsetX.y = overlap.bottom + gapSize / 2 + 6;\n } else if (plot.groupByY) {\n offsetX.y = gapSize;\n }\n\n var labels = self.svgG.selectAll(\"text.\" + labelXClass).data(plot.x.allValuesList, function (d, i) {\n return i;\n });\n\n labels.enter().append(\"text\").attr(\"class\", function (d, i) {\n return labelClass + \" \" + labelXClass + \" \" + labelXClass + \"-\" + i;\n });\n\n labels.attr(\"x\", function (d, i) {\n return i * plot.cellWidth + plot.cellWidth / 2 + d.group.gapsSize + offsetX.x;\n }).attr(\"y\", plot.height + offsetX.y).attr(\"dy\", 10).attr(\"text-anchor\", \"middle\").text(function (d) {\n return self.formatValueX(d.val);\n });\n\n var maxWidth = self.computeXAxisLabelsWidth(offsetX);\n\n labels.each(function (label) {\n var elem = d3.select(this),\n text = self.formatValueX(label.val);\n _utils.Utils.placeTextWithEllipsisAndTooltip(elem, text, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\n });\n\n if (self.config.x.rotateLabels) {\n labels.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + (i * plot.cellWidth + plot.cellWidth / 2 + d.group.gapsSize + offsetX.x) + \", \" + (plot.height + offsetX.y) + \")\";\n }).attr(\"dx\", -2).attr(\"dy\", 8).attr(\"text-anchor\", \"end\");\n }\n\n labels.exit().remove();\n\n self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x')).attr(\"transform\", \"translate(\" + plot.width / 2 + \",\" + (plot.height + plot.margin.bottom) + \")\").selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"dy\", \"-0.5em\").style(\"text-anchor\", \"middle\").text(self.config.x.title);\n }\n }, {\n key: 'updateAxisY',\n value: function updateAxisY() {\n var self = this;\n var plot = self.plot;\n var labelClass = self.prefixClass(\"label\");\n var labelYClass = labelClass + \"-y\";\n plot.labelClass = labelClass;\n\n var labels = self.svgG.selectAll(\"text.\" + labelYClass).data(plot.y.allValuesList);\n\n labels.enter().append(\"text\");\n\n var offsetY = {\n x: 0,\n y: 0\n };\n if (plot.groupByY) {\n var overlap = self.config.y.groups.overlap;\n var gapSize = Heatmap.computeGapSize(0);\n offsetY.x = -overlap.left;\n\n offsetY.y = gapSize / 2;\n }\n labels.attr(\"x\", offsetY.x).attr(\"y\", function (d, i) {\n return i * plot.cellHeight + plot.cellHeight / 2 + d.group.gapsSize + offsetY.y;\n }).attr(\"dx\", -2).attr(\"text-anchor\", \"end\").attr(\"class\", function (d, i) {\n return labelClass + \" \" + labelYClass + \" \" + labelYClass + \"-\" + i;\n }).text(function (d) {\n var formatted = self.formatValueY(d.val);\n return formatted;\n });\n\n var maxWidth = self.computeYAxisLabelsWidth(offsetY);\n\n labels.each(function (label) {\n var elem = d3.select(this),\n text = self.formatValueY(label.val);\n _utils.Utils.placeTextWithEllipsisAndTooltip(elem, text, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\n });\n\n if (self.config.y.rotateLabels) {\n labels.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + offsetY.x + \", \" + (d.group.gapsSize + (i * plot.cellHeight + plot.cellHeight / 2) + offsetY.y) + \")\";\n }).attr(\"text-anchor\", \"end\");\n // .attr(\"dx\", -7);\n } else {\n labels.attr(\"dominant-baseline\", \"middle\");\n }\n\n labels.exit().remove();\n\n self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y')).selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + plot.height / 2 + \")rotate(-90)\").attr(\"dy\", \"1em\").style(\"text-anchor\", \"middle\").text(self.config.y.title);\n }\n }, {\n key: 'drawGroupsY',\n value: function drawGroupsY(parentGroup, container, availableWidth) {\n\n var self = this;\n var plot = self.plot;\n\n var groupClass = self.prefixClass(\"group\");\n var groupYClass = groupClass + \"-y\";\n var groups = container.selectAll(\"g.\" + groupClass + \".\" + groupYClass).data(parentGroup.childrenList);\n\n var valuesBeforeCount = 0;\n var gapsBeforeSize = 0;\n\n var groupsEnterG = groups.enter().append(\"g\");\n groupsEnterG.classed(groupClass, true).classed(groupYClass, true).append(\"rect\").classed(\"group-rect\", true);\n\n var titleGroupEnter = groupsEnterG.appendSelector(\"g.title\");\n titleGroupEnter.append(\"rect\");\n titleGroupEnter.append(\"text\");\n\n var gapSize = Heatmap.computeGapSize(parentGroup.level);\n var padding = gapSize / 4;\n\n var titleRectWidth = Heatmap.groupTitleRectHeight;\n var depth = self.config.y.groups.keys.length - parentGroup.level;\n var overlap = {\n left: 0,\n right: 0\n };\n\n if (!availableWidth) {\n overlap.right = plot.y.overlap.left;\n overlap.left = plot.y.overlap.left;\n availableWidth = plot.width + gapSize + overlap.left + overlap.right;\n }\n\n groups.attr(\"transform\", function (d, i) {\n var translate = \"translate(\" + (padding - overlap.left) + \",\" + (plot.cellHeight * valuesBeforeCount + i * gapSize + gapsBeforeSize + padding) + \")\";\n gapsBeforeSize += d.gapsInsideSize || 0;\n valuesBeforeCount += d.allValuesCount || 0;\n return translate;\n });\n\n var groupWidth = availableWidth - padding * 2;\n\n var titleGroups = groups.selectAll(\"g.title\").attr(\"transform\", function (d, i) {\n return \"translate(\" + (groupWidth - titleRectWidth) + \", 0)\";\n });\n\n var tileRects = titleGroups.selectAll(\"rect\").attr(\"width\", titleRectWidth).attr(\"height\", function (d) {\n return (d.gapsInsideSize || 0) + plot.cellHeight * d.allValuesCount + padding * 2;\n }).attr(\"x\", 0).attr(\"y\", 0)\n // .attr(\"fill\", \"lightgrey\")\n .attr(\"stroke-width\", 0);\n\n this.setGroupMouseCallbacks(parentGroup, tileRects);\n\n groups.selectAll(\"rect.group-rect\").attr(\"class\", function (d) {\n return \"group-rect group-rect-\" + d.index;\n }).attr(\"width\", groupWidth).attr(\"height\", function (d) {\n return (d.gapsInsideSize || 0) + plot.cellHeight * d.allValuesCount + padding * 2;\n }).attr(\"x\", 0).attr(\"y\", 0).attr(\"fill\", \"white\").attr(\"fill-opacity\", 0).attr(\"stroke-width\", 0.5).attr(\"stroke\", \"black\");\n\n groups.each(function (group) {\n\n self.drawGroupsY.call(self, group, d3.select(this), groupWidth - titleRectWidth);\n });\n }\n }, {\n key: 'drawGroupsX',\n value: function drawGroupsX(parentGroup, container, availableHeight) {\n\n var self = this;\n var plot = self.plot;\n\n var groupClass = self.prefixClass(\"group\");\n var groupXClass = groupClass + \"-x\";\n var groups = container.selectAll(\"g.\" + groupClass + \".\" + groupXClass).data(parentGroup.childrenList);\n\n var valuesBeforeCount = 0;\n var gapsBeforeSize = 0;\n\n var groupsEnterG = groups.enter().append(\"g\");\n groupsEnterG.classed(groupClass, true).classed(groupXClass, true).append(\"rect\").classed(\"group-rect\", true);\n\n var titleGroupEnter = groupsEnterG.appendSelector(\"g.title\");\n titleGroupEnter.append(\"rect\");\n titleGroupEnter.append(\"text\");\n\n var gapSize = Heatmap.computeGapSize(parentGroup.level);\n var padding = gapSize / 4;\n var titleRectHeight = Heatmap.groupTitleRectHeight;\n\n var depth = self.config.x.groups.keys.length - parentGroup.level;\n\n var overlap = {\n top: 0,\n bottom: 0\n };\n\n if (!availableHeight) {\n overlap.bottom = plot.x.overlap.bottom;\n overlap.top = plot.x.overlap.top;\n availableHeight = plot.height + gapSize + overlap.top + overlap.bottom;\n } else {\n overlap.top = -titleRectHeight;\n }\n // console.log('parentGroup',parentGroup, 'gapSize', gapSize, plot.x.overlap);\n\n groups.attr(\"transform\", function (d, i) {\n var translate = \"translate(\" + (plot.cellWidth * valuesBeforeCount + i * gapSize + gapsBeforeSize + padding) + \", \" + (padding - overlap.top) + \")\";\n gapsBeforeSize += d.gapsInsideSize || 0;\n valuesBeforeCount += d.allValuesCount || 0;\n return translate;\n });\n\n var groupHeight = availableHeight - padding * 2;\n\n var titleGroups = groups.selectAll(\"g.title\").attr(\"transform\", function (d, i) {\n return \"translate(0, \" + 0 + \")\";\n });\n\n var tileRects = titleGroups.selectAll(\"rect\").attr(\"height\", titleRectHeight).attr(\"width\", function (d) {\n return (d.gapsInsideSize || 0) + plot.cellWidth * d.allValuesCount + padding * 2;\n }).attr(\"x\", 0).attr(\"y\", 0)\n // .attr(\"fill\", \"lightgrey\")\n .attr(\"stroke-width\", 0);\n\n this.setGroupMouseCallbacks(parentGroup, tileRects);\n\n groups.selectAll(\"rect.group-rect\").attr(\"class\", function (d) {\n return \"group-rect group-rect-\" + d.index;\n }).attr(\"height\", groupHeight).attr(\"width\", function (d) {\n return (d.gapsInsideSize || 0) + plot.cellWidth * d.allValuesCount + padding * 2;\n }).attr(\"x\", 0).attr(\"y\", 0).attr(\"fill\", \"white\").attr(\"fill-opacity\", 0).attr(\"stroke-width\", 0.5).attr(\"stroke\", \"black\");\n\n groups.each(function (group) {\n self.drawGroupsX.call(self, group, d3.select(this), groupHeight - titleRectHeight);\n });\n\n groups.exit().remove();\n }\n }, {\n key: 'setGroupMouseCallbacks',\n value: function setGroupMouseCallbacks(parentGroup, tileRects) {\n var plot = this.plot;\n var self = this;\n var mouseoverCallbacks = [];\n mouseoverCallbacks.push(function (d) {\n d3.select(this).classed('highlighted', true);\n d3.select(this.parentNode.parentNode).selectAll(\"rect.group-rect-\" + d.index).classed('highlighted', true);\n });\n\n var mouseoutCallbacks = [];\n mouseoutCallbacks.push(function (d) {\n d3.select(this).classed('highlighted', false);\n d3.select(this.parentNode.parentNode).selectAll(\"rect.group-rect-\" + d.index).classed('highlighted', false);\n });\n if (plot.tooltip) {\n\n mouseoverCallbacks.push(function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = parentGroup.label + \": \" + d.groupingValue;\n\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n });\n\n mouseoutCallbacks.push(function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n tileRects.on(\"mouseover\", function (d) {\n var self = this;\n mouseoverCallbacks.forEach(function (callback) {\n callback.call(self, d);\n });\n });\n tileRects.on(\"mouseout\", function (d) {\n var self = this;\n mouseoutCallbacks.forEach(function (callback) {\n callback.call(self, d);\n });\n });\n }\n }, {\n key: 'updateCells',\n value: function updateCells() {\n\n var self = this;\n var plot = self.plot;\n var cellContainerClass = self.prefixClass(\"cells\");\n var gapSize = Heatmap.computeGapSize(0);\n var paddingX = plot.x.groups.childrenList.length ? gapSize / 2 : 0;\n var paddingY = plot.y.groups.childrenList.length ? gapSize / 2 : 0;\n var cellContainer = self.svgG.selectOrAppend(\"g.\" + cellContainerClass);\n cellContainer.attr(\"transform\", \"translate(\" + paddingX + \", \" + paddingY + \")\");\n\n var cellClass = self.prefixClass(\"cell\");\n var cellShape = plot.z.shape.type;\n\n var cells = cellContainer.selectAll(\"g.\" + cellClass).data(self.plot.cells);\n\n var cellEnterG = cells.enter().append(\"g\").classed(cellClass, true);\n cells.attr(\"transform\", function (c) {\n return \"translate(\" + (plot.cellWidth * c.col + plot.cellWidth / 2 + c.colVar.group.gapsSize) + \",\" + (plot.cellHeight * c.row + plot.cellHeight / 2 + c.rowVar.group.gapsSize) + \")\";\n });\n\n var shapes = cells.selectOrAppend(cellShape + \".cell-shape-\" + cellShape);\n\n shapes.attr(\"width\", plot.z.shape.width).attr(\"height\", plot.z.shape.height).attr(\"x\", -plot.cellWidth / 2).attr(\"y\", -plot.cellHeight / 2);\n\n shapes.style(\"fill\", function (c) {\n return c.value === undefined ? self.config.color.noDataColor : plot.z.color.scale(c.value);\n });\n shapes.attr(\"fill-opacity\", function (d) {\n return d.value === undefined ? 0 : 1;\n });\n\n var mouseoverCallbacks = [];\n var mouseoutCallbacks = [];\n\n if (plot.tooltip) {\n\n mouseoverCallbacks.push(function (c) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = c.value === undefined ? self.config.tooltip.noDataText : self.formatValueZ(c.value);\n\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n });\n\n mouseoutCallbacks.push(function (c) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n\n if (self.config.highlightLabels) {\n var highlightClass = self.config.cssClassPrefix + \"highlight\";\n var xLabelClass = function xLabelClass(c) {\n return plot.labelClass + \"-x-\" + c.col;\n };\n var yLabelClass = function yLabelClass(c) {\n return plot.labelClass + \"-y-\" + c.row;\n };\n\n mouseoverCallbacks.push(function (c) {\n\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, true);\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, true);\n });\n mouseoutCallbacks.push(function (c) {\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, false);\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, false);\n });\n }\n\n cells.on(\"mouseover\", function (c) {\n mouseoverCallbacks.forEach(function (callback) {\n return callback(c);\n });\n }).on(\"mouseout\", function (c) {\n mouseoutCallbacks.forEach(function (callback) {\n return callback(c);\n });\n });\n\n cells.on(\"click\", function (c) {\n self.trigger(\"cell-selected\", c);\n });\n\n cells.exit().remove();\n }\n }, {\n key: 'formatValueX',\n value: function formatValueX(value) {\n if (!this.config.x.formatter) return value;\n\n return this.config.x.formatter.call(this.config, value);\n }\n }, {\n key: 'formatValueY',\n value: function formatValueY(value) {\n if (!this.config.y.formatter) return value;\n\n return this.config.y.formatter.call(this.config, value);\n }\n }, {\n key: 'formatValueZ',\n value: function formatValueZ(value) {\n if (!this.config.z.formatter) return value;\n\n return this.config.z.formatter.call(this.config, value);\n }\n }, {\n key: 'formatLegendValue',\n value: function formatLegendValue(value) {\n if (!this.config.legend.formatter) return value;\n\n return this.config.legend.formatter.call(this.config, value);\n }\n }, {\n key: 'updateLegend',\n value: function updateLegend() {\n var self = this;\n var plot = this.plot;\n var legendX = this.plot.width + 10;\n var gapSize = Heatmap.computeGapSize(0);\n if (this.plot.groupByY) {\n legendX += gapSize / 2 + plot.y.overlap.right;\n } else if (this.plot.groupByX) {\n legendX += gapSize;\n }\n var legendY = 0;\n if (this.plot.groupByX || this.plot.groupByY) {\n legendY += gapSize / 2;\n }\n\n var barWidth = 10;\n var barHeight = this.plot.height - 2;\n var scale = plot.z.color.scale;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY, function (v) {\n return self.formatLegendValue(v);\n }).setRotateLabels(self.config.legend.rotateLabels).linearGradientBar(barWidth, barHeight);\n }\n }], [{\n key: 'computeGapSize',\n value: function computeGapSize(gapLevel) {\n return Heatmap.maxGroupGapSize / (gapLevel + 1);\n }\n }, {\n key: 'computeGapsSize',\n value: function computeGapsSize(gaps) {\n var gapsSize = 0;\n gaps.forEach(function (gapsNumber, gapsLevel) {\n return gapsSize += gapsNumber * Heatmap.computeGapSize(gapsLevel);\n });\n return gapsSize;\n }\n }]);\n\n return Heatmap;\n}(_chart.Chart);\n\nHeatmap.maxGroupGapSize = 24;\nHeatmap.groupTitleRectHeight = 6;\n\n},{\"./chart\":20,\"./legend\":27,\"./utils\":33}],25:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Histogram = exports.HistogramConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _utils = require(\"./utils\");\n\nvar _legend = require(\"./legend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar HistogramConfig = exports.HistogramConfig = function (_ChartConfig) {\n _inherits(HistogramConfig, _ChartConfig);\n\n // string or function returning color's value for color scale\n\n function HistogramConfig(custom) {\n _classCallCheck(this, HistogramConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(HistogramConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'histogram';\n _this.showLegend = true;\n _this.showTooltip = true;\n _this.legend = {\n width: 80,\n margin: 10,\n shapeWidth: 20\n };\n _this.x = { // X axis config\n label: '', // axis label\n key: 0,\n value: function value(d, key) {\n return _utils.Utils.isNumber(d) ? d : d[key];\n }, // x value accessor\n scale: \"linear\",\n ticks: undefined\n };\n _this.y = { // Y axis config\n label: '', // axis label,\n orient: \"left\",\n scale: \"linear\"\n };\n _this.frequency = true;\n _this.groups = {\n key: 1,\n value: function value(d) {\n return d[_this.groups.key];\n }, // grouping value accessor,\n label: \"\"\n };\n _this.color = undefined;\n _this.d3ColorCategory = 'category10';\n _this.transition = true;\n\n var config = _this;\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n }\n\n return HistogramConfig;\n}(_chart.ChartConfig);\n\nvar Histogram = exports.Histogram = function (_Chart) {\n _inherits(Histogram, _Chart);\n\n function Histogram(placeholderSelector, data, config) {\n _classCallCheck(this, Histogram);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(Histogram).call(this, placeholderSelector, data, new HistogramConfig(config)));\n }\n\n _createClass(Histogram, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(Histogram.prototype), \"setConfig\", this).call(this, new HistogramConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n var _this3 = this;\n\n _get(Object.getPrototypeOf(Histogram.prototype), \"initPlot\", this).call(this);\n var self = this;\n\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.y = {};\n this.plot.bar = {\n color: null //color scale mapping function\n };\n\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n this.plot.margin.right = conf.margin.right + conf.legend.width + conf.legend.margin * 2;\n }\n\n this.computePlotSize();\n\n if (conf.d3ColorCategory) {\n this.plot.colorCategory = d3.scale[conf.d3ColorCategory]();\n }\n var colorValue = conf.color;\n if (colorValue && typeof colorValue === 'string' || colorValue instanceof String) {\n this.plot.color = colorValue;\n } else if (this.plot.colorCategory) {\n if (this.config.groups) {\n var domain = Object.getOwnPropertyNames(d3.map(this.data, function (d) {\n return _this3.config.groups.value.call(_this3.config, d);\n })['_']);\n self.plot.colorCategory.domain(domain);\n }\n\n this.plot.color = function (d) {\n return self.plot.colorCategory(d.key);\n };\n }\n\n this.plot.data = this.getDataToPlot();\n this.setupX();\n this.setupHistogram();\n this.setupGroupStacks();\n this.setupY();\n\n return this;\n }\n }, {\n key: \"setupX\",\n value: function setupX() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config.x;\n\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\n x.value = function (d) {\n return conf.value(d, conf.key);\n };\n x.scale = d3.scale[conf.scale]().range([0, plot.width]);\n x.map = function (d) {\n return x.scale(x.value(d));\n };\n\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\n if (conf.ticks) {\n x.axis.ticks(conf.ticks);\n }\n var data = this.plot.data;\n plot.x.scale.domain([d3.min(data, plot.x.value), d3.max(data, plot.x.value)]);\n }\n }, {\n key: \"setupY\",\n value: function setupY() {\n\n var plot = this.plot;\n var y = plot.y;\n var conf = this.config.y;\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\n\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\n\n var data = this.plot.data;\n plot.y.scale.domain([0, d3.max(plot.histogramBins, function (d) {\n return d.y;\n })]);\n }\n }, {\n key: \"setupHistogram\",\n value: function setupHistogram() {\n var plot = this.plot;\n var x = plot.x;\n var y = plot.y;\n var ticks = this.config.x.ticks ? x.scale.ticks(this.config.x.ticks) : x.scale.ticks();\n\n plot.histogram = d3.layout.histogram().frequency(this.config.frequency).value(x.value).bins(ticks);\n plot.histogramBins = plot.histogram(this.plot.data);\n }\n }, {\n key: \"setupGroupStacks\",\n value: function setupGroupStacks() {\n var _this4 = this;\n\n var self = this;\n this.plot.groupingEnabled = this.config.groups && this.config.groups.value;\n\n this.plot.stack = d3.layout.stack().values(function (d) {\n return d.histogramBins;\n });\n this.plot.groupedData = d3.nest().key(function (d) {\n return _this4.plot.groupingEnabled ? _this4.config.groups.value.call(_this4.config, d) : 'root';\n }).entries(this.plot.data);\n this.plot.groupedData.forEach(function (d) {\n d.histogramBins = _this4.plot.histogram.frequency(_this4.config.frequency || _this4.plot.groupingEnabled)(d.values);\n if (!_this4.config.frequency && _this4.plot.groupingEnabled) {\n d.histogramBins.forEach(function (b) {\n b.dy = b.dy / _this4.plot.data.length;\n b.y = b.y / _this4.plot.data.length;\n });\n }\n });\n this.plot.stackedHistograms = this.plot.stack(this.plot.groupedData);\n }\n }, {\n key: \"getDataToPlot\",\n value: function getDataToPlot() {\n var _this5 = this;\n\n if (!this.enabledGroups) {\n return this.data;\n }\n\n return this.data.filter(function (d) {\n return _this5.enabledGroups.indexOf(_this5.config.groups.value.call(_this5.config, d)) > -1;\n });\n }\n }, {\n key: \"drawAxisX\",\n value: function drawAxisX() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.x;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides'))).attr(\"transform\", \"translate(0,\" + plot.height + \")\");\n\n var axisT = axis;\n if (self.config.transition) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.x.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + plot.width / 2 + \",\" + plot.margin.bottom + \")\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"-1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawAxisY\",\n value: function drawAxisY() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.y;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides')));\n\n var axisT = axis;\n if (self.config.transition) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.y.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + plot.height / 2 + \")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawHistogram\",\n value: function drawHistogram() {\n var self = this;\n var plot = self.plot;\n\n var layerClass = this.prefixClass(\"layer\");\n\n var barClass = this.prefixClass(\"bar\");\n var layer = self.svgG.selectAll(\".\" + layerClass).data(plot.stackedHistograms);\n\n layer.enter().append(\"g\").attr(\"class\", layerClass);\n\n var bar = layer.selectAll(\".\" + barClass).data(function (d) {\n return d.histogramBins;\n });\n\n bar.enter().append(\"g\").attr(\"class\", barClass).append(\"rect\").attr(\"x\", 1);\n\n var barRect = bar.select(\"rect\");\n\n var barRectT = barRect;\n var barT = bar;\n var layerT = layer;\n if (this.transitionEnabled()) {\n barRectT = barRect.transition();\n barT = bar.transition();\n layerT = layer.transition();\n }\n\n barT.attr(\"transform\", function (d) {\n return \"translate(\" + plot.x.scale(d.x) + \",\" + plot.y.scale(d.y0 + d.y) + \")\";\n });\n\n var dx = plot.histogramBins.length ? plot.x.scale(plot.histogramBins[0].dx) : 0;\n barRectT.attr(\"width\", dx - plot.x.scale(0) - 1).attr(\"height\", function (d) {\n return plot.height - plot.y.scale(d.y);\n });\n\n if (this.plot.color) {\n layerT.attr(\"fill\", this.plot.color);\n }\n\n if (plot.tooltip) {\n bar.on(\"mouseover\", function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n plot.tooltip.html(d.y).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n }).on(\"mouseout\", function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n layer.exit().remove();\n bar.exit().remove();\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(Histogram.prototype), \"update\", this).call(this, newData);\n this.drawAxisX();\n this.drawAxisY();\n\n this.drawHistogram();\n\n this.updateLegend();\n }\n }, {\n key: \"updateLegend\",\n value: function updateLegend() {\n var _this6 = this;\n\n var plot = this.plot;\n\n var scale = plot.colorCategory;\n if (!scale.domain() || scale.domain().length < 2) {\n plot.showLegend = false;\n }\n\n if (!plot.showLegend) {\n if (plot.legend && plot.legend.container) {\n plot.legend.container.remove();\n }\n return;\n }\n\n var legendX = this.plot.width + this.config.legend.margin;\n var legendY = this.config.legend.margin;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY);\n\n plot.legendColor = plot.legend.color().shapeWidth(this.config.legend.shapeWidth).orient('vertical').scale(scale);\n\n plot.legendColor.on('cellclick', function (c) {\n return _this6.onLegendCellClick(c);\n });\n\n plot.legend.container.call(plot.legendColor);\n }\n }, {\n key: \"onLegendCellClick\",\n value: function onLegendCellClick(cellValue) {\n this.updateEnabledGroups(cellValue);\n\n var isDisabled = this.enabledGroups.indexOf(cellValue) < 0;\n this.plot.legend.container.selectAll(\"g.cell\").each(function (cell) {\n if (cell == cellValue) {\n d3.select(this).classed(\"odc-disabled\", isDisabled);\n }\n });\n\n this.init();\n }\n }, {\n key: \"updateEnabledGroups\",\n value: function updateEnabledGroups(cellValue) {\n if (!this.enabledGroups) {\n this.enabledGroups = this.plot.colorCategory.domain().slice();\n }\n var index = this.enabledGroups.indexOf(cellValue);\n\n if (index < 0) {\n this.enabledGroups.push(cellValue);\n } else {\n this.enabledGroups.splice(index, 1);\n }\n }\n }, {\n key: \"setData\",\n value: function setData(data) {\n _get(Object.getPrototypeOf(Histogram.prototype), \"setData\", this).call(this, data);\n this.enabledGroups = null;\n }\n }]);\n\n return Histogram;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./utils\":33}],26:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Legend = exports.StatisticsUtils = exports.BarChartConfig = exports.BarChart = exports.HistogramConfig = exports.Histogram = exports.HeatmapTimeSeriesConfig = exports.HeatmapTimeSeries = exports.HeatmapConfig = exports.Heatmap = exports.RegressionConfig = exports.Regression = exports.CorrelationMatrixConfig = exports.CorrelationMatrix = exports.ScatterPlotMatrixConfig = exports.ScatterPlotMatrix = exports.ScatterPlotConfig = exports.ScatterPlot = undefined;\n\nvar _scatterplot = require(\"./scatterplot\");\n\nObject.defineProperty(exports, \"ScatterPlot\", {\n enumerable: true,\n get: function get() {\n return _scatterplot.ScatterPlot;\n }\n});\nObject.defineProperty(exports, \"ScatterPlotConfig\", {\n enumerable: true,\n get: function get() {\n return _scatterplot.ScatterPlotConfig;\n }\n});\n\nvar _scatterplotMatrix = require(\"./scatterplot-matrix\");\n\nObject.defineProperty(exports, \"ScatterPlotMatrix\", {\n enumerable: true,\n get: function get() {\n return _scatterplotMatrix.ScatterPlotMatrix;\n }\n});\nObject.defineProperty(exports, \"ScatterPlotMatrixConfig\", {\n enumerable: true,\n get: function get() {\n return _scatterplotMatrix.ScatterPlotMatrixConfig;\n }\n});\n\nvar _correlationMatrix = require(\"./correlation-matrix\");\n\nObject.defineProperty(exports, \"CorrelationMatrix\", {\n enumerable: true,\n get: function get() {\n return _correlationMatrix.CorrelationMatrix;\n }\n});\nObject.defineProperty(exports, \"CorrelationMatrixConfig\", {\n enumerable: true,\n get: function get() {\n return _correlationMatrix.CorrelationMatrixConfig;\n }\n});\n\nvar _regression = require(\"./regression\");\n\nObject.defineProperty(exports, \"Regression\", {\n enumerable: true,\n get: function get() {\n return _regression.Regression;\n }\n});\nObject.defineProperty(exports, \"RegressionConfig\", {\n enumerable: true,\n get: function get() {\n return _regression.RegressionConfig;\n }\n});\n\nvar _heatmap = require(\"./heatmap\");\n\nObject.defineProperty(exports, \"Heatmap\", {\n enumerable: true,\n get: function get() {\n return _heatmap.Heatmap;\n }\n});\nObject.defineProperty(exports, \"HeatmapConfig\", {\n enumerable: true,\n get: function get() {\n return _heatmap.HeatmapConfig;\n }\n});\n\nvar _heatmapTimeseries = require(\"./heatmap-timeseries\");\n\nObject.defineProperty(exports, \"HeatmapTimeSeries\", {\n enumerable: true,\n get: function get() {\n return _heatmapTimeseries.HeatmapTimeSeries;\n }\n});\nObject.defineProperty(exports, \"HeatmapTimeSeriesConfig\", {\n enumerable: true,\n get: function get() {\n return _heatmapTimeseries.HeatmapTimeSeriesConfig;\n }\n});\n\nvar _histogram = require(\"./histogram\");\n\nObject.defineProperty(exports, \"Histogram\", {\n enumerable: true,\n get: function get() {\n return _histogram.Histogram;\n }\n});\nObject.defineProperty(exports, \"HistogramConfig\", {\n enumerable: true,\n get: function get() {\n return _histogram.HistogramConfig;\n }\n});\n\nvar _barChart = require(\"./bar-chart\");\n\nObject.defineProperty(exports, \"BarChart\", {\n enumerable: true,\n get: function get() {\n return _barChart.BarChart;\n }\n});\nObject.defineProperty(exports, \"BarChartConfig\", {\n enumerable: true,\n get: function get() {\n return _barChart.BarChartConfig;\n }\n});\n\nvar _statisticsUtils = require(\"./statistics-utils\");\n\nObject.defineProperty(exports, \"StatisticsUtils\", {\n enumerable: true,\n get: function get() {\n return _statisticsUtils.StatisticsUtils;\n }\n});\n\nvar _legend = require(\"./legend\");\n\nObject.defineProperty(exports, \"Legend\", {\n enumerable: true,\n get: function get() {\n return _legend.Legend;\n }\n});\n\nvar _d3Extensions = require(\"./d3-extensions\");\n\n_d3Extensions.D3Extensions.extend();\n\n},{\"./bar-chart\":19,\"./correlation-matrix\":21,\"./d3-extensions\":22,\"./heatmap\":24,\"./heatmap-timeseries\":23,\"./histogram\":25,\"./legend\":27,\"./regression\":28,\"./scatterplot\":30,\"./scatterplot-matrix\":29,\"./statistics-utils\":32}],27:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Legend = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _utils = require(\"./utils\");\n\nvar _noExtend = require(\"../bower_components/d3-legend/no-extend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*var d3 = require('../bower_components/d3');\r\n*/\n// var legend = require('../bower_components/d3-legend/no-extend');\n//\n// module.exports.legend = legend;\n\nvar Legend = exports.Legend = function () {\n function Legend(svg, legendParent, scale, legendX, legendY, labelFormat) {\n _classCallCheck(this, Legend);\n\n this.cssClassPrefix = \"odc-\";\n this.legendClass = this.cssClassPrefix + \"legend\";\n this.color = _noExtend.color;\n this.size = _noExtend.size;\n this.symbol = _noExtend.symbol;\n this.labelFormat = undefined;\n\n this.scale = scale;\n this.svg = svg;\n this.guid = _utils.Utils.guid();\n this.container = _utils.Utils.selectOrAppend(legendParent, \"g.\" + this.legendClass, \"g\").attr(\"transform\", \"translate(\" + legendX + \",\" + legendY + \")\").classed(this.legendClass, true);\n\n this.labelFormat = labelFormat;\n }\n\n _createClass(Legend, [{\n key: \"linearGradientBar\",\n value: function linearGradientBar(barWidth, barHeight, title) {\n var gradientId = this.cssClassPrefix + \"linear-gradient\" + \"-\" + this.guid;\n var scale = this.scale;\n var self = this;\n\n this.linearGradient = _utils.Utils.linearGradient(this.svg, gradientId, this.scale.range(), 0, 100, 0, 0);\n\n this.container.append(\"rect\").attr(\"width\", barWidth).attr(\"height\", barHeight).attr(\"x\", 0).attr(\"y\", 0).style(\"fill\", \"url(#\" + gradientId + \")\");\n\n var ticks = this.container.selectAll(\"text\").data(scale.domain());\n var ticksNumber = scale.domain().length - 1;\n ticks.enter().append(\"text\");\n\n ticks.attr(\"x\", barWidth).attr(\"y\", function (d, i) {\n return barHeight - i * barHeight / ticksNumber;\n }).attr(\"dx\", 3)\n // .attr(\"dy\", 1)\n .attr(\"alignment-baseline\", \"middle\").text(function (d) {\n return self.labelFormat ? self.labelFormat(d) : d;\n });\n ticks.attr(\"dominant-baseline\", \"middle\");\n if (this.rotateLabels) {\n ticks.attr(\"transform\", function (d, i) {\n return \"rotate(-45, \" + barWidth + \", \" + (barHeight - i * barHeight / ticksNumber) + \")\";\n }).attr(\"text-anchor\", \"start\").attr(\"dx\", 5).attr(\"dy\", 5);\n } else {}\n\n ticks.exit().remove();\n\n return this;\n }\n }, {\n key: \"setRotateLabels\",\n value: function setRotateLabels(rotateLabels) {\n this.rotateLabels = rotateLabels;\n return this;\n }\n }]);\n\n return Legend;\n}();\n\n},{\"../bower_components/d3-legend/no-extend\":1,\"./utils\":33}],28:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.Regression = exports.RegressionConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _scatterplot = require(\"./scatterplot\");\n\nvar _utils = require(\"./utils\");\n\nvar _statisticsUtils = require(\"./statistics-utils\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar RegressionConfig = exports.RegressionConfig = function (_ScatterPlotConfig) {\n _inherits(RegressionConfig, _ScatterPlotConfig);\n\n function RegressionConfig(custom) {\n _classCallCheck(this, RegressionConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(RegressionConfig).call(this));\n\n _this.mainRegression = true;\n _this.groupRegression = true;\n _this.confidence = {\n level: 0.95,\n criticalValue: function criticalValue(degreesOfFreedom, criticalProbability) {\n return _statisticsUtils.StatisticsUtils.tValue(degreesOfFreedom, criticalProbability);\n },\n marginOfError: undefined //custom margin Of Error function (x, points)\n };\n\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n }\n\n return RegressionConfig;\n}(_scatterplot.ScatterPlotConfig);\n\nvar Regression = exports.Regression = function (_ScatterPlot) {\n _inherits(Regression, _ScatterPlot);\n\n function Regression(placeholderSelector, data, config) {\n _classCallCheck(this, Regression);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(Regression).call(this, placeholderSelector, data, new RegressionConfig(config)));\n }\n\n _createClass(Regression, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(Regression.prototype), \"setConfig\", this).call(this, new RegressionConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(Regression.prototype), \"initPlot\", this).call(this);\n this.initRegressionLines();\n }\n }, {\n key: \"initRegressionLines\",\n value: function initRegressionLines() {\n\n var self = this;\n var groupsAvailable = self.config.groups && self.config.groups.value;\n\n self.plot.regressions = [];\n\n if (groupsAvailable && self.config.mainRegression) {\n var regression = this.initRegression(this.plot.data, false);\n self.plot.regressions.push(regression);\n }\n\n if (self.config.groupRegression) {\n this.initGroupRegression();\n }\n }\n }, {\n key: \"initGroupRegression\",\n value: function initGroupRegression() {\n var self = this;\n var dataByGroup = {};\n this.plot.data.forEach(function (d) {\n var groupVal = self.config.groups.value(d, self.config.groups.key);\n\n if (!groupVal && groupVal !== 0) {\n return;\n }\n\n if (!dataByGroup[groupVal]) {\n dataByGroup[groupVal] = [];\n }\n dataByGroup[groupVal].push(d);\n });\n\n for (var key in dataByGroup) {\n if (!dataByGroup.hasOwnProperty(key)) {\n continue;\n }\n\n var regression = this.initRegression(dataByGroup[key], key);\n self.plot.regressions.push(regression);\n }\n }\n }, {\n key: \"initRegression\",\n value: function initRegression(values, groupVal) {\n var self = this;\n\n var points = values.map(function (d) {\n return [parseFloat(self.plot.x.value(d)), parseFloat(self.plot.y.value(d))];\n });\n\n // points.sort((a,b) => a[0]-b[0]);\n\n var linearRegression = _statisticsUtils.StatisticsUtils.linearRegression(points);\n var linearRegressionLine = _statisticsUtils.StatisticsUtils.linearRegressionLine(linearRegression);\n\n var extentX = d3.extent(points, function (d) {\n return d[0];\n });\n\n var linePoints = [{\n x: extentX[0],\n y: linearRegressionLine(extentX[0])\n }, {\n x: extentX[1],\n y: linearRegressionLine(extentX[1])\n }];\n\n var line = d3.svg.line().interpolate(\"basis\").x(function (d) {\n return self.plot.x.scale(d.x);\n }).y(function (d) {\n return self.plot.y.scale(d.y);\n });\n\n var color = self.plot.dot.color;\n\n var defaultColor = \"black\";\n if (_utils.Utils.isFunction(color)) {\n if (values.length && groupVal !== false) {\n color = color(values[0]);\n } else {\n color = defaultColor;\n }\n } else if (!color && groupVal === false) {\n color = defaultColor;\n }\n\n var confidence = this.computeConfidence(points, extentX, linearRegression, linearRegressionLine);\n return {\n group: groupVal || false,\n line: line,\n linePoints: linePoints,\n color: color,\n confidence: confidence\n };\n }\n }, {\n key: \"computeConfidence\",\n value: function computeConfidence(points, extentX, linearRegression, linearRegressionLine) {\n var self = this;\n var slope = linearRegression.m;\n var n = points.length;\n var degreesOfFreedom = Math.max(0, n - 2);\n\n var alpha = 1 - self.config.confidence.level;\n var criticalProbability = 1 - alpha / 2;\n var criticalValue = self.config.confidence.criticalValue(degreesOfFreedom, criticalProbability);\n\n var xValues = points.map(function (d) {\n return d[0];\n });\n var meanX = _statisticsUtils.StatisticsUtils.mean(xValues);\n var xMySum = 0;\n var xSum = 0;\n var xPowSum = 0;\n var ySum = 0;\n var yPowSum = 0;\n points.forEach(function (p) {\n var x = p[0];\n var y = p[1];\n\n xMySum += x * y;\n xSum += x;\n ySum += y;\n xPowSum += x * x;\n yPowSum += y * y;\n });\n var a = linearRegression.m;\n var b = linearRegression.b;\n\n var Sa2 = n / (n + 2) * ((yPowSum - a * xMySum - b * ySum) / (n * xPowSum - xSum * xSum)); //Wariancja współczynnika kierunkowego regresji liniowej a\n var Sy2 = (yPowSum - a * xMySum - b * ySum) / (n * (n - 2)); //Sa2 //Mean y value variance\n\n var errorFn = function errorFn(x) {\n return Math.sqrt(Sy2 + Math.pow(x - meanX, 2) * Sa2);\n }; //pierwiastek kwadratowy z wariancji dowolnego punktu prostej\n var marginOfError = function marginOfError(x) {\n return criticalValue * errorFn(x);\n };\n\n // console.log('n', n, 'degreesOfFreedom', degreesOfFreedom, 'criticalProbability',criticalProbability);\n // var confidenceDown = x => linearRegressionLine(x) - marginOfError(x);\n // var confidenceUp = x => linearRegressionLine(x) + marginOfError(x);\n\n var computeConfidenceAreaPoint = function computeConfidenceAreaPoint(x) {\n var linearRegression = linearRegressionLine(x);\n var moe = marginOfError(x);\n var confDown = linearRegression - moe;\n var confUp = linearRegression + moe;\n return {\n x: x,\n y0: confDown,\n y1: confUp\n };\n };\n\n var centerX = (extentX[1] + extentX[0]) / 2;\n\n // var confidenceAreaPoints = [extentX[0], centerX, extentX[1]].map(computeConfidenceAreaPoint);\n var confidenceAreaPoints = [extentX[0], centerX, extentX[1]].map(computeConfidenceAreaPoint);\n\n var fitInPlot = function fitInPlot(y) {\n return y;\n };\n\n var confidenceArea = d3.svg.area().interpolate(\"monotone\").x(function (d) {\n return self.plot.x.scale(d.x);\n }).y0(function (d) {\n return fitInPlot(self.plot.y.scale(d.y0));\n }).y1(function (d) {\n return fitInPlot(self.plot.y.scale(d.y1));\n });\n\n return {\n area: confidenceArea,\n points: confidenceAreaPoints\n };\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(Regression.prototype), \"update\", this).call(this, newData);\n this.updateRegressionLines();\n }\n }, {\n key: \"updateRegressionLines\",\n value: function updateRegressionLines() {\n var self = this;\n var regressionContainerClass = this.prefixClass(\"regression-container\");\n var regressionContainerSelector = \"g.\" + regressionContainerClass;\n\n var clipPathId = self.prefixClass(\"clip\");\n\n var regressionContainer = self.svgG.selectOrInsert(regressionContainerSelector, \".\" + self.dotsContainerClass);\n var regressionContainerClip = regressionContainer.selectOrAppend(\"clipPath\").attr(\"id\", clipPathId);\n\n regressionContainerClip.selectOrAppend('rect').attr('width', self.plot.width).attr('height', self.plot.height).attr('x', 0).attr('y', 0);\n\n regressionContainer.attr(\"clip-path\", function (d, i) {\n return \"url(#\" + clipPathId + \")\";\n });\n\n var regressionClass = this.prefixClass(\"regression\");\n var confidenceAreaClass = self.prefixClass(\"confidence\");\n var regressionSelector = \"g.\" + regressionClass;\n var regression = regressionContainer.selectAll(regressionSelector).data(self.plot.regressions, function (d, i) {\n return d.group;\n });\n\n var regressionEnterG = regression.enter().insertSelector(regressionSelector);\n var lineClass = self.prefixClass(\"line\");\n regressionEnterG.append(\"path\").attr(\"class\", lineClass).attr(\"shape-rendering\", \"optimizeQuality\");\n // .append(\"line\")\n // .attr(\"class\", \"line\")\n // .attr(\"shape-rendering\", \"optimizeQuality\");\n\n var line = regression.select(\"path.\" + lineClass).style(\"stroke\", function (r) {\n return r.color;\n });\n // .attr(\"x1\", r=> self.plot.x.scale(r.linePoints[0].x))\n // .attr(\"y1\", r=> self.plot.y.scale(r.linePoints[0].y))\n // .attr(\"x2\", r=> self.plot.x.scale(r.linePoints[1].x))\n // .attr(\"y2\", r=> self.plot.y.scale(r.linePoints[1].y))\n\n var lineT = line;\n if (self.transitionEnabled()) {\n lineT = line.transition();\n }\n\n lineT.attr(\"d\", function (r) {\n return r.line(r.linePoints);\n });\n\n regressionEnterG.append(\"path\").attr(\"class\", confidenceAreaClass).attr(\"shape-rendering\", \"optimizeQuality\").style(\"opacity\", \"0.4\");\n\n var area = regression.select(\"path.\" + confidenceAreaClass);\n\n var areaT = area;\n if (self.transitionEnabled()) {\n areaT = area.transition();\n }\n areaT.attr(\"d\", function (r) {\n return r.confidence.area(r.confidence.points);\n });\n areaT.style(\"fill\", function (r) {\n return r.color;\n });\n regression.exit().remove();\n }\n }]);\n\n return Regression;\n}(_scatterplot.ScatterPlot);\n\n},{\"./chart\":20,\"./scatterplot\":30,\"./statistics-utils\":32,\"./utils\":33}],29:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ScatterPlotMatrix = exports.ScatterPlotMatrixConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _scatterplot = require(\"./scatterplot\");\n\nvar _utils = require(\"./utils\");\n\nvar _legend = require(\"./legend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar ScatterPlotMatrixConfig = exports.ScatterPlotMatrixConfig = function (_ScatterPlotConfig) {\n _inherits(ScatterPlotMatrixConfig, _ScatterPlotConfig);\n\n //ticks number, (default: computed using cell size)\n //show axis guides\n //scatter plot cell padding\n\n function ScatterPlotMatrixConfig(custom) {\n _classCallCheck(this, ScatterPlotMatrixConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ScatterPlotMatrixConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'scatterplot-matrix';\n _this.size = 200;\n _this.padding = 20;\n _this.brush = true;\n _this.guides = true;\n _this.showTooltip = true;\n _this.ticks = undefined;\n _this.x = { // X axis config\n orient: \"bottom\",\n scale: \"linear\"\n };\n _this.y = { // Y axis config\n orient: \"left\",\n scale: \"linear\"\n };\n _this.groups = {\n key: undefined, //object property name or array index with grouping variable\n includeInPlot: false, //include group as variable in plot, boolean (default: false)\n value: function value(d, key) {\n return d[key];\n }, // grouping value accessor,\n label: \"\"\n };\n _this.variables = {\n labels: [], //optional array of variable labels (for the diagonal of the plot).\n keys: [], //optional array of variable keys\n value: function value(d, variableKey) {\n return d[variableKey];\n } // variable value accessor\n };\n\n _utils.Utils.deepExtend(_this, custom);\n return _this;\n } //show tooltip on dot hover\n //scatter plot cell size\n\n\n return ScatterPlotMatrixConfig;\n}(_scatterplot.ScatterPlotConfig);\n\nvar ScatterPlotMatrix = exports.ScatterPlotMatrix = function (_Chart) {\n _inherits(ScatterPlotMatrix, _Chart);\n\n function ScatterPlotMatrix(placeholderSelector, data, config) {\n _classCallCheck(this, ScatterPlotMatrix);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(ScatterPlotMatrix).call(this, placeholderSelector, data, new ScatterPlotMatrixConfig(config)));\n }\n\n _createClass(ScatterPlotMatrix, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(ScatterPlotMatrix.prototype), \"setConfig\", this).call(this, new ScatterPlotMatrixConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(ScatterPlotMatrix.prototype), \"initPlot\", this).call(this);\n\n var self = this;\n var margin = this.plot.margin;\n var conf = this.config;\n this.plot.x = {};\n this.plot.y = {};\n this.plot.dot = {\n color: null //color scale mapping function\n };\n\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n margin.right = conf.margin.right + conf.legend.width + conf.legend.margin * 2;\n }\n\n this.setupGroups();\n\n this.plot.data = this.getDataToPlot();\n this.setupVariables();\n\n this.plot.size = conf.size;\n\n var width = conf.width;\n var boundingClientRect = this.getBaseContainerNode().getBoundingClientRect();\n if (!width) {\n var maxWidth = margin.left + margin.right + this.plot.variables.length * this.plot.size;\n width = Math.min(boundingClientRect.width, maxWidth);\n }\n var height = width;\n if (!height) {\n height = boundingClientRect.height;\n }\n\n this.plot.width = width - margin.left - margin.right;\n this.plot.height = height - margin.top - margin.bottom;\n\n if (conf.ticks === undefined) {\n conf.ticks = this.plot.size / 40;\n }\n\n this.setupX();\n this.setupY();\n\n return this;\n }\n }, {\n key: \"setupGroups\",\n value: function setupGroups() {\n var self = this;\n var conf = this.config;\n this.plot.groupValue = function (d) {\n return conf.groups.value(d, conf.groups.key);\n };\n if (conf.dot.d3ColorCategory) {\n this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();\n }\n var colorValue = conf.dot.color;\n if (colorValue) {\n this.plot.dot.colorValue = colorValue;\n\n if (typeof colorValue === 'string' || colorValue instanceof String) {\n this.plot.dot.color = colorValue;\n } else if (this.plot.dot.colorCategory) {\n var domain = Object.getOwnPropertyNames(d3.map(this.data, function (d) {\n return self.plot.dot.colorValue.call(self, d);\n })['_']);\n self.plot.dot.colorCategory.domain(domain);\n this.plot.dot.color = function (d) {\n return self.plot.dot.colorCategory(self.plot.dot.colorValue.call(self, d));\n };\n }\n }\n }\n }, {\n key: \"getDataToPlot\",\n value: function getDataToPlot() {\n var _this3 = this;\n\n if (!this.enabledGroups) {\n return this.data;\n }\n\n var filter = this.data.filter(function (d) {\n return _this3.enabledGroups.indexOf(_this3.plot.groupValue(d)) > -1;\n });\n void 0;\n return filter;\n }\n }, {\n key: \"setupVariables\",\n value: function setupVariables() {\n var variablesConf = this.config.variables;\n\n var data = this.data;\n var plot = this.plot;\n plot.domainByVariable = {};\n plot.variables = variablesConf.keys;\n if (!plot.variables || !plot.variables.length) {\n plot.variables = _utils.Utils.inferVariables(data, this.config.groups.key, this.config.includeInPlot);\n }\n\n plot.labels = [];\n plot.labelByVariable = {};\n plot.variables.forEach(function (variableKey, index) {\n plot.domainByVariable[variableKey] = d3.extent(data, function (d) {\n return variablesConf.value(d, variableKey);\n });\n var label = variableKey;\n if (variablesConf.labels && variablesConf.labels.length > index) {\n\n label = variablesConf.labels[index];\n }\n plot.labels.push(label);\n plot.labelByVariable[variableKey] = label;\n });\n\n void 0;\n\n plot.subplots = [];\n }\n }, {\n key: \"setupX\",\n value: function setupX() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config;\n\n x.value = conf.variables.value;\n x.scale = d3.scale[conf.x.scale]().range([conf.padding / 2, plot.size - conf.padding / 2]);\n x.map = function (d, variable) {\n return x.scale(x.value(d, variable));\n };\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.x.orient).ticks(conf.ticks);\n x.axis.tickSize(plot.size * plot.variables.length);\n }\n }, {\n key: \"setupY\",\n value: function setupY() {\n\n var plot = this.plot;\n var y = plot.y;\n var conf = this.config;\n\n y.value = conf.variables.value;\n y.scale = d3.scale[conf.y.scale]().range([plot.size - conf.padding / 2, conf.padding / 2]);\n y.map = function (d, variable) {\n return y.scale(y.value(d, variable));\n };\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.y.orient).ticks(conf.ticks);\n y.axis.tickSize(-plot.size * plot.variables.length);\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(ScatterPlotMatrix.prototype), \"update\", this).call(this, newData);\n\n var self = this;\n var n = self.plot.variables.length;\n var conf = this.config;\n\n var axisClass = self.prefixClass(\"axis\");\n var axisXClass = axisClass + \"-x\";\n var axisYClass = axisClass + \"-y\";\n\n var xAxisSelector = \"g.\" + axisXClass + \".\" + axisClass;\n var yAxisSelector = \"g.\" + axisYClass + \".\" + axisClass;\n\n var noGuidesClass = self.prefixClass(\"no-guides\");\n self.svgG.selectAll(xAxisSelector).data(self.plot.variables).enter().appendSelector(xAxisSelector).classed(noGuidesClass, !conf.guides).attr(\"transform\", function (d, i) {\n return \"translate(\" + (n - i - 1) * self.plot.size + \",0)\";\n }).each(function (d) {\n self.plot.x.scale.domain(self.plot.domainByVariable[d]);d3.select(this).call(self.plot.x.axis);\n });\n\n self.svgG.selectAll(yAxisSelector).data(self.plot.variables).enter().appendSelector(yAxisSelector).classed(noGuidesClass, !conf.guides).attr(\"transform\", function (d, i) {\n return \"translate(0,\" + i * self.plot.size + \")\";\n }).each(function (d) {\n self.plot.y.scale.domain(self.plot.domainByVariable[d]);d3.select(this).call(self.plot.y.axis);\n });\n\n var cellClass = self.prefixClass(\"cell\");\n var cell = self.svgG.selectAll(\".\" + cellClass).data(self.utils.cross(self.plot.variables, self.plot.variables));\n\n cell.enter().appendSelector(\"g.\" + cellClass).filter(function (d) {\n return d.i === d.j;\n }).append(\"text\");\n\n cell.attr(\"transform\", function (d) {\n return \"translate(\" + (n - d.i - 1) * self.plot.size + \",\" + d.j * self.plot.size + \")\";\n });\n\n if (conf.brush) {\n this.drawBrush(cell);\n }\n\n cell.each(plotSubplot);\n\n //Labels\n cell.select(\"text\").attr(\"x\", conf.padding).attr(\"y\", conf.padding).attr(\"dy\", \".71em\").text(function (d) {\n return self.plot.labelByVariable[d.x];\n });\n\n function plotSubplot(p) {\n var plot = self.plot;\n plot.subplots.push(p);\n var cell = d3.select(this);\n\n plot.x.scale.domain(plot.domainByVariable[p.x]);\n plot.y.scale.domain(plot.domainByVariable[p.y]);\n\n var frameClass = self.prefixClass(\"frame\");\n cell.selectOrAppend(\"rect.\" + frameClass).attr(\"class\", frameClass).attr(\"x\", conf.padding / 2).attr(\"y\", conf.padding / 2).attr(\"width\", conf.size - conf.padding).attr(\"height\", conf.size - conf.padding);\n\n p.update = function () {\n\n var subplot = this;\n var dots = cell.selectAll(\"circle\").data(self.plot.data);\n\n dots.enter().append(\"circle\");\n\n var dotsT = dots;\n if (self.transitionEnabled()) {\n dotsT = dots.transition();\n }\n\n dotsT.attr(\"cx\", function (d) {\n return plot.x.map(d, subplot.x);\n }).attr(\"cy\", function (d) {\n return plot.y.map(d, subplot.y);\n }).attr(\"r\", self.config.dot.radius);\n\n if (plot.dot.color) {\n dotsT.style(\"fill\", plot.dot.color);\n }\n\n if (plot.tooltip) {\n dots.on(\"mouseover\", function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = \"(\" + plot.x.value(d, subplot.x) + \", \" + plot.y.value(d, subplot.y) + \")\";\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n\n var group = self.config.groups ? self.config.groups.value(d) : false;\n if (group || group === 0) {\n html += \"
\";\n var label = self.config.groups.label;\n if (label) {\n html += label + \": \";\n }\n html += group;\n }\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n }).on(\"mouseout\", function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n\n dots.exit().remove();\n };\n p.update();\n }\n\n this.updateLegend();\n }\n }, {\n key: \"drawBrush\",\n value: function drawBrush(cell) {\n var self = this;\n var brush = d3.svg.brush().x(self.plot.x.scale).y(self.plot.y.scale).on(\"brushstart\", brushstart).on(\"brush\", brushmove).on(\"brushend\", brushend);\n\n cell.append(\"g\").call(brush);\n\n var brushCell;\n\n // Clear the previously-active brush, if any.\n function brushstart(p) {\n if (brushCell !== this) {\n d3.select(brushCell).call(brush.clear());\n self.plot.x.scale.domain(self.plot.domainByVariable[p.x]);\n self.plot.y.scale.domain(self.plot.domainByVariable[p.y]);\n brushCell = this;\n }\n }\n\n // Highlight the selected circles.\n function brushmove(p) {\n var e = brush.extent();\n self.svgG.selectAll(\"circle\").classed(\"hidden\", function (d) {\n return e[0][0] > d[p.x] || d[p.x] > e[1][0] || e[0][1] > d[p.y] || d[p.y] > e[1][1];\n });\n }\n // If the brush is empty, select all circles.\n function brushend() {\n if (brush.empty()) self.svgG.selectAll(\".hidden\").classed(\"hidden\", false);\n }\n }\n }, {\n key: \"updateLegend\",\n value: function updateLegend() {\n\n var self = this;\n var plot = this.plot;\n\n var scale = plot.dot.colorCategory;\n\n if (!scale.domain() || scale.domain().length < 2) {\n plot.showLegend = false;\n }\n\n if (!plot.showLegend) {\n if (plot.legend && plot.legend.container) {\n plot.legend.container.remove();\n }\n return;\n }\n\n var legendX = this.plot.width + this.config.legend.margin;\n var legendY = this.config.legend.margin;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY);\n\n plot.legendColor = plot.legend.color().shapeWidth(this.config.legend.shapeWidth).orient('vertical').scale(scale);\n\n plot.legendColor.on('cellclick', function (c) {\n return self.onLegendCellClick(c);\n });\n\n plot.legend.container.call(plot.legendColor);\n }\n }, {\n key: \"onLegendCellClick\",\n value: function onLegendCellClick(cellValue) {\n this.updateEnabledGroups(cellValue);\n\n var isDisabled = this.enabledGroups.indexOf(cellValue) < 0;\n this.plot.legend.container.selectAll(\"g.cell\").each(function (cell) {\n if (cell == cellValue) {\n d3.select(this).classed(\"odc-disabled\", isDisabled);\n }\n });\n\n this.init();\n }\n }, {\n key: \"updateEnabledGroups\",\n value: function updateEnabledGroups(cellValue) {\n if (!this.enabledGroups) {\n this.enabledGroups = this.plot.dot.colorCategory.domain().slice();\n }\n var index = this.enabledGroups.indexOf(cellValue);\n\n if (index < 0) {\n this.enabledGroups.push(cellValue);\n } else {\n this.enabledGroups.splice(index, 1);\n }\n }\n }, {\n key: \"setData\",\n value: function setData(data) {\n _get(Object.getPrototypeOf(ScatterPlotMatrix.prototype), \"setData\", this).call(this, data);\n this.enabledGroups = null;\n }\n }]);\n\n return ScatterPlotMatrix;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./scatterplot\":30,\"./utils\":33}],30:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ScatterPlot = exports.ScatterPlotConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _chart = require(\"./chart\");\n\nvar _utils = require(\"./utils\");\n\nvar _legend = require(\"./legend\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar ScatterPlotConfig = exports.ScatterPlotConfig = function (_ChartConfig) {\n _inherits(ScatterPlotConfig, _ChartConfig);\n\n //show axis guides\n\n function ScatterPlotConfig(custom) {\n _classCallCheck(this, ScatterPlotConfig);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ScatterPlotConfig).call(this));\n\n _this.svgClass = _this.cssClassPrefix + 'scatterplot';\n _this.guides = false;\n _this.showTooltip = true;\n _this.showLegend = true;\n _this.legend = {\n width: 80,\n margin: 10,\n shapeWidth: 20\n };\n _this.x = { // X axis config\n label: 'X', // axis label\n key: 0,\n value: function value(d, key) {\n return d[key];\n }, // x value accessor\n orient: \"bottom\",\n scale: \"linear\"\n };\n _this.y = { // Y axis config\n label: 'Y', // axis label,\n key: 1,\n value: function value(d, key) {\n return d[key];\n }, // y value accessor\n orient: \"left\",\n scale: \"linear\"\n };\n _this.groups = {\n key: 2,\n value: function value(d, key) {\n return d[key];\n }, // grouping value accessor,\n label: \"\"\n };\n _this.dot = {\n radius: 2,\n color: function color(d) {\n return _this.groups ? _this.groups.value(d, _this.groups.key) : '';\n }, // string or function returning color's value for color scale\n d3ColorCategory: 'category10'\n };\n _this.transition = true;\n\n\n if (custom) {\n _utils.Utils.deepExtend(_this, custom);\n }\n\n return _this;\n } //show tooltip on dot hover\n\n\n return ScatterPlotConfig;\n}(_chart.ChartConfig);\n\nvar ScatterPlot = exports.ScatterPlot = function (_Chart) {\n _inherits(ScatterPlot, _Chart);\n\n function ScatterPlot(placeholderSelector, data, config) {\n _classCallCheck(this, ScatterPlot);\n\n return _possibleConstructorReturn(this, Object.getPrototypeOf(ScatterPlot).call(this, placeholderSelector, data, new ScatterPlotConfig(config)));\n }\n\n _createClass(ScatterPlot, [{\n key: \"setConfig\",\n value: function setConfig(config) {\n return _get(Object.getPrototypeOf(ScatterPlot.prototype), \"setConfig\", this).call(this, new ScatterPlotConfig(config));\n }\n }, {\n key: \"initPlot\",\n value: function initPlot() {\n _get(Object.getPrototypeOf(ScatterPlot.prototype), \"initPlot\", this).call(this);\n var self = this;\n\n var conf = this.config;\n\n this.plot.x = {};\n this.plot.y = {};\n this.plot.dot = {\n color: null //color scale mapping function\n };\n\n this.plot.showLegend = conf.showLegend;\n if (this.plot.showLegend) {\n this.plot.margin.right = conf.margin.right + conf.legend.width + conf.legend.margin * 2;\n }\n\n this.computePlotSize();\n\n this.setupGroups();\n\n this.plot.data = this.getDataToPlot();\n this.setupX();\n this.setupY();\n\n return this;\n }\n }, {\n key: \"setupGroups\",\n value: function setupGroups() {\n var self = this;\n var conf = this.config;\n this.plot.groupValue = function (d) {\n return conf.groups.value(d, conf.groups.key);\n };\n if (conf.dot.d3ColorCategory) {\n this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();\n }\n var colorValue = conf.dot.color;\n if (colorValue) {\n this.plot.dot.colorValue = colorValue;\n\n if (typeof colorValue === 'string' || colorValue instanceof String) {\n this.plot.dot.color = colorValue;\n } else if (this.plot.dot.colorCategory) {\n var domain = Object.getOwnPropertyNames(d3.map(this.data, function (d) {\n return self.plot.dot.colorValue.call(self, d);\n })['_']);\n self.plot.dot.colorCategory.domain(domain);\n this.plot.dot.color = function (d) {\n return self.plot.dot.colorCategory(self.plot.dot.colorValue.call(self, d));\n };\n }\n }\n }\n }, {\n key: \"getDataToPlot\",\n value: function getDataToPlot() {\n var _this3 = this;\n\n if (!this.enabledGroups) {\n return this.data;\n }\n\n return this.data.filter(function (d) {\n return _this3.enabledGroups.indexOf(_this3.plot.groupValue(d)) > -1;\n });\n }\n }, {\n key: \"setupX\",\n value: function setupX() {\n\n var plot = this.plot;\n var x = plot.x;\n var conf = this.config.x;\n\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\n x.value = function (d) {\n return conf.value(d, conf.key);\n };\n x.scale = d3.scale[conf.scale]().range([0, plot.width]);\n x.map = function (d) {\n return x.scale(x.value(d));\n };\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\n var data = this.plot.data;\n plot.x.scale.domain([d3.min(data, plot.x.value) - 1, d3.max(data, plot.x.value) + 1]);\n if (this.config.guides) {\n x.axis.tickSize(-plot.height);\n }\n }\n }, {\n key: \"setupY\",\n value: function setupY() {\n\n var plot = this.plot;\n var y = plot.y;\n var conf = this.config.y;\n\n /*\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n */\n y.value = function (d) {\n return conf.value(d, conf.key);\n };\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\n y.map = function (d) {\n return y.scale(y.value(d));\n };\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\n\n if (this.config.guides) {\n y.axis.tickSize(-plot.width);\n }\n\n var data = this.plot.data;\n plot.y.scale.domain([d3.min(data, plot.y.value) - 1, d3.max(data, plot.y.value) + 1]);\n }\n }, {\n key: \"drawAxisX\",\n value: function drawAxisX() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.x;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides'))).attr(\"transform\", \"translate(0,\" + plot.height + \")\");\n\n var axisT = axis;\n if (self.transitionEnabled()) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.x.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + plot.width / 2 + \",\" + plot.margin.bottom + \")\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"-1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"drawAxisY\",\n value: function drawAxisY() {\n var self = this;\n var plot = self.plot;\n var axisConf = this.config.y;\n var axis = self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y') + \".\" + self.prefixClass('axis') + (self.config.guides ? '' : '.' + self.prefixClass('no-guides')));\n\n var axisT = axis;\n if (self.transitionEnabled()) {\n axisT = axis.transition().ease(\"sin-in-out\");\n }\n\n axisT.call(plot.y.axis);\n\n axis.selectOrAppend(\"text.\" + self.prefixClass('label')).attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + plot.height / 2 + \")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\n .attr(\"dy\", \"1em\").style(\"text-anchor\", \"middle\").text(axisConf.label);\n }\n }, {\n key: \"update\",\n value: function update(newData) {\n _get(Object.getPrototypeOf(ScatterPlot.prototype), \"update\", this).call(this, newData);\n this.drawAxisX();\n this.drawAxisY();\n\n this.updateDots();\n\n this.updateLegend();\n }\n }, {\n key: \"updateDots\",\n value: function updateDots() {\n var self = this;\n var plot = self.plot;\n var data = plot.data;\n var dotClass = self.prefixClass('dot');\n self.dotsContainerClass = self.prefixClass('dots-container');\n\n var dotsContainer = self.svgG.selectOrAppend(\"g.\" + self.dotsContainerClass);\n\n var dots = dotsContainer.selectAll('.' + dotClass).data(data);\n\n dots.enter().append(\"circle\").attr(\"class\", dotClass);\n\n var dotsT = dots;\n if (self.transitionEnabled()) {\n dotsT = dots.transition();\n }\n\n dotsT.attr(\"r\", self.config.dot.radius).attr(\"cx\", plot.x.map).attr(\"cy\", plot.y.map);\n\n if (plot.tooltip) {\n dots.on(\"mouseover\", function (d) {\n plot.tooltip.transition().duration(200).style(\"opacity\", .9);\n var html = \"(\" + plot.x.value(d) + \", \" + plot.y.value(d) + \")\";\n var group = self.config.groups ? self.config.groups.value(d, self.config.groups.key) : null;\n if (group || group === 0) {\n html += \"
\";\n var label = self.config.groups.label;\n if (label) {\n html += label + \": \";\n }\n html += group;\n }\n plot.tooltip.html(html).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n }).on(\"mouseout\", function (d) {\n plot.tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n\n if (plot.dot.color) {\n dots.style(\"fill\", plot.dot.color);\n }\n\n dots.exit().remove();\n }\n }, {\n key: \"updateLegend\",\n value: function updateLegend() {\n\n var self = this;\n var plot = this.plot;\n\n var scale = plot.dot.colorCategory;\n\n if (!scale.domain() || scale.domain().length < 2) {\n plot.showLegend = false;\n }\n\n if (!plot.showLegend) {\n if (plot.legend && plot.legend.container) {\n plot.legend.container.remove();\n }\n return;\n }\n\n var legendX = this.plot.width + this.config.legend.margin;\n var legendY = this.config.legend.margin;\n\n plot.legend = new _legend.Legend(this.svg, this.svgG, scale, legendX, legendY);\n\n plot.legendColor = plot.legend.color().shapeWidth(this.config.legend.shapeWidth).orient('vertical').scale(scale);\n\n plot.legendColor.on('cellclick', function (c) {\n return self.onLegendCellClick(c);\n });\n\n plot.legend.container.call(plot.legendColor);\n }\n }, {\n key: \"onLegendCellClick\",\n value: function onLegendCellClick(cellValue) {\n this.updateEnabledGroups(cellValue);\n\n var isDisabled = this.enabledGroups.indexOf(cellValue) < 0;\n this.plot.legend.container.selectAll(\"g.cell\").each(function (cell) {\n if (cell == cellValue) {\n d3.select(this).classed(\"odc-disabled\", isDisabled);\n }\n });\n\n this.init();\n }\n }, {\n key: \"updateEnabledGroups\",\n value: function updateEnabledGroups(cellValue) {\n if (!this.enabledGroups) {\n this.enabledGroups = this.plot.dot.colorCategory.domain().slice();\n }\n var index = this.enabledGroups.indexOf(cellValue);\n\n if (index < 0) {\n this.enabledGroups.push(cellValue);\n } else {\n this.enabledGroups.splice(index, 1);\n }\n }\n }, {\n key: \"setData\",\n value: function setData(data) {\n _get(Object.getPrototypeOf(ScatterPlot.prototype), \"setData\", this).call(this, data);\n this.enabledGroups = null;\n }\n }]);\n\n return ScatterPlot;\n}(_chart.Chart);\n\n},{\"./chart\":20,\"./legend\":27,\"./utils\":33}],31:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports.tdistr = tdistr;\n/*\n * https://gist.github.com/benrasmusen/1261977\n * NAME\n * \n * statistics-distributions.js - JavaScript library for calculating\n * critical values and upper probabilities of common statistical\n * distributions\n * \n * SYNOPSIS\n * \n * \n * // Chi-squared-crit (2 degrees of freedom, 95th percentile = 0.05 level\n * chisqrdistr(2, .05)\n * \n * // u-crit (95th percentile = 0.05 level)\n * udistr(.05);\n * \n * // t-crit (1 degree of freedom, 99.5th percentile = 0.005 level) \n * tdistr(1,.005);\n * \n * // F-crit (1 degree of freedom in numerator, 3 degrees of freedom \n * // in denominator, 99th percentile = 0.01 level)\n * fdistr(1,3,.01);\n * \n * // upper probability of the u distribution (u = -0.85): Q(u) = 1-G(u)\n * uprob(-0.85);\n * \n * // upper probability of the chi-square distribution\n * // (3 degrees of freedom, chi-squared = 6.25): Q = 1-G\n * chisqrprob(3,6.25);\n * \n * // upper probability of the t distribution\n * // (3 degrees of freedom, t = 6.251): Q = 1-G\n * tprob(3,6.251);\n * \n * // upper probability of the F distribution\n * // (3 degrees of freedom in numerator, 5 degrees of freedom in\n * // denominator, F = 6.25): Q = 1-G\n * fprob(3,5,.625);\n * \n * \n * DESCRIPTION\n * \n * This library calculates percentage points (5 significant digits) of the u\n * (standard normal) distribution, the student's t distribution, the\n * chi-square distribution and the F distribution. It can also calculate the\n * upper probability (5 significant digits) of the u (standard normal), the\n * chi-square, the t and the F distribution.\n * \n * These critical values are needed to perform statistical tests, like the u\n * test, the t test, the F test and the chi-squared test, and to calculate\n * confidence intervals.\n * \n * If you are interested in more precise algorithms you could look at:\n * StatLib: http://lib.stat.cmu.edu/apstat/ ; \n * Applied Statistics Algorithms by Griffiths, P. and Hill, I.D.\n * , Ellis Horwood: Chichester (1985)\n * \n * BUGS \n * \n * This port was produced from the Perl module Statistics::Distributions\n * that has had no bug reports in several years. If you find a bug then\n * please double-check that JavaScript does not thing the numbers you are\n * passing in are strings. (You can subtract 0 from them as you pass them\n * in so that \"5\" is properly understood to be 5.) If you have passed in a\n * number then please contact the author\n * \n * AUTHOR\n * \n * Ben Tilly \n * \n * Originl Perl version by Michael Kospach \n * \n * Nice formating, simplification and bug repair by Matthias Trautner Kromann\n * \n * \n * COPYRIGHT \n * \n * Copyright 2008 Ben Tilly.\n * \n * This library is free software; you can redistribute it and/or modify it\n * under the same terms as Perl itself. This means under either the Perl\n * Artistic License or the GPL v1 or later.\n */\n\nvar SIGNIFICANT = 5; // number of significant digits to be returned\n\nfunction chisqrdistr($n, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* degree of freedom */\n\t}\n\tif ($p <= 0 || $p > 1) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\treturn precision_string(_subchisqr($n - 0, $p - 0));\n}\n\nfunction udistr($p) {\n\tif ($p > 1 || $p <= 0) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\treturn precision_string(_subu($p - 0));\n}\n\nfunction tdistr($n, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\";\n\t}\n\tif ($p <= 0 || $p >= 1) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\treturn precision_string(_subt($n - 0, $p - 0));\n}\n\nfunction fdistr($n, $m, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* first degree of freedom */\n\t}\n\tif ($m <= 0 || Math.abs($m) - Math.abs(integer($m)) != 0) {\n\t\tthrow \"Invalid m: $m\\n\"; /* second degree of freedom */\n\t}\n\tif ($p <= 0 || $p > 1) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\treturn precision_string(_subf($n - 0, $m - 0, $p - 0));\n}\n\nfunction uprob($x) {\n\treturn precision_string(_subuprob($x - 0));\n}\n\nfunction chisqrprob($n, $x) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* degree of freedom */\n\t}\n\treturn precision_string(_subchisqrprob($n - 0, $x - 0));\n}\n\nfunction tprob($n, $x) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* degree of freedom */\n\t}\n\treturn precision_string(_subtprob($n - 0, $x - 0));\n}\n\nfunction fprob($n, $m, $x) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow \"Invalid n: $n\\n\"; /* first degree of freedom */\n\t}\n\tif ($m <= 0 || Math.abs($m) - Math.abs(integer($m)) != 0) {\n\t\tthrow \"Invalid m: $m\\n\"; /* second degree of freedom */\n\t}\n\treturn precision_string(_subfprob($n - 0, $m - 0, $x - 0));\n}\n\nfunction _subfprob($n, $m, $x) {\n\tvar $p;\n\n\tif ($x <= 0) {\n\t\t$p = 1;\n\t} else if ($m % 2 == 0) {\n\t\tvar $z = $m / ($m + $n * $x);\n\t\tvar $a = 1;\n\t\tfor (var $i = $m - 2; $i >= 2; $i -= 2) {\n\t\t\t$a = 1 + ($n + $i - 2) / $i * $z * $a;\n\t\t}\n\t\t$p = 1 - Math.pow(1 - $z, $n / 2 * $a);\n\t} else if ($n % 2 == 0) {\n\t\tvar $z = $n * $x / ($m + $n * $x);\n\t\tvar $a = 1;\n\t\tfor (var $i = $n - 2; $i >= 2; $i -= 2) {\n\t\t\t$a = 1 + ($m + $i - 2) / $i * $z * $a;\n\t\t}\n\t\t$p = Math.pow(1 - $z, $m / 2) * $a;\n\t} else {\n\t\tvar $y = Math.atan2(Math.sqrt($n * $x / $m), 1);\n\t\tvar $z = Math.pow(Math.sin($y), 2);\n\t\tvar $a = $n == 1 ? 0 : 1;\n\t\tfor (var $i = $n - 2; $i >= 3; $i -= 2) {\n\t\t\t$a = 1 + ($m + $i - 2) / $i * $z * $a;\n\t\t}\n\t\tvar $b = Math.PI;\n\t\tfor (var $i = 2; $i <= $m - 1; $i += 2) {\n\t\t\t$b *= ($i - 1) / $i;\n\t\t}\n\t\tvar $p1 = 2 / $b * Math.sin($y) * Math.pow(Math.cos($y), $m) * $a;\n\n\t\t$z = Math.pow(Math.cos($y), 2);\n\t\t$a = $m == 1 ? 0 : 1;\n\t\tfor (var $i = $m - 2; $i >= 3; $i -= 2) {\n\t\t\t$a = 1 + ($i - 1) / $i * $z * $a;\n\t\t}\n\t\t$p = max(0, $p1 + 1 - 2 * $y / Math.PI - 2 / Math.PI * Math.sin($y) * Math.cos($y) * $a);\n\t}\n\treturn $p;\n}\n\nfunction _subchisqrprob($n, $x) {\n\tvar $p;\n\n\tif ($x <= 0) {\n\t\t$p = 1;\n\t} else if ($n > 100) {\n\t\t$p = _subuprob((Math.pow($x / $n, 1 / 3) - (1 - 2 / 9 / $n)) / Math.sqrt(2 / 9 / $n));\n\t} else if ($x > 400) {\n\t\t$p = 0;\n\t} else {\n\t\tvar $a;\n\t\tvar $i;\n\t\tvar $i1;\n\t\tif ($n % 2 != 0) {\n\t\t\t$p = 2 * _subuprob(Math.sqrt($x));\n\t\t\t$a = Math.sqrt(2 / Math.PI) * Math.exp(-$x / 2) / Math.sqrt($x);\n\t\t\t$i1 = 1;\n\t\t} else {\n\t\t\t$p = $a = Math.exp(-$x / 2);\n\t\t\t$i1 = 2;\n\t\t}\n\n\t\tfor ($i = $i1; $i <= $n - 2; $i += 2) {\n\t\t\t$a *= $x / $i;\n\t\t\t$p += $a;\n\t\t}\n\t}\n\treturn $p;\n}\n\nfunction _subu($p) {\n\tvar $y = -Math.log(4 * $p * (1 - $p));\n\tvar $x = Math.sqrt($y * (1.570796288 + $y * (.03706987906 + $y * (-.8364353589E-3 + $y * (-.2250947176E-3 + $y * (.6841218299E-5 + $y * (0.5824238515E-5 + $y * (-.104527497E-5 + $y * (.8360937017E-7 + $y * (-.3231081277E-8 + $y * (.3657763036E-10 + $y * .6936233982E-12)))))))))));\n\tif ($p > .5) $x = -$x;\n\treturn $x;\n}\n\nfunction _subuprob($x) {\n\tvar $p = 0; /* if ($absx > 100) */\n\tvar $absx = Math.abs($x);\n\n\tif ($absx < 1.9) {\n\t\t$p = Math.pow(1 + $absx * (.049867347 + $absx * (.0211410061 + $absx * (.0032776263 + $absx * (.0000380036 + $absx * (.0000488906 + $absx * .000005383))))), -16) / 2;\n\t} else if ($absx <= 100) {\n\t\tfor (var $i = 18; $i >= 1; $i--) {\n\t\t\t$p = $i / ($absx + $p);\n\t\t}\n\t\t$p = Math.exp(-.5 * $absx * $absx) / Math.sqrt(2 * Math.PI) / ($absx + $p);\n\t}\n\n\tif ($x < 0) $p = 1 - $p;\n\treturn $p;\n}\n\nfunction _subt($n, $p) {\n\n\tif ($p >= 1 || $p <= 0) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\n\tif ($p == 0.5) {\n\t\treturn 0;\n\t} else if ($p < 0.5) {\n\t\treturn -_subt($n, 1 - $p);\n\t}\n\n\tvar $u = _subu($p);\n\tvar $u2 = Math.pow($u, 2);\n\n\tvar $a = ($u2 + 1) / 4;\n\tvar $b = ((5 * $u2 + 16) * $u2 + 3) / 96;\n\tvar $c = (((3 * $u2 + 19) * $u2 + 17) * $u2 - 15) / 384;\n\tvar $d = ((((79 * $u2 + 776) * $u2 + 1482) * $u2 - 1920) * $u2 - 945) / 92160;\n\tvar $e = (((((27 * $u2 + 339) * $u2 + 930) * $u2 - 1782) * $u2 - 765) * $u2 + 17955) / 368640;\n\n\tvar $x = $u * (1 + ($a + ($b + ($c + ($d + $e / $n) / $n) / $n) / $n) / $n);\n\n\tif ($n <= Math.pow(log10($p), 2) + 3) {\n\t\tvar $round;\n\t\tdo {\n\t\t\tvar $p1 = _subtprob($n, $x);\n\t\t\tvar $n1 = $n + 1;\n\t\t\tvar $delta = ($p1 - $p) / Math.exp(($n1 * Math.log($n1 / ($n + $x * $x)) + Math.log($n / $n1 / 2 / Math.PI) - 1 + (1 / $n1 - 1 / $n) / 6) / 2);\n\t\t\t$x += $delta;\n\t\t\t$round = round_to_precision($delta, Math.abs(integer(log10(Math.abs($x)) - 4)));\n\t\t} while ($x && $round != 0);\n\t}\n\treturn $x;\n}\n\nfunction _subtprob($n, $x) {\n\n\tvar $a;\n\tvar $b;\n\tvar $w = Math.atan2($x / Math.sqrt($n), 1);\n\tvar $z = Math.pow(Math.cos($w), 2);\n\tvar $y = 1;\n\n\tfor (var $i = $n - 2; $i >= 2; $i -= 2) {\n\t\t$y = 1 + ($i - 1) / $i * $z * $y;\n\t}\n\n\tif ($n % 2 == 0) {\n\t\t$a = Math.sin($w) / 2;\n\t\t$b = .5;\n\t} else {\n\t\t$a = $n == 1 ? 0 : Math.sin($w) * Math.cos($w) / Math.PI;\n\t\t$b = .5 + $w / Math.PI;\n\t}\n\treturn max(0, 1 - $b - $a * $y);\n}\n\nfunction _subf($n, $m, $p) {\n\tvar $x;\n\n\tif ($p >= 1 || $p <= 0) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t}\n\n\tif ($p == 1) {\n\t\t$x = 0;\n\t} else if ($m == 1) {\n\t\t$x = 1 / Math.pow(_subt($n, 0.5 - $p / 2), 2);\n\t} else if ($n == 1) {\n\t\t$x = Math.pow(_subt($m, $p / 2), 2);\n\t} else if ($m == 2) {\n\t\tvar $u = _subchisqr($m, 1 - $p);\n\t\tvar $a = $m - 2;\n\t\t$x = 1 / ($u / $m * (1 + (($u - $a) / 2 + (((4 * $u - 11 * $a) * $u + $a * (7 * $m - 10)) / 24 + (((2 * $u - 10 * $a) * $u + $a * (17 * $m - 26)) * $u - $a * $a * (9 * $m - 6)) / 48 / $n) / $n) / $n));\n\t} else if ($n > $m) {\n\t\t$x = 1 / _subf2($m, $n, 1 - $p);\n\t} else {\n\t\t$x = _subf2($n, $m, $p);\n\t}\n\treturn $x;\n}\n\nfunction _subf2($n, $m, $p) {\n\tvar $u = _subchisqr($n, $p);\n\tvar $n2 = $n - 2;\n\tvar $x = $u / $n * (1 + (($u - $n2) / 2 + (((4 * $u - 11 * $n2) * $u + $n2 * (7 * $n - 10)) / 24 + (((2 * $u - 10 * $n2) * $u + $n2 * (17 * $n - 26)) * $u - $n2 * $n2 * (9 * $n - 6)) / 48 / $m) / $m) / $m);\n\tvar $delta;\n\tdo {\n\t\tvar $z = Math.exp((($n + $m) * Math.log(($n + $m) / ($n * $x + $m)) + ($n - 2) * Math.log($x) + Math.log($n * $m / ($n + $m)) - Math.log(4 * Math.PI) - (1 / $n + 1 / $m - 1 / ($n + $m)) / 6) / 2);\n\t\t$delta = (_subfprob($n, $m, $x) - $p) / $z;\n\t\t$x += $delta;\n\t} while (Math.abs($delta) > 3e-4);\n\treturn $x;\n}\n\nfunction _subchisqr($n, $p) {\n\tvar $x;\n\n\tif ($p > 1 || $p <= 0) {\n\t\tthrow \"Invalid p: $p\\n\";\n\t} else if ($p == 1) {\n\t\t$x = 0;\n\t} else if ($n == 1) {\n\t\t$x = Math.pow(_subu($p / 2), 2);\n\t} else if ($n == 2) {\n\t\t$x = -2 * Math.log($p);\n\t} else {\n\t\tvar $u = _subu($p);\n\t\tvar $u2 = $u * $u;\n\n\t\t$x = max(0, $n + Math.sqrt(2 * $n) * $u + 2 / 3 * ($u2 - 1) + $u * ($u2 - 7) / 9 / Math.sqrt(2 * $n) - 2 / 405 / $n * ($u2 * (3 * $u2 + 7) - 16));\n\n\t\tif ($n <= 100) {\n\t\t\tvar $x0;\n\t\t\tvar $p1;\n\t\t\tvar $z;\n\t\t\tdo {\n\t\t\t\t$x0 = $x;\n\t\t\t\tif ($x < 0) {\n\t\t\t\t\t$p1 = 1;\n\t\t\t\t} else if ($n > 100) {\n\t\t\t\t\t$p1 = _subuprob((Math.pow($x / $n, 1 / 3) - (1 - 2 / 9 / $n)) / Math.sqrt(2 / 9 / $n));\n\t\t\t\t} else if ($x > 400) {\n\t\t\t\t\t$p1 = 0;\n\t\t\t\t} else {\n\t\t\t\t\tvar $i0;\n\t\t\t\t\tvar $a;\n\t\t\t\t\tif ($n % 2 != 0) {\n\t\t\t\t\t\t$p1 = 2 * _subuprob(Math.sqrt($x));\n\t\t\t\t\t\t$a = Math.sqrt(2 / Math.PI) * Math.exp(-$x / 2) / Math.sqrt($x);\n\t\t\t\t\t\t$i0 = 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$p1 = $a = Math.exp(-$x / 2);\n\t\t\t\t\t\t$i0 = 2;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (var $i = $i0; $i <= $n - 2; $i += 2) {\n\t\t\t\t\t\t$a *= $x / $i;\n\t\t\t\t\t\t$p1 += $a;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$z = Math.exp((($n - 1) * Math.log($x / $n) - Math.log(4 * Math.PI * $x) + $n - $x - 1 / $n / 6) / 2);\n\t\t\t\t$x += ($p1 - $p) / $z;\n\t\t\t\t$x = round_to_precision($x, 5);\n\t\t\t} while ($n < 31 && Math.abs($x0 - $x) > 1e-4);\n\t\t}\n\t}\n\treturn $x;\n}\n\nfunction log10($n) {\n\treturn Math.log($n) / Math.log(10);\n}\n\nfunction max() {\n\tvar $max = arguments[0];\n\tfor (var $i = 0; i < arguments.length; i++) {\n\t\tif ($max < arguments[$i]) $max = arguments[$i];\n\t}\n\treturn $max;\n}\n\nfunction min() {\n\tvar $min = arguments[0];\n\tfor (var $i = 0; i < arguments.length; i++) {\n\t\tif ($min > arguments[$i]) $min = arguments[$i];\n\t}\n\treturn $min;\n}\n\nfunction precision($x) {\n\treturn Math.abs(integer(log10(Math.abs($x)) - SIGNIFICANT));\n}\n\nfunction precision_string($x) {\n\tif ($x) {\n\t\treturn round_to_precision($x, precision($x));\n\t} else {\n\t\treturn \"0\";\n\t}\n}\n\nfunction round_to_precision($x, $p) {\n\t$x = $x * Math.pow(10, $p);\n\t$x = Math.round($x);\n\treturn $x / Math.pow(10, $p);\n}\n\nfunction integer($i) {\n\tif ($i > 0) return Math.floor($i);else return Math.ceil($i);\n}\n\n},{}],32:[function(require,module,exports){\n'use strict';\n\nvar _statisticsDistributions = require('./statistics-distributions');\n\nvar su = module.exports.StatisticsUtils = {};\nsu.sampleCorrelation = require('../bower_components/simple-statistics/src/sample_correlation');\nsu.linearRegression = require('../bower_components/simple-statistics/src/linear_regression');\nsu.linearRegressionLine = require('../bower_components/simple-statistics/src/linear_regression_line');\nsu.errorFunction = require('../bower_components/simple-statistics/src/error_function');\nsu.standardDeviation = require('../bower_components/simple-statistics/src/standard_deviation');\nsu.sampleStandardDeviation = require('../bower_components/simple-statistics/src/sample_standard_deviation');\nsu.variance = require('../bower_components/simple-statistics/src/variance');\nsu.mean = require('../bower_components/simple-statistics/src/mean');\nsu.zScore = require('../bower_components/simple-statistics/src/z_score');\nsu.standardError = function (arr) {\n return Math.sqrt(su.variance(arr) / (arr.length - 1));\n};\n\nsu.tValue = function (degreesOfFreedom, criticalProbability) {\n //as in http://stattrek.com/online-calculator/t-distribution.aspx\n return (0, _statisticsDistributions.tdistr)(degreesOfFreedom, criticalProbability);\n};\n\n},{\"../bower_components/simple-statistics/src/error_function\":6,\"../bower_components/simple-statistics/src/linear_regression\":7,\"../bower_components/simple-statistics/src/linear_regression_line\":8,\"../bower_components/simple-statistics/src/mean\":9,\"../bower_components/simple-statistics/src/sample_correlation\":10,\"../bower_components/simple-statistics/src/sample_standard_deviation\":12,\"../bower_components/simple-statistics/src/standard_deviation\":14,\"../bower_components/simple-statistics/src/variance\":17,\"../bower_components/simple-statistics/src/z_score\":18,\"./statistics-distributions\":31}],33:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\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\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Utils = exports.Utils = function () {\n function Utils() {\n _classCallCheck(this, Utils);\n }\n\n _createClass(Utils, null, [{\n key: 'deepExtend',\n\n // usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB);\n value: function deepExtend(out) {\n\n var utils = this;\n var emptyOut = {};\n\n if (!out && arguments.length > 1 && Array.isArray(arguments[1])) {\n out = [];\n }\n out = out || {};\n\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n if (!source) continue;\n\n for (var key in source) {\n if (!source.hasOwnProperty(key)) {\n continue;\n }\n var isArray = Array.isArray(out[key]);\n var isObject = utils.isObject(out[key]);\n var srcObj = utils.isObject(source[key]);\n\n if (isObject && !isArray && srcObj) {\n utils.deepExtend(out[key], source[key]);\n } else {\n out[key] = source[key];\n }\n }\n }\n\n return out;\n }\n }, {\n key: 'mergeDeep',\n value: function mergeDeep(target, source) {\n var output = Object.assign({}, target);\n if (Utils.isObjectNotArray(target) && Utils.isObjectNotArray(source)) {\n Object.keys(source).forEach(function (key) {\n if (Utils.isObjectNotArray(source[key])) {\n if (!(key in target)) Object.assign(output, _defineProperty({}, key, source[key]));else output[key] = Utils.mergeDeep(target[key], source[key]);\n } else {\n Object.assign(output, _defineProperty({}, key, source[key]));\n }\n });\n }\n return output;\n }\n }, {\n key: 'cross',\n value: function cross(a, b) {\n var c = [],\n n = a.length,\n m = b.length,\n i,\n j;\n for (i = -1; ++i < n;) {\n for (j = -1; ++j < m;) {\n c.push({ x: a[i], i: i, y: b[j], j: j });\n }\n }return c;\n }\n }, {\n key: 'inferVariables',\n value: function inferVariables(data, groupKey, includeGroup) {\n var res = [];\n if (data.length) {\n var d = data[0];\n if (d instanceof Array) {\n res = d.map(function (v, i) {\n return i;\n });\n } else if ((typeof d === 'undefined' ? 'undefined' : _typeof(d)) === 'object') {\n\n for (var prop in d) {\n if (!d.hasOwnProperty(prop)) continue;\n\n res.push(prop);\n }\n }\n }\n if (!includeGroup) {\n var index = res.indexOf(groupKey);\n if (index > -1) {\n res.splice(index, 1);\n }\n }\n return res;\n }\n }, {\n key: 'isObjectNotArray',\n value: function isObjectNotArray(item) {\n return item && (typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object' && !Array.isArray(item) && item !== null;\n }\n }, {\n key: 'isObject',\n value: function isObject(a) {\n return a !== null && (typeof a === 'undefined' ? 'undefined' : _typeof(a)) === 'object';\n }\n }, {\n key: 'isNumber',\n value: function isNumber(a) {\n return !isNaN(a) && typeof a === 'number';\n }\n }, {\n key: 'isFunction',\n value: function isFunction(a) {\n return typeof a === 'function';\n }\n }, {\n key: 'isDate',\n value: function isDate(a) {\n return Object.prototype.toString.call(a) === '[object Date]';\n }\n }, {\n key: 'isString',\n value: function isString(a) {\n return typeof a === 'string' || a instanceof String;\n }\n }, {\n key: 'insertOrAppendSelector',\n value: function insertOrAppendSelector(parent, selector, operation, before) {\n var selectorParts = selector.split(/([\\.\\#])/);\n var element = parent[operation](selectorParts.shift(), before); //\":first-child\"\n while (selectorParts.length > 1) {\n var selectorModifier = selectorParts.shift();\n var selectorItem = selectorParts.shift();\n if (selectorModifier === \".\") {\n element = element.classed(selectorItem, true);\n } else if (selectorModifier === \"#\") {\n element = element.attr('id', selectorItem);\n }\n }\n return element;\n }\n }, {\n key: 'insertSelector',\n value: function insertSelector(parent, selector, before) {\n return Utils.insertOrAppendSelector(parent, selector, \"insert\", before);\n }\n }, {\n key: 'appendSelector',\n value: function appendSelector(parent, selector) {\n return Utils.insertOrAppendSelector(parent, selector, \"append\");\n }\n }, {\n key: 'selectOrAppend',\n value: function selectOrAppend(parent, selector, element) {\n var selection = parent.select(selector);\n if (selection.empty()) {\n if (element) {\n return parent.append(element);\n }\n return Utils.appendSelector(parent, selector);\n }\n return selection;\n }\n }, {\n key: 'selectOrInsert',\n value: function selectOrInsert(parent, selector, before) {\n var selection = parent.select(selector);\n if (selection.empty()) {\n return Utils.insertSelector(parent, selector, before);\n }\n return selection;\n }\n }, {\n key: 'linearGradient',\n value: function linearGradient(svg, gradientId, range, x1, y1, x2, y2) {\n var defs = Utils.selectOrAppend(svg, \"defs\");\n var linearGradient = defs.append(\"linearGradient\").attr(\"id\", gradientId);\n\n linearGradient.attr(\"x1\", x1 + \"%\").attr(\"y1\", y1 + \"%\").attr(\"x2\", x2 + \"%\").attr(\"y2\", y2 + \"%\");\n\n //Append multiple color stops by using D3's data/enter step\n var stops = linearGradient.selectAll(\"stop\").data(range);\n\n stops.enter().append(\"stop\");\n\n stops.attr(\"offset\", function (d, i) {\n return i / (range.length - 1);\n }).attr(\"stop-color\", function (d) {\n return d;\n });\n\n stops.exit().remove();\n }\n }, {\n key: 'guid',\n value: function guid() {\n function s4() {\n return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);\n }\n\n return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\n }\n\n //places textString in textObj, adds an ellipsis if text can't fit in width\n\n }, {\n key: 'placeTextWithEllipsis',\n value: function placeTextWithEllipsis(textD3Obj, textString, width) {\n var textObj = textD3Obj.node();\n textObj.textContent = textString;\n\n var margin = 0;\n var ellipsisLength = 9;\n //ellipsis is needed\n if (textObj.getComputedTextLength() > width + margin) {\n for (var x = textString.length - 3; x > 0; x -= 1) {\n if (textObj.getSubStringLength(0, x) + ellipsisLength <= width + margin) {\n textObj.textContent = textString.substring(0, x) + \"...\";\n return true;\n }\n }\n textObj.textContent = \"...\"; //can't place at all\n return true;\n }\n return false;\n }\n }, {\n key: 'placeTextWithEllipsisAndTooltip',\n value: function placeTextWithEllipsisAndTooltip(textD3Obj, textString, width, tooltip) {\n var ellipsisPlaced = Utils.placeTextWithEllipsis(textD3Obj, textString, width);\n if (ellipsisPlaced && tooltip) {\n textD3Obj.on(\"mouseover\", function (d) {\n tooltip.transition().duration(200).style(\"opacity\", .9);\n tooltip.html(textString).style(\"left\", d3.event.pageX + 5 + \"px\").style(\"top\", d3.event.pageY - 28 + \"px\");\n });\n\n textD3Obj.on(\"mouseout\", function (d) {\n tooltip.transition().duration(500).style(\"opacity\", 0);\n });\n }\n }\n }, {\n key: 'getFontSize',\n value: function getFontSize(element) {\n return window.getComputedStyle(element, null).getPropertyValue(\"font-size\");\n }\n }]);\n\n return Utils;\n}();\n\nUtils.SQRT_2 = 1.41421356237;\n\nUtils.sanitizeHeight = function (height, container) {\n return height || parseInt(container.style('height'), 10) || 400;\n};\n\nUtils.sanitizeWidth = function (width, container) {\n return width || parseInt(container.style('width'), 10) || 960;\n};\n\nUtils.availableHeight = function (height, container, margin) {\n return Math.max(0, Utils.sanitizeHeight(height, container) - margin.top - margin.bottom);\n};\n\nUtils.availableWidth = function (width, container, margin) {\n return Math.max(0, Utils.sanitizeWidth(width, container) - margin.left - margin.right);\n};\n\n},{}]},{},[26])(26)\n});\n\n","module.exports = {\r\n color: require('./src/color'),\r\n size: require('./src/size'),\r\n symbol: require('./src/symbol')\r\n};\r\n","var helper = require('./legend');\r\n\r\nmodule.exports = function(){\r\n\r\n var scale = d3.scale.linear(),\r\n shape = \"rect\",\r\n shapeWidth = 15,\r\n shapeHeight = 15,\r\n shapeRadius = 10,\r\n shapePadding = 2,\r\n cells = [5],\r\n labels = [],\r\n classPrefix = \"\",\r\n useClass = false,\r\n title = \"\",\r\n labelFormat = d3.format(\".01f\"),\r\n labelOffset = 10,\r\n labelAlign = \"middle\",\r\n labelDelimiter = \"to\",\r\n orient = \"vertical\",\r\n ascending = false,\r\n path,\r\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\r\n\r\n function legend(svg){\r\n\r\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\r\n legendG = svg.selectAll('g').data([scale]);\r\n\r\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\r\n\r\n\r\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\r\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\r\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\r\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\r\n\r\n //add event handlers\r\n helper.d3_addEvents(cellEnter, legendDispatcher);\r\n\r\n cell.exit().transition().style(\"opacity\", 0).remove();\r\n\r\n helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path);\r\n\r\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix)\r\n\r\n // sets placement\r\n var text = cell.select(\"text\"),\r\n shapeSize = shapes[0].map( function(d){ return d.getBBox(); });\r\n\r\n //sets scale\r\n //everything is fill except for line which is stroke,\r\n if (!useClass){\r\n if (shape == \"line\"){\r\n shapes.style(\"stroke\", type.feature);\r\n } else {\r\n shapes.style(\"fill\", type.feature);\r\n }\r\n } else {\r\n shapes.attr(\"class\", function(d){ return classPrefix + \"swatch \" + type.feature(d); });\r\n }\r\n\r\n var cellTrans,\r\n textTrans,\r\n textAlign = (labelAlign == \"start\") ? 0 : (labelAlign == \"middle\") ? 0.5 : 1;\r\n\r\n //positions cells and text\r\n if (orient === \"vertical\"){\r\n cellTrans = function(d,i) { return \"translate(0, \" + (i * (shapeSize[i].height + shapePadding)) + \")\"; };\r\n textTrans = function(d,i) { return \"translate(\" + (shapeSize[i].width + shapeSize[i].x +\r\n labelOffset) + \",\" + (shapeSize[i].y + shapeSize[i].height/2 + 5) + \")\"; };\r\n\r\n } else if (orient === \"horizontal\"){\r\n cellTrans = function(d,i) { return \"translate(\" + (i * (shapeSize[i].width + shapePadding)) + \",0)\"; }\r\n textTrans = function(d,i) { return \"translate(\" + (shapeSize[i].width*textAlign + shapeSize[i].x) +\r\n \",\" + (shapeSize[i].height + shapeSize[i].y + labelOffset + 8) + \")\"; };\r\n }\r\n\r\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\r\n helper.d3_title(svg, legendG, title, classPrefix);\r\n\r\n cell.transition().style(\"opacity\", 1);\r\n\r\n }\r\n\r\n\r\n\r\n legend.scale = function(_) {\r\n if (!arguments.length) return scale;\r\n scale = _;\r\n return legend;\r\n };\r\n\r\n legend.cells = function(_) {\r\n if (!arguments.length) return cells;\r\n if (_.length > 1 || _ >= 2 ){\r\n cells = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.shape = function(_, d) {\r\n if (!arguments.length) return shape;\r\n if (_ == \"rect\" || _ == \"circle\" || _ == \"line\" || (_ == \"path\" && (typeof d === 'string')) ){\r\n shape = _;\r\n path = d;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.shapeWidth = function(_) {\r\n if (!arguments.length) return shapeWidth;\r\n shapeWidth = +_;\r\n return legend;\r\n };\r\n\r\n legend.shapeHeight = function(_) {\r\n if (!arguments.length) return shapeHeight;\r\n shapeHeight = +_;\r\n return legend;\r\n };\r\n\r\n legend.shapeRadius = function(_) {\r\n if (!arguments.length) return shapeRadius;\r\n shapeRadius = +_;\r\n return legend;\r\n };\r\n\r\n legend.shapePadding = function(_) {\r\n if (!arguments.length) return shapePadding;\r\n shapePadding = +_;\r\n return legend;\r\n };\r\n\r\n legend.labels = function(_) {\r\n if (!arguments.length) return labels;\r\n labels = _;\r\n return legend;\r\n };\r\n\r\n legend.labelAlign = function(_) {\r\n if (!arguments.length) return labelAlign;\r\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\r\n labelAlign = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.labelFormat = function(_) {\r\n if (!arguments.length) return labelFormat;\r\n labelFormat = _;\r\n return legend;\r\n };\r\n\r\n legend.labelOffset = function(_) {\r\n if (!arguments.length) return labelOffset;\r\n labelOffset = +_;\r\n return legend;\r\n };\r\n\r\n legend.labelDelimiter = function(_) {\r\n if (!arguments.length) return labelDelimiter;\r\n labelDelimiter = _;\r\n return legend;\r\n };\r\n\r\n legend.useClass = function(_) {\r\n if (!arguments.length) return useClass;\r\n if (_ === true || _ === false){\r\n useClass = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.orient = function(_){\r\n if (!arguments.length) return orient;\r\n _ = _.toLowerCase();\r\n if (_ == \"horizontal\" || _ == \"vertical\") {\r\n orient = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.ascending = function(_) {\r\n if (!arguments.length) return ascending;\r\n ascending = !!_;\r\n return legend;\r\n };\r\n\r\n legend.classPrefix = function(_) {\r\n if (!arguments.length) return classPrefix;\r\n classPrefix = _;\r\n return legend;\r\n };\r\n\r\n legend.title = function(_) {\r\n if (!arguments.length) return title;\r\n title = _;\r\n return legend;\r\n };\r\n\r\n d3.rebind(legend, legendDispatcher, \"on\");\r\n\r\n return legend;\r\n\r\n};\r\n","module.exports = {\r\n\r\n d3_identity: function (d) {\r\n return d;\r\n },\r\n\r\n d3_mergeLabels: function (gen, labels) {\r\n\r\n if(labels.length === 0) return gen;\r\n\r\n gen = (gen) ? gen : [];\r\n\r\n var i = labels.length;\r\n for (; i < gen.length; i++) {\r\n labels.push(gen[i]);\r\n }\r\n return labels;\r\n },\r\n\r\n d3_linearLegend: function (scale, cells, labelFormat) {\r\n var data = [];\r\n\r\n if (cells.length > 1){\r\n data = cells;\r\n\r\n } else {\r\n var domain = scale.domain(),\r\n increment = (domain[domain.length - 1] - domain[0])/(cells - 1),\r\n i = 0;\r\n\r\n for (; i < cells; i++){\r\n data.push(domain[0] + i*increment);\r\n }\r\n }\r\n\r\n var labels = data.map(labelFormat);\r\n\r\n return {data: data,\r\n labels: labels,\r\n feature: function(d){ return scale(d); }};\r\n },\r\n\r\n d3_quantLegend: function (scale, labelFormat, labelDelimiter) {\r\n var labels = scale.range().map(function(d){\r\n var invert = scale.invertExtent(d),\r\n a = labelFormat(invert[0]),\r\n b = labelFormat(invert[1]);\r\n\r\n // if (( (a) && (a.isNan()) && b){\r\n // console.log(\"in initial statement\")\r\n return labelFormat(invert[0]) + \" \" + labelDelimiter + \" \" + labelFormat(invert[1]);\r\n // } else if (a || b) {\r\n // console.log('in else statement')\r\n // return (a) ? a : b;\r\n // }\r\n\r\n });\r\n\r\n return {data: scale.range(),\r\n labels: labels,\r\n feature: this.d3_identity\r\n };\r\n },\r\n\r\n d3_ordinalLegend: function (scale) {\r\n return {data: scale.domain(),\r\n labels: scale.domain(),\r\n feature: function(d){ return scale(d); }};\r\n },\r\n\r\n d3_drawShapes: function (shape, shapes, shapeHeight, shapeWidth, shapeRadius, path) {\r\n if (shape === \"rect\"){\r\n shapes.attr(\"height\", shapeHeight).attr(\"width\", shapeWidth);\r\n\r\n } else if (shape === \"circle\") {\r\n shapes.attr(\"r\", shapeRadius)//.attr(\"cx\", shapeRadius).attr(\"cy\", shapeRadius);\r\n\r\n } else if (shape === \"line\") {\r\n shapes.attr(\"x1\", 0).attr(\"x2\", shapeWidth).attr(\"y1\", 0).attr(\"y2\", 0);\r\n\r\n } else if (shape === \"path\") {\r\n shapes.attr(\"d\", path);\r\n }\r\n },\r\n\r\n d3_addText: function (svg, enter, labels, classPrefix){\r\n enter.append(\"text\").attr(\"class\", classPrefix + \"label\");\r\n svg.selectAll(\"g.\" + classPrefix + \"cell text\").data(labels).text(this.d3_identity);\r\n },\r\n\r\n d3_calcType: function (scale, ascending, cells, labels, labelFormat, labelDelimiter){\r\n var type = scale.ticks ?\r\n this.d3_linearLegend(scale, cells, labelFormat) : scale.invertExtent ?\r\n this.d3_quantLegend(scale, labelFormat, labelDelimiter) : this.d3_ordinalLegend(scale);\r\n\r\n type.labels = this.d3_mergeLabels(type.labels, labels);\r\n\r\n if (ascending) {\r\n type.labels = this.d3_reverse(type.labels);\r\n type.data = this.d3_reverse(type.data);\r\n }\r\n\r\n return type;\r\n },\r\n\r\n d3_reverse: function(arr) {\r\n var mirror = [];\r\n for (var i = 0, l = arr.length; i < l; i++) {\r\n mirror[i] = arr[l-i-1];\r\n }\r\n return mirror;\r\n },\r\n\r\n d3_placement: function (orient, cell, cellTrans, text, textTrans, labelAlign) {\r\n cell.attr(\"transform\", cellTrans);\r\n text.attr(\"transform\", textTrans);\r\n if (orient === \"horizontal\"){\r\n text.style(\"text-anchor\", labelAlign);\r\n }\r\n },\r\n\r\n d3_addEvents: function(cells, dispatcher){\r\n var _ = this;\r\n\r\n cells.on(\"mouseover.legend\", function (d) { _.d3_cellOver(dispatcher, d, this); })\r\n .on(\"mouseout.legend\", function (d) { _.d3_cellOut(dispatcher, d, this); })\r\n .on(\"click.legend\", function (d) { _.d3_cellClick(dispatcher, d, this); });\r\n },\r\n\r\n d3_cellOver: function(cellDispatcher, d, obj){\r\n cellDispatcher.cellover.call(obj, d);\r\n },\r\n\r\n d3_cellOut: function(cellDispatcher, d, obj){\r\n cellDispatcher.cellout.call(obj, d);\r\n },\r\n\r\n d3_cellClick: function(cellDispatcher, d, obj){\r\n cellDispatcher.cellclick.call(obj, d);\r\n },\r\n\r\n d3_title: function(svg, cellsSvg, title, classPrefix){\r\n if (title !== \"\"){\r\n\r\n var titleText = svg.selectAll('text.' + classPrefix + 'legendTitle');\r\n\r\n titleText.data([title])\r\n .enter()\r\n .append('text')\r\n .attr('class', classPrefix + 'legendTitle');\r\n\r\n svg.selectAll('text.' + classPrefix + 'legendTitle')\r\n .text(title)\r\n\r\n var yOffset = svg.select('.' + classPrefix + 'legendTitle')\r\n .map(function(d) { return d[0].getBBox().height})[0],\r\n xOffset = -cellsSvg.map(function(d) { return d[0].getBBox().x})[0];\r\n\r\n cellsSvg.attr('transform', 'translate(' + xOffset + ',' + (yOffset + 10) + ')');\r\n\r\n }\r\n }\r\n}\r\n","var helper = require('./legend');\r\n\r\nmodule.exports = function(){\r\n\r\n var scale = d3.scale.linear(),\r\n shape = \"rect\",\r\n shapeWidth = 15,\r\n shapePadding = 2,\r\n cells = [5],\r\n labels = [],\r\n useStroke = false,\r\n classPrefix = \"\",\r\n title = \"\",\r\n labelFormat = d3.format(\".01f\"),\r\n labelOffset = 10,\r\n labelAlign = \"middle\",\r\n labelDelimiter = \"to\",\r\n orient = \"vertical\",\r\n ascending = false,\r\n path,\r\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\r\n\r\n function legend(svg){\r\n\r\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\r\n legendG = svg.selectAll('g').data([scale]);\r\n\r\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\r\n\r\n\r\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\r\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\r\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\r\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\r\n\r\n //add event handlers\r\n helper.d3_addEvents(cellEnter, legendDispatcher);\r\n\r\n cell.exit().transition().style(\"opacity\", 0).remove();\r\n\r\n //creates shape\r\n if (shape === \"line\"){\r\n helper.d3_drawShapes(shape, shapes, 0, shapeWidth);\r\n shapes.attr(\"stroke-width\", type.feature);\r\n } else {\r\n helper.d3_drawShapes(shape, shapes, type.feature, type.feature, type.feature, path);\r\n }\r\n\r\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix)\r\n\r\n //sets placement\r\n var text = cell.select(\"text\"),\r\n shapeSize = shapes[0].map(\r\n function(d, i){\r\n var bbox = d.getBBox()\r\n var stroke = scale(type.data[i]);\r\n\r\n if (shape === \"line\" && orient === \"horizontal\") {\r\n bbox.height = bbox.height + stroke;\r\n } else if (shape === \"line\" && orient === \"vertical\"){\r\n bbox.width = bbox.width;\r\n }\r\n\r\n return bbox;\r\n });\r\n\r\n var maxH = d3.max(shapeSize, function(d){ return d.height + d.y; }),\r\n maxW = d3.max(shapeSize, function(d){ return d.width + d.x; });\r\n\r\n var cellTrans,\r\n textTrans,\r\n textAlign = (labelAlign == \"start\") ? 0 : (labelAlign == \"middle\") ? 0.5 : 1;\r\n\r\n //positions cells and text\r\n if (orient === \"vertical\"){\r\n\r\n cellTrans = function(d,i) {\r\n var height = d3.sum(shapeSize.slice(0, i + 1 ), function(d){ return d.height; });\r\n return \"translate(0, \" + (height + i*shapePadding) + \")\"; };\r\n\r\n textTrans = function(d,i) { return \"translate(\" + (maxW + labelOffset) + \",\" +\r\n (shapeSize[i].y + shapeSize[i].height/2 + 5) + \")\"; };\r\n\r\n } else if (orient === \"horizontal\"){\r\n cellTrans = function(d,i) {\r\n var width = d3.sum(shapeSize.slice(0, i + 1 ), function(d){ return d.width; });\r\n return \"translate(\" + (width + i*shapePadding) + \",0)\"; };\r\n\r\n textTrans = function(d,i) { return \"translate(\" + (shapeSize[i].width*textAlign + shapeSize[i].x) + \",\" +\r\n (maxH + labelOffset ) + \")\"; };\r\n }\r\n\r\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\r\n helper.d3_title(svg, legendG, title, classPrefix);\r\n\r\n cell.transition().style(\"opacity\", 1);\r\n\r\n }\r\n\r\n legend.scale = function(_) {\r\n if (!arguments.length) return scale;\r\n scale = _;\r\n return legend;\r\n };\r\n\r\n legend.cells = function(_) {\r\n if (!arguments.length) return cells;\r\n if (_.length > 1 || _ >= 2 ){\r\n cells = _;\r\n }\r\n return legend;\r\n };\r\n\r\n\r\n legend.shape = function(_, d) {\r\n if (!arguments.length) return shape;\r\n if (_ == \"rect\" || _ == \"circle\" || _ == \"line\" ){\r\n shape = _;\r\n path = d;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.shapeWidth = function(_) {\r\n if (!arguments.length) return shapeWidth;\r\n shapeWidth = +_;\r\n return legend;\r\n };\r\n\r\n legend.shapePadding = function(_) {\r\n if (!arguments.length) return shapePadding;\r\n shapePadding = +_;\r\n return legend;\r\n };\r\n\r\n legend.labels = function(_) {\r\n if (!arguments.length) return labels;\r\n labels = _;\r\n return legend;\r\n };\r\n\r\n legend.labelAlign = function(_) {\r\n if (!arguments.length) return labelAlign;\r\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\r\n labelAlign = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.labelFormat = function(_) {\r\n if (!arguments.length) return labelFormat;\r\n labelFormat = _;\r\n return legend;\r\n };\r\n\r\n legend.labelOffset = function(_) {\r\n if (!arguments.length) return labelOffset;\r\n labelOffset = +_;\r\n return legend;\r\n };\r\n\r\n legend.labelDelimiter = function(_) {\r\n if (!arguments.length) return labelDelimiter;\r\n labelDelimiter = _;\r\n return legend;\r\n };\r\n\r\n legend.orient = function(_){\r\n if (!arguments.length) return orient;\r\n _ = _.toLowerCase();\r\n if (_ == \"horizontal\" || _ == \"vertical\") {\r\n orient = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.ascending = function(_) {\r\n if (!arguments.length) return ascending;\r\n ascending = !!_;\r\n return legend;\r\n };\r\n\r\n legend.classPrefix = function(_) {\r\n if (!arguments.length) return classPrefix;\r\n classPrefix = _;\r\n return legend;\r\n };\r\n\r\n legend.title = function(_) {\r\n if (!arguments.length) return title;\r\n title = _;\r\n return legend;\r\n };\r\n\r\n d3.rebind(legend, legendDispatcher, \"on\");\r\n\r\n return legend;\r\n\r\n};\r\n","var helper = require('./legend');\r\n\r\nmodule.exports = function(){\r\n\r\n var scale = d3.scale.linear(),\r\n shape = \"path\",\r\n shapeWidth = 15,\r\n shapeHeight = 15,\r\n shapeRadius = 10,\r\n shapePadding = 5,\r\n cells = [5],\r\n labels = [],\r\n classPrefix = \"\",\r\n useClass = false,\r\n title = \"\",\r\n labelFormat = d3.format(\".01f\"),\r\n labelAlign = \"middle\",\r\n labelOffset = 10,\r\n labelDelimiter = \"to\",\r\n orient = \"vertical\",\r\n ascending = false,\r\n legendDispatcher = d3.dispatch(\"cellover\", \"cellout\", \"cellclick\");\r\n\r\n function legend(svg){\r\n\r\n var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter),\r\n legendG = svg.selectAll('g').data([scale]);\r\n\r\n legendG.enter().append('g').attr('class', classPrefix + 'legendCells');\r\n\r\n var cell = legendG.selectAll(\".\" + classPrefix + \"cell\").data(type.data),\r\n cellEnter = cell.enter().append(\"g\", \".cell\").attr(\"class\", classPrefix + \"cell\").style(\"opacity\", 1e-6),\r\n shapeEnter = cellEnter.append(shape).attr(\"class\", classPrefix + \"swatch\"),\r\n shapes = cell.select(\"g.\" + classPrefix + \"cell \" + shape);\r\n\r\n //add event handlers\r\n helper.d3_addEvents(cellEnter, legendDispatcher);\r\n\r\n //remove old shapes\r\n cell.exit().transition().style(\"opacity\", 0).remove();\r\n\r\n helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, type.feature);\r\n helper.d3_addText(legendG, cellEnter, type.labels, classPrefix)\r\n\r\n // sets placement\r\n var text = cell.select(\"text\"),\r\n shapeSize = shapes[0].map( function(d){ return d.getBBox(); });\r\n\r\n var maxH = d3.max(shapeSize, function(d){ return d.height; }),\r\n maxW = d3.max(shapeSize, function(d){ return d.width; });\r\n\r\n var cellTrans,\r\n textTrans,\r\n textAlign = (labelAlign == \"start\") ? 0 : (labelAlign == \"middle\") ? 0.5 : 1;\r\n\r\n //positions cells and text\r\n if (orient === \"vertical\"){\r\n cellTrans = function(d,i) { return \"translate(0, \" + (i * (maxH + shapePadding)) + \")\"; };\r\n textTrans = function(d,i) { return \"translate(\" + (maxW + labelOffset) + \",\" +\r\n (shapeSize[i].y + shapeSize[i].height/2 + 5) + \")\"; };\r\n\r\n } else if (orient === \"horizontal\"){\r\n cellTrans = function(d,i) { return \"translate(\" + (i * (maxW + shapePadding)) + \",0)\"; };\r\n textTrans = function(d,i) { return \"translate(\" + (shapeSize[i].width*textAlign + shapeSize[i].x) + \",\" +\r\n (maxH + labelOffset ) + \")\"; };\r\n }\r\n\r\n helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);\r\n helper.d3_title(svg, legendG, title, classPrefix);\r\n cell.transition().style(\"opacity\", 1);\r\n\r\n }\r\n\r\n\r\n legend.scale = function(_) {\r\n if (!arguments.length) return scale;\r\n scale = _;\r\n return legend;\r\n };\r\n\r\n legend.cells = function(_) {\r\n if (!arguments.length) return cells;\r\n if (_.length > 1 || _ >= 2 ){\r\n cells = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.shapePadding = function(_) {\r\n if (!arguments.length) return shapePadding;\r\n shapePadding = +_;\r\n return legend;\r\n };\r\n\r\n legend.labels = function(_) {\r\n if (!arguments.length) return labels;\r\n labels = _;\r\n return legend;\r\n };\r\n\r\n legend.labelAlign = function(_) {\r\n if (!arguments.length) return labelAlign;\r\n if (_ == \"start\" || _ == \"end\" || _ == \"middle\") {\r\n labelAlign = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.labelFormat = function(_) {\r\n if (!arguments.length) return labelFormat;\r\n labelFormat = _;\r\n return legend;\r\n };\r\n\r\n legend.labelOffset = function(_) {\r\n if (!arguments.length) return labelOffset;\r\n labelOffset = +_;\r\n return legend;\r\n };\r\n\r\n legend.labelDelimiter = function(_) {\r\n if (!arguments.length) return labelDelimiter;\r\n labelDelimiter = _;\r\n return legend;\r\n };\r\n\r\n legend.orient = function(_){\r\n if (!arguments.length) return orient;\r\n _ = _.toLowerCase();\r\n if (_ == \"horizontal\" || _ == \"vertical\") {\r\n orient = _;\r\n }\r\n return legend;\r\n };\r\n\r\n legend.ascending = function(_) {\r\n if (!arguments.length) return ascending;\r\n ascending = !!_;\r\n return legend;\r\n };\r\n\r\n legend.classPrefix = function(_) {\r\n if (!arguments.length) return classPrefix;\r\n classPrefix = _;\r\n return legend;\r\n };\r\n\r\n legend.title = function(_) {\r\n if (!arguments.length) return title;\r\n title = _;\r\n return legend;\r\n };\r\n\r\n d3.rebind(legend, legendDispatcher, \"on\");\r\n\r\n return legend;\r\n\r\n};\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * **[Gaussian error function](http://en.wikipedia.org/wiki/Error_function)**\r\n *\r\n * The `errorFunction(x/(sd * Math.sqrt(2)))` is the probability that a value in a\r\n * normal distribution with standard deviation sd is within x of the mean.\r\n *\r\n * This function returns a numerical approximation to the exact value.\r\n *\r\n * @param {number} x input\r\n * @return {number} error estimation\r\n * @example\r\n * errorFunction(1); //= 0.8427\r\n */\r\nfunction errorFunction(x/*: number */)/*: number */ {\r\n var t = 1 / (1 + 0.5 * Math.abs(x));\r\n var tau = t * Math.exp(-Math.pow(x, 2) -\r\n 1.26551223 +\r\n 1.00002368 * t +\r\n 0.37409196 * Math.pow(t, 2) +\r\n 0.09678418 * Math.pow(t, 3) -\r\n 0.18628806 * Math.pow(t, 4) +\r\n 0.27886807 * Math.pow(t, 5) -\r\n 1.13520398 * Math.pow(t, 6) +\r\n 1.48851587 * Math.pow(t, 7) -\r\n 0.82215223 * Math.pow(t, 8) +\r\n 0.17087277 * Math.pow(t, 9));\r\n if (x >= 0) {\r\n return 1 - tau;\r\n } else {\r\n return tau - 1;\r\n }\r\n}\r\n\r\nmodule.exports = errorFunction;\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * [Simple linear regression](http://en.wikipedia.org/wiki/Simple_linear_regression)\r\n * is a simple way to find a fitted line\r\n * between a set of coordinates. This algorithm finds the slope and y-intercept of a regression line\r\n * using the least sum of squares.\r\n *\r\n * @param {Array>} data an array of two-element of arrays,\r\n * like `[[0, 1], [2, 3]]`\r\n * @returns {Object} object containing slope and intersect of regression line\r\n * @example\r\n * linearRegression([[0, 0], [1, 1]]); // { m: 1, b: 0 }\r\n */\r\nfunction linearRegression(data/*: Array> */)/*: { m: number, b: number } */ {\r\n\r\n var m, b;\r\n\r\n // Store data length in a local variable to reduce\r\n // repeated object property lookups\r\n var dataLength = data.length;\r\n\r\n //if there's only one point, arbitrarily choose a slope of 0\r\n //and a y-intercept of whatever the y of the initial point is\r\n if (dataLength === 1) {\r\n m = 0;\r\n b = data[0][1];\r\n } else {\r\n // Initialize our sums and scope the `m` and `b`\r\n // variables that define the line.\r\n var sumX = 0, sumY = 0,\r\n sumXX = 0, sumXY = 0;\r\n\r\n // Use local variables to grab point values\r\n // with minimal object property lookups\r\n var point, x, y;\r\n\r\n // Gather the sum of all x values, the sum of all\r\n // y values, and the sum of x^2 and (x*y) for each\r\n // value.\r\n //\r\n // In math notation, these would be SS_x, SS_y, SS_xx, and SS_xy\r\n for (var i = 0; i < dataLength; i++) {\r\n point = data[i];\r\n x = point[0];\r\n y = point[1];\r\n\r\n sumX += x;\r\n sumY += y;\r\n\r\n sumXX += x * x;\r\n sumXY += x * y;\r\n }\r\n\r\n // `m` is the slope of the regression line\r\n m = ((dataLength * sumXY) - (sumX * sumY)) /\r\n ((dataLength * sumXX) - (sumX * sumX));\r\n\r\n // `b` is the y-intercept of the line.\r\n b = (sumY / dataLength) - ((m * sumX) / dataLength);\r\n }\r\n\r\n // Return both values as an object.\r\n return {\r\n m: m,\r\n b: b\r\n };\r\n}\r\n\r\n\r\nmodule.exports = linearRegression;\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * Given the output of `linearRegression`: an object\r\n * with `m` and `b` values indicating slope and intercept,\r\n * respectively, generate a line function that translates\r\n * x values into y values.\r\n *\r\n * @param {Object} mb object with `m` and `b` members, representing\r\n * slope and intersect of desired line\r\n * @returns {Function} method that computes y-value at any given\r\n * x-value on the line.\r\n * @example\r\n * var l = linearRegressionLine(linearRegression([[0, 0], [1, 1]]));\r\n * l(0) //= 0\r\n * l(2) //= 2\r\n */\r\nfunction linearRegressionLine(mb/*: { b: number, m: number }*/)/*: Function */ {\r\n // Return a function that computes a `y` value for each\r\n // x value it is given, based on the values of `b` and `a`\r\n // that we just computed.\r\n return function(x) {\r\n return mb.b + (mb.m * x);\r\n };\r\n}\r\n\r\nmodule.exports = linearRegressionLine;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sum = require('./sum');\r\n\r\n/**\r\n * The mean, _also known as average_,\r\n * is the sum of all values over the number of values.\r\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\r\n * a method of finding a typical or central value of a set of numbers.\r\n *\r\n * This runs on `O(n)`, linear time in respect to the array\r\n *\r\n * @param {Array} x input values\r\n * @returns {number} mean\r\n * @example\r\n * console.log(mean([0, 10])); // 5\r\n */\r\nfunction mean(x /*: Array */)/*:number*/ {\r\n // The mean of no numbers is null\r\n if (x.length === 0) { return NaN; }\r\n\r\n return sum(x) / x.length;\r\n}\r\n\r\nmodule.exports = mean;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sampleCovariance = require('./sample_covariance');\r\nvar sampleStandardDeviation = require('./sample_standard_deviation');\r\n\r\n/**\r\n * The [correlation](http://en.wikipedia.org/wiki/Correlation_and_dependence) is\r\n * a measure of how correlated two datasets are, between -1 and 1\r\n *\r\n * @param {Array} x first input\r\n * @param {Array} y second input\r\n * @returns {number} sample correlation\r\n * @example\r\n * var a = [1, 2, 3, 4, 5, 6];\r\n * var b = [2, 2, 3, 4, 5, 60];\r\n * sampleCorrelation(a, b); //= 0.691\r\n */\r\nfunction sampleCorrelation(x/*: Array */, y/*: Array */)/*:number*/ {\r\n var cov = sampleCovariance(x, y),\r\n xstd = sampleStandardDeviation(x),\r\n ystd = sampleStandardDeviation(y);\r\n\r\n return cov / xstd / ystd;\r\n}\r\n\r\nmodule.exports = sampleCorrelation;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar mean = require('./mean');\r\n\r\n/**\r\n * [Sample covariance](https://en.wikipedia.org/wiki/Sample_mean_and_sampleCovariance) of two datasets:\r\n * how much do the two datasets move together?\r\n * x and y are two datasets, represented as arrays of numbers.\r\n *\r\n * @param {Array} x first input\r\n * @param {Array} y second input\r\n * @returns {number} sample covariance\r\n * @example\r\n * var x = [1, 2, 3, 4, 5, 6];\r\n * var y = [6, 5, 4, 3, 2, 1];\r\n * sampleCovariance(x, y); //= -3.5\r\n */\r\nfunction sampleCovariance(x /*:Array*/, y /*:Array*/)/*:number*/ {\r\n\r\n // The two datasets must have the same length which must be more than 1\r\n if (x.length <= 1 || x.length !== y.length) {\r\n return NaN;\r\n }\r\n\r\n // determine the mean of each dataset so that we can judge each\r\n // value of the dataset fairly as the difference from the mean. this\r\n // way, if one dataset is [1, 2, 3] and [2, 3, 4], their covariance\r\n // does not suffer because of the difference in absolute values\r\n var xmean = mean(x),\r\n ymean = mean(y),\r\n sum = 0;\r\n\r\n // for each pair of values, the covariance increases when their\r\n // difference from the mean is associated - if both are well above\r\n // or if both are well below\r\n // the mean, the covariance increases significantly.\r\n for (var i = 0; i < x.length; i++) {\r\n sum += (x[i] - xmean) * (y[i] - ymean);\r\n }\r\n\r\n // this is Bessels' Correction: an adjustment made to sample statistics\r\n // that allows for the reduced degree of freedom entailed in calculating\r\n // values from samples rather than complete populations.\r\n var besselsCorrection = x.length - 1;\r\n\r\n // the covariance is weighted by the length of the datasets.\r\n return sum / besselsCorrection;\r\n}\r\n\r\nmodule.exports = sampleCovariance;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sampleVariance = require('./sample_variance');\r\n\r\n/**\r\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\r\n * is the square root of the variance.\r\n *\r\n * @param {Array} x input array\r\n * @returns {number} sample standard deviation\r\n * @example\r\n * ss.sampleStandardDeviation([2, 4, 4, 4, 5, 5, 7, 9]);\r\n * //= 2.138\r\n */\r\nfunction sampleStandardDeviation(x/*:Array*/)/*:number*/ {\r\n // The standard deviation of no numbers is null\r\n var sampleVarianceX = sampleVariance(x);\r\n if (isNaN(sampleVarianceX)) { return NaN; }\r\n return Math.sqrt(sampleVarianceX);\r\n}\r\n\r\nmodule.exports = sampleStandardDeviation;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sumNthPowerDeviations = require('./sum_nth_power_deviations');\r\n\r\n/*\r\n * The [sample variance](https://en.wikipedia.org/wiki/Variance#Sample_variance)\r\n * is the sum of squared deviations from the mean. The sample variance\r\n * is distinguished from the variance by the usage of [Bessel's Correction](https://en.wikipedia.org/wiki/Bessel's_correction):\r\n * instead of dividing the sum of squared deviations by the length of the input,\r\n * it is divided by the length minus one. This corrects the bias in estimating\r\n * a value from a set that you don't know if full.\r\n *\r\n * References:\r\n * * [Wolfram MathWorld on Sample Variance](http://mathworld.wolfram.com/SampleVariance.html)\r\n *\r\n * @param {Array} x input array\r\n * @return {number} sample variance\r\n * @example\r\n * sampleVariance([1, 2, 3, 4, 5]); //= 2.5\r\n */\r\nfunction sampleVariance(x /*: Array */)/*:number*/ {\r\n // The variance of no numbers is null\r\n if (x.length <= 1) { return NaN; }\r\n\r\n var sumSquaredDeviationsValue = sumNthPowerDeviations(x, 2);\r\n\r\n // this is Bessels' Correction: an adjustment made to sample statistics\r\n // that allows for the reduced degree of freedom entailed in calculating\r\n // values from samples rather than complete populations.\r\n var besselsCorrection = x.length - 1;\r\n\r\n // Find the mean value of that list\r\n return sumSquaredDeviationsValue / besselsCorrection;\r\n}\r\n\r\nmodule.exports = sampleVariance;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar variance = require('./variance');\r\n\r\n/**\r\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\r\n * is the square root of the variance. It's useful for measuring the amount\r\n * of variation or dispersion in a set of values.\r\n *\r\n * Standard deviation is only appropriate for full-population knowledge: for\r\n * samples of a population, {@link sampleStandardDeviation} is\r\n * more appropriate.\r\n *\r\n * @param {Array} x input\r\n * @returns {number} standard deviation\r\n * @example\r\n * var scores = [2, 4, 4, 4, 5, 5, 7, 9];\r\n * variance(scores); //= 4\r\n * standardDeviation(scores); //= 2\r\n */\r\nfunction standardDeviation(x /*: Array */)/*:number*/ {\r\n // The standard deviation of no numbers is null\r\n var v = variance(x);\r\n if (isNaN(v)) { return 0; }\r\n return Math.sqrt(v);\r\n}\r\n\r\nmodule.exports = standardDeviation;\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * Our default sum is the [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) is\r\n * a method for computing the sum of a list of numbers while correcting\r\n * for floating-point errors. Traditionally, sums are calculated as many\r\n * successive additions, each one with its own floating-point roundoff. These\r\n * losses in precision add up as the number of numbers increases. This alternative\r\n * algorithm is more accurate than the simple way of calculating sums by simple\r\n * addition.\r\n *\r\n * This runs on `O(n)`, linear time in respect to the array\r\n *\r\n * @param {Array} x input\r\n * @return {number} sum of all input numbers\r\n * @example\r\n * console.log(sum([1, 2, 3])); // 6\r\n */\r\nfunction sum(x/*: Array */)/*: number */ {\r\n\r\n // like the traditional sum algorithm, we keep a running\r\n // count of the current sum.\r\n var sum = 0;\r\n\r\n // but we also keep three extra variables as bookkeeping:\r\n // most importantly, an error correction value. This will be a very\r\n // small number that is the opposite of the floating point precision loss.\r\n var errorCompensation = 0;\r\n\r\n // this will be each number in the list corrected with the compensation value.\r\n var correctedCurrentValue;\r\n\r\n // and this will be the next sum\r\n var nextSum;\r\n\r\n for (var i = 0; i < x.length; i++) {\r\n // first correct the value that we're going to add to the sum\r\n correctedCurrentValue = x[i] - errorCompensation;\r\n\r\n // compute the next sum. sum is likely a much larger number\r\n // than correctedCurrentValue, so we'll lose precision here,\r\n // and measure how much precision is lost in the next step\r\n nextSum = sum + correctedCurrentValue;\r\n\r\n // we intentionally didn't assign sum immediately, but stored\r\n // it for now so we can figure out this: is (sum + nextValue) - nextValue\r\n // not equal to 0? ideally it would be, but in practice it won't:\r\n // it will be some very small number. that's what we record\r\n // as errorCompensation.\r\n errorCompensation = nextSum - sum - correctedCurrentValue;\r\n\r\n // now that we've computed how much we'll correct for in the next\r\n // loop, start treating the nextSum as the current sum.\r\n sum = nextSum;\r\n }\r\n\r\n return sum;\r\n}\r\n\r\nmodule.exports = sum;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar mean = require('./mean');\r\n\r\n/**\r\n * The sum of deviations to the Nth power.\r\n * When n=2 it's the sum of squared deviations.\r\n * When n=3 it's the sum of cubed deviations.\r\n *\r\n * @param {Array} x\r\n * @param {number} n power\r\n * @returns {number} sum of nth power deviations\r\n * @example\r\n * var input = [1, 2, 3];\r\n * // since the variance of a set is the mean squared\r\n * // deviations, we can calculate that with sumNthPowerDeviations:\r\n * var variance = sumNthPowerDeviations(input) / input.length;\r\n */\r\nfunction sumNthPowerDeviations(x/*: Array */, n/*: number */)/*:number*/ {\r\n var meanValue = mean(x),\r\n sum = 0;\r\n\r\n for (var i = 0; i < x.length; i++) {\r\n sum += Math.pow(x[i] - meanValue, n);\r\n }\r\n\r\n return sum;\r\n}\r\n\r\nmodule.exports = sumNthPowerDeviations;\r\n","'use strict';\r\n/* @flow */\r\n\r\nvar sumNthPowerDeviations = require('./sum_nth_power_deviations');\r\n\r\n/**\r\n * The [variance](http://en.wikipedia.org/wiki/Variance)\r\n * is the sum of squared deviations from the mean.\r\n *\r\n * This is an implementation of variance, not sample variance:\r\n * see the `sampleVariance` method if you want a sample measure.\r\n *\r\n * @param {Array} x a population\r\n * @returns {number} variance: a value greater than or equal to zero.\r\n * zero indicates that all values are identical.\r\n * @example\r\n * ss.variance([1, 2, 3, 4, 5, 6]); //= 2.917\r\n */\r\nfunction variance(x/*: Array */)/*:number*/ {\r\n // The variance of no numbers is null\r\n if (x.length === 0) { return NaN; }\r\n\r\n // Find the mean of squared deviations between the\r\n // mean value and each value.\r\n return sumNthPowerDeviations(x, 2) / x.length;\r\n}\r\n\r\nmodule.exports = variance;\r\n","'use strict';\r\n/* @flow */\r\n\r\n/**\r\n * The [Z-Score, or Standard Score](http://en.wikipedia.org/wiki/Standard_score).\r\n *\r\n * The standard score is the number of standard deviations an observation\r\n * or datum is above or below the mean. Thus, a positive standard score\r\n * represents a datum above the mean, while a negative standard score\r\n * represents a datum below the mean. It is a dimensionless quantity\r\n * obtained by subtracting the population mean from an individual raw\r\n * score and then dividing the difference by the population standard\r\n * deviation.\r\n *\r\n * The z-score is only defined if one knows the population parameters;\r\n * if one only has a sample set, then the analogous computation with\r\n * sample mean and sample standard deviation yields the\r\n * Student's t-statistic.\r\n *\r\n * @param {number} x\r\n * @param {number} mean\r\n * @param {number} standardDeviation\r\n * @return {number} z score\r\n * @example\r\n * ss.zScore(78, 80, 5); //= -0.4\r\n */\r\nfunction zScore(x/*:number*/, mean/*:number*/, standardDeviation/*:number*/)/*:number*/ {\r\n return (x - mean) / standardDeviation;\r\n}\r\n\r\nmodule.exports = zScore;\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from \"./legend\";\r\n\r\nexport class BarChartConfig extends ChartConfig{\r\n\r\n svgClass= this.cssClassPrefix+'bar-chart';\r\n showLegend=true;\r\n showTooltip =true;\r\n legend={\r\n width: 80,\r\n margin: 10,\r\n shapeWidth: 20\r\n };\r\n x={// X axis config\r\n label: '', // axis label\r\n key: 0,\r\n value: (d, key) => Utils.isNumber(d) ? d : d[key], // x value accessor\r\n scale: \"ordinal\",\r\n ticks: undefined,\r\n };\r\n y={// Y axis config\r\n key: 1,\r\n value: (d, key) => Utils.isNumber(d) ? d : d[key], // x value accessor\r\n label: '', // axis label,\r\n orient: \"left\",\r\n scale: \"linear\"\r\n };\r\n groups={\r\n key: 1,\r\n value: (d) => d[this.groups.key] , // grouping value accessor,\r\n label: \"\"\r\n };\r\n color = undefined // string or function returning color's value for color scale\r\n d3ColorCategory= 'category10';\r\n transition= true;\r\n\r\n constructor(custom){\r\n super();\r\n var config = this;\r\n\r\n if(custom){\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class BarChart extends Chart{\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new BarChartConfig(config));\r\n }\r\n\r\n setConfig(config){\r\n return super.setConfig(new BarChartConfig(config));\r\n }\r\n\r\n initPlot(){\r\n super.initPlot();\r\n var self=this;\r\n\r\n var conf = this.config;\r\n\r\n this.plot.x={};\r\n this.plot.y={};\r\n\r\n this.plot.showLegend = conf.showLegend;\r\n if(this.plot.showLegend){\r\n this.plot.margin.right = conf.margin.right + conf.legend.width+conf.legend.margin*2;\r\n }\r\n\r\n\r\n this.computePlotSize();\r\n this.setupY();\r\n this.setupX();\r\n this.setupGroupStacks();\r\n\r\n\r\n this.setupYDomain();\r\n\r\n\r\n if(conf.d3ColorCategory){\r\n this.plot.colorCategory = d3.scale[conf.d3ColorCategory]();\r\n }\r\n var colorValue = conf.color;\r\n if (colorValue && typeof colorValue === 'string' || colorValue instanceof String){\r\n this.plot.color = colorValue;\r\n }else if(this.plot.colorCategory){\r\n this.plot.color = d => self.plot.colorCategory(d.key);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n\r\n\r\n setupX(){\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config.x;\r\n\r\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\r\n x.value = d => conf.value(d, conf.key);\r\n x.scale = d3.scale.ordinal().rangeRoundBands([0, plot.width], .08);\r\n x.map = d => x.scale(x.value(d));\r\n\r\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\r\n\r\n var data = this.data;\r\n var domain;\r\n if(!this.config.series){\r\n domain = d3.map(data, x.value).keys();\r\n }else{\r\n domain = d3.map(data[0].values, x.value).keys();\r\n }\r\n\r\n plot.x.scale.domain(domain);\r\n console.log(' plot.x.scale.domain', plot.x.scale.domain());\r\n \r\n };\r\n\r\n setupY (){\r\n\r\n var plot = this.plot;\r\n var y = plot.y;\r\n var conf = this.config.y;\r\n y.value = d => conf.value(d, conf.key);\r\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\r\n y.map = d => y.scale(y.value(d));\r\n\r\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\r\n if(conf.ticks){\r\n y.axis.ticks(conf.ticks);\r\n }\r\n };\r\n\r\n setupYDomain() {\r\n var plot = this.plot;\r\n var data = this.data;\r\n var domain;\r\n var yStackMax = d3.max(plot.layers, layer => d3.max(layer.values, d => d.y0 + d.y));\r\n if(!this.config.series){\r\n domain = [d3.min(data, plot.y.value), d3.max(data, plot.y.value)];\r\n }else{\r\n\r\n // var min = d3.min(data, s=>d3.min(s.values, plot.y.value));\r\n var max = yStackMax;\r\n domain = [0, max];\r\n }\r\n plot.y.scale.domain(domain);\r\n console.log(' plot.y.scale.domain', plot.y.scale.domain());\r\n }\r\n groupData(){\r\n var self=this;\r\n this.plot.groupingEnabled = this.config.series;\r\n var data = this.data;\r\n if(!this.plot.groupingEnabled ){\r\n this.plot.groupedData = [{\r\n key: 'root',\r\n values: self.mapToPoints(data)\r\n }];\r\n }else{\r\n\r\n this.plot.groupedData = data.map(s=>{\r\n return{\r\n key: s.key,\r\n values: self.mapToPoints(s.values)\r\n }\r\n });\r\n\r\n }\r\n }\r\n setupGroupStacks() {\r\n var self=this;\r\n this.groupData();\r\n\r\n this.plot.stack = d3.layout.stack().values(d=>d.values);\r\n this.plot.layers = this.plot.stack(this.plot.groupedData);\r\n\r\n }\r\n\r\n mapToPoints(values){\r\n var plot = this.plot;\r\n return values.map(v=>{\r\n return {\r\n x: plot.x.value(v),\r\n y: plot.y.value(v),\r\n }\r\n })\r\n }\r\n\r\n drawAxisX(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.x;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-x')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')))\r\n .attr(\"transform\", \"translate(0,\" + plot.height + \")\");\r\n\r\n var axisT = axis;\r\n if (self.config.transition) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.x.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ (plot.width/2) +\",\"+ (plot.margin.bottom) +\")\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"-1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n drawAxisY(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.y;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-y')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')));\r\n\r\n var axisT = axis;\r\n if (self.config.transition) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.y.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ -plot.margin.left +\",\"+(plot.height/2)+\")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n\r\n drawBars() {\r\n var self = this;\r\n var plot = self.plot;\r\n\r\n console.log(plot.layers);\r\n\r\n var layerClass = this.prefixClass(\"layer\");\r\n\r\n var barClass = this.prefixClass(\"bar\");\r\n var layer = self.svgG.selectAll(\".\"+layerClass)\r\n .data(plot.layers);\r\n\r\n layer.enter().append(\"g\")\r\n .attr(\"class\", layerClass);\r\n\r\n var bar = layer.selectAll(\".\"+barClass)\r\n .data(d => d.values);\r\n\r\n bar.enter().append(\"g\")\r\n .attr(\"class\", barClass)\r\n .append(\"rect\")\r\n .attr(\"x\", 1);\r\n\r\n\r\n var barRect = bar.select(\"rect\");\r\n\r\n var barRectT = barRect;\r\n var barT = bar;\r\n var layerT = layer;\r\n if (this.transitionEnabled()) {\r\n barRectT = barRect.transition();\r\n barT = bar.transition();\r\n layerT= layer.transition();\r\n }\r\n\r\n var yDomain = plot.y.scale.domain();\r\n barT.attr(\"transform\", function(d) { return \"translate(\" + plot.x.scale(d.x) + \",\" + (plot.y.scale(d.y0+d.y )) + \")\"; });\r\n\r\n barRectT\r\n .attr(\"width\", plot.x.scale.rangeBand())\r\n .attr(\"height\", d => plot.y.scale(d.y0 ) - plot.y.scale(d.y0 + d.y - yDomain[0]));\r\n\r\n\r\n if(this.plot.color){\r\n layerT\r\n .attr(\"fill\", this.plot.color);\r\n }\r\n\r\n if (plot.tooltip) {\r\n bar.on(\"mouseover\", d => {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n plot.tooltip.html(d.y)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n }).on(\"mouseout\", d => {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n layer.exit().remove();\r\n bar.exit().remove();\r\n }\r\n\r\n update(newData){\r\n super.update(newData);\r\n this.drawAxisX();\r\n this.drawAxisY();\r\n\r\n this.drawBars();\r\n\r\n this.updateLegend();\r\n };\r\n\r\n\r\n updateLegend() {\r\n var plot = this.plot;\r\n\r\n var scale = plot.colorCategory;\r\n if(!scale.domain() || scale.domain().length<2){\r\n plot.showLegend = false;\r\n }\r\n\r\n if(!plot.showLegend){\r\n if(plot.legend && plot.legend.container){\r\n plot.legend.container.remove();\r\n }\r\n return;\r\n }\r\n\r\n\r\n var legendX = this.plot.width + this.config.legend.margin;\r\n var legendY = this.config.legend.margin;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY);\r\n\r\n var legendLinear = plot.legend.color()\r\n .shapeWidth(this.config.legend.shapeWidth)\r\n .orient('vertical')\r\n .scale(scale);\r\n\r\n plot.legend.container\r\n .call(legendLinear);\r\n }\r\n\r\n\r\n}\r\n","import {Utils} from './utils'\r\n\r\n\r\nexport class ChartConfig {\r\n cssClassPrefix = \"odc-\";\r\n svgClass = this.cssClassPrefix + 'mw-d3-chart';\r\n width = undefined;\r\n height = undefined;\r\n margin = {\r\n left: 50,\r\n right: 30,\r\n top: 30,\r\n bottom: 50\r\n };\r\n showTooltip = false;\r\n transition = true;\r\n\r\n constructor(custom) {\r\n if (custom) {\r\n Utils.deepExtend(this, custom);\r\n }\r\n }\r\n\r\n\r\n}\r\n\r\nexport class Chart {\r\n utils = Utils;\r\n baseContainer;\r\n svg;\r\n config;\r\n plot = {\r\n margin: {}\r\n };\r\n _attached = {};\r\n _layers = {};\r\n _events = {};\r\n _isAttached;\r\n _isInitialized=false;\r\n\r\n\r\n constructor(base, data, config) {\r\n \r\n this._isAttached = base instanceof Chart;\r\n\r\n this.baseContainer = base;\r\n\r\n this.setConfig(config);\r\n\r\n if (data) {\r\n this.setData(data);\r\n }\r\n\r\n this.init();\r\n this.postInit();\r\n }\r\n\r\n setConfig(config) {\r\n if (!config) {\r\n this.config = new ChartConfig();\r\n } else {\r\n this.config = config;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n setData(data) {\r\n this.data = data;\r\n return this;\r\n }\r\n\r\n init() {\r\n var self = this;\r\n\r\n\r\n self.initPlot();\r\n self.initSvg();\r\n\r\n self.initTooltip();\r\n self.draw();\r\n this._isInitialized=true;\r\n return this;\r\n }\r\n\r\n postInit(){\r\n\r\n }\r\n\r\n initSvg() {\r\n var self = this;\r\n var config = this.config;\r\n\r\n var margin = self.plot.margin;\r\n var width = self.plot.width + margin.left + margin.right;\r\n var height = self.plot.height + margin.top + margin.bottom;\r\n var aspect = width / height;\r\n if(!self._isAttached){\r\n if(!this._isInitialized){\r\n d3.select(self.baseContainer).select(\"svg\").remove();\r\n }\r\n self.svg = d3.select(self.baseContainer).selectOrAppend(\"svg\");\r\n\r\n self.svg\r\n .attr(\"width\", width)\r\n .attr(\"height\", height)\r\n .attr(\"viewBox\", \"0 0 \" + \" \" + width + \" \" + height)\r\n .attr(\"preserveAspectRatio\", \"xMidYMid meet\")\r\n .attr(\"class\", config.svgClass);\r\n self.svgG = self.svg.selectOrAppend(\"g.main-group\");\r\n }else{\r\n console.log(self.baseContainer);\r\n self.svg = self.baseContainer.svg;\r\n self.svgG = self.svg.selectOrAppend(\"g.main-group.\"+config.svgClass)\r\n }\r\n\r\n self.svgG.attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");\r\n\r\n if (!config.width || config.height) {\r\n d3.select(window)\r\n .on(\"resize\", function () {\r\n //TODO add responsiveness if width/height not specified\r\n });\r\n }\r\n }\r\n\r\n initTooltip(){\r\n var self = this;\r\n if (self.config.showTooltip) {\r\n if(!self._isAttached ){\r\n self.plot.tooltip = d3.select(\"body\").selectOrAppend('div.'+self.config.cssClassPrefix+'tooltip')\r\n .style(\"opacity\", 0);\r\n }else{\r\n self.plot.tooltip= self.baseContainer.plot.tooltip;\r\n }\r\n\r\n }\r\n }\r\n\r\n initPlot() {\r\n var margin = this.config.margin;\r\n this.plot = this.plot || {};\r\n this.plot.margin = {\r\n top: margin.top,\r\n bottom: margin.bottom,\r\n left: margin.left,\r\n right: margin.right\r\n };\r\n }\r\n\r\n update(data) {\r\n if (data) {\r\n this.setData(data);\r\n }\r\n var layerName, attachmentData;\r\n for (var attachmentName in this._attached) {\r\n\r\n attachmentData = data;\r\n\r\n this._attached[attachmentName].update(attachmentData);\r\n }\r\n return this;\r\n }\r\n\r\n draw(data) {\r\n this.update(data);\r\n\r\n\r\n return this;\r\n }\r\n\r\n\r\n //Borrowed from d3.chart\r\n /**\r\n * Register or retrieve an \"attachment\" Chart. The \"attachment\" chart's `draw`\r\n * method will be invoked whenever the containing chart's `draw` method is\r\n * invoked.\r\n *\r\n * @externalExample chart-attach\r\n *\r\n * @param {String} attachmentName Name of the attachment\r\n * @param {Chart} [chart] Chart to register as a mix in of this chart. When\r\n * unspecified, this method will return the attachment previously\r\n * registered with the specified `attachmentName` (if any).\r\n *\r\n * @returns {Chart} Reference to this chart (chainable).\r\n */\r\n attach(attachmentName, chart) {\r\n if (arguments.length === 1) {\r\n return this._attached[attachmentName];\r\n }\r\n\r\n this._attached[attachmentName] = chart;\r\n return chart;\r\n };\r\n\r\n \r\n\r\n //Borrowed from d3.chart\r\n /**\r\n * Subscribe a callback function to an event triggered on the chart. See {@link\r\n * Chart#once} to subscribe a callback function to an event for one occurence.\r\n *\r\n * @externalExample {runnable} chart-on\r\n *\r\n * @param {String} name Name of the event\r\n * @param {ChartEventHandler} callback Function to be invoked when the event\r\n * occurs\r\n * @param {Object} [context] Value to set as `this` when invoking the\r\n * `callback`. Defaults to the chart instance.\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\r\n on(name, callback, context) {\r\n var events = this._events[name] || (this._events[name] = []);\r\n events.push({\r\n callback: callback,\r\n context: context || this,\r\n _chart: this\r\n });\r\n return this;\r\n }\r\n\r\n //Borrowed from d3.chart\r\n /**\r\n *\r\n * Subscribe a callback function to an event triggered on the chart. This\r\n * function will be invoked at the next occurance of the event and immediately\r\n * unsubscribed. See {@link Chart#on} to subscribe a callback function to an\r\n * event indefinitely.\r\n *\r\n * @externalExample {runnable} chart-once\r\n *\r\n * @param {String} name Name of the event\r\n * @param {ChartEventHandler} callback Function to be invoked when the event\r\n * occurs\r\n * @param {Object} [context] Value to set as `this` when invoking the\r\n * `callback`. Defaults to the chart instance\r\n *\r\n * @returns {Chart} A reference to this chart (chainable)\r\n */\r\n once(name, callback, context) {\r\n var self = this;\r\n var once = function () {\r\n self.off(name, once);\r\n callback.apply(this, arguments);\r\n };\r\n return this.on(name, once, context);\r\n }\r\n\r\n\r\n //Borrowed from d3.chart\r\n /**\r\n * Unsubscribe one or more callback functions from an event triggered on the\r\n * chart. When no arguments are specified, *all* handlers will be unsubscribed.\r\n * When only a `name` is specified, all handlers subscribed to that event will\r\n * be unsubscribed. When a `name` and `callback` are specified, only that\r\n * function will be unsubscribed from that event. When a `name` and `context`\r\n * are specified (but `callback` is omitted), all events bound to the given\r\n * event with the given context will be unsubscribed.\r\n *\r\n * @externalExample {runnable} chart-off\r\n *\r\n * @param {String} [name] Name of the event to be unsubscribed\r\n * @param {ChartEventHandler} [callback] Function to be unsubscribed\r\n * @param {Object} [context] Contexts to be unsubscribe\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\r\n\r\n off(name, callback, context) {\r\n var names, n, events, event, i, j;\r\n\r\n // remove all events\r\n if (arguments.length === 0) {\r\n for (name in this._events) {\r\n this._events[name].length = 0;\r\n }\r\n return this;\r\n }\r\n\r\n // remove all events for a specific name\r\n if (arguments.length === 1) {\r\n events = this._events[name];\r\n if (events) {\r\n events.length = 0;\r\n }\r\n return this;\r\n }\r\n\r\n // remove all events that match whatever combination of name, context\r\n // and callback.\r\n names = name ? [name] : Object.keys(this._events);\r\n for (i = 0; i < names.length; i++) {\r\n n = names[i];\r\n events = this._events[n];\r\n j = events.length;\r\n while (j--) {\r\n event = events[j];\r\n if ((callback && callback === event.callback) ||\r\n (context && context === event.context)) {\r\n events.splice(j, 1);\r\n }\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n\r\n //Borrowed from d3.chart\r\n /**\r\n * Publish an event on this chart with the given `name`.\r\n *\r\n * @externalExample {runnable} chart-trigger\r\n *\r\n * @param {String} name Name of the event to publish\r\n * @param {...*} arguments Values with which to invoke the registered\r\n * callbacks.\r\n *\r\n * @returns {Chart} A reference to this chart (chainable).\r\n */\r\n trigger(name) {\r\n var args = Array.prototype.slice.call(arguments, 1);\r\n var events = this._events[name];\r\n var i, ev;\r\n\r\n if (events !== undefined) {\r\n for (i = 0; i < events.length; i++) {\r\n ev = events[i];\r\n ev.callback.apply(ev.context, args);\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n getBaseContainer(){\r\n if(this._isAttached){\r\n return this.baseContainer.svg;\r\n }\r\n return d3.select(this.baseContainer);\r\n }\r\n\r\n getBaseContainerNode(){\r\n\r\n return this.getBaseContainer().node();\r\n }\r\n\r\n prefixClass(clazz, addDot){\r\n return addDot? '.': ''+this.config.cssClassPrefix+clazz;\r\n }\r\n computePlotSize() {\r\n this.plot.width = Utils.availableWidth(this.config.width, this.getBaseContainer(), this.plot.margin);\r\n this.plot.height = Utils.availableHeight(this.config.height, this.getBaseContainer(), this.plot.margin);\r\n }\r\n\r\n transitionEnabled(){\r\n return this._isInitialized && this.config.transition;\r\n }\r\n}\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {StatisticsUtils} from './statistics-utils'\r\nimport {Legend} from './legend'\r\nimport {ScatterPlot} from './scatterplot'\r\n\r\nexport class CorrelationMatrixConfig extends ChartConfig {\r\n\r\n svgClass = this.cssClassPrefix+'correlation-matrix';\r\n guides = false; //show axis guides\r\n showTooltip = true; //show tooltip on dot hover\r\n showLegend = true;\r\n highlightLabels = true;\r\n rotateLabelsX = true;\r\n rotateLabelsY = true;\r\n variables = {\r\n labels: undefined,\r\n keys: [], //optional array of variable keys\r\n value: (d, variableKey) => d[variableKey], // variable value accessor\r\n scale: \"ordinal\"\r\n };\r\n correlation = {\r\n scale: \"linear\",\r\n domain: [-1, -0.75, -0.5, 0, 0.5, 0.75, 1],\r\n range: [\"darkblue\", \"blue\", \"lightskyblue\", \"white\", \"orangered\", \"crimson\", \"darkred\"],\r\n value: (xValues, yValues) => StatisticsUtils.sampleCorrelation(xValues, yValues)\r\n\r\n };\r\n cell = {\r\n shape: \"ellipse\", //possible values: rect, circle, ellipse\r\n size: undefined,\r\n sizeMin: 15,\r\n sizeMax: 250,\r\n padding: 1\r\n };\r\n margin = {\r\n left: 60,\r\n right: 50,\r\n top: 30,\r\n bottom: 60\r\n };\r\n\r\n constructor(custom) {\r\n super();\r\n if (custom) {\r\n Utils.deepExtend(this, custom);\r\n }\r\n }\r\n}\r\n\r\nexport class CorrelationMatrix extends Chart {\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new CorrelationMatrixConfig(config));\r\n }\r\n\r\n setConfig(config) {\r\n return super.setConfig(new CorrelationMatrixConfig(config));\r\n\r\n }\r\n\r\n initPlot() {\r\n super.initPlot();\r\n var self = this;\r\n var margin = this.config.margin;\r\n var conf = this.config;\r\n\r\n this.plot.x = {};\r\n this.plot.correlation = {\r\n matrix: undefined,\r\n cells: undefined,\r\n color: {},\r\n shape: {}\r\n };\r\n\r\n\r\n this.setupVariables();\r\n var width = conf.width;\r\n var placeholderNode = this.getBaseContainerNode();\r\n this.plot.placeholderNode = placeholderNode;\r\n\r\n var parentWidth = placeholderNode.getBoundingClientRect().width;\r\n if (width) {\r\n\r\n if (!this.plot.cellSize) {\r\n this.plot.cellSize = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (width - margin.left - margin.right) / this.plot.variables.length));\r\n }\r\n\r\n } else {\r\n this.plot.cellSize = this.config.cell.size;\r\n\r\n if (!this.plot.cellSize) {\r\n this.plot.cellSize = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (parentWidth - margin.left - margin.right) / this.plot.variables.length));\r\n }\r\n\r\n width = this.plot.cellSize * this.plot.variables.length + margin.left + margin.right;\r\n\r\n }\r\n\r\n var height = width;\r\n if (!height) {\r\n height = placeholderNode.getBoundingClientRect().height;\r\n }\r\n\r\n this.plot.width = width - margin.left - margin.right;\r\n this.plot.height = this.plot.width;\r\n\r\n this.setupVariablesScales();\r\n this.setupCorrelationScales();\r\n this.setupCorrelationMatrix();\r\n\r\n\r\n return this;\r\n }\r\n\r\n setupVariablesScales() {\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config.variables;\r\n\r\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\r\n x.value = conf.value;\r\n x.scale = d3.scale[conf.scale]().rangeBands([plot.width, 0]);\r\n x.map = d => x.scale(x.value(d));\r\n\r\n };\r\n\r\n setupCorrelationScales() {\r\n var plot = this.plot;\r\n var corrConf = this.config.correlation;\r\n\r\n plot.correlation.color.scale = d3.scale[corrConf.scale]().domain(corrConf.domain).range(corrConf.range);\r\n var shape = plot.correlation.shape = {};\r\n\r\n var cellConf = this.config.cell;\r\n shape.type = cellConf.shape;\r\n\r\n var shapeSize = plot.cellSize - cellConf.padding * 2;\r\n if (shape.type == 'circle') {\r\n var radiusMax = shapeSize / 2;\r\n shape.radiusScale = d3.scale.linear().domain([0, 1]).range([2, radiusMax]);\r\n shape.radius = c=> shape.radiusScale(Math.abs(c.value));\r\n } else if (shape.type == 'ellipse') {\r\n var radiusMax = shapeSize / 2;\r\n shape.radiusScale = d3.scale.linear().domain([0, 1]).range([radiusMax, 2]);\r\n shape.radiusX = c=> shape.radiusScale(Math.abs(c.value));\r\n shape.radiusY = radiusMax;\r\n\r\n shape.rotateVal = v => {\r\n if (v == 0) return \"0\";\r\n if (v < 0) return \"-45\";\r\n return \"45\"\r\n }\r\n } else if (shape.type == 'rect') {\r\n shape.size = shapeSize;\r\n }\r\n\r\n }\r\n\r\n\r\n setupVariables() {\r\n\r\n var variablesConf = this.config.variables;\r\n\r\n var data = this.data;\r\n var plot = this.plot;\r\n plot.domainByVariable = {};\r\n plot.variables = variablesConf.keys;\r\n if (!plot.variables || !plot.variables.length) {\r\n plot.variables = Utils.inferVariables(data, this.config.groups.key, this.config.includeInPlot);\r\n }\r\n\r\n plot.labels = [];\r\n plot.labelByVariable = {};\r\n plot.variables.forEach((variableKey, index) => {\r\n plot.domainByVariable[variableKey] = d3.extent(data, (d) => variablesConf.value(d, variableKey));\r\n var label = variableKey;\r\n if (variablesConf.labels && variablesConf.labels.length > index) {\r\n\r\n label = variablesConf.labels[index];\r\n }\r\n plot.labels.push(label);\r\n plot.labelByVariable[variableKey] = label;\r\n });\r\n\r\n console.log(plot.labelByVariable);\r\n\r\n };\r\n\r\n\r\n setupCorrelationMatrix() {\r\n var self = this;\r\n var data = this.data;\r\n var matrix = this.plot.correlation.matrix = [];\r\n var matrixCells = this.plot.correlation.matrix.cells = [];\r\n var plot = this.plot;\r\n\r\n var variableToValues = {};\r\n plot.variables.forEach((v, i) => {\r\n\r\n variableToValues[v] = data.map(d=>plot.x.value(d, v));\r\n });\r\n\r\n plot.variables.forEach((v1, i) => {\r\n var row = [];\r\n matrix.push(row);\r\n\r\n plot.variables.forEach((v2, j) => {\r\n var corr = 1;\r\n if (v1 != v2) {\r\n corr = self.config.correlation.value(variableToValues[v1], variableToValues[v2]);\r\n }\r\n var cell = {\r\n rowVar: v1,\r\n colVar: v2,\r\n row: i,\r\n col: j,\r\n value: corr\r\n };\r\n row.push(cell);\r\n\r\n matrixCells.push(cell);\r\n });\r\n\r\n });\r\n }\r\n\r\n\r\n update(newData) {\r\n super.update(newData);\r\n // this.update\r\n this.updateCells();\r\n this.updateVariableLabels();\r\n\r\n\r\n if (this.config.showLegend) {\r\n this.updateLegend();\r\n }\r\n };\r\n\r\n updateVariableLabels() {\r\n this.plot.labelClass = this.prefixClass(\"label\");\r\n this.updateAxisX();\r\n this.updateAxisY();\r\n }\r\n\r\n updateAxisX() {\r\n var self = this;\r\n var plot = self.plot;\r\n var labelClass = plot.labelClass;\r\n var labelXClass = labelClass + \"-x\";\r\n\r\n var labels = self.svgG.selectAll(\"text.\" + labelXClass)\r\n .data(plot.variables, (d, i)=>i);\r\n\r\n labels.enter().append(\"text\").attr(\"class\", (d, i) => labelClass + \" \" + labelXClass + \" \" + labelXClass + \"-\" + i);\r\n\r\n labels\r\n .attr(\"x\", (d, i) => i * plot.cellSize + plot.cellSize / 2)\r\n .attr(\"y\", plot.height)\r\n .attr(\"dx\", -2)\r\n .attr(\"dy\", 5)\r\n .attr(\"text-anchor\", \"end\")\r\n\r\n // .attr(\"dominant-baseline\", \"hanging\")\r\n .text(v=>plot.labelByVariable[v]);\r\n\r\n if (this.config.rotateLabelsX) {\r\n labels.attr(\"transform\", (d, i) => \"rotate(-45, \" + (i * plot.cellSize + plot.cellSize / 2 ) + \", \" + plot.height + \")\")\r\n }\r\n\r\n var maxWidth = self.computeXAxisLabelsWidth();\r\n labels.each(function (label) {\r\n Utils.placeTextWithEllipsisAndTooltip(d3.select(this), label, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\r\n });\r\n\r\n labels.exit().remove();\r\n }\r\n\r\n updateAxisY() {\r\n var self = this;\r\n var plot = self.plot;\r\n var labelClass = plot.labelClass;\r\n var labelYClass = plot.labelClass + \"-y\";\r\n var labels = self.svgG.selectAll(\"text.\" + labelYClass)\r\n .data(plot.variables);\r\n\r\n labels.enter().append(\"text\");\r\n\r\n labels\r\n .attr(\"x\", 0)\r\n .attr(\"y\", (d, i) => i * plot.cellSize + plot.cellSize / 2)\r\n .attr(\"dx\", -2)\r\n .attr(\"text-anchor\", \"end\")\r\n .attr(\"class\", (d, i) => labelClass + \" \" + labelYClass + \" \" + labelYClass + \"-\" + i)\r\n // .attr(\"dominant-baseline\", \"hanging\")\r\n .text(v=>plot.labelByVariable[v]);\r\n\r\n if (this.config.rotateLabelsY) {\r\n labels\r\n .attr(\"transform\", (d, i) => \"rotate(-45, \" + 0 + \", \" + (i * plot.cellSize + plot.cellSize / 2) + \")\")\r\n .attr(\"text-anchor\", \"end\");\r\n }\r\n\r\n var maxWidth = self.computeYAxisLabelsWidth();\r\n labels.each(function (label) {\r\n Utils.placeTextWithEllipsisAndTooltip(d3.select(this), label, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\r\n });\r\n\r\n labels.exit().remove();\r\n }\r\n\r\n computeYAxisLabelsWidth() {\r\n var maxWidth = this.plot.margin.left;\r\n if (!this.config.rotateLabelsY) {\r\n return maxWidth;\r\n }\r\n\r\n maxWidth *= Utils.SQRT_2;\r\n var fontSize = 11; //todo check actual font size\r\n maxWidth -= fontSize / 2;\r\n\r\n return maxWidth;\r\n }\r\n\r\n computeXAxisLabelsWidth(offset) {\r\n if (!this.config.rotateLabelsX) {\r\n return this.plot.cellSize - 2;\r\n }\r\n var size = this.plot.margin.bottom;\r\n size *= Utils.SQRT_2;\r\n var fontSize = 11; //todo check actual font size\r\n size -= fontSize / 2;\r\n return size;\r\n }\r\n\r\n updateCells() {\r\n\r\n var self = this;\r\n var plot = self.plot;\r\n var cellClass = self.prefixClass(\"cell\");\r\n var cellShape = plot.correlation.shape.type;\r\n\r\n var cells = self.svgG.selectAll(\"g.\" + cellClass)\r\n .data(plot.correlation.matrix.cells);\r\n\r\n var cellEnterG = cells.enter().append(\"g\")\r\n .classed(cellClass, true);\r\n cells.attr(\"transform\", c=> \"translate(\" + (plot.cellSize * c.col + plot.cellSize / 2) + \",\" + (plot.cellSize * c.row + plot.cellSize / 2) + \")\");\r\n\r\n cells.classed(self.config.cssClassPrefix + \"selectable\", !!self.scatterPlot);\r\n\r\n var selector = \"*:not(.cell-shape-\" + cellShape + \")\";\r\n\r\n var wrongShapes = cells.selectAll(selector);\r\n wrongShapes.remove();\r\n\r\n var shapes = cells.selectOrAppend(cellShape + \".cell-shape-\" + cellShape);\r\n\r\n if (plot.correlation.shape.type == 'circle') {\r\n\r\n shapes\r\n .attr(\"r\", plot.correlation.shape.radius)\r\n .attr(\"cx\", 0)\r\n .attr(\"cy\", 0);\r\n }\r\n\r\n if (plot.correlation.shape.type == 'ellipse') {\r\n // cells.attr(\"transform\", c=> \"translate(300,150) rotate(\"+plot.correlation.shape.rotateVal(c.value)+\")\");\r\n shapes\r\n .attr(\"rx\", plot.correlation.shape.radiusX)\r\n .attr(\"ry\", plot.correlation.shape.radiusY)\r\n .attr(\"cx\", 0)\r\n .attr(\"cy\", 0)\r\n\r\n .attr(\"transform\", c=> \"rotate(\" + plot.correlation.shape.rotateVal(c.value) + \")\");\r\n }\r\n\r\n\r\n if (plot.correlation.shape.type == 'rect') {\r\n shapes\r\n .attr(\"width\", plot.correlation.shape.size)\r\n .attr(\"height\", plot.correlation.shape.size)\r\n .attr(\"x\", -plot.cellSize / 2)\r\n .attr(\"y\", -plot.cellSize / 2);\r\n }\r\n shapes.style(\"fill\", c=> plot.correlation.color.scale(c.value));\r\n\r\n var mouseoverCallbacks = [];\r\n var mouseoutCallbacks = [];\r\n\r\n if (plot.tooltip) {\r\n\r\n mouseoverCallbacks.push(c=> {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = c.value;\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n });\r\n\r\n mouseoutCallbacks.push(c=> {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n\r\n\r\n }\r\n\r\n if (self.config.highlightLabels) {\r\n var highlightClass = self.config.cssClassPrefix + \"highlight\";\r\n var xLabelClass = c=>plot.labelClass + \"-x-\" + c.col;\r\n var yLabelClass = c=>plot.labelClass + \"-y-\" + c.row;\r\n\r\n\r\n mouseoverCallbacks.push(c=> {\r\n\r\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, true);\r\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, true);\r\n });\r\n mouseoutCallbacks.push(c=> {\r\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, false);\r\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, false);\r\n });\r\n }\r\n\r\n\r\n cells.on(\"mouseover\", c => {\r\n mouseoverCallbacks.forEach(callback=>callback(c));\r\n })\r\n .on(\"mouseout\", c => {\r\n mouseoutCallbacks.forEach(callback=>callback(c));\r\n });\r\n\r\n cells.on(\"click\", c=> {\r\n self.trigger(\"cell-selected\", c);\r\n });\r\n\r\n\r\n cells.exit().remove();\r\n }\r\n\r\n\r\n updateLegend() {\r\n\r\n var plot = this.plot;\r\n var legendX = this.plot.width + 10;\r\n var legendY = 0;\r\n var barWidth = 10;\r\n var barHeight = this.plot.height - 2;\r\n var scale = plot.correlation.color.scale;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY).linearGradientBar(barWidth, barHeight);\r\n\r\n\r\n }\r\n\r\n attachScatterPlot(containerSelector, config) {\r\n var self = this;\r\n\r\n config = config || {};\r\n\r\n\r\n var scatterPlotConfig = {\r\n height: self.plot.height + self.config.margin.top + self.config.margin.bottom,\r\n width: self.plot.height + self.config.margin.top + self.config.margin.bottom,\r\n groups: {\r\n key: self.config.groups.key,\r\n label: self.config.groups.label\r\n },\r\n guides: true,\r\n showLegend: false\r\n };\r\n\r\n self.scatterPlot = true;\r\n\r\n scatterPlotConfig = Utils.deepExtend(scatterPlotConfig, config);\r\n this.update();\r\n\r\n this.on(\"cell-selected\", c=> {\r\n\r\n\r\n scatterPlotConfig.x = {\r\n key: c.rowVar,\r\n label: self.plot.labelByVariable[c.rowVar]\r\n };\r\n scatterPlotConfig.y = {\r\n key: c.colVar,\r\n label: self.plot.labelByVariable[c.colVar]\r\n };\r\n if (self.scatterPlot && self.scatterPlot !== true) {\r\n self.scatterPlot.setConfig(scatterPlotConfig).init();\r\n } else {\r\n self.scatterPlot = new ScatterPlot(containerSelector, self.data, scatterPlotConfig);\r\n this.attach(\"ScatterPlot\", self.scatterPlot);\r\n }\r\n\r\n\r\n });\r\n\r\n\r\n }\r\n}\r\n","import {Utils} from './utils'\r\n\r\n\r\nexport class D3Extensions{\r\n\r\n static extend(){\r\n\r\n d3.selection.enter.prototype.insertSelector =\r\n d3.selection.prototype.insertSelector = function(selector, before) {\r\n return Utils.insertSelector(this, selector, before);\r\n };\r\n\r\n\r\n d3.selection.enter.prototype.appendSelector =\r\n d3.selection.prototype.appendSelector = function(selector) {\r\n return Utils.appendSelector(this, selector);\r\n };\r\n\r\n d3.selection.enter.prototype.selectOrAppend =\r\n d3.selection.prototype.selectOrAppend = function(selector) {\r\n return Utils.selectOrAppend(this, selector);\r\n };\r\n\r\n d3.selection.enter.prototype.selectOrInsert =\r\n d3.selection.prototype.selectOrInsert = function(selector, before) {\r\n return Utils.selectOrInsert(this, selector, before);\r\n };\r\n\r\n\r\n\r\n }\r\n}\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Heatmap, HeatmapConfig} from \"./heatmap\";\r\nimport {Utils} from './utils'\r\nimport {StatisticsUtils} from './statistics-utils'\r\n\r\n\r\nexport class HeatmapTimeSeriesConfig extends HeatmapConfig {\r\n x = {\r\n fillMissing: false, // fill missing values using interval and intervalStep\r\n interval: undefined, //used in filling missing ticks\r\n intervalStep: 1,\r\n format: undefined, //input data d3 time format\r\n displayFormat: undefined,//d3 time format for display\r\n intervalToFormats: [ //used to guess interval and format\r\n {\r\n name: 'year',\r\n formats: [\"%Y\"]\r\n },\r\n {\r\n name: 'month',\r\n formats: [\"%Y-%m\"]\r\n },\r\n {\r\n name: 'day',\r\n formats: [\"%Y-%m-%d\"]\r\n },\r\n {\r\n name: 'hour',\r\n formats: ['%H', '%Y-%m-%d %H']\r\n },\r\n {\r\n name: 'minute',\r\n formats: ['%H:%M', '%Y-%m-%d %H:%M']\r\n },\r\n {\r\n name: 'second',\r\n formats: ['%H:%M:%S', '%Y-%m-%d %H:%M:%S']\r\n }\r\n ],\r\n\r\n sortComparator: function sortComparator(a, b) {\r\n return Utils.isString(a) ? a.localeCompare(b) : a - b;\r\n },\r\n formatter: undefined\r\n };\r\n z = {\r\n fillMissing: true // fiill missing values with nearest previous value\r\n };\r\n\r\n legend = {\r\n formatter: function (v) {\r\n var suffix = \"\";\r\n if (v / 1000000 >= 1) {\r\n suffix = \" M\";\r\n v = Number(v / 1000000).toFixed(3);\r\n }\r\n var nf = Intl.NumberFormat();\r\n return nf.format(v) + suffix;\r\n }\r\n };\r\n\r\n constructor(custom) {\r\n super();\r\n\r\n if (custom) {\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class HeatmapTimeSeries extends Heatmap {\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new HeatmapTimeSeriesConfig(config));\r\n }\r\n\r\n setConfig(config) {\r\n return super.setConfig(new HeatmapTimeSeriesConfig(config));\r\n }\r\n\r\n\r\n setupValuesBeforeGroupsSort() {\r\n\r\n this.plot.x.timeFormat = this.config.x.format;\r\n if(this.config.x.displayFormat && !this.plot.x.timeFormat){\r\n this.guessTimeFormat();\r\n }\r\n\r\n\r\n super.setupValuesBeforeGroupsSort();\r\n if (!this.config.x.fillMissing) {\r\n return;\r\n }\r\n\r\n var self = this;\r\n\r\n this.initTimeFormatAndInterval();\r\n\r\n this.plot.x.intervalStep = this.config.x.intervalStep || 1;\r\n\r\n this.plot.x.timeParser = this.getTimeParser();\r\n\r\n\r\n\r\n this.plot.x.uniqueValues.sort(this.config.x.sortComparator);\r\n\r\n var prev = null;\r\n\r\n this.plot.x.uniqueValues.forEach((x, i)=> {\r\n var current = this.parseTime(x);\r\n if (prev === null) {\r\n prev = current;\r\n return;\r\n }\r\n\r\n var next = self.nextTimeTickValue(prev);\r\n var missing = [];\r\n var iteration = 0;\r\n while (self.compareTimeValues(next, current)<=0) {\r\n iteration++;\r\n if (iteration > 100) {\r\n break;\r\n }\r\n var d = {};\r\n var timeString = self.formatTime(next);\r\n d[this.config.x.key] = timeString;\r\n\r\n self.updateGroups(d, timeString, self.plot.x.groups, self.config.x.groups);\r\n missing.push(next);\r\n next = self.nextTimeTickValue(next);\r\n }\r\n prev = current;\r\n });\r\n\r\n }\r\n\r\n parseTime(x) {\r\n var parser = this.getTimeParser();\r\n return parser.parse(x);\r\n }\r\n\r\n formatTime(date){\r\n var parser = this.getTimeParser();\r\n return parser(date);\r\n }\r\n\r\n formatValueX(value) { //used only for display\r\n if (this.config.x.formatter) return this.config.x.formatter.call(this.config, value);\r\n\r\n if(this.config.x.displayFormat){\r\n var date = this.parseTime(value);\r\n return d3.time.format(this.config.x.displayFormat)(date);\r\n }\r\n\r\n if(!this.plot.x.timeFormat) return value;\r\n\r\n if(Utils.isDate(value)){\r\n return this.formatTime(value);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n compareTimeValues(a, b){\r\n return a-b;\r\n }\r\n\r\n timeValuesEqual(a, b) {\r\n var parser = this.plot.x.timeParser;\r\n return parser(a) === parser(b);\r\n }\r\n\r\n nextTimeTickValue(t) {\r\n var interval = this.plot.x.interval;\r\n return d3.time[interval].offset(t, this.plot.x.intervalStep);\r\n }\r\n\r\n initPlot() {\r\n super.initPlot();\r\n\r\n if (this.config.z.fillMissing) {\r\n this.plot.matrix.forEach((row, rowIndex) => {\r\n var prevRowValue = undefined;\r\n row.forEach((cell, colIndex) => {\r\n if (cell.value === undefined && prevRowValue !== undefined) {\r\n cell.value = prevRowValue;\r\n cell.missing = true;\r\n }\r\n prevRowValue = cell.value;\r\n });\r\n });\r\n }\r\n\r\n\r\n }\r\n\r\n update(newData) {\r\n super.update(newData);\r\n\r\n };\r\n\r\n\r\n initTimeFormatAndInterval() {\r\n\r\n this.plot.x.interval = this.config.x.interval;\r\n\r\n if(!this.plot.x.timeFormat){\r\n this.guessTimeFormat();\r\n }\r\n\r\n if(!this.plot.x.interval && this.plot.x.timeFormat){\r\n this.guessInterval();\r\n }\r\n }\r\n\r\n guessTimeFormat() {\r\n var self = this;\r\n for(let i=0; i < self.config.x.intervalToFormats.length; i++){\r\n let intervalFormat = self.config.x.intervalToFormats[i];\r\n var format = null;\r\n var formatMatch = intervalFormat.formats.some(f=>{\r\n format = f;\r\n var parser = d3.time.format(f);\r\n return self.plot.x.uniqueValues.every(x=>{\r\n return parser.parse(x) !== null\r\n });\r\n });\r\n if(formatMatch){\r\n self.plot.x.timeFormat = format;\r\n console.log('Guessed timeFormat', format);\r\n if(!self.plot.x.interval){\r\n self.plot.x.interval = intervalFormat.name;\r\n console.log('Guessed interval', self.plot.x.interval);\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n\r\n guessInterval() {\r\n var self = this;\r\n for(let i=0; i < self.config.x.intervalToFormats.length; i++) {\r\n let intervalFormat = self.config.x.intervalToFormats[i];\r\n\r\n if(intervalFormat.formats.indexOf(self.plot.x.timeFormat) >= 0){\r\n self.plot.x.interval = intervalFormat.name;\r\n console.log('Guessed interval', self.plot.x.interval);\r\n return;\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n\r\n getTimeParser() {\r\n if(!this.plot.x.timeParser){\r\n this.plot.x.timeParser = d3.time.format(this.plot.x.timeFormat);\r\n }\r\n return this.plot.x.timeParser;\r\n }\r\n}\r\n\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from './legend'\r\n\r\n\r\nexport class HeatmapConfig extends ChartConfig {\r\n\r\n svgClass = 'odc-heatmap';\r\n showTooltip = true; //show tooltip on dot hover\r\n tooltip = {\r\n noDataText: \"N/A\"\r\n };\r\n showLegend = true;\r\n legend = {\r\n width: 30,\r\n rotateLabels: false,\r\n decimalPlaces: undefined,\r\n formatter: v => this.legend.decimalPlaces === undefined ? v : Number(v).toFixed(this.legend.decimalPlaces)\r\n }\r\n highlightLabels = true;\r\n x = {// X axis config\r\n title: '', // axis title\r\n key: 0,\r\n value: (d) => d[this.x.key], // x value accessor\r\n rotateLabels: true,\r\n sortLabels: false,\r\n sortComparator: (a, b)=> Utils.isNumber(a) ? a - b : a.localeCompare(b),\r\n groups: {\r\n keys: [],\r\n labels: [],\r\n value: (d, key) => d[key],\r\n overlap: {\r\n top: 20,\r\n bottom: 20\r\n }\r\n },\r\n formatter: undefined // value formatter function\r\n\r\n };\r\n y = {// Y axis config\r\n title: '', // axis title,\r\n rotateLabels: true,\r\n key: 1,\r\n value: (d) => d[this.y.key], // y value accessor\r\n sortLabels: false,\r\n sortComparator: (a, b)=> Utils.isNumber(b) ? b - a : b.localeCompare(a),\r\n groups: {\r\n keys: [],\r\n labels: [],\r\n value: (d, key) => d[key],\r\n overlap: {\r\n left: 20,\r\n right: 20\r\n }\r\n },\r\n formatter: undefined// value formatter function\r\n };\r\n z = {\r\n key: 2,\r\n value: (d) => d[this.z.key],\r\n notAvailableValue: (v) => v === null || v === undefined,\r\n\r\n decimalPlaces: undefined,\r\n formatter: v => this.z.decimalPlaces === undefined ? v : Number(v).toFixed(this.z.decimalPlaces)// value formatter function\r\n\r\n };\r\n color = {\r\n noDataColor: \"white\",\r\n scale: \"linear\",\r\n reverseScale: false,\r\n range: [\"darkblue\", \"lightskyblue\", \"orange\", \"crimson\", \"darkred\"]\r\n };\r\n cell = {\r\n width: undefined,\r\n height: undefined,\r\n sizeMin: 15,\r\n sizeMax: 250,\r\n padding: 0\r\n };\r\n margin = {\r\n left: 60,\r\n right: 50,\r\n top: 30,\r\n bottom: 80\r\n };\r\n\r\n constructor(custom) {\r\n super();\r\n if (custom) {\r\n Utils.deepExtend(this, custom);\r\n }\r\n }\r\n}\r\n\r\n//TODO refactor\r\nexport class Heatmap extends Chart {\r\n\r\n static maxGroupGapSize = 24;\r\n static groupTitleRectHeight = 6;\r\n\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new HeatmapConfig(config));\r\n }\r\n\r\n setConfig(config) {\r\n return super.setConfig(new HeatmapConfig(config));\r\n\r\n }\r\n\r\n initPlot() {\r\n super.initPlot();\r\n var self = this;\r\n var margin = this.config.margin;\r\n var conf = this.config;\r\n\r\n this.plot.x = {};\r\n this.plot.y = {};\r\n this.plot.z = {\r\n matrixes: undefined,\r\n cells: undefined,\r\n color: {},\r\n shape: {}\r\n };\r\n\r\n\r\n this.setupValues();\r\n this.buildCells();\r\n\r\n var titleRectWidth = 6;\r\n this.plot.x.overlap = {\r\n top: 0,\r\n bottom: 0\r\n };\r\n if (this.plot.groupByX) {\r\n let depth = self.config.x.groups.keys.length;\r\n let allTitlesWidth = depth * (titleRectWidth);\r\n\r\n this.plot.x.overlap.bottom = self.config.x.groups.overlap.bottom;\r\n this.plot.x.overlap.top = self.config.x.groups.overlap.top + allTitlesWidth;\r\n this.plot.margin.top = conf.margin.right + conf.x.groups.overlap.top;\r\n this.plot.margin.bottom = conf.margin.bottom + conf.x.groups.overlap.bottom;\r\n }\r\n\r\n\r\n this.plot.y.overlap = {\r\n left: 0,\r\n right: 0\r\n };\r\n\r\n\r\n if (this.plot.groupByY) {\r\n let depth = self.config.y.groups.keys.length;\r\n let allTitlesWidth = depth * (titleRectWidth);\r\n this.plot.y.overlap.right = self.config.y.groups.overlap.left + allTitlesWidth;\r\n this.plot.y.overlap.left = self.config.y.groups.overlap.left;\r\n this.plot.margin.left = conf.margin.left + this.plot.y.overlap.left;\r\n this.plot.margin.right = conf.margin.right + this.plot.y.overlap.right;\r\n }\r\n this.plot.showLegend = conf.showLegend;\r\n if (this.plot.showLegend) {\r\n this.plot.margin.right += conf.legend.width;\r\n }\r\n this.computePlotSize();\r\n this.setupZScale();\r\n\r\n return this;\r\n }\r\n\r\n setupValues() {\r\n var self = this;\r\n var config = self.config;\r\n var x = self.plot.x;\r\n var y = self.plot.y;\r\n var z = self.plot.z;\r\n\r\n\r\n x.value = d => config.x.value.call(config, d);\r\n y.value = d => config.y.value.call(config, d);\r\n z.value = d => config.z.value.call(config, d);\r\n\r\n x.uniqueValues = [];\r\n y.uniqueValues = [];\r\n\r\n\r\n self.plot.groupByY = !!config.y.groups.keys.length;\r\n self.plot.groupByX = !!config.x.groups.keys.length;\r\n\r\n y.groups = {\r\n key: undefined,\r\n label: '',\r\n values: [],\r\n children: null,\r\n level: 0,\r\n index: 0,\r\n lastIndex: 0\r\n };\r\n x.groups = {\r\n key: undefined,\r\n label: '',\r\n values: [],\r\n children: null,\r\n level: 0,\r\n index: 0,\r\n lastIndex: 0\r\n };\r\n\r\n var valueMap = {};\r\n var minZ = undefined;\r\n var maxZ = undefined;\r\n this.data.forEach(d=> {\r\n\r\n var xVal = x.value(d);\r\n var yVal = y.value(d);\r\n var zValRaw = z.value(d);\r\n var zVal = config.z.notAvailableValue(zValRaw) ? undefined : parseFloat(zValRaw);\r\n\r\n\r\n if (x.uniqueValues.indexOf(xVal) === -1) {\r\n x.uniqueValues.push(xVal);\r\n }\r\n\r\n if (y.uniqueValues.indexOf(yVal) === -1) {\r\n y.uniqueValues.push(yVal);\r\n }\r\n\r\n var groupY = y.groups;\r\n if (self.plot.groupByY) {\r\n groupY = this.updateGroups(d, yVal, y.groups, config.y.groups);\r\n }\r\n var groupX = x.groups;\r\n if (self.plot.groupByX) {\r\n\r\n groupX = this.updateGroups(d, xVal, x.groups, config.x.groups);\r\n }\r\n\r\n if (!valueMap[groupY.index]) {\r\n valueMap[groupY.index] = {};\r\n }\r\n\r\n if (!valueMap[groupY.index][groupX.index]) {\r\n valueMap[groupY.index][groupX.index] = {};\r\n }\r\n if (!valueMap[groupY.index][groupX.index][yVal]) {\r\n valueMap[groupY.index][groupX.index][yVal] = {};\r\n }\r\n valueMap[groupY.index][groupX.index][yVal][xVal] = zVal;\r\n\r\n\r\n if (minZ === undefined || zVal < minZ) {\r\n minZ = zVal;\r\n }\r\n if (maxZ === undefined || zVal > maxZ) {\r\n maxZ = zVal;\r\n }\r\n });\r\n self.plot.valueMap = valueMap;\r\n\r\n\r\n if (!self.plot.groupByX) {\r\n x.groups.values = x.uniqueValues;\r\n }\r\n\r\n if (!self.plot.groupByY) {\r\n y.groups.values = y.uniqueValues;\r\n }\r\n\r\n this.setupValuesBeforeGroupsSort();\r\n\r\n x.gaps = [];\r\n x.totalValuesCount = 0;\r\n x.allValuesList = [];\r\n this.sortGroups(x, x.groups, config.x);\r\n\r\n y.gaps = [];\r\n y.totalValuesCount = 0;\r\n y.allValuesList = [];\r\n this.sortGroups(y, y.groups, config.y);\r\n\r\n z.min = minZ;\r\n z.max = maxZ;\r\n\r\n }\r\n\r\n setupValuesBeforeGroupsSort() {\r\n }\r\n\r\n buildCells() {\r\n var self = this;\r\n var x = self.plot.x;\r\n var y = self.plot.y;\r\n var z = self.plot.z;\r\n var valueMap = self.plot.valueMap;\r\n\r\n var matrixCells = self.plot.cells = [];\r\n var matrix = self.plot.matrix = [];\r\n\r\n y.allValuesList.forEach((v1, i)=> {\r\n var row = [];\r\n matrix.push(row);\r\n\r\n x.allValuesList.forEach((v2, j) => {\r\n var zVal = undefined;\r\n try {\r\n zVal = valueMap[v1.group.index][v2.group.index][v1.val][v2.val]\r\n } catch (e) {\r\n }\r\n\r\n var cell = {\r\n rowVar: v1,\r\n colVar: v2,\r\n row: i,\r\n col: j,\r\n value: zVal\r\n };\r\n row.push(cell);\r\n\r\n matrixCells.push(cell);\r\n });\r\n });\r\n\r\n }\r\n\r\n updateGroups(d, axisVal, rootGroup, axisGroupsConfig) {\r\n\r\n var config = this.config;\r\n var currentGroup = rootGroup;\r\n axisGroupsConfig.keys.forEach((groupKey, groupKeyIndex) => {\r\n currentGroup.key = groupKey;\r\n\r\n if (!currentGroup.children) {\r\n currentGroup.children = {};\r\n }\r\n\r\n var groupingValue = axisGroupsConfig.value.call(config, d, groupKey);\r\n\r\n if (!currentGroup.children.hasOwnProperty(groupingValue)) {\r\n rootGroup.lastIndex++;\r\n currentGroup.children[groupingValue] = {\r\n values: [],\r\n children: null,\r\n groupingValue: groupingValue,\r\n level: currentGroup.level + 1,\r\n index: rootGroup.lastIndex,\r\n key: groupKey\r\n }\r\n }\r\n\r\n currentGroup = currentGroup.children[groupingValue];\r\n });\r\n\r\n if (currentGroup.values.indexOf(axisVal) === -1) {\r\n currentGroup.values.push(axisVal);\r\n }\r\n\r\n return currentGroup;\r\n }\r\n\r\n sortGroups(axis, group, axisConfig, gaps) {\r\n if (axisConfig.groups.labels && axisConfig.groups.labels.length > group.level) {\r\n group.label = axisConfig.groups.labels[group.level];\r\n } else {\r\n group.label = group.key;\r\n }\r\n\r\n if (!gaps) {\r\n gaps = [0];\r\n }\r\n if (gaps.length <= group.level) {\r\n gaps.push(0);\r\n }\r\n\r\n group.allValuesCount = group.allValuesCount || 0;\r\n group.allValuesBeforeCount = group.allValuesBeforeCount || 0;\r\n\r\n group.gaps = gaps.slice();\r\n group.gapsBefore = gaps.slice();\r\n\r\n\r\n group.gapsSize = Heatmap.computeGapsSize(group.gaps);\r\n group.gapsBeforeSize = group.gapsSize;\r\n if (group.values) {\r\n if (axisConfig.sortLabels) {\r\n group.values.sort(axisConfig.sortComparator);\r\n }\r\n group.values.forEach(v=>axis.allValuesList.push({val: v, group: group}));\r\n group.allValuesBeforeCount = axis.totalValuesCount;\r\n axis.totalValuesCount += group.values.length;\r\n group.allValuesCount += group.values.length;\r\n }\r\n\r\n group.childrenList = [];\r\n if (group.children) {\r\n var childrenCount = 0;\r\n\r\n for (var childProp in group.children) {\r\n if (group.children.hasOwnProperty(childProp)) {\r\n var child = group.children[childProp];\r\n group.childrenList.push(child);\r\n childrenCount++;\r\n\r\n this.sortGroups(axis, child, axisConfig, gaps);\r\n group.allValuesCount += child.allValuesCount;\r\n gaps[group.level] += 1;\r\n }\r\n }\r\n\r\n if (gaps && childrenCount > 1) {\r\n gaps[group.level] -= 1;\r\n }\r\n\r\n group.gapsInside = [];\r\n gaps.forEach((d, i)=> {\r\n group.gapsInside.push(d - (group.gapsBefore[i] || 0));\r\n });\r\n group.gapsInsideSize = Heatmap.computeGapsSize(group.gapsInside);\r\n\r\n if (axis.gaps.length < gaps.length) {\r\n axis.gaps = gaps;\r\n }\r\n }\r\n\r\n }\r\n\r\n computeYAxisLabelsWidth(offset) {\r\n var maxWidth = this.plot.margin.left;\r\n if (this.config.y.title) {\r\n maxWidth -= 15;\r\n }\r\n if (offset && offset.x) {\r\n maxWidth += offset.x;\r\n }\r\n\r\n if (this.config.y.rotateLabels) {\r\n maxWidth *= Utils.SQRT_2;\r\n var fontSize = 11; //todo check actual font size\r\n maxWidth -=fontSize/2;\r\n }\r\n\r\n return maxWidth;\r\n }\r\n\r\n computeXAxisLabelsWidth(offset) {\r\n if (!this.config.x.rotateLabels) {\r\n return this.plot.cellWidth - 2;\r\n }\r\n var size = this.plot.margin.bottom;\r\n if (this.config.x.title) {\r\n size -= 15;\r\n }\r\n if (offset && offset.y) {\r\n size -= offset.y;\r\n }\r\n\r\n size *= Utils.SQRT_2;\r\n\r\n var fontSize = 11; //todo check actual font size\r\n size -=fontSize/2;\r\n\r\n return size;\r\n }\r\n\r\n static computeGapSize(gapLevel) {\r\n return Heatmap.maxGroupGapSize / (gapLevel + 1);\r\n }\r\n\r\n static computeGapsSize(gaps) {\r\n var gapsSize = 0;\r\n gaps.forEach((gapsNumber, gapsLevel)=> gapsSize += gapsNumber * Heatmap.computeGapSize(gapsLevel));\r\n return gapsSize;\r\n }\r\n\r\n computePlotSize() {\r\n\r\n var plot = this.plot;\r\n var conf = this.config;\r\n var margin = plot.margin;\r\n var availableWidth = Utils.availableWidth(this.config.width, this.getBaseContainer(), this.plot.margin);\r\n var availableHeight = Utils.availableHeight(this.config.height, this.getBaseContainer(), this.plot.margin);\r\n var width = availableWidth;\r\n var height = availableHeight;\r\n\r\n var xGapsSize = Heatmap.computeGapsSize(plot.x.gaps);\r\n\r\n\r\n var computedCellWidth = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (availableWidth - xGapsSize) / this.plot.x.totalValuesCount));\r\n if (this.config.width) {\r\n\r\n if (!this.config.cell.width) {\r\n this.plot.cellWidth = computedCellWidth;\r\n }\r\n\r\n } else {\r\n this.plot.cellWidth = this.config.cell.width;\r\n\r\n if (!this.plot.cellWidth) {\r\n this.plot.cellWidth = computedCellWidth;\r\n }\r\n\r\n }\r\n width = this.plot.cellWidth * this.plot.x.totalValuesCount + margin.left + margin.right + xGapsSize;\r\n\r\n var yGapsSize = Heatmap.computeGapsSize(plot.y.gaps);\r\n var computedCellHeight = Math.max(conf.cell.sizeMin, Math.min(conf.cell.sizeMax, (availableHeight - yGapsSize) / this.plot.y.totalValuesCount));\r\n if (this.config.height) {\r\n if (!this.config.cell.height) {\r\n this.plot.cellHeight = computedCellHeight;\r\n }\r\n } else {\r\n this.plot.cellHeight = this.config.cell.height;\r\n\r\n if (!this.plot.cellHeight) {\r\n this.plot.cellHeight = computedCellHeight;\r\n }\r\n\r\n }\r\n\r\n height = this.plot.cellHeight * this.plot.y.totalValuesCount + margin.top + margin.bottom + yGapsSize;\r\n\r\n\r\n this.plot.width = width - margin.left - margin.right;\r\n this.plot.height = height - margin.top - margin.bottom;\r\n }\r\n\r\n\r\n setupZScale() {\r\n\r\n var self = this;\r\n var config = self.config;\r\n var z = self.plot.z;\r\n var range = config.color.range;\r\n var extent = z.max - z.min;\r\n var scale;\r\n z.domain = [];\r\n if (config.color.scale == \"pow\") {\r\n var exponent = 10;\r\n range.forEach((c, i)=> {\r\n var v = z.max - (extent / Math.pow(10, i));\r\n z.domain.push(v)\r\n });\r\n scale = d3.scale.pow().exponent(exponent);\r\n } else if (config.color.scale == \"log\") {\r\n\r\n range.forEach((c, i)=> {\r\n var v = z.min + (extent / Math.pow(10, i));\r\n z.domain.unshift(v)\r\n\r\n });\r\n\r\n scale = d3.scale.log()\r\n } else {\r\n range.forEach((c, i)=> {\r\n var v = z.min + (extent * (i / (range.length - 1)));\r\n z.domain.push(v)\r\n });\r\n scale = d3.scale[config.color.scale]();\r\n }\r\n\r\n\r\n z.domain[0] = z.min; //removing unnecessary floating points\r\n z.domain[z.domain.length - 1] = z.max; //removing unnecessary floating points\r\n console.log(z.domain);\r\n\r\n if (config.color.reverseScale) {\r\n z.domain.reverse();\r\n }\r\n\r\n var plot = this.plot;\r\n\r\n console.log(range);\r\n plot.z.color.scale = scale.domain(z.domain).range(range);\r\n var shape = plot.z.shape = {};\r\n\r\n var cellConf = this.config.cell;\r\n shape.type = \"rect\";\r\n\r\n plot.z.shape.width = plot.cellWidth - cellConf.padding * 2;\r\n plot.z.shape.height = plot.cellHeight - cellConf.padding * 2;\r\n }\r\n\r\n\r\n update(newData) {\r\n super.update(newData);\r\n if (this.plot.groupByY) {\r\n this.drawGroupsY(this.plot.y.groups, this.svgG);\r\n }\r\n if (this.plot.groupByX) {\r\n this.drawGroupsX(this.plot.x.groups, this.svgG);\r\n }\r\n\r\n this.updateCells();\r\n\r\n // this.updateVariableLabels();\r\n\r\n this.updateAxisX();\r\n this.updateAxisY();\r\n\r\n if (this.config.showLegend) {\r\n this.updateLegend();\r\n }\r\n\r\n this.updateAxisTitles();\r\n };\r\n\r\n updateAxisTitles() {\r\n var self = this;\r\n var plot = self.plot;\r\n\r\n\r\n }\r\n\r\n\r\n updateAxisX() {\r\n var self = this;\r\n var plot = self.plot;\r\n var labelClass = self.prefixClass(\"label\");\r\n var labelXClass = labelClass + \"-x\";\r\n var labelYClass = labelClass + \"-y\";\r\n plot.labelClass = labelClass;\r\n\r\n var offsetX = {\r\n x: 0,\r\n y: 0\r\n };\r\n let gapSize = Heatmap.computeGapSize(0);\r\n if (plot.groupByX) {\r\n let overlap = self.config.x.groups.overlap;\r\n\r\n offsetX.x = gapSize / 2;\r\n offsetX.y = overlap.bottom + gapSize / 2 + 6;\r\n } else if (plot.groupByY) {\r\n offsetX.y = gapSize;\r\n }\r\n\r\n\r\n var labels = self.svgG.selectAll(\"text.\" + labelXClass)\r\n .data(plot.x.allValuesList, (d, i)=>i);\r\n\r\n labels.enter().append(\"text\").attr(\"class\", (d, i) => labelClass + \" \" + labelXClass + \" \" + labelXClass + \"-\" + i);\r\n\r\n labels\r\n .attr(\"x\", (d, i) => (i * plot.cellWidth + plot.cellWidth / 2) + (d.group.gapsSize) + offsetX.x)\r\n .attr(\"y\", plot.height + offsetX.y)\r\n .attr(\"dy\", 10)\r\n\r\n .attr(\"text-anchor\", \"middle\")\r\n .text(d=>self.formatValueX(d.val));\r\n\r\n\r\n\r\n var maxWidth = self.computeXAxisLabelsWidth(offsetX);\r\n\r\n labels.each(function (label) {\r\n var elem = d3.select(this),\r\n text = self.formatValueX(label.val);\r\n Utils.placeTextWithEllipsisAndTooltip(elem, text, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\r\n });\r\n\r\n if (self.config.x.rotateLabels) {\r\n labels.attr(\"transform\", (d, i) => \"rotate(-45, \" + ((i * plot.cellWidth + plot.cellWidth / 2) + d.group.gapsSize + offsetX.x ) + \", \" + ( plot.height + offsetX.y) + \")\")\r\n .attr(\"dx\", -2)\r\n .attr(\"dy\", 8)\r\n .attr(\"text-anchor\", \"end\");\r\n }\r\n\r\n\r\n labels.exit().remove();\r\n\r\n\r\n self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-x'))\r\n .attr(\"transform\", \"translate(\" + (plot.width / 2) + \",\" + (plot.height + plot.margin.bottom) + \")\")\r\n .selectOrAppend(\"text.\" + self.prefixClass('label'))\r\n\r\n .attr(\"dy\", \"-0.5em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(self.config.x.title);\r\n }\r\n\r\n updateAxisY() {\r\n var self = this;\r\n var plot = self.plot;\r\n var labelClass = self.prefixClass(\"label\");\r\n var labelYClass = labelClass + \"-y\";\r\n plot.labelClass = labelClass;\r\n\r\n\r\n var labels = self.svgG.selectAll(\"text.\" + labelYClass)\r\n .data(plot.y.allValuesList);\r\n\r\n labels.enter().append(\"text\");\r\n\r\n var offsetY = {\r\n x: 0,\r\n y: 0\r\n };\r\n if (plot.groupByY) {\r\n let overlap = self.config.y.groups.overlap;\r\n let gapSize = Heatmap.computeGapSize(0);\r\n offsetY.x = -overlap.left;\r\n\r\n offsetY.y = gapSize / 2;\r\n }\r\n labels\r\n .attr(\"x\", offsetY.x)\r\n .attr(\"y\", (d, i) => (i * plot.cellHeight + plot.cellHeight / 2) + d.group.gapsSize + offsetY.y)\r\n .attr(\"dx\", -2)\r\n .attr(\"text-anchor\", \"end\")\r\n .attr(\"class\", (d, i) => labelClass + \" \" + labelYClass + \" \" + labelYClass + \"-\" + i)\r\n\r\n .text(function (d) {\r\n var formatted = self.formatValueY(d.val);\r\n return formatted\r\n });\r\n\r\n var maxWidth = self.computeYAxisLabelsWidth(offsetY);\r\n\r\n labels.each(function (label) {\r\n var elem = d3.select(this),\r\n text = self.formatValueY(label.val);\r\n Utils.placeTextWithEllipsisAndTooltip(elem, text, maxWidth, self.config.showTooltip ? self.plot.tooltip : false);\r\n });\r\n\r\n if (self.config.y.rotateLabels) {\r\n labels\r\n .attr(\"transform\", (d, i) => \"rotate(-45, \" + (offsetY.x ) + \", \" + (d.group.gapsSize + (i * plot.cellHeight + plot.cellHeight / 2) + offsetY.y) + \")\")\r\n .attr(\"text-anchor\", \"end\");\r\n // .attr(\"dx\", -7);\r\n } else {\r\n labels.attr(\"dominant-baseline\", \"middle\")\r\n }\r\n\r\n\r\n labels.exit().remove();\r\n\r\n\r\n self.svgG.selectOrAppend(\"g.\" + self.prefixClass('axis-y'))\r\n .selectOrAppend(\"text.\" + self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\" + -plot.margin.left + \",\" + (plot.height / 2) + \")rotate(-90)\")\r\n .attr(\"dy\", \"1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(self.config.y.title);\r\n\r\n }\r\n\r\n\r\n drawGroupsY(parentGroup, container, availableWidth) {\r\n\r\n var self = this;\r\n var plot = self.plot;\r\n\r\n var groupClass = self.prefixClass(\"group\");\r\n var groupYClass = groupClass + \"-y\";\r\n var groups = container.selectAll(\"g.\" + groupClass + \".\" + groupYClass)\r\n .data(parentGroup.childrenList);\r\n\r\n var valuesBeforeCount = 0;\r\n var gapsBeforeSize = 0;\r\n\r\n var groupsEnterG = groups.enter().append(\"g\");\r\n groupsEnterG\r\n .classed(groupClass, true)\r\n .classed(groupYClass, true)\r\n .append(\"rect\").classed(\"group-rect\", true);\r\n\r\n var titleGroupEnter = groupsEnterG.appendSelector(\"g.title\");\r\n titleGroupEnter.append(\"rect\");\r\n titleGroupEnter.append(\"text\");\r\n\r\n var gapSize = Heatmap.computeGapSize(parentGroup.level);\r\n var padding = gapSize / 4;\r\n\r\n var titleRectWidth = Heatmap.groupTitleRectHeight;\r\n var depth = self.config.y.groups.keys.length - parentGroup.level;\r\n var overlap = {\r\n left: 0,\r\n right: 0\r\n };\r\n\r\n if (!availableWidth) {\r\n overlap.right = plot.y.overlap.left;\r\n overlap.left = plot.y.overlap.left;\r\n availableWidth = plot.width + gapSize + overlap.left + overlap.right;\r\n }\r\n\r\n\r\n groups\r\n .attr(\"transform\", (d, i) => {\r\n var translate = \"translate(\" + (padding - overlap.left) + \",\" + ((plot.cellHeight * valuesBeforeCount) + i * gapSize + gapsBeforeSize + padding) + \")\";\r\n gapsBeforeSize += (d.gapsInsideSize || 0);\r\n valuesBeforeCount += d.allValuesCount || 0;\r\n return translate\r\n });\r\n\r\n\r\n var groupWidth = availableWidth - padding * 2;\r\n\r\n var titleGroups = groups.selectAll(\"g.title\")\r\n .attr(\"transform\", (d, i) => \"translate(\" + (groupWidth - titleRectWidth) + \", 0)\");\r\n\r\n var tileRects = titleGroups.selectAll(\"rect\")\r\n .attr(\"width\", titleRectWidth)\r\n .attr(\"height\", d=> {\r\n return (d.gapsInsideSize || 0) + plot.cellHeight * d.allValuesCount + padding * 2\r\n })\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n // .attr(\"fill\", \"lightgrey\")\r\n .attr(\"stroke-width\", 0);\r\n\r\n this.setGroupMouseCallbacks(parentGroup, tileRects);\r\n\r\n\r\n groups.selectAll(\"rect.group-rect\")\r\n .attr(\"class\", d=> \"group-rect group-rect-\" + d.index)\r\n .attr(\"width\", groupWidth)\r\n .attr(\"height\", d=> {\r\n return (d.gapsInsideSize || 0) + plot.cellHeight * d.allValuesCount + padding * 2\r\n })\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n .attr(\"fill\", \"white\")\r\n .attr(\"fill-opacity\", 0)\r\n .attr(\"stroke-width\", 0.5)\r\n .attr(\"stroke\", \"black\")\r\n\r\n\r\n groups.each(function (group) {\r\n\r\n self.drawGroupsY.call(self, group, d3.select(this), groupWidth - titleRectWidth);\r\n });\r\n\r\n }\r\n\r\n drawGroupsX(parentGroup, container, availableHeight) {\r\n\r\n var self = this;\r\n var plot = self.plot;\r\n\r\n var groupClass = self.prefixClass(\"group\");\r\n var groupXClass = groupClass + \"-x\";\r\n var groups = container.selectAll(\"g.\" + groupClass + \".\" + groupXClass)\r\n .data(parentGroup.childrenList);\r\n\r\n var valuesBeforeCount = 0;\r\n var gapsBeforeSize = 0;\r\n\r\n var groupsEnterG = groups.enter().append(\"g\");\r\n groupsEnterG\r\n .classed(groupClass, true)\r\n .classed(groupXClass, true)\r\n .append(\"rect\").classed(\"group-rect\", true);\r\n\r\n var titleGroupEnter = groupsEnterG.appendSelector(\"g.title\");\r\n titleGroupEnter.append(\"rect\");\r\n titleGroupEnter.append(\"text\");\r\n\r\n var gapSize = Heatmap.computeGapSize(parentGroup.level);\r\n var padding = gapSize / 4;\r\n var titleRectHeight = Heatmap.groupTitleRectHeight;\r\n\r\n var depth = self.config.x.groups.keys.length - parentGroup.level;\r\n\r\n var overlap = {\r\n top: 0,\r\n bottom: 0\r\n };\r\n\r\n if (!availableHeight) {\r\n overlap.bottom = plot.x.overlap.bottom;\r\n overlap.top = plot.x.overlap.top;\r\n availableHeight = plot.height + gapSize + overlap.top + overlap.bottom;\r\n\r\n } else {\r\n overlap.top = -titleRectHeight;\r\n }\r\n // console.log('parentGroup',parentGroup, 'gapSize', gapSize, plot.x.overlap);\r\n\r\n groups\r\n .attr(\"transform\", (d, i) => {\r\n var translate = \"translate(\" + ((plot.cellWidth * valuesBeforeCount) + i * gapSize + gapsBeforeSize + padding) + \", \" + (padding - overlap.top) + \")\";\r\n gapsBeforeSize += (d.gapsInsideSize || 0);\r\n valuesBeforeCount += d.allValuesCount || 0;\r\n return translate\r\n });\r\n\r\n var groupHeight = availableHeight - padding * 2;\r\n\r\n var titleGroups = groups.selectAll(\"g.title\")\r\n .attr(\"transform\", (d, i) => \"translate(0, \" + (0) + \")\");\r\n\r\n\r\n var tileRects = titleGroups.selectAll(\"rect\")\r\n .attr(\"height\", titleRectHeight)\r\n .attr(\"width\", d=> {\r\n return (d.gapsInsideSize || 0) + plot.cellWidth * d.allValuesCount + padding * 2\r\n })\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n // .attr(\"fill\", \"lightgrey\")\r\n .attr(\"stroke-width\", 0);\r\n\r\n this.setGroupMouseCallbacks(parentGroup, tileRects);\r\n\r\n\r\n groups.selectAll(\"rect.group-rect\")\r\n .attr(\"class\", d=> \"group-rect group-rect-\" + d.index)\r\n .attr(\"height\", groupHeight)\r\n .attr(\"width\", d=> {\r\n return (d.gapsInsideSize || 0) + plot.cellWidth * d.allValuesCount + padding * 2\r\n })\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n .attr(\"fill\", \"white\")\r\n .attr(\"fill-opacity\", 0)\r\n .attr(\"stroke-width\", 0.5)\r\n .attr(\"stroke\", \"black\");\r\n\r\n groups.each(function (group) {\r\n self.drawGroupsX.call(self, group, d3.select(this), groupHeight - titleRectHeight);\r\n });\r\n\r\n groups.exit().remove();\r\n\r\n }\r\n\r\n setGroupMouseCallbacks(parentGroup, tileRects) {\r\n var plot = this.plot;\r\n var self = this;\r\n var mouseoverCallbacks = [];\r\n mouseoverCallbacks.push(function (d) {\r\n d3.select(this).classed('highlighted', true);\r\n d3.select(this.parentNode.parentNode).selectAll(\"rect.group-rect-\" + d.index).classed('highlighted', true);\r\n });\r\n\r\n var mouseoutCallbacks = [];\r\n mouseoutCallbacks.push(function (d) {\r\n d3.select(this).classed('highlighted', false);\r\n d3.select(this.parentNode.parentNode).selectAll(\"rect.group-rect-\" + d.index).classed('highlighted', false);\r\n });\r\n if (plot.tooltip) {\r\n\r\n mouseoverCallbacks.push(d=> {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = parentGroup.label + \": \" + d.groupingValue;\r\n\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n });\r\n\r\n mouseoutCallbacks.push(d=> {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n\r\n\r\n }\r\n tileRects.on(\"mouseover\", function (d) {\r\n var self = this;\r\n mouseoverCallbacks.forEach(function (callback) {\r\n callback.call(self, d)\r\n });\r\n });\r\n tileRects.on(\"mouseout\", function (d) {\r\n var self = this;\r\n mouseoutCallbacks.forEach(function (callback) {\r\n callback.call(self, d)\r\n });\r\n });\r\n }\r\n\r\n updateCells() {\r\n\r\n var self = this;\r\n var plot = self.plot;\r\n var cellContainerClass = self.prefixClass(\"cells\");\r\n var gapSize = Heatmap.computeGapSize(0);\r\n var paddingX = plot.x.groups.childrenList.length ? gapSize / 2 : 0;\r\n var paddingY = plot.y.groups.childrenList.length ? gapSize / 2 : 0;\r\n var cellContainer = self.svgG.selectOrAppend(\"g.\" + cellContainerClass);\r\n cellContainer.attr(\"transform\", \"translate(\" + paddingX + \", \" + paddingY + \")\");\r\n\r\n var cellClass = self.prefixClass(\"cell\");\r\n var cellShape = plot.z.shape.type;\r\n\r\n var cells = cellContainer.selectAll(\"g.\" + cellClass)\r\n .data(self.plot.cells);\r\n\r\n var cellEnterG = cells.enter().append(\"g\")\r\n .classed(cellClass, true);\r\n cells.attr(\"transform\", c=> \"translate(\" + ((plot.cellWidth * c.col + plot.cellWidth / 2) + c.colVar.group.gapsSize) + \",\" + ((plot.cellHeight * c.row + plot.cellHeight / 2) + c.rowVar.group.gapsSize) + \")\");\r\n\r\n var shapes = cells.selectOrAppend(cellShape + \".cell-shape-\" + cellShape);\r\n\r\n shapes\r\n .attr(\"width\", plot.z.shape.width)\r\n .attr(\"height\", plot.z.shape.height)\r\n .attr(\"x\", -plot.cellWidth / 2)\r\n .attr(\"y\", -plot.cellHeight / 2);\r\n\r\n shapes.style(\"fill\", c=> c.value === undefined ? self.config.color.noDataColor : plot.z.color.scale(c.value));\r\n shapes.attr(\"fill-opacity\", d=> d.value === undefined ? 0 : 1);\r\n\r\n var mouseoverCallbacks = [];\r\n var mouseoutCallbacks = [];\r\n\r\n if (plot.tooltip) {\r\n\r\n mouseoverCallbacks.push(c=> {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = c.value === undefined ? self.config.tooltip.noDataText : self.formatValueZ(c.value);\r\n\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n });\r\n\r\n mouseoutCallbacks.push(c=> {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n\r\n\r\n }\r\n\r\n if (self.config.highlightLabels) {\r\n var highlightClass = self.config.cssClassPrefix + \"highlight\";\r\n var xLabelClass = c=>plot.labelClass + \"-x-\" + c.col;\r\n var yLabelClass = c=>plot.labelClass + \"-y-\" + c.row;\r\n\r\n\r\n mouseoverCallbacks.push(c=> {\r\n\r\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, true);\r\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, true);\r\n });\r\n mouseoutCallbacks.push(c=> {\r\n self.svgG.selectAll(\"text.\" + xLabelClass(c)).classed(highlightClass, false);\r\n self.svgG.selectAll(\"text.\" + yLabelClass(c)).classed(highlightClass, false);\r\n });\r\n }\r\n\r\n\r\n cells.on(\"mouseover\", c => {\r\n mouseoverCallbacks.forEach(callback=>callback(c));\r\n })\r\n .on(\"mouseout\", c => {\r\n mouseoutCallbacks.forEach(callback=>callback(c));\r\n });\r\n\r\n cells.on(\"click\", c=> {\r\n self.trigger(\"cell-selected\", c);\r\n });\r\n\r\n\r\n cells.exit().remove();\r\n }\r\n\r\n formatValueX(value) {\r\n if (!this.config.x.formatter) return value;\r\n\r\n return this.config.x.formatter.call(this.config, value);\r\n }\r\n\r\n formatValueY(value) {\r\n if (!this.config.y.formatter) return value;\r\n\r\n return this.config.y.formatter.call(this.config, value);\r\n }\r\n\r\n formatValueZ(value) {\r\n if (!this.config.z.formatter) return value;\r\n\r\n return this.config.z.formatter.call(this.config, value);\r\n }\r\n\r\n formatLegendValue(value) {\r\n if (!this.config.legend.formatter) return value;\r\n\r\n return this.config.legend.formatter.call(this.config, value);\r\n }\r\n\r\n updateLegend() {\r\n var self = this;\r\n var plot = this.plot;\r\n var legendX = this.plot.width + 10;\r\n var gapSize = Heatmap.computeGapSize(0);\r\n if (this.plot.groupByY) {\r\n legendX += gapSize / 2 + plot.y.overlap.right;\r\n } else if (this.plot.groupByX) {\r\n legendX += gapSize;\r\n }\r\n var legendY = 0;\r\n if (this.plot.groupByX || this.plot.groupByY) {\r\n legendY += gapSize / 2;\r\n }\r\n\r\n var barWidth = 10;\r\n var barHeight = this.plot.height - 2;\r\n var scale = plot.z.color.scale;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY, v => self.formatLegendValue(v)).setRotateLabels(self.config.legend.rotateLabels).linearGradientBar(barWidth, barHeight);\r\n }\r\n\r\n\r\n}\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from \"./legend\";\r\n\r\nexport class HistogramConfig extends ChartConfig{\r\n\r\n svgClass= this.cssClassPrefix+'histogram';\r\n showLegend=true;\r\n showTooltip =true;\r\n legend={\r\n width: 80,\r\n margin: 10,\r\n shapeWidth: 20\r\n };\r\n x={// X axis config\r\n label: '', // axis label\r\n key: 0,\r\n value: (d, key) => Utils.isNumber(d) ? d : d[key], // x value accessor\r\n scale: \"linear\",\r\n ticks: undefined,\r\n };\r\n y={// Y axis config\r\n label: '', // axis label,\r\n orient: \"left\",\r\n scale: \"linear\"\r\n };\r\n frequency=true;\r\n groups={\r\n key: 1,\r\n value: (d) => d[this.groups.key] , // grouping value accessor,\r\n label: \"\"\r\n };\r\n color = undefined // string or function returning color's value for color scale\r\n d3ColorCategory= 'category10';\r\n transition= true;\r\n\r\n constructor(custom){\r\n super();\r\n var config = this;\r\n\r\n if(custom){\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class Histogram extends Chart{\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new HistogramConfig(config));\r\n }\r\n\r\n setConfig(config){\r\n return super.setConfig(new HistogramConfig(config));\r\n }\r\n\r\n initPlot(){\r\n super.initPlot();\r\n var self=this;\r\n\r\n var conf = this.config;\r\n\r\n this.plot.x={};\r\n this.plot.y={};\r\n this.plot.bar={\r\n color: null//color scale mapping function\r\n };\r\n\r\n this.plot.showLegend = conf.showLegend;\r\n if(this.plot.showLegend){\r\n this.plot.margin.right = conf.margin.right + conf.legend.width+conf.legend.margin*2;\r\n }\r\n\r\n\r\n this.computePlotSize();\r\n\r\n\r\n\r\n if(conf.d3ColorCategory){\r\n this.plot.colorCategory = d3.scale[conf.d3ColorCategory]();\r\n }\r\n var colorValue = conf.color;\r\n if (colorValue && typeof colorValue === 'string' || colorValue instanceof String){\r\n this.plot.color = colorValue;\r\n }else if(this.plot.colorCategory){\r\n if(this.config.groups){\r\n var domain = Object.getOwnPropertyNames(d3.map(this.data, d => this.config.groups.value.call(this.config, d))['_']);\r\n self.plot.colorCategory.domain(domain);\r\n }\r\n\r\n this.plot.color = d => self.plot.colorCategory(d.key);\r\n }\r\n\r\n this.plot.data = this.getDataToPlot();\r\n this.setupX();\r\n this.setupHistogram();\r\n this.setupGroupStacks();\r\n this.setupY();\r\n\r\n return this;\r\n }\r\n\r\n setupX(){\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config.x;\r\n\r\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\r\n x.value = d => conf.value(d, conf.key);\r\n x.scale = d3.scale[conf.scale]().range([0, plot.width]);\r\n x.map = d => x.scale(x.value(d));\r\n\r\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\r\n if(conf.ticks){\r\n x.axis.ticks(conf.ticks);\r\n }\r\n var data = this.plot.data;\r\n plot.x.scale.domain([d3.min(data, plot.x.value), d3.max(data, plot.x.value)]);\r\n \r\n };\r\n\r\n setupY (){\r\n\r\n var plot = this.plot;\r\n var y = plot.y;\r\n var conf = this.config.y;\r\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\r\n\r\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\r\n\r\n var data = this.plot.data;\r\n plot.y.scale.domain([0, d3.max(plot.histogramBins, d=>d.y)]);\r\n };\r\n\r\n setupHistogram() {\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var y = plot.y;\r\n var ticks = this.config.x.ticks ? x.scale.ticks(this.config.x.ticks) : x.scale.ticks();\r\n\r\n plot.histogram = d3.layout.histogram().frequency(this.config.frequency)\r\n .value(x.value)\r\n .bins(ticks);\r\n plot.histogramBins = plot.histogram(this.plot.data);\r\n\r\n }\r\n\r\n setupGroupStacks() {\r\n var self=this;\r\n this.plot.groupingEnabled = this.config.groups && this.config.groups.value;\r\n \r\n this.plot.stack = d3.layout.stack().values(d=>d.histogramBins);\r\n this.plot.groupedData = d3.nest().key(d => this.plot.groupingEnabled ? this.config.groups.value.call(this.config, d) : 'root' ).entries(this.plot.data);\r\n this.plot.groupedData.forEach(d=>{\r\n d.histogramBins = this.plot.histogram.frequency(this.config.frequency || this.plot.groupingEnabled)(d.values);\r\n if(!this.config.frequency && this.plot.groupingEnabled){\r\n d.histogramBins.forEach(b => {\r\n b.dy = b.dy/this.plot.data.length\r\n b.y = b.y/this.plot.data.length\r\n });\r\n }\r\n });\r\n this.plot.stackedHistograms = this.plot.stack(this.plot.groupedData);\r\n }\r\n\r\n getDataToPlot(){\r\n if(!this.enabledGroups){\r\n return this.data;\r\n }\r\n\r\n return this.data.filter(d => this.enabledGroups.indexOf(this.config.groups.value.call(this.config, d))>-1);\r\n }\r\n\r\n drawAxisX(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.x;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-x')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')))\r\n .attr(\"transform\", \"translate(0,\" + plot.height + \")\");\r\n\r\n var axisT = axis;\r\n if (self.config.transition) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.x.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ (plot.width/2) +\",\"+ (plot.margin.bottom) +\")\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"-1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n drawAxisY(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.y;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-y')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')));\r\n\r\n var axisT = axis;\r\n if (self.config.transition) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.y.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ -plot.margin.left +\",\"+(plot.height/2)+\")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n\r\n drawHistogram() {\r\n var self = this;\r\n var plot = self.plot;\r\n \r\n var layerClass = this.prefixClass(\"layer\");\r\n\r\n var barClass = this.prefixClass(\"bar\");\r\n var layer = self.svgG.selectAll(\".\"+layerClass)\r\n .data(plot.stackedHistograms);\r\n\r\n layer.enter().append(\"g\")\r\n .attr(\"class\", layerClass);\r\n\r\n var bar = layer.selectAll(\".\"+barClass)\r\n .data(d => d.histogramBins);\r\n\r\n bar.enter().append(\"g\")\r\n .attr(\"class\", barClass)\r\n .append(\"rect\")\r\n .attr(\"x\", 1);\r\n\r\n\r\n var barRect = bar.select(\"rect\");\r\n\r\n var barRectT = barRect;\r\n var barT = bar;\r\n var layerT = layer;\r\n if (this.transitionEnabled()) {\r\n barRectT = barRect.transition();\r\n barT = bar.transition();\r\n layerT= layer.transition();\r\n }\r\n\r\n barT.attr(\"transform\", function(d) { return \"translate(\" + plot.x.scale(d.x) + \",\" + (plot.y.scale(d.y0 +d.y)) + \")\"; });\r\n\r\n var dx = plot.histogramBins.length ? plot.x.scale(plot.histogramBins[0].dx) : 0;\r\n barRectT\r\n .attr(\"width\", dx - plot.x.scale(0)- 1)\r\n .attr(\"height\", d => plot.height - plot.y.scale(d.y));\r\n\r\n if(this.plot.color){\r\n layerT\r\n .attr(\"fill\", this.plot.color);\r\n }\r\n\r\n if (plot.tooltip) {\r\n bar.on(\"mouseover\", d => {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n plot.tooltip.html(d.y)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n }).on(\"mouseout\", d => {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n layer.exit().remove();\r\n bar.exit().remove();\r\n }\r\n\r\n update(newData){\r\n super.update(newData);\r\n this.drawAxisX();\r\n this.drawAxisY();\r\n\r\n this.drawHistogram();\r\n\r\n this.updateLegend();\r\n };\r\n\r\n\r\n updateLegend() {\r\n var plot = this.plot;\r\n\r\n var scale = plot.colorCategory;\r\n if(!scale.domain() || scale.domain().length<2){\r\n plot.showLegend = false;\r\n }\r\n\r\n if(!plot.showLegend){\r\n if(plot.legend && plot.legend.container){\r\n plot.legend.container.remove();\r\n }\r\n return;\r\n }\r\n\r\n\r\n var legendX = this.plot.width + this.config.legend.margin;\r\n var legendY = this.config.legend.margin;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY);\r\n\r\n plot.legendColor = plot.legend.color()\r\n .shapeWidth(this.config.legend.shapeWidth)\r\n .orient('vertical')\r\n .scale(scale);\r\n\r\n\r\n plot.legendColor.on('cellclick', c=> this.onLegendCellClick(c));\r\n\r\n plot.legend.container\r\n .call(plot.legendColor);\r\n }\r\n\r\n onLegendCellClick(cellValue){\r\n this.updateEnabledGroups(cellValue);\r\n\r\n var isDisabled = this.enabledGroups.indexOf(cellValue)<0;\r\n this.plot.legend.container.selectAll(\"g.cell\").each(function(cell){\r\n if(cell == cellValue){\r\n d3.select(this).classed(\"odc-disabled\", isDisabled);\r\n }\r\n\r\n });\r\n\r\n this.init();\r\n }\r\n\r\n updateEnabledGroups(cellValue) {\r\n if (!this.enabledGroups) {\r\n this.enabledGroups = this.plot.colorCategory.domain().slice();\r\n }\r\n var index = this.enabledGroups.indexOf(cellValue);\r\n\r\n if (index < 0) {\r\n this.enabledGroups.push(cellValue);\r\n } else {\r\n this.enabledGroups.splice(index, 1);\r\n }\r\n }\r\n\r\n\r\n\r\n setData(data){\r\n super.setData(data);\r\n this.enabledGroups = null;\r\n }\r\n}\r\n","import {D3Extensions} from './d3-extensions'\r\nD3Extensions.extend();\r\n\r\nexport {ScatterPlot, ScatterPlotConfig} from \"./scatterplot\";\r\nexport {ScatterPlotMatrix, ScatterPlotMatrixConfig} from \"./scatterplot-matrix\";\r\nexport {CorrelationMatrix, CorrelationMatrixConfig} from './correlation-matrix'\r\nexport {Regression, RegressionConfig} from './regression'\r\nexport {Heatmap, HeatmapConfig} from './heatmap'\r\nexport {HeatmapTimeSeries, HeatmapTimeSeriesConfig} from './heatmap-timeseries'\r\nexport {Histogram, HistogramConfig} from './histogram'\r\nexport {BarChart, BarChartConfig} from './bar-chart'\r\nexport {StatisticsUtils} from './statistics-utils'\r\nexport {Legend} from './legend'\r\n\r\n\r\n\r\n\r\n\r\n","import {Utils} from \"./utils\";\r\nimport {color, size, symbol} from \"../bower_components/d3-legend/no-extend\";\r\n\r\n/*var d3 = require('../bower_components/d3');\r\n*/\r\n// var legend = require('../bower_components/d3-legend/no-extend');\r\n//\r\n// module.exports.legend = legend;\r\n\r\nexport class Legend {\r\n\r\n cssClassPrefix=\"odc-\";\r\n legendClass=this.cssClassPrefix+\"legend\";\r\n container;\r\n scale;\r\n color= color;\r\n size = size;\r\n symbol= symbol;\r\n guid;\r\n\r\n labelFormat = undefined;\r\n\r\n constructor(svg, legendParent, scale, legendX, legendY, labelFormat){\r\n this.scale=scale;\r\n this.svg = svg;\r\n this.guid = Utils.guid();\r\n this.container = Utils.selectOrAppend(legendParent, \"g.\"+this.legendClass, \"g\")\r\n .attr(\"transform\", \"translate(\"+legendX+\",\"+legendY+\")\")\r\n .classed(this.legendClass, true);\r\n\r\n this.labelFormat = labelFormat;\r\n }\r\n\r\n\r\n\r\n linearGradientBar(barWidth, barHeight, title){\r\n var gradientId = this.cssClassPrefix+\"linear-gradient\"+\"-\"+this.guid;\r\n var scale= this.scale;\r\n var self = this;\r\n\r\n this.linearGradient = Utils.linearGradient(this.svg, gradientId, this.scale.range(), 0, 100, 0, 0);\r\n\r\n this.container.append(\"rect\")\r\n .attr(\"width\", barWidth)\r\n .attr(\"height\", barHeight)\r\n .attr(\"x\", 0)\r\n .attr(\"y\", 0)\r\n .style(\"fill\", \"url(#\"+gradientId+\")\");\r\n\r\n\r\n var ticks = this.container.selectAll(\"text\")\r\n .data( scale.domain() );\r\n var ticksNumber =scale.domain().length-1;\r\n ticks.enter().append(\"text\");\r\n\r\n ticks.attr(\"x\", barWidth)\r\n .attr(\"y\", (d, i) => barHeight -(i*barHeight/ticksNumber))\r\n .attr(\"dx\", 3)\r\n // .attr(\"dy\", 1)\r\n .attr(\"alignment-baseline\", \"middle\")\r\n .text(d=> self.labelFormat ? self.labelFormat(d) : d);\r\n ticks.attr(\"dominant-baseline\", \"middle\")\r\n if(this.rotateLabels){\r\n ticks\r\n .attr(\"transform\", (d, i) => \"rotate(-45, \" + barWidth + \", \" + (barHeight -(i*barHeight/ticksNumber)) + \")\")\r\n .attr(\"text-anchor\", \"start\")\r\n .attr(\"dx\", 5)\r\n .attr(\"dy\", 5);\r\n\r\n }else{\r\n\r\n }\r\n\r\n ticks.exit().remove();\r\n\r\n return this;\r\n }\r\n\r\n setRotateLabels(rotateLabels) {\r\n this.rotateLabels = rotateLabels;\r\n return this;\r\n }\r\n\r\n \r\n}","import {Chart, ChartConfig} from \"./chart\";\r\nimport {ScatterPlot, ScatterPlotConfig} from \"./scatterplot\";\r\nimport {Utils} from './utils'\r\nimport {StatisticsUtils} from './statistics-utils'\r\n\r\n\r\nexport class RegressionConfig extends ScatterPlotConfig{\r\n\r\n mainRegression = true;\r\n groupRegression = true;\r\n confidence={\r\n level: 0.95,\r\n criticalValue: (degreesOfFreedom, criticalProbability) => StatisticsUtils.tValue(degreesOfFreedom, criticalProbability),\r\n marginOfError: undefined //custom margin Of Error function (x, points)\r\n };\r\n\r\n constructor(custom){\r\n super();\r\n\r\n if(custom){\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class Regression extends ScatterPlot{\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new RegressionConfig(config));\r\n }\r\n\r\n setConfig(config){\r\n return super.setConfig(new RegressionConfig(config));\r\n }\r\n\r\n initPlot(){\r\n super.initPlot();\r\n this.initRegressionLines();\r\n }\r\n\r\n initRegressionLines(){\r\n\r\n var self = this;\r\n var groupsAvailable = self.config.groups && self.config.groups.value;\r\n\r\n self.plot.regressions= [];\r\n\r\n\r\n if(groupsAvailable && self.config.mainRegression){\r\n var regression = this.initRegression(this.plot.data, false);\r\n self.plot.regressions.push(regression);\r\n }\r\n\r\n if(self.config.groupRegression){\r\n this.initGroupRegression();\r\n }\r\n\r\n }\r\n\r\n initGroupRegression() {\r\n var self = this;\r\n var dataByGroup = {};\r\n this.plot.data.forEach (d=>{\r\n var groupVal = self.config.groups.value(d, self.config.groups.key);\r\n\r\n if(!groupVal && groupVal!==0){\r\n return;\r\n }\r\n\r\n if(!dataByGroup[groupVal]){\r\n dataByGroup[groupVal] = [];\r\n }\r\n dataByGroup[groupVal].push(d);\r\n });\r\n\r\n for(var key in dataByGroup){\r\n if (!dataByGroup.hasOwnProperty(key)) {\r\n continue;\r\n }\r\n\r\n var regression = this.initRegression(dataByGroup[key], key);\r\n self.plot.regressions.push(regression);\r\n }\r\n }\r\n\r\n initRegression(values, groupVal){\r\n var self = this;\r\n\r\n var points = values.map(d=>{\r\n return [parseFloat(self.plot.x.value(d)), parseFloat(self.plot.y.value(d))];\r\n });\r\n\r\n // points.sort((a,b) => a[0]-b[0]);\r\n\r\n var linearRegression = StatisticsUtils.linearRegression(points);\r\n var linearRegressionLine = StatisticsUtils.linearRegressionLine(linearRegression);\r\n\r\n\r\n var extentX = d3.extent(points, d=>d[0]);\r\n\r\n\r\n var linePoints = [\r\n {\r\n x: extentX[0],\r\n y: linearRegressionLine(extentX[0])\r\n },\r\n {\r\n x: extentX[1],\r\n y: linearRegressionLine(extentX[1])\r\n }\r\n ];\r\n\r\n var line = d3.svg.line()\r\n .interpolate(\"basis\")\r\n .x(d => self.plot.x.scale(d.x))\r\n .y(d => self.plot.y.scale(d.y));\r\n \r\n\r\n var color = self.plot.dot.color;\r\n\r\n var defaultColor = \"black\";\r\n if(Utils.isFunction(color)){\r\n if(values.length && groupVal!==false){\r\n color = color(values[0]);\r\n }else{\r\n color = defaultColor;\r\n }\r\n }else if(!color && groupVal===false){\r\n color = defaultColor;\r\n }\r\n\r\n\r\n var confidence = this.computeConfidence(points, extentX, linearRegression,linearRegressionLine);\r\n return {\r\n group: groupVal || false,\r\n line: line,\r\n linePoints: linePoints,\r\n color: color,\r\n confidence: confidence\r\n };\r\n }\r\n\r\n computeConfidence(points, extentX, linearRegression,linearRegressionLine){\r\n var self = this;\r\n var slope = linearRegression.m;\r\n var n = points.length;\r\n var degreesOfFreedom = Math.max(0, n-2);\r\n\r\n var alpha = 1 - self.config.confidence.level;\r\n var criticalProbability = 1 - alpha/2;\r\n var criticalValue = self.config.confidence.criticalValue(degreesOfFreedom,criticalProbability);\r\n\r\n var xValues = points.map(d=>d[0]);\r\n var meanX = StatisticsUtils.mean(xValues);\r\n var xMySum=0;\r\n var xSum=0;\r\n var xPowSum=0;\r\n var ySum=0;\r\n var yPowSum=0;\r\n points.forEach(p=>{\r\n var x = p[0];\r\n var y = p[1];\r\n\r\n xMySum += x*y;\r\n xSum+=x;\r\n ySum+=y;\r\n xPowSum+= x*x;\r\n yPowSum+= y*y;\r\n });\r\n var a = linearRegression.m;\r\n var b = linearRegression.b;\r\n\r\n var Sa2 = n/(n+2) * ((yPowSum-a*xMySum-b*ySum)/(n*xPowSum-(xSum*xSum))); //Wariancja współczynnika kierunkowego regresji liniowej a\r\n var Sy2 = (yPowSum - a*xMySum-b*ySum)/(n*(n-2)); //Sa2 //Mean y value variance\r\n\r\n var errorFn = x=> Math.sqrt(Sy2 + Math.pow(x-meanX,2)*Sa2); //pierwiastek kwadratowy z wariancji dowolnego punktu prostej\r\n var marginOfError = x=> criticalValue* errorFn(x);\r\n\r\n\r\n // console.log('n', n, 'degreesOfFreedom', degreesOfFreedom, 'criticalProbability',criticalProbability);\r\n // var confidenceDown = x => linearRegressionLine(x) - marginOfError(x);\r\n // var confidenceUp = x => linearRegressionLine(x) + marginOfError(x);\r\n\r\n\r\n var computeConfidenceAreaPoint = x=>{\r\n var linearRegression = linearRegressionLine(x);\r\n var moe = marginOfError(x);\r\n var confDown = linearRegression - moe;\r\n var confUp = linearRegression + moe;\r\n return {\r\n x: x,\r\n y0: confDown,\r\n y1: confUp\r\n }\r\n\r\n };\r\n\r\n var centerX = (extentX[1]+extentX[0])/2;\r\n\r\n // var confidenceAreaPoints = [extentX[0], centerX, extentX[1]].map(computeConfidenceAreaPoint);\r\n var confidenceAreaPoints = [extentX[0], centerX, extentX[1]].map(computeConfidenceAreaPoint);\r\n\r\n var fitInPlot = y => y;\r\n\r\n var confidenceArea = d3.svg.area()\r\n .interpolate(\"monotone\")\r\n .x(d => self.plot.x.scale(d.x))\r\n .y0(d => fitInPlot(self.plot.y.scale(d.y0)))\r\n .y1(d => fitInPlot(self.plot.y.scale(d.y1)));\r\n\r\n return {\r\n area:confidenceArea,\r\n points:confidenceAreaPoints\r\n };\r\n }\r\n\r\n update(newData){\r\n super.update(newData);\r\n this.updateRegressionLines();\r\n\r\n };\r\n\r\n updateRegressionLines() {\r\n var self = this;\r\n var regressionContainerClass = this.prefixClass(\"regression-container\");\r\n var regressionContainerSelector = \"g.\"+regressionContainerClass;\r\n\r\n var clipPathId = self.prefixClass(\"clip\");\r\n\r\n var regressionContainer = self.svgG.selectOrInsert(regressionContainerSelector, \".\"+self.dotsContainerClass);\r\n var regressionContainerClip = regressionContainer.selectOrAppend(\"clipPath\")\r\n .attr(\"id\", clipPathId);\r\n\r\n\r\n regressionContainerClip.selectOrAppend('rect')\r\n .attr('width', self.plot.width)\r\n .attr('height', self.plot.height)\r\n .attr('x', 0)\r\n .attr('y', 0);\r\n\r\n regressionContainer.attr(\"clip-path\", (d,i) => \"url(#\"+clipPathId+\")\");\r\n\r\n var regressionClass = this.prefixClass(\"regression\");\r\n var confidenceAreaClass = self.prefixClass(\"confidence\");\r\n var regressionSelector = \"g.\"+regressionClass;\r\n var regression = regressionContainer.selectAll(regressionSelector)\r\n .data(self.plot.regressions, (d,i)=> d.group);\r\n\r\n var regressionEnterG = regression.enter().insertSelector(regressionSelector);\r\n var lineClass = self.prefixClass(\"line\");\r\n regressionEnterG\r\n\r\n .append(\"path\")\r\n .attr(\"class\", lineClass)\r\n .attr(\"shape-rendering\", \"optimizeQuality\");\r\n // .append(\"line\")\r\n // .attr(\"class\", \"line\")\r\n // .attr(\"shape-rendering\", \"optimizeQuality\");\r\n\r\n var line = regression.select(\"path.\"+lineClass)\r\n .style(\"stroke\", r => r.color);\r\n // .attr(\"x1\", r=> self.plot.x.scale(r.linePoints[0].x))\r\n // .attr(\"y1\", r=> self.plot.y.scale(r.linePoints[0].y))\r\n // .attr(\"x2\", r=> self.plot.x.scale(r.linePoints[1].x))\r\n // .attr(\"y2\", r=> self.plot.y.scale(r.linePoints[1].y))\r\n\r\n\r\n var lineT = line;\r\n if (self.transitionEnabled()) {\r\n lineT = line.transition();\r\n }\r\n\r\n lineT.attr(\"d\", r => r.line(r.linePoints))\r\n\r\n\r\n regressionEnterG\r\n .append(\"path\")\r\n .attr(\"class\", confidenceAreaClass)\r\n .attr(\"shape-rendering\", \"optimizeQuality\")\r\n .style(\"opacity\", \"0.4\");\r\n\r\n\r\n\r\n var area = regression.select(\"path.\"+confidenceAreaClass);\r\n\r\n var areaT = area;\r\n if (self.transitionEnabled()) {\r\n areaT = area.transition();\r\n }\r\n areaT.attr(\"d\", r => r.confidence.area(r.confidence.points));\r\n areaT.style(\"fill\", r => r.color)\r\n regression.exit().remove();\r\n\r\n }\r\n\r\n\r\n\r\n}\r\n\r\n","import {Chart, ChartConfig} from \"./chart\";\r\nimport {ScatterPlotConfig} from \"./scatterplot\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from \"./legend\";\r\n\r\nexport class ScatterPlotMatrixConfig extends ScatterPlotConfig{\r\n\r\n svgClass= this.cssClassPrefix+'scatterplot-matrix';\r\n size= 200; //scatter plot cell size\r\n padding= 20; //scatter plot cell padding\r\n brush= true;\r\n guides= true; //show axis guides\r\n showTooltip= true; //show tooltip on dot hover\r\n ticks= undefined; //ticks number, (default: computed using cell size)\r\n x={// X axis config\r\n orient: \"bottom\",\r\n scale: \"linear\"\r\n };\r\n y={// Y axis config\r\n orient: \"left\",\r\n scale: \"linear\"\r\n };\r\n groups={\r\n key: undefined, //object property name or array index with grouping variable\r\n includeInPlot: false, //include group as variable in plot, boolean (default: false)\r\n value: (d, key) => d[key], // grouping value accessor,\r\n label: \"\"\r\n };\r\n variables= {\r\n labels: [], //optional array of variable labels (for the diagonal of the plot).\r\n keys: [], //optional array of variable keys\r\n value: (d, variableKey) => d[variableKey] // variable value accessor\r\n };\r\n\r\n constructor(custom){\r\n super();\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n\r\n}\r\n\r\nexport class ScatterPlotMatrix extends Chart {\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new ScatterPlotMatrixConfig(config));\r\n }\r\n\r\n setConfig(config) {\r\n return super.setConfig(new ScatterPlotMatrixConfig(config));\r\n\r\n }\r\n\r\n initPlot() {\r\n super.initPlot();\r\n\r\n var self = this;\r\n var margin = this.plot.margin;\r\n var conf = this.config;\r\n this.plot.x={};\r\n this.plot.y={};\r\n this.plot.dot={\r\n color: null//color scale mapping function\r\n };\r\n\r\n\r\n this.plot.showLegend = conf.showLegend;\r\n if(this.plot.showLegend){\r\n margin.right = conf.margin.right + conf.legend.width+conf.legend.margin*2;\r\n }\r\n\r\n this.setupGroups();\r\n\r\n this.plot.data = this.getDataToPlot();\r\n this.setupVariables();\r\n\r\n this.plot.size = conf.size;\r\n\r\n\r\n var width = conf.width;\r\n var boundingClientRect = this.getBaseContainerNode().getBoundingClientRect();\r\n if (!width) {\r\n var maxWidth = margin.left + margin.right + this.plot.variables.length*this.plot.size;\r\n width = Math.min(boundingClientRect.width, maxWidth);\r\n\r\n }\r\n var height = width;\r\n if (!height) {\r\n height = boundingClientRect.height;\r\n }\r\n\r\n this.plot.width = width - margin.left - margin.right;\r\n this.plot.height = height - margin.top - margin.bottom;\r\n\r\n\r\n\r\n\r\n if(conf.ticks===undefined){\r\n conf.ticks = this.plot.size / 40;\r\n }\r\n\r\n\r\n\r\n this.setupX();\r\n this.setupY();\r\n\r\n return this;\r\n\r\n };\r\n\r\n setupGroups() {\r\n var self=this;\r\n var conf = this.config;\r\n this.plot.groupValue = d => conf.groups.value(d, conf.groups.key);\r\n if(conf.dot.d3ColorCategory){\r\n this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();\r\n }\r\n var colorValue = conf.dot.color;\r\n if(colorValue){\r\n this.plot.dot.colorValue = colorValue;\r\n\r\n if (typeof colorValue === 'string' || colorValue instanceof String){\r\n this.plot.dot.color = colorValue;\r\n }else if(this.plot.dot.colorCategory){\r\n var domain = Object.getOwnPropertyNames(d3.map(this.data, d => self.plot.dot.colorValue.call(self,d))['_']);\r\n self.plot.dot.colorCategory.domain(domain);\r\n this.plot.dot.color = d => self.plot.dot.colorCategory(self.plot.dot.colorValue.call(self,d));\r\n }\r\n }\r\n }\r\n\r\n getDataToPlot(){\r\n if(!this.enabledGroups){\r\n return this.data;\r\n }\r\n\r\n var filter = this.data.filter(d => this.enabledGroups.indexOf(this.plot.groupValue(d))>-1);\r\n console.log(filter.length);\r\n return filter;\r\n }\r\n\r\n setupVariables() {\r\n var variablesConf = this.config.variables;\r\n\r\n var data = this.data;\r\n var plot = this.plot;\r\n plot.domainByVariable = {};\r\n plot.variables = variablesConf.keys;\r\n if(!plot.variables || !plot.variables.length){\r\n plot.variables = Utils.inferVariables(data, this.config.groups.key, this.config.includeInPlot);\r\n }\r\n\r\n plot.labels = [];\r\n plot.labelByVariable = {};\r\n plot.variables.forEach((variableKey, index) => {\r\n plot.domainByVariable[variableKey] = d3.extent(data, function(d) { return variablesConf.value(d, variableKey) });\r\n var label = variableKey;\r\n if(variablesConf.labels && variablesConf.labels.length>index){\r\n\r\n label = variablesConf.labels[index];\r\n }\r\n plot.labels.push(label);\r\n plot.labelByVariable[variableKey] = label;\r\n });\r\n\r\n console.log(plot.labelByVariable);\r\n\r\n plot.subplots = [];\r\n };\r\n\r\n setupX() {\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config;\r\n\r\n x.value = conf.variables.value;\r\n x.scale = d3.scale[conf.x.scale]().range([conf.padding / 2, plot.size - conf.padding / 2]);\r\n x.map = (d, variable) => x.scale(x.value(d, variable));\r\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.x.orient).ticks(conf.ticks);\r\n x.axis.tickSize(plot.size * plot.variables.length);\r\n\r\n };\r\n\r\n setupY() {\r\n\r\n var plot = this.plot;\r\n var y = plot.y;\r\n var conf = this.config;\r\n\r\n y.value = conf.variables.value;\r\n y.scale = d3.scale[conf.y.scale]().range([ plot.size - conf.padding / 2, conf.padding / 2]);\r\n y.map = (d, variable) => y.scale(y.value(d, variable));\r\n y.axis= d3.svg.axis().scale(y.scale).orient(conf.y.orient).ticks(conf.ticks);\r\n y.axis.tickSize(-plot.size * plot.variables.length);\r\n };\r\n\r\n update( newData) {\r\n super.update(newData);\r\n\r\n var self =this;\r\n var n = self.plot.variables.length;\r\n var conf = this.config;\r\n\r\n var axisClass = self.prefixClass(\"axis\");\r\n var axisXClass = axisClass+\"-x\";\r\n var axisYClass = axisClass+\"-y\";\r\n\r\n var xAxisSelector = \"g.\"+axisXClass+\".\"+axisClass;\r\n var yAxisSelector = \"g.\"+axisYClass+\".\"+axisClass;\r\n\r\n var noGuidesClass = self.prefixClass(\"no-guides\");\r\n self.svgG.selectAll(xAxisSelector)\r\n .data(self.plot.variables)\r\n .enter().appendSelector(xAxisSelector)\r\n .classed(noGuidesClass, !conf.guides)\r\n .attr(\"transform\", (d, i) => \"translate(\" + (n - i - 1) * self.plot.size + \",0)\")\r\n .each(function(d) { self.plot.x.scale.domain(self.plot.domainByVariable[d]); d3.select(this).call(self.plot.x.axis); });\r\n\r\n self.svgG.selectAll(yAxisSelector)\r\n .data(self.plot.variables)\r\n .enter().appendSelector(yAxisSelector)\r\n .classed(noGuidesClass, !conf.guides)\r\n .attr(\"transform\", (d, i) => \"translate(0,\" + i * self.plot.size + \")\")\r\n .each(function(d) { self.plot.y.scale.domain(self.plot.domainByVariable[d]); d3.select(this).call(self.plot.y.axis); });\r\n\r\n var cellClass = self.prefixClass(\"cell\");\r\n var cell = self.svgG.selectAll(\".\"+cellClass)\r\n .data(self.utils.cross(self.plot.variables, self.plot.variables));\r\n\r\n cell.enter().appendSelector(\"g.\"+cellClass).filter(d => d.i === d.j)\r\n .append(\"text\");\r\n\r\n cell.attr(\"transform\", d => \"translate(\" + (n - d.i - 1) * self.plot.size + \",\" + d.j * self.plot.size + \")\");\r\n\r\n if(conf.brush){\r\n this.drawBrush(cell);\r\n }\r\n\r\n cell.each(plotSubplot);\r\n\r\n //Labels\r\n cell.select(\"text\")\r\n .attr(\"x\", conf.padding)\r\n .attr(\"y\", conf.padding)\r\n .attr(\"dy\", \".71em\")\r\n .text( d => self.plot.labelByVariable[d.x]);\r\n\r\n\r\n\r\n\r\n function plotSubplot(p) {\r\n var plot = self.plot;\r\n plot.subplots.push(p);\r\n var cell = d3.select(this);\r\n\r\n plot.x.scale.domain(plot.domainByVariable[p.x]);\r\n plot.y.scale.domain(plot.domainByVariable[p.y]);\r\n\r\n var frameClass = self.prefixClass(\"frame\");\r\n cell.selectOrAppend(\"rect.\"+frameClass)\r\n .attr(\"class\", frameClass)\r\n .attr(\"x\", conf.padding / 2)\r\n .attr(\"y\", conf.padding / 2)\r\n .attr(\"width\", conf.size - conf.padding)\r\n .attr(\"height\", conf.size - conf.padding);\r\n\r\n\r\n p.update = function() {\r\n\r\n var subplot = this;\r\n var dots = cell.selectAll(\"circle\")\r\n .data(self.plot.data);\r\n\r\n dots.enter().append(\"circle\");\r\n\r\n var dotsT = dots;\r\n if (self.transitionEnabled()) {\r\n dotsT = dots.transition();\r\n }\r\n\r\n dotsT.attr(\"cx\", (d) => plot.x.map(d, subplot.x))\r\n .attr(\"cy\", (d) => plot.y.map(d, subplot.y))\r\n .attr(\"r\", self.config.dot.radius);\r\n\r\n if (plot.dot.color) {\r\n dotsT.style(\"fill\", plot.dot.color)\r\n }\r\n\r\n if(plot.tooltip){\r\n dots.on(\"mouseover\", (d) => {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = \"(\" + plot.x.value(d, subplot.x) + \", \" +plot.y.value(d, subplot.y) + \")\";\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n\r\n var group = self.config.groups ? self.config.groups.value(d) : false;\r\n if(group || group===0 ){\r\n html+=\"
\";\r\n var label = self.config.groups.label;\r\n if(label){\r\n html+=label+\": \";\r\n }\r\n html+=group\r\n }\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n })\r\n .on(\"mouseout\", (d)=> {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n\r\n dots.exit().remove();\r\n };\r\n p.update();\r\n\r\n }\r\n\r\n\r\n this.updateLegend();\r\n };\r\n\r\n drawBrush(cell) {\r\n var self = this;\r\n var brush = d3.svg.brush()\r\n .x(self.plot.x.scale)\r\n .y(self.plot.y.scale)\r\n .on(\"brushstart\", brushstart)\r\n .on(\"brush\", brushmove)\r\n .on(\"brushend\", brushend);\r\n\r\n cell.append(\"g\").call(brush);\r\n\r\n\r\n var brushCell;\r\n\r\n // Clear the previously-active brush, if any.\r\n function brushstart(p) {\r\n if (brushCell !== this) {\r\n d3.select(brushCell).call(brush.clear());\r\n self.plot.x.scale.domain(self.plot.domainByVariable[p.x]);\r\n self.plot.y.scale.domain(self.plot.domainByVariable[p.y]);\r\n brushCell = this;\r\n }\r\n }\r\n\r\n // Highlight the selected circles.\r\n function brushmove(p) {\r\n var e = brush.extent();\r\n self.svgG.selectAll(\"circle\").classed(\"hidden\", function (d) {\r\n return e[0][0] > d[p.x] || d[p.x] > e[1][0]\r\n || e[0][1] > d[p.y] || d[p.y] > e[1][1];\r\n });\r\n }\r\n // If the brush is empty, select all circles.\r\n function brushend() {\r\n if (brush.empty()) self.svgG.selectAll(\".hidden\").classed(\"hidden\", false);\r\n }\r\n };\r\n\r\n updateLegend() {\r\n\r\n var self =this;\r\n var plot = this.plot;\r\n\r\n var scale = plot.dot.colorCategory;\r\n\r\n\r\n\r\n if(!scale.domain() || scale.domain().length<2){\r\n plot.showLegend = false;\r\n }\r\n\r\n if(!plot.showLegend){\r\n if(plot.legend && plot.legend.container){\r\n plot.legend.container.remove();\r\n }\r\n return;\r\n }\r\n\r\n\r\n var legendX = this.plot.width + this.config.legend.margin;\r\n var legendY = this.config.legend.margin;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY);\r\n\r\n plot.legendColor = plot.legend.color()\r\n .shapeWidth(this.config.legend.shapeWidth)\r\n .orient('vertical')\r\n .scale(scale);\r\n\r\n\r\n plot.legendColor.on('cellclick', c=> self.onLegendCellClick(c));\r\n\r\n plot.legend.container\r\n .call(plot.legendColor);\r\n }\r\n\r\n onLegendCellClick(cellValue){\r\n this.updateEnabledGroups(cellValue);\r\n\r\n var isDisabled = this.enabledGroups.indexOf(cellValue)<0;\r\n this.plot.legend.container.selectAll(\"g.cell\").each(function(cell){\r\n if(cell == cellValue){\r\n d3.select(this).classed(\"odc-disabled\", isDisabled);\r\n }\r\n\r\n });\r\n\r\n this.init();\r\n }\r\n\r\n updateEnabledGroups(cellValue) {\r\n if (!this.enabledGroups) {\r\n this.enabledGroups = this.plot.dot.colorCategory.domain().slice();\r\n }\r\n var index = this.enabledGroups.indexOf(cellValue);\r\n\r\n if (index < 0) {\r\n this.enabledGroups.push(cellValue);\r\n } else {\r\n this.enabledGroups.splice(index, 1);\r\n }\r\n }\r\n\r\n\r\n\r\n setData(data){\r\n super.setData(data);\r\n this.enabledGroups = null;\r\n }\r\n}","import {Chart, ChartConfig} from \"./chart\";\r\nimport {Utils} from './utils'\r\nimport {Legend} from \"./legend\";\r\n\r\nexport class ScatterPlotConfig extends ChartConfig{\r\n\r\n svgClass= this.cssClassPrefix+'scatterplot';\r\n guides= false; //show axis guides\r\n showTooltip= true; //show tooltip on dot hover\r\n showLegend=true;\r\n legend={\r\n width: 80,\r\n margin: 10,\r\n shapeWidth: 20\r\n };\r\n\r\n x={// X axis config\r\n label: 'X', // axis label\r\n key: 0,\r\n value: (d, key) => d[key], // x value accessor\r\n orient: \"bottom\",\r\n scale: \"linear\"\r\n };\r\n y={// Y axis config\r\n label: 'Y', // axis label,\r\n key: 1,\r\n value: (d, key) => d[key], // y value accessor\r\n orient: \"left\",\r\n scale: \"linear\"\r\n };\r\n groups={\r\n key: 2,\r\n value: (d, key) => d[key] , // grouping value accessor,\r\n label: \"\"\r\n };\r\n dot = {\r\n radius: 2,\r\n color: d => this.groups ? this.groups.value(d, this.groups.key) : '', // string or function returning color's value for color scale\r\n d3ColorCategory: 'category10'\r\n };\r\n transition= true;\r\n\r\n constructor(custom){\r\n super();\r\n\r\n\r\n\r\n if(custom){\r\n Utils.deepExtend(this, custom);\r\n }\r\n\r\n }\r\n}\r\n\r\nexport class ScatterPlot extends Chart{\r\n constructor(placeholderSelector, data, config) {\r\n super(placeholderSelector, data, new ScatterPlotConfig(config));\r\n }\r\n\r\n setConfig(config){\r\n return super.setConfig(new ScatterPlotConfig(config));\r\n }\r\n\r\n initPlot(){\r\n super.initPlot();\r\n var self=this;\r\n\r\n var conf = this.config;\r\n\r\n this.plot.x={};\r\n this.plot.y={};\r\n this.plot.dot={\r\n color: null//color scale mapping function\r\n };\r\n\r\n\r\n this.plot.showLegend = conf.showLegend;\r\n if(this.plot.showLegend){\r\n this.plot.margin.right = conf.margin.right + conf.legend.width+conf.legend.margin*2;\r\n }\r\n \r\n\r\n this.computePlotSize();\r\n\r\n\r\n this.setupGroups();\r\n\r\n this.plot.data = this.getDataToPlot();\r\n this.setupX();\r\n this.setupY();\r\n\r\n\r\n\r\n return this;\r\n }\r\n\r\n setupGroups() {\r\n var self=this;\r\n var conf = this.config;\r\n this.plot.groupValue = d => conf.groups.value(d, conf.groups.key);\r\n if(conf.dot.d3ColorCategory){\r\n this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();\r\n }\r\n var colorValue = conf.dot.color;\r\n if(colorValue){\r\n this.plot.dot.colorValue = colorValue;\r\n\r\n if (typeof colorValue === 'string' || colorValue instanceof String){\r\n this.plot.dot.color = colorValue;\r\n }else if(this.plot.dot.colorCategory){\r\n var domain = Object.getOwnPropertyNames(d3.map(this.data, d => self.plot.dot.colorValue.call(self,d))['_']);\r\n self.plot.dot.colorCategory.domain(domain);\r\n this.plot.dot.color = d => self.plot.dot.colorCategory(self.plot.dot.colorValue.call(self,d));\r\n }\r\n }\r\n }\r\n\r\n getDataToPlot(){\r\n if(!this.enabledGroups){\r\n return this.data;\r\n }\r\n\r\n return this.data.filter(d => this.enabledGroups.indexOf(this.plot.groupValue(d))>-1);\r\n }\r\n\r\n setupX(){\r\n\r\n var plot = this.plot;\r\n var x = plot.x;\r\n var conf = this.config.x;\r\n\r\n /* *\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n **/\r\n x.value = d => conf.value(d, conf.key);\r\n x.scale = d3.scale[conf.scale]().range([0, plot.width]);\r\n x.map = d => x.scale(x.value(d));\r\n x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);\r\n var data = this.plot.data;\r\n plot.x.scale.domain([d3.min(data, plot.x.value)-1, d3.max(data, plot.x.value)+1]);\r\n if(this.config.guides) {\r\n x.axis.tickSize(-plot.height);\r\n }\r\n\r\n };\r\n\r\n setupY (){\r\n\r\n var plot = this.plot;\r\n var y = plot.y;\r\n var conf = this.config.y;\r\n\r\n /*\r\n * value accessor - returns the value to encode for a given data object.\r\n * scale - maps value to a visual display encoding, such as a pixel position.\r\n * map function - maps from data value to display value\r\n * axis - sets up axis\r\n */\r\n y.value = d => conf.value(d, conf.key);\r\n y.scale = d3.scale[conf.scale]().range([plot.height, 0]);\r\n y.map = d => y.scale(y.value(d));\r\n y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);\r\n\r\n if(this.config.guides){\r\n y.axis.tickSize(-plot.width);\r\n }\r\n\r\n\r\n var data = this.plot.data;\r\n plot.y.scale.domain([d3.min(data, plot.y.value)-1, d3.max(data, plot.y.value)+1]);\r\n };\r\n\r\n drawAxisX(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.x;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-x')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')))\r\n .attr(\"transform\", \"translate(0,\" + plot.height + \")\");\r\n \r\n var axisT = axis;\r\n if (self.transitionEnabled()) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.x.axis);\r\n \r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ (plot.width/2) +\",\"+ (plot.margin.bottom) +\")\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"-1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n drawAxisY(){\r\n var self = this;\r\n var plot = self.plot;\r\n var axisConf = this.config.y;\r\n var axis = self.svgG.selectOrAppend(\"g.\"+self.prefixClass('axis-y')+\".\"+self.prefixClass('axis')+(self.config.guides ? '' : '.'+self.prefixClass('no-guides')));\r\n\r\n var axisT = axis;\r\n if (self.transitionEnabled()) {\r\n axisT = axis.transition().ease(\"sin-in-out\");\r\n }\r\n\r\n axisT.call(plot.y.axis);\r\n\r\n axis.selectOrAppend(\"text.\"+self.prefixClass('label'))\r\n .attr(\"transform\", \"translate(\"+ -plot.margin.left +\",\"+(plot.height/2)+\")rotate(-90)\") // text is drawn off the screen top left, move down and out and rotate\r\n .attr(\"dy\", \"1em\")\r\n .style(\"text-anchor\", \"middle\")\r\n .text(axisConf.label);\r\n };\r\n\r\n update(newData){\r\n super.update(newData);\r\n this.drawAxisX();\r\n this.drawAxisY();\r\n\r\n this.updateDots();\r\n\r\n this.updateLegend();\r\n };\r\n\r\n updateDots() {\r\n var self = this;\r\n var plot = self.plot;\r\n var data = plot.data;\r\n var dotClass = self.prefixClass('dot');\r\n self.dotsContainerClass = self.prefixClass('dots-container');\r\n\r\n\r\n var dotsContainer = self.svgG.selectOrAppend(\"g.\" + self.dotsContainerClass);\r\n\r\n var dots = dotsContainer.selectAll('.' + dotClass)\r\n .data(data);\r\n\r\n dots.enter().append(\"circle\")\r\n .attr(\"class\", dotClass);\r\n\r\n var dotsT = dots;\r\n if (self.transitionEnabled()) {\r\n dotsT = dots.transition();\r\n }\r\n\r\n dotsT.attr(\"r\", self.config.dot.radius)\r\n .attr(\"cx\", plot.x.map)\r\n .attr(\"cy\", plot.y.map);\r\n\r\n if (plot.tooltip) {\r\n dots.on(\"mouseover\", d => {\r\n plot.tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n var html = \"(\" + plot.x.value(d) + \", \" + plot.y.value(d) + \")\";\r\n var group = self.config.groups ? self.config.groups.value(d, self.config.groups.key) : null;\r\n if (group || group === 0) {\r\n html += \"
\";\r\n var label = self.config.groups.label;\r\n if (label) {\r\n html += label + \": \";\r\n }\r\n html += group\r\n }\r\n plot.tooltip.html(html)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n })\r\n .on(\"mouseout\", d => {\r\n plot.tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n\r\n if (plot.dot.color) {\r\n dots.style(\"fill\", plot.dot.color)\r\n }\r\n\r\n dots.exit().remove();\r\n }\r\n\r\n updateLegend() {\r\n\r\n var self =this;\r\n var plot = this.plot;\r\n\r\n var scale = plot.dot.colorCategory;\r\n\r\n\r\n\r\n if(!scale.domain() || scale.domain().length<2){\r\n plot.showLegend = false;\r\n }\r\n\r\n if(!plot.showLegend){\r\n if(plot.legend && plot.legend.container){\r\n plot.legend.container.remove();\r\n }\r\n return;\r\n }\r\n\r\n\r\n var legendX = this.plot.width + this.config.legend.margin;\r\n var legendY = this.config.legend.margin;\r\n\r\n plot.legend = new Legend(this.svg, this.svgG, scale, legendX, legendY);\r\n\r\n plot.legendColor = plot.legend.color()\r\n .shapeWidth(this.config.legend.shapeWidth)\r\n .orient('vertical')\r\n .scale(scale);\r\n\r\n\r\n plot.legendColor.on('cellclick', c=> self.onLegendCellClick(c));\r\n \r\n plot.legend.container\r\n .call(plot.legendColor);\r\n }\r\n\r\n onLegendCellClick(cellValue){\r\n this.updateEnabledGroups(cellValue);\r\n\r\n var isDisabled = this.enabledGroups.indexOf(cellValue)<0;\r\n this.plot.legend.container.selectAll(\"g.cell\").each(function(cell){\r\n if(cell == cellValue){\r\n d3.select(this).classed(\"odc-disabled\", isDisabled);\r\n }\r\n\r\n });\r\n\r\n this.init();\r\n }\r\n\r\n updateEnabledGroups(cellValue) {\r\n if (!this.enabledGroups) {\r\n this.enabledGroups = this.plot.dot.colorCategory.domain().slice();\r\n }\r\n var index = this.enabledGroups.indexOf(cellValue);\r\n\r\n if (index < 0) {\r\n this.enabledGroups.push(cellValue);\r\n } else {\r\n this.enabledGroups.splice(index, 1);\r\n }\r\n }\r\n\r\n\r\n\r\n setData(data){\r\n super.setData(data);\r\n this.enabledGroups = null;\r\n }\r\n}\r\n","/*\n * https://gist.github.com/benrasmusen/1261977\n * NAME\n * \n * statistics-distributions.js - JavaScript library for calculating\n * critical values and upper probabilities of common statistical\n * distributions\n * \n * SYNOPSIS\n * \n * \n * // Chi-squared-crit (2 degrees of freedom, 95th percentile = 0.05 level\n * chisqrdistr(2, .05)\n * \n * // u-crit (95th percentile = 0.05 level)\n * udistr(.05);\n * \n * // t-crit (1 degree of freedom, 99.5th percentile = 0.005 level) \n * tdistr(1,.005);\n * \n * // F-crit (1 degree of freedom in numerator, 3 degrees of freedom \n * // in denominator, 99th percentile = 0.01 level)\n * fdistr(1,3,.01);\n * \n * // upper probability of the u distribution (u = -0.85): Q(u) = 1-G(u)\n * uprob(-0.85);\n * \n * // upper probability of the chi-square distribution\n * // (3 degrees of freedom, chi-squared = 6.25): Q = 1-G\n * chisqrprob(3,6.25);\n * \n * // upper probability of the t distribution\n * // (3 degrees of freedom, t = 6.251): Q = 1-G\n * tprob(3,6.251);\n * \n * // upper probability of the F distribution\n * // (3 degrees of freedom in numerator, 5 degrees of freedom in\n * // denominator, F = 6.25): Q = 1-G\n * fprob(3,5,.625);\n * \n * \n * DESCRIPTION\n * \n * This library calculates percentage points (5 significant digits) of the u\n * (standard normal) distribution, the student's t distribution, the\n * chi-square distribution and the F distribution. It can also calculate the\n * upper probability (5 significant digits) of the u (standard normal), the\n * chi-square, the t and the F distribution.\n * \n * These critical values are needed to perform statistical tests, like the u\n * test, the t test, the F test and the chi-squared test, and to calculate\n * confidence intervals.\n * \n * If you are interested in more precise algorithms you could look at:\n * StatLib: http://lib.stat.cmu.edu/apstat/ ; \n * Applied Statistics Algorithms by Griffiths, P. and Hill, I.D.\n * , Ellis Horwood: Chichester (1985)\n * \n * BUGS \n * \n * This port was produced from the Perl module Statistics::Distributions\n * that has had no bug reports in several years. If you find a bug then\n * please double-check that JavaScript does not thing the numbers you are\n * passing in are strings. (You can subtract 0 from them as you pass them\n * in so that \"5\" is properly understood to be 5.) If you have passed in a\n * number then please contact the author\n * \n * AUTHOR\n * \n * Ben Tilly \n * \n * Originl Perl version by Michael Kospach \n * \n * Nice formating, simplification and bug repair by Matthias Trautner Kromann\n * \n * \n * COPYRIGHT \n * \n * Copyright 2008 Ben Tilly.\n * \n * This library is free software; you can redistribute it and/or modify it\n * under the same terms as Perl itself. This means under either the Perl\n * Artistic License or the GPL v1 or later.\n */\n\nvar SIGNIFICANT = 5; // number of significant digits to be returned\n\nfunction chisqrdistr ($n, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* degree of freedom */\n\t}\n\tif ($p <= 0 || $p > 1) {\n\t\tthrow(\"Invalid p: $p\\n\"); \n\t}\n\treturn precision_string(_subchisqr($n-0, $p-0));\n}\n\nfunction udistr ($p) {\n\tif ($p > 1 || $p <= 0) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\treturn precision_string(_subu($p-0));\n}\n\nexport function tdistr ($n, $p) {\n\tif ($n <= 0 || Math.abs($n) - Math.abs(integer($n)) != 0) {\n\t\tthrow(\"Invalid n: $n\\n\");\n\t}\n\tif ($p <= 0 || $p >= 1) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\treturn precision_string(_subt($n-0, $p-0));\n}\n\nfunction fdistr ($n, $m, $p) {\n\tif (($n<=0) || ((Math.abs($n)-(Math.abs(integer($n))))!=0)) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* first degree of freedom */\n\t}\n\tif (($m<=0) || ((Math.abs($m)-(Math.abs(integer($m))))!=0)) {\n\t\tthrow(\"Invalid m: $m\\n\"); /* second degree of freedom */\n\t}\n\tif (($p<=0) || ($p>1)) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\treturn precision_string(_subf($n-0, $m-0, $p-0));\n}\n\nfunction uprob ($x) {\n\treturn precision_string(_subuprob($x-0));\n}\n\nfunction chisqrprob ($n,$x) {\n\tif (($n <= 0) || ((Math.abs($n) - (Math.abs(integer($n)))) != 0)) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* degree of freedom */\n\t}\n\treturn precision_string(_subchisqrprob($n-0, $x-0));\n}\n\nfunction tprob ($n, $x) {\n\tif (($n <= 0) || ((Math.abs($n) - Math.abs(integer($n))) !=0)) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* degree of freedom */\n\t}\n\treturn precision_string(_subtprob($n-0, $x-0));\n}\n\nfunction fprob ($n, $m, $x) {\n\tif (($n<=0) || ((Math.abs($n)-(Math.abs(integer($n))))!=0)) {\n\t\tthrow(\"Invalid n: $n\\n\"); /* first degree of freedom */\n\t}\n\tif (($m<=0) || ((Math.abs($m)-(Math.abs(integer($m))))!=0)) {\n\t\tthrow(\"Invalid m: $m\\n\"); /* second degree of freedom */\n\t} \n\treturn precision_string(_subfprob($n-0, $m-0, $x-0));\n}\n\n\nfunction _subfprob ($n, $m, $x) {\n\tvar $p;\n\n\tif ($x<=0) {\n\t\t$p=1;\n\t} else if ($m % 2 == 0) {\n\t\tvar $z = $m / ($m + $n * $x);\n\t\tvar $a = 1;\n\t\tfor (var $i = $m - 2; $i >= 2; $i -= 2) {\n\t\t\t$a = 1 + ($n + $i - 2) / $i * $z * $a;\n\t\t}\n\t\t$p = 1 - Math.pow((1 - $z), ($n / 2) * $a);\n\t} else if ($n % 2 == 0) {\n\t\tvar $z = $n * $x / ($m + $n * $x);\n\t\tvar $a = 1;\n\t\tfor (var $i = $n - 2; $i >= 2; $i -= 2) {\n\t\t\t$a = 1 + ($m + $i - 2) / $i * $z * $a;\n\t\t}\n\t\t$p = Math.pow((1 - $z), ($m / 2)) * $a;\n\t} else {\n\t\tvar $y = Math.atan2(Math.sqrt($n * $x / $m), 1);\n\t\tvar $z = Math.pow(Math.sin($y), 2);\n\t\tvar $a = ($n == 1) ? 0 : 1;\n\t\tfor (var $i = $n - 2; $i >= 3; $i -= 2) {\n\t\t\t$a = 1 + ($m + $i - 2) / $i * $z * $a;\n\t\t} \n\t\tvar $b = Math.PI;\n\t\tfor (var $i = 2; $i <= $m - 1; $i += 2) {\n\t\t\t$b *= ($i - 1) / $i;\n\t\t}\n\t\tvar $p1 = 2 / $b * Math.sin($y) * Math.pow(Math.cos($y), $m) * $a;\n\n\t\t$z = Math.pow(Math.cos($y), 2);\n\t\t$a = ($m == 1) ? 0 : 1;\n\t\tfor (var $i = $m-2; $i >= 3; $i -= 2) {\n\t\t\t$a = 1 + ($i - 1) / $i * $z * $a;\n\t\t}\n\t\t$p = max(0, $p1 + 1 - 2 * $y / Math.PI\n\t\t\t- 2 / Math.PI * Math.sin($y) * Math.cos($y) * $a);\n\t}\n\treturn $p;\n}\n\n\nfunction _subchisqrprob ($n,$x) {\n\tvar $p;\n\n\tif ($x <= 0) {\n\t\t$p = 1;\n\t} else if ($n > 100) {\n\t\t$p = _subuprob((Math.pow(($x / $n), 1/3)\n\t\t\t\t- (1 - 2/9/$n)) / Math.sqrt(2/9/$n));\n\t} else if ($x > 400) {\n\t\t$p = 0;\n\t} else { \n\t\tvar $a;\n var $i;\n var $i1;\n\t\tif (($n % 2) != 0) {\n\t\t\t$p = 2 * _subuprob(Math.sqrt($x));\n\t\t\t$a = Math.sqrt(2/Math.PI) * Math.exp(-$x/2) / Math.sqrt($x);\n\t\t\t$i1 = 1;\n\t\t} else {\n\t\t\t$p = $a = Math.exp(-$x/2);\n\t\t\t$i1 = 2;\n\t\t}\n\n\t\tfor ($i = $i1; $i <= ($n-2); $i += 2) {\n\t\t\t$a *= $x / $i;\n\t\t\t$p += $a;\n\t\t}\n\t}\n\treturn $p;\n}\n\nfunction _subu ($p) {\n\tvar $y = -Math.log(4 * $p * (1 - $p));\n\tvar $x = Math.sqrt(\n\t\t$y * (1.570796288\n\t\t + $y * (.03706987906\n\t\t \t+ $y * (-.8364353589E-3\n\t\t\t + $y *(-.2250947176E-3\n\t\t\t \t+ $y * (.6841218299E-5\n\t\t\t\t + $y * (0.5824238515E-5\n\t\t\t\t\t+ $y * (-.104527497E-5\n\t\t\t\t\t + $y * (.8360937017E-7\n\t\t\t\t\t\t+ $y * (-.3231081277E-8\n\t\t\t\t\t\t + $y * (.3657763036E-10\n\t\t\t\t\t\t\t+ $y *.6936233982E-12)))))))))));\n\tif ($p>.5)\n $x = -$x;\n\treturn $x;\n}\n\nfunction _subuprob ($x) {\n\tvar $p = 0; /* if ($absx > 100) */\n\tvar $absx = Math.abs($x);\n\n\tif ($absx < 1.9) {\n\t\t$p = Math.pow((1 +\n\t\t\t$absx * (.049867347\n\t\t\t + $absx * (.0211410061\n\t\t\t \t+ $absx * (.0032776263\n\t\t\t\t + $absx * (.0000380036\n\t\t\t\t\t+ $absx * (.0000488906\n\t\t\t\t\t + $absx * .000005383)))))), -16)/2;\n\t} else if ($absx <= 100) {\n\t\tfor (var $i = 18; $i >= 1; $i--) {\n\t\t\t$p = $i / ($absx + $p);\n\t\t}\n\t\t$p = Math.exp(-.5 * $absx * $absx) \n\t\t\t/ Math.sqrt(2 * Math.PI) / ($absx + $p);\n\t}\n\n\tif ($x<0)\n \t$p = 1 - $p;\n\treturn $p;\n}\n\n \nfunction _subt ($n, $p) {\n\n\tif ($p >= 1 || $p <= 0) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\n\tif ($p == 0.5) {\n\t\treturn 0;\n\t} else if ($p < 0.5) {\n\t\treturn - _subt($n, 1 - $p);\n\t}\n\n\tvar $u = _subu($p);\n\tvar $u2 = Math.pow($u, 2);\n\n\tvar $a = ($u2 + 1) / 4;\n\tvar $b = ((5 * $u2 + 16) * $u2 + 3) / 96;\n\tvar $c = (((3 * $u2 + 19) * $u2 + 17) * $u2 - 15) / 384;\n\tvar $d = ((((79 * $u2 + 776) * $u2 + 1482) * $u2 - 1920) * $u2 - 945) \n\t\t\t\t/ 92160;\n\tvar $e = (((((27 * $u2 + 339) * $u2 + 930) * $u2 - 1782) * $u2 - 765) * $u2\n\t\t\t+ 17955) / 368640;\n\n\tvar $x = $u * (1 + ($a + ($b + ($c + ($d + $e / $n) / $n) / $n) / $n) / $n);\n\n\tif ($n <= Math.pow(log10($p), 2) + 3) {\n\t\tvar $round;\n\t\tdo { \n\t\t\tvar $p1 = _subtprob($n, $x);\n\t\t\tvar $n1 = $n + 1;\n\t\t\tvar $delta = ($p1 - $p) \n\t\t\t\t/ Math.exp(($n1 * Math.log($n1 / ($n + $x * $x)) \n\t\t\t\t\t+ Math.log($n/$n1/2/Math.PI) - 1 \n\t\t\t\t\t+ (1/$n1 - 1/$n) / 6) / 2);\n\t\t\t$x += $delta;\n\t\t\t$round = round_to_precision($delta, Math.abs(integer(log10(Math.abs($x))-4)));\n\t\t} while (($x) && ($round != 0));\n\t}\n\treturn $x;\n}\n\nfunction _subtprob ($n, $x) {\n\n\tvar $a;\n var $b;\n\tvar $w = Math.atan2($x / Math.sqrt($n), 1);\n\tvar $z = Math.pow(Math.cos($w), 2);\n\tvar $y = 1;\n\n\tfor (var $i = $n-2; $i >= 2; $i -= 2) {\n\t\t$y = 1 + ($i-1) / $i * $z * $y;\n\t} \n\n\tif ($n % 2 == 0) {\n\t\t$a = Math.sin($w)/2;\n\t\t$b = .5;\n\t} else {\n\t\t$a = ($n == 1) ? 0 : Math.sin($w)*Math.cos($w)/Math.PI;\n\t\t$b= .5 + $w/Math.PI;\n\t}\n\treturn max(0, 1 - $b - $a * $y);\n}\n\nfunction _subf ($n, $m, $p) {\n\tvar $x;\n\n\tif ($p >= 1 || $p <= 0) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t}\n\n\tif ($p == 1) {\n\t\t$x = 0;\n\t} else if ($m == 1) {\n\t\t$x = 1 / Math.pow(_subt($n, 0.5 - $p / 2), 2);\n\t} else if ($n == 1) {\n\t\t$x = Math.pow(_subt($m, $p/2), 2);\n\t} else if ($m == 2) {\n\t\tvar $u = _subchisqr($m, 1 - $p);\n\t\tvar $a = $m - 2;\n\t\t$x = 1 / ($u / $m * (1 +\n\t\t\t(($u - $a) / 2 +\n\t\t\t\t(((4 * $u - 11 * $a) * $u + $a * (7 * $m - 10)) / 24 +\n\t\t\t\t\t(((2 * $u - 10 * $a) * $u + $a * (17 * $m - 26)) * $u\n\t\t\t\t\t\t- $a * $a * (9 * $m - 6)\n\t\t\t\t\t)/48/$n\n\t\t\t\t)/$n\n\t\t\t)/$n));\n\t} else if ($n > $m) {\n\t\t$x = 1 / _subf2($m, $n, 1 - $p)\n\t} else {\n\t\t$x = _subf2($n, $m, $p)\n\t}\n\treturn $x;\n}\n\nfunction _subf2 ($n, $m, $p) {\n\tvar $u = _subchisqr($n, $p);\n\tvar $n2 = $n - 2;\n\tvar $x = $u / $n * \n\t\t(1 + \n\t\t\t(($u - $n2) / 2 + \n\t\t\t\t(((4 * $u - 11 * $n2) * $u + $n2 * (7 * $n - 10)) / 24 + \n\t\t\t\t\t(((2 * $u - 10 * $n2) * $u + $n2 * (17 * $n - 26)) * $u \n\t\t\t\t\t\t- $n2 * $n2 * (9 * $n - 6)) / 48 / $m) / $m) / $m);\n\tvar $delta;\n\tdo {\n\t\tvar $z = Math.exp(\n\t\t\t(($n+$m) * Math.log(($n+$m) / ($n * $x + $m)) \n\t\t\t\t+ ($n - 2) * Math.log($x)\n\t\t\t\t+ Math.log($n * $m / ($n+$m))\n\t\t\t\t- Math.log(4 * Math.PI)\n\t\t\t\t- (1/$n + 1/$m - 1/($n+$m))/6\n\t\t\t)/2);\n\t\t$delta = (_subfprob($n, $m, $x) - $p) / $z;\n\t\t$x += $delta;\n\t} while (Math.abs($delta)>3e-4);\n\treturn $x;\n}\n\nfunction _subchisqr ($n, $p) {\n\tvar $x;\n\n\tif (($p > 1) || ($p <= 0)) {\n\t\tthrow(\"Invalid p: $p\\n\");\n\t} else if ($p == 1){\n\t\t$x = 0;\n\t} else if ($n == 1) {\n\t\t$x = Math.pow(_subu($p / 2), 2);\n\t} else if ($n == 2) {\n\t\t$x = -2 * Math.log($p);\n\t} else {\n\t\tvar $u = _subu($p);\n\t\tvar $u2 = $u * $u;\n\n\t\t$x = max(0, $n + Math.sqrt(2 * $n) * $u \n\t\t\t+ 2/3 * ($u2 - 1)\n\t\t\t+ $u * ($u2 - 7) / 9 / Math.sqrt(2 * $n)\n\t\t\t- 2/405 / $n * ($u2 * (3 *$u2 + 7) - 16));\n\n\t\tif ($n <= 100) {\n\t\t\tvar $x0;\n var $p1;\n var $z;\n\t\t\tdo {\n\t\t\t\t$x0 = $x;\n\t\t\t\tif ($x < 0) {\n\t\t\t\t\t$p1 = 1;\n\t\t\t\t} else if ($n>100) {\n\t\t\t\t\t$p1 = _subuprob((Math.pow(($x / $n), (1/3)) - (1 - 2/9/$n))\n\t\t\t\t\t\t/ Math.sqrt(2/9/$n));\n\t\t\t\t} else if ($x>400) {\n\t\t\t\t\t$p1 = 0;\n\t\t\t\t} else {\n\t\t\t\t\tvar $i0\n var $a;\n\t\t\t\t\tif (($n % 2) != 0) {\n\t\t\t\t\t\t$p1 = 2 * _subuprob(Math.sqrt($x));\n\t\t\t\t\t\t$a = Math.sqrt(2/Math.PI) * Math.exp(-$x/2) / Math.sqrt($x);\n\t\t\t\t\t\t$i0 = 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$p1 = $a = Math.exp(-$x/2);\n\t\t\t\t\t\t$i0 = 2;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (var $i = $i0; $i <= $n-2; $i += 2) {\n\t\t\t\t\t\t$a *= $x / $i;\n\t\t\t\t\t\t$p1 += $a;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$z = Math.exp((($n-1) * Math.log($x/$n) - Math.log(4*Math.PI*$x) \n\t\t\t\t\t+ $n - $x - 1/$n/6) / 2);\n\t\t\t\t$x += ($p1 - $p) / $z;\n\t\t\t\t$x = round_to_precision($x, 5);\n\t\t\t} while (($n < 31) && (Math.abs($x0 - $x) > 1e-4));\n\t\t}\n\t}\n\treturn $x;\n}\n\nfunction log10 ($n) {\n\treturn Math.log($n) / Math.log(10);\n}\n \nfunction max () {\n\tvar $max = arguments[0];\n\tfor (var $i = 0; i < arguments.length; i++) {\n if ($max < arguments[$i])\n $max = arguments[$i];\n\t}\t\n\treturn $max;\n}\n\nfunction min () {\n\tvar $min = arguments[0];\n\tfor (var $i = 0; i < arguments.length; i++) {\n if ($min > arguments[$i])\n $min = arguments[$i];\n\t}\n\treturn $min;\n}\n\nfunction precision ($x) {\n\treturn Math.abs(integer(log10(Math.abs($x)) - SIGNIFICANT));\n}\n\nfunction precision_string ($x) {\n\tif ($x) {\n\t\treturn round_to_precision($x, precision($x));\n\t} else {\n\t\treturn \"0\";\n\t}\n}\n\nfunction round_to_precision ($x, $p) {\n $x = $x * Math.pow(10, $p);\n $x = Math.round($x);\n return $x / Math.pow(10, $p);\n}\n\nfunction integer ($i) {\n if ($i > 0)\n return Math.floor($i);\n else\n return Math.ceil($i);\n}","import {tdistr} from \"./statistics-distributions\"\r\n\r\nvar su = module.exports.StatisticsUtils ={};\r\nsu.sampleCorrelation = require('../bower_components/simple-statistics/src/sample_correlation');\r\nsu.linearRegression = require('../bower_components/simple-statistics/src/linear_regression');\r\nsu.linearRegressionLine = require('../bower_components/simple-statistics/src/linear_regression_line');\r\nsu.errorFunction = require('../bower_components/simple-statistics/src/error_function');\r\nsu.standardDeviation = require('../bower_components/simple-statistics/src/standard_deviation');\r\nsu.sampleStandardDeviation = require('../bower_components/simple-statistics/src/sample_standard_deviation');\r\nsu.variance = require('../bower_components/simple-statistics/src/variance');\r\nsu.mean = require('../bower_components/simple-statistics/src/mean');\r\nsu.zScore = require('../bower_components/simple-statistics/src/z_score');\r\nsu.standardError= arr => Math.sqrt(su.variance(arr)/(arr.length-1));\r\n\r\n\r\nsu.tValue= (degreesOfFreedom, criticalProbability) => { //as in http://stattrek.com/online-calculator/t-distribution.aspx\r\n return tdistr(degreesOfFreedom, criticalProbability);\r\n};","export class Utils {\r\n static SQRT_2 = 1.41421356237;\r\n // usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB);\r\n static deepExtend(out) {\r\n\r\n var utils = this;\r\n var emptyOut = {};\r\n\r\n\r\n if (!out && arguments.length > 1 && Array.isArray(arguments[1])) {\r\n out = [];\r\n }\r\n out = out || {};\r\n\r\n for (var i = 1; i < arguments.length; i++) {\r\n var source = arguments[i];\r\n if (!source)\r\n continue;\r\n\r\n for (var key in source) {\r\n if (!source.hasOwnProperty(key)) {\r\n continue;\r\n }\r\n var isArray = Array.isArray(out[key]);\r\n var isObject = utils.isObject(out[key]);\r\n var srcObj = utils.isObject(source[key]);\r\n\r\n if (isObject && !isArray && srcObj) {\r\n utils.deepExtend(out[key], source[key]);\r\n } else {\r\n out[key] = source[key];\r\n }\r\n }\r\n }\r\n\r\n return out;\r\n };\r\n\r\n static mergeDeep(target, source) {\r\n let output = Object.assign({}, target);\r\n if (Utils.isObjectNotArray(target) && Utils.isObjectNotArray(source)) {\r\n Object.keys(source).forEach(key => {\r\n if (Utils.isObjectNotArray(source[key])) {\r\n if (!(key in target))\r\n Object.assign(output, {[key]: source[key]});\r\n else\r\n output[key] = Utils.mergeDeep(target[key], source[key]);\r\n } else {\r\n Object.assign(output, {[key]: source[key]});\r\n }\r\n });\r\n }\r\n return output;\r\n }\r\n\r\n static cross(a, b) {\r\n var c = [], n = a.length, m = b.length, i, j;\r\n for (i = -1; ++i < n;) for (j = -1; ++j < m;) c.push({x: a[i], i: i, y: b[j], j: j});\r\n return c;\r\n };\r\n\r\n static inferVariables(data, groupKey, includeGroup) {\r\n var res = [];\r\n if (data.length) {\r\n var d = data[0];\r\n if (d instanceof Array) {\r\n res = d.map(function (v, i) {\r\n return i;\r\n });\r\n } else if (typeof d === 'object') {\r\n\r\n for (var prop in d) {\r\n if (!d.hasOwnProperty(prop)) continue;\r\n\r\n res.push(prop);\r\n }\r\n }\r\n }\r\n if (!includeGroup) {\r\n var index = res.indexOf(groupKey);\r\n if (index > -1) {\r\n res.splice(index, 1);\r\n }\r\n }\r\n return res\r\n };\r\n\r\n static isObjectNotArray(item) {\r\n return (item && typeof item === 'object' && !Array.isArray(item) && item !== null);\r\n };\r\n\r\n static isObject(a) {\r\n return a !== null && typeof a === 'object';\r\n };\r\n\r\n static isNumber(a) {\r\n return !isNaN(a) && typeof a === 'number';\r\n };\r\n\r\n static isFunction(a) {\r\n return typeof a === 'function';\r\n };\r\n\r\n static isDate(a){\r\n return Object.prototype.toString.call(a) === '[object Date]'\r\n }\r\n\r\n static isString(a){\r\n return typeof a === 'string' || a instanceof String\r\n }\r\n\r\n static insertOrAppendSelector(parent, selector, operation, before) {\r\n var selectorParts = selector.split(/([\\.\\#])/);\r\n var element = parent[operation](selectorParts.shift(), before);//\":first-child\"\r\n while (selectorParts.length > 1) {\r\n var selectorModifier = selectorParts.shift();\r\n var selectorItem = selectorParts.shift();\r\n if (selectorModifier === \".\") {\r\n element = element.classed(selectorItem, true);\r\n } else if (selectorModifier === \"#\") {\r\n element = element.attr('id', selectorItem);\r\n }\r\n }\r\n return element;\r\n }\r\n\r\n static insertSelector(parent, selector, before) {\r\n return Utils.insertOrAppendSelector(parent, selector, \"insert\", before);\r\n }\r\n\r\n static appendSelector(parent, selector) {\r\n return Utils.insertOrAppendSelector(parent, selector, \"append\");\r\n }\r\n\r\n static selectOrAppend(parent, selector, element) {\r\n var selection = parent.select(selector);\r\n if (selection.empty()) {\r\n if (element) {\r\n return parent.append(element);\r\n }\r\n return Utils.appendSelector(parent, selector);\r\n\r\n }\r\n return selection;\r\n };\r\n\r\n static selectOrInsert(parent, selector, before) {\r\n var selection = parent.select(selector);\r\n if (selection.empty()) {\r\n return Utils.insertSelector(parent, selector, before);\r\n }\r\n return selection;\r\n };\r\n\r\n static linearGradient(svg, gradientId, range, x1, y1, x2, y2) {\r\n var defs = Utils.selectOrAppend(svg, \"defs\");\r\n var linearGradient = defs.append(\"linearGradient\")\r\n .attr(\"id\", gradientId);\r\n\r\n linearGradient\r\n .attr(\"x1\", x1 + \"%\")\r\n .attr(\"y1\", y1 + \"%\")\r\n .attr(\"x2\", x2 + \"%\")\r\n .attr(\"y2\", y2 + \"%\");\r\n\r\n //Append multiple color stops by using D3's data/enter step\r\n var stops = linearGradient.selectAll(\"stop\")\r\n .data(range);\r\n\r\n stops.enter().append(\"stop\");\r\n\r\n stops.attr(\"offset\", (d, i) => i / (range.length - 1))\r\n .attr(\"stop-color\", d => d);\r\n\r\n stops.exit().remove();\r\n }\r\n\r\n static sanitizeHeight = function (height, container) {\r\n return (height || parseInt(container.style('height'), 10) || 400);\r\n };\r\n\r\n static sanitizeWidth = function (width, container) {\r\n return (width || parseInt(container.style('width'), 10) || 960);\r\n };\r\n\r\n static availableHeight = function (height, container, margin) {\r\n return Math.max(0, Utils.sanitizeHeight(height, container) - margin.top - margin.bottom);\r\n };\r\n\r\n static availableWidth = function (width, container, margin) {\r\n return Math.max(0, Utils.sanitizeWidth(width, container) - margin.left - margin.right);\r\n };\r\n\r\n static guid() {\r\n function s4() {\r\n return Math.floor((1 + Math.random()) * 0x10000)\r\n .toString(16)\r\n .substring(1);\r\n }\r\n\r\n return s4() + s4() + '-' + s4() + '-' + s4() + '-' +\r\n s4() + '-' + s4() + s4() + s4();\r\n }\r\n\r\n //places textString in textObj, adds an ellipsis if text can't fit in width\r\n static placeTextWithEllipsis(textD3Obj, textString, width){\r\n var textObj = textD3Obj.node();\r\n textObj.textContent=textString;\r\n\r\n var margin = 0;\r\n var ellipsisLength = 9;\r\n //ellipsis is needed\r\n if (textObj.getComputedTextLength()>width+margin){\r\n for (var x=textString.length-3;x>0;x-=1){\r\n if (textObj.getSubStringLength(0,x)+ellipsisLength<=width+margin){\r\n textObj.textContent=textString.substring(0,x)+\"...\";\r\n return true;\r\n }\r\n }\r\n textObj.textContent=\"...\"; //can't place at all\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n static placeTextWithEllipsisAndTooltip(textD3Obj, textString, width, tooltip){\r\n var ellipsisPlaced = Utils.placeTextWithEllipsis(textD3Obj, textString, width);\r\n if(ellipsisPlaced && tooltip){\r\n textD3Obj.on(\"mouseover\", function (d) {\r\n tooltip.transition()\r\n .duration(200)\r\n .style(\"opacity\", .9);\r\n tooltip.html(textString)\r\n .style(\"left\", (d3.event.pageX + 5) + \"px\")\r\n .style(\"top\", (d3.event.pageY - 28) + \"px\");\r\n });\r\n\r\n textD3Obj.on(\"mouseout\", function (d) {\r\n tooltip.transition()\r\n .duration(500)\r\n .style(\"opacity\", 0);\r\n });\r\n }\r\n\r\n }\r\n\r\n static getFontSize(element){\r\n return window.getComputedStyle(element, null).getPropertyValue(\"font-size\");\r\n }\r\n}\r\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/src/histogram.js b/src/histogram.js index e23f3a7..4f97066 100644 --- a/src/histogram.js +++ b/src/histogram.js @@ -83,8 +83,11 @@ export class Histogram extends Chart{ if (colorValue && typeof colorValue === 'string' || colorValue instanceof String){ this.plot.color = colorValue; }else if(this.plot.colorCategory){ - var domain = Object.getOwnPropertyNames(d3.map(this.data, d => this.config.groups.value.call(this.config, d))['_']); - self.plot.colorCategory.domain(domain); + if(this.config.groups){ + var domain = Object.getOwnPropertyNames(d3.map(this.data, d => this.config.groups.value.call(this.config, d))['_']); + self.plot.colorCategory.domain(domain); + } + this.plot.color = d => self.plot.colorCategory(d.key); } diff --git a/src/scatterplot-matrix.js b/src/scatterplot-matrix.js index 014a393..916195c 100644 --- a/src/scatterplot-matrix.js +++ b/src/scatterplot-matrix.js @@ -249,7 +249,6 @@ export class ScatterPlotMatrix extends Chart { function plotSubplot(p) { - console.log('plotSubplot'); var plot = self.plot; plot.subplots.push(p); var cell = d3.select(this); @@ -297,7 +296,7 @@ export class ScatterPlotMatrix extends Chart { .style("left", (d3.event.pageX + 5) + "px") .style("top", (d3.event.pageY - 28) + "px"); - var group = self.config.groups.value(d); + var group = self.config.groups ? self.config.groups.value(d) : false; if(group || group===0 ){ html+="
"; var label = self.config.groups.label; diff --git a/src/scatterplot.js b/src/scatterplot.js index 4676f74..9633ffa 100644 --- a/src/scatterplot.js +++ b/src/scatterplot.js @@ -35,7 +35,7 @@ export class ScatterPlotConfig extends ChartConfig{ }; dot = { radius: 2, - color: d => this.groups.value(d, this.groups.key), // string or function returning color's value for color scale + color: d => this.groups ? this.groups.value(d, this.groups.key) : '', // string or function returning color's value for color scale d3ColorCategory: 'category10' }; transition= true; @@ -255,7 +255,7 @@ export class ScatterPlot extends Chart{ .duration(200) .style("opacity", .9); var html = "(" + plot.x.value(d) + ", " + plot.y.value(d) + ")"; - var group = self.config.groups.value(d, self.config.groups.key); + var group = self.config.groups ? self.config.groups.value(d, self.config.groups.key) : null; if (group || group === 0) { html += "
"; var label = self.config.groups.label;