diff --git a/README.md b/README.md index 5d4df03..d7726e9 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,16 @@ Mutations Needle Plot (muts-needle-plot) A needle-plot (aka stem-plot or lollipop-plot) plots each data point as a big dot and adds a vertical line that makes it appear like a needle. -[![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.13185.svg)](http://dx.doi.org/10.5281/zenodo.13185) +![DOI](https://zenodo.org/badge/7688/bbglab/muts-needle-plot.svg) + +This software is **citable**! Different citation styles available at *http://dx.doi.org/*+DOI Availability ----------------------- - * **BioJS-registry** (with live examples): - * **npm-registry**: - * **GitHub**: + * **Live examples** at the BioJS-registry: + * **Installable JavaScript library** at npm-registry: + * **Source code** at GitHub: ![Image of a Needle-Plot](mutations-needle-plot.png) diff --git a/build/muts-needle-plot.css b/build/muts-needle-plot.css index 67c4a1d..fd12679 100644 --- a/build/muts-needle-plot.css +++ b/build/muts-needle-plot.css @@ -42,7 +42,7 @@ body { fill: lightgrey; } -.regionGroup:hover > .regionName { +.regionGroup:hover > text { fill: black; font-weight: bold; opacity: 1; @@ -57,6 +57,11 @@ body { opacity: 0.5; } +.repeatedName.noshow { + fill: black; + opacity: 0; +} + .x-axis path, .x-axis line, .y-axis path, .y-axis line { fill: none; } diff --git a/build/muts-needle-plot.js b/build/muts-needle-plot.js index 41daa84..46afe1f 100644 --- a/build/muts-needle-plot.js +++ b/build/muts-needle-plot.js @@ -730,6 +730,18 @@ function MutsNeedlePlot (config) { .call(selector) .selectAll('.extent') .attr('height', height); + selectionRect.on("mouseenter", function() { + var selection = selector.extent(); + self.selectionTip.show({left: selection[0], right: selection[1]}, selectionRect.node()); + }) + .on("mouseout", function(){ + d3.select(".d3-tip-selection") + .transition() + .delay(3000) + .duration(1000) + .style("opacity",0) + .style('pointer-events', 'none'); + }); function brushmove() { @@ -808,6 +820,12 @@ function MutsNeedlePlot (config) { selection = edata.coords; if (selection[1] - selection[0] > 0) { self.selectionTip.show({left: selection[0], right: selection[1]}, selectionRect.node()); + d3.select(".d3-tip-selection") + .transition() + .delay(3000) + .duration(1000) + .style("opacity",0) + .style('pointer-events', 'none'); } else { self.selectionTip.hide(); } @@ -840,7 +858,8 @@ MutsNeedlePlot.prototype.drawLegend = function(svg) { var domain = self.x.domain(); - xplacement = (domain[1] - domain[0]) * 0.75 + (domain[1] - domain[0]); + xplacement = (self.x(domain[1]) - self.x(domain[0])) * 0.75 + self.x(domain[0]); + var sum = 0; for (var c in self.totalCategCounts) { @@ -974,8 +993,18 @@ MutsNeedlePlot.prototype.drawRegions = function(svg, regionData) { // Place and label location var labels = []; + var repeatedRegion = {}; + var getRegionClass = function(region) { + var c = "regionName"; + var repeatedClass = "RR_"+region.name; + if(_.has(repeatedRegion, region.name)) { + c = "repeatedName noshow " + repeatedClass; + } + repeatedRegion[region.name] = repeatedClass; + return c; + }; regions.append("text") - .attr("class", "regionName") + .attr("class", getRegionClass) .attr("text-anchor", "middle") .attr("x", function (r) { r.x = x(r.start) + (x(r.end) - x(r.start)) / 2; @@ -1036,6 +1065,11 @@ MutsNeedlePlot.prototype.drawRegions = function(svg, regionData) { || y2 < ny1; }; } + var moveRepeatedLabels = function(label, x) { + var name = repeatedRegion[label]; + svg.selectAll("text."+name) + .attr("x", newx); + }; force.on("tick", function(e) { var q = d3.geom.quadtree(labels), i = 0, @@ -1044,14 +1078,12 @@ MutsNeedlePlot.prototype.drawRegions = function(svg, regionData) { q.visit(collide(labels[i])); } // Update the position of the text element + var i = 0; svg.selectAll("text.regionName") .attr("x", function(d) { - for (i = 0; i < n; i++) { - if (d.name == labels[i].label) { - labels[i].x = withinBounds(labels[i].x); - return labels[i].x; - } - } + newx = labels[i++].x; + moveRepeatedLabels(d.name, newx); + return newx; } ); }); @@ -1059,17 +1091,19 @@ MutsNeedlePlot.prototype.drawRegions = function(svg, regionData) { } function formatRegions(regions) { - regionList = []; - for (key in regions) { + for (key in Object.keys(regions)) { - regionList.push({ + regions[key].start = getRegionStart(regions[key].coord); + regions[key].end = getRegionEnd(regions[key].coord); + regions[key].color = getColor(regions[key].name); + /*regionList.push({ 'name': key, 'start': getRegionStart(regions[key]), 'end': getRegionEnd(regions[key]), 'color': getColor(key) - }); + });*/ } - return regionList; + return regions; } if (typeof regionData == "string") { @@ -1289,4 +1323,4 @@ module.exports = MutsNeedlePlot; module.exports = require("./src/js/MutsNeedlePlot.js"); },{"./src/js/MutsNeedlePlot.js":5}]},{},["muts-needle-plot"]) -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvaG9tZS9tc2Nocm9lZGVyL0RvY3VtZW50cy9wcm9qZWN0cy9uZWVkbGVwbG90L25vZGVfbW9kdWxlcy9iaW9qcy1ldmVudHMvaW5kZXguanMiLCIvaG9tZS9tc2Nocm9lZGVyL0RvY3VtZW50cy9wcm9qZWN0cy9uZWVkbGVwbG90L25vZGVfbW9kdWxlcy9iaW9qcy1ldmVudHMvbm9kZV9tb2R1bGVzL2JhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lL2JhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lLmpzIiwiL2hvbWUvbXNjaHJvZWRlci9Eb2N1bWVudHMvcHJvamVjdHMvbmVlZGxlcGxvdC9ub2RlX21vZHVsZXMvYmlvanMtZXZlbnRzL25vZGVfbW9kdWxlcy9iYWNrYm9uZS1ldmVudHMtc3RhbmRhbG9uZS9pbmRleC5qcyIsIi9ob21lL21zY2hyb2VkZXIvRG9jdW1lbnRzL3Byb2plY3RzL25lZWRsZXBsb3Qvbm9kZV9tb2R1bGVzL2QzLXRpcC9pbmRleC5qcyIsIi9ob21lL21zY2hyb2VkZXIvRG9jdW1lbnRzL3Byb2plY3RzL25lZWRsZXBsb3Qvc3JjL2pzL011dHNOZWVkbGVQbG90LmpzIiwiLi9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JSQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNscUJBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwidmFyIGV2ZW50cyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1ldmVudHMtc3RhbmRhbG9uZVwiKTtcblxuZXZlbnRzLm9uQWxsID0gZnVuY3Rpb24oY2FsbGJhY2ssY29udGV4dCl7XG4gIHRoaXMub24oXCJhbGxcIiwgY2FsbGJhY2ssY29udGV4dCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gTWl4aW4gdXRpbGl0eVxuZXZlbnRzLm9sZE1peGluID0gZXZlbnRzLm1peGluO1xuZXZlbnRzLm1peGluID0gZnVuY3Rpb24ocHJvdG8pIHtcbiAgZXZlbnRzLm9sZE1peGluKHByb3RvKTtcbiAgLy8gYWRkIGN1c3RvbSBvbkFsbFxuICB2YXIgZXhwb3J0cyA9IFsnb25BbGwnXTtcbiAgZm9yKHZhciBpPTA7IGkgPCBleHBvcnRzLmxlbmd0aDtpKyspe1xuICAgIHZhciBuYW1lID0gZXhwb3J0c1tpXTtcbiAgICBwcm90b1tuYW1lXSA9IHRoaXNbbmFtZV07XG4gIH1cbiAgcmV0dXJuIHByb3RvO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBldmVudHM7XG4iLCIvKipcbiAqIFN0YW5kYWxvbmUgZXh0cmFjdGlvbiBvZiBCYWNrYm9uZS5FdmVudHMsIG5vIGV4dGVybmFsIGRlcGVuZGVuY3kgcmVxdWlyZWQuXG4gKiBEZWdyYWRlcyBuaWNlbHkgd2hlbiBCYWNrb25lL3VuZGVyc2NvcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50XG4gKiBnbG9iYWwgY29udGV4dC5cbiAqXG4gKiBOb3RlIHRoYXQgZG9jcyBzdWdnZXN0IHRvIHVzZSB1bmRlcnNjb3JlJ3MgYF8uZXh0ZW5kKClgIG1ldGhvZCB0byBhZGQgRXZlbnRzXG4gKiBzdXBwb3J0IHRvIHNvbWUgZ2l2ZW4gb2JqZWN0LiBBIGBtaXhpbigpYCBtZXRob2QgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIEV2ZW50c1xuICogcHJvdG90eXBlIHRvIGF2b2lkIHVzaW5nIHVuZGVyc2NvcmUgZm9yIHRoYXQgc29sZSBwdXJwb3NlOlxuICpcbiAqICAgICB2YXIgbXlFdmVudEVtaXR0ZXIgPSBCYWNrYm9uZUV2ZW50cy5taXhpbih7fSk7XG4gKlxuICogT3IgZm9yIGEgZnVuY3Rpb24gY29uc3RydWN0b3I6XG4gKlxuICogICAgIGZ1bmN0aW9uIE15Q29uc3RydWN0b3IoKXt9XG4gKiAgICAgTXlDb25zdHJ1Y3Rvci5wcm90b3R5cGUuZm9vID0gZnVuY3Rpb24oKXt9XG4gKiAgICAgQmFja2JvbmVFdmVudHMubWl4aW4oTXlDb25zdHJ1Y3Rvci5wcm90b3R5cGUpO1xuICpcbiAqIChjKSAyMDA5LTIwMTMgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIEluYy5cbiAqIChjKSAyMDEzIE5pY29sYXMgUGVycmlhdWx0XG4gKi9cbi8qIGdsb2JhbCBleHBvcnRzOnRydWUsIGRlZmluZSwgbW9kdWxlICovXG4oZnVuY3Rpb24oKSB7XG4gIHZhciByb290ID0gdGhpcyxcbiAgICAgIGJyZWFrZXIgPSB7fSxcbiAgICAgIG5hdGl2ZUZvckVhY2ggPSBBcnJheS5wcm90b3R5cGUuZm9yRWFjaCxcbiAgICAgIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxcbiAgICAgIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLFxuICAgICAgaWRDb3VudGVyID0gMDtcblxuICAvLyBSZXR1cm5zIGEgcGFydGlhbCBpbXBsZW1lbnRhdGlvbiBtYXRjaGluZyB0aGUgbWluaW1hbCBBUEkgc3Vic2V0IHJlcXVpcmVkXG4gIC8vIGJ5IEJhY2tib25lLkV2ZW50c1xuICBmdW5jdGlvbiBtaW5pc2NvcmUoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleXM6IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmogIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXlzKCkgY2FsbGVkIG9uIGEgbm9uLW9iamVjdFwiKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIga2V5LCBrZXlzID0gW107XG4gICAgICAgIGZvciAoa2V5IGluIG9iaikge1xuICAgICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAga2V5c1trZXlzLmxlbmd0aF0gPSBrZXk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXlzO1xuICAgICAgfSxcblxuICAgICAgdW5pcXVlSWQ6IGZ1bmN0aW9uKHByZWZpeCkge1xuICAgICAgICB2YXIgaWQgPSArK2lkQ291bnRlciArICcnO1xuICAgICAgICByZXR1cm4gcHJlZml4ID8gcHJlZml4ICsgaWQgOiBpZDtcbiAgICAgIH0sXG5cbiAgICAgIGhhczogZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xuICAgICAgfSxcblxuICAgICAgZWFjaDogZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgICAgICBpZiAob2JqID09IG51bGwpIHJldHVybjtcbiAgICAgICAgaWYgKG5hdGl2ZUZvckVhY2ggJiYgb2JqLmZvckVhY2ggPT09IG5hdGl2ZUZvckVhY2gpIHtcbiAgICAgICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgICAgIH0gZWxzZSBpZiAob2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGgpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtpXSwgaSwgb2JqKSA9PT0gYnJlYWtlcikgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5oYXMob2JqLCBrZXkpKSB7XG4gICAgICAgICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaikgPT09IGJyZWFrZXIpIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIG9uY2U6IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICAgICAgdmFyIHJhbiA9IGZhbHNlLCBtZW1vO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKHJhbikgcmV0dXJuIG1lbW87XG4gICAgICAgICAgcmFuID0gdHJ1ZTtcbiAgICAgICAgICBtZW1vID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgIGZ1bmMgPSBudWxsO1xuICAgICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICB2YXIgXyA9IG1pbmlzY29yZSgpLCBFdmVudHM7XG5cbiAgLy8gQmFja2JvbmUuRXZlbnRzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLVxuXG4gIC8vIEEgbW9kdWxlIHRoYXQgY2FuIGJlIG1peGVkIGluIHRvICphbnkgb2JqZWN0KiBpbiBvcmRlciB0byBwcm92aWRlIGl0IHdpdGhcbiAgLy8gY3VzdG9tIGV2ZW50cy4gWW91IG1heSBiaW5kIHdpdGggYG9uYCBvciByZW1vdmUgd2l0aCBgb2ZmYCBjYWxsYmFja1xuICAvLyBmdW5jdGlvbnMgdG8gYW4gZXZlbnQ7IGB0cmlnZ2VyYC1pbmcgYW4gZXZlbnQgZmlyZXMgYWxsIGNhbGxiYWNrcyBpblxuICAvLyBzdWNjZXNzaW9uLlxuICAvL1xuICAvLyAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAvLyAgICAgXy5leHRlbmQob2JqZWN0LCBCYWNrYm9uZS5FdmVudHMpO1xuICAvLyAgICAgb2JqZWN0Lm9uKCdleHBhbmQnLCBmdW5jdGlvbigpeyBhbGVydCgnZXhwYW5kZWQnKTsgfSk7XG4gIC8vICAgICBvYmplY3QudHJpZ2dlcignZXhwYW5kJyk7XG4gIC8vXG4gIEV2ZW50cyA9IHtcblxuICAgIC8vIEJpbmQgYW4gZXZlbnQgdG8gYSBgY2FsbGJhY2tgIGZ1bmN0aW9uLiBQYXNzaW5nIGBcImFsbFwiYCB3aWxsIGJpbmRcbiAgICAvLyB0aGUgY2FsbGJhY2sgdG8gYWxsIGV2ZW50cyBmaXJlZC5cbiAgICBvbjogZnVuY3Rpb24obmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICdvbicsIG5hbWUsIFtjYWxsYmFjaywgY29udGV4dF0pIHx8ICFjYWxsYmFjaykgcmV0dXJuIHRoaXM7XG4gICAgICB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICAgIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNbbmFtZV0gfHwgKHRoaXMuX2V2ZW50c1tuYW1lXSA9IFtdKTtcbiAgICAgIGV2ZW50cy5wdXNoKHtjYWxsYmFjazogY2FsbGJhY2ssIGNvbnRleHQ6IGNvbnRleHQsIGN0eDogY29udGV4dCB8fCB0aGlzfSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLy8gQmluZCBhbiBldmVudCB0byBvbmx5IGJlIHRyaWdnZXJlZCBhIHNpbmdsZSB0aW1lLiBBZnRlciB0aGUgZmlyc3QgdGltZVxuICAgIC8vIHRoZSBjYWxsYmFjayBpcyBpbnZva2VkLCBpdCB3aWxsIGJlIHJlbW92ZWQuXG4gICAgb25jZTogZnVuY3Rpb24obmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICdvbmNlJywgbmFtZSwgW2NhbGxiYWNrLCBjb250ZXh0XSkgfHwgIWNhbGxiYWNrKSByZXR1cm4gdGhpcztcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIHZhciBvbmNlID0gXy5vbmNlKGZ1bmN0aW9uKCkge1xuICAgICAgICBzZWxmLm9mZihuYW1lLCBvbmNlKTtcbiAgICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH0pO1xuICAgICAgb25jZS5fY2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICAgIHJldHVybiB0aGlzLm9uKG5hbWUsIG9uY2UsIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICAvLyBSZW1vdmUgb25lIG9yIG1hbnkgY2FsbGJhY2tzLiBJZiBgY29udGV4dGAgaXMgbnVsbCwgcmVtb3ZlcyBhbGxcbiAgICAvLyBjYWxsYmFja3Mgd2l0aCB0aGF0IGZ1bmN0aW9uLiBJZiBgY2FsbGJhY2tgIGlzIG51bGwsIHJlbW92ZXMgYWxsXG4gICAgLy8gY2FsbGJhY2tzIGZvciB0aGUgZXZlbnQuIElmIGBuYW1lYCBpcyBudWxsLCByZW1vdmVzIGFsbCBib3VuZFxuICAgIC8vIGNhbGxiYWNrcyBmb3IgYWxsIGV2ZW50cy5cbiAgICBvZmY6IGZ1bmN0aW9uKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmV0YWluLCBldiwgZXZlbnRzLCBuYW1lcywgaSwgbCwgaiwgaztcbiAgICAgIGlmICghdGhpcy5fZXZlbnRzIHx8ICFldmVudHNBcGkodGhpcywgJ29mZicsIG5hbWUsIFtjYWxsYmFjaywgY29udGV4dF0pKSByZXR1cm4gdGhpcztcbiAgICAgIGlmICghbmFtZSAmJiAhY2FsbGJhY2sgJiYgIWNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBuYW1lcyA9IG5hbWUgPyBbbmFtZV0gOiBfLmtleXModGhpcy5fZXZlbnRzKTtcbiAgICAgIGZvciAoaSA9IDAsIGwgPSBuYW1lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgbmFtZSA9IG5hbWVzW2ldO1xuICAgICAgICBpZiAoZXZlbnRzID0gdGhpcy5fZXZlbnRzW25hbWVdKSB7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzW25hbWVdID0gcmV0YWluID0gW107XG4gICAgICAgICAgaWYgKGNhbGxiYWNrIHx8IGNvbnRleHQpIHtcbiAgICAgICAgICAgIGZvciAoaiA9IDAsIGsgPSBldmVudHMubGVuZ3RoOyBqIDwgazsgaisrKSB7XG4gICAgICAgICAgICAgIGV2ID0gZXZlbnRzW2pdO1xuICAgICAgICAgICAgICBpZiAoKGNhbGxiYWNrICYmIGNhbGxiYWNrICE9PSBldi5jYWxsYmFjayAmJiBjYWxsYmFjayAhPT0gZXYuY2FsbGJhY2suX2NhbGxiYWNrKSB8fFxuICAgICAgICAgICAgICAgICAgKGNvbnRleHQgJiYgY29udGV4dCAhPT0gZXYuY29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICByZXRhaW4ucHVzaChldik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFyZXRhaW4ubGVuZ3RoKSBkZWxldGUgdGhpcy5fZXZlbnRzW25hbWVdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBUcmlnZ2VyIG9uZSBvciBtYW55IGV2ZW50cywgZmlyaW5nIGFsbCBib3VuZCBjYWxsYmFja3MuIENhbGxiYWNrcyBhcmVcbiAgICAvLyBwYXNzZWQgdGhlIHNhbWUgYXJndW1lbnRzIGFzIGB0cmlnZ2VyYCBpcywgYXBhcnQgZnJvbSB0aGUgZXZlbnQgbmFtZVxuICAgIC8vICh1bmxlc3MgeW91J3JlIGxpc3RlbmluZyBvbiBgXCJhbGxcImAsIHdoaWNoIHdpbGwgY2F1c2UgeW91ciBjYWxsYmFjayB0b1xuICAgIC8vIHJlY2VpdmUgdGhlIHRydWUgbmFtZSBvZiB0aGUgZXZlbnQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50KS5cbiAgICB0cmlnZ2VyOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgICBpZiAoIXRoaXMuX2V2ZW50cykgcmV0dXJuIHRoaXM7XG4gICAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICd0cmlnZ2VyJywgbmFtZSwgYXJncykpIHJldHVybiB0aGlzO1xuICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuYW1lXTtcbiAgICAgIHZhciBhbGxFdmVudHMgPSB0aGlzLl9ldmVudHMuYWxsO1xuICAgICAgaWYgKGV2ZW50cykgdHJpZ2dlckV2ZW50cyhldmVudHMsIGFyZ3MpO1xuICAgICAgaWYgKGFsbEV2ZW50cykgdHJpZ2dlckV2ZW50cyhhbGxFdmVudHMsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLy8gVGVsbCB0aGlzIG9iamVjdCB0byBzdG9wIGxpc3RlbmluZyB0byBlaXRoZXIgc3BlY2lmaWMgZXZlbnRzIC4uLiBvclxuICAgIC8vIHRvIGV2ZXJ5IG9iamVjdCBpdCdzIGN1cnJlbnRseSBsaXN0ZW5pbmcgdG8uXG4gICAgc3RvcExpc3RlbmluZzogZnVuY3Rpb24ob2JqLCBuYW1lLCBjYWxsYmFjaykge1xuICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycztcbiAgICAgIGlmICghbGlzdGVuZXJzKSByZXR1cm4gdGhpcztcbiAgICAgIHZhciBkZWxldGVMaXN0ZW5lciA9ICFuYW1lICYmICFjYWxsYmFjaztcbiAgICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ29iamVjdCcpIGNhbGxiYWNrID0gdGhpcztcbiAgICAgIGlmIChvYmopIChsaXN0ZW5lcnMgPSB7fSlbb2JqLl9saXN0ZW5lcklkXSA9IG9iajtcbiAgICAgIGZvciAodmFyIGlkIGluIGxpc3RlbmVycykge1xuICAgICAgICBsaXN0ZW5lcnNbaWRdLm9mZihuYW1lLCBjYWxsYmFjaywgdGhpcyk7XG4gICAgICAgIGlmIChkZWxldGVMaXN0ZW5lcikgZGVsZXRlIHRoaXMuX2xpc3RlbmVyc1tpZF07XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgfTtcblxuICAvLyBSZWd1bGFyIGV4cHJlc3Npb24gdXNlZCB0byBzcGxpdCBldmVudCBzdHJpbmdzLlxuICB2YXIgZXZlbnRTcGxpdHRlciA9IC9cXHMrLztcblxuICAvLyBJbXBsZW1lbnQgZmFuY3kgZmVhdHVyZXMgb2YgdGhlIEV2ZW50cyBBUEkgc3VjaCBhcyBtdWx0aXBsZSBldmVudFxuICAvLyBuYW1lcyBgXCJjaGFuZ2UgYmx1clwiYCBhbmQgalF1ZXJ5LXN0eWxlIGV2ZW50IG1hcHMgYHtjaGFuZ2U6IGFjdGlvbn1gXG4gIC8vIGluIHRlcm1zIG9mIHRoZSBleGlzdGluZyBBUEkuXG4gIHZhciBldmVudHNBcGkgPSBmdW5jdGlvbihvYmosIGFjdGlvbiwgbmFtZSwgcmVzdCkge1xuICAgIGlmICghbmFtZSkgcmV0dXJuIHRydWU7XG5cbiAgICAvLyBIYW5kbGUgZXZlbnQgbWFwcy5cbiAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gbmFtZSkge1xuICAgICAgICBvYmpbYWN0aW9uXS5hcHBseShvYmosIFtrZXksIG5hbWVba2V5XV0uY29uY2F0KHJlc3QpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgc3BhY2Ugc2VwYXJhdGVkIGV2ZW50IG5hbWVzLlxuICAgIGlmIChldmVudFNwbGl0dGVyLnRlc3QobmFtZSkpIHtcbiAgICAgIHZhciBuYW1lcyA9IG5hbWUuc3BsaXQoZXZlbnRTcGxpdHRlcik7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG5hbWVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBvYmpbYWN0aW9uXS5hcHBseShvYmosIFtuYW1lc1tpXV0uY29uY2F0KHJlc3QpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICAvLyBBIGRpZmZpY3VsdC10by1iZWxpZXZlLCBidXQgb3B0aW1pemVkIGludGVybmFsIGRpc3BhdGNoIGZ1bmN0aW9uIGZvclxuICAvLyB0cmlnZ2VyaW5nIGV2ZW50cy4gVHJpZXMgdG8ga2VlcCB0aGUgdXN1YWwgY2FzZXMgc3BlZWR5IChtb3N0IGludGVybmFsXG4gIC8vIEJhY2tib25lIGV2ZW50cyBoYXZlIDMgYXJndW1lbnRzKS5cbiAgdmFyIHRyaWdnZXJFdmVudHMgPSBmdW5jdGlvbihldmVudHMsIGFyZ3MpIHtcbiAgICB2YXIgZXYsIGkgPSAtMSwgbCA9IGV2ZW50cy5sZW5ndGgsIGExID0gYXJnc1swXSwgYTIgPSBhcmdzWzFdLCBhMyA9IGFyZ3NbMl07XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCk7IHJldHVybjtcbiAgICAgIGNhc2UgMTogd2hpbGUgKCsraSA8IGwpIChldiA9IGV2ZW50c1tpXSkuY2FsbGJhY2suY2FsbChldi5jdHgsIGExKTsgcmV0dXJuO1xuICAgICAgY2FzZSAyOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCwgYTEsIGEyKTsgcmV0dXJuO1xuICAgICAgY2FzZSAzOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCwgYTEsIGEyLCBhMyk7IHJldHVybjtcbiAgICAgIGRlZmF1bHQ6IHdoaWxlICgrK2kgPCBsKSAoZXYgPSBldmVudHNbaV0pLmNhbGxiYWNrLmFwcGx5KGV2LmN0eCwgYXJncyk7XG4gICAgfVxuICB9O1xuXG4gIHZhciBsaXN0ZW5NZXRob2RzID0ge2xpc3RlblRvOiAnb24nLCBsaXN0ZW5Ub09uY2U6ICdvbmNlJ307XG5cbiAgLy8gSW52ZXJzaW9uLW9mLWNvbnRyb2wgdmVyc2lvbnMgb2YgYG9uYCBhbmQgYG9uY2VgLiBUZWxsICp0aGlzKiBvYmplY3QgdG9cbiAgLy8gbGlzdGVuIHRvIGFuIGV2ZW50IGluIGFub3RoZXIgb2JqZWN0IC4uLiBrZWVwaW5nIHRyYWNrIG9mIHdoYXQgaXQnc1xuICAvLyBsaXN0ZW5pbmcgdG8uXG4gIF8uZWFjaChsaXN0ZW5NZXRob2RzLCBmdW5jdGlvbihpbXBsZW1lbnRhdGlvbiwgbWV0aG9kKSB7XG4gICAgRXZlbnRzW21ldGhvZF0gPSBmdW5jdGlvbihvYmosIG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzIHx8ICh0aGlzLl9saXN0ZW5lcnMgPSB7fSk7XG4gICAgICB2YXIgaWQgPSBvYmouX2xpc3RlbmVySWQgfHwgKG9iai5fbGlzdGVuZXJJZCA9IF8udW5pcXVlSWQoJ2wnKSk7XG4gICAgICBsaXN0ZW5lcnNbaWRdID0gb2JqO1xuICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0JykgY2FsbGJhY2sgPSB0aGlzO1xuICAgICAgb2JqW2ltcGxlbWVudGF0aW9uXShuYW1lLCBjYWxsYmFjaywgdGhpcyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICB9KTtcblxuICAvLyBBbGlhc2VzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgRXZlbnRzLmJpbmQgICA9IEV2ZW50cy5vbjtcbiAgRXZlbnRzLnVuYmluZCA9IEV2ZW50cy5vZmY7XG5cbiAgLy8gTWl4aW4gdXRpbGl0eVxuICBFdmVudHMubWl4aW4gPSBmdW5jdGlvbihwcm90bykge1xuICAgIHZhciBleHBvcnRzID0gWydvbicsICdvbmNlJywgJ29mZicsICd0cmlnZ2VyJywgJ3N0b3BMaXN0ZW5pbmcnLCAnbGlzdGVuVG8nLFxuICAgICAgICAgICAgICAgICAgICdsaXN0ZW5Ub09uY2UnLCAnYmluZCcsICd1bmJpbmQnXTtcbiAgICBfLmVhY2goZXhwb3J0cywgZnVuY3Rpb24obmFtZSkge1xuICAgICAgcHJvdG9bbmFtZV0gPSB0aGlzW25hbWVdO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiBwcm90bztcbiAgfTtcblxuICAvLyBFeHBvcnQgRXZlbnRzIGFzIEJhY2tib25lRXZlbnRzIGRlcGVuZGluZyBvbiBjdXJyZW50IGNvbnRleHRcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBFdmVudHM7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBFdmVudHM7XG4gICAgfVxuICAgIGV4cG9ydHMuQmFja2JvbmVFdmVudHMgPSBFdmVudHM7XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5CYWNrYm9uZUV2ZW50cyA9IEV2ZW50cztcbiAgfVxufSkodGhpcyk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUnKTtcbiIsIi8vIGQzLnRpcFxuLy8gQ29weXJpZ2h0IChjKSAyMDEzIEp1c3RpbiBQYWxtZXJcbi8vXG4vLyBUb29sdGlwcyBmb3IgZDMuanMgU1ZHIHZpc3VhbGl6YXRpb25zXG5cbihmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgLy8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlIHdpdGggZDMgYXMgYSBkZXBlbmRlbmN5LlxuICAgIGRlZmluZShbJ2QzJ10sIGZhY3RvcnkpXG4gIH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAvLyBDb21tb25KU1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZDMpIHtcbiAgICAgIGQzLnRpcCA9IGZhY3RvcnkoZDMpXG4gICAgICByZXR1cm4gZDMudGlwXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIEJyb3dzZXIgZ2xvYmFsLlxuICAgIHJvb3QuZDMudGlwID0gZmFjdG9yeShyb290LmQzKVxuICB9XG59KHRoaXMsIGZ1bmN0aW9uIChkMykge1xuXG4gIC8vIFB1YmxpYyAtIGNvbnRydWN0cyBhIG5ldyB0b29sdGlwXG4gIC8vXG4gIC8vIFJldHVybnMgYSB0aXBcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBkaXJlY3Rpb24gPSBkM190aXBfZGlyZWN0aW9uLFxuICAgICAgICBvZmZzZXQgICAgPSBkM190aXBfb2Zmc2V0LFxuICAgICAgICBodG1sICAgICAgPSBkM190aXBfaHRtbCxcbiAgICAgICAgbm9kZSAgICAgID0gaW5pdE5vZGUoKSxcbiAgICAgICAgc3ZnICAgICAgID0gbnVsbCxcbiAgICAgICAgcG9pbnQgICAgID0gbnVsbCxcbiAgICAgICAgdGFyZ2V0ICAgID0gbnVsbFxuXG4gICAgZnVuY3Rpb24gdGlwKHZpcykge1xuICAgICAgc3ZnID0gZ2V0U1ZHTm9kZSh2aXMpXG4gICAgICBwb2ludCA9IHN2Zy5jcmVhdGVTVkdQb2ludCgpXG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKG5vZGUpXG4gICAgfVxuXG4gICAgLy8gUHVibGljIC0gc2hvdyB0aGUgdG9vbHRpcCBvbiB0aGUgc2NyZWVuXG4gICAgLy9cbiAgICAvLyBSZXR1cm5zIGEgdGlwXG4gICAgdGlwLnNob3cgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKVxuICAgICAgaWYoYXJnc1thcmdzLmxlbmd0aCAtIDFdIGluc3RhbmNlb2YgU1ZHRWxlbWVudCkgdGFyZ2V0ID0gYXJncy5wb3AoKVxuXG4gICAgICB2YXIgY29udGVudCA9IGh0bWwuYXBwbHkodGhpcywgYXJncyksXG4gICAgICAgICAgcG9mZnNldCA9IG9mZnNldC5hcHBseSh0aGlzLCBhcmdzKSxcbiAgICAgICAgICBkaXIgICAgID0gZGlyZWN0aW9uLmFwcGx5KHRoaXMsIGFyZ3MpLFxuICAgICAgICAgIG5vZGVsICAgPSBkMy5zZWxlY3Qobm9kZSksXG4gICAgICAgICAgaSAgICAgICA9IGRpcmVjdGlvbnMubGVuZ3RoLFxuICAgICAgICAgIGNvb3JkcyxcbiAgICAgICAgICBzY3JvbGxUb3AgID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCxcbiAgICAgICAgICBzY3JvbGxMZWZ0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0XG5cbiAgICAgIG5vZGVsLmh0bWwoY29udGVudClcbiAgICAgICAgLnN0eWxlKHsgb3BhY2l0eTogMSwgJ3BvaW50ZXItZXZlbnRzJzogJ2FsbCcgfSlcblxuICAgICAgd2hpbGUoaS0tKSBub2RlbC5jbGFzc2VkKGRpcmVjdGlvbnNbaV0sIGZhbHNlKVxuICAgICAgY29vcmRzID0gZGlyZWN0aW9uX2NhbGxiYWNrcy5nZXQoZGlyKS5hcHBseSh0aGlzKVxuICAgICAgbm9kZWwuY2xhc3NlZChkaXIsIHRydWUpLnN0eWxlKHtcbiAgICAgICAgdG9wOiAoY29vcmRzLnRvcCArICBwb2Zmc2V0WzBdKSArIHNjcm9sbFRvcCArICdweCcsXG4gICAgICAgIGxlZnQ6IChjb29yZHMubGVmdCArIHBvZmZzZXRbMV0pICsgc2Nyb2xsTGVmdCArICdweCdcbiAgICAgIH0pXG5cbiAgICAgIHJldHVybiB0aXBcbiAgICB9XG5cbiAgICAvLyBQdWJsaWMgLSBoaWRlIHRoZSB0b29sdGlwXG4gICAgLy9cbiAgICAvLyBSZXR1cm5zIGEgdGlwXG4gICAgdGlwLmhpZGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBub2RlbCA9IGQzLnNlbGVjdChub2RlKVxuICAgICAgbm9kZWwuc3R5bGUoeyBvcGFjaXR5OiAwLCAncG9pbnRlci1ldmVudHMnOiAnbm9uZScgfSlcbiAgICAgIHJldHVybiB0aXBcbiAgICB9XG5cbiAgICAvLyBQdWJsaWM6IFByb3h5IGF0dHIgY2FsbHMgdG8gdGhlIGQzIHRpcCBjb250YWluZXIuICBTZXRzIG9yIGdldHMgYXR0cmlidXRlIHZhbHVlLlxuICAgIC8vXG4gICAgLy8gbiAtIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZVxuICAgIC8vIHYgLSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlXG4gICAgLy9cbiAgICAvLyBSZXR1cm5zIHRpcCBvciBhdHRyaWJ1dGUgdmFsdWVcbiAgICB0aXAuYXR0ciA9IGZ1bmN0aW9uKG4sIHYpIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMiAmJiB0eXBlb2YgbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGQzLnNlbGVjdChub2RlKS5hdHRyKG4pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgYXJncyA9ICBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpXG4gICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUuYXR0ci5hcHBseShkMy5zZWxlY3Qobm9kZSksIGFyZ3MpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aXBcbiAgICB9XG5cbiAgICAvLyBQdWJsaWM6IFByb3h5IHN0eWxlIGNhbGxzIHRvIHRoZSBkMyB0aXAgY29udGFpbmVyLiAgU2V0cyBvciBnZXRzIGEgc3R5bGUgdmFsdWUuXG4gICAgLy9cbiAgICAvLyBuIC0gbmFtZSBvZiB0aGUgcHJvcGVydHlcbiAgICAvLyB2IC0gdmFsdWUgb2YgdGhlIHByb3BlcnR5XG4gICAgLy9cbiAgICAvLyBSZXR1cm5zIHRpcCBvciBzdHlsZSBwcm9wZXJ0eSB2YWx1ZVxuICAgIHRpcC5zdHlsZSA9IGZ1bmN0aW9uKG4sIHYpIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMiAmJiB0eXBlb2YgbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGQzLnNlbGVjdChub2RlKS5zdHlsZShuKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGFyZ3MgPSAgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKVxuICAgICAgICBkMy5zZWxlY3Rpb24ucHJvdG90eXBlLnN0eWxlLmFwcGx5KGQzLnNlbGVjdChub2RlKSwgYXJncylcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRpcFxuICAgIH1cblxuICAgIC8vIFB1YmxpYzogU2V0IG9yIGdldCB0aGUgZGlyZWN0aW9uIG9mIHRoZSB0b29sdGlwXG4gICAgLy9cbiAgICAvLyB2IC0gT25lIG9mIG4obm9ydGgpLCBzKHNvdXRoKSwgZShlYXN0KSwgb3Igdyh3ZXN0KSwgbncobm9ydGh3ZXN0KSxcbiAgICAvLyAgICAgc3coc291dGh3ZXN0KSwgbmUobm9ydGhlYXN0KSBvciBzZShzb3V0aGVhc3QpXG4gICAgLy9cbiAgICAvLyBSZXR1cm5zIHRpcCBvciBkaXJlY3Rpb25cbiAgICB0aXAuZGlyZWN0aW9uID0gZnVuY3Rpb24odikge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZGlyZWN0aW9uXG4gICAgICBkaXJlY3Rpb24gPSB2ID09IG51bGwgPyB2IDogZDMuZnVuY3Rvcih2KVxuXG4gICAgICByZXR1cm4gdGlwXG4gICAgfVxuXG4gICAgLy8gUHVibGljOiBTZXRzIG9yIGdldHMgdGhlIG9mZnNldCBvZiB0aGUgdGlwXG4gICAgLy9cbiAgICAvLyB2IC0gQXJyYXkgb2YgW3gsIHldIG9mZnNldFxuICAgIC8vXG4gICAgLy8gUmV0dXJucyBvZmZzZXQgb3JcbiAgICB0aXAub2Zmc2V0ID0gZnVuY3Rpb24odikge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gb2Zmc2V0XG4gICAgICBvZmZzZXQgPSB2ID09IG51bGwgPyB2IDogZDMuZnVuY3Rvcih2KVxuXG4gICAgICByZXR1cm4gdGlwXG4gICAgfVxuXG4gICAgLy8gUHVibGljOiBzZXRzIG9yIGdldHMgdGhlIGh0bWwgdmFsdWUgb2YgdGhlIHRvb2x0aXBcbiAgICAvL1xuICAgIC8vIHYgLSBTdHJpbmcgdmFsdWUgb2YgdGhlIHRpcFxuICAgIC8vXG4gICAgLy8gUmV0dXJucyBodG1sIHZhbHVlIG9yIHRpcFxuICAgIHRpcC5odG1sID0gZnVuY3Rpb24odikge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gaHRtbFxuICAgICAgaHRtbCA9IHYgPT0gbnVsbCA/IHYgOiBkMy5mdW5jdG9yKHYpXG5cbiAgICAgIHJldHVybiB0aXBcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkM190aXBfZGlyZWN0aW9uKCkgeyByZXR1cm4gJ24nIH1cbiAgICBmdW5jdGlvbiBkM190aXBfb2Zmc2V0KCkgeyByZXR1cm4gWzAsIDBdIH1cbiAgICBmdW5jdGlvbiBkM190aXBfaHRtbCgpIHsgcmV0dXJuICcgJyB9XG5cbiAgICB2YXIgZGlyZWN0aW9uX2NhbGxiYWNrcyA9IGQzLm1hcCh7XG4gICAgICBuOiAgZGlyZWN0aW9uX24sXG4gICAgICBzOiAgZGlyZWN0aW9uX3MsXG4gICAgICBlOiAgZGlyZWN0aW9uX2UsXG4gICAgICB3OiAgZGlyZWN0aW9uX3csXG4gICAgICBudzogZGlyZWN0aW9uX253LFxuICAgICAgbmU6IGRpcmVjdGlvbl9uZSxcbiAgICAgIHN3OiBkaXJlY3Rpb25fc3csXG4gICAgICBzZTogZGlyZWN0aW9uX3NlXG4gICAgfSksXG5cbiAgICBkaXJlY3Rpb25zID0gZGlyZWN0aW9uX2NhbGxiYWNrcy5rZXlzKClcblxuICAgIGZ1bmN0aW9uIGRpcmVjdGlvbl9uKCkge1xuICAgICAgdmFyIGJib3ggPSBnZXRTY3JlZW5CQm94KClcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogIGJib3gubi55IC0gbm9kZS5vZmZzZXRIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGJib3gubi54IC0gbm9kZS5vZmZzZXRXaWR0aCAvIDJcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkaXJlY3Rpb25fcygpIHtcbiAgICAgIHZhciBiYm94ID0gZ2V0U2NyZWVuQkJveCgpXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6ICBiYm94LnMueSxcbiAgICAgICAgbGVmdDogYmJveC5zLnggLSBub2RlLm9mZnNldFdpZHRoIC8gMlxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRpcmVjdGlvbl9lKCkge1xuICAgICAgdmFyIGJib3ggPSBnZXRTY3JlZW5CQm94KClcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogIGJib3guZS55IC0gbm9kZS5vZmZzZXRIZWlnaHQgLyAyLFxuICAgICAgICBsZWZ0OiBiYm94LmUueFxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRpcmVjdGlvbl93KCkge1xuICAgICAgdmFyIGJib3ggPSBnZXRTY3JlZW5CQm94KClcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogIGJib3gudy55IC0gbm9kZS5vZmZzZXRIZWlnaHQgLyAyLFxuICAgICAgICBsZWZ0OiBiYm94LncueCAtIG5vZGUub2Zmc2V0V2lkdGhcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkaXJlY3Rpb25fbncoKSB7XG4gICAgICB2YXIgYmJveCA9IGdldFNjcmVlbkJCb3goKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiAgYmJveC5udy55IC0gbm9kZS5vZmZzZXRIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGJib3gubncueCAtIG5vZGUub2Zmc2V0V2lkdGhcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkaXJlY3Rpb25fbmUoKSB7XG4gICAgICB2YXIgYmJveCA9IGdldFNjcmVlbkJCb3goKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiAgYmJveC5uZS55IC0gbm9kZS5vZmZzZXRIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGJib3gubmUueFxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRpcmVjdGlvbl9zdygpIHtcbiAgICAgIHZhciBiYm94ID0gZ2V0U2NyZWVuQkJveCgpXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6ICBiYm94LnN3LnksXG4gICAgICAgIGxlZnQ6IGJib3guc3cueCAtIG5vZGUub2Zmc2V0V2lkdGhcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkaXJlY3Rpb25fc2UoKSB7XG4gICAgICB2YXIgYmJveCA9IGdldFNjcmVlbkJCb3goKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiAgYmJveC5zZS55LFxuICAgICAgICBsZWZ0OiBiYm94LmUueFxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluaXROb2RlKCkge1xuICAgICAgdmFyIG5vZGUgPSBkMy5zZWxlY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykpXG4gICAgICBub2RlLnN0eWxlKHtcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgIHRvcDogMCxcbiAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgJ3BvaW50ZXItZXZlbnRzJzogJ25vbmUnLFxuICAgICAgICAnYm94LXNpemluZyc6ICdib3JkZXItYm94J1xuICAgICAgfSlcblxuICAgICAgcmV0dXJuIG5vZGUubm9kZSgpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U1ZHTm9kZShlbCkge1xuICAgICAgZWwgPSBlbC5ub2RlKClcbiAgICAgIGlmKGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3N2ZycpXG4gICAgICAgIHJldHVybiBlbFxuXG4gICAgICByZXR1cm4gZWwub3duZXJTVkdFbGVtZW50XG4gICAgfVxuXG4gICAgLy8gUHJpdmF0ZSAtIGdldHMgdGhlIHNjcmVlbiBjb29yZGluYXRlcyBvZiBhIHNoYXBlXG4gICAgLy9cbiAgICAvLyBHaXZlbiBhIHNoYXBlIG9uIHRoZSBzY3JlZW4sIHdpbGwgcmV0dXJuIGFuIFNWR1BvaW50IGZvciB0aGUgZGlyZWN0aW9uc1xuICAgIC8vIG4obm9ydGgpLCBzKHNvdXRoKSwgZShlYXN0KSwgdyh3ZXN0KSwgbmUobm9ydGhlYXN0KSwgc2Uoc291dGhlYXN0KSwgbncobm9ydGh3ZXN0KSxcbiAgICAvLyBzdyhzb3V0aHdlc3QpLlxuICAgIC8vXG4gICAgLy8gICAgKy0rLStcbiAgICAvLyAgICB8ICAgfFxuICAgIC8vICAgICsgICArXG4gICAgLy8gICAgfCAgIHxcbiAgICAvLyAgICArLSstK1xuICAgIC8vXG4gICAgLy8gUmV0dXJucyBhbiBPYmplY3Qge24sIHMsIGUsIHcsIG53LCBzdywgbmUsIHNlfVxuICAgIGZ1bmN0aW9uIGdldFNjcmVlbkJCb3goKSB7XG4gICAgICB2YXIgdGFyZ2V0ZWwgICA9IHRhcmdldCB8fCBkMy5ldmVudC50YXJnZXQ7XG5cbiAgICAgIHdoaWxlICgndW5kZWZpbmVkJyA9PT0gdHlwZW9mIHRhcmdldGVsLmdldFNjcmVlbkNUTSAmJiAndW5kZWZpbmVkJyA9PT0gdGFyZ2V0ZWwucGFyZW50Tm9kZSkge1xuICAgICAgICAgIHRhcmdldGVsID0gdGFyZ2V0ZWwucGFyZW50Tm9kZTtcbiAgICAgIH1cblxuICAgICAgdmFyIGJib3ggICAgICAgPSB7fSxcbiAgICAgICAgICBtYXRyaXggICAgID0gdGFyZ2V0ZWwuZ2V0U2NyZWVuQ1RNKCksXG4gICAgICAgICAgdGJib3ggICAgICA9IHRhcmdldGVsLmdldEJCb3goKSxcbiAgICAgICAgICB3aWR0aCAgICAgID0gdGJib3gud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0ICAgICA9IHRiYm94LmhlaWdodCxcbiAgICAgICAgICB4ICAgICAgICAgID0gdGJib3gueCxcbiAgICAgICAgICB5ICAgICAgICAgID0gdGJib3gueVxuXG4gICAgICBwb2ludC54ID0geFxuICAgICAgcG9pbnQueSA9IHlcbiAgICAgIGJib3gubncgPSBwb2ludC5tYXRyaXhUcmFuc2Zvcm0obWF0cml4KVxuICAgICAgcG9pbnQueCArPSB3aWR0aFxuICAgICAgYmJveC5uZSA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShtYXRyaXgpXG4gICAgICBwb2ludC55ICs9IGhlaWdodFxuICAgICAgYmJveC5zZSA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShtYXRyaXgpXG4gICAgICBwb2ludC54IC09IHdpZHRoXG4gICAgICBiYm94LnN3ID0gcG9pbnQubWF0cml4VHJhbnNmb3JtKG1hdHJpeClcbiAgICAgIHBvaW50LnkgLT0gaGVpZ2h0IC8gMlxuICAgICAgYmJveC53ICA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShtYXRyaXgpXG4gICAgICBwb2ludC54ICs9IHdpZHRoXG4gICAgICBiYm94LmUgPSBwb2ludC5tYXRyaXhUcmFuc2Zvcm0obWF0cml4KVxuICAgICAgcG9pbnQueCAtPSB3aWR0aCAvIDJcbiAgICAgIHBvaW50LnkgLT0gaGVpZ2h0IC8gMlxuICAgICAgYmJveC5uID0gcG9pbnQubWF0cml4VHJhbnNmb3JtKG1hdHJpeClcbiAgICAgIHBvaW50LnkgKz0gaGVpZ2h0XG4gICAgICBiYm94LnMgPSBwb2ludC5tYXRyaXhUcmFuc2Zvcm0obWF0cml4KVxuXG4gICAgICByZXR1cm4gYmJveFxuICAgIH1cblxuICAgIHJldHVybiB0aXBcbiAgfTtcblxufSkpO1xuIiwiLyoqXG4gKlxuICogTXV0YXRpb25zIE5lZWRsZSBQbG90IChtdXRzLW5lZWRsZS1wbG90KVxuICpcbiAqIENyZWF0ZXMgYSBuZWVkbGUgcGxvdCAoYS5rLmEgc3RlbSBwbG90LCBsb2xsaXBvcC1wbG90IGFuZCBzb29uIGFsc28gYmFsbG9vbiBwbG90IDstKVxuICogVGhpcyBjbGFzcyB1c2VzIHRoZSBucG0tcmVxdWlyZSBtb2R1bGUgdG8gbG9hZCBkZXBlbmRlbmNpZXMgZDMsIGQzLXRpcFxuICpcbiAqIEBhdXRob3IgTWljaGFlbCBQIFNjaHJvZWRlclxuICogQGNsYXNzXG4gKi9cblxuZnVuY3Rpb24gTXV0c05lZWRsZVBsb3QgKGNvbmZpZykge1xuXG4gICAgLy8gSU5JVElBTElaQVRJT05cblxuICAgIHZhciBzZWxmID0gdGhpczsgICAgICAgIC8vIHNlbGYgPSBNdXRzTmVlZGxlUGxvdFxuXG4gICAgLy8gWC1jb29yZGluYXRlc1xuICAgIHRoaXMubWF4Q29vcmQgPSBjb25maWcubWF4Q29vcmQgfHwgLTE7ICAgICAgICAgICAgIC8vIFRoZSBtYXhpbXVtIGNvb3JkICh4LWF4aXMpXG4gICAgaWYgKHRoaXMubWF4Q29vcmQgPCAwKSB7IHRocm93IG5ldyBFcnJvcihcIidtYXhDb29yZCcgbXVzdCBiZSBkZWZpbmVkIGluaXRpYXRpb24gY29uZmlnIVwiKTsgfVxuICAgIHRoaXMubWluQ29vcmQgPSBjb25maWcubWluQ29vcmQgfHwgMTsgICAgICAgICAgICAgICAvLyBUaGUgbWluaW11bSBjb29yZCAoeC1heGlzKVxuXG4gICAgLy8gZGF0YVxuICAgIG11dGF0aW9uRGF0YSA9IGNvbmZpZy5tdXRhdGlvbkRhdGEgfHwgLTE7ICAgICAgICAgIC8vIC5qc29uIGZpbGUgb3IgZGljdFxuICAgIGlmICh0aGlzLm1heENvb3JkIDwgMCkgeyB0aHJvdyBuZXcgRXJyb3IoXCInbXV0YXRpb25EYXRhJyBtdXN0IGJlIGRlZmluZWQgaW5pdGlhdGlvbiBjb25maWchXCIpOyB9XG4gICAgcmVnaW9uRGF0YSA9IGNvbmZpZy5yZWdpb25EYXRhIHx8IC0xOyAgICAgICAgICAgICAgLy8gLmpzb24gZmlsZSBvciBkaWN0XG4gICAgaWYgKHRoaXMubWF4Q29vcmQgPCAwKSB7IHRocm93IG5ldyBFcnJvcihcIidyZWdpb25EYXRhJyBtdXN0IGJlIGRlZmluZWQgaW5pdGlhdGlvbiBjb25maWchXCIpOyB9XG4gICAgdGhpcy50b3RhbENhdGVnQ291bnRzID0ge307XG4gICAgdGhpcy5jYXRlZ0NvdW50cyA9IHt9O1xuICAgIHRoaXMuc2VsZWN0ZWROZWVkbGVzID0gW107XG5cbiAgICAvLyBQbG90IGRpbWVuc2lvbnMgJiB0YXJnZXRcbiAgICB2YXIgdGFyZ2V0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGNvbmZpZy50YXJnZXRFbGVtZW50KSB8fCBjb25maWcudGFyZ2V0RWxlbWVudCB8fCBkb2N1bWVudC5ib2R5ICAgLy8gV2hlcmUgdG8gYXBwZW5kIHRoZSBwbG90IChzdmcpXG5cbiAgICB2YXIgd2lkdGggPSB0aGlzLndpZHRoID0gY29uZmlnLndpZHRoIHx8IHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggfHwgMTAwMDtcbiAgICB2YXIgaGVpZ2h0ID0gdGhpcy5oZWlnaHQgPSBjb25maWcuaGVpZ2h0IHx8IHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IDUwMDtcblxuICAgIC8vIENvbG9yIHNjYWxlICYgbWFwXG4gICAgdGhpcy5jb2xvck1hcCA9IGNvbmZpZy5jb2xvck1hcCB8fCB7fTsgICAgICAgICAgICAgIC8vIGRpY3RcbiAgICB2YXIgY29sb3JzID0gT2JqZWN0LmtleXModGhpcy5jb2xvck1hcCkubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuY29sb3JNYXBba2V5XTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbG9yU2NhbGUgPSBkMy5zY2FsZS5jYXRlZ29yeTIwKClcbiAgICAgICAgLmRvbWFpbihPYmplY3Qua2V5cyh0aGlzLmNvbG9yTWFwKSlcbiAgICAgICAgLnJhbmdlKGNvbG9ycy5jb25jYXQoZDMuc2NhbGUuY2F0ZWdvcnkyMCgpLnJhbmdlKCkpKTtcbiAgICB0aGlzLmxlZ2VuZHMgPSBjb25maWcubGVnZW5kcyB8fCB7XG4gICAgICAgIFwieVwiOiBcIlZhbHVlXCIsXG4gICAgICAgIFwieFwiOiBcIkNvb3JkaW5hdGVcIlxuICAgIH07XG5cbiAgICB0aGlzLnN2Z0NsYXNzZXMgPSBcIm11dG5lZWRsZXNcIlxuICAgIHRoaXMuYnVmZmVyID0gMDtcblxuICAgIHZhciBtYXhDb29yZCA9IHRoaXMubWF4Q29vcmQ7XG5cbiAgICB2YXIgYnVmZmVyID0gMDtcbiAgICBpZiAod2lkdGggPj0gaGVpZ2h0KSB7XG4gICAgICBidWZmZXIgPSBoZWlnaHQgLyA4O1xuICAgIH0gZWxzZSB7XG4gICAgICBidWZmZXIgPSB3aWR0aCAvIDg7XG4gICAgfVxuXG4gICAgdGhpcy5idWZmZXIgPSBidWZmZXI7XG5cbiAgICAvLyBJSU1QT1JUIEFORCBDT05GSUdVUkUgVElQU1xuICAgIHZhciBkM3RpcCA9IHJlcXVpcmUoJ2QzLXRpcCcpO1xuICAgIGQzdGlwKGQzKTtcblxuXG4gICAgdGhpcy50aXAgPSBkMy50aXAoKVxuICAgICAgLmF0dHIoJ2NsYXNzJywgJ2QzLXRpcCBkMy10aXAtbmVlZGxlJylcbiAgICAgIC5vZmZzZXQoWy0xMCwgMF0pXG4gICAgICAuaHRtbChmdW5jdGlvbihkKSB7XG4gICAgICAgIHJldHVybiBcIjxzcGFuPlwiICsgZC52YWx1ZSArIFwiIFwiICsgZC5jYXRlZ29yeSArICBcIiBhdCBjb29yZC4gXCIgKyBkLmNvb3JkU3RyaW5nICsgXCI8L3NwYW4+XCI7XG4gICAgICB9KTtcblxuICAgIHRoaXMuc2VsZWN0aW9uVGlwID0gZDMudGlwKClcbiAgICAgICAgLmF0dHIoJ2NsYXNzJywgJ2QzLXRpcCBkMy10aXAtc2VsZWN0aW9uJylcbiAgICAgICAgLm9mZnNldChbMTAwLCAwXSlcbiAgICAgICAgLmh0bWwoZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiPHNwYW4+IFNlbGVjdGVkIGNvb3JkaW5hdGVzPGJyLz5cIiArIE1hdGgucm91bmQoZC5sZWZ0KSArIFwiIC0gXCIgKyBNYXRoLnJvdW5kKGQucmlnaHQpICsgXCI8L3NwYW4+XCI7XG4gICAgICAgIH0pXG4gICAgICAgIC5kaXJlY3Rpb24oJ24nKTtcblxuICAgIC8vIElOSVQgU1ZHXG5cbiAgICB2YXIgc3ZnID0gZDMuc2VsZWN0KHRhcmdldEVsZW1lbnQpLmFwcGVuZChcInN2Z1wiKVxuICAgICAgICAuYXR0cihcIndpZHRoXCIsIHdpZHRoKVxuICAgICAgICAuYXR0cihcImhlaWdodFwiLCBoZWlnaHQpXG4gICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgdGhpcy5zdmdDbGFzc2VzKTtcblxuICAgIHN2Zy5jYWxsKHRoaXMudGlwKTtcbiAgICBzdmcuY2FsbCh0aGlzLnNlbGVjdGlvblRpcCk7XG5cbiAgICAvLyBERUZJTkUgU0NBTEVTXG5cbiAgICB2YXIgeCA9IGQzLnNjYWxlLmxpbmVhcigpXG4gICAgICAuZG9tYWluKFt0aGlzLm1pbkNvb3JkLCB0aGlzLm1heENvb3JkXSlcbiAgICAgIC5yYW5nZShbYnVmZmVyICogMS41ICwgd2lkdGggLSBidWZmZXJdKVxuICAgICAgLm5pY2UoKTtcbiAgICB0aGlzLnggPSB4O1xuXG4gICAgdmFyIHkgPSBkMy5zY2FsZS5saW5lYXIoKVxuICAgICAgLmRvbWFpbihbMSwyMF0pXG4gICAgICAucmFuZ2UoW2hlaWdodCAtIGJ1ZmZlciAqIDEuNSwgYnVmZmVyXSlcbiAgICAgIC5uaWNlKCk7XG4gICAgdGhpcy55ID0geTtcblxuICAgIC8vIENPTkZJR1VSRSBCUlVTSFxuICAgIHNlbGYuc2VsZWN0b3IgPSBkMy5zdmcuYnJ1c2goKVxuICAgICAgICAueCh4KVxuICAgICAgICAub24oXCJicnVzaFwiLCBicnVzaG1vdmUpXG4gICAgICAgIC5vbihcImJydXNoZW5kXCIsIGJydXNoZW5kKTtcbiAgICB2YXIgc2VsZWN0b3IgPSBzZWxmLnNlbGVjdG9yO1xuXG4gICAgdGhpcy5zdmdDbGFzc2VzICs9IFwiIGJydXNoXCI7XG4gICAgdmFyIHNlbGVjdGlvblJlY3QgPSBzdmcuYXR0cihcImNsYXNzXCIsIHRoaXMuc3ZnQ2xhc3NlcylcbiAgICAgICAgLmNhbGwoc2VsZWN0b3IpXG4gICAgICAgIC5zZWxlY3RBbGwoJy5leHRlbnQnKVxuICAgICAgICAuYXR0cignaGVpZ2h0JywgaGVpZ2h0KTtcblxuICAgIGZ1bmN0aW9uIGJydXNobW92ZSgpIHtcblxuICAgICAgICB2YXIgZXh0ZW50ID0gc2VsZWN0b3IuZXh0ZW50KCk7XG4gICAgICAgIG5lZWRsZUhlYWRzID0gZDMuc2VsZWN0QWxsKFwiLm5lZWRsZS1oZWFkXCIpO1xuICAgICAgICBzZWxlY3RlZE5lZWRsZXMgPSBbXTtcbiAgICAgICAgY2F0ZWdDb3VudHMgPSB7fTtcbiAgICAgICAgZm9yIChrZXkgaW4gT2JqZWN0LmtleXMoc2VsZi50b3RhbENhdGVnQ291bnRzKSkge1xuICAgICAgICAgICAgY2F0ZWdDb3VudHNba2V5XSA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBuZWVkbGVIZWFkcy5jbGFzc2VkKFwic2VsZWN0ZWRcIiwgZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgaXNfYnJ1c2hlZCA9IGV4dGVudFswXSA8PSBkLmNvb3JkICYmIGQuY29vcmQgPD0gZXh0ZW50WzFdO1xuICAgICAgICAgICAgaWYgKGlzX2JydXNoZWQpIHtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZE5lZWRsZXMucHVzaChkKTtcbiAgICAgICAgICAgICAgICBjYXRlZ0NvdW50c1tkLmNhdGVnb3J5XSA9IChjYXRlZ0NvdW50c1tkLmNhdGVnb3J5XSB8fCAwKSArIGQudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaXNfYnJ1c2hlZDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2VsZi50cmlnZ2VyKCduZWVkbGVTZWxlY3Rpb25DaGFuZ2UnLCB7XG4gICAgICAgIHNlbGVjdGVkIDogc2VsZWN0ZWROZWVkbGVzLFxuICAgICAgICAgICAgY2F0ZWdDb3VudHM6IGNhdGVnQ291bnRzLFxuICAgICAgICAgICAgY29vcmRzOiBleHRlbnRcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYnJ1c2hlbmQoKSB7XG4gICAgICAgIGdldF9idXR0b24gPSBkMy5zZWxlY3QoXCIuY2xlYXItYnV0dG9uXCIpO1xuICAgICAgICBzZWxmLnRyaWdnZXIoJ25lZWRsZVNlbGVjdGlvbkNoYW5nZUVuZCcsIHtcbiAgICAgICAgICAgIHNlbGVjdGVkIDogc2VsZWN0ZWROZWVkbGVzLFxuICAgICAgICAgICAgY2F0ZWdDb3VudHM6IGNhdGVnQ291bnRzLFxuICAgICAgICAgICAgY29vcmRzOiBzZWxlY3Rvci5leHRlbnQoKVxuICAgICAgICB9KTtcbiAgICAgICAgLyppZihnZXRfYnV0dG9uLmVtcHR5KCkgPT09IHRydWUpIHtcbiAgICAgICAgIGNsZWFyX2J1dHRvbiA9IHN2Zy5hcHBlbmQoJ3RleHQnKVxuICAgICAgICAgLmF0dHIoXCJ5XCIsIDQ2MClcbiAgICAgICAgIC5hdHRyKFwieFwiLCA4MjUpXG4gICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwiY2xlYXItYnV0dG9uXCIpXG4gICAgICAgICAudGV4dChcIkNsZWFyIEJydXNoXCIpO1xuICAgICAgICAgfVxuXG4gICAgICAgICB4LmRvbWFpbihicnVzaC5leHRlbnQoKSk7XG5cbiAgICAgICAgIHRyYW5zaXRpb25fZGF0YSgpO1xuICAgICAgICAgcmVzZXRfYXhpcygpO1xuXG4gICAgICAgICBwb2ludHMuY2xhc3NlZChcInNlbGVjdGVkXCIsIGZhbHNlKTtcbiAgICAgICAgIGQzLnNlbGVjdChcIi5icnVzaFwiKS5jYWxsKGJydXNoLmNsZWFyKCkpO1xuXG4gICAgICAgICBjbGVhcl9idXR0b24ub24oJ2NsaWNrJywgZnVuY3Rpb24oKXtcbiAgICAgICAgIHguZG9tYWluKFswLCA1MF0pO1xuICAgICAgICAgdHJhbnNpdGlvbl9kYXRhKCk7XG4gICAgICAgICByZXNldF9heGlzKCk7XG4gICAgICAgICBjbGVhcl9idXR0b24ucmVtb3ZlKCk7XG4gICAgICAgICB9KTsqL1xuICAgIH1cblxuICAgIC8vLyBEUkFXXG4gICAgdGhpcy5kcmF3TmVlZGxlcyhzdmcsIG11dGF0aW9uRGF0YSwgcmVnaW9uRGF0YSk7XG5cblxuICAgIHNlbGYub24oXCJuZWVkbGVTZWxlY3Rpb25DaGFuZ2VcIiwgZnVuY3Rpb24gKGVkYXRhKSB7XG4gICAgICAgIHNlbGYuY2F0ZWdDb3VudHMgPSBlZGF0YS5jYXRlZ0NvdW50cztcbiAgICAgICAgc2VsZi5zZWxlY3RlZE5lZWRsZXMgPSBlZGF0YS5zZWxlY3RlZDtcbiAgICAgICAgc3ZnLmNhbGwodmVydGljYWxMZWdlbmQpO1xuICAgIH0pO1xuXG4gICAgc2VsZi5vbihcIm5lZWRsZVNlbGVjdGlvbkNoYW5nZUVuZFwiLCBmdW5jdGlvbiAoZWRhdGEpIHtcbiAgICAgICAgc2VsZi5jYXRlZ0NvdW50cyA9IGVkYXRhLmNhdGVnQ291bnRzO1xuICAgICAgICBzZWxmLnNlbGVjdGVkTmVlZGxlcyA9IGVkYXRhLnNlbGVjdGVkO1xuICAgICAgICBzdmcuY2FsbCh2ZXJ0aWNhbExlZ2VuZCk7XG4gICAgfSk7XG5cbiAgICBzZWxmLm9uKFwibmVlZGxlU2VsZWN0aW9uQ2hhbmdlXCIsIGZ1bmN0aW9uKGVkYXRhKSB7XG4gICAgICAgICAgICBzZWxlY3Rpb24gPSBlZGF0YS5jb29yZHM7XG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uWzFdIC0gc2VsZWN0aW9uWzBdID4gMCkge1xuICAgICAgICAgICAgICAgIHNlbGYuc2VsZWN0aW9uVGlwLnNob3coe2xlZnQ6IHNlbGVjdGlvblswXSwgcmlnaHQ6IHNlbGVjdGlvblsxXX0sIHNlbGVjdGlvblJlY3Qubm9kZSgpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2VsZi5zZWxlY3Rpb25UaXAuaGlkZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuXG5cbn1cblxuTXV0c05lZWRsZVBsb3QucHJvdG90eXBlLmRyYXdMZWdlbmQgPSBmdW5jdGlvbihzdmcpIHtcblxuICAgIC8vIExFR0VORFxuICAgIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gcHJlcGFyZSBsZWdlbmQgY2F0ZWdvcmllcyAoY29ycmVjdCBvcmRlcilcbiAgICBtdXRDYXRlZ29yaWVzID0gW107XG4gICAgY2F0ZWdvcnlDb2xvcnMgPSBbXTtcbiAgICBhbGxjYXRlZ3MgPSBPYmplY3Qua2V5cyhzZWxmLnRvdGFsQ2F0ZWdDb3VudHMpOyAvLyByYW5kb20gb3JkZXJcbiAgICBvcmRlcmVkRGVjbGFyYXRpb24gPSBzZWxmLmNvbG9yU2NhbGUuZG9tYWluKCk7ICAvLyB3YW50ZWQgb3JkZXJcbiAgICBmb3IgKGlkeCBpbiBvcmRlcmVkRGVjbGFyYXRpb24pIHtcbiAgICAgICAgYyA9IG9yZGVyZWREZWNsYXJhdGlvbltpZHhdO1xuICAgICAgICBpZiAoYWxsY2F0ZWdzLmluZGV4T2YoYykgPiAtMSkge1xuICAgICAgICAgICAgbXV0Q2F0ZWdvcmllcy5wdXNoKGMpO1xuICAgICAgICAgICAgY2F0ZWdvcnlDb2xvcnMucHVzaChzZWxmLmNvbG9yU2NhbGUoYykpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjcmVhdGUgc2NhbGUgd2l0aCBjb3JyZWN0IG9yZGVyIG9mIGNhdGVnb3JpZXNcbiAgICBtdXRzU2NhbGUgPSBzZWxmLmNvbG9yU2NhbGUuZG9tYWluKG11dENhdGVnb3JpZXMpLnJhbmdlKGNhdGVnb3J5Q29sb3JzKTtcblxuXG4gICAgdmFyIGRvbWFpbiA9IHNlbGYueC5kb21haW4oKTtcbiAgICB4cGxhY2VtZW50ID0gKGRvbWFpblsxXSAtIGRvbWFpblswXSkgKiAwLjc1ICsgKGRvbWFpblsxXSAtIGRvbWFpblswXSk7XG5cbiAgICB2YXIgc3VtID0gMDtcbiAgICBmb3IgKHZhciBjIGluIHNlbGYudG90YWxDYXRlZ0NvdW50cykge1xuICAgICAgICBzdW0gKz0gc2VsZi50b3RhbENhdGVnQ291bnRzW2NdO1xuICAgIH1cblxuICAgIGxlZ2VuZExhYmVsID0gZnVuY3Rpb24oY2F0ZWcpIHtcbiAgICAgICAgdmFyIGNvdW50ID0gKHNlbGYuY2F0ZWdDb3VudHNbY2F0ZWddIHx8IChzZWxmLnNlbGVjdGVkTmVlZGxlcy5sZW5ndGggPT0gMCAmJiBzZWxmLnRvdGFsQ2F0ZWdDb3VudHNbY2F0ZWddKSB8fCAwKTtcbiAgICAgICAgcmV0dXJuICBjYXRlZyArIChjb3VudCA+IDAgPyBcIjogXCIgKyBNYXRoLnJvdW5kKGNvdW50L3N1bSoxMDApICsgXCIlXCIgOiBcIlwiKTtcbiAgICB9O1xuXG4gICAgbGVnZW5kQ2xhc3MgPSBmdW5jdGlvbihjYXRlZykge1xuICAgICAgICB2YXIgY291bnQgPSAoc2VsZi5jYXRlZ0NvdW50c1tjYXRlZ10gfHwgKHNlbGYuc2VsZWN0ZWROZWVkbGVzLmxlbmd0aCA9PSAwICYmIHNlbGYudG90YWxDYXRlZ0NvdW50c1tjYXRlZ10pIHx8IDApO1xuICAgICAgICByZXR1cm4gKGNvdW50ID4gMCkgPyBcIlwiIDogXCJub211dHNcIjtcbiAgICB9O1xuXG4gICAgc2VsZi5ub3Nob3cgPSBbXTtcbiAgICB2YXIgbmVlZGxlSGVhZHMgPSBkMy5zZWxlY3RBbGwoXCIubmVlZGxlLWhlYWRcIik7XG4gICAgc2hvd05vU2hvdyA9IGZ1bmN0aW9uKGNhdGVnKXtcbiAgICAgICAgaWYgKF8uY29udGFpbnMoc2VsZi5ub3Nob3csIGNhdGVnKSkge1xuICAgICAgICAgICAgc2VsZi5ub3Nob3cgPSBfLmZpbHRlcihzZWxmLm5vc2hvdywgZnVuY3Rpb24ocykgeyByZXR1cm4gcyAhPSBjYXRlZyB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGYubm9zaG93LnB1c2goY2F0ZWcpO1xuICAgICAgICB9XG4gICAgICAgIG5lZWRsZUhlYWRzLmNsYXNzZWQoXCJub3Nob3dcIiwgZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgcmV0dXJuIF8uY29udGFpbnMoc2VsZi5ub3Nob3csIGQuY2F0ZWdvcnkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGxlZ2VuZENlbGxzID0gZDMuc2VsZWN0QWxsKFwiZy5sZWdlbmRDZWxsc1wiKTtcbiAgICAgICAgbGVnZW5kQ2VsbHMuY2xhc3NlZChcIm5vc2hvd1wiLCBmdW5jdGlvbihkKSB7XG4gICAgICAgICAgICByZXR1cm4gXy5jb250YWlucyhzZWxmLm5vc2hvdywgZC5zdG9wWzBdKTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuXG4gICAgdmVydGljYWxMZWdlbmQgPSBkMy5zdmcubGVnZW5kKClcbiAgICAgICAgLmxhYmVsRm9ybWF0KGxlZ2VuZExhYmVsKVxuICAgICAgICAubGFiZWxDbGFzcyhsZWdlbmRDbGFzcylcbiAgICAgICAgLm9uTGVnZW5kQ2xpY2soc2hvd05vU2hvdylcbiAgICAgICAgLmNlbGxQYWRkaW5nKDQpXG4gICAgICAgIC5vcmllbnRhdGlvbihcInZlcnRpY2FsXCIpXG4gICAgICAgIC51bml0cyhzdW0gKyBcIiBNdXRhdGlvbnNcIilcbiAgICAgICAgLmNlbGxXaWR0aCgyMClcbiAgICAgICAgLmNlbGxIZWlnaHQoMTIpXG4gICAgICAgIC5pbnB1dFNjYWxlKG11dHNTY2FsZSlcbiAgICAgICAgLmNlbGxTdGVwcGluZyg0KVxuICAgICAgICAucGxhY2Uoe3g6IHhwbGFjZW1lbnQsIHk6IDUwfSk7XG5cbiAgICBzdmcuY2FsbCh2ZXJ0aWNhbExlZ2VuZCk7XG5cbn07XG5cbk11dHNOZWVkbGVQbG90LnByb3RvdHlwZS5kcmF3UmVnaW9ucyA9IGZ1bmN0aW9uKHN2ZywgcmVnaW9uRGF0YSkge1xuXG4gICAgdmFyIG1heENvb3JkID0gdGhpcy5tYXhDb29yZDtcbiAgICB2YXIgbWluQ29vcmQgPSB0aGlzLm1pbkNvb3JkO1xuICAgIHZhciBidWZmZXIgPSB0aGlzLmJ1ZmZlcjtcbiAgICB2YXIgY29sb3JzID0gdGhpcy5jb2xvck1hcDtcbiAgICB2YXIgeSA9IHRoaXMueTtcbiAgICB2YXIgeCA9IHRoaXMueDtcblxuICAgIHZhciBiZWxvdyA9IHRydWU7XG5cblxuICAgIGdldFJlZ2lvblN0YXJ0ID0gZnVuY3Rpb24ocmVnaW9uKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUludChyZWdpb24uc3BsaXQoXCItXCIpWzBdKVxuICAgIH07XG5cbiAgICBnZXRSZWdpb25FbmQgPSBmdW5jdGlvbihyZWdpb24pIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHJlZ2lvbi5zcGxpdChcIi1cIilbMV0pXG4gICAgfTtcblxuICAgIGdldENvbG9yID0gdGhpcy5jb2xvclNjYWxlO1xuXG4gICAgdmFyIGJnX29mZnNldCA9IDA7XG4gICAgdmFyIHJlZ2lvbl9vZmZzZXQgPSBiZ19vZmZzZXQtM1xuICAgIHZhciB0ZXh0X29mZnNldCA9IGJnX29mZnNldCArIDIwO1xuICAgIGlmIChiZWxvdyAhPSB0cnVlKSB7XG4gICAgICAgIHRleHRfb2Zmc2V0ID0gYmdfb2Zmc2V0KzU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZHJhdyhyZWdpb25MaXN0KSB7XG5cbiAgICAgICAgdmFyIHJlZ2lvbnNCRyA9IGQzLnNlbGVjdChcIi5tdXRuZWVkbGVzXCIpLnNlbGVjdEFsbCgpXG4gICAgICAgICAgICAuZGF0YShbXCJkdW1teVwiXSkuZW50ZXIoKVxuICAgICAgICAgICAgLmluc2VydChcImdcIiwgXCI6Zmlyc3QtY2hpbGRcIilcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJyZWdpb25zQkdcIilcbiAgICAgICAgICAgIC5hcHBlbmQoXCJyZWN0XCIpXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgeChtaW5Db29yZCkgKVxuICAgICAgICAgICAgLmF0dHIoXCJ5XCIsIHkoMCkgKyBiZ19vZmZzZXQgKVxuICAgICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCB4KG1heENvb3JkKSAtIHgobWluQ29vcmQpIClcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIDEwKTtcblxuXG4gICAgICAgIHZhciByZWdpb25zID0gcmVnaW9uc0JHID0gZDMuc2VsZWN0KFwiLm11dG5lZWRsZXNcIikuc2VsZWN0QWxsKClcbiAgICAgICAgICAgIC5kYXRhKHJlZ2lvbkxpc3QpXG4gICAgICAgICAgICAuZW50ZXIoKVxuICAgICAgICAgICAgLmFwcGVuZChcImdcIilcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJyZWdpb25Hcm91cFwiKTtcblxuICAgICAgICByZWdpb25zLmFwcGVuZChcInJlY3RcIilcbiAgICAgICAgICAgIC5hdHRyKFwieFwiLCBmdW5jdGlvbiAocikge1xuICAgICAgICAgICAgICAgIHJldHVybiB4KHIuc3RhcnQpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCB5KDApICsgcmVnaW9uX29mZnNldCApXG4gICAgICAgICAgICAuYXR0cihcInJ5XCIsIFwiM1wiKVxuICAgICAgICAgICAgLmF0dHIoXCJyeFwiLCBcIjNcIilcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geChyLmVuZCkgLSB4KHIuc3RhcnQpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgMTYpXG4gICAgICAgICAgICAuc3R5bGUoXCJmaWxsXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29sb3JcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuc3R5bGUoXCJzdHJva2VcIiwgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZDMucmdiKGRhdGEuY29sb3IpLmRhcmtlcigpXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICByZWdpb25zXG4gICAgICAgICAgICAuYXR0cigncG9pbnRlci1ldmVudHMnLCAnYWxsJylcbiAgICAgICAgICAgIC5hdHRyKCdjdXJzb3InLCAncG9pbnRlcicpXG4gICAgICAgICAgICAub24oXCJjbGlja1wiLCAgZnVuY3Rpb24ocikge1xuICAgICAgICAgICAgLy8gc2V0IGN1c3RvbSBzZWxlY3Rpb24gZXh0ZW50XG4gICAgICAgICAgICBzZWxmLnNlbGVjdG9yLmV4dGVudChbci5zdGFydCwgci5lbmRdKTtcbiAgICAgICAgICAgIC8vIGNhbGwgdGhlIGV4dGVudCB0byBjaGFuZ2Ugd2l0aCB0cmFuc2l0aW9uXG4gICAgICAgICAgICBzZWxmLnNlbGVjdG9yKGQzLnNlbGVjdChcIi5icnVzaFwiKS50cmFuc2l0aW9uKCkpO1xuICAgICAgICAgICAgLy8gY2FsbCBleHRlbnQgKHNlbGVjdGlvbikgY2hhbmdlIGxpc3RlbmVyc1xuICAgICAgICAgICAgc2VsZi5zZWxlY3Rvci5ldmVudChkMy5zZWxlY3QoXCIuYnJ1c2hcIikudHJhbnNpdGlvbigpLmRlbGF5KDMwMCkpO1xuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFBsYWNlIGFuZCBsYWJlbCBsb2NhdGlvblxuICAgICAgICB2YXIgbGFiZWxzID0gW107XG5cbiAgICAgICAgcmVnaW9ucy5hcHBlbmQoXCJ0ZXh0XCIpXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwicmVnaW9uTmFtZVwiKVxuICAgICAgICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICAgICAgci54ID0geChyLnN0YXJ0KSArICh4KHIuZW5kKSAtIHgoci5zdGFydCkpIC8gMjtcbiAgICAgICAgICAgICAgICByZXR1cm4gci54O1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCBmdW5jdGlvbihyKSB7ci55ID0geSgwKSArIHRleHRfb2Zmc2V0OyByZXR1cm4gci55OyB9IClcbiAgICAgICAgICAgIC5hdHRyKFwiZHlcIiwgXCIwLjM1ZW1cIilcbiAgICAgICAgICAgIC5zdHlsZShcImZvbnQtc2l6ZVwiLCBcIjEycHhcIilcbiAgICAgICAgICAgIC5zdHlsZShcInRleHQtZGVjb3JhdGlvblwiLCBcImJvbGRcIilcbiAgICAgICAgICAgIC50ZXh0KGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEubmFtZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHJlZ2lvbk5hbWVzID0gZDMuc2VsZWN0QWxsKFwiLnJlZ2lvbk5hbWVcIik7XG4gICAgICAgIHJlZ2lvbk5hbWVzLmVhY2goZnVuY3Rpb24oZCwgaSkge1xuICAgICAgICAgICAgdmFyIGludGVyYWN0aW9uTGVuZ3RoID0gdGhpcy5nZXRCQm94KCkud2lkdGggLyAyO1xuICAgICAgICAgICAgbGFiZWxzLnB1c2goe3g6IGQueCwgeTogZC55LCBsYWJlbDogZC5uYW1lLCB3ZWlnaHQ6IGQubmFtZS5sZW5ndGgsIHJhZGl1czogaW50ZXJhY3Rpb25MZW5ndGh9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIGZvcmNlID0gZDMubGF5b3V0LmZvcmNlKClcbiAgICAgICAgICAgIC5jaGFyZ2VEaXN0YW5jZSg1KVxuICAgICAgICAgICAgLm5vZGVzKGxhYmVscylcbiAgICAgICAgICAgIC5jaGFyZ2UoLTEwKVxuICAgICAgICAgICAgLmdyYXZpdHkoMCk7XG5cbiAgICAgICAgdmFyIG1pblggPSB4KG1pbkNvb3JkKTtcbiAgICAgICAgdmFyIG1heFggPSB4KG1heENvb3JkKTtcbiAgICAgICAgdmFyIHdpdGhpbkJvdW5kcyA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgICAgICAgIHJldHVybiBkMy5taW4oW1xuICAgICAgICAgICAgICAgIGQzLm1heChbXG4gICAgICAgICAgICAgICAgICAgIG1pblgsXG4gICAgICAgICAgICAgICAgICAgIHhdKSxcbiAgICAgICAgICAgICAgICBtYXhYXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgfTtcbiAgICAgICAgZnVuY3Rpb24gY29sbGlkZShub2RlKSB7XG4gICAgICAgICAgICB2YXIgciA9IG5vZGUucmFkaXVzICsgMyxcbiAgICAgICAgICAgICAgICBueDEgPSBub2RlLnggLSByLFxuICAgICAgICAgICAgICAgIG54MiA9IG5vZGUueCArIHIsXG4gICAgICAgICAgICAgICAgbnkxID0gbm9kZS55IC0gcixcbiAgICAgICAgICAgICAgICBueTIgPSBub2RlLnkgKyByO1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHF1YWQsIHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHF1YWQucG9pbnQgJiYgKHF1YWQucG9pbnQgIT09IG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsID0gbm9kZS54IC0gcXVhZC5wb2ludC54LFxuICAgICAgICAgICAgICAgICAgICAgICAgeCA9IGw7XG4gICAgICAgICAgICAgICAgICAgIHIgPSBub2RlLnJhZGl1cyArIHF1YWQucG9pbnQucmFkaXVzO1xuICAgICAgICAgICAgICAgICAgICBpZiAoTWF0aC5hYnMobCkgPCByKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsID0gKGwgLSByKSAvIGwgKiAuMDA1O1xuICAgICAgICAgICAgICAgICAgICAgICAgeCAqPSBsO1xuICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICAobm9kZS54ID4gcXVhZC5wb2ludC54ICYmIHggPCAwKSA/IC14IDogeDtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUueCArPSB4O1xuICAgICAgICAgICAgICAgICAgICAgICAgcXVhZC5wb2ludC54IC09IHg7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHgxID4gbngyXG4gICAgICAgICAgICAgICAgICAgIHx8IHgyIDwgbngxXG4gICAgICAgICAgICAgICAgICAgIHx8IHkxID4gbnkyXG4gICAgICAgICAgICAgICAgICAgIHx8IHkyIDwgbnkxO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBmb3JjZS5vbihcInRpY2tcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgdmFyIHEgPSBkMy5nZW9tLnF1YWR0cmVlKGxhYmVscyksXG4gICAgICAgICAgICAgICAgaSA9IDAsXG4gICAgICAgICAgICAgICAgbiA9IGxhYmVscy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAgICAgICAgIHEudmlzaXQoY29sbGlkZShsYWJlbHNbaV0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgcG9zaXRpb24gb2YgdGhlIHRleHQgZWxlbWVudFxuICAgICAgICAgICAgc3ZnLnNlbGVjdEFsbChcInRleHQucmVnaW9uTmFtZVwiKVxuICAgICAgICAgICAgICAgIC5hdHRyKFwieFwiLCBmdW5jdGlvbihkKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkLm5hbWUgPT0gbGFiZWxzW2ldLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzW2ldLnggPSB3aXRoaW5Cb3VuZHMobGFiZWxzW2ldLngpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsYWJlbHNbaV0ueDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgICBmb3JjZS5zdGFydCgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZvcm1hdFJlZ2lvbnMocmVnaW9ucykge1xuICAgICAgICByZWdpb25MaXN0ID0gW107XG4gICAgICAgIGZvciAoa2V5IGluIHJlZ2lvbnMpIHtcblxuICAgICAgICAgICAgcmVnaW9uTGlzdC5wdXNoKHtcbiAgICAgICAgICAgICAgICAnbmFtZSc6IGtleSxcbiAgICAgICAgICAgICAgICAnc3RhcnQnOiBnZXRSZWdpb25TdGFydChyZWdpb25zW2tleV0pLFxuICAgICAgICAgICAgICAgICdlbmQnOiBnZXRSZWdpb25FbmQocmVnaW9uc1trZXldKSxcbiAgICAgICAgICAgICAgICAnY29sb3InOiBnZXRDb2xvcihrZXkpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVnaW9uTGlzdDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlZ2lvbkRhdGEgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAvLyBhc3N1bWUgZGF0YSBpcyBpbiBhIGZpbGVcbiAgICAgICAgZDMuanNvbihyZWdpb25EYXRhLCBmdW5jdGlvbihlcnJvciwgcmVnaW9ucykge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7cmV0dXJuIGNvbnNvbGUuZGVidWcoZXJyb3IpfVxuICAgICAgICAgICAgcmVnaW9uTGlzdCA9IGZvcm1hdFJlZ2lvbnMocmVnaW9ucyk7XG4gICAgICAgICAgICBkcmF3KHJlZ2lvbkxpc3QpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZWdpb25MaXN0ID0gZm9ybWF0UmVnaW9ucyhyZWdpb25EYXRhKTtcbiAgICAgICAgZHJhdyhyZWdpb25MaXN0KTtcbiAgICB9XG5cbn07XG5cblxuTXV0c05lZWRsZVBsb3QucHJvdG90eXBlLmRyYXdBeGVzID0gZnVuY3Rpb24oc3ZnKSB7XG5cbiAgICB2YXIgeSA9IHRoaXMueTtcbiAgICB2YXIgeCA9IHRoaXMueDtcblxuICAgIHhBeGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh4KS5vcmllbnQoXCJib3R0b21cIik7XG5cbiAgICBzdmcuYXBwZW5kKFwic3ZnOmdcIilcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJ4LWF4aXNcIilcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKDAsXCIgKyAodGhpcy5oZWlnaHQgLSB0aGlzLmJ1ZmZlcikgKyBcIilcIilcbiAgICAgIC5jYWxsKHhBeGlzKTtcblxuICAgIHlBeGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh5KS5vcmllbnQoXCJsZWZ0XCIpO1xuXG5cbiAgICBzdmcuYXBwZW5kKFwic3ZnOmdcIilcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJ5LWF4aXNcIilcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgKHRoaXMuYnVmZmVyICogMS4yICsgLSAxMCkgICsgXCIsMClcIilcbiAgICAgIC5jYWxsKHlBeGlzKTtcblxuICAgIHN2Zy5hcHBlbmQoXCJ0ZXh0XCIpXG4gICAgICAuYXR0cihcImNsYXNzXCIsIFwieS1sYWJlbFwiKVxuICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxuICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAodGhpcy5idWZmZXIgLyAzKSArIFwiLFwiICsgKHRoaXMuaGVpZ2h0IC8gMikgKyBcIiksIHJvdGF0ZSgtOTApXCIpXG4gICAgICAudGV4dCh0aGlzLmxlZ2VuZHMueSk7XG5cbiAgICBzdmcuYXBwZW5kKFwidGV4dFwiKVxuICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcIngtbGFiZWxcIilcbiAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIilcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgKHRoaXMud2lkdGggLyAyKSArIFwiLFwiICsgKHRoaXMuaGVpZ2h0IC0gdGhpcy5idWZmZXIgLyAzKSArIFwiKVwiKVxuICAgICAgLnRleHQodGhpcy5sZWdlbmRzLngpO1xuICAgIFxufTtcblxuXG5cbk11dHNOZWVkbGVQbG90LnByb3RvdHlwZS5kcmF3TmVlZGxlcyA9IGZ1bmN0aW9uKHN2ZywgbXV0YXRpb25EYXRhLCByZWdpb25EYXRhKSB7XG5cbiAgICB2YXIgeSA9IHRoaXMueTtcbiAgICB2YXIgeCA9IHRoaXMueDtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBnZXRZQXhpcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4geTtcbiAgICB9O1xuXG4gICAgZm9ybWF0Q29vcmQgPSBmdW5jdGlvbihjb29yZCkge1xuICAgICAgIGlmIChjb29yZC5pbmRleE9mKFwiLVwiKSA+IC0xKSB7XG4gICAgICAgICAgIGNvb3JkcyA9IGNvb3JkLnNwbGl0KFwiLVwiKTtcblxuICAgICAgICAgICAvLyBwbGFjZSBuZWVkZSBhdCBtaWRkbGUgb2YgYWZmZWN0ZWQgcmVnaW9uXG4gICAgICAgICAgIGNvb3JkID0gTWF0aC5mbG9vcigocGFyc2VJbnQoY29vcmRzWzBdKSArIHBhcnNlSW50KGNvb3Jkc1sxXSkpIC8gMik7XG5cbiAgICAgICAgICAgLy8gY2hlY2sgZm9yIHNwbGljZSBzaXRlczogXCI/LTlcIiBvciBcIjktP1wiXG4gICAgICAgICAgIGlmIChpc05hTihjb29yZCkpIHtcbiAgICAgICAgICAgICAgIGlmIChjb29yZHNbMF0gPT0gXCI/XCIpIHsgY29vcmQgPSBwYXJzZUludChjb29yZHNbMV0pIH1cbiAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvb3JkcyBbMV0gPT0gXCI/XCIpIHsgY29vcmQgPSBwYXJzZUludChjb29yZHNbMF0pIH1cbiAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29vcmQgPSBwYXJzZUludChjb29yZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvb3JkO1xuICAgIH07XG5cbiAgICB0aXAgPSB0aGlzLnRpcDtcblxuICAgIC8vIHN0YWNrIG5lZWRsZXMgYXQgc2FtZSBwb3NcbiAgICBuZWVkbGVQb2ludCA9IHt9O1xuICAgIGhpZ2hlc3QgPSAwO1xuXG4gICAgc3RhY2tOZWVkbGUgPSBmdW5jdGlvbihwb3MsdmFsdWUscG9pbnREaWN0KSB7XG4gICAgICBzdGlja0hlaWdodCA9IDA7XG4gICAgICBwb3MgPSBcInBcIitTdHJpbmcocG9zKTtcbiAgICAgIGlmIChwb3MgaW4gcG9pbnREaWN0KSB7XG4gICAgICAgICBzdGlja0hlaWdodCA9IHBvaW50RGljdFtwb3NdO1xuICAgICAgICAgbmV3SGVpZ2h0ID0gc3RpY2tIZWlnaHQgKyB2YWx1ZTtcbiAgICAgICAgIHBvaW50RGljdFtwb3NdID0gbmV3SGVpZ2h0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgIHBvaW50RGljdFtwb3NdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RpY2tIZWlnaHQ7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGZvcm1hdE11dGF0aW9uRW50cnkoZCkge1xuXG4gICAgICAgIGNvb3JkU3RyaW5nID0gZC5jb29yZDtcbiAgICAgICAgbnVtZXJpY0Nvb3JkID0gZm9ybWF0Q29vcmQoZC5jb29yZCk7XG4gICAgICAgIG51bWVyaWNWYWx1ZSA9IE51bWJlcihkLnZhbHVlKTtcbiAgICAgICAgc3RpY2tIZWlnaHQgPSBzdGFja05lZWRsZShudW1lcmljQ29vcmQsIG51bWVyaWNWYWx1ZSwgbmVlZGxlUG9pbnQpO1xuICAgICAgICBjYXRlZ29yeSA9IGQuY2F0ZWdvcnkgfHwgXCJvdGhlclwiO1xuXG4gICAgICAgIGlmIChzdGlja0hlaWdodCArIG51bWVyaWNWYWx1ZSA+IGhpZ2hlc3QpIHtcbiAgICAgICAgICAgIC8vIHNldCBZLUF4aXMgYWx3YXlzIHRvIGhpZ2hlc3QgYXZhaWxhYmxlXG4gICAgICAgICAgICBoaWdoZXN0ID0gc3RpY2tIZWlnaHQgKyBudW1lcmljVmFsdWU7XG4gICAgICAgICAgICBnZXRZQXhpcygpLmRvbWFpbihbMCwgaGlnaGVzdCArIDJdKTtcbiAgICAgICAgfVxuXG5cbiAgICAgICAgaWYgKG51bWVyaWNDb29yZCA+IDApIHtcblxuICAgICAgICAgICAgLy8gcmVjb3JkIGFuZCBjb3VudCBjYXRlZ29yaWVzXG4gICAgICAgICAgICBzZWxmLnRvdGFsQ2F0ZWdDb3VudHNbY2F0ZWdvcnldID0gKHNlbGYudG90YWxDYXRlZ0NvdW50c1tjYXRlZ29yeV0gfHwgMCkgKyBudW1lcmljVmFsdWU7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgY2F0ZWdvcnk6IGNhdGVnb3J5LFxuICAgICAgICAgICAgICAgIGNvb3JkU3RyaW5nOiBjb29yZFN0cmluZyxcbiAgICAgICAgICAgICAgICBjb29yZDogbnVtZXJpY0Nvb3JkLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgICAgICAgICAgc3RpY2tIZWlnaHQ6IHN0aWNrSGVpZ2h0LFxuICAgICAgICAgICAgICAgIGNvbG9yOiBzZWxmLmNvbG9yU2NhbGUoY2F0ZWdvcnkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiZGlzY2FyZGluZyBcIiArIGQuY29vcmQgKyBcIiBcIiArIGQuY2F0ZWdvcnkgKyBcIihcIisgbnVtZXJpY0Nvb3JkICtcIilcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgbXV0cyA9IFtdO1xuXG5cbiAgICBpZiAodHlwZW9mIG11dGF0aW9uRGF0YSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGQzLmpzb24obXV0YXRpb25EYXRhLCBmdW5jdGlvbihlcnJvciwgdW5mb3JtYXR0ZWRNdXRzKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG11dHMgPSBwcmVwYXJlTXV0cyh1bmZvcm1hdHRlZE11dHMpO1xuICAgICAgICAgICAgcGFpbnRNdXRzKG11dHMpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBtdXRzID0gcHJlcGFyZU11dHMobXV0YXRpb25EYXRhKTtcbiAgICAgICAgcGFpbnRNdXRzKG11dHMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXBhcmVNdXRzKHVuZm9ybWF0dGVkTXV0cykge1xuICAgICAgICBmb3IgKGtleSBpbiB1bmZvcm1hdHRlZE11dHMpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZCA9IGZvcm1hdE11dGF0aW9uRW50cnkodW5mb3JtYXR0ZWRNdXRzW2tleV0pO1xuICAgICAgICAgICAgaWYgKGZvcm1hdHRlZCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBtdXRzLnB1c2goZm9ybWF0dGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbXV0cztcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIHBhaW50TXV0cyhtdXRzKSB7XG5cbiAgICAgICAgbWluU2l6ZSA9IDQ7XG4gICAgICAgIG1heFNpemUgPSAxMDtcbiAgICAgICAgaGVhZFNpemVTY2FsZSA9IGQzLnNjYWxlLmxvZygpLnJhbmdlKFttaW5TaXplLG1heFNpemVdKS5kb21haW4oWzEsIGhpZ2hlc3QvMl0pO1xuICAgICAgICB2YXIgaGVhZFNpemUgPSBmdW5jdGlvbihuKSB7XG4gICAgICAgICAgICByZXR1cm4gZDMubWluKFtkMy5tYXgoW2hlYWRTaXplU2NhbGUobiksbWluU2l6ZV0pLCBtYXhTaXplXSk7XG4gICAgICAgIH07XG5cblxuICAgICAgICB2YXIgbmVlZGxlcyA9IGQzLnNlbGVjdChcIi5tdXRuZWVkbGVzXCIpLnNlbGVjdEFsbCgpXG4gICAgICAgICAgICAuZGF0YShtdXRzKS5lbnRlcigpXG4gICAgICAgICAgICAuYXBwZW5kKFwibGluZVwiKVxuICAgICAgICAgICAgLmF0dHIoXCJ5MVwiLCBmdW5jdGlvbihkYXRhKSB7IHJldHVybiB5KGRhdGEuc3RpY2tIZWlnaHQgKyBkYXRhLnZhbHVlKSArIGhlYWRTaXplKGRhdGEudmFsdWUpIDsgfSApXG4gICAgICAgICAgICAuYXR0cihcInkyXCIsIGZ1bmN0aW9uKGRhdGEpIHsgcmV0dXJuIHkoZGF0YS5zdGlja0hlaWdodCkgfSlcbiAgICAgICAgICAgIC5hdHRyKFwieDFcIiwgZnVuY3Rpb24oZGF0YSkgeyByZXR1cm4geChkYXRhLmNvb3JkKSB9KVxuICAgICAgICAgICAgLmF0dHIoXCJ4MlwiLCBmdW5jdGlvbihkYXRhKSB7IHJldHVybiB4KGRhdGEuY29vcmQpIH0pXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwibmVlZGxlLWxpbmVcIik7XG5cbiAgICAgICAgdmFyIG5lZWRsZUhlYWRzID0gZDMuc2VsZWN0KFwiLm11dG5lZWRsZXNcIikuc2VsZWN0QWxsKClcbiAgICAgICAgICAgIC5kYXRhKG11dHMpXG4gICAgICAgICAgICAuZW50ZXIoKS5hcHBlbmQoXCJjaXJjbGVcIilcbiAgICAgICAgICAgIC5hdHRyKFwiY3lcIiwgZnVuY3Rpb24oZGF0YSkgeyByZXR1cm4geShkYXRhLnN0aWNrSGVpZ2h0K2RhdGEudmFsdWUpIH0gKVxuICAgICAgICAgICAgLmF0dHIoXCJjeFwiLCBmdW5jdGlvbihkYXRhKSB7IHJldHVybiB4KGRhdGEuY29vcmQpIH0gKVxuICAgICAgICAgICAgLmF0dHIoXCJyXCIsIGZ1bmN0aW9uKGRhdGEpIHsgcmV0dXJuIGhlYWRTaXplKGRhdGEudmFsdWUpIH0pXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwibmVlZGxlLWhlYWRcIilcbiAgICAgICAgICAgIC5zdHlsZShcImZpbGxcIiwgZnVuY3Rpb24oZGF0YSkgeyByZXR1cm4gZGF0YS5jb2xvciB9KVxuICAgICAgICAgICAgLnN0eWxlKFwic3Ryb2tlXCIsIGZ1bmN0aW9uKGRhdGEpIHtyZXR1cm4gZDMucmdiKGRhdGEuY29sb3IpLmRhcmtlcigpfSlcbiAgICAgICAgICAgIC5vbignbW91c2VvdmVyJywgIGZ1bmN0aW9uKGQpeyBkMy5zZWxlY3QodGhpcykubW92ZVRvRnJvbnQoKTsgdGlwLnNob3coZCk7IH0pXG4gICAgICAgICAgICAub24oJ21vdXNlb3V0JywgdGlwLmhpZGUpO1xuXG4gICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUubW92ZVRvRnJvbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBhZGp1c3QgeS1zY2FsZSBhY2NvcmRpbmcgdG8gaGlnaGVzdCB2YWx1ZSBhbiBkcmF3IHRoZSByZXN0XG4gICAgICAgIGlmIChyZWdpb25EYXRhICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc2VsZi5kcmF3UmVnaW9ucyhzdmcsIHJlZ2lvbkRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHNlbGYuZHJhd0xlZ2VuZChzdmcpO1xuICAgICAgICBzZWxmLmRyYXdBeGVzKHN2Zyk7XG4gICAgfVxuXG59O1xuXG5cblxudmFyIEV2ZW50cyA9IHJlcXVpcmUoJ2Jpb2pzLWV2ZW50cycpO1xuRXZlbnRzLm1peGluKE11dHNOZWVkbGVQbG90LnByb3RvdHlwZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTXV0c05lZWRsZVBsb3Q7XG5cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vc3JjL2pzL011dHNOZWVkbGVQbG90LmpzXCIpO1xuIl19 +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvaG9tZS9tc2Nocm9lZGVyL0RvY3VtZW50cy9wcm9qZWN0cy9uZWVkbGVwbG90L25vZGVfbW9kdWxlcy9iaW9qcy1ldmVudHMvaW5kZXguanMiLCIvaG9tZS9tc2Nocm9lZGVyL0RvY3VtZW50cy9wcm9qZWN0cy9uZWVkbGVwbG90L25vZGVfbW9kdWxlcy9iaW9qcy1ldmVudHMvbm9kZV9tb2R1bGVzL2JhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lL2JhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lLmpzIiwiL2hvbWUvbXNjaHJvZWRlci9Eb2N1bWVudHMvcHJvamVjdHMvbmVlZGxlcGxvdC9ub2RlX21vZHVsZXMvYmlvanMtZXZlbnRzL25vZGVfbW9kdWxlcy9iYWNrYm9uZS1ldmVudHMtc3RhbmRhbG9uZS9pbmRleC5qcyIsIi9ob21lL21zY2hyb2VkZXIvRG9jdW1lbnRzL3Byb2plY3RzL25lZWRsZXBsb3Qvbm9kZV9tb2R1bGVzL2QzLXRpcC9pbmRleC5qcyIsIi9ob21lL21zY2hyb2VkZXIvRG9jdW1lbnRzL3Byb2plY3RzL25lZWRsZXBsb3Qvc3JjL2pzL011dHNOZWVkbGVQbG90LmpzIiwiLi9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JSQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BzQkE7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJ2YXIgZXZlbnRzID0gcmVxdWlyZShcImJhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lXCIpO1xuXG5ldmVudHMub25BbGwgPSBmdW5jdGlvbihjYWxsYmFjayxjb250ZXh0KXtcbiAgdGhpcy5vbihcImFsbFwiLCBjYWxsYmFjayxjb250ZXh0KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBNaXhpbiB1dGlsaXR5XG5ldmVudHMub2xkTWl4aW4gPSBldmVudHMubWl4aW47XG5ldmVudHMubWl4aW4gPSBmdW5jdGlvbihwcm90bykge1xuICBldmVudHMub2xkTWl4aW4ocHJvdG8pO1xuICAvLyBhZGQgY3VzdG9tIG9uQWxsXG4gIHZhciBleHBvcnRzID0gWydvbkFsbCddO1xuICBmb3IodmFyIGk9MDsgaSA8IGV4cG9ydHMubGVuZ3RoO2krKyl7XG4gICAgdmFyIG5hbWUgPSBleHBvcnRzW2ldO1xuICAgIHByb3RvW25hbWVdID0gdGhpc1tuYW1lXTtcbiAgfVxuICByZXR1cm4gcHJvdG87XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV2ZW50cztcbiIsIi8qKlxuICogU3RhbmRhbG9uZSBleHRyYWN0aW9uIG9mIEJhY2tib25lLkV2ZW50cywgbm8gZXh0ZXJuYWwgZGVwZW5kZW5jeSByZXF1aXJlZC5cbiAqIERlZ3JhZGVzIG5pY2VseSB3aGVuIEJhY2tvbmUvdW5kZXJzY29yZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgaW4gdGhlIGN1cnJlbnRcbiAqIGdsb2JhbCBjb250ZXh0LlxuICpcbiAqIE5vdGUgdGhhdCBkb2NzIHN1Z2dlc3QgdG8gdXNlIHVuZGVyc2NvcmUncyBgXy5leHRlbmQoKWAgbWV0aG9kIHRvIGFkZCBFdmVudHNcbiAqIHN1cHBvcnQgdG8gc29tZSBnaXZlbiBvYmplY3QuIEEgYG1peGluKClgIG1ldGhvZCBoYXMgYmVlbiBhZGRlZCB0byB0aGUgRXZlbnRzXG4gKiBwcm90b3R5cGUgdG8gYXZvaWQgdXNpbmcgdW5kZXJzY29yZSBmb3IgdGhhdCBzb2xlIHB1cnBvc2U6XG4gKlxuICogICAgIHZhciBteUV2ZW50RW1pdHRlciA9IEJhY2tib25lRXZlbnRzLm1peGluKHt9KTtcbiAqXG4gKiBPciBmb3IgYSBmdW5jdGlvbiBjb25zdHJ1Y3RvcjpcbiAqXG4gKiAgICAgZnVuY3Rpb24gTXlDb25zdHJ1Y3Rvcigpe31cbiAqICAgICBNeUNvbnN0cnVjdG9yLnByb3RvdHlwZS5mb28gPSBmdW5jdGlvbigpe31cbiAqICAgICBCYWNrYm9uZUV2ZW50cy5taXhpbihNeUNvbnN0cnVjdG9yLnByb3RvdHlwZSk7XG4gKlxuICogKGMpIDIwMDktMjAxMyBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgSW5jLlxuICogKGMpIDIwMTMgTmljb2xhcyBQZXJyaWF1bHRcbiAqL1xuLyogZ2xvYmFsIGV4cG9ydHM6dHJ1ZSwgZGVmaW5lLCBtb2R1bGUgKi9cbihmdW5jdGlvbigpIHtcbiAgdmFyIHJvb3QgPSB0aGlzLFxuICAgICAgYnJlYWtlciA9IHt9LFxuICAgICAgbmF0aXZlRm9yRWFjaCA9IEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLFxuICAgICAgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LFxuICAgICAgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UsXG4gICAgICBpZENvdW50ZXIgPSAwO1xuXG4gIC8vIFJldHVybnMgYSBwYXJ0aWFsIGltcGxlbWVudGF0aW9uIG1hdGNoaW5nIHRoZSBtaW5pbWFsIEFQSSBzdWJzZXQgcmVxdWlyZWRcbiAgLy8gYnkgQmFja2JvbmUuRXZlbnRzXG4gIGZ1bmN0aW9uIG1pbmlzY29yZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAga2V5czogT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICAgICAgICBpZiAodHlwZW9mIG9iaiAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2Ygb2JqICE9PSBcImZ1bmN0aW9uXCIgfHwgb2JqID09PSBudWxsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleXMoKSBjYWxsZWQgb24gYSBub24tb2JqZWN0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBrZXksIGtleXMgPSBbXTtcbiAgICAgICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBrZXlzW2tleXMubGVuZ3RoXSA9IGtleTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgICB9LFxuXG4gICAgICB1bmlxdWVJZDogZnVuY3Rpb24ocHJlZml4KSB7XG4gICAgICAgIHZhciBpZCA9ICsraWRDb3VudGVyICsgJyc7XG4gICAgICAgIHJldHVybiBwcmVmaXggPyBwcmVmaXggKyBpZCA6IGlkO1xuICAgICAgfSxcblxuICAgICAgaGFzOiBmdW5jdGlvbihvYmosIGtleSkge1xuICAgICAgICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSk7XG4gICAgICB9LFxuXG4gICAgICBlYWNoOiBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuO1xuICAgICAgICBpZiAobmF0aXZlRm9yRWFjaCAmJiBvYmouZm9yRWFjaCA9PT0gbmF0aXZlRm9yRWFjaCkge1xuICAgICAgICAgIG9iai5mb3JFYWNoKGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgICAgICAgfSBlbHNlIGlmIChvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCkge1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gb2JqLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgaWYgKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2ldLCBpLCBvYmopID09PSBicmVha2VyKSByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmhhcyhvYmosIGtleSkpIHtcbiAgICAgICAgICAgICAgaWYgKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2tleV0sIGtleSwgb2JqKSA9PT0gYnJlYWtlcikgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgb25jZTogZnVuY3Rpb24oZnVuYykge1xuICAgICAgICB2YXIgcmFuID0gZmFsc2UsIG1lbW87XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAocmFuKSByZXR1cm4gbWVtbztcbiAgICAgICAgICByYW4gPSB0cnVlO1xuICAgICAgICAgIG1lbW8gPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgZnVuYyA9IG51bGw7XG4gICAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHZhciBfID0gbWluaXNjb3JlKCksIEV2ZW50cztcblxuICAvLyBCYWNrYm9uZS5FdmVudHNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gQSBtb2R1bGUgdGhhdCBjYW4gYmUgbWl4ZWQgaW4gdG8gKmFueSBvYmplY3QqIGluIG9yZGVyIHRvIHByb3ZpZGUgaXQgd2l0aFxuICAvLyBjdXN0b20gZXZlbnRzLiBZb3UgbWF5IGJpbmQgd2l0aCBgb25gIG9yIHJlbW92ZSB3aXRoIGBvZmZgIGNhbGxiYWNrXG4gIC8vIGZ1bmN0aW9ucyB0byBhbiBldmVudDsgYHRyaWdnZXJgLWluZyBhbiBldmVudCBmaXJlcyBhbGwgY2FsbGJhY2tzIGluXG4gIC8vIHN1Y2Nlc3Npb24uXG4gIC8vXG4gIC8vICAgICB2YXIgb2JqZWN0ID0ge307XG4gIC8vICAgICBfLmV4dGVuZChvYmplY3QsIEJhY2tib25lLkV2ZW50cyk7XG4gIC8vICAgICBvYmplY3Qub24oJ2V4cGFuZCcsIGZ1bmN0aW9uKCl7IGFsZXJ0KCdleHBhbmRlZCcpOyB9KTtcbiAgLy8gICAgIG9iamVjdC50cmlnZ2VyKCdleHBhbmQnKTtcbiAgLy9cbiAgRXZlbnRzID0ge1xuXG4gICAgLy8gQmluZCBhbiBldmVudCB0byBhIGBjYWxsYmFja2AgZnVuY3Rpb24uIFBhc3NpbmcgYFwiYWxsXCJgIHdpbGwgYmluZFxuICAgIC8vIHRoZSBjYWxsYmFjayB0byBhbGwgZXZlbnRzIGZpcmVkLlxuICAgIG9uOiBmdW5jdGlvbihuYW1lLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgICAgaWYgKCFldmVudHNBcGkodGhpcywgJ29uJywgbmFtZSwgW2NhbGxiYWNrLCBjb250ZXh0XSkgfHwgIWNhbGxiYWNrKSByZXR1cm4gdGhpcztcbiAgICAgIHRoaXMuX2V2ZW50cyB8fCAodGhpcy5fZXZlbnRzID0ge30pO1xuICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuYW1lXSB8fCAodGhpcy5fZXZlbnRzW25hbWVdID0gW10pO1xuICAgICAgZXZlbnRzLnB1c2goe2NhbGxiYWNrOiBjYWxsYmFjaywgY29udGV4dDogY29udGV4dCwgY3R4OiBjb250ZXh0IHx8IHRoaXN9KTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBCaW5kIGFuIGV2ZW50IHRvIG9ubHkgYmUgdHJpZ2dlcmVkIGEgc2luZ2xlIHRpbWUuIEFmdGVyIHRoZSBmaXJzdCB0aW1lXG4gICAgLy8gdGhlIGNhbGxiYWNrIGlzIGludm9rZWQsIGl0IHdpbGwgYmUgcmVtb3ZlZC5cbiAgICBvbmNlOiBmdW5jdGlvbihuYW1lLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgICAgaWYgKCFldmVudHNBcGkodGhpcywgJ29uY2UnLCBuYW1lLCBbY2FsbGJhY2ssIGNvbnRleHRdKSB8fCAhY2FsbGJhY2spIHJldHVybiB0aGlzO1xuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgdmFyIG9uY2UgPSBfLm9uY2UoZnVuY3Rpb24oKSB7XG4gICAgICAgIHNlbGYub2ZmKG5hbWUsIG9uY2UpO1xuICAgICAgICBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfSk7XG4gICAgICBvbmNlLl9jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgICAgcmV0dXJuIHRoaXMub24obmFtZSwgb25jZSwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIC8vIFJlbW92ZSBvbmUgb3IgbWFueSBjYWxsYmFja3MuIElmIGBjb250ZXh0YCBpcyBudWxsLCByZW1vdmVzIGFsbFxuICAgIC8vIGNhbGxiYWNrcyB3aXRoIHRoYXQgZnVuY3Rpb24uIElmIGBjYWxsYmFja2AgaXMgbnVsbCwgcmVtb3ZlcyBhbGxcbiAgICAvLyBjYWxsYmFja3MgZm9yIHRoZSBldmVudC4gSWYgYG5hbWVgIGlzIG51bGwsIHJlbW92ZXMgYWxsIGJvdW5kXG4gICAgLy8gY2FsbGJhY2tzIGZvciBhbGwgZXZlbnRzLlxuICAgIG9mZjogZnVuY3Rpb24obmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgIHZhciByZXRhaW4sIGV2LCBldmVudHMsIG5hbWVzLCBpLCBsLCBqLCBrO1xuICAgICAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIWV2ZW50c0FwaSh0aGlzLCAnb2ZmJywgbmFtZSwgW2NhbGxiYWNrLCBjb250ZXh0XSkpIHJldHVybiB0aGlzO1xuICAgICAgaWYgKCFuYW1lICYmICFjYWxsYmFjayAmJiAhY29udGV4dCkge1xuICAgICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIG5hbWVzID0gbmFtZSA/IFtuYW1lXSA6IF8ua2V5cyh0aGlzLl9ldmVudHMpO1xuICAgICAgZm9yIChpID0gMCwgbCA9IG5hbWVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBuYW1lID0gbmFtZXNbaV07XG4gICAgICAgIGlmIChldmVudHMgPSB0aGlzLl9ldmVudHNbbmFtZV0pIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHNbbmFtZV0gPSByZXRhaW4gPSBbXTtcbiAgICAgICAgICBpZiAoY2FsbGJhY2sgfHwgY29udGV4dCkge1xuICAgICAgICAgICAgZm9yIChqID0gMCwgayA9IGV2ZW50cy5sZW5ndGg7IGogPCBrOyBqKyspIHtcbiAgICAgICAgICAgICAgZXYgPSBldmVudHNbal07XG4gICAgICAgICAgICAgIGlmICgoY2FsbGJhY2sgJiYgY2FsbGJhY2sgIT09IGV2LmNhbGxiYWNrICYmIGNhbGxiYWNrICE9PSBldi5jYWxsYmFjay5fY2FsbGJhY2spIHx8XG4gICAgICAgICAgICAgICAgICAoY29udGV4dCAmJiBjb250ZXh0ICE9PSBldi5jb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIHJldGFpbi5wdXNoKGV2KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXJldGFpbi5sZW5ndGgpIGRlbGV0ZSB0aGlzLl9ldmVudHNbbmFtZV07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8vIFRyaWdnZXIgb25lIG9yIG1hbnkgZXZlbnRzLCBmaXJpbmcgYWxsIGJvdW5kIGNhbGxiYWNrcy4gQ2FsbGJhY2tzIGFyZVxuICAgIC8vIHBhc3NlZCB0aGUgc2FtZSBhcmd1bWVudHMgYXMgYHRyaWdnZXJgIGlzLCBhcGFydCBmcm9tIHRoZSBldmVudCBuYW1lXG4gICAgLy8gKHVubGVzcyB5b3UncmUgbGlzdGVuaW5nIG9uIGBcImFsbFwiYCwgd2hpY2ggd2lsbCBjYXVzZSB5b3VyIGNhbGxiYWNrIHRvXG4gICAgLy8gcmVjZWl2ZSB0aGUgdHJ1ZSBuYW1lIG9mIHRoZSBldmVudCBhcyB0aGUgZmlyc3QgYXJndW1lbnQpLlxuICAgIHRyaWdnZXI6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIGlmICghdGhpcy5fZXZlbnRzKSByZXR1cm4gdGhpcztcbiAgICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgaWYgKCFldmVudHNBcGkodGhpcywgJ3RyaWdnZXInLCBuYW1lLCBhcmdzKSkgcmV0dXJuIHRoaXM7XG4gICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzW25hbWVdO1xuICAgICAgdmFyIGFsbEV2ZW50cyA9IHRoaXMuX2V2ZW50cy5hbGw7XG4gICAgICBpZiAoZXZlbnRzKSB0cmlnZ2VyRXZlbnRzKGV2ZW50cywgYXJncyk7XG4gICAgICBpZiAoYWxsRXZlbnRzKSB0cmlnZ2VyRXZlbnRzKGFsbEV2ZW50cywgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBUZWxsIHRoaXMgb2JqZWN0IHRvIHN0b3AgbGlzdGVuaW5nIHRvIGVpdGhlciBzcGVjaWZpYyBldmVudHMgLi4uIG9yXG4gICAgLy8gdG8gZXZlcnkgb2JqZWN0IGl0J3MgY3VycmVudGx5IGxpc3RlbmluZyB0by5cbiAgICBzdG9wTGlzdGVuaW5nOiBmdW5jdGlvbihvYmosIG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzO1xuICAgICAgaWYgKCFsaXN0ZW5lcnMpIHJldHVybiB0aGlzO1xuICAgICAgdmFyIGRlbGV0ZUxpc3RlbmVyID0gIW5hbWUgJiYgIWNhbGxiYWNrO1xuICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0JykgY2FsbGJhY2sgPSB0aGlzO1xuICAgICAgaWYgKG9iaikgKGxpc3RlbmVycyA9IHt9KVtvYmouX2xpc3RlbmVySWRdID0gb2JqO1xuICAgICAgZm9yICh2YXIgaWQgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgIGxpc3RlbmVyc1tpZF0ub2ZmKG5hbWUsIGNhbGxiYWNrLCB0aGlzKTtcbiAgICAgICAgaWYgKGRlbGV0ZUxpc3RlbmVyKSBkZWxldGUgdGhpcy5fbGlzdGVuZXJzW2lkXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICB9O1xuXG4gIC8vIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHNwbGl0IGV2ZW50IHN0cmluZ3MuXG4gIHZhciBldmVudFNwbGl0dGVyID0gL1xccysvO1xuXG4gIC8vIEltcGxlbWVudCBmYW5jeSBmZWF0dXJlcyBvZiB0aGUgRXZlbnRzIEFQSSBzdWNoIGFzIG11bHRpcGxlIGV2ZW50XG4gIC8vIG5hbWVzIGBcImNoYW5nZSBibHVyXCJgIGFuZCBqUXVlcnktc3R5bGUgZXZlbnQgbWFwcyBge2NoYW5nZTogYWN0aW9ufWBcbiAgLy8gaW4gdGVybXMgb2YgdGhlIGV4aXN0aW5nIEFQSS5cbiAgdmFyIGV2ZW50c0FwaSA9IGZ1bmN0aW9uKG9iaiwgYWN0aW9uLCBuYW1lLCByZXN0KSB7XG4gICAgaWYgKCFuYW1lKSByZXR1cm4gdHJ1ZTtcblxuICAgIC8vIEhhbmRsZSBldmVudCBtYXBzLlxuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiBuYW1lKSB7XG4gICAgICAgIG9ialthY3Rpb25dLmFwcGx5KG9iaiwgW2tleSwgbmFtZVtrZXldXS5jb25jYXQocmVzdCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBzcGFjZSBzZXBhcmF0ZWQgZXZlbnQgbmFtZXMuXG4gICAgaWYgKGV2ZW50U3BsaXR0ZXIudGVzdChuYW1lKSkge1xuICAgICAgdmFyIG5hbWVzID0gbmFtZS5zcGxpdChldmVudFNwbGl0dGVyKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gbmFtZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIG9ialthY3Rpb25dLmFwcGx5KG9iaiwgW25hbWVzW2ldXS5jb25jYXQocmVzdCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8vIEEgZGlmZmljdWx0LXRvLWJlbGlldmUsIGJ1dCBvcHRpbWl6ZWQgaW50ZXJuYWwgZGlzcGF0Y2ggZnVuY3Rpb24gZm9yXG4gIC8vIHRyaWdnZXJpbmcgZXZlbnRzLiBUcmllcyB0byBrZWVwIHRoZSB1c3VhbCBjYXNlcyBzcGVlZHkgKG1vc3QgaW50ZXJuYWxcbiAgLy8gQmFja2JvbmUgZXZlbnRzIGhhdmUgMyBhcmd1bWVudHMpLlxuICB2YXIgdHJpZ2dlckV2ZW50cyA9IGZ1bmN0aW9uKGV2ZW50cywgYXJncykge1xuICAgIHZhciBldiwgaSA9IC0xLCBsID0gZXZlbnRzLmxlbmd0aCwgYTEgPSBhcmdzWzBdLCBhMiA9IGFyZ3NbMV0sIGEzID0gYXJnc1syXTtcbiAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6IHdoaWxlICgrK2kgPCBsKSAoZXYgPSBldmVudHNbaV0pLmNhbGxiYWNrLmNhbGwoZXYuY3R4KTsgcmV0dXJuO1xuICAgICAgY2FzZSAxOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCwgYTEpOyByZXR1cm47XG4gICAgICBjYXNlIDI6IHdoaWxlICgrK2kgPCBsKSAoZXYgPSBldmVudHNbaV0pLmNhbGxiYWNrLmNhbGwoZXYuY3R4LCBhMSwgYTIpOyByZXR1cm47XG4gICAgICBjYXNlIDM6IHdoaWxlICgrK2kgPCBsKSAoZXYgPSBldmVudHNbaV0pLmNhbGxiYWNrLmNhbGwoZXYuY3R4LCBhMSwgYTIsIGEzKTsgcmV0dXJuO1xuICAgICAgZGVmYXVsdDogd2hpbGUgKCsraSA8IGwpIChldiA9IGV2ZW50c1tpXSkuY2FsbGJhY2suYXBwbHkoZXYuY3R4LCBhcmdzKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIGxpc3Rlbk1ldGhvZHMgPSB7bGlzdGVuVG86ICdvbicsIGxpc3RlblRvT25jZTogJ29uY2UnfTtcblxuICAvLyBJbnZlcnNpb24tb2YtY29udHJvbCB2ZXJzaW9ucyBvZiBgb25gIGFuZCBgb25jZWAuIFRlbGwgKnRoaXMqIG9iamVjdCB0b1xuICAvLyBsaXN0ZW4gdG8gYW4gZXZlbnQgaW4gYW5vdGhlciBvYmplY3QgLi4uIGtlZXBpbmcgdHJhY2sgb2Ygd2hhdCBpdCdzXG4gIC8vIGxpc3RlbmluZyB0by5cbiAgXy5lYWNoKGxpc3Rlbk1ldGhvZHMsIGZ1bmN0aW9uKGltcGxlbWVudGF0aW9uLCBtZXRob2QpIHtcbiAgICBFdmVudHNbbWV0aG9kXSA9IGZ1bmN0aW9uKG9iaiwgbmFtZSwgY2FsbGJhY2spIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnMgfHwgKHRoaXMuX2xpc3RlbmVycyA9IHt9KTtcbiAgICAgIHZhciBpZCA9IG9iai5fbGlzdGVuZXJJZCB8fCAob2JqLl9saXN0ZW5lcklkID0gXy51bmlxdWVJZCgnbCcpKTtcbiAgICAgIGxpc3RlbmVyc1tpZF0gPSBvYmo7XG4gICAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdvYmplY3QnKSBjYWxsYmFjayA9IHRoaXM7XG4gICAgICBvYmpbaW1wbGVtZW50YXRpb25dKG5hbWUsIGNhbGxiYWNrLCB0aGlzKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIEFsaWFzZXMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuICBFdmVudHMuYmluZCAgID0gRXZlbnRzLm9uO1xuICBFdmVudHMudW5iaW5kID0gRXZlbnRzLm9mZjtcblxuICAvLyBNaXhpbiB1dGlsaXR5XG4gIEV2ZW50cy5taXhpbiA9IGZ1bmN0aW9uKHByb3RvKSB7XG4gICAgdmFyIGV4cG9ydHMgPSBbJ29uJywgJ29uY2UnLCAnb2ZmJywgJ3RyaWdnZXInLCAnc3RvcExpc3RlbmluZycsICdsaXN0ZW5UbycsXG4gICAgICAgICAgICAgICAgICAgJ2xpc3RlblRvT25jZScsICdiaW5kJywgJ3VuYmluZCddO1xuICAgIF8uZWFjaChleHBvcnRzLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgICBwcm90b1tuYW1lXSA9IHRoaXNbbmFtZV07XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIHByb3RvO1xuICB9O1xuXG4gIC8vIEV4cG9ydCBFdmVudHMgYXMgQmFja2JvbmVFdmVudHMgZGVwZW5kaW5nIG9uIGN1cnJlbnQgY29udGV4dFxuICBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIEV2ZW50cztcbiAgICB9KTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50cztcbiAgICB9XG4gICAgZXhwb3J0cy5CYWNrYm9uZUV2ZW50cyA9IEV2ZW50cztcbiAgfSBlbHNlIHtcbiAgICByb290LkJhY2tib25lRXZlbnRzID0gRXZlbnRzO1xuICB9XG59KSh0aGlzKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9iYWNrYm9uZS1ldmVudHMtc3RhbmRhbG9uZScpO1xuIiwiLy8gZDMudGlwXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTMgSnVzdGluIFBhbG1lclxuLy9cbi8vIFRvb2x0aXBzIGZvciBkMy5qcyBTVkcgdmlzdWFsaXphdGlvbnNcblxuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAvLyBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUgd2l0aCBkMyBhcyBhIGRlcGVuZGVuY3kuXG4gICAgZGVmaW5lKFsnZDMnXSwgZmFjdG9yeSlcbiAgfSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgIC8vIENvbW1vbkpTXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihkMykge1xuICAgICAgZDMudGlwID0gZmFjdG9yeShkMylcbiAgICAgIHJldHVybiBkMy50aXBcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gQnJvd3NlciBnbG9iYWwuXG4gICAgcm9vdC5kMy50aXAgPSBmYWN0b3J5KHJvb3QuZDMpXG4gIH1cbn0odGhpcywgZnVuY3Rpb24gKGQzKSB7XG5cbiAgLy8gUHVibGljIC0gY29udHJ1Y3RzIGEgbmV3IHRvb2x0aXBcbiAgLy9cbiAgLy8gUmV0dXJucyBhIHRpcFxuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRpcmVjdGlvbiA9IGQzX3RpcF9kaXJlY3Rpb24sXG4gICAgICAgIG9mZnNldCAgICA9IGQzX3RpcF9vZmZzZXQsXG4gICAgICAgIGh0bWwgICAgICA9IGQzX3RpcF9odG1sLFxuICAgICAgICBub2RlICAgICAgPSBpbml0Tm9kZSgpLFxuICAgICAgICBzdmcgICAgICAgPSBudWxsLFxuICAgICAgICBwb2ludCAgICAgPSBudWxsLFxuICAgICAgICB0YXJnZXQgICAgPSBudWxsXG5cbiAgICBmdW5jdGlvbiB0aXAodmlzKSB7XG4gICAgICBzdmcgPSBnZXRTVkdOb2RlKHZpcylcbiAgICAgIHBvaW50ID0gc3ZnLmNyZWF0ZVNWR1BvaW50KClcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobm9kZSlcbiAgICB9XG5cbiAgICAvLyBQdWJsaWMgLSBzaG93IHRoZSB0b29sdGlwIG9uIHRoZSBzY3JlZW5cbiAgICAvL1xuICAgIC8vIFJldHVybnMgYSB0aXBcbiAgICB0aXAuc2hvdyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpXG4gICAgICBpZihhcmdzW2FyZ3MubGVuZ3RoIC0gMV0gaW5zdGFuY2VvZiBTVkdFbGVtZW50KSB0YXJnZXQgPSBhcmdzLnBvcCgpXG5cbiAgICAgIHZhciBjb250ZW50ID0gaHRtbC5hcHBseSh0aGlzLCBhcmdzKSxcbiAgICAgICAgICBwb2Zmc2V0ID0gb2Zmc2V0LmFwcGx5KHRoaXMsIGFyZ3MpLFxuICAgICAgICAgIGRpciAgICAgPSBkaXJlY3Rpb24uYXBwbHkodGhpcywgYXJncyksXG4gICAgICAgICAgbm9kZWwgICA9IGQzLnNlbGVjdChub2RlKSxcbiAgICAgICAgICBpICAgICAgID0gZGlyZWN0aW9ucy5sZW5ndGgsXG4gICAgICAgICAgY29vcmRzLFxuICAgICAgICAgIHNjcm9sbFRvcCAgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wIHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wLFxuICAgICAgICAgIHNjcm9sbExlZnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbExlZnRcblxuICAgICAgbm9kZWwuaHRtbChjb250ZW50KVxuICAgICAgICAuc3R5bGUoeyBvcGFjaXR5OiAxLCAncG9pbnRlci1ldmVudHMnOiAnYWxsJyB9KVxuXG4gICAgICB3aGlsZShpLS0pIG5vZGVsLmNsYXNzZWQoZGlyZWN0aW9uc1tpXSwgZmFsc2UpXG4gICAgICBjb29yZHMgPSBkaXJlY3Rpb25fY2FsbGJhY2tzLmdldChkaXIpLmFwcGx5KHRoaXMpXG4gICAgICBub2RlbC5jbGFzc2VkKGRpciwgdHJ1ZSkuc3R5bGUoe1xuICAgICAgICB0b3A6IChjb29yZHMudG9wICsgIHBvZmZzZXRbMF0pICsgc2Nyb2xsVG9wICsgJ3B4JyxcbiAgICAgICAgbGVmdDogKGNvb3Jkcy5sZWZ0ICsgcG9mZnNldFsxXSkgKyBzY3JvbGxMZWZ0ICsgJ3B4J1xuICAgICAgfSlcblxuICAgICAgcmV0dXJuIHRpcFxuICAgIH1cblxuICAgIC8vIFB1YmxpYyAtIGhpZGUgdGhlIHRvb2x0aXBcbiAgICAvL1xuICAgIC8vIFJldHVybnMgYSB0aXBcbiAgICB0aXAuaGlkZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG5vZGVsID0gZDMuc2VsZWN0KG5vZGUpXG4gICAgICBub2RlbC5zdHlsZSh7IG9wYWNpdHk6IDAsICdwb2ludGVyLWV2ZW50cyc6ICdub25lJyB9KVxuICAgICAgcmV0dXJuIHRpcFxuICAgIH1cblxuICAgIC8vIFB1YmxpYzogUHJveHkgYXR0ciBjYWxscyB0byB0aGUgZDMgdGlwIGNvbnRhaW5lci4gIFNldHMgb3IgZ2V0cyBhdHRyaWJ1dGUgdmFsdWUuXG4gICAgLy9cbiAgICAvLyBuIC0gbmFtZSBvZiB0aGUgYXR0cmlidXRlXG4gICAgLy8gdiAtIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGVcbiAgICAvL1xuICAgIC8vIFJldHVybnMgdGlwIG9yIGF0dHJpYnV0ZSB2YWx1ZVxuICAgIHRpcC5hdHRyID0gZnVuY3Rpb24obiwgdikge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyICYmIHR5cGVvZiBuID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZDMuc2VsZWN0KG5vZGUpLmF0dHIobilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBhcmdzID0gIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cylcbiAgICAgICAgZDMuc2VsZWN0aW9uLnByb3RvdHlwZS5hdHRyLmFwcGx5KGQzLnNlbGVjdChub2RlKSwgYXJncylcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRpcFxuICAgIH1cblxuICAgIC8vIFB1YmxpYzogUHJveHkgc3R5bGUgY2FsbHMgdG8gdGhlIGQzIHRpcCBjb250YWluZXIuICBTZXRzIG9yIGdldHMgYSBzdHlsZSB2YWx1ZS5cbiAgICAvL1xuICAgIC8vIG4gLSBuYW1lIG9mIHRoZSBwcm9wZXJ0eVxuICAgIC8vIHYgLSB2YWx1ZSBvZiB0aGUgcHJvcGVydHlcbiAgICAvL1xuICAgIC8vIFJldHVybnMgdGlwIG9yIHN0eWxlIHByb3BlcnR5IHZhbHVlXG4gICAgdGlwLnN0eWxlID0gZnVuY3Rpb24obiwgdikge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyICYmIHR5cGVvZiBuID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZDMuc2VsZWN0KG5vZGUpLnN0eWxlKG4pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgYXJncyA9ICBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpXG4gICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUuc3R5bGUuYXBwbHkoZDMuc2VsZWN0KG5vZGUpLCBhcmdzKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGlwXG4gICAgfVxuXG4gICAgLy8gUHVibGljOiBTZXQgb3IgZ2V0IHRoZSBkaXJlY3Rpb24gb2YgdGhlIHRvb2x0aXBcbiAgICAvL1xuICAgIC8vIHYgLSBPbmUgb2Ygbihub3J0aCksIHMoc291dGgpLCBlKGVhc3QpLCBvciB3KHdlc3QpLCBudyhub3J0aHdlc3QpLFxuICAgIC8vICAgICBzdyhzb3V0aHdlc3QpLCBuZShub3J0aGVhc3QpIG9yIHNlKHNvdXRoZWFzdClcbiAgICAvL1xuICAgIC8vIFJldHVybnMgdGlwIG9yIGRpcmVjdGlvblxuICAgIHRpcC5kaXJlY3Rpb24gPSBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBkaXJlY3Rpb25cbiAgICAgIGRpcmVjdGlvbiA9IHYgPT0gbnVsbCA/IHYgOiBkMy5mdW5jdG9yKHYpXG5cbiAgICAgIHJldHVybiB0aXBcbiAgICB9XG5cbiAgICAvLyBQdWJsaWM6IFNldHMgb3IgZ2V0cyB0aGUgb2Zmc2V0IG9mIHRoZSB0aXBcbiAgICAvL1xuICAgIC8vIHYgLSBBcnJheSBvZiBbeCwgeV0gb2Zmc2V0XG4gICAgLy9cbiAgICAvLyBSZXR1cm5zIG9mZnNldCBvclxuICAgIHRpcC5vZmZzZXQgPSBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBvZmZzZXRcbiAgICAgIG9mZnNldCA9IHYgPT0gbnVsbCA/IHYgOiBkMy5mdW5jdG9yKHYpXG5cbiAgICAgIHJldHVybiB0aXBcbiAgICB9XG5cbiAgICAvLyBQdWJsaWM6IHNldHMgb3IgZ2V0cyB0aGUgaHRtbCB2YWx1ZSBvZiB0aGUgdG9vbHRpcFxuICAgIC8vXG4gICAgLy8gdiAtIFN0cmluZyB2YWx1ZSBvZiB0aGUgdGlwXG4gICAgLy9cbiAgICAvLyBSZXR1cm5zIGh0bWwgdmFsdWUgb3IgdGlwXG4gICAgdGlwLmh0bWwgPSBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBodG1sXG4gICAgICBodG1sID0gdiA9PSBudWxsID8gdiA6IGQzLmZ1bmN0b3IodilcblxuICAgICAgcmV0dXJuIHRpcFxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGQzX3RpcF9kaXJlY3Rpb24oKSB7IHJldHVybiAnbicgfVxuICAgIGZ1bmN0aW9uIGQzX3RpcF9vZmZzZXQoKSB7IHJldHVybiBbMCwgMF0gfVxuICAgIGZ1bmN0aW9uIGQzX3RpcF9odG1sKCkgeyByZXR1cm4gJyAnIH1cblxuICAgIHZhciBkaXJlY3Rpb25fY2FsbGJhY2tzID0gZDMubWFwKHtcbiAgICAgIG46ICBkaXJlY3Rpb25fbixcbiAgICAgIHM6ICBkaXJlY3Rpb25fcyxcbiAgICAgIGU6ICBkaXJlY3Rpb25fZSxcbiAgICAgIHc6ICBkaXJlY3Rpb25fdyxcbiAgICAgIG53OiBkaXJlY3Rpb25fbncsXG4gICAgICBuZTogZGlyZWN0aW9uX25lLFxuICAgICAgc3c6IGRpcmVjdGlvbl9zdyxcbiAgICAgIHNlOiBkaXJlY3Rpb25fc2VcbiAgICB9KSxcblxuICAgIGRpcmVjdGlvbnMgPSBkaXJlY3Rpb25fY2FsbGJhY2tzLmtleXMoKVxuXG4gICAgZnVuY3Rpb24gZGlyZWN0aW9uX24oKSB7XG4gICAgICB2YXIgYmJveCA9IGdldFNjcmVlbkJCb3goKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiAgYmJveC5uLnkgLSBub2RlLm9mZnNldEhlaWdodCxcbiAgICAgICAgbGVmdDogYmJveC5uLnggLSBub2RlLm9mZnNldFdpZHRoIC8gMlxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRpcmVjdGlvbl9zKCkge1xuICAgICAgdmFyIGJib3ggPSBnZXRTY3JlZW5CQm94KClcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogIGJib3gucy55LFxuICAgICAgICBsZWZ0OiBiYm94LnMueCAtIG5vZGUub2Zmc2V0V2lkdGggLyAyXG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlyZWN0aW9uX2UoKSB7XG4gICAgICB2YXIgYmJveCA9IGdldFNjcmVlbkJCb3goKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiAgYmJveC5lLnkgLSBub2RlLm9mZnNldEhlaWdodCAvIDIsXG4gICAgICAgIGxlZnQ6IGJib3guZS54XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlyZWN0aW9uX3coKSB7XG4gICAgICB2YXIgYmJveCA9IGdldFNjcmVlbkJCb3goKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiAgYmJveC53LnkgLSBub2RlLm9mZnNldEhlaWdodCAvIDIsXG4gICAgICAgIGxlZnQ6IGJib3gudy54IC0gbm9kZS5vZmZzZXRXaWR0aFxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRpcmVjdGlvbl9udygpIHtcbiAgICAgIHZhciBiYm94ID0gZ2V0U2NyZWVuQkJveCgpXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6ICBiYm94Lm53LnkgLSBub2RlLm9mZnNldEhlaWdodCxcbiAgICAgICAgbGVmdDogYmJveC5udy54IC0gbm9kZS5vZmZzZXRXaWR0aFxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRpcmVjdGlvbl9uZSgpIHtcbiAgICAgIHZhciBiYm94ID0gZ2V0U2NyZWVuQkJveCgpXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6ICBiYm94Lm5lLnkgLSBub2RlLm9mZnNldEhlaWdodCxcbiAgICAgICAgbGVmdDogYmJveC5uZS54XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlyZWN0aW9uX3N3KCkge1xuICAgICAgdmFyIGJib3ggPSBnZXRTY3JlZW5CQm94KClcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogIGJib3guc3cueSxcbiAgICAgICAgbGVmdDogYmJveC5zdy54IC0gbm9kZS5vZmZzZXRXaWR0aFxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRpcmVjdGlvbl9zZSgpIHtcbiAgICAgIHZhciBiYm94ID0gZ2V0U2NyZWVuQkJveCgpXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6ICBiYm94LnNlLnksXG4gICAgICAgIGxlZnQ6IGJib3guZS54XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5pdE5vZGUoKSB7XG4gICAgICB2YXIgbm9kZSA9IGQzLnNlbGVjdChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSlcbiAgICAgIG5vZGUuc3R5bGUoe1xuICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgdG9wOiAwLFxuICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAncG9pbnRlci1ldmVudHMnOiAnbm9uZScsXG4gICAgICAgICdib3gtc2l6aW5nJzogJ2JvcmRlci1ib3gnXG4gICAgICB9KVxuXG4gICAgICByZXR1cm4gbm9kZS5ub2RlKClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTVkdOb2RlKGVsKSB7XG4gICAgICBlbCA9IGVsLm5vZGUoKVxuICAgICAgaWYoZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnc3ZnJylcbiAgICAgICAgcmV0dXJuIGVsXG5cbiAgICAgIHJldHVybiBlbC5vd25lclNWR0VsZW1lbnRcbiAgICB9XG5cbiAgICAvLyBQcml2YXRlIC0gZ2V0cyB0aGUgc2NyZWVuIGNvb3JkaW5hdGVzIG9mIGEgc2hhcGVcbiAgICAvL1xuICAgIC8vIEdpdmVuIGEgc2hhcGUgb24gdGhlIHNjcmVlbiwgd2lsbCByZXR1cm4gYW4gU1ZHUG9pbnQgZm9yIHRoZSBkaXJlY3Rpb25zXG4gICAgLy8gbihub3J0aCksIHMoc291dGgpLCBlKGVhc3QpLCB3KHdlc3QpLCBuZShub3J0aGVhc3QpLCBzZShzb3V0aGVhc3QpLCBudyhub3J0aHdlc3QpLFxuICAgIC8vIHN3KHNvdXRod2VzdCkuXG4gICAgLy9cbiAgICAvLyAgICArLSstK1xuICAgIC8vICAgIHwgICB8XG4gICAgLy8gICAgKyAgICtcbiAgICAvLyAgICB8ICAgfFxuICAgIC8vICAgICstKy0rXG4gICAgLy9cbiAgICAvLyBSZXR1cm5zIGFuIE9iamVjdCB7biwgcywgZSwgdywgbncsIHN3LCBuZSwgc2V9XG4gICAgZnVuY3Rpb24gZ2V0U2NyZWVuQkJveCgpIHtcbiAgICAgIHZhciB0YXJnZXRlbCAgID0gdGFyZ2V0IHx8IGQzLmV2ZW50LnRhcmdldDtcblxuICAgICAgd2hpbGUgKCd1bmRlZmluZWQnID09PSB0eXBlb2YgdGFyZ2V0ZWwuZ2V0U2NyZWVuQ1RNICYmICd1bmRlZmluZWQnID09PSB0YXJnZXRlbC5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgdGFyZ2V0ZWwgPSB0YXJnZXRlbC5wYXJlbnROb2RlO1xuICAgICAgfVxuXG4gICAgICB2YXIgYmJveCAgICAgICA9IHt9LFxuICAgICAgICAgIG1hdHJpeCAgICAgPSB0YXJnZXRlbC5nZXRTY3JlZW5DVE0oKSxcbiAgICAgICAgICB0YmJveCAgICAgID0gdGFyZ2V0ZWwuZ2V0QkJveCgpLFxuICAgICAgICAgIHdpZHRoICAgICAgPSB0YmJveC53aWR0aCxcbiAgICAgICAgICBoZWlnaHQgICAgID0gdGJib3guaGVpZ2h0LFxuICAgICAgICAgIHggICAgICAgICAgPSB0YmJveC54LFxuICAgICAgICAgIHkgICAgICAgICAgPSB0YmJveC55XG5cbiAgICAgIHBvaW50LnggPSB4XG4gICAgICBwb2ludC55ID0geVxuICAgICAgYmJveC5udyA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShtYXRyaXgpXG4gICAgICBwb2ludC54ICs9IHdpZHRoXG4gICAgICBiYm94Lm5lID0gcG9pbnQubWF0cml4VHJhbnNmb3JtKG1hdHJpeClcbiAgICAgIHBvaW50LnkgKz0gaGVpZ2h0XG4gICAgICBiYm94LnNlID0gcG9pbnQubWF0cml4VHJhbnNmb3JtKG1hdHJpeClcbiAgICAgIHBvaW50LnggLT0gd2lkdGhcbiAgICAgIGJib3guc3cgPSBwb2ludC5tYXRyaXhUcmFuc2Zvcm0obWF0cml4KVxuICAgICAgcG9pbnQueSAtPSBoZWlnaHQgLyAyXG4gICAgICBiYm94LncgID0gcG9pbnQubWF0cml4VHJhbnNmb3JtKG1hdHJpeClcbiAgICAgIHBvaW50LnggKz0gd2lkdGhcbiAgICAgIGJib3guZSA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShtYXRyaXgpXG4gICAgICBwb2ludC54IC09IHdpZHRoIC8gMlxuICAgICAgcG9pbnQueSAtPSBoZWlnaHQgLyAyXG4gICAgICBiYm94Lm4gPSBwb2ludC5tYXRyaXhUcmFuc2Zvcm0obWF0cml4KVxuICAgICAgcG9pbnQueSArPSBoZWlnaHRcbiAgICAgIGJib3gucyA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShtYXRyaXgpXG5cbiAgICAgIHJldHVybiBiYm94XG4gICAgfVxuXG4gICAgcmV0dXJuIHRpcFxuICB9O1xuXG59KSk7XG4iLCIvKipcbiAqXG4gKiBNdXRhdGlvbnMgTmVlZGxlIFBsb3QgKG11dHMtbmVlZGxlLXBsb3QpXG4gKlxuICogQ3JlYXRlcyBhIG5lZWRsZSBwbG90IChhLmsuYSBzdGVtIHBsb3QsIGxvbGxpcG9wLXBsb3QgYW5kIHNvb24gYWxzbyBiYWxsb29uIHBsb3QgOy0pXG4gKiBUaGlzIGNsYXNzIHVzZXMgdGhlIG5wbS1yZXF1aXJlIG1vZHVsZSB0byBsb2FkIGRlcGVuZGVuY2llcyBkMywgZDMtdGlwXG4gKlxuICogQGF1dGhvciBNaWNoYWVsIFAgU2Nocm9lZGVyXG4gKiBAY2xhc3NcbiAqL1xuXG5mdW5jdGlvbiBNdXRzTmVlZGxlUGxvdCAoY29uZmlnKSB7XG5cbiAgICAvLyBJTklUSUFMSVpBVElPTlxuXG4gICAgdmFyIHNlbGYgPSB0aGlzOyAgICAgICAgLy8gc2VsZiA9IE11dHNOZWVkbGVQbG90XG5cbiAgICAvLyBYLWNvb3JkaW5hdGVzXG4gICAgdGhpcy5tYXhDb29yZCA9IGNvbmZpZy5tYXhDb29yZCB8fCAtMTsgICAgICAgICAgICAgLy8gVGhlIG1heGltdW0gY29vcmQgKHgtYXhpcylcbiAgICBpZiAodGhpcy5tYXhDb29yZCA8IDApIHsgdGhyb3cgbmV3IEVycm9yKFwiJ21heENvb3JkJyBtdXN0IGJlIGRlZmluZWQgaW5pdGlhdGlvbiBjb25maWchXCIpOyB9XG4gICAgdGhpcy5taW5Db29yZCA9IGNvbmZpZy5taW5Db29yZCB8fCAxOyAgICAgICAgICAgICAgIC8vIFRoZSBtaW5pbXVtIGNvb3JkICh4LWF4aXMpXG5cbiAgICAvLyBkYXRhXG4gICAgbXV0YXRpb25EYXRhID0gY29uZmlnLm11dGF0aW9uRGF0YSB8fCAtMTsgICAgICAgICAgLy8gLmpzb24gZmlsZSBvciBkaWN0XG4gICAgaWYgKHRoaXMubWF4Q29vcmQgPCAwKSB7IHRocm93IG5ldyBFcnJvcihcIidtdXRhdGlvbkRhdGEnIG11c3QgYmUgZGVmaW5lZCBpbml0aWF0aW9uIGNvbmZpZyFcIik7IH1cbiAgICByZWdpb25EYXRhID0gY29uZmlnLnJlZ2lvbkRhdGEgfHwgLTE7ICAgICAgICAgICAgICAvLyAuanNvbiBmaWxlIG9yIGRpY3RcbiAgICBpZiAodGhpcy5tYXhDb29yZCA8IDApIHsgdGhyb3cgbmV3IEVycm9yKFwiJ3JlZ2lvbkRhdGEnIG11c3QgYmUgZGVmaW5lZCBpbml0aWF0aW9uIGNvbmZpZyFcIik7IH1cbiAgICB0aGlzLnRvdGFsQ2F0ZWdDb3VudHMgPSB7fTtcbiAgICB0aGlzLmNhdGVnQ291bnRzID0ge307XG4gICAgdGhpcy5zZWxlY3RlZE5lZWRsZXMgPSBbXTtcblxuICAgIC8vIFBsb3QgZGltZW5zaW9ucyAmIHRhcmdldFxuICAgIHZhciB0YXJnZXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoY29uZmlnLnRhcmdldEVsZW1lbnQpIHx8IGNvbmZpZy50YXJnZXRFbGVtZW50IHx8IGRvY3VtZW50LmJvZHkgICAvLyBXaGVyZSB0byBhcHBlbmQgdGhlIHBsb3QgKHN2ZylcblxuICAgIHZhciB3aWR0aCA9IHRoaXMud2lkdGggPSBjb25maWcud2lkdGggfHwgdGFyZ2V0RWxlbWVudC5vZmZzZXRXaWR0aCB8fCAxMDAwO1xuICAgIHZhciBoZWlnaHQgPSB0aGlzLmhlaWdodCA9IGNvbmZpZy5oZWlnaHQgfHwgdGFyZ2V0RWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgNTAwO1xuXG4gICAgLy8gQ29sb3Igc2NhbGUgJiBtYXBcbiAgICB0aGlzLmNvbG9yTWFwID0gY29uZmlnLmNvbG9yTWFwIHx8IHt9OyAgICAgICAgICAgICAgLy8gZGljdFxuICAgIHZhciBjb2xvcnMgPSBPYmplY3Qua2V5cyh0aGlzLmNvbG9yTWFwKS5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICByZXR1cm4gc2VsZi5jb2xvck1hcFtrZXldO1xuICAgIH0pO1xuICAgIHRoaXMuY29sb3JTY2FsZSA9IGQzLnNjYWxlLmNhdGVnb3J5MjAoKVxuICAgICAgICAuZG9tYWluKE9iamVjdC5rZXlzKHRoaXMuY29sb3JNYXApKVxuICAgICAgICAucmFuZ2UoY29sb3JzLmNvbmNhdChkMy5zY2FsZS5jYXRlZ29yeTIwKCkucmFuZ2UoKSkpO1xuICAgIHRoaXMubGVnZW5kcyA9IGNvbmZpZy5sZWdlbmRzIHx8IHtcbiAgICAgICAgXCJ5XCI6IFwiVmFsdWVcIixcbiAgICAgICAgXCJ4XCI6IFwiQ29vcmRpbmF0ZVwiXG4gICAgfTtcblxuICAgIHRoaXMuc3ZnQ2xhc3NlcyA9IFwibXV0bmVlZGxlc1wiXG4gICAgdGhpcy5idWZmZXIgPSAwO1xuXG4gICAgdmFyIG1heENvb3JkID0gdGhpcy5tYXhDb29yZDtcblxuICAgIHZhciBidWZmZXIgPSAwO1xuICAgIGlmICh3aWR0aCA+PSBoZWlnaHQpIHtcbiAgICAgIGJ1ZmZlciA9IGhlaWdodCAvIDg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1ZmZlciA9IHdpZHRoIC8gODtcbiAgICB9XG5cbiAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcblxuICAgIC8vIElJTVBPUlQgQU5EIENPTkZJR1VSRSBUSVBTXG4gICAgdmFyIGQzdGlwID0gcmVxdWlyZSgnZDMtdGlwJyk7XG4gICAgZDN0aXAoZDMpO1xuXG5cbiAgICB0aGlzLnRpcCA9IGQzLnRpcCgpXG4gICAgICAuYXR0cignY2xhc3MnLCAnZDMtdGlwIGQzLXRpcC1uZWVkbGUnKVxuICAgICAgLm9mZnNldChbLTEwLCAwXSlcbiAgICAgIC5odG1sKGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgcmV0dXJuIFwiPHNwYW4+XCIgKyBkLnZhbHVlICsgXCIgXCIgKyBkLmNhdGVnb3J5ICsgIFwiIGF0IGNvb3JkLiBcIiArIGQuY29vcmRTdHJpbmcgKyBcIjwvc3Bhbj5cIjtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5zZWxlY3Rpb25UaXAgPSBkMy50aXAoKVxuICAgICAgICAuYXR0cignY2xhc3MnLCAnZDMtdGlwIGQzLXRpcC1zZWxlY3Rpb24nKVxuICAgICAgICAub2Zmc2V0KFsxMDAsIDBdKVxuICAgICAgICAuaHRtbChmdW5jdGlvbihkKSB7XG4gICAgICAgICAgICByZXR1cm4gXCI8c3Bhbj4gU2VsZWN0ZWQgY29vcmRpbmF0ZXM8YnIvPlwiICsgTWF0aC5yb3VuZChkLmxlZnQpICsgXCIgLSBcIiArIE1hdGgucm91bmQoZC5yaWdodCkgKyBcIjwvc3Bhbj5cIjtcbiAgICAgICAgfSlcbiAgICAgICAgLmRpcmVjdGlvbignbicpO1xuXG4gICAgLy8gSU5JVCBTVkdcblxuICAgIHZhciBzdmcgPSBkMy5zZWxlY3QodGFyZ2V0RWxlbWVudCkuYXBwZW5kKFwic3ZnXCIpXG4gICAgICAgIC5hdHRyKFwid2lkdGhcIiwgd2lkdGgpXG4gICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGhlaWdodClcbiAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCB0aGlzLnN2Z0NsYXNzZXMpO1xuXG4gICAgc3ZnLmNhbGwodGhpcy50aXApO1xuICAgIHN2Zy5jYWxsKHRoaXMuc2VsZWN0aW9uVGlwKTtcblxuICAgIC8vIERFRklORSBTQ0FMRVNcblxuICAgIHZhciB4ID0gZDMuc2NhbGUubGluZWFyKClcbiAgICAgIC5kb21haW4oW3RoaXMubWluQ29vcmQsIHRoaXMubWF4Q29vcmRdKVxuICAgICAgLnJhbmdlKFtidWZmZXIgKiAxLjUgLCB3aWR0aCAtIGJ1ZmZlcl0pXG4gICAgICAubmljZSgpO1xuICAgIHRoaXMueCA9IHg7XG5cbiAgICB2YXIgeSA9IGQzLnNjYWxlLmxpbmVhcigpXG4gICAgICAuZG9tYWluKFsxLDIwXSlcbiAgICAgIC5yYW5nZShbaGVpZ2h0IC0gYnVmZmVyICogMS41LCBidWZmZXJdKVxuICAgICAgLm5pY2UoKTtcbiAgICB0aGlzLnkgPSB5O1xuXG4gICAgLy8gQ09ORklHVVJFIEJSVVNIXG4gICAgc2VsZi5zZWxlY3RvciA9IGQzLnN2Zy5icnVzaCgpXG4gICAgICAgIC54KHgpXG4gICAgICAgIC5vbihcImJydXNoXCIsIGJydXNobW92ZSlcbiAgICAgICAgLm9uKFwiYnJ1c2hlbmRcIiwgYnJ1c2hlbmQpO1xuICAgIHZhciBzZWxlY3RvciA9IHNlbGYuc2VsZWN0b3I7XG5cbiAgICB0aGlzLnN2Z0NsYXNzZXMgKz0gXCIgYnJ1c2hcIjtcbiAgICB2YXIgc2VsZWN0aW9uUmVjdCA9IHN2Zy5hdHRyKFwiY2xhc3NcIiwgdGhpcy5zdmdDbGFzc2VzKVxuICAgICAgICAuY2FsbChzZWxlY3RvcilcbiAgICAgICAgLnNlbGVjdEFsbCgnLmV4dGVudCcpXG4gICAgICAgIC5hdHRyKCdoZWlnaHQnLCBoZWlnaHQpO1xuICAgIHNlbGVjdGlvblJlY3Qub24oXCJtb3VzZWVudGVyXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgc2VsZWN0aW9uID0gc2VsZWN0b3IuZXh0ZW50KCk7XG4gICAgICAgIHNlbGYuc2VsZWN0aW9uVGlwLnNob3coe2xlZnQ6IHNlbGVjdGlvblswXSwgcmlnaHQ6IHNlbGVjdGlvblsxXX0sIHNlbGVjdGlvblJlY3Qubm9kZSgpKTtcbiAgICB9KVxuICAgICAgICAub24oXCJtb3VzZW91dFwiLCBmdW5jdGlvbigpe1xuICAgICAgICAgICAgZDMuc2VsZWN0KFwiLmQzLXRpcC1zZWxlY3Rpb25cIilcbiAgICAgICAgICAgICAgICAudHJhbnNpdGlvbigpXG4gICAgICAgICAgICAgICAgLmRlbGF5KDMwMDApXG4gICAgICAgICAgICAgICAgLmR1cmF0aW9uKDEwMDApXG4gICAgICAgICAgICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLDApXG4gICAgICAgICAgICAgICAgLnN0eWxlKCdwb2ludGVyLWV2ZW50cycsICdub25lJyk7XG4gICAgICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYnJ1c2htb3ZlKCkge1xuXG4gICAgICAgIHZhciBleHRlbnQgPSBzZWxlY3Rvci5leHRlbnQoKTtcbiAgICAgICAgbmVlZGxlSGVhZHMgPSBkMy5zZWxlY3RBbGwoXCIubmVlZGxlLWhlYWRcIik7XG4gICAgICAgIHNlbGVjdGVkTmVlZGxlcyA9IFtdO1xuICAgICAgICBjYXRlZ0NvdW50cyA9IHt9O1xuICAgICAgICBmb3IgKGtleSBpbiBPYmplY3Qua2V5cyhzZWxmLnRvdGFsQ2F0ZWdDb3VudHMpKSB7XG4gICAgICAgICAgICBjYXRlZ0NvdW50c1trZXldID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIG5lZWRsZUhlYWRzLmNsYXNzZWQoXCJzZWxlY3RlZFwiLCBmdW5jdGlvbihkKSB7XG4gICAgICAgICAgICBpc19icnVzaGVkID0gZXh0ZW50WzBdIDw9IGQuY29vcmQgJiYgZC5jb29yZCA8PSBleHRlbnRbMV07XG4gICAgICAgICAgICBpZiAoaXNfYnJ1c2hlZCkge1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkTmVlZGxlcy5wdXNoKGQpO1xuICAgICAgICAgICAgICAgIGNhdGVnQ291bnRzW2QuY2F0ZWdvcnldID0gKGNhdGVnQ291bnRzW2QuY2F0ZWdvcnldIHx8IDApICsgZC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpc19icnVzaGVkO1xuICAgICAgICB9KTtcblxuICAgICAgICBzZWxmLnRyaWdnZXIoJ25lZWRsZVNlbGVjdGlvbkNoYW5nZScsIHtcbiAgICAgICAgc2VsZWN0ZWQgOiBzZWxlY3RlZE5lZWRsZXMsXG4gICAgICAgICAgICBjYXRlZ0NvdW50czogY2F0ZWdDb3VudHMsXG4gICAgICAgICAgICBjb29yZHM6IGV4dGVudFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBicnVzaGVuZCgpIHtcbiAgICAgICAgZ2V0X2J1dHRvbiA9IGQzLnNlbGVjdChcIi5jbGVhci1idXR0b25cIik7XG4gICAgICAgIHNlbGYudHJpZ2dlcignbmVlZGxlU2VsZWN0aW9uQ2hhbmdlRW5kJywge1xuICAgICAgICAgICAgc2VsZWN0ZWQgOiBzZWxlY3RlZE5lZWRsZXMsXG4gICAgICAgICAgICBjYXRlZ0NvdW50czogY2F0ZWdDb3VudHMsXG4gICAgICAgICAgICBjb29yZHM6IHNlbGVjdG9yLmV4dGVudCgpXG4gICAgICAgIH0pO1xuICAgICAgICAvKmlmKGdldF9idXR0b24uZW1wdHkoKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgY2xlYXJfYnV0dG9uID0gc3ZnLmFwcGVuZCgndGV4dCcpXG4gICAgICAgICAuYXR0cihcInlcIiwgNDYwKVxuICAgICAgICAgLmF0dHIoXCJ4XCIsIDgyNSlcbiAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJjbGVhci1idXR0b25cIilcbiAgICAgICAgIC50ZXh0KFwiQ2xlYXIgQnJ1c2hcIik7XG4gICAgICAgICB9XG5cbiAgICAgICAgIHguZG9tYWluKGJydXNoLmV4dGVudCgpKTtcblxuICAgICAgICAgdHJhbnNpdGlvbl9kYXRhKCk7XG4gICAgICAgICByZXNldF9heGlzKCk7XG5cbiAgICAgICAgIHBvaW50cy5jbGFzc2VkKFwic2VsZWN0ZWRcIiwgZmFsc2UpO1xuICAgICAgICAgZDMuc2VsZWN0KFwiLmJydXNoXCIpLmNhbGwoYnJ1c2guY2xlYXIoKSk7XG5cbiAgICAgICAgIGNsZWFyX2J1dHRvbi5vbignY2xpY2snLCBmdW5jdGlvbigpe1xuICAgICAgICAgeC5kb21haW4oWzAsIDUwXSk7XG4gICAgICAgICB0cmFuc2l0aW9uX2RhdGEoKTtcbiAgICAgICAgIHJlc2V0X2F4aXMoKTtcbiAgICAgICAgIGNsZWFyX2J1dHRvbi5yZW1vdmUoKTtcbiAgICAgICAgIH0pOyovXG4gICAgfVxuXG4gICAgLy8vIERSQVdcbiAgICB0aGlzLmRyYXdOZWVkbGVzKHN2ZywgbXV0YXRpb25EYXRhLCByZWdpb25EYXRhKTtcblxuXG4gICAgc2VsZi5vbihcIm5lZWRsZVNlbGVjdGlvbkNoYW5nZVwiLCBmdW5jdGlvbiAoZWRhdGEpIHtcbiAgICAgICAgc2VsZi5jYXRlZ0NvdW50cyA9IGVkYXRhLmNhdGVnQ291bnRzO1xuICAgICAgICBzZWxmLnNlbGVjdGVkTmVlZGxlcyA9IGVkYXRhLnNlbGVjdGVkO1xuICAgICAgICBzdmcuY2FsbCh2ZXJ0aWNhbExlZ2VuZCk7XG4gICAgfSk7XG5cbiAgICBzZWxmLm9uKFwibmVlZGxlU2VsZWN0aW9uQ2hhbmdlRW5kXCIsIGZ1bmN0aW9uIChlZGF0YSkge1xuICAgICAgICBzZWxmLmNhdGVnQ291bnRzID0gZWRhdGEuY2F0ZWdDb3VudHM7XG4gICAgICAgIHNlbGYuc2VsZWN0ZWROZWVkbGVzID0gZWRhdGEuc2VsZWN0ZWQ7XG4gICAgICAgIHN2Zy5jYWxsKHZlcnRpY2FsTGVnZW5kKTtcbiAgICB9KTtcblxuICAgIHNlbGYub24oXCJuZWVkbGVTZWxlY3Rpb25DaGFuZ2VcIiwgZnVuY3Rpb24oZWRhdGEpIHtcbiAgICAgICAgICAgIHNlbGVjdGlvbiA9IGVkYXRhLmNvb3JkcztcbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25bMV0gLSBzZWxlY3Rpb25bMF0gPiAwKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5zZWxlY3Rpb25UaXAuc2hvdyh7bGVmdDogc2VsZWN0aW9uWzBdLCByaWdodDogc2VsZWN0aW9uWzFdfSwgc2VsZWN0aW9uUmVjdC5ub2RlKCkpO1xuICAgICAgICAgICAgICAgIGQzLnNlbGVjdChcIi5kMy10aXAtc2VsZWN0aW9uXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmFuc2l0aW9uKClcbiAgICAgICAgICAgICAgICAgICAgLmRlbGF5KDMwMDApXG4gICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbigxMDAwKVxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsMClcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKCdwb2ludGVyLWV2ZW50cycsICdub25lJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlbGYuc2VsZWN0aW9uVGlwLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cblxuXG59XG5cbk11dHNOZWVkbGVQbG90LnByb3RvdHlwZS5kcmF3TGVnZW5kID0gZnVuY3Rpb24oc3ZnKSB7XG5cbiAgICAvLyBMRUdFTkRcbiAgICBzZWxmID0gdGhpcztcblxuICAgIC8vIHByZXBhcmUgbGVnZW5kIGNhdGVnb3JpZXMgKGNvcnJlY3Qgb3JkZXIpXG4gICAgbXV0Q2F0ZWdvcmllcyA9IFtdO1xuICAgIGNhdGVnb3J5Q29sb3JzID0gW107XG4gICAgYWxsY2F0ZWdzID0gT2JqZWN0LmtleXMoc2VsZi50b3RhbENhdGVnQ291bnRzKTsgLy8gcmFuZG9tIG9yZGVyXG4gICAgb3JkZXJlZERlY2xhcmF0aW9uID0gc2VsZi5jb2xvclNjYWxlLmRvbWFpbigpOyAgLy8gd2FudGVkIG9yZGVyXG4gICAgZm9yIChpZHggaW4gb3JkZXJlZERlY2xhcmF0aW9uKSB7XG4gICAgICAgIGMgPSBvcmRlcmVkRGVjbGFyYXRpb25baWR4XTtcbiAgICAgICAgaWYgKGFsbGNhdGVncy5pbmRleE9mKGMpID4gLTEpIHtcbiAgICAgICAgICAgIG11dENhdGVnb3JpZXMucHVzaChjKTtcbiAgICAgICAgICAgIGNhdGVnb3J5Q29sb3JzLnB1c2goc2VsZi5jb2xvclNjYWxlKGMpKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIHNjYWxlIHdpdGggY29ycmVjdCBvcmRlciBvZiBjYXRlZ29yaWVzXG4gICAgbXV0c1NjYWxlID0gc2VsZi5jb2xvclNjYWxlLmRvbWFpbihtdXRDYXRlZ29yaWVzKS5yYW5nZShjYXRlZ29yeUNvbG9ycyk7XG5cblxuICAgIHZhciBkb21haW4gPSBzZWxmLnguZG9tYWluKCk7XG4gICAgeHBsYWNlbWVudCA9IChzZWxmLngoZG9tYWluWzFdKSAtIHNlbGYueChkb21haW5bMF0pKSAqIDAuNzUgKyBzZWxmLngoZG9tYWluWzBdKTtcblxuXG4gICAgdmFyIHN1bSA9IDA7XG4gICAgZm9yICh2YXIgYyBpbiBzZWxmLnRvdGFsQ2F0ZWdDb3VudHMpIHtcbiAgICAgICAgc3VtICs9IHNlbGYudG90YWxDYXRlZ0NvdW50c1tjXTtcbiAgICB9XG5cbiAgICBsZWdlbmRMYWJlbCA9IGZ1bmN0aW9uKGNhdGVnKSB7XG4gICAgICAgIHZhciBjb3VudCA9IChzZWxmLmNhdGVnQ291bnRzW2NhdGVnXSB8fCAoc2VsZi5zZWxlY3RlZE5lZWRsZXMubGVuZ3RoID09IDAgJiYgc2VsZi50b3RhbENhdGVnQ291bnRzW2NhdGVnXSkgfHwgMCk7XG4gICAgICAgIHJldHVybiAgY2F0ZWcgKyAoY291bnQgPiAwID8gXCI6IFwiICsgTWF0aC5yb3VuZChjb3VudC9zdW0qMTAwKSArIFwiJVwiIDogXCJcIik7XG4gICAgfTtcblxuICAgIGxlZ2VuZENsYXNzID0gZnVuY3Rpb24oY2F0ZWcpIHtcbiAgICAgICAgdmFyIGNvdW50ID0gKHNlbGYuY2F0ZWdDb3VudHNbY2F0ZWddIHx8IChzZWxmLnNlbGVjdGVkTmVlZGxlcy5sZW5ndGggPT0gMCAmJiBzZWxmLnRvdGFsQ2F0ZWdDb3VudHNbY2F0ZWddKSB8fCAwKTtcbiAgICAgICAgcmV0dXJuIChjb3VudCA+IDApID8gXCJcIiA6IFwibm9tdXRzXCI7XG4gICAgfTtcblxuICAgIHNlbGYubm9zaG93ID0gW107XG4gICAgdmFyIG5lZWRsZUhlYWRzID0gZDMuc2VsZWN0QWxsKFwiLm5lZWRsZS1oZWFkXCIpO1xuICAgIHNob3dOb1Nob3cgPSBmdW5jdGlvbihjYXRlZyl7XG4gICAgICAgIGlmIChfLmNvbnRhaW5zKHNlbGYubm9zaG93LCBjYXRlZykpIHtcbiAgICAgICAgICAgIHNlbGYubm9zaG93ID0gXy5maWx0ZXIoc2VsZi5ub3Nob3csIGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHMgIT0gY2F0ZWcgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxmLm5vc2hvdy5wdXNoKGNhdGVnKTtcbiAgICAgICAgfVxuICAgICAgICBuZWVkbGVIZWFkcy5jbGFzc2VkKFwibm9zaG93XCIsIGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgICAgIHJldHVybiBfLmNvbnRhaW5zKHNlbGYubm9zaG93LCBkLmNhdGVnb3J5KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBsZWdlbmRDZWxscyA9IGQzLnNlbGVjdEFsbChcImcubGVnZW5kQ2VsbHNcIik7XG4gICAgICAgIGxlZ2VuZENlbGxzLmNsYXNzZWQoXCJub3Nob3dcIiwgZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgcmV0dXJuIF8uY29udGFpbnMoc2VsZi5ub3Nob3csIGQuc3RvcFswXSk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cblxuICAgIHZlcnRpY2FsTGVnZW5kID0gZDMuc3ZnLmxlZ2VuZCgpXG4gICAgICAgIC5sYWJlbEZvcm1hdChsZWdlbmRMYWJlbClcbiAgICAgICAgLmxhYmVsQ2xhc3MobGVnZW5kQ2xhc3MpXG4gICAgICAgIC5vbkxlZ2VuZENsaWNrKHNob3dOb1Nob3cpXG4gICAgICAgIC5jZWxsUGFkZGluZyg0KVxuICAgICAgICAub3JpZW50YXRpb24oXCJ2ZXJ0aWNhbFwiKVxuICAgICAgICAudW5pdHMoc3VtICsgXCIgTXV0YXRpb25zXCIpXG4gICAgICAgIC5jZWxsV2lkdGgoMjApXG4gICAgICAgIC5jZWxsSGVpZ2h0KDEyKVxuICAgICAgICAuaW5wdXRTY2FsZShtdXRzU2NhbGUpXG4gICAgICAgIC5jZWxsU3RlcHBpbmcoNClcbiAgICAgICAgLnBsYWNlKHt4OiB4cGxhY2VtZW50LCB5OiA1MH0pO1xuXG4gICAgc3ZnLmNhbGwodmVydGljYWxMZWdlbmQpO1xuXG59O1xuXG5NdXRzTmVlZGxlUGxvdC5wcm90b3R5cGUuZHJhd1JlZ2lvbnMgPSBmdW5jdGlvbihzdmcsIHJlZ2lvbkRhdGEpIHtcblxuICAgIHZhciBtYXhDb29yZCA9IHRoaXMubWF4Q29vcmQ7XG4gICAgdmFyIG1pbkNvb3JkID0gdGhpcy5taW5Db29yZDtcbiAgICB2YXIgYnVmZmVyID0gdGhpcy5idWZmZXI7XG4gICAgdmFyIGNvbG9ycyA9IHRoaXMuY29sb3JNYXA7XG4gICAgdmFyIHkgPSB0aGlzLnk7XG4gICAgdmFyIHggPSB0aGlzLng7XG5cbiAgICB2YXIgYmVsb3cgPSB0cnVlO1xuXG5cbiAgICBnZXRSZWdpb25TdGFydCA9IGZ1bmN0aW9uKHJlZ2lvbikge1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQocmVnaW9uLnNwbGl0KFwiLVwiKVswXSlcbiAgICB9O1xuXG4gICAgZ2V0UmVnaW9uRW5kID0gZnVuY3Rpb24ocmVnaW9uKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUludChyZWdpb24uc3BsaXQoXCItXCIpWzFdKVxuICAgIH07XG5cbiAgICBnZXRDb2xvciA9IHRoaXMuY29sb3JTY2FsZTtcblxuICAgIHZhciBiZ19vZmZzZXQgPSAwO1xuICAgIHZhciByZWdpb25fb2Zmc2V0ID0gYmdfb2Zmc2V0LTNcbiAgICB2YXIgdGV4dF9vZmZzZXQgPSBiZ19vZmZzZXQgKyAyMDtcbiAgICBpZiAoYmVsb3cgIT0gdHJ1ZSkge1xuICAgICAgICB0ZXh0X29mZnNldCA9IGJnX29mZnNldCs1O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRyYXcocmVnaW9uTGlzdCkge1xuXG4gICAgICAgIHZhciByZWdpb25zQkcgPSBkMy5zZWxlY3QoXCIubXV0bmVlZGxlc1wiKS5zZWxlY3RBbGwoKVxuICAgICAgICAgICAgLmRhdGEoW1wiZHVtbXlcIl0pLmVudGVyKClcbiAgICAgICAgICAgIC5pbnNlcnQoXCJnXCIsIFwiOmZpcnN0LWNoaWxkXCIpXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwicmVnaW9uc0JHXCIpXG4gICAgICAgICAgICAuYXBwZW5kKFwicmVjdFwiKVxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIHgobWluQ29vcmQpIClcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCB5KDApICsgYmdfb2Zmc2V0IClcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgeChtYXhDb29yZCkgLSB4KG1pbkNvb3JkKSApXG4gICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCAxMCk7XG5cblxuICAgICAgICB2YXIgcmVnaW9ucyA9IHJlZ2lvbnNCRyA9IGQzLnNlbGVjdChcIi5tdXRuZWVkbGVzXCIpLnNlbGVjdEFsbCgpXG4gICAgICAgICAgICAuZGF0YShyZWdpb25MaXN0KVxuICAgICAgICAgICAgLmVudGVyKClcbiAgICAgICAgICAgIC5hcHBlbmQoXCJnXCIpXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwicmVnaW9uR3JvdXBcIik7XG5cbiAgICAgICAgcmVnaW9ucy5hcHBlbmQoXCJyZWN0XCIpXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geChyLnN0YXJ0KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgeSgwKSArIHJlZ2lvbl9vZmZzZXQgKVxuICAgICAgICAgICAgLmF0dHIoXCJyeVwiLCBcIjNcIilcbiAgICAgICAgICAgIC5hdHRyKFwicnhcIiwgXCIzXCIpXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHgoci5lbmQpIC0geChyLnN0YXJ0KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIDE2KVxuICAgICAgICAgICAgLnN0eWxlKFwiZmlsbFwiLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbG9yXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnN0eWxlKFwic3Ryb2tlXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGQzLnJnYihkYXRhLmNvbG9yKS5kYXJrZXIoKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgcmVnaW9uc1xuICAgICAgICAgICAgLmF0dHIoJ3BvaW50ZXItZXZlbnRzJywgJ2FsbCcpXG4gICAgICAgICAgICAuYXR0cignY3Vyc29yJywgJ3BvaW50ZXInKVxuICAgICAgICAgICAgLm9uKFwiY2xpY2tcIiwgIGZ1bmN0aW9uKHIpIHtcbiAgICAgICAgICAgIC8vIHNldCBjdXN0b20gc2VsZWN0aW9uIGV4dGVudFxuICAgICAgICAgICAgc2VsZi5zZWxlY3Rvci5leHRlbnQoW3Iuc3RhcnQsIHIuZW5kXSk7XG4gICAgICAgICAgICAvLyBjYWxsIHRoZSBleHRlbnQgdG8gY2hhbmdlIHdpdGggdHJhbnNpdGlvblxuICAgICAgICAgICAgc2VsZi5zZWxlY3RvcihkMy5zZWxlY3QoXCIuYnJ1c2hcIikudHJhbnNpdGlvbigpKTtcbiAgICAgICAgICAgIC8vIGNhbGwgZXh0ZW50IChzZWxlY3Rpb24pIGNoYW5nZSBsaXN0ZW5lcnNcbiAgICAgICAgICAgIHNlbGYuc2VsZWN0b3IuZXZlbnQoZDMuc2VsZWN0KFwiLmJydXNoXCIpLnRyYW5zaXRpb24oKS5kZWxheSgzMDApKTtcblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBQbGFjZSBhbmQgbGFiZWwgbG9jYXRpb25cbiAgICAgICAgdmFyIGxhYmVscyA9IFtdO1xuXG4gICAgICAgIHZhciByZXBlYXRlZFJlZ2lvbiA9IHt9O1xuICAgICAgICB2YXIgZ2V0UmVnaW9uQ2xhc3MgPSBmdW5jdGlvbihyZWdpb24pIHtcbiAgICAgICAgICAgIHZhciBjID0gXCJyZWdpb25OYW1lXCI7XG4gICAgICAgICAgICB2YXIgcmVwZWF0ZWRDbGFzcyA9IFwiUlJfXCIrcmVnaW9uLm5hbWU7XG4gICAgICAgICAgICBpZihfLmhhcyhyZXBlYXRlZFJlZ2lvbiwgcmVnaW9uLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgYyA9IFwicmVwZWF0ZWROYW1lIG5vc2hvdyBcIiArIHJlcGVhdGVkQ2xhc3M7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXBlYXRlZFJlZ2lvbltyZWdpb24ubmFtZV0gPSByZXBlYXRlZENsYXNzO1xuICAgICAgICAgICAgcmV0dXJuIGM7XG4gICAgICAgIH07XG4gICAgICAgIHJlZ2lvbnMuYXBwZW5kKFwidGV4dFwiKVxuICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBnZXRSZWdpb25DbGFzcylcbiAgICAgICAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIilcbiAgICAgICAgICAgIC5hdHRyKFwieFwiLCBmdW5jdGlvbiAocikge1xuICAgICAgICAgICAgICAgIHIueCA9IHgoci5zdGFydCkgKyAoeChyLmVuZCkgLSB4KHIuc3RhcnQpKSAvIDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHIueDtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgZnVuY3Rpb24ocikge3IueSA9IHkoMCkgKyB0ZXh0X29mZnNldDsgcmV0dXJuIHIueTsgfSApXG4gICAgICAgICAgICAuYXR0cihcImR5XCIsIFwiMC4zNWVtXCIpXG4gICAgICAgICAgICAuc3R5bGUoXCJmb250LXNpemVcIiwgXCIxMnB4XCIpXG4gICAgICAgICAgICAuc3R5bGUoXCJ0ZXh0LWRlY29yYXRpb25cIiwgXCJib2xkXCIpXG4gICAgICAgICAgICAudGV4dChmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLm5hbWVcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHZhciByZWdpb25OYW1lcyA9IGQzLnNlbGVjdEFsbChcIi5yZWdpb25OYW1lXCIpO1xuICAgICAgICByZWdpb25OYW1lcy5lYWNoKGZ1bmN0aW9uKGQsIGkpIHtcbiAgICAgICAgICAgIHZhciBpbnRlcmFjdGlvbkxlbmd0aCA9IHRoaXMuZ2V0QkJveCgpLndpZHRoIC8gMjtcbiAgICAgICAgICAgIGxhYmVscy5wdXNoKHt4OiBkLngsIHk6IGQueSwgbGFiZWw6IGQubmFtZSwgd2VpZ2h0OiBkLm5hbWUubGVuZ3RoLCByYWRpdXM6IGludGVyYWN0aW9uTGVuZ3RofSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHZhciBmb3JjZSA9IGQzLmxheW91dC5mb3JjZSgpXG4gICAgICAgICAgICAuY2hhcmdlRGlzdGFuY2UoNSlcbiAgICAgICAgICAgIC5ub2RlcyhsYWJlbHMpXG4gICAgICAgICAgICAuY2hhcmdlKC0xMClcbiAgICAgICAgICAgIC5ncmF2aXR5KDApO1xuXG4gICAgICAgIHZhciBtaW5YID0geChtaW5Db29yZCk7XG4gICAgICAgIHZhciBtYXhYID0geChtYXhDb29yZCk7XG4gICAgICAgIHZhciB3aXRoaW5Cb3VuZHMgPSBmdW5jdGlvbih4KSB7XG4gICAgICAgICAgICByZXR1cm4gZDMubWluKFtcbiAgICAgICAgICAgICAgICBkMy5tYXgoW1xuICAgICAgICAgICAgICAgICAgICBtaW5YLFxuICAgICAgICAgICAgICAgICAgICB4XSksXG4gICAgICAgICAgICAgICAgbWF4WFxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH07XG4gICAgICAgIGZ1bmN0aW9uIGNvbGxpZGUobm9kZSkge1xuICAgICAgICAgICAgdmFyIHIgPSBub2RlLnJhZGl1cyArIDMsXG4gICAgICAgICAgICAgICAgbngxID0gbm9kZS54IC0gcixcbiAgICAgICAgICAgICAgICBueDIgPSBub2RlLnggKyByLFxuICAgICAgICAgICAgICAgIG55MSA9IG5vZGUueSAtIHIsXG4gICAgICAgICAgICAgICAgbnkyID0gbm9kZS55ICsgcjtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihxdWFkLCB4MSwgeTEsIHgyLCB5Mikge1xuICAgICAgICAgICAgICAgIGlmIChxdWFkLnBvaW50ICYmIChxdWFkLnBvaW50ICE9PSBub2RlKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbCA9IG5vZGUueCAtIHF1YWQucG9pbnQueCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSBsO1xuICAgICAgICAgICAgICAgICAgICByID0gbm9kZS5yYWRpdXMgKyBxdWFkLnBvaW50LnJhZGl1cztcbiAgICAgICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKGwpIDwgcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbCA9IChsIC0gcikgLyBsICogLjAwNTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHggKj0gbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSAgKG5vZGUueCA+IHF1YWQucG9pbnQueCAmJiB4IDwgMCkgPyAteCA6IHg7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnggKz0geDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHF1YWQucG9pbnQueCAtPSB4O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB4MSA+IG54MlxuICAgICAgICAgICAgICAgICAgICB8fCB4MiA8IG54MVxuICAgICAgICAgICAgICAgICAgICB8fCB5MSA+IG55MlxuICAgICAgICAgICAgICAgICAgICB8fCB5MiA8IG55MTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG1vdmVSZXBlYXRlZExhYmVscyA9IGZ1bmN0aW9uKGxhYmVsLCB4KSB7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IHJlcGVhdGVkUmVnaW9uW2xhYmVsXTtcbiAgICAgICAgICAgIHN2Zy5zZWxlY3RBbGwoXCJ0ZXh0LlwiK25hbWUpXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIG5ld3gpO1xuICAgICAgICB9O1xuICAgICAgICBmb3JjZS5vbihcInRpY2tcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgdmFyIHEgPSBkMy5nZW9tLnF1YWR0cmVlKGxhYmVscyksXG4gICAgICAgICAgICAgICAgaSA9IDAsXG4gICAgICAgICAgICAgICAgbiA9IGxhYmVscy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAgICAgICAgIHEudmlzaXQoY29sbGlkZShsYWJlbHNbaV0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgcG9zaXRpb24gb2YgdGhlIHRleHQgZWxlbWVudFxuICAgICAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICAgICAgc3ZnLnNlbGVjdEFsbChcInRleHQucmVnaW9uTmFtZVwiKVxuICAgICAgICAgICAgICAgIC5hdHRyKFwieFwiLCBmdW5jdGlvbihkKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld3ggPSBsYWJlbHNbaSsrXS54O1xuICAgICAgICAgICAgICAgICAgICBtb3ZlUmVwZWF0ZWRMYWJlbHMoZC5uYW1lLCBuZXd4KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ld3g7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGZvcmNlLnN0YXJ0KCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0UmVnaW9ucyhyZWdpb25zKSB7XG4gICAgICAgIGZvciAoa2V5IGluIE9iamVjdC5rZXlzKHJlZ2lvbnMpKSB7XG5cbiAgICAgICAgICAgIHJlZ2lvbnNba2V5XS5zdGFydCA9IGdldFJlZ2lvblN0YXJ0KHJlZ2lvbnNba2V5XS5jb29yZCk7XG4gICAgICAgICAgICByZWdpb25zW2tleV0uZW5kID0gZ2V0UmVnaW9uRW5kKHJlZ2lvbnNba2V5XS5jb29yZCk7XG4gICAgICAgICAgICByZWdpb25zW2tleV0uY29sb3IgPSBnZXRDb2xvcihyZWdpb25zW2tleV0ubmFtZSk7XG4gICAgICAgICAgICAvKnJlZ2lvbkxpc3QucHVzaCh7XG4gICAgICAgICAgICAgICAgJ25hbWUnOiBrZXksXG4gICAgICAgICAgICAgICAgJ3N0YXJ0JzogZ2V0UmVnaW9uU3RhcnQocmVnaW9uc1trZXldKSxcbiAgICAgICAgICAgICAgICAnZW5kJzogZ2V0UmVnaW9uRW5kKHJlZ2lvbnNba2V5XSksXG4gICAgICAgICAgICAgICAgJ2NvbG9yJzogZ2V0Q29sb3Ioa2V5KVxuICAgICAgICAgICAgfSk7Ki9cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVnaW9ucztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlZ2lvbkRhdGEgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAvLyBhc3N1bWUgZGF0YSBpcyBpbiBhIGZpbGVcbiAgICAgICAgZDMuanNvbihyZWdpb25EYXRhLCBmdW5jdGlvbihlcnJvciwgcmVnaW9ucykge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7cmV0dXJuIGNvbnNvbGUuZGVidWcoZXJyb3IpfVxuICAgICAgICAgICAgcmVnaW9uTGlzdCA9IGZvcm1hdFJlZ2lvbnMocmVnaW9ucyk7XG4gICAgICAgICAgICBkcmF3KHJlZ2lvbkxpc3QpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZWdpb25MaXN0ID0gZm9ybWF0UmVnaW9ucyhyZWdpb25EYXRhKTtcbiAgICAgICAgZHJhdyhyZWdpb25MaXN0KTtcbiAgICB9XG5cbn07XG5cblxuTXV0c05lZWRsZVBsb3QucHJvdG90eXBlLmRyYXdBeGVzID0gZnVuY3Rpb24oc3ZnKSB7XG5cbiAgICB2YXIgeSA9IHRoaXMueTtcbiAgICB2YXIgeCA9IHRoaXMueDtcblxuICAgIHhBeGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh4KS5vcmllbnQoXCJib3R0b21cIik7XG5cbiAgICBzdmcuYXBwZW5kKFwic3ZnOmdcIilcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJ4LWF4aXNcIilcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKDAsXCIgKyAodGhpcy5oZWlnaHQgLSB0aGlzLmJ1ZmZlcikgKyBcIilcIilcbiAgICAgIC5jYWxsKHhBeGlzKTtcblxuICAgIHlBeGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh5KS5vcmllbnQoXCJsZWZ0XCIpO1xuXG5cbiAgICBzdmcuYXBwZW5kKFwic3ZnOmdcIilcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJ5LWF4aXNcIilcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgKHRoaXMuYnVmZmVyICogMS4yICsgLSAxMCkgICsgXCIsMClcIilcbiAgICAgIC5jYWxsKHlBeGlzKTtcblxuICAgIHN2Zy5hcHBlbmQoXCJ0ZXh0XCIpXG4gICAgICAuYXR0cihcImNsYXNzXCIsIFwieS1sYWJlbFwiKVxuICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKVxuICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAodGhpcy5idWZmZXIgLyAzKSArIFwiLFwiICsgKHRoaXMuaGVpZ2h0IC8gMikgKyBcIiksIHJvdGF0ZSgtOTApXCIpXG4gICAgICAudGV4dCh0aGlzLmxlZ2VuZHMueSk7XG5cbiAgICBzdmcuYXBwZW5kKFwidGV4dFwiKVxuICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcIngtbGFiZWxcIilcbiAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIilcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgKHRoaXMud2lkdGggLyAyKSArIFwiLFwiICsgKHRoaXMuaGVpZ2h0IC0gdGhpcy5idWZmZXIgLyAzKSArIFwiKVwiKVxuICAgICAgLnRleHQodGhpcy5sZWdlbmRzLngpO1xuICAgIFxufTtcblxuXG5cbk11dHNOZWVkbGVQbG90LnByb3RvdHlwZS5kcmF3TmVlZGxlcyA9IGZ1bmN0aW9uKHN2ZywgbXV0YXRpb25EYXRhLCByZWdpb25EYXRhKSB7XG5cbiAgICB2YXIgeSA9IHRoaXMueTtcbiAgICB2YXIgeCA9IHRoaXMueDtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBnZXRZQXhpcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4geTtcbiAgICB9O1xuXG4gICAgZm9ybWF0Q29vcmQgPSBmdW5jdGlvbihjb29yZCkge1xuICAgICAgIGlmIChjb29yZC5pbmRleE9mKFwiLVwiKSA+IC0xKSB7XG4gICAgICAgICAgIGNvb3JkcyA9IGNvb3JkLnNwbGl0KFwiLVwiKTtcblxuICAgICAgICAgICAvLyBwbGFjZSBuZWVkZSBhdCBtaWRkbGUgb2YgYWZmZWN0ZWQgcmVnaW9uXG4gICAgICAgICAgIGNvb3JkID0gTWF0aC5mbG9vcigocGFyc2VJbnQoY29vcmRzWzBdKSArIHBhcnNlSW50KGNvb3Jkc1sxXSkpIC8gMik7XG5cbiAgICAgICAgICAgLy8gY2hlY2sgZm9yIHNwbGljZSBzaXRlczogXCI/LTlcIiBvciBcIjktP1wiXG4gICAgICAgICAgIGlmIChpc05hTihjb29yZCkpIHtcbiAgICAgICAgICAgICAgIGlmIChjb29yZHNbMF0gPT0gXCI/XCIpIHsgY29vcmQgPSBwYXJzZUludChjb29yZHNbMV0pIH1cbiAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvb3JkcyBbMV0gPT0gXCI/XCIpIHsgY29vcmQgPSBwYXJzZUludChjb29yZHNbMF0pIH1cbiAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29vcmQgPSBwYXJzZUludChjb29yZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvb3JkO1xuICAgIH07XG5cbiAgICB0aXAgPSB0aGlzLnRpcDtcblxuICAgIC8vIHN0YWNrIG5lZWRsZXMgYXQgc2FtZSBwb3NcbiAgICBuZWVkbGVQb2ludCA9IHt9O1xuICAgIGhpZ2hlc3QgPSAwO1xuXG4gICAgc3RhY2tOZWVkbGUgPSBmdW5jdGlvbihwb3MsdmFsdWUscG9pbnREaWN0KSB7XG4gICAgICBzdGlja0hlaWdodCA9IDA7XG4gICAgICBwb3MgPSBcInBcIitTdHJpbmcocG9zKTtcbiAgICAgIGlmIChwb3MgaW4gcG9pbnREaWN0KSB7XG4gICAgICAgICBzdGlja0hlaWdodCA9IHBvaW50RGljdFtwb3NdO1xuICAgICAgICAgbmV3SGVpZ2h0ID0gc3RpY2tIZWlnaHQgKyB2YWx1ZTtcbiAgICAgICAgIHBvaW50RGljdFtwb3NdID0gbmV3SGVpZ2h0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgIHBvaW50RGljdFtwb3NdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RpY2tIZWlnaHQ7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGZvcm1hdE11dGF0aW9uRW50cnkoZCkge1xuXG4gICAgICAgIGNvb3JkU3RyaW5nID0gZC5jb29yZDtcbiAgICAgICAgbnVtZXJpY0Nvb3JkID0gZm9ybWF0Q29vcmQoZC5jb29yZCk7XG4gICAgICAgIG51bWVyaWNWYWx1ZSA9IE51bWJlcihkLnZhbHVlKTtcbiAgICAgICAgc3RpY2tIZWlnaHQgPSBzdGFja05lZWRsZShudW1lcmljQ29vcmQsIG51bWVyaWNWYWx1ZSwgbmVlZGxlUG9pbnQpO1xuICAgICAgICBjYXRlZ29yeSA9IGQuY2F0ZWdvcnkgfHwgXCJvdGhlclwiO1xuXG4gICAgICAgIGlmIChzdGlja0hlaWdodCArIG51bWVyaWNWYWx1ZSA+IGhpZ2hlc3QpIHtcbiAgICAgICAgICAgIC8vIHNldCBZLUF4aXMgYWx3YXlzIHRvIGhpZ2hlc3QgYXZhaWxhYmxlXG4gICAgICAgICAgICBoaWdoZXN0ID0gc3RpY2tIZWlnaHQgKyBudW1lcmljVmFsdWU7XG4gICAgICAgICAgICBnZXRZQXhpcygpLmRvbWFpbihbMCwgaGlnaGVzdCArIDJdKTtcbiAgICAgICAgfVxuXG5cbiAgICAgICAgaWYgKG51bWVyaWNDb29yZCA+IDApIHtcblxuICAgICAgICAgICAgLy8gcmVjb3JkIGFuZCBjb3VudCBjYXRlZ29yaWVzXG4gICAgICAgICAgICBzZWxmLnRvdGFsQ2F0ZWdDb3VudHNbY2F0ZWdvcnldID0gKHNlbGYudG90YWxDYXRlZ0NvdW50c1tjYXRlZ29yeV0gfHwgMCkgKyBudW1lcmljVmFsdWU7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgY2F0ZWdvcnk6IGNhdGVnb3J5LFxuICAgICAgICAgICAgICAgIGNvb3JkU3RyaW5nOiBjb29yZFN0cmluZyxcbiAgICAgICAgICAgICAgICBjb29yZDogbnVtZXJpY0Nvb3JkLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgICAgICAgICAgc3RpY2tIZWlnaHQ6IHN0aWNrSGVpZ2h0LFxuICAgICAgICAgICAgICAgIGNvbG9yOiBzZWxmLmNvbG9yU2NhbGUoY2F0ZWdvcnkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiZGlzY2FyZGluZyBcIiArIGQuY29vcmQgKyBcIiBcIiArIGQuY2F0ZWdvcnkgKyBcIihcIisgbnVtZXJpY0Nvb3JkICtcIilcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgbXV0cyA9IFtdO1xuXG5cbiAgICBpZiAodHlwZW9mIG11dGF0aW9uRGF0YSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGQzLmpzb24obXV0YXRpb25EYXRhLCBmdW5jdGlvbihlcnJvciwgdW5mb3JtYXR0ZWRNdXRzKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG11dHMgPSBwcmVwYXJlTXV0cyh1bmZvcm1hdHRlZE11dHMpO1xuICAgICAgICAgICAgcGFpbnRNdXRzKG11dHMpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBtdXRzID0gcHJlcGFyZU11dHMobXV0YXRpb25EYXRhKTtcbiAgICAgICAgcGFpbnRNdXRzKG11dHMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXBhcmVNdXRzKHVuZm9ybWF0dGVkTXV0cykge1xuICAgICAgICBmb3IgKGtleSBpbiB1bmZvcm1hdHRlZE11dHMpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZCA9IGZvcm1hdE11dGF0aW9uRW50cnkodW5mb3JtYXR0ZWRNdXRzW2tleV0pO1xuICAgICAgICAgICAgaWYgKGZvcm1hdHRlZCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBtdXRzLnB1c2goZm9ybWF0dGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbXV0cztcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIHBhaW50TXV0cyhtdXRzKSB7XG5cbiAgICAgICAgbWluU2l6ZSA9IDQ7XG4gICAgICAgIG1heFNpemUgPSAxMDtcbiAgICAgICAgaGVhZFNpemVTY2FsZSA9IGQzLnNjYWxlLmxvZygpLnJhbmdlKFttaW5TaXplLG1heFNpemVdKS5kb21haW4oWzEsIGhpZ2hlc3QvMl0pO1xuICAgICAgICB2YXIgaGVhZFNpemUgPSBmdW5jdGlvbihuKSB7XG4gICAgICAgICAgICByZXR1cm4gZDMubWluKFtkMy5tYXgoW2hlYWRTaXplU2NhbGUobiksbWluU2l6ZV0pLCBtYXhTaXplXSk7XG4gICAgICAgIH07XG5cblxuICAgICAgICB2YXIgbmVlZGxlcyA9IGQzLnNlbGVjdChcIi5tdXRuZWVkbGVzXCIpLnNlbGVjdEFsbCgpXG4gICAgICAgICAgICAuZGF0YShtdXRzKS5lbnRlcigpXG4gICAgICAgICAgICAuYXBwZW5kKFwibGluZVwiKVxuICAgICAgICAgICAgLmF0dHIoXCJ5MVwiLCBmdW5jdGlvbihkYXRhKSB7IHJldHVybiB5KGRhdGEuc3RpY2tIZWlnaHQgKyBkYXRhLnZhbHVlKSArIGhlYWRTaXplKGRhdGEudmFsdWUpIDsgfSApXG4gICAgICAgICAgICAuYXR0cihcInkyXCIsIGZ1bmN0aW9uKGRhdGEpIHsgcmV0dXJuIHkoZGF0YS5zdGlja0hlaWdodCkgfSlcbiAgICAgICAgICAgIC5hdHRyKFwieDFcIiwgZnVuY3Rpb24oZGF0YSkgeyByZXR1cm4geChkYXRhLmNvb3JkKSB9KVxuICAgICAgICAgICAgLmF0dHIoXCJ4MlwiLCBmdW5jdGlvbihkYXRhKSB7IHJldHVybiB4KGRhdGEuY29vcmQpIH0pXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwibmVlZGxlLWxpbmVcIik7XG5cbiAgICAgICAgdmFyIG5lZWRsZUhlYWRzID0gZDMuc2VsZWN0KFwiLm11dG5lZWRsZXNcIikuc2VsZWN0QWxsKClcbiAgICAgICAgICAgIC5kYXRhKG11dHMpXG4gICAgICAgICAgICAuZW50ZXIoKS5hcHBlbmQoXCJjaXJjbGVcIilcbiAgICAgICAgICAgIC5hdHRyKFwiY3lcIiwgZnVuY3Rpb24oZGF0YSkgeyByZXR1cm4geShkYXRhLnN0aWNrSGVpZ2h0K2RhdGEudmFsdWUpIH0gKVxuICAgICAgICAgICAgLmF0dHIoXCJjeFwiLCBmdW5jdGlvbihkYXRhKSB7IHJldHVybiB4KGRhdGEuY29vcmQpIH0gKVxuICAgICAgICAgICAgLmF0dHIoXCJyXCIsIGZ1bmN0aW9uKGRhdGEpIHsgcmV0dXJuIGhlYWRTaXplKGRhdGEudmFsdWUpIH0pXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwibmVlZGxlLWhlYWRcIilcbiAgICAgICAgICAgIC5zdHlsZShcImZpbGxcIiwgZnVuY3Rpb24oZGF0YSkgeyByZXR1cm4gZGF0YS5jb2xvciB9KVxuICAgICAgICAgICAgLnN0eWxlKFwic3Ryb2tlXCIsIGZ1bmN0aW9uKGRhdGEpIHtyZXR1cm4gZDMucmdiKGRhdGEuY29sb3IpLmRhcmtlcigpfSlcbiAgICAgICAgICAgIC5vbignbW91c2VvdmVyJywgIGZ1bmN0aW9uKGQpeyBkMy5zZWxlY3QodGhpcykubW92ZVRvRnJvbnQoKTsgdGlwLnNob3coZCk7IH0pXG4gICAgICAgICAgICAub24oJ21vdXNlb3V0JywgdGlwLmhpZGUpO1xuXG4gICAgICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUubW92ZVRvRnJvbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBhZGp1c3QgeS1zY2FsZSBhY2NvcmRpbmcgdG8gaGlnaGVzdCB2YWx1ZSBhbiBkcmF3IHRoZSByZXN0XG4gICAgICAgIGlmIChyZWdpb25EYXRhICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc2VsZi5kcmF3UmVnaW9ucyhzdmcsIHJlZ2lvbkRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHNlbGYuZHJhd0xlZ2VuZChzdmcpO1xuICAgICAgICBzZWxmLmRyYXdBeGVzKHN2Zyk7XG4gICAgfVxuXG59O1xuXG5cblxudmFyIEV2ZW50cyA9IHJlcXVpcmUoJ2Jpb2pzLWV2ZW50cycpO1xuRXZlbnRzLm1peGluKE11dHNOZWVkbGVQbG90LnByb3RvdHlwZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTXV0c05lZWRsZVBsb3Q7XG5cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vc3JjL2pzL011dHNOZWVkbGVQbG90LmpzXCIpO1xuIl19 diff --git a/build/muts-needle-plot.min.css b/build/muts-needle-plot.min.css index 64d0aa8..39e0390 100644 --- a/build/muts-needle-plot.min.css +++ b/build/muts-needle-plot.min.css @@ -1 +1 @@ -body{font-family:Verdana,Geneva,sans-serif}.extent{opacity:.2}.selected{fill:#add8e6;stroke-width:4}.mutLegendBG{opacity:.7;stroke-width:2;stroke:lightgrey}.breakLabels{font-size:12px}.breakLabels.nomuts{font-weight:400;opacity:.3}.needle-line{stroke:#000;stroke-width:1}.noshow{opacity:.1}.regionsBG{fill:lightgrey}.regionGroup:hover>.regionName{fill:#000;font-weight:700;opacity:1}.regionGroup:hover>rect{stroke-width:4}.regionName{fill:#000;opacity:.5}.x-axis line,.x-axis path,.y-axis line,.y-axis path{fill:none}.x-label,.y-label{font-weight:700;font-size:12px}.domain{fill:none;stroke:#000;stroke-width:1}.d3-tip{line-height:1;font-size:11px;color:#000;font-weight:700;padding:10px;background:rgba(240,240,240,.8);border-width:1px;border-color:rgba(190,190,190,1);border-radius:6px}.d3-tip-selection{font-size:12px;text-align:center}.d3-tip:after{box-sizing:border-box;display:inline;font-size:10px;width:100%;line-height:1;color:rgba(0,0,0,.6);content:"\25BC";position:absolute;text-align:center}.d3-tip.n:after{margin:-1px 0 0;top:100%;left:0} \ No newline at end of file +body{font-family:Verdana,Geneva,sans-serif}.extent{opacity:.2}.selected{fill:#add8e6;stroke-width:4}.mutLegendBG{opacity:.7;stroke-width:2;stroke:lightgrey}.breakLabels{font-size:12px}.breakLabels.nomuts{font-weight:400;opacity:.3}.needle-line{stroke:#000;stroke-width:1}.noshow{opacity:.1}.regionsBG{fill:lightgrey}.regionGroup:hover>text{fill:#000;font-weight:700;opacity:1}.regionGroup:hover>rect{stroke-width:4}.regionName{fill:#000;opacity:.5}.repeatedName.noshow{fill:#000;opacity:0}.x-axis line,.x-axis path,.y-axis line,.y-axis path{fill:none}.x-label,.y-label{font-weight:700;font-size:12px}.domain{fill:none;stroke:#000;stroke-width:1}.d3-tip{line-height:1;font-size:11px;color:#000;font-weight:700;padding:10px;background:rgba(240,240,240,.8);border-width:1px;border-color:rgba(190,190,190,1);border-radius:6px}.d3-tip-selection{font-size:12px;text-align:center}.d3-tip:after{box-sizing:border-box;display:inline;font-size:10px;width:100%;line-height:1;color:rgba(0,0,0,.6);content:"\25BC";position:absolute;text-align:center}.d3-tip.n:after{margin:-1px 0 0;top:100%;left:0} \ No newline at end of file diff --git a/build/muts-needle-plot.min.gz.js b/build/muts-needle-plot.min.gz.js index 12c4d0f..cd5e113 100644 Binary files a/build/muts-needle-plot.min.gz.js and b/build/muts-needle-plot.min.gz.js differ diff --git a/build/muts-needle-plot.min.js b/build/muts-needle-plot.min.js index c547e29..946f022 100644 --- a/build/muts-needle-plot.min.js +++ b/build/muts-needle-plot.min.js @@ -1 +1 @@ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),e.mutsNeedlePlot=t()}}(function(){var t;return function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[s]={exports:{}};t[s][0].call(u.exports,function(e){var n=t[s][1][e];return o(n?n:e)},u,u.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)if(e.call(n,t[r],r,t)===s)return}else for(var i in t)if(this.has(t,i)&&e.call(n,t[i],i,t)===s)return},once:function(t){var e,n=!1;return function(){return n?e:(n=!0,e=t.apply(this,arguments),t=null,e)}}}}var o,i=this,s={},a=Array.prototype.forEach,l=Object.prototype.hasOwnProperty,c=Array.prototype.slice,u=0,d=e();o={on:function(t,e,n){if(!h(this,"on",t,[e,n])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);return r.push({callback:e,context:n,ctx:n||this}),this},once:function(t,e,n){if(!h(this,"once",t,[e,n])||!e)return this;var r=this,o=d.once(function(){r.off(t,o),e.apply(this,arguments)});return o._callback=e,this.on(t,o,n)},off:function(t,e,n){var r,o,i,s,a,l,c,u;if(!this._events||!h(this,"off",t,[e,n]))return this;if(!t&&!e&&!n)return this._events={},this;for(s=t?[t]:d.keys(this._events),a=0,l=s.length;l>a;a++)if(t=s[a],i=this._events[t]){if(this._events[t]=r=[],e||n)for(c=0,u=i.length;u>c;c++)o=i[c],(e&&e!==o.callback&&e!==o.callback._callback||n&&n!==o.context)&&r.push(o);r.length||delete this._events[t]}return this},trigger:function(t){if(!this._events)return this;var e=c.call(arguments,1);if(!h(this,"trigger",t,e))return this;var n=this._events[t],r=this._events.all;return n&&g(n,e),r&&g(r,arguments),this},stopListening:function(t,e,n){var r=this._listeners;if(!r)return this;var o=!e&&!n;"object"==typeof e&&(n=this),t&&((r={})[t._listenerId]=t);for(var i in r)r[i].off(e,n,this),o&&delete this._listeners[i];return this}};var f=/\s+/,h=function(t,e,n,r){if(!n)return!0;if("object"==typeof n){for(var o in n)t[e].apply(t,[o,n[o]].concat(r));return!1}if(f.test(n)){for(var i=n.split(f),s=0,a=i.length;a>s;s++)t[e].apply(t,[i[s]].concat(r));return!1}return!0},g=function(t,e){var n,r=-1,o=t.length,i=e[0],s=e[1],a=e[2];switch(e.length){case 0:for(;++r=a?a/8:s/8,this.buffer=c;var u=t("d3-tip");u(d3),this.tip=d3.tip().attr("class","d3-tip d3-tip-needle").offset([-10,0]).html(function(t){return""+t.value+" "+t.category+" at coord. "+t.coordString+""}),this.selectionTip=d3.tip().attr("class","d3-tip d3-tip-selection").offset([100,0]).html(function(t){return" Selected coordinates
"+Math.round(t.left)+" - "+Math.round(t.right)+"
"}).direction("n");var d=d3.select(i).append("svg").attr("width",s).attr("height",a).attr("class",this.svgClasses);d.call(this.tip),d.call(this.selectionTip);var f=d3.scale.linear().domain([this.minCoord,this.maxCoord]).range([1.5*c,s-c]).nice();this.x=f;var h=d3.scale.linear().domain([1,20]).range([a-1.5*c,c]).nice();this.y=h,o.selector=d3.svg.brush().x(f).on("brush",n).on("brushend",r);var g=o.selector;this.svgClasses+=" brush";var p=d.attr("class",this.svgClasses).call(g).selectAll(".extent").attr("height",a);this.drawNeedles(d,mutationData,regionData),o.on("needleSelectionChange",function(t){o.categCounts=t.categCounts,o.selectedNeedles=t.selected,d.call(verticalLegend)}),o.on("needleSelectionChangeEnd",function(t){o.categCounts=t.categCounts,o.selectedNeedles=t.selected,d.call(verticalLegend)}),o.on("needleSelectionChange",function(t){selection=t.coords,selection[1]-selection[0]>0?o.selectionTip.show({left:selection[0],right:selection[1]},p.node()):o.selectionTip.hide()})}n.prototype.drawLegend=function(t){self=this,mutCategories=[],categoryColors=[],allcategs=Object.keys(self.totalCategCounts),orderedDeclaration=self.colorScale.domain();for(idx in orderedDeclaration)r=orderedDeclaration[idx],allcategs.indexOf(r)>-1&&(mutCategories.push(r),categoryColors.push(self.colorScale(r)));mutsScale=self.colorScale.domain(mutCategories).range(categoryColors);var e=self.x.domain();xplacement=.75*(e[1]-e[0])+(e[1]-e[0]);var n=0;for(var r in self.totalCategCounts)n+=self.totalCategCounts[r];legendLabel=function(t){var e=self.categCounts[t]||0==self.selectedNeedles.length&&self.totalCategCounts[t]||0;return t+(e>0?": "+Math.round(e/n*100)+"%":"")},legendClass=function(t){var e=self.categCounts[t]||0==self.selectedNeedles.length&&self.totalCategCounts[t]||0;return e>0?"":"nomuts"},self.noshow=[];var o=d3.selectAll(".needle-head");showNoShow=function(t){_.contains(self.noshow,t)?self.noshow=_.filter(self.noshow,function(e){return e!=t}):self.noshow.push(t),o.classed("noshow",function(t){return _.contains(self.noshow,t.category)});var e=d3.selectAll("g.legendCells");e.classed("noshow",function(t){return _.contains(self.noshow,t.stop[0])})},verticalLegend=d3.svg.legend().labelFormat(legendLabel).labelClass(legendClass).onLegendClick(showNoShow).cellPadding(4).orientation("vertical").units(n+" Mutations").cellWidth(20).cellHeight(12).inputScale(mutsScale).cellStepping(4).place({x:xplacement,y:50}),t.call(verticalLegend)},n.prototype.drawRegions=function(t,e){function n(e){function n(t){var e=t.radius+3,n=t.x-e,r=t.x+e,o=t.y-e,i=t.y+e;return function(s,a,l,c,u){if(s.point&&s.point!==t){var d=t.x-s.point.x,f=d;e=t.radius+s.point.radius,Math.abs(d)s.point.x&&0>f?-f:f,t.x+=f,s.point.x-=f)}return a>r||n>c||l>i||o>u}}var r=d3.select(".mutneedles").selectAll().data(["dummy"]).enter().insert("g",":first-child").attr("class","regionsBG").append("rect").attr("x",a(i)).attr("y",s(0)+c).attr("width",a(o)-a(i)).attr("height",10),l=r=d3.select(".mutneedles").selectAll().data(e).enter().append("g").attr("class","regionGroup");l.append("rect").attr("x",function(t){return a(t.start)}).attr("y",s(0)+u).attr("ry","3").attr("rx","3").attr("width",function(t){return a(t.end)-a(t.start)}).attr("height",16).style("fill",function(t){return t.color}).style("stroke",function(t){return d3.rgb(t.color).darker()}),l.attr("pointer-events","all").attr("cursor","pointer").on("click",function(t){self.selector.extent([t.start,t.end]),self.selector(d3.select(".brush").transition()),self.selector.event(d3.select(".brush").transition().delay(300))});var f=[];l.append("text").attr("class","regionName").attr("text-anchor","middle").attr("x",function(t){return t.x=a(t.start)+(a(t.end)-a(t.start))/2,t.x}).attr("y",function(t){return t.y=s(0)+d,t.y}).attr("dy","0.35em").style("font-size","12px").style("text-decoration","bold").text(function(t){return t.name});var h=d3.selectAll(".regionName");h.each(function(t){var e=this.getBBox().width/2;f.push({x:t.x,y:t.y,label:t.name,weight:t.name.length,radius:e})});var g=d3.layout.force().chargeDistance(5).nodes(f).charge(-10).gravity(0),p=a(i),m=a(o),y=function(t){return d3.min([d3.max([p,t]),m])};g.on("tick",function(){for(var e=d3.geom.quadtree(f),r=0,o=f.length;++rr;r++)if(t.name==f[r].label)return f[r].x=y(f[r].x),f[r].x})}),g.start()}function r(t){regionList=[];for(key in t)regionList.push({name:key,start:getRegionStart(t[key]),end:getRegionEnd(t[key]),color:getColor(key)});return regionList}var o=this.maxCoord,i=this.minCoord,s=(this.buffer,this.colorMap,this.y),a=this.x,l=!0;getRegionStart=function(t){return parseInt(t.split("-")[0])},getRegionEnd=function(t){return parseInt(t.split("-")[1])},getColor=this.colorScale;var c=0,u=c-3,d=c+20;1!=l&&(d=c+5),"string"==typeof e?d3.json(e,function(t,e){return t?console.debug(t):(regionList=r(e),void n(regionList))}):(regionList=r(e),n(regionList))},n.prototype.drawAxes=function(t){var e=this.y,n=this.x;xAxis=d3.svg.axis().scale(n).orient("bottom"),t.append("svg:g").attr("class","x-axis").attr("transform","translate(0,"+(this.height-this.buffer)+")").call(xAxis),yAxis=d3.svg.axis().scale(e).orient("left"),t.append("svg:g").attr("class","y-axis").attr("transform","translate("+(1.2*this.buffer+-10)+",0)").call(yAxis),t.append("text").attr("class","y-label").attr("text-anchor","middle").attr("transform","translate("+this.buffer/3+","+this.height/2+"), rotate(-90)").text(this.legends.y),t.append("text").attr("class","x-label").attr("text-anchor","middle").attr("transform","translate("+this.width/2+","+(this.height-this.buffer/3)+")").text(this.legends.x)},n.prototype.drawNeedles=function(t,e,n){function r(t){return coordString=t.coord,numericCoord=formatCoord(t.coord),numericValue=Number(t.value),stickHeight=stackNeedle(numericCoord,numericValue,needlePoint),category=t.category||"other",stickHeight+numericValue>highest&&(highest=stickHeight+numericValue,getYAxis().domain([0,highest+2])),numericCoord>0?(l.totalCategCounts[category]=(l.totalCategCounts[category]||0)+numericValue,{category:category,coordString:coordString,coord:numericCoord,value:numericValue,stickHeight:stickHeight,color:l.colorScale(category)}):void console.debug("discarding "+t.coord+" "+t.category+"("+numericCoord+")")}function o(t){for(key in t)formatted=r(t[key]),void 0!=formatted&&c.push(formatted);return c}function i(e){minSize=4,maxSize=10,headSizeScale=d3.scale.log().range([minSize,maxSize]).domain([1,highest/2]);{var r=function(t){return d3.min([d3.max([headSizeScale(t),minSize]),maxSize])};d3.select(".mutneedles").selectAll().data(e).enter().append("line").attr("y1",function(t){return s(t.stickHeight+t.value)+r(t.value)}).attr("y2",function(t){return s(t.stickHeight)}).attr("x1",function(t){return a(t.coord)}).attr("x2",function(t){return a(t.coord)}).attr("class","needle-line"),d3.select(".mutneedles").selectAll().data(e).enter().append("circle").attr("cy",function(t){return s(t.stickHeight+t.value)}).attr("cx",function(t){return a(t.coord)}).attr("r",function(t){return r(t.value)}).attr("class","needle-head").style("fill",function(t){return t.color}).style("stroke",function(t){return d3.rgb(t.color).darker()}).on("mouseover",function(t){d3.select(this).moveToFront(),tip.show(t)}).on("mouseout",tip.hide)}d3.selection.prototype.moveToFront=function(){return this.each(function(){this.parentNode.appendChild(this)})},void 0!=n&&l.drawRegions(t,n),l.drawLegend(t),l.drawAxes(t)}var s=this.y,a=this.x,l=this;getYAxis=function(){return s},formatCoord=function(t){return t.indexOf("-")>-1?(coords=t.split("-"),t=Math.floor((parseInt(coords[0])+parseInt(coords[1]))/2),isNaN(t)&&("?"==coords[0]?t=parseInt(coords[1]):"?"==coords[1]&&(t=parseInt(coords[0])))):t=parseInt(t),t},tip=this.tip,needlePoint={},highest=0,stackNeedle=function(t,e,n){return stickHeight=0,t="p"+String(t),t in n?(stickHeight=n[t],newHeight=stickHeight+e,n[t]=newHeight):n[t]=e,stickHeight};var c=[];"string"==typeof e?d3.json(e,function(t,e){if(t)throw new Error(t);c=o(e),i(c)}):(c=o(e),i(c))};var r=t("biojs-events");r.mixin(n.prototype),e.exports=n},{"biojs-events":1,"d3-tip":4}],"muts-needle-plot":[function(t,e){e.exports=t("./src/js/MutsNeedlePlot.js")},{"./src/js/MutsNeedlePlot.js":5}]},{},["muts-needle-plot"])("muts-needle-plot")}); \ No newline at end of file +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.mutsNeedlePlot=e()}}(function(){var e;return function t(e,n,r){function o(s,a){if(!n[s]){if(!e[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[s]={exports:{}};e[s][0].call(u.exports,function(t){var n=e[s][1][t];return o(n?n:t)},u,u.exports,t,e,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)if(t.call(n,e[r],r,e)===s)return}else for(var i in e)if(this.has(e,i)&&t.call(n,e[i],i,e)===s)return},once:function(e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}}}}var o,i=this,s={},a=Array.prototype.forEach,l=Object.prototype.hasOwnProperty,c=Array.prototype.slice,u=0,d=t();o={on:function(e,t,n){if(!h(this,"on",e,[t,n])||!t)return this;this._events||(this._events={});var r=this._events[e]||(this._events[e]=[]);return r.push({callback:t,context:n,ctx:n||this}),this},once:function(e,t,n){if(!h(this,"once",e,[t,n])||!t)return this;var r=this,o=d.once(function(){r.off(e,o),t.apply(this,arguments)});return o._callback=t,this.on(e,o,n)},off:function(e,t,n){var r,o,i,s,a,l,c,u;if(!this._events||!h(this,"off",e,[t,n]))return this;if(!e&&!t&&!n)return this._events={},this;for(s=e?[e]:d.keys(this._events),a=0,l=s.length;l>a;a++)if(e=s[a],i=this._events[e]){if(this._events[e]=r=[],t||n)for(c=0,u=i.length;u>c;c++)o=i[c],(t&&t!==o.callback&&t!==o.callback._callback||n&&n!==o.context)&&r.push(o);r.length||delete this._events[e]}return this},trigger:function(e){if(!this._events)return this;var t=c.call(arguments,1);if(!h(this,"trigger",e,t))return this;var n=this._events[e],r=this._events.all;return n&&g(n,t),r&&g(r,arguments),this},stopListening:function(e,t,n){var r=this._listeners;if(!r)return this;var o=!t&&!n;"object"==typeof t&&(n=this),e&&((r={})[e._listenerId]=e);for(var i in r)r[i].off(t,n,this),o&&delete this._listeners[i];return this}};var f=/\s+/,h=function(e,t,n,r){if(!n)return!0;if("object"==typeof n){for(var o in n)e[t].apply(e,[o,n[o]].concat(r));return!1}if(f.test(n)){for(var i=n.split(f),s=0,a=i.length;a>s;s++)e[t].apply(e,[i[s]].concat(r));return!1}return!0},g=function(e,t){var n,r=-1,o=e.length,i=t[0],s=t[1],a=t[2];switch(t.length){case 0:for(;++r=a?a/8:s/8,this.buffer=c;var u=e("d3-tip");u(d3),this.tip=d3.tip().attr("class","d3-tip d3-tip-needle").offset([-10,0]).html(function(e){return""+e.value+" "+e.category+" at coord. "+e.coordString+""}),this.selectionTip=d3.tip().attr("class","d3-tip d3-tip-selection").offset([100,0]).html(function(e){return" Selected coordinates
"+Math.round(e.left)+" - "+Math.round(e.right)+"
"}).direction("n");var d=d3.select(i).append("svg").attr("width",s).attr("height",a).attr("class",this.svgClasses);d.call(this.tip),d.call(this.selectionTip);var f=d3.scale.linear().domain([this.minCoord,this.maxCoord]).range([1.5*c,s-c]).nice();this.x=f;var h=d3.scale.linear().domain([1,20]).range([a-1.5*c,c]).nice();this.y=h,o.selector=d3.svg.brush().x(f).on("brush",n).on("brushend",r);var g=o.selector;this.svgClasses+=" brush";var p=d.attr("class",this.svgClasses).call(g).selectAll(".extent").attr("height",a);p.on("mouseenter",function(){var e=g.extent();o.selectionTip.show({left:e[0],right:e[1]},p.node())}).on("mouseout",function(){d3.select(".d3-tip-selection").transition().delay(3e3).duration(1e3).style("opacity",0).style("pointer-events","none")}),this.drawNeedles(d,mutationData,regionData),o.on("needleSelectionChange",function(e){o.categCounts=e.categCounts,o.selectedNeedles=e.selected,d.call(verticalLegend)}),o.on("needleSelectionChangeEnd",function(e){o.categCounts=e.categCounts,o.selectedNeedles=e.selected,d.call(verticalLegend)}),o.on("needleSelectionChange",function(e){selection=e.coords,selection[1]-selection[0]>0?(o.selectionTip.show({left:selection[0],right:selection[1]},p.node()),d3.select(".d3-tip-selection").transition().delay(3e3).duration(1e3).style("opacity",0).style("pointer-events","none")):o.selectionTip.hide()})}n.prototype.drawLegend=function(e){self=this,mutCategories=[],categoryColors=[],allcategs=Object.keys(self.totalCategCounts),orderedDeclaration=self.colorScale.domain();for(idx in orderedDeclaration)r=orderedDeclaration[idx],allcategs.indexOf(r)>-1&&(mutCategories.push(r),categoryColors.push(self.colorScale(r)));mutsScale=self.colorScale.domain(mutCategories).range(categoryColors);var t=self.x.domain();xplacement=.75*(self.x(t[1])-self.x(t[0]))+self.x(t[0]);var n=0;for(var r in self.totalCategCounts)n+=self.totalCategCounts[r];legendLabel=function(e){var t=self.categCounts[e]||0==self.selectedNeedles.length&&self.totalCategCounts[e]||0;return e+(t>0?": "+Math.round(t/n*100)+"%":"")},legendClass=function(e){var t=self.categCounts[e]||0==self.selectedNeedles.length&&self.totalCategCounts[e]||0;return t>0?"":"nomuts"},self.noshow=[];var o=d3.selectAll(".needle-head");showNoShow=function(e){_.contains(self.noshow,e)?self.noshow=_.filter(self.noshow,function(t){return t!=e}):self.noshow.push(e),o.classed("noshow",function(e){return _.contains(self.noshow,e.category)});var t=d3.selectAll("g.legendCells");t.classed("noshow",function(e){return _.contains(self.noshow,e.stop[0])})},verticalLegend=d3.svg.legend().labelFormat(legendLabel).labelClass(legendClass).onLegendClick(showNoShow).cellPadding(4).orientation("vertical").units(n+" Mutations").cellWidth(20).cellHeight(12).inputScale(mutsScale).cellStepping(4).place({x:xplacement,y:50}),e.call(verticalLegend)},n.prototype.drawRegions=function(e,t){function n(t){function n(e){var t=e.radius+3,n=e.x-t,r=e.x+t,o=e.y-t,i=e.y+t;return function(s,a,l,c,u){if(s.point&&s.point!==e){var d=e.x-s.point.x,f=d;t=e.radius+s.point.radius,Math.abs(d)s.point.x&&0>f?-f:f,e.x+=f,s.point.x-=f)}return a>r||n>c||l>i||o>u}}var r=d3.select(".mutneedles").selectAll().data(["dummy"]).enter().insert("g",":first-child").attr("class","regionsBG").append("rect").attr("x",a(i)).attr("y",s(0)+c).attr("width",a(o)-a(i)).attr("height",10),l=r=d3.select(".mutneedles").selectAll().data(t).enter().append("g").attr("class","regionGroup");l.append("rect").attr("x",function(e){return a(e.start)}).attr("y",s(0)+u).attr("ry","3").attr("rx","3").attr("width",function(e){return a(e.end)-a(e.start)}).attr("height",16).style("fill",function(e){return e.color}).style("stroke",function(e){return d3.rgb(e.color).darker()}),l.attr("pointer-events","all").attr("cursor","pointer").on("click",function(e){self.selector.extent([e.start,e.end]),self.selector(d3.select(".brush").transition()),self.selector.event(d3.select(".brush").transition().delay(300))});var f=[],h={},g=function(e){var t="regionName",n="RR_"+e.name;return _.has(h,e.name)&&(t="repeatedName noshow "+n),h[e.name]=n,t};l.append("text").attr("class",g).attr("text-anchor","middle").attr("x",function(e){return e.x=a(e.start)+(a(e.end)-a(e.start))/2,e.x}).attr("y",function(e){return e.y=s(0)+d,e.y}).attr("dy","0.35em").style("font-size","12px").style("text-decoration","bold").text(function(e){return e.name});var p=d3.selectAll(".regionName");p.each(function(e){var t=this.getBBox().width/2;f.push({x:e.x,y:e.y,label:e.name,weight:e.name.length,radius:t})});var y=d3.layout.force().chargeDistance(5).nodes(f).charge(-10).gravity(0),m=(a(i),a(o),function(t){var n=h[t];e.selectAll("text."+n).attr("x",newx)});y.on("tick",function(){for(var t=d3.geom.quadtree(f),r=0,o=f.length;++rhighest&&(highest=stickHeight+numericValue,getYAxis().domain([0,highest+2])),numericCoord>0?(l.totalCategCounts[category]=(l.totalCategCounts[category]||0)+numericValue,{category:category,coordString:coordString,coord:numericCoord,value:numericValue,stickHeight:stickHeight,color:l.colorScale(category)}):void console.debug("discarding "+e.coord+" "+e.category+"("+numericCoord+")")}function o(e){for(key in e)formatted=r(e[key]),void 0!=formatted&&c.push(formatted);return c}function i(t){minSize=4,maxSize=10,headSizeScale=d3.scale.log().range([minSize,maxSize]).domain([1,highest/2]);{var r=function(e){return d3.min([d3.max([headSizeScale(e),minSize]),maxSize])};d3.select(".mutneedles").selectAll().data(t).enter().append("line").attr("y1",function(e){return s(e.stickHeight+e.value)+r(e.value)}).attr("y2",function(e){return s(e.stickHeight)}).attr("x1",function(e){return a(e.coord)}).attr("x2",function(e){return a(e.coord)}).attr("class","needle-line"),d3.select(".mutneedles").selectAll().data(t).enter().append("circle").attr("cy",function(e){return s(e.stickHeight+e.value)}).attr("cx",function(e){return a(e.coord)}).attr("r",function(e){return r(e.value)}).attr("class","needle-head").style("fill",function(e){return e.color}).style("stroke",function(e){return d3.rgb(e.color).darker()}).on("mouseover",function(e){d3.select(this).moveToFront(),tip.show(e)}).on("mouseout",tip.hide)}d3.selection.prototype.moveToFront=function(){return this.each(function(){this.parentNode.appendChild(this)})},void 0!=n&&l.drawRegions(e,n),l.drawLegend(e),l.drawAxes(e)}var s=this.y,a=this.x,l=this;getYAxis=function(){return s},formatCoord=function(e){return e.indexOf("-")>-1?(coords=e.split("-"),e=Math.floor((parseInt(coords[0])+parseInt(coords[1]))/2),isNaN(e)&&("?"==coords[0]?e=parseInt(coords[1]):"?"==coords[1]&&(e=parseInt(coords[0])))):e=parseInt(e),e},tip=this.tip,needlePoint={},highest=0,stackNeedle=function(e,t,n){return stickHeight=0,e="p"+String(e),e in n?(stickHeight=n[e],newHeight=stickHeight+t,n[e]=newHeight):n[e]=t,stickHeight};var c=[];"string"==typeof t?d3.json(t,function(e,t){if(e)throw new Error(e);c=o(t),i(c)}):(c=o(t),i(c))};var r=e("biojs-events");r.mixin(n.prototype),t.exports=n},{"biojs-events":1,"d3-tip":4}],"muts-needle-plot":[function(e,t){t.exports=e("./src/js/MutsNeedlePlot.js")},{"./src/js/MutsNeedlePlot.js":5}]},{},["muts-needle-plot"])("muts-needle-plot")}); \ No newline at end of file diff --git a/how-to-publish.txt b/how-to-publish.txt index a3bda03..8c6ad97 100644 --- a/how-to-publish.txt +++ b/how-to-publish.txt @@ -6,7 +6,7 @@ Make sure you have npm installed. git pull -2. Check and increment the version in the `package.json` file. E.g. version "0.6.0" +2. Check and increment the version in the `package.json` file. E.g. version "0.7.0" 3. Check if examples are working fine @@ -23,8 +23,8 @@ Make sure you have npm installed. 5. Commit all changes, push to repository - git commit -a -m "Release of version 0.6.0" - git tag -a v0.6.0 -m 'version 0.6.0' + git commit -a -m "Release of version 0.7.0" + git tag -a v0.7.0 -m 'version 0.7.0' git push git push origin --tags @@ -35,6 +35,9 @@ Make sure you have npm installed. A needle-plot (aka stem-plot or lollipop-plot) plots each data point as a big dot and adds a vertical line that makes it appear like a needle. Changelog: - v0.6.0 - * Selection (new) - * Legend (new) + v0.7.0 + * Regions format changed (new) + * Repeated regions labels stacked (one visible) + * Legend placement fix + * Coordinates tip disappears in time. + diff --git a/package.json b/package.json index 02079a0..a40b940 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "muts-needle-plot", "description": "Draws a Needle-Plot for mutation data (stacked).", - "version": "0.6.1", + "version": "0.7.0", "homepage": "https://github.com/bbglab/muts-needle-plot", "author": { "name": "Michael P Schroeder", diff --git a/snippets/EXAMPLE.js b/snippets/EXAMPLE.js index 1f63a89..c1a1346 100644 --- a/snippets/EXAMPLE.js +++ b/snippets/EXAMPLE.js @@ -18,7 +18,7 @@ colorMap = { legends = { x: "Corresponding protein positions to transcript X", - y: "Number of recorded mutation in transcript X of Gene Y and CT Z" + y: "Number of recorded mutation" }; //Crate config Object @@ -27,9 +27,7 @@ plotConfig = { minCoord : 0, targetElement : yourDiv, mutationData: "./data/muts.json", - //mutationData: [{"category": "test", "coord": "99", "value": 77}], regionData: "./data/regions.json", - //regionData: {"beautiful-region": "99-199"}, colorMap: colorMap, legends: legends }; diff --git a/snippets/EXAMPLE_AGGREGATION.js b/snippets/EXAMPLE_AGGREGATION.js index 20cbba5..6f88823 100644 --- a/snippets/EXAMPLE_AGGREGATION.js +++ b/snippets/EXAMPLE_AGGREGATION.js @@ -40,7 +40,7 @@ mapper = function(data) { legends = { x: "Corresponding protein positions to transcript X", - y: "Number of recorded mutation in transcript X of Gene Y and CT Z" + y: "Number of recorded mutation" }; // aggregation by sum of value @@ -65,7 +65,7 @@ d3.json("./data/muts.json", function(error, data){ //Crate config Object plotConfig = { - maxCoord : 350, + maxCoord : 250, minCoord : 0, targetElement : yourDiv, mutationData: agg_muts, diff --git a/snippets/KRAS.js b/snippets/KRAS.js index 8520b12..ce859a8 100644 --- a/snippets/KRAS.js +++ b/snippets/KRAS.js @@ -6,7 +6,12 @@ var mutneedles = require("muts-needle-plot"); var target = yourDiv; // autmically generated in snippets examples var muts = "./data/ENST00000557334.json"; -var regions = {"dummy": "155-209"}; +var regions = [ + {"name": "dummy", "coord": "155-209"}, + {"name": "repeat", "coord": "15-20"}, + {"name": "repeat", "coord": "5-10"}, + {"name": "repeat", "coord": "25-35"} +]; var legends = {x: "KRAS-003 (ENST00000557334) AA pos", y: "Mutation Count"} var colorMap = { // mutation categories diff --git a/snippets/LOGO.js b/snippets/LOGO.js index 530cf38..589486a 100644 --- a/snippets/LOGO.js +++ b/snippets/LOGO.js @@ -20,10 +20,10 @@ var muts = [ { coord: "172", category : "mild", value: 50 } ]; -var regions = { - "cluster 1": "145-155", - "cluster 2": "170-172" -}; +var regions = [ + {"name": "cluster-1", "coord": "145-155"}, + {"name": "cluster-2", "coord": "170-172"} +]; var legends = {x: "Mutations Needle Plot", y: "# Mutations"} diff --git a/snippets/data/regions.json b/snippets/data/regions.json index 43d74e3..3b6b53c 100644 --- a/snippets/data/regions.json +++ b/snippets/data/regions.json @@ -1,8 +1,34 @@ -{ - "region1": "50-58", - "region2": "120-180", - "C1": "187-190", - "X-binding": "2-40", - "X99" : "4.5-5.5", - "X88" : "191-192" -} +[ + { + "name": "region1", + "coord": "50-58" + }, + { + "name": "region2", + "coord": "120-180" + }, + { + "name": "C1", "coord": "187-190" + }, + { + "name": "C2", "coord": "194-199" + }, + { + "name": "X-binding", "coord": "2-40" + }, + { + "name": "X99-REPEAT", "coord": "60-61" + }, + { + "name": "X99-REPEAT", "coord": "4-5" + }, + { + "name": "X99-REPEAT", "coord": "73-74" + }, + { + "name": "X99-REPEAT", "coord": "78-79" + }, + { + "name": "X99-REPEAT", "coord": "191-192" + } +] diff --git a/src/css/muts-needle-plot.css b/src/css/muts-needle-plot.css index 67c4a1d..fd12679 100644 --- a/src/css/muts-needle-plot.css +++ b/src/css/muts-needle-plot.css @@ -42,7 +42,7 @@ body { fill: lightgrey; } -.regionGroup:hover > .regionName { +.regionGroup:hover > text { fill: black; font-weight: bold; opacity: 1; @@ -57,6 +57,11 @@ body { opacity: 0.5; } +.repeatedName.noshow { + fill: black; + opacity: 0; +} + .x-axis path, .x-axis line, .y-axis path, .y-axis line { fill: none; } diff --git a/src/js/MutsNeedlePlot.js b/src/js/MutsNeedlePlot.js index 872f629..6b03ccb 100644 --- a/src/js/MutsNeedlePlot.js +++ b/src/js/MutsNeedlePlot.js @@ -118,6 +118,18 @@ function MutsNeedlePlot (config) { .call(selector) .selectAll('.extent') .attr('height', height); + selectionRect.on("mouseenter", function() { + var selection = selector.extent(); + self.selectionTip.show({left: selection[0], right: selection[1]}, selectionRect.node()); + }) + .on("mouseout", function(){ + d3.select(".d3-tip-selection") + .transition() + .delay(3000) + .duration(1000) + .style("opacity",0) + .style('pointer-events', 'none'); + }); function brushmove() { @@ -196,6 +208,12 @@ function MutsNeedlePlot (config) { selection = edata.coords; if (selection[1] - selection[0] > 0) { self.selectionTip.show({left: selection[0], right: selection[1]}, selectionRect.node()); + d3.select(".d3-tip-selection") + .transition() + .delay(3000) + .duration(1000) + .style("opacity",0) + .style('pointer-events', 'none'); } else { self.selectionTip.hide(); } @@ -228,7 +246,8 @@ MutsNeedlePlot.prototype.drawLegend = function(svg) { var domain = self.x.domain(); - xplacement = (domain[1] - domain[0]) * 0.75 + (domain[1] - domain[0]); + xplacement = (self.x(domain[1]) - self.x(domain[0])) * 0.75 + self.x(domain[0]); + var sum = 0; for (var c in self.totalCategCounts) { @@ -362,8 +381,18 @@ MutsNeedlePlot.prototype.drawRegions = function(svg, regionData) { // Place and label location var labels = []; + var repeatedRegion = {}; + var getRegionClass = function(region) { + var c = "regionName"; + var repeatedClass = "RR_"+region.name; + if(_.has(repeatedRegion, region.name)) { + c = "repeatedName noshow " + repeatedClass; + } + repeatedRegion[region.name] = repeatedClass; + return c; + }; regions.append("text") - .attr("class", "regionName") + .attr("class", getRegionClass) .attr("text-anchor", "middle") .attr("x", function (r) { r.x = x(r.start) + (x(r.end) - x(r.start)) / 2; @@ -424,6 +453,11 @@ MutsNeedlePlot.prototype.drawRegions = function(svg, regionData) { || y2 < ny1; }; } + var moveRepeatedLabels = function(label, x) { + var name = repeatedRegion[label]; + svg.selectAll("text."+name) + .attr("x", newx); + }; force.on("tick", function(e) { var q = d3.geom.quadtree(labels), i = 0, @@ -432,14 +466,12 @@ MutsNeedlePlot.prototype.drawRegions = function(svg, regionData) { q.visit(collide(labels[i])); } // Update the position of the text element + var i = 0; svg.selectAll("text.regionName") .attr("x", function(d) { - for (i = 0; i < n; i++) { - if (d.name == labels[i].label) { - labels[i].x = withinBounds(labels[i].x); - return labels[i].x; - } - } + newx = labels[i++].x; + moveRepeatedLabels(d.name, newx); + return newx; } ); }); @@ -447,17 +479,19 @@ MutsNeedlePlot.prototype.drawRegions = function(svg, regionData) { } function formatRegions(regions) { - regionList = []; - for (key in regions) { + for (key in Object.keys(regions)) { - regionList.push({ + regions[key].start = getRegionStart(regions[key].coord); + regions[key].end = getRegionEnd(regions[key].coord); + regions[key].color = getColor(regions[key].name); + /*regionList.push({ 'name': key, 'start': getRegionStart(regions[key]), 'end': getRegionEnd(regions[key]), 'color': getColor(key) - }); + });*/ } - return regionList; + return regions; } if (typeof regionData == "string") {