diff --git a/dist/leaflet.minichart.js b/dist/leaflet.minichart.js index c60c237..962282d 100644 --- a/dist/leaflet.minichart.js +++ b/dist/leaflet.minichart.js @@ -1,12 +1,12 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o b ? 1 : a >= b ? 0 : NaN; @@ -48,6 +48,24 @@ var ascendingBisect = bisector(ascending); var bisectRight = ascendingBisect.right; var bisectLeft = ascendingBisect.left; +var pairs = function(array, f) { + if (f == null) f = pair; + var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n); + while (i < n) pairs[i] = f(p, p = array[++i]); + return pairs; +}; + +function pair(a, b) { + return [a, b]; +} + +var cross = function(a, b, f) { + var na = a.length, nb = b.length, c = new Array(na * nb), ia, ib, ic, va; + if (f == null) f = pair; + for (ia = ic = 0; ia < na; ++ia) for (va = a[ia], ib = 0; ib < nb; ++ib, ++ic) c[ic] = f(va, b[ib]); + return c; +}; + var descending = function(a, b) { return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; }; @@ -124,7 +142,7 @@ var array = Array.prototype; var slice = array.slice; var map = array.map; -var constant$1 = function(x) { +var constant = function(x) { return function() { return x; }; @@ -134,7 +152,7 @@ var identity = function(x) { return x; }; -var range = function(start, stop, step) { +var sequence = function(start, stop, step) { start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; var i = -1, @@ -154,7 +172,7 @@ var e2 = Math.sqrt(2); var ticks = function(start, stop, count) { var step = tickStep(start, stop, count); - return range( + return sequence( Math.ceil(start / step) * step, Math.floor(stop / step) * step + step / 2, // inclusive step @@ -225,15 +243,15 @@ var histogram = function() { } histogram.value = function(_) { - return arguments.length ? (value = typeof _ === "function" ? _ : constant$1(_), histogram) : value; + return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value; }; histogram.domain = function(_) { - return arguments.length ? (domain = typeof _ === "function" ? _ : constant$1([_[0], _[1]]), histogram) : domain; + return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain; }; histogram.thresholds = function(_) { - return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant$1(slice.call(_)) : constant$1(_), histogram) : threshold; + return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold; }; return histogram; @@ -356,12 +374,6 @@ var min = function(array, f) { return a; }; -var pairs = function(array) { - var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n); - while (i < n) pairs[i] = [p, p = array[++i]]; - return pairs; -}; - var permute = function(array, indexes) { var i = indexes.length, permutes = new Array(i); while (i--) permutes[i] = array[indexes[i]]; @@ -433,8578 +445,9012 @@ var zip = function() { return transpose(arguments); }; -var prefix = "$"; - -function Map() {} +var slice$1 = Array.prototype.slice; -Map.prototype = map$1.prototype = { - constructor: Map, - has: function(key) { - return (prefix + key) in this; - }, - get: function(key) { - return this[prefix + key]; - }, - set: function(key, value) { - this[prefix + key] = value; - return this; - }, - remove: function(key) { - var property = prefix + key; - return property in this && delete this[property]; - }, - clear: function() { - for (var property in this) if (property[0] === prefix) delete this[property]; - }, - keys: function() { - var keys = []; - for (var property in this) if (property[0] === prefix) keys.push(property.slice(1)); - return keys; - }, - values: function() { - var values = []; - for (var property in this) if (property[0] === prefix) values.push(this[property]); - return values; - }, - entries: function() { - var entries = []; - for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]}); - return entries; - }, - size: function() { - var size = 0; - for (var property in this) if (property[0] === prefix) ++size; - return size; - }, - empty: function() { - for (var property in this) if (property[0] === prefix) return false; - return true; - }, - each: function(f) { - for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this); - } +var identity$1 = function(x) { + return x; }; -function map$1(object, f) { - var map = new Map; - - // Copy constructor. - if (object instanceof Map) object.each(function(value, key) { map.set(key, value); }); - - // Index array by numeric index or specified key function. - else if (Array.isArray(object)) { - var i = -1, - n = object.length, - o; - - if (f == null) while (++i < n) map.set(i, object[i]); - else while (++i < n) map.set(f(o = object[i], i, object), o); - } +var top = 1; +var right = 2; +var bottom = 3; +var left = 4; +var epsilon = 1e-6; - // Convert object to map. - else if (object) for (var key in object) map.set(key, object[key]); +function translateX(x) { + return "translate(" + x + ",0)"; +} - return map; +function translateY(y) { + return "translate(0," + y + ")"; } -var nest = function() { - var keys = [], - sortKeys = [], - sortValues, - rollup, - nest; +function center(scale) { + var offset = scale.bandwidth() / 2; + if (scale.round()) offset = Math.round(offset); + return function(d) { + return scale(d) + offset; + }; +} - function apply(array, depth, createResult, setResult) { - if (depth >= keys.length) return rollup != null - ? rollup(array) : (sortValues != null - ? array.sort(sortValues) - : array); +function entering() { + return !this.__axis; +} - var i = -1, - n = array.length, - key = keys[depth++], - keyValue, - value, - valuesByKey = map$1(), - values, - result = createResult(); +function axis(orient, scale) { + var tickArguments = [], + tickValues = null, + tickFormat = null, + tickSizeInner = 6, + tickSizeOuter = 6, + tickPadding = 3, + k = orient === top || orient === left ? -1 : 1, + x, y = orient === left || orient === right ? (x = "x", "y") : (x = "y", "x"), + transform = orient === top || orient === bottom ? translateX : translateY; - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) { - values.push(value); - } else { - valuesByKey.set(keyValue, [value]); - } - } + function axis(context) { + var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues, + format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat, + spacing = Math.max(tickSizeInner, 0) + tickPadding, + range = scale.range(), + range0 = range[0] + 0.5, + range1 = range[range.length - 1] + 0.5, + position = (scale.bandwidth ? center : identity$1)(scale.copy()), + selection = context.selection ? context.selection() : context, + path = selection.selectAll(".domain").data([null]), + tick = selection.selectAll(".tick").data(values, scale).order(), + tickExit = tick.exit(), + tickEnter = tick.enter().append("g").attr("class", "tick"), + line = tick.select("line"), + text = tick.select("text"); - valuesByKey.each(function(values, key) { - setResult(result, key, apply(values, depth, createResult, setResult)); - }); + path = path.merge(path.enter().insert("path", ".tick") + .attr("class", "domain") + .attr("stroke", "#000")); - return result; - } + tick = tick.merge(tickEnter); - function entries(map, depth) { - if (++depth > keys.length) return map; - var array, sortKey = sortKeys[depth - 1]; - if (rollup != null && depth >= keys.length) array = map.entries(); - else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); }); - return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; - } + line = line.merge(tickEnter.append("line") + .attr("stroke", "#000") + .attr(x + "2", k * tickSizeInner) + .attr(y + "1", 0.5) + .attr(y + "2", 0.5)); - return nest = { - object: function(array) { return apply(array, 0, createObject, setObject); }, - map: function(array) { return apply(array, 0, createMap, setMap); }, - entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, - key: function(d) { keys.push(d); return nest; }, - sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, - sortValues: function(order) { sortValues = order; return nest; }, - rollup: function(f) { rollup = f; return nest; } - }; -}; + text = text.merge(tickEnter.append("text") + .attr("fill", "#000") + .attr(x, k * spacing) + .attr(y, 0.5) + .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em")); -function createObject() { - return {}; -} + if (context !== selection) { + path = path.transition(context); + tick = tick.transition(context); + line = line.transition(context); + text = text.transition(context); -function setObject(object, key, value) { - object[key] = value; -} + tickExit = tickExit.transition(context) + .attr("opacity", epsilon) + .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); }); -function createMap() { - return map$1(); -} + tickEnter + .attr("opacity", epsilon) + .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); }); + } -function setMap(map, key, value) { - map.set(key, value); -} + tickExit.remove(); -function Set() {} + path + .attr("d", orient === left || orient == right + ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter + : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter); -var proto = map$1.prototype; + tick + .attr("opacity", 1) + .attr("transform", function(d) { return transform(position(d)); }); -Set.prototype = set.prototype = { - constructor: Set, - has: proto.has, - add: function(value) { - value += ""; - this[prefix + value] = value; - return this; - }, - remove: proto.remove, - clear: proto.clear, - values: proto.keys, - size: proto.size, - empty: proto.empty, - each: proto.each -}; + line + .attr(x + "2", k * tickSizeInner); -function set(object, f) { - var set = new Set; + text + .attr(x, k * spacing) + .text(format); - // Copy constructor. - if (object instanceof Set) object.each(function(value) { set.add(value); }); + selection.filter(entering) + .attr("fill", "none") + .attr("font-size", 10) + .attr("font-family", "sans-serif") + .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle"); - // Otherwise, assume it’s an array. - else if (object) { - var i = -1, n = object.length; - if (f == null) while (++i < n) set.add(object[i]); - else while (++i < n) set.add(f(object[i], i, object)); + selection + .each(function() { this.__axis = position; }); } - return set; -} + axis.scale = function(_) { + return arguments.length ? (scale = _, axis) : scale; + }; -var keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; -}; + axis.ticks = function() { + return tickArguments = slice$1.call(arguments), axis; + }; -var values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; -}; - -var entries = function(map) { - var entries = []; - for (var key in map) entries.push({key: key, value: map[key]}); - return entries; -}; - -var uniform = function(min, max) { - min = min == null ? 0 : +min; - max = max == null ? 1 : +max; - if (arguments.length === 1) max = min, min = 0; - else max -= min; - return function() { - return Math.random() * max + min; + axis.tickArguments = function(_) { + return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice(); }; -}; - -var normal = function(mu, sigma) { - var x, r; - mu = mu == null ? 0 : +mu; - sigma = sigma == null ? 1 : +sigma; - return function() { - var y; - - // If available, use the second previously-generated uniform random. - if (x != null) y = x, x = null; - // Otherwise, generate a new x and y. - else do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); + axis.tickValues = function(_) { + return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice(); + }; - return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r); + axis.tickFormat = function(_) { + return arguments.length ? (tickFormat = _, axis) : tickFormat; }; -}; -var logNormal = function() { - var randomNormal = normal.apply(this, arguments); - return function() { - return Math.exp(randomNormal()); + axis.tickSize = function(_) { + return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner; }; -}; -var irwinHall = function(n) { - return function() { - for (var sum = 0, i = 0; i < n; ++i) sum += Math.random(); - return sum; + axis.tickSizeInner = function(_) { + return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner; }; -}; -var bates = function(n) { - var randomIrwinHall = irwinHall(n); - return function() { - return randomIrwinHall() / n; + axis.tickSizeOuter = function(_) { + return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter; }; -}; -var exponential = function(lambda) { - return function() { - return -Math.log(1 - Math.random()) / lambda; + axis.tickPadding = function(_) { + return arguments.length ? (tickPadding = +_, axis) : tickPadding; }; -}; -function linear(t) { - return +t; + return axis; } -function quadIn(t) { - return t * t; +function axisTop(scale) { + return axis(top, scale); } -function quadOut(t) { - return t * (2 - t); +function axisRight(scale) { + return axis(right, scale); } -function quadInOut(t) { - return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2; +function axisBottom(scale) { + return axis(bottom, scale); } -function cubicIn(t) { - return t * t * t; +function axisLeft(scale) { + return axis(left, scale); } -function cubicOut(t) { - return --t * t * t + 1; -} +var noop = {value: function() {}}; -function cubicInOut(t) { - return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; +function dispatch() { + for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { + if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); + _[t] = []; + } + return new Dispatch(_); } -var exponent = 3; - -var polyIn = (function custom(e) { - e = +e; +function Dispatch(_) { + this._ = _; +} - function polyIn(t) { - return Math.pow(t, e); - } +function parseTypenames(typenames, types) { + return typenames.trim().split(/^|\s+/).map(function(t) { + var name = "", i = t.indexOf("."); + if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); + if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); + return {type: t, name: name}; + }); +} - polyIn.exponent = custom; +Dispatch.prototype = dispatch.prototype = { + constructor: Dispatch, + on: function(typename, callback) { + var _ = this._, + T = parseTypenames(typename + "", _), + t, + i = -1, + n = T.length; - return polyIn; -})(exponent); + // If no callback was specified, return the callback of the given type and name. + if (arguments.length < 2) { + while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; + return; + } -var polyOut = (function custom(e) { - e = +e; + // If a type was specified, set the callback for the given type and name. + // Otherwise, if a null callback was specified, remove callbacks of the given name. + if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); + while (++i < n) { + if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback); + else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null); + } - function polyOut(t) { - return 1 - Math.pow(1 - t, e); + return this; + }, + copy: function() { + var copy = {}, _ = this._; + for (var t in _) copy[t] = _[t].slice(); + return new Dispatch(copy); + }, + call: function(type, that) { + if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; + if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); + for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); + }, + apply: function(type, that, args) { + if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); + for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); } +}; - polyOut.exponent = custom; - - return polyOut; -})(exponent); - -var polyInOut = (function custom(e) { - e = +e; - - function polyInOut(t) { - return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2; +function get(type, name) { + for (var i = 0, n = type.length, c; i < n; ++i) { + if ((c = type[i]).name === name) { + return c.value; + } } +} - polyInOut.exponent = custom; +function set(type, name, callback) { + for (var i = 0, n = type.length; i < n; ++i) { + if (type[i].name === name) { + type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); + break; + } + } + if (callback != null) type.push({name: name, value: callback}); + return type; +} - return polyInOut; -})(exponent); +var xhtml = "http://www.w3.org/1999/xhtml"; -var pi = Math.PI; -var halfPi = pi / 2; +var namespaces = { + svg: "http://www.w3.org/2000/svg", + xhtml: xhtml, + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" +}; -function sinIn(t) { - return 1 - Math.cos(t * halfPi); -} +var namespace = function(name) { + var prefix = name += "", i = prefix.indexOf(":"); + if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); + return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; +}; -function sinOut(t) { - return Math.sin(t * halfPi); +function creatorInherit(name) { + return function() { + var document = this.ownerDocument, + uri = this.namespaceURI; + return uri === xhtml && document.documentElement.namespaceURI === xhtml + ? document.createElement(name) + : document.createElementNS(uri, name); + }; } -function sinInOut(t) { - return (1 - Math.cos(pi * t)) / 2; +function creatorFixed(fullname) { + return function() { + return this.ownerDocument.createElementNS(fullname.space, fullname.local); + }; } -function expIn(t) { - return Math.pow(2, 10 * t - 10); -} +var creator = function(name) { + var fullname = namespace(name); + return (fullname.local + ? creatorFixed + : creatorInherit)(fullname); +}; -function expOut(t) { - return 1 - Math.pow(2, -10 * t); -} +var nextId = 0; -function expInOut(t) { - return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2; +function local$1() { + return new Local; } -function circleIn(t) { - return 1 - Math.sqrt(1 - t * t); +function Local() { + this._ = "@" + (++nextId).toString(36); } -function circleOut(t) { - return Math.sqrt(1 - --t * t); -} +Local.prototype = local$1.prototype = { + constructor: Local, + get: function(node) { + var id = this._; + while (!(id in node)) if (!(node = node.parentNode)) return; + return node[id]; + }, + set: function(node, value) { + return node[this._] = value; + }, + remove: function(node) { + return this._ in node && delete node[this._]; + }, + toString: function() { + return this._; + } +}; -function circleInOut(t) { - return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2; +var matcher = function(selector) { + return function() { + return this.matches(selector); + }; +}; + +if (typeof document !== "undefined") { + var element = document.documentElement; + if (!element.matches) { + var vendorMatches = element.webkitMatchesSelector + || element.msMatchesSelector + || element.mozMatchesSelector + || element.oMatchesSelector; + matcher = function(selector) { + return function() { + return vendorMatches.call(this, selector); + }; + }; + } } -var b1 = 4 / 11; -var b2 = 6 / 11; -var b3 = 8 / 11; -var b4 = 3 / 4; -var b5 = 9 / 11; -var b6 = 10 / 11; -var b7 = 15 / 16; -var b8 = 21 / 22; -var b9 = 63 / 64; -var b0 = 1 / b1 / b1; +var matcher$1 = matcher; -function bounceIn(t) { - return 1 - bounceOut(1 - t); +var filterEvents = {}; + +exports.event = null; + +if (typeof document !== "undefined") { + var element$1 = document.documentElement; + if (!("onmouseenter" in element$1)) { + filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; + } } -function bounceOut(t) { - return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9; +function filterContextListener(listener, index, group) { + listener = contextListener(listener, index, group); + return function(event) { + var related = event.relatedTarget; + if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { + listener.call(this, event); + } + }; } -function bounceInOut(t) { - return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2; +function contextListener(listener, index, group) { + return function(event1) { + var event0 = exports.event; // Events can be reentrant (e.g., focus). + exports.event = event1; + try { + listener.call(this, this.__data__, index, group); + } finally { + exports.event = event0; + } + }; } -var overshoot = 1.70158; +function parseTypenames$1(typenames) { + return typenames.trim().split(/^|\s+/).map(function(t) { + var name = "", i = t.indexOf("."); + if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); + return {type: t, name: name}; + }); +} -var backIn = (function custom(s) { - s = +s; +function onRemove(typename) { + return function() { + var on = this.__on; + if (!on) return; + for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { + if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { + this.removeEventListener(o.type, o.listener, o.capture); + } else { + on[++i] = o; + } + } + if (++i) on.length = i; + else delete this.__on; + }; +} - function backIn(t) { - return t * t * ((s + 1) * t - s); - } +function onAdd(typename, value, capture) { + var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; + return function(d, i, group) { + var on = this.__on, o, listener = wrap(value, i, group); + if (on) for (var j = 0, m = on.length; j < m; ++j) { + if ((o = on[j]).type === typename.type && o.name === typename.name) { + this.removeEventListener(o.type, o.listener, o.capture); + this.addEventListener(o.type, o.listener = listener, o.capture = capture); + o.value = value; + return; + } + } + this.addEventListener(typename.type, listener, capture); + o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; + if (!on) this.__on = [o]; + else on.push(o); + }; +} - backIn.overshoot = custom; +var selection_on = function(typename, value, capture) { + var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t; - return backIn; -})(overshoot); + if (arguments.length < 2) { + var on = this.node().__on; + if (on) for (var j = 0, m = on.length, o; j < m; ++j) { + for (i = 0, o = on[j]; i < n; ++i) { + if ((t = typenames[i]).type === o.type && t.name === o.name) { + return o.value; + } + } + } + return; + } -var backOut = (function custom(s) { - s = +s; + on = value ? onAdd : onRemove; + if (capture == null) capture = false; + for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); + return this; +}; - function backOut(t) { - return --t * t * ((s + 1) * t + s) + 1; +function customEvent(event1, listener, that, args) { + var event0 = exports.event; + event1.sourceEvent = exports.event; + exports.event = event1; + try { + return listener.apply(that, args); + } finally { + exports.event = event0; } +} - backOut.overshoot = custom; - - return backOut; -})(overshoot); +var sourceEvent = function() { + var current = exports.event, source; + while (source = current.sourceEvent) current = source; + return current; +}; -var backInOut = (function custom(s) { - s = +s; +var point = function(node, event) { + var svg = node.ownerSVGElement || node; - function backInOut(t) { - return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2; + if (svg.createSVGPoint) { + var point = svg.createSVGPoint(); + point.x = event.clientX, point.y = event.clientY; + point = point.matrixTransform(node.getScreenCTM().inverse()); + return [point.x, point.y]; } - backInOut.overshoot = custom; + var rect = node.getBoundingClientRect(); + return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; +}; - return backInOut; -})(overshoot); +var mouse = function(node) { + var event = sourceEvent(); + if (event.changedTouches) event = event.changedTouches[0]; + return point(node, event); +}; -var tau = 2 * Math.PI; -var amplitude = 1; -var period = 0.3; +function none() {} -var elasticIn = (function custom(a, p) { - var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); +var selector = function(selector) { + return selector == null ? none : function() { + return this.querySelector(selector); + }; +}; - function elasticIn(t) { - return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p); +var selection_select = function(select) { + if (typeof select !== "function") select = selector(select); + + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { + if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + subgroup[i] = subnode; + } + } } - elasticIn.amplitude = function(a) { return custom(a, p * tau); }; - elasticIn.period = function(p) { return custom(a, p); }; + return new Selection(subgroups, this._parents); +}; - return elasticIn; -})(amplitude, period); +function empty$1() { + return []; +} -var elasticOut = (function custom(a, p) { - var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); +var selectorAll = function(selector) { + return selector == null ? empty$1 : function() { + return this.querySelectorAll(selector); + }; +}; - function elasticOut(t) { - return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p); - } +var selection_selectAll = function(select) { + if (typeof select !== "function") select = selectorAll(select); - elasticOut.amplitude = function(a) { return custom(a, p * tau); }; - elasticOut.period = function(p) { return custom(a, p); }; + for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + subgroups.push(select.call(node, node.__data__, i, group)); + parents.push(node); + } + } + } - return elasticOut; -})(amplitude, period); + return new Selection(subgroups, parents); +}; -var elasticInOut = (function custom(a, p) { - var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); +var selection_filter = function(match) { + if (typeof match !== "function") match = matcher$1(match); - function elasticInOut(t) { - return ((t = t * 2 - 1) < 0 - ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p) - : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2; + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { + if ((node = group[i]) && match.call(node, node.__data__, i, group)) { + subgroup.push(node); + } + } } - elasticInOut.amplitude = function(a) { return custom(a, p * tau); }; - elasticInOut.period = function(p) { return custom(a, p); }; - - return elasticInOut; -})(amplitude, period); + return new Selection(subgroups, this._parents); +}; -var area = function(polygon) { - var i = -1, - n = polygon.length, - a, - b = polygon[n - 1], - area = 0; +var sparse = function(update) { + return new Array(update.length); +}; - while (++i < n) { - a = b; - b = polygon[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - - return area / 2; +var selection_enter = function() { + return new Selection(this._enter || this._groups.map(sparse), this._parents); }; -var centroid = function(polygon) { - var i = -1, - n = polygon.length, - x = 0, - y = 0, - a, - b = polygon[n - 1], - c, - k = 0; - - while (++i < n) { - a = b; - b = polygon[i]; - k += c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } +function EnterNode(parent, datum) { + this.ownerDocument = parent.ownerDocument; + this.namespaceURI = parent.namespaceURI; + this._next = null; + this._parent = parent; + this.__data__ = datum; +} - return k *= 3, [x / k, y / k]; +EnterNode.prototype = { + constructor: EnterNode, + appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, + insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, + querySelector: function(selector) { return this._parent.querySelector(selector); }, + querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } }; -// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of -// the 3D cross product in a quadrant I Cartesian coordinate system (+x is -// right, +y is up). Returns a positive value if ABC is counter-clockwise, -// negative if clockwise, and zero if the points are collinear. -var cross = function(a, b, c) { - return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); +var constant$1 = function(x) { + return function() { + return x; + }; }; -function lexicographicOrder(a, b) { - return a[0] - b[0] || a[1] - b[1]; +var keyPrefix = "$"; // Protect against keys like “__proto__”. + +function bindIndex(parent, group, enter, update, exit, data) { + var i = 0, + node, + groupLength = group.length, + dataLength = data.length; + + // Put any non-null nodes that fit into update. + // Put any null nodes into enter. + // Put any remaining data into enter. + for (; i < dataLength; ++i) { + if (node = group[i]) { + node.__data__ = data[i]; + update[i] = node; + } else { + enter[i] = new EnterNode(parent, data[i]); + } + } + + // Put any non-null nodes that don’t fit into exit. + for (; i < groupLength; ++i) { + if (node = group[i]) { + exit[i] = node; + } + } } -// Computes the upper convex hull per the monotone chain algorithm. -// Assumes points.length >= 3, is sorted by x, unique in y. -// Returns an array of indices into points in left-to-right order. -function computeUpperHullIndexes(points) { - var n = points.length, - indexes = [0, 1], - size = 2; +function bindKey(parent, group, enter, update, exit, data, key) { + var i, + node, + nodeByKeyValue = {}, + groupLength = group.length, + dataLength = data.length, + keyValues = new Array(groupLength), + keyValue; - for (var i = 2; i < n; ++i) { - while (size > 1 && cross(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size; - indexes[size++] = i; + // Compute the key for each node. + // If multiple nodes have the same key, the duplicates are added to exit. + for (i = 0; i < groupLength; ++i) { + if (node = group[i]) { + keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); + if (keyValue in nodeByKeyValue) { + exit[i] = node; + } else { + nodeByKeyValue[keyValue] = node; + } + } } - return indexes.slice(0, size); // remove popped points + // Compute the key for each datum. + // If there a node associated with this key, join and add it to update. + // If there is not (or the key is a duplicate), add it to enter. + for (i = 0; i < dataLength; ++i) { + keyValue = keyPrefix + key.call(parent, data[i], i, data); + if (node = nodeByKeyValue[keyValue]) { + update[i] = node; + node.__data__ = data[i]; + nodeByKeyValue[keyValue] = null; + } else { + enter[i] = new EnterNode(parent, data[i]); + } + } + + // Add any remaining nodes that were not bound to data to exit. + for (i = 0; i < groupLength; ++i) { + if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { + exit[i] = node; + } + } } -var hull = function(points) { - if ((n = points.length) < 3) return null; +var selection_data = function(value, key) { + if (!value) { + data = new Array(this.size()), j = -1; + this.each(function(d) { data[++j] = d; }); + return data; + } - var i, - n, - sortedPoints = new Array(n), - flippedPoints = new Array(n); + var bind = key ? bindKey : bindIndex, + parents = this._parents, + groups = this._groups; - for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i]; - sortedPoints.sort(lexicographicOrder); - for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]]; + if (typeof value !== "function") value = constant$1(value); - var upperIndexes = computeUpperHullIndexes(sortedPoints), - lowerIndexes = computeUpperHullIndexes(flippedPoints); + for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { + var parent = parents[j], + group = groups[j], + groupLength = group.length, + data = value.call(parent, parent && parent.__data__, j, parents), + dataLength = data.length, + enterGroup = enter[j] = new Array(dataLength), + updateGroup = update[j] = new Array(dataLength), + exitGroup = exit[j] = new Array(groupLength); - // Construct the hull polygon, removing possible duplicate endpoints. - var skipLeft = lowerIndexes[0] === upperIndexes[0], - skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1], - hull = []; + bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); - // Add upper hull in right-to-l order. - // Then add lower hull in left-to-right order. - for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]); - for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]); + // Now connect the enter nodes to their following update node, such that + // appendChild can insert the materialized enter node before this node, + // rather than at the end of the parent node. + for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { + if (previous = enterGroup[i0]) { + if (i0 >= i1) i1 = i0 + 1; + while (!(next = updateGroup[i1]) && ++i1 < dataLength); + previous._next = next || null; + } + } + } - return hull; + update = new Selection(update, parents); + update._enter = enter; + update._exit = exit; + return update; }; -var contains = function(polygon, point) { - var n = polygon.length, - p = polygon[n - 1], - x = point[0], y = point[1], - x0 = p[0], y0 = p[1], - x1, y1, - inside = false; +var selection_exit = function() { + return new Selection(this._exit || this._groups.map(sparse), this._parents); +}; - for (var i = 0; i < n; ++i) { - p = polygon[i], x1 = p[0], y1 = p[1]; - if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside; - x0 = x1, y0 = y1; +var selection_merge = function(selection) { + + for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { + for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group0[i] || group1[i]) { + merge[i] = node; + } + } } - return inside; + for (; j < m0; ++j) { + merges[j] = groups0[j]; + } + + return new Selection(merges, this._parents); }; -var length$1 = function(polygon) { - var i = -1, - n = polygon.length, - b = polygon[n - 1], - xa, - ya, - xb = b[0], - yb = b[1], - perimeter = 0; +var selection_order = function() { - while (++i < n) { - xa = xb; - ya = yb; - b = polygon[i]; - xb = b[0]; - yb = b[1]; - xa -= xb; - ya -= yb; - perimeter += Math.sqrt(xa * xa + ya * ya); + for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { + for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { + if (node = group[i]) { + if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); + next = node; + } + } } - return perimeter; + return this; }; -var pi$1 = Math.PI; -var tau$1 = 2 * pi$1; -var epsilon = 1e-6; -var tauEpsilon = tau$1 - epsilon; +var selection_sort = function(compare) { + if (!compare) compare = ascending$1; -function Path() { - this._x0 = this._y0 = // start of current subpath - this._x1 = this._y1 = null; // end of current subpath - this._ = ""; -} + function compareNode(a, b) { + return a && b ? compare(a.__data__, b.__data__) : !a - !b; + } -function path() { - return new Path; -} + for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group[i]) { + sortgroup[i] = node; + } + } + sortgroup.sort(compareNode); + } -Path.prototype = path.prototype = { - constructor: Path, - moveTo: function(x, y) { - this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); - }, - closePath: function() { - if (this._x1 !== null) { - this._x1 = this._x0, this._y1 = this._y0; - this._ += "Z"; - } - }, - lineTo: function(x, y) { - this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); - }, - quadraticCurveTo: function(x1, y1, x, y) { - this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); - }, - bezierCurveTo: function(x1, y1, x2, y2, x, y) { - this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); - }, - arcTo: function(x1, y1, x2, y2, r) { - x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; - var x0 = this._x1, - y0 = this._y1, - x21 = x2 - x1, - y21 = y2 - y1, - x01 = x0 - x1, - y01 = y0 - y1, - l01_2 = x01 * x01 + y01 * y01; - - // Is the radius negative? Error. - if (r < 0) throw new Error("negative radius: " + r); - - // Is this path empty? Move to (x1,y1). - if (this._x1 === null) { - this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); - } + return new Selection(sortgroups, this._parents).order(); +}; - // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. - else if (!(l01_2 > epsilon)) {} +function ascending$1(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +} - // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? - // Equivalently, is (x1,y1) coincident with (x2,y2)? - // Or, is the radius zero? Line to (x1,y1). - else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) { - this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); - } +var selection_call = function() { + var callback = arguments[0]; + arguments[0] = this; + callback.apply(null, arguments); + return this; +}; - // Otherwise, draw an arc! - else { - var x20 = x2 - x0, - y20 = y2 - y0, - l21_2 = x21 * x21 + y21 * y21, - l20_2 = x20 * x20 + y20 * y20, - l21 = Math.sqrt(l21_2), - l01 = Math.sqrt(l01_2), - l = r * Math.tan((pi$1 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), - t01 = l / l01, - t21 = l / l21; +var selection_nodes = function() { + var nodes = new Array(this.size()), i = -1; + this.each(function() { nodes[++i] = this; }); + return nodes; +}; - // If the start tangent is not coincident with (x0,y0), line to. - if (Math.abs(t01 - 1) > epsilon) { - this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); - } +var selection_node = function() { - this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { + var node = group[i]; + if (node) return node; } - }, - arc: function(x, y, r, a0, a1, ccw) { - x = +x, y = +y, r = +r; - var dx = r * Math.cos(a0), - dy = r * Math.sin(a0), - x0 = x + dx, - y0 = y + dy, - cw = 1 ^ ccw, - da = ccw ? a0 - a1 : a1 - a0; - - // Is the radius negative? Error. - if (r < 0) throw new Error("negative radius: " + r); + } - // Is this path empty? Move to (x0,y0). - if (this._x1 === null) { - this._ += "M" + x0 + "," + y0; - } + return null; +}; - // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). - else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) { - this._ += "L" + x0 + "," + y0; - } +var selection_size = function() { + var size = 0; + this.each(function() { ++size; }); + return size; +}; - // Is this arc empty? We’re done. - if (!r) return; +var selection_empty = function() { + return !this.node(); +}; - // Is this a complete circle? Draw two arcs to complete the circle. - if (da > tauEpsilon) { - this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); - } +var selection_each = function(callback) { - // Otherwise, draw an arc! - else { - if (da < 0) da = da % tau$1 + tau$1; - this._ += "A" + r + "," + r + ",0," + (+(da >= pi$1)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { + if (node = group[i]) callback.call(node, node.__data__, i, group); } - }, - rect: function(x, y, w, h) { - this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; - }, - toString: function() { - return this._; } -}; -var tree_add = function(d) { - var x = +this._x.call(null, d), - y = +this._y.call(null, d); - return add(this.cover(x, y), x, y, d); + return this; }; -function add(tree, x, y, d) { - if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points +function attrRemove(name) { + return function() { + this.removeAttribute(name); + }; +} - var parent, - node = tree._root, - leaf = {data: d}, - x0 = tree._x0, - y0 = tree._y0, - x1 = tree._x1, - y1 = tree._y1, - xm, - ym, - xp, - yp, - right, - bottom, - i, - j; +function attrRemoveNS(fullname) { + return function() { + this.removeAttributeNS(fullname.space, fullname.local); + }; +} - // If the tree is empty, initialize the root as a leaf. - if (!node) return tree._root = leaf, tree; +function attrConstant(name, value) { + return function() { + this.setAttribute(name, value); + }; +} - // Find the existing leaf for the new point, or add it. - while (node.length) { - if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; - if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; - if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; - } +function attrConstantNS(fullname, value) { + return function() { + this.setAttributeNS(fullname.space, fullname.local, value); + }; +} - // Is the new point is exactly coincident with the existing point? - xp = +tree._x.call(null, node.data); - yp = +tree._y.call(null, node.data); - if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; +function attrFunction(name, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.removeAttribute(name); + else this.setAttribute(name, v); + }; +} - // Otherwise, split the leaf node until the old and new point are separated. - do { - parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); - if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; - if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; - } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm))); - return parent[j] = node, parent[i] = leaf, tree; +function attrFunctionNS(fullname, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.removeAttributeNS(fullname.space, fullname.local); + else this.setAttributeNS(fullname.space, fullname.local, v); + }; } -function addAll(data) { - var d, i, n = data.length, - x, - y, - xz = new Array(n), - yz = new Array(n), - x0 = Infinity, - y0 = Infinity, - x1 = -Infinity, - y1 = -Infinity; +var selection_attr = function(name, value) { + var fullname = namespace(name); - // Compute the points and their extent. - for (i = 0; i < n; ++i) { - if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue; - xz[i] = x; - yz[i] = y; - if (x < x0) x0 = x; - if (x > x1) x1 = x; - if (y < y0) y0 = y; - if (y > y1) y1 = y; + if (arguments.length < 2) { + var node = this.node(); + return fullname.local + ? node.getAttributeNS(fullname.space, fullname.local) + : node.getAttribute(fullname); } - // If there were no (valid) points, inherit the existing extent. - if (x1 < x0) x0 = this._x0, x1 = this._x1; - if (y1 < y0) y0 = this._y0, y1 = this._y1; + return this.each((value == null + ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" + ? (fullname.local ? attrFunctionNS : attrFunction) + : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); +}; - // Expand the tree to cover the new points. - this.cover(x0, y0).cover(x1, y1); +var window = function(node) { + return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node + || (node.document && node) // node is a Window + || node.defaultView; // node is a Document +}; - // Add the new points. - for (i = 0; i < n; ++i) { - add(this, xz[i], yz[i], data[i]); - } +function styleRemove(name) { + return function() { + this.style.removeProperty(name); + }; +} - return this; +function styleConstant(name, value, priority) { + return function() { + this.style.setProperty(name, value, priority); + }; } -var tree_cover = function(x, y) { - if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points - - var x0 = this._x0, - y0 = this._y0, - x1 = this._x1, - y1 = this._y1; - - // If the quadtree has no extent, initialize them. - // Integer extent are necessary so that if we later double the extent, - // the existing quadrant boundaries don’t change due to floating point error! - if (isNaN(x0)) { - x1 = (x0 = Math.floor(x)) + 1; - y1 = (y0 = Math.floor(y)) + 1; - } - - // Otherwise, double repeatedly to cover. - else if (x0 > x || x > x1 || y0 > y || y > y1) { - var z = x1 - x0, - node = this._root, - parent, - i; +function styleFunction(name, value, priority) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.style.removeProperty(name); + else this.style.setProperty(name, v, priority); + }; +} - switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) { - case 0: { - do parent = new Array(4), parent[i] = node, node = parent; - while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1); - break; - } - case 1: { - do parent = new Array(4), parent[i] = node, node = parent; - while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1); - break; - } - case 2: { - do parent = new Array(4), parent[i] = node, node = parent; - while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y); - break; - } - case 3: { - do parent = new Array(4), parent[i] = node, node = parent; - while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y); - break; - } - } +var selection_style = function(name, value, priority) { + var node; + return arguments.length > 1 + ? this.each((value == null + ? styleRemove : typeof value === "function" + ? styleFunction + : styleConstant)(name, value, priority == null ? "" : priority)) + : window(node = this.node()) + .getComputedStyle(node, null) + .getPropertyValue(name); +}; - if (this._root && this._root.length) this._root = node; - } +function propertyRemove(name) { + return function() { + delete this[name]; + }; +} - // If the quadtree covers the point already, just return. - else return this; +function propertyConstant(name, value) { + return function() { + this[name] = value; + }; +} - this._x0 = x0; - this._y0 = y0; - this._x1 = x1; - this._y1 = y1; - return this; -}; +function propertyFunction(name, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) delete this[name]; + else this[name] = v; + }; +} -var tree_data = function() { - var data = []; - this.visit(function(node) { - if (!node.length) do data.push(node.data); while (node = node.next) - }); - return data; +var selection_property = function(name, value) { + return arguments.length > 1 + ? this.each((value == null + ? propertyRemove : typeof value === "function" + ? propertyFunction + : propertyConstant)(name, value)) + : this.node()[name]; }; -var tree_extent = function(_) { - return arguments.length - ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) - : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]]; -}; +function classArray(string) { + return string.trim().split(/^|\s+/); +} -var Quad = function(node, x0, y0, x1, y1) { - this.node = node; - this.x0 = x0; - this.y0 = y0; - this.x1 = x1; - this.y1 = y1; -}; +function classList(node) { + return node.classList || new ClassList(node); +} -var tree_find = function(x, y, radius) { - var data, - x0 = this._x0, - y0 = this._y0, - x1, - y1, - x2, - y2, - x3 = this._x1, - y3 = this._y1, - quads = [], - node = this._root, - q, - i; +function ClassList(node) { + this._node = node; + this._names = classArray(node.getAttribute("class") || ""); +} - if (node) quads.push(new Quad(node, x0, y0, x3, y3)); - if (radius == null) radius = Infinity; - else { - x0 = x - radius, y0 = y - radius; - x3 = x + radius, y3 = y + radius; - radius *= radius; +ClassList.prototype = { + add: function(name) { + var i = this._names.indexOf(name); + if (i < 0) { + this._names.push(name); + this._node.setAttribute("class", this._names.join(" ")); + } + }, + remove: function(name) { + var i = this._names.indexOf(name); + if (i >= 0) { + this._names.splice(i, 1); + this._node.setAttribute("class", this._names.join(" ")); + } + }, + contains: function(name) { + return this._names.indexOf(name) >= 0; } +}; - while (q = quads.pop()) { +function classedAdd(node, names) { + var list = classList(node), i = -1, n = names.length; + while (++i < n) list.add(names[i]); +} - // Stop searching if this quadrant can’t contain a closer node. - if (!(node = q.node) - || (x1 = q.x0) > x3 - || (y1 = q.y0) > y3 - || (x2 = q.x1) < x0 - || (y2 = q.y1) < y0) continue; +function classedRemove(node, names) { + var list = classList(node), i = -1, n = names.length; + while (++i < n) list.remove(names[i]); +} - // Bisect the current quadrant. - if (node.length) { - var xm = (x1 + x2) / 2, - ym = (y1 + y2) / 2; +function classedTrue(names) { + return function() { + classedAdd(this, names); + }; +} - quads.push( - new Quad(node[3], xm, ym, x2, y2), - new Quad(node[2], x1, ym, xm, y2), - new Quad(node[1], xm, y1, x2, ym), - new Quad(node[0], x1, y1, xm, ym) - ); +function classedFalse(names) { + return function() { + classedRemove(this, names); + }; +} - // Visit the closest quadrant first. - if (i = (y >= ym) << 1 | (x >= xm)) { - q = quads[quads.length - 1]; - quads[quads.length - 1] = quads[quads.length - 1 - i]; - quads[quads.length - 1 - i] = q; - } - } +function classedFunction(names, value) { + return function() { + (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); + }; +} - // Visit this point. (Visiting coincident points isn’t necessary!) - else { - var dx = x - +this._x.call(null, node.data), - dy = y - +this._y.call(null, node.data), - d2 = dx * dx + dy * dy; - if (d2 < radius) { - var d = Math.sqrt(radius = d2); - x0 = x - d, y0 = y - d; - x3 = x + d, y3 = y + d; - data = node.data; - } - } +var selection_classed = function(name, value) { + var names = classArray(name + ""); + + if (arguments.length < 2) { + var list = classList(this.node()), i = -1, n = names.length; + while (++i < n) if (!list.contains(names[i])) return false; + return true; } - return data; + return this.each((typeof value === "function" + ? classedFunction : value + ? classedTrue + : classedFalse)(names, value)); }; -var tree_remove = function(d) { - if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points - - var parent, - node = this._root, - retainer, - previous, - next, - x0 = this._x0, - y0 = this._y0, - x1 = this._x1, - y1 = this._y1, - x, - y, - xm, - ym, - right, - bottom, - i, - j; +function textRemove() { + this.textContent = ""; +} - // If the tree is empty, initialize the root as a leaf. - if (!node) return this; - - // Find the leaf node for the point. - // While descending, also retain the deepest parent with a non-removed sibling. - if (node.length) while (true) { - if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; - if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; - if (!(parent = node, node = node[i = bottom << 1 | right])) return this; - if (!node.length) break; - if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i; - } +function textConstant(value) { + return function() { + this.textContent = value; + }; +} - // Find the point to remove. - while (node.data !== d) if (!(previous = node, node = node.next)) return this; - if (next = node.next) delete node.next; +function textFunction(value) { + return function() { + var v = value.apply(this, arguments); + this.textContent = v == null ? "" : v; + }; +} - // If there are multiple coincident points, remove just the point. - if (previous) return (next ? previous.next = next : delete previous.next), this; +var selection_text = function(value) { + return arguments.length + ? this.each(value == null + ? textRemove : (typeof value === "function" + ? textFunction + : textConstant)(value)) + : this.node().textContent; +}; - // If this is the root point, remove it. - if (!parent) return this._root = next, this; +function htmlRemove() { + this.innerHTML = ""; +} - // Remove this leaf. - next ? parent[i] = next : delete parent[i]; +function htmlConstant(value) { + return function() { + this.innerHTML = value; + }; +} - // If the parent now contains exactly one leaf, collapse superfluous parents. - if ((node = parent[0] || parent[1] || parent[2] || parent[3]) - && node === (parent[3] || parent[2] || parent[1] || parent[0]) - && !node.length) { - if (retainer) retainer[j] = node; - else this._root = node; - } +function htmlFunction(value) { + return function() { + var v = value.apply(this, arguments); + this.innerHTML = v == null ? "" : v; + }; +} - return this; +var selection_html = function(value) { + return arguments.length + ? this.each(value == null + ? htmlRemove : (typeof value === "function" + ? htmlFunction + : htmlConstant)(value)) + : this.node().innerHTML; }; -function removeAll(data) { - for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); - return this; +function raise() { + if (this.nextSibling) this.parentNode.appendChild(this); } -var tree_root = function() { - return this._root; +var selection_raise = function() { + return this.each(raise); }; -var tree_size = function() { - var size = 0; - this.visit(function(node) { - if (!node.length) do ++size; while (node = node.next) - }); - return size; -}; +function lower() { + if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); +} -var tree_visit = function(callback) { - var quads = [], q, node = this._root, child, x0, y0, x1, y1; - if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1)); - while (q = quads.pop()) { - if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { - var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; - if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); - if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); - if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); - if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); - } - } - return this; +var selection_lower = function() { + return this.each(lower); }; -var tree_visitAfter = function(callback) { - var quads = [], next = [], q; - if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1)); - while (q = quads.pop()) { - var node = q.node; - if (node.length) { - var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; - if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); - if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); - if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); - if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); - } - next.push(q); - } - while (q = next.pop()) { - callback(q.node, q.x0, q.y0, q.x1, q.y1); - } - return this; +var selection_append = function(name) { + var create = typeof name === "function" ? name : creator(name); + return this.select(function() { + return this.appendChild(create.apply(this, arguments)); + }); }; -function defaultX(d) { - return d[0]; +function constantNull() { + return null; } -var tree_x = function(_) { - return arguments.length ? (this._x = _, this) : this._x; +var selection_insert = function(name, before) { + var create = typeof name === "function" ? name : creator(name), + select = before == null ? constantNull : typeof before === "function" ? before : selector(before); + return this.select(function() { + return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); + }); }; -function defaultY(d) { - return d[1]; +function remove() { + var parent = this.parentNode; + if (parent) parent.removeChild(this); } -var tree_y = function(_) { - return arguments.length ? (this._y = _, this) : this._y; +var selection_remove = function() { + return this.each(remove); }; -function quadtree(nodes, x, y) { - var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN); - return nodes == null ? tree : tree.addAll(nodes); +var selection_datum = function(value) { + return arguments.length + ? this.property("__data__", value) + : this.node().__data__; +}; + +function dispatchEvent(node, type, params) { + var window$$1 = window(node), + event = window$$1.CustomEvent; + + if (event) { + event = new event(type, params); + } else { + event = window$$1.document.createEvent("Event"); + if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; + else event.initEvent(type, false, false); + } + + node.dispatchEvent(event); } -function Quadtree(x, y, x0, y0, x1, y1) { - this._x = x; - this._y = y; - this._x0 = x0; - this._y0 = y0; - this._x1 = x1; - this._y1 = y1; - this._root = undefined; +function dispatchConstant(type, params) { + return function() { + return dispatchEvent(this, type, params); + }; } -function leaf_copy(leaf) { - var copy = {data: leaf.data}, next = copy; - while (leaf = leaf.next) next = next.next = {data: leaf.data}; - return copy; +function dispatchFunction(type, params) { + return function() { + return dispatchEvent(this, type, params.apply(this, arguments)); + }; } -var treeProto = quadtree.prototype = Quadtree.prototype; +var selection_dispatch = function(type, params) { + return this.each((typeof params === "function" + ? dispatchFunction + : dispatchConstant)(type, params)); +}; -treeProto.copy = function() { - var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), - node = this._root, - nodes, - child; +var root = [null]; - if (!node) return copy; +function Selection(groups, parents) { + this._groups = groups; + this._parents = parents; +} - if (!node.length) return copy._root = leaf_copy(node), copy; +function selection() { + return new Selection([[document.documentElement]], root); +} - nodes = [{source: node, target: copy._root = new Array(4)}]; - while (node = nodes.pop()) { - for (var i = 0; i < 4; ++i) { - if (child = node.source[i]) { - if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)}); - else node.target[i] = leaf_copy(child); - } - } - } +Selection.prototype = selection.prototype = { + constructor: Selection, + select: selection_select, + selectAll: selection_selectAll, + filter: selection_filter, + data: selection_data, + enter: selection_enter, + exit: selection_exit, + merge: selection_merge, + order: selection_order, + sort: selection_sort, + call: selection_call, + nodes: selection_nodes, + node: selection_node, + size: selection_size, + empty: selection_empty, + each: selection_each, + attr: selection_attr, + style: selection_style, + property: selection_property, + classed: selection_classed, + text: selection_text, + html: selection_html, + raise: selection_raise, + lower: selection_lower, + append: selection_append, + insert: selection_insert, + remove: selection_remove, + datum: selection_datum, + on: selection_on, + dispatch: selection_dispatch +}; - return copy; +var select = function(selector) { + return typeof selector === "string" + ? new Selection([[document.querySelector(selector)]], [document.documentElement]) + : new Selection([[selector]], root); }; -treeProto.add = tree_add; -treeProto.addAll = addAll; -treeProto.cover = tree_cover; -treeProto.data = tree_data; -treeProto.extent = tree_extent; -treeProto.find = tree_find; -treeProto.remove = tree_remove; -treeProto.removeAll = removeAll; -treeProto.root = tree_root; -treeProto.size = tree_size; -treeProto.visit = tree_visit; -treeProto.visitAfter = tree_visitAfter; -treeProto.x = tree_x; -treeProto.y = tree_y; - -var slice$1 = [].slice; - -var noabort = {}; +var selectAll = function(selector) { + return typeof selector === "string" + ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) + : new Selection([selector == null ? [] : selector], root); +}; -function Queue(size) { - if (!(size >= 1)) throw new Error; - this._size = size; - this._call = - this._error = null; - this._tasks = []; - this._data = []; - this._waiting = - this._active = - this._ended = - this._start = 0; // inside a synchronous task callback? -} +var touch = function(node, touches, identifier) { + if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; -Queue.prototype = queue.prototype = { - constructor: Queue, - defer: function(callback) { - if (typeof callback !== "function" || this._call) throw new Error; - if (this._error != null) return this; - var t = slice$1.call(arguments, 1); - t.push(callback); - ++this._waiting, this._tasks.push(t); - poke(this); - return this; - }, - abort: function() { - if (this._error == null) abort(this, new Error("abort")); - return this; - }, - await: function(callback) { - if (typeof callback !== "function" || this._call) throw new Error; - this._call = function(error, results) { callback.apply(null, [error].concat(results)); }; - maybeNotify(this); - return this; - }, - awaitAll: function(callback) { - if (typeof callback !== "function" || this._call) throw new Error; - this._call = callback; - maybeNotify(this); - return this; + for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { + if ((touch = touches[i]).identifier === identifier) { + return point(node, touch); + } } + + return null; }; -function poke(q) { - if (!q._start) { - try { start(q); } // let the current task complete - catch (e) { - if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously - else if (!q._data) throw e; // await callback errored synchronously - } - } -} +var touches = function(node, touches) { + if (touches == null) touches = sourceEvent().touches; -function start(q) { - while (q._start = q._waiting && q._active < q._size) { - var i = q._ended + q._active, - t = q._tasks[i], - j = t.length - 1, - c = t[j]; - t[j] = end(q, i); - --q._waiting, ++q._active; - t = c.apply(null, t); - if (!q._tasks[i]) continue; // task finished synchronously - q._tasks[i] = t || noabort; + for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) { + points[i] = point(node, touches[i]); } -} -function end(q, i) { - return function(e, r) { - if (!q._tasks[i]) return; // ignore multiple callbacks - --q._active, ++q._ended; - q._tasks[i] = null; - if (q._error != null) return; // ignore secondary errors - if (e != null) { - abort(q, e); - } else { - q._data[i] = r; - if (q._waiting) poke(q); - else maybeNotify(q); - } - }; + return points; +}; + +function nopropagation() { + exports.event.stopImmediatePropagation(); } -function abort(q, e) { - var i = q._tasks.length, t; - q._error = e; // ignore active callbacks - q._data = undefined; // allow gc - q._waiting = NaN; // prevent starting +var noevent = function() { + exports.event.preventDefault(); + exports.event.stopImmediatePropagation(); +}; - while (--i >= 0) { - if (t = q._tasks[i]) { - q._tasks[i] = null; - if (t.abort) { - try { t.abort(); } - catch (e) { /* ignore */ } - } - } +var dragDisable = function(view) { + var root = view.document.documentElement, + selection$$1 = select(view).on("dragstart.drag", noevent, true); + if ("onselectstart" in root) { + selection$$1.on("selectstart.drag", noevent, true); + } else { + root.__noselect = root.style.MozUserSelect; + root.style.MozUserSelect = "none"; } +}; - q._active = NaN; // allow notification - maybeNotify(q); -} - -function maybeNotify(q) { - if (!q._active && q._call) { - var d = q._data; - q._data = undefined; // allow gc - q._call(q._error, d); +function yesdrag(view, noclick) { + var root = view.document.documentElement, + selection$$1 = select(view).on("dragstart.drag", null); + if (noclick) { + selection$$1.on("click.drag", noevent, true); + setTimeout(function() { selection$$1.on("click.drag", null); }, 0); + } + if ("onselectstart" in root) { + selection$$1.on("selectstart.drag", null); + } else { + root.style.MozUserSelect = root.__noselect; + delete root.__noselect; } -} - -function queue(concurrency) { - return new Queue(arguments.length ? +concurrency : Infinity); } var constant$2 = function(x) { - return function constant() { + return function() { return x; }; }; -var epsilon$1 = 1e-12; -var pi$2 = Math.PI; -var halfPi$1 = pi$2 / 2; -var tau$2 = 2 * pi$2; - -function arcInnerRadius(d) { - return d.innerRadius; -} - -function arcOuterRadius(d) { - return d.outerRadius; +function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) { + this.target = target; + this.type = type; + this.subject = subject; + this.identifier = id; + this.active = active; + this.x = x; + this.y = y; + this.dx = dx; + this.dy = dy; + this._ = dispatch; } -function arcStartAngle(d) { - return d.startAngle; -} +DragEvent.prototype.on = function() { + var value = this._.on.apply(this._, arguments); + return value === this._ ? this : value; +}; -function arcEndAngle(d) { - return d.endAngle; +// Ignore right-click, since that should open the context menu. +function defaultFilter$1() { + return !exports.event.button; } -function arcPadAngle(d) { - return d && d.padAngle; // Note: optional! +function defaultContainer() { + return this.parentNode; } -function asin(x) { - return x >= 1 ? halfPi$1 : x <= -1 ? -halfPi$1 : Math.asin(x); +function defaultSubject(d) { + return d == null ? {x: exports.event.x, y: exports.event.y} : d; } -function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { - var x10 = x1 - x0, y10 = y1 - y0, - x32 = x3 - x2, y32 = y3 - y2, - t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10); - return [x0 + t * x10, y0 + t * y10]; -} +var drag = function() { + var filter = defaultFilter$1, + container = defaultContainer, + subject = defaultSubject, + gestures = {}, + listeners = dispatch("start", "drag", "end"), + active = 0, + mousemoving, + touchending; -// Compute perpendicular offset line of length rc. -// http://mathworld.wolfram.com/Circle-LineIntersection.html -function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { - var x01 = x0 - x1, - y01 = y0 - y1, - lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), - ox = lo * y01, - oy = -lo * x01, - x11 = x0 + ox, - y11 = y0 + oy, - x10 = x1 + ox, - y10 = y1 + oy, - x00 = (x11 + x10) / 2, - y00 = (y11 + y10) / 2, - dx = x10 - x11, - dy = y10 - y11, - d2 = dx * dx + dy * dy, - r = r1 - rc, - D = x11 * y10 - x10 * y11, - d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)), - cx0 = (D * dy - dx * d) / d2, - cy0 = (-D * dx - dy * d) / d2, - cx1 = (D * dy + dx * d) / d2, - cy1 = (-D * dx + dy * d) / d2, - dx0 = cx0 - x00, - dy0 = cy0 - y00, - dx1 = cx1 - x00, - dy1 = cy1 - y00; + function drag(selection$$1) { + selection$$1 + .on("mousedown.drag", mousedowned) + .on("touchstart.drag", touchstarted) + .on("touchmove.drag", touchmoved) + .on("touchend.drag touchcancel.drag", touchended) + .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); + } - // Pick the closer of the two intersection points. - // TODO Is there a faster way to determine which intersection to use? - if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; + function mousedowned() { + if (touchending || !filter.apply(this, arguments)) return; + var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments); + if (!gesture) return; + select(exports.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); + dragDisable(exports.event.view); + nopropagation(); + mousemoving = false; + gesture("start"); + } - return { - cx: cx0, - cy: cy0, - x01: -ox, - y01: -oy, - x11: cx0 * (r1 / r - 1), - y11: cy0 * (r1 / r - 1) - }; -} - -var arc = function() { - var innerRadius = arcInnerRadius, - outerRadius = arcOuterRadius, - cornerRadius = constant$2(0), - padRadius = null, - startAngle = arcStartAngle, - endAngle = arcEndAngle, - padAngle = arcPadAngle, - context = null; - - function arc() { - var buffer, - r, - r0 = +innerRadius.apply(this, arguments), - r1 = +outerRadius.apply(this, arguments), - a0 = startAngle.apply(this, arguments) - halfPi$1, - a1 = endAngle.apply(this, arguments) - halfPi$1, - da = Math.abs(a1 - a0), - cw = a1 > a0; - - if (!context) context = buffer = path(); + function mousemoved() { + noevent(); + mousemoving = true; + gestures.mouse("drag"); + } - // Ensure that the outer radius is always larger than the inner radius. - if (r1 < r0) r = r1, r1 = r0, r0 = r; + function mouseupped() { + select(exports.event.view).on("mousemove.drag mouseup.drag", null); + yesdrag(exports.event.view, mousemoving); + noevent(); + gestures.mouse("end"); + } - // Is it a point? - if (!(r1 > epsilon$1)) context.moveTo(0, 0); + function touchstarted() { + if (!filter.apply(this, arguments)) return; + var touches$$1 = exports.event.changedTouches, + c = container.apply(this, arguments), + n = touches$$1.length, i, gesture; - // Or is it a circle or annulus? - else if (da > tau$2 - epsilon$1) { - context.moveTo(r1 * Math.cos(a0), r1 * Math.sin(a0)); - context.arc(0, 0, r1, a0, a1, !cw); - if (r0 > epsilon$1) { - context.moveTo(r0 * Math.cos(a1), r0 * Math.sin(a1)); - context.arc(0, 0, r0, a1, a0, cw); + for (i = 0; i < n; ++i) { + if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) { + nopropagation(); + gesture("start"); } } + } - // Or is it a circular or annular sector? - else { - var a01 = a0, - a11 = a1, - a00 = a0, - a10 = a1, - da0 = da, - da1 = da, - ap = padAngle.apply(this, arguments) / 2, - rp = (ap > epsilon$1) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)), - rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), - rc0 = rc, - rc1 = rc, - t0, - t1; - - // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. - if (rp > epsilon$1) { - var p0 = asin(rp / r0 * Math.sin(ap)), - p1 = asin(rp / r1 * Math.sin(ap)); - if ((da0 -= p0 * 2) > epsilon$1) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; - else da0 = 0, a00 = a10 = (a0 + a1) / 2; - if ((da1 -= p1 * 2) > epsilon$1) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; - else da1 = 0, a01 = a11 = (a0 + a1) / 2; - } - - var x01 = r1 * Math.cos(a01), - y01 = r1 * Math.sin(a01), - x10 = r0 * Math.cos(a10), - y10 = r0 * Math.sin(a10); - - // Apply rounded corners? - if (rc > epsilon$1) { - var x11 = r1 * Math.cos(a11), - y11 = r1 * Math.sin(a11), - x00 = r0 * Math.cos(a00), - y00 = r0 * Math.sin(a00); - - // Restrict the corner radius according to the sector angle. - if (da < pi$2) { - var oc = da0 > epsilon$1 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10], - ax = x01 - oc[0], - ay = y01 - oc[1], - bx = x11 - oc[0], - by = y11 - oc[1], - kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), - lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]); - rc0 = Math.min(rc, (r0 - lc) / (kc - 1)); - rc1 = Math.min(rc, (r1 - lc) / (kc + 1)); - } - } - - // Is the sector collapsed to a line? - if (!(da1 > epsilon$1)) context.moveTo(x01, y01); - - // Does the sector’s outer ring have rounded corners? - else if (rc1 > epsilon$1) { - t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); - t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); - - context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); - - // Have the corners merged? - if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw); + function touchmoved() { + var touches$$1 = exports.event.changedTouches, + n = touches$$1.length, i, gesture; - // Otherwise, draw the two corners and the ring. - else { - context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw); - context.arc(0, 0, r1, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw); - context.arc(t1.cx, t1.cy, rc1, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw); - } + for (i = 0; i < n; ++i) { + if (gesture = gestures[touches$$1[i].identifier]) { + noevent(); + gesture("drag"); } + } + } - // Or is the outer ring just a circular arc? - else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); - - // Is there no inner ring, and it’s a circular sector? - // Or perhaps it’s an annular sector collapsed due to padding? - if (!(r0 > epsilon$1) || !(da0 > epsilon$1)) context.lineTo(x10, y10); - - // Does the sector’s inner ring (or point) have rounded corners? - else if (rc0 > epsilon$1) { - t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); - t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); - - context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); - - // Have the corners merged? - if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw); + function touchended() { + var touches$$1 = exports.event.changedTouches, + n = touches$$1.length, i, gesture; - // Otherwise, draw the two corners and the ring. - else { - context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw); - context.arc(0, 0, r0, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw); - context.arc(t1.cx, t1.cy, rc0, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw); - } + if (touchending) clearTimeout(touchending); + touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! + for (i = 0; i < n; ++i) { + if (gesture = gestures[touches$$1[i].identifier]) { + nopropagation(); + gesture("end"); } - - // Or is the inner ring just a circular arc? - else context.arc(0, 0, r0, a10, a00, cw); } - - context.closePath(); - - if (buffer) return context = null, buffer + "" || null; } - arc.centroid = function() { - var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, - a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$2 / 2; - return [Math.cos(a) * r, Math.sin(a) * r]; - }; - - arc.innerRadius = function(_) { - return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : innerRadius; - }; - - arc.outerRadius = function(_) { - return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : outerRadius; - }; + function beforestart(id, container, point, that, args) { + var p = point(container, id), s, dx, dy, + sublisteners = listeners.copy(); - arc.cornerRadius = function(_) { - return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : cornerRadius; - }; + if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { + if ((exports.event.subject = s = subject.apply(that, args)) == null) return false; + dx = s.x - p[0] || 0; + dy = s.y - p[1] || 0; + return true; + })) return; - arc.padRadius = function(_) { - return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), arc) : padRadius; - }; + return function gesture(type) { + var p0 = p, n; + switch (type) { + case "start": gestures[id] = gesture, n = active++; break; + case "end": delete gestures[id], --active; // nobreak + case "drag": p = point(container, id), n = active; break; + } + customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); + }; + } - arc.startAngle = function(_) { - return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : startAngle; + drag.filter = function(_) { + return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter; }; - arc.endAngle = function(_) { - return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : endAngle; + drag.container = function(_) { + return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container; }; - arc.padAngle = function(_) { - return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : padAngle; + drag.subject = function(_) { + return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject; }; - arc.context = function(_) { - return arguments.length ? ((context = _ == null ? null : _), arc) : context; + drag.on = function() { + var value = listeners.on.apply(listeners, arguments); + return value === listeners ? drag : value; }; - return arc; -}; - -function Linear(context) { - this._context = context; -} - -Linear.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._point = 0; - }, - lineEnd: function() { - if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; - case 1: this._point = 2; // proceed - default: this._context.lineTo(x, y); break; - } - } + return drag; }; -var curveLinear = function(context) { - return new Linear(context); +var define = function(constructor, factory, prototype) { + constructor.prototype = factory.prototype = prototype; + prototype.constructor = constructor; }; -function x(p) { - return p[0]; -} - -function y(p) { - return p[1]; +function extend(parent, definition) { + var prototype = Object.create(parent.prototype); + for (var key in definition) prototype[key] = definition[key]; + return prototype; } -var line = function() { - var x$$1 = x, - y$$1 = y, - defined = constant$2(true), - context = null, - curve = curveLinear, - output = null; - - function line(data) { - var i, - n = data.length, - d, - defined0 = false, - buffer; +function Color() {} - if (context == null) output = curve(buffer = path()); +var darker = 0.7; +var brighter = 1 / darker; - for (i = 0; i <= n; ++i) { - if (!(i < n && defined(d = data[i], i, data)) === defined0) { - if (defined0 = !defined0) output.lineStart(); - else output.lineEnd(); - } - if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data)); - } +var reI = "\\s*([+-]?\\d+)\\s*"; +var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*"; +var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*"; +var reHex3 = /^#([0-9a-f]{3})$/; +var reHex6 = /^#([0-9a-f]{6})$/; +var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"); +var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"); +var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"); +var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"); +var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"); +var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); - if (buffer) return output = null, buffer + "" || null; - } - - line.x = function(_) { - return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$2(+_), line) : x$$1; - }; - - line.y = function(_) { - return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$2(+_), line) : y$$1; - }; - - line.defined = function(_) { - return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), line) : defined; - }; - - line.curve = function(_) { - return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve; - }; - - line.context = function(_) { - return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; - }; - - return line; -}; - -var area$1 = function() { - var x0 = x, - x1 = null, - y0 = constant$2(0), - y1 = y, - defined = constant$2(true), - context = null, - curve = curveLinear, - output = null; - - function area(data) { - var i, - j, - k, - n = data.length, - d, - defined0 = false, - buffer, - x0z = new Array(n), - y0z = new Array(n); - - if (context == null) output = curve(buffer = path()); - - for (i = 0; i <= n; ++i) { - if (!(i < n && defined(d = data[i], i, data)) === defined0) { - if (defined0 = !defined0) { - j = i; - output.areaStart(); - output.lineStart(); - } else { - output.lineEnd(); - output.lineStart(); - for (k = i - 1; k >= j; --k) { - output.point(x0z[k], y0z[k]); - } - output.lineEnd(); - output.areaEnd(); - } - } - if (defined0) { - x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data); - output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]); - } - } - - if (buffer) return output = null, buffer + "" || null; - } - - function arealine() { - return line().defined(defined).curve(curve).context(context); - } - - area.x = function(_) { - return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$2(+_), x1 = null, area) : x0; - }; - - area.x0 = function(_) { - return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$2(+_), area) : x0; - }; - - area.x1 = function(_) { - return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), area) : x1; - }; - - area.y = function(_) { - return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$2(+_), y1 = null, area) : y0; - }; - - area.y0 = function(_) { - return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$2(+_), area) : y0; - }; - - area.y1 = function(_) { - return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), area) : y1; - }; - - area.lineX0 = - area.lineY0 = function() { - return arealine().x(x0).y(y0); - }; - - area.lineY1 = function() { - return arealine().x(x0).y(y1); - }; - - area.lineX1 = function() { - return arealine().x(x1).y(y0); - }; - - area.defined = function(_) { - return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), area) : defined; - }; - - area.curve = function(_) { - return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve; - }; - - area.context = function(_) { - return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context; - }; - - return area; -}; - -var descending$1 = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; -}; - -var identity$1 = function(d) { - return d; -}; - -var pie = function() { - var value = identity$1, - sortValues = descending$1, - sort = null, - startAngle = constant$2(0), - endAngle = constant$2(tau$2), - padAngle = constant$2(0); - - function pie(data) { - var i, - n = data.length, - j, - k, - sum = 0, - index = new Array(n), - arcs = new Array(n), - a0 = +startAngle.apply(this, arguments), - da = Math.min(tau$2, Math.max(-tau$2, endAngle.apply(this, arguments) - a0)), - a1, - p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)), - pa = p * (da < 0 ? -1 : 1), - v; - - for (i = 0; i < n; ++i) { - if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) { - sum += v; - } - } - - // Optionally sort the arcs by previously-computed values or by data. - if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); }); - else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); }); - - // Compute the arcs! They are stored in the original data's order. - for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) { - j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = { - data: data[j], - index: i, - value: v, - startAngle: a0, - endAngle: a1, - padAngle: p - }; - } +var named = { + aliceblue: 0xf0f8ff, + antiquewhite: 0xfaebd7, + aqua: 0x00ffff, + aquamarine: 0x7fffd4, + azure: 0xf0ffff, + beige: 0xf5f5dc, + bisque: 0xffe4c4, + black: 0x000000, + blanchedalmond: 0xffebcd, + blue: 0x0000ff, + blueviolet: 0x8a2be2, + brown: 0xa52a2a, + burlywood: 0xdeb887, + cadetblue: 0x5f9ea0, + chartreuse: 0x7fff00, + chocolate: 0xd2691e, + coral: 0xff7f50, + cornflowerblue: 0x6495ed, + cornsilk: 0xfff8dc, + crimson: 0xdc143c, + cyan: 0x00ffff, + darkblue: 0x00008b, + darkcyan: 0x008b8b, + darkgoldenrod: 0xb8860b, + darkgray: 0xa9a9a9, + darkgreen: 0x006400, + darkgrey: 0xa9a9a9, + darkkhaki: 0xbdb76b, + darkmagenta: 0x8b008b, + darkolivegreen: 0x556b2f, + darkorange: 0xff8c00, + darkorchid: 0x9932cc, + darkred: 0x8b0000, + darksalmon: 0xe9967a, + darkseagreen: 0x8fbc8f, + darkslateblue: 0x483d8b, + darkslategray: 0x2f4f4f, + darkslategrey: 0x2f4f4f, + darkturquoise: 0x00ced1, + darkviolet: 0x9400d3, + deeppink: 0xff1493, + deepskyblue: 0x00bfff, + dimgray: 0x696969, + dimgrey: 0x696969, + dodgerblue: 0x1e90ff, + firebrick: 0xb22222, + floralwhite: 0xfffaf0, + forestgreen: 0x228b22, + fuchsia: 0xff00ff, + gainsboro: 0xdcdcdc, + ghostwhite: 0xf8f8ff, + gold: 0xffd700, + goldenrod: 0xdaa520, + gray: 0x808080, + green: 0x008000, + greenyellow: 0xadff2f, + grey: 0x808080, + honeydew: 0xf0fff0, + hotpink: 0xff69b4, + indianred: 0xcd5c5c, + indigo: 0x4b0082, + ivory: 0xfffff0, + khaki: 0xf0e68c, + lavender: 0xe6e6fa, + lavenderblush: 0xfff0f5, + lawngreen: 0x7cfc00, + lemonchiffon: 0xfffacd, + lightblue: 0xadd8e6, + lightcoral: 0xf08080, + lightcyan: 0xe0ffff, + lightgoldenrodyellow: 0xfafad2, + lightgray: 0xd3d3d3, + lightgreen: 0x90ee90, + lightgrey: 0xd3d3d3, + lightpink: 0xffb6c1, + lightsalmon: 0xffa07a, + lightseagreen: 0x20b2aa, + lightskyblue: 0x87cefa, + lightslategray: 0x778899, + lightslategrey: 0x778899, + lightsteelblue: 0xb0c4de, + lightyellow: 0xffffe0, + lime: 0x00ff00, + limegreen: 0x32cd32, + linen: 0xfaf0e6, + magenta: 0xff00ff, + maroon: 0x800000, + mediumaquamarine: 0x66cdaa, + mediumblue: 0x0000cd, + mediumorchid: 0xba55d3, + mediumpurple: 0x9370db, + mediumseagreen: 0x3cb371, + mediumslateblue: 0x7b68ee, + mediumspringgreen: 0x00fa9a, + mediumturquoise: 0x48d1cc, + mediumvioletred: 0xc71585, + midnightblue: 0x191970, + mintcream: 0xf5fffa, + mistyrose: 0xffe4e1, + moccasin: 0xffe4b5, + navajowhite: 0xffdead, + navy: 0x000080, + oldlace: 0xfdf5e6, + olive: 0x808000, + olivedrab: 0x6b8e23, + orange: 0xffa500, + orangered: 0xff4500, + orchid: 0xda70d6, + palegoldenrod: 0xeee8aa, + palegreen: 0x98fb98, + paleturquoise: 0xafeeee, + palevioletred: 0xdb7093, + papayawhip: 0xffefd5, + peachpuff: 0xffdab9, + peru: 0xcd853f, + pink: 0xffc0cb, + plum: 0xdda0dd, + powderblue: 0xb0e0e6, + purple: 0x800080, + rebeccapurple: 0x663399, + red: 0xff0000, + rosybrown: 0xbc8f8f, + royalblue: 0x4169e1, + saddlebrown: 0x8b4513, + salmon: 0xfa8072, + sandybrown: 0xf4a460, + seagreen: 0x2e8b57, + seashell: 0xfff5ee, + sienna: 0xa0522d, + silver: 0xc0c0c0, + skyblue: 0x87ceeb, + slateblue: 0x6a5acd, + slategray: 0x708090, + slategrey: 0x708090, + snow: 0xfffafa, + springgreen: 0x00ff7f, + steelblue: 0x4682b4, + tan: 0xd2b48c, + teal: 0x008080, + thistle: 0xd8bfd8, + tomato: 0xff6347, + turquoise: 0x40e0d0, + violet: 0xee82ee, + wheat: 0xf5deb3, + white: 0xffffff, + whitesmoke: 0xf5f5f5, + yellow: 0xffff00, + yellowgreen: 0x9acd32 +}; - return arcs; +define(Color, color, { + displayable: function() { + return this.rgb().displayable(); + }, + toString: function() { + return this.rgb() + ""; } +}); - pie.value = function(_) { - return arguments.length ? (value = typeof _ === "function" ? _ : constant$2(+_), pie) : value; - }; - - pie.sortValues = function(_) { - return arguments.length ? (sortValues = _, sort = null, pie) : sortValues; - }; - - pie.sort = function(_) { - return arguments.length ? (sort = _, sortValues = null, pie) : sort; - }; - - pie.startAngle = function(_) { - return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : startAngle; - }; +function color(format) { + var m; + format = (format + "").trim().toLowerCase(); + return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00 + : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000 + : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) + : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) + : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) + : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) + : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) + : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) + : named.hasOwnProperty(format) ? rgbn(named[format]) + : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) + : null; +} - pie.endAngle = function(_) { - return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : endAngle; - }; +function rgbn(n) { + return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); +} - pie.padAngle = function(_) { - return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : padAngle; - }; +function rgba(r, g, b, a) { + if (a <= 0) r = g = b = NaN; + return new Rgb(r, g, b, a); +} - return pie; -}; +function rgbConvert(o) { + if (!(o instanceof Color)) o = color(o); + if (!o) return new Rgb; + o = o.rgb(); + return new Rgb(o.r, o.g, o.b, o.opacity); +} -var curveRadialLinear = curveRadial(curveLinear); +function rgb(r, g, b, opacity) { + return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); +} -function Radial(curve) { - this._curve = curve; +function Rgb(r, g, b, opacity) { + this.r = +r; + this.g = +g; + this.b = +b; + this.opacity = +opacity; } -Radial.prototype = { - areaStart: function() { - this._curve.areaStart(); +define(Rgb, rgb, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, - areaEnd: function() { - this._curve.areaEnd(); + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, - lineStart: function() { - this._curve.lineStart(); + rgb: function() { + return this; }, - lineEnd: function() { - this._curve.lineEnd(); + displayable: function() { + return (0 <= this.r && this.r <= 255) + && (0 <= this.g && this.g <= 255) + && (0 <= this.b && this.b <= 255) + && (0 <= this.opacity && this.opacity <= 1); }, - point: function(a, r) { - this._curve.point(r * Math.sin(a), r * -Math.cos(a)); + toString: function() { + var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); + return (a === 1 ? "rgb(" : "rgba(") + + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + + (a === 1 ? ")" : ", " + a + ")"); } -}; +})); -function curveRadial(curve) { +function hsla(h, s, l, a) { + if (a <= 0) h = s = l = NaN; + else if (l <= 0 || l >= 1) h = s = NaN; + else if (s <= 0) h = NaN; + return new Hsl(h, s, l, a); +} - function radial(context) { - return new Radial(curve(context)); +function hslConvert(o) { + if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); + if (!(o instanceof Color)) o = color(o); + if (!o) return new Hsl; + if (o instanceof Hsl) return o; + o = o.rgb(); + var r = o.r / 255, + g = o.g / 255, + b = o.b / 255, + min = Math.min(r, g, b), + max = Math.max(r, g, b), + h = NaN, + s = max - min, + l = (max + min) / 2; + if (s) { + if (r === max) h = (g - b) / s + (g < b) * 6; + else if (g === max) h = (b - r) / s + 2; + else h = (r - g) / s + 4; + s /= l < 0.5 ? max + min : 2 - max - min; + h *= 60; + } else { + s = l > 0 && l < 1 ? 0 : h; } - - radial._curve = curve; - - return radial; + return new Hsl(h, s, l, o.opacity); } -function radialLine(l) { - var c = l.curve; - - l.angle = l.x, delete l.x; - l.radius = l.y, delete l.y; - - l.curve = function(_) { - return arguments.length ? c(curveRadial(_)) : c()._curve; - }; - - return l; +function hsl(h, s, l, opacity) { + return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); } -var radialLine$1 = function() { - return radialLine(line().curve(curveRadialLinear)); -}; - -var radialArea = function() { - var a = area$1().curve(curveRadialLinear), - c = a.curve, - x0 = a.lineX0, - x1 = a.lineX1, - y0 = a.lineY0, - y1 = a.lineY1; - - a.angle = a.x, delete a.x; - a.startAngle = a.x0, delete a.x0; - a.endAngle = a.x1, delete a.x1; - a.radius = a.y, delete a.y; - a.innerRadius = a.y0, delete a.y0; - a.outerRadius = a.y1, delete a.y1; - a.lineStartAngle = function() { return radialLine(x0()); }, delete a.lineX0; - a.lineEndAngle = function() { return radialLine(x1()); }, delete a.lineX1; - a.lineInnerRadius = function() { return radialLine(y0()); }, delete a.lineY0; - a.lineOuterRadius = function() { return radialLine(y1()); }, delete a.lineY1; - - a.curve = function(_) { - return arguments.length ? c(curveRadial(_)) : c()._curve; - }; - - return a; -}; - -var circle = { - draw: function(context, size) { - var r = Math.sqrt(size / pi$2); - context.moveTo(r, 0); - context.arc(0, 0, r, 0, tau$2); - } -}; - -var cross$1 = { - draw: function(context, size) { - var r = Math.sqrt(size / 5) / 2; - context.moveTo(-3 * r, -r); - context.lineTo(-r, -r); - context.lineTo(-r, -3 * r); - context.lineTo(r, -3 * r); - context.lineTo(r, -r); - context.lineTo(3 * r, -r); - context.lineTo(3 * r, r); - context.lineTo(r, r); - context.lineTo(r, 3 * r); - context.lineTo(-r, 3 * r); - context.lineTo(-r, r); - context.lineTo(-3 * r, r); - context.closePath(); - } -}; - -var tan30 = Math.sqrt(1 / 3); -var tan30_2 = tan30 * 2; - -var diamond = { - draw: function(context, size) { - var y = Math.sqrt(size / tan30_2), - x = y * tan30; - context.moveTo(0, -y); - context.lineTo(x, 0); - context.lineTo(0, y); - context.lineTo(-x, 0); - context.closePath(); - } -}; - -var ka = 0.89081309152928522810; -var kr = Math.sin(pi$2 / 10) / Math.sin(7 * pi$2 / 10); -var kx = Math.sin(tau$2 / 10) * kr; -var ky = -Math.cos(tau$2 / 10) * kr; - -var star = { - draw: function(context, size) { - var r = Math.sqrt(size * ka), - x = kx * r, - y = ky * r; - context.moveTo(0, -r); - context.lineTo(x, y); - for (var i = 1; i < 5; ++i) { - var a = tau$2 * i / 5, - c = Math.cos(a), - s = Math.sin(a); - context.lineTo(s * r, -c * r); - context.lineTo(c * x - s * y, s * x + c * y); - } - context.closePath(); - } -}; +function Hsl(h, s, l, opacity) { + this.h = +h; + this.s = +s; + this.l = +l; + this.opacity = +opacity; +} -var square = { - draw: function(context, size) { - var w = Math.sqrt(size), - x = -w / 2; - context.rect(x, x, w, w); +define(Hsl, hsl, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Hsl(this.h, this.s, this.l * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Hsl(this.h, this.s, this.l * k, this.opacity); + }, + rgb: function() { + var h = this.h % 360 + (this.h < 0) * 360, + s = isNaN(h) || isNaN(this.s) ? 0 : this.s, + l = this.l, + m2 = l + (l < 0.5 ? l : 1 - l) * s, + m1 = 2 * l - m2; + return new Rgb( + hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), + hsl2rgb(h, m1, m2), + hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), + this.opacity + ); + }, + displayable: function() { + return (0 <= this.s && this.s <= 1 || isNaN(this.s)) + && (0 <= this.l && this.l <= 1) + && (0 <= this.opacity && this.opacity <= 1); } -}; +})); -var sqrt3 = Math.sqrt(3); +/* From FvD 13.37, CSS Color Module Level 3 */ +function hsl2rgb(h, m1, m2) { + return (h < 60 ? m1 + (m2 - m1) * h / 60 + : h < 180 ? m2 + : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 + : m1) * 255; +} -var triangle = { - draw: function(context, size) { - var y = -Math.sqrt(size / (sqrt3 * 3)); - context.moveTo(0, y * 2); - context.lineTo(-sqrt3 * y, -y); - context.lineTo(sqrt3 * y, -y); - context.closePath(); - } -}; +var deg2rad = Math.PI / 180; +var rad2deg = 180 / Math.PI; -var c = -0.5; -var s = Math.sqrt(3) / 2; -var k = 1 / Math.sqrt(12); -var a = (k / 2 + 1) * 3; +var Kn = 18; +var Xn = 0.950470; +var Yn = 1; +var Zn = 1.088830; +var t0 = 4 / 29; +var t1 = 6 / 29; +var t2 = 3 * t1 * t1; +var t3 = t1 * t1 * t1; -var wye = { - draw: function(context, size) { - var r = Math.sqrt(size / a), - x0 = r / 2, - y0 = r * k, - x1 = x0, - y1 = r * k + r, - x2 = -x1, - y2 = y1; - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - context.lineTo(c * x0 - s * y0, s * x0 + c * y0); - context.lineTo(c * x1 - s * y1, s * x1 + c * y1); - context.lineTo(c * x2 - s * y2, s * x2 + c * y2); - context.lineTo(c * x0 + s * y0, c * y0 - s * x0); - context.lineTo(c * x1 + s * y1, c * y1 - s * x1); - context.lineTo(c * x2 + s * y2, c * y2 - s * x2); - context.closePath(); +function labConvert(o) { + if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); + if (o instanceof Hcl) { + var h = o.h * deg2rad; + return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); } -}; + if (!(o instanceof Rgb)) o = rgbConvert(o); + var b = rgb2xyz(o.r), + a = rgb2xyz(o.g), + l = rgb2xyz(o.b), + x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn), + y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn), + z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn); + return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); +} -var symbols = [ - circle, - cross$1, - diamond, - square, - star, - triangle, - wye -]; +function lab(l, a, b, opacity) { + return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); +} -var symbol = function() { - var type = constant$2(circle), - size = constant$2(64), - context = null; +function Lab(l, a, b, opacity) { + this.l = +l; + this.a = +a; + this.b = +b; + this.opacity = +opacity; +} - function symbol() { - var buffer; - if (!context) context = buffer = path(); - type.apply(this, arguments).draw(context, +size.apply(this, arguments)); - if (buffer) return context = null, buffer + "" || null; +define(Lab, lab, extend(Color, { + brighter: function(k) { + return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); + }, + darker: function(k) { + return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); + }, + rgb: function() { + var y = (this.l + 16) / 116, + x = isNaN(this.a) ? y : y + this.a / 500, + z = isNaN(this.b) ? y : y - this.b / 200; + y = Yn * lab2xyz(y); + x = Xn * lab2xyz(x); + z = Zn * lab2xyz(z); + return new Rgb( + xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB + xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), + xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z), + this.opacity + ); } +})); - symbol.type = function(_) { - return arguments.length ? (type = typeof _ === "function" ? _ : constant$2(_), symbol) : type; - }; +function xyz2lab(t) { + return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; +} - symbol.size = function(_) { - return arguments.length ? (size = typeof _ === "function" ? _ : constant$2(+_), symbol) : size; - }; +function lab2xyz(t) { + return t > t1 ? t * t * t : t2 * (t - t0); +} - symbol.context = function(_) { - return arguments.length ? (context = _ == null ? null : _, symbol) : context; - }; +function xyz2rgb(x) { + return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); +} - return symbol; -}; +function rgb2xyz(x) { + return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); +} -var noop = function() {}; +function hclConvert(o) { + if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); + if (!(o instanceof Lab)) o = labConvert(o); + var h = Math.atan2(o.b, o.a) * rad2deg; + return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); +} -function point(that, x, y) { - that._context.bezierCurveTo( - (2 * that._x0 + that._x1) / 3, - (2 * that._y0 + that._y1) / 3, - (that._x0 + 2 * that._x1) / 3, - (that._y0 + 2 * that._y1) / 3, - (that._x0 + 4 * that._x1 + x) / 6, - (that._y0 + 4 * that._y1 + y) / 6 - ); +function hcl(h, c, l, opacity) { + return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); } -function Basis(context) { - this._context = context; +function Hcl(h, c, l, opacity) { + this.h = +h; + this.c = +c; + this.l = +l; + this.opacity = +opacity; } -Basis.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x0 = this._x1 = - this._y0 = this._y1 = NaN; - this._point = 0; +define(Hcl, hcl, extend(Color, { + brighter: function(k) { + return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity); }, - lineEnd: function() { - switch (this._point) { - case 3: point(this, this._x1, this._y1); // proceed - case 2: this._context.lineTo(this._x1, this._y1); break; - } - if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); - this._line = 1 - this._line; + darker: function(k) { + return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity); }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; - case 1: this._point = 2; break; - case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed - default: point(this, x, y); break; - } - this._x0 = this._x1, this._x1 = x; - this._y0 = this._y1, this._y1 = y; + rgb: function() { + return labConvert(this).rgb(); } -}; +})); -var basis = function(context) { - return new Basis(context); -}; +var A = -0.14861; +var B = +1.78277; +var C = -0.29227; +var D = -0.90649; +var E = +1.97294; +var ED = E * D; +var EB = E * B; +var BC_DA = B * C - D * A; -function BasisClosed(context) { - this._context = context; +function cubehelixConvert(o) { + if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); + if (!(o instanceof Rgb)) o = rgbConvert(o); + var r = o.r / 255, + g = o.g / 255, + b = o.b / 255, + l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), + bl = b - l, + k = (E * (g - l) - C * bl) / D, + s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 + h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; + return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); +} + +function cubehelix(h, s, l, opacity) { + return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); +} + +function Cubehelix(h, s, l, opacity) { + this.h = +h; + this.s = +s; + this.l = +l; + this.opacity = +opacity; } -BasisClosed.prototype = { - areaStart: noop, - areaEnd: noop, - lineStart: function() { - this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = - this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN; - this._point = 0; +define(Cubehelix, cubehelix, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Cubehelix(this.h, this.s, this.l * k, this.opacity); }, - lineEnd: function() { - switch (this._point) { - case 1: { - this._context.moveTo(this._x2, this._y2); - this._context.closePath(); - break; - } - case 2: { - this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3); - this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3); - this._context.closePath(); - break; - } - case 3: { - this.point(this._x2, this._y2); - this.point(this._x3, this._y3); - this.point(this._x4, this._y4); - break; - } - } + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Cubehelix(this.h, this.s, this.l * k, this.opacity); }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; this._x2 = x, this._y2 = y; break; - case 1: this._point = 2; this._x3 = x, this._y3 = y; break; - case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break; - default: point(this, x, y); break; - } - this._x0 = this._x1, this._x1 = x; - this._y0 = this._y1, this._y1 = y; + rgb: function() { + var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, + l = +this.l, + a = isNaN(this.s) ? 0 : this.s * l * (1 - l), + cosh = Math.cos(h), + sinh = Math.sin(h); + return new Rgb( + 255 * (l + a * (A * cosh + B * sinh)), + 255 * (l + a * (C * cosh + D * sinh)), + 255 * (l + a * (E * cosh)), + this.opacity + ); } +})); + +function basis(t1, v0, v1, v2, v3) { + var t2 = t1 * t1, t3 = t2 * t1; + return ((1 - 3 * t1 + 3 * t2 - t3) * v0 + + (4 - 6 * t2 + 3 * t3) * v1 + + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + + t3 * v3) / 6; +} + +var basis$1 = function(values) { + var n = values.length - 1; + return function(t) { + var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), + v1 = values[i], + v2 = values[i + 1], + v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, + v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; + return basis((t - i / n) * n, v0, v1, v2, v3); + }; }; -var basisClosed = function(context) { - return new BasisClosed(context); +var basisClosed = function(values) { + var n = values.length; + return function(t) { + var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), + v0 = values[(i + n - 1) % n], + v1 = values[i % n], + v2 = values[(i + 1) % n], + v3 = values[(i + 2) % n]; + return basis((t - i / n) * n, v0, v1, v2, v3); + }; }; -function BasisOpen(context) { - this._context = context; +var constant$3 = function(x) { + return function() { + return x; + }; +}; + +function linear(a, d) { + return function(t) { + return a + t * d; + }; } -BasisOpen.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x0 = this._x1 = - this._y0 = this._y1 = NaN; - this._point = 0; - }, - lineEnd: function() { - if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; break; - case 1: this._point = 2; break; - case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break; - case 3: this._point = 4; // proceed - default: point(this, x, y); break; - } - this._x0 = this._x1, this._x1 = x; - this._y0 = this._y1, this._y1 = y; - } -}; +function exponential(a, b, y) { + return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { + return Math.pow(a + t * b, y); + }; +} -var basisOpen = function(context) { - return new BasisOpen(context); -}; +function hue(a, b) { + var d = b - a; + return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a); +} -function Bundle(context, beta) { - this._basis = new Basis(context); - this._beta = beta; +function gamma(y) { + return (y = +y) === 1 ? nogamma : function(a, b) { + return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a); + }; } -Bundle.prototype = { - lineStart: function() { - this._x = []; - this._y = []; - this._basis.lineStart(); - }, - lineEnd: function() { - var x = this._x, - y = this._y, - j = x.length - 1; +function nogamma(a, b) { + var d = b - a; + return d ? linear(a, d) : constant$3(isNaN(a) ? b : a); +} - if (j > 0) { - var x0 = x[0], - y0 = y[0], - dx = x[j] - x0, - dy = y[j] - y0, - i = -1, - t; +var interpolateRgb = ((function rgbGamma(y) { + var color$$1 = gamma(y); - while (++i <= j) { - t = i / j; - this._basis.point( - this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), - this._beta * y[i] + (1 - this._beta) * (y0 + t * dy) - ); - } + function rgb$$1(start, end) { + var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r), + g = color$$1(start.g, end.g), + b = color$$1(start.b, end.b), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.r = r(t); + start.g = g(t); + start.b = b(t); + start.opacity = opacity(t); + return start + ""; + }; + } + + rgb$$1.gamma = rgbGamma; + + return rgb$$1; +}))(1); + +function rgbSpline(spline) { + return function(colors) { + var n = colors.length, + r = new Array(n), + g = new Array(n), + b = new Array(n), + i, color$$1; + for (i = 0; i < n; ++i) { + color$$1 = rgb(colors[i]); + r[i] = color$$1.r || 0; + g[i] = color$$1.g || 0; + b[i] = color$$1.b || 0; } + r = spline(r); + g = spline(g); + b = spline(b); + color$$1.opacity = 1; + return function(t) { + color$$1.r = r(t); + color$$1.g = g(t); + color$$1.b = b(t); + return color$$1 + ""; + }; + }; +} - this._x = this._y = null; - this._basis.lineEnd(); - }, - point: function(x, y) { - this._x.push(+x); - this._y.push(+y); - } -}; +var rgbBasis = rgbSpline(basis$1); +var rgbBasisClosed = rgbSpline(basisClosed); -var bundle = (function custom(beta) { +var array$1 = function(a, b) { + var nb = b ? b.length : 0, + na = a ? Math.min(nb, a.length) : 0, + x = new Array(nb), + c = new Array(nb), + i; - function bundle(context) { - return beta === 1 ? new Basis(context) : new Bundle(context, beta); - } + for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]); + for (; i < nb; ++i) c[i] = b[i]; - bundle.beta = function(beta) { - return custom(+beta); + return function(t) { + for (i = 0; i < na; ++i) c[i] = x[i](t); + return c; }; +}; - return bundle; -})(0.85); +var date = function(a, b) { + var d = new Date; + return a = +a, b -= a, function(t) { + return d.setTime(a + b * t), d; + }; +}; -function point$1(that, x, y) { - that._context.bezierCurveTo( - that._x1 + that._k * (that._x2 - that._x0), - that._y1 + that._k * (that._y2 - that._y0), - that._x2 + that._k * (that._x1 - x), - that._y2 + that._k * (that._y1 - y), - that._x2, - that._y2 - ); -} +var reinterpolate = function(a, b) { + return a = +a, b -= a, function(t) { + return a + b * t; + }; +}; -function Cardinal(context, tension) { - this._context = context; - this._k = (1 - tension) / 6; -} +var object = function(a, b) { + var i = {}, + c = {}, + k; -Cardinal.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x0 = this._x1 = this._x2 = - this._y0 = this._y1 = this._y2 = NaN; - this._point = 0; - }, - lineEnd: function() { - switch (this._point) { - case 2: this._context.lineTo(this._x2, this._y2); break; - case 3: point$1(this, this._x1, this._y1); break; - } - if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; - case 1: this._point = 2; this._x1 = x, this._y1 = y; break; - case 2: this._point = 3; // proceed - default: point$1(this, x, y); break; + if (a === null || typeof a !== "object") a = {}; + if (b === null || typeof b !== "object") b = {}; + + for (k in b) { + if (k in a) { + i[k] = interpolateValue(a[k], b[k]); + } else { + c[k] = b[k]; } - this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; - this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } + + return function(t) { + for (k in i) c[k] = i[k](t); + return c; + }; }; -var cardinal = (function custom(tension) { +var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; +var reB = new RegExp(reA.source, "g"); - function cardinal(context) { - return new Cardinal(context, tension); - } +function zero(b) { + return function() { + return b; + }; +} - cardinal.tension = function(tension) { - return custom(+tension); +function one(b) { + return function(t) { + return b(t) + ""; }; +} - return cardinal; -})(0); +var interpolateString = function(a, b) { + var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b + am, // current match in a + bm, // current match in b + bs, // string preceding current number in b, if any + i = -1, // index in s + s = [], // string constants and placeholders + q = []; // number interpolators -function CardinalClosed(context, tension) { - this._context = context; - this._k = (1 - tension) / 6; -} + // Coerce inputs to strings. + a = a + "", b = b + ""; -CardinalClosed.prototype = { - areaStart: noop, - areaEnd: noop, - lineStart: function() { - this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = - this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; - this._point = 0; - }, - lineEnd: function() { - switch (this._point) { - case 1: { - this._context.moveTo(this._x3, this._y3); - this._context.closePath(); - break; - } - case 2: { - this._context.lineTo(this._x3, this._y3); - this._context.closePath(); - break; - } - case 3: { - this.point(this._x3, this._y3); - this.point(this._x4, this._y4); - this.point(this._x5, this._y5); - break; - } + // Interpolate pairs of numbers in a & b. + while ((am = reA.exec(a)) + && (bm = reB.exec(b))) { + if ((bs = bm.index) > bi) { // a string precedes the next number in b + bs = b.slice(bi, bs); + if (s[i]) s[i] += bs; // coalesce with previous string + else s[++i] = bs; } - }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; this._x3 = x, this._y3 = y; break; - case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; - case 2: this._point = 3; this._x5 = x, this._y5 = y; break; - default: point$1(this, x, y); break; + if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match + if (s[i]) s[i] += bm; // coalesce with previous string + else s[++i] = bm; + } else { // interpolate non-matching numbers + s[++i] = null; + q.push({i: i, x: reinterpolate(am, bm)}); } - this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; - this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + bi = reB.lastIndex; + } + + // Add remains of b. + if (bi < b.length) { + bs = b.slice(bi); + if (s[i]) s[i] += bs; // coalesce with previous string + else s[++i] = bs; } + + // Special optimization for only a single match. + // Otherwise, interpolate each of the numbers and rejoin the string. + return s.length < 2 ? (q[0] + ? one(q[0].x) + : zero(b)) + : (b = q.length, function(t) { + for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }); }; -var cardinalClosed = (function custom(tension) { +var interpolateValue = function(a, b) { + var t = typeof b, c; + return b == null || t === "boolean" ? constant$3(b) + : (t === "number" ? reinterpolate + : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString) + : b instanceof color ? interpolateRgb + : b instanceof Date ? date + : Array.isArray(b) ? array$1 + : isNaN(b) ? object + : reinterpolate)(a, b); +}; - function cardinal(context) { - return new CardinalClosed(context, tension); - } +var interpolateRound = function(a, b) { + return a = +a, b -= a, function(t) { + return Math.round(a + b * t); + }; +}; - cardinal.tension = function(tension) { - return custom(+tension); +var degrees = 180 / Math.PI; + +var identity$2 = { + translateX: 0, + translateY: 0, + rotate: 0, + skewX: 0, + scaleX: 1, + scaleY: 1 +}; + +var decompose = function(a, b, c, d, e, f) { + var scaleX, scaleY, skewX; + if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; + if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; + if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; + if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; + return { + translateX: e, + translateY: f, + rotate: Math.atan2(b, a) * degrees, + skewX: Math.atan(skewX) * degrees, + scaleX: scaleX, + scaleY: scaleY }; +}; - return cardinal; -})(0); +var cssNode; +var cssRoot; +var cssView; +var svgNode; -function CardinalOpen(context, tension) { - this._context = context; - this._k = (1 - tension) / 6; +function parseCss(value) { + if (value === "none") return identity$2; + if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; + cssNode.style.transform = value; + value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); + cssRoot.removeChild(cssNode); + value = value.slice(7, -1).split(","); + return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); } -CardinalOpen.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x0 = this._x1 = this._x2 = - this._y0 = this._y1 = this._y2 = NaN; - this._point = 0; - }, - lineEnd: function() { - if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; break; - case 1: this._point = 2; break; - case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; - case 3: this._point = 4; // proceed - default: point$1(this, x, y); break; +function parseSvg(value) { + if (value == null) return identity$2; + if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); + svgNode.setAttribute("transform", value); + if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2; + value = value.matrix; + return decompose(value.a, value.b, value.c, value.d, value.e, value.f); +} + +function interpolateTransform(parse, pxComma, pxParen, degParen) { + + function pop(s) { + return s.length ? s.pop() + " " : ""; + } + + function translate(xa, ya, xb, yb, s, q) { + if (xa !== xb || ya !== yb) { + var i = s.push("translate(", null, pxComma, null, pxParen); + q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)}); + } else if (xb || yb) { + s.push("translate(" + xb + pxComma + yb + pxParen); + } + } + + function rotate(a, b, s, q) { + if (a !== b) { + if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path + q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: reinterpolate(a, b)}); + } else if (b) { + s.push(pop(s) + "rotate(" + b + degParen); } - this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; - this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } -}; -var cardinalOpen = (function custom(tension) { + function skewX(a, b, s, q) { + if (a !== b) { + q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: reinterpolate(a, b)}); + } else if (b) { + s.push(pop(s) + "skewX(" + b + degParen); + } + } - function cardinal(context) { - return new CardinalOpen(context, tension); + function scale(xa, ya, xb, yb, s, q) { + if (xa !== xb || ya !== yb) { + var i = s.push(pop(s) + "scale(", null, ",", null, ")"); + q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)}); + } else if (xb !== 1 || yb !== 1) { + s.push(pop(s) + "scale(" + xb + "," + yb + ")"); + } } - cardinal.tension = function(tension) { - return custom(+tension); + return function(a, b) { + var s = [], // string constants and placeholders + q = []; // number interpolators + a = parse(a), b = parse(b); + translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); + rotate(a.rotate, b.rotate, s, q); + skewX(a.skewX, b.skewX, s, q); + scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); + a = b = null; // gc + return function(t) { + var i = -1, n = q.length, o; + while (++i < n) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; }; +} - return cardinal; -})(0); - -function point$2(that, x, y) { - var x1 = that._x1, - y1 = that._y1, - x2 = that._x2, - y2 = that._y2; - - if (that._l01_a > epsilon$1) { - var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a, - n = 3 * that._l01_a * (that._l01_a + that._l12_a); - x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n; - y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n; - } +var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); +var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); - if (that._l23_a > epsilon$1) { - var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a, - m = 3 * that._l23_a * (that._l23_a + that._l12_a); - x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m; - y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m; - } +var rho = Math.SQRT2; +var rho2 = 2; +var rho4 = 4; +var epsilon2 = 1e-12; - that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2); +function cosh(x) { + return ((x = Math.exp(x)) + 1 / x) / 2; } -function CatmullRom(context, alpha) { - this._context = context; - this._alpha = alpha; +function sinh(x) { + return ((x = Math.exp(x)) - 1 / x) / 2; } -CatmullRom.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x0 = this._x1 = this._x2 = - this._y0 = this._y1 = this._y2 = NaN; - this._l01_a = this._l12_a = this._l23_a = - this._l01_2a = this._l12_2a = this._l23_2a = - this._point = 0; - }, - lineEnd: function() { - switch (this._point) { - case 2: this._context.lineTo(this._x2, this._y2); break; - case 3: this.point(this._x2, this._y2); break; - } - if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; +function tanh(x) { + return ((x = Math.exp(2 * x)) - 1) / (x + 1); +} - if (this._point) { - var x23 = this._x2 - x, - y23 = this._y2 - y; - this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); - } +// p0 = [ux0, uy0, w0] +// p1 = [ux1, uy1, w1] +var interpolateZoom = function(p0, p1) { + var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], + ux1 = p1[0], uy1 = p1[1], w1 = p1[2], + dx = ux1 - ux0, + dy = uy1 - uy0, + d2 = dx * dx + dy * dy, + i, + S; - switch (this._point) { - case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; - case 1: this._point = 2; break; - case 2: this._point = 3; // proceed - default: point$2(this, x, y); break; - } + // Special case for u0 ≅ u1. + if (d2 < epsilon2) { + S = Math.log(w1 / w0) / rho; + i = function(t) { + return [ + ux0 + t * dx, + uy0 + t * dy, + w0 * Math.exp(rho * t * S) + ]; + }; + } - this._l01_a = this._l12_a, this._l12_a = this._l23_a; - this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; - this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; - this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + // General case. + else { + var d1 = Math.sqrt(d2), + b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), + b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), + r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), + r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); + S = (r1 - r0) / rho; + i = function(t) { + var s = t * S, + coshr0 = cosh(r0), + u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); + return [ + ux0 + u * dx, + uy0 + u * dy, + w0 * coshr0 / cosh(rho * s + r0) + ]; + }; } -}; -var catmullRom = (function custom(alpha) { + i.duration = S * 1000; - function catmullRom(context) { - return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0); - } + return i; +}; - catmullRom.alpha = function(alpha) { - return custom(+alpha); - }; +function hsl$1(hue$$1) { + return function(start, end) { + var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h), + s = nogamma(start.s, end.s), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.s = s(t); + start.l = l(t); + start.opacity = opacity(t); + return start + ""; + }; + } +} - return catmullRom; -})(0.5); +var hsl$2 = hsl$1(hue); +var hslLong = hsl$1(nogamma); -function CatmullRomClosed(context, alpha) { - this._context = context; - this._alpha = alpha; +function lab$1(start, end) { + var l = nogamma((start = lab(start)).l, (end = lab(end)).l), + a = nogamma(start.a, end.a), + b = nogamma(start.b, end.b), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.l = l(t); + start.a = a(t); + start.b = b(t); + start.opacity = opacity(t); + return start + ""; + }; } -CatmullRomClosed.prototype = { - areaStart: noop, - areaEnd: noop, - lineStart: function() { - this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = - this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; - this._l01_a = this._l12_a = this._l23_a = - this._l01_2a = this._l12_2a = this._l23_2a = - this._point = 0; - }, - lineEnd: function() { - switch (this._point) { - case 1: { - this._context.moveTo(this._x3, this._y3); - this._context.closePath(); - break; - } - case 2: { - this._context.lineTo(this._x3, this._y3); - this._context.closePath(); - break; - } - case 3: { - this.point(this._x3, this._y3); - this.point(this._x4, this._y4); - this.point(this._x5, this._y5); - break; - } - } - }, - point: function(x, y) { - x = +x, y = +y; +function hcl$1(hue$$1) { + return function(start, end) { + var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h), + c = nogamma(start.c, end.c), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.c = c(t); + start.l = l(t); + start.opacity = opacity(t); + return start + ""; + }; + } +} - if (this._point) { - var x23 = this._x2 - x, - y23 = this._y2 - y; - this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); - } +var hcl$2 = hcl$1(hue); +var hclLong = hcl$1(nogamma); - switch (this._point) { - case 0: this._point = 1; this._x3 = x, this._y3 = y; break; - case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; - case 2: this._point = 3; this._x5 = x, this._y5 = y; break; - default: point$2(this, x, y); break; - } +function cubehelix$1(hue$$1) { + return (function cubehelixGamma(y) { + y = +y; - this._l01_a = this._l12_a, this._l12_a = this._l23_a; - this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; - this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; - this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; - } -}; + function cubehelix$$1(start, end) { + var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h), + s = nogamma(start.s, end.s), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.s = s(t); + start.l = l(Math.pow(t, y)); + start.opacity = opacity(t); + return start + ""; + }; + } -var catmullRomClosed = (function custom(alpha) { + cubehelix$$1.gamma = cubehelixGamma; - function catmullRom(context) { - return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0); - } + return cubehelix$$1; + })(1); +} - catmullRom.alpha = function(alpha) { - return custom(+alpha); - }; +var cubehelix$2 = cubehelix$1(hue); +var cubehelixLong = cubehelix$1(nogamma); - return catmullRom; -})(0.5); +var quantize = function(interpolator, n) { + var samples = new Array(n); + for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); + return samples; +}; -function CatmullRomOpen(context, alpha) { - this._context = context; - this._alpha = alpha; +var frame = 0; +var timeout = 0; +var interval = 0; +var pokeDelay = 1000; +var taskHead; +var taskTail; +var clockLast = 0; +var clockNow = 0; +var clockSkew = 0; +var clock = typeof performance === "object" && performance.now ? performance : Date; +var setFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : function(f) { setTimeout(f, 17); }; + +function now() { + return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); } -CatmullRomOpen.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x0 = this._x1 = this._x2 = - this._y0 = this._y1 = this._y2 = NaN; - this._l01_a = this._l12_a = this._l23_a = - this._l01_2a = this._l12_2a = this._l23_2a = - this._point = 0; - }, - lineEnd: function() { - if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; +function clearNow() { + clockNow = 0; +} - if (this._point) { - var x23 = this._x2 - x, - y23 = this._y2 - y; - this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); - } +function Timer() { + this._call = + this._time = + this._next = null; +} - switch (this._point) { - case 0: this._point = 1; break; - case 1: this._point = 2; break; - case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; - case 3: this._point = 4; // proceed - default: point$2(this, x, y); break; +Timer.prototype = timer.prototype = { + constructor: Timer, + restart: function(callback, delay, time) { + if (typeof callback !== "function") throw new TypeError("callback is not a function"); + time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); + if (!this._next && taskTail !== this) { + if (taskTail) taskTail._next = this; + else taskHead = this; + taskTail = this; + } + this._call = callback; + this._time = time; + sleep(); + }, + stop: function() { + if (this._call) { + this._call = null; + this._time = Infinity; + sleep(); } - - this._l01_a = this._l12_a, this._l12_a = this._l23_a; - this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; - this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; - this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; -var catmullRomOpen = (function custom(alpha) { +function timer(callback, delay, time) { + var t = new Timer; + t.restart(callback, delay, time); + return t; +} - function catmullRom(context) { - return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0); +function timerFlush() { + now(); // Get the current time, if not already set. + ++frame; // Pretend we’ve set an alarm, if we haven’t already. + var t = taskHead, e; + while (t) { + if ((e = clockNow - t._time) >= 0) t._call.call(null, e); + t = t._next; } + --frame; +} - catmullRom.alpha = function(alpha) { - return custom(+alpha); - }; +function wake() { + clockNow = (clockLast = clock.now()) + clockSkew; + frame = timeout = 0; + try { + timerFlush(); + } finally { + frame = 0; + nap(); + clockNow = 0; + } +} - return catmullRom; -})(0.5); +function poke() { + var now = clock.now(), delay = now - clockLast; + if (delay > pokeDelay) clockSkew -= delay, clockLast = now; +} -function LinearClosed(context) { - this._context = context; +function nap() { + var t0, t1 = taskHead, t2, time = Infinity; + while (t1) { + if (t1._call) { + if (time > t1._time) time = t1._time; + t0 = t1, t1 = t1._next; + } else { + t2 = t1._next, t1._next = null; + t1 = t0 ? t0._next = t2 : taskHead = t2; + } + } + taskTail = t0; + sleep(time); } -LinearClosed.prototype = { - areaStart: noop, - areaEnd: noop, - lineStart: function() { - this._point = 0; - }, - lineEnd: function() { - if (this._point) this._context.closePath(); - }, - point: function(x, y) { - x = +x, y = +y; - if (this._point) this._context.lineTo(x, y); - else this._point = 1, this._context.moveTo(x, y); +function sleep(time) { + if (frame) return; // Soonest alarm already set, or will be. + if (timeout) timeout = clearTimeout(timeout); + var delay = time - clockNow; + if (delay > 24) { + if (time < Infinity) timeout = setTimeout(wake, delay); + if (interval) interval = clearInterval(interval); + } else { + if (!interval) clockLast = clockNow, interval = setInterval(poke, pokeDelay); + frame = 1, setFrame(wake); } +} + +var timeout$1 = function(callback, delay, time) { + var t = new Timer; + delay = delay == null ? 0 : +delay; + t.restart(function(elapsed) { + t.stop(); + callback(elapsed + delay); + }, delay, time); + return t; }; -var linearClosed = function(context) { - return new LinearClosed(context); +var interval$1 = function(callback, delay, time) { + var t = new Timer, total = delay; + if (delay == null) return t.restart(callback, delay, time), t; + delay = +delay, time = time == null ? now() : +time; + t.restart(function tick(elapsed) { + elapsed += total; + t.restart(tick, total += delay, time); + callback(elapsed); + }, delay, time); + return t; }; -function sign(x) { - return x < 0 ? -1 : 1; -} +var emptyOn = dispatch("start", "end", "interrupt"); +var emptyTween = []; -// Calculate the slopes of the tangents (Hermite-type interpolation) based on -// the following paper: Steffen, M. 1990. A Simple Method for Monotonic -// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO. -// NOV(II), P. 443, 1990. -function slope3(that, x2, y2) { - var h0 = that._x1 - that._x0, - h1 = x2 - that._x1, - s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0), - s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0), - p = (s0 * h1 + s1 * h0) / (h0 + h1); - return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0; -} +var CREATED = 0; +var SCHEDULED = 1; +var STARTING = 2; +var STARTED = 3; +var RUNNING = 4; +var ENDING = 5; +var ENDED = 6; -// Calculate a one-sided slope. -function slope2(that, t) { - var h = that._x1 - that._x0; - return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t; +var schedule = function(node, name, id, index, group, timing) { + var schedules = node.__transition; + if (!schedules) node.__transition = {}; + else if (id in schedules) return; + create(node, id, { + name: name, + index: index, // For context during callback. + group: group, // For context during callback. + on: emptyOn, + tween: emptyTween, + time: timing.time, + delay: timing.delay, + duration: timing.duration, + ease: timing.ease, + timer: null, + state: CREATED + }); +}; + +function init(node, id) { + var schedule = node.__transition; + if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late"); + return schedule; } -// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations -// "you can express cubic Hermite interpolation in terms of cubic Bézier curves -// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1". -function point$3(that, t0, t1) { - var x0 = that._x0, - y0 = that._y0, - x1 = that._x1, - y1 = that._y1, - dx = (x1 - x0) / 3; - that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1); +function set$1(node, id) { + var schedule = node.__transition; + if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late"); + return schedule; } -function MonotoneX(context) { - this._context = context; +function get$1(node, id) { + var schedule = node.__transition; + if (!schedule || !(schedule = schedule[id])) throw new Error("too late"); + return schedule; } -MonotoneX.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x0 = this._x1 = - this._y0 = this._y1 = - this._t0 = NaN; - this._point = 0; - }, - lineEnd: function() { - switch (this._point) { - case 2: this._context.lineTo(this._x1, this._y1); break; - case 3: point$3(this, this._t0, slope2(this, this._t0)); break; - } - if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - var t1 = NaN; +function create(node, id, self) { + var schedules = node.__transition, + tween; - x = +x, y = +y; - if (x === this._x1 && y === this._y1) return; // Ignore coincident points. - switch (this._point) { - case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; - case 1: this._point = 2; break; - case 2: this._point = 3; point$3(this, slope2(this, t1 = slope3(this, x, y)), t1); break; - default: point$3(this, this._t0, t1 = slope3(this, x, y)); break; - } + // Initialize the self timer when the transition is created. + // Note the actual delay is not known until the first callback! + schedules[id] = self; + self.timer = timer(schedule, 0, self.time); - this._x0 = this._x1, this._x1 = x; - this._y0 = this._y1, this._y1 = y; - this._t0 = t1; + function schedule(elapsed) { + self.state = SCHEDULED; + self.timer.restart(start, self.delay, self.time); + + // If the elapsed delay is less than our first sleep, start immediately. + if (self.delay <= elapsed) start(elapsed - self.delay); } -}; -function MonotoneY(context) { - this._context = new ReflectContext(context); -} + function start(elapsed) { + var i, j, n, o; -(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) { - MonotoneX.prototype.point.call(this, y, x); -}; + // If the state is not SCHEDULED, then we previously errored on start. + if (self.state !== SCHEDULED) return stop(); -function ReflectContext(context) { - this._context = context; -} + for (i in schedules) { + o = schedules[i]; + if (o.name !== self.name) continue; -ReflectContext.prototype = { - moveTo: function(x, y) { this._context.moveTo(y, x); }, - closePath: function() { this._context.closePath(); }, - lineTo: function(x, y) { this._context.lineTo(y, x); }, - bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); } -}; + // While this element already has a starting transition during this frame, + // defer starting an interrupting transition until that transition has a + // chance to tick (and possibly end); see d3/d3-transition#54! + if (o.state === STARTED) return timeout$1(start); -function monotoneX(context) { - return new MonotoneX(context); -} + // Interrupt the active transition, if any. + // Dispatch the interrupt event. + if (o.state === RUNNING) { + o.state = ENDED; + o.timer.stop(); + o.on.call("interrupt", node, node.__data__, o.index, o.group); + delete schedules[i]; + } -function monotoneY(context) { - return new MonotoneY(context); -} + // Cancel any pre-empted transitions. No interrupt event is dispatched + // because the cancelled transitions never started. Note that this also + // removes this transition from the pending list! + else if (+i < id) { + o.state = ENDED; + o.timer.stop(); + delete schedules[i]; + } + } -function Natural(context) { - this._context = context; -} + // Defer the first tick to end of the current frame; see d3/d3#1576. + // Note the transition may be canceled after start and before the first tick! + // Note this must be scheduled before the start event; see d3/d3-transition#16! + // Assuming this is successful, subsequent callbacks go straight to tick. + timeout$1(function() { + if (self.state === STARTED) { + self.state = RUNNING; + self.timer.restart(tick, self.delay, self.time); + tick(elapsed); + } + }); -Natural.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x = []; - this._y = []; - }, - lineEnd: function() { - var x = this._x, - y = this._y, - n = x.length; + // Dispatch the start event. + // Note this must be done before the tween are initialized. + self.state = STARTING; + self.on.call("start", node, node.__data__, self.index, self.group); + if (self.state !== STARTING) return; // interrupted + self.state = STARTED; - if (n) { - this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]); - if (n === 2) { - this._context.lineTo(x[1], y[1]); - } else { - var px = controlPoints(x), - py = controlPoints(y); - for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) { - this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]); - } + // Initialize the tween, deleting null tween. + tween = new Array(n = self.tween.length); + for (i = 0, j = -1; i < n; ++i) { + if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { + tween[++j] = o; } } + tween.length = j + 1; + } - if (this._line || (this._line !== 0 && n === 1)) this._context.closePath(); - this._line = 1 - this._line; - this._x = this._y = null; - }, - point: function(x, y) { - this._x.push(+x); - this._y.push(+y); + function tick(elapsed) { + var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), + i = -1, + n = tween.length; + + while (++i < n) { + tween[i].call(null, t); + } + + // Dispatch the end event. + if (self.state === ENDING) { + self.on.call("end", node, node.__data__, self.index, self.group); + stop(); + } } -}; -// See https://www.particleincell.com/2012/bezier-splines/ for derivation. -function controlPoints(x) { - var i, - n = x.length - 1, - m, - a = new Array(n), - b = new Array(n), - r = new Array(n); - a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1]; - for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1]; - a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n]; - for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1]; - a[n - 1] = r[n - 1] / b[n - 1]; - for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i]; - b[n - 1] = (x[n] + a[n - 1]) / 2; - for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1]; - return [a, b]; + function stop() { + self.state = ENDED; + self.timer.stop(); + delete schedules[id]; + for (var i in schedules) return; // eslint-disable-line no-unused-vars + delete node.__transition; + } } -var natural = function(context) { - return new Natural(context); -}; +var interrupt = function(node, name) { + var schedules = node.__transition, + schedule, + active, + empty = true, + i; -function Step(context, t) { - this._context = context; - this._t = t; -} + if (!schedules) return; -Step.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x = this._y = NaN; - this._point = 0; - }, - lineEnd: function() { - if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y); - if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); - if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; - case 1: this._point = 2; // proceed - default: { - if (this._t <= 0) { - this._context.lineTo(this._x, y); - this._context.lineTo(x, y); - } else { - var x1 = this._x * (1 - this._t) + x * this._t; - this._context.lineTo(x1, this._y); - this._context.lineTo(x1, y); - } - break; - } - } - this._x = x, this._y = y; + name = name == null ? null : name + ""; + + for (i in schedules) { + if ((schedule = schedules[i]).name !== name) { empty = false; continue; } + active = schedule.state > STARTING && schedule.state < ENDING; + schedule.state = ENDED; + schedule.timer.stop(); + if (active) schedule.on.call("interrupt", node, node.__data__, schedule.index, schedule.group); + delete schedules[i]; } + + if (empty) delete node.__transition; +}; + +var selection_interrupt = function(name) { + return this.each(function() { + interrupt(this, name); + }); }; -var step = function(context) { - return new Step(context, 0.5); -}; +function tweenRemove(id, name) { + var tween0, tween1; + return function() { + var schedule = set$1(this, id), + tween = schedule.tween; -function stepBefore(context) { - return new Step(context, 0); -} + // If this node shared tween with the previous node, + // just assign the updated shared tween and we’re done! + // Otherwise, copy-on-write. + if (tween !== tween0) { + tween1 = tween0 = tween; + for (var i = 0, n = tween1.length; i < n; ++i) { + if (tween1[i].name === name) { + tween1 = tween1.slice(); + tween1.splice(i, 1); + break; + } + } + } -function stepAfter(context) { - return new Step(context, 1); + schedule.tween = tween1; + }; } -var slice$2 = Array.prototype.slice; +function tweenFunction(id, name, value) { + var tween0, tween1; + if (typeof value !== "function") throw new Error; + return function() { + var schedule = set$1(this, id), + tween = schedule.tween; -var none = function(series, order) { - if (!((n = series.length) > 1)) return; - for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) { - s0 = s1, s1 = series[order[i]]; - for (var j = 0; j < m; ++j) { - s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1]; + // If this node shared tween with the previous node, + // just assign the updated shared tween and we’re done! + // Otherwise, copy-on-write. + if (tween !== tween0) { + tween1 = (tween0 = tween).slice(); + for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { + if (tween1[i].name === name) { + tween1[i] = t; + break; + } + } + if (i === n) tween1.push(t); } - } -}; - -var none$1 = function(series) { - var n = series.length, o = new Array(n); - while (--n >= 0) o[n] = n; - return o; -}; -function stackValue(d, key) { - return d[key]; + schedule.tween = tween1; + }; } -var stack = function() { - var keys = constant$2([]), - order = none$1, - offset = none, - value = stackValue; +var transition_tween = function(name, value) { + var id = this._id; - function stack(data) { - var kz = keys.apply(this, arguments), - i, - m = data.length, - n = kz.length, - sz = new Array(n), - oz; + name += ""; - for (i = 0; i < n; ++i) { - for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) { - si[j] = sij = [0, +value(data[j], ki, j, data)]; - sij.data = data[j]; + if (arguments.length < 2) { + var tween = get$1(this.node(), id).tween; + for (var i = 0, n = tween.length, t; i < n; ++i) { + if ((t = tween[i]).name === name) { + return t.value; } - si.key = ki; - } - - for (i = 0, oz = order(sz); i < n; ++i) { - sz[oz[i]].index = i; } - - offset(sz, oz); - return sz; + return null; } - stack.keys = function(_) { - return arguments.length ? (keys = typeof _ === "function" ? _ : constant$2(slice$2.call(_)), stack) : keys; - }; + return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); +}; - stack.value = function(_) { - return arguments.length ? (value = typeof _ === "function" ? _ : constant$2(+_), stack) : value; - }; +function tweenValue(transition, name, value) { + var id = transition._id; - stack.order = function(_) { - return arguments.length ? (order = _ == null ? none$1 : typeof _ === "function" ? _ : constant$2(slice$2.call(_)), stack) : order; - }; + transition.each(function() { + var schedule = set$1(this, id); + (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); + }); - stack.offset = function(_) { - return arguments.length ? (offset = _ == null ? none : _, stack) : offset; + return function(node) { + return get$1(node, id).value[name]; }; +} - return stack; +var interpolate$$1 = function(a, b) { + var c; + return (typeof b === "number" ? reinterpolate + : b instanceof color ? interpolateRgb + : (c = color(b)) ? (b = c, interpolateRgb) + : interpolateString)(a, b); }; -var expand = function(series, order) { - if (!((n = series.length) > 0)) return; - for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) { - for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0; - if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y; - } - none(series, order); -}; +function attrRemove$1(name) { + return function() { + this.removeAttribute(name); + }; +} -var silhouette = function(series, order) { - if (!((n = series.length) > 0)) return; - for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) { - for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0; - s0[j][1] += s0[j][0] = -y / 2; - } - none(series, order); -}; +function attrRemoveNS$1(fullname) { + return function() { + this.removeAttributeNS(fullname.space, fullname.local); + }; +} -var wiggle = function(series, order) { - if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return; - for (var y = 0, j = 1, s0, m, n; j < m; ++j) { - for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) { - var si = series[order[i]], - sij0 = si[j][1] || 0, - sij1 = si[j - 1][1] || 0, - s3 = (sij0 - sij1) / 2; - for (var k = 0; k < i; ++k) { - var sk = series[order[k]], - skj0 = sk[j][1] || 0, - skj1 = sk[j - 1][1] || 0; - s3 += skj0 - skj1; - } - s1 += sij0, s2 += s3 * sij0; - } - s0[j - 1][1] += s0[j - 1][0] = y; - if (s1) y -= s2 / s1; - } - s0[j - 1][1] += s0[j - 1][0] = y; - none(series, order); -}; +function attrConstant$1(name, interpolate$$1, value1) { + var value00, + interpolate0; + return function() { + var value0 = this.getAttribute(name); + return value0 === value1 ? null + : value0 === value00 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value1); + }; +} -var ascending$1 = function(series) { - var sums = series.map(sum$1); - return none$1(series).sort(function(a, b) { return sums[a] - sums[b]; }); -}; +function attrConstantNS$1(fullname, interpolate$$1, value1) { + var value00, + interpolate0; + return function() { + var value0 = this.getAttributeNS(fullname.space, fullname.local); + return value0 === value1 ? null + : value0 === value00 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value1); + }; +} -function sum$1(series) { - var s = 0, i = -1, n = series.length, v; - while (++i < n) if (v = +series[i][1]) s += v; - return s; +function attrFunction$1(name, interpolate$$1, value) { + var value00, + value10, + interpolate0; + return function() { + var value0, value1 = value(this); + if (value1 == null) return void this.removeAttribute(name); + value0 = this.getAttribute(name); + return value0 === value1 ? null + : value0 === value00 && value1 === value10 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); + }; } -var descending$2 = function(series) { - return ascending$1(series).reverse(); +function attrFunctionNS$1(fullname, interpolate$$1, value) { + var value00, + value10, + interpolate0; + return function() { + var value0, value1 = value(this); + if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); + value0 = this.getAttributeNS(fullname.space, fullname.local); + return value0 === value1 ? null + : value0 === value00 && value1 === value10 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); + }; +} + +var transition_attr = function(name, value) { + var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate$$1; + return this.attrTween(name, typeof value === "function" + ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value)) + : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname) + : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + "")); }; -var insideOut = function(series) { - var n = series.length, - i, - j, - sums = series.map(sum$1), - order = none$1(series).sort(function(a, b) { return sums[b] - sums[a]; }), - top = 0, - bottom = 0, - tops = [], - bottoms = []; +function attrTweenNS(fullname, value) { + function tween() { + var node = this, i = value.apply(node, arguments); + return i && function(t) { + node.setAttributeNS(fullname.space, fullname.local, i(t)); + }; + } + tween._value = value; + return tween; +} - for (i = 0; i < n; ++i) { - j = order[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } +function attrTween(name, value) { + function tween() { + var node = this, i = value.apply(node, arguments); + return i && function(t) { + node.setAttribute(name, i(t)); + }; } + tween._value = value; + return tween; +} - return bottoms.reverse().concat(tops); +var transition_attrTween = function(name, value) { + var key = "attr." + name; + if (arguments.length < 2) return (key = this.tween(key)) && key._value; + if (value == null) return this.tween(key, null); + if (typeof value !== "function") throw new Error; + var fullname = namespace(name); + return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); }; -var reverse = function(series) { - return none$1(series).reverse(); -}; +function delayFunction(id, value) { + return function() { + init(this, id).delay = +value.apply(this, arguments); + }; +} -var define = function(constructor, factory, prototype) { - constructor.prototype = factory.prototype = prototype; - prototype.constructor = constructor; +function delayConstant(id, value) { + return value = +value, function() { + init(this, id).delay = value; + }; +} + +var transition_delay = function(value) { + var id = this._id; + + return arguments.length + ? this.each((typeof value === "function" + ? delayFunction + : delayConstant)(id, value)) + : get$1(this.node(), id).delay; }; -function extend(parent, definition) { - var prototype = Object.create(parent.prototype); - for (var key in definition) prototype[key] = definition[key]; - return prototype; +function durationFunction(id, value) { + return function() { + set$1(this, id).duration = +value.apply(this, arguments); + }; } -function Color() {} +function durationConstant(id, value) { + return value = +value, function() { + set$1(this, id).duration = value; + }; +} -var darker = 0.7; -var brighter = 1 / darker; +var transition_duration = function(value) { + var id = this._id; -var reI = "\\s*([+-]?\\d+)\\s*"; -var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*"; -var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*"; -var reHex3 = /^#([0-9a-f]{3})$/; -var reHex6 = /^#([0-9a-f]{6})$/; -var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"); -var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"); -var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"); -var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"); -var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"); -var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); + return arguments.length + ? this.each((typeof value === "function" + ? durationFunction + : durationConstant)(id, value)) + : get$1(this.node(), id).duration; +}; -var named = { - aliceblue: 0xf0f8ff, - antiquewhite: 0xfaebd7, - aqua: 0x00ffff, - aquamarine: 0x7fffd4, - azure: 0xf0ffff, - beige: 0xf5f5dc, - bisque: 0xffe4c4, - black: 0x000000, - blanchedalmond: 0xffebcd, - blue: 0x0000ff, - blueviolet: 0x8a2be2, - brown: 0xa52a2a, - burlywood: 0xdeb887, - cadetblue: 0x5f9ea0, - chartreuse: 0x7fff00, - chocolate: 0xd2691e, - coral: 0xff7f50, - cornflowerblue: 0x6495ed, - cornsilk: 0xfff8dc, - crimson: 0xdc143c, - cyan: 0x00ffff, - darkblue: 0x00008b, - darkcyan: 0x008b8b, - darkgoldenrod: 0xb8860b, - darkgray: 0xa9a9a9, - darkgreen: 0x006400, - darkgrey: 0xa9a9a9, - darkkhaki: 0xbdb76b, - darkmagenta: 0x8b008b, - darkolivegreen: 0x556b2f, - darkorange: 0xff8c00, - darkorchid: 0x9932cc, - darkred: 0x8b0000, - darksalmon: 0xe9967a, - darkseagreen: 0x8fbc8f, - darkslateblue: 0x483d8b, - darkslategray: 0x2f4f4f, - darkslategrey: 0x2f4f4f, - darkturquoise: 0x00ced1, - darkviolet: 0x9400d3, - deeppink: 0xff1493, - deepskyblue: 0x00bfff, - dimgray: 0x696969, - dimgrey: 0x696969, - dodgerblue: 0x1e90ff, - firebrick: 0xb22222, - floralwhite: 0xfffaf0, - forestgreen: 0x228b22, - fuchsia: 0xff00ff, - gainsboro: 0xdcdcdc, - ghostwhite: 0xf8f8ff, - gold: 0xffd700, - goldenrod: 0xdaa520, - gray: 0x808080, - green: 0x008000, - greenyellow: 0xadff2f, - grey: 0x808080, - honeydew: 0xf0fff0, - hotpink: 0xff69b4, - indianred: 0xcd5c5c, - indigo: 0x4b0082, - ivory: 0xfffff0, - khaki: 0xf0e68c, - lavender: 0xe6e6fa, - lavenderblush: 0xfff0f5, - lawngreen: 0x7cfc00, - lemonchiffon: 0xfffacd, - lightblue: 0xadd8e6, - lightcoral: 0xf08080, - lightcyan: 0xe0ffff, - lightgoldenrodyellow: 0xfafad2, - lightgray: 0xd3d3d3, - lightgreen: 0x90ee90, - lightgrey: 0xd3d3d3, - lightpink: 0xffb6c1, - lightsalmon: 0xffa07a, - lightseagreen: 0x20b2aa, - lightskyblue: 0x87cefa, - lightslategray: 0x778899, - lightslategrey: 0x778899, - lightsteelblue: 0xb0c4de, - lightyellow: 0xffffe0, - lime: 0x00ff00, - limegreen: 0x32cd32, - linen: 0xfaf0e6, - magenta: 0xff00ff, - maroon: 0x800000, - mediumaquamarine: 0x66cdaa, - mediumblue: 0x0000cd, - mediumorchid: 0xba55d3, - mediumpurple: 0x9370db, - mediumseagreen: 0x3cb371, - mediumslateblue: 0x7b68ee, - mediumspringgreen: 0x00fa9a, - mediumturquoise: 0x48d1cc, - mediumvioletred: 0xc71585, - midnightblue: 0x191970, - mintcream: 0xf5fffa, - mistyrose: 0xffe4e1, - moccasin: 0xffe4b5, - navajowhite: 0xffdead, - navy: 0x000080, - oldlace: 0xfdf5e6, - olive: 0x808000, - olivedrab: 0x6b8e23, - orange: 0xffa500, - orangered: 0xff4500, - orchid: 0xda70d6, - palegoldenrod: 0xeee8aa, - palegreen: 0x98fb98, - paleturquoise: 0xafeeee, - palevioletred: 0xdb7093, - papayawhip: 0xffefd5, - peachpuff: 0xffdab9, - peru: 0xcd853f, - pink: 0xffc0cb, - plum: 0xdda0dd, - powderblue: 0xb0e0e6, - purple: 0x800080, - rebeccapurple: 0x663399, - red: 0xff0000, - rosybrown: 0xbc8f8f, - royalblue: 0x4169e1, - saddlebrown: 0x8b4513, - salmon: 0xfa8072, - sandybrown: 0xf4a460, - seagreen: 0x2e8b57, - seashell: 0xfff5ee, - sienna: 0xa0522d, - silver: 0xc0c0c0, - skyblue: 0x87ceeb, - slateblue: 0x6a5acd, - slategray: 0x708090, - slategrey: 0x708090, - snow: 0xfffafa, - springgreen: 0x00ff7f, - steelblue: 0x4682b4, - tan: 0xd2b48c, - teal: 0x008080, - thistle: 0xd8bfd8, - tomato: 0xff6347, - turquoise: 0x40e0d0, - violet: 0xee82ee, - wheat: 0xf5deb3, - white: 0xffffff, - whitesmoke: 0xf5f5f5, - yellow: 0xffff00, - yellowgreen: 0x9acd32 +function easeConstant(id, value) { + if (typeof value !== "function") throw new Error; + return function() { + set$1(this, id).ease = value; + }; +} + +var transition_ease = function(value) { + var id = this._id; + + return arguments.length + ? this.each(easeConstant(id, value)) + : get$1(this.node(), id).ease; }; -define(Color, color, { - displayable: function() { - return this.rgb().displayable(); - }, - toString: function() { - return this.rgb() + ""; +var transition_filter = function(match) { + if (typeof match !== "function") match = matcher$1(match); + + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { + if ((node = group[i]) && match.call(node, node.__data__, i, group)) { + subgroup.push(node); + } + } } -}); -function color(format) { - var m; - format = (format + "").trim().toLowerCase(); - return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00 - : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000 - : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) - : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) - : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) - : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) - : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) - : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) - : named.hasOwnProperty(format) ? rgbn(named[format]) - : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) - : null; -} + return new Transition(subgroups, this._parents, this._name, this._id); +}; + +var transition_merge = function(transition) { + if (transition._id !== this._id) throw new Error; -function rgbn(n) { - return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); -} + for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { + for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group0[i] || group1[i]) { + merge[i] = node; + } + } + } -function rgba(r, g, b, a) { - if (a <= 0) r = g = b = NaN; - return new Rgb(r, g, b, a); -} + for (; j < m0; ++j) { + merges[j] = groups0[j]; + } -function rgbConvert(o) { - if (!(o instanceof Color)) o = color(o); - if (!o) return new Rgb; - o = o.rgb(); - return new Rgb(o.r, o.g, o.b, o.opacity); -} + return new Transition(merges, this._parents, this._name, this._id); +}; -function rgb(r, g, b, opacity) { - return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); +function start(name) { + return (name + "").trim().split(/^|\s+/).every(function(t) { + var i = t.indexOf("."); + if (i >= 0) t = t.slice(0, i); + return !t || t === "start"; + }); } -function Rgb(r, g, b, opacity) { - this.r = +r; - this.g = +g; - this.b = +b; - this.opacity = +opacity; -} +function onFunction(id, name, listener) { + var on0, on1, sit = start(name) ? init : set$1; + return function() { + var schedule = sit(this, id), + on = schedule.on; -define(Rgb, rgb, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - rgb: function() { - return this; - }, - displayable: function() { - return (0 <= this.r && this.r <= 255) - && (0 <= this.g && this.g <= 255) - && (0 <= this.b && this.b <= 255) - && (0 <= this.opacity && this.opacity <= 1); - }, - toString: function() { - var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); - return (a === 1 ? "rgb(" : "rgba(") - + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " - + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " - + Math.max(0, Math.min(255, Math.round(this.b) || 0)) - + (a === 1 ? ")" : ", " + a + ")"); - } -})); + // If this node shared a dispatch with the previous node, + // just assign the updated shared dispatch and we’re done! + // Otherwise, copy-on-write. + if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); -function hsla(h, s, l, a) { - if (a <= 0) h = s = l = NaN; - else if (l <= 0 || l >= 1) h = s = NaN; - else if (s <= 0) h = NaN; - return new Hsl(h, s, l, a); + schedule.on = on1; + }; } -function hslConvert(o) { - if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); - if (!(o instanceof Color)) o = color(o); - if (!o) return new Hsl; - if (o instanceof Hsl) return o; - o = o.rgb(); - var r = o.r / 255, - g = o.g / 255, - b = o.b / 255, - min = Math.min(r, g, b), - max = Math.max(r, g, b), - h = NaN, - s = max - min, - l = (max + min) / 2; - if (s) { - if (r === max) h = (g - b) / s + (g < b) * 6; - else if (g === max) h = (b - r) / s + 2; - else h = (r - g) / s + 4; - s /= l < 0.5 ? max + min : 2 - max - min; - h *= 60; - } else { - s = l > 0 && l < 1 ? 0 : h; - } - return new Hsl(h, s, l, o.opacity); -} +var transition_on = function(name, listener) { + var id = this._id; -function hsl(h, s, l, opacity) { - return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); -} + return arguments.length < 2 + ? get$1(this.node(), id).on.on(name) + : this.each(onFunction(id, name, listener)); +}; -function Hsl(h, s, l, opacity) { - this.h = +h; - this.s = +s; - this.l = +l; - this.opacity = +opacity; +function removeFunction(id) { + return function() { + var parent = this.parentNode; + for (var i in this.__transition) if (+i !== id) return; + if (parent) parent.removeChild(this); + }; } -define(Hsl, hsl, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - rgb: function() { - var h = this.h % 360 + (this.h < 0) * 360, - s = isNaN(h) || isNaN(this.s) ? 0 : this.s, - l = this.l, - m2 = l + (l < 0.5 ? l : 1 - l) * s, - m1 = 2 * l - m2; - return new Rgb( - hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), - hsl2rgb(h, m1, m2), - hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), - this.opacity - ); - }, - displayable: function() { - return (0 <= this.s && this.s <= 1 || isNaN(this.s)) - && (0 <= this.l && this.l <= 1) - && (0 <= this.opacity && this.opacity <= 1); +var transition_remove = function() { + return this.on("end.remove", removeFunction(this._id)); +}; + +var transition_select = function(select$$1) { + var name = this._name, + id = this._id; + + if (typeof select$$1 !== "function") select$$1 = selector(select$$1); + + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { + if ((node = group[i]) && (subnode = select$$1.call(node, node.__data__, i, group))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + subgroup[i] = subnode; + schedule(subgroup[i], name, id, i, subgroup, get$1(node, id)); + } + } } -})); -/* From FvD 13.37, CSS Color Module Level 3 */ -function hsl2rgb(h, m1, m2) { - return (h < 60 ? m1 + (m2 - m1) * h / 60 - : h < 180 ? m2 - : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 - : m1) * 255; -} + return new Transition(subgroups, this._parents, name, id); +}; -var deg2rad = Math.PI / 180; -var rad2deg = 180 / Math.PI; +var transition_selectAll = function(select$$1) { + var name = this._name, + id = this._id; -var Kn = 18; -var Xn = 0.950470; -var Yn = 1; -var Zn = 1.088830; -var t0 = 4 / 29; -var t1 = 6 / 29; -var t2 = 3 * t1 * t1; -var t3 = t1 * t1 * t1; + if (typeof select$$1 !== "function") select$$1 = selectorAll(select$$1); -function labConvert(o) { - if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); - if (o instanceof Hcl) { - var h = o.h * deg2rad; - return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); + for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + for (var children = select$$1.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) { + if (child = children[k]) { + schedule(child, name, id, k, children, inherit); + } + } + subgroups.push(children); + parents.push(node); + } + } } - if (!(o instanceof Rgb)) o = rgbConvert(o); - var b = rgb2xyz(o.r), - a = rgb2xyz(o.g), - l = rgb2xyz(o.b), - x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn), - y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn), - z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn); - return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); -} -function lab(l, a, b, opacity) { - return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); -} + return new Transition(subgroups, parents, name, id); +}; -function Lab(l, a, b, opacity) { - this.l = +l; - this.a = +a; - this.b = +b; - this.opacity = +opacity; -} +var Selection$1 = selection.prototype.constructor; -define(Lab, lab, extend(Color, { - brighter: function(k) { - return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); - }, - darker: function(k) { - return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); - }, - rgb: function() { - var y = (this.l + 16) / 116, - x = isNaN(this.a) ? y : y + this.a / 500, - z = isNaN(this.b) ? y : y - this.b / 200; - y = Yn * lab2xyz(y); - x = Xn * lab2xyz(x); - z = Zn * lab2xyz(z); - return new Rgb( - xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB - xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), - xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z), - this.opacity - ); - } -})); +var transition_selection = function() { + return new Selection$1(this._groups, this._parents); +}; -function xyz2lab(t) { - return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; +function styleRemove$1(name, interpolate$$2) { + var value00, + value10, + interpolate0; + return function() { + var style = window(this).getComputedStyle(this, null), + value0 = style.getPropertyValue(name), + value1 = (this.style.removeProperty(name), style.getPropertyValue(name)); + return value0 === value1 ? null + : value0 === value00 && value1 === value10 ? interpolate0 + : interpolate0 = interpolate$$2(value00 = value0, value10 = value1); + }; } -function lab2xyz(t) { - return t > t1 ? t * t * t : t2 * (t - t0); +function styleRemoveEnd(name) { + return function() { + this.style.removeProperty(name); + }; } -function xyz2rgb(x) { - return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); +function styleConstant$1(name, interpolate$$2, value1) { + var value00, + interpolate0; + return function() { + var value0 = window(this).getComputedStyle(this, null).getPropertyValue(name); + return value0 === value1 ? null + : value0 === value00 ? interpolate0 + : interpolate0 = interpolate$$2(value00 = value0, value1); + }; } -function rgb2xyz(x) { - return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); +function styleFunction$1(name, interpolate$$2, value) { + var value00, + value10, + interpolate0; + return function() { + var style = window(this).getComputedStyle(this, null), + value0 = style.getPropertyValue(name), + value1 = value(this); + if (value1 == null) value1 = (this.style.removeProperty(name), style.getPropertyValue(name)); + return value0 === value1 ? null + : value0 === value00 && value1 === value10 ? interpolate0 + : interpolate0 = interpolate$$2(value00 = value0, value10 = value1); + }; } -function hclConvert(o) { - if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); - if (!(o instanceof Lab)) o = labConvert(o); - var h = Math.atan2(o.b, o.a) * rad2deg; - return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); +var transition_style = function(name, value, priority) { + var i = (name += "") === "transform" ? interpolateTransformCss : interpolate$$1; + return value == null ? this + .styleTween(name, styleRemove$1(name, i)) + .on("end.style." + name, styleRemoveEnd(name)) + : this.styleTween(name, typeof value === "function" + ? styleFunction$1(name, i, tweenValue(this, "style." + name, value)) + : styleConstant$1(name, i, value + ""), priority); +}; + +function styleTween(name, value, priority) { + function tween() { + var node = this, i = value.apply(node, arguments); + return i && function(t) { + node.style.setProperty(name, i(t), priority); + }; + } + tween._value = value; + return tween; } -function hcl(h, c, l, opacity) { - return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); +var transition_styleTween = function(name, value, priority) { + var key = "style." + (name += ""); + if (arguments.length < 2) return (key = this.tween(key)) && key._value; + if (value == null) return this.tween(key, null); + if (typeof value !== "function") throw new Error; + return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); +}; + +function textConstant$1(value) { + return function() { + this.textContent = value; + }; } -function Hcl(h, c, l, opacity) { - this.h = +h; - this.c = +c; - this.l = +l; - this.opacity = +opacity; +function textFunction$1(value) { + return function() { + var value1 = value(this); + this.textContent = value1 == null ? "" : value1; + }; } -define(Hcl, hcl, extend(Color, { - brighter: function(k) { - return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity); - }, - darker: function(k) { - return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity); - }, - rgb: function() { - return labConvert(this).rgb(); +var transition_text = function(value) { + return this.tween("text", typeof value === "function" + ? textFunction$1(tweenValue(this, "text", value)) + : textConstant$1(value == null ? "" : value + "")); +}; + +var transition_transition = function() { + var name = this._name, + id0 = this._id, + id1 = newId(); + + for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + var inherit = get$1(node, id0); + schedule(node, name, id1, i, group, { + time: inherit.time + inherit.delay + inherit.duration, + delay: 0, + duration: inherit.duration, + ease: inherit.ease + }); + } + } } -})); -var A = -0.14861; -var B = +1.78277; -var C = -0.29227; -var D = -0.90649; -var E = +1.97294; -var ED = E * D; -var EB = E * B; -var BC_DA = B * C - D * A; + return new Transition(groups, this._parents, name, id1); +}; -function cubehelixConvert(o) { - if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); - if (!(o instanceof Rgb)) o = rgbConvert(o); - var r = o.r / 255, - g = o.g / 255, - b = o.b / 255, - l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), - bl = b - l, - k = (E * (g - l) - C * bl) / D, - s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 - h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; - return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); -} +var id = 0; -function cubehelix(h, s, l, opacity) { - return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); +function Transition(groups, parents, name, id) { + this._groups = groups; + this._parents = parents; + this._name = name; + this._id = id; } -function Cubehelix(h, s, l, opacity) { - this.h = +h; - this.s = +s; - this.l = +l; - this.opacity = +opacity; +function transition(name) { + return selection().transition(name); } -define(Cubehelix, cubehelix, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Cubehelix(this.h, this.s, this.l * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Cubehelix(this.h, this.s, this.l * k, this.opacity); - }, - rgb: function() { - var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, - l = +this.l, - a = isNaN(this.s) ? 0 : this.s * l * (1 - l), - cosh = Math.cos(h), - sinh = Math.sin(h); - return new Rgb( - 255 * (l + a * (A * cosh + B * sinh)), - 255 * (l + a * (C * cosh + D * sinh)), - 255 * (l + a * (E * cosh)), - this.opacity - ); - } -})); - -function basis$1(t1, v0, v1, v2, v3) { - var t2 = t1 * t1, t3 = t2 * t1; - return ((1 - 3 * t1 + 3 * t2 - t3) * v0 - + (4 - 6 * t2 + 3 * t3) * v1 - + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 - + t3 * v3) / 6; +function newId() { + return ++id; } -var basis$2 = function(values) { - var n = values.length - 1; - return function(t) { - var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), - v1 = values[i], - v2 = values[i + 1], - v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, - v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; - return basis$1((t - i / n) * n, v0, v1, v2, v3); - }; -}; - -var basisClosed$1 = function(values) { - var n = values.length; - return function(t) { - var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), - v0 = values[(i + n - 1) % n], - v1 = values[i % n], - v2 = values[(i + 1) % n], - v3 = values[(i + 2) % n]; - return basis$1((t - i / n) * n, v0, v1, v2, v3); - }; -}; +var selection_prototype = selection.prototype; -var constant$3 = function(x) { - return function() { - return x; - }; +Transition.prototype = transition.prototype = { + constructor: Transition, + select: transition_select, + selectAll: transition_selectAll, + filter: transition_filter, + merge: transition_merge, + selection: transition_selection, + transition: transition_transition, + call: selection_prototype.call, + nodes: selection_prototype.nodes, + node: selection_prototype.node, + size: selection_prototype.size, + empty: selection_prototype.empty, + each: selection_prototype.each, + on: transition_on, + attr: transition_attr, + attrTween: transition_attrTween, + style: transition_style, + styleTween: transition_styleTween, + text: transition_text, + remove: transition_remove, + tween: transition_tween, + delay: transition_delay, + duration: transition_duration, + ease: transition_ease }; -function linear$1(a, d) { - return function(t) { - return a + t * d; - }; -} - -function exponential$1(a, b, y) { - return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { - return Math.pow(a + t * b, y); - }; +function linear$1(t) { + return +t; } -function hue(a, b) { - var d = b - a; - return d ? linear$1(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a); +function quadIn(t) { + return t * t; } -function gamma(y) { - return (y = +y) === 1 ? nogamma : function(a, b) { - return b - a ? exponential$1(a, b, y) : constant$3(isNaN(a) ? b : a); - }; +function quadOut(t) { + return t * (2 - t); } -function nogamma(a, b) { - var d = b - a; - return d ? linear$1(a, d) : constant$3(isNaN(a) ? b : a); +function quadInOut(t) { + return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2; } -var interpolateRgb = (function rgbGamma(y) { - var color$$1 = gamma(y); +function cubicIn(t) { + return t * t * t; +} - function rgb$$1(start, end) { - var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r), - g = color$$1(start.g, end.g), - b = color$$1(start.b, end.b), - opacity = color$$1(start.opacity, end.opacity); - return function(t) { - start.r = r(t); - start.g = g(t); - start.b = b(t); - start.opacity = opacity(t); - return start + ""; - }; - } +function cubicOut(t) { + return --t * t * t + 1; +} - rgb$$1.gamma = rgbGamma; +function cubicInOut(t) { + return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; +} - return rgb$$1; -})(1); +var exponent = 3; -function rgbSpline(spline) { - return function(colors) { - var n = colors.length, - r = new Array(n), - g = new Array(n), - b = new Array(n), - i, color$$1; - for (i = 0; i < n; ++i) { - color$$1 = rgb(colors[i]); - r[i] = color$$1.r || 0; - g[i] = color$$1.g || 0; - b[i] = color$$1.b || 0; - } - r = spline(r); - g = spline(g); - b = spline(b); - color$$1.opacity = 1; - return function(t) { - color$$1.r = r(t); - color$$1.g = g(t); - color$$1.b = b(t); - return color$$1 + ""; - }; - }; -} +var polyIn = (function custom(e) { + e = +e; -var rgbBasis = rgbSpline(basis$2); -var rgbBasisClosed = rgbSpline(basisClosed$1); + function polyIn(t) { + return Math.pow(t, e); + } -var array$1 = function(a, b) { - var nb = b ? b.length : 0, - na = a ? Math.min(nb, a.length) : 0, - x = new Array(nb), - c = new Array(nb), - i; + polyIn.exponent = custom; - for (i = 0; i < na; ++i) x[i] = interpolate(a[i], b[i]); - for (; i < nb; ++i) c[i] = b[i]; + return polyIn; +})(exponent); - return function(t) { - for (i = 0; i < na; ++i) c[i] = x[i](t); - return c; - }; -}; +var polyOut = (function custom(e) { + e = +e; -var date = function(a, b) { - var d = new Date; - return a = +a, b -= a, function(t) { - return d.setTime(a + b * t), d; - }; -}; + function polyOut(t) { + return 1 - Math.pow(1 - t, e); + } -var interpolateNumber = function(a, b) { - return a = +a, b -= a, function(t) { - return a + b * t; - }; -}; + polyOut.exponent = custom; -var object = function(a, b) { - var i = {}, - c = {}, - k; + return polyOut; +})(exponent); - if (a === null || typeof a !== "object") a = {}; - if (b === null || typeof b !== "object") b = {}; +var polyInOut = (function custom(e) { + e = +e; - for (k in b) { - if (k in a) { - i[k] = interpolate(a[k], b[k]); - } else { - c[k] = b[k]; - } + function polyInOut(t) { + return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2; } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; -}; + polyInOut.exponent = custom; -var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; -var reB = new RegExp(reA.source, "g"); + return polyInOut; +})(exponent); -function zero(b) { - return function() { - return b; - }; -} +var pi = Math.PI; +var halfPi = pi / 2; -function one(b) { - return function(t) { - return b(t) + ""; - }; +function sinIn(t) { + return 1 - Math.cos(t * halfPi); } -var interpolateString = function(a, b) { - var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b - am, // current match in a - bm, // current match in b - bs, // string preceding current number in b, if any - i = -1, // index in s - s = [], // string constants and placeholders - q = []; // number interpolators - - // Coerce inputs to strings. - a = a + "", b = b + ""; - - // Interpolate pairs of numbers in a & b. - while ((am = reA.exec(a)) - && (bm = reB.exec(b))) { - if ((bs = bm.index) > bi) { // a string precedes the next number in b - bs = b.slice(bi, bs); - if (s[i]) s[i] += bs; // coalesce with previous string - else s[++i] = bs; - } - if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match - if (s[i]) s[i] += bm; // coalesce with previous string - else s[++i] = bm; - } else { // interpolate non-matching numbers - s[++i] = null; - q.push({i: i, x: interpolateNumber(am, bm)}); - } - bi = reB.lastIndex; - } - - // Add remains of b. - if (bi < b.length) { - bs = b.slice(bi); - if (s[i]) s[i] += bs; // coalesce with previous string - else s[++i] = bs; - } +function sinOut(t) { + return Math.sin(t * halfPi); +} - // Special optimization for only a single match. - // Otherwise, interpolate each of the numbers and rejoin the string. - return s.length < 2 ? (q[0] - ? one(q[0].x) - : zero(b)) - : (b = q.length, function(t) { - for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }); -}; +function sinInOut(t) { + return (1 - Math.cos(pi * t)) / 2; +} -var interpolate = function(a, b) { - var t = typeof b, c; - return b == null || t === "boolean" ? constant$3(b) - : (t === "number" ? interpolateNumber - : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString) - : b instanceof color ? interpolateRgb - : b instanceof Date ? date - : Array.isArray(b) ? array$1 - : isNaN(b) ? object - : interpolateNumber)(a, b); -}; +function expIn(t) { + return Math.pow(2, 10 * t - 10); +} -var interpolateRound = function(a, b) { - return a = +a, b -= a, function(t) { - return Math.round(a + b * t); - }; -}; +function expOut(t) { + return 1 - Math.pow(2, -10 * t); +} -var degrees = 180 / Math.PI; +function expInOut(t) { + return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2; +} -var identity$2 = { - translateX: 0, - translateY: 0, - rotate: 0, - skewX: 0, - scaleX: 1, - scaleY: 1 -}; +function circleIn(t) { + return 1 - Math.sqrt(1 - t * t); +} -var decompose = function(a, b, c, d, e, f) { - var scaleX, scaleY, skewX; - if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; - if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; - if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; - if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; - return { - translateX: e, - translateY: f, - rotate: Math.atan2(b, a) * degrees, - skewX: Math.atan(skewX) * degrees, - scaleX: scaleX, - scaleY: scaleY - }; -}; +function circleOut(t) { + return Math.sqrt(1 - --t * t); +} -var cssNode; -var cssRoot; -var cssView; -var svgNode; +function circleInOut(t) { + return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2; +} -function parseCss(value) { - if (value === "none") return identity$2; - if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; - cssNode.style.transform = value; - value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); - cssRoot.removeChild(cssNode); - value = value.slice(7, -1).split(","); - return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); +var b1 = 4 / 11; +var b2 = 6 / 11; +var b3 = 8 / 11; +var b4 = 3 / 4; +var b5 = 9 / 11; +var b6 = 10 / 11; +var b7 = 15 / 16; +var b8 = 21 / 22; +var b9 = 63 / 64; +var b0 = 1 / b1 / b1; + +function bounceIn(t) { + return 1 - bounceOut(1 - t); } -function parseSvg(value) { - if (value == null) return identity$2; - if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); - svgNode.setAttribute("transform", value); - if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2; - value = value.matrix; - return decompose(value.a, value.b, value.c, value.d, value.e, value.f); +function bounceOut(t) { + return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9; } -function interpolateTransform(parse, pxComma, pxParen, degParen) { +function bounceInOut(t) { + return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2; +} - function pop(s) { - return s.length ? s.pop() + " " : ""; - } +var overshoot = 1.70158; - function translate(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push("translate(", null, pxComma, null, pxParen); - q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); - } else if (xb || yb) { - s.push("translate(" + xb + pxComma + yb + pxParen); - } - } +var backIn = (function custom(s) { + s = +s; - function rotate(a, b, s, q) { - if (a !== b) { - if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path - q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpolateNumber(a, b)}); - } else if (b) { - s.push(pop(s) + "rotate(" + b + degParen); - } + function backIn(t) { + return t * t * ((s + 1) * t - s); } - function skewX(a, b, s, q) { - if (a !== b) { - q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b)}); - } else if (b) { - s.push(pop(s) + "skewX(" + b + degParen); - } + backIn.overshoot = custom; + + return backIn; +})(overshoot); + +var backOut = (function custom(s) { + s = +s; + + function backOut(t) { + return --t * t * ((s + 1) * t + s) + 1; } - function scale(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push(pop(s) + "scale(", null, ",", null, ")"); - q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); - } else if (xb !== 1 || yb !== 1) { - s.push(pop(s) + "scale(" + xb + "," + yb + ")"); - } + backOut.overshoot = custom; + + return backOut; +})(overshoot); + +var backInOut = (function custom(s) { + s = +s; + + function backInOut(t) { + return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2; } - return function(a, b) { - var s = [], // string constants and placeholders - q = []; // number interpolators - a = parse(a), b = parse(b); - translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); - rotate(a.rotate, b.rotate, s, q); - skewX(a.skewX, b.skewX, s, q); - scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); - a = b = null; // gc - return function(t) { - var i = -1, n = q.length, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - }; -} + backInOut.overshoot = custom; -var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); -var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); + return backInOut; +})(overshoot); -var rho = Math.SQRT2; -var rho2 = 2; -var rho4 = 4; -var epsilon2 = 1e-12; +var tau = 2 * Math.PI; +var amplitude = 1; +var period = 0.3; -function cosh(x) { - return ((x = Math.exp(x)) + 1 / x) / 2; -} +var elasticIn = (function custom(a, p) { + var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); -function sinh(x) { - return ((x = Math.exp(x)) - 1 / x) / 2; -} + function elasticIn(t) { + return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p); + } -function tanh(x) { - return ((x = Math.exp(2 * x)) - 1) / (x + 1); -} + elasticIn.amplitude = function(a) { return custom(a, p * tau); }; + elasticIn.period = function(p) { return custom(a, p); }; -// p0 = [ux0, uy0, w0] -// p1 = [ux1, uy1, w1] -var interpolateZoom = function(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], - ux1 = p1[0], uy1 = p1[1], w1 = p1[2], - dx = ux1 - ux0, - dy = uy1 - uy0, - d2 = dx * dx + dy * dy, - i, - S; + return elasticIn; +})(amplitude, period); - // Special case for u0 ≅ u1. - if (d2 < epsilon2) { - S = Math.log(w1 / w0) / rho; - i = function(t) { - return [ - ux0 + t * dx, - uy0 + t * dy, - w0 * Math.exp(rho * t * S) - ]; - }; +var elasticOut = (function custom(a, p) { + var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); + + function elasticOut(t) { + return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p); } - // General case. - else { - var d1 = Math.sqrt(d2), - b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), - b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), - r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), - r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); - S = (r1 - r0) / rho; - i = function(t) { - var s = t * S, - coshr0 = cosh(r0), - u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); - return [ - ux0 + u * dx, - uy0 + u * dy, - w0 * coshr0 / cosh(rho * s + r0) - ]; - }; + elasticOut.amplitude = function(a) { return custom(a, p * tau); }; + elasticOut.period = function(p) { return custom(a, p); }; + + return elasticOut; +})(amplitude, period); + +var elasticInOut = (function custom(a, p) { + var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); + + function elasticInOut(t) { + return ((t = t * 2 - 1) < 0 + ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p) + : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2; } - i.duration = S * 1000; + elasticInOut.amplitude = function(a) { return custom(a, p * tau); }; + elasticInOut.period = function(p) { return custom(a, p); }; - return i; + return elasticInOut; +})(amplitude, period); + +var defaultTiming = { + time: null, // Set on use. + delay: 0, + duration: 250, + ease: cubicInOut }; -function hsl$1(hue$$1) { - return function(start, end) { - var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h), - s = nogamma(start.s, end.s), - l = nogamma(start.l, end.l), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.h = h(t); - start.s = s(t); - start.l = l(t); - start.opacity = opacity(t); - return start + ""; - }; +function inherit(node, id) { + var timing; + while (!(timing = node.__transition) || !(timing = timing[id])) { + if (!(node = node.parentNode)) { + return defaultTiming.time = now(), defaultTiming; + } } + return timing; } -var hsl$2 = hsl$1(hue); -var hslLong = hsl$1(nogamma); +var selection_transition = function(name) { + var id, + timing; -function lab$1(start, end) { - var l = nogamma((start = lab(start)).l, (end = lab(end)).l), - a = nogamma(start.a, end.a), - b = nogamma(start.b, end.b), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.l = l(t); - start.a = a(t); - start.b = b(t); - start.opacity = opacity(t); - return start + ""; + if (name instanceof Transition) { + id = name._id, name = name._name; + } else { + id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; + } + + for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + schedule(node, name, id, i, group, timing || inherit(node, id)); + } + } + } + + return new Transition(groups, this._parents, name, id); +}; + +selection.prototype.interrupt = selection_interrupt; +selection.prototype.transition = selection_transition; + +var root$1 = [null]; + +var active = function(node, name) { + var schedules = node.__transition, + schedule, + i; + + if (schedules) { + name = name == null ? null : name + ""; + for (i in schedules) { + if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) { + return new Transition([[node]], root$1, name, +i); + } + } + } + + return null; +}; + +var constant$4 = function(x) { + return function() { + return x; }; -} +}; -function hcl$1(hue$$1) { - return function(start, end) { - var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h), - c = nogamma(start.c, end.c), - l = nogamma(start.l, end.l), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.h = h(t); - start.c = c(t); - start.l = l(t); - start.opacity = opacity(t); - return start + ""; - }; - } +var BrushEvent = function(target, type, selection) { + this.target = target; + this.type = type; + this.selection = selection; +}; + +function nopropagation$1() { + exports.event.stopImmediatePropagation(); } -var hcl$2 = hcl$1(hue); -var hclLong = hcl$1(nogamma); +var noevent$1 = function() { + exports.event.preventDefault(); + exports.event.stopImmediatePropagation(); +}; -function cubehelix$1(hue$$1) { - return (function cubehelixGamma(y) { - y = +y; +var MODE_DRAG = {name: "drag"}; +var MODE_SPACE = {name: "space"}; +var MODE_HANDLE = {name: "handle"}; +var MODE_CENTER = {name: "center"}; - function cubehelix$$1(start, end) { - var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h), - s = nogamma(start.s, end.s), - l = nogamma(start.l, end.l), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.h = h(t); - start.s = s(t); - start.l = l(Math.pow(t, y)); - start.opacity = opacity(t); - return start + ""; - }; - } +var X = { + name: "x", + handles: ["e", "w"].map(type), + input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; }, + output: function(xy) { return xy && [xy[0][0], xy[1][0]]; } +}; - cubehelix$$1.gamma = cubehelixGamma; +var Y = { + name: "y", + handles: ["n", "s"].map(type), + input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; }, + output: function(xy) { return xy && [xy[0][1], xy[1][1]]; } +}; - return cubehelix$$1; - })(1); -} +var XY = { + name: "xy", + handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type), + input: function(xy) { return xy; }, + output: function(xy) { return xy; } +}; -var cubehelix$2 = cubehelix$1(hue); -var cubehelixLong = cubehelix$1(nogamma); +var cursors = { + overlay: "crosshair", + selection: "move", + n: "ns-resize", + e: "ew-resize", + s: "ns-resize", + w: "ew-resize", + nw: "nwse-resize", + ne: "nesw-resize", + se: "nwse-resize", + sw: "nesw-resize" +}; -var quantize = function(interpolator, n) { - var samples = new Array(n); - for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); - return samples; +var flipX = { + e: "w", + w: "e", + nw: "ne", + ne: "nw", + se: "sw", + sw: "se" }; -var noop$1 = {value: function() {}}; +var flipY = { + n: "s", + s: "n", + nw: "sw", + ne: "se", + se: "ne", + sw: "nw" +}; -function dispatch() { - for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { - if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); - _[t] = []; - } - return new Dispatch(_); -} +var signsX = { + overlay: +1, + selection: +1, + n: null, + e: +1, + s: null, + w: -1, + nw: -1, + ne: +1, + se: +1, + sw: -1 +}; -function Dispatch(_) { - this._ = _; -} +var signsY = { + overlay: +1, + selection: +1, + n: -1, + e: null, + s: +1, + w: null, + nw: -1, + ne: -1, + se: +1, + sw: +1 +}; -function parseTypenames(typenames, types) { - return typenames.trim().split(/^|\s+/).map(function(t) { - var name = "", i = t.indexOf("."); - if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); - if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); - return {type: t, name: name}; - }); +function type(t) { + return {type: t}; } -Dispatch.prototype = dispatch.prototype = { - constructor: Dispatch, - on: function(typename, callback) { - var _ = this._, - T = parseTypenames(typename + "", _), - t, - i = -1, - n = T.length; - - // If no callback was specified, return the callback of the given type and name. - if (arguments.length < 2) { - while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; - return; - } +// Ignore right-click, since that should open the context menu. +function defaultFilter() { + return !exports.event.button; +} - // If a type was specified, set the callback for the given type and name. - // Otherwise, if a null callback was specified, remove callbacks of the given name. - if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); - while (++i < n) { - if (t = (typename = T[i]).type) _[t] = set$2(_[t], typename.name, callback); - else if (callback == null) for (t in _) _[t] = set$2(_[t], typename.name, null); - } +function defaultExtent() { + var svg = this.ownerSVGElement || this; + return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]]; +} - return this; - }, - copy: function() { - var copy = {}, _ = this._; - for (var t in _) copy[t] = _[t].slice(); - return new Dispatch(copy); - }, - call: function(type, that) { - if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; - if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); - for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); - }, - apply: function(type, that, args) { - if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); - for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); - } -}; +// Like d3.local, but with the name “__brush” rather than auto-generated. +function local$$1(node) { + while (!node.__brush) if (!(node = node.parentNode)) return; + return node.__brush; +} -function get(type, name) { - for (var i = 0, n = type.length, c; i < n; ++i) { - if ((c = type[i]).name === name) { - return c.value; - } - } +function empty(extent) { + return extent[0][0] === extent[1][0] + || extent[0][1] === extent[1][1]; } -function set$2(type, name, callback) { - for (var i = 0, n = type.length; i < n; ++i) { - if (type[i].name === name) { - type[i] = noop$1, type = type.slice(0, i).concat(type.slice(i + 1)); - break; - } - } - if (callback != null) type.push({name: name, value: callback}); - return type; +function brushSelection(node) { + var state = node.__brush; + return state ? state.dim.output(state.selection) : null; } -function objectConverter(columns) { - return new Function("d", "return {" + columns.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); +function brushX() { + return brush$1(X); } -function customConverter(columns, f) { - var object = objectConverter(columns); - return function(row, i) { - return f(object(row), i, columns); - }; +function brushY() { + return brush$1(Y); } -// Compute unique columns in order of discovery. -function inferColumns(rows) { - var columnSet = Object.create(null), - columns = []; +var brush = function() { + return brush$1(XY); +}; + +function brush$1(dim) { + var extent = defaultExtent, + filter = defaultFilter, + listeners = dispatch(brush, "start", "brush", "end"), + handleSize = 6, + touchending; + + function brush(group) { + var overlay = group + .property("__brush", initialize) + .selectAll(".overlay") + .data([type("overlay")]); + + overlay.enter().append("rect") + .attr("class", "overlay") + .attr("pointer-events", "all") + .attr("cursor", cursors.overlay) + .merge(overlay) + .each(function() { + var extent = local$$1(this).extent; + select(this) + .attr("x", extent[0][0]) + .attr("y", extent[0][1]) + .attr("width", extent[1][0] - extent[0][0]) + .attr("height", extent[1][1] - extent[0][1]); + }); + + group.selectAll(".selection") + .data([type("selection")]) + .enter().append("rect") + .attr("class", "selection") + .attr("cursor", cursors.selection) + .attr("fill", "#777") + .attr("fill-opacity", 0.3) + .attr("stroke", "#fff") + .attr("shape-rendering", "crispEdges"); - rows.forEach(function(row) { - for (var column in row) { - if (!(column in columnSet)) { - columns.push(columnSet[column] = column); - } - } - }); + var handle = group.selectAll(".handle") + .data(dim.handles, function(d) { return d.type; }); - return columns; -} + handle.exit().remove(); -var dsv = function(delimiter) { - var reFormat = new RegExp("[\"" + delimiter + "\n]"), - delimiterCode = delimiter.charCodeAt(0); + handle.enter().append("rect") + .attr("class", function(d) { return "handle handle--" + d.type; }) + .attr("cursor", function(d) { return cursors[d.type]; }); - function parse(text, f) { - var convert, columns, rows = parseRows(text, function(row, i) { - if (convert) return convert(row, i - 1); - columns = row, convert = f ? customConverter(row, f) : objectConverter(row); - }); - rows.columns = columns; - return rows; + group + .each(redraw) + .attr("fill", "none") + .attr("pointer-events", "all") + .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") + .on("mousedown.brush touchstart.brush", started); } - function parseRows(text, f) { - var EOL = {}, // sentinel value for end-of-line - EOF = {}, // sentinel value for end-of-file - rows = [], // output rows - N = text.length, - I = 0, // current character index - n = 0, // the current line number - t, // the current token - eol; // is the current token followed by EOL? - - function token() { - if (I >= N) return EOF; // special case: end of file - if (eol) return eol = false, EOL; // special case: end of line + brush.move = function(group, selection$$1) { + if (group.selection) { + group + .on("start.brush", function() { emitter(this, arguments).beforestart().start(); }) + .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); }) + .tween("brush", function() { + var that = this, + state = that.__brush, + emit = emitter(that, arguments), + selection0 = state.selection, + selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(this, arguments) : selection$$1, state.extent), + i = interpolateValue(selection0, selection1); - // special case: quotes - var j = I, c; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.slice(j + 1, i).replace(/""/g, "\""); - } + function tween(t) { + state.selection = t === 1 && empty(selection1) ? null : i(t); + redraw.call(that); + emit.brush(); + } - // common case: find next delimiter or newline - while (I < N) { - var k = 1; - c = text.charCodeAt(I++); - if (c === 10) eol = true; // \n - else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n - else if (c !== delimiterCode) continue; - return text.slice(j, I - k); - } + return selection0 && selection1 ? tween : tween(1); + }); + } else { + group + .each(function() { + var that = this, + args = arguments, + state = that.__brush, + selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(that, args) : selection$$1, state.extent), + emit = emitter(that, args).beforestart(); - // special case: last token before EOF - return text.slice(j); + interrupt(that); + state.selection = selection1 == null || empty(selection1) ? null : selection1; + redraw.call(that); + emit.start().brush().end(); + }); } + }; - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && (a = f(a, n++)) == null) continue; - rows.push(a); - } + function redraw() { + var group = select(this), + selection$$1 = local$$1(this).selection; - return rows; - } + if (selection$$1) { + group.selectAll(".selection") + .style("display", null) + .attr("x", selection$$1[0][0]) + .attr("y", selection$$1[0][1]) + .attr("width", selection$$1[1][0] - selection$$1[0][0]) + .attr("height", selection$$1[1][1] - selection$$1[0][1]); - function format(rows, columns) { - if (columns == null) columns = inferColumns(rows); - return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) { - return columns.map(function(column) { - return formatValue(row[column]); - }).join(delimiter); - })).join("\n"); - } + group.selectAll(".handle") + .style("display", null) + .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handleSize / 2; }) + .attr("y", function(d) { return d.type[0] === "s" ? selection$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; }) + .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : handleSize; }) + .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : handleSize; }); + } - function formatRows(rows) { - return rows.map(formatRow).join("\n"); + else { + group.selectAll(".selection,.handle") + .style("display", "none") + .attr("x", null) + .attr("y", null) + .attr("width", null) + .attr("height", null); + } } - function formatRow(row) { - return row.map(formatValue).join(delimiter); + function emitter(that, args) { + return that.__brush.emitter || new Emitter(that, args); } - function formatValue(text) { - return text == null ? "" - : reFormat.test(text += "") ? "\"" + text.replace(/\"/g, "\"\"") + "\"" - : text; + function Emitter(that, args) { + this.that = that; + this.args = args; + this.state = that.__brush; + this.active = 0; } - return { - parse: parse, - parseRows: parseRows, - format: format, - formatRows: formatRows + Emitter.prototype = { + beforestart: function() { + if (++this.active === 1) this.state.emitter = this, this.starting = true; + return this; + }, + start: function() { + if (this.starting) this.starting = false, this.emit("start"); + return this; + }, + brush: function() { + this.emit("brush"); + return this; + }, + end: function() { + if (--this.active === 0) delete this.state.emitter, this.emit("end"); + return this; + }, + emit: function(type) { + customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]); + } }; -}; -var csv = dsv(","); - -var csvParse = csv.parse; -var csvParseRows = csv.parseRows; -var csvFormat = csv.format; -var csvFormatRows = csv.formatRows; + function started() { + if (exports.event.touches) { if (exports.event.changedTouches.length < exports.event.touches.length) return noevent$1(); } + else if (touchending) return; + if (!filter.apply(this, arguments)) return; -var tsv = dsv("\t"); + var that = this, + type = exports.event.target.__data__.type, + mode = (exports.event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (exports.event.altKey ? MODE_CENTER : MODE_HANDLE), + signX = dim === Y ? null : signsX[type], + signY = dim === X ? null : signsY[type], + state = local$$1(that), + extent = state.extent, + selection$$1 = state.selection, + W = extent[0][0], w0, w1, + N = extent[0][1], n0, n1, + E = extent[1][0], e0, e1, + S = extent[1][1], s0, s1, + dx, + dy, + moving, + shifting = signX && signY && exports.event.shiftKey, + lockX, + lockY, + point0 = mouse(that), + point = point0, + emit = emitter(that, arguments).beforestart(); -var tsvParse = tsv.parse; -var tsvParseRows = tsv.parseRows; -var tsvFormat = tsv.format; -var tsvFormatRows = tsv.formatRows; + if (type === "overlay") { + state.selection = selection$$1 = [ + [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]], + [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0] + ]; + } else { + w0 = selection$$1[0][0]; + n0 = selection$$1[0][1]; + e0 = selection$$1[1][0]; + s0 = selection$$1[1][1]; + } -var request = function(url, callback) { - var request, - event = dispatch("beforesend", "progress", "load", "error"), - mimeType, - headers = map$1(), - xhr = new XMLHttpRequest, - user = null, - password = null, - response, - responseType, - timeout = 0; + w1 = w0; + n1 = n0; + e1 = e0; + s1 = s0; - // If IE does not support CORS, use XDomainRequest. - if (typeof XDomainRequest !== "undefined" - && !("withCredentials" in xhr) - && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest; + var group = select(that) + .attr("pointer-events", "none"); - "onload" in xhr - ? xhr.onload = xhr.onerror = xhr.ontimeout = respond - : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); }; + var overlay = group.selectAll(".overlay") + .attr("cursor", cursors[type]); - function respond(o) { - var status = xhr.status, result; - if (!status && hasResponse(xhr) - || status >= 200 && status < 300 - || status === 304) { - if (response) { - try { - result = response.call(request, xhr); - } catch (e) { - event.call("error", request, e); - return; - } - } else { - result = xhr; - } - event.call("load", request, result); + if (exports.event.touches) { + group + .on("touchmove.brush", moved, true) + .on("touchend.brush touchcancel.brush", ended, true); } else { - event.call("error", request, o); - } - } + var view = select(exports.event.view) + .on("keydown.brush", keydowned, true) + .on("keyup.brush", keyupped, true) + .on("mousemove.brush", moved, true) + .on("mouseup.brush", ended, true); - xhr.onprogress = function(e) { - event.call("progress", request, e); - }; + dragDisable(exports.event.view); + } - request = { - header: function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers.get(name); - if (value == null) headers.remove(name); - else headers.set(name, value + ""); - return request; - }, + nopropagation$1(); + interrupt(that); + redraw.call(that); + emit.start(); - // If mimeType is non-null and no Accept header is set, a default is used. - mimeType: function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return request; - }, + function moved() { + var point1 = mouse(that); + if (shifting && !lockX && !lockY) { + if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true; + else lockX = true; + } + point = point1; + moving = true; + noevent$1(); + move(); + } - // Specifies what type the response value should take; - // for instance, arraybuffer, blob, document, or text. - responseType: function(value) { - if (!arguments.length) return responseType; - responseType = value; - return request; - }, + function move() { + var t; - timeout: function(value) { - if (!arguments.length) return timeout; - timeout = +value; - return request; - }, + dx = point[0] - point0[0]; + dy = point[1] - point0[1]; - user: function(value) { - return arguments.length < 1 ? user : (user = value == null ? null : value + "", request); - }, + switch (mode) { + case MODE_SPACE: + case MODE_DRAG: { + if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx; + if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy; + break; + } + case MODE_HANDLE: { + if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0; + else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx; + if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0; + else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy; + break; + } + case MODE_CENTER: { + if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX)); + if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY)); + break; + } + } - password: function(value) { - return arguments.length < 1 ? password : (password = value == null ? null : value + "", request); - }, + if (e1 < w1) { + signX *= -1; + t = w0, w0 = e0, e0 = t; + t = w1, w1 = e1, e1 = t; + if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]); + } - // Specify how to convert the response content to a specific type; - // changes the callback value on "load" events. - response: function(value) { - response = value; - return request; - }, + if (s1 < n1) { + signY *= -1; + t = n0, n0 = s0, s0 = t; + t = n1, n1 = s1, s1 = t; + if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]); + } - // Alias for send("GET", …). - get: function(data, callback) { - return request.send("GET", data, callback); - }, + if (state.selection) selection$$1 = state.selection; // May be set by brush.move! + if (lockX) w1 = selection$$1[0][0], e1 = selection$$1[1][0]; + if (lockY) n1 = selection$$1[0][1], s1 = selection$$1[1][1]; - // Alias for send("POST", …). - post: function(data, callback) { - return request.send("POST", data, callback); - }, + if (selection$$1[0][0] !== w1 + || selection$$1[0][1] !== n1 + || selection$$1[1][0] !== e1 + || selection$$1[1][1] !== s1) { + state.selection = [[w1, n1], [e1, s1]]; + redraw.call(that); + emit.brush(); + } + } - // If callback is non-null, it will be used for error and load events. - send: function(method, data, callback) { - xhr.open(method, url, true, user, password); - if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*"); - if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); }); - if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType); - if (responseType != null) xhr.responseType = responseType; - if (timeout > 0) xhr.timeout = timeout; - if (callback == null && typeof data === "function") callback = data, data = null; - if (callback != null && callback.length === 1) callback = fixCallback(callback); - if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); }); - event.call("beforesend", request, xhr); - xhr.send(data == null ? null : data); - return request; - }, + function ended() { + nopropagation$1(); + if (exports.event.touches) { + if (exports.event.touches.length) return; + if (touchending) clearTimeout(touchending); + touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! + group.on("touchmove.brush touchend.brush touchcancel.brush", null); + } else { + yesdrag(exports.event.view, moving); + view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null); + } + group.attr("pointer-events", "all"); + overlay.attr("cursor", cursors.overlay); + if (state.selection) selection$$1 = state.selection; // May be set by brush.move (on start)! + if (empty(selection$$1)) state.selection = null, redraw.call(that); + emit.end(); + } - abort: function() { - xhr.abort(); - return request; - }, + function keydowned() { + switch (exports.event.keyCode) { + case 16: { // SHIFT + shifting = signX && signY; + break; + } + case 18: { // ALT + if (mode === MODE_HANDLE) { + if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; + if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; + mode = MODE_CENTER; + move(); + } + break; + } + case 32: { // SPACE; takes priority over ALT + if (mode === MODE_HANDLE || mode === MODE_CENTER) { + if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx; + if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy; + mode = MODE_SPACE; + overlay.attr("cursor", cursors.selection); + move(); + } + break; + } + default: return; + } + noevent$1(); + } - on: function() { - var value = event.on.apply(event, arguments); - return value === event ? request : value; + function keyupped() { + switch (exports.event.keyCode) { + case 16: { // SHIFT + if (shifting) { + lockX = lockY = shifting = false; + move(); + } + break; + } + case 18: { // ALT + if (mode === MODE_CENTER) { + if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; + if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; + mode = MODE_HANDLE; + move(); + } + break; + } + case 32: { // SPACE + if (mode === MODE_SPACE) { + if (exports.event.altKey) { + if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; + if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; + mode = MODE_CENTER; + } else { + if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; + if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; + mode = MODE_HANDLE; + } + overlay.attr("cursor", cursors[type]); + move(); + } + break; + } + default: return; + } + noevent$1(); } - }; - - if (callback != null) { - if (typeof callback !== "function") throw new Error("invalid callback: " + callback); - return request.get(callback); } - return request; -}; + function initialize() { + var state = this.__brush || {selection: null}; + state.extent = extent.apply(this, arguments); + state.dim = dim; + return state; + } -function fixCallback(callback) { - return function(error, xhr) { - callback(error == null ? xhr : null); + brush.extent = function(_) { + return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent; }; -} - -function hasResponse(xhr) { - var type = xhr.responseType; - return type && type !== "text" - ? xhr.response // null on error - : xhr.responseText; // "" on error -} -var type = function(defaultMimeType, response) { - return function(url, callback) { - var r = request(url).mimeType(defaultMimeType).response(response); - if (callback != null) { - if (typeof callback !== "function") throw new Error("invalid callback: " + callback); - return r.get(callback); - } - return r; + brush.filter = function(_) { + return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter; }; -}; - -var html = type("text/html", function(xhr) { - return document.createRange().createContextualFragment(xhr.responseText); -}); - -var json = type("application/json", function(xhr) { - return JSON.parse(xhr.responseText); -}); - -var text = type("text/plain", function(xhr) { - return xhr.responseText; -}); - -var xml = type("application/xml", function(xhr) { - var xml = xhr.responseXML; - if (!xml) throw new Error("parse error"); - return xml; -}); -var dsv$1 = function(defaultMimeType, parse) { - return function(url, row, callback) { - if (arguments.length < 3) callback = row, row = null; - var r = request(url).mimeType(defaultMimeType); - r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; }; - r.row(row); - return callback ? r.get(callback) : r; + brush.handleSize = function(_) { + return arguments.length ? (handleSize = +_, brush) : handleSize; }; -}; -function responseOf(parse, row) { - return function(request$$1) { - return parse(request$$1.responseText, row); + brush.on = function() { + var value = listeners.on.apply(listeners, arguments); + return value === listeners ? brush : value; }; -} - -var csv$1 = dsv$1("text/csv", csvParse); - -var tsv$1 = dsv$1("text/tab-separated-values", tsvParse); - -var frame = 0; -var timeout = 0; -var interval = 0; -var pokeDelay = 1000; -var taskHead; -var taskTail; -var clockLast = 0; -var clockNow = 0; -var clockSkew = 0; -var clock = typeof performance === "object" && performance.now ? performance : Date; -var setFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : function(f) { setTimeout(f, 17); }; - -function now() { - return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); -} - -function clearNow() { - clockNow = 0; -} -function Timer() { - this._call = - this._time = - this._next = null; + return brush; } -Timer.prototype = timer.prototype = { - constructor: Timer, - restart: function(callback, delay, time) { - if (typeof callback !== "function") throw new TypeError("callback is not a function"); - time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); - if (!this._next && taskTail !== this) { - if (taskTail) taskTail._next = this; - else taskHead = this; - taskTail = this; - } - this._call = callback; - this._time = time; - sleep(); - }, - stop: function() { - if (this._call) { - this._call = null; - this._time = Infinity; - sleep(); - } - } -}; - -function timer(callback, delay, time) { - var t = new Timer; - t.restart(callback, delay, time); - return t; -} +var cos = Math.cos; +var sin = Math.sin; +var pi$1 = Math.PI; +var halfPi$1 = pi$1 / 2; +var tau$1 = pi$1 * 2; +var max$1 = Math.max; -function timerFlush() { - now(); // Get the current time, if not already set. - ++frame; // Pretend we’ve set an alarm, if we haven’t already. - var t = taskHead, e; - while (t) { - if ((e = clockNow - t._time) >= 0) t._call.call(null, e); - t = t._next; - } - --frame; +function compareValue(compare) { + return function(a, b) { + return compare( + a.source.value + a.target.value, + b.source.value + b.target.value + ); + }; } -function wake() { - clockNow = (clockLast = clock.now()) + clockSkew; - frame = timeout = 0; - try { - timerFlush(); - } finally { - frame = 0; - nap(); - clockNow = 0; - } -} +var chord = function() { + var padAngle = 0, + sortGroups = null, + sortSubgroups = null, + sortChords = null; -function poke$1() { - var now = clock.now(), delay = now - clockLast; - if (delay > pokeDelay) clockSkew -= delay, clockLast = now; -} + function chord(matrix) { + var n = matrix.length, + groupSums = [], + groupIndex = sequence(n), + subgroupIndex = [], + chords = [], + groups = chords.groups = new Array(n), + subgroups = new Array(n * n), + k, + x, + x0, + dx, + i, + j; -function nap() { - var t0, t1 = taskHead, t2, time = Infinity; - while (t1) { - if (t1._call) { - if (time > t1._time) time = t1._time; - t0 = t1, t1 = t1._next; - } else { - t2 = t1._next, t1._next = null; - t1 = t0 ? t0._next = t2 : taskHead = t2; + // Compute the sum. + k = 0, i = -1; while (++i < n) { + x = 0, j = -1; while (++j < n) { + x += matrix[i][j]; + } + groupSums.push(x); + subgroupIndex.push(sequence(n)); + k += x; } - } - taskTail = t0; - sleep(time); -} -function sleep(time) { - if (frame) return; // Soonest alarm already set, or will be. - if (timeout) timeout = clearTimeout(timeout); - var delay = time - clockNow; - if (delay > 24) { - if (time < Infinity) timeout = setTimeout(wake, delay); - if (interval) interval = clearInterval(interval); - } else { - if (!interval) interval = setInterval(poke$1, pokeDelay); - frame = 1, setFrame(wake); - } -} + // Sort groups… + if (sortGroups) groupIndex.sort(function(a, b) { + return sortGroups(groupSums[a], groupSums[b]); + }); -var timeout$1 = function(callback, delay, time) { - var t = new Timer; - delay = delay == null ? 0 : +delay; - t.restart(function(elapsed) { - t.stop(); - callback(elapsed + delay); - }, delay, time); - return t; -}; + // Sort subgroups… + if (sortSubgroups) subgroupIndex.forEach(function(d, i) { + d.sort(function(a, b) { + return sortSubgroups(matrix[i][a], matrix[i][b]); + }); + }); -var interval$1 = function(callback, delay, time) { - var t = new Timer, total = delay; - if (delay == null) return t.restart(callback, delay, time), t; - delay = +delay, time = time == null ? now() : +time; - t.restart(function tick(elapsed) { - elapsed += total; - t.restart(tick, total += delay, time); - callback(elapsed); - }, delay, time); - return t; -}; + // Convert the sum to scaling factor for [0, 2pi]. + // TODO Allow start and end angle to be specified? + // TODO Allow padding to be specified as percentage? + k = max$1(0, tau$1 - padAngle * n) / k; + dx = k ? padAngle : tau$1 / n; -var t0$1 = new Date; -var t1$1 = new Date; + // Compute the start and end angle for each group and subgroup. + // Note: Opera has a bug reordering object literal properties! + x = 0, i = -1; while (++i < n) { + x0 = x, j = -1; while (++j < n) { + var di = groupIndex[i], + dj = subgroupIndex[di][j], + v = matrix[di][dj], + a0 = x, + a1 = x += v * k; + subgroups[dj * n + di] = { + index: di, + subindex: dj, + startAngle: a0, + endAngle: a1, + value: v + }; + } + groups[di] = { + index: di, + startAngle: x0, + endAngle: x, + value: groupSums[di] + }; + x += dx; + } -function newInterval(floori, offseti, count, field) { + // Generate chords for each (non-empty) subgroup-subgroup link. + i = -1; while (++i < n) { + j = i - 1; while (++j < n) { + var source = subgroups[j * n + i], + target = subgroups[i * n + j]; + if (source.value || target.value) { + chords.push(source.value < target.value + ? {source: target, target: source} + : {source: source, target: target}); + } + } + } - function interval(date) { - return floori(date = new Date(+date)), date; + return sortChords ? chords.sort(sortChords) : chords; } - interval.floor = interval; - - interval.ceil = function(date) { - return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date; + chord.padAngle = function(_) { + return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle; }; - interval.round = function(date) { - var d0 = interval(date), - d1 = interval.ceil(date); - return date - d0 < d1 - date ? d0 : d1; + chord.sortGroups = function(_) { + return arguments.length ? (sortGroups = _, chord) : sortGroups; }; - interval.offset = function(date, step) { - return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; + chord.sortSubgroups = function(_) { + return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups; }; - interval.range = function(start, stop, step) { - var range = []; - start = interval.ceil(start); - step = step == null ? 1 : Math.floor(step); - if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date - do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop) - return range; + chord.sortChords = function(_) { + return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._; }; - interval.filter = function(test) { - return newInterval(function(date) { - if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); - }, function(date, step) { - if (date >= date) while (--step >= 0) while (offseti(date, 1), !test(date)) {} // eslint-disable-line no-empty - }); + return chord; +}; + +var slice$2 = Array.prototype.slice; + +var constant$5 = function(x) { + return function() { + return x; }; +}; - if (count) { - interval.count = function(start, end) { - t0$1.setTime(+start), t1$1.setTime(+end); - floori(t0$1), floori(t1$1); - return Math.floor(count(t0$1, t1$1)); - }; +var pi$2 = Math.PI; +var tau$2 = 2 * pi$2; +var epsilon$1 = 1e-6; +var tauEpsilon = tau$2 - epsilon$1; - interval.every = function(step) { - step = Math.floor(step); - return !isFinite(step) || !(step > 0) ? null - : !(step > 1) ? interval - : interval.filter(field - ? function(d) { return field(d) % step === 0; } - : function(d) { return interval.count(0, d) % step === 0; }); - }; - } +function Path() { + this._x0 = this._y0 = // start of current subpath + this._x1 = this._y1 = null; // end of current subpath + this._ = ""; +} - return interval; +function path() { + return new Path; } -var millisecond = newInterval(function() { - // noop -}, function(date, step) { - date.setTime(+date + step); -}, function(start, end) { - return end - start; -}); +Path.prototype = path.prototype = { + constructor: Path, + moveTo: function(x, y) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); + }, + closePath: function() { + if (this._x1 !== null) { + this._x1 = this._x0, this._y1 = this._y0; + this._ += "Z"; + } + }, + lineTo: function(x, y) { + this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); + }, + quadraticCurveTo: function(x1, y1, x, y) { + this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + bezierCurveTo: function(x1, y1, x2, y2, x, y) { + this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + arcTo: function(x1, y1, x2, y2, r) { + x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; + var x0 = this._x1, + y0 = this._y1, + x21 = x2 - x1, + y21 = y2 - y1, + x01 = x0 - x1, + y01 = y0 - y1, + l01_2 = x01 * x01 + y01 * y01; -// An optimized implementation for this simple case. -millisecond.every = function(k) { - k = Math.floor(k); - if (!isFinite(k) || !(k > 0)) return null; - if (!(k > 1)) return millisecond; - return newInterval(function(date) { - date.setTime(Math.floor(date / k) * k); - }, function(date, step) { - date.setTime(+date + step * k); - }, function(start, end) { - return (end - start) / k; - }); -}; + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); -var milliseconds = millisecond.range; + // Is this path empty? Move to (x1,y1). + if (this._x1 === null) { + this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); + } -var durationSecond = 1e3; -var durationMinute = 6e4; -var durationHour = 36e5; -var durationDay = 864e5; -var durationWeek = 6048e5; + // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. + else if (!(l01_2 > epsilon$1)) {} -var second = newInterval(function(date) { - date.setTime(Math.floor(date / durationSecond) * durationSecond); -}, function(date, step) { - date.setTime(+date + step * durationSecond); -}, function(start, end) { - return (end - start) / durationSecond; -}, function(date) { - return date.getUTCSeconds(); -}); + // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? + // Equivalently, is (x1,y1) coincident with (x2,y2)? + // Or, is the radius zero? Line to (x1,y1). + else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) { + this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); + } -var seconds = second.range; + // Otherwise, draw an arc! + else { + var x20 = x2 - x0, + y20 = y2 - y0, + l21_2 = x21 * x21 + y21 * y21, + l20_2 = x20 * x20 + y20 * y20, + l21 = Math.sqrt(l21_2), + l01 = Math.sqrt(l01_2), + l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), + t01 = l / l01, + t21 = l / l21; -var minute = newInterval(function(date) { - date.setTime(Math.floor(date / durationMinute) * durationMinute); -}, function(date, step) { - date.setTime(+date + step * durationMinute); -}, function(start, end) { - return (end - start) / durationMinute; -}, function(date) { - return date.getMinutes(); -}); + // If the start tangent is not coincident with (x0,y0), line to. + if (Math.abs(t01 - 1) > epsilon$1) { + this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); + } -var minutes = minute.range; + this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); + } + }, + arc: function(x, y, r, a0, a1, ccw) { + x = +x, y = +y, r = +r; + var dx = r * Math.cos(a0), + dy = r * Math.sin(a0), + x0 = x + dx, + y0 = y + dy, + cw = 1 ^ ccw, + da = ccw ? a0 - a1 : a1 - a0; -var hour = newInterval(function(date) { - var offset = date.getTimezoneOffset() * durationMinute % durationHour; - if (offset < 0) offset += durationHour; - date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset); -}, function(date, step) { - date.setTime(+date + step * durationHour); -}, function(start, end) { - return (end - start) / durationHour; -}, function(date) { - return date.getHours(); -}); + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); -var hours = hour.range; + // Is this path empty? Move to (x0,y0). + if (this._x1 === null) { + this._ += "M" + x0 + "," + y0; + } -var day = newInterval(function(date) { - date.setHours(0, 0, 0, 0); -}, function(date, step) { - date.setDate(date.getDate() + step); -}, function(start, end) { - return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay; -}, function(date) { - return date.getDate() - 1; -}); + // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). + else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) { + this._ += "L" + x0 + "," + y0; + } -var days = day.range; + // Is this arc empty? We’re done. + if (!r) return; -function weekday(i) { - return newInterval(function(date) { - date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); - date.setHours(0, 0, 0, 0); - }, function(date, step) { - date.setDate(date.getDate() + step * 7); - }, function(start, end) { - return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek; - }); + // Does the angle go the wrong way? Flip the direction. + if (da < 0) da = da % tau$2 + tau$2; + + // Is this a complete circle? Draw two arcs to complete the circle. + if (da > tauEpsilon) { + this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); + } + + // Is this arc non-empty? Draw an arc! + else if (da > epsilon$1) { + this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); + } + }, + rect: function(x, y, w, h) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; + }, + toString: function() { + return this._; + } +}; + +function defaultSource(d) { + return d.source; +} + +function defaultTarget(d) { + return d.target; +} + +function defaultRadius(d) { + return d.radius; +} + +function defaultStartAngle(d) { + return d.startAngle; } -var sunday = weekday(0); -var monday = weekday(1); -var tuesday = weekday(2); -var wednesday = weekday(3); -var thursday = weekday(4); -var friday = weekday(5); -var saturday = weekday(6); +function defaultEndAngle(d) { + return d.endAngle; +} -var sundays = sunday.range; -var mondays = monday.range; -var tuesdays = tuesday.range; -var wednesdays = wednesday.range; -var thursdays = thursday.range; -var fridays = friday.range; -var saturdays = saturday.range; +var ribbon = function() { + var source = defaultSource, + target = defaultTarget, + radius = defaultRadius, + startAngle = defaultStartAngle, + endAngle = defaultEndAngle, + context = null; -var month = newInterval(function(date) { - date.setDate(1); - date.setHours(0, 0, 0, 0); -}, function(date, step) { - date.setMonth(date.getMonth() + step); -}, function(start, end) { - return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; -}, function(date) { - return date.getMonth(); -}); + function ribbon() { + var buffer, + argv = slice$2.call(arguments), + s = source.apply(this, argv), + t = target.apply(this, argv), + sr = +radius.apply(this, (argv[0] = s, argv)), + sa0 = startAngle.apply(this, argv) - halfPi$1, + sa1 = endAngle.apply(this, argv) - halfPi$1, + sx0 = sr * cos(sa0), + sy0 = sr * sin(sa0), + tr = +radius.apply(this, (argv[0] = t, argv)), + ta0 = startAngle.apply(this, argv) - halfPi$1, + ta1 = endAngle.apply(this, argv) - halfPi$1; -var months = month.range; + if (!context) context = buffer = path(); -var year = newInterval(function(date) { - date.setMonth(0, 1); - date.setHours(0, 0, 0, 0); -}, function(date, step) { - date.setFullYear(date.getFullYear() + step); -}, function(start, end) { - return end.getFullYear() - start.getFullYear(); -}, function(date) { - return date.getFullYear(); -}); + context.moveTo(sx0, sy0); + context.arc(0, 0, sr, sa0, sa1); + if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr? + context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0)); + context.arc(0, 0, tr, ta0, ta1); + } + context.quadraticCurveTo(0, 0, sx0, sy0); + context.closePath(); -// An optimized implementation for this simple case. -year.every = function(k) { - return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { - date.setFullYear(Math.floor(date.getFullYear() / k) * k); - date.setMonth(0, 1); - date.setHours(0, 0, 0, 0); - }, function(date, step) { - date.setFullYear(date.getFullYear() + step * k); - }); -}; + if (buffer) return context = null, buffer + "" || null; + } -var years = year.range; + ribbon.radius = function(_) { + return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius; + }; -var utcMinute = newInterval(function(date) { - date.setUTCSeconds(0, 0); -}, function(date, step) { - date.setTime(+date + step * durationMinute); -}, function(start, end) { - return (end - start) / durationMinute; -}, function(date) { - return date.getUTCMinutes(); -}); + ribbon.startAngle = function(_) { + return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle; + }; -var utcMinutes = utcMinute.range; + ribbon.endAngle = function(_) { + return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle; + }; -var utcHour = newInterval(function(date) { - date.setUTCMinutes(0, 0, 0); -}, function(date, step) { - date.setTime(+date + step * durationHour); -}, function(start, end) { - return (end - start) / durationHour; -}, function(date) { - return date.getUTCHours(); -}); + ribbon.source = function(_) { + return arguments.length ? (source = _, ribbon) : source; + }; -var utcHours = utcHour.range; + ribbon.target = function(_) { + return arguments.length ? (target = _, ribbon) : target; + }; -var utcDay = newInterval(function(date) { - date.setUTCHours(0, 0, 0, 0); -}, function(date, step) { - date.setUTCDate(date.getUTCDate() + step); -}, function(start, end) { - return (end - start) / durationDay; -}, function(date) { - return date.getUTCDate() - 1; -}); + ribbon.context = function(_) { + return arguments.length ? ((context = _ == null ? null : _), ribbon) : context; + }; -var utcDays = utcDay.range; + return ribbon; +}; -function utcWeekday(i) { - return newInterval(function(date) { - date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); - date.setUTCHours(0, 0, 0, 0); - }, function(date, step) { - date.setUTCDate(date.getUTCDate() + step * 7); - }, function(start, end) { - return (end - start) / durationWeek; - }); -} +var prefix = "$"; -var utcSunday = utcWeekday(0); -var utcMonday = utcWeekday(1); -var utcTuesday = utcWeekday(2); -var utcWednesday = utcWeekday(3); -var utcThursday = utcWeekday(4); -var utcFriday = utcWeekday(5); -var utcSaturday = utcWeekday(6); +function Map() {} -var utcSundays = utcSunday.range; -var utcMondays = utcMonday.range; -var utcTuesdays = utcTuesday.range; -var utcWednesdays = utcWednesday.range; -var utcThursdays = utcThursday.range; -var utcFridays = utcFriday.range; -var utcSaturdays = utcSaturday.range; +Map.prototype = map$1.prototype = { + constructor: Map, + has: function(key) { + return (prefix + key) in this; + }, + get: function(key) { + return this[prefix + key]; + }, + set: function(key, value) { + this[prefix + key] = value; + return this; + }, + remove: function(key) { + var property = prefix + key; + return property in this && delete this[property]; + }, + clear: function() { + for (var property in this) if (property[0] === prefix) delete this[property]; + }, + keys: function() { + var keys = []; + for (var property in this) if (property[0] === prefix) keys.push(property.slice(1)); + return keys; + }, + values: function() { + var values = []; + for (var property in this) if (property[0] === prefix) values.push(this[property]); + return values; + }, + entries: function() { + var entries = []; + for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]}); + return entries; + }, + size: function() { + var size = 0; + for (var property in this) if (property[0] === prefix) ++size; + return size; + }, + empty: function() { + for (var property in this) if (property[0] === prefix) return false; + return true; + }, + each: function(f) { + for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this); + } +}; -var utcMonth = newInterval(function(date) { - date.setUTCDate(1); - date.setUTCHours(0, 0, 0, 0); -}, function(date, step) { - date.setUTCMonth(date.getUTCMonth() + step); -}, function(start, end) { - return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; -}, function(date) { - return date.getUTCMonth(); -}); +function map$1(object, f) { + var map = new Map; -var utcMonths = utcMonth.range; + // Copy constructor. + if (object instanceof Map) object.each(function(value, key) { map.set(key, value); }); -var utcYear = newInterval(function(date) { - date.setUTCMonth(0, 1); - date.setUTCHours(0, 0, 0, 0); -}, function(date, step) { - date.setUTCFullYear(date.getUTCFullYear() + step); -}, function(start, end) { - return end.getUTCFullYear() - start.getUTCFullYear(); -}, function(date) { - return date.getUTCFullYear(); -}); + // Index array by numeric index or specified key function. + else if (Array.isArray(object)) { + var i = -1, + n = object.length, + o; -// An optimized implementation for this simple case. -utcYear.every = function(k) { - return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { - date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k); - date.setUTCMonth(0, 1); - date.setUTCHours(0, 0, 0, 0); - }, function(date, step) { - date.setUTCFullYear(date.getUTCFullYear() + step * k); - }); -}; + if (f == null) while (++i < n) map.set(i, object[i]); + else while (++i < n) map.set(f(o = object[i], i, object), o); + } -var utcYears = utcYear.range; + // Convert object to map. + else if (object) for (var key in object) map.set(key, object[key]); -// Computes the decimal coefficient and exponent of the specified number x with -// significant digits p, where x is positive and p is in [1, 21] or undefined. -// For example, formatDecimal(1.23) returns ["123", 0]. -var formatDecimal = function(x, p) { - if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity - var i, coefficient = x.slice(0, i); + return map; +} - // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ - // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). - return [ - coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, - +x.slice(i + 1) - ]; -}; +var nest = function() { + var keys = [], + sortKeys = [], + sortValues, + rollup, + nest; -var exponent$1 = function(x) { - return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; -}; + function apply(array, depth, createResult, setResult) { + if (depth >= keys.length) return rollup != null + ? rollup(array) : (sortValues != null + ? array.sort(sortValues) + : array); -var formatGroup = function(grouping, thousands) { - return function(value, width) { - var i = value.length, - t = [], - j = 0, - g = grouping[0], - length = 0; + var i = -1, + n = array.length, + key = keys[depth++], + keyValue, + value, + valuesByKey = map$1(), + values, + result = createResult(); - while (i > 0 && g > 0) { - if (length + g + 1 > width) g = Math.max(1, width - length); - t.push(value.substring(i -= g, i + g)); - if ((length += g + 1) > width) break; - g = grouping[j = (j + 1) % grouping.length]; + while (++i < n) { + if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) { + values.push(value); + } else { + valuesByKey.set(keyValue, [value]); + } } - return t.reverse().join(thousands); - }; -}; + valuesByKey.each(function(values, key) { + setResult(result, key, apply(values, depth, createResult, setResult)); + }); -var formatDefault = function(x, p) { - x = x.toPrecision(p); + return result; + } - out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { - switch (x[i]) { - case ".": i0 = i1 = i; break; - case "0": if (i0 === 0) i0 = i; i1 = i; break; - case "e": break out; - default: if (i0 > 0) i0 = 0; break; - } + function entries(map, depth) { + if (++depth > keys.length) return map; + var array, sortKey = sortKeys[depth - 1]; + if (rollup != null && depth >= keys.length) array = map.entries(); + else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); }); + return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; } - return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; + return nest = { + object: function(array) { return apply(array, 0, createObject, setObject); }, + map: function(array) { return apply(array, 0, createMap, setMap); }, + entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, + key: function(d) { keys.push(d); return nest; }, + sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, + sortValues: function(order) { sortValues = order; return nest; }, + rollup: function(f) { rollup = f; return nest; } + }; }; -var prefixExponent; - -var formatPrefixAuto = function(x, p) { - var d = formatDecimal(x, p); - if (!d) return x + ""; - var coefficient = d[0], - exponent = d[1], - i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, - n = coefficient.length; - return i === n ? coefficient - : i > n ? coefficient + new Array(i - n + 1).join("0") - : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) - : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! -}; +function createObject() { + return {}; +} -var formatRounded = function(x, p) { - var d = formatDecimal(x, p); - if (!d) return x + ""; - var coefficient = d[0], - exponent = d[1]; - return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient - : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) - : coefficient + new Array(exponent - coefficient.length + 2).join("0"); -}; +function setObject(object, key, value) { + object[key] = value; +} -var formatTypes = { - "": formatDefault, - "%": function(x, p) { return (x * 100).toFixed(p); }, - "b": function(x) { return Math.round(x).toString(2); }, - "c": function(x) { return x + ""; }, - "d": function(x) { return Math.round(x).toString(10); }, - "e": function(x, p) { return x.toExponential(p); }, - "f": function(x, p) { return x.toFixed(p); }, - "g": function(x, p) { return x.toPrecision(p); }, - "o": function(x) { return Math.round(x).toString(8); }, - "p": function(x, p) { return formatRounded(x * 100, p); }, - "r": formatRounded, - "s": formatPrefixAuto, - "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, - "x": function(x) { return Math.round(x).toString(16); } -}; +function createMap() { + return map$1(); +} -// [[fill]align][sign][symbol][0][width][,][.precision][type] -var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; +function setMap(map, key, value) { + map.set(key, value); +} -var formatSpecifier = function(specifier) { - return new FormatSpecifier(specifier); -}; +function Set() {} -function FormatSpecifier(specifier) { - if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); +var proto = map$1.prototype; - var match, - fill = match[1] || " ", - align = match[2] || ">", - sign = match[3] || "-", - symbol = match[4] || "", - zero = !!match[5], - width = match[6] && +match[6], - comma = !!match[7], - precision = match[8] && +match[8].slice(1), - type = match[9] || ""; +Set.prototype = set$2.prototype = { + constructor: Set, + has: proto.has, + add: function(value) { + value += ""; + this[prefix + value] = value; + return this; + }, + remove: proto.remove, + clear: proto.clear, + values: proto.keys, + size: proto.size, + empty: proto.empty, + each: proto.each +}; - // The "n" type is an alias for ",g". - if (type === "n") comma = true, type = "g"; +function set$2(object, f) { + var set = new Set; - // Map invalid types to the default format. - else if (!formatTypes[type]) type = ""; + // Copy constructor. + if (object instanceof Set) object.each(function(value) { set.add(value); }); - // If zero fill is specified, padding goes after sign and before digits. - if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; + // Otherwise, assume it’s an array. + else if (object) { + var i = -1, n = object.length; + if (f == null) while (++i < n) set.add(object[i]); + else while (++i < n) set.add(f(object[i], i, object)); + } - this.fill = fill; - this.align = align; - this.sign = sign; - this.symbol = symbol; - this.zero = zero; - this.width = width; - this.comma = comma; - this.precision = precision; - this.type = type; + return set; } -FormatSpecifier.prototype.toString = function() { - return this.fill - + this.align - + this.sign - + this.symbol - + (this.zero ? "0" : "") - + (this.width == null ? "" : Math.max(1, this.width | 0)) - + (this.comma ? "," : "") - + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) - + this.type; +var keys = function(map) { + var keys = []; + for (var key in map) keys.push(key); + return keys; }; -var prefixes = ["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P","E","Z","Y"]; - -function identity$3(x) { - return x; -} - -var formatLocale = function(locale) { - var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3, - currency = locale.currency, - decimal = locale.decimal; - - function newFormat(specifier) { - specifier = formatSpecifier(specifier); - - var fill = specifier.fill, - align = specifier.align, - sign = specifier.sign, - symbol = specifier.symbol, - zero = specifier.zero, - width = specifier.width, - comma = specifier.comma, - precision = specifier.precision, - type = specifier.type; +var values = function(map) { + var values = []; + for (var key in map) values.push(map[key]); + return values; +}; - // Compute the prefix and suffix. - // For SI-prefix, the suffix is lazily computed. - var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", - suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : ""; +var entries = function(map) { + var entries = []; + for (var key in map) entries.push({key: key, value: map[key]}); + return entries; +}; - // What format function should we use? - // Is this an integer type? - // Can this type generate exponential notation? - var formatType = formatTypes[type], - maybeSuffix = !type || /[defgprs%]/.test(type); +function objectConverter(columns) { + return new Function("d", "return {" + columns.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); +} - // Set the default precision if not specified, - // or clamp the specified precision to the supported range. - // For significant precision, it must be in [1, 21]. - // For fixed precision, it must be in [0, 20]. - precision = precision == null ? (type ? 6 : 12) - : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) - : Math.max(0, Math.min(20, precision)); +function customConverter(columns, f) { + var object = objectConverter(columns); + return function(row, i) { + return f(object(row), i, columns); + }; +} - function format(value) { - var valuePrefix = prefix, - valueSuffix = suffix, - i, n, c; +// Compute unique columns in order of discovery. +function inferColumns(rows) { + var columnSet = Object.create(null), + columns = []; - if (type === "c") { - valueSuffix = formatType(value) + valueSuffix; - value = ""; - } else { - value = +value; + rows.forEach(function(row) { + for (var column in row) { + if (!(column in columnSet)) { + columns.push(columnSet[column] = column); + } + } + }); - // Convert negative to positive, and compute the prefix. - // Note that -0 is not less than 0, but 1 / -0 is! - var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true); + return columns; +} - // Perform the initial formatting. - value = formatType(value, precision); +var dsv = function(delimiter) { + var reFormat = new RegExp("[\"" + delimiter + "\n\r]"), + delimiterCode = delimiter.charCodeAt(0); - // If the original value was negative, it may be rounded to zero during - // formatting; treat this as (positive) zero. - if (valueNegative) { - i = -1, n = value.length; - valueNegative = false; - while (++i < n) { - if (c = value.charCodeAt(i), (48 < c && c < 58) - || (type === "x" && 96 < c && c < 103) - || (type === "X" && 64 < c && c < 71)) { - valueNegative = true; - break; - } - } - } + function parse(text, f) { + var convert, columns, rows = parseRows(text, function(row, i) { + if (convert) return convert(row, i - 1); + columns = row, convert = f ? customConverter(row, f) : objectConverter(row); + }); + rows.columns = columns; + return rows; + } - // Compute the prefix and suffix. - valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; - valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : ""); + function parseRows(text, f) { + var EOL = {}, // sentinel value for end-of-line + EOF = {}, // sentinel value for end-of-file + rows = [], // output rows + N = text.length, + I = 0, // current character index + n = 0, // the current line number + t, // the current token + eol; // is the current token followed by EOL? - // Break the formatted value into the integer “value” part that can be - // grouped, and fractional or exponential “suffix” part that is not. - if (maybeSuffix) { - i = -1, n = value.length; - while (++i < n) { - if (c = value.charCodeAt(i), 48 > c || c > 57) { - valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; - value = value.slice(0, i); - break; - } + function token() { + if (I >= N) return EOF; // special case: end of file + if (eol) return eol = false, EOL; // special case: end of line + + // special case: quotes + var j = I, c; + if (text.charCodeAt(j) === 34) { + var i = j; + while (i++ < N) { + if (text.charCodeAt(i) === 34) { + if (text.charCodeAt(i + 1) !== 34) break; + ++i; } } + I = i + 2; + c = text.charCodeAt(i + 1); + if (c === 13) { + eol = true; + if (text.charCodeAt(i + 2) === 10) ++I; + } else if (c === 10) { + eol = true; + } + return text.slice(j + 1, i).replace(/""/g, "\""); } - // If the fill character is not "0", grouping is applied before padding. - if (comma && !zero) value = group(value, Infinity); - - // Compute the padding. - var length = valuePrefix.length + value.length + valueSuffix.length, - padding = length < width ? new Array(width - length + 1).join(fill) : ""; + // common case: find next delimiter or newline + while (I < N) { + var k = 1; + c = text.charCodeAt(I++); + if (c === 10) eol = true; // \n + else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n + else if (c !== delimiterCode) continue; + return text.slice(j, I - k); + } - // If the fill character is "0", grouping is applied after padding. - if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; + // special case: last token before EOF + return text.slice(j); + } - // Reconstruct the final output based on the desired alignment. - switch (align) { - case "<": return valuePrefix + value + valueSuffix + padding; - case "=": return valuePrefix + padding + value + valueSuffix; - case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); + while ((t = token()) !== EOF) { + var a = []; + while (t !== EOL && t !== EOF) { + a.push(t); + t = token(); } - return padding + valuePrefix + value + valueSuffix; + if (f && (a = f(a, n++)) == null) continue; + rows.push(a); } - format.toString = function() { - return specifier + ""; - }; - - return format; + return rows; } - function formatPrefix(specifier, value) { - var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), - e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3, - k = Math.pow(10, -e), - prefix = prefixes[8 + e / 3]; - return function(value) { - return f(k * value) + prefix; - }; + function format(rows, columns) { + if (columns == null) columns = inferColumns(rows); + return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) { + return columns.map(function(column) { + return formatValue(row[column]); + }).join(delimiter); + })).join("\n"); } - return { - format: newFormat, - formatPrefix: formatPrefix - }; -}; - -var locale$1; - - + function formatRows(rows) { + return rows.map(formatRow).join("\n"); + } -defaultLocale({ - decimal: ".", - thousands: ",", - grouping: [3], - currency: ["$", ""] -}); + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } -function defaultLocale(definition) { - locale$1 = formatLocale(definition); - exports.format = locale$1.format; - exports.formatPrefix = locale$1.formatPrefix; - return locale$1; -} + function formatValue(text) { + return text == null ? "" + : reFormat.test(text += "") ? "\"" + text.replace(/\"/g, "\"\"") + "\"" + : text; + } -var precisionFixed = function(step) { - return Math.max(0, -exponent$1(Math.abs(step))); + return { + parse: parse, + parseRows: parseRows, + format: format, + formatRows: formatRows + }; }; -var precisionPrefix = function(step, value) { - return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step))); -}; +var csv = dsv(","); -var precisionRound = function(step, max) { - step = Math.abs(step), max = Math.abs(max) - step; - return Math.max(0, exponent$1(max) - exponent$1(step)) + 1; -}; +var csvParse = csv.parse; +var csvParseRows = csv.parseRows; +var csvFormat = csv.format; +var csvFormatRows = csv.formatRows; -function localDate(d) { - if (0 <= d.y && d.y < 100) { - var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); - date.setFullYear(d.y); - return date; - } - return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); -} +var tsv = dsv("\t"); -function utcDate(d) { - if (0 <= d.y && d.y < 100) { - var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); - date.setUTCFullYear(d.y); - return date; - } - return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); -} +var tsvParse = tsv.parse; +var tsvParseRows = tsv.parseRows; +var tsvFormat = tsv.format; +var tsvFormatRows = tsv.formatRows; -function newYear(y) { - return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; -} +var center$1 = function(x, y) { + var nodes; -function formatLocale$1(locale) { - var locale_dateTime = locale.dateTime, - locale_date = locale.date, - locale_time = locale.time, - locale_periods = locale.periods, - locale_weekdays = locale.days, - locale_shortWeekdays = locale.shortDays, - locale_months = locale.months, - locale_shortMonths = locale.shortMonths; + if (x == null) x = 0; + if (y == null) y = 0; - var periodRe = formatRe(locale_periods), - periodLookup = formatLookup(locale_periods), - weekdayRe = formatRe(locale_weekdays), - weekdayLookup = formatLookup(locale_weekdays), - shortWeekdayRe = formatRe(locale_shortWeekdays), - shortWeekdayLookup = formatLookup(locale_shortWeekdays), - monthRe = formatRe(locale_months), - monthLookup = formatLookup(locale_months), - shortMonthRe = formatRe(locale_shortMonths), - shortMonthLookup = formatLookup(locale_shortMonths); + function force() { + var i, + n = nodes.length, + node, + sx = 0, + sy = 0; - var formats = { - "a": formatShortWeekday, - "A": formatWeekday, - "b": formatShortMonth, - "B": formatMonth, - "c": null, - "d": formatDayOfMonth, - "e": formatDayOfMonth, - "H": formatHour24, - "I": formatHour12, - "j": formatDayOfYear, - "L": formatMilliseconds, - "m": formatMonthNumber, - "M": formatMinutes, - "p": formatPeriod, - "S": formatSeconds, - "U": formatWeekNumberSunday, - "w": formatWeekdayNumber, - "W": formatWeekNumberMonday, - "x": null, - "X": null, - "y": formatYear, - "Y": formatFullYear, - "Z": formatZone, - "%": formatLiteralPercent + for (i = 0; i < n; ++i) { + node = nodes[i], sx += node.x, sy += node.y; + } + + for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) { + node = nodes[i], node.x -= sx, node.y -= sy; + } + } + + force.initialize = function(_) { + nodes = _; }; - var utcFormats = { - "a": formatUTCShortWeekday, - "A": formatUTCWeekday, - "b": formatUTCShortMonth, - "B": formatUTCMonth, - "c": null, - "d": formatUTCDayOfMonth, - "e": formatUTCDayOfMonth, - "H": formatUTCHour24, - "I": formatUTCHour12, - "j": formatUTCDayOfYear, - "L": formatUTCMilliseconds, - "m": formatUTCMonthNumber, - "M": formatUTCMinutes, - "p": formatUTCPeriod, - "S": formatUTCSeconds, - "U": formatUTCWeekNumberSunday, - "w": formatUTCWeekdayNumber, - "W": formatUTCWeekNumberMonday, - "x": null, - "X": null, - "y": formatUTCYear, - "Y": formatUTCFullYear, - "Z": formatUTCZone, - "%": formatLiteralPercent + force.x = function(_) { + return arguments.length ? (x = +_, force) : x; }; - var parses = { - "a": parseShortWeekday, - "A": parseWeekday, - "b": parseShortMonth, - "B": parseMonth, - "c": parseLocaleDateTime, - "d": parseDayOfMonth, - "e": parseDayOfMonth, - "H": parseHour24, - "I": parseHour24, - "j": parseDayOfYear, - "L": parseMilliseconds, - "m": parseMonthNumber, - "M": parseMinutes, - "p": parsePeriod, - "S": parseSeconds, - "U": parseWeekNumberSunday, - "w": parseWeekdayNumber, - "W": parseWeekNumberMonday, - "x": parseLocaleDate, - "X": parseLocaleTime, - "y": parseYear, - "Y": parseFullYear, - "Z": parseZone, - "%": parseLiteralPercent + force.y = function(_) { + return arguments.length ? (y = +_, force) : y; }; - // These recursive directive definitions must be deferred. - formats.x = newFormat(locale_date, formats); - formats.X = newFormat(locale_time, formats); - formats.c = newFormat(locale_dateTime, formats); - utcFormats.x = newFormat(locale_date, utcFormats); - utcFormats.X = newFormat(locale_time, utcFormats); - utcFormats.c = newFormat(locale_dateTime, utcFormats); + return force; +}; - function newFormat(specifier, formats) { - return function(date) { - var string = [], - i = -1, - j = 0, - n = specifier.length, - c, - pad, - format; +var constant$6 = function(x) { + return function() { + return x; + }; +}; - if (!(date instanceof Date)) date = new Date(+date); +var jiggle = function() { + return (Math.random() - 0.5) * 1e-6; +}; - while (++i < n) { - if (specifier.charCodeAt(i) === 37) { - string.push(specifier.slice(j, i)); - if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); - else pad = c === "e" ? " " : "0"; - if (format = formats[c]) c = format(date, pad); - string.push(c); - j = i + 1; - } - } +var tree_add = function(d) { + var x = +this._x.call(null, d), + y = +this._y.call(null, d); + return add(this.cover(x, y), x, y, d); +}; - string.push(specifier.slice(j, i)); - return string.join(""); - }; +function add(tree, x, y, d) { + if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points + + var parent, + node = tree._root, + leaf = {data: d}, + x0 = tree._x0, + y0 = tree._y0, + x1 = tree._x1, + y1 = tree._y1, + xm, + ym, + xp, + yp, + right, + bottom, + i, + j; + + // If the tree is empty, initialize the root as a leaf. + if (!node) return tree._root = leaf, tree; + + // Find the existing leaf for the new point, or add it. + while (node.length) { + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; } - function newParse(specifier, newDate) { - return function(string) { - var d = newYear(1900), - i = parseSpecifier(d, specifier, string += "", 0); - if (i != string.length) return null; + // Is the new point is exactly coincident with the existing point? + xp = +tree._x.call(null, node.data); + yp = +tree._y.call(null, node.data); + if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; - // The am-pm flag is 0 for AM, and 1 for PM. - if ("p" in d) d.H = d.H % 12 + d.p * 12; + // Otherwise, split the leaf node until the old and new point are separated. + do { + parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm))); + return parent[j] = node, parent[i] = leaf, tree; +} - // Convert day-of-week and week-of-year to day-of-year. - if ("W" in d || "U" in d) { - if (!("w" in d)) d.w = "W" in d ? 1 : 0; - var day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay(); - d.m = 0; - d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7; - } +function addAll(data) { + var d, i, n = data.length, + x, + y, + xz = new Array(n), + yz = new Array(n), + x0 = Infinity, + y0 = Infinity, + x1 = -Infinity, + y1 = -Infinity; - // If a time zone is specified, all fields are interpreted as UTC and then - // offset according to the specified time zone. - if ("Z" in d) { - d.H += d.Z / 100 | 0; - d.M += d.Z % 100; - return utcDate(d); - } + // Compute the points and their extent. + for (i = 0; i < n; ++i) { + if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue; + xz[i] = x; + yz[i] = y; + if (x < x0) x0 = x; + if (x > x1) x1 = x; + if (y < y0) y0 = y; + if (y > y1) y1 = y; + } - // Otherwise, all fields are in local time. - return newDate(d); - }; + // If there were no (valid) points, inherit the existing extent. + if (x1 < x0) x0 = this._x0, x1 = this._x1; + if (y1 < y0) y0 = this._y0, y1 = this._y1; + + // Expand the tree to cover the new points. + this.cover(x0, y0).cover(x1, y1); + + // Add the new points. + for (i = 0; i < n; ++i) { + add(this, xz[i], yz[i], data[i]); } - function parseSpecifier(d, specifier, string, j) { - var i = 0, - n = specifier.length, - m = string.length, - c, - parse; + return this; +} - while (i < n) { - if (j >= m) return -1; - c = specifier.charCodeAt(i++); - if (c === 37) { - c = specifier.charAt(i++); - parse = parses[c in pads ? specifier.charAt(i++) : c]; - if (!parse || ((j = parse(d, string, j)) < 0)) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; +var tree_cover = function(x, y) { + if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points + + var x0 = this._x0, + y0 = this._y0, + x1 = this._x1, + y1 = this._y1; + + // If the quadtree has no extent, initialize them. + // Integer extent are necessary so that if we later double the extent, + // the existing quadrant boundaries don’t change due to floating point error! + if (isNaN(x0)) { + x1 = (x0 = Math.floor(x)) + 1; + y1 = (y0 = Math.floor(y)) + 1; + } + + // Otherwise, double repeatedly to cover. + else if (x0 > x || x > x1 || y0 > y || y > y1) { + var z = x1 - x0, + node = this._root, + parent, + i; + + switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) { + case 0: { + do parent = new Array(4), parent[i] = node, node = parent; + while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1); + break; + } + case 1: { + do parent = new Array(4), parent[i] = node, node = parent; + while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1); + break; + } + case 2: { + do parent = new Array(4), parent[i] = node, node = parent; + while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y); + break; + } + case 3: { + do parent = new Array(4), parent[i] = node, node = parent; + while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y); + break; } } - return j; + if (this._root && this._root.length) this._root = node; } - function parsePeriod(d, string, i) { - var n = periodRe.exec(string.slice(i)); - return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } + // If the quadtree covers the point already, just return. + else return this; - function parseShortWeekday(d, string, i) { - var n = shortWeekdayRe.exec(string.slice(i)); - return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } + this._x0 = x0; + this._y0 = y0; + this._x1 = x1; + this._y1 = y1; + return this; +}; - function parseWeekday(d, string, i) { - var n = weekdayRe.exec(string.slice(i)); - return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } +var tree_data = function() { + var data = []; + this.visit(function(node) { + if (!node.length) do data.push(node.data); while (node = node.next) + }); + return data; +}; - function parseShortMonth(d, string, i) { - var n = shortMonthRe.exec(string.slice(i)); - return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } +var tree_extent = function(_) { + return arguments.length + ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) + : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]]; +}; - function parseMonth(d, string, i) { - var n = monthRe.exec(string.slice(i)); - return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; - } +var Quad = function(node, x0, y0, x1, y1) { + this.node = node; + this.x0 = x0; + this.y0 = y0; + this.x1 = x1; + this.y1 = y1; +}; - function parseLocaleDateTime(d, string, i) { - return parseSpecifier(d, locale_dateTime, string, i); - } +var tree_find = function(x, y, radius) { + var data, + x0 = this._x0, + y0 = this._y0, + x1, + y1, + x2, + y2, + x3 = this._x1, + y3 = this._y1, + quads = [], + node = this._root, + q, + i; - function parseLocaleDate(d, string, i) { - return parseSpecifier(d, locale_date, string, i); + if (node) quads.push(new Quad(node, x0, y0, x3, y3)); + if (radius == null) radius = Infinity; + else { + x0 = x - radius, y0 = y - radius; + x3 = x + radius, y3 = y + radius; + radius *= radius; } - function parseLocaleTime(d, string, i) { - return parseSpecifier(d, locale_time, string, i); - } + while (q = quads.pop()) { - function formatShortWeekday(d) { - return locale_shortWeekdays[d.getDay()]; - } + // Stop searching if this quadrant can’t contain a closer node. + if (!(node = q.node) + || (x1 = q.x0) > x3 + || (y1 = q.y0) > y3 + || (x2 = q.x1) < x0 + || (y2 = q.y1) < y0) continue; - function formatWeekday(d) { - return locale_weekdays[d.getDay()]; - } + // Bisect the current quadrant. + if (node.length) { + var xm = (x1 + x2) / 2, + ym = (y1 + y2) / 2; - function formatShortMonth(d) { - return locale_shortMonths[d.getMonth()]; - } + quads.push( + new Quad(node[3], xm, ym, x2, y2), + new Quad(node[2], x1, ym, xm, y2), + new Quad(node[1], xm, y1, x2, ym), + new Quad(node[0], x1, y1, xm, ym) + ); - function formatMonth(d) { - return locale_months[d.getMonth()]; - } + // Visit the closest quadrant first. + if (i = (y >= ym) << 1 | (x >= xm)) { + q = quads[quads.length - 1]; + quads[quads.length - 1] = quads[quads.length - 1 - i]; + quads[quads.length - 1 - i] = q; + } + } - function formatPeriod(d) { - return locale_periods[+(d.getHours() >= 12)]; + // Visit this point. (Visiting coincident points isn’t necessary!) + else { + var dx = x - +this._x.call(null, node.data), + dy = y - +this._y.call(null, node.data), + d2 = dx * dx + dy * dy; + if (d2 < radius) { + var d = Math.sqrt(radius = d2); + x0 = x - d, y0 = y - d; + x3 = x + d, y3 = y + d; + data = node.data; + } + } } - function formatUTCShortWeekday(d) { - return locale_shortWeekdays[d.getUTCDay()]; - } + return data; +}; - function formatUTCWeekday(d) { - return locale_weekdays[d.getUTCDay()]; - } +var tree_remove = function(d) { + if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points - function formatUTCShortMonth(d) { - return locale_shortMonths[d.getUTCMonth()]; - } + var parent, + node = this._root, + retainer, + previous, + next, + x0 = this._x0, + y0 = this._y0, + x1 = this._x1, + y1 = this._y1, + x, + y, + xm, + ym, + right, + bottom, + i, + j; - function formatUTCMonth(d) { - return locale_months[d.getUTCMonth()]; - } + // If the tree is empty, initialize the root as a leaf. + if (!node) return this; - function formatUTCPeriod(d) { - return locale_periods[+(d.getUTCHours() >= 12)]; + // Find the leaf node for the point. + // While descending, also retain the deepest parent with a non-removed sibling. + if (node.length) while (true) { + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + if (!(parent = node, node = node[i = bottom << 1 | right])) return this; + if (!node.length) break; + if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i; } - return { - format: function(specifier) { - var f = newFormat(specifier += "", formats); - f.toString = function() { return specifier; }; - return f; - }, - parse: function(specifier) { - var p = newParse(specifier += "", localDate); - p.toString = function() { return specifier; }; - return p; - }, - utcFormat: function(specifier) { - var f = newFormat(specifier += "", utcFormats); - f.toString = function() { return specifier; }; - return f; - }, - utcParse: function(specifier) { - var p = newParse(specifier, utcDate); - p.toString = function() { return specifier; }; - return p; - } - }; -} + // Find the point to remove. + while (node.data !== d) if (!(previous = node, node = node.next)) return this; + if (next = node.next) delete node.next; -var pads = {"-": "", "_": " ", "0": "0"}; -var numberRe = /^\s*\d+/; -var percentRe = /^%/; -var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; + // If there are multiple coincident points, remove just the point. + if (previous) return (next ? previous.next = next : delete previous.next), this; -function pad(value, fill, width) { - var sign = value < 0 ? "-" : "", - string = (sign ? -value : value) + "", - length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); -} + // If this is the root point, remove it. + if (!parent) return this._root = next, this; -function requote(s) { - return s.replace(requoteRe, "\\$&"); -} + // Remove this leaf. + next ? parent[i] = next : delete parent[i]; -function formatRe(names) { - return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); -} + // If the parent now contains exactly one leaf, collapse superfluous parents. + if ((node = parent[0] || parent[1] || parent[2] || parent[3]) + && node === (parent[3] || parent[2] || parent[1] || parent[0]) + && !node.length) { + if (retainer) retainer[j] = node; + else this._root = node; + } -function formatLookup(names) { - var map = {}, i = -1, n = names.length; - while (++i < n) map[names[i].toLowerCase()] = i; - return map; + return this; +}; + +function removeAll(data) { + for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); + return this; } -function parseWeekdayNumber(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 1)); - return n ? (d.w = +n[0], i + n[0].length) : -1; -} +var tree_root = function() { + return this._root; +}; + +var tree_size = function() { + var size = 0; + this.visit(function(node) { + if (!node.length) do ++size; while (node = node.next) + }); + return size; +}; + +var tree_visit = function(callback) { + var quads = [], q, node = this._root, child, x0, y0, x1, y1; + if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1)); + while (q = quads.pop()) { + if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { + var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; + if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); + if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); + if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); + if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); + } + } + return this; +}; + +var tree_visitAfter = function(callback) { + var quads = [], next = [], q; + if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1)); + while (q = quads.pop()) { + var node = q.node; + if (node.length) { + var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; + if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); + if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); + if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); + if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); + } + next.push(q); + } + while (q = next.pop()) { + callback(q.node, q.x0, q.y0, q.x1, q.y1); + } + return this; +}; -function parseWeekNumberSunday(d, string, i) { - var n = numberRe.exec(string.slice(i)); - return n ? (d.U = +n[0], i + n[0].length) : -1; +function defaultX(d) { + return d[0]; } -function parseWeekNumberMonday(d, string, i) { - var n = numberRe.exec(string.slice(i)); - return n ? (d.W = +n[0], i + n[0].length) : -1; -} +var tree_x = function(_) { + return arguments.length ? (this._x = _, this) : this._x; +}; -function parseFullYear(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 4)); - return n ? (d.y = +n[0], i + n[0].length) : -1; +function defaultY(d) { + return d[1]; } -function parseYear(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; -} +var tree_y = function(_) { + return arguments.length ? (this._y = _, this) : this._y; +}; -function parseZone(d, string, i) { - var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6)); - return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1; +function quadtree(nodes, x, y) { + var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN); + return nodes == null ? tree : tree.addAll(nodes); } -function parseMonthNumber(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.m = n[0] - 1, i + n[0].length) : -1; +function Quadtree(x, y, x0, y0, x1, y1) { + this._x = x; + this._y = y; + this._x0 = x0; + this._y0 = y0; + this._x1 = x1; + this._y1 = y1; + this._root = undefined; } -function parseDayOfMonth(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.d = +n[0], i + n[0].length) : -1; +function leaf_copy(leaf) { + var copy = {data: leaf.data}, next = copy; + while (leaf = leaf.next) next = next.next = {data: leaf.data}; + return copy; } -function parseDayOfYear(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 3)); - return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; -} +var treeProto = quadtree.prototype = Quadtree.prototype; -function parseHour24(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.H = +n[0], i + n[0].length) : -1; -} +treeProto.copy = function() { + var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), + node = this._root, + nodes, + child; -function parseMinutes(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.M = +n[0], i + n[0].length) : -1; -} + if (!node) return copy; -function parseSeconds(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 2)); - return n ? (d.S = +n[0], i + n[0].length) : -1; -} + if (!node.length) return copy._root = leaf_copy(node), copy; -function parseMilliseconds(d, string, i) { - var n = numberRe.exec(string.slice(i, i + 3)); - return n ? (d.L = +n[0], i + n[0].length) : -1; -} + nodes = [{source: node, target: copy._root = new Array(4)}]; + while (node = nodes.pop()) { + for (var i = 0; i < 4; ++i) { + if (child = node.source[i]) { + if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)}); + else node.target[i] = leaf_copy(child); + } + } + } -function parseLiteralPercent(d, string, i) { - var n = percentRe.exec(string.slice(i, i + 1)); - return n ? i + n[0].length : -1; -} + return copy; +}; -function formatDayOfMonth(d, p) { - return pad(d.getDate(), p, 2); -} +treeProto.add = tree_add; +treeProto.addAll = addAll; +treeProto.cover = tree_cover; +treeProto.data = tree_data; +treeProto.extent = tree_extent; +treeProto.find = tree_find; +treeProto.remove = tree_remove; +treeProto.removeAll = removeAll; +treeProto.root = tree_root; +treeProto.size = tree_size; +treeProto.visit = tree_visit; +treeProto.visitAfter = tree_visitAfter; +treeProto.x = tree_x; +treeProto.y = tree_y; -function formatHour24(d, p) { - return pad(d.getHours(), p, 2); +function x(d) { + return d.x + d.vx; } -function formatHour12(d, p) { - return pad(d.getHours() % 12 || 12, p, 2); +function y(d) { + return d.y + d.vy; } -function formatDayOfYear(d, p) { - return pad(1 + day.count(year(d), d), p, 3); -} +var collide = function(radius) { + var nodes, + radii, + strength = 1, + iterations = 1; -function formatMilliseconds(d, p) { - return pad(d.getMilliseconds(), p, 3); -} + if (typeof radius !== "function") radius = constant$6(radius == null ? 1 : +radius); -function formatMonthNumber(d, p) { - return pad(d.getMonth() + 1, p, 2); -} + function force() { + var i, n = nodes.length, + tree, + node, + xi, + yi, + ri, + ri2; -function formatMinutes(d, p) { - return pad(d.getMinutes(), p, 2); -} + for (var k = 0; k < iterations; ++k) { + tree = quadtree(nodes, x, y).visitAfter(prepare); + for (i = 0; i < n; ++i) { + node = nodes[i]; + ri = radii[node.index], ri2 = ri * ri; + xi = node.x + node.vx; + yi = node.y + node.vy; + tree.visit(apply); + } + } -function formatSeconds(d, p) { - return pad(d.getSeconds(), p, 2); -} + function apply(quad, x0, y0, x1, y1) { + var data = quad.data, rj = quad.r, r = ri + rj; + if (data) { + if (data.index > node.index) { + var x = xi - data.x - data.vx, + y = yi - data.y - data.vy, + l = x * x + y * y; + if (l < r * r) { + if (x === 0) x = jiggle(), l += x * x; + if (y === 0) y = jiggle(), l += y * y; + l = (r - (l = Math.sqrt(l))) / l * strength; + node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj)); + node.vy += (y *= l) * r; + data.vx -= x * (r = 1 - r); + data.vy -= y * r; + } + } + return; + } + return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r; + } + } -function formatWeekNumberSunday(d, p) { - return pad(sunday.count(year(d), d), p, 2); -} + function prepare(quad) { + if (quad.data) return quad.r = radii[quad.data.index]; + for (var i = quad.r = 0; i < 4; ++i) { + if (quad[i] && quad[i].r > quad.r) { + quad.r = quad[i].r; + } + } + } -function formatWeekdayNumber(d) { - return d.getDay(); -} + function initialize() { + if (!nodes) return; + var i, n = nodes.length, node; + radii = new Array(n); + for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes); + } -function formatWeekNumberMonday(d, p) { - return pad(monday.count(year(d), d), p, 2); -} + force.initialize = function(_) { + nodes = _; + initialize(); + }; -function formatYear(d, p) { - return pad(d.getFullYear() % 100, p, 2); -} + force.iterations = function(_) { + return arguments.length ? (iterations = +_, force) : iterations; + }; -function formatFullYear(d, p) { - return pad(d.getFullYear() % 10000, p, 4); -} + force.strength = function(_) { + return arguments.length ? (strength = +_, force) : strength; + }; -function formatZone(d) { - var z = d.getTimezoneOffset(); - return (z > 0 ? "-" : (z *= -1, "+")) - + pad(z / 60 | 0, "0", 2) - + pad(z % 60, "0", 2); -} + force.radius = function(_) { + return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius; + }; -function formatUTCDayOfMonth(d, p) { - return pad(d.getUTCDate(), p, 2); -} + return force; +}; -function formatUTCHour24(d, p) { - return pad(d.getUTCHours(), p, 2); +function index(d) { + return d.index; } -function formatUTCHour12(d, p) { - return pad(d.getUTCHours() % 12 || 12, p, 2); +function find(nodeById, nodeId) { + var node = nodeById.get(nodeId); + if (!node) throw new Error("missing: " + nodeId); + return node; } -function formatUTCDayOfYear(d, p) { - return pad(1 + utcDay.count(utcYear(d), d), p, 3); -} +var link = function(links) { + var id = index, + strength = defaultStrength, + strengths, + distance = constant$6(30), + distances, + nodes, + count, + bias, + iterations = 1; -function formatUTCMilliseconds(d, p) { - return pad(d.getUTCMilliseconds(), p, 3); -} + if (links == null) links = []; -function formatUTCMonthNumber(d, p) { - return pad(d.getUTCMonth() + 1, p, 2); -} + function defaultStrength(link) { + return 1 / Math.min(count[link.source.index], count[link.target.index]); + } -function formatUTCMinutes(d, p) { - return pad(d.getUTCMinutes(), p, 2); -} + function force(alpha) { + for (var k = 0, n = links.length; k < iterations; ++k) { + for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { + link = links[i], source = link.source, target = link.target; + x = target.x + target.vx - source.x - source.vx || jiggle(); + y = target.y + target.vy - source.y - source.vy || jiggle(); + l = Math.sqrt(x * x + y * y); + l = (l - distances[i]) / l * alpha * strengths[i]; + x *= l, y *= l; + target.vx -= x * (b = bias[i]); + target.vy -= y * b; + source.vx += x * (b = 1 - b); + source.vy += y * b; + } + } + } -function formatUTCSeconds(d, p) { - return pad(d.getUTCSeconds(), p, 2); -} + function initialize() { + if (!nodes) return; -function formatUTCWeekNumberSunday(d, p) { - return pad(utcSunday.count(utcYear(d), d), p, 2); -} + var i, + n = nodes.length, + m = links.length, + nodeById = map$1(nodes, id), + link; -function formatUTCWeekdayNumber(d) { - return d.getUTCDay(); -} + for (i = 0, count = new Array(n); i < m; ++i) { + link = links[i], link.index = i; + if (typeof link.source !== "object") link.source = find(nodeById, link.source); + if (typeof link.target !== "object") link.target = find(nodeById, link.target); + count[link.source.index] = (count[link.source.index] || 0) + 1; + count[link.target.index] = (count[link.target.index] || 0) + 1; + } -function formatUTCWeekNumberMonday(d, p) { - return pad(utcMonday.count(utcYear(d), d), p, 2); -} + for (i = 0, bias = new Array(m); i < m; ++i) { + link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]); + } -function formatUTCYear(d, p) { - return pad(d.getUTCFullYear() % 100, p, 2); -} + strengths = new Array(m), initializeStrength(); + distances = new Array(m), initializeDistance(); + } -function formatUTCFullYear(d, p) { - return pad(d.getUTCFullYear() % 10000, p, 4); -} + function initializeStrength() { + if (!nodes) return; -function formatUTCZone() { - return "+0000"; -} + for (var i = 0, n = links.length; i < n; ++i) { + strengths[i] = +strength(links[i], i, links); + } + } -function formatLiteralPercent() { - return "%"; -} + function initializeDistance() { + if (!nodes) return; -var locale$2; + for (var i = 0, n = links.length; i < n; ++i) { + distances[i] = +distance(links[i], i, links); + } + } + force.initialize = function(_) { + nodes = _; + initialize(); + }; + force.links = function(_) { + return arguments.length ? (links = _, initialize(), force) : links; + }; + force.id = function(_) { + return arguments.length ? (id = _, force) : id; + }; + force.iterations = function(_) { + return arguments.length ? (iterations = +_, force) : iterations; + }; -defaultLocale$1({ - dateTime: "%x, %X", - date: "%-m/%-d/%Y", - time: "%-I:%M:%S %p", - periods: ["AM", "PM"], - days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], - shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], - months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] -}); + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initializeStrength(), force) : strength; + }; -function defaultLocale$1(definition) { - locale$2 = formatLocale$1(definition); - exports.timeFormat = locale$2.format; - exports.timeParse = locale$2.parse; - exports.utcFormat = locale$2.utcFormat; - exports.utcParse = locale$2.utcParse; - return locale$2; -} + force.distance = function(_) { + return arguments.length ? (distance = typeof _ === "function" ? _ : constant$6(+_), initializeDistance(), force) : distance; + }; -var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; + return force; +}; -function formatIsoNative(date) { - return date.toISOString(); +function x$1(d) { + return d.x; } -var formatIso = Date.prototype.toISOString - ? formatIsoNative - : exports.utcFormat(isoSpecifier); - -function parseIsoNative(string) { - var date = new Date(string); - return isNaN(date) ? null : date; +function y$1(d) { + return d.y; } -var parseIso = +new Date("2000-01-01T00:00:00.000Z") - ? parseIsoNative - : exports.utcParse(isoSpecifier); +var initialRadius = 10; +var initialAngle = Math.PI * (3 - Math.sqrt(5)); -var array$2 = Array.prototype; +var simulation = function(nodes) { + var simulation, + alpha = 1, + alphaMin = 0.001, + alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), + alphaTarget = 0, + velocityDecay = 0.6, + forces = map$1(), + stepper = timer(step), + event = dispatch("tick", "end"); -var map$3 = array$2.map; -var slice$3 = array$2.slice; + if (nodes == null) nodes = []; -var implicit = {name: "implicit"}; + function step() { + tick(); + event.call("tick", simulation); + if (alpha < alphaMin) { + stepper.stop(); + event.call("end", simulation); + } + } -function ordinal(range) { - var index = map$1(), - domain = [], - unknown = implicit; + function tick() { + var i, n = nodes.length, node; - range = range == null ? [] : slice$3.call(range); + alpha += (alphaTarget - alpha) * alphaDecay; - function scale(d) { - var key = d + "", i = index.get(key); - if (!i) { - if (unknown !== implicit) return unknown; - index.set(key, i = domain.push(d)); + forces.each(function(force) { + force(alpha); + }); + + for (i = 0; i < n; ++i) { + node = nodes[i]; + if (node.fx == null) node.x += node.vx *= velocityDecay; + else node.x = node.fx, node.vx = 0; + if (node.fy == null) node.y += node.vy *= velocityDecay; + else node.y = node.fy, node.vy = 0; } - return range[(i - 1) % range.length]; } - scale.domain = function(_) { - if (!arguments.length) return domain.slice(); - domain = [], index = map$1(); - var i = -1, n = _.length, d, key; - while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d)); - return scale; - }; + function initializeNodes() { + for (var i = 0, n = nodes.length, node; i < n; ++i) { + node = nodes[i], node.index = i; + if (isNaN(node.x) || isNaN(node.y)) { + var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle; + node.x = radius * Math.cos(angle); + node.y = radius * Math.sin(angle); + } + if (isNaN(node.vx) || isNaN(node.vy)) { + node.vx = node.vy = 0; + } + } + } - scale.range = function(_) { - return arguments.length ? (range = slice$3.call(_), scale) : range.slice(); - }; + function initializeForce(force) { + if (force.initialize) force.initialize(nodes); + return force; + } + + initializeNodes(); + + return simulation = { + tick: tick, + + restart: function() { + return stepper.restart(step), simulation; + }, + + stop: function() { + return stepper.stop(), simulation; + }, + + nodes: function(_) { + return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes; + }, - scale.unknown = function(_) { - return arguments.length ? (unknown = _, scale) : unknown; - }; + alpha: function(_) { + return arguments.length ? (alpha = +_, simulation) : alpha; + }, - scale.copy = function() { - return ordinal() - .domain(domain) - .range(range) - .unknown(unknown); - }; + alphaMin: function(_) { + return arguments.length ? (alphaMin = +_, simulation) : alphaMin; + }, - return scale; -} + alphaDecay: function(_) { + return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay; + }, -function band() { - var scale = ordinal().unknown(undefined), - domain = scale.domain, - ordinalRange = scale.range, - range$$1 = [0, 1], - step, - bandwidth, - round = false, - paddingInner = 0, - paddingOuter = 0, - align = 0.5; + alphaTarget: function(_) { + return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget; + }, - delete scale.unknown; + velocityDecay: function(_) { + return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay; + }, - function rescale() { - var n = domain().length, - reverse = range$$1[1] < range$$1[0], - start = range$$1[reverse - 0], - stop = range$$1[1 - reverse]; - step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); - if (round) step = Math.floor(step); - start += (stop - start - step * (n - paddingInner)) * align; - bandwidth = step * (1 - paddingInner); - if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); - var values = range(n).map(function(i) { return start + step * i; }); - return ordinalRange(reverse ? values.reverse() : values); - } + force: function(name, _) { + return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name); + }, - scale.domain = function(_) { - return arguments.length ? (domain(_), rescale()) : domain(); - }; + find: function(x, y, radius) { + var i = 0, + n = nodes.length, + dx, + dy, + d2, + node, + closest; - scale.range = function(_) { - return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice(); - }; + if (radius == null) radius = Infinity; + else radius *= radius; - scale.rangeRound = function(_) { - return range$$1 = [+_[0], +_[1]], round = true, rescale(); - }; + for (i = 0; i < n; ++i) { + node = nodes[i]; + dx = x - node.x; + dy = y - node.y; + d2 = dx * dx + dy * dy; + if (d2 < radius) closest = node, radius = d2; + } - scale.bandwidth = function() { - return bandwidth; - }; + return closest; + }, - scale.step = function() { - return step; + on: function(name, _) { + return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); + } }; +}; - scale.round = function(_) { - return arguments.length ? (round = !!_, rescale()) : round; - }; +var manyBody = function() { + var nodes, + node, + alpha, + strength = constant$6(-30), + strengths, + distanceMin2 = 1, + distanceMax2 = Infinity, + theta2 = 0.81; - scale.padding = function(_) { - return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner; - }; + function force(_) { + var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate); + for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); + } - scale.paddingInner = function(_) { - return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner; - }; + function initialize() { + if (!nodes) return; + var i, n = nodes.length, node; + strengths = new Array(n); + for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes); + } - scale.paddingOuter = function(_) { - return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter; - }; + function accumulate(quad) { + var strength = 0, q, c, x$$1, y$$1, i; - scale.align = function(_) { - return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align; - }; + // For internal nodes, accumulate forces from child quadrants. + if (quad.length) { + for (x$$1 = y$$1 = i = 0; i < 4; ++i) { + if ((q = quad[i]) && (c = q.value)) { + strength += c, x$$1 += c * q.x, y$$1 += c * q.y; + } + } + quad.x = x$$1 / strength; + quad.y = y$$1 / strength; + } - scale.copy = function() { - return band() - .domain(domain()) - .range(range$$1) - .round(round) - .paddingInner(paddingInner) - .paddingOuter(paddingOuter) - .align(align); - }; + // For leaf nodes, accumulate forces from coincident quadrants. + else { + q = quad; + q.x = q.data.x; + q.y = q.data.y; + do strength += strengths[q.data.index]; + while (q = q.next); + } - return rescale(); -} + quad.value = strength; + } -function pointish(scale) { - var copy = scale.copy; + function apply(quad, x1, _, x2) { + if (!quad.value) return true; - scale.padding = scale.paddingOuter; - delete scale.paddingInner; - delete scale.paddingOuter; + var x$$1 = quad.x - node.x, + y$$1 = quad.y - node.y, + w = x2 - x1, + l = x$$1 * x$$1 + y$$1 * y$$1; - scale.copy = function() { - return pointish(copy()); - }; + // Apply the Barnes-Hut approximation if possible. + // Limit forces for very close nodes; randomize direction if coincident. + if (w * w / theta2 < l) { + if (l < distanceMax2) { + if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1; + if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1; + if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); + node.vx += x$$1 * quad.value * alpha / l; + node.vy += y$$1 * quad.value * alpha / l; + } + return true; + } - return scale; -} + // Otherwise, process points directly. + else if (quad.length || l >= distanceMax2) return; -function point$4() { - return pointish(band().paddingInner(1)); -} + // Limit forces for very close nodes; randomize direction if coincident. + if (quad.data !== node || quad.next) { + if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1; + if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1; + if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); + } -var constant$4 = function(x) { - return function() { - return x; - }; -}; + do if (quad.data !== node) { + w = strengths[quad.data.index] * alpha / l; + node.vx += x$$1 * w; + node.vy += y$$1 * w; + } while (quad = quad.next); + } -var number$1 = function(x) { - return +x; -}; + force.initialize = function(_) { + nodes = _; + initialize(); + }; -var unit = [0, 1]; + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength; + }; -function deinterpolateLinear(a, b) { - return (b -= (a = +a)) - ? function(x) { return (x - a) / b; } - : constant$4(b); -} + force.distanceMin = function(_) { + return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2); + }; -function deinterpolateClamp(deinterpolate) { - return function(a, b) { - var d = deinterpolate(a = +a, b = +b); - return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); }; + force.distanceMax = function(_) { + return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2); }; -} -function reinterpolateClamp(reinterpolate) { - return function(a, b) { - var r = reinterpolate(a = +a, b = +b); - return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); }; + force.theta = function(_) { + return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2); }; -} -function bimap(domain, range$$1, deinterpolate, reinterpolate) { - var d0 = domain[0], d1 = domain[1], r0 = range$$1[0], r1 = range$$1[1]; - if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0); - else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1); - return function(x) { return r0(d0(x)); }; -} + return force; +}; -function polymap(domain, range$$1, deinterpolate, reinterpolate) { - var j = Math.min(domain.length, range$$1.length) - 1, - d = new Array(j), - r = new Array(j), - i = -1; +var x$2 = function(x) { + var strength = constant$6(0.1), + nodes, + strengths, + xz; - // Reverse descending domains. - if (domain[j] < domain[0]) { - domain = domain.slice().reverse(); - range$$1 = range$$1.slice().reverse(); + if (typeof x !== "function") x = constant$6(x == null ? 0 : +x); + + function force(alpha) { + for (var i = 0, n = nodes.length, node; i < n; ++i) { + node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha; + } } - while (++i < j) { - d[i] = deinterpolate(domain[i], domain[i + 1]); - r[i] = reinterpolate(range$$1[i], range$$1[i + 1]); + function initialize() { + if (!nodes) return; + var i, n = nodes.length; + strengths = new Array(n); + xz = new Array(n); + for (i = 0; i < n; ++i) { + strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); + } } - return function(x) { - var i = bisectRight(domain, x, 1, j) - 1; - return r[i](d[i](x)); + force.initialize = function(_) { + nodes = _; + initialize(); }; -} -function copy(source, target) { - return target - .domain(source.domain()) - .range(source.range()) - .interpolate(source.interpolate()) - .clamp(source.clamp()); -} + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength; + }; -// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. -// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b]. -function continuous(deinterpolate, reinterpolate) { - var domain = unit, - range$$1 = unit, - interpolate$$1 = interpolate, - clamp = false, - piecewise, - output, - input; + force.x = function(_) { + return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : x; + }; - function rescale() { - piecewise = Math.min(domain.length, range$$1.length) > 2 ? polymap : bimap; - output = input = null; - return scale; + return force; +}; + +var y$2 = function(y) { + var strength = constant$6(0.1), + nodes, + strengths, + yz; + + if (typeof y !== "function") y = constant$6(y == null ? 0 : +y); + + function force(alpha) { + for (var i = 0, n = nodes.length, node; i < n; ++i) { + node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha; + } } - function scale(x) { - return (output || (output = piecewise(domain, range$$1, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x); + function initialize() { + if (!nodes) return; + var i, n = nodes.length; + strengths = new Array(n); + yz = new Array(n); + for (i = 0; i < n; ++i) { + strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); + } } - scale.invert = function(y) { - return (input || (input = piecewise(range$$1, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y); + force.initialize = function(_) { + nodes = _; + initialize(); }; - scale.domain = function(_) { - return arguments.length ? (domain = map$3.call(_, number$1), rescale()) : domain.slice(); + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength; }; - scale.range = function(_) { - return arguments.length ? (range$$1 = slice$3.call(_), rescale()) : range$$1.slice(); + force.y = function(_) { + return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : y; }; - scale.rangeRound = function(_) { - return range$$1 = slice$3.call(_), interpolate$$1 = interpolateRound, rescale(); - }; + return force; +}; - scale.clamp = function(_) { - return arguments.length ? (clamp = !!_, rescale()) : clamp; +// Computes the decimal coefficient and exponent of the specified number x with +// significant digits p, where x is positive and p is in [1, 21] or undefined. +// For example, formatDecimal(1.23) returns ["123", 0]. +var formatDecimal = function(x, p) { + if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity + var i, coefficient = x.slice(0, i); + + // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ + // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). + return [ + coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, + +x.slice(i + 1) + ]; +}; + +var exponent$1 = function(x) { + return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; +}; + +var formatGroup = function(grouping, thousands) { + return function(value, width) { + var i = value.length, + t = [], + j = 0, + g = grouping[0], + length = 0; + + while (i > 0 && g > 0) { + if (length + g + 1 > width) g = Math.max(1, width - length); + t.push(value.substring(i -= g, i + g)); + if ((length += g + 1) > width) break; + g = grouping[j = (j + 1) % grouping.length]; + } + + return t.reverse().join(thousands); }; +}; - scale.interpolate = function(_) { - return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1; +var formatNumerals = function(numerals) { + return function(value) { + return value.replace(/[0-9]/g, function(i) { + return numerals[+i]; + }); }; +}; - return rescale(); -} +var formatDefault = function(x, p) { + x = x.toPrecision(p); -var tickFormat = function(domain, count, specifier) { - var start = domain[0], - stop = domain[domain.length - 1], - step = tickStep(start, stop, count == null ? 10 : count), - precision; - specifier = formatSpecifier(specifier == null ? ",f" : specifier); - switch (specifier.type) { - case "s": { - var value = Math.max(Math.abs(start), Math.abs(stop)); - if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; - return exports.formatPrefix(specifier, value); - } - case "": - case "e": - case "g": - case "p": - case "r": { - if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); - break; - } - case "f": - case "%": { - if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; - break; + out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { + switch (x[i]) { + case ".": i0 = i1 = i; break; + case "0": if (i0 === 0) i0 = i; i1 = i; break; + case "e": break out; + default: if (i0 > 0) i0 = 0; break; } } - return exports.format(specifier); + + return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; }; -function linearish(scale) { - var domain = scale.domain; +var prefixExponent; - scale.ticks = function(count) { - var d = domain(); - return ticks(d[0], d[d.length - 1], count == null ? 10 : count); - }; +var formatPrefixAuto = function(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1], + i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, + n = coefficient.length; + return i === n ? coefficient + : i > n ? coefficient + new Array(i - n + 1).join("0") + : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) + : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! +}; - scale.tickFormat = function(count, specifier) { - return tickFormat(domain(), count, specifier); - }; +var formatRounded = function(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1]; + return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient + : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) + : coefficient + new Array(exponent - coefficient.length + 2).join("0"); +}; - scale.nice = function(count) { - var d = domain(), - i = d.length - 1, - n = count == null ? 10 : count, - start = d[0], - stop = d[i], - step = tickStep(start, stop, n); +var formatTypes = { + "": formatDefault, + "%": function(x, p) { return (x * 100).toFixed(p); }, + "b": function(x) { return Math.round(x).toString(2); }, + "c": function(x) { return x + ""; }, + "d": function(x) { return Math.round(x).toString(10); }, + "e": function(x, p) { return x.toExponential(p); }, + "f": function(x, p) { return x.toFixed(p); }, + "g": function(x, p) { return x.toPrecision(p); }, + "o": function(x) { return Math.round(x).toString(8); }, + "p": function(x, p) { return formatRounded(x * 100, p); }, + "r": formatRounded, + "s": formatPrefixAuto, + "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, + "x": function(x) { return Math.round(x).toString(16); } +}; - if (step) { - step = tickStep(Math.floor(start / step) * step, Math.ceil(stop / step) * step, n); - d[0] = Math.floor(start / step) * step; - d[i] = Math.ceil(stop / step) * step; - domain(d); - } +// [[fill]align][sign][symbol][0][width][,][.precision][type] +var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; + +function formatSpecifier(specifier) { + return new FormatSpecifier(specifier); +} + +formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof + +function FormatSpecifier(specifier) { + if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); + + var match, + fill = match[1] || " ", + align = match[2] || ">", + sign = match[3] || "-", + symbol = match[4] || "", + zero = !!match[5], + width = match[6] && +match[6], + comma = !!match[7], + precision = match[8] && +match[8].slice(1), + type = match[9] || ""; + + // The "n" type is an alias for ",g". + if (type === "n") comma = true, type = "g"; + + // Map invalid types to the default format. + else if (!formatTypes[type]) type = ""; + + // If zero fill is specified, padding goes after sign and before digits. + if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; + + this.fill = fill; + this.align = align; + this.sign = sign; + this.symbol = symbol; + this.zero = zero; + this.width = width; + this.comma = comma; + this.precision = precision; + this.type = type; +} - return scale; - }; +FormatSpecifier.prototype.toString = function() { + return this.fill + + this.align + + this.sign + + this.symbol + + (this.zero ? "0" : "") + + (this.width == null ? "" : Math.max(1, this.width | 0)) + + (this.comma ? "," : "") + + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) + + this.type; +}; - return scale; -} +var identity$3 = function(x) { + return x; +}; -function linear$2() { - var scale = continuous(deinterpolateLinear, interpolateNumber); +var prefixes = ["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P","E","Z","Y"]; - scale.copy = function() { - return copy(scale, linear$2()); - }; +var formatLocale = function(locale) { + var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3, + currency = locale.currency, + decimal = locale.decimal, + numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3; - return linearish(scale); -} + function newFormat(specifier) { + specifier = formatSpecifier(specifier); -function identity$4() { - var domain = [0, 1]; + var fill = specifier.fill, + align = specifier.align, + sign = specifier.sign, + symbol = specifier.symbol, + zero = specifier.zero, + width = specifier.width, + comma = specifier.comma, + precision = specifier.precision, + type = specifier.type; - function scale(x) { - return +x; - } + // Compute the prefix and suffix. + // For SI-prefix, the suffix is lazily computed. + var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", + suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : ""; - scale.invert = scale; + // What format function should we use? + // Is this an integer type? + // Can this type generate exponential notation? + var formatType = formatTypes[type], + maybeSuffix = !type || /[defgprs%]/.test(type); - scale.domain = scale.range = function(_) { - return arguments.length ? (domain = map$3.call(_, number$1), scale) : domain.slice(); - }; + // Set the default precision if not specified, + // or clamp the specified precision to the supported range. + // For significant precision, it must be in [1, 21]. + // For fixed precision, it must be in [0, 20]. + precision = precision == null ? (type ? 6 : 12) + : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) + : Math.max(0, Math.min(20, precision)); - scale.copy = function() { - return identity$4().domain(domain); - }; + function format(value) { + var valuePrefix = prefix, + valueSuffix = suffix, + i, n, c; - return linearish(scale); -} + if (type === "c") { + valueSuffix = formatType(value) + valueSuffix; + value = ""; + } else { + value = +value; -var nice = function(domain, interval) { - domain = domain.slice(); + // Perform the initial formatting. + var valueNegative = value < 0; + value = formatType(Math.abs(value), precision); - var i0 = 0, - i1 = domain.length - 1, - x0 = domain[i0], - x1 = domain[i1], - t; + // If a negative value rounds to zero during formatting, treat as positive. + if (valueNegative && +value === 0) valueNegative = false; - if (x1 < x0) { - t = i0, i0 = i1, i1 = t; - t = x0, x0 = x1, x1 = t; - } + // Compute the prefix and suffix. + valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; + valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : ""); - domain[i0] = interval.floor(x0); - domain[i1] = interval.ceil(x1); - return domain; -}; + // Break the formatted value into the integer “value” part that can be + // grouped, and fractional or exponential “suffix” part that is not. + if (maybeSuffix) { + i = -1, n = value.length; + while (++i < n) { + if (c = value.charCodeAt(i), 48 > c || c > 57) { + valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; + value = value.slice(0, i); + break; + } + } + } + } -function deinterpolate(a, b) { - return (b = Math.log(b / a)) - ? function(x) { return Math.log(x / a) / b; } - : constant$4(b); -} + // If the fill character is not "0", grouping is applied before padding. + if (comma && !zero) value = group(value, Infinity); -function reinterpolate(a, b) { - return a < 0 - ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); } - : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); }; -} + // Compute the padding. + var length = valuePrefix.length + value.length + valueSuffix.length, + padding = length < width ? new Array(width - length + 1).join(fill) : ""; -function pow10(x) { - return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x; -} + // If the fill character is "0", grouping is applied after padding. + if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; -function powp(base) { - return base === 10 ? pow10 - : base === Math.E ? Math.exp - : function(x) { return Math.pow(base, x); }; -} + // Reconstruct the final output based on the desired alignment. + switch (align) { + case "<": value = valuePrefix + value + valueSuffix + padding; break; + case "=": value = valuePrefix + padding + value + valueSuffix; break; + case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; + default: value = padding + valuePrefix + value + valueSuffix; break; + } -function logp(base) { - return base === Math.E ? Math.log - : base === 10 && Math.log10 - || base === 2 && Math.log2 - || (base = Math.log(base), function(x) { return Math.log(x) / base; }); -} + return numerals(value); + } -function reflect(f) { - return function(x) { - return -f(-x); - }; -} + format.toString = function() { + return specifier + ""; + }; -function log() { - var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]), - domain = scale.domain, - base = 10, - logs = logp(10), - pows = powp(10); + return format; + } - function rescale() { - logs = logp(base), pows = powp(base); - if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows); - return scale; + function formatPrefix(specifier, value) { + var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), + e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3, + k = Math.pow(10, -e), + prefix = prefixes[8 + e / 3]; + return function(value) { + return f(k * value) + prefix; + }; } - scale.base = function(_) { - return arguments.length ? (base = +_, rescale()) : base; + return { + format: newFormat, + formatPrefix: formatPrefix }; +}; - scale.domain = function(_) { - return arguments.length ? (domain(_), rescale()) : domain(); - }; +var locale$1; - scale.ticks = function(count) { - var d = domain(), - u = d[0], - v = d[d.length - 1], - r; - if (r = v < u) i = u, u = v, v = i; - var i = logs(u), - j = logs(v), - p, - k, - t, - n = count == null ? 10 : +count, - z = []; +defaultLocale({ + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] +}); - if (!(base % 1) && j - i < n) { - i = Math.round(i) - 1, j = Math.round(j) + 1; - if (u > 0) for (; i < j; ++i) { - for (k = 1, p = pows(i); k < base; ++k) { - t = p * k; - if (t < u) continue; - if (t > v) break; - z.push(t); - } - } else for (; i < j; ++i) { - for (k = base - 1, p = pows(i); k >= 1; --k) { - t = p * k; - if (t < u) continue; - if (t > v) break; - z.push(t); - } - } - } else { - z = ticks(i, j, Math.min(j - i, n)).map(pows); - } +function defaultLocale(definition) { + locale$1 = formatLocale(definition); + exports.format = locale$1.format; + exports.formatPrefix = locale$1.formatPrefix; + return locale$1; +} - return r ? z.reverse() : z; - }; +var precisionFixed = function(step) { + return Math.max(0, -exponent$1(Math.abs(step))); +}; - scale.tickFormat = function(count, specifier) { - if (specifier == null) specifier = base === 10 ? ".0e" : ","; - if (typeof specifier !== "function") specifier = exports.format(specifier); - if (count === Infinity) return specifier; - if (count == null) count = 10; - var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate? - return function(d) { - var i = d / pows(Math.round(logs(d))); - if (i * base < base - 0.5) i *= base; - return i <= k ? specifier(d) : ""; - }; - }; +var precisionPrefix = function(step, value) { + return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step))); +}; - scale.nice = function() { - return domain(nice(domain(), { - floor: function(x) { return pows(Math.floor(logs(x))); }, - ceil: function(x) { return pows(Math.ceil(logs(x))); } - })); - }; +var precisionRound = function(step, max) { + step = Math.abs(step), max = Math.abs(max) - step; + return Math.max(0, exponent$1(max) - exponent$1(step)) + 1; +}; - scale.copy = function() { - return copy(scale, log().base(base)); - }; +// Adds floating point numbers with twice the normal precision. +// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and +// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3) +// 305–363 (1997). +// Code adapted from GeographicLib by Charles F. F. Karney, +// http://geographiclib.sourceforge.net/ - return scale; +var adder = function() { + return new Adder; +}; + +function Adder() { + this.reset(); } -function raise(x, exponent) { - return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent); +Adder.prototype = { + constructor: Adder, + reset: function() { + this.s = // rounded value + this.t = 0; // exact error + }, + add: function(y) { + add$1(temp, y, this.t); + add$1(this, temp.s, this.s); + if (this.s) this.t += temp.t; + else this.s = temp.t; + }, + valueOf: function() { + return this.s; + } +}; + +var temp = new Adder; + +function add$1(adder, a, b) { + var x = adder.s = a + b, + bv = x - a, + av = x - bv; + adder.t = (a - av) + (b - bv); } -function pow() { - var exponent = 1, - scale = continuous(deinterpolate, reinterpolate), - domain = scale.domain; +var epsilon$2 = 1e-6; +var epsilon2$1 = 1e-12; +var pi$3 = Math.PI; +var halfPi$2 = pi$3 / 2; +var quarterPi = pi$3 / 4; +var tau$3 = pi$3 * 2; - function deinterpolate(a, b) { - return (b = raise(b, exponent) - (a = raise(a, exponent))) - ? function(x) { return (raise(x, exponent) - a) / b; } - : constant$4(b); - } +var degrees$1 = 180 / pi$3; +var radians = pi$3 / 180; - function reinterpolate(a, b) { - b = raise(b, exponent) - (a = raise(a, exponent)); - return function(t) { return raise(a + b * t, 1 / exponent); }; - } +var abs = Math.abs; +var atan = Math.atan; +var atan2 = Math.atan2; +var cos$1 = Math.cos; +var ceil = Math.ceil; +var exp = Math.exp; - scale.exponent = function(_) { - return arguments.length ? (exponent = +_, domain(domain())) : exponent; - }; +var log = Math.log; +var pow = Math.pow; +var sin$1 = Math.sin; +var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }; +var sqrt = Math.sqrt; +var tan = Math.tan; - scale.copy = function() { - return copy(scale, pow().exponent(exponent)); - }; +function acos(x) { + return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x); +} - return linearish(scale); +function asin(x) { + return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x); } -function sqrt() { - return pow().exponent(0.5); +function haversin(x) { + return (x = sin$1(x / 2)) * x; } -function quantile$$1() { - var domain = [], - range$$1 = [], - thresholds = []; +function noop$1() {} - function rescale() { - var i = 0, n = Math.max(1, range$$1.length); - thresholds = new Array(n - 1); - while (++i < n) thresholds[i - 1] = threshold(domain, i / n); - return scale; +function streamGeometry(geometry, stream) { + if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) { + streamGeometryType[geometry.type](geometry, stream); } +} - function scale(x) { - if (!isNaN(x = +x)) return range$$1[bisectRight(thresholds, x)]; +var streamObjectType = { + Feature: function(object, stream) { + streamGeometry(object.geometry, stream); + }, + FeatureCollection: function(object, stream) { + var features = object.features, i = -1, n = features.length; + while (++i < n) streamGeometry(features[i].geometry, stream); } +}; - scale.invertExtent = function(y) { - var i = range$$1.indexOf(y); - return i < 0 ? [NaN, NaN] : [ - i > 0 ? thresholds[i - 1] : domain[0], - i < thresholds.length ? thresholds[i] : domain[domain.length - 1] - ]; - }; - - scale.domain = function(_) { - if (!arguments.length) return domain.slice(); - domain = []; - for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d); - domain.sort(ascending); - return rescale(); - }; - - scale.range = function(_) { - return arguments.length ? (range$$1 = slice$3.call(_), rescale()) : range$$1.slice(); - }; - - scale.quantiles = function() { - return thresholds.slice(); - }; - - scale.copy = function() { - return quantile$$1() - .domain(domain) - .range(range$$1); - }; +var streamGeometryType = { + Sphere: function(object, stream) { + stream.sphere(); + }, + Point: function(object, stream) { + object = object.coordinates; + stream.point(object[0], object[1], object[2]); + }, + MultiPoint: function(object, stream) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]); + }, + LineString: function(object, stream) { + streamLine(object.coordinates, stream, 0); + }, + MultiLineString: function(object, stream) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) streamLine(coordinates[i], stream, 0); + }, + Polygon: function(object, stream) { + streamPolygon(object.coordinates, stream); + }, + MultiPolygon: function(object, stream) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) streamPolygon(coordinates[i], stream); + }, + GeometryCollection: function(object, stream) { + var geometries = object.geometries, i = -1, n = geometries.length; + while (++i < n) streamGeometry(geometries[i], stream); + } +}; - return scale; +function streamLine(coordinates, stream, closed) { + var i = -1, n = coordinates.length - closed, coordinate; + stream.lineStart(); + while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]); + stream.lineEnd(); } -function quantize$1() { - var x0 = 0, - x1 = 1, - n = 1, - domain = [0.5], - range$$1 = [0, 1]; - - function scale(x) { - if (x <= x) return range$$1[bisectRight(domain, x, 0, n)]; - } +function streamPolygon(coordinates, stream) { + var i = -1, n = coordinates.length; + stream.polygonStart(); + while (++i < n) streamLine(coordinates[i], stream, 1); + stream.polygonEnd(); +} - function rescale() { - var i = -1; - domain = new Array(n); - while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1); - return scale; +var geoStream = function(object, stream) { + if (object && streamObjectType.hasOwnProperty(object.type)) { + streamObjectType[object.type](object, stream); + } else { + streamGeometry(object, stream); } +}; - scale.domain = function(_) { - return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1]; - }; +var areaRingSum = adder(); - scale.range = function(_) { - return arguments.length ? (n = (range$$1 = slice$3.call(_)).length - 1, rescale()) : range$$1.slice(); - }; +var areaSum = adder(); +var lambda00; +var phi00; +var lambda0; +var cosPhi0; +var sinPhi0; - scale.invertExtent = function(y) { - var i = range$$1.indexOf(y); - return i < 0 ? [NaN, NaN] - : i < 1 ? [x0, domain[0]] - : i >= n ? [domain[n - 1], x1] - : [domain[i - 1], domain[i]]; - }; +var areaStream = { + point: noop$1, + lineStart: noop$1, + lineEnd: noop$1, + polygonStart: function() { + areaRingSum.reset(); + areaStream.lineStart = areaRingStart; + areaStream.lineEnd = areaRingEnd; + }, + polygonEnd: function() { + var areaRing = +areaRingSum; + areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing); + this.lineStart = this.lineEnd = this.point = noop$1; + }, + sphere: function() { + areaSum.add(tau$3); + } +}; - scale.copy = function() { - return quantize$1() - .domain([x0, x1]) - .range(range$$1); - }; +function areaRingStart() { + areaStream.point = areaPointFirst; +} - return linearish(scale); +function areaRingEnd() { + areaPoint(lambda00, phi00); } -function threshold$1() { - var domain = [0.5], - range$$1 = [0, 1], - n = 1; +function areaPointFirst(lambda, phi) { + areaStream.point = areaPoint; + lambda00 = lambda, phi00 = phi; + lambda *= radians, phi *= radians; + lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi); +} - function scale(x) { - if (x <= x) return range$$1[bisectRight(domain, x, 0, n)]; - } +function areaPoint(lambda, phi) { + lambda *= radians, phi *= radians; + phi = phi / 2 + quarterPi; // half the angular distance from south pole - scale.domain = function(_) { - return arguments.length ? (domain = slice$3.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice(); - }; + // Spherical excess E for a spherical triangle with vertices: south pole, + // previous point, current point. Uses a formula derived from Cagnoli’s + // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2). + var dLambda = lambda - lambda0, + sdLambda = dLambda >= 0 ? 1 : -1, + adLambda = sdLambda * dLambda, + cosPhi = cos$1(phi), + sinPhi = sin$1(phi), + k = sinPhi0 * sinPhi, + u = cosPhi0 * cosPhi + k * cos$1(adLambda), + v = k * sdLambda * sin$1(adLambda); + areaRingSum.add(atan2(v, u)); - scale.range = function(_) { - return arguments.length ? (range$$1 = slice$3.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice(); - }; + // Advance the previous points. + lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi; +} - scale.invertExtent = function(y) { - var i = range$$1.indexOf(y); - return [domain[i - 1], domain[i]]; - }; +var area = function(object) { + areaSum.reset(); + geoStream(object, areaStream); + return areaSum * 2; +}; - scale.copy = function() { - return threshold$1() - .domain(domain) - .range(range$$1); - }; +function spherical(cartesian) { + return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])]; +} - return scale; +function cartesian(spherical) { + var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi); + return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)]; } -var durationSecond$1 = 1000; -var durationMinute$1 = durationSecond$1 * 60; -var durationHour$1 = durationMinute$1 * 60; -var durationDay$1 = durationHour$1 * 24; -var durationWeek$1 = durationDay$1 * 7; -var durationMonth = durationDay$1 * 30; -var durationYear = durationDay$1 * 365; +function cartesianDot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} -function date$1(t) { - return new Date(t); +function cartesianCross(a, b) { + return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]; } -function number$2(t) { - return t instanceof Date ? +t : +new Date(+t); +// TODO return a +function cartesianAddInPlace(a, b) { + a[0] += b[0], a[1] += b[1], a[2] += b[2]; } -function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) { - var scale = continuous(deinterpolateLinear, interpolateNumber), - invert = scale.invert, - domain = scale.domain; +function cartesianScale(vector, k) { + return [vector[0] * k, vector[1] * k, vector[2] * k]; +} - var formatMillisecond = format(".%L"), - formatSecond = format(":%S"), - formatMinute = format("%I:%M"), - formatHour = format("%I %p"), - formatDay = format("%a %d"), - formatWeek = format("%b %d"), - formatMonth = format("%B"), - formatYear = format("%Y"); +// TODO return d +function cartesianNormalizeInPlace(d) { + var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); + d[0] /= l, d[1] /= l, d[2] /= l; +} - var tickIntervals = [ - [second$$1, 1, durationSecond$1], - [second$$1, 5, 5 * durationSecond$1], - [second$$1, 15, 15 * durationSecond$1], - [second$$1, 30, 30 * durationSecond$1], - [minute$$1, 1, durationMinute$1], - [minute$$1, 5, 5 * durationMinute$1], - [minute$$1, 15, 15 * durationMinute$1], - [minute$$1, 30, 30 * durationMinute$1], - [ hour$$1, 1, durationHour$1 ], - [ hour$$1, 3, 3 * durationHour$1 ], - [ hour$$1, 6, 6 * durationHour$1 ], - [ hour$$1, 12, 12 * durationHour$1 ], - [ day$$1, 1, durationDay$1 ], - [ day$$1, 2, 2 * durationDay$1 ], - [ week, 1, durationWeek$1 ], - [ month$$1, 1, durationMonth ], - [ month$$1, 3, 3 * durationMonth ], - [ year$$1, 1, durationYear ] - ]; +var lambda0$1; +var phi0; +var lambda1; +var phi1; +var lambda2; +var lambda00$1; +var phi00$1; +var p0; +var deltaSum = adder(); +var ranges; +var range; - function tickFormat(date) { - return (second$$1(date) < date ? formatMillisecond - : minute$$1(date) < date ? formatSecond - : hour$$1(date) < date ? formatMinute - : day$$1(date) < date ? formatHour - : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek) - : year$$1(date) < date ? formatMonth - : formatYear)(date); +var boundsStream = { + point: boundsPoint, + lineStart: boundsLineStart, + lineEnd: boundsLineEnd, + polygonStart: function() { + boundsStream.point = boundsRingPoint; + boundsStream.lineStart = boundsRingStart; + boundsStream.lineEnd = boundsRingEnd; + deltaSum.reset(); + areaStream.polygonStart(); + }, + polygonEnd: function() { + areaStream.polygonEnd(); + boundsStream.point = boundsPoint; + boundsStream.lineStart = boundsLineStart; + boundsStream.lineEnd = boundsLineEnd; + if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90); + else if (deltaSum > epsilon$2) phi1 = 90; + else if (deltaSum < -epsilon$2) phi0 = -90; + range[0] = lambda0$1, range[1] = lambda1; } +}; - function tickInterval(interval, start, stop, step) { - if (interval == null) interval = 10; +function boundsPoint(lambda, phi) { + ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]); + if (phi < phi0) phi0 = phi; + if (phi > phi1) phi1 = phi; +} - // If a desired tick count is specified, pick a reasonable tick interval - // based on the extent of the domain and a rough estimate of tick size. - // Otherwise, assume interval is already a time interval and use it. - if (typeof interval === "number") { - var target = Math.abs(stop - start) / interval, - i = bisector(function(i) { return i[2]; }).right(tickIntervals, target); - if (i === tickIntervals.length) { - step = tickStep(start / durationYear, stop / durationYear, interval); - interval = year$$1; - } else if (i) { - i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i]; - step = i[1]; - interval = i[0]; +function linePoint(lambda, phi) { + var p = cartesian([lambda * radians, phi * radians]); + if (p0) { + var normal = cartesianCross(p0, p), + equatorial = [normal[1], -normal[0], 0], + inflection = cartesianCross(equatorial, normal); + cartesianNormalizeInPlace(inflection); + inflection = spherical(inflection); + var delta = lambda - lambda2, + sign$$1 = delta > 0 ? 1 : -1, + lambdai = inflection[0] * degrees$1 * sign$$1, + phii, + antimeridian = abs(delta) > 180; + if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) { + phii = inflection[1] * degrees$1; + if (phii > phi1) phi1 = phii; + } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) { + phii = -inflection[1] * degrees$1; + if (phii < phi0) phi0 = phii; + } else { + if (phi < phi0) phi0 = phi; + if (phi > phi1) phi1 = phi; + } + if (antimeridian) { + if (lambda < lambda2) { + if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; } else { - step = tickStep(start, stop, interval); - interval = millisecond$$1; + if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; + } + } else { + if (lambda1 >= lambda0$1) { + if (lambda < lambda0$1) lambda0$1 = lambda; + if (lambda > lambda1) lambda1 = lambda; + } else { + if (lambda > lambda2) { + if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; + } else { + if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; + } } } + } else { + ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]); + } + if (phi < phi0) phi0 = phi; + if (phi > phi1) phi1 = phi; + p0 = p, lambda2 = lambda; +} - return step == null ? interval : interval.every(step); +function boundsLineStart() { + boundsStream.point = linePoint; +} + +function boundsLineEnd() { + range[0] = lambda0$1, range[1] = lambda1; + boundsStream.point = boundsPoint; + p0 = null; +} + +function boundsRingPoint(lambda, phi) { + if (p0) { + var delta = lambda - lambda2; + deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta); + } else { + lambda00$1 = lambda, phi00$1 = phi; } + areaStream.point(lambda, phi); + linePoint(lambda, phi); +} - scale.invert = function(y) { - return new Date(invert(y)); - }; +function boundsRingStart() { + areaStream.lineStart(); +} - scale.domain = function(_) { - return arguments.length ? domain(map$3.call(_, number$2)) : domain().map(date$1); - }; +function boundsRingEnd() { + boundsRingPoint(lambda00$1, phi00$1); + areaStream.lineEnd(); + if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180); + range[0] = lambda0$1, range[1] = lambda1; + p0 = null; +} - scale.ticks = function(interval, step) { - var d = domain(), - t0 = d[0], - t1 = d[d.length - 1], - r = t1 < t0, - t; - if (r) t = t0, t0 = t1, t1 = t; - t = tickInterval(interval, t0, t1, step); - t = t ? t.range(t0, t1 + 1) : []; // inclusive stop - return r ? t.reverse() : t; - }; +// Finds the left-right distance between two longitudes. +// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want +// the distance between ±180° to be 360°. +function angle(lambda0, lambda1) { + return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1; +} - scale.tickFormat = function(count, specifier) { - return specifier == null ? tickFormat : format(specifier); - }; +function rangeCompare(a, b) { + return a[0] - b[0]; +} - scale.nice = function(interval, step) { - var d = domain(); - return (interval = tickInterval(interval, d[0], d[d.length - 1], step)) - ? domain(nice(d, interval)) - : scale; - }; +function rangeContains(range, x) { + return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; +} - scale.copy = function() { - return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format)); - }; +var bounds = function(feature) { + var i, n, a, b, merged, deltaMax, delta; + + phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity); + ranges = []; + geoStream(feature, boundsStream); + + // First, sort ranges by their minimum longitudes. + if (n = ranges.length) { + ranges.sort(rangeCompare); + + // Then, merge any ranges that overlap. + for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) { + b = ranges[i]; + if (rangeContains(a, b[0]) || rangeContains(a, b[1])) { + if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; + if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; + } else { + merged.push(a = b); + } + } + + // Finally, find the largest gap between the merged ranges. + // The final bounding box will be the inverse of this gap. + for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) { + b = merged[i]; + if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1]; + } + } - return scale; -} + ranges = range = null; -var time = function() { - return calendar(year, month, sunday, day, hour, minute, second, millisecond, exports.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]); + return lambda0$1 === Infinity || phi0 === Infinity + ? [[NaN, NaN], [NaN, NaN]] + : [[lambda0$1, phi0], [lambda1, phi1]]; }; -var utcTime = function() { - return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, exports.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]); -}; +var W0; +var W1; +var X0; +var Y0; +var Z0; +var X1; +var Y1; +var Z1; +var X2; +var Y2; +var Z2; +var lambda00$2; +var phi00$2; +var x0; +var y0; +var z0; // previous point -var colors = function(s) { - return s.match(/.{6}/g).map(function(x) { - return "#" + x; - }); +var centroidStream = { + sphere: noop$1, + point: centroidPoint, + lineStart: centroidLineStart, + lineEnd: centroidLineEnd, + polygonStart: function() { + centroidStream.lineStart = centroidRingStart; + centroidStream.lineEnd = centroidRingEnd; + }, + polygonEnd: function() { + centroidStream.lineStart = centroidLineStart; + centroidStream.lineEnd = centroidLineEnd; + } }; -var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"); - -var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6"); - -var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9"); - -var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5"); +// Arithmetic mean of Cartesian vectors. +function centroidPoint(lambda, phi) { + lambda *= radians, phi *= radians; + var cosPhi = cos$1(phi); + centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)); +} -var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0)); +function centroidPointCartesian(x, y, z) { + ++W0; + X0 += (x - X0) / W0; + Y0 += (y - Y0) / W0; + Z0 += (z - Z0) / W0; +} -var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8)); +function centroidLineStart() { + centroidStream.point = centroidLinePointFirst; +} -var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8)); +function centroidLinePointFirst(lambda, phi) { + lambda *= radians, phi *= radians; + var cosPhi = cos$1(phi); + x0 = cosPhi * cos$1(lambda); + y0 = cosPhi * sin$1(lambda); + z0 = sin$1(phi); + centroidStream.point = centroidLinePoint; + centroidPointCartesian(x0, y0, z0); +} -var rainbow = cubehelix(); +function centroidLinePoint(lambda, phi) { + lambda *= radians, phi *= radians; + var cosPhi = cos$1(phi), + x = cosPhi * cos$1(lambda), + y = cosPhi * sin$1(lambda), + z = sin$1(phi), + w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); + W1 += w; + X1 += w * (x0 + (x0 = x)); + Y1 += w * (y0 + (y0 = y)); + Z1 += w * (z0 + (z0 = z)); + centroidPointCartesian(x0, y0, z0); +} -var rainbow$1 = function(t) { - if (t < 0 || t > 1) t -= Math.floor(t); - var ts = Math.abs(t - 0.5); - rainbow.h = 360 * t - 100; - rainbow.s = 1.5 - 1.5 * ts; - rainbow.l = 0.8 - 0.9 * ts; - return rainbow + ""; -}; +function centroidLineEnd() { + centroidStream.point = centroidPoint; +} -function ramp(range) { - var n = range.length; - return function(t) { - return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))]; - }; +// See J. E. Brock, The Inertia Tensor for a Spherical Triangle, +// J. Applied Mechanics 42, 239 (1975). +function centroidRingStart() { + centroidStream.point = centroidRingPointFirst; } -var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")); +function centroidRingEnd() { + centroidRingPoint(lambda00$2, phi00$2); + centroidStream.point = centroidPoint; +} -var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")); +function centroidRingPointFirst(lambda, phi) { + lambda00$2 = lambda, phi00$2 = phi; + lambda *= radians, phi *= radians; + centroidStream.point = centroidRingPoint; + var cosPhi = cos$1(phi); + x0 = cosPhi * cos$1(lambda); + y0 = cosPhi * sin$1(lambda); + z0 = sin$1(phi); + centroidPointCartesian(x0, y0, z0); +} -var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")); +function centroidRingPoint(lambda, phi) { + lambda *= radians, phi *= radians; + var cosPhi = cos$1(phi), + x = cosPhi * cos$1(lambda), + y = cosPhi * sin$1(lambda), + z = sin$1(phi), + cx = y0 * z - z0 * y, + cy = z0 * x - x0 * z, + cz = x0 * y - y0 * x, + m = sqrt(cx * cx + cy * cy + cz * cz), + w = asin(m), // line weight = angle + v = m && -w / m; // area weight multiplier + X2 += v * cx; + Y2 += v * cy; + Z2 += v * cz; + W1 += w; + X1 += w * (x0 + (x0 = x)); + Y1 += w * (y0 + (y0 = y)); + Z1 += w * (z0 + (z0 = z)); + centroidPointCartesian(x0, y0, z0); +} -var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")); +var centroid = function(object) { + W0 = W1 = + X0 = Y0 = Z0 = + X1 = Y1 = Z1 = + X2 = Y2 = Z2 = 0; + geoStream(object, centroidStream); -function sequential(interpolator) { - var x0 = 0, - x1 = 1, - clamp = false; + var x = X2, + y = Y2, + z = Z2, + m = x * x + y * y + z * z; - function scale(x) { - var t = (x - x0) / (x1 - x0); - return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t); + // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid. + if (m < epsilon2$1) { + x = X1, y = Y1, z = Z1; + // If the feature has zero length, fall back to arithmetic mean of point vectors. + if (W1 < epsilon$2) x = X0, y = Y0, z = Z0; + m = x * x + y * y + z * z; + // If the feature still has an undefined ccentroid, then return. + if (m < epsilon2$1) return [NaN, NaN]; } - scale.domain = function(_) { - return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1]; - }; + return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1]; +}; - scale.clamp = function(_) { - return arguments.length ? (clamp = !!_, scale) : clamp; +var constant$7 = function(x) { + return function() { + return x; }; +}; - scale.interpolator = function(_) { - return arguments.length ? (interpolator = _, scale) : interpolator; - }; +var compose = function(a, b) { - scale.copy = function() { - return sequential(interpolator).domain([x0, x1]).clamp(clamp); + function compose(x, y) { + return x = a(x, y), b(x[0], x[1]); + } + + if (a.invert && b.invert) compose.invert = function(x, y) { + return x = b.invert(x, y), x && a.invert(x[0], x[1]); }; - return linearish(scale); -} + return compose; +}; -var xhtml = "http://www.w3.org/1999/xhtml"; +function rotationIdentity(lambda, phi) { + return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi]; +} -var namespaces = { - svg: "http://www.w3.org/2000/svg", - xhtml: xhtml, - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" -}; +rotationIdentity.invert = rotationIdentity; -var namespace = function(name) { - var prefix = name += "", i = prefix.indexOf(":"); - if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); - return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; -}; +function rotateRadians(deltaLambda, deltaPhi, deltaGamma) { + return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma)) + : rotationLambda(deltaLambda)) + : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma) + : rotationIdentity); +} -function creatorInherit(name) { - return function() { - var document = this.ownerDocument, - uri = this.namespaceURI; - return uri === xhtml && document.documentElement.namespaceURI === xhtml - ? document.createElement(name) - : document.createElementNS(uri, name); +function forwardRotationLambda(deltaLambda) { + return function(lambda, phi) { + return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi]; }; } -function creatorFixed(fullname) { - return function() { - return this.ownerDocument.createElementNS(fullname.space, fullname.local); - }; +function rotationLambda(deltaLambda) { + var rotation = forwardRotationLambda(deltaLambda); + rotation.invert = forwardRotationLambda(-deltaLambda); + return rotation; } -var creator = function(name) { - var fullname = namespace(name); - return (fullname.local - ? creatorFixed - : creatorInherit)(fullname); -}; +function rotationPhiGamma(deltaPhi, deltaGamma) { + var cosDeltaPhi = cos$1(deltaPhi), + sinDeltaPhi = sin$1(deltaPhi), + cosDeltaGamma = cos$1(deltaGamma), + sinDeltaGamma = sin$1(deltaGamma); -var nextId = 0; + function rotation(lambda, phi) { + var cosPhi = cos$1(phi), + x = cos$1(lambda) * cosPhi, + y = sin$1(lambda) * cosPhi, + z = sin$1(phi), + k = z * cosDeltaPhi + x * sinDeltaPhi; + return [ + atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi), + asin(k * cosDeltaGamma + y * sinDeltaGamma) + ]; + } + + rotation.invert = function(lambda, phi) { + var cosPhi = cos$1(phi), + x = cos$1(lambda) * cosPhi, + y = sin$1(lambda) * cosPhi, + z = sin$1(phi), + k = z * cosDeltaGamma - y * sinDeltaGamma; + return [ + atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi), + asin(k * cosDeltaPhi - x * sinDeltaPhi) + ]; + }; -function local() { - return new Local; + return rotation; } -function Local() { - this._ = "@" + (++nextId).toString(36); -} +var rotation = function(rotate) { + rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0); -Local.prototype = local.prototype = { - constructor: Local, - get: function(node) { - var id = this._; - while (!(id in node)) if (!(node = node.parentNode)) return; - return node[id]; - }, - set: function(node, value) { - return node[this._] = value; - }, - remove: function(node) { - return this._ in node && delete node[this._]; - }, - toString: function() { - return this._; + function forward(coordinates) { + coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians); + return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates; } -}; -var matcher = function(selector) { - return function() { - return this.matches(selector); + forward.invert = function(coordinates) { + coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians); + return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates; }; + + return forward; }; -if (typeof document !== "undefined") { - var element = document.documentElement; - if (!element.matches) { - var vendorMatches = element.webkitMatchesSelector - || element.msMatchesSelector - || element.mozMatchesSelector - || element.oMatchesSelector; - matcher = function(selector) { - return function() { - return vendorMatches.call(this, selector); - }; - }; +// Generates a circle centered at [0°, 0°], with a given radius and precision. +function circleStream(stream, radius, delta, direction, t0, t1) { + if (!delta) return; + var cosRadius = cos$1(radius), + sinRadius = sin$1(radius), + step = direction * delta; + if (t0 == null) { + t0 = radius + direction * tau$3; + t1 = radius - step / 2; + } else { + t0 = circleRadius(cosRadius, t0); + t1 = circleRadius(cosRadius, t1); + if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3; + } + for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) { + point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]); + stream.point(point[0], point[1]); } } -var matcher$1 = matcher; +// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0]. +function circleRadius(cosRadius, point) { + point = cartesian(point), point[0] -= cosRadius; + cartesianNormalizeInPlace(point); + var radius = acos(-point[1]); + return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3; +} -var filterEvents = {}; +var circle = function() { + var center = constant$7([0, 0]), + radius = constant$7(90), + precision = constant$7(6), + ring, + rotate, + stream = {point: point}; -exports.event = null; + function point(x, y) { + ring.push(x = rotate(x, y)); + x[0] *= degrees$1, x[1] *= degrees$1; + } -if (typeof document !== "undefined") { - var element$1 = document.documentElement; - if (!("onmouseenter" in element$1)) { - filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; + function circle() { + var c = center.apply(this, arguments), + r = radius.apply(this, arguments) * radians, + p = precision.apply(this, arguments) * radians; + ring = []; + rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert; + circleStream(stream, r, p, 1); + c = {type: "Polygon", coordinates: [ring]}; + ring = rotate = null; + return c; } -} -function filterContextListener(listener, index, group) { - listener = contextListener(listener, index, group); - return function(event) { - var related = event.relatedTarget; - if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { - listener.call(this, event); - } + circle.center = function(_) { + return arguments.length ? (center = typeof _ === "function" ? _ : constant$7([+_[0], +_[1]]), circle) : center; }; -} -function contextListener(listener, index, group) { - return function(event1) { - var event0 = exports.event; // Events can be reentrant (e.g., focus). - exports.event = event1; - try { - listener.call(this, this.__data__, index, group); - } finally { - exports.event = event0; - } + circle.radius = function(_) { + return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), circle) : radius; }; -} - -function parseTypenames$1(typenames) { - return typenames.trim().split(/^|\s+/).map(function(t) { - var name = "", i = t.indexOf("."); - if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); - return {type: t, name: name}; - }); -} -function onRemove(typename) { - return function() { - var on = this.__on; - if (!on) return; - for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { - if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { - this.removeEventListener(o.type, o.listener, o.capture); - } else { - on[++i] = o; - } - } - if (++i) on.length = i; - else delete this.__on; + circle.precision = function(_) { + return arguments.length ? (precision = typeof _ === "function" ? _ : constant$7(+_), circle) : precision; }; -} -function onAdd(typename, value, capture) { - var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; - return function(d, i, group) { - var on = this.__on, o, listener = wrap(value, i, group); - if (on) for (var j = 0, m = on.length; j < m; ++j) { - if ((o = on[j]).type === typename.type && o.name === typename.name) { - this.removeEventListener(o.type, o.listener, o.capture); - this.addEventListener(o.type, o.listener = listener, o.capture = capture); - o.value = value; - return; - } + return circle; +}; + +var clipBuffer = function() { + var lines = [], + line; + return { + point: function(x, y) { + line.push([x, y]); + }, + lineStart: function() { + lines.push(line = []); + }, + lineEnd: noop$1, + rejoin: function() { + if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); + }, + result: function() { + var result = lines; + lines = []; + line = null; + return result; } - this.addEventListener(typename.type, listener, capture); - o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; - if (!on) this.__on = [o]; - else on.push(o); }; -} +}; -var selection_on = function(typename, value, capture) { - var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t; +var clipLine = function(a, b, x0, y0, x1, y1) { + var ax = a[0], + ay = a[1], + bx = b[0], + by = b[1], + t0 = 0, + t1 = 1, + dx = bx - ax, + dy = by - ay, + r; - if (arguments.length < 2) { - var on = this.node().__on; - if (on) for (var j = 0, m = on.length, o; j < m; ++j) { - for (i = 0, o = on[j]; i < n; ++i) { - if ((t = typenames[i]).type === o.type && t.name === o.name) { - return o.value; - } - } - } - return; + r = x0 - ax; + if (!dx && r > 0) return; + r /= dx; + if (dx < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dx > 0) { + if (r > t1) return; + if (r > t0) t0 = r; } - on = value ? onAdd : onRemove; - if (capture == null) capture = false; - for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); - return this; -}; - -function customEvent(event1, listener, that, args) { - var event0 = exports.event; - event1.sourceEvent = exports.event; - exports.event = event1; - try { - return listener.apply(that, args); - } finally { - exports.event = event0; + r = x1 - ax; + if (!dx && r < 0) return; + r /= dx; + if (dx < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dx > 0) { + if (r < t0) return; + if (r < t1) t1 = r; } -} - -var sourceEvent = function() { - var current = exports.event, source; - while (source = current.sourceEvent) current = source; - return current; -}; - -var point$5 = function(node, event) { - var svg = node.ownerSVGElement || node; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - point.x = event.clientX, point.y = event.clientY; - point = point.matrixTransform(node.getScreenCTM().inverse()); - return [point.x, point.y]; + r = y0 - ay; + if (!dy && r > 0) return; + r /= dy; + if (dy < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dy > 0) { + if (r > t1) return; + if (r > t0) t0 = r; } - var rect = node.getBoundingClientRect(); - return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; + r = y1 - ay; + if (!dy && r < 0) return; + r /= dy; + if (dy < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dy > 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } + + if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy; + if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy; + return true; }; -var mouse = function(node) { - var event = sourceEvent(); - if (event.changedTouches) event = event.changedTouches[0]; - return point$5(node, event); +var pointEqual = function(a, b) { + return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2; }; -function none$2() {} +function Intersection(point, points, other, entry) { + this.x = point; + this.z = points; + this.o = other; // another intersection + this.e = entry; // is an entry? + this.v = false; // visited + this.n = this.p = null; // next & previous +} -var selector = function(selector) { - return selector == null ? none$2 : function() { - return this.querySelector(selector); - }; -}; +// A generalized polygon clipping algorithm: given a polygon that has been cut +// into its visible line segments, and rejoins the segments by interpolating +// along the clip edge. +var clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) { + var subject = [], + clip = [], + i, + n; -var selection_select = function(select) { - if (typeof select !== "function") select = selector(select); + segments.forEach(function(segment) { + if ((n = segment.length - 1) <= 0) return; + var n, p0 = segment[0], p1 = segment[n], x; - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { - if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - } + // If the first and last points of a segment are coincident, then treat as a + // closed ring. TODO if all rings are closed, then the winding order of the + // exterior ring should be checked. + if (pointEqual(p0, p1)) { + stream.lineStart(); + for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]); + stream.lineEnd(); + return; } - } - return new Selection(subgroups, this._parents); -}; + subject.push(x = new Intersection(p0, segment, null, true)); + clip.push(x.o = new Intersection(p0, null, x, false)); + subject.push(x = new Intersection(p1, segment, null, false)); + clip.push(x.o = new Intersection(p1, null, x, true)); + }); -function empty() { - return []; -} + if (!subject.length) return; -var selectorAll = function(selector) { - return selector == null ? empty : function() { - return this.querySelectorAll(selector); - }; -}; + clip.sort(compareIntersection); + link$1(subject); + link$1(clip); -var selection_selectAll = function(select) { - if (typeof select !== "function") select = selectorAll(select); + for (i = 0, n = clip.length; i < n; ++i) { + clip[i].e = startInside = !startInside; + } - for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - subgroups.push(select.call(node, node.__data__, i, group)); - parents.push(node); + var start = subject[0], + points, + point; + + while (1) { + // Find first unvisited intersection. + var current = start, + isSubject = true; + while (current.v) if ((current = current.n) === start) return; + points = current.z; + stream.lineStart(); + do { + current.v = current.o.v = true; + if (current.e) { + if (isSubject) { + for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]); + } else { + interpolate(current.x, current.n.x, 1, stream); + } + current = current.n; + } else { + if (isSubject) { + points = current.p.z; + for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]); + } else { + interpolate(current.x, current.p.x, -1, stream); + } + current = current.p; } - } + current = current.o; + points = current.z; + isSubject = !isSubject; + } while (!current.v); + stream.lineEnd(); } - - return new Selection(subgroups, parents); }; -var selection_filter = function(match) { - if (typeof match !== "function") match = matcher$1(match); +function link$1(array) { + if (!(n = array.length)) return; + var n, + i = 0, + a = array[0], + b; + while (++i < n) { + a.n = b = array[i]; + b.p = a; + a = b; + } + a.n = b = array[0]; + b.p = a; +} - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } +var clipMax = 1e9; +var clipMin = -clipMax; + +// TODO Use d3-polygon’s polygonContains here for the ring check? +// TODO Eliminate duplicate buffering in clipBuffer and polygon.push? + +function clipExtent(x0, y0, x1, y1) { + + function visible(x, y) { + return x0 <= x && x <= x1 && y0 <= y && y <= y1; + } + + function interpolate(from, to, direction, stream) { + var a = 0, a1 = 0; + if (from == null + || (a = corner(from, direction)) !== (a1 = corner(to, direction)) + || comparePoint(from, to) < 0 ^ direction > 0) { + do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); + while ((a = (a + direction + 4) % 4) !== a1); + } else { + stream.point(to[0], to[1]); } } - return new Selection(subgroups, this._parents); -}; + function corner(p, direction) { + return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3 + : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1 + : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0 + : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon + } -var sparse = function(update) { - return new Array(update.length); -}; + function compareIntersection(a, b) { + return comparePoint(a.x, b.x); + } -var selection_enter = function() { - return new Selection(this._enter || this._groups.map(sparse), this._parents); -}; + function comparePoint(a, b) { + var ca = corner(a, 1), + cb = corner(b, 1); + return ca !== cb ? ca - cb + : ca === 0 ? b[1] - a[1] + : ca === 1 ? a[0] - b[0] + : ca === 2 ? a[1] - b[1] + : b[0] - a[0]; + } -function EnterNode(parent, datum) { - this.ownerDocument = parent.ownerDocument; - this.namespaceURI = parent.namespaceURI; - this._next = null; - this._parent = parent; - this.__data__ = datum; -} + return function(stream) { + var activeStream = stream, + bufferStream = clipBuffer(), + segments, + polygon, + ring, + x__, y__, v__, // first point + x_, y_, v_, // previous point + first, + clean; -EnterNode.prototype = { - constructor: EnterNode, - appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, - insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, - querySelector: function(selector) { return this._parent.querySelector(selector); }, - querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } -}; + var clipStream = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: polygonStart, + polygonEnd: polygonEnd + }; -var constant$5 = function(x) { - return function() { - return x; - }; -}; + function point(x, y) { + if (visible(x, y)) activeStream.point(x, y); + } -var keyPrefix = "$"; // Protect against keys like “__proto__”. + function polygonInside() { + var winding = 0; -function bindIndex(parent, group, enter, update, exit, data) { - var i = 0, - node, - groupLength = group.length, - dataLength = data.length; + for (var i = 0, n = polygon.length; i < n; ++i) { + for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) { + a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1]; + if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; } + else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; } + } + } - // Put any non-null nodes that fit into update. - // Put any null nodes into enter. - // Put any remaining data into enter. - for (; i < dataLength; ++i) { - if (node = group[i]) { - node.__data__ = data[i]; - update[i] = node; - } else { - enter[i] = new EnterNode(parent, data[i]); + return winding; + } + + // Buffer geometry within a polygon and then clip it en masse. + function polygonStart() { + activeStream = bufferStream, segments = [], polygon = [], clean = true; } - } - // Put any non-null nodes that don’t fit into exit. - for (; i < groupLength; ++i) { - if (node = group[i]) { - exit[i] = node; + function polygonEnd() { + var startInside = polygonInside(), + cleanInside = clean && startInside, + visible = (segments = merge(segments)).length; + if (cleanInside || visible) { + stream.polygonStart(); + if (cleanInside) { + stream.lineStart(); + interpolate(null, null, 1, stream); + stream.lineEnd(); + } + if (visible) { + clipPolygon(segments, compareIntersection, startInside, interpolate, stream); + } + stream.polygonEnd(); + } + activeStream = stream, segments = polygon = ring = null; } - } -} -function bindKey(parent, group, enter, update, exit, data, key) { - var i, - node, - nodeByKeyValue = {}, - groupLength = group.length, - dataLength = data.length, - keyValues = new Array(groupLength), - keyValue; + function lineStart() { + clipStream.point = linePoint; + if (polygon) polygon.push(ring = []); + first = true; + v_ = false; + x_ = y_ = NaN; + } - // Compute the key for each node. - // If multiple nodes have the same key, the duplicates are added to exit. - for (i = 0; i < groupLength; ++i) { - if (node = group[i]) { - keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); - if (keyValue in nodeByKeyValue) { - exit[i] = node; - } else { - nodeByKeyValue[keyValue] = node; + // TODO rather than special-case polygons, simply handle them separately. + // Ideally, coincident intersection points should be jittered to avoid + // clipping issues. + function lineEnd() { + if (segments) { + linePoint(x__, y__); + if (v__ && v_) bufferStream.rejoin(); + segments.push(bufferStream.result()); } + clipStream.point = point; + if (v_) activeStream.lineEnd(); } - } - // Compute the key for each datum. - // If there a node associated with this key, join and add it to update. - // If there is not (or the key is a duplicate), add it to enter. - for (i = 0; i < dataLength; ++i) { - keyValue = keyPrefix + key.call(parent, data[i], i, data); - if (node = nodeByKeyValue[keyValue]) { - update[i] = node; - node.__data__ = data[i]; - nodeByKeyValue[keyValue] = null; - } else { - enter[i] = new EnterNode(parent, data[i]); + function linePoint(x, y) { + var v = visible(x, y); + if (polygon) ring.push([x, y]); + if (first) { + x__ = x, y__ = y, v__ = v; + first = false; + if (v) { + activeStream.lineStart(); + activeStream.point(x, y); + } + } else { + if (v && v_) activeStream.point(x, y); + else { + var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))], + b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))]; + if (clipLine(a, b, x0, y0, x1, y1)) { + if (!v_) { + activeStream.lineStart(); + activeStream.point(a[0], a[1]); + } + activeStream.point(b[0], b[1]); + if (!v) activeStream.lineEnd(); + clean = false; + } else if (v) { + activeStream.lineStart(); + activeStream.point(x, y); + clean = false; + } + } + } + x_ = x, y_ = y, v_ = v; } - } - // Add any remaining nodes that were not bound to data to exit. - for (i = 0; i < groupLength; ++i) { - if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { - exit[i] = node; - } - } + return clipStream; + }; } -var selection_data = function(value, key) { - if (!value) { - data = new Array(this.size()), j = -1; - this.each(function(d) { data[++j] = d; }); - return data; - } +var extent$1 = function() { + var x0 = 0, + y0 = 0, + x1 = 960, + y1 = 500, + cache, + cacheStream, + clip; - var bind = key ? bindKey : bindIndex, - parents = this._parents, - groups = this._groups; + return clip = { + stream: function(stream) { + return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream); + }, + extent: function(_) { + return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]]; + } + }; +}; - if (typeof value !== "function") value = constant$5(value); +var sum$1 = adder(); - for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { - var parent = parents[j], - group = groups[j], - groupLength = group.length, - data = value.call(parent, parent && parent.__data__, j, parents), - dataLength = data.length, - enterGroup = enter[j] = new Array(dataLength), - updateGroup = update[j] = new Array(dataLength), - exitGroup = exit[j] = new Array(groupLength); +var polygonContains = function(polygon, point) { + var lambda = point[0], + phi = point[1], + normal = [sin$1(lambda), -cos$1(lambda), 0], + angle = 0, + winding = 0; - bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); + sum$1.reset(); - // Now connect the enter nodes to their following update node, such that - // appendChild can insert the materialized enter node before this node, - // rather than at the end of the parent node. - for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { - if (previous = enterGroup[i0]) { - if (i0 >= i1) i1 = i0 + 1; - while (!(next = updateGroup[i1]) && ++i1 < dataLength); - previous._next = next || null; + for (var i = 0, n = polygon.length; i < n; ++i) { + if (!(m = (ring = polygon[i]).length)) continue; + var ring, + m, + point0 = ring[m - 1], + lambda0 = point0[0], + phi0 = point0[1] / 2 + quarterPi, + sinPhi0 = sin$1(phi0), + cosPhi0 = cos$1(phi0); + + for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) { + var point1 = ring[j], + lambda1 = point1[0], + phi1 = point1[1] / 2 + quarterPi, + sinPhi1 = sin$1(phi1), + cosPhi1 = cos$1(phi1), + delta = lambda1 - lambda0, + sign$$1 = delta >= 0 ? 1 : -1, + absDelta = sign$$1 * delta, + antimeridian = absDelta > pi$3, + k = sinPhi0 * sinPhi1; + + sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta))); + angle += antimeridian ? delta + sign$$1 * tau$3 : delta; + + // Are the longitudes either side of the point’s meridian (lambda), + // and are the latitudes smaller than the parallel (phi)? + if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) { + var arc = cartesianCross(cartesian(point0), cartesian(point1)); + cartesianNormalizeInPlace(arc); + var intersection = cartesianCross(normal, arc); + cartesianNormalizeInPlace(intersection); + var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]); + if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) { + winding += antimeridian ^ delta >= 0 ? 1 : -1; + } } } } - update = new Selection(update, parents); - update._enter = enter; - update._exit = exit; - return update; + // First, determine whether the South pole is inside or outside: + // + // It is inside if: + // * the polygon winds around it in a clockwise direction. + // * the polygon does not (cumulatively) wind around it, but has a negative + // (counter-clockwise) area. + // + // Second, count the (signed) number of times a segment crosses a lambda + // from the point to the South pole. If it is zero, then the point is the + // same side as the South pole. + + return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1); }; -var selection_exit = function() { - return new Selection(this._exit || this._groups.map(sparse), this._parents); +var lengthSum = adder(); +var lambda0$2; +var sinPhi0$1; +var cosPhi0$1; + +var lengthStream = { + sphere: noop$1, + point: noop$1, + lineStart: lengthLineStart, + lineEnd: noop$1, + polygonStart: noop$1, + polygonEnd: noop$1 }; -var selection_merge = function(selection) { +function lengthLineStart() { + lengthStream.point = lengthPointFirst; + lengthStream.lineEnd = lengthLineEnd; +} - for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { - for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group0[i] || group1[i]) { - merge[i] = node; - } - } - } +function lengthLineEnd() { + lengthStream.point = lengthStream.lineEnd = noop$1; +} - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } +function lengthPointFirst(lambda, phi) { + lambda *= radians, phi *= radians; + lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi); + lengthStream.point = lengthPoint; +} - return new Selection(merges, this._parents); +function lengthPoint(lambda, phi) { + lambda *= radians, phi *= radians; + var sinPhi = sin$1(phi), + cosPhi = cos$1(phi), + delta = abs(lambda - lambda0$2), + cosDelta = cos$1(delta), + sinDelta = sin$1(delta), + x = cosPhi * sinDelta, + y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta, + z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta; + lengthSum.add(atan2(sqrt(x * x + y * y), z)); + lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi; +} + +var length$1 = function(object) { + lengthSum.reset(); + geoStream(object, lengthStream); + return +lengthSum; }; -var selection_order = function() { +var coordinates = [null, null]; +var object$1 = {type: "LineString", coordinates: coordinates}; - for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { - for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } +var distance = function(a, b) { + coordinates[0] = a; + coordinates[1] = b; + return length$1(object$1); +}; + +var containsObjectType = { + Feature: function(object, point) { + return containsGeometry(object.geometry, point); + }, + FeatureCollection: function(object, point) { + var features = object.features, i = -1, n = features.length; + while (++i < n) if (containsGeometry(features[i].geometry, point)) return true; + return false; } +}; - return this; +var containsGeometryType = { + Sphere: function() { + return true; + }, + Point: function(object, point) { + return containsPoint(object.coordinates, point); + }, + MultiPoint: function(object, point) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) if (containsPoint(coordinates[i], point)) return true; + return false; + }, + LineString: function(object, point) { + return containsLine(object.coordinates, point); + }, + MultiLineString: function(object, point) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) if (containsLine(coordinates[i], point)) return true; + return false; + }, + Polygon: function(object, point) { + return containsPolygon(object.coordinates, point); + }, + MultiPolygon: function(object, point) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) if (containsPolygon(coordinates[i], point)) return true; + return false; + }, + GeometryCollection: function(object, point) { + var geometries = object.geometries, i = -1, n = geometries.length; + while (++i < n) if (containsGeometry(geometries[i], point)) return true; + return false; + } }; -var selection_sort = function(compare) { - if (!compare) compare = ascending$2; +function containsGeometry(geometry, point) { + return geometry && containsGeometryType.hasOwnProperty(geometry.type) + ? containsGeometryType[geometry.type](geometry, point) + : false; +} - function compareNode(a, b) { - return a && b ? compare(a.__data__, b.__data__) : !a - !b; - } +function containsPoint(coordinates, point) { + return distance(coordinates, point) === 0; +} - for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group[i]) { - sortgroup[i] = node; - } - } - sortgroup.sort(compareNode); - } +function containsLine(coordinates, point) { + var ab = distance(coordinates[0], coordinates[1]), + ao = distance(coordinates[0], point), + ob = distance(point, coordinates[1]); + return ao + ob <= ab + epsilon$2; +} - return new Selection(sortgroups, this._parents).order(); -}; +function containsPolygon(coordinates, point) { + return !!polygonContains(coordinates.map(ringRadians), pointRadians(point)); +} -function ascending$2(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +function ringRadians(ring) { + return ring = ring.map(pointRadians), ring.pop(), ring; } -var selection_call = function() { - var callback = arguments[0]; - arguments[0] = this; - callback.apply(null, arguments); - return this; -}; +function pointRadians(point) { + return [point[0] * radians, point[1] * radians]; +} -var selection_nodes = function() { - var nodes = new Array(this.size()), i = -1; - this.each(function() { nodes[++i] = this; }); - return nodes; +var contains = function(object, point) { + return (object && containsObjectType.hasOwnProperty(object.type) + ? containsObjectType[object.type] + : containsGeometry)(object, point); }; -var selection_node = function() { +function graticuleX(y0, y1, dy) { + var y = sequence(y0, y1 - epsilon$2, dy).concat(y1); + return function(x) { return y.map(function(y) { return [x, y]; }); }; +} - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { - var node = group[i]; - if (node) return node; - } +function graticuleY(x0, x1, dx) { + var x = sequence(x0, x1 - epsilon$2, dx).concat(x1); + return function(y) { return x.map(function(x) { return [x, y]; }); }; +} + +function graticule() { + var x1, x0, X1, X0, + y1, y0, Y1, Y0, + dx = 10, dy = dx, DX = 90, DY = 360, + x, y, X, Y, + precision = 2.5; + + function graticule() { + return {type: "MultiLineString", coordinates: lines()}; } - return null; -}; + function lines() { + return sequence(ceil(X0 / DX) * DX, X1, DX).map(X) + .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y)) + .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x)) + .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y)); + } -var selection_size = function() { - var size = 0; - this.each(function() { ++size; }); - return size; -}; + graticule.lines = function() { + return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; }); + }; -var selection_empty = function() { - return !this.node(); -}; + graticule.outline = function() { + return { + type: "Polygon", + coordinates: [ + X(X0).concat( + Y(Y1).slice(1), + X(X1).reverse().slice(1), + Y(Y0).reverse().slice(1)) + ] + }; + }; -var selection_each = function(callback) { + graticule.extent = function(_) { + if (!arguments.length) return graticule.extentMinor(); + return graticule.extentMajor(_).extentMinor(_); + }; - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { - if (node = group[i]) callback.call(node, node.__data__, i, group); - } - } + graticule.extentMajor = function(_) { + if (!arguments.length) return [[X0, Y0], [X1, Y1]]; + X0 = +_[0][0], X1 = +_[1][0]; + Y0 = +_[0][1], Y1 = +_[1][1]; + if (X0 > X1) _ = X0, X0 = X1, X1 = _; + if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; + return graticule.precision(precision); + }; - return this; -}; + graticule.extentMinor = function(_) { + if (!arguments.length) return [[x0, y0], [x1, y1]]; + x0 = +_[0][0], x1 = +_[1][0]; + y0 = +_[0][1], y1 = +_[1][1]; + if (x0 > x1) _ = x0, x0 = x1, x1 = _; + if (y0 > y1) _ = y0, y0 = y1, y1 = _; + return graticule.precision(precision); + }; -function attrRemove(name) { - return function() { - this.removeAttribute(name); + graticule.step = function(_) { + if (!arguments.length) return graticule.stepMinor(); + return graticule.stepMajor(_).stepMinor(_); }; -} -function attrRemoveNS(fullname) { - return function() { - this.removeAttributeNS(fullname.space, fullname.local); + graticule.stepMajor = function(_) { + if (!arguments.length) return [DX, DY]; + DX = +_[0], DY = +_[1]; + return graticule; }; -} -function attrConstant(name, value) { - return function() { - this.setAttribute(name, value); + graticule.stepMinor = function(_) { + if (!arguments.length) return [dx, dy]; + dx = +_[0], dy = +_[1]; + return graticule; }; -} -function attrConstantNS(fullname, value) { - return function() { - this.setAttributeNS(fullname.space, fullname.local, value); + graticule.precision = function(_) { + if (!arguments.length) return precision; + precision = +_; + x = graticuleX(y0, y1, 90); + y = graticuleY(x0, x1, precision); + X = graticuleX(Y0, Y1, 90); + Y = graticuleY(X0, X1, precision); + return graticule; }; + + return graticule + .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]]) + .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]); } -function attrFunction(name, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.removeAttribute(name); - else this.setAttribute(name, v); - }; +function graticule10() { + return graticule()(); } -function attrFunctionNS(fullname, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.removeAttributeNS(fullname.space, fullname.local); - else this.setAttributeNS(fullname.space, fullname.local, v); +var interpolate$1 = function(a, b) { + var x0 = a[0] * radians, + y0 = a[1] * radians, + x1 = b[0] * radians, + y1 = b[1] * radians, + cy0 = cos$1(y0), + sy0 = sin$1(y0), + cy1 = cos$1(y1), + sy1 = sin$1(y1), + kx0 = cy0 * cos$1(x0), + ky0 = cy0 * sin$1(x0), + kx1 = cy1 * cos$1(x1), + ky1 = cy1 * sin$1(x1), + d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))), + k = sin$1(d); + + var interpolate = d ? function(t) { + var B = sin$1(t *= d) / k, + A = sin$1(d - t) / k, + x = A * kx0 + B * kx1, + y = A * ky0 + B * ky1, + z = A * sy0 + B * sy1; + return [ + atan2(y, x) * degrees$1, + atan2(z, sqrt(x * x + y * y)) * degrees$1 + ]; + } : function() { + return [x0 * degrees$1, y0 * degrees$1]; }; -} -var selection_attr = function(name, value) { - var fullname = namespace(name); + interpolate.distance = d; - if (arguments.length < 2) { - var node = this.node(); - return fullname.local - ? node.getAttributeNS(fullname.space, fullname.local) - : node.getAttribute(fullname); - } + return interpolate; +}; - return this.each((value == null - ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" - ? (fullname.local ? attrFunctionNS : attrFunction) - : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); +var identity$4 = function(x) { + return x; }; -var window = function(node) { - return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node - || (node.document && node) // node is a Window - || node.defaultView; // node is a Document +var areaSum$1 = adder(); +var areaRingSum$1 = adder(); +var x00; +var y00; +var x0$1; +var y0$1; + +var areaStream$1 = { + point: noop$1, + lineStart: noop$1, + lineEnd: noop$1, + polygonStart: function() { + areaStream$1.lineStart = areaRingStart$1; + areaStream$1.lineEnd = areaRingEnd$1; + }, + polygonEnd: function() { + areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1; + areaSum$1.add(abs(areaRingSum$1)); + areaRingSum$1.reset(); + }, + result: function() { + var area = areaSum$1 / 2; + areaSum$1.reset(); + return area; + } }; -function styleRemove(name) { - return function() { - this.style.removeProperty(name); - }; -} - -function styleConstant(name, value, priority) { - return function() { - this.style.setProperty(name, value, priority); - }; +function areaRingStart$1() { + areaStream$1.point = areaPointFirst$1; } -function styleFunction(name, value, priority) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.style.removeProperty(name); - else this.style.setProperty(name, v, priority); - }; +function areaPointFirst$1(x, y) { + areaStream$1.point = areaPoint$1; + x00 = x0$1 = x, y00 = y0$1 = y; } -var selection_style = function(name, value, priority) { - var node; - return arguments.length > 1 - ? this.each((value == null - ? styleRemove : typeof value === "function" - ? styleFunction - : styleConstant)(name, value, priority == null ? "" : priority)) - : window(node = this.node()) - .getComputedStyle(node, null) - .getPropertyValue(name); -}; - -function propertyRemove(name) { - return function() { - delete this[name]; - }; +function areaPoint$1(x, y) { + areaRingSum$1.add(y0$1 * x - x0$1 * y); + x0$1 = x, y0$1 = y; } -function propertyConstant(name, value) { - return function() { - this[name] = value; - }; +function areaRingEnd$1() { + areaPoint$1(x00, y00); } -function propertyFunction(name, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) delete this[name]; - else this[name] = v; - }; -} +var x0$2 = Infinity; +var y0$2 = x0$2; +var x1 = -x0$2; +var y1 = x1; -var selection_property = function(name, value) { - return arguments.length > 1 - ? this.each((value == null - ? propertyRemove : typeof value === "function" - ? propertyFunction - : propertyConstant)(name, value)) - : this.node()[name]; +var boundsStream$1 = { + point: boundsPoint$1, + lineStart: noop$1, + lineEnd: noop$1, + polygonStart: noop$1, + polygonEnd: noop$1, + result: function() { + var bounds = [[x0$2, y0$2], [x1, y1]]; + x1 = y1 = -(y0$2 = x0$2 = Infinity); + return bounds; + } }; -function classArray(string) { - return string.trim().split(/^|\s+/); +function boundsPoint$1(x, y) { + if (x < x0$2) x0$2 = x; + if (x > x1) x1 = x; + if (y < y0$2) y0$2 = y; + if (y > y1) y1 = y; } -function classList(node) { - return node.classList || new ClassList(node); -} +// TODO Enforce positive area for exterior, negative area for interior? -function ClassList(node) { - this._node = node; - this._names = classArray(node.getAttribute("class") || ""); -} +var X0$1 = 0; +var Y0$1 = 0; +var Z0$1 = 0; +var X1$1 = 0; +var Y1$1 = 0; +var Z1$1 = 0; +var X2$1 = 0; +var Y2$1 = 0; +var Z2$1 = 0; +var x00$1; +var y00$1; +var x0$3; +var y0$3; -ClassList.prototype = { - add: function(name) { - var i = this._names.indexOf(name); - if (i < 0) { - this._names.push(name); - this._node.setAttribute("class", this._names.join(" ")); - } +var centroidStream$1 = { + point: centroidPoint$1, + lineStart: centroidLineStart$1, + lineEnd: centroidLineEnd$1, + polygonStart: function() { + centroidStream$1.lineStart = centroidRingStart$1; + centroidStream$1.lineEnd = centroidRingEnd$1; }, - remove: function(name) { - var i = this._names.indexOf(name); - if (i >= 0) { - this._names.splice(i, 1); - this._node.setAttribute("class", this._names.join(" ")); - } + polygonEnd: function() { + centroidStream$1.point = centroidPoint$1; + centroidStream$1.lineStart = centroidLineStart$1; + centroidStream$1.lineEnd = centroidLineEnd$1; }, - contains: function(name) { - return this._names.indexOf(name) >= 0; + result: function() { + var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1] + : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1] + : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1] + : [NaN, NaN]; + X0$1 = Y0$1 = Z0$1 = + X1$1 = Y1$1 = Z1$1 = + X2$1 = Y2$1 = Z2$1 = 0; + return centroid; } }; -function classedAdd(node, names) { - var list = classList(node), i = -1, n = names.length; - while (++i < n) list.add(names[i]); +function centroidPoint$1(x, y) { + X0$1 += x; + Y0$1 += y; + ++Z0$1; } -function classedRemove(node, names) { - var list = classList(node), i = -1, n = names.length; - while (++i < n) list.remove(names[i]); +function centroidLineStart$1() { + centroidStream$1.point = centroidPointFirstLine; } -function classedTrue(names) { - return function() { - classedAdd(this, names); - }; +function centroidPointFirstLine(x, y) { + centroidStream$1.point = centroidPointLine; + centroidPoint$1(x0$3 = x, y0$3 = y); } -function classedFalse(names) { - return function() { - classedRemove(this, names); - }; +function centroidPointLine(x, y) { + var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy); + X1$1 += z * (x0$3 + x) / 2; + Y1$1 += z * (y0$3 + y) / 2; + Z1$1 += z; + centroidPoint$1(x0$3 = x, y0$3 = y); } -function classedFunction(names, value) { - return function() { - (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); - }; +function centroidLineEnd$1() { + centroidStream$1.point = centroidPoint$1; } -var selection_classed = function(name, value) { - var names = classArray(name + ""); - - if (arguments.length < 2) { - var list = classList(this.node()), i = -1, n = names.length; - while (++i < n) if (!list.contains(names[i])) return false; - return true; - } +function centroidRingStart$1() { + centroidStream$1.point = centroidPointFirstRing; +} - return this.each((typeof value === "function" - ? classedFunction : value - ? classedTrue - : classedFalse)(names, value)); -}; +function centroidRingEnd$1() { + centroidPointRing(x00$1, y00$1); +} -function textRemove() { - this.textContent = ""; +function centroidPointFirstRing(x, y) { + centroidStream$1.point = centroidPointRing; + centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y); } -function textConstant(value) { - return function() { - this.textContent = value; - }; +function centroidPointRing(x, y) { + var dx = x - x0$3, + dy = y - y0$3, + z = sqrt(dx * dx + dy * dy); + + X1$1 += z * (x0$3 + x) / 2; + Y1$1 += z * (y0$3 + y) / 2; + Z1$1 += z; + + z = y0$3 * x - x0$3 * y; + X2$1 += z * (x0$3 + x); + Y2$1 += z * (y0$3 + y); + Z2$1 += z * 3; + centroidPoint$1(x0$3 = x, y0$3 = y); } -function textFunction(value) { - return function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - }; +function PathContext(context) { + this._context = context; } -var selection_text = function(value) { - return arguments.length - ? this.each(value == null - ? textRemove : (typeof value === "function" - ? textFunction - : textConstant)(value)) - : this.node().textContent; +PathContext.prototype = { + _radius: 4.5, + pointRadius: function(_) { + return this._radius = _, this; + }, + polygonStart: function() { + this._line = 0; + }, + polygonEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._point = 0; + }, + lineEnd: function() { + if (this._line === 0) this._context.closePath(); + this._point = NaN; + }, + point: function(x, y) { + switch (this._point) { + case 0: { + this._context.moveTo(x, y); + this._point = 1; + break; + } + case 1: { + this._context.lineTo(x, y); + break; + } + default: { + this._context.moveTo(x + this._radius, y); + this._context.arc(x, y, this._radius, 0, tau$3); + break; + } + } + }, + result: noop$1 +}; + +var lengthSum$1 = adder(); +var lengthRing; +var x00$2; +var y00$2; +var x0$4; +var y0$4; + +var lengthStream$1 = { + point: noop$1, + lineStart: function() { + lengthStream$1.point = lengthPointFirst$1; + }, + lineEnd: function() { + if (lengthRing) lengthPoint$1(x00$2, y00$2); + lengthStream$1.point = noop$1; + }, + polygonStart: function() { + lengthRing = true; + }, + polygonEnd: function() { + lengthRing = null; + }, + result: function() { + var length = +lengthSum$1; + lengthSum$1.reset(); + return length; + } }; -function htmlRemove() { - this.innerHTML = ""; +function lengthPointFirst$1(x, y) { + lengthStream$1.point = lengthPoint$1; + x00$2 = x0$4 = x, y00$2 = y0$4 = y; } -function htmlConstant(value) { - return function() { - this.innerHTML = value; - }; +function lengthPoint$1(x, y) { + x0$4 -= x, y0$4 -= y; + lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4)); + x0$4 = x, y0$4 = y; } -function htmlFunction(value) { - return function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - }; +function PathString() { + this._string = []; } -var selection_html = function(value) { - return arguments.length - ? this.each(value == null - ? htmlRemove : (typeof value === "function" - ? htmlFunction - : htmlConstant)(value)) - : this.node().innerHTML; +PathString.prototype = { + _circle: circle$1(4.5), + pointRadius: function(_) { + return this._circle = circle$1(_), this; + }, + polygonStart: function() { + this._line = 0; + }, + polygonEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._point = 0; + }, + lineEnd: function() { + if (this._line === 0) this._string.push("Z"); + this._point = NaN; + }, + point: function(x, y) { + switch (this._point) { + case 0: { + this._string.push("M", x, ",", y); + this._point = 1; + break; + } + case 1: { + this._string.push("L", x, ",", y); + break; + } + default: { + this._string.push("M", x, ",", y, this._circle); + break; + } + } + }, + result: function() { + if (this._string.length) { + var result = this._string.join(""); + this._string = []; + return result; + } + } }; -function raise$1() { - if (this.nextSibling) this.parentNode.appendChild(this); +function circle$1(radius) { + return "m0," + radius + + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + + "z"; } -var selection_raise = function() { - return this.each(raise$1); -}; +var index$1 = function(projection, context) { + var pointRadius = 4.5, + projectionStream, + contextStream; -function lower() { - if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); -} + function path(object) { + if (object) { + if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); + geoStream(object, projectionStream(contextStream)); + } + return contextStream.result(); + } -var selection_lower = function() { - return this.each(lower); -}; + path.area = function(object) { + geoStream(object, projectionStream(areaStream$1)); + return areaStream$1.result(); + }; -var selection_append = function(name) { - var create = typeof name === "function" ? name : creator(name); - return this.select(function() { - return this.appendChild(create.apply(this, arguments)); - }); -}; + path.measure = function(object) { + geoStream(object, projectionStream(lengthStream$1)); + return lengthStream$1.result(); + }; -function constantNull() { - return null; -} + path.bounds = function(object) { + geoStream(object, projectionStream(boundsStream$1)); + return boundsStream$1.result(); + }; -var selection_insert = function(name, before) { - var create = typeof name === "function" ? name : creator(name), - select = before == null ? constantNull : typeof before === "function" ? before : selector(before); - return this.select(function() { - return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); - }); -}; + path.centroid = function(object) { + geoStream(object, projectionStream(centroidStream$1)); + return centroidStream$1.result(); + }; -function remove() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); -} + path.projection = function(_) { + return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection; + }; -var selection_remove = function() { - return this.each(remove); -}; + path.context = function(_) { + if (!arguments.length) return context; + contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _); + if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); + return path; + }; -var selection_datum = function(value) { - return arguments.length - ? this.property("__data__", value) - : this.node().__data__; + path.pointRadius = function(_) { + if (!arguments.length) return pointRadius; + pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); + return path; + }; + + return path.projection(projection).context(context); }; -function dispatchEvent(node, type, params) { - var window$$1 = window(node), - event = window$$1.CustomEvent; +var clip = function(pointVisible, clipLine, interpolate, start) { + return function(rotate, sink) { + var line = clipLine(sink), + rotatedStart = rotate.invert(start[0], start[1]), + ringBuffer = clipBuffer(), + ringSink = clipLine(ringBuffer), + polygonStarted = false, + polygon, + segments, + ring; - if (event) { - event = new event(type, params); - } else { - event = window$$1.document.createEvent("Event"); - if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; - else event.initEvent(type, false, false); - } + var clip = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + clip.point = pointRing; + clip.lineStart = ringStart; + clip.lineEnd = ringEnd; + segments = []; + polygon = []; + }, + polygonEnd: function() { + clip.point = point; + clip.lineStart = lineStart; + clip.lineEnd = lineEnd; + segments = merge(segments); + var startInside = polygonContains(polygon, rotatedStart); + if (segments.length) { + if (!polygonStarted) sink.polygonStart(), polygonStarted = true; + clipPolygon(segments, compareIntersection, startInside, interpolate, sink); + } else if (startInside) { + if (!polygonStarted) sink.polygonStart(), polygonStarted = true; + sink.lineStart(); + interpolate(null, null, 1, sink); + sink.lineEnd(); + } + if (polygonStarted) sink.polygonEnd(), polygonStarted = false; + segments = polygon = null; + }, + sphere: function() { + sink.polygonStart(); + sink.lineStart(); + interpolate(null, null, 1, sink); + sink.lineEnd(); + sink.polygonEnd(); + } + }; - node.dispatchEvent(event); -} + function point(lambda, phi) { + var point = rotate(lambda, phi); + if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi); + } -function dispatchConstant(type, params) { - return function() { - return dispatchEvent(this, type, params); - }; -} + function pointLine(lambda, phi) { + var point = rotate(lambda, phi); + line.point(point[0], point[1]); + } -function dispatchFunction(type, params) { - return function() { - return dispatchEvent(this, type, params.apply(this, arguments)); - }; -} + function lineStart() { + clip.point = pointLine; + line.lineStart(); + } -var selection_dispatch = function(type, params) { - return this.each((typeof params === "function" - ? dispatchFunction - : dispatchConstant)(type, params)); -}; + function lineEnd() { + clip.point = point; + line.lineEnd(); + } -var root = [null]; + function pointRing(lambda, phi) { + ring.push([lambda, phi]); + var point = rotate(lambda, phi); + ringSink.point(point[0], point[1]); + } + + function ringStart() { + ringSink.lineStart(); + ring = []; + } -function Selection(groups, parents) { - this._groups = groups; - this._parents = parents; -} + function ringEnd() { + pointRing(ring[0][0], ring[0][1]); + ringSink.lineEnd(); -function selection() { - return new Selection([[document.documentElement]], root); -} + var clean = ringSink.clean(), + ringSegments = ringBuffer.result(), + i, n = ringSegments.length, m, + segment, + point; -Selection.prototype = selection.prototype = { - constructor: Selection, - select: selection_select, - selectAll: selection_selectAll, - filter: selection_filter, - data: selection_data, - enter: selection_enter, - exit: selection_exit, - merge: selection_merge, - order: selection_order, - sort: selection_sort, - call: selection_call, - nodes: selection_nodes, - node: selection_node, - size: selection_size, - empty: selection_empty, - each: selection_each, - attr: selection_attr, - style: selection_style, - property: selection_property, - classed: selection_classed, - text: selection_text, - html: selection_html, - raise: selection_raise, - lower: selection_lower, - append: selection_append, - insert: selection_insert, - remove: selection_remove, - datum: selection_datum, - on: selection_on, - dispatch: selection_dispatch -}; + ring.pop(); + polygon.push(ring); + ring = null; -var select = function(selector) { - return typeof selector === "string" - ? new Selection([[document.querySelector(selector)]], [document.documentElement]) - : new Selection([[selector]], root); -}; + if (!n) return; -var selectAll = function(selector) { - return typeof selector === "string" - ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) - : new Selection([selector == null ? [] : selector], root); -}; + // No intersections. + if (clean & 1) { + segment = ringSegments[0]; + if ((m = segment.length - 1) > 0) { + if (!polygonStarted) sink.polygonStart(), polygonStarted = true; + sink.lineStart(); + for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]); + sink.lineEnd(); + } + return; + } -var touch = function(node, touches, identifier) { - if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; + // Rejoin connected segments. + // TODO reuse ringBuffer.rejoin()? + if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { - if ((touch = touches[i]).identifier === identifier) { - return point$5(node, touch); + segments.push(ringSegments.filter(validSegment)); } - } - return null; + return clip; + }; }; -var touches = function(node, touches) { - if (touches == null) touches = sourceEvent().touches; - - for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) { - points[i] = point$5(node, touches[i]); - } - - return points; -}; +function validSegment(segment) { + return segment.length > 1; +} -var emptyOn = dispatch("start", "end", "interrupt"); -var emptyTween = []; +// Intersections are sorted along the clip edge. For both antimeridian cutting +// and circle clipping, the same comparison is used. +function compareIntersection(a, b) { + return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1]) + - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]); +} -var CREATED = 0; -var SCHEDULED = 1; -var STARTING = 2; -var STARTED = 3; -var RUNNING = 4; -var ENDING = 5; -var ENDED = 6; +var clipAntimeridian = clip( + function() { return true; }, + clipAntimeridianLine, + clipAntimeridianInterpolate, + [-pi$3, -halfPi$2] +); -var schedule = function(node, name, id, index, group, timing) { - var schedules = node.__transition; - if (!schedules) node.__transition = {}; - else if (id in schedules) return; - create(node, id, { - name: name, - index: index, // For context during callback. - group: group, // For context during callback. - on: emptyOn, - tween: emptyTween, - time: timing.time, - delay: timing.delay, - duration: timing.duration, - ease: timing.ease, - timer: null, - state: CREATED - }); -}; +// Takes a line and cuts into visible segments. Return values: 0 - there were +// intersections or the line was empty; 1 - no intersections; 2 - there were +// intersections, and the first and last segments should be rejoined. +function clipAntimeridianLine(stream) { + var lambda0 = NaN, + phi0 = NaN, + sign0 = NaN, + clean; // no intersections -function init(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late"); - return schedule; + return { + lineStart: function() { + stream.lineStart(); + clean = 1; + }, + point: function(lambda1, phi1) { + var sign1 = lambda1 > 0 ? pi$3 : -pi$3, + delta = abs(lambda1 - lambda0); + if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole + stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2); + stream.point(sign0, phi0); + stream.lineEnd(); + stream.lineStart(); + stream.point(sign1, phi0); + stream.point(lambda1, phi0); + clean = 0; + } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian + if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies + if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2; + phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1); + stream.point(sign0, phi0); + stream.lineEnd(); + stream.lineStart(); + stream.point(sign1, phi0); + clean = 0; + } + stream.point(lambda0 = lambda1, phi0 = phi1); + sign0 = sign1; + }, + lineEnd: function() { + stream.lineEnd(); + lambda0 = phi0 = NaN; + }, + clean: function() { + return 2 - clean; // if intersections, rejoin first and last segments + } + }; } -function set$3(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late"); - return schedule; +function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) { + var cosPhi0, + cosPhi1, + sinLambda0Lambda1 = sin$1(lambda0 - lambda1); + return abs(sinLambda0Lambda1) > epsilon$2 + ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1) + - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0)) + / (cosPhi0 * cosPhi1 * sinLambda0Lambda1)) + : (phi0 + phi1) / 2; } -function get$1(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id])) throw new Error("too late"); - return schedule; +function clipAntimeridianInterpolate(from, to, direction, stream) { + var phi; + if (from == null) { + phi = direction * halfPi$2; + stream.point(-pi$3, phi); + stream.point(0, phi); + stream.point(pi$3, phi); + stream.point(pi$3, 0); + stream.point(pi$3, -phi); + stream.point(0, -phi); + stream.point(-pi$3, -phi); + stream.point(-pi$3, 0); + stream.point(-pi$3, phi); + } else if (abs(from[0] - to[0]) > epsilon$2) { + var lambda = from[0] < to[0] ? pi$3 : -pi$3; + phi = direction * lambda / 2; + stream.point(-lambda, phi); + stream.point(0, phi); + stream.point(lambda, phi); + } else { + stream.point(to[0], to[1]); + } } -function create(node, id, self) { - var schedules = node.__transition, - tween; +var clipCircle = function(radius, delta) { + var cr = cos$1(radius), + smallRadius = cr > 0, + notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case + + function interpolate(from, to, direction, stream) { + circleStream(stream, radius, delta, direction, from, to); + } + + function visible(lambda, phi) { + return cos$1(lambda) * cos$1(phi) > cr; + } + + // Takes a line and cuts into visible segments. Return values used for polygon + // clipping: 0 - there were intersections or the line was empty; 1 - no + // intersections 2 - there were intersections, and the first and last segments + // should be rejoined. + function clipLine(stream) { + var point0, // previous point + c0, // code for previous point + v0, // visibility of previous point + v00, // visibility of first point + clean; // no intersections + return { + lineStart: function() { + v00 = v0 = false; + clean = 1; + }, + point: function(lambda, phi) { + var point1 = [lambda, phi], + point2, + v = visible(lambda, phi), + c = smallRadius + ? v ? 0 : code(lambda, phi) + : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0; + if (!point0 && (v00 = v0 = v)) stream.lineStart(); + // Handle degeneracies. + // TODO ignore if not clipping polygons. + if (v !== v0) { + point2 = intersect(point0, point1); + if (pointEqual(point0, point2) || pointEqual(point1, point2)) { + point1[0] += epsilon$2; + point1[1] += epsilon$2; + v = visible(point1[0], point1[1]); + } + } + if (v !== v0) { + clean = 0; + if (v) { + // outside going in + stream.lineStart(); + point2 = intersect(point1, point0); + stream.point(point2[0], point2[1]); + } else { + // inside going out + point2 = intersect(point0, point1); + stream.point(point2[0], point2[1]); + stream.lineEnd(); + } + point0 = point2; + } else if (notHemisphere && point0 && smallRadius ^ v) { + var t; + // If the codes for two points are different, or are both zero, + // and there this segment intersects with the small circle. + if (!(c & c0) && (t = intersect(point1, point0, true))) { + clean = 0; + if (smallRadius) { + stream.lineStart(); + stream.point(t[0][0], t[0][1]); + stream.point(t[1][0], t[1][1]); + stream.lineEnd(); + } else { + stream.point(t[1][0], t[1][1]); + stream.lineEnd(); + stream.lineStart(); + stream.point(t[0][0], t[0][1]); + } + } + } + if (v && (!point0 || !pointEqual(point0, point1))) { + stream.point(point1[0], point1[1]); + } + point0 = point1, v0 = v, c0 = c; + }, + lineEnd: function() { + if (v0) stream.lineEnd(); + point0 = null; + }, + // Rejoin first and last segments if there were intersections and the first + // and last points were visible. + clean: function() { + return clean | ((v00 && v0) << 1); + } + }; + } + + // Intersects the great circle between a and b with the clip circle. + function intersect(a, b, two) { + var pa = cartesian(a), + pb = cartesian(b); - // Initialize the self timer when the transition is created. - // Note the actual delay is not known until the first callback! - schedules[id] = self; - self.timer = timer(schedule, 0, self.time); + // We have two planes, n1.p = d1 and n2.p = d2. + // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2). + var n1 = [1, 0, 0], // normal + n2 = cartesianCross(pa, pb), + n2n2 = cartesianDot(n2, n2), + n1n2 = n2[0], // cartesianDot(n1, n2), + determinant = n2n2 - n1n2 * n1n2; - function schedule(elapsed) { - self.state = SCHEDULED; - self.timer.restart(start, self.delay, self.time); + // Two polar points. + if (!determinant) return !two && a; - // If the elapsed delay is less than our first sleep, start immediately. - if (self.delay <= elapsed) start(elapsed - self.delay); - } + var c1 = cr * n2n2 / determinant, + c2 = -cr * n1n2 / determinant, + n1xn2 = cartesianCross(n1, n2), + A = cartesianScale(n1, c1), + B = cartesianScale(n2, c2); + cartesianAddInPlace(A, B); - function start(elapsed) { - var i, j, n, o; + // Solve |p(t)|^2 = 1. + var u = n1xn2, + w = cartesianDot(A, u), + uu = cartesianDot(u, u), + t2 = w * w - uu * (cartesianDot(A, A) - 1); - // If the state is not SCHEDULED, then we previously errored on start. - if (self.state !== SCHEDULED) return stop(); + if (t2 < 0) return; - for (i in schedules) { - o = schedules[i]; - if (o.name !== self.name) continue; + var t = sqrt(t2), + q = cartesianScale(u, (-w - t) / uu); + cartesianAddInPlace(q, A); + q = spherical(q); - // While this element already has a starting transition during this frame, - // defer starting an interrupting transition until that transition has a - // chance to tick (and possibly end); see d3/d3-transition#54! - if (o.state === STARTED) return timeout$1(start); + if (!two) return q; - // Interrupt the active transition, if any. - // Dispatch the interrupt event. - if (o.state === RUNNING) { - o.state = ENDED; - o.timer.stop(); - o.on.call("interrupt", node, node.__data__, o.index, o.group); - delete schedules[i]; - } + // Two intersection points. + var lambda0 = a[0], + lambda1 = b[0], + phi0 = a[1], + phi1 = b[1], + z; - // Cancel any pre-empted transitions. No interrupt event is dispatched - // because the cancelled transitions never started. Note that this also - // removes this transition from the pending list! - else if (+i < id) { - o.state = ENDED; - o.timer.stop(); - delete schedules[i]; - } - } + if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z; - // Defer the first tick to end of the current frame; see d3/d3#1576. - // Note the transition may be canceled after start and before the first tick! - // Note this must be scheduled before the start event; see d3/d3-transition#16! - // Assuming this is successful, subsequent callbacks go straight to tick. - timeout$1(function() { - if (self.state === STARTED) { - self.state = RUNNING; - self.timer.restart(tick, self.delay, self.time); - tick(elapsed); - } - }); + var delta = lambda1 - lambda0, + polar = abs(delta - pi$3) < epsilon$2, + meridian = polar || delta < epsilon$2; - // Dispatch the start event. - // Note this must be done before the tween are initialized. - self.state = STARTING; - self.on.call("start", node, node.__data__, self.index, self.group); - if (self.state !== STARTING) return; // interrupted - self.state = STARTED; + if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z; - // Initialize the tween, deleting null tween. - tween = new Array(n = self.tween.length); - for (i = 0, j = -1; i < n; ++i) { - if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { - tween[++j] = o; - } + // Check that the first point is between a and b. + if (meridian + ? polar + ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1) + : phi0 <= q[1] && q[1] <= phi1 + : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) { + var q1 = cartesianScale(u, (-w + t) / uu); + cartesianAddInPlace(q1, A); + return [q, spherical(q1)]; } - tween.length = j + 1; } - function tick(elapsed) { - var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), - i = -1, - n = tween.length; + // Generates a 4-bit vector representing the location of a point relative to + // the small circle's bounding box. + function code(lambda, phi) { + var r = smallRadius ? radius : pi$3 - radius, + code = 0; + if (lambda < -r) code |= 1; // left + else if (lambda > r) code |= 2; // right + if (phi < -r) code |= 4; // below + else if (phi > r) code |= 8; // above + return code; + } - while (++i < n) { - tween[i].call(null, t); - } + return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]); +}; - // Dispatch the end event. - if (self.state === ENDING) { - self.on.call("end", node, node.__data__, self.index, self.group); - stop(); - } - } +var transform = function(methods) { + return { + stream: transformer(methods) + }; +}; - function stop() { - self.state = ENDED; - self.timer.stop(); - delete schedules[id]; - for (var i in schedules) return; // eslint-disable-line no-unused-vars - delete node.__transition; - } +function transformer(methods) { + return function(stream) { + var s = new TransformStream; + for (var key in methods) s[key] = methods[key]; + s.stream = stream; + return s; + }; } -var interrupt = function(node, name) { - var schedules = node.__transition, - schedule, - active, - empty = true, - i; - - if (!schedules) return; +function TransformStream() {} - name = name == null ? null : name + ""; +TransformStream.prototype = { + constructor: TransformStream, + point: function(x, y) { this.stream.point(x, y); }, + sphere: function() { this.stream.sphere(); }, + lineStart: function() { this.stream.lineStart(); }, + lineEnd: function() { this.stream.lineEnd(); }, + polygonStart: function() { this.stream.polygonStart(); }, + polygonEnd: function() { this.stream.polygonEnd(); } +}; - for (i in schedules) { - if ((schedule = schedules[i]).name !== name) { empty = false; continue; } - active = schedule.state > STARTING && schedule.state < ENDING; - schedule.state = ENDED; - schedule.timer.stop(); - if (active) schedule.on.call("interrupt", node, node.__data__, schedule.index, schedule.group); - delete schedules[i]; - } +function fitExtent(projection, extent, object) { + var w = extent[1][0] - extent[0][0], + h = extent[1][1] - extent[0][1], + clip = projection.clipExtent && projection.clipExtent(); - if (empty) delete node.__transition; -}; + projection + .scale(150) + .translate([0, 0]); -var selection_interrupt = function(name) { - return this.each(function() { - interrupt(this, name); - }); -}; + if (clip != null) projection.clipExtent(null); -function tweenRemove(id, name) { - var tween0, tween1; - return function() { - var schedule = set$3(this, id), - tween = schedule.tween; + geoStream(object, projection.stream(boundsStream$1)); - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = tween0 = tween; - for (var i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1 = tween1.slice(); - tween1.splice(i, 1); - break; - } - } - } + var b = boundsStream$1.result(), + k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])), + x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2, + y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2; - schedule.tween = tween1; - }; + if (clip != null) projection.clipExtent(clip); + + return projection + .scale(k * 150) + .translate([x, y]); } -function tweenFunction(id, name, value) { - var tween0, tween1; - if (typeof value !== "function") throw new Error; - return function() { - var schedule = set$3(this, id), - tween = schedule.tween; +function fitSize(projection, size, object) { + return fitExtent(projection, [[0, 0], size], object); +} - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = (tween0 = tween).slice(); - for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1[i] = t; - break; - } - } - if (i === n) tween1.push(t); - } +var maxDepth = 16; +var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance) - schedule.tween = tween1; - }; -} +var resample = function(project, delta2) { + return +delta2 ? resample$1(project, delta2) : resampleNone(project); +}; -var transition_tween = function(name, value) { - var id = this._id; +function resampleNone(project) { + return transformer({ + point: function(x, y) { + x = project(x, y); + this.stream.point(x[0], x[1]); + } + }); +} - name += ""; +function resample$1(project, delta2) { - if (arguments.length < 2) { - var tween = get$1(this.node(), id).tween; - for (var i = 0, n = tween.length, t; i < n; ++i) { - if ((t = tween[i]).name === name) { - return t.value; + function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) { + var dx = x1 - x0, + dy = y1 - y0, + d2 = dx * dx + dy * dy; + if (d2 > 4 * delta2 && depth--) { + var a = a0 + a1, + b = b0 + b1, + c = c0 + c1, + m = sqrt(a * a + b * b + c * c), + phi2 = asin(c /= m), + lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a), + p = project(lambda2, phi2), + x2 = p[0], + y2 = p[1], + dx2 = x2 - x0, + dy2 = y2 - y0, + dz = dy * dx2 - dx * dy2; + if (dz * dz / d2 > delta2 // perpendicular projected distance + || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end + || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance + resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream); + stream.point(x2, y2); + resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream); } } - return null; } + return function(stream) { + var lambda00, x00, y00, a00, b00, c00, // first point + lambda0, x0, y0, a0, b0, c0; // previous point - return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); -}; - -function tweenValue(transition, name, value) { - var id = transition._id; - - transition.each(function() { - var schedule = set$3(this, id); - (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); - }); + var resampleStream = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; }, + polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; } + }; - return function(node) { - return get$1(node, id).value[name]; - }; -} + function point(x, y) { + x = project(x, y); + stream.point(x[0], x[1]); + } -var interpolate$1 = function(a, b) { - var c; - return (typeof b === "number" ? interpolateNumber - : b instanceof color ? interpolateRgb - : (c = color(b)) ? (b = c, interpolateRgb) - : interpolateString)(a, b); -}; + function lineStart() { + x0 = NaN; + resampleStream.point = linePoint; + stream.lineStart(); + } -function attrRemove$1(name) { - return function() { - this.removeAttribute(name); - }; -} + function linePoint(lambda, phi) { + var c = cartesian([lambda, phi]), p = project(lambda, phi); + resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); + stream.point(x0, y0); + } -function attrRemoveNS$1(fullname) { - return function() { - this.removeAttributeNS(fullname.space, fullname.local); - }; -} + function lineEnd() { + resampleStream.point = point; + stream.lineEnd(); + } -function attrConstant$1(name, interpolate$$1, value1) { - var value00, - interpolate0; - return function() { - var value0 = this.getAttribute(name); - return value0 === value1 ? null - : value0 === value00 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value1); - }; -} + function ringStart() { + lineStart(); + resampleStream.point = ringPoint; + resampleStream.lineEnd = ringEnd; + } -function attrConstantNS$1(fullname, interpolate$$1, value1) { - var value00, - interpolate0; - return function() { - var value0 = this.getAttributeNS(fullname.space, fullname.local); - return value0 === value1 ? null - : value0 === value00 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value1); - }; -} + function ringPoint(lambda, phi) { + linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; + resampleStream.point = linePoint; + } -function attrFunction$1(name, interpolate$$1, value) { - var value00, - value10, - interpolate0; - return function() { - var value0, value1 = value(this); - if (value1 == null) return void this.removeAttribute(name); - value0 = this.getAttribute(name); - return value0 === value1 ? null - : value0 === value00 && value1 === value10 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); - }; -} + function ringEnd() { + resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream); + resampleStream.lineEnd = lineEnd; + lineEnd(); + } -function attrFunctionNS$1(fullname, interpolate$$1, value) { - var value00, - value10, - interpolate0; - return function() { - var value0, value1 = value(this); - if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); - value0 = this.getAttributeNS(fullname.space, fullname.local); - return value0 === value1 ? null - : value0 === value00 && value1 === value10 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); + return resampleStream; }; } -var transition_attr = function(name, value) { - var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate$1; - return this.attrTween(name, typeof value === "function" - ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value)) - : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname) - : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value)); -}; - -function attrTweenNS(fullname, value) { - function tween() { - var node = this, i = value.apply(node, arguments); - return i && function(t) { - node.setAttributeNS(fullname.space, fullname.local, i(t)); - }; +var transformRadians = transformer({ + point: function(x, y) { + this.stream.point(x * radians, y * radians); } - tween._value = value; - return tween; -} +}); -function attrTween(name, value) { - function tween() { - var node = this, i = value.apply(node, arguments); - return i && function(t) { - node.setAttribute(name, i(t)); - }; - } - tween._value = value; - return tween; +function projection(project) { + return projectionMutator(function() { return project; })(); } -var transition_attrTween = function(name, value) { - var key = "attr." + name; - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - var fullname = namespace(name); - return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); -}; - -function delayFunction(id, value) { - return function() { - init(this, id).delay = +value.apply(this, arguments); - }; -} +function projectionMutator(projectAt) { + var project, + k = 150, // scale + x = 480, y = 250, // translate + dx, dy, lambda = 0, phi = 0, // center + deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate + theta = null, preclip = clipAntimeridian, // clip angle + x0 = null, y0, x1, y1, postclip = identity$4, // clip extent + delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision + cache, + cacheStream; -function delayConstant(id, value) { - return value = +value, function() { - init(this, id).delay = value; - }; -} + function projection(point) { + point = projectRotate(point[0] * radians, point[1] * radians); + return [point[0] * k + dx, dy - point[1] * k]; + } -var transition_delay = function(value) { - var id = this._id; + function invert(point) { + point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k); + return point && [point[0] * degrees$1, point[1] * degrees$1]; + } - return arguments.length - ? this.each((typeof value === "function" - ? delayFunction - : delayConstant)(id, value)) - : get$1(this.node(), id).delay; -}; + function projectTransform(x, y) { + return x = project(x, y), [x[0] * k + dx, dy - x[1] * k]; + } -function durationFunction(id, value) { - return function() { - set$3(this, id).duration = +value.apply(this, arguments); + projection.stream = function(stream) { + return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream)))); }; -} -function durationConstant(id, value) { - return value = +value, function() { - set$3(this, id).duration = value; + projection.clipAngle = function(_) { + return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1; }; -} - -var transition_duration = function(value) { - var id = this._id; - return arguments.length - ? this.each((typeof value === "function" - ? durationFunction - : durationConstant)(id, value)) - : get$1(this.node(), id).duration; -}; + projection.clipExtent = function(_) { + return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; + }; -function easeConstant(id, value) { - if (typeof value !== "function") throw new Error; - return function() { - set$3(this, id).ease = value; + projection.scale = function(_) { + return arguments.length ? (k = +_, recenter()) : k; }; -} -var transition_ease = function(value) { - var id = this._id; + projection.translate = function(_) { + return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y]; + }; - return arguments.length - ? this.each(easeConstant(id, value)) - : get$1(this.node(), id).ease; -}; + projection.center = function(_) { + return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1]; + }; -var transition_filter = function(match) { - if (typeof match !== "function") match = matcher$1(match); + projection.rotate = function(_) { + return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1]; + }; - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } - } - } + projection.precision = function(_) { + return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2); + }; - return new Transition(subgroups, this._parents, this._name, this._id); -}; + projection.fitExtent = function(extent, object) { + return fitExtent(projection, extent, object); + }; -var transition_merge = function(transition) { - if (transition._id !== this._id) throw new Error; + projection.fitSize = function(size, object) { + return fitSize(projection, size, object); + }; - for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { - for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group0[i] || group1[i]) { - merge[i] = node; - } - } + function recenter() { + projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project); + var center = project(lambda, phi); + dx = x - center[0] * k; + dy = y + center[1] * k; + return reset(); } - for (; j < m0; ++j) { - merges[j] = groups0[j]; + function reset() { + cache = cacheStream = null; + return projection; } - return new Transition(merges, this._parents, this._name, this._id); -}; - -function start$1(name) { - return (name + "").trim().split(/^|\s+/).every(function(t) { - var i = t.indexOf("."); - if (i >= 0) t = t.slice(0, i); - return !t || t === "start"; - }); -} - -function onFunction(id, name, listener) { - var on0, on1, sit = start$1(name) ? init : set$3; return function() { - var schedule = sit(this, id), - on = schedule.on; + project = projectAt.apply(this, arguments); + projection.invert = project.invert && invert; + return recenter(); + }; +} - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); +function conicProjection(projectAt) { + var phi0 = 0, + phi1 = pi$3 / 3, + m = projectionMutator(projectAt), + p = m(phi0, phi1); - schedule.on = on1; + p.parallels = function(_) { + return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1]; }; + + return p; } -var transition_on = function(name, listener) { - var id = this._id; +function cylindricalEqualAreaRaw(phi0) { + var cosPhi0 = cos$1(phi0); - return arguments.length < 2 - ? get$1(this.node(), id).on.on(name) - : this.each(onFunction(id, name, listener)); -}; + function forward(lambda, phi) { + return [lambda * cosPhi0, sin$1(phi) / cosPhi0]; + } -function removeFunction(id) { - return function() { - var parent = this.parentNode; - for (var i in this.__transition) if (+i !== id) return; - if (parent) parent.removeChild(this); + forward.invert = function(x, y) { + return [x / cosPhi0, asin(y * cosPhi0)]; }; + + return forward; } -var transition_remove = function() { - return this.on("end.remove", removeFunction(this._id)); -}; +function conicEqualAreaRaw(y0, y1) { + var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2; -var transition_select = function(select$$1) { - var name = this._name, - id = this._id; + // Are the parallels symmetrical around the Equator? + if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0); - if (typeof select$$1 !== "function") select$$1 = selector(select$$1); + var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n; - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { - if ((node = group[i]) && (subnode = select$$1.call(node, node.__data__, i, group))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - schedule(subgroup[i], name, id, i, subgroup, get$1(node, id)); - } - } + function project(x, y) { + var r = sqrt(c - 2 * n * sin$1(y)) / n; + return [r * sin$1(x *= n), r0 - r * cos$1(x)]; } - return new Transition(subgroups, this._parents, name, id); -}; - -var transition_selectAll = function(select$$1) { - var name = this._name, - id = this._id; - - if (typeof select$$1 !== "function") select$$1 = selectorAll(select$$1); + project.invert = function(x, y) { + var r0y = r0 - y; + return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))]; + }; - for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - for (var children = select$$1.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) { - if (child = children[k]) { - schedule(child, name, id, k, children, inherit); - } - } - subgroups.push(children); - parents.push(node); - } - } - } + return project; +} - return new Transition(subgroups, parents, name, id); +var conicEqualArea = function() { + return conicProjection(conicEqualAreaRaw) + .scale(155.424) + .center([0, 33.6442]); }; -var Selection$1 = selection.prototype.constructor; - -var transition_selection = function() { - return new Selection$1(this._groups, this._parents); +var albers = function() { + return conicEqualArea() + .parallels([29.5, 45.5]) + .scale(1070) + .translate([480, 250]) + .rotate([96, 0]) + .center([-0.6, 38.7]); }; -function styleRemove$1(name, interpolate$$1) { - var value00, - value10, - interpolate0; - return function() { - var style = window(this).getComputedStyle(this, null), - value0 = style.getPropertyValue(name), - value1 = (this.style.removeProperty(name), style.getPropertyValue(name)); - return value0 === value1 ? null - : value0 === value00 && value1 === value10 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); +// The projections must have mutually exclusive clip regions on the sphere, +// as this will avoid emitting interleaving lines and polygons. +function multiplex(streams) { + var n = streams.length; + return { + point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); }, + sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); }, + lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); }, + lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); }, + polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); }, + polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); } }; } -function styleRemoveEnd(name) { - return function() { - this.style.removeProperty(name); +// A composite projection for the United States, configured by default for +// 960×500. The projection also works quite well at 960×600 if you change the +// scale to 1285 and adjust the translate accordingly. The set of standard +// parallels for each region comes from USGS, which is published here: +// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers +var albersUsa = function() { + var cache, + cacheStream, + lower48 = albers(), lower48Point, + alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338 + hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007 + point, pointStream = {point: function(x, y) { point = [x, y]; }}; + + function albersUsa(coordinates) { + var x = coordinates[0], y = coordinates[1]; + return point = null, + (lower48Point.point(x, y), point) + || (alaskaPoint.point(x, y), point) + || (hawaiiPoint.point(x, y), point); + } + + albersUsa.invert = function(coordinates) { + var k = lower48.scale(), + t = lower48.translate(), + x = (coordinates[0] - t[0]) / k, + y = (coordinates[1] - t[1]) / k; + return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska + : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii + : lower48).invert(coordinates); + }; + + albersUsa.stream = function(stream) { + return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]); }; -} -function styleConstant$1(name, interpolate$$1, value1) { - var value00, - interpolate0; - return function() { - var value0 = window(this).getComputedStyle(this, null).getPropertyValue(name); - return value0 === value1 ? null - : value0 === value00 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value1); + albersUsa.precision = function(_) { + if (!arguments.length) return lower48.precision(); + lower48.precision(_), alaska.precision(_), hawaii.precision(_); + return reset(); }; -} -function styleFunction$1(name, interpolate$$1, value) { - var value00, - value10, - interpolate0; - return function() { - var style = window(this).getComputedStyle(this, null), - value0 = style.getPropertyValue(name), - value1 = value(this); - if (value1 == null) value1 = (this.style.removeProperty(name), style.getPropertyValue(name)); - return value0 === value1 ? null - : value0 === value00 && value1 === value10 ? interpolate0 - : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); + albersUsa.scale = function(_) { + if (!arguments.length) return lower48.scale(); + lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_); + return albersUsa.translate(lower48.translate()); }; -} -var transition_style = function(name, value, priority) { - var i = (name += "") === "transform" ? interpolateTransformCss : interpolate$1; - return value == null ? this - .styleTween(name, styleRemove$1(name, i)) - .on("end.style." + name, styleRemoveEnd(name)) - : this.styleTween(name, typeof value === "function" - ? styleFunction$1(name, i, tweenValue(this, "style." + name, value)) - : styleConstant$1(name, i, value), priority); -}; + albersUsa.translate = function(_) { + if (!arguments.length) return lower48.translate(); + var k = lower48.scale(), x = +_[0], y = +_[1]; -function styleTween(name, value, priority) { - function tween() { - var node = this, i = value.apply(node, arguments); - return i && function(t) { - node.style.setProperty(name, i(t), priority); - }; - } - tween._value = value; - return tween; -} + lower48Point = lower48 + .translate(_) + .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]]) + .stream(pointStream); -var transition_styleTween = function(name, value, priority) { - var key = "style." + (name += ""); - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); -}; + alaskaPoint = alaska + .translate([x - 0.307 * k, y + 0.201 * k]) + .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]]) + .stream(pointStream); -function textConstant$1(value) { - return function() { - this.textContent = value; - }; -} + hawaiiPoint = hawaii + .translate([x - 0.205 * k, y + 0.212 * k]) + .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]]) + .stream(pointStream); -function textFunction$1(value) { - return function() { - var value1 = value(this); - this.textContent = value1 == null ? "" : value1; + return reset(); }; -} -var transition_text = function(value) { - return this.tween("text", typeof value === "function" - ? textFunction$1(tweenValue(this, "text", value)) - : textConstant$1(value == null ? "" : value + "")); -}; + albersUsa.fitExtent = function(extent, object) { + return fitExtent(albersUsa, extent, object); + }; -var transition_transition = function() { - var name = this._name, - id0 = this._id, - id1 = newId(); + albersUsa.fitSize = function(size, object) { + return fitSize(albersUsa, size, object); + }; - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - var inherit = get$1(node, id0); - schedule(node, name, id1, i, group, { - time: inherit.time + inherit.delay + inherit.duration, - delay: 0, - duration: inherit.duration, - ease: inherit.ease - }); - } - } + function reset() { + cache = cacheStream = null; + return albersUsa; } - return new Transition(groups, this._parents, name, id1); + return albersUsa.scale(1070); }; -var id = 0; - -function Transition(groups, parents, name, id) { - this._groups = groups; - this._parents = parents; - this._name = name; - this._id = id; -} - -function transition(name) { - return selection().transition(name); +function azimuthalRaw(scale) { + return function(x, y) { + var cx = cos$1(x), + cy = cos$1(y), + k = scale(cx * cy); + return [ + k * cy * sin$1(x), + k * sin$1(y) + ]; + } } -function newId() { - return ++id; +function azimuthalInvert(angle) { + return function(x, y) { + var z = sqrt(x * x + y * y), + c = angle(z), + sc = sin$1(c), + cc = cos$1(c); + return [ + atan2(x * sc, z * cc), + asin(z && y * sc / z) + ]; + } } -var selection_prototype = selection.prototype; +var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) { + return sqrt(2 / (1 + cxcy)); +}); -Transition.prototype = transition.prototype = { - constructor: Transition, - select: transition_select, - selectAll: transition_selectAll, - filter: transition_filter, - merge: transition_merge, - selection: transition_selection, - transition: transition_transition, - call: selection_prototype.call, - nodes: selection_prototype.nodes, - node: selection_prototype.node, - size: selection_prototype.size, - empty: selection_prototype.empty, - each: selection_prototype.each, - on: transition_on, - attr: transition_attr, - attrTween: transition_attrTween, - style: transition_style, - styleTween: transition_styleTween, - text: transition_text, - remove: transition_remove, - tween: transition_tween, - delay: transition_delay, - duration: transition_duration, - ease: transition_ease -}; +azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) { + return 2 * asin(z / 2); +}); -var defaultTiming = { - time: null, // Set on use. - delay: 0, - duration: 250, - ease: cubicInOut +var azimuthalEqualArea = function() { + return projection(azimuthalEqualAreaRaw) + .scale(124.75) + .clipAngle(180 - 1e-3); }; -function inherit(node, id) { - var timing; - while (!(timing = node.__transition) || !(timing = timing[id])) { - if (!(node = node.parentNode)) { - return defaultTiming.time = now(), defaultTiming; - } - } - return timing; -} +var azimuthalEquidistantRaw = azimuthalRaw(function(c) { + return (c = acos(c)) && c / sin$1(c); +}); -var selection_transition = function(name) { - var id, - timing; +azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) { + return z; +}); - if (name instanceof Transition) { - id = name._id, name = name._name; - } else { - id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; - } +var azimuthalEquidistant = function() { + return projection(azimuthalEquidistantRaw) + .scale(79.4188) + .clipAngle(180 - 1e-3); +}; - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - schedule(node, name, id, i, group, timing || inherit(node, id)); - } - } - } +function mercatorRaw(lambda, phi) { + return [lambda, log(tan((halfPi$2 + phi) / 2))]; +} - return new Transition(groups, this._parents, name, id); +mercatorRaw.invert = function(x, y) { + return [x, 2 * atan(exp(y)) - halfPi$2]; }; -selection.prototype.interrupt = selection_interrupt; -selection.prototype.transition = selection_transition; - -var root$1 = [null]; +var mercator = function() { + return mercatorProjection(mercatorRaw) + .scale(961 / tau$3); +}; -var active = function(node, name) { - var schedules = node.__transition, - schedule, - i; +function mercatorProjection(project) { + var m = projection(project), + center = m.center, + scale = m.scale, + translate = m.translate, + clipExtent = m.clipExtent, + x0 = null, y0, x1, y1; // clip extent - if (schedules) { - name = name == null ? null : name + ""; - for (i in schedules) { - if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) { - return new Transition([[node]], root$1, name, +i); - } - } - } + m.scale = function(_) { + return arguments.length ? (scale(_), reclip()) : scale(); + }; - return null; -}; + m.translate = function(_) { + return arguments.length ? (translate(_), reclip()) : translate(); + }; -var slice$4 = Array.prototype.slice; + m.center = function(_) { + return arguments.length ? (center(_), reclip()) : center(); + }; -var identity$5 = function(x) { - return x; -}; + m.clipExtent = function(_) { + return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]]; + }; -var top = 1; -var right = 2; -var bottom = 3; -var left = 4; -var epsilon$2 = 1e-6; + function reclip() { + var k = pi$3 * scale(), + t = m(rotation(m.rotate()).invert([0, 0])); + return clipExtent(x0 == null + ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw + ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]] + : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]); + } -function translateX(scale0, scale1, d) { - var x = scale0(d); - return "translate(" + (isFinite(x) ? x : scale1(d)) + ",0)"; + return reclip(); } -function translateY(scale0, scale1, d) { - var y = scale0(d); - return "translate(0," + (isFinite(y) ? y : scale1(d)) + ")"; +function tany(y) { + return tan((halfPi$2 + y) / 2); } -function center(scale) { - var offset = scale.bandwidth() / 2; - if (scale.round()) offset = Math.round(offset); - return function(d) { - return scale(d) + offset; +function conicConformalRaw(y0, y1) { + var cy0 = cos$1(y0), + n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)), + f = cy0 * pow(tany(y0), n) / n; + + if (!n) return mercatorRaw; + + function project(x, y) { + if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; } + else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; } + var r = f / pow(tany(y), n); + return [r * sin$1(n * x), f - r * cos$1(n * x)]; + } + + project.invert = function(x, y) { + var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy); + return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2]; }; -} -function entering() { - return !this.__axis; + return project; } -function axis(orient, scale) { - var tickArguments = [], - tickValues = null, - tickFormat = null, - tickSizeInner = 6, - tickSizeOuter = 6, - tickPadding = 3; +var conicConformal = function() { + return conicProjection(conicConformalRaw) + .scale(109.5) + .parallels([30, 30]); +}; - function axis(context) { - var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues, - format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$5) : tickFormat, - spacing = Math.max(tickSizeInner, 0) + tickPadding, - transform = orient === top || orient === bottom ? translateX : translateY, - range = scale.range(), - range0 = range[0] + 0.5, - range1 = range[range.length - 1] + 0.5, - position = (scale.bandwidth ? center : identity$5)(scale.copy()), - selection = context.selection ? context.selection() : context, - path = selection.selectAll(".domain").data([null]), - tick = selection.selectAll(".tick").data(values, scale).order(), - tickExit = tick.exit(), - tickEnter = tick.enter().append("g").attr("class", "tick"), - line = tick.select("line"), - text = tick.select("text"), - k = orient === top || orient === left ? -1 : 1, - x, y = orient === left || orient === right ? (x = "x", "y") : (x = "y", "x"); +function equirectangularRaw(lambda, phi) { + return [lambda, phi]; +} - path = path.merge(path.enter().insert("path", ".tick") - .attr("class", "domain") - .attr("stroke", "#000")); +equirectangularRaw.invert = equirectangularRaw; - tick = tick.merge(tickEnter); +var equirectangular = function() { + return projection(equirectangularRaw) + .scale(152.63); +}; - line = line.merge(tickEnter.append("line") - .attr("stroke", "#000") - .attr(x + "2", k * tickSizeInner) - .attr(y + "1", 0.5) - .attr(y + "2", 0.5)); +function conicEquidistantRaw(y0, y1) { + var cy0 = cos$1(y0), + n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0), + g = cy0 / n + y0; - text = text.merge(tickEnter.append("text") - .attr("fill", "#000") - .attr(x, k * spacing) - .attr(y, 0.5) - .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em")); + if (abs(n) < epsilon$2) return equirectangularRaw; - if (context !== selection) { - path = path.transition(context); - tick = tick.transition(context); - line = line.transition(context); - text = text.transition(context); + function project(x, y) { + var gy = g - y, nx = n * x; + return [gy * sin$1(nx), g - gy * cos$1(nx)]; + } - tickExit = tickExit.transition(context) - .attr("opacity", epsilon$2) - .attr("transform", function(d) { return transform(position, this.parentNode.__axis || position, d); }); + project.invert = function(x, y) { + var gy = g - y; + return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)]; + }; - tickEnter - .attr("opacity", epsilon$2) - .attr("transform", function(d) { return transform(this.parentNode.__axis || position, position, d); }); - } + return project; +} - tickExit.remove(); +var conicEquidistant = function() { + return conicProjection(conicEquidistantRaw) + .scale(131.154) + .center([0, 13.9389]); +}; - path - .attr("d", orient === left || orient == right - ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter - : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter); +function gnomonicRaw(x, y) { + var cy = cos$1(y), k = cos$1(x) * cy; + return [cy * sin$1(x) / k, sin$1(y) / k]; +} - tick - .attr("opacity", 1) - .attr("transform", function(d) { return transform(position, position, d); }); +gnomonicRaw.invert = azimuthalInvert(atan); - line - .attr(x + "2", k * tickSizeInner); +var gnomonic = function() { + return projection(gnomonicRaw) + .scale(144.049) + .clipAngle(60); +}; - text - .attr(x, k * spacing) - .text(format); +function scaleTranslate(kx, ky, tx, ty) { + return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({ + point: function(x, y) { + this.stream.point(x * kx + tx, y * ky + ty); + } + }); +} - selection.filter(entering) - .attr("fill", "none") - .attr("font-size", 10) - .attr("font-family", "sans-serif") - .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle"); +var identity$5 = function() { + var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$4, // scale, translate and reflect + x0 = null, y0, x1, y1, clip = identity$4, // clip extent + cache, + cacheStream, + projection; - selection - .each(function() { this.__axis = position; }); + function reset() { + cache = cacheStream = null; + return projection; } - axis.scale = function(_) { - return arguments.length ? (scale = _, axis) : scale; - }; - - axis.ticks = function() { - return tickArguments = slice$4.call(arguments), axis; - }; - - axis.tickArguments = function(_) { - return arguments.length ? (tickArguments = _ == null ? [] : slice$4.call(_), axis) : tickArguments.slice(); + return projection = { + stream: function(stream) { + return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream)); + }, + clipExtent: function(_) { + return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; + }, + scale: function(_) { + return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k; + }, + translate: function(_) { + return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty]; + }, + reflectX: function(_) { + return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0; + }, + reflectY: function(_) { + return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0; + }, + fitExtent: function(extent, object) { + return fitExtent(projection, extent, object); + }, + fitSize: function(size, object) { + return fitSize(projection, size, object); + } }; +}; - axis.tickValues = function(_) { - return arguments.length ? (tickValues = _ == null ? null : slice$4.call(_), axis) : tickValues && tickValues.slice(); - }; +function orthographicRaw(x, y) { + return [cos$1(y) * sin$1(x), sin$1(y)]; +} - axis.tickFormat = function(_) { - return arguments.length ? (tickFormat = _, axis) : tickFormat; - }; +orthographicRaw.invert = azimuthalInvert(asin); - axis.tickSize = function(_) { - return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner; - }; +var orthographic = function() { + return projection(orthographicRaw) + .scale(249.5) + .clipAngle(90 + epsilon$2); +}; - axis.tickSizeInner = function(_) { - return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner; - }; +function stereographicRaw(x, y) { + var cy = cos$1(y), k = 1 + cos$1(x) * cy; + return [cy * sin$1(x) / k, sin$1(y) / k]; +} - axis.tickSizeOuter = function(_) { - return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter; - }; +stereographicRaw.invert = azimuthalInvert(function(z) { + return 2 * atan(z); +}); - axis.tickPadding = function(_) { - return arguments.length ? (tickPadding = +_, axis) : tickPadding; - }; +var stereographic = function() { + return projection(stereographicRaw) + .scale(250) + .clipAngle(142); +}; - return axis; +function transverseMercatorRaw(lambda, phi) { + return [log(tan((halfPi$2 + phi) / 2)), -lambda]; } -function axisTop(scale) { - return axis(top, scale); -} +transverseMercatorRaw.invert = function(x, y) { + return [-y, 2 * atan(exp(x)) - halfPi$2]; +}; -function axisRight(scale) { - return axis(right, scale); -} +var transverseMercator = function() { + var m = mercatorProjection(transverseMercatorRaw), + center = m.center, + rotate = m.rotate; -function axisBottom(scale) { - return axis(bottom, scale); -} + m.center = function(_) { + return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]); + }; -function axisLeft(scale) { - return axis(left, scale); -} + m.rotate = function(_) { + return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]); + }; + + return rotate([0, 0, 90]) + .scale(159.155); +}; function defaultSeparation(a, b) { return a.parent === b.parent ? 1 : 2; @@ -9091,6 +9537,19 @@ var cluster = function() { return cluster; }; +function count(node) { + var sum = 0, + children = node.children, + i = children && children.length; + if (!i) sum = 1; + else while (--i >= 0) sum += children[i].value; + node.value = sum; +} + +var node_count = function() { + return this.eachAfter(count); +}; + var node_each = function(callback) { var node = this, current, next = [node], children, i, n; do { @@ -9269,6 +9728,7 @@ function Node(data) { Node.prototype = hierarchy.prototype = { constructor: Node, + count: node_count, each: node_each, eachAfter: node_eachAfter, eachBefore: node_eachBefore, @@ -9429,12 +9889,15 @@ function intersects(a, b) { var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; - return dr * dr > dx * dx + dy * dy; + return dr * dr - 1e-6 > dx * dx + dy * dy; } -function distance2(circle, x, y) { - var dx = circle.x - x, - dy = circle.y - y; +function distance2(node, x, y) { + var a = node._, + b = node.next._, + ab = a.r + b.r, + dx = (a.x * b.r + b.x * a.r) / ab - x, + dy = (a.y * b.r + b.y * a.r) / ab - y; return dx * dx + dy * dy; } @@ -9478,36 +9941,26 @@ function packEnclose(circles) { // Attempt to place each remaining circle… pack: for (i = 3; i < n; ++i) { place(a._, b._, c = circles[i]), c = new Node$1(c); - - // If there are only three elements in the front-chain… - if ((k = a.previous) === (j = b.next)) { - // If the new circle intersects the third circle, - // rotate the front chain to try the next position. - if (intersects(j._, c._)) { - a = b, b = j, --i; - continue pack; - } - } - - // Find the closest intersecting circle on the front-chain, if any. - else { - sj = j._.r, sk = k._.r; - do { - if (sj <= sk) { - if (intersects(j._, c._)) { - b = j, a.next = b, b.previous = a, --i; - continue pack; - } - j = j.next, sj += j._.r; - } else { - if (intersects(k._, c._)) { - a = k, a.next = b, b.previous = a, --i; - continue pack; - } - k = k.previous, sk += k._.r; + + // Find the closest intersecting circle on the front-chain, if any. + // “Closeness” is determined by linear distance along the front-chain. + // “Ahead” or “behind” is likewise determined by linear distance. + j = b.next, k = a.previous, sj = b._.r, sk = a._.r; + do { + if (sj <= sk) { + if (intersects(j._, c._)) { + b = j, a.next = b, b.previous = a, --i; + continue pack; } - } while (j !== k.next); - } + sj += j._.r, j = j.next; + } else { + if (intersects(k._, c._)) { + a = k, a.next = b, b.previous = a, --i; + continue pack; + } + sk += k._.r, k = k.previous; + } + } while (j !== k.next); // Success! Insert the new circle c between a and b. c.previous = a, c.next = b, a.next = b.previous = b = c; @@ -9517,10 +9970,10 @@ function packEnclose(circles) { ox += ca * c._.x; oy += ca * c._.y; - // Compute the new closest circle a to centroid. - aa = distance2(a._, cx = ox / oa, cy = oy / oa); + // Compute the new closest circle pair to the centroid. + aa = distance2(a, cx = ox / oa, cy = oy / oa); while ((c = c.next) !== b) { - if ((ca = distance2(c._, cx, cy)) < aa) { + if ((ca = distance2(c, cx, cy)) < aa) { a = c, aa = ca; } } @@ -9554,17 +10007,17 @@ function constantZero() { return 0; } -var constant$6 = function(x) { +var constant$8 = function(x) { return function() { return x; }; }; -function defaultRadius(d) { +function defaultRadius$1(d) { return Math.sqrt(d.value); } -var index = function() { +var index$2 = function() { var radius = null, dx = 1, dy = 1, @@ -9577,7 +10030,7 @@ var index = function() { .eachAfter(packChildren(padding, 0.5)) .eachBefore(translateChild(1)); } else { - root.eachBefore(radiusLeaf(defaultRadius)) + root.eachBefore(radiusLeaf(defaultRadius$1)) .eachAfter(packChildren(constantZero, 1)) .eachAfter(packChildren(padding, root.r / Math.min(dx, dy))) .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r))); @@ -9594,7 +10047,7 @@ var index = function() { }; pack.padding = function(x) { - return arguments.length ? (padding = typeof x === "function" ? x : constant$6(+x), pack) : padding; + return arguments.length ? (padding = typeof x === "function" ? x : constant$8(+x), pack) : padding; }; return pack; @@ -10077,7 +10530,7 @@ function squarifyRatio(ratio, parent, x0, y0, x1, y1) { return rows; } -var squarify = (function custom(ratio) { +var squarify = ((function custom(ratio) { function squarify(parent, x0, y0, x1, y1) { squarifyRatio(ratio, parent, x0, y0, x1, y1); @@ -10088,9 +10541,9 @@ var squarify = (function custom(ratio) { }; return squarify; -})(phi); +}))(phi); -var index$1 = function() { +var index$3 = function() { var tile = squarify, round = false, dx = 1, @@ -10113,5902 +10566,5615 @@ var index$1 = function() { return root; } - function positionNode(node) { - var p = paddingStack[node.depth], - x0 = node.x0 + p, - y0 = node.y0 + p, - x1 = node.x1 - p, - y1 = node.y1 - p; - if (x1 < x0) x0 = x1 = (x0 + x1) / 2; - if (y1 < y0) y0 = y1 = (y0 + y1) / 2; - node.x0 = x0; - node.y0 = y0; - node.x1 = x1; - node.y1 = y1; - if (node.children) { - p = paddingStack[node.depth + 1] = paddingInner(node) / 2; - x0 += paddingLeft(node) - p; - y0 += paddingTop(node) - p; - x1 -= paddingRight(node) - p; - y1 -= paddingBottom(node) - p; - if (x1 < x0) x0 = x1 = (x0 + x1) / 2; - if (y1 < y0) y0 = y1 = (y0 + y1) / 2; - tile(node, x0, y0, x1, y1); - } - } - - treemap.round = function(x) { - return arguments.length ? (round = !!x, treemap) : round; - }; - - treemap.size = function(x) { - return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy]; - }; - - treemap.tile = function(x) { - return arguments.length ? (tile = required(x), treemap) : tile; - }; - - treemap.padding = function(x) { - return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner(); - }; - - treemap.paddingInner = function(x) { - return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$6(+x), treemap) : paddingInner; - }; - - treemap.paddingOuter = function(x) { - return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop(); - }; - - treemap.paddingTop = function(x) { - return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$6(+x), treemap) : paddingTop; - }; - - treemap.paddingRight = function(x) { - return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$6(+x), treemap) : paddingRight; - }; - - treemap.paddingBottom = function(x) { - return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$6(+x), treemap) : paddingBottom; - }; - - treemap.paddingLeft = function(x) { - return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$6(+x), treemap) : paddingLeft; - }; - - return treemap; -}; - -var binary = function(parent, x0, y0, x1, y1) { - var nodes = parent.children, - i, n = nodes.length, - sum, sums = new Array(n + 1); - - for (sums[0] = sum = i = 0; i < n; ++i) { - sums[i + 1] = sum += nodes[i].value; - } - - partition(0, n, parent.value, x0, y0, x1, y1); - - function partition(i, j, value, x0, y0, x1, y1) { - if (i >= j - 1) { - var node = nodes[i]; - node.x0 = x0, node.y0 = y0; - node.x1 = x1, node.y1 = y1; - return; - } - - var valueOffset = sums[i], - valueTarget = (value / 2) + valueOffset, - k = i + 1, - hi = j - 1; - - while (k < hi) { - var mid = k + hi >>> 1; - if (sums[mid] < valueTarget) k = mid + 1; - else hi = mid; - } - - var valueLeft = sums[k] - valueOffset, - valueRight = value - valueLeft; - - if ((y1 - y0) > (x1 - x0)) { - var yk = (y0 * valueRight + y1 * valueLeft) / value; - partition(i, k, valueLeft, x0, y0, x1, yk); - partition(k, j, valueRight, x0, yk, x1, y1); - } else { - var xk = (x0 * valueRight + x1 * valueLeft) / value; - partition(i, k, valueLeft, x0, y0, xk, y1); - partition(k, j, valueRight, xk, y0, x1, y1); - } - } -}; - -var sliceDice = function(parent, x0, y0, x1, y1) { - (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1); -}; - -var resquarify = (function custom(ratio) { - - function resquarify(parent, x0, y0, x1, y1) { - if ((rows = parent._squarify) && (rows.ratio === ratio)) { - var rows, - row, - nodes, - i, - j = -1, - n, - m = rows.length, - value = parent.value; - - while (++j < m) { - row = rows[j], nodes = row.children; - for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value; - if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value); - else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1); - value -= row.value; - } - } else { - parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1); - rows.ratio = ratio; - } - } - - resquarify.ratio = function(x) { - return custom((x = +x) > 1 ? x : 1); - }; - - return resquarify; -})(phi); - -var center$1 = function(x, y) { - var nodes; - - if (x == null) x = 0; - if (y == null) y = 0; - - function force() { - var i, - n = nodes.length, - node, - sx = 0, - sy = 0; - - for (i = 0; i < n; ++i) { - node = nodes[i], sx += node.x, sy += node.y; - } - - for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) { - node = nodes[i], node.x -= sx, node.y -= sy; - } - } - - force.initialize = function(_) { - nodes = _; - }; - - force.x = function(_) { - return arguments.length ? (x = +_, force) : x; - }; - - force.y = function(_) { - return arguments.length ? (y = +_, force) : y; - }; - - return force; -}; - -var constant$7 = function(x) { - return function() { - return x; - }; -}; - -var jiggle = function() { - return (Math.random() - 0.5) * 1e-6; -}; - -function x$1(d) { - return d.x + d.vx; -} - -function y$1(d) { - return d.y + d.vy; -} - -var collide = function(radius) { - var nodes, - radii, - strength = 1, - iterations = 1; - - if (typeof radius !== "function") radius = constant$7(radius == null ? 1 : +radius); - - function force() { - var i, n = nodes.length, - tree, - node, - xi, - yi, - ri, - ri2; - - for (var k = 0; k < iterations; ++k) { - tree = quadtree(nodes, x$1, y$1).visitAfter(prepare); - for (i = 0; i < n; ++i) { - node = nodes[i]; - ri = radii[node.index], ri2 = ri * ri; - xi = node.x + node.vx; - yi = node.y + node.vy; - tree.visit(apply); - } - } - - function apply(quad, x0, y0, x1, y1) { - var data = quad.data, rj = quad.r, r = ri + rj; - if (data) { - if (data.index > node.index) { - var x = xi - data.x - data.vx, - y = yi - data.y - data.vy, - l = x * x + y * y; - if (l < r * r) { - if (x === 0) x = jiggle(), l += x * x; - if (y === 0) y = jiggle(), l += y * y; - l = (r - (l = Math.sqrt(l))) / l * strength; - node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj)); - node.vy += (y *= l) * r; - data.vx -= x * (r = 1 - r); - data.vy -= y * r; - } - } - return; - } - return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r; - } - } - - function prepare(quad) { - if (quad.data) return quad.r = radii[quad.data.index]; - for (var i = quad.r = 0; i < 4; ++i) { - if (quad[i] && quad[i].r > quad.r) { - quad.r = quad[i].r; - } + function positionNode(node) { + var p = paddingStack[node.depth], + x0 = node.x0 + p, + y0 = node.y0 + p, + x1 = node.x1 - p, + y1 = node.y1 - p; + if (x1 < x0) x0 = x1 = (x0 + x1) / 2; + if (y1 < y0) y0 = y1 = (y0 + y1) / 2; + node.x0 = x0; + node.y0 = y0; + node.x1 = x1; + node.y1 = y1; + if (node.children) { + p = paddingStack[node.depth + 1] = paddingInner(node) / 2; + x0 += paddingLeft(node) - p; + y0 += paddingTop(node) - p; + x1 -= paddingRight(node) - p; + y1 -= paddingBottom(node) - p; + if (x1 < x0) x0 = x1 = (x0 + x1) / 2; + if (y1 < y0) y0 = y1 = (y0 + y1) / 2; + tile(node, x0, y0, x1, y1); } } - function initialize() { - if (!nodes) return; - var i, n = nodes.length, node; - radii = new Array(n); - for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes); - } + treemap.round = function(x) { + return arguments.length ? (round = !!x, treemap) : round; + }; - force.initialize = function(_) { - nodes = _; - initialize(); + treemap.size = function(x) { + return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy]; }; - force.iterations = function(_) { - return arguments.length ? (iterations = +_, force) : iterations; + treemap.tile = function(x) { + return arguments.length ? (tile = required(x), treemap) : tile; }; - force.strength = function(_) { - return arguments.length ? (strength = +_, force) : strength; + treemap.padding = function(x) { + return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner(); }; - force.radius = function(_) { - return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : radius; + treemap.paddingInner = function(x) { + return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$8(+x), treemap) : paddingInner; }; - return force; -}; + treemap.paddingOuter = function(x) { + return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop(); + }; -function index$2(d) { - return d.index; -} + treemap.paddingTop = function(x) { + return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$8(+x), treemap) : paddingTop; + }; -function find(nodeById, nodeId) { - var node = nodeById.get(nodeId); - if (!node) throw new Error("missing: " + nodeId); - return node; -} + treemap.paddingRight = function(x) { + return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$8(+x), treemap) : paddingRight; + }; -var link = function(links) { - var id = index$2, - strength = defaultStrength, - strengths, - distance = constant$7(30), - distances, - nodes, - count, - bias, - iterations = 1; + treemap.paddingBottom = function(x) { + return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$8(+x), treemap) : paddingBottom; + }; - if (links == null) links = []; + treemap.paddingLeft = function(x) { + return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$8(+x), treemap) : paddingLeft; + }; - function defaultStrength(link) { - return 1 / Math.min(count[link.source.index], count[link.target.index]); - } + return treemap; +}; - function force(alpha) { - for (var k = 0, n = links.length; k < iterations; ++k) { - for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { - link = links[i], source = link.source, target = link.target; - x = target.x + target.vx - source.x - source.vx || jiggle(); - y = target.y + target.vy - source.y - source.vy || jiggle(); - l = Math.sqrt(x * x + y * y); - l = (l - distances[i]) / l * alpha * strengths[i]; - x *= l, y *= l; - target.vx -= x * (b = bias[i]); - target.vy -= y * b; - source.vx += x * (b = 1 - b); - source.vy += y * b; - } - } - } +var binary = function(parent, x0, y0, x1, y1) { + var nodes = parent.children, + i, n = nodes.length, + sum, sums = new Array(n + 1); - function initialize() { - if (!nodes) return; + for (sums[0] = sum = i = 0; i < n; ++i) { + sums[i + 1] = sum += nodes[i].value; + } - var i, - n = nodes.length, - m = links.length, - nodeById = map$1(nodes, id), - link; + partition(0, n, parent.value, x0, y0, x1, y1); - for (i = 0, count = new Array(n); i < m; ++i) { - link = links[i], link.index = i; - if (typeof link.source !== "object") link.source = find(nodeById, link.source); - if (typeof link.target !== "object") link.target = find(nodeById, link.target); - count[link.source.index] = (count[link.source.index] || 0) + 1; - count[link.target.index] = (count[link.target.index] || 0) + 1; + function partition(i, j, value, x0, y0, x1, y1) { + if (i >= j - 1) { + var node = nodes[i]; + node.x0 = x0, node.y0 = y0; + node.x1 = x1, node.y1 = y1; + return; } - for (i = 0, bias = new Array(m); i < m; ++i) { - link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]); + var valueOffset = sums[i], + valueTarget = (value / 2) + valueOffset, + k = i + 1, + hi = j - 1; + + while (k < hi) { + var mid = k + hi >>> 1; + if (sums[mid] < valueTarget) k = mid + 1; + else hi = mid; } - strengths = new Array(m), initializeStrength(); - distances = new Array(m), initializeDistance(); - } + if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k; - function initializeStrength() { - if (!nodes) return; + var valueLeft = sums[k] - valueOffset, + valueRight = value - valueLeft; - for (var i = 0, n = links.length; i < n; ++i) { - strengths[i] = +strength(links[i], i, links); + if ((x1 - x0) > (y1 - y0)) { + var xk = (x0 * valueRight + x1 * valueLeft) / value; + partition(i, k, valueLeft, x0, y0, xk, y1); + partition(k, j, valueRight, xk, y0, x1, y1); + } else { + var yk = (y0 * valueRight + y1 * valueLeft) / value; + partition(i, k, valueLeft, x0, y0, x1, yk); + partition(k, j, valueRight, x0, yk, x1, y1); } } +}; - function initializeDistance() { - if (!nodes) return; +var sliceDice = function(parent, x0, y0, x1, y1) { + (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1); +}; - for (var i = 0, n = links.length; i < n; ++i) { - distances[i] = +distance(links[i], i, links); - } - } +var resquarify = ((function custom(ratio) { - force.initialize = function(_) { - nodes = _; - initialize(); - }; + function resquarify(parent, x0, y0, x1, y1) { + if ((rows = parent._squarify) && (rows.ratio === ratio)) { + var rows, + row, + nodes, + i, + j = -1, + n, + m = rows.length, + value = parent.value; - force.links = function(_) { - return arguments.length ? (links = _, initialize(), force) : links; - }; + while (++j < m) { + row = rows[j], nodes = row.children; + for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value; + if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value); + else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1); + value -= row.value; + } + } else { + parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1); + rows.ratio = ratio; + } + } - force.id = function(_) { - return arguments.length ? (id = _, force) : id; + resquarify.ratio = function(x) { + return custom((x = +x) > 1 ? x : 1); }; - force.iterations = function(_) { - return arguments.length ? (iterations = +_, force) : iterations; - }; + return resquarify; +}))(phi); - force.strength = function(_) { - return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initializeStrength(), force) : strength; - }; +var area$1 = function(polygon) { + var i = -1, + n = polygon.length, + a, + b = polygon[n - 1], + area = 0; - force.distance = function(_) { - return arguments.length ? (distance = typeof _ === "function" ? _ : constant$7(+_), initializeDistance(), force) : distance; - }; + while (++i < n) { + a = b; + b = polygon[i]; + area += a[1] * b[0] - a[0] * b[1]; + } - return force; + return area / 2; }; -function x$2(d) { - return d.x; -} - -function y$2(d) { - return d.y; -} - -var initialRadius = 10; -var initialAngle = Math.PI * (3 - Math.sqrt(5)); - -var simulation = function(nodes) { - var simulation, - alpha = 1, - alphaMin = 0.001, - alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), - alphaTarget = 0, - velocityDecay = 0.6, - forces = map$1(), - stepper = timer(step), - event = dispatch("tick", "end"); - - if (nodes == null) nodes = []; +var centroid$1 = function(polygon) { + var i = -1, + n = polygon.length, + x = 0, + y = 0, + a, + b = polygon[n - 1], + c, + k = 0; - function step() { - tick(); - event.call("tick", simulation); - if (alpha < alphaMin) { - stepper.stop(); - event.call("end", simulation); - } + while (++i < n) { + a = b; + b = polygon[i]; + k += c = a[0] * b[1] - b[0] * a[1]; + x += (a[0] + b[0]) * c; + y += (a[1] + b[1]) * c; } - function tick() { - var i, n = nodes.length, node; + return k *= 3, [x / k, y / k]; +}; - alpha += (alphaTarget - alpha) * alphaDecay; +// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of +// the 3D cross product in a quadrant I Cartesian coordinate system (+x is +// right, +y is up). Returns a positive value if ABC is counter-clockwise, +// negative if clockwise, and zero if the points are collinear. +var cross$1 = function(a, b, c) { + return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); +}; - forces.each(function(force) { - force(alpha); - }); +function lexicographicOrder(a, b) { + return a[0] - b[0] || a[1] - b[1]; +} - for (i = 0; i < n; ++i) { - node = nodes[i]; - if (node.fx == null) node.x += node.vx *= velocityDecay; - else node.x = node.fx, node.vx = 0; - if (node.fy == null) node.y += node.vy *= velocityDecay; - else node.y = node.fy, node.vy = 0; - } - } +// Computes the upper convex hull per the monotone chain algorithm. +// Assumes points.length >= 3, is sorted by x, unique in y. +// Returns an array of indices into points in left-to-right order. +function computeUpperHullIndexes(points) { + var n = points.length, + indexes = [0, 1], + size = 2; - function initializeNodes() { - for (var i = 0, n = nodes.length, node; i < n; ++i) { - node = nodes[i], node.index = i; - if (isNaN(node.x) || isNaN(node.y)) { - var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle; - node.x = radius * Math.cos(angle); - node.y = radius * Math.sin(angle); - } - if (isNaN(node.vx) || isNaN(node.vy)) { - node.vx = node.vy = 0; - } - } + for (var i = 2; i < n; ++i) { + while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size; + indexes[size++] = i; } - function initializeForce(force) { - if (force.initialize) force.initialize(nodes); - return force; - } + return indexes.slice(0, size); // remove popped points +} - initializeNodes(); +var hull = function(points) { + if ((n = points.length) < 3) return null; - return simulation = { - tick: tick, + var i, + n, + sortedPoints = new Array(n), + flippedPoints = new Array(n); - restart: function() { - return stepper.restart(step), simulation; - }, + for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i]; + sortedPoints.sort(lexicographicOrder); + for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]]; - stop: function() { - return stepper.stop(), simulation; - }, + var upperIndexes = computeUpperHullIndexes(sortedPoints), + lowerIndexes = computeUpperHullIndexes(flippedPoints); - nodes: function(_) { - return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes; - }, + // Construct the hull polygon, removing possible duplicate endpoints. + var skipLeft = lowerIndexes[0] === upperIndexes[0], + skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1], + hull = []; - alpha: function(_) { - return arguments.length ? (alpha = +_, simulation) : alpha; - }, + // Add upper hull in right-to-l order. + // Then add lower hull in left-to-right order. + for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]); + for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]); - alphaMin: function(_) { - return arguments.length ? (alphaMin = +_, simulation) : alphaMin; - }, + return hull; +}; - alphaDecay: function(_) { - return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay; - }, +var contains$1 = function(polygon, point) { + var n = polygon.length, + p = polygon[n - 1], + x = point[0], y = point[1], + x0 = p[0], y0 = p[1], + x1, y1, + inside = false; - alphaTarget: function(_) { - return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget; - }, + for (var i = 0; i < n; ++i) { + p = polygon[i], x1 = p[0], y1 = p[1]; + if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside; + x0 = x1, y0 = y1; + } - velocityDecay: function(_) { - return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay; - }, + return inside; +}; - force: function(name, _) { - return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name); - }, +var length$2 = function(polygon) { + var i = -1, + n = polygon.length, + b = polygon[n - 1], + xa, + ya, + xb = b[0], + yb = b[1], + perimeter = 0; - find: function(x, y, radius) { - var i = 0, - n = nodes.length, - dx, - dy, - d2, - node, - closest; + while (++i < n) { + xa = xb; + ya = yb; + b = polygon[i]; + xb = b[0]; + yb = b[1]; + xa -= xb; + ya -= yb; + perimeter += Math.sqrt(xa * xa + ya * ya); + } - if (radius == null) radius = Infinity; - else radius *= radius; + return perimeter; +}; - for (i = 0; i < n; ++i) { - node = nodes[i]; - dx = x - node.x; - dy = y - node.y; - d2 = dx * dx + dy * dy; - if (d2 < radius) closest = node, radius = d2; - } +var slice$3 = [].slice; - return closest; - }, +var noabort = {}; - on: function(name, _) { - return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); - } - }; -}; +function Queue(size) { + if (!(size >= 1)) throw new Error; + this._size = size; + this._call = + this._error = null; + this._tasks = []; + this._data = []; + this._waiting = + this._active = + this._ended = + this._start = 0; // inside a synchronous task callback? +} -var manyBody = function() { - var nodes, - node, - alpha, - strength = constant$7(-30), - strengths, - distanceMin2 = 1, - distanceMax2 = Infinity, - theta2 = 0.81; +Queue.prototype = queue.prototype = { + constructor: Queue, + defer: function(callback) { + if (typeof callback !== "function" || this._call) throw new Error; + if (this._error != null) return this; + var t = slice$3.call(arguments, 1); + t.push(callback); + ++this._waiting, this._tasks.push(t); + poke$1(this); + return this; + }, + abort: function() { + if (this._error == null) abort(this, new Error("abort")); + return this; + }, + await: function(callback) { + if (typeof callback !== "function" || this._call) throw new Error; + this._call = function(error, results) { callback.apply(null, [error].concat(results)); }; + maybeNotify(this); + return this; + }, + awaitAll: function(callback) { + if (typeof callback !== "function" || this._call) throw new Error; + this._call = callback; + maybeNotify(this); + return this; + } +}; - function force(_) { - var i, n = nodes.length, tree = quadtree(nodes, x$2, y$2).visitAfter(accumulate); - for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); +function poke$1(q) { + if (!q._start) { + try { start$1(q); } // let the current task complete + catch (e) { + if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously + else if (!q._data) throw e; // await callback errored synchronously + } } +} - function initialize() { - if (!nodes) return; - var i, n = nodes.length, node; - strengths = new Array(n); - for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes); +function start$1(q) { + while (q._start = q._waiting && q._active < q._size) { + var i = q._ended + q._active, + t = q._tasks[i], + j = t.length - 1, + c = t[j]; + t[j] = end(q, i); + --q._waiting, ++q._active; + t = c.apply(null, t); + if (!q._tasks[i]) continue; // task finished synchronously + q._tasks[i] = t || noabort; } +} - function accumulate(quad) { - var strength = 0, q, c, x$$1, y$$1, i; +function end(q, i) { + return function(e, r) { + if (!q._tasks[i]) return; // ignore multiple callbacks + --q._active, ++q._ended; + q._tasks[i] = null; + if (q._error != null) return; // ignore secondary errors + if (e != null) { + abort(q, e); + } else { + q._data[i] = r; + if (q._waiting) poke$1(q); + else maybeNotify(q); + } + }; +} + +function abort(q, e) { + var i = q._tasks.length, t; + q._error = e; // ignore active callbacks + q._data = undefined; // allow gc + q._waiting = NaN; // prevent starting - // For internal nodes, accumulate forces from child quadrants. - if (quad.length) { - for (x$$1 = y$$1 = i = 0; i < 4; ++i) { - if ((q = quad[i]) && (c = q.value)) { - strength += c, x$$1 += c * q.x, y$$1 += c * q.y; - } + while (--i >= 0) { + if (t = q._tasks[i]) { + q._tasks[i] = null; + if (t.abort) { + try { t.abort(); } + catch (e) { /* ignore */ } } - quad.x = x$$1 / strength; - quad.y = y$$1 / strength; } + } - // For leaf nodes, accumulate forces from coincident quadrants. - else { - q = quad; - q.x = q.data.x; - q.y = q.data.y; - do strength += strengths[q.data.index]; - while (q = q.next); - } + q._active = NaN; // allow notification + maybeNotify(q); +} - quad.value = strength; +function maybeNotify(q) { + if (!q._active && q._call) { + var d = q._data; + q._data = undefined; // allow gc + q._call(q._error, d); } +} - function apply(quad, x1, _, x2) { - if (!quad.value) return true; - - var x$$1 = quad.x - node.x, - y$$1 = quad.y - node.y, - w = x2 - x1, - l = x$$1 * x$$1 + y$$1 * y$$1; +function queue(concurrency) { + return new Queue(arguments.length ? +concurrency : Infinity); +} - // Apply the Barnes-Hut approximation if possible. - // Limit forces for very close nodes; randomize direction if coincident. - if (w * w / theta2 < l) { - if (l < distanceMax2) { - if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1; - if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1; - if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); - node.vx += x$$1 * quad.value * alpha / l; - node.vy += y$$1 * quad.value * alpha / l; - } - return true; - } +var uniform = function(min, max) { + min = min == null ? 0 : +min; + max = max == null ? 1 : +max; + if (arguments.length === 1) max = min, min = 0; + else max -= min; + return function() { + return Math.random() * max + min; + }; +}; - // Otherwise, process points directly. - else if (quad.length || l >= distanceMax2) return; +var normal = function(mu, sigma) { + var x, r; + mu = mu == null ? 0 : +mu; + sigma = sigma == null ? 1 : +sigma; + return function() { + var y; - // Limit forces for very close nodes; randomize direction if coincident. - if (quad.data !== node || quad.next) { - if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1; - if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1; - if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); - } + // If available, use the second previously-generated uniform random. + if (x != null) y = x, x = null; - do if (quad.data !== node) { - w = strengths[quad.data.index] * alpha / l; - node.vx += x$$1 * w; - node.vy += y$$1 * w; - } while (quad = quad.next); - } + // Otherwise, generate a new x and y. + else do { + x = Math.random() * 2 - 1; + y = Math.random() * 2 - 1; + r = x * x + y * y; + } while (!r || r > 1); - force.initialize = function(_) { - nodes = _; - initialize(); + return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r); }; +}; - force.strength = function(_) { - return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength; +var logNormal = function() { + var randomNormal = normal.apply(this, arguments); + return function() { + return Math.exp(randomNormal()); }; +}; - force.distanceMin = function(_) { - return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2); +var irwinHall = function(n) { + return function() { + for (var sum = 0, i = 0; i < n; ++i) sum += Math.random(); + return sum; }; +}; - force.distanceMax = function(_) { - return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2); +var bates = function(n) { + var randomIrwinHall = irwinHall(n); + return function() { + return randomIrwinHall() / n; }; +}; - force.theta = function(_) { - return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2); +var exponential$1 = function(lambda) { + return function() { + return -Math.log(1 - Math.random()) / lambda; }; - - return force; }; -var x$3 = function(x) { - var strength = constant$7(0.1), - nodes, - strengths, - xz; +var request = function(url, callback) { + var request, + event = dispatch("beforesend", "progress", "load", "error"), + mimeType, + headers = map$1(), + xhr = new XMLHttpRequest, + user = null, + password = null, + response, + responseType, + timeout = 0; - if (typeof x !== "function") x = constant$7(x == null ? 0 : +x); + // If IE does not support CORS, use XDomainRequest. + if (typeof XDomainRequest !== "undefined" + && !("withCredentials" in xhr) + && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest; - function force(alpha) { - for (var i = 0, n = nodes.length, node; i < n; ++i) { - node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha; - } - } + "onload" in xhr + ? xhr.onload = xhr.onerror = xhr.ontimeout = respond + : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); }; - function initialize() { - if (!nodes) return; - var i, n = nodes.length; - strengths = new Array(n); - xz = new Array(n); - for (i = 0; i < n; ++i) { - strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); + function respond(o) { + var status = xhr.status, result; + if (!status && hasResponse(xhr) + || status >= 200 && status < 300 + || status === 304) { + if (response) { + try { + result = response.call(request, xhr); + } catch (e) { + event.call("error", request, e); + return; + } + } else { + result = xhr; + } + event.call("load", request, result); + } else { + event.call("error", request, o); } } - force.initialize = function(_) { - nodes = _; - initialize(); + xhr.onprogress = function(e) { + event.call("progress", request, e); }; - force.strength = function(_) { - return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength; - }; + request = { + header: function(name, value) { + name = (name + "").toLowerCase(); + if (arguments.length < 2) return headers.get(name); + if (value == null) headers.remove(name); + else headers.set(name, value + ""); + return request; + }, - force.x = function(_) { - return arguments.length ? (x = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : x; - }; + // If mimeType is non-null and no Accept header is set, a default is used. + mimeType: function(value) { + if (!arguments.length) return mimeType; + mimeType = value == null ? null : value + ""; + return request; + }, - return force; -}; + // Specifies what type the response value should take; + // for instance, arraybuffer, blob, document, or text. + responseType: function(value) { + if (!arguments.length) return responseType; + responseType = value; + return request; + }, -var y$3 = function(y) { - var strength = constant$7(0.1), - nodes, - strengths, - yz; + timeout: function(value) { + if (!arguments.length) return timeout; + timeout = +value; + return request; + }, - if (typeof y !== "function") y = constant$7(y == null ? 0 : +y); + user: function(value) { + return arguments.length < 1 ? user : (user = value == null ? null : value + "", request); + }, - function force(alpha) { - for (var i = 0, n = nodes.length, node; i < n; ++i) { - node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha; - } - } + password: function(value) { + return arguments.length < 1 ? password : (password = value == null ? null : value + "", request); + }, - function initialize() { - if (!nodes) return; - var i, n = nodes.length; - strengths = new Array(n); - yz = new Array(n); - for (i = 0; i < n; ++i) { - strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); - } - } + // Specify how to convert the response content to a specific type; + // changes the callback value on "load" events. + response: function(value) { + response = value; + return request; + }, + + // Alias for send("GET", …). + get: function(data, callback) { + return request.send("GET", data, callback); + }, + + // Alias for send("POST", …). + post: function(data, callback) { + return request.send("POST", data, callback); + }, + + // If callback is non-null, it will be used for error and load events. + send: function(method, data, callback) { + xhr.open(method, url, true, user, password); + if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*"); + if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); }); + if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType); + if (responseType != null) xhr.responseType = responseType; + if (timeout > 0) xhr.timeout = timeout; + if (callback == null && typeof data === "function") callback = data, data = null; + if (callback != null && callback.length === 1) callback = fixCallback(callback); + if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); }); + event.call("beforesend", request, xhr); + xhr.send(data == null ? null : data); + return request; + }, - force.initialize = function(_) { - nodes = _; - initialize(); - }; + abort: function() { + xhr.abort(); + return request; + }, - force.strength = function(_) { - return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength; + on: function() { + var value = event.on.apply(event, arguments); + return value === event ? request : value; + } }; - force.y = function(_) { - return arguments.length ? (y = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : y; - }; + if (callback != null) { + if (typeof callback !== "function") throw new Error("invalid callback: " + callback); + return request.get(callback); + } - return force; + return request; }; -function nopropagation() { - exports.event.stopImmediatePropagation(); +function fixCallback(callback) { + return function(error, xhr) { + callback(error == null ? xhr : null); + }; } -var noevent = function() { - exports.event.preventDefault(); - exports.event.stopImmediatePropagation(); -}; - -var dragDisable = function(view) { - var root = view.document.documentElement, - selection$$1 = select(view).on("dragstart.drag", noevent, true); - if ("onselectstart" in root) { - selection$$1.on("selectstart.drag", noevent, true); - } else { - root.__noselect = root.style.MozUserSelect; - root.style.MozUserSelect = "none"; - } -}; - -function yesdrag(view, noclick) { - var root = view.document.documentElement, - selection$$1 = select(view).on("dragstart.drag", null); - if (noclick) { - selection$$1.on("click.drag", noevent, true); - setTimeout(function() { selection$$1.on("click.drag", null); }, 0); - } - if ("onselectstart" in root) { - selection$$1.on("selectstart.drag", null); - } else { - root.style.MozUserSelect = root.__noselect; - delete root.__noselect; - } +function hasResponse(xhr) { + var type = xhr.responseType; + return type && type !== "text" + ? xhr.response // null on error + : xhr.responseText; // "" on error } -var constant$8 = function(x) { - return function() { - return x; +var type$1 = function(defaultMimeType, response) { + return function(url, callback) { + var r = request(url).mimeType(defaultMimeType).response(response); + if (callback != null) { + if (typeof callback !== "function") throw new Error("invalid callback: " + callback); + return r.get(callback); + } + return r; }; }; -function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) { - this.target = target; - this.type = type; - this.subject = subject; - this.identifier = id; - this.active = active; - this.x = x; - this.y = y; - this.dx = dx; - this.dy = dy; - this._ = dispatch; -} - -DragEvent.prototype.on = function() { - var value = this._.on.apply(this._, arguments); - return value === this._ ? this : value; -}; - -// Ignore right-click, since that should open the context menu. -function defaultFilter() { - return !exports.event.button; -} +var html = type$1("text/html", function(xhr) { + return document.createRange().createContextualFragment(xhr.responseText); +}); -function defaultContainer() { - return this.parentNode; -} +var json = type$1("application/json", function(xhr) { + return JSON.parse(xhr.responseText); +}); -function defaultSubject(d) { - return d == null ? {x: exports.event.x, y: exports.event.y} : d; -} +var text = type$1("text/plain", function(xhr) { + return xhr.responseText; +}); -var drag = function() { - var filter = defaultFilter, - container = defaultContainer, - subject = defaultSubject, - gestures = {}, - listeners = dispatch("start", "drag", "end"), - active = 0, - mousemoving, - touchending; +var xml = type$1("application/xml", function(xhr) { + var xml = xhr.responseXML; + if (!xml) throw new Error("parse error"); + return xml; +}); - function drag(selection$$1) { - selection$$1 - .on("mousedown.drag", mousedowned) - .on("touchstart.drag", touchstarted) - .on("touchmove.drag", touchmoved) - .on("touchend.drag touchcancel.drag", touchended) - .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); - } +var dsv$1 = function(defaultMimeType, parse) { + return function(url, row, callback) { + if (arguments.length < 3) callback = row, row = null; + var r = request(url).mimeType(defaultMimeType); + r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; }; + r.row(row); + return callback ? r.get(callback) : r; + }; +}; - function mousedowned() { - if (touchending || !filter.apply(this, arguments)) return; - var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments); - if (!gesture) return; - select(exports.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); - dragDisable(exports.event.view); - nopropagation(); - mousemoving = false; - gesture("start"); - } +function responseOf(parse, row) { + return function(request$$1) { + return parse(request$$1.responseText, row); + }; +} - function mousemoved() { - noevent(); - mousemoving = true; - gestures.mouse("drag"); - } +var csv$1 = dsv$1("text/csv", csvParse); - function mouseupped() { - select(exports.event.view).on("mousemove.drag mouseup.drag", null); - yesdrag(exports.event.view, mousemoving); - noevent(); - gestures.mouse("end"); - } +var tsv$1 = dsv$1("text/tab-separated-values", tsvParse); - function touchstarted() { - if (!filter.apply(this, arguments)) return; - var touches$$1 = exports.event.changedTouches, - c = container.apply(this, arguments), - n = touches$$1.length, i, gesture; +var array$2 = Array.prototype; - for (i = 0; i < n; ++i) { - if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) { - nopropagation(); - gesture("start"); - } - } - } +var map$3 = array$2.map; +var slice$4 = array$2.slice; - function touchmoved() { - var touches$$1 = exports.event.changedTouches, - n = touches$$1.length, i, gesture; +var implicit = {name: "implicit"}; - for (i = 0; i < n; ++i) { - if (gesture = gestures[touches$$1[i].identifier]) { - noevent(); - gesture("drag"); - } - } - } +function ordinal(range) { + var index = map$1(), + domain = [], + unknown = implicit; - function touchended() { - var touches$$1 = exports.event.changedTouches, - n = touches$$1.length, i, gesture; + range = range == null ? [] : slice$4.call(range); - if (touchending) clearTimeout(touchending); - touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! - for (i = 0; i < n; ++i) { - if (gesture = gestures[touches$$1[i].identifier]) { - nopropagation(); - gesture("end"); - } + function scale(d) { + var key = d + "", i = index.get(key); + if (!i) { + if (unknown !== implicit) return unknown; + index.set(key, i = domain.push(d)); } + return range[(i - 1) % range.length]; } - function beforestart(id, container, point, that, args) { - var p = point(container, id), s, dx, dy, - sublisteners = listeners.copy(); - - if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { - if ((exports.event.subject = s = subject.apply(that, args)) == null) return false; - dx = s.x - p[0] || 0; - dy = s.y - p[1] || 0; - return true; - })) return; - - return function gesture(type) { - var p0 = p, n; - switch (type) { - case "start": gestures[id] = gesture, n = active++; break; - case "end": delete gestures[id], --active; // nobreak - case "drag": p = point(container, id), n = active; break; - } - customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); - }; - } - - drag.filter = function(_) { - return arguments.length ? (filter = typeof _ === "function" ? _ : constant$8(!!_), drag) : filter; - }; - - drag.container = function(_) { - return arguments.length ? (container = typeof _ === "function" ? _ : constant$8(_), drag) : container; + scale.domain = function(_) { + if (!arguments.length) return domain.slice(); + domain = [], index = map$1(); + var i = -1, n = _.length, d, key; + while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d)); + return scale; }; - drag.subject = function(_) { - return arguments.length ? (subject = typeof _ === "function" ? _ : constant$8(_), drag) : subject; + scale.range = function(_) { + return arguments.length ? (range = slice$4.call(_), scale) : range.slice(); }; - drag.on = function() { - var value = listeners.on.apply(listeners, arguments); - return value === listeners ? drag : value; + scale.unknown = function(_) { + return arguments.length ? (unknown = _, scale) : unknown; }; - return drag; -}; - -var constant$9 = function(x) { - return function() { - return x; + scale.copy = function() { + return ordinal() + .domain(domain) + .range(range) + .unknown(unknown); }; -}; -function x$4(d) { - return d[0]; + return scale; } -function y$4(d) { - return d[1]; -} +function band() { + var scale = ordinal().unknown(undefined), + domain = scale.domain, + ordinalRange = scale.range, + range$$1 = [0, 1], + step, + bandwidth, + round = false, + paddingInner = 0, + paddingOuter = 0, + align = 0.5; -function RedBlackTree() { - this._ = null; // root node -} + delete scale.unknown; -function RedBlackNode(node) { - node.U = // parent node - node.C = // color - true for red, false for black - node.L = // left node - node.R = // right node - node.P = // previous node - node.N = null; // next node -} + function rescale() { + var n = domain().length, + reverse = range$$1[1] < range$$1[0], + start = range$$1[reverse - 0], + stop = range$$1[1 - reverse]; + step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); + if (round) step = Math.floor(step); + start += (stop - start - step * (n - paddingInner)) * align; + bandwidth = step * (1 - paddingInner); + if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); + var values = sequence(n).map(function(i) { return start + step * i; }); + return ordinalRange(reverse ? values.reverse() : values); + } -RedBlackTree.prototype = { - constructor: RedBlackTree, + scale.domain = function(_) { + return arguments.length ? (domain(_), rescale()) : domain(); + }; - insert: function(after, node) { - var parent, grandpa, uncle; + scale.range = function(_) { + return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice(); + }; - if (after) { - node.P = after; - node.N = after.N; - if (after.N) after.N.P = node; - after.N = node; - if (after.R) { - after = after.R; - while (after.L) after = after.L; - after.L = node; - } else { - after.R = node; - } - parent = after; - } else if (this._) { - after = RedBlackFirst(this._); - node.P = null; - node.N = after; - after.P = after.L = node; - parent = after; - } else { - node.P = node.N = null; - this._ = node; - parent = null; - } - node.L = node.R = null; - node.U = parent; - node.C = true; + scale.rangeRound = function(_) { + return range$$1 = [+_[0], +_[1]], round = true, rescale(); + }; - after = node; - while (parent && parent.C) { - grandpa = parent.U; - if (parent === grandpa.L) { - uncle = grandpa.R; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.R) { - RedBlackRotateLeft(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - RedBlackRotateRight(this, grandpa); - } - } else { - uncle = grandpa.L; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.L) { - RedBlackRotateRight(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - RedBlackRotateLeft(this, grandpa); - } - } - parent = after.U; - } - this._.C = false; - }, + scale.bandwidth = function() { + return bandwidth; + }; - remove: function(node) { - if (node.N) node.N.P = node.P; - if (node.P) node.P.N = node.N; - node.N = node.P = null; + scale.step = function() { + return step; + }; - var parent = node.U, - sibling, - left = node.L, - right = node.R, - next, - red; + scale.round = function(_) { + return arguments.length ? (round = !!_, rescale()) : round; + }; - if (!left) next = right; - else if (!right) next = left; - else next = RedBlackFirst(right); + scale.padding = function(_) { + return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner; + }; - if (parent) { - if (parent.L === node) parent.L = next; - else parent.R = next; - } else { - this._ = next; - } + scale.paddingInner = function(_) { + return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner; + }; - if (left && right) { - red = next.C; - next.C = node.C; - next.L = left; - left.U = next; - if (next !== right) { - parent = next.U; - next.U = node.U; - node = next.R; - parent.L = node; - next.R = right; - right.U = next; - } else { - next.U = parent; - parent = next; - node = next.R; - } - } else { - red = node.C; - node = next; - } + scale.paddingOuter = function(_) { + return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter; + }; - if (node) node.U = parent; - if (red) return; - if (node && node.C) { node.C = false; return; } + scale.align = function(_) { + return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align; + }; - do { - if (node === this._) break; - if (node === parent.L) { - sibling = parent.R; - if (sibling.C) { - sibling.C = false; - parent.C = true; - RedBlackRotateLeft(this, parent); - sibling = parent.R; - } - if ((sibling.L && sibling.L.C) - || (sibling.R && sibling.R.C)) { - if (!sibling.R || !sibling.R.C) { - sibling.L.C = false; - sibling.C = true; - RedBlackRotateRight(this, sibling); - sibling = parent.R; - } - sibling.C = parent.C; - parent.C = sibling.R.C = false; - RedBlackRotateLeft(this, parent); - node = this._; - break; - } - } else { - sibling = parent.L; - if (sibling.C) { - sibling.C = false; - parent.C = true; - RedBlackRotateRight(this, parent); - sibling = parent.L; - } - if ((sibling.L && sibling.L.C) - || (sibling.R && sibling.R.C)) { - if (!sibling.L || !sibling.L.C) { - sibling.R.C = false; - sibling.C = true; - RedBlackRotateLeft(this, sibling); - sibling = parent.L; - } - sibling.C = parent.C; - parent.C = sibling.L.C = false; - RedBlackRotateRight(this, parent); - node = this._; - break; - } - } - sibling.C = true; - node = parent; - parent = parent.U; - } while (!node.C); + scale.copy = function() { + return band() + .domain(domain()) + .range(range$$1) + .round(round) + .paddingInner(paddingInner) + .paddingOuter(paddingOuter) + .align(align); + }; - if (node) node.C = false; - } -}; + return rescale(); +} -function RedBlackRotateLeft(tree, node) { - var p = node, - q = node.R, - parent = p.U; +function pointish(scale) { + var copy = scale.copy; - if (parent) { - if (parent.L === p) parent.L = q; - else parent.R = q; - } else { - tree._ = q; - } + scale.padding = scale.paddingOuter; + delete scale.paddingInner; + delete scale.paddingOuter; - q.U = parent; - p.U = q; - p.R = q.L; - if (p.R) p.R.U = p; - q.L = p; + scale.copy = function() { + return pointish(copy()); + }; + + return scale; } -function RedBlackRotateRight(tree, node) { - var p = node, - q = node.L, - parent = p.U; +function point$1() { + return pointish(band().paddingInner(1)); +} - if (parent) { - if (parent.L === p) parent.L = q; - else parent.R = q; - } else { - tree._ = q; - } +var constant$9 = function(x) { + return function() { + return x; + }; +}; - q.U = parent; - p.U = q; - p.L = q.R; - if (p.L) p.L.U = p; - q.R = p; -} +var number$1 = function(x) { + return +x; +}; -function RedBlackFirst(node) { - while (node.L) node = node.L; - return node; +var unit = [0, 1]; + +function deinterpolateLinear(a, b) { + return (b -= (a = +a)) + ? function(x) { return (x - a) / b; } + : constant$9(b); } -function createEdge(left, right, v0, v1) { - var edge = [null, null], - index = edges.push(edge) - 1; - edge.left = left; - edge.right = right; - if (v0) setEdgeEnd(edge, left, right, v0); - if (v1) setEdgeEnd(edge, right, left, v1); - cells[left.index].halfedges.push(index); - cells[right.index].halfedges.push(index); - return edge; +function deinterpolateClamp(deinterpolate) { + return function(a, b) { + var d = deinterpolate(a = +a, b = +b); + return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); }; + }; } -function createBorderEdge(left, v0, v1) { - var edge = [v0, v1]; - edge.left = left; - return edge; +function reinterpolateClamp(reinterpolate) { + return function(a, b) { + var r = reinterpolate(a = +a, b = +b); + return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); }; + }; } -function setEdgeEnd(edge, left, right, vertex) { - if (!edge[0] && !edge[1]) { - edge[0] = vertex; - edge.left = left; - edge.right = right; - } else if (edge.left === right) { - edge[1] = vertex; - } else { - edge[0] = vertex; - } +function bimap(domain, range$$1, deinterpolate, reinterpolate) { + var d0 = domain[0], d1 = domain[1], r0 = range$$1[0], r1 = range$$1[1]; + if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0); + else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1); + return function(x) { return r0(d0(x)); }; } -// Liang–Barsky line clipping. -function clipEdge(edge, x0, y0, x1, y1) { - var a = edge[0], - b = edge[1], - ax = a[0], - ay = a[1], - bx = b[0], - by = b[1], - t0 = 0, - t1 = 1, - dx = bx - ax, - dy = by - ay, - r; +function polymap(domain, range$$1, deinterpolate, reinterpolate) { + var j = Math.min(domain.length, range$$1.length) - 1, + d = new Array(j), + r = new Array(j), + i = -1; - r = x0 - ax; - if (!dx && r > 0) return; - r /= dx; - if (dx < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dx > 0) { - if (r > t1) return; - if (r > t0) t0 = r; + // Reverse descending domains. + if (domain[j] < domain[0]) { + domain = domain.slice().reverse(); + range$$1 = range$$1.slice().reverse(); } - r = x1 - ax; - if (!dx && r < 0) return; - r /= dx; - if (dx < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dx > 0) { - if (r < t0) return; - if (r < t1) t1 = r; + while (++i < j) { + d[i] = deinterpolate(domain[i], domain[i + 1]); + r[i] = reinterpolate(range$$1[i], range$$1[i + 1]); } - r = y0 - ay; - if (!dy && r > 0) return; - r /= dy; - if (dy < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dy > 0) { - if (r > t1) return; - if (r > t0) t0 = r; + return function(x) { + var i = bisectRight(domain, x, 1, j) - 1; + return r[i](d[i](x)); + }; +} + +function copy(source, target) { + return target + .domain(source.domain()) + .range(source.range()) + .interpolate(source.interpolate()) + .clamp(source.clamp()); +} + +// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. +// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b]. +function continuous(deinterpolate, reinterpolate) { + var domain = unit, + range$$1 = unit, + interpolate$$1 = interpolateValue, + clamp = false, + piecewise, + output, + input; + + function rescale() { + piecewise = Math.min(domain.length, range$$1.length) > 2 ? polymap : bimap; + output = input = null; + return scale; } - r = y1 - ay; - if (!dy && r < 0) return; - r /= dy; - if (dy < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dy > 0) { - if (r < t0) return; - if (r < t1) t1 = r; + function scale(x) { + return (output || (output = piecewise(domain, range$$1, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x); } - if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check? + scale.invert = function(y) { + return (input || (input = piecewise(range$$1, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y); + }; - if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy]; - if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy]; - return true; -} + scale.domain = function(_) { + return arguments.length ? (domain = map$3.call(_, number$1), rescale()) : domain.slice(); + }; -function connectEdge(edge, x0, y0, x1, y1) { - var v1 = edge[1]; - if (v1) return true; + scale.range = function(_) { + return arguments.length ? (range$$1 = slice$4.call(_), rescale()) : range$$1.slice(); + }; - var v0 = edge[0], - left = edge.left, - right = edge.right, - lx = left[0], - ly = left[1], - rx = right[0], - ry = right[1], - fx = (lx + rx) / 2, - fy = (ly + ry) / 2, - fm, - fb; + scale.rangeRound = function(_) { + return range$$1 = slice$4.call(_), interpolate$$1 = interpolateRound, rescale(); + }; - if (ry === ly) { - if (fx < x0 || fx >= x1) return; - if (lx > rx) { - if (!v0) v0 = [fx, y0]; - else if (v0[1] >= y1) return; - v1 = [fx, y1]; - } else { - if (!v0) v0 = [fx, y1]; - else if (v0[1] < y0) return; - v1 = [fx, y0]; + scale.clamp = function(_) { + return arguments.length ? (clamp = !!_, rescale()) : clamp; + }; + + scale.interpolate = function(_) { + return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1; + }; + + return rescale(); +} + +var tickFormat = function(domain, count, specifier) { + var start = domain[0], + stop = domain[domain.length - 1], + step = tickStep(start, stop, count == null ? 10 : count), + precision; + specifier = formatSpecifier(specifier == null ? ",f" : specifier); + switch (specifier.type) { + case "s": { + var value = Math.max(Math.abs(start), Math.abs(stop)); + if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; + return exports.formatPrefix(specifier, value); } - } else { - fm = (lx - rx) / (ry - ly); - fb = fy - fm * fx; - if (fm < -1 || fm > 1) { - if (lx > rx) { - if (!v0) v0 = [(y0 - fb) / fm, y0]; - else if (v0[1] >= y1) return; - v1 = [(y1 - fb) / fm, y1]; - } else { - if (!v0) v0 = [(y1 - fb) / fm, y1]; - else if (v0[1] < y0) return; - v1 = [(y0 - fb) / fm, y0]; - } - } else { - if (ly < ry) { - if (!v0) v0 = [x0, fm * x0 + fb]; - else if (v0[0] >= x1) return; - v1 = [x1, fm * x1 + fb]; - } else { - if (!v0) v0 = [x1, fm * x1 + fb]; - else if (v0[0] < x0) return; - v1 = [x0, fm * x0 + fb]; - } + case "": + case "e": + case "g": + case "p": + case "r": { + if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); + break; + } + case "f": + case "%": { + if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; + break; } } + return exports.format(specifier); +}; - edge[0] = v0; - edge[1] = v1; - return true; -} +function linearish(scale) { + var domain = scale.domain; -function clipEdges(x0, y0, x1, y1) { - var i = edges.length, - edge; + scale.ticks = function(count) { + var d = domain(); + return ticks(d[0], d[d.length - 1], count == null ? 10 : count); + }; - while (i--) { - if (!connectEdge(edge = edges[i], x0, y0, x1, y1) - || !clipEdge(edge, x0, y0, x1, y1) - || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$3 - || Math.abs(edge[0][1] - edge[1][1]) > epsilon$3)) { - delete edges[i]; + scale.tickFormat = function(count, specifier) { + return tickFormat(domain(), count, specifier); + }; + + scale.nice = function(count) { + var d = domain(), + i = d.length - 1, + n = count == null ? 10 : count, + start = d[0], + stop = d[i], + step = tickStep(start, stop, n); + + if (step) { + step = tickStep(Math.floor(start / step) * step, Math.ceil(stop / step) * step, n); + d[0] = Math.floor(start / step) * step; + d[i] = Math.ceil(stop / step) * step; + domain(d); } - } -} -function createCell(site) { - return cells[site.index] = { - site: site, - halfedges: [] + return scale; }; -} -function cellHalfedgeAngle(cell, edge) { - var site = cell.site, - va = edge.left, - vb = edge.right; - if (site === vb) vb = va, va = site; - if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]); - if (site === va) va = edge[1], vb = edge[0]; - else va = edge[0], vb = edge[1]; - return Math.atan2(va[0] - vb[0], vb[1] - va[1]); + return scale; } -function cellHalfedgeStart(cell, edge) { - return edge[+(edge.left !== cell.site)]; -} +function linear$2() { + var scale = continuous(deinterpolateLinear, reinterpolate); -function cellHalfedgeEnd(cell, edge) { - return edge[+(edge.left === cell.site)]; -} + scale.copy = function() { + return copy(scale, linear$2()); + }; -function sortCellHalfedges() { - for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) { - if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) { - var index = new Array(m), - array = new Array(m); - for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]); - index.sort(function(i, j) { return array[j] - array[i]; }); - for (j = 0; j < m; ++j) array[j] = halfedges[index[j]]; - for (j = 0; j < m; ++j) halfedges[j] = array[j]; - } - } + return linearish(scale); } -function clipCells(x0, y0, x1, y1) { - var nCells = cells.length, - iCell, - cell, - site, - iHalfedge, - halfedges, - nHalfedges, - start, - startX, - startY, - end, - endX, - endY, - cover = true; +function identity$6() { + var domain = [0, 1]; - for (iCell = 0; iCell < nCells; ++iCell) { - if (cell = cells[iCell]) { - site = cell.site; - halfedges = cell.halfedges; - iHalfedge = halfedges.length; + function scale(x) { + return +x; + } - // Remove any dangling clipped edges. - while (iHalfedge--) { - if (!edges[halfedges[iHalfedge]]) { - halfedges.splice(iHalfedge, 1); - } - } + scale.invert = scale; - // Insert any border edges as necessary. - iHalfedge = 0, nHalfedges = halfedges.length; - while (iHalfedge < nHalfedges) { - end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1]; - start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1]; - if (Math.abs(endX - startX) > epsilon$3 || Math.abs(endY - startY) > epsilon$3) { - halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end, - Math.abs(endX - x0) < epsilon$3 && y1 - endY > epsilon$3 ? [x0, Math.abs(startX - x0) < epsilon$3 ? startY : y1] - : Math.abs(endY - y1) < epsilon$3 && x1 - endX > epsilon$3 ? [Math.abs(startY - y1) < epsilon$3 ? startX : x1, y1] - : Math.abs(endX - x1) < epsilon$3 && endY - y0 > epsilon$3 ? [x1, Math.abs(startX - x1) < epsilon$3 ? startY : y0] - : Math.abs(endY - y0) < epsilon$3 && endX - x0 > epsilon$3 ? [Math.abs(startY - y0) < epsilon$3 ? startX : x0, y0] - : null)) - 1); - ++nHalfedges; - } - } + scale.domain = scale.range = function(_) { + return arguments.length ? (domain = map$3.call(_, number$1), scale) : domain.slice(); + }; - if (nHalfedges) cover = false; - } - } + scale.copy = function() { + return identity$6().domain(domain); + }; - // If there weren’t any edges, have the closest site cover the extent. - // It doesn’t matter which corner of the extent we measure! - if (cover) { - var dx, dy, d2, dc = Infinity; + return linearish(scale); +} - for (iCell = 0, cover = null; iCell < nCells; ++iCell) { - if (cell = cells[iCell]) { - site = cell.site; - dx = site[0] - x0; - dy = site[1] - y0; - d2 = dx * dx + dy * dy; - if (d2 < dc) dc = d2, cover = cell; - } - } +var nice = function(domain, interval) { + domain = domain.slice(); - if (cover) { - var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0]; - cover.halfedges.push( - edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1, - edges.push(createBorderEdge(site, v01, v11)) - 1, - edges.push(createBorderEdge(site, v11, v10)) - 1, - edges.push(createBorderEdge(site, v10, v00)) - 1 - ); - } - } + var i0 = 0, + i1 = domain.length - 1, + x0 = domain[i0], + x1 = domain[i1], + t; - // Lastly delete any cells with no edges; these were entirely clipped. - for (iCell = 0; iCell < nCells; ++iCell) { - if (cell = cells[iCell]) { - if (!cell.halfedges.length) { - delete cells[iCell]; - } - } + if (x1 < x0) { + t = i0, i0 = i1, i1 = t; + t = x0, x0 = x1, x1 = t; } -} -var circlePool = []; + domain[i0] = interval.floor(x0); + domain[i1] = interval.ceil(x1); + return domain; +}; -var firstCircle; +function deinterpolate(a, b) { + return (b = Math.log(b / a)) + ? function(x) { return Math.log(x / a) / b; } + : constant$9(b); +} -function Circle() { - RedBlackNode(this); - this.x = - this.y = - this.arc = - this.site = - this.cy = null; +function reinterpolate$1(a, b) { + return a < 0 + ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); } + : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); }; } -function attachCircle(arc) { - var lArc = arc.P, - rArc = arc.N; +function pow10(x) { + return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x; +} - if (!lArc || !rArc) return; +function powp(base) { + return base === 10 ? pow10 + : base === Math.E ? Math.exp + : function(x) { return Math.pow(base, x); }; +} - var lSite = lArc.site, - cSite = arc.site, - rSite = rArc.site; +function logp(base) { + return base === Math.E ? Math.log + : base === 10 && Math.log10 + || base === 2 && Math.log2 + || (base = Math.log(base), function(x) { return Math.log(x) / base; }); +} - if (lSite === rSite) return; +function reflect(f) { + return function(x) { + return -f(-x); + }; +} + +function log$1() { + var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]), + domain = scale.domain, + base = 10, + logs = logp(10), + pows = powp(10); - var bx = cSite[0], - by = cSite[1], - ax = lSite[0] - bx, - ay = lSite[1] - by, - cx = rSite[0] - bx, - cy = rSite[1] - by; + function rescale() { + logs = logp(base), pows = powp(base); + if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows); + return scale; + } - var d = 2 * (ax * cy - ay * cx); - if (d >= -epsilon2$1) return; + scale.base = function(_) { + return arguments.length ? (base = +_, rescale()) : base; + }; - var ha = ax * ax + ay * ay, - hc = cx * cx + cy * cy, - x = (cy * ha - ay * hc) / d, - y = (ax * hc - cx * ha) / d; + scale.domain = function(_) { + return arguments.length ? (domain(_), rescale()) : domain(); + }; - var circle = circlePool.pop() || new Circle; - circle.arc = arc; - circle.site = cSite; - circle.x = x + bx; - circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom + scale.ticks = function(count) { + var d = domain(), + u = d[0], + v = d[d.length - 1], + r; - arc.circle = circle; + if (r = v < u) i = u, u = v, v = i; - var before = null, - node = circles._; + var i = logs(u), + j = logs(v), + p, + k, + t, + n = count == null ? 10 : +count, + z = []; - while (node) { - if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) { - if (node.L) node = node.L; - else { before = node.P; break; } + if (!(base % 1) && j - i < n) { + i = Math.round(i) - 1, j = Math.round(j) + 1; + if (u > 0) for (; i < j; ++i) { + for (k = 1, p = pows(i); k < base; ++k) { + t = p * k; + if (t < u) continue; + if (t > v) break; + z.push(t); + } + } else for (; i < j; ++i) { + for (k = base - 1, p = pows(i); k >= 1; --k) { + t = p * k; + if (t < u) continue; + if (t > v) break; + z.push(t); + } + } } else { - if (node.R) node = node.R; - else { before = node; break; } + z = ticks(i, j, Math.min(j - i, n)).map(pows); } - } - circles.insert(before, circle); - if (!before) firstCircle = circle; -} + return r ? z.reverse() : z; + }; -function detachCircle(arc) { - var circle = arc.circle; - if (circle) { - if (!circle.P) firstCircle = circle.N; - circles.remove(circle); - circlePool.push(circle); - RedBlackNode(circle); - arc.circle = null; - } -} + scale.tickFormat = function(count, specifier) { + if (specifier == null) specifier = base === 10 ? ".0e" : ","; + if (typeof specifier !== "function") specifier = exports.format(specifier); + if (count === Infinity) return specifier; + if (count == null) count = 10; + var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate? + return function(d) { + var i = d / pows(Math.round(logs(d))); + if (i * base < base - 0.5) i *= base; + return i <= k ? specifier(d) : ""; + }; + }; -var beachPool = []; + scale.nice = function() { + return domain(nice(domain(), { + floor: function(x) { return pows(Math.floor(logs(x))); }, + ceil: function(x) { return pows(Math.ceil(logs(x))); } + })); + }; -function Beach() { - RedBlackNode(this); - this.edge = - this.site = - this.circle = null; -} + scale.copy = function() { + return copy(scale, log$1().base(base)); + }; -function createBeach(site) { - var beach = beachPool.pop() || new Beach; - beach.site = site; - return beach; + return scale; } -function detachBeach(beach) { - detachCircle(beach); - beaches.remove(beach); - beachPool.push(beach); - RedBlackNode(beach); +function raise$1(x, exponent) { + return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent); } -function removeBeach(beach) { - var circle = beach.circle, - x = circle.x, - y = circle.cy, - vertex = [x, y], - previous = beach.P, - next = beach.N, - disappearing = [beach]; - - detachBeach(beach); +function pow$1() { + var exponent = 1, + scale = continuous(deinterpolate, reinterpolate), + domain = scale.domain; - var lArc = previous; - while (lArc.circle - && Math.abs(x - lArc.circle.x) < epsilon$3 - && Math.abs(y - lArc.circle.cy) < epsilon$3) { - previous = lArc.P; - disappearing.unshift(lArc); - detachBeach(lArc); - lArc = previous; + function deinterpolate(a, b) { + return (b = raise$1(b, exponent) - (a = raise$1(a, exponent))) + ? function(x) { return (raise$1(x, exponent) - a) / b; } + : constant$9(b); } - disappearing.unshift(lArc); - detachCircle(lArc); - - var rArc = next; - while (rArc.circle - && Math.abs(x - rArc.circle.x) < epsilon$3 - && Math.abs(y - rArc.circle.cy) < epsilon$3) { - next = rArc.N; - disappearing.push(rArc); - detachBeach(rArc); - rArc = next; + function reinterpolate(a, b) { + b = raise$1(b, exponent) - (a = raise$1(a, exponent)); + return function(t) { return raise$1(a + b * t, 1 / exponent); }; } - disappearing.push(rArc); - detachCircle(rArc); + scale.exponent = function(_) { + return arguments.length ? (exponent = +_, domain(domain())) : exponent; + }; - var nArcs = disappearing.length, - iArc; - for (iArc = 1; iArc < nArcs; ++iArc) { - rArc = disappearing[iArc]; - lArc = disappearing[iArc - 1]; - setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); - } + scale.copy = function() { + return copy(scale, pow$1().exponent(exponent)); + }; - lArc = disappearing[0]; - rArc = disappearing[nArcs - 1]; - rArc.edge = createEdge(lArc.site, rArc.site, null, vertex); + return linearish(scale); +} - attachCircle(lArc); - attachCircle(rArc); +function sqrt$1() { + return pow$1().exponent(0.5); } -function addBeach(site) { - var x = site[0], - directrix = site[1], - lArc, - rArc, - dxl, - dxr, - node = beaches._; +function quantile$$1() { + var domain = [], + range$$1 = [], + thresholds = []; - while (node) { - dxl = leftBreakPoint(node, directrix) - x; - if (dxl > epsilon$3) node = node.L; else { - dxr = x - rightBreakPoint(node, directrix); - if (dxr > epsilon$3) { - if (!node.R) { - lArc = node; - break; - } - node = node.R; - } else { - if (dxl > -epsilon$3) { - lArc = node.P; - rArc = node; - } else if (dxr > -epsilon$3) { - lArc = node; - rArc = node.N; - } else { - lArc = rArc = node; - } - break; - } - } + function rescale() { + var i = 0, n = Math.max(1, range$$1.length); + thresholds = new Array(n - 1); + while (++i < n) thresholds[i - 1] = threshold(domain, i / n); + return scale; } - createCell(site); - var newArc = createBeach(site); - beaches.insert(lArc, newArc); + function scale(x) { + if (!isNaN(x = +x)) return range$$1[bisectRight(thresholds, x)]; + } - if (!lArc && !rArc) return; + scale.invertExtent = function(y) { + var i = range$$1.indexOf(y); + return i < 0 ? [NaN, NaN] : [ + i > 0 ? thresholds[i - 1] : domain[0], + i < thresholds.length ? thresholds[i] : domain[domain.length - 1] + ]; + }; - if (lArc === rArc) { - detachCircle(lArc); - rArc = createBeach(lArc.site); - beaches.insert(newArc, rArc); - newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site); - attachCircle(lArc); - attachCircle(rArc); - return; + scale.domain = function(_) { + if (!arguments.length) return domain.slice(); + domain = []; + for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d); + domain.sort(ascending); + return rescale(); + }; + + scale.range = function(_) { + return arguments.length ? (range$$1 = slice$4.call(_), rescale()) : range$$1.slice(); + }; + + scale.quantiles = function() { + return thresholds.slice(); + }; + + scale.copy = function() { + return quantile$$1() + .domain(domain) + .range(range$$1); + }; + + return scale; +} + +function quantize$1() { + var x0 = 0, + x1 = 1, + n = 1, + domain = [0.5], + range$$1 = [0, 1]; + + function scale(x) { + if (x <= x) return range$$1[bisectRight(domain, x, 0, n)]; } - if (!rArc) { // && lArc - newArc.edge = createEdge(lArc.site, newArc.site); - return; + function rescale() { + var i = -1; + domain = new Array(n); + while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1); + return scale; } - // else lArc !== rArc - detachCircle(lArc); - detachCircle(rArc); + scale.domain = function(_) { + return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1]; + }; - var lSite = lArc.site, - ax = lSite[0], - ay = lSite[1], - bx = site[0] - ax, - by = site[1] - ay, - rSite = rArc.site, - cx = rSite[0] - ax, - cy = rSite[1] - ay, - d = 2 * (bx * cy - by * cx), - hb = bx * bx + by * by, - hc = cx * cx + cy * cy, - vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay]; + scale.range = function(_) { + return arguments.length ? (n = (range$$1 = slice$4.call(_)).length - 1, rescale()) : range$$1.slice(); + }; - setEdgeEnd(rArc.edge, lSite, rSite, vertex); - newArc.edge = createEdge(lSite, site, null, vertex); - rArc.edge = createEdge(site, rSite, null, vertex); - attachCircle(lArc); - attachCircle(rArc); -} + scale.invertExtent = function(y) { + var i = range$$1.indexOf(y); + return i < 0 ? [NaN, NaN] + : i < 1 ? [x0, domain[0]] + : i >= n ? [domain[n - 1], x1] + : [domain[i - 1], domain[i]]; + }; -function leftBreakPoint(arc, directrix) { - var site = arc.site, - rfocx = site[0], - rfocy = site[1], - pby2 = rfocy - directrix; + scale.copy = function() { + return quantize$1() + .domain([x0, x1]) + .range(range$$1); + }; - if (!pby2) return rfocx; + return linearish(scale); +} - var lArc = arc.P; - if (!lArc) return -Infinity; +function threshold$1() { + var domain = [0.5], + range$$1 = [0, 1], + n = 1; - site = lArc.site; - var lfocx = site[0], - lfocy = site[1], - plby2 = lfocy - directrix; + function scale(x) { + if (x <= x) return range$$1[bisectRight(domain, x, 0, n)]; + } - if (!plby2) return lfocx; + scale.domain = function(_) { + return arguments.length ? (domain = slice$4.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice(); + }; - var hl = lfocx - rfocx, - aby2 = 1 / pby2 - 1 / plby2, - b = hl / plby2; + scale.range = function(_) { + return arguments.length ? (range$$1 = slice$4.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice(); + }; - if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; + scale.invertExtent = function(y) { + var i = range$$1.indexOf(y); + return [domain[i - 1], domain[i]]; + }; - return (rfocx + lfocx) / 2; -} + scale.copy = function() { + return threshold$1() + .domain(domain) + .range(range$$1); + }; -function rightBreakPoint(arc, directrix) { - var rArc = arc.N; - if (rArc) return leftBreakPoint(rArc, directrix); - var site = arc.site; - return site[1] === directrix ? site[0] : Infinity; + return scale; } -var epsilon$3 = 1e-6; -var epsilon2$1 = 1e-12; -var beaches; -var cells; -var circles; -var edges; +var t0$1 = new Date; +var t1$1 = new Date; -function triangleArea(a, b, c) { - return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]); -} +function newInterval(floori, offseti, count, field) { -function lexicographic(a, b) { - return b[1] - a[1] - || b[0] - a[0]; -} + function interval(date) { + return floori(date = new Date(+date)), date; + } -function Diagram(sites, extent) { - var site = sites.sort(lexicographic).pop(), - x, - y, - circle; + interval.floor = interval; - edges = []; - cells = new Array(sites.length); - beaches = new RedBlackTree; - circles = new RedBlackTree; + interval.ceil = function(date) { + return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date; + }; - while (true) { - circle = firstCircle; - if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) { - if (site[0] !== x || site[1] !== y) { - addBeach(site); - x = site[0], y = site[1]; - } - site = sites.pop(); - } else if (circle) { - removeBeach(circle.arc); - } else { - break; - } - } + interval.round = function(date) { + var d0 = interval(date), + d1 = interval.ceil(date); + return date - d0 < d1 - date ? d0 : d1; + }; - sortCellHalfedges(); + interval.offset = function(date, step) { + return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; + }; - if (extent) { - var x0 = +extent[0][0], - y0 = +extent[0][1], - x1 = +extent[1][0], - y1 = +extent[1][1]; - clipEdges(x0, y0, x1, y1); - clipCells(x0, y0, x1, y1); - } + interval.range = function(start, stop, step) { + var range = []; + start = interval.ceil(start); + step = step == null ? 1 : Math.floor(step); + if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date + do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop) + return range; + }; - this.edges = edges; - this.cells = cells; + interval.filter = function(test) { + return newInterval(function(date) { + if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); + }, function(date, step) { + if (date >= date) while (--step >= 0) while (offseti(date, 1), !test(date)) {} // eslint-disable-line no-empty + }); + }; - beaches = - circles = - edges = - cells = null; + if (count) { + interval.count = function(start, end) { + t0$1.setTime(+start), t1$1.setTime(+end); + floori(t0$1), floori(t1$1); + return Math.floor(count(t0$1, t1$1)); + }; + + interval.every = function(step) { + step = Math.floor(step); + return !isFinite(step) || !(step > 0) ? null + : !(step > 1) ? interval + : interval.filter(field + ? function(d) { return field(d) % step === 0; } + : function(d) { return interval.count(0, d) % step === 0; }); + }; + } + + return interval; } -Diagram.prototype = { - constructor: Diagram, +var millisecond = newInterval(function() { + // noop +}, function(date, step) { + date.setTime(+date + step); +}, function(start, end) { + return end - start; +}); - polygons: function() { - var edges = this.edges; +// An optimized implementation for this simple case. +millisecond.every = function(k) { + k = Math.floor(k); + if (!isFinite(k) || !(k > 0)) return null; + if (!(k > 1)) return millisecond; + return newInterval(function(date) { + date.setTime(Math.floor(date / k) * k); + }, function(date, step) { + date.setTime(+date + step * k); + }, function(start, end) { + return (end - start) / k; + }); +}; - return this.cells.map(function(cell) { - var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); }); - polygon.data = cell.site.data; - return polygon; - }); - }, +var milliseconds = millisecond.range; - triangles: function() { - var triangles = [], - edges = this.edges; +var durationSecond$1 = 1e3; +var durationMinute$1 = 6e4; +var durationHour$1 = 36e5; +var durationDay$1 = 864e5; +var durationWeek$1 = 6048e5; - this.cells.forEach(function(cell, i) { - var site = cell.site, - halfedges = cell.halfedges, - j = -1, - m = halfedges.length, - s0, - e1 = edges[halfedges[m - 1]], - s1 = e1.left === site ? e1.right : e1.left; +var second = newInterval(function(date) { + date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1); +}, function(date, step) { + date.setTime(+date + step * durationSecond$1); +}, function(start, end) { + return (end - start) / durationSecond$1; +}, function(date) { + return date.getUTCSeconds(); +}); + +var seconds = second.range; + +var minute = newInterval(function(date) { + date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1); +}, function(date, step) { + date.setTime(+date + step * durationMinute$1); +}, function(start, end) { + return (end - start) / durationMinute$1; +}, function(date) { + return date.getMinutes(); +}); - while (++j < m) { - s0 = s1; - e1 = edges[halfedges[j]]; - s1 = e1.left === site ? e1.right : e1.left; - if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) { - triangles.push([site.data, s0.data, s1.data]); - } - } - }); +var minutes = minute.range; - return triangles; - }, +var hour = newInterval(function(date) { + var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1; + if (offset < 0) offset += durationHour$1; + date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset); +}, function(date, step) { + date.setTime(+date + step * durationHour$1); +}, function(start, end) { + return (end - start) / durationHour$1; +}, function(date) { + return date.getHours(); +}); - links: function() { - return this.edges.filter(function(edge) { - return edge.right; - }).map(function(edge) { - return { - source: edge.left.data, - target: edge.right.data - }; - }); - }, +var hours = hour.range; - find: function(x, y, radius) { - var that = this, - i0, i1 = that._found || 0, - cell = that.cells[i1] || that.cells[i1 = 0], - dx = x - cell.site[0], - dy = y - cell.site[1], - d2 = dx * dx + dy * dy; +var day = newInterval(function(date) { + date.setHours(0, 0, 0, 0); +}, function(date, step) { + date.setDate(date.getDate() + step); +}, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1; +}, function(date) { + return date.getDate() - 1; +}); - do { - cell = that.cells[i0 = i1], i1 = null; - cell.halfedges.forEach(function(e) { - var edge = that.edges[e], v = edge.left; - if ((v === cell.site || !v) && !(v = edge.right)) return; - var vx = x - v[0], - vy = y - v[1], - v2 = vx * vx + vy * vy; - if (v2 < d2) d2 = v2, i1 = v.index; - }); - } while (i1 !== null); +var days = day.range; - that._found = i0; +function weekday(i) { + return newInterval(function(date) { + date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setDate(date.getDate() + step * 7); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1; + }); +} - return radius == null || d2 <= radius * radius ? cell.site : null; - } -}; +var sunday = weekday(0); +var monday = weekday(1); +var tuesday = weekday(2); +var wednesday = weekday(3); +var thursday = weekday(4); +var friday = weekday(5); +var saturday = weekday(6); -var voronoi = function() { - var x$$1 = x$4, - y$$1 = y$4, - extent = null; +var sundays = sunday.range; +var mondays = monday.range; +var tuesdays = tuesday.range; +var wednesdays = wednesday.range; +var thursdays = thursday.range; +var fridays = friday.range; +var saturdays = saturday.range; - function voronoi(data) { - return new Diagram(data.map(function(d, i) { - var s = [Math.round(x$$1(d, i, data) / epsilon$3) * epsilon$3, Math.round(y$$1(d, i, data) / epsilon$3) * epsilon$3]; - s.index = i; - s.data = d; - return s; - }), extent); - } +var month = newInterval(function(date) { + date.setDate(1); + date.setHours(0, 0, 0, 0); +}, function(date, step) { + date.setMonth(date.getMonth() + step); +}, function(start, end) { + return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; +}, function(date) { + return date.getMonth(); +}); - voronoi.polygons = function(data) { - return voronoi(data).polygons(); - }; +var months = month.range; - voronoi.links = function(data) { - return voronoi(data).links(); - }; +var year = newInterval(function(date) { + date.setMonth(0, 1); + date.setHours(0, 0, 0, 0); +}, function(date, step) { + date.setFullYear(date.getFullYear() + step); +}, function(start, end) { + return end.getFullYear() - start.getFullYear(); +}, function(date) { + return date.getFullYear(); +}); - voronoi.triangles = function(data) { - return voronoi(data).triangles(); - }; +// An optimized implementation for this simple case. +year.every = function(k) { + return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { + date.setFullYear(Math.floor(date.getFullYear() / k) * k); + date.setMonth(0, 1); + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setFullYear(date.getFullYear() + step * k); + }); +}; - voronoi.x = function(_) { - return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$9(+_), voronoi) : x$$1; - }; +var years = year.range; - voronoi.y = function(_) { - return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$9(+_), voronoi) : y$$1; - }; +var utcMinute = newInterval(function(date) { + date.setUTCSeconds(0, 0); +}, function(date, step) { + date.setTime(+date + step * durationMinute$1); +}, function(start, end) { + return (end - start) / durationMinute$1; +}, function(date) { + return date.getUTCMinutes(); +}); - voronoi.extent = function(_) { - return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]]; - }; +var utcMinutes = utcMinute.range; - voronoi.size = function(_) { - return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]]; - }; +var utcHour = newInterval(function(date) { + date.setUTCMinutes(0, 0, 0); +}, function(date, step) { + date.setTime(+date + step * durationHour$1); +}, function(start, end) { + return (end - start) / durationHour$1; +}, function(date) { + return date.getUTCHours(); +}); - return voronoi; -}; +var utcHours = utcHour.range; -var constant$10 = function(x) { - return function() { - return x; - }; -}; +var utcDay = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); +}, function(date, step) { + date.setUTCDate(date.getUTCDate() + step); +}, function(start, end) { + return (end - start) / durationDay$1; +}, function(date) { + return date.getUTCDate() - 1; +}); -function ZoomEvent(target, type, transform) { - this.target = target; - this.type = type; - this.transform = transform; -} +var utcDays = utcDay.range; -function Transform(k, x, y) { - this.k = k; - this.x = x; - this.y = y; +function utcWeekday(i) { + return newInterval(function(date) { + date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step * 7); + }, function(start, end) { + return (end - start) / durationWeek$1; + }); } -Transform.prototype = { - constructor: Transform, - scale: function(k) { - return k === 1 ? this : new Transform(this.k * k, this.x, this.y); - }, - translate: function(x, y) { - return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); - }, - apply: function(point) { - return [point[0] * this.k + this.x, point[1] * this.k + this.y]; - }, - applyX: function(x) { - return x * this.k + this.x; - }, - applyY: function(y) { - return y * this.k + this.y; - }, - invert: function(location) { - return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; - }, - invertX: function(x) { - return (x - this.x) / this.k; - }, - invertY: function(y) { - return (y - this.y) / this.k; - }, - rescaleX: function(x) { - return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); - }, - rescaleY: function(y) { - return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); - }, - toString: function() { - return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; - } -}; +var utcSunday = utcWeekday(0); +var utcMonday = utcWeekday(1); +var utcTuesday = utcWeekday(2); +var utcWednesday = utcWeekday(3); +var utcThursday = utcWeekday(4); +var utcFriday = utcWeekday(5); +var utcSaturday = utcWeekday(6); -var identity$6 = new Transform(1, 0, 0); +var utcSundays = utcSunday.range; +var utcMondays = utcMonday.range; +var utcTuesdays = utcTuesday.range; +var utcWednesdays = utcWednesday.range; +var utcThursdays = utcThursday.range; +var utcFridays = utcFriday.range; +var utcSaturdays = utcSaturday.range; -transform.prototype = Transform.prototype; +var utcMonth = newInterval(function(date) { + date.setUTCDate(1); + date.setUTCHours(0, 0, 0, 0); +}, function(date, step) { + date.setUTCMonth(date.getUTCMonth() + step); +}, function(start, end) { + return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; +}, function(date) { + return date.getUTCMonth(); +}); -function transform(node) { - return node.__zoom || identity$6; -} +var utcMonths = utcMonth.range; -function nopropagation$1() { - exports.event.stopImmediatePropagation(); -} +var utcYear = newInterval(function(date) { + date.setUTCMonth(0, 1); + date.setUTCHours(0, 0, 0, 0); +}, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step); +}, function(start, end) { + return end.getUTCFullYear() - start.getUTCFullYear(); +}, function(date) { + return date.getUTCFullYear(); +}); -var noevent$1 = function() { - exports.event.preventDefault(); - exports.event.stopImmediatePropagation(); +// An optimized implementation for this simple case. +utcYear.every = function(k) { + return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { + date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k); + date.setUTCMonth(0, 1); + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step * k); + }); }; -// Ignore right-click, since that should open the context menu. -function defaultFilter$1() { - return !exports.event.button; -} +var utcYears = utcYear.range; -function defaultExtent() { - var e = this, w, h; - if (e instanceof SVGElement) { - e = e.ownerSVGElement || e; - w = e.width.baseVal.value; - h = e.height.baseVal.value; - } else { - w = e.clientWidth; - h = e.clientHeight; +function localDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); + date.setFullYear(d.y); + return date; } - return [[0, 0], [w, h]]; + return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); } -function defaultTransform() { - return this.__zoom || identity$6; +function utcDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); + date.setUTCFullYear(d.y); + return date; + } + return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); } -var zoom = function() { - var filter = defaultFilter$1, - extent = defaultExtent, - k0 = 0, - k1 = Infinity, - x0 = -k1, - x1 = k1, - y0 = x0, - y1 = x1, - duration = 250, - interpolate$$1 = interpolateZoom, - gestures = [], - listeners = dispatch("start", "zoom", "end"), - touchstarting, - touchending, - touchDelay = 500, - wheelDelay = 150; +function newYear(y) { + return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; +} - function zoom(selection$$1) { - selection$$1 - .on("wheel.zoom", wheeled) - .on("mousedown.zoom", mousedowned) - .on("dblclick.zoom", dblclicked) - .on("touchstart.zoom", touchstarted) - .on("touchmove.zoom", touchmoved) - .on("touchend.zoom touchcancel.zoom", touchended) - .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") - .property("__zoom", defaultTransform); - } +function formatLocale$1(locale) { + var locale_dateTime = locale.dateTime, + locale_date = locale.date, + locale_time = locale.time, + locale_periods = locale.periods, + locale_weekdays = locale.days, + locale_shortWeekdays = locale.shortDays, + locale_months = locale.months, + locale_shortMonths = locale.shortMonths; - zoom.transform = function(collection, transform) { - var selection$$1 = collection.selection ? collection.selection() : collection; - selection$$1.property("__zoom", defaultTransform); - if (collection !== selection$$1) { - schedule(collection, transform); - } else { - selection$$1.interrupt().each(function() { - gesture(this, arguments) - .start() - .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform) - .end(); - }); - } - }; + var periodRe = formatRe(locale_periods), + periodLookup = formatLookup(locale_periods), + weekdayRe = formatRe(locale_weekdays), + weekdayLookup = formatLookup(locale_weekdays), + shortWeekdayRe = formatRe(locale_shortWeekdays), + shortWeekdayLookup = formatLookup(locale_shortWeekdays), + monthRe = formatRe(locale_months), + monthLookup = formatLookup(locale_months), + shortMonthRe = formatRe(locale_shortMonths), + shortMonthLookup = formatLookup(locale_shortMonths); - zoom.scaleBy = function(selection$$1, k) { - zoom.scaleTo(selection$$1, function() { - var k0 = this.__zoom.k, - k1 = typeof k === "function" ? k.apply(this, arguments) : k; - return k0 * k1; - }); + var formats = { + "a": formatShortWeekday, + "A": formatWeekday, + "b": formatShortMonth, + "B": formatMonth, + "c": null, + "d": formatDayOfMonth, + "e": formatDayOfMonth, + "H": formatHour24, + "I": formatHour12, + "j": formatDayOfYear, + "L": formatMilliseconds, + "m": formatMonthNumber, + "M": formatMinutes, + "p": formatPeriod, + "S": formatSeconds, + "U": formatWeekNumberSunday, + "w": formatWeekdayNumber, + "W": formatWeekNumberMonday, + "x": null, + "X": null, + "y": formatYear, + "Y": formatFullYear, + "Z": formatZone, + "%": formatLiteralPercent }; - zoom.scaleTo = function(selection$$1, k) { - zoom.transform(selection$$1, function() { - var e = extent.apply(this, arguments), - t0 = this.__zoom, - p0 = centroid(e), - p1 = t0.invert(p0), - k1 = typeof k === "function" ? k.apply(this, arguments) : k; - return constrain(translate(scale(t0, k1), p0, p1), e); - }); + var utcFormats = { + "a": formatUTCShortWeekday, + "A": formatUTCWeekday, + "b": formatUTCShortMonth, + "B": formatUTCMonth, + "c": null, + "d": formatUTCDayOfMonth, + "e": formatUTCDayOfMonth, + "H": formatUTCHour24, + "I": formatUTCHour12, + "j": formatUTCDayOfYear, + "L": formatUTCMilliseconds, + "m": formatUTCMonthNumber, + "M": formatUTCMinutes, + "p": formatUTCPeriod, + "S": formatUTCSeconds, + "U": formatUTCWeekNumberSunday, + "w": formatUTCWeekdayNumber, + "W": formatUTCWeekNumberMonday, + "x": null, + "X": null, + "y": formatUTCYear, + "Y": formatUTCFullYear, + "Z": formatUTCZone, + "%": formatLiteralPercent }; - zoom.translateBy = function(selection$$1, x, y) { - zoom.transform(selection$$1, function() { - return constrain(this.__zoom.translate( - typeof x === "function" ? x.apply(this, arguments) : x, - typeof y === "function" ? y.apply(this, arguments) : y - ), extent.apply(this, arguments)); - }); + var parses = { + "a": parseShortWeekday, + "A": parseWeekday, + "b": parseShortMonth, + "B": parseMonth, + "c": parseLocaleDateTime, + "d": parseDayOfMonth, + "e": parseDayOfMonth, + "H": parseHour24, + "I": parseHour24, + "j": parseDayOfYear, + "L": parseMilliseconds, + "m": parseMonthNumber, + "M": parseMinutes, + "p": parsePeriod, + "S": parseSeconds, + "U": parseWeekNumberSunday, + "w": parseWeekdayNumber, + "W": parseWeekNumberMonday, + "x": parseLocaleDate, + "X": parseLocaleTime, + "y": parseYear, + "Y": parseFullYear, + "Z": parseZone, + "%": parseLiteralPercent }; - function scale(transform, k) { - k = Math.max(k0, Math.min(k1, k)); - return k === transform.k ? transform : new Transform(k, transform.x, transform.y); - } - - function translate(transform, p0, p1) { - var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k; - return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); - } - - function constrain(transform, extent) { - var dx0 = transform.invertX(extent[0][0]) - x0, - dx1 = transform.invertX(extent[1][0]) - x1, - dy0 = transform.invertY(extent[0][1]) - y0, - dy1 = transform.invertY(extent[1][1]) - y1; - return transform.translate( - dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), - dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) - ); - } - - function centroid(extent) { - return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; - } - - function schedule(transition$$1, transform, center) { - transition$$1 - .on("start.zoom", function() { gesture(this, arguments).start(); }) - .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); }) - .tween("zoom", function() { - var that = this, - args = arguments, - g = gesture(that, args), - e = extent.apply(that, args), - p = center || centroid(e), - w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), - a = that.__zoom, - b = typeof transform === "function" ? transform.apply(that, args) : transform, - i = interpolate$$1(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); - return function(t) { - if (t === 1) t = b; // Avoid rounding error on end. - else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } - g.zoom(null, t); - }; - }); - } + // These recursive directive definitions must be deferred. + formats.x = newFormat(locale_date, formats); + formats.X = newFormat(locale_time, formats); + formats.c = newFormat(locale_dateTime, formats); + utcFormats.x = newFormat(locale_date, utcFormats); + utcFormats.X = newFormat(locale_time, utcFormats); + utcFormats.c = newFormat(locale_dateTime, utcFormats); - function gesture(that, args) { - for (var i = 0, n = gestures.length, g; i < n; ++i) { - if ((g = gestures[i]).that === that) { - return g; + function newFormat(specifier, formats) { + return function(date) { + var string = [], + i = -1, + j = 0, + n = specifier.length, + c, + pad, + format; + + if (!(date instanceof Date)) date = new Date(+date); + + while (++i < n) { + if (specifier.charCodeAt(i) === 37) { + string.push(specifier.slice(j, i)); + if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); + else pad = c === "e" ? " " : "0"; + if (format = formats[c]) c = format(date, pad); + string.push(c); + j = i + 1; + } } - } - return new Gesture(that, args); - } - function Gesture(that, args) { - this.that = that; - this.args = args; - this.index = -1; - this.active = 0; - this.extent = extent.apply(that, args); + string.push(specifier.slice(j, i)); + return string.join(""); + }; } - Gesture.prototype = { - start: function() { - if (++this.active === 1) { - this.index = gestures.push(this) - 1; - this.emit("start"); + function newParse(specifier, newDate) { + return function(string) { + var d = newYear(1900), + i = parseSpecifier(d, specifier, string += "", 0); + if (i != string.length) return null; + + // The am-pm flag is 0 for AM, and 1 for PM. + if ("p" in d) d.H = d.H % 12 + d.p * 12; + + // Convert day-of-week and week-of-year to day-of-year. + if ("W" in d || "U" in d) { + if (!("w" in d)) d.w = "W" in d ? 1 : 0; + var day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay(); + d.m = 0; + d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7; } - return this; - }, - zoom: function(key, transform) { - if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]); - if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]); - if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]); - this.that.__zoom = transform; - this.emit("zoom"); - return this; - }, - end: function() { - if (--this.active === 0) { - gestures.splice(this.index, 1); - this.index = -1; - this.emit("end"); + + // If a time zone is specified, all fields are interpreted as UTC and then + // offset according to the specified time zone. + if ("Z" in d) { + d.H += d.Z / 100 | 0; + d.M += d.Z % 100; + return utcDate(d); } - return this; - }, - emit: function(type) { - customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]); - } - }; - function wheeled() { - if (!filter.apply(this, arguments)) return; - var g = gesture(this, arguments), - t = this.__zoom, - k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500))), - p = mouse(this); + // Otherwise, all fields are in local time. + return newDate(d); + }; + } - // If the mouse is in the same location as before, reuse it. - // If there were recent wheel events, reset the wheel idle timeout. - if (g.wheel) { - if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { - g.mouse[1] = t.invert(g.mouse[0] = p); + function parseSpecifier(d, specifier, string, j) { + var i = 0, + n = specifier.length, + m = string.length, + c, + parse; + + while (i < n) { + if (j >= m) return -1; + c = specifier.charCodeAt(i++); + if (c === 37) { + c = specifier.charAt(i++); + parse = parses[c in pads ? specifier.charAt(i++) : c]; + if (!parse || ((j = parse(d, string, j)) < 0)) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; } - clearTimeout(g.wheel); } - // If this wheel event won’t trigger a transform change, ignore it. - else if (t.k === k) return; - - // Otherwise, capture the mouse point and location at the start. - else { - g.mouse = [p, t.invert(p)]; - interrupt(this); - g.start(); - } + return j; + } - noevent$1(); - g.wheel = setTimeout(wheelidled, wheelDelay); - g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent)); + function parsePeriod(d, string, i) { + var n = periodRe.exec(string.slice(i)); + return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } - function wheelidled() { - g.wheel = null; - g.end(); - } + function parseShortWeekday(d, string, i) { + var n = shortWeekdayRe.exec(string.slice(i)); + return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; } - function mousedowned() { - if (touchending || !filter.apply(this, arguments)) return; - var g = gesture(this, arguments), - v = select(exports.event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), - p = mouse(this); + function parseWeekday(d, string, i) { + var n = weekdayRe.exec(string.slice(i)); + return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } - dragDisable(exports.event.view); - nopropagation$1(); - g.mouse = [p, this.__zoom.invert(p)]; - interrupt(this); - g.start(); + function parseShortMonth(d, string, i) { + var n = shortMonthRe.exec(string.slice(i)); + return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } - function mousemoved() { - noevent$1(); - g.moved = true; - g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent)); - } + function parseMonth(d, string, i) { + var n = monthRe.exec(string.slice(i)); + return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } - function mouseupped() { - v.on("mousemove.zoom mouseup.zoom", null); - yesdrag(exports.event.view, g.moved); - noevent$1(); - g.end(); - } + function parseLocaleDateTime(d, string, i) { + return parseSpecifier(d, locale_dateTime, string, i); } - function dblclicked() { - if (!filter.apply(this, arguments)) return; - var t0 = this.__zoom, - p0 = mouse(this), - p1 = t0.invert(p0), - k1 = t0.k * (exports.event.shiftKey ? 0.5 : 2), - t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments)); + function parseLocaleDate(d, string, i) { + return parseSpecifier(d, locale_date, string, i); + } - noevent$1(); - if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0); - else select(this).call(zoom.transform, t1); + function parseLocaleTime(d, string, i) { + return parseSpecifier(d, locale_time, string, i); } - function touchstarted() { - if (!filter.apply(this, arguments)) return; - var g = gesture(this, arguments), - touches$$1 = exports.event.changedTouches, - n = touches$$1.length, i, t, p; + function formatShortWeekday(d) { + return locale_shortWeekdays[d.getDay()]; + } - nopropagation$1(); - for (i = 0; i < n; ++i) { - t = touches$$1[i], p = touch(this, touches$$1, t.identifier); - p = [p, this.__zoom.invert(p), t.identifier]; - if (!g.touch0) g.touch0 = p; - else if (!g.touch1) g.touch1 = p; - } + function formatWeekday(d) { + return locale_weekdays[d.getDay()]; + } - // If this is a dbltap, reroute to the (optional) dblclick.zoom handler. - if (touchstarting) { - touchstarting = clearTimeout(touchstarting); - if (!g.touch1) { - g.end(); - p = select(this).on("dblclick.zoom"); - if (p) p.apply(this, arguments); - return; - } - } + function formatShortMonth(d) { + return locale_shortMonths[d.getMonth()]; + } - if (exports.event.touches.length === n) { - touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); - interrupt(this); - g.start(); - } + function formatMonth(d) { + return locale_months[d.getMonth()]; } - function touchmoved() { - var g = gesture(this, arguments), - touches$$1 = exports.event.changedTouches, - n = touches$$1.length, i, t, p, l; + function formatPeriod(d) { + return locale_periods[+(d.getHours() >= 12)]; + } - noevent$1(); - if (touchstarting) touchstarting = clearTimeout(touchstarting); - for (i = 0; i < n; ++i) { - t = touches$$1[i], p = touch(this, touches$$1, t.identifier); - if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; - else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; - } - t = g.that.__zoom; - if (g.touch1) { - var p0 = g.touch0[0], l0 = g.touch0[1], - p1 = g.touch1[0], l1 = g.touch1[1], - dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, - dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; - t = scale(t, Math.sqrt(dp / dl)); - p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; - l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; - } - else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; - else return; - g.zoom("touch", constrain(translate(t, p, l), g.extent)); + function formatUTCShortWeekday(d) { + return locale_shortWeekdays[d.getUTCDay()]; } - function touchended() { - var g = gesture(this, arguments), - touches$$1 = exports.event.changedTouches, - n = touches$$1.length, i, t; + function formatUTCWeekday(d) { + return locale_weekdays[d.getUTCDay()]; + } - nopropagation$1(); - if (touchending) clearTimeout(touchending); - touchending = setTimeout(function() { touchending = null; }, touchDelay); - for (i = 0; i < n; ++i) { - t = touches$$1[i]; - if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; - else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; - } - if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; - if (!g.touch0) g.end(); + function formatUTCShortMonth(d) { + return locale_shortMonths[d.getUTCMonth()]; } - zoom.filter = function(_) { - return arguments.length ? (filter = typeof _ === "function" ? _ : constant$10(!!_), zoom) : filter; - }; + function formatUTCMonth(d) { + return locale_months[d.getUTCMonth()]; + } - zoom.extent = function(_) { - return arguments.length ? (extent = typeof _ === "function" ? _ : constant$10([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; - }; + function formatUTCPeriod(d) { + return locale_periods[+(d.getUTCHours() >= 12)]; + } - zoom.scaleExtent = function(_) { - return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1]; + return { + format: function(specifier) { + var f = newFormat(specifier += "", formats); + f.toString = function() { return specifier; }; + return f; + }, + parse: function(specifier) { + var p = newParse(specifier += "", localDate); + p.toString = function() { return specifier; }; + return p; + }, + utcFormat: function(specifier) { + var f = newFormat(specifier += "", utcFormats); + f.toString = function() { return specifier; }; + return f; + }, + utcParse: function(specifier) { + var p = newParse(specifier, utcDate); + p.toString = function() { return specifier; }; + return p; + } }; +} - zoom.translateExtent = function(_) { - return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]]; - }; +var pads = {"-": "", "_": " ", "0": "0"}; +var numberRe = /^\s*\d+/; +var percentRe = /^%/; +var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; - zoom.duration = function(_) { - return arguments.length ? (duration = +_, zoom) : duration; - }; +function pad(value, fill, width) { + var sign = value < 0 ? "-" : "", + string = (sign ? -value : value) + "", + length = string.length; + return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); +} - zoom.interpolate = function(_) { - return arguments.length ? (interpolate$$1 = _, zoom) : interpolate$$1; - }; +function requote(s) { + return s.replace(requoteRe, "\\$&"); +} - zoom.on = function() { - var value = listeners.on.apply(listeners, arguments); - return value === listeners ? zoom : value; - }; +function formatRe(names) { + return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); +} - return zoom; -}; +function formatLookup(names) { + var map = {}, i = -1, n = names.length; + while (++i < n) map[names[i].toLowerCase()] = i; + return map; +} -var constant$11 = function(x) { - return function() { - return x; - }; -}; +function parseWeekdayNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 1)); + return n ? (d.w = +n[0], i + n[0].length) : -1; +} -var BrushEvent = function(target, type, selection) { - this.target = target; - this.type = type; - this.selection = selection; -}; +function parseWeekNumberSunday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.U = +n[0], i + n[0].length) : -1; +} -function nopropagation$2() { - exports.event.stopImmediatePropagation(); +function parseWeekNumberMonday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.W = +n[0], i + n[0].length) : -1; } -var noevent$2 = function() { - exports.event.preventDefault(); - exports.event.stopImmediatePropagation(); -}; +function parseFullYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 4)); + return n ? (d.y = +n[0], i + n[0].length) : -1; +} -var MODE_DRAG = {name: "drag"}; -var MODE_SPACE = {name: "space"}; -var MODE_HANDLE = {name: "handle"}; -var MODE_CENTER = {name: "center"}; +function parseYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; +} -var X = { - name: "x", - handles: ["e", "w"].map(type$1), - input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; }, - output: function(xy) { return xy && [xy[0][0], xy[1][0]]; } -}; +function parseZone(d, string, i) { + var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6)); + return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1; +} -var Y = { - name: "y", - handles: ["n", "s"].map(type$1), - input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; }, - output: function(xy) { return xy && [xy[0][1], xy[1][1]]; } -}; +function parseMonthNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.m = n[0] - 1, i + n[0].length) : -1; +} -var XY = { - name: "xy", - handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type$1), - input: function(xy) { return xy; }, - output: function(xy) { return xy; } -}; +function parseDayOfMonth(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.d = +n[0], i + n[0].length) : -1; +} -var cursors = { - overlay: "crosshair", - selection: "move", - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" -}; +function parseDayOfYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; +} -var flipX = { - e: "w", - w: "e", - nw: "ne", - ne: "nw", - se: "sw", - sw: "se" -}; +function parseHour24(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.H = +n[0], i + n[0].length) : -1; +} -var flipY = { - n: "s", - s: "n", - nw: "sw", - ne: "se", - se: "ne", - sw: "nw" -}; +function parseMinutes(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.M = +n[0], i + n[0].length) : -1; +} -var signsX = { - overlay: +1, - selection: +1, - n: null, - e: +1, - s: null, - w: -1, - nw: -1, - ne: +1, - se: +1, - sw: -1 -}; +function parseSeconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.S = +n[0], i + n[0].length) : -1; +} -var signsY = { - overlay: +1, - selection: +1, - n: -1, - e: null, - s: +1, - w: null, - nw: -1, - ne: -1, - se: +1, - sw: +1 -}; +function parseMilliseconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.L = +n[0], i + n[0].length) : -1; +} -function type$1(t) { - return {type: t}; +function parseLiteralPercent(d, string, i) { + var n = percentRe.exec(string.slice(i, i + 1)); + return n ? i + n[0].length : -1; } -// Ignore right-click, since that should open the context menu. -function defaultFilter$2() { - return !exports.event.button; +function formatDayOfMonth(d, p) { + return pad(d.getDate(), p, 2); +} + +function formatHour24(d, p) { + return pad(d.getHours(), p, 2); +} + +function formatHour12(d, p) { + return pad(d.getHours() % 12 || 12, p, 2); +} + +function formatDayOfYear(d, p) { + return pad(1 + day.count(year(d), d), p, 3); +} + +function formatMilliseconds(d, p) { + return pad(d.getMilliseconds(), p, 3); +} + +function formatMonthNumber(d, p) { + return pad(d.getMonth() + 1, p, 2); } -function defaultExtent$1() { - var svg = this.ownerSVGElement || this; - return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]]; +function formatMinutes(d, p) { + return pad(d.getMinutes(), p, 2); } -// Like d3.local, but with the name “__brush” rather than auto-generated. -function local$1(node) { - while (!node.__brush) if (!(node = node.parentNode)) return; - return node.__brush; +function formatSeconds(d, p) { + return pad(d.getSeconds(), p, 2); } -function empty$1(extent) { - return extent[0][0] === extent[1][0] - || extent[0][1] === extent[1][1]; +function formatWeekNumberSunday(d, p) { + return pad(sunday.count(year(d), d), p, 2); } -function brushSelection(node) { - var state = node.__brush; - return state ? state.dim.output(state.selection) : null; +function formatWeekdayNumber(d) { + return d.getDay(); } -function brushX() { - return brush$1(X); +function formatWeekNumberMonday(d, p) { + return pad(monday.count(year(d), d), p, 2); } -function brushY() { - return brush$1(Y); +function formatYear(d, p) { + return pad(d.getFullYear() % 100, p, 2); } -var brush = function() { - return brush$1(XY); -}; +function formatFullYear(d, p) { + return pad(d.getFullYear() % 10000, p, 4); +} -function brush$1(dim) { - var extent = defaultExtent$1, - filter = defaultFilter$2, - listeners = dispatch(brush, "start", "brush", "end"), - handleSize = 6, - touchending; +function formatZone(d) { + var z = d.getTimezoneOffset(); + return (z > 0 ? "-" : (z *= -1, "+")) + + pad(z / 60 | 0, "0", 2) + + pad(z % 60, "0", 2); +} - function brush(group) { - var overlay = group - .property("__brush", initialize) - .selectAll(".overlay") - .data([type$1("overlay")]); +function formatUTCDayOfMonth(d, p) { + return pad(d.getUTCDate(), p, 2); +} - overlay.enter().append("rect") - .attr("class", "overlay") - .attr("pointer-events", "all") - .attr("cursor", cursors.overlay) - .merge(overlay) - .each(function() { - var extent = local$1(this).extent; - select(this) - .attr("x", extent[0][0]) - .attr("y", extent[0][1]) - .attr("width", extent[1][0] - extent[0][0]) - .attr("height", extent[1][1] - extent[0][1]); - }); +function formatUTCHour24(d, p) { + return pad(d.getUTCHours(), p, 2); +} - group.selectAll(".selection") - .data([type$1("selection")]) - .enter().append("rect") - .attr("class", "selection") - .attr("cursor", cursors.selection) - .attr("fill", "#777") - .attr("fill-opacity", 0.3) - .attr("stroke", "#fff") - .attr("shape-rendering", "crispEdges"); +function formatUTCHour12(d, p) { + return pad(d.getUTCHours() % 12 || 12, p, 2); +} - var handle = group.selectAll(".handle") - .data(dim.handles, function(d) { return d.type; }); +function formatUTCDayOfYear(d, p) { + return pad(1 + utcDay.count(utcYear(d), d), p, 3); +} - handle.exit().remove(); +function formatUTCMilliseconds(d, p) { + return pad(d.getUTCMilliseconds(), p, 3); +} - handle.enter().append("rect") - .attr("class", function(d) { return "handle handle--" + d.type; }) - .attr("cursor", function(d) { return cursors[d.type]; }); +function formatUTCMonthNumber(d, p) { + return pad(d.getUTCMonth() + 1, p, 2); +} - group - .each(redraw) - .attr("fill", "none") - .attr("pointer-events", "all") - .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") - .on("mousedown.brush touchstart.brush", started); - } +function formatUTCMinutes(d, p) { + return pad(d.getUTCMinutes(), p, 2); +} - brush.move = function(group, selection$$1) { - if (group.selection) { - group - .on("start.brush", function() { emitter(this, arguments).beforestart().start(); }) - .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); }) - .tween("brush", function() { - var that = this, - state = that.__brush, - emit = emitter(that, arguments), - selection0 = state.selection, - selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(this, arguments) : selection$$1, state.extent), - i = interpolate(selection0, selection1); +function formatUTCSeconds(d, p) { + return pad(d.getUTCSeconds(), p, 2); +} - function tween(t) { - state.selection = t === 1 && empty$1(selection1) ? null : i(t); - redraw.call(that); - emit.brush(); - } +function formatUTCWeekNumberSunday(d, p) { + return pad(utcSunday.count(utcYear(d), d), p, 2); +} - return selection0 && selection1 ? tween : tween(1); - }); - } else { - group - .each(function() { - var that = this, - args = arguments, - state = that.__brush, - selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(that, args) : selection$$1, state.extent), - emit = emitter(that, args).beforestart(); +function formatUTCWeekdayNumber(d) { + return d.getUTCDay(); +} - interrupt(that); - state.selection = selection1 == null || empty$1(selection1) ? null : selection1; - redraw.call(that); - emit.start().brush().end(); - }); - } - }; +function formatUTCWeekNumberMonday(d, p) { + return pad(utcMonday.count(utcYear(d), d), p, 2); +} - function redraw() { - var group = select(this), - selection$$1 = local$1(this).selection; +function formatUTCYear(d, p) { + return pad(d.getUTCFullYear() % 100, p, 2); +} - if (selection$$1) { - group.selectAll(".selection") - .style("display", null) - .attr("x", selection$$1[0][0]) - .attr("y", selection$$1[0][1]) - .attr("width", selection$$1[1][0] - selection$$1[0][0]) - .attr("height", selection$$1[1][1] - selection$$1[0][1]); +function formatUTCFullYear(d, p) { + return pad(d.getUTCFullYear() % 10000, p, 4); +} - group.selectAll(".handle") - .style("display", null) - .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handleSize / 2; }) - .attr("y", function(d) { return d.type[0] === "s" ? selection$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; }) - .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : handleSize; }) - .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : handleSize; }); - } +function formatUTCZone() { + return "+0000"; +} - else { - group.selectAll(".selection,.handle") - .style("display", "none") - .attr("x", null) - .attr("y", null) - .attr("width", null) - .attr("height", null); - } - } +function formatLiteralPercent() { + return "%"; +} - function emitter(that, args) { - return that.__brush.emitter || new Emitter(that, args); - } +var locale$2; - function Emitter(that, args) { - this.that = that; - this.args = args; - this.state = that.__brush; - this.active = 0; - } - Emitter.prototype = { - beforestart: function() { - if (++this.active === 1) this.state.emitter = this, this.starting = true; - return this; - }, - start: function() { - if (this.starting) this.starting = false, this.emit("start"); - return this; - }, - brush: function() { - this.emit("brush"); - return this; - }, - end: function() { - if (--this.active === 0) delete this.state.emitter, this.emit("end"); - return this; - }, - emit: function(type) { - customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]); - } - }; - function started() { - if (exports.event.touches) { if (exports.event.changedTouches.length < exports.event.touches.length) return noevent$2(); } - else if (touchending) return; - if (!filter.apply(this, arguments)) return; - var that = this, - type = exports.event.target.__data__.type, - mode = (exports.event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (exports.event.altKey ? MODE_CENTER : MODE_HANDLE), - signX = dim === Y ? null : signsX[type], - signY = dim === X ? null : signsY[type], - state = local$1(that), - extent = state.extent, - selection$$1 = state.selection, - W = extent[0][0], w0, w1, - N = extent[0][1], n0, n1, - E = extent[1][0], e0, e1, - S = extent[1][1], s0, s1, - dx, - dy, - moving, - shifting = signX && signY && exports.event.shiftKey, - lockX, - lockY, - point0 = mouse(that), - point = point0, - emit = emitter(that, arguments).beforestart(); - if (type === "overlay") { - state.selection = selection$$1 = [ - [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]], - [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0] - ]; - } else { - w0 = selection$$1[0][0]; - n0 = selection$$1[0][1]; - e0 = selection$$1[1][0]; - s0 = selection$$1[1][1]; - } +defaultLocale$1({ + dateTime: "%x, %X", + date: "%-m/%-d/%Y", + time: "%-I:%M:%S %p", + periods: ["AM", "PM"], + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] +}); - w1 = w0; - n1 = n0; - e1 = e0; - s1 = s0; +function defaultLocale$1(definition) { + locale$2 = formatLocale$1(definition); + exports.timeFormat = locale$2.format; + exports.timeParse = locale$2.parse; + exports.utcFormat = locale$2.utcFormat; + exports.utcParse = locale$2.utcParse; + return locale$2; +} - var group = select(that) - .attr("pointer-events", "none"); +var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; - var overlay = group.selectAll(".overlay") - .attr("cursor", cursors[type]); +function formatIsoNative(date) { + return date.toISOString(); +} - if (exports.event.touches) { - group - .on("touchmove.brush", moved, true) - .on("touchend.brush touchcancel.brush", ended, true); - } else { - var view = select(exports.event.view) - .on("keydown.brush", keydowned, true) - .on("keyup.brush", keyupped, true) - .on("mousemove.brush", moved, true) - .on("mouseup.brush", ended, true); +var formatIso = Date.prototype.toISOString + ? formatIsoNative + : exports.utcFormat(isoSpecifier); - dragDisable(exports.event.view); - } +function parseIsoNative(string) { + var date = new Date(string); + return isNaN(date) ? null : date; +} - nopropagation$2(); - interrupt(that); - redraw.call(that); - emit.start(); +var parseIso = +new Date("2000-01-01T00:00:00.000Z") + ? parseIsoNative + : exports.utcParse(isoSpecifier); - function moved() { - var point1 = mouse(that); - if (shifting && !lockX && !lockY) { - if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true; - else lockX = true; - } - point = point1; - moving = true; - noevent$2(); - move(); - } +var durationSecond = 1000; +var durationMinute = durationSecond * 60; +var durationHour = durationMinute * 60; +var durationDay = durationHour * 24; +var durationWeek = durationDay * 7; +var durationMonth = durationDay * 30; +var durationYear = durationDay * 365; - function move() { - var t; +function date$1(t) { + return new Date(t); +} - dx = point[0] - point0[0]; - dy = point[1] - point0[1]; +function number$2(t) { + return t instanceof Date ? +t : +new Date(+t); +} - switch (mode) { - case MODE_SPACE: - case MODE_DRAG: { - if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx; - if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy; - break; - } - case MODE_HANDLE: { - if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0; - else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx; - if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0; - else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy; - break; - } - case MODE_CENTER: { - if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX)); - if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY)); - break; - } - } +function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) { + var scale = continuous(deinterpolateLinear, reinterpolate), + invert = scale.invert, + domain = scale.domain; - if (e1 < w1) { - signX *= -1; - t = w0, w0 = e0, e0 = t; - t = w1, w1 = e1, e1 = t; - if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]); - } + var formatMillisecond = format(".%L"), + formatSecond = format(":%S"), + formatMinute = format("%I:%M"), + formatHour = format("%I %p"), + formatDay = format("%a %d"), + formatWeek = format("%b %d"), + formatMonth = format("%B"), + formatYear = format("%Y"); - if (s1 < n1) { - signY *= -1; - t = n0, n0 = s0, s0 = t; - t = n1, n1 = s1, s1 = t; - if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]); - } + var tickIntervals = [ + [second$$1, 1, durationSecond], + [second$$1, 5, 5 * durationSecond], + [second$$1, 15, 15 * durationSecond], + [second$$1, 30, 30 * durationSecond], + [minute$$1, 1, durationMinute], + [minute$$1, 5, 5 * durationMinute], + [minute$$1, 15, 15 * durationMinute], + [minute$$1, 30, 30 * durationMinute], + [ hour$$1, 1, durationHour ], + [ hour$$1, 3, 3 * durationHour ], + [ hour$$1, 6, 6 * durationHour ], + [ hour$$1, 12, 12 * durationHour ], + [ day$$1, 1, durationDay ], + [ day$$1, 2, 2 * durationDay ], + [ week, 1, durationWeek ], + [ month$$1, 1, durationMonth ], + [ month$$1, 3, 3 * durationMonth ], + [ year$$1, 1, durationYear ] + ]; - if (state.selection) selection$$1 = state.selection; // May be set by brush.move! - if (lockX) w1 = selection$$1[0][0], e1 = selection$$1[1][0]; - if (lockY) n1 = selection$$1[0][1], s1 = selection$$1[1][1]; + function tickFormat(date) { + return (second$$1(date) < date ? formatMillisecond + : minute$$1(date) < date ? formatSecond + : hour$$1(date) < date ? formatMinute + : day$$1(date) < date ? formatHour + : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek) + : year$$1(date) < date ? formatMonth + : formatYear)(date); + } - if (selection$$1[0][0] !== w1 - || selection$$1[0][1] !== n1 - || selection$$1[1][0] !== e1 - || selection$$1[1][1] !== s1) { - state.selection = [[w1, n1], [e1, s1]]; - redraw.call(that); - emit.brush(); - } - } + function tickInterval(interval, start, stop, step) { + if (interval == null) interval = 10; - function ended() { - nopropagation$2(); - if (exports.event.touches) { - if (exports.event.touches.length) return; - if (touchending) clearTimeout(touchending); - touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! - group.on("touchmove.brush touchend.brush touchcancel.brush", null); + // If a desired tick count is specified, pick a reasonable tick interval + // based on the extent of the domain and a rough estimate of tick size. + // Otherwise, assume interval is already a time interval and use it. + if (typeof interval === "number") { + var target = Math.abs(stop - start) / interval, + i = bisector(function(i) { return i[2]; }).right(tickIntervals, target); + if (i === tickIntervals.length) { + step = tickStep(start / durationYear, stop / durationYear, interval); + interval = year$$1; + } else if (i) { + i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i]; + step = i[1]; + interval = i[0]; } else { - yesdrag(exports.event.view, moving); - view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null); - } - group.attr("pointer-events", "all"); - overlay.attr("cursor", cursors.overlay); - if (state.selection) selection$$1 = state.selection; // May be set by brush.move (on start)! - if (empty$1(selection$$1)) state.selection = null, redraw.call(that); - emit.end(); - } - - function keydowned() { - switch (exports.event.keyCode) { - case 16: { // SHIFT - shifting = signX && signY; - break; - } - case 18: { // ALT - if (mode === MODE_HANDLE) { - if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; - if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; - mode = MODE_CENTER; - move(); - } - break; - } - case 32: { // SPACE; takes priority over ALT - if (mode === MODE_HANDLE || mode === MODE_CENTER) { - if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx; - if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy; - mode = MODE_SPACE; - overlay.attr("cursor", cursors.selection); - move(); - } - break; - } - default: return; + step = tickStep(start, stop, interval); + interval = millisecond$$1; } - noevent$2(); } - function keyupped() { - switch (exports.event.keyCode) { - case 16: { // SHIFT - if (shifting) { - lockX = lockY = shifting = false; - move(); - } - break; - } - case 18: { // ALT - if (mode === MODE_CENTER) { - if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; - if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; - mode = MODE_HANDLE; - move(); - } - break; - } - case 32: { // SPACE - if (mode === MODE_SPACE) { - if (exports.event.altKey) { - if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; - if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; - mode = MODE_CENTER; - } else { - if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; - if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; - mode = MODE_HANDLE; - } - overlay.attr("cursor", cursors[type]); - move(); - } - break; - } - default: return; - } - noevent$2(); - } + return step == null ? interval : interval.every(step); } - function initialize() { - var state = this.__brush || {selection: null}; - state.extent = extent.apply(this, arguments); - state.dim = dim; - return state; - } + scale.invert = function(y) { + return new Date(invert(y)); + }; - brush.extent = function(_) { - return arguments.length ? (extent = typeof _ === "function" ? _ : constant$11([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent; + scale.domain = function(_) { + return arguments.length ? domain(map$3.call(_, number$2)) : domain().map(date$1); + }; + + scale.ticks = function(interval, step) { + var d = domain(), + t0 = d[0], + t1 = d[d.length - 1], + r = t1 < t0, + t; + if (r) t = t0, t0 = t1, t1 = t; + t = tickInterval(interval, t0, t1, step); + t = t ? t.range(t0, t1 + 1) : []; // inclusive stop + return r ? t.reverse() : t; }; - brush.filter = function(_) { - return arguments.length ? (filter = typeof _ === "function" ? _ : constant$11(!!_), brush) : filter; + scale.tickFormat = function(count, specifier) { + return specifier == null ? tickFormat : format(specifier); }; - brush.handleSize = function(_) { - return arguments.length ? (handleSize = +_, brush) : handleSize; + scale.nice = function(interval, step) { + var d = domain(); + return (interval = tickInterval(interval, d[0], d[d.length - 1], step)) + ? domain(nice(d, interval)) + : scale; }; - brush.on = function() { - var value = listeners.on.apply(listeners, arguments); - return value === listeners ? brush : value; + scale.copy = function() { + return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format)); }; - return brush; + return scale; } -var cos = Math.cos; -var sin = Math.sin; -var pi$3 = Math.PI; -var halfPi$2 = pi$3 / 2; -var tau$3 = pi$3 * 2; -var max$1 = Math.max; +var time = function() { + return calendar(year, month, sunday, day, hour, minute, second, millisecond, exports.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]); +}; -function compareValue(compare) { - return function(a, b) { - return compare( - a.source.value + a.target.value, - b.source.value + b.target.value - ); - }; -} +var utcTime = function() { + return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, exports.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]); +}; -var chord = function() { - var padAngle = 0, - sortGroups = null, - sortSubgroups = null, - sortChords = null; +var colors = function(s) { + return s.match(/.{6}/g).map(function(x) { + return "#" + x; + }); +}; - function chord(matrix) { - var n = matrix.length, - groupSums = [], - groupIndex = range(n), - subgroupIndex = [], - chords = [], - groups = chords.groups = new Array(n), - subgroups = new Array(n * n), - k, - x, - x0, - dx, - i, - j; +var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"); - // Compute the sum. - k = 0, i = -1; while (++i < n) { - x = 0, j = -1; while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(range(n)); - k += x; - } +var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6"); - // Sort groups… - if (sortGroups) groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); +var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9"); - // Sort subgroups… - if (sortSubgroups) subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); +var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5"); - // Convert the sum to scaling factor for [0, 2pi]. - // TODO Allow start and end angle to be specified? - // TODO Allow padding to be specified as percentage? - k = max$1(0, tau$3 - padAngle * n) / k; - dx = k ? padAngle : tau$3 / n; +var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0)); - // Compute the start and end angle for each group and subgroup. - // Note: Opera has a bug reordering object literal properties! - x = 0, i = -1; while (++i < n) { - x0 = x, j = -1; while (++j < n) { - var di = groupIndex[i], - dj = subgroupIndex[di][j], - v = matrix[di][dj], - a0 = x, - a1 = x += v * k; - subgroups[dj * n + di] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: groupSums[di] - }; - x += dx; - } +var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8)); - // Generate chords for each (non-empty) subgroup-subgroup link. - i = -1; while (++i < n) { - j = i - 1; while (++j < n) { - var source = subgroups[j * n + i], - target = subgroups[i * n + j]; - if (source.value || target.value) { - chords.push(source.value < target.value - ? {source: target, target: source} - : {source: source, target: target}); - } - } - } +var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8)); - return sortChords ? chords.sort(sortChords) : chords; - } +var rainbow = cubehelix(); - chord.padAngle = function(_) { - return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle; +var rainbow$1 = function(t) { + if (t < 0 || t > 1) t -= Math.floor(t); + var ts = Math.abs(t - 0.5); + rainbow.h = 360 * t - 100; + rainbow.s = 1.5 - 1.5 * ts; + rainbow.l = 0.8 - 0.9 * ts; + return rainbow + ""; +}; + +function ramp(range) { + var n = range.length; + return function(t) { + return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))]; }; +} - chord.sortGroups = function(_) { - return arguments.length ? (sortGroups = _, chord) : sortGroups; +var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")); + +var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")); + +var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")); + +var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")); + +function sequential(interpolator) { + var x0 = 0, + x1 = 1, + clamp = false; + + function scale(x) { + var t = (x - x0) / (x1 - x0); + return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t); + } + + scale.domain = function(_) { + return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1]; }; - chord.sortSubgroups = function(_) { - return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups; + scale.clamp = function(_) { + return arguments.length ? (clamp = !!_, scale) : clamp; }; - chord.sortChords = function(_) { - return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._; + scale.interpolator = function(_) { + return arguments.length ? (interpolator = _, scale) : interpolator; }; - return chord; -}; + scale.copy = function() { + return sequential(interpolator).domain([x0, x1]).clamp(clamp); + }; -var slice$5 = Array.prototype.slice; + return linearish(scale); +} -var constant$12 = function(x) { - return function() { +var constant$10 = function(x) { + return function constant() { return x; }; }; -function defaultSource(d) { - return d.source; +var abs$1 = Math.abs; +var atan2$1 = Math.atan2; +var cos$2 = Math.cos; +var max$2 = Math.max; +var min$1 = Math.min; +var sin$2 = Math.sin; +var sqrt$2 = Math.sqrt; + +var epsilon$3 = 1e-12; +var pi$4 = Math.PI; +var halfPi$3 = pi$4 / 2; +var tau$4 = 2 * pi$4; + +function acos$1(x) { + return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x); } -function defaultTarget(d) { - return d.target; +function asin$1(x) { + return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x); } -function defaultRadius$1(d) { - return d.radius; +function arcInnerRadius(d) { + return d.innerRadius; } -function defaultStartAngle(d) { +function arcOuterRadius(d) { + return d.outerRadius; +} + +function arcStartAngle(d) { return d.startAngle; } -function defaultEndAngle(d) { +function arcEndAngle(d) { return d.endAngle; } -var ribbon = function() { - var source = defaultSource, - target = defaultTarget, - radius = defaultRadius$1, - startAngle = defaultStartAngle, - endAngle = defaultEndAngle, +function arcPadAngle(d) { + return d && d.padAngle; // Note: optional! +} + +function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { + var x10 = x1 - x0, y10 = y1 - y0, + x32 = x3 - x2, y32 = y3 - y2, + t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10); + return [x0 + t * x10, y0 + t * y10]; +} + +// Compute perpendicular offset line of length rc. +// http://mathworld.wolfram.com/Circle-LineIntersection.html +function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { + var x01 = x0 - x1, + y01 = y0 - y1, + lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01), + ox = lo * y01, + oy = -lo * x01, + x11 = x0 + ox, + y11 = y0 + oy, + x10 = x1 + ox, + y10 = y1 + oy, + x00 = (x11 + x10) / 2, + y00 = (y11 + y10) / 2, + dx = x10 - x11, + dy = y10 - y11, + d2 = dx * dx + dy * dy, + r = r1 - rc, + D = x11 * y10 - x10 * y11, + d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)), + cx0 = (D * dy - dx * d) / d2, + cy0 = (-D * dx - dy * d) / d2, + cx1 = (D * dy + dx * d) / d2, + cy1 = (-D * dx + dy * d) / d2, + dx0 = cx0 - x00, + dy0 = cy0 - y00, + dx1 = cx1 - x00, + dy1 = cy1 - y00; + + // Pick the closer of the two intersection points. + // TODO Is there a faster way to determine which intersection to use? + if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; + + return { + cx: cx0, + cy: cy0, + x01: -ox, + y01: -oy, + x11: cx0 * (r1 / r - 1), + y11: cy0 * (r1 / r - 1) + }; +} + +var arc = function() { + var innerRadius = arcInnerRadius, + outerRadius = arcOuterRadius, + cornerRadius = constant$10(0), + padRadius = null, + startAngle = arcStartAngle, + endAngle = arcEndAngle, + padAngle = arcPadAngle, context = null; - function ribbon() { + function arc() { var buffer, - argv = slice$5.call(arguments), - s = source.apply(this, argv), - t = target.apply(this, argv), - sr = +radius.apply(this, (argv[0] = s, argv)), - sa0 = startAngle.apply(this, argv) - halfPi$2, - sa1 = endAngle.apply(this, argv) - halfPi$2, - sx0 = sr * cos(sa0), - sy0 = sr * sin(sa0), - tr = +radius.apply(this, (argv[0] = t, argv)), - ta0 = startAngle.apply(this, argv) - halfPi$2, - ta1 = endAngle.apply(this, argv) - halfPi$2; + r, + r0 = +innerRadius.apply(this, arguments), + r1 = +outerRadius.apply(this, arguments), + a0 = startAngle.apply(this, arguments) - halfPi$3, + a1 = endAngle.apply(this, arguments) - halfPi$3, + da = abs$1(a1 - a0), + cw = a1 > a0; if (!context) context = buffer = path(); - context.moveTo(sx0, sy0); - context.arc(0, 0, sr, sa0, sa1); - if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr? - context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0)); - context.arc(0, 0, tr, ta0, ta1); + // Ensure that the outer radius is always larger than the inner radius. + if (r1 < r0) r = r1, r1 = r0, r0 = r; + + // Is it a point? + if (!(r1 > epsilon$3)) context.moveTo(0, 0); + + // Or is it a circle or annulus? + else if (da > tau$4 - epsilon$3) { + context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0)); + context.arc(0, 0, r1, a0, a1, !cw); + if (r0 > epsilon$3) { + context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1)); + context.arc(0, 0, r0, a1, a0, cw); + } } - context.quadraticCurveTo(0, 0, sx0, sy0); - context.closePath(); - if (buffer) return context = null, buffer + "" || null; - } + // Or is it a circular or annular sector? + else { + var a01 = a0, + a11 = a1, + a00 = a0, + a10 = a1, + da0 = da, + da1 = da, + ap = padAngle.apply(this, arguments) / 2, + rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)), + rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), + rc0 = rc, + rc1 = rc, + t0, + t1; - ribbon.radius = function(_) { - return arguments.length ? (radius = typeof _ === "function" ? _ : constant$12(+_), ribbon) : radius; - }; + // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. + if (rp > epsilon$3) { + var p0 = asin$1(rp / r0 * sin$2(ap)), + p1 = asin$1(rp / r1 * sin$2(ap)); + if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; + else da0 = 0, a00 = a10 = (a0 + a1) / 2; + if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; + else da1 = 0, a01 = a11 = (a0 + a1) / 2; + } - ribbon.startAngle = function(_) { - return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$12(+_), ribbon) : startAngle; - }; + var x01 = r1 * cos$2(a01), + y01 = r1 * sin$2(a01), + x10 = r0 * cos$2(a10), + y10 = r0 * sin$2(a10); - ribbon.endAngle = function(_) { - return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$12(+_), ribbon) : endAngle; - }; + // Apply rounded corners? + if (rc > epsilon$3) { + var x11 = r1 * cos$2(a11), + y11 = r1 * sin$2(a11), + x00 = r0 * cos$2(a00), + y00 = r0 * sin$2(a00); - ribbon.source = function(_) { - return arguments.length ? (source = _, ribbon) : source; - }; + // Restrict the corner radius according to the sector angle. + if (da < pi$4) { + var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10], + ax = x01 - oc[0], + ay = y01 - oc[1], + bx = x11 - oc[0], + by = y11 - oc[1], + kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2), + lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]); + rc0 = min$1(rc, (r0 - lc) / (kc - 1)); + rc1 = min$1(rc, (r1 - lc) / (kc + 1)); + } + } - ribbon.target = function(_) { - return arguments.length ? (target = _, ribbon) : target; - }; + // Is the sector collapsed to a line? + if (!(da1 > epsilon$3)) context.moveTo(x01, y01); - ribbon.context = function(_) { - return arguments.length ? ((context = _ == null ? null : _), ribbon) : context; - }; + // Does the sector’s outer ring have rounded corners? + else if (rc1 > epsilon$3) { + t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); + t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); - return ribbon; -}; + context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); -// Adds floating point numbers with twice the normal precision. -// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and -// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3) -// 305–363 (1997). -// Code adapted from GeographicLib by Charles F. F. Karney, -// http://geographiclib.sourceforge.net/ + // Have the corners merged? + if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw); -var adder = function() { - return new Adder; -}; + // Otherwise, draw the two corners and the ring. + else { + context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw); + context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw); + context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw); + } + } -function Adder() { - this.reset(); -} + // Or is the outer ring just a circular arc? + else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); -Adder.prototype = { - constructor: Adder, - reset: function() { - this.s = // rounded value - this.t = 0; // exact error - }, - add: function(y) { - add$1(temp, y, this.t); - add$1(this, temp.s, this.s); - if (this.s) this.t += temp.t; - else this.s = temp.t; - }, - valueOf: function() { - return this.s; - } -}; + // Is there no inner ring, and it’s a circular sector? + // Or perhaps it’s an annular sector collapsed due to padding? + if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10); -var temp = new Adder; + // Does the sector’s inner ring (or point) have rounded corners? + else if (rc0 > epsilon$3) { + t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); + t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); -function add$1(adder, a, b) { - var x = adder.s = a + b, - bv = x - a, - av = x - bv; - adder.t = (a - av) + (b - bv); -} + context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); -var epsilon$4 = 1e-6; -var epsilon2$2 = 1e-12; -var pi$4 = Math.PI; -var halfPi$3 = pi$4 / 2; -var quarterPi = pi$4 / 4; -var tau$4 = pi$4 * 2; + // Have the corners merged? + if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw); -var degrees$1 = 180 / pi$4; -var radians = pi$4 / 180; + // Otherwise, draw the two corners and the ring. + else { + context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw); + context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw); + context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw); + } + } -var abs = Math.abs; -var atan = Math.atan; -var atan2 = Math.atan2; -var cos$1 = Math.cos; -var ceil = Math.ceil; -var exp = Math.exp; + // Or is the inner ring just a circular arc? + else context.arc(0, 0, r0, a10, a00, cw); + } -var log$1 = Math.log; -var pow$1 = Math.pow; -var sin$1 = Math.sin; -var sign$1 = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }; -var sqrt$1 = Math.sqrt; -var tan = Math.tan; + context.closePath(); -function acos(x) { - return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x); -} + if (buffer) return context = null, buffer + "" || null; + } -function asin$1(x) { - return x > 1 ? halfPi$3 : x < -1 ? -halfPi$3 : Math.asin(x); -} + arc.centroid = function() { + var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, + a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2; + return [cos$2(a) * r, sin$2(a) * r]; + }; -function haversin(x) { - return (x = sin$1(x / 2)) * x; -} + arc.innerRadius = function(_) { + return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : innerRadius; + }; -function noop$2() {} + arc.outerRadius = function(_) { + return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : outerRadius; + }; -function streamGeometry(geometry, stream) { - if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) { - streamGeometryType[geometry.type](geometry, stream); - } -} + arc.cornerRadius = function(_) { + return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : cornerRadius; + }; -var streamObjectType = { - Feature: function(feature, stream) { - streamGeometry(feature.geometry, stream); - }, - FeatureCollection: function(object, stream) { - var features = object.features, i = -1, n = features.length; - while (++i < n) streamGeometry(features[i].geometry, stream); - } -}; + arc.padRadius = function(_) { + return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), arc) : padRadius; + }; -var streamGeometryType = { - Sphere: function(object, stream) { - stream.sphere(); - }, - Point: function(object, stream) { - object = object.coordinates; - stream.point(object[0], object[1], object[2]); - }, - MultiPoint: function(object, stream) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]); - }, - LineString: function(object, stream) { - streamLine(object.coordinates, stream, 0); - }, - MultiLineString: function(object, stream) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) streamLine(coordinates[i], stream, 0); - }, - Polygon: function(object, stream) { - streamPolygon(object.coordinates, stream); - }, - MultiPolygon: function(object, stream) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) streamPolygon(coordinates[i], stream); - }, - GeometryCollection: function(object, stream) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) streamGeometry(geometries[i], stream); - } -}; + arc.startAngle = function(_) { + return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : startAngle; + }; -function streamLine(coordinates, stream, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - stream.lineStart(); - while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]); - stream.lineEnd(); -} + arc.endAngle = function(_) { + return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : endAngle; + }; -function streamPolygon(coordinates, stream) { - var i = -1, n = coordinates.length; - stream.polygonStart(); - while (++i < n) streamLine(coordinates[i], stream, 1); - stream.polygonEnd(); -} + arc.padAngle = function(_) { + return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : padAngle; + }; -var geoStream = function(object, stream) { - if (object && streamObjectType.hasOwnProperty(object.type)) { - streamObjectType[object.type](object, stream); - } else { - streamGeometry(object, stream); - } -}; + arc.context = function(_) { + return arguments.length ? ((context = _ == null ? null : _), arc) : context; + }; -var areaRingSum = adder(); + return arc; +}; -var areaSum = adder(); -var lambda00; -var phi00; -var lambda0; -var cosPhi0; -var sinPhi0; +function Linear(context) { + this._context = context; +} -var areaStream = { - point: noop$2, - lineStart: noop$2, - lineEnd: noop$2, - polygonStart: function() { - areaRingSum.reset(); - areaStream.lineStart = areaRingStart; - areaStream.lineEnd = areaRingEnd; +Linear.prototype = { + areaStart: function() { + this._line = 0; }, - polygonEnd: function() { - var areaRing = +areaRingSum; - areaSum.add(areaRing < 0 ? tau$4 + areaRing : areaRing); - this.lineStart = this.lineEnd = this.point = noop$2; + areaEnd: function() { + this._line = NaN; }, - sphere: function() { - areaSum.add(tau$4); + lineStart: function() { + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; // proceed + default: this._context.lineTo(x, y); break; + } } }; -function areaRingStart() { - areaStream.point = areaPointFirst; -} +var curveLinear = function(context) { + return new Linear(context); +}; -function areaRingEnd() { - areaPoint(lambda00, phi00); +function x$3(p) { + return p[0]; } -function areaPointFirst(lambda, phi) { - areaStream.point = areaPoint; - lambda00 = lambda, phi00 = phi; - lambda *= radians, phi *= radians; - lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi); +function y$3(p) { + return p[1]; } -function areaPoint(lambda, phi) { - lambda *= radians, phi *= radians; - phi = phi / 2 + quarterPi; // half the angular distance from south pole +var line = function() { + var x$$1 = x$3, + y$$1 = y$3, + defined = constant$10(true), + context = null, + curve = curveLinear, + output = null; - // Spherical excess E for a spherical triangle with vertices: south pole, - // previous point, current point. Uses a formula derived from Cagnoli’s - // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2). - var dLambda = lambda - lambda0, - sdLambda = dLambda >= 0 ? 1 : -1, - adLambda = sdLambda * dLambda, - cosPhi = cos$1(phi), - sinPhi = sin$1(phi), - k = sinPhi0 * sinPhi, - u = cosPhi0 * cosPhi + k * cos$1(adLambda), - v = k * sdLambda * sin$1(adLambda); - areaRingSum.add(atan2(v, u)); + function line(data) { + var i, + n = data.length, + d, + defined0 = false, + buffer; - // Advance the previous points. - lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi; -} + if (context == null) output = curve(buffer = path()); -var area$2 = function(object) { - areaSum.reset(); - geoStream(object, areaStream); - return areaSum * 2; -}; + for (i = 0; i <= n; ++i) { + if (!(i < n && defined(d = data[i], i, data)) === defined0) { + if (defined0 = !defined0) output.lineStart(); + else output.lineEnd(); + } + if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data)); + } -function spherical(cartesian) { - return [atan2(cartesian[1], cartesian[0]), asin$1(cartesian[2])]; -} + if (buffer) return output = null, buffer + "" || null; + } -function cartesian(spherical) { - var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi); - return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)]; -} + line.x = function(_) { + return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : x$$1; + }; -function cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; -} + line.y = function(_) { + return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : y$$1; + }; -function cartesianCross(a, b) { - return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]; -} + line.defined = function(_) { + return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), line) : defined; + }; -// TODO return a -function cartesianAddInPlace(a, b) { - a[0] += b[0], a[1] += b[1], a[2] += b[2]; -} + line.curve = function(_) { + return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve; + }; -function cartesianScale(vector, k) { - return [vector[0] * k, vector[1] * k, vector[2] * k]; -} + line.context = function(_) { + return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; + }; -// TODO return d -function cartesianNormalizeInPlace(d) { - var l = sqrt$1(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l, d[1] /= l, d[2] /= l; -} + return line; +}; -var lambda0$1; -var phi0; -var lambda1; -var phi1; -var lambda2; -var lambda00$1; -var phi00$1; -var p0; -var deltaSum = adder(); -var ranges; -var range$1; +var area$2 = function() { + var x0 = x$3, + x1 = null, + y0 = constant$10(0), + y1 = y$3, + defined = constant$10(true), + context = null, + curve = curveLinear, + output = null; -var boundsStream = { - point: boundsPoint, - lineStart: boundsLineStart, - lineEnd: boundsLineEnd, - polygonStart: function() { - boundsStream.point = boundsRingPoint; - boundsStream.lineStart = boundsRingStart; - boundsStream.lineEnd = boundsRingEnd; - deltaSum.reset(); - areaStream.polygonStart(); - }, - polygonEnd: function() { - areaStream.polygonEnd(); - boundsStream.point = boundsPoint; - boundsStream.lineStart = boundsLineStart; - boundsStream.lineEnd = boundsLineEnd; - if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90); - else if (deltaSum > epsilon$4) phi1 = 90; - else if (deltaSum < -epsilon$4) phi0 = -90; - range$1[0] = lambda0$1, range$1[1] = lambda1; - } -}; + function area(data) { + var i, + j, + k, + n = data.length, + d, + defined0 = false, + buffer, + x0z = new Array(n), + y0z = new Array(n); -function boundsPoint(lambda, phi) { - ranges.push(range$1 = [lambda0$1 = lambda, lambda1 = lambda]); - if (phi < phi0) phi0 = phi; - if (phi > phi1) phi1 = phi; -} + if (context == null) output = curve(buffer = path()); -function linePoint(lambda, phi) { - var p = cartesian([lambda * radians, phi * radians]); - if (p0) { - var normal = cartesianCross(p0, p), - equatorial = [normal[1], -normal[0], 0], - inflection = cartesianCross(equatorial, normal); - cartesianNormalizeInPlace(inflection); - inflection = spherical(inflection); - var delta = lambda - lambda2, - sign$$1 = delta > 0 ? 1 : -1, - lambdai = inflection[0] * degrees$1 * sign$$1, - phii, - antimeridian = abs(delta) > 180; - if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) { - phii = inflection[1] * degrees$1; - if (phii > phi1) phi1 = phii; - } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) { - phii = -inflection[1] * degrees$1; - if (phii < phi0) phi0 = phii; - } else { - if (phi < phi0) phi0 = phi; - if (phi > phi1) phi1 = phi; - } - if (antimeridian) { - if (lambda < lambda2) { - if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; - } else { - if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; - } - } else { - if (lambda1 >= lambda0$1) { - if (lambda < lambda0$1) lambda0$1 = lambda; - if (lambda > lambda1) lambda1 = lambda; - } else { - if (lambda > lambda2) { - if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; + for (i = 0; i <= n; ++i) { + if (!(i < n && defined(d = data[i], i, data)) === defined0) { + if (defined0 = !defined0) { + j = i; + output.areaStart(); + output.lineStart(); } else { - if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; + output.lineEnd(); + output.lineStart(); + for (k = i - 1; k >= j; --k) { + output.point(x0z[k], y0z[k]); + } + output.lineEnd(); + output.areaEnd(); } } + if (defined0) { + x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data); + output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]); + } } - } else { - boundsPoint(lambda, phi); - } - p0 = p, lambda2 = lambda; -} -function boundsLineStart() { - boundsStream.point = linePoint; -} - -function boundsLineEnd() { - range$1[0] = lambda0$1, range$1[1] = lambda1; - boundsStream.point = boundsPoint; - p0 = null; -} - -function boundsRingPoint(lambda, phi) { - if (p0) { - var delta = lambda - lambda2; - deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta); - } else { - lambda00$1 = lambda, phi00$1 = phi; + if (buffer) return output = null, buffer + "" || null; } - areaStream.point(lambda, phi); - linePoint(lambda, phi); -} -function boundsRingStart() { - areaStream.lineStart(); -} + function arealine() { + return line().defined(defined).curve(curve).context(context); + } -function boundsRingEnd() { - boundsRingPoint(lambda00$1, phi00$1); - areaStream.lineEnd(); - if (abs(deltaSum) > epsilon$4) lambda0$1 = -(lambda1 = 180); - range$1[0] = lambda0$1, range$1[1] = lambda1; - p0 = null; -} + area.x = function(_) { + return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), x1 = null, area) : x0; + }; -// Finds the left-right distance between two longitudes. -// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want -// the distance between ±180° to be 360°. -function angle(lambda0, lambda1) { - return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1; -} + area.x0 = function(_) { + return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), area) : x0; + }; -function rangeCompare(a, b) { - return a[0] - b[0]; -} + area.x1 = function(_) { + return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : x1; + }; -function rangeContains(range, x) { - return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; -} + area.y = function(_) { + return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), y1 = null, area) : y0; + }; -var bounds = function(feature) { - var i, n, a, b, merged, deltaMax, delta; + area.y0 = function(_) { + return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), area) : y0; + }; - phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity); - ranges = []; - geoStream(feature, boundsStream); + area.y1 = function(_) { + return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : y1; + }; - // First, sort ranges by their minimum longitudes. - if (n = ranges.length) { - ranges.sort(rangeCompare); + area.lineX0 = + area.lineY0 = function() { + return arealine().x(x0).y(y0); + }; - // Then, merge any ranges that overlap. - for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) { - b = ranges[i]; - if (rangeContains(a, b[0]) || rangeContains(a, b[1])) { - if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; - if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; - } else { - merged.push(a = b); - } - } + area.lineY1 = function() { + return arealine().x(x0).y(y1); + }; - // Finally, find the largest gap between the merged ranges. - // The final bounding box will be the inverse of this gap. - for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) { - b = merged[i]; - if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1]; - } - } + area.lineX1 = function() { + return arealine().x(x1).y(y0); + }; - ranges = range$1 = null; + area.defined = function(_) { + return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), area) : defined; + }; - return lambda0$1 === Infinity || phi0 === Infinity - ? [[NaN, NaN], [NaN, NaN]] - : [[lambda0$1, phi0], [lambda1, phi1]]; -}; + area.curve = function(_) { + return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve; + }; -var W0; -var W1; -var X0; -var Y0; -var Z0; -var X1; -var Y1; -var Z1; -var X2; -var Y2; -var Z2; -var lambda00$2; -var phi00$2; -var x0; -var y0; -var z0; // previous point + area.context = function(_) { + return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context; + }; -var centroidStream = { - sphere: noop$2, - point: centroidPoint, - lineStart: centroidLineStart, - lineEnd: centroidLineEnd, - polygonStart: function() { - centroidStream.lineStart = centroidRingStart; - centroidStream.lineEnd = centroidRingEnd; - }, - polygonEnd: function() { - centroidStream.lineStart = centroidLineStart; - centroidStream.lineEnd = centroidLineEnd; - } + return area; }; -// Arithmetic mean of Cartesian vectors. -function centroidPoint(lambda, phi) { - lambda *= radians, phi *= radians; - var cosPhi = cos$1(phi); - centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)); -} - -function centroidPointCartesian(x, y, z) { - ++W0; - X0 += (x - X0) / W0; - Y0 += (y - Y0) / W0; - Z0 += (z - Z0) / W0; -} - -function centroidLineStart() { - centroidStream.point = centroidLinePointFirst; -} - -function centroidLinePointFirst(lambda, phi) { - lambda *= radians, phi *= radians; - var cosPhi = cos$1(phi); - x0 = cosPhi * cos$1(lambda); - y0 = cosPhi * sin$1(lambda); - z0 = sin$1(phi); - centroidStream.point = centroidLinePoint; - centroidPointCartesian(x0, y0, z0); -} - -function centroidLinePoint(lambda, phi) { - lambda *= radians, phi *= radians; - var cosPhi = cos$1(phi), - x = cosPhi * cos$1(lambda), - y = cosPhi * sin$1(lambda), - z = sin$1(phi), - w = atan2(sqrt$1((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); - W1 += w; - X1 += w * (x0 + (x0 = x)); - Y1 += w * (y0 + (y0 = y)); - Z1 += w * (z0 + (z0 = z)); - centroidPointCartesian(x0, y0, z0); -} - -function centroidLineEnd() { - centroidStream.point = centroidPoint; -} +var descending$1 = function(a, b) { + return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; +}; -// See J. E. Brock, The Inertia Tensor for a Spherical Triangle, -// J. Applied Mechanics 42, 239 (1975). -function centroidRingStart() { - centroidStream.point = centroidRingPointFirst; -} +var identity$7 = function(d) { + return d; +}; -function centroidRingEnd() { - centroidRingPoint(lambda00$2, phi00$2); - centroidStream.point = centroidPoint; -} +var pie = function() { + var value = identity$7, + sortValues = descending$1, + sort = null, + startAngle = constant$10(0), + endAngle = constant$10(tau$4), + padAngle = constant$10(0); -function centroidRingPointFirst(lambda, phi) { - lambda00$2 = lambda, phi00$2 = phi; - lambda *= radians, phi *= radians; - centroidStream.point = centroidRingPoint; - var cosPhi = cos$1(phi); - x0 = cosPhi * cos$1(lambda); - y0 = cosPhi * sin$1(lambda); - z0 = sin$1(phi); - centroidPointCartesian(x0, y0, z0); -} + function pie(data) { + var i, + n = data.length, + j, + k, + sum = 0, + index = new Array(n), + arcs = new Array(n), + a0 = +startAngle.apply(this, arguments), + da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)), + a1, + p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)), + pa = p * (da < 0 ? -1 : 1), + v; -function centroidRingPoint(lambda, phi) { - lambda *= radians, phi *= radians; - var cosPhi = cos$1(phi), - x = cosPhi * cos$1(lambda), - y = cosPhi * sin$1(lambda), - z = sin$1(phi), - cx = y0 * z - z0 * y, - cy = z0 * x - x0 * z, - cz = x0 * y - y0 * x, - m = sqrt$1(cx * cx + cy * cy + cz * cz), - u = x0 * x + y0 * y + z0 * z, - v = m && -acos(u) / m, // area weight - w = atan2(m, u); // line weight - X2 += v * cx; - Y2 += v * cy; - Z2 += v * cz; - W1 += w; - X1 += w * (x0 + (x0 = x)); - Y1 += w * (y0 + (y0 = y)); - Z1 += w * (z0 + (z0 = z)); - centroidPointCartesian(x0, y0, z0); -} + for (i = 0; i < n; ++i) { + if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) { + sum += v; + } + } -var centroid$1 = function(object) { - W0 = W1 = - X0 = Y0 = Z0 = - X1 = Y1 = Z1 = - X2 = Y2 = Z2 = 0; - geoStream(object, centroidStream); + // Optionally sort the arcs by previously-computed values or by data. + if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); }); + else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); }); - var x = X2, - y = Y2, - z = Z2, - m = x * x + y * y + z * z; + // Compute the arcs! They are stored in the original data's order. + for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) { + j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = { + data: data[j], + index: i, + value: v, + startAngle: a0, + endAngle: a1, + padAngle: p + }; + } - // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid. - if (m < epsilon2$2) { - x = X1, y = Y1, z = Z1; - // If the feature has zero length, fall back to arithmetic mean of point vectors. - if (W1 < epsilon$4) x = X0, y = Y0, z = Z0; - m = x * x + y * y + z * z; - // If the feature still has an undefined ccentroid, then return. - if (m < epsilon2$2) return [NaN, NaN]; + return arcs; } - return [atan2(y, x) * degrees$1, asin$1(z / sqrt$1(m)) * degrees$1]; -}; + pie.value = function(_) { + return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), pie) : value; + }; + + pie.sortValues = function(_) { + return arguments.length ? (sortValues = _, sort = null, pie) : sortValues; + }; -var constant$13 = function(x) { - return function() { - return x; + pie.sort = function(_) { + return arguments.length ? (sort = _, sortValues = null, pie) : sort; }; -}; -var compose = function(a, b) { + pie.startAngle = function(_) { + return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : startAngle; + }; - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } + pie.endAngle = function(_) { + return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : endAngle; + }; - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), x && a.invert(x[0], x[1]); + pie.padAngle = function(_) { + return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : padAngle; }; - return compose; + return pie; }; -function rotationIdentity(lambda, phi) { - return [lambda > pi$4 ? lambda - tau$4 : lambda < -pi$4 ? lambda + tau$4 : lambda, phi]; +var curveRadialLinear = curveRadial(curveLinear); + +function Radial(curve) { + this._curve = curve; } -rotationIdentity.invert = rotationIdentity; +Radial.prototype = { + areaStart: function() { + this._curve.areaStart(); + }, + areaEnd: function() { + this._curve.areaEnd(); + }, + lineStart: function() { + this._curve.lineStart(); + }, + lineEnd: function() { + this._curve.lineEnd(); + }, + point: function(a, r) { + this._curve.point(r * Math.sin(a), r * -Math.cos(a)); + } +}; -function rotateRadians(deltaLambda, deltaPhi, deltaGamma) { - return (deltaLambda %= tau$4) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma)) - : rotationLambda(deltaLambda)) - : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma) - : rotationIdentity); +function curveRadial(curve) { + + function radial(context) { + return new Radial(curve(context)); + } + + radial._curve = curve; + + return radial; } -function forwardRotationLambda(deltaLambda) { - return function(lambda, phi) { - return lambda += deltaLambda, [lambda > pi$4 ? lambda - tau$4 : lambda < -pi$4 ? lambda + tau$4 : lambda, phi]; +function radialLine(l) { + var c = l.curve; + + l.angle = l.x, delete l.x; + l.radius = l.y, delete l.y; + + l.curve = function(_) { + return arguments.length ? c(curveRadial(_)) : c()._curve; }; -} -function rotationLambda(deltaLambda) { - var rotation = forwardRotationLambda(deltaLambda); - rotation.invert = forwardRotationLambda(-deltaLambda); - return rotation; + return l; } -function rotationPhiGamma(deltaPhi, deltaGamma) { - var cosDeltaPhi = cos$1(deltaPhi), - sinDeltaPhi = sin$1(deltaPhi), - cosDeltaGamma = cos$1(deltaGamma), - sinDeltaGamma = sin$1(deltaGamma); +var radialLine$1 = function() { + return radialLine(line().curve(curveRadialLinear)); +}; - function rotation(lambda, phi) { - var cosPhi = cos$1(phi), - x = cos$1(lambda) * cosPhi, - y = sin$1(lambda) * cosPhi, - z = sin$1(phi), - k = z * cosDeltaPhi + x * sinDeltaPhi; - return [ - atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi), - asin$1(k * cosDeltaGamma + y * sinDeltaGamma) - ]; - } +var radialArea = function() { + var a = area$2().curve(curveRadialLinear), + c = a.curve, + x0 = a.lineX0, + x1 = a.lineX1, + y0 = a.lineY0, + y1 = a.lineY1; - rotation.invert = function(lambda, phi) { - var cosPhi = cos$1(phi), - x = cos$1(lambda) * cosPhi, - y = sin$1(lambda) * cosPhi, - z = sin$1(phi), - k = z * cosDeltaGamma - y * sinDeltaGamma; - return [ - atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi), - asin$1(k * cosDeltaPhi - x * sinDeltaPhi) - ]; + a.angle = a.x, delete a.x; + a.startAngle = a.x0, delete a.x0; + a.endAngle = a.x1, delete a.x1; + a.radius = a.y, delete a.y; + a.innerRadius = a.y0, delete a.y0; + a.outerRadius = a.y1, delete a.y1; + a.lineStartAngle = function() { return radialLine(x0()); }, delete a.lineX0; + a.lineEndAngle = function() { return radialLine(x1()); }, delete a.lineX1; + a.lineInnerRadius = function() { return radialLine(y0()); }, delete a.lineY0; + a.lineOuterRadius = function() { return radialLine(y1()); }, delete a.lineY1; + + a.curve = function(_) { + return arguments.length ? c(curveRadial(_)) : c()._curve; }; - return rotation; -} + return a; +}; -var rotation = function(rotate) { - rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0); +var circle$2 = { + draw: function(context, size) { + var r = Math.sqrt(size / pi$4); + context.moveTo(r, 0); + context.arc(0, 0, r, 0, tau$4); + } +}; - function forward(coordinates) { - coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians); - return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates; +var cross$2 = { + draw: function(context, size) { + var r = Math.sqrt(size / 5) / 2; + context.moveTo(-3 * r, -r); + context.lineTo(-r, -r); + context.lineTo(-r, -3 * r); + context.lineTo(r, -3 * r); + context.lineTo(r, -r); + context.lineTo(3 * r, -r); + context.lineTo(3 * r, r); + context.lineTo(r, r); + context.lineTo(r, 3 * r); + context.lineTo(-r, 3 * r); + context.lineTo(-r, r); + context.lineTo(-3 * r, r); + context.closePath(); } +}; - forward.invert = function(coordinates) { - coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians); - return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates; - }; +var tan30 = Math.sqrt(1 / 3); +var tan30_2 = tan30 * 2; - return forward; +var diamond = { + draw: function(context, size) { + var y = Math.sqrt(size / tan30_2), + x = y * tan30; + context.moveTo(0, -y); + context.lineTo(x, 0); + context.lineTo(0, y); + context.lineTo(-x, 0); + context.closePath(); + } }; -// Generates a circle centered at [0°, 0°], with a given radius and precision. -function circleStream(stream, radius, delta, direction, t0, t1) { - if (!delta) return; - var cosRadius = cos$1(radius), - sinRadius = sin$1(radius), - step = direction * delta; - if (t0 == null) { - t0 = radius + direction * tau$4; - t1 = radius - step / 2; - } else { - t0 = circleRadius(cosRadius, t0); - t1 = circleRadius(cosRadius, t1); - if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$4; +var ka = 0.89081309152928522810; +var kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10); +var kx = Math.sin(tau$4 / 10) * kr; +var ky = -Math.cos(tau$4 / 10) * kr; + +var star = { + draw: function(context, size) { + var r = Math.sqrt(size * ka), + x = kx * r, + y = ky * r; + context.moveTo(0, -r); + context.lineTo(x, y); + for (var i = 1; i < 5; ++i) { + var a = tau$4 * i / 5, + c = Math.cos(a), + s = Math.sin(a); + context.lineTo(s * r, -c * r); + context.lineTo(c * x - s * y, s * x + c * y); + } + context.closePath(); } - for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) { - point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]); - stream.point(point[0], point[1]); +}; + +var square = { + draw: function(context, size) { + var w = Math.sqrt(size), + x = -w / 2; + context.rect(x, x, w, w); } -} +}; -// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0]. -function circleRadius(cosRadius, point) { - point = cartesian(point), point[0] -= cosRadius; - cartesianNormalizeInPlace(point); - var radius = acos(-point[1]); - return ((-point[2] < 0 ? -radius : radius) + tau$4 - epsilon$4) % tau$4; -} +var sqrt3 = Math.sqrt(3); -var circle$1 = function() { - var center = constant$13([0, 0]), - radius = constant$13(90), - precision = constant$13(6), - ring, - rotate, - stream = {point: point}; +var triangle = { + draw: function(context, size) { + var y = -Math.sqrt(size / (sqrt3 * 3)); + context.moveTo(0, y * 2); + context.lineTo(-sqrt3 * y, -y); + context.lineTo(sqrt3 * y, -y); + context.closePath(); + } +}; + +var c = -0.5; +var s = Math.sqrt(3) / 2; +var k = 1 / Math.sqrt(12); +var a = (k / 2 + 1) * 3; + +var wye = { + draw: function(context, size) { + var r = Math.sqrt(size / a), + x0 = r / 2, + y0 = r * k, + x1 = x0, + y1 = r * k + r, + x2 = -x1, + y2 = y1; + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + context.lineTo(c * x0 - s * y0, s * x0 + c * y0); + context.lineTo(c * x1 - s * y1, s * x1 + c * y1); + context.lineTo(c * x2 - s * y2, s * x2 + c * y2); + context.lineTo(c * x0 + s * y0, c * y0 - s * x0); + context.lineTo(c * x1 + s * y1, c * y1 - s * x1); + context.lineTo(c * x2 + s * y2, c * y2 - s * x2); + context.closePath(); + } +}; + +var symbols = [ + circle$2, + cross$2, + diamond, + square, + star, + triangle, + wye +]; - function point(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= degrees$1, x[1] *= degrees$1; - } +var symbol = function() { + var type = constant$10(circle$2), + size = constant$10(64), + context = null; - function circle() { - var c = center.apply(this, arguments), - r = radius.apply(this, arguments) * radians, - p = precision.apply(this, arguments) * radians; - ring = []; - rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert; - circleStream(stream, r, p, 1); - c = {type: "Polygon", coordinates: [ring]}; - ring = rotate = null; - return c; + function symbol() { + var buffer; + if (!context) context = buffer = path(); + type.apply(this, arguments).draw(context, +size.apply(this, arguments)); + if (buffer) return context = null, buffer + "" || null; } - circle.center = function(_) { - return arguments.length ? (center = typeof _ === "function" ? _ : constant$13([+_[0], +_[1]]), circle) : center; + symbol.type = function(_) { + return arguments.length ? (type = typeof _ === "function" ? _ : constant$10(_), symbol) : type; }; - circle.radius = function(_) { - return arguments.length ? (radius = typeof _ === "function" ? _ : constant$13(+_), circle) : radius; + symbol.size = function(_) { + return arguments.length ? (size = typeof _ === "function" ? _ : constant$10(+_), symbol) : size; }; - circle.precision = function(_) { - return arguments.length ? (precision = typeof _ === "function" ? _ : constant$13(+_), circle) : precision; + symbol.context = function(_) { + return arguments.length ? (context = _ == null ? null : _, symbol) : context; }; - return circle; -}; - -var clipBuffer = function() { - var lines = [], - line; - return { - point: function(x, y) { - line.push([x, y]); - }, - lineStart: function() { - lines.push(line = []); - }, - lineEnd: noop$2, - rejoin: function() { - if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); - }, - result: function() { - var result = lines; - lines = []; - line = null; - return result; - } - }; + return symbol; }; -var clipLine = function(a, b, x0, y0, x1, y1) { - var ax = a[0], - ay = a[1], - bx = b[0], - by = b[1], - t0 = 0, - t1 = 1, - dx = bx - ax, - dy = by - ay, - r; - - r = x0 - ax; - if (!dx && r > 0) return; - r /= dx; - if (dx < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dx > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } +var noop$2 = function() {}; - r = x1 - ax; - if (!dx && r < 0) return; - r /= dx; - if (dx < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dx > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } +function point$2(that, x, y) { + that._context.bezierCurveTo( + (2 * that._x0 + that._x1) / 3, + (2 * that._y0 + that._y1) / 3, + (that._x0 + 2 * that._x1) / 3, + (that._y0 + 2 * that._y1) / 3, + (that._x0 + 4 * that._x1 + x) / 6, + (that._y0 + 4 * that._y1 + y) / 6 + ); +} - r = y0 - ay; - if (!dy && r > 0) return; - r /= dy; - if (dy < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dy > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } +function Basis(context) { + this._context = context; +} - r = y1 - ay; - if (!dy && r < 0) return; - r /= dy; - if (dy < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dy > 0) { - if (r < t0) return; - if (r < t1) t1 = r; +Basis.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = + this._y0 = this._y1 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 3: point$2(this, this._x1, this._y1); // proceed + case 2: this._context.lineTo(this._x1, this._y1); break; + } + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; break; + case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed + default: point$2(this, x, y); break; + } + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; } - - if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy; - if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy; - return true; }; -var pointEqual = function(a, b) { - return abs(a[0] - b[0]) < epsilon$4 && abs(a[1] - b[1]) < epsilon$4; +var basis$2 = function(context) { + return new Basis(context); }; -function Intersection(point, points, other, entry) { - this.x = point; - this.z = points; - this.o = other; // another intersection - this.e = entry; // is an entry? - this.v = false; // visited - this.n = this.p = null; // next & previous +function BasisClosed(context) { + this._context = context; } -// A generalized polygon clipping algorithm: given a polygon that has been cut -// into its visible line segments, and rejoins the segments by interpolating -// along the clip edge. -var clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) { - var subject = [], - clip = [], - i, - n; - - segments.forEach(function(segment) { - if ((n = segment.length - 1) <= 0) return; - var n, p0 = segment[0], p1 = segment[n], x; - - // If the first and last points of a segment are coincident, then treat as a - // closed ring. TODO if all rings are closed, then the winding order of the - // exterior ring should be checked. - if (pointEqual(p0, p1)) { - stream.lineStart(); - for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]); - stream.lineEnd(); - return; - } - - subject.push(x = new Intersection(p0, segment, null, true)); - clip.push(x.o = new Intersection(p0, null, x, false)); - subject.push(x = new Intersection(p1, segment, null, false)); - clip.push(x.o = new Intersection(p1, null, x, true)); - }); - - if (!subject.length) return; - - clip.sort(compareIntersection); - link$1(subject); - link$1(clip); - - for (i = 0, n = clip.length; i < n; ++i) { - clip[i].e = startInside = !startInside; - } - - var start = subject[0], - points, - point; - - while (1) { - // Find first unvisited intersection. - var current = start, - isSubject = true; - while (current.v) if ((current = current.n) === start) return; - points = current.z; - stream.lineStart(); - do { - current.v = current.o.v = true; - if (current.e) { - if (isSubject) { - for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.n.x, 1, stream); - } - current = current.n; - } else { - if (isSubject) { - points = current.p.z; - for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.p.x, -1, stream); - } - current = current.p; +BasisClosed.prototype = { + areaStart: noop$2, + areaEnd: noop$2, + lineStart: function() { + this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = + this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 1: { + this._context.moveTo(this._x2, this._y2); + this._context.closePath(); + break; } - current = current.o; - points = current.z; - isSubject = !isSubject; - } while (!current.v); - stream.lineEnd(); + case 2: { + this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3); + this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3); + this._context.closePath(); + break; + } + case 3: { + this.point(this._x2, this._y2); + this.point(this._x3, this._y3); + this.point(this._x4, this._y4); + break; + } + } + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._x2 = x, this._y2 = y; break; + case 1: this._point = 2; this._x3 = x, this._y3 = y; break; + case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break; + default: point$2(this, x, y); break; + } + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; } }; -function link$1(array) { - if (!(n = array.length)) return; - var n, - i = 0, - a = array[0], - b; - while (++i < n) { - a.n = b = array[i]; - b.p = a; - a = b; - } - a.n = b = array[0]; - b.p = a; -} - -var clipMax = 1e9; -var clipMin = -clipMax; - -// TODO Use d3-polygon’s polygonContains here for the ring check? -// TODO Eliminate duplicate buffering in clipBuffer and polygon.push? - -function clipExtent(x0, y0, x1, y1) { +var basisClosed$1 = function(context) { + return new BasisClosed(context); +}; - function visible(x, y) { - return x0 <= x && x <= x1 && y0 <= y && y <= y1; - } +function BasisOpen(context) { + this._context = context; +} - function interpolate(from, to, direction, stream) { - var a = 0, a1 = 0; - if (from == null - || (a = corner(from, direction)) !== (a1 = corner(to, direction)) - || comparePoint(from, to) < 0 ^ direction > 0) { - do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); - while ((a = (a + direction + 4) % 4) !== a1); - } else { - stream.point(to[0], to[1]); +BasisOpen.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = + this._y0 = this._y1 = NaN; + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; break; + case 1: this._point = 2; break; + case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break; + case 3: this._point = 4; // proceed + default: point$2(this, x, y); break; } + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; } +}; - function corner(p, direction) { - return abs(p[0] - x0) < epsilon$4 ? direction > 0 ? 0 : 3 - : abs(p[0] - x1) < epsilon$4 ? direction > 0 ? 2 : 1 - : abs(p[1] - y0) < epsilon$4 ? direction > 0 ? 1 : 0 - : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon - } - - function compareIntersection(a, b) { - return comparePoint(a.x, b.x); - } +var basisOpen = function(context) { + return new BasisOpen(context); +}; - function comparePoint(a, b) { - var ca = corner(a, 1), - cb = corner(b, 1); - return ca !== cb ? ca - cb - : ca === 0 ? b[1] - a[1] - : ca === 1 ? a[0] - b[0] - : ca === 2 ? a[1] - b[1] - : b[0] - a[0]; - } +function Bundle(context, beta) { + this._basis = new Basis(context); + this._beta = beta; +} - return function(stream) { - var activeStream = stream, - bufferStream = clipBuffer(), - segments, - polygon, - ring, - x__, y__, v__, // first point - x_, y_, v_, // previous point - first, - clean; +Bundle.prototype = { + lineStart: function() { + this._x = []; + this._y = []; + this._basis.lineStart(); + }, + lineEnd: function() { + var x = this._x, + y = this._y, + j = x.length - 1; - var clipStream = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: polygonStart, - polygonEnd: polygonEnd - }; + if (j > 0) { + var x0 = x[0], + y0 = y[0], + dx = x[j] - x0, + dy = y[j] - y0, + i = -1, + t; - function point(x, y) { - if (visible(x, y)) activeStream.point(x, y); + while (++i <= j) { + t = i / j; + this._basis.point( + this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), + this._beta * y[i] + (1 - this._beta) * (y0 + t * dy) + ); + } } - function polygonInside() { - var winding = 0; + this._x = this._y = null; + this._basis.lineEnd(); + }, + point: function(x, y) { + this._x.push(+x); + this._y.push(+y); + } +}; - for (var i = 0, n = polygon.length; i < n; ++i) { - for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) { - a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1]; - if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; } - else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; } - } - } +var bundle = ((function custom(beta) { - return winding; - } + function bundle(context) { + return beta === 1 ? new Basis(context) : new Bundle(context, beta); + } - // Buffer geometry within a polygon and then clip it en masse. - function polygonStart() { - activeStream = bufferStream, segments = [], polygon = [], clean = true; - } + bundle.beta = function(beta) { + return custom(+beta); + }; - function polygonEnd() { - var startInside = polygonInside(), - cleanInside = clean && startInside, - visible = (segments = merge(segments)).length; - if (cleanInside || visible) { - stream.polygonStart(); - if (cleanInside) { - stream.lineStart(); - interpolate(null, null, 1, stream); - stream.lineEnd(); - } - if (visible) { - clipPolygon(segments, compareIntersection, startInside, interpolate, stream); - } - stream.polygonEnd(); - } - activeStream = stream, segments = polygon = ring = null; - } + return bundle; +}))(0.85); - function lineStart() { - clipStream.point = linePoint; - if (polygon) polygon.push(ring = []); - first = true; - v_ = false; - x_ = y_ = NaN; - } +function point$3(that, x, y) { + that._context.bezierCurveTo( + that._x1 + that._k * (that._x2 - that._x0), + that._y1 + that._k * (that._y2 - that._y0), + that._x2 + that._k * (that._x1 - x), + that._y2 + that._k * (that._y1 - y), + that._x2, + that._y2 + ); +} - // TODO rather than special-case polygons, simply handle them separately. - // Ideally, coincident intersection points should be jittered to avoid - // clipping issues. - function lineEnd() { - if (segments) { - linePoint(x__, y__); - if (v__ && v_) bufferStream.rejoin(); - segments.push(bufferStream.result()); - } - clipStream.point = point; - if (v_) activeStream.lineEnd(); - } +function Cardinal(context, tension) { + this._context = context; + this._k = (1 - tension) / 6; +} - function linePoint(x, y) { - var v = visible(x, y); - if (polygon) ring.push([x, y]); - if (first) { - x__ = x, y__ = y, v__ = v; - first = false; - if (v) { - activeStream.lineStart(); - activeStream.point(x, y); - } - } else { - if (v && v_) activeStream.point(x, y); - else { - var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))], - b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))]; - if (clipLine(a, b, x0, y0, x1, y1)) { - if (!v_) { - activeStream.lineStart(); - activeStream.point(a[0], a[1]); - } - activeStream.point(b[0], b[1]); - if (!v) activeStream.lineEnd(); - clean = false; - } else if (v) { - activeStream.lineStart(); - activeStream.point(x, y); - clean = false; - } - } - } - x_ = x, y_ = y, v_ = v; +Cardinal.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = this._x2 = + this._y0 = this._y1 = this._y2 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 2: this._context.lineTo(this._x2, this._y2); break; + case 3: point$3(this, this._x1, this._y1); break; + } + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; this._x1 = x, this._y1 = y; break; + case 2: this._point = 3; // proceed + default: point$3(this, x, y); break; } + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } +}; - return clipStream; - }; -} +var cardinal = ((function custom(tension) { -var extent$1 = function() { - var x0 = 0, - y0 = 0, - x1 = 960, - y1 = 500, - cache, - cacheStream, - clip; + function cardinal(context) { + return new Cardinal(context, tension); + } - return clip = { - stream: function(stream) { - return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream); - }, - extent: function(_) { - return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]]; - } + cardinal.tension = function(tension) { + return custom(+tension); }; -}; -var lengthSum = adder(); -var lambda0$2; -var sinPhi0$1; -var cosPhi0$1; + return cardinal; +}))(0); -var lengthStream = { - sphere: noop$2, - point: noop$2, - lineStart: lengthLineStart, - lineEnd: noop$2, - polygonStart: noop$2, - polygonEnd: noop$2 +function CardinalClosed(context, tension) { + this._context = context; + this._k = (1 - tension) / 6; +} + +CardinalClosed.prototype = { + areaStart: noop$2, + areaEnd: noop$2, + lineStart: function() { + this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = + this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 1: { + this._context.moveTo(this._x3, this._y3); + this._context.closePath(); + break; + } + case 2: { + this._context.lineTo(this._x3, this._y3); + this._context.closePath(); + break; + } + case 3: { + this.point(this._x3, this._y3); + this.point(this._x4, this._y4); + this.point(this._x5, this._y5); + break; + } + } + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._x3 = x, this._y3 = y; break; + case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; + case 2: this._point = 3; this._x5 = x, this._y5 = y; break; + default: point$3(this, x, y); break; + } + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } }; -function lengthLineStart() { - lengthStream.point = lengthPointFirst; - lengthStream.lineEnd = lengthLineEnd; -} +var cardinalClosed = ((function custom(tension) { -function lengthLineEnd() { - lengthStream.point = lengthStream.lineEnd = noop$2; -} + function cardinal(context) { + return new CardinalClosed(context, tension); + } -function lengthPointFirst(lambda, phi) { - lambda *= radians, phi *= radians; - lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi); - lengthStream.point = lengthPoint; -} + cardinal.tension = function(tension) { + return custom(+tension); + }; -function lengthPoint(lambda, phi) { - lambda *= radians, phi *= radians; - var sinPhi = sin$1(phi), - cosPhi = cos$1(phi), - delta = abs(lambda - lambda0$2), - cosDelta = cos$1(delta), - sinDelta = sin$1(delta), - x = cosPhi * sinDelta, - y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta, - z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta; - lengthSum.add(atan2(sqrt$1(x * x + y * y), z)); - lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi; + return cardinal; +}))(0); + +function CardinalOpen(context, tension) { + this._context = context; + this._k = (1 - tension) / 6; } -var length$2 = function(object) { - lengthSum.reset(); - geoStream(object, lengthStream); - return +lengthSum; +CardinalOpen.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = this._x2 = + this._y0 = this._y1 = this._y2 = NaN; + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; break; + case 1: this._point = 2; break; + case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; + case 3: this._point = 4; // proceed + default: point$3(this, x, y); break; + } + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } }; -var coordinates = [null, null]; -var object$1 = {type: "LineString", coordinates: coordinates}; +var cardinalOpen = ((function custom(tension) { -var distance = function(a, b) { - coordinates[0] = a; - coordinates[1] = b; - return length$2(object$1); -}; + function cardinal(context) { + return new CardinalOpen(context, tension); + } -function graticuleX(y0, y1, dy) { - var y = range(y0, y1 - epsilon$4, dy).concat(y1); - return function(x) { return y.map(function(y) { return [x, y]; }); }; -} + cardinal.tension = function(tension) { + return custom(+tension); + }; -function graticuleY(x0, x1, dx) { - var x = range(x0, x1 - epsilon$4, dx).concat(x1); - return function(y) { return x.map(function(x) { return [x, y]; }); }; -} + return cardinal; +}))(0); -function graticule() { - var x1, x0, X1, X0, - y1, y0, Y1, Y0, - dx = 10, dy = dx, DX = 90, DY = 360, - x, y, X, Y, - precision = 2.5; +function point$4(that, x, y) { + var x1 = that._x1, + y1 = that._y1, + x2 = that._x2, + y2 = that._y2; - function graticule() { - return {type: "MultiLineString", coordinates: lines()}; + if (that._l01_a > epsilon$3) { + var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a, + n = 3 * that._l01_a * (that._l01_a + that._l12_a); + x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n; + y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n; } - function lines() { - return range(ceil(X0 / DX) * DX, X1, DX).map(X) - .concat(range(ceil(Y0 / DY) * DY, Y1, DY).map(Y)) - .concat(range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$4; }).map(x)) - .concat(range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$4; }).map(y)); + if (that._l23_a > epsilon$3) { + var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a, + m = 3 * that._l23_a * (that._l23_a + that._l12_a); + x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m; + y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m; } - graticule.lines = function() { - return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; }); - }; - - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ - X(X0).concat( - Y(Y1).slice(1), - X(X1).reverse().slice(1), - Y(Y0).reverse().slice(1)) - ] - }; - }; + that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2); +} - graticule.extent = function(_) { - if (!arguments.length) return graticule.extentMinor(); - return graticule.extentMajor(_).extentMinor(_); - }; +function CatmullRom(context, alpha) { + this._context = context; + this._alpha = alpha; +} - graticule.extentMajor = function(_) { - if (!arguments.length) return [[X0, Y0], [X1, Y1]]; - X0 = +_[0][0], X1 = +_[1][0]; - Y0 = +_[0][1], Y1 = +_[1][1]; - if (X0 > X1) _ = X0, X0 = X1, X1 = _; - if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; - return graticule.precision(precision); - }; +CatmullRom.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = this._x2 = + this._y0 = this._y1 = this._y2 = NaN; + this._l01_a = this._l12_a = this._l23_a = + this._l01_2a = this._l12_2a = this._l23_2a = + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 2: this._context.lineTo(this._x2, this._y2); break; + case 3: this.point(this._x2, this._y2); break; + } + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; - graticule.extentMinor = function(_) { - if (!arguments.length) return [[x0, y0], [x1, y1]]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; + if (this._point) { + var x23 = this._x2 - x, + y23 = this._y2 - y; + this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); + } - graticule.step = function(_) { - if (!arguments.length) return graticule.stepMinor(); - return graticule.stepMajor(_).stepMinor(_); - }; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; break; + case 2: this._point = 3; // proceed + default: point$4(this, x, y); break; + } - graticule.stepMajor = function(_) { - if (!arguments.length) return [DX, DY]; - DX = +_[0], DY = +_[1]; - return graticule; - }; + this._l01_a = this._l12_a, this._l12_a = this._l23_a; + this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } +}; - graticule.stepMinor = function(_) { - if (!arguments.length) return [dx, dy]; - dx = +_[0], dy = +_[1]; - return graticule; - }; +var catmullRom = ((function custom(alpha) { - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = graticuleX(y0, y1, 90); - y = graticuleY(x0, x1, precision); - X = graticuleX(Y0, Y1, 90); - Y = graticuleY(X0, X1, precision); - return graticule; + function catmullRom(context) { + return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0); + } + + catmullRom.alpha = function(alpha) { + return custom(+alpha); }; - return graticule - .extentMajor([[-180, -90 + epsilon$4], [180, 90 - epsilon$4]]) - .extentMinor([[-180, -80 - epsilon$4], [180, 80 + epsilon$4]]); -} + return catmullRom; +}))(0.5); -function graticule10() { - return graticule()(); +function CatmullRomClosed(context, alpha) { + this._context = context; + this._alpha = alpha; } -var interpolate$2 = function(a, b) { - var x0 = a[0] * radians, - y0 = a[1] * radians, - x1 = b[0] * radians, - y1 = b[1] * radians, - cy0 = cos$1(y0), - sy0 = sin$1(y0), - cy1 = cos$1(y1), - sy1 = sin$1(y1), - kx0 = cy0 * cos$1(x0), - ky0 = cy0 * sin$1(x0), - kx1 = cy1 * cos$1(x1), - ky1 = cy1 * sin$1(x1), - d = 2 * asin$1(sqrt$1(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))), - k = sin$1(d); - - var interpolate = d ? function(t) { - var B = sin$1(t *= d) / k, - A = sin$1(d - t) / k, - x = A * kx0 + B * kx1, - y = A * ky0 + B * ky1, - z = A * sy0 + B * sy1; - return [ - atan2(y, x) * degrees$1, - atan2(z, sqrt$1(x * x + y * y)) * degrees$1 - ]; - } : function() { - return [x0 * degrees$1, y0 * degrees$1]; - }; +CatmullRomClosed.prototype = { + areaStart: noop$2, + areaEnd: noop$2, + lineStart: function() { + this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = + this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; + this._l01_a = this._l12_a = this._l23_a = + this._l01_2a = this._l12_2a = this._l23_2a = + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 1: { + this._context.moveTo(this._x3, this._y3); + this._context.closePath(); + break; + } + case 2: { + this._context.lineTo(this._x3, this._y3); + this._context.closePath(); + break; + } + case 3: { + this.point(this._x3, this._y3); + this.point(this._x4, this._y4); + this.point(this._x5, this._y5); + break; + } + } + }, + point: function(x, y) { + x = +x, y = +y; - interpolate.distance = d; + if (this._point) { + var x23 = this._x2 - x, + y23 = this._y2 - y; + this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); + } - return interpolate; -}; + switch (this._point) { + case 0: this._point = 1; this._x3 = x, this._y3 = y; break; + case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; + case 2: this._point = 3; this._x5 = x, this._y5 = y; break; + default: point$4(this, x, y); break; + } -var identity$7 = function(x) { - return x; + this._l01_a = this._l12_a, this._l12_a = this._l23_a; + this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } }; -var areaSum$1 = adder(); -var areaRingSum$1 = adder(); -var x00; -var y00; -var x0$1; -var y0$1; +var catmullRomClosed = ((function custom(alpha) { -var areaStream$1 = { - point: noop$2, - lineStart: noop$2, - lineEnd: noop$2, - polygonStart: function() { - areaStream$1.lineStart = areaRingStart$1; - areaStream$1.lineEnd = areaRingEnd$1; - }, - polygonEnd: function() { - areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$2; - areaSum$1.add(abs(areaRingSum$1)); - areaRingSum$1.reset(); - }, - result: function() { - var area = areaSum$1 / 2; - areaSum$1.reset(); - return area; + function catmullRom(context) { + return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0); } -}; -function areaRingStart$1() { - areaStream$1.point = areaPointFirst$1; -} + catmullRom.alpha = function(alpha) { + return custom(+alpha); + }; -function areaPointFirst$1(x, y) { - areaStream$1.point = areaPoint$1; - x00 = x0$1 = x, y00 = y0$1 = y; -} + return catmullRom; +}))(0.5); -function areaPoint$1(x, y) { - areaRingSum$1.add(y0$1 * x - x0$1 * y); - x0$1 = x, y0$1 = y; +function CatmullRomOpen(context, alpha) { + this._context = context; + this._alpha = alpha; } -function areaRingEnd$1() { - areaPoint$1(x00, y00); -} +CatmullRomOpen.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = this._x2 = + this._y0 = this._y1 = this._y2 = NaN; + this._l01_a = this._l12_a = this._l23_a = + this._l01_2a = this._l12_2a = this._l23_2a = + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; -var x0$2 = Infinity; -var y0$2 = x0$2; -var x1 = -x0$2; -var y1 = x1; + if (this._point) { + var x23 = this._x2 - x, + y23 = this._y2 - y; + this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); + } -var boundsStream$1 = { - point: boundsPoint$1, - lineStart: noop$2, - lineEnd: noop$2, - polygonStart: noop$2, - polygonEnd: noop$2, - result: function() { - var bounds = [[x0$2, y0$2], [x1, y1]]; - x1 = y1 = -(y0$2 = x0$2 = Infinity); - return bounds; + switch (this._point) { + case 0: this._point = 1; break; + case 1: this._point = 2; break; + case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; + case 3: this._point = 4; // proceed + default: point$4(this, x, y); break; + } + + this._l01_a = this._l12_a, this._l12_a = this._l23_a; + this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; -function boundsPoint$1(x, y) { - if (x < x0$2) x0$2 = x; - if (x > x1) x1 = x; - if (y < y0$2) y0$2 = y; - if (y > y1) y1 = y; -} +var catmullRomOpen = ((function custom(alpha) { -// TODO Enforce positive area for exterior, negative area for interior? + function catmullRom(context) { + return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0); + } -var X0$1 = 0; -var Y0$1 = 0; -var Z0$1 = 0; -var X1$1 = 0; -var Y1$1 = 0; -var Z1$1 = 0; -var X2$1 = 0; -var Y2$1 = 0; -var Z2$1 = 0; -var x00$1; -var y00$1; -var x0$3; -var y0$3; + catmullRom.alpha = function(alpha) { + return custom(+alpha); + }; + + return catmullRom; +}))(0.5); + +function LinearClosed(context) { + this._context = context; +} -var centroidStream$1 = { - point: centroidPoint$1, - lineStart: centroidLineStart$1, - lineEnd: centroidLineEnd$1, - polygonStart: function() { - centroidStream$1.lineStart = centroidRingStart$1; - centroidStream$1.lineEnd = centroidRingEnd$1; +LinearClosed.prototype = { + areaStart: noop$2, + areaEnd: noop$2, + lineStart: function() { + this._point = 0; }, - polygonEnd: function() { - centroidStream$1.point = centroidPoint$1; - centroidStream$1.lineStart = centroidLineStart$1; - centroidStream$1.lineEnd = centroidLineEnd$1; + lineEnd: function() { + if (this._point) this._context.closePath(); }, - result: function() { - var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1] - : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1] - : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1] - : [NaN, NaN]; - X0$1 = Y0$1 = Z0$1 = - X1$1 = Y1$1 = Z1$1 = - X2$1 = Y2$1 = Z2$1 = 0; - return centroid; + point: function(x, y) { + x = +x, y = +y; + if (this._point) this._context.lineTo(x, y); + else this._point = 1, this._context.moveTo(x, y); } }; -function centroidPoint$1(x, y) { - X0$1 += x; - Y0$1 += y; - ++Z0$1; -} +var linearClosed = function(context) { + return new LinearClosed(context); +}; -function centroidLineStart$1() { - centroidStream$1.point = centroidPointFirstLine; +function sign$1(x) { + return x < 0 ? -1 : 1; } -function centroidPointFirstLine(x, y) { - centroidStream$1.point = centroidPointLine; - centroidPoint$1(x0$3 = x, y0$3 = y); +// Calculate the slopes of the tangents (Hermite-type interpolation) based on +// the following paper: Steffen, M. 1990. A Simple Method for Monotonic +// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO. +// NOV(II), P. 443, 1990. +function slope3(that, x2, y2) { + var h0 = that._x1 - that._x0, + h1 = x2 - that._x1, + s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0), + s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0), + p = (s0 * h1 + s1 * h0) / (h0 + h1); + return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0; } -function centroidPointLine(x, y) { - var dx = x - x0$3, dy = y - y0$3, z = sqrt$1(dx * dx + dy * dy); - X1$1 += z * (x0$3 + x) / 2; - Y1$1 += z * (y0$3 + y) / 2; - Z1$1 += z; - centroidPoint$1(x0$3 = x, y0$3 = y); +// Calculate a one-sided slope. +function slope2(that, t) { + var h = that._x1 - that._x0; + return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t; } -function centroidLineEnd$1() { - centroidStream$1.point = centroidPoint$1; +// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations +// "you can express cubic Hermite interpolation in terms of cubic Bézier curves +// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1". +function point$5(that, t0, t1) { + var x0 = that._x0, + y0 = that._y0, + x1 = that._x1, + y1 = that._y1, + dx = (x1 - x0) / 3; + that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1); } -function centroidRingStart$1() { - centroidStream$1.point = centroidPointFirstRing; +function MonotoneX(context) { + this._context = context; } -function centroidRingEnd$1() { - centroidPointRing(x00$1, y00$1); +MonotoneX.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = + this._y0 = this._y1 = + this._t0 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 2: this._context.lineTo(this._x1, this._y1); break; + case 3: point$5(this, this._t0, slope2(this, this._t0)); break; + } + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + var t1 = NaN; + + x = +x, y = +y; + if (x === this._x1 && y === this._y1) return; // Ignore coincident points. + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; break; + case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break; + default: point$5(this, this._t0, t1 = slope3(this, x, y)); break; + } + + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; + this._t0 = t1; + } +}; + +function MonotoneY(context) { + this._context = new ReflectContext(context); } -function centroidPointFirstRing(x, y) { - centroidStream$1.point = centroidPointRing; - centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y); +(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) { + MonotoneX.prototype.point.call(this, y, x); +}; + +function ReflectContext(context) { + this._context = context; } -function centroidPointRing(x, y) { - var dx = x - x0$3, - dy = y - y0$3, - z = sqrt$1(dx * dx + dy * dy); +ReflectContext.prototype = { + moveTo: function(x, y) { this._context.moveTo(y, x); }, + closePath: function() { this._context.closePath(); }, + lineTo: function(x, y) { this._context.lineTo(y, x); }, + bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); } +}; - X1$1 += z * (x0$3 + x) / 2; - Y1$1 += z * (y0$3 + y) / 2; - Z1$1 += z; +function monotoneX(context) { + return new MonotoneX(context); +} - z = y0$3 * x - x0$3 * y; - X2$1 += z * (x0$3 + x); - Y2$1 += z * (y0$3 + y); - Z2$1 += z * 3; - centroidPoint$1(x0$3 = x, y0$3 = y); +function monotoneY(context) { + return new MonotoneY(context); } -function PathContext(context) { +function Natural(context) { this._context = context; } -PathContext.prototype = { - _radius: 4.5, - pointRadius: function(_) { - return this._radius = _, this; - }, - polygonStart: function() { +Natural.prototype = { + areaStart: function() { this._line = 0; }, - polygonEnd: function() { + areaEnd: function() { this._line = NaN; }, lineStart: function() { - this._point = 0; + this._x = []; + this._y = []; }, lineEnd: function() { - if (this._line === 0) this._context.closePath(); - this._point = NaN; - }, - point: function(x, y) { - switch (this._point) { - case 0: { - this._context.moveTo(x, y); - this._point = 1; - break; - } - case 1: { - this._context.lineTo(x, y); - break; - } - default: { - this._context.moveTo(x + this._radius, y); - this._context.arc(x, y, this._radius, 0, tau$4); - break; + var x = this._x, + y = this._y, + n = x.length; + + if (n) { + this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]); + if (n === 2) { + this._context.lineTo(x[1], y[1]); + } else { + var px = controlPoints(x), + py = controlPoints(y); + for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) { + this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]); + } } } + + if (this._line || (this._line !== 0 && n === 1)) this._context.closePath(); + this._line = 1 - this._line; + this._x = this._y = null; }, - result: noop$2 + point: function(x, y) { + this._x.push(+x); + this._y.push(+y); + } }; -function PathString() { - this._string = []; +// See https://www.particleincell.com/2012/bezier-splines/ for derivation. +function controlPoints(x) { + var i, + n = x.length - 1, + m, + a = new Array(n), + b = new Array(n), + r = new Array(n); + a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1]; + for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1]; + a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n]; + for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1]; + a[n - 1] = r[n - 1] / b[n - 1]; + for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i]; + b[n - 1] = (x[n] + a[n - 1]) / 2; + for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1]; + return [a, b]; } -PathString.prototype = { - _circle: circle$2(4.5), - pointRadius: function(_) { - return this._circle = circle$2(_), this; - }, - polygonStart: function() { +var natural = function(context) { + return new Natural(context); +}; + +function Step(context, t) { + this._context = context; + this._t = t; +} + +Step.prototype = { + areaStart: function() { this._line = 0; }, - polygonEnd: function() { + areaEnd: function() { this._line = NaN; }, lineStart: function() { + this._x = this._y = NaN; this._point = 0; }, - lineEnd: function() { - if (this._line === 0) this._string.push("Z"); - this._point = NaN; - }, - point: function(x, y) { - switch (this._point) { - case 0: { - this._string.push("M", x, ",", y); - this._point = 1; - break; - } - case 1: { - this._string.push("L", x, ",", y); - break; - } + lineEnd: function() { + if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y); + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; // proceed default: { - this._string.push("M", x, ",", y, this._circle); + if (this._t <= 0) { + this._context.lineTo(this._x, y); + this._context.lineTo(x, y); + } else { + var x1 = this._x * (1 - this._t) + x * this._t; + this._context.lineTo(x1, this._y); + this._context.lineTo(x1, y); + } break; } } - }, - result: function() { - if (this._string.length) { - var result = this._string.join(""); - this._string = []; - return result; - } + this._x = x, this._y = y; } }; -function circle$2(radius) { - return "m0," + radius - + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius - + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius - + "z"; +var step = function(context) { + return new Step(context, 0.5); +}; + +function stepBefore(context) { + return new Step(context, 0); } -var index$3 = function(projection, context) { - var pointRadius = 4.5, - projectionStream, - contextStream; +function stepAfter(context) { + return new Step(context, 1); +} - function path(object) { - if (object) { - if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); - geoStream(object, projectionStream(contextStream)); +var slice$5 = Array.prototype.slice; + +var none$1 = function(series, order) { + if (!((n = series.length) > 1)) return; + for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) { + s0 = s1, s1 = series[order[i]]; + for (var j = 0; j < m; ++j) { + s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1]; } - return contextStream.result(); } +}; - path.area = function(object) { - geoStream(object, projectionStream(areaStream$1)); - return areaStream$1.result(); - }; +var none$2 = function(series) { + var n = series.length, o = new Array(n); + while (--n >= 0) o[n] = n; + return o; +}; - path.bounds = function(object) { - geoStream(object, projectionStream(boundsStream$1)); - return boundsStream$1.result(); - }; +function stackValue(d, key) { + return d[key]; +} - path.centroid = function(object) { - geoStream(object, projectionStream(centroidStream$1)); - return centroidStream$1.result(); +var stack = function() { + var keys = constant$10([]), + order = none$2, + offset = none$1, + value = stackValue; + + function stack(data) { + var kz = keys.apply(this, arguments), + i, + m = data.length, + n = kz.length, + sz = new Array(n), + oz; + + for (i = 0; i < n; ++i) { + for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) { + si[j] = sij = [0, +value(data[j], ki, j, data)]; + sij.data = data[j]; + } + si.key = ki; + } + + for (i = 0, oz = order(sz); i < n; ++i) { + sz[oz[i]].index = i; + } + + offset(sz, oz); + return sz; + } + + stack.keys = function(_) { + return arguments.length ? (keys = typeof _ === "function" ? _ : constant$10(slice$5.call(_)), stack) : keys; }; - path.projection = function(_) { - return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$7) : (projection = _).stream, path) : projection; + stack.value = function(_) { + return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), stack) : value; }; - path.context = function(_) { - if (!arguments.length) return context; - contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _); - if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); - return path; + stack.order = function(_) { + return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$10(slice$5.call(_)), stack) : order; }; - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); - return path; + stack.offset = function(_) { + return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset; }; - return path.projection(projection).context(context); + return stack; }; -var sum$2 = adder(); +var expand = function(series, order) { + if (!((n = series.length) > 0)) return; + for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) { + for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0; + if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y; + } + none$1(series, order); +}; -var polygonContains = function(polygon, point) { - var lambda = point[0], - phi = point[1], - normal = [sin$1(lambda), -cos$1(lambda), 0], - angle = 0, - winding = 0; +var silhouette = function(series, order) { + if (!((n = series.length) > 0)) return; + for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) { + for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0; + s0[j][1] += s0[j][0] = -y / 2; + } + none$1(series, order); +}; - sum$2.reset(); +var wiggle = function(series, order) { + if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return; + for (var y = 0, j = 1, s0, m, n; j < m; ++j) { + for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) { + var si = series[order[i]], + sij0 = si[j][1] || 0, + sij1 = si[j - 1][1] || 0, + s3 = (sij0 - sij1) / 2; + for (var k = 0; k < i; ++k) { + var sk = series[order[k]], + skj0 = sk[j][1] || 0, + skj1 = sk[j - 1][1] || 0; + s3 += skj0 - skj1; + } + s1 += sij0, s2 += s3 * sij0; + } + s0[j - 1][1] += s0[j - 1][0] = y; + if (s1) y -= s2 / s1; + } + s0[j - 1][1] += s0[j - 1][0] = y; + none$1(series, order); +}; - for (var i = 0, n = polygon.length; i < n; ++i) { - if (!(m = (ring = polygon[i]).length)) continue; - var ring, - m, - point0 = ring[m - 1], - lambda0 = point0[0], - phi0 = point0[1] / 2 + quarterPi, - sinPhi0 = sin$1(phi0), - cosPhi0 = cos$1(phi0); +var ascending$2 = function(series) { + var sums = series.map(sum$2); + return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; }); +}; - for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) { - var point1 = ring[j], - lambda1 = point1[0], - phi1 = point1[1] / 2 + quarterPi, - sinPhi1 = sin$1(phi1), - cosPhi1 = cos$1(phi1), - delta = lambda1 - lambda0, - sign$$1 = delta >= 0 ? 1 : -1, - absDelta = sign$$1 * delta, - antimeridian = absDelta > pi$4, - k = sinPhi0 * sinPhi1; +function sum$2(series) { + var s = 0, i = -1, n = series.length, v; + while (++i < n) if (v = +series[i][1]) s += v; + return s; +} - sum$2.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta))); - angle += antimeridian ? delta + sign$$1 * tau$4 : delta; +var descending$2 = function(series) { + return ascending$2(series).reverse(); +}; - // Are the longitudes either side of the point’s meridian (lambda), - // and are the latitudes smaller than the parallel (phi)? - if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) { - var arc = cartesianCross(cartesian(point0), cartesian(point1)); - cartesianNormalizeInPlace(arc); - var intersection = cartesianCross(normal, arc); - cartesianNormalizeInPlace(intersection); - var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin$1(intersection[2]); - if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) { - winding += antimeridian ^ delta >= 0 ? 1 : -1; - } - } +var insideOut = function(series) { + var n = series.length, + i, + j, + sums = series.map(sum$2), + order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }), + top = 0, + bottom = 0, + tops = [], + bottoms = []; + + for (i = 0; i < n; ++i) { + j = order[i]; + if (top < bottom) { + top += sums[j]; + tops.push(j); + } else { + bottom += sums[j]; + bottoms.push(j); } } - // First, determine whether the South pole is inside or outside: - // - // It is inside if: - // * the polygon winds around it in a clockwise direction. - // * the polygon does not (cumulatively) wind around it, but has a negative - // (counter-clockwise) area. - // - // Second, count the (signed) number of times a segment crosses a lambda - // from the point to the South pole. If it is zero, then the point is the - // same side as the South pole. + return bottoms.reverse().concat(tops); +}; + +var reverse = function(series) { + return none$2(series).reverse(); +}; + +var constant$11 = function(x) { + return function() { + return x; + }; +}; + +function x$4(d) { + return d[0]; +} + +function y$4(d) { + return d[1]; +} + +function RedBlackTree() { + this._ = null; // root node +} + +function RedBlackNode(node) { + node.U = // parent node + node.C = // color - true for red, false for black + node.L = // left node + node.R = // right node + node.P = // previous node + node.N = null; // next node +} + +RedBlackTree.prototype = { + constructor: RedBlackTree, - return (angle < -epsilon$4 || angle < epsilon$4 && sum$2 < -epsilon$4) ^ (winding & 1); -}; + insert: function(after, node) { + var parent, grandpa, uncle; -var clip = function(pointVisible, clipLine, interpolate, start) { - return function(rotate, sink) { - var line = clipLine(sink), - rotatedStart = rotate.invert(start[0], start[1]), - ringBuffer = clipBuffer(), - ringSink = clipLine(ringBuffer), - polygonStarted = false, - polygon, - segments, - ring; + if (after) { + node.P = after; + node.N = after.N; + if (after.N) after.N.P = node; + after.N = node; + if (after.R) { + after = after.R; + while (after.L) after = after.L; + after.L = node; + } else { + after.R = node; + } + parent = after; + } else if (this._) { + after = RedBlackFirst(this._); + node.P = null; + node.N = after; + after.P = after.L = node; + parent = after; + } else { + node.P = node.N = null; + this._ = node; + parent = null; + } + node.L = node.R = null; + node.U = parent; + node.C = true; - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - segments = []; - polygon = []; - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - segments = merge(segments); - var startInside = polygonContains(polygon, rotatedStart); - if (segments.length) { - if (!polygonStarted) sink.polygonStart(), polygonStarted = true; - clipPolygon(segments, compareIntersection, startInside, interpolate, sink); - } else if (startInside) { - if (!polygonStarted) sink.polygonStart(), polygonStarted = true; - sink.lineStart(); - interpolate(null, null, 1, sink); - sink.lineEnd(); + after = node; + while (parent && parent.C) { + grandpa = parent.U; + if (parent === grandpa.L) { + uncle = grandpa.R; + if (uncle && uncle.C) { + parent.C = uncle.C = false; + grandpa.C = true; + after = grandpa; + } else { + if (after === parent.R) { + RedBlackRotateLeft(this, parent); + after = parent; + parent = after.U; + } + parent.C = false; + grandpa.C = true; + RedBlackRotateRight(this, grandpa); + } + } else { + uncle = grandpa.L; + if (uncle && uncle.C) { + parent.C = uncle.C = false; + grandpa.C = true; + after = grandpa; + } else { + if (after === parent.L) { + RedBlackRotateRight(this, parent); + after = parent; + parent = after.U; + } + parent.C = false; + grandpa.C = true; + RedBlackRotateLeft(this, grandpa); } - if (polygonStarted) sink.polygonEnd(), polygonStarted = false; - segments = polygon = null; - }, - sphere: function() { - sink.polygonStart(); - sink.lineStart(); - interpolate(null, null, 1, sink); - sink.lineEnd(); - sink.polygonEnd(); } - }; - - function point(lambda, phi) { - var point = rotate(lambda, phi); - if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi); + parent = after.U; } + this._.C = false; + }, - function pointLine(lambda, phi) { - var point = rotate(lambda, phi); - line.point(point[0], point[1]); - } + remove: function(node) { + if (node.N) node.N.P = node.P; + if (node.P) node.P.N = node.N; + node.N = node.P = null; - function lineStart() { - clip.point = pointLine; - line.lineStart(); - } + var parent = node.U, + sibling, + left = node.L, + right = node.R, + next, + red; - function lineEnd() { - clip.point = point; - line.lineEnd(); - } + if (!left) next = right; + else if (!right) next = left; + else next = RedBlackFirst(right); - function pointRing(lambda, phi) { - ring.push([lambda, phi]); - var point = rotate(lambda, phi); - ringSink.point(point[0], point[1]); + if (parent) { + if (parent.L === node) parent.L = next; + else parent.R = next; + } else { + this._ = next; } - function ringStart() { - ringSink.lineStart(); - ring = []; + if (left && right) { + red = next.C; + next.C = node.C; + next.L = left; + left.U = next; + if (next !== right) { + parent = next.U; + next.U = node.U; + node = next.R; + parent.L = node; + next.R = right; + right.U = next; + } else { + next.U = parent; + parent = next; + node = next.R; + } + } else { + red = node.C; + node = next; } - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringSink.lineEnd(); - - var clean = ringSink.clean(), - ringSegments = ringBuffer.result(), - i, n = ringSegments.length, m, - segment, - point; - - ring.pop(); - polygon.push(ring); - ring = null; - - if (!n) return; + if (node) node.U = parent; + if (red) return; + if (node && node.C) { node.C = false; return; } - // No intersections. - if (clean & 1) { - segment = ringSegments[0]; - if ((m = segment.length - 1) > 0) { - if (!polygonStarted) sink.polygonStart(), polygonStarted = true; - sink.lineStart(); - for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]); - sink.lineEnd(); + do { + if (node === this._) break; + if (node === parent.L) { + sibling = parent.R; + if (sibling.C) { + sibling.C = false; + parent.C = true; + RedBlackRotateLeft(this, parent); + sibling = parent.R; + } + if ((sibling.L && sibling.L.C) + || (sibling.R && sibling.R.C)) { + if (!sibling.R || !sibling.R.C) { + sibling.L.C = false; + sibling.C = true; + RedBlackRotateRight(this, sibling); + sibling = parent.R; + } + sibling.C = parent.C; + parent.C = sibling.R.C = false; + RedBlackRotateLeft(this, parent); + node = this._; + break; + } + } else { + sibling = parent.L; + if (sibling.C) { + sibling.C = false; + parent.C = true; + RedBlackRotateRight(this, parent); + sibling = parent.L; + } + if ((sibling.L && sibling.L.C) + || (sibling.R && sibling.R.C)) { + if (!sibling.L || !sibling.L.C) { + sibling.R.C = false; + sibling.C = true; + RedBlackRotateLeft(this, sibling); + sibling = parent.L; + } + sibling.C = parent.C; + parent.C = sibling.L.C = false; + RedBlackRotateRight(this, parent); + node = this._; + break; } - return; } + sibling.C = true; + node = parent; + parent = parent.U; + } while (!node.C); - // Rejoin connected segments. - // TODO reuse ringBuffer.rejoin()? - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); + if (node) node.C = false; + } +}; - segments.push(ringSegments.filter(validSegment)); - } +function RedBlackRotateLeft(tree, node) { + var p = node, + q = node.R, + parent = p.U; - return clip; - }; -}; + if (parent) { + if (parent.L === p) parent.L = q; + else parent.R = q; + } else { + tree._ = q; + } -function validSegment(segment) { - return segment.length > 1; + q.U = parent; + p.U = q; + p.R = q.L; + if (p.R) p.R.U = p; + q.L = p; } -// Intersections are sorted along the clip edge. For both antimeridian cutting -// and circle clipping, the same comparison is used. -function compareIntersection(a, b) { - return ((a = a.x)[0] < 0 ? a[1] - halfPi$3 - epsilon$4 : halfPi$3 - a[1]) - - ((b = b.x)[0] < 0 ? b[1] - halfPi$3 - epsilon$4 : halfPi$3 - b[1]); -} +function RedBlackRotateRight(tree, node) { + var p = node, + q = node.L, + parent = p.U; -var clipAntimeridian = clip( - function() { return true; }, - clipAntimeridianLine, - clipAntimeridianInterpolate, - [-pi$4, -halfPi$3] -); + if (parent) { + if (parent.L === p) parent.L = q; + else parent.R = q; + } else { + tree._ = q; + } -// Takes a line and cuts into visible segments. Return values: 0 - there were -// intersections or the line was empty; 1 - no intersections; 2 - there were -// intersections, and the first and last segments should be rejoined. -function clipAntimeridianLine(stream) { - var lambda0 = NaN, - phi0 = NaN, - sign0 = NaN, - clean; // no intersections + q.U = parent; + p.U = q; + p.L = q.R; + if (p.L) p.L.U = p; + q.R = p; +} - return { - lineStart: function() { - stream.lineStart(); - clean = 1; - }, - point: function(lambda1, phi1) { - var sign1 = lambda1 > 0 ? pi$4 : -pi$4, - delta = abs(lambda1 - lambda0); - if (abs(delta - pi$4) < epsilon$4) { // line crosses a pole - stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$3 : -halfPi$3); - stream.point(sign0, phi0); - stream.lineEnd(); - stream.lineStart(); - stream.point(sign1, phi0); - stream.point(lambda1, phi0); - clean = 0; - } else if (sign0 !== sign1 && delta >= pi$4) { // line crosses antimeridian - if (abs(lambda0 - sign0) < epsilon$4) lambda0 -= sign0 * epsilon$4; // handle degeneracies - if (abs(lambda1 - sign1) < epsilon$4) lambda1 -= sign1 * epsilon$4; - phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1); - stream.point(sign0, phi0); - stream.lineEnd(); - stream.lineStart(); - stream.point(sign1, phi0); - clean = 0; - } - stream.point(lambda0 = lambda1, phi0 = phi1); - sign0 = sign1; - }, - lineEnd: function() { - stream.lineEnd(); - lambda0 = phi0 = NaN; - }, - clean: function() { - return 2 - clean; // if intersections, rejoin first and last segments - } - }; +function RedBlackFirst(node) { + while (node.L) node = node.L; + return node; } -function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) { - var cosPhi0, - cosPhi1, - sinLambda0Lambda1 = sin$1(lambda0 - lambda1); - return abs(sinLambda0Lambda1) > epsilon$4 - ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1) - - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0)) - / (cosPhi0 * cosPhi1 * sinLambda0Lambda1)) - : (phi0 + phi1) / 2; +function createEdge(left, right, v0, v1) { + var edge = [null, null], + index = edges.push(edge) - 1; + edge.left = left; + edge.right = right; + if (v0) setEdgeEnd(edge, left, right, v0); + if (v1) setEdgeEnd(edge, right, left, v1); + cells[left.index].halfedges.push(index); + cells[right.index].halfedges.push(index); + return edge; } -function clipAntimeridianInterpolate(from, to, direction, stream) { - var phi; - if (from == null) { - phi = direction * halfPi$3; - stream.point(-pi$4, phi); - stream.point(0, phi); - stream.point(pi$4, phi); - stream.point(pi$4, 0); - stream.point(pi$4, -phi); - stream.point(0, -phi); - stream.point(-pi$4, -phi); - stream.point(-pi$4, 0); - stream.point(-pi$4, phi); - } else if (abs(from[0] - to[0]) > epsilon$4) { - var lambda = from[0] < to[0] ? pi$4 : -pi$4; - phi = direction * lambda / 2; - stream.point(-lambda, phi); - stream.point(0, phi); - stream.point(lambda, phi); +function createBorderEdge(left, v0, v1) { + var edge = [v0, v1]; + edge.left = left; + return edge; +} + +function setEdgeEnd(edge, left, right, vertex) { + if (!edge[0] && !edge[1]) { + edge[0] = vertex; + edge.left = left; + edge.right = right; + } else if (edge.left === right) { + edge[1] = vertex; } else { - stream.point(to[0], to[1]); + edge[0] = vertex; } } -var clipCircle = function(radius, delta) { - var cr = cos$1(radius), - smallRadius = cr > 0, - notHemisphere = abs(cr) > epsilon$4; // TODO optimise for this common case +// Liang–Barsky line clipping. +function clipEdge(edge, x0, y0, x1, y1) { + var a = edge[0], + b = edge[1], + ax = a[0], + ay = a[1], + bx = b[0], + by = b[1], + t0 = 0, + t1 = 1, + dx = bx - ax, + dy = by - ay, + r; - function interpolate(from, to, direction, stream) { - circleStream(stream, radius, delta, direction, from, to); + r = x0 - ax; + if (!dx && r > 0) return; + r /= dx; + if (dx < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dx > 0) { + if (r > t1) return; + if (r > t0) t0 = r; } - function visible(lambda, phi) { - return cos$1(lambda) * cos$1(phi) > cr; + r = x1 - ax; + if (!dx && r < 0) return; + r /= dx; + if (dx < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dx > 0) { + if (r < t0) return; + if (r < t1) t1 = r; } - // Takes a line and cuts into visible segments. Return values used for polygon - // clipping: 0 - there were intersections or the line was empty; 1 - no - // intersections 2 - there were intersections, and the first and last segments - // should be rejoined. - function clipLine(stream) { - var point0, // previous point - c0, // code for previous point - v0, // visibility of previous point - v00, // visibility of first point - clean; // no intersections - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(lambda, phi) { - var point1 = [lambda, phi], - point2, - v = visible(lambda, phi), - c = smallRadius - ? v ? 0 : code(lambda, phi) - : v ? code(lambda + (lambda < 0 ? pi$4 : -pi$4), phi) : 0; - if (!point0 && (v00 = v0 = v)) stream.lineStart(); - // Handle degeneracies. - // TODO ignore if not clipping polygons. - if (v !== v0) { - point2 = intersect(point0, point1); - if (pointEqual(point0, point2) || pointEqual(point1, point2)) { - point1[0] += epsilon$4; - point1[1] += epsilon$4; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v) { - // outside going in - stream.lineStart(); - point2 = intersect(point1, point0); - stream.point(point2[0], point2[1]); - } else { - // inside going out - point2 = intersect(point0, point1); - stream.point(point2[0], point2[1]); - stream.lineEnd(); - } - point0 = point2; - } else if (notHemisphere && point0 && smallRadius ^ v) { - var t; - // If the codes for two points are different, or are both zero, - // and there this segment intersects with the small circle. - if (!(c & c0) && (t = intersect(point1, point0, true))) { - clean = 0; - if (smallRadius) { - stream.lineStart(); - stream.point(t[0][0], t[0][1]); - stream.point(t[1][0], t[1][1]); - stream.lineEnd(); - } else { - stream.point(t[1][0], t[1][1]); - stream.lineEnd(); - stream.lineStart(); - stream.point(t[0][0], t[0][1]); - } - } - } - if (v && (!point0 || !pointEqual(point0, point1))) { - stream.point(point1[0], point1[1]); - } - point0 = point1, v0 = v, c0 = c; - }, - lineEnd: function() { - if (v0) stream.lineEnd(); - point0 = null; - }, - // Rejoin first and last segments if there were intersections and the first - // and last points were visible. - clean: function() { - return clean | ((v00 && v0) << 1); + r = y0 - ay; + if (!dy && r > 0) return; + r /= dy; + if (dy < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dy > 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } + + r = y1 - ay; + if (!dy && r < 0) return; + r /= dy; + if (dy < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dy > 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } + + if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check? + + if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy]; + if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy]; + return true; +} + +function connectEdge(edge, x0, y0, x1, y1) { + var v1 = edge[1]; + if (v1) return true; + + var v0 = edge[0], + left = edge.left, + right = edge.right, + lx = left[0], + ly = left[1], + rx = right[0], + ry = right[1], + fx = (lx + rx) / 2, + fy = (ly + ry) / 2, + fm, + fb; + + if (ry === ly) { + if (fx < x0 || fx >= x1) return; + if (lx > rx) { + if (!v0) v0 = [fx, y0]; + else if (v0[1] >= y1) return; + v1 = [fx, y1]; + } else { + if (!v0) v0 = [fx, y1]; + else if (v0[1] < y0) return; + v1 = [fx, y0]; + } + } else { + fm = (lx - rx) / (ry - ly); + fb = fy - fm * fx; + if (fm < -1 || fm > 1) { + if (lx > rx) { + if (!v0) v0 = [(y0 - fb) / fm, y0]; + else if (v0[1] >= y1) return; + v1 = [(y1 - fb) / fm, y1]; + } else { + if (!v0) v0 = [(y1 - fb) / fm, y1]; + else if (v0[1] < y0) return; + v1 = [(y0 - fb) / fm, y0]; } - }; + } else { + if (ly < ry) { + if (!v0) v0 = [x0, fm * x0 + fb]; + else if (v0[0] >= x1) return; + v1 = [x1, fm * x1 + fb]; + } else { + if (!v0) v0 = [x1, fm * x1 + fb]; + else if (v0[0] < x0) return; + v1 = [x0, fm * x0 + fb]; + } + } } - // Intersects the great circle between a and b with the clip circle. - function intersect(a, b, two) { - var pa = cartesian(a), - pb = cartesian(b); + edge[0] = v0; + edge[1] = v1; + return true; +} - // We have two planes, n1.p = d1 and n2.p = d2. - // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2). - var n1 = [1, 0, 0], // normal - n2 = cartesianCross(pa, pb), - n2n2 = cartesianDot(n2, n2), - n1n2 = n2[0], // cartesianDot(n1, n2), - determinant = n2n2 - n1n2 * n1n2; +function clipEdges(x0, y0, x1, y1) { + var i = edges.length, + edge; - // Two polar points. - if (!determinant) return !two && a; + while (i--) { + if (!connectEdge(edge = edges[i], x0, y0, x1, y1) + || !clipEdge(edge, x0, y0, x1, y1) + || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4 + || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) { + delete edges[i]; + } + } +} - var c1 = cr * n2n2 / determinant, - c2 = -cr * n1n2 / determinant, - n1xn2 = cartesianCross(n1, n2), - A = cartesianScale(n1, c1), - B = cartesianScale(n2, c2); - cartesianAddInPlace(A, B); +function createCell(site) { + return cells[site.index] = { + site: site, + halfedges: [] + }; +} - // Solve |p(t)|^2 = 1. - var u = n1xn2, - w = cartesianDot(A, u), - uu = cartesianDot(u, u), - t2 = w * w - uu * (cartesianDot(A, A) - 1); +function cellHalfedgeAngle(cell, edge) { + var site = cell.site, + va = edge.left, + vb = edge.right; + if (site === vb) vb = va, va = site; + if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]); + if (site === va) va = edge[1], vb = edge[0]; + else va = edge[0], vb = edge[1]; + return Math.atan2(va[0] - vb[0], vb[1] - va[1]); +} - if (t2 < 0) return; +function cellHalfedgeStart(cell, edge) { + return edge[+(edge.left !== cell.site)]; +} - var t = sqrt$1(t2), - q = cartesianScale(u, (-w - t) / uu); - cartesianAddInPlace(q, A); - q = spherical(q); +function cellHalfedgeEnd(cell, edge) { + return edge[+(edge.left === cell.site)]; +} - if (!two) return q; +function sortCellHalfedges() { + for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) { + if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) { + var index = new Array(m), + array = new Array(m); + for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]); + index.sort(function(i, j) { return array[j] - array[i]; }); + for (j = 0; j < m; ++j) array[j] = halfedges[index[j]]; + for (j = 0; j < m; ++j) halfedges[j] = array[j]; + } + } +} - // Two intersection points. - var lambda0 = a[0], - lambda1 = b[0], - phi0 = a[1], - phi1 = b[1], - z; +function clipCells(x0, y0, x1, y1) { + var nCells = cells.length, + iCell, + cell, + site, + iHalfedge, + halfedges, + nHalfedges, + start, + startX, + startY, + end, + endX, + endY, + cover = true; - if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z; + for (iCell = 0; iCell < nCells; ++iCell) { + if (cell = cells[iCell]) { + site = cell.site; + halfedges = cell.halfedges; + iHalfedge = halfedges.length; - var delta = lambda1 - lambda0, - polar = abs(delta - pi$4) < epsilon$4, - meridian = polar || delta < epsilon$4; + // Remove any dangling clipped edges. + while (iHalfedge--) { + if (!edges[halfedges[iHalfedge]]) { + halfedges.splice(iHalfedge, 1); + } + } - if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z; + // Insert any border edges as necessary. + iHalfedge = 0, nHalfedges = halfedges.length; + while (iHalfedge < nHalfedges) { + end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1]; + start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1]; + if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) { + halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end, + Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1] + : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1] + : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0] + : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0] + : null)) - 1); + ++nHalfedges; + } + } - // Check that the first point is between a and b. - if (meridian - ? polar - ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$4 ? phi0 : phi1) - : phi0 <= q[1] && q[1] <= phi1 - : delta > pi$4 ^ (lambda0 <= q[0] && q[0] <= lambda1)) { - var q1 = cartesianScale(u, (-w + t) / uu); - cartesianAddInPlace(q1, A); - return [q, spherical(q1)]; + if (nHalfedges) cover = false; } } - // Generates a 4-bit vector representing the location of a point relative to - // the small circle's bounding box. - function code(lambda, phi) { - var r = smallRadius ? radius : pi$4 - radius, - code = 0; - if (lambda < -r) code |= 1; // left - else if (lambda > r) code |= 2; // right - if (phi < -r) code |= 4; // below - else if (phi > r) code |= 8; // above - return code; + // If there weren’t any edges, have the closest site cover the extent. + // It doesn’t matter which corner of the extent we measure! + if (cover) { + var dx, dy, d2, dc = Infinity; + + for (iCell = 0, cover = null; iCell < nCells; ++iCell) { + if (cell = cells[iCell]) { + site = cell.site; + dx = site[0] - x0; + dy = site[1] - y0; + d2 = dx * dx + dy * dy; + if (d2 < dc) dc = d2, cover = cell; + } + } + + if (cover) { + var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0]; + cover.halfedges.push( + edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1, + edges.push(createBorderEdge(site, v01, v11)) - 1, + edges.push(createBorderEdge(site, v11, v10)) - 1, + edges.push(createBorderEdge(site, v10, v00)) - 1 + ); + } } - return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$4, radius - pi$4]); -}; + // Lastly delete any cells with no edges; these were entirely clipped. + for (iCell = 0; iCell < nCells; ++iCell) { + if (cell = cells[iCell]) { + if (!cell.halfedges.length) { + delete cells[iCell]; + } + } + } +} + +var circlePool = []; + +var firstCircle; + +function Circle() { + RedBlackNode(this); + this.x = + this.y = + this.arc = + this.site = + this.cy = null; +} + +function attachCircle(arc) { + var lArc = arc.P, + rArc = arc.N; -var transform$1 = function(methods) { - return { - stream: transformer(methods) - }; -}; + if (!lArc || !rArc) return; -function transformer(methods) { - return function(stream) { - var s = new TransformStream; - for (var key in methods) s[key] = methods[key]; - s.stream = stream; - return s; - }; -} + var lSite = lArc.site, + cSite = arc.site, + rSite = rArc.site; -function TransformStream() {} + if (lSite === rSite) return; -TransformStream.prototype = { - constructor: TransformStream, - point: function(x, y) { this.stream.point(x, y); }, - sphere: function() { this.stream.sphere(); }, - lineStart: function() { this.stream.lineStart(); }, - lineEnd: function() { this.stream.lineEnd(); }, - polygonStart: function() { this.stream.polygonStart(); }, - polygonEnd: function() { this.stream.polygonEnd(); } -}; + var bx = cSite[0], + by = cSite[1], + ax = lSite[0] - bx, + ay = lSite[1] - by, + cx = rSite[0] - bx, + cy = rSite[1] - by; -function fitExtent(projection, extent, object) { - var w = extent[1][0] - extent[0][0], - h = extent[1][1] - extent[0][1], - clip = projection.clipExtent && projection.clipExtent(); + var d = 2 * (ax * cy - ay * cx); + if (d >= -epsilon2$2) return; - projection - .scale(150) - .translate([0, 0]); + var ha = ax * ax + ay * ay, + hc = cx * cx + cy * cy, + x = (cy * ha - ay * hc) / d, + y = (ax * hc - cx * ha) / d; - if (clip != null) projection.clipExtent(null); + var circle = circlePool.pop() || new Circle; + circle.arc = arc; + circle.site = cSite; + circle.x = x + bx; + circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom - geoStream(object, projection.stream(boundsStream$1)); + arc.circle = circle; - var b = boundsStream$1.result(), - k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])), - x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2, - y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2; + var before = null, + node = circles._; - if (clip != null) projection.clipExtent(clip); + while (node) { + if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) { + if (node.L) node = node.L; + else { before = node.P; break; } + } else { + if (node.R) node = node.R; + else { before = node; break; } + } + } - return projection - .scale(k * 150) - .translate([x, y]); + circles.insert(before, circle); + if (!before) firstCircle = circle; } -function fitSize(projection, size, object) { - return fitExtent(projection, [[0, 0], size], object); +function detachCircle(arc) { + var circle = arc.circle; + if (circle) { + if (!circle.P) firstCircle = circle.N; + circles.remove(circle); + circlePool.push(circle); + RedBlackNode(circle); + arc.circle = null; + } } -var maxDepth = 16; -var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance) - -var resample = function(project, delta2) { - return +delta2 ? resample$1(project, delta2) : resampleNone(project); -}; +var beachPool = []; -function resampleNone(project) { - return transformer({ - point: function(x, y) { - x = project(x, y); - this.stream.point(x[0], x[1]); - } - }); +function Beach() { + RedBlackNode(this); + this.edge = + this.site = + this.circle = null; } -function resample$1(project, delta2) { +function createBeach(site) { + var beach = beachPool.pop() || new Beach; + beach.site = site; + return beach; +} - function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, - dy = y1 - y0, - d2 = dx * dx + dy * dy; - if (d2 > 4 * delta2 && depth--) { - var a = a0 + a1, - b = b0 + b1, - c = c0 + c1, - m = sqrt$1(a * a + b * b + c * c), - phi2 = asin$1(c /= m), - lambda2 = abs(abs(c) - 1) < epsilon$4 || abs(lambda0 - lambda1) < epsilon$4 ? (lambda0 + lambda1) / 2 : atan2(b, a), - p = project(lambda2, phi2), - x2 = p[0], - y2 = p[1], - dx2 = x2 - x0, - dy2 = y2 - y0, - dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > delta2 // perpendicular projected distance - || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end - || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance - resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream); - } - } - } - return function(stream) { - var lambda00, x00, y00, a00, b00, c00, // first point - lambda0, x0, y0, a0, b0, c0; // previous point +function detachBeach(beach) { + detachCircle(beach); + beaches.remove(beach); + beachPool.push(beach); + RedBlackNode(beach); +} - var resampleStream = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; }, - polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; } - }; +function removeBeach(beach) { + var circle = beach.circle, + x = circle.x, + y = circle.cy, + vertex = [x, y], + previous = beach.P, + next = beach.N, + disappearing = [beach]; - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } + detachBeach(beach); - function lineStart() { - x0 = NaN; - resampleStream.point = linePoint; - stream.lineStart(); - } + var lArc = previous; + while (lArc.circle + && Math.abs(x - lArc.circle.x) < epsilon$4 + && Math.abs(y - lArc.circle.cy) < epsilon$4) { + previous = lArc.P; + disappearing.unshift(lArc); + detachBeach(lArc); + lArc = previous; + } - function linePoint(lambda, phi) { - var c = cartesian([lambda, phi]), p = project(lambda, phi); - resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } + disappearing.unshift(lArc); + detachCircle(lArc); - function lineEnd() { - resampleStream.point = point; - stream.lineEnd(); - } + var rArc = next; + while (rArc.circle + && Math.abs(x - rArc.circle.x) < epsilon$4 + && Math.abs(y - rArc.circle.cy) < epsilon$4) { + next = rArc.N; + disappearing.push(rArc); + detachBeach(rArc); + rArc = next; + } - function ringStart() { - lineStart(); - resampleStream.point = ringPoint; - resampleStream.lineEnd = ringEnd; - } + disappearing.push(rArc); + detachCircle(rArc); - function ringPoint(lambda, phi) { - linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resampleStream.point = linePoint; - } + var nArcs = disappearing.length, + iArc; + for (iArc = 1; iArc < nArcs; ++iArc) { + rArc = disappearing[iArc]; + lArc = disappearing[iArc - 1]; + setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); + } - function ringEnd() { - resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream); - resampleStream.lineEnd = lineEnd; - lineEnd(); - } + lArc = disappearing[0]; + rArc = disappearing[nArcs - 1]; + rArc.edge = createEdge(lArc.site, rArc.site, null, vertex); - return resampleStream; - }; + attachCircle(lArc); + attachCircle(rArc); } -var transformRadians = transformer({ - point: function(x, y) { - this.stream.point(x * radians, y * radians); +function addBeach(site) { + var x = site[0], + directrix = site[1], + lArc, + rArc, + dxl, + dxr, + node = beaches._; + + while (node) { + dxl = leftBreakPoint(node, directrix) - x; + if (dxl > epsilon$4) node = node.L; else { + dxr = x - rightBreakPoint(node, directrix); + if (dxr > epsilon$4) { + if (!node.R) { + lArc = node; + break; + } + node = node.R; + } else { + if (dxl > -epsilon$4) { + lArc = node.P; + rArc = node; + } else if (dxr > -epsilon$4) { + lArc = node; + rArc = node.N; + } else { + lArc = rArc = node; + } + break; + } + } } -}); -function projection(project) { - return projectionMutator(function() { return project; })(); -} + createCell(site); + var newArc = createBeach(site); + beaches.insert(lArc, newArc); -function projectionMutator(projectAt) { - var project, - k = 150, // scale - x = 480, y = 250, // translate - dx, dy, lambda = 0, phi = 0, // center - deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate - theta = null, preclip = clipAntimeridian, // clip angle - x0 = null, y0, x1, y1, postclip = identity$7, // clip extent - delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision - cache, - cacheStream; + if (!lArc && !rArc) return; - function projection(point) { - point = projectRotate(point[0] * radians, point[1] * radians); - return [point[0] * k + dx, dy - point[1] * k]; + if (lArc === rArc) { + detachCircle(lArc); + rArc = createBeach(lArc.site); + beaches.insert(newArc, rArc); + newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site); + attachCircle(lArc); + attachCircle(rArc); + return; } - function invert(point) { - point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k); - return point && [point[0] * degrees$1, point[1] * degrees$1]; + if (!rArc) { // && lArc + newArc.edge = createEdge(lArc.site, newArc.site); + return; } - function projectTransform(x, y) { - return x = project(x, y), [x[0] * k + dx, dy - x[1] * k]; - } + // else lArc !== rArc + detachCircle(lArc); + detachCircle(rArc); - projection.stream = function(stream) { - return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream)))); - }; + var lSite = lArc.site, + ax = lSite[0], + ay = lSite[1], + bx = site[0] - ax, + by = site[1] - ay, + rSite = rArc.site, + cx = rSite[0] - ax, + cy = rSite[1] - ay, + d = 2 * (bx * cy - by * cx), + hb = bx * bx + by * by, + hc = cx * cx + cy * cy, + vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay]; - projection.clipAngle = function(_) { - return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1; - }; + setEdgeEnd(rArc.edge, lSite, rSite, vertex); + newArc.edge = createEdge(lSite, site, null, vertex); + rArc.edge = createEdge(site, rSite, null, vertex); + attachCircle(lArc); + attachCircle(rArc); +} - projection.clipExtent = function(_) { - return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$7) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; - }; +function leftBreakPoint(arc, directrix) { + var site = arc.site, + rfocx = site[0], + rfocy = site[1], + pby2 = rfocy - directrix; - projection.scale = function(_) { - return arguments.length ? (k = +_, recenter()) : k; - }; + if (!pby2) return rfocx; - projection.translate = function(_) { - return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y]; - }; + var lArc = arc.P; + if (!lArc) return -Infinity; - projection.center = function(_) { - return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1]; - }; + site = lArc.site; + var lfocx = site[0], + lfocy = site[1], + plby2 = lfocy - directrix; - projection.rotate = function(_) { - return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1]; - }; + if (!plby2) return lfocx; - projection.precision = function(_) { - return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt$1(delta2); - }; + var hl = lfocx - rfocx, + aby2 = 1 / pby2 - 1 / plby2, + b = hl / plby2; - projection.fitExtent = function(extent, object) { - return fitExtent(projection, extent, object); - }; + if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; - projection.fitSize = function(size, object) { - return fitSize(projection, size, object); - }; + return (rfocx + lfocx) / 2; +} - function recenter() { - projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project); - var center = project(lambda, phi); - dx = x - center[0] * k; - dy = y + center[1] * k; - return reset(); - } +function rightBreakPoint(arc, directrix) { + var rArc = arc.N; + if (rArc) return leftBreakPoint(rArc, directrix); + var site = arc.site; + return site[1] === directrix ? site[0] : Infinity; +} - function reset() { - cache = cacheStream = null; - return projection; - } +var epsilon$4 = 1e-6; +var epsilon2$2 = 1e-12; +var beaches; +var cells; +var circles; +var edges; - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return recenter(); - }; +function triangleArea(a, b, c) { + return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]); } -function conicProjection(projectAt) { - var phi0 = 0, - phi1 = pi$4 / 3, - m = projectionMutator(projectAt), - p = m(phi0, phi1); +function lexicographic(a, b) { + return b[1] - a[1] + || b[0] - a[0]; +} - p.parallels = function(_) { - return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1]; - }; +function Diagram(sites, extent) { + var site = sites.sort(lexicographic).pop(), + x, + y, + circle; - return p; -} + edges = []; + cells = new Array(sites.length); + beaches = new RedBlackTree; + circles = new RedBlackTree; -function cylindricalEqualAreaRaw(phi0) { - var cosPhi0 = cos$1(phi0); + while (true) { + circle = firstCircle; + if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) { + if (site[0] !== x || site[1] !== y) { + addBeach(site); + x = site[0], y = site[1]; + } + site = sites.pop(); + } else if (circle) { + removeBeach(circle.arc); + } else { + break; + } + } - function forward(lambda, phi) { - return [lambda * cosPhi0, sin$1(phi) / cosPhi0]; + sortCellHalfedges(); + + if (extent) { + var x0 = +extent[0][0], + y0 = +extent[0][1], + x1 = +extent[1][0], + y1 = +extent[1][1]; + clipEdges(x0, y0, x1, y1); + clipCells(x0, y0, x1, y1); } - forward.invert = function(x, y) { - return [x / cosPhi0, asin$1(y * cosPhi0)]; - }; + this.edges = edges; + this.cells = cells; - return forward; + beaches = + circles = + edges = + cells = null; } -function conicEqualAreaRaw(y0, y1) { - var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2; +Diagram.prototype = { + constructor: Diagram, - // Are the parallels symmetrical around the Equator? - if (abs(n) < epsilon$4) return cylindricalEqualAreaRaw(y0); + polygons: function() { + var edges = this.edges; - var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt$1(c) / n; + return this.cells.map(function(cell) { + var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); }); + polygon.data = cell.site.data; + return polygon; + }); + }, - function project(x, y) { - var r = sqrt$1(c - 2 * n * sin$1(y)) / n; - return [r * sin$1(x *= n), r0 - r * cos$1(x)]; - } + triangles: function() { + var triangles = [], + edges = this.edges; - project.invert = function(x, y) { - var r0y = r0 - y; - return [atan2(x, abs(r0y)) / n * sign$1(r0y), asin$1((c - (x * x + r0y * r0y) * n * n) / (2 * n))]; - }; + this.cells.forEach(function(cell, i) { + if (!(m = (halfedges = cell.halfedges).length)) return; + var site = cell.site, + halfedges, + j = -1, + m, + s0, + e1 = edges[halfedges[m - 1]], + s1 = e1.left === site ? e1.right : e1.left; - return project; -} + while (++j < m) { + s0 = s1; + e1 = edges[halfedges[j]]; + s1 = e1.left === site ? e1.right : e1.left; + if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) { + triangles.push([site.data, s0.data, s1.data]); + } + } + }); + + return triangles; + }, + + links: function() { + return this.edges.filter(function(edge) { + return edge.right; + }).map(function(edge) { + return { + source: edge.left.data, + target: edge.right.data + }; + }); + }, + + find: function(x, y, radius) { + var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell; + + // Use the previously-found cell, or start with an arbitrary one. + while (!(cell = that.cells[i1])) if (++i1 >= n) return null; + var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy; + + // Traverse the half-edges to find a closer cell, if any. + do { + cell = that.cells[i0 = i1], i1 = null; + cell.halfedges.forEach(function(e) { + var edge = that.edges[e], v = edge.left; + if ((v === cell.site || !v) && !(v = edge.right)) return; + var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy; + if (v2 < d2) d2 = v2, i1 = v.index; + }); + } while (i1 !== null); -var conicEqualArea = function() { - return conicProjection(conicEqualAreaRaw) - .scale(155.424) - .center([0, 33.6442]); -}; + that._found = i0; -var albers = function() { - return conicEqualArea() - .parallels([29.5, 45.5]) - .scale(1070) - .translate([480, 250]) - .rotate([96, 0]) - .center([-0.6, 38.7]); + return radius == null || d2 <= radius * radius ? cell.site : null; + } }; -// The projections must have mutually exclusive clip regions on the sphere, -// as this will avoid emitting interleaving lines and polygons. -function multiplex(streams) { - var n = streams.length; - return { - point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); }, - sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); }, - lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); }, - lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); }, - polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); }, - polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); } - }; -} - -// A composite projection for the United States, configured by default for -// 960×500. The projection also works quite well at 960×600 if you change the -// scale to 1285 and adjust the translate accordingly. The set of standard -// parallels for each region comes from USGS, which is published here: -// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers -var albersUsa = function() { - var cache, - cacheStream, - lower48 = albers(), lower48Point, - alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338 - hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007 - point, pointStream = {point: function(x, y) { point = [x, y]; }}; +var voronoi = function() { + var x$$1 = x$4, + y$$1 = y$4, + extent = null; - function albersUsa(coordinates) { - var x = coordinates[0], y = coordinates[1]; - return point = null, - (lower48Point.point(x, y), point) - || (alaskaPoint.point(x, y), point) - || (hawaiiPoint.point(x, y), point); + function voronoi(data) { + return new Diagram(data.map(function(d, i) { + var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4]; + s.index = i; + s.data = d; + return s; + }), extent); } - albersUsa.invert = function(coordinates) { - var k = lower48.scale(), - t = lower48.translate(), - x = (coordinates[0] - t[0]) / k, - y = (coordinates[1] - t[1]) / k; - return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska - : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii - : lower48).invert(coordinates); + voronoi.polygons = function(data) { + return voronoi(data).polygons(); }; - albersUsa.stream = function(stream) { - return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]); + voronoi.links = function(data) { + return voronoi(data).links(); }; - albersUsa.precision = function(_) { - if (!arguments.length) return lower48.precision(); - lower48.precision(_), alaska.precision(_), hawaii.precision(_); - return reset(); + voronoi.triangles = function(data) { + return voronoi(data).triangles(); }; - albersUsa.scale = function(_) { - if (!arguments.length) return lower48.scale(); - lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_); - return albersUsa.translate(lower48.translate()); + voronoi.x = function(_) { + return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : x$$1; }; - albersUsa.translate = function(_) { - if (!arguments.length) return lower48.translate(); - var k = lower48.scale(), x = +_[0], y = +_[1]; - - lower48Point = lower48 - .translate(_) - .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]]) - .stream(pointStream); - - alaskaPoint = alaska - .translate([x - 0.307 * k, y + 0.201 * k]) - .clipExtent([[x - 0.425 * k + epsilon$4, y + 0.120 * k + epsilon$4], [x - 0.214 * k - epsilon$4, y + 0.234 * k - epsilon$4]]) - .stream(pointStream); - - hawaiiPoint = hawaii - .translate([x - 0.205 * k, y + 0.212 * k]) - .clipExtent([[x - 0.214 * k + epsilon$4, y + 0.166 * k + epsilon$4], [x - 0.115 * k - epsilon$4, y + 0.234 * k - epsilon$4]]) - .stream(pointStream); - - return reset(); + voronoi.y = function(_) { + return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : y$$1; }; - albersUsa.fitExtent = function(extent, object) { - return fitExtent(albersUsa, extent, object); + voronoi.extent = function(_) { + return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]]; }; - albersUsa.fitSize = function(size, object) { - return fitSize(albersUsa, size, object); + voronoi.size = function(_) { + return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]]; }; - function reset() { - cache = cacheStream = null; - return albersUsa; - } + return voronoi; +}; - return albersUsa.scale(1070); +var constant$12 = function(x) { + return function() { + return x; + }; }; -function azimuthalRaw(scale) { - return function(x, y) { - var cx = cos$1(x), - cy = cos$1(y), - k = scale(cx * cy); - return [ - k * cy * sin$1(x), - k * sin$1(y) - ]; - } +function ZoomEvent(target, type, transform) { + this.target = target; + this.type = type; + this.transform = transform; } -function azimuthalInvert(angle) { - return function(x, y) { - var z = sqrt$1(x * x + y * y), - c = angle(z), - sc = sin$1(c), - cc = cos$1(c); - return [ - atan2(x * sc, z * cc), - asin$1(z && y * sc / z) - ]; - } +function Transform(k, x, y) { + this.k = k; + this.x = x; + this.y = y; } -var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) { - return sqrt$1(2 / (1 + cxcy)); -}); +Transform.prototype = { + constructor: Transform, + scale: function(k) { + return k === 1 ? this : new Transform(this.k * k, this.x, this.y); + }, + translate: function(x, y) { + return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); + }, + apply: function(point) { + return [point[0] * this.k + this.x, point[1] * this.k + this.y]; + }, + applyX: function(x) { + return x * this.k + this.x; + }, + applyY: function(y) { + return y * this.k + this.y; + }, + invert: function(location) { + return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; + }, + invertX: function(x) { + return (x - this.x) / this.k; + }, + invertY: function(y) { + return (y - this.y) / this.k; + }, + rescaleX: function(x) { + return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); + }, + rescaleY: function(y) { + return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); + }, + toString: function() { + return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; + } +}; -azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) { - return 2 * asin$1(z / 2); -}); +var identity$8 = new Transform(1, 0, 0); -var azimuthalEqualArea = function() { - return projection(azimuthalEqualAreaRaw) - .scale(124.75) - .clipAngle(180 - 1e-3); -}; +transform$1.prototype = Transform.prototype; -var azimuthalEquidistantRaw = azimuthalRaw(function(c) { - return (c = acos(c)) && c / sin$1(c); -}); +function transform$1(node) { + return node.__zoom || identity$8; +} -azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) { - return z; -}); +function nopropagation$2() { + exports.event.stopImmediatePropagation(); +} -var azimuthalEquidistant = function() { - return projection(azimuthalEquidistantRaw) - .scale(79.4188) - .clipAngle(180 - 1e-3); +var noevent$2 = function() { + exports.event.preventDefault(); + exports.event.stopImmediatePropagation(); }; -function mercatorRaw(lambda, phi) { - return [lambda, log$1(tan((halfPi$3 + phi) / 2))]; +// Ignore right-click, since that should open the context menu. +function defaultFilter$2() { + return !exports.event.button; } -mercatorRaw.invert = function(x, y) { - return [x, 2 * atan(exp(y)) - halfPi$3]; -}; +function defaultExtent$1() { + var e = this, w, h; + if (e instanceof SVGElement) { + e = e.ownerSVGElement || e; + w = e.width.baseVal.value; + h = e.height.baseVal.value; + } else { + w = e.clientWidth; + h = e.clientHeight; + } + return [[0, 0], [w, h]]; +} -var mercator = function() { - return mercatorProjection(mercatorRaw) - .scale(961 / tau$4); -}; +function defaultTransform() { + return this.__zoom || identity$8; +} + +var zoom = function() { + var filter = defaultFilter$2, + extent = defaultExtent$1, + k0 = 0, + k1 = Infinity, + x0 = -k1, + x1 = k1, + y0 = x0, + y1 = x1, + duration = 250, + interpolate$$1 = interpolateZoom, + gestures = [], + listeners = dispatch("start", "zoom", "end"), + touchstarting, + touchending, + touchDelay = 500, + wheelDelay = 150; + + function zoom(selection$$1) { + selection$$1 + .on("wheel.zoom", wheeled) + .on("mousedown.zoom", mousedowned) + .on("dblclick.zoom", dblclicked) + .on("touchstart.zoom", touchstarted) + .on("touchmove.zoom", touchmoved) + .on("touchend.zoom touchcancel.zoom", touchended) + .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") + .property("__zoom", defaultTransform); + } -function mercatorProjection(project) { - var m = projection(project), - scale = m.scale, - translate = m.translate, - clipExtent = m.clipExtent, - clipAuto; + zoom.transform = function(collection, transform) { + var selection$$1 = collection.selection ? collection.selection() : collection; + selection$$1.property("__zoom", defaultTransform); + if (collection !== selection$$1) { + schedule(collection, transform); + } else { + selection$$1.interrupt().each(function() { + gesture(this, arguments) + .start() + .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform) + .end(); + }); + } + }; - m.scale = function(_) { - return arguments.length ? (scale(_), clipAuto && m.clipExtent(null), m) : scale(); + zoom.scaleBy = function(selection$$1, k) { + zoom.scaleTo(selection$$1, function() { + var k0 = this.__zoom.k, + k1 = typeof k === "function" ? k.apply(this, arguments) : k; + return k0 * k1; + }); }; - m.translate = function(_) { - return arguments.length ? (translate(_), clipAuto && m.clipExtent(null), m) : translate(); + zoom.scaleTo = function(selection$$1, k) { + zoom.transform(selection$$1, function() { + var e = extent.apply(this, arguments), + t0 = this.__zoom, + p0 = centroid(e), + p1 = t0.invert(p0), + k1 = typeof k === "function" ? k.apply(this, arguments) : k; + return constrain(translate(scale(t0, k1), p0, p1), e); + }); }; - m.clipExtent = function(_) { - if (!arguments.length) return clipAuto ? null : clipExtent(); - if (clipAuto = _ == null) { - var k = pi$4 * scale(), - t = translate(); - _ = [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]]; - } - clipExtent(_); - return m; + zoom.translateBy = function(selection$$1, x, y) { + zoom.transform(selection$$1, function() { + return constrain(this.__zoom.translate( + typeof x === "function" ? x.apply(this, arguments) : x, + typeof y === "function" ? y.apply(this, arguments) : y + ), extent.apply(this, arguments)); + }); }; - return m.clipExtent(null); -} + function scale(transform, k) { + k = Math.max(k0, Math.min(k1, k)); + return k === transform.k ? transform : new Transform(k, transform.x, transform.y); + } -function tany(y) { - return tan((halfPi$3 + y) / 2); -} + function translate(transform, p0, p1) { + var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k; + return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); + } -function conicConformalRaw(y0, y1) { - var cy0 = cos$1(y0), - n = y0 === y1 ? sin$1(y0) : log$1(cy0 / cos$1(y1)) / log$1(tany(y1) / tany(y0)), - f = cy0 * pow$1(tany(y0), n) / n; + function constrain(transform, extent) { + var dx0 = transform.invertX(extent[0][0]) - x0, + dx1 = transform.invertX(extent[1][0]) - x1, + dy0 = transform.invertY(extent[0][1]) - y0, + dy1 = transform.invertY(extent[1][1]) - y1; + return transform.translate( + dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), + dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) + ); + } - if (!n) return mercatorRaw; + function centroid(extent) { + return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; + } - function project(x, y) { - if (f > 0) { if (y < -halfPi$3 + epsilon$4) y = -halfPi$3 + epsilon$4; } - else { if (y > halfPi$3 - epsilon$4) y = halfPi$3 - epsilon$4; } - var r = f / pow$1(tany(y), n); - return [r * sin$1(n * x), f - r * cos$1(n * x)]; + function schedule(transition$$1, transform, center) { + transition$$1 + .on("start.zoom", function() { gesture(this, arguments).start(); }) + .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); }) + .tween("zoom", function() { + var that = this, + args = arguments, + g = gesture(that, args), + e = extent.apply(that, args), + p = center || centroid(e), + w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), + a = that.__zoom, + b = typeof transform === "function" ? transform.apply(that, args) : transform, + i = interpolate$$1(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); + return function(t) { + if (t === 1) t = b; // Avoid rounding error on end. + else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } + g.zoom(null, t); + }; + }); } - project.invert = function(x, y) { - var fy = f - y, r = sign$1(n) * sqrt$1(x * x + fy * fy); - return [atan2(x, abs(fy)) / n * sign$1(fy), 2 * atan(pow$1(f / r, 1 / n)) - halfPi$3]; - }; + function gesture(that, args) { + for (var i = 0, n = gestures.length, g; i < n; ++i) { + if ((g = gestures[i]).that === that) { + return g; + } + } + return new Gesture(that, args); + } - return project; -} + function Gesture(that, args) { + this.that = that; + this.args = args; + this.index = -1; + this.active = 0; + this.extent = extent.apply(that, args); + } -var conicConformal = function() { - return conicProjection(conicConformalRaw) - .scale(109.5) - .parallels([30, 30]); -}; + Gesture.prototype = { + start: function() { + if (++this.active === 1) { + this.index = gestures.push(this) - 1; + this.emit("start"); + } + return this; + }, + zoom: function(key, transform) { + if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]); + if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]); + if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]); + this.that.__zoom = transform; + this.emit("zoom"); + return this; + }, + end: function() { + if (--this.active === 0) { + gestures.splice(this.index, 1); + this.index = -1; + this.emit("end"); + } + return this; + }, + emit: function(type) { + customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]); + } + }; -function equirectangularRaw(lambda, phi) { - return [lambda, phi]; -} + function wheeled() { + if (!filter.apply(this, arguments)) return; + var g = gesture(this, arguments), + t = this.__zoom, + k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500))), + p = mouse(this); -equirectangularRaw.invert = equirectangularRaw; + // If the mouse is in the same location as before, reuse it. + // If there were recent wheel events, reset the wheel idle timeout. + if (g.wheel) { + if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { + g.mouse[1] = t.invert(g.mouse[0] = p); + } + clearTimeout(g.wheel); + } -var equirectangular = function() { - return projection(equirectangularRaw) - .scale(152.63); -}; + // If this wheel event won’t trigger a transform change, ignore it. + else if (t.k === k) return; -function conicEquidistantRaw(y0, y1) { - var cy0 = cos$1(y0), - n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0), - g = cy0 / n + y0; + // Otherwise, capture the mouse point and location at the start. + else { + g.mouse = [p, t.invert(p)]; + interrupt(this); + g.start(); + } - if (abs(n) < epsilon$4) return equirectangularRaw; + noevent$2(); + g.wheel = setTimeout(wheelidled, wheelDelay); + g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent)); - function project(x, y) { - var gy = g - y, nx = n * x; - return [gy * sin$1(nx), g - gy * cos$1(nx)]; + function wheelidled() { + g.wheel = null; + g.end(); + } } - project.invert = function(x, y) { - var gy = g - y; - return [atan2(x, abs(gy)) / n * sign$1(gy), g - sign$1(n) * sqrt$1(x * x + gy * gy)]; - }; + function mousedowned() { + if (touchending || !filter.apply(this, arguments)) return; + var g = gesture(this, arguments), + v = select(exports.event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), + p = mouse(this); - return project; -} + dragDisable(exports.event.view); + nopropagation$2(); + g.mouse = [p, this.__zoom.invert(p)]; + interrupt(this); + g.start(); -var conicEquidistant = function() { - return conicProjection(conicEquidistantRaw) - .scale(131.154) - .center([0, 13.9389]); -}; + function mousemoved() { + noevent$2(); + g.moved = true; + g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent)); + } -function gnomonicRaw(x, y) { - var cy = cos$1(y), k = cos$1(x) * cy; - return [cy * sin$1(x) / k, sin$1(y) / k]; -} + function mouseupped() { + v.on("mousemove.zoom mouseup.zoom", null); + yesdrag(exports.event.view, g.moved); + noevent$2(); + g.end(); + } + } -gnomonicRaw.invert = azimuthalInvert(atan); + function dblclicked() { + if (!filter.apply(this, arguments)) return; + var t0 = this.__zoom, + p0 = mouse(this), + p1 = t0.invert(p0), + k1 = t0.k * (exports.event.shiftKey ? 0.5 : 2), + t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments)); -var gnomonic = function() { - return projection(gnomonicRaw) - .scale(144.049) - .clipAngle(60); -}; + noevent$2(); + if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0); + else select(this).call(zoom.transform, t1); + } -function scaleTranslate(kx, ky, tx, ty) { - return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$7 : transformer({ - point: function(x, y) { - this.stream.point(x * kx + tx, y * ky + ty); - } - }); -} + function touchstarted() { + if (!filter.apply(this, arguments)) return; + var g = gesture(this, arguments), + touches$$1 = exports.event.changedTouches, + started, + n = touches$$1.length, i, t, p; -var identity$8 = function() { - var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$7, // scale, translate and reflect - x0 = null, y0, x1, y1, clip = identity$7, // clip extent - cache, - cacheStream, - projection; + nopropagation$2(); + for (i = 0; i < n; ++i) { + t = touches$$1[i], p = touch(this, touches$$1, t.identifier); + p = [p, this.__zoom.invert(p), t.identifier]; + if (!g.touch0) g.touch0 = p, started = true; + else if (!g.touch1) g.touch1 = p; + } - function reset() { - cache = cacheStream = null; - return projection; - } + // If this is a dbltap, reroute to the (optional) dblclick.zoom handler. + if (touchstarting) { + touchstarting = clearTimeout(touchstarting); + if (!g.touch1) { + g.end(); + p = select(this).on("dblclick.zoom"); + if (p) p.apply(this, arguments); + return; + } + } - return projection = { - stream: function(stream) { - return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream)); - }, - clipExtent: function(_) { - return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$7) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; - }, - scale: function(_) { - return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k; - }, - translate: function(_) { - return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty]; - }, - reflectX: function(_) { - return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0; - }, - reflectY: function(_) { - return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0; - }, - fitExtent: function(extent, object) { - return fitExtent(projection, extent, object); - }, - fitSize: function(size, object) { - return fitSize(projection, size, object); + if (started) { + touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); + interrupt(this); + g.start(); } - }; -}; + } -function orthographicRaw(x, y) { - return [cos$1(y) * sin$1(x), sin$1(y)]; -} + function touchmoved() { + var g = gesture(this, arguments), + touches$$1 = exports.event.changedTouches, + n = touches$$1.length, i, t, p, l; -orthographicRaw.invert = azimuthalInvert(asin$1); + noevent$2(); + if (touchstarting) touchstarting = clearTimeout(touchstarting); + for (i = 0; i < n; ++i) { + t = touches$$1[i], p = touch(this, touches$$1, t.identifier); + if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; + else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; + } + t = g.that.__zoom; + if (g.touch1) { + var p0 = g.touch0[0], l0 = g.touch0[1], + p1 = g.touch1[0], l1 = g.touch1[1], + dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, + dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; + t = scale(t, Math.sqrt(dp / dl)); + p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; + l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; + } + else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; + else return; + g.zoom("touch", constrain(translate(t, p, l), g.extent)); + } -var orthographic = function() { - return projection(orthographicRaw) - .scale(249.5) - .clipAngle(90 + epsilon$4); -}; + function touchended() { + var g = gesture(this, arguments), + touches$$1 = exports.event.changedTouches, + n = touches$$1.length, i, t; -function stereographicRaw(x, y) { - var cy = cos$1(y), k = 1 + cos$1(x) * cy; - return [cy * sin$1(x) / k, sin$1(y) / k]; -} + nopropagation$2(); + if (touchending) clearTimeout(touchending); + touchending = setTimeout(function() { touchending = null; }, touchDelay); + for (i = 0; i < n; ++i) { + t = touches$$1[i]; + if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; + else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; + } + if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; + if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]); + else g.end(); + } -stereographicRaw.invert = azimuthalInvert(function(z) { - return 2 * atan(z); -}); + zoom.filter = function(_) { + return arguments.length ? (filter = typeof _ === "function" ? _ : constant$12(!!_), zoom) : filter; + }; -var stereographic = function() { - return projection(stereographicRaw) - .scale(250) - .clipAngle(142); -}; + zoom.extent = function(_) { + return arguments.length ? (extent = typeof _ === "function" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; + }; -function transverseMercatorRaw(lambda, phi) { - return [log$1(tan((halfPi$3 + phi) / 2)), -lambda]; -} + zoom.scaleExtent = function(_) { + return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1]; + }; -transverseMercatorRaw.invert = function(x, y) { - return [-y, 2 * atan(exp(x)) - halfPi$3]; -}; + zoom.translateExtent = function(_) { + return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]]; + }; -var transverseMercator = function() { - var m = mercatorProjection(transverseMercatorRaw), - center = m.center, - rotate = m.rotate; + zoom.duration = function(_) { + return arguments.length ? (duration = +_, zoom) : duration; + }; - m.center = function(_) { - return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]); + zoom.interpolate = function(_) { + return arguments.length ? (interpolate$$1 = _, zoom) : interpolate$$1; }; - m.rotate = function(_) { - return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]); + zoom.on = function() { + var value = listeners.on.apply(listeners, arguments); + return value === listeners ? zoom : value; }; - return rotate([0, 0, 90]) - .scale(159.155); + return zoom; }; exports.version = version; @@ -16017,6 +16183,7 @@ exports.bisectRight = bisectRight; exports.bisectLeft = bisectLeft; exports.ascending = ascending; exports.bisector = bisector; +exports.cross = cross; exports.descending = descending; exports.deviation = deviation; exports.extent = extent; @@ -16032,7 +16199,7 @@ exports.min = min; exports.pairs = pairs; exports.permute = permute; exports.quantile = threshold; -exports.range = range; +exports.range = sequence; exports.scan = scan; exports.shuffle = shuffle; exports.sum = sum; @@ -16041,19 +16208,42 @@ exports.tickStep = tickStep; exports.transpose = transpose; exports.variance = variance; exports.zip = zip; -exports.entries = entries; +exports.axisTop = axisTop; +exports.axisRight = axisRight; +exports.axisBottom = axisBottom; +exports.axisLeft = axisLeft; +exports.brush = brush; +exports.brushX = brushX; +exports.brushY = brushY; +exports.brushSelection = brushSelection; +exports.chord = chord; +exports.ribbon = ribbon; +exports.nest = nest; +exports.set = set$2; +exports.map = map$1; exports.keys = keys; exports.values = values; -exports.map = map$1; -exports.set = set; -exports.nest = nest; -exports.randomUniform = uniform; -exports.randomNormal = normal; -exports.randomLogNormal = logNormal; -exports.randomBates = bates; -exports.randomIrwinHall = irwinHall; -exports.randomExponential = exponential; -exports.easeLinear = linear; +exports.entries = entries; +exports.color = color; +exports.rgb = rgb; +exports.hsl = hsl; +exports.lab = lab; +exports.hcl = hcl; +exports.cubehelix = cubehelix; +exports.dispatch = dispatch; +exports.drag = drag; +exports.dragDisable = dragDisable; +exports.dragEnable = yesdrag; +exports.dsvFormat = dsv; +exports.csvParse = csvParse; +exports.csvParseRows = csvParseRows; +exports.csvFormat = csvFormat; +exports.csvFormatRows = csvFormatRows; +exports.tsvParse = tsvParse; +exports.tsvParseRows = tsvParseRows; +exports.tsvFormat = tsvFormat; +exports.tsvFormatRows = tsvFormatRows; +exports.easeLinear = linear$1; exports.easeQuad = quadInOut; exports.easeQuadIn = quadIn; exports.easeQuadOut = quadOut; @@ -16090,32 +16280,180 @@ exports.easeElastic = elasticOut; exports.easeElasticIn = elasticIn; exports.easeElasticOut = elasticOut; exports.easeElasticInOut = elasticInOut; -exports.polygonArea = area; -exports.polygonCentroid = centroid; -exports.polygonHull = hull; -exports.polygonContains = contains; -exports.polygonLength = length$1; +exports.forceCenter = center$1; +exports.forceCollide = collide; +exports.forceLink = link; +exports.forceManyBody = manyBody; +exports.forceSimulation = simulation; +exports.forceX = x$2; +exports.forceY = y$2; +exports.formatDefaultLocale = defaultLocale; +exports.formatLocale = formatLocale; +exports.formatSpecifier = formatSpecifier; +exports.precisionFixed = precisionFixed; +exports.precisionPrefix = precisionPrefix; +exports.precisionRound = precisionRound; +exports.geoArea = area; +exports.geoBounds = bounds; +exports.geoCentroid = centroid; +exports.geoCircle = circle; +exports.geoClipExtent = extent$1; +exports.geoContains = contains; +exports.geoDistance = distance; +exports.geoGraticule = graticule; +exports.geoGraticule10 = graticule10; +exports.geoInterpolate = interpolate$1; +exports.geoLength = length$1; +exports.geoPath = index$1; +exports.geoAlbers = albers; +exports.geoAlbersUsa = albersUsa; +exports.geoAzimuthalEqualArea = azimuthalEqualArea; +exports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw; +exports.geoAzimuthalEquidistant = azimuthalEquidistant; +exports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw; +exports.geoConicConformal = conicConformal; +exports.geoConicConformalRaw = conicConformalRaw; +exports.geoConicEqualArea = conicEqualArea; +exports.geoConicEqualAreaRaw = conicEqualAreaRaw; +exports.geoConicEquidistant = conicEquidistant; +exports.geoConicEquidistantRaw = conicEquidistantRaw; +exports.geoEquirectangular = equirectangular; +exports.geoEquirectangularRaw = equirectangularRaw; +exports.geoGnomonic = gnomonic; +exports.geoGnomonicRaw = gnomonicRaw; +exports.geoIdentity = identity$5; +exports.geoProjection = projection; +exports.geoProjectionMutator = projectionMutator; +exports.geoMercator = mercator; +exports.geoMercatorRaw = mercatorRaw; +exports.geoOrthographic = orthographic; +exports.geoOrthographicRaw = orthographicRaw; +exports.geoStereographic = stereographic; +exports.geoStereographicRaw = stereographicRaw; +exports.geoTransverseMercator = transverseMercator; +exports.geoTransverseMercatorRaw = transverseMercatorRaw; +exports.geoRotation = rotation; +exports.geoStream = geoStream; +exports.geoTransform = transform; +exports.cluster = cluster; +exports.hierarchy = hierarchy; +exports.pack = index$2; +exports.packSiblings = siblings; +exports.packEnclose = enclose; +exports.partition = partition; +exports.stratify = stratify; +exports.tree = tree; +exports.treemap = index$3; +exports.treemapBinary = binary; +exports.treemapDice = treemapDice; +exports.treemapSlice = treemapSlice; +exports.treemapSliceDice = sliceDice; +exports.treemapSquarify = squarify; +exports.treemapResquarify = resquarify; +exports.interpolate = interpolateValue; +exports.interpolateArray = array$1; +exports.interpolateBasis = basis$1; +exports.interpolateBasisClosed = basisClosed; +exports.interpolateDate = date; +exports.interpolateNumber = reinterpolate; +exports.interpolateObject = object; +exports.interpolateRound = interpolateRound; +exports.interpolateString = interpolateString; +exports.interpolateTransformCss = interpolateTransformCss; +exports.interpolateTransformSvg = interpolateTransformSvg; +exports.interpolateZoom = interpolateZoom; +exports.interpolateRgb = interpolateRgb; +exports.interpolateRgbBasis = rgbBasis; +exports.interpolateRgbBasisClosed = rgbBasisClosed; +exports.interpolateHsl = hsl$2; +exports.interpolateHslLong = hslLong; +exports.interpolateLab = lab$1; +exports.interpolateHcl = hcl$2; +exports.interpolateHclLong = hclLong; +exports.interpolateCubehelix = cubehelix$2; +exports.interpolateCubehelixLong = cubehelixLong; +exports.quantize = quantize; exports.path = path; +exports.polygonArea = area$1; +exports.polygonCentroid = centroid$1; +exports.polygonHull = hull; +exports.polygonContains = contains$1; +exports.polygonLength = length$2; exports.quadtree = quadtree; exports.queue = queue; +exports.randomUniform = uniform; +exports.randomNormal = normal; +exports.randomLogNormal = logNormal; +exports.randomBates = bates; +exports.randomIrwinHall = irwinHall; +exports.randomExponential = exponential$1; +exports.request = request; +exports.html = html; +exports.json = json; +exports.text = text; +exports.xml = xml; +exports.csv = csv$1; +exports.tsv = tsv$1; +exports.scaleBand = band; +exports.scalePoint = point$1; +exports.scaleIdentity = identity$6; +exports.scaleLinear = linear$2; +exports.scaleLog = log$1; +exports.scaleOrdinal = ordinal; +exports.scaleImplicit = implicit; +exports.scalePow = pow$1; +exports.scaleSqrt = sqrt$1; +exports.scaleQuantile = quantile$$1; +exports.scaleQuantize = quantize$1; +exports.scaleThreshold = threshold$1; +exports.scaleTime = time; +exports.scaleUtc = utcTime; +exports.schemeCategory10 = category10; +exports.schemeCategory20b = category20b; +exports.schemeCategory20c = category20c; +exports.schemeCategory20 = category20; +exports.interpolateCubehelixDefault = cubehelix$3; +exports.interpolateRainbow = rainbow$1; +exports.interpolateWarm = warm; +exports.interpolateCool = cool; +exports.interpolateViridis = viridis; +exports.interpolateMagma = magma; +exports.interpolateInferno = inferno; +exports.interpolatePlasma = plasma; +exports.scaleSequential = sequential; +exports.creator = creator; +exports.local = local$1; +exports.matcher = matcher$1; +exports.mouse = mouse; +exports.namespace = namespace; +exports.namespaces = namespaces; +exports.select = select; +exports.selectAll = selectAll; +exports.selection = selection; +exports.selector = selector; +exports.selectorAll = selectorAll; +exports.touch = touch; +exports.touches = touches; +exports.window = window; +exports.customEvent = customEvent; exports.arc = arc; -exports.area = area$1; +exports.area = area$2; exports.line = line; exports.pie = pie; exports.radialArea = radialArea; exports.radialLine = radialLine$1; exports.symbol = symbol; exports.symbols = symbols; -exports.symbolCircle = circle; -exports.symbolCross = cross$1; +exports.symbolCircle = circle$2; +exports.symbolCross = cross$2; exports.symbolDiamond = diamond; exports.symbolSquare = square; exports.symbolStar = star; exports.symbolTriangle = triangle; exports.symbolWye = wye; -exports.curveBasisClosed = basisClosed; +exports.curveBasisClosed = basisClosed$1; exports.curveBasisOpen = basisOpen; -exports.curveBasis = basis; +exports.curveBasis = basis$2; exports.curveBundle = bundle; exports.curveCardinalClosed = cardinalClosed; exports.curveCardinalOpen = cardinalOpen; @@ -16133,70 +16471,23 @@ exports.curveStepAfter = stepAfter; exports.curveStepBefore = stepBefore; exports.stack = stack; exports.stackOffsetExpand = expand; -exports.stackOffsetNone = none; +exports.stackOffsetNone = none$1; exports.stackOffsetSilhouette = silhouette; exports.stackOffsetWiggle = wiggle; -exports.stackOrderAscending = ascending$1; +exports.stackOrderAscending = ascending$2; exports.stackOrderDescending = descending$2; exports.stackOrderInsideOut = insideOut; -exports.stackOrderNone = none$1; +exports.stackOrderNone = none$2; exports.stackOrderReverse = reverse; -exports.color = color; -exports.rgb = rgb; -exports.hsl = hsl; -exports.lab = lab; -exports.hcl = hcl; -exports.cubehelix = cubehelix; -exports.interpolate = interpolate; -exports.interpolateArray = array$1; -exports.interpolateDate = date; -exports.interpolateNumber = interpolateNumber; -exports.interpolateObject = object; -exports.interpolateRound = interpolateRound; -exports.interpolateString = interpolateString; -exports.interpolateTransformCss = interpolateTransformCss; -exports.interpolateTransformSvg = interpolateTransformSvg; -exports.interpolateZoom = interpolateZoom; -exports.interpolateRgb = interpolateRgb; -exports.interpolateRgbBasis = rgbBasis; -exports.interpolateRgbBasisClosed = rgbBasisClosed; -exports.interpolateHsl = hsl$2; -exports.interpolateHslLong = hslLong; -exports.interpolateLab = lab$1; -exports.interpolateHcl = hcl$2; -exports.interpolateHclLong = hclLong; -exports.interpolateCubehelix = cubehelix$2; -exports.interpolateCubehelixLong = cubehelixLong; -exports.interpolateBasis = basis$2; -exports.interpolateBasisClosed = basisClosed$1; -exports.quantize = quantize; -exports.dispatch = dispatch; -exports.dsvFormat = dsv; -exports.csvParse = csvParse; -exports.csvParseRows = csvParseRows; -exports.csvFormat = csvFormat; -exports.csvFormatRows = csvFormatRows; -exports.tsvParse = tsvParse; -exports.tsvParseRows = tsvParseRows; -exports.tsvFormat = tsvFormat; -exports.tsvFormatRows = tsvFormatRows; -exports.request = request; -exports.html = html; -exports.json = json; -exports.text = text; -exports.xml = xml; -exports.csv = csv$1; -exports.tsv = tsv$1; -exports.now = now; -exports.timer = timer; -exports.timerFlush = timerFlush; -exports.timeout = timeout$1; -exports.interval = interval$1; exports.timeInterval = newInterval; exports.timeMillisecond = millisecond; exports.timeMilliseconds = milliseconds; +exports.utcMillisecond = millisecond; +exports.utcMilliseconds = milliseconds; exports.timeSecond = second; exports.timeSeconds = seconds; +exports.utcSecond = second; +exports.utcSeconds = seconds; exports.timeMinute = minute; exports.timeMinutes = minutes; exports.timeHour = hour; @@ -16223,10 +16514,6 @@ exports.timeMonth = month; exports.timeMonths = months; exports.timeYear = year; exports.timeYears = years; -exports.utcMillisecond = millisecond; -exports.utcMilliseconds = milliseconds; -exports.utcSecond = second; -exports.utcSeconds = seconds; exports.utcMinute = utcMinute; exports.utcMinutes = utcMinutes; exports.utcHour = utcHour; @@ -16253,1145 +16540,1026 @@ exports.utcMonth = utcMonth; exports.utcMonths = utcMonths; exports.utcYear = utcYear; exports.utcYears = utcYears; -exports.formatLocale = formatLocale; -exports.formatDefaultLocale = defaultLocale; -exports.formatSpecifier = formatSpecifier; -exports.precisionFixed = precisionFixed; -exports.precisionPrefix = precisionPrefix; -exports.precisionRound = precisionRound; -exports.isoFormat = formatIso; -exports.isoParse = parseIso; -exports.timeFormatLocale = formatLocale$1; exports.timeFormatDefaultLocale = defaultLocale$1; -exports.scaleBand = band; -exports.scalePoint = point$4; -exports.scaleIdentity = identity$4; -exports.scaleLinear = linear$2; -exports.scaleLog = log; -exports.scaleOrdinal = ordinal; -exports.scaleImplicit = implicit; -exports.scalePow = pow; -exports.scaleSqrt = sqrt; -exports.scaleQuantile = quantile$$1; -exports.scaleQuantize = quantize$1; -exports.scaleThreshold = threshold$1; -exports.scaleTime = time; -exports.scaleUtc = utcTime; -exports.schemeCategory10 = category10; -exports.schemeCategory20b = category20b; -exports.schemeCategory20c = category20c; -exports.schemeCategory20 = category20; -exports.scaleSequential = sequential; -exports.interpolateCubehelixDefault = cubehelix$3; -exports.interpolateRainbow = rainbow$1; -exports.interpolateWarm = warm; -exports.interpolateCool = cool; -exports.interpolateViridis = viridis; -exports.interpolateMagma = magma; -exports.interpolateInferno = inferno; -exports.interpolatePlasma = plasma; -exports.creator = creator; -exports.customEvent = customEvent; -exports.local = local; -exports.matcher = matcher$1; -exports.mouse = mouse; -exports.namespace = namespace; -exports.namespaces = namespaces; -exports.select = select; -exports.selectAll = selectAll; -exports.selection = selection; -exports.selector = selector; -exports.selectorAll = selectorAll; -exports.touch = touch; -exports.touches = touches; -exports.window = window; -exports.active = active; -exports.interrupt = interrupt; -exports.transition = transition; -exports.axisTop = axisTop; -exports.axisRight = axisRight; -exports.axisBottom = axisBottom; -exports.axisLeft = axisLeft; -exports.cluster = cluster; -exports.hierarchy = hierarchy; -exports.pack = index; -exports.packSiblings = siblings; -exports.packEnclose = enclose; -exports.partition = partition; -exports.stratify = stratify; -exports.tree = tree; -exports.treemap = index$1; -exports.treemapBinary = binary; -exports.treemapDice = treemapDice; -exports.treemapSlice = treemapSlice; -exports.treemapSliceDice = sliceDice; -exports.treemapSquarify = squarify; -exports.treemapResquarify = resquarify; -exports.forceCenter = center$1; -exports.forceCollide = collide; -exports.forceLink = link; -exports.forceManyBody = manyBody; -exports.forceSimulation = simulation; -exports.forceX = x$3; -exports.forceY = y$3; -exports.drag = drag; -exports.dragDisable = dragDisable; -exports.dragEnable = yesdrag; -exports.voronoi = voronoi; -exports.zoom = zoom; -exports.zoomIdentity = identity$6; -exports.zoomTransform = transform; -exports.brush = brush; -exports.brushX = brushX; -exports.brushY = brushY; -exports.brushSelection = brushSelection; -exports.chord = chord; -exports.ribbon = ribbon; -exports.geoAlbers = albers; -exports.geoAlbersUsa = albersUsa; -exports.geoArea = area$2; -exports.geoAzimuthalEqualArea = azimuthalEqualArea; -exports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw; -exports.geoAzimuthalEquidistant = azimuthalEquidistant; -exports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw; -exports.geoBounds = bounds; -exports.geoCentroid = centroid$1; -exports.geoCircle = circle$1; -exports.geoClipExtent = extent$1; -exports.geoConicConformal = conicConformal; -exports.geoConicConformalRaw = conicConformalRaw; -exports.geoConicEqualArea = conicEqualArea; -exports.geoConicEqualAreaRaw = conicEqualAreaRaw; -exports.geoConicEquidistant = conicEquidistant; -exports.geoConicEquidistantRaw = conicEquidistantRaw; -exports.geoDistance = distance; -exports.geoEquirectangular = equirectangular; -exports.geoEquirectangularRaw = equirectangularRaw; -exports.geoGnomonic = gnomonic; -exports.geoGnomonicRaw = gnomonicRaw; -exports.geoGraticule = graticule; -exports.geoGraticule10 = graticule10; -exports.geoIdentity = identity$8; -exports.geoInterpolate = interpolate$2; -exports.geoLength = length$2; -exports.geoMercator = mercator; -exports.geoMercatorRaw = mercatorRaw; -exports.geoOrthographic = orthographic; -exports.geoOrthographicRaw = orthographicRaw; -exports.geoPath = index$3; -exports.geoProjection = projection; -exports.geoProjectionMutator = projectionMutator; -exports.geoRotation = rotation; -exports.geoStereographic = stereographic; -exports.geoStereographicRaw = stereographicRaw; -exports.geoStream = geoStream; -exports.geoTransform = transform$1; -exports.geoTransverseMercator = transverseMercator; -exports.geoTransverseMercatorRaw = transverseMercatorRaw; - -Object.defineProperty(exports, '__esModule', { value: true }); - -}))); - -},{}],2:[function(require,module,exports){ -// Copyright © 2016 RTE Réseau de transport d’électricité -(function() { - 'use strict'; - - var d3 = require("d3"); - var Chart = require("./chart.js"); - - module.exports = Barchart; - - // Barchart inherits from Chart - Barchart.prototype = Object.create(Chart.prototype); - Barchart.prototype.constructor = Barchart; - - /** - * @class Barchart - * @summary Represent data with a barchart - * @desc Barcharts are polyvalent charts that should be used most of the time. - * In a barchart individual value are visually easy to compare because the - * human eye is good at comparing lengths. Moreover barcharts can represent - * negative values while polar charts can only represent positive values; - * @param {string} el CSS selector representing the element that will hold the chart. - * @param {number[]} data Data the chart has to represent. - * @param {BarchartOptions} options Options controling graphical aspects of the chart. - */ - - /** @typedef {object} BarchartOptions - * @memberOf Barchart - * @prop {number|"auto"} [minValue="auto"] Minimum value data could take. It - * is important to set this option explicitely if one wants to compare - * charts and use the same scale on each one. By default `minValue` equals to 0 - * if all data values are positive or the minimum value if some values are - * negative. - * @prop {number|"auto"} [maxValue="auto"] Maximum value data could take.It - * is important to set this option explicitely if one wants to compare - * charts and use the same scale on each one. By default it equals to 0 if all - * values are negative or to maximmum value if some value is positive. - * @prop {number} [width=60] Width of the chart. - * @prop {number} [height=60] Height of the chart. - * @prop {number} [transitionTime=750] Duration of the transitions, in milliseconds. - * @prop {string[]|function}[colors=d3.schemeCategory10] Either an array of - * colors or a function `(d, i) -> color` where `d` is a data value and `i` - * is the index of the value.If it is an array with length less than the length - * of data, then the colors are recycled. - * @prop {string[]|"none"|"auto"|function}[labels="none"] Labels to display in bars. - * It can be an array with same length as the data. It can also be a function - * `(d, i) -> labelText` where `d` is a data value and `i` - * is the index of the value. Finally it can be equal to "none" to hide labels - * or "auto" to display in a compact way values. - * @prop {string|string[]|"auto"|function}[labelColors="auto"] Color of the labels. - * It can be a single value or an array with same length as the data. It can - * also be a function `(d, i) -> color` where `d` is a data value and `i` - * is the index of the value. Finally it can be equal to "auto". In this case, - * the most readable color is choosen depding on the color of the bar. - * @prop {number}[labelMinSize=8] Label minimum size in pixels. If there is - * not enough space for a given label, then it is hidden. - * @prop {number}[labelMaxSize=24] Label maximum size in pixels. - * @prop {number}[labelPadding=2] Padding to apply to apply to labels. - * @prop {string}[labelClass=""] Labels CSS class. - * @prop {string}[shapeClass=""] bars CSS class. - * @prop {string}[zeroLineStyle="stroke:#333;stroke-width:1;"] CSS style of the - * line representing the zero value. - */ - - /** @method setData - * @desc Update the data represented by the chart - * @instance - * @memberOf Barchart - * @param {number[]} data Data the chart has to represent. - */ - - /** @method setOptions - * @desc Update the graphical options of a chart - * @instance - * @memberOf Barchart - * @param {BarchartOptions} options Options controling graphical aspects of the chart. - */ - - /** @method update - * @desc Update simulatenously data and options of a barchart. - * @instance - * @memberOf Barchart - * @param {number[]} data Data the chart has to represent. - * @param {BarchartOptions} options Options controling graphical aspects of the chart. - */ - function Barchart(el, data, options) { - // Default options - var defaults = { - minValue: "auto", - maxValue: "auto", - zeroLineStyle: "stroke:#333;stroke-width:1;" - }; - - // Call super constructor - Chart.call(this, el, data, options, defaults); - - // Initialize the zero line - var scaleFun = d3.scaleLinear() - .domain([this._options.minValue, this._options.maxValue]) - .range([this._options.height, 0]); - - this._zeroLine = this._container.append("line") - .attr("x1", 0) - .attr("y1", scaleFun(0)) - .attr("x2", this._options.width) - .attr("y2", scaleFun(0)) - .attr("style", this._options.zeroLineStyle); - - this._draw(); - } - - // See comments in chart.js - Barchart.prototype._processOptions = function(options) { - options = Chart.prototype._processOptions.call(this, options, this._options); - - // Set min value and max value if necessary. - if (options.minValue === "auto") { - var min = d3.min(this._data); - var max = options.maxValue === "auto"? d3.max(this._data): options.maxValue; - - if (max > 0 && min > 0) options.minValue = 0; - else options.minValue = min; - } - - if (options.maxValue === "auto") { - var max = options.minValue === "auto"? d3.min(this._data): options.minValue; - var max = d3.max(this._data); - - if (max < 0 && min < 0) options.maxValue = 0; - else options.maxValue = max; - } - - return options; - }; - - // See comments in chart.js - Barchart.prototype._draw = function() { - var self = this; - Chart.prototype._draw.call(this); - - var barWidth = (self._options.width - 6) / self._data.length; - var scaleFun = d3.scaleLinear() - .domain([self._options.minValue, self._options.maxValue]) - .range([self._options.height, 0]); - - // Update the zero line - self._zeroLine - .transition() - .duration(self._options.transitionTime) - .attr("x1", 0) - .attr("y1", scaleFun(0)) - .attr("x2", self._options.width) - .attr("y2", scaleFun(0)) - .attr("style", self._options.zeroLineStyle); - - // Update bars - var bar = self._chart.selectAll("path").data(self._data); - // Add new bars - function rectPath(x, y, w, h) { - return ("M" + x + " " + y + "l" + w + " 0l0 " + h + "l" + (-w) + " 0Z") - } - - bar.enter() - .append("path") - .attr("d", function(d, i) {return rectPath((i + 1) * barWidth + 3, scaleFun(0), 0, 0)}) - // Update bars - .merge(bar) - .attr("class", self._options.shapeClass) - .transition() - .duration(self._options.transitionTime) - .attr("d", function(d, i) {return rectPath(i * barWidth + 3, scaleFun(0), barWidth, scaleFun(d) - scaleFun(0))}) - .attr("fill", self._options.colorFun); - // Remove bars - bar.exit() - .transition() - .duration(self._options.transitionTime) - .attr("x", function(d, i) {return i * barWidth + 3;}) - .attr("y", 0) - .attr("width", 0) - .attr("height", 0) - .remove(); - - // Add/ update labels - function initLabel(label, d, i) { - label.fillRect( - i * barWidth + 3, scaleFun(0), - barWidth, 0, - self._options.labelPadding, - "center", d >= 0? "top": "bottom", - 0 - ); - } +exports.timeFormatLocale = formatLocale$1; +exports.isoFormat = formatIso; +exports.isoParse = parseIso; +exports.now = now; +exports.timer = timer; +exports.timerFlush = timerFlush; +exports.timeout = timeout$1; +exports.interval = interval$1; +exports.transition = transition; +exports.active = active; +exports.interrupt = interrupt; +exports.voronoi = voronoi; +exports.zoom = zoom; +exports.zoomTransform = transform$1; +exports.zoomIdentity = identity$8; - function updateLabel(label, d, i) { - label.fillRect( - i * barWidth + 3, d >= 0? scaleFun(d) : scaleFun(0), - barWidth, Math.abs(scaleFun(d) - scaleFun(0)), - self._options.labelPadding, - "center", d >= 0? "top": "bottom", - self._options.transitionTime); - } +Object.defineProperty(exports, '__esModule', { value: true }); - this._drawLabels(initLabel, updateLabel); - } +}))); -}()); +},{}],2:[function(require,module,exports){ +// Copyright © 2016 RTE Réseau de transport d’électricité +(function() { + 'use strict'; + + var d3 = require("d3"); + var Chart = require("./chart.js"); + + module.exports = Barchart; + + // Barchart inherits from Chart + Barchart.prototype = Object.create(Chart.prototype); + Barchart.prototype.constructor = Barchart; + + /** + * @class Barchart + * @summary Represent data with a barchart + * @desc Barcharts are polyvalent charts that should be used most of the time. + * In a barchart individual value are visually easy to compare because the + * human eye is good at comparing lengths. Moreover barcharts can represent + * negative values while polar charts can only represent positive values; + * @param {string} el CSS selector representing the element that will hold the chart. + * @param {number[]} data Data the chart has to represent. + * @param {BarchartOptions} options Options controling graphical aspects of the chart. + */ + + /** @typedef {object} BarchartOptions + * @memberOf Barchart + * @prop {number|"auto"} [minValue="auto"] Minimum value data could take. It + * is important to set this option explicitely if one wants to compare + * charts and use the same scale on each one. By default `minValue` equals to 0 + * if all data values are positive or the minimum value if some values are + * negative. + * @prop {number|"auto"} [maxValue="auto"] Maximum value data could take.It + * is important to set this option explicitely if one wants to compare + * charts and use the same scale on each one. By default it equals to 0 if all + * values are negative or to maximmum value if some value is positive. + * @prop {number} [width=60] Width of the chart. + * @prop {number} [height=60] Height of the chart. + * @prop {number} [transitionTime=750] Duration of the transitions, in milliseconds. + * @prop {string[]|function}[colors=d3.schemeCategory10] Either an array of + * colors or a function `(d, i) -> color` where `d` is a data value and `i` + * is the index of the value.If it is an array with length less than the length + * of data, then the colors are recycled. + * @prop {string[]|"none"|"auto"|function}[labels="none"] Labels to display in bars. + * It can be an array with same length as the data. It can also be a function + * `(d, i) -> labelText` where `d` is a data value and `i` + * is the index of the value. Finally it can be equal to "none" to hide labels + * or "auto" to display in a compact way values. + * @prop {string|string[]|"auto"|function}[labelColors="auto"] Color of the labels. + * It can be a single value or an array with same length as the data. It can + * also be a function `(d, i) -> color` where `d` is a data value and `i` + * is the index of the value. Finally it can be equal to "auto". In this case, + * the most readable color is choosen depding on the color of the bar. + * @prop {number}[labelMinSize=8] Label minimum size in pixels. If there is + * not enough space for a given label, then it is hidden. + * @prop {number}[labelMaxSize=24] Label maximum size in pixels. + * @prop {number}[labelPadding=2] Padding to apply to apply to labels. + * @prop {string}[labelClass=""] Labels CSS class. + * @prop {string}[shapeClass=""] bars CSS class. + * @prop {string}[zeroLineStyle="stroke:#333;stroke-width:1;"] CSS style of the + * line representing the zero value. + */ + + /** @method setData + * @desc Update the data represented by the chart + * @instance + * @memberOf Barchart + * @param {number[]} data Data the chart has to represent. + */ + + /** @method setOptions + * @desc Update the graphical options of a chart + * @instance + * @memberOf Barchart + * @param {BarchartOptions} options Options controling graphical aspects of the chart. + */ + + /** @method update + * @desc Update simulatenously data and options of a barchart. + * @instance + * @memberOf Barchart + * @param {number[]} data Data the chart has to represent. + * @param {BarchartOptions} options Options controling graphical aspects of the chart. + */ + function Barchart(el, data, options) { + // Default options + var defaults = { + minValue: "auto", + maxValue: "auto", + zeroLineStyle: "stroke:#333;stroke-width:1;" + }; + + // Call super constructor + Chart.call(this, el, data, options, defaults); + + // Initialize the zero line + var scaleFun = d3.scaleLinear() + .domain([this._options.minValue, this._options.maxValue]) + .range([this._options.height, 0]); + + this._zeroLine = this._container.append("line") + .attr("x1", 0) + .attr("y1", scaleFun(0)) + .attr("x2", this._options.width) + .attr("y2", scaleFun(0)) + .attr("style", this._options.zeroLineStyle); + + this._draw(); + } + + // See comments in chart.js + Barchart.prototype._processOptions = function(options) { + options = Chart.prototype._processOptions.call(this, options, this._options); + + // Set min value and max value if necessary. + if (options.minValue === "auto") { + var min = d3.min(this._data); + var max = options.maxValue === "auto"? d3.max(this._data): options.maxValue; + + if (max > 0 && min > 0) options.minValue = 0; + else options.minValue = min; + } + + if (options.maxValue === "auto") { + var max = options.minValue === "auto"? d3.min(this._data): options.minValue; + var max = d3.max(this._data); + + if (max < 0 && min < 0) options.maxValue = 0; + else options.maxValue = max; + } + + return options; + }; + + // See comments in chart.js + Barchart.prototype._draw = function() { + var self = this; + Chart.prototype._draw.call(this); + + var barWidth = (self._options.width - 6) / self._data.length; + var scaleFun = d3.scaleLinear() + .domain([self._options.minValue, self._options.maxValue]) + .range([self._options.height, 0]); + + // Update the zero line + self._zeroLine + .transition() + .duration(self._options.transitionTime) + .attr("x1", 0) + .attr("y1", scaleFun(0)) + .attr("x2", self._options.width) + .attr("y2", scaleFun(0)) + .attr("style", self._options.zeroLineStyle); + + // Update bars + var bar = self._chart.selectAll("path").data(self._data); + // Add new bars + function rectPath(x, y, w, h) { + return ("M" + x + " " + y + "l" + w + " 0l0 " + h + "l" + (-w) + " 0Z") + } + + bar.enter() + .append("path") + .attr("d", function(d, i) {return rectPath((i + 1) * barWidth + 3, scaleFun(0), 0, 0)}) + // Update bars + .merge(bar) + .attr("class", self._options.shapeClass) + .transition() + .duration(self._options.transitionTime) + .attr("d", function(d, i) {return rectPath(i * barWidth + 3, scaleFun(0), barWidth, scaleFun(d) - scaleFun(0))}) + .attr("fill", self._options.colorFun); + // Remove bars + bar.exit() + .transition() + .duration(self._options.transitionTime) + .attr("x", function(d, i) {return i * barWidth + 3;}) + .attr("y", 0) + .attr("width", 0) + .attr("height", 0) + .remove(); + + // Add/ update labels + function initLabel(label, d, i) { + label.fillRect( + i * barWidth + 3, scaleFun(0), + barWidth, 0, + self._options.labelPadding, + "center", d >= 0? "top": "bottom", + 0 + ); + } + + function updateLabel(label, d, i) { + label.fillRect( + i * barWidth + 3, d >= 0? scaleFun(d) : scaleFun(0), + barWidth, Math.abs(scaleFun(d) - scaleFun(0)), + self._options.labelPadding, + "center", d >= 0? "top": "bottom", + self._options.transitionTime); + } + + this._drawLabels(initLabel, updateLabel); + } + +}()); },{"./chart.js":3,"d3":1}],3:[function(require,module,exports){ -// Copyright © 2016 RTE Réseau de transport d’électricité -(function() { - 'use strict'; - - var d3 = require("d3"); - var tinycolor = require("tinycolor2"); - var utils = require("./utils.js"); - var Label = require("./label.js") - - module.exports = Chart; - - /* @class Chart - * Abstract class inherited by other classes - * @param{string} el - * @param{number[]} data - * @param {object} options - * @param {object} defaults - * - */ - function Chart(el, data, options, defaults) { - this._data = data; - - // Merge options with default options of this class and of the child class - /** - * @prop {number} [height=60] width - * @prop {number} [width=60] height - * @prop {number} [transitionTime=750] transitionTime - * @prop {string[]|function} [colors=d3.schemeCategory10] colors - * @prop {string[]|"none"|"auto"|function} [labels="none"] labels - * @prop {string[]|"auto"|function} [labelColors="auto"] labelColors - * @prop {number} [labelMinSize=8] labelMinSize - * @prop {number} [labelMaxSize=24] labelMaxSize - * @prop {number} [labelPadding=2] labelPadding - * @prop {labelClass} [labelClass=""]labelClass - * @prop {shapeClass} [shapeClass=""] shapeClass - */ - this._options = { - width:60, - height: 60, - transitionTime: 750, - colors: d3.schemeCategory10, - labels: "none", - labelColors: "auto", - labelMinSize: 8, - labelMaxSize: 24, - labelPadding: 2, - labelClass: "", - shapeClass: "" - }; - this._options = utils.mergeOptions(this._options, defaults || {}); - this._options = this._processOptions(options); - - // Remove everything in the container and create required elements - d3.select(el).select("*").remove(); - this._container = d3.select(el).append("svg") - .attr("width", this._options.width) - .attr("height", this._options.height); - this._chart = this._container.append("g"); - } - - /* Update data and options of a chart - * - */ - Chart.prototype.update = function(data, options) { - this._data = data; - this._options = this._processOptions(options); - this._draw(); - }; - - Chart.prototype.setOptions = function(options) { - this._options = this._processOptions(options); - this._draw(); - }; - - Chart.prototype.setData = function(data) { - this._data = data; - this._draw(); - }; - - Chart.prototype._draw = function() { - var self = this; - // Update container size - self._container - .transition() - .duration(self._options.transitionTime) - .attr("width", self._options.width) - .attr("height", self._options.height); - }; - - Chart.prototype._processOptions = function(options) { - options = utils.mergeOptions(options, this._options); - - // Convert parameters colors, labels and labelColors to functions - options.colorFun = utils.toFunction(options.colors); - options.labelClass = utils.toFunction(options.labelClass); - options.shapeClass = utils.toFunction(options.shapeClass); - - if (options.labels === "none") { - options.labelText = null; - } else if (options.labels === "auto") { - options.labelText = utils.prettyNumber; - } else { - options.labelText = utils.toFunction(options.labels); - } - - if (options.labelColors === "auto") { - options.labelColorFun = function(d, i) { - return tinycolor.mostReadable(options.colorFun(d, i), ["white", "black"])._originalInput - }; - } else { - options.labelColorFun = utils.toFunction(options.labelColorFun); - } - - return options; - } - - Chart.prototype._drawLabels = function(initFun, updateFun) { - var self = this; - - if (self._options.labels === "none") { - self._chart.selectAll(".labels-container").remove(); - return; - } - - - self._labels = self._chart.selectAll(".labels-container").data(self._data); - self._labels.enter() - .append("g") - .attr("class", "labels-container") - .each(function(d, i) { - this._label = new Label(this, self._options.labelStyle, self._options.labelColorFun(d, i), - self._options.labelMinSize, self._options.labelMaxSize); - this._label.updateText(self._options.labelText(d, i)) - initFun(this._label, d, i); - }) - - .merge(self._labels) - .each(function(d, i) { - this._label.updateText(self._options.labelText(d, i)); - this._label._text - .attr("fill", self._options.labelColorFun(d, i)) - .attr("class", self._options.labelClass(d, i)); - updateFun(this._label, d, i); - }); - - self._labels.exit().remove(); - } - -}()); +// Copyright © 2016 RTE Réseau de transport d’électricité +(function() { + 'use strict'; + + var d3 = require("d3"); + var tinycolor = require("tinycolor2"); + var utils = require("./utils.js"); + var Label = require("./label.js") + + module.exports = Chart; + + /* @class Chart + * Abstract class inherited by other classes + * @param{string} el + * @param{number[]} data + * @param {object} options + * @param {object} defaults + * + */ + function Chart(el, data, options, defaults) { + this._data = data; + + // Merge options with default options of this class and of the child class + /** + * @prop {number} [height=60] width + * @prop {number} [width=60] height + * @prop {number} [transitionTime=750] transitionTime + * @prop {string[]|function} [colors=d3.schemeCategory10] colors + * @prop {string[]|"none"|"auto"|function} [labels="none"] labels + * @prop {string[]|"auto"|function} [labelColors="auto"] labelColors + * @prop {number} [labelMinSize=8] labelMinSize + * @prop {number} [labelMaxSize=24] labelMaxSize + * @prop {number} [labelPadding=2] labelPadding + * @prop {labelClass} [labelClass=""]labelClass + * @prop {shapeClass} [shapeClass=""] shapeClass + */ + this._options = { + width:60, + height: 60, + transitionTime: 750, + colors: d3.schemeCategory10, + labels: "none", + labelColors: "auto", + labelMinSize: 8, + labelMaxSize: 24, + labelPadding: 2, + labelClass: "", + shapeClass: "" + }; + this._options = utils.mergeOptions(this._options, defaults || {}); + this._options = this._processOptions(options); + + // Remove everything in the container and create required elements + d3.select(el).select("*").remove(); + this._container = d3.select(el).append("svg") + .attr("width", this._options.width) + .attr("height", this._options.height); + this._chart = this._container.append("g"); + } + + /* Update data and options of a chart + * + */ + Chart.prototype.update = function(data, options) { + this._data = data; + this._options = this._processOptions(options); + this._draw(); + }; + + Chart.prototype.setOptions = function(options) { + this._options = this._processOptions(options); + this._draw(); + }; + + Chart.prototype.setData = function(data) { + this._data = data; + this._draw(); + }; + + Chart.prototype._draw = function() { + var self = this; + // Update container size + self._container + .transition() + .duration(self._options.transitionTime) + .attr("width", self._options.width) + .attr("height", self._options.height); + }; + + Chart.prototype._processOptions = function(options) { + options = utils.mergeOptions(options, this._options); + + // Convert parameters colors, labels and labelColors to functions + options.colorFun = utils.toFunction(options.colors); + options.labelClass = utils.toFunction(options.labelClass); + options.shapeClass = utils.toFunction(options.shapeClass); + + if (options.labels === "none") { + options.labelText = null; + } else if (options.labels === "auto") { + options.labelText = utils.prettyNumber; + } else { + options.labelText = utils.toFunction(options.labels); + } + + if (options.labelColors === "auto") { + options.labelColorFun = function(d, i) { + return tinycolor.mostReadable(options.colorFun(d, i), ["white", "black"])._originalInput + }; + } else { + options.labelColorFun = utils.toFunction(options.labelColorFun); + } + + return options; + } + + Chart.prototype._drawLabels = function(initFun, updateFun) { + var self = this; + + if (self._options.labels === "none") { + self._chart.selectAll(".labels-container").remove(); + return; + } + + + self._labels = self._chart.selectAll(".labels-container").data(self._data); + self._labels.enter() + .append("g") + .attr("class", "labels-container") + .each(function(d, i) { + this._label = new Label(this, self._options.labelStyle, self._options.labelColorFun(d, i), + self._options.labelMinSize, self._options.labelMaxSize); + this._label.updateText(self._options.labelText(d, i)) + initFun(this._label, d, i); + }) + + .merge(self._labels) + .each(function(d, i) { + this._label.updateText(self._options.labelText(d, i)); + this._label._text + .attr("fill", self._options.labelColorFun(d, i)) + .attr("class", self._options.labelClass(d, i)); + updateFun(this._label, d, i); + }); + + self._labels.exit().remove(); + } + +}()); },{"./label.js":5,"./utils.js":9,"d3":1,"tinycolor2":10}],4:[function(require,module,exports){ -// Copyright © 2016 RTE Réseau de transport d’électricité -(function() { - 'use strict'; - - module.exports.Point = Point; - module.exports.Line = Line; - module.exports.intersectionOfTwoLines = intersectionOfTwoLines; - module.exports.intersectionLineAndCircle = intersectionLineAndCircle; - module.exports.pointInSegment = pointInSegment; - module.exports.intersectionLineRadius = intersectionLineRadius ; - module.exports.distance = distance; - - function Point(x, y) { - this.x = x; - this.y = y; - } - - function Line(a, b) { - this.a = a; - this.b = b - } - Line.prototype.getY = function(x) { - return this.a + this.b * x; - } - - function intersectionOfTwoLines(l1, l2) { - if (l1.b == l2.b) return [] - return [new Point( - (l2.a - l1.a) / (l1.b - l2.b), - (l1.b * l2.a - l1.a * l2.b) / (l1.b - l2.b) - )] - } - - function intersectionLineRadius(l, angle, radius) { - var l2 = new Line(0, Math.tan(angle)); - var intersect = intersectionOfTwoLines(l, l2); - var s1 = new Point(0, 0); - var s2 = new Point(radius * Math.cos(angle), radius * Math.sin(angle)); - - if (intersect.length == 0 || !pointInSegment(intersect[0], s1, s2)) { - return []; - } else { - return intersect; - } - } - - function intersectionLineAndCircle(l, r) { - var x = solveEqSecondDegree(l.b * l.b + 1, 2 * l.a * l.b, l.a * l.a - r * r); - return x.map(function(x) {return new Point(x, l.getY(x))}); - } - - // Is point p inside the segment defined by s1 and s2. It is assumed that the - // three points are aligned. - function pointInSegment(p, s1, s2) { - var kp = dotProd(pointDiff(s2, s1), pointDiff(p, s1)); - var ks = dotProd(pointDiff(s2, s1), pointDiff(s2, s1)); - return kp >= 0 && kp <= ks; - } - - function pointDiff(p1, p2) { - return new Point(p1.x - p2.x, p1.y - p2.y); - } - - function dotProd(p1, p2) { - return p1.x * p2.x + p1.y * p2.y; - } - - function solveEqSecondDegree(a, b, c) { - var det = b * b - 4 * a * c - if (det < 0) return []; - if (det == 0) return [(- b) / (2 * a)]; - else return [ - (-b - Math.sqrt(det)) / (2 * a), - (-b + Math.sqrt(det)) / (2 * a) - ] - } - - function distance(p1, p2) { - return Math.sqrt( Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)) - } -}()); +// Copyright © 2016 RTE Réseau de transport d’électricité +(function() { + 'use strict'; + + module.exports.Point = Point; + module.exports.Line = Line; + module.exports.intersectionOfTwoLines = intersectionOfTwoLines; + module.exports.intersectionLineAndCircle = intersectionLineAndCircle; + module.exports.pointInSegment = pointInSegment; + module.exports.intersectionLineRadius = intersectionLineRadius ; + module.exports.distance = distance; + + function Point(x, y) { + this.x = x; + this.y = y; + } + + function Line(a, b) { + this.a = a; + this.b = b + } + Line.prototype.getY = function(x) { + return this.a + this.b * x; + } + + function intersectionOfTwoLines(l1, l2) { + if (l1.b == l2.b) return [] + return [new Point( + (l2.a - l1.a) / (l1.b - l2.b), + (l1.b * l2.a - l1.a * l2.b) / (l1.b - l2.b) + )] + } + + function intersectionLineRadius(l, angle, radius) { + var l2 = new Line(0, Math.tan(angle)); + var intersect = intersectionOfTwoLines(l, l2); + var s1 = new Point(0, 0); + var s2 = new Point(radius * Math.cos(angle), radius * Math.sin(angle)); + + if (intersect.length == 0 || !pointInSegment(intersect[0], s1, s2)) { + return []; + } else { + return intersect; + } + } + + function intersectionLineAndCircle(l, r) { + var x = solveEqSecondDegree(l.b * l.b + 1, 2 * l.a * l.b, l.a * l.a - r * r); + return x.map(function(x) {return new Point(x, l.getY(x))}); + } + + // Is point p inside the segment defined by s1 and s2. It is assumed that the + // three points are aligned. + function pointInSegment(p, s1, s2) { + var kp = dotProd(pointDiff(s2, s1), pointDiff(p, s1)); + var ks = dotProd(pointDiff(s2, s1), pointDiff(s2, s1)); + return kp >= 0 && kp <= ks; + } + + function pointDiff(p1, p2) { + return new Point(p1.x - p2.x, p1.y - p2.y); + } + + function dotProd(p1, p2) { + return p1.x * p2.x + p1.y * p2.y; + } + + function solveEqSecondDegree(a, b, c) { + var det = b * b - 4 * a * c + if (det < 0) return []; + if (det == 0) return [(- b) / (2 * a)]; + else return [ + (-b - Math.sqrt(det)) / (2 * a), + (-b + Math.sqrt(det)) / (2 * a) + ] + } + + function distance(p1, p2) { + return Math.sqrt( Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)) + } +}()); },{}],5:[function(require,module,exports){ -// Copyright © 2016 RTE Réseau de transport d’électricité -(function() { - 'use strict'; - - var d3 = require("d3"); - var g = require("./geometry.js") - - module.exports = Label; - - function Label(el, style, color, minSize, maxSize) { - this._el = el; - this._minSize = minSize; - this._maxSize = maxSize; - this._container = d3.select(el); - this._label = this._container.append("g") - .attr("class", "label"); - - this._text = this._label.append("text") - .attr("dy", "0.35em") - .attr("text-anchor", "middle") - .attr("style", style || "") - .attr("fill", color || "black"); - } - - // Size of the label before scaling - Label.prototype.innerSize = function() { - return this._text.node().getBBox(); - } - - Label.prototype.size = function() { - var bbox = this.innerSize(); - return { - width: bbox.width * this._scale, - height: bbox.height * this._scale - } - } - - Label.prototype.updateText = function(newText) { - // New label should fit in the old bounding bbox - var oldSize = this.size(); - this._text.text(newText); - var newSize = this.size(); - - var scale = Math.min( - oldSize.width / newSize.width, - oldSize.height / newSize.height - ); - this.updateScale(this._scale * scale, 0); - return this; - } - - Label.prototype.updatePosition = function(x, y, transitionTime) { - this._container - .transition() - .duration(transitionTime || 0) - .attr("transform", "translate(" + x + "," + y + ")"); - return this; - } - - Label.prototype.updateScale = function(newScale, transitionTime) { - if (!newScale || isNaN(newScale) || !isFinite(newScale)) { - newScale = 0; - } - var newHeight = this.innerSize().height * newScale; - if (this._minSize && newHeight < this._minSize) { - newScale = 0; - } - if (this._maxSize && newHeight > this._maxSize) { - newScale = this._maxSize / this.innerSize().height; - } - this._label - .transition() - .duration(transitionTime || 0) - .attr("transform", "scale(" + newScale + ")"); - this._scale = newScale; - - return this; - } - - Label.prototype.fillRect = function(x, y, width, height, padding, - hAlign, vAlign, - transitionTime) { - var bbox = this.innerSize(); - this.updateScale(Math.min( - (width - 2 * padding) / bbox.width, - (Math.abs(height)) / bbox.height - ), transitionTime); - - var lsize = this.size(); - var lx, ly; - switch(vAlign) { - case "top": - ly = y + lsize.height / 2; - break; - case "center": - ly = y + (height) / 2; - break; - case "bottom": - ly = y + height - lsize.height / 2; - } - - switch(hAlign) { - case "left": - lx = x + padding + lsize.width / 2; - break; - case "center": - lx = x + width / 2; - break; - case "right": - lx = x + width - padding - lsize.width / 2; - } - - this.updatePosition(lx, ly, transitionTime); - - return this; - } - - Label.prototype.fillCircle = function(radius, transitionTime) { - this.updatePosition(0, 0, transitionTime); - - var bbox = this.innerSize(); - var ratio = bbox.height / bbox.width; - - var maxHeight = radius * 2 * Math.cos(Math.PI/2 - Math.atan(ratio)) - this.updateScale(maxHeight / bbox.height, transitionTime); - } - - Label.prototype.fillSlice = function(arc, radius, d, transitionTime) { - var c = arc.centroid(d); - this.updatePosition(c[0], c[1], transitionTime); - - var bbox = this.innerSize(); - var ratio = bbox.height / bbox.width; - - // Get maximal scale so that label fits in the slice. - var diag1 = new g.Line(c[1] - ratio * c[0], ratio); - var diag2 = new g.Line(c[1] + ratio * c[0], -ratio); - var limit1 = new g.Line(0, Math.tan(d.startAngle + Math.PI/2)); - var limit2 = new g.Line(0, Math.tan(d.endAngle + Math.PI/2)); - - // Get all intersection points - var intersects = []; - intersects = intersects.concat(g.intersectionLineRadius(diag1, d.startAngle - Math.PI/2, radius)); - intersects = intersects.concat(g.intersectionLineRadius(diag1, d.endAngle - Math.PI/2, radius)); - intersects = intersects.concat(g.intersectionLineAndCircle(diag1, radius)); - intersects = intersects.concat(g.intersectionLineRadius(diag2, d.startAngle - Math.PI/2, radius)); - intersects = intersects.concat(g.intersectionLineRadius(diag2, d.endAngle - Math.PI/2, radius)); - intersects = intersects.concat(g.intersectionLineAndCircle(diag2, radius)); - - // Compute distance between all these points and take the minimum - var center = new g.Point(c[0], c[1]); - var distances = intersects.map(function(x) {return g.distance(center, x)}); - var minDist = d3.min(distances); - var actualDist = Math.sqrt( Math.pow(bbox.height / 2, 2) + Math.pow(bbox.width / 2, 2)); - - this.updateScale(minDist / actualDist, transitionTime); - } -}()); +// Copyright © 2016 RTE Réseau de transport d’électricité +(function() { + 'use strict'; + + var d3 = require("d3"); + var g = require("./geometry.js") + + module.exports = Label; + + function Label(el, style, color, minSize, maxSize) { + this._el = el; + this._minSize = minSize; + this._maxSize = maxSize; + this._container = d3.select(el); + this._label = this._container.append("g") + .attr("class", "label"); + + this._text = this._label.append("text") + .attr("dy", "0.35em") + .attr("text-anchor", "middle") + .attr("style", style || "") + .attr("fill", color || "black"); + } + + // Size of the label before scaling + Label.prototype.innerSize = function() { + return this._text.node().getBBox(); + } + + Label.prototype.size = function() { + var bbox = this.innerSize(); + return { + width: bbox.width * this._scale, + height: bbox.height * this._scale + } + } + + Label.prototype.updateText = function(newText) { + // New label should fit in the old bounding bbox + var oldSize = this.size(); + this._text.text(newText); + var newSize = this.size(); + + var scale = Math.min( + oldSize.width / newSize.width, + oldSize.height / newSize.height + ); + this.updateScale(this._scale * scale, 0); + return this; + } + + Label.prototype.updatePosition = function(x, y, transitionTime) { + this._container + .transition() + .duration(transitionTime || 0) + .attr("transform", "translate(" + x + "," + y + ")"); + return this; + } + + Label.prototype.updateScale = function(newScale, transitionTime) { + if (!newScale || isNaN(newScale) || !isFinite(newScale)) { + newScale = 0; + } + var newHeight = this.innerSize().height * newScale; + if (this._minSize && newHeight < this._minSize) { + newScale = 0; + } + if (this._maxSize && newHeight > this._maxSize) { + newScale = this._maxSize / this.innerSize().height; + } + this._label + .transition() + .duration(transitionTime || 0) + .attr("transform", "scale(" + newScale + ")"); + this._scale = newScale; + + return this; + } + + Label.prototype.fillRect = function(x, y, width, height, padding, + hAlign, vAlign, + transitionTime) { + var bbox = this.innerSize(); + this.updateScale(Math.min( + (width - 2 * padding) / bbox.width, + (Math.abs(height)) / bbox.height + ), transitionTime); + + var lsize = this.size(); + var lx, ly; + switch(vAlign) { + case "top": + ly = y + lsize.height / 2; + break; + case "center": + ly = y + (height) / 2; + break; + case "bottom": + ly = y + height - lsize.height / 2; + } + + switch(hAlign) { + case "left": + lx = x + padding + lsize.width / 2; + break; + case "center": + lx = x + width / 2; + break; + case "right": + lx = x + width - padding - lsize.width / 2; + } + + this.updatePosition(lx, ly, transitionTime); + + return this; + } + + Label.prototype.fillCircle = function(radius, transitionTime) { + this.updatePosition(0, 0, transitionTime); + + var bbox = this.innerSize(); + var ratio = bbox.height / bbox.width; + + var maxHeight = radius * 2 * Math.cos(Math.PI/2 - Math.atan(ratio)) + this.updateScale(maxHeight / bbox.height, transitionTime); + } + + Label.prototype.fillSlice = function(arc, radius, d, transitionTime) { + var c = arc.centroid(d); + this.updatePosition(c[0], c[1], transitionTime); + + var bbox = this.innerSize(); + var ratio = bbox.height / bbox.width; + + // Get maximal scale so that label fits in the slice. + var diag1 = new g.Line(c[1] - ratio * c[0], ratio); + var diag2 = new g.Line(c[1] + ratio * c[0], -ratio); + var limit1 = new g.Line(0, Math.tan(d.startAngle + Math.PI/2)); + var limit2 = new g.Line(0, Math.tan(d.endAngle + Math.PI/2)); + + // Get all intersection points + var intersects = []; + intersects = intersects.concat(g.intersectionLineRadius(diag1, d.startAngle - Math.PI/2, radius)); + intersects = intersects.concat(g.intersectionLineRadius(diag1, d.endAngle - Math.PI/2, radius)); + intersects = intersects.concat(g.intersectionLineAndCircle(diag1, radius)); + intersects = intersects.concat(g.intersectionLineRadius(diag2, d.startAngle - Math.PI/2, radius)); + intersects = intersects.concat(g.intersectionLineRadius(diag2, d.endAngle - Math.PI/2, radius)); + intersects = intersects.concat(g.intersectionLineAndCircle(diag2, radius)); + + // Compute distance between all these points and take the minimum + var center = new g.Point(c[0], c[1]); + var distances = intersects.map(function(x) {return g.distance(center, x)}); + var minDist = d3.min(distances); + var actualDist = Math.sqrt( Math.pow(bbox.height / 2, 2) + Math.pow(bbox.width / 2, 2)); + + this.updateScale(minDist / actualDist, transitionTime); + } +}()); },{"./geometry.js":4,"d3":1}],6:[function(require,module,exports){ -// Copyright © 2016 RTE Réseau de transport d’électricité -(function() { - 'use strict'; - - module.exports.Barchart = require("./barchart.js"); - module.exports.Polarchart = require("./polarchart.js"); - module.exports.Piechart = require("./piechart.js"); - - if (window) window.minicharts = module.exports; -}()); +// Copyright © 2016 RTE Réseau de transport d’électricité +(function() { + 'use strict'; + + module.exports.Barchart = require("./barchart.js"); + module.exports.Polarchart = require("./polarchart.js"); + module.exports.Piechart = require("./piechart.js"); + + if (window) window.minicharts = module.exports; +}()); },{"./barchart.js":2,"./piechart.js":7,"./polarchart.js":8}],7:[function(require,module,exports){ -// Copyright © 2016 RTE Réseau de transport d’électricité -(function() { - 'use strict'; - var Polarchart = require("./polarchart.js"); - module.exports = Piechart; - - Piechart.prototype = Object.create(Polarchart.prototype); - Piechart.prototype.constructor = Piechart; - - /** - * @class Piechart - * @summary Represent data with a pie chart - * @desc A pie chart is a special case of polar chart where the data values - * are represented by the angle of the slices. They should only be used to - * compare qualitatively proportions and compositions. Indeed, human eye is - * not good at comparing angles so only large differences are visible. - * @param {string} el CSS selector representing the element that will hold the chart. - * @param {number[]} data Data the chart has to represent. - * @param {PiechartOptions} options Options controling graphical aspects of the chart. - */ - - /** @typedef {object} PiechartOptions - * @memberOf Piechart - * @prop {number} [width=60] Width of the chart. - * @prop {number} [height=60] Height of the chart. - * @prop {number} [transitionTime=750] Duration of the transitions, in milliseconds. - * @prop {string[]|function}[colors=d3.schemeCategory10] Either an array of - * colors or a function `(d, i) -> color` where `d` is a data value and `i` - * is the index of the value.If it is an array with length less than the length - * of data, then the colors are recycled. - * @prop {string[]|"none"|"auto"|function}[labels="none"] Labels to display in slices. - * It can be an array with same length as the data. It can also be a function - * `(d, i) -> labelText` where `d` is a data value and `i` - * is the index of the value. Finally it can be equal to "none" to hide labels - * or "auto" to display in a compact way values. - * @prop {string|string[]|"auto"|function}[labelColors="auto"] Color of the labels. - * It can be a single value or an array with same length as the data. It can - * also be a function `(d, i) -> color` where `d` is a data value and `i` - * is the index of the value. Finally it can be equal to "auto". In this case, - * the most readable color is choosen depding on the color of the slice. - * @prop {number}[labelMinSize=8] Label minimum size in pixels. If there is - * not enough space for a given label, then it is hidden. - * @prop {number}[labelMaxSize=24] Label maximum size in pixels. - * @prop {string}[labelClass=""] Labels CSS class. - * @prop {string}[shapeClass=""] slices CSS class. - */ - - /** @method setData - * @desc Update the data represented by the chart - * @instance - * @memberOf Piechart - * @param {number[]} data Data the chart has to represent. - */ - - /** @method setOptions - * @desc Update the graphical options of a chart - * @instance - * @memberOf Piechart - * @param {PiechartOptions} options Options controling graphical aspects of the chart. - */ - - /** @method update - * @desc Update simulatenously data and options of a pie chart. - * @instance - * @memberOf Piechart - * @param {number[]} data Data the chart has to represent. - * @param {PiechartOptions} options Options controling graphical aspects of the chart. - */ - function Piechart(el, data, options) { - Polarchart.call(this, el, data, options); - } - - Piechart.prototype._processOptions = function(options) { - options = options || {}; - options.type = "angle"; - return Polarchart.prototype._processOptions.call(this, options); - } - -}()); +// Copyright © 2016 RTE Réseau de transport d’électricité +(function() { + 'use strict'; + var Polarchart = require("./polarchart.js"); + module.exports = Piechart; + + Piechart.prototype = Object.create(Polarchart.prototype); + Piechart.prototype.constructor = Piechart; + + /** + * @class Piechart + * @summary Represent data with a pie chart + * @desc A pie chart is a special case of polar chart where the data values + * are represented by the angle of the slices. They should only be used to + * compare qualitatively proportions and compositions. Indeed, human eye is + * not good at comparing angles so only large differences are visible. + * @param {string} el CSS selector representing the element that will hold the chart. + * @param {number[]} data Data the chart has to represent. + * @param {PiechartOptions} options Options controling graphical aspects of the chart. + */ + + /** @typedef {object} PiechartOptions + * @memberOf Piechart + * @prop {number} [width=60] Width of the chart. + * @prop {number} [height=60] Height of the chart. + * @prop {number} [transitionTime=750] Duration of the transitions, in milliseconds. + * @prop {string[]|function}[colors=d3.schemeCategory10] Either an array of + * colors or a function `(d, i) -> color` where `d` is a data value and `i` + * is the index of the value.If it is an array with length less than the length + * of data, then the colors are recycled. + * @prop {string[]|"none"|"auto"|function}[labels="none"] Labels to display in slices. + * It can be an array with same length as the data. It can also be a function + * `(d, i) -> labelText` where `d` is a data value and `i` + * is the index of the value. Finally it can be equal to "none" to hide labels + * or "auto" to display in a compact way values. + * @prop {string|string[]|"auto"|function}[labelColors="auto"] Color of the labels. + * It can be a single value or an array with same length as the data. It can + * also be a function `(d, i) -> color` where `d` is a data value and `i` + * is the index of the value. Finally it can be equal to "auto". In this case, + * the most readable color is choosen depding on the color of the slice. + * @prop {number}[labelMinSize=8] Label minimum size in pixels. If there is + * not enough space for a given label, then it is hidden. + * @prop {number}[labelMaxSize=24] Label maximum size in pixels. + * @prop {string}[labelClass=""] Labels CSS class. + * @prop {string}[shapeClass=""] slices CSS class. + */ + + /** @method setData + * @desc Update the data represented by the chart + * @instance + * @memberOf Piechart + * @param {number[]} data Data the chart has to represent. + */ + + /** @method setOptions + * @desc Update the graphical options of a chart + * @instance + * @memberOf Piechart + * @param {PiechartOptions} options Options controling graphical aspects of the chart. + */ + + /** @method update + * @desc Update simulatenously data and options of a pie chart. + * @instance + * @memberOf Piechart + * @param {number[]} data Data the chart has to represent. + * @param {PiechartOptions} options Options controling graphical aspects of the chart. + */ + function Piechart(el, data, options) { + Polarchart.call(this, el, data, options); + } + + Piechart.prototype._processOptions = function(options) { + options = options || {}; + options.type = "angle"; + return Polarchart.prototype._processOptions.call(this, options); + } + +}()); },{"./polarchart.js":8}],8:[function(require,module,exports){ -// Copyright © 2016 RTE Réseau de transport d’électricité -(function() { - 'use strict'; - - var d3 = require("d3"); - var Chart = require("./chart.js"); - - module.exports = Polarchart; - - Polarchart.prototype = Object.create(Chart.prototype); - Polarchart.prototype.constructor = Polarchart; - - /** - * @class Polarchart - * @summary Represent data with a polar chart - * @desc Polar charts are nice looking charts especially on a map, - * but individual values are hard to compare - * on these charts: the human eye is good to compare lengths, but not - * to compare agnles, radius or areas. Polar charts should only be used when - * one wants to point out qualitative results and does not need a precise - * representation of data. Another limitation compared to barcharts is that - * polar charts cannot represent negative values. - * @param {string} el CSS selector representing the element that will hold the chart. - * @param {number[]} data Data the chart has to represent. - * @param {PolarchartOptions} options Options controling graphical aspects of the chart. - */ - - /** @typedef {object} PolarchartOptions - * @memberOf Polarchart - * @prop {number|"auto"} [maxValue="auto"] Maximum value data could take.It - * is important to set this option explicitely if one wants to compare - * charts and use the same scale on each one. By default it equals to the - * maximum value of the data. - * @prop {"area"|"radius"|"angle"} [type="area"] What kind of scale to use to - * represent the data? `angle` produces a pie chart and should be used only to visualize - * proportions. In other cases, `area` (the default) should generally be - * prefered. `radius` should only be used when one wants to magnify differences. - * @prop {number} [width=60] Width of the chart. - * @prop {number} [height=60] Height of the chart. - * @prop {number} [transitionTime=750] Duration of the transitions, in milliseconds. - * @prop {string[]|function}[colors=d3.schemeCategory10] Either an array of - * colors or a function `(d, i) -> color` where `d` is a data value and `i` - * is the index of the value.If it is an array with length less than the length - * of data, then the colors are recycled. - * @prop {string[]|"none"|"auto"|function}[labels="none"] Labels to display in slices. - * It can be an array with same length as the data. It can also be a function - * `(d, i) -> labelText` where `d` is a data value and `i` - * is the index of the value. Finally it can be equal to "none" to hide labels - * or "auto" to display in a compact way values. - * @prop {string|string[]|"auto"|function}[labelColors="auto"] Color of the labels. - * It can be a single value or an array with same length as the data. It can - * also be a function `(d, i) -> color` where `d` is a data value and `i` - * is the index of the value. Finally it can be equal to "auto". In this case, - * the most readable color is choosen depding on the color of the slice. - * @prop {number}[labelMinSize=8] Label minimum size in pixels. If there is - * not enough space for a given label, then it is hidden. - * @prop {number}[labelMaxSize=24] Label maximum size in pixels. - * @prop {string}[labelClass=""] Labels CSS class. - * @prop {string}[shapeClass=""] slices CSS class. - */ - - /** @method setData - * @desc Update the data represented by the chart - * @instance - * @memberOf Polarchart - * @param {number[]} data Data the chart has to represent. - */ - - /** @method setOptions - * @desc Update the graphical options of a chart - * @instance - * @memberOf Polarchart - * @param {PolarchartOptions} options Options controling graphical aspects of the chart. - */ - - /** @method update - * @desc Update simulatenously data and options of a polar chart. - * @instance - * @memberOf Polarchart - * @param {number[]} data Data the chart has to represent. - * @param {PolarchartOptions} options Options controling graphical aspects of the chart. - */ - - function Polarchart(el, data, options) { - var defaults = { - type: "area", - maxValue: "auto", - } - - Chart.call(this, el, data, options, defaults); - - // Center the chart group inside the container - this._chart - .attr("transform", "translate(" + this._options.width/2 + "," + this._options.width/2 + ")"); - - this._draw(); - } - - Polarchart.prototype._processOptions = function(options) { - options = Chart.prototype._processOptions.call(this, options, this._options); - - options.height = options.width; - - if (options.maxValue === "auto") { - options.maxValue = d3.max(this._data); - } - //debugger; - var radius = options.width / 2; - var pie = d3.pie().sort(null); - var arc = d3.arc().innerRadius(0); - var radiusFun; - - if (options.type === "angle") { - radiusFun = function(d) {return radius} - pie.value(function(d) {return d}); - } else { - radiusFun = options.type == "radius" ? d3.scaleLinear() : d3.scalePow().exponent(0.5); - radiusFun.range([0, radius]) - .domain([0, options.maxValue]); - pie.value(function(d) {return 1}); - } - - arc.outerRadius(function(d, i) {return radiusFun(d.data)}); - - options.radius = radiusFun; - options.pie = pie; - options. arc = arc; - return options; - } - - Polarchart.prototype._draw = function() { - var self = this; - Chart.prototype._draw.call(this); - - // Move center of the chart - this._chart - .transition() - .duration(self._options.transitionTime) - .attr("transform", "translate(" + self._options.width/2 + "," + self._options.width/2 + ")"); - - var slices = this._chart.selectAll("path").data(this._options.pie(this._data)); - - // Initialize new slices - slices.enter() - .append("path") - .attr("class", "leaflet-clickable") - .attr("d", this._options.arc) - .attr("fill", function(d, i) {return self._options.colorFun(d, i)}) - .each(function(d, i) { - if (self._data.length == 1) this._current = {startAngle:d.startAngle, endAngle:d.endAngle, data:0} - else this._current = {startAngle:d.endAngle, endAngle:d.endAngle} - }) - // Update slices - .merge(slices) - .attr("class", function(d, i) {return self._options.shapeClass(d.data, i)}) - .transition() - .duration(self._options.transitionTime) - .attrTween("d", arcTween) - .attr("fill", function(d, i) {return self._options.colorFun(d, i)}); - // Remove slices - slices.exit().remove(); - - function arcTween(a) { - var i = d3.interpolate(this._current, a); - this._current = i(0); - return function(t) { - return self._options.arc(i(t)); - }; - } - - // Add/update labels - // function(arc, radiusFun, d, transitionTime) - var initLabel, updateLabel; - if (this._data.length > 1) { - var data = this._options.pie(this._data); - initLabel = function(label, d, i) { - label.fillSlice(self._options.arc, self._options.radius(d), data[i], 0); - } - - updateLabel = function(label, d, i) { - label.fillSlice(self._options.arc, self._options.radius(d), data[i], - self._options.transitionTime); - } - } else { - initLabel = function(label, d, i) { - label.fillCircle(self._options.radius(d), 0); - } - - updateLabel = function(label, d, i) { - label.fillCircle(self._options.radius(d), self._options.transitionTime); - } - } - - this._drawLabels(initLabel, updateLabel); - } - -}()); +// Copyright © 2016 RTE Réseau de transport d’électricité +(function() { + 'use strict'; + + var d3 = require("d3"); + var Chart = require("./chart.js"); + + module.exports = Polarchart; + + Polarchart.prototype = Object.create(Chart.prototype); + Polarchart.prototype.constructor = Polarchart; + + /** + * @class Polarchart + * @summary Represent data with a polar chart + * @desc Polar charts are nice looking charts especially on a map, + * but individual values are hard to compare + * on these charts: the human eye is good to compare lengths, but not + * to compare agnles, radius or areas. Polar charts should only be used when + * one wants to point out qualitative results and does not need a precise + * representation of data. Another limitation compared to barcharts is that + * polar charts cannot represent negative values. + * @param {string} el CSS selector representing the element that will hold the chart. + * @param {number[]} data Data the chart has to represent. + * @param {PolarchartOptions} options Options controling graphical aspects of the chart. + */ + + /** @typedef {object} PolarchartOptions + * @memberOf Polarchart + * @prop {number|"auto"} [maxValue="auto"] Maximum value data could take.It + * is important to set this option explicitely if one wants to compare + * charts and use the same scale on each one. By default it equals to the + * maximum value of the data. + * @prop {"area"|"radius"|"angle"} [type="area"] What kind of scale to use to + * represent the data? `angle` produces a pie chart and should be used only to visualize + * proportions. In other cases, `area` (the default) should generally be + * prefered. `radius` should only be used when one wants to magnify differences. + * @prop {number} [width=60] Width of the chart. + * @prop {number} [height=60] Height of the chart. + * @prop {number} [transitionTime=750] Duration of the transitions, in milliseconds. + * @prop {string[]|function}[colors=d3.schemeCategory10] Either an array of + * colors or a function `(d, i) -> color` where `d` is a data value and `i` + * is the index of the value.If it is an array with length less than the length + * of data, then the colors are recycled. + * @prop {string[]|"none"|"auto"|function}[labels="none"] Labels to display in slices. + * It can be an array with same length as the data. It can also be a function + * `(d, i) -> labelText` where `d` is a data value and `i` + * is the index of the value. Finally it can be equal to "none" to hide labels + * or "auto" to display in a compact way values. + * @prop {string|string[]|"auto"|function}[labelColors="auto"] Color of the labels. + * It can be a single value or an array with same length as the data. It can + * also be a function `(d, i) -> color` where `d` is a data value and `i` + * is the index of the value. Finally it can be equal to "auto". In this case, + * the most readable color is choosen depding on the color of the slice. + * @prop {number}[labelMinSize=8] Label minimum size in pixels. If there is + * not enough space for a given label, then it is hidden. + * @prop {number}[labelMaxSize=24] Label maximum size in pixels. + * @prop {string}[labelClass=""] Labels CSS class. + * @prop {string}[shapeClass=""] slices CSS class. + */ + + /** @method setData + * @desc Update the data represented by the chart + * @instance + * @memberOf Polarchart + * @param {number[]} data Data the chart has to represent. + */ + + /** @method setOptions + * @desc Update the graphical options of a chart + * @instance + * @memberOf Polarchart + * @param {PolarchartOptions} options Options controling graphical aspects of the chart. + */ + + /** @method update + * @desc Update simulatenously data and options of a polar chart. + * @instance + * @memberOf Polarchart + * @param {number[]} data Data the chart has to represent. + * @param {PolarchartOptions} options Options controling graphical aspects of the chart. + */ + + function Polarchart(el, data, options) { + var defaults = { + type: "area", + maxValue: "auto", + } + + Chart.call(this, el, data, options, defaults); + + // Center the chart group inside the container + this._chart + .attr("transform", "translate(" + this._options.width/2 + "," + this._options.width/2 + ")"); + + this._draw(); + } + + Polarchart.prototype._processOptions = function(options) { + options = Chart.prototype._processOptions.call(this, options, this._options); + + options.height = options.width; + + if (options.maxValue === "auto") { + options.maxValue = d3.max(this._data); + } + //debugger; + var radius = options.width / 2; + var pie = d3.pie().sort(null); + var arc = d3.arc().innerRadius(0); + var radiusFun; + + if (options.type === "angle") { + radiusFun = function(d) {return radius} + pie.value(function(d) {return d}); + } else { + radiusFun = options.type == "radius" ? d3.scaleLinear() : d3.scalePow().exponent(0.5); + radiusFun.range([0, radius]) + .domain([0, options.maxValue]); + pie.value(function(d) {return 1}); + } + + arc.outerRadius(function(d, i) {return radiusFun(d.data)}); + + options.radius = radiusFun; + options.pie = pie; + options. arc = arc; + return options; + } + + Polarchart.prototype._draw = function() { + var self = this; + Chart.prototype._draw.call(this); + + // Move center of the chart + this._chart + .transition() + .duration(self._options.transitionTime) + .attr("transform", "translate(" + self._options.width/2 + "," + self._options.width/2 + ")"); + + var slices = this._chart.selectAll("path").data(this._options.pie(this._data)); + + // Initialize new slices + slices.enter() + .append("path") + .attr("class", "leaflet-clickable") + .attr("d", this._options.arc) + .attr("fill", function(d, i) {return self._options.colorFun(d, i)}) + .each(function(d, i) { + if (self._data.length == 1) this._current = {startAngle:d.startAngle, endAngle:d.endAngle, data:0} + else this._current = {startAngle:d.endAngle, endAngle:d.endAngle} + }) + // Update slices + .merge(slices) + .attr("class", function(d, i) {return self._options.shapeClass(d.data, i)}) + .transition() + .duration(self._options.transitionTime) + .attrTween("d", arcTween) + .attr("fill", function(d, i) {return self._options.colorFun(d, i)}); + // Remove slices + slices.exit().remove(); + + function arcTween(a) { + var i = d3.interpolate(this._current, a); + this._current = i(0); + return function(t) { + return self._options.arc(i(t)); + }; + } + + // Add/update labels + // function(arc, radiusFun, d, transitionTime) + var initLabel, updateLabel; + if (this._data.length > 1) { + var data = this._options.pie(this._data); + initLabel = function(label, d, i) { + label.fillSlice(self._options.arc, self._options.radius(d), data[i], 0); + } + + updateLabel = function(label, d, i) { + label.fillSlice(self._options.arc, self._options.radius(d), data[i], + self._options.transitionTime); + } + } else { + initLabel = function(label, d, i) { + label.fillCircle(self._options.radius(d), 0); + } + + updateLabel = function(label, d, i) { + label.fillCircle(self._options.radius(d), self._options.transitionTime); + } + } + + this._drawLabels(initLabel, updateLabel); + } + +}()); },{"./chart.js":3,"d3":1}],9:[function(require,module,exports){ -// Copyright © 2016 RTE Réseau de transport d’électricité -(function() { - 'use strict'; - - module.exports.mergeOptions = mergeOptions; - module.exports.toArray = toArray; - module.exports.toFunction = toFunction; - module.exports.prettyNumber = prettyNumber; - - /** Merge the properties of two objects. More precisely, if a property is - * present in "defaults" but not in "options" it is copied in options. this - * function is used to specified default options for a function. - * - * @param {object} options Option object - * @param {object} defaults Object containing default values of options - * - * @return {object} Merged object. - */ - function mergeOptions(options, defaults) { - if (options) options = JSON.parse(JSON.stringify(options)); - else options = {}; - defaults = defaults || {}; - for (var opt in defaults) { - if (defaults.hasOwnProperty(opt) && !options.hasOwnProperty(opt)) { - options[opt] = defaults[opt]; - } - } - return options; - } - - /** Converts parameter to Array. Used when user wants to pass a single value, - * but a function expects an array. - * @param {any} x An array or a scalar value - * @return {any[]} - * 'x' if it is an array, else an array with 'x' as its unique - * element. - */ - function toArray(x) { - if (x.constructor !== Array) x = [x]; - return x; - } - - /** Converts its argument in a function. - * @param {any} x A function, an array, or a scalar. - * @return {function} - * - 'x' if it is a function. - * - If 'x' is a scalar, it returns a function that always returns 'x' - * - If 'x' is an array it returns the function (d, i) -> x[i] - */ - function toFunction(x) { - if (typeof x === "function") return (x); - x = toArray(x); - return function(d, i) {return x[i % x.length]}; - } - - /** Transforms a number in a pretty and small string - * @param {number} number - * @return {string} - * A string representing the number. It only keeps at most 2 decimal - * digits and it adds suffixes "K", "M", "B", "T" for large values. - */ - function prettyNumber(number) { - if (isNaN(number) || !isFinite(number)) return ""; - - var absVal = Math.abs(number); - var sign= number < 0? "-": ""; - var scale; - - if( absVal < 1000 ) { - scale = ''; - } else if( absVal < 1000000 ) { - scale = 'K'; - absVal = absVal/1000; - - } else if( absVal < 1000000000 ) { - scale = 'M'; - absVal = absVal/1000000; - - } else if( absVal < 1000000000000 ) { - scale = 'B'; - absVal = absVal/1000000000; - - } else if( absVal < 1000000000000000 ) { - scale = 'T'; - absVal = absVal/1000000000000; - } - - if (absVal > 10) absVal = roundTo(absVal); - else if (absVal > 1) absVal = roundTo(absVal, 10, true); - else absVal = roundTo(absVal, 100, true); - - return sign + absVal + scale; - } - - /** Round a number - * @param {number} number - * @param {number} to: desired precision - * @param {boolean} inverse If true, number is rounded at the 1 / 'to' - */ - function roundTo(number, to, inverse) { - to = to || 1; - if (inverse) return Math.round(number * to) / to; - else return Math.round(number / to) * to; - } -}()); +// Copyright © 2016 RTE Réseau de transport d’électricité +(function() { + 'use strict'; + + module.exports.mergeOptions = mergeOptions; + module.exports.toArray = toArray; + module.exports.toFunction = toFunction; + module.exports.prettyNumber = prettyNumber; + + /** Merge the properties of two objects. More precisely, if a property is + * present in "defaults" but not in "options" it is copied in options. this + * function is used to specified default options for a function. + * + * @param {object} options Option object + * @param {object} defaults Object containing default values of options + * + * @return {object} Merged object. + */ + function mergeOptions(options, defaults) { + if (options) options = JSON.parse(JSON.stringify(options)); + else options = {}; + defaults = defaults || {}; + for (var opt in defaults) { + if (defaults.hasOwnProperty(opt) && !options.hasOwnProperty(opt)) { + options[opt] = defaults[opt]; + } + } + return options; + } + + /** Converts parameter to Array. Used when user wants to pass a single value, + * but a function expects an array. + * @param {any} x An array or a scalar value + * @return {any[]} + * 'x' if it is an array, else an array with 'x' as its unique + * element. + */ + function toArray(x) { + if (x.constructor !== Array) x = [x]; + return x; + } + + /** Converts its argument in a function. + * @param {any} x A function, an array, or a scalar. + * @return {function} + * - 'x' if it is a function. + * - If 'x' is a scalar, it returns a function that always returns 'x' + * - If 'x' is an array it returns the function (d, i) -> x[i] + */ + function toFunction(x) { + if (typeof x === "function") return (x); + x = toArray(x); + return function(d, i) {return x[i % x.length]}; + } + + /** Transforms a number in a pretty and small string + * @param {number} number + * @return {string} + * A string representing the number. It only keeps at most 2 decimal + * digits and it adds suffixes "K", "M", "B", "T" for large values. + */ + function prettyNumber(number) { + if (isNaN(number) || !isFinite(number)) return ""; + + var absVal = Math.abs(number); + var sign= number < 0? "-": ""; + var scale; + + if( absVal < 1000 ) { + scale = ''; + } else if( absVal < 1000000 ) { + scale = 'K'; + absVal = absVal/1000; + + } else if( absVal < 1000000000 ) { + scale = 'M'; + absVal = absVal/1000000; + + } else if( absVal < 1000000000000 ) { + scale = 'B'; + absVal = absVal/1000000000; + + } else if( absVal < 1000000000000000 ) { + scale = 'T'; + absVal = absVal/1000000000000; + } + + if (absVal > 10) absVal = roundTo(absVal); + else if (absVal > 1) absVal = roundTo(absVal, 10, true); + else absVal = roundTo(absVal, 100, true); + + return sign + absVal + scale; + } + + /** Round a number + * @param {number} number + * @param {number} to: desired precision + * @param {boolean} inverse If true, number is rounded at the 1 / 'to' + */ + function roundTo(number, to, inverse) { + to = to || 1; + if (inverse) return Math.round(number * to) / to; + else return Math.round(number / to) * to; + } +}()); },{}],10:[function(require,module,exports){ // TinyColor v1.4.1 @@ -18686,13 +18854,16 @@ else { onAdd: function(map) { L.CircleMarker.prototype.onAdd.call(this, map); // Change class of container so that the element hides when zooming - var container = this._container || this._renderer._container; + var container = this._container || this._renderer._rootGroup; container.setAttribute("class", "leaflet-zoom-hide"); // create the svg element that holds the chart this._chart = d3.select(container).append("g"); + if (L.version >= "1.0") this.addInteractiveTarget(this._chart.node()); + map.on('moveend', this._onMoveend, this); + this._redraw(true); }, @@ -18809,8 +18980,8 @@ else { labelMinSize: this.options.labelMinSize, labelMaxSize: this.options.labelMaxSize, labelPadding: this.options.labelPadding, - labelClass: "leaflet-clickable", - shapeClass: "leaflet-clickable" + labelClass: "leaflet-clickable leaflet-interactive", + shapeClass: "leaflet-clickable leaflet-interactive" }; // Create of update chart @@ -18903,4 +19074,4 @@ else { }()); },{}]},{},[11]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvZDMvYnVpbGQvZDMuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvYmFyY2hhcnQuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvY2hhcnQuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvZ2VvbWV0cnkuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvbGFiZWwuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvbWluaWNoYXJ0cy5qcyIsIm5vZGVfbW9kdWxlcy9taW5pY2hhcnRzL3NyYy9waWVjaGFydC5qcyIsIm5vZGVfbW9kdWxlcy9taW5pY2hhcnRzL3NyYy9wb2xhcmNoYXJ0LmpzIiwibm9kZV9tb2R1bGVzL21pbmljaGFydHMvc3JjL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL3Rpbnljb2xvcjIvdGlueWNvbG9yLmpzIiwic3JjL21pbmljaGFydC5qcyIsInNyYy91dGlscy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDemdnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM3FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIi8vIGh0dHBzOi8vZDNqcy5vcmcgVmVyc2lvbiA0LjQuMC4gQ29weXJpZ2h0IDIwMTYgTWlrZSBCb3N0b2NrLlxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG4gIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSkgOlxuICAoZmFjdG9yeSgoZ2xvYmFsLmQzID0gZ2xvYmFsLmQzIHx8IHt9KSkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG52YXIgdmVyc2lvbiA9IFwiNC40LjBcIjtcblxudmFyIGFzY2VuZGluZyA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiBhID49IGIgPyAwIDogTmFOO1xufTtcblxudmFyIGJpc2VjdG9yID0gZnVuY3Rpb24oY29tcGFyZSkge1xuICBpZiAoY29tcGFyZS5sZW5ndGggPT09IDEpIGNvbXBhcmUgPSBhc2NlbmRpbmdDb21wYXJhdG9yKGNvbXBhcmUpO1xuICByZXR1cm4ge1xuICAgIGxlZnQ6IGZ1bmN0aW9uKGEsIHgsIGxvLCBoaSkge1xuICAgICAgaWYgKGxvID09IG51bGwpIGxvID0gMDtcbiAgICAgIGlmIChoaSA9PSBudWxsKSBoaSA9IGEubGVuZ3RoO1xuICAgICAgd2hpbGUgKGxvIDwgaGkpIHtcbiAgICAgICAgdmFyIG1pZCA9IGxvICsgaGkgPj4+IDE7XG4gICAgICAgIGlmIChjb21wYXJlKGFbbWlkXSwgeCkgPCAwKSBsbyA9IG1pZCArIDE7XG4gICAgICAgIGVsc2UgaGkgPSBtaWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gbG87XG4gICAgfSxcbiAgICByaWdodDogZnVuY3Rpb24oYSwgeCwgbG8sIGhpKSB7XG4gICAgICBpZiAobG8gPT0gbnVsbCkgbG8gPSAwO1xuICAgICAgaWYgKGhpID09IG51bGwpIGhpID0gYS5sZW5ndGg7XG4gICAgICB3aGlsZSAobG8gPCBoaSkge1xuICAgICAgICB2YXIgbWlkID0gbG8gKyBoaSA+Pj4gMTtcbiAgICAgICAgaWYgKGNvbXBhcmUoYVttaWRdLCB4KSA+IDApIGhpID0gbWlkO1xuICAgICAgICBlbHNlIGxvID0gbWlkICsgMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBsbztcbiAgICB9XG4gIH07XG59O1xuXG5mdW5jdGlvbiBhc2NlbmRpbmdDb21wYXJhdG9yKGYpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGQsIHgpIHtcbiAgICByZXR1cm4gYXNjZW5kaW5nKGYoZCksIHgpO1xuICB9O1xufVxuXG52YXIgYXNjZW5kaW5nQmlzZWN0ID0gYmlzZWN0b3IoYXNjZW5kaW5nKTtcbnZhciBiaXNlY3RSaWdodCA9IGFzY2VuZGluZ0Jpc2VjdC5yaWdodDtcbnZhciBiaXNlY3RMZWZ0ID0gYXNjZW5kaW5nQmlzZWN0LmxlZnQ7XG5cbnZhciBkZXNjZW5kaW5nID0gZnVuY3Rpb24oYSwgYikge1xuICByZXR1cm4gYiA8IGEgPyAtMSA6IGIgPiBhID8gMSA6IGIgPj0gYSA/IDAgOiBOYU47XG59O1xuXG52YXIgbnVtYmVyID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4geCA9PT0gbnVsbCA/IE5hTiA6ICt4O1xufTtcblxudmFyIHZhcmlhbmNlID0gZnVuY3Rpb24oYXJyYXksIGYpIHtcbiAgdmFyIG4gPSBhcnJheS5sZW5ndGgsXG4gICAgICBtID0gMCxcbiAgICAgIGEsXG4gICAgICBkLFxuICAgICAgcyA9IDAsXG4gICAgICBpID0gLTEsXG4gICAgICBqID0gMDtcblxuICBpZiAoZiA9PSBudWxsKSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIGlmICghaXNOYU4oYSA9IG51bWJlcihhcnJheVtpXSkpKSB7XG4gICAgICAgIGQgPSBhIC0gbTtcbiAgICAgICAgbSArPSBkIC8gKytqO1xuICAgICAgICBzICs9IGQgKiAoYSAtIG0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBpZiAoIWlzTmFOKGEgPSBudW1iZXIoZihhcnJheVtpXSwgaSwgYXJyYXkpKSkpIHtcbiAgICAgICAgZCA9IGEgLSBtO1xuICAgICAgICBtICs9IGQgLyArK2o7XG4gICAgICAgIHMgKz0gZCAqIChhIC0gbSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGogPiAxKSByZXR1cm4gcyAvIChqIC0gMSk7XG59O1xuXG52YXIgZGV2aWF0aW9uID0gZnVuY3Rpb24oYXJyYXksIGYpIHtcbiAgdmFyIHYgPSB2YXJpYW5jZShhcnJheSwgZik7XG4gIHJldHVybiB2ID8gTWF0aC5zcXJ0KHYpIDogdjtcbn07XG5cbnZhciBleHRlbnQgPSBmdW5jdGlvbihhcnJheSwgZikge1xuICB2YXIgaSA9IC0xLFxuICAgICAgbiA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGEsXG4gICAgICBiLFxuICAgICAgYztcblxuICBpZiAoZiA9PSBudWxsKSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGFycmF5W2ldKSAhPSBudWxsICYmIGIgPj0gYikgeyBhID0gYyA9IGI7IGJyZWFrOyB9XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGFycmF5W2ldKSAhPSBudWxsKSB7XG4gICAgICBpZiAoYSA+IGIpIGEgPSBiO1xuICAgICAgaWYgKGMgPCBiKSBjID0gYjtcbiAgICB9XG4gIH1cblxuICBlbHNlIHtcbiAgICB3aGlsZSAoKytpIDwgbikgaWYgKChiID0gZihhcnJheVtpXSwgaSwgYXJyYXkpKSAhPSBudWxsICYmIGIgPj0gYikgeyBhID0gYyA9IGI7IGJyZWFrOyB9XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGYoYXJyYXlbaV0sIGksIGFycmF5KSkgIT0gbnVsbCkge1xuICAgICAgaWYgKGEgPiBiKSBhID0gYjtcbiAgICAgIGlmIChjIDwgYikgYyA9IGI7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIFthLCBjXTtcbn07XG5cbnZhciBhcnJheSA9IEFycmF5LnByb3RvdHlwZTtcblxudmFyIHNsaWNlID0gYXJyYXkuc2xpY2U7XG52YXIgbWFwID0gYXJyYXkubWFwO1xuXG52YXIgY29uc3RhbnQkMSA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxudmFyIGlkZW50aXR5ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4geDtcbn07XG5cbnZhciByYW5nZSA9IGZ1bmN0aW9uKHN0YXJ0LCBzdG9wLCBzdGVwKSB7XG4gIHN0YXJ0ID0gK3N0YXJ0LCBzdG9wID0gK3N0b3AsIHN0ZXAgPSAobiA9IGFyZ3VtZW50cy5sZW5ndGgpIDwgMiA/IChzdG9wID0gc3RhcnQsIHN0YXJ0ID0gMCwgMSkgOiBuIDwgMyA/IDEgOiArc3RlcDtcblxuICB2YXIgaSA9IC0xLFxuICAgICAgbiA9IE1hdGgubWF4KDAsIE1hdGguY2VpbCgoc3RvcCAtIHN0YXJ0KSAvIHN0ZXApKSB8IDAsXG4gICAgICByYW5nZSA9IG5ldyBBcnJheShuKTtcblxuICB3aGlsZSAoKytpIDwgbikge1xuICAgIHJhbmdlW2ldID0gc3RhcnQgKyBpICogc3RlcDtcbiAgfVxuXG4gIHJldHVybiByYW5nZTtcbn07XG5cbnZhciBlMTAgPSBNYXRoLnNxcnQoNTApO1xudmFyIGU1ID0gTWF0aC5zcXJ0KDEwKTtcbnZhciBlMiA9IE1hdGguc3FydCgyKTtcblxudmFyIHRpY2tzID0gZnVuY3Rpb24oc3RhcnQsIHN0b3AsIGNvdW50KSB7XG4gIHZhciBzdGVwID0gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIGNvdW50KTtcbiAgcmV0dXJuIHJhbmdlKFxuICAgIE1hdGguY2VpbChzdGFydCAvIHN0ZXApICogc3RlcCxcbiAgICBNYXRoLmZsb29yKHN0b3AgLyBzdGVwKSAqIHN0ZXAgKyBzdGVwIC8gMiwgLy8gaW5jbHVzaXZlXG4gICAgc3RlcFxuICApO1xufTtcblxuZnVuY3Rpb24gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIGNvdW50KSB7XG4gIHZhciBzdGVwMCA9IE1hdGguYWJzKHN0b3AgLSBzdGFydCkgLyBNYXRoLm1heCgwLCBjb3VudCksXG4gICAgICBzdGVwMSA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKE1hdGgubG9nKHN0ZXAwKSAvIE1hdGguTE4xMCkpLFxuICAgICAgZXJyb3IgPSBzdGVwMCAvIHN0ZXAxO1xuICBpZiAoZXJyb3IgPj0gZTEwKSBzdGVwMSAqPSAxMDtcbiAgZWxzZSBpZiAoZXJyb3IgPj0gZTUpIHN0ZXAxICo9IDU7XG4gIGVsc2UgaWYgKGVycm9yID49IGUyKSBzdGVwMSAqPSAyO1xuICByZXR1cm4gc3RvcCA8IHN0YXJ0ID8gLXN0ZXAxIDogc3RlcDE7XG59XG5cbnZhciBzdHVyZ2VzID0gZnVuY3Rpb24odmFsdWVzKSB7XG4gIHJldHVybiBNYXRoLmNlaWwoTWF0aC5sb2codmFsdWVzLmxlbmd0aCkgLyBNYXRoLkxOMikgKyAxO1xufTtcblxudmFyIGhpc3RvZ3JhbSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdmFsdWUgPSBpZGVudGl0eSxcbiAgICAgIGRvbWFpbiA9IGV4dGVudCxcbiAgICAgIHRocmVzaG9sZCA9IHN0dXJnZXM7XG5cbiAgZnVuY3Rpb24gaGlzdG9ncmFtKGRhdGEpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgICB4LFxuICAgICAgICB2YWx1ZXMgPSBuZXcgQXJyYXkobik7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICB2YWx1ZXNbaV0gPSB2YWx1ZShkYXRhW2ldLCBpLCBkYXRhKTtcbiAgICB9XG5cbiAgICB2YXIgeHogPSBkb21haW4odmFsdWVzKSxcbiAgICAgICAgeDAgPSB4elswXSxcbiAgICAgICAgeDEgPSB4elsxXSxcbiAgICAgICAgdHogPSB0aHJlc2hvbGQodmFsdWVzLCB4MCwgeDEpO1xuXG4gICAgLy8gQ29udmVydCBudW1iZXIgb2YgdGhyZXNob2xkcyBpbnRvIHVuaWZvcm0gdGhyZXNob2xkcy5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodHopKSB0eiA9IHRpY2tzKHgwLCB4MSwgdHopO1xuXG4gICAgLy8gUmVtb3ZlIGFueSB0aHJlc2hvbGRzIG91dHNpZGUgdGhlIGRvbWFpbi5cbiAgICB2YXIgbSA9IHR6Lmxlbmd0aDtcbiAgICB3aGlsZSAodHpbMF0gPD0geDApIHR6LnNoaWZ0KCksIC0tbTtcbiAgICB3aGlsZSAodHpbbSAtIDFdID49IHgxKSB0ei5wb3AoKSwgLS1tO1xuXG4gICAgdmFyIGJpbnMgPSBuZXcgQXJyYXkobSArIDEpLFxuICAgICAgICBiaW47XG5cbiAgICAvLyBJbml0aWFsaXplIGJpbnMuXG4gICAgZm9yIChpID0gMDsgaSA8PSBtOyArK2kpIHtcbiAgICAgIGJpbiA9IGJpbnNbaV0gPSBbXTtcbiAgICAgIGJpbi54MCA9IGkgPiAwID8gdHpbaSAtIDFdIDogeDA7XG4gICAgICBiaW4ueDEgPSBpIDwgbSA/IHR6W2ldIDogeDE7XG4gICAgfVxuXG4gICAgLy8gQXNzaWduIGRhdGEgdG8gYmlucyBieSB2YWx1ZSwgaWdub3JpbmcgYW55IG91dHNpZGUgdGhlIGRvbWFpbi5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICB4ID0gdmFsdWVzW2ldO1xuICAgICAgaWYgKHgwIDw9IHggJiYgeCA8PSB4MSkge1xuICAgICAgICBiaW5zW2Jpc2VjdFJpZ2h0KHR6LCB4LCAwLCBtKV0ucHVzaChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYmlucztcbiAgfVxuXG4gIGhpc3RvZ3JhbS52YWx1ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh2YWx1ZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMShfKSwgaGlzdG9ncmFtKSA6IHZhbHVlO1xuICB9O1xuXG4gIGhpc3RvZ3JhbS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZG9tYWluID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxKFtfWzBdLCBfWzFdXSksIGhpc3RvZ3JhbSkgOiBkb21haW47XG4gIH07XG5cbiAgaGlzdG9ncmFtLnRocmVzaG9sZHMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGhyZXNob2xkID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBBcnJheS5pc0FycmF5KF8pID8gY29uc3RhbnQkMShzbGljZS5jYWxsKF8pKSA6IGNvbnN0YW50JDEoXyksIGhpc3RvZ3JhbSkgOiB0aHJlc2hvbGQ7XG4gIH07XG5cbiAgcmV0dXJuIGhpc3RvZ3JhbTtcbn07XG5cbnZhciB0aHJlc2hvbGQgPSBmdW5jdGlvbihhcnJheSwgcCwgZikge1xuICBpZiAoZiA9PSBudWxsKSBmID0gbnVtYmVyO1xuICBpZiAoIShuID0gYXJyYXkubGVuZ3RoKSkgcmV0dXJuO1xuICBpZiAoKHAgPSArcCkgPD0gMCB8fCBuIDwgMikgcmV0dXJuICtmKGFycmF5WzBdLCAwLCBhcnJheSk7XG4gIGlmIChwID49IDEpIHJldHVybiArZihhcnJheVtuIC0gMV0sIG4gLSAxLCBhcnJheSk7XG4gIHZhciBuLFxuICAgICAgaCA9IChuIC0gMSkgKiBwLFxuICAgICAgaSA9IE1hdGguZmxvb3IoaCksXG4gICAgICBhID0gK2YoYXJyYXlbaV0sIGksIGFycmF5KSxcbiAgICAgIGIgPSArZihhcnJheVtpICsgMV0sIGkgKyAxLCBhcnJheSk7XG4gIHJldHVybiBhICsgKGIgLSBhKSAqIChoIC0gaSk7XG59O1xuXG52YXIgZnJlZWRtYW5EaWFjb25pcyA9IGZ1bmN0aW9uKHZhbHVlcywgbWluLCBtYXgpIHtcbiAgdmFsdWVzID0gbWFwLmNhbGwodmFsdWVzLCBudW1iZXIpLnNvcnQoYXNjZW5kaW5nKTtcbiAgcmV0dXJuIE1hdGguY2VpbCgobWF4IC0gbWluKSAvICgyICogKHRocmVzaG9sZCh2YWx1ZXMsIDAuNzUpIC0gdGhyZXNob2xkKHZhbHVlcywgMC4yNSkpICogTWF0aC5wb3codmFsdWVzLmxlbmd0aCwgLTEgLyAzKSkpO1xufTtcblxudmFyIHNjb3R0ID0gZnVuY3Rpb24odmFsdWVzLCBtaW4sIG1heCkge1xuICByZXR1cm4gTWF0aC5jZWlsKChtYXggLSBtaW4pIC8gKDMuNSAqIGRldmlhdGlvbih2YWx1ZXMpICogTWF0aC5wb3codmFsdWVzLmxlbmd0aCwgLTEgLyAzKSkpO1xufTtcblxudmFyIG1heCA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBpID0gLTEsXG4gICAgICBuID0gYXJyYXkubGVuZ3RoLFxuICAgICAgYSxcbiAgICAgIGI7XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBhcnJheVtpXSkgIT0gbnVsbCAmJiBiID49IGIpIHsgYSA9IGI7IGJyZWFrOyB9XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGFycmF5W2ldKSAhPSBudWxsICYmIGIgPiBhKSBhID0gYjtcbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwgJiYgYiA+PSBiKSB7IGEgPSBiOyBicmVhazsgfVxuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwgJiYgYiA+IGEpIGEgPSBiO1xuICB9XG5cbiAgcmV0dXJuIGE7XG59O1xuXG52YXIgbWVhbiA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBzID0gMCxcbiAgICAgIG4gPSBhcnJheS5sZW5ndGgsXG4gICAgICBhLFxuICAgICAgaSA9IC0xLFxuICAgICAgaiA9IG47XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoIWlzTmFOKGEgPSBudW1iZXIoYXJyYXlbaV0pKSkgcyArPSBhOyBlbHNlIC0tajtcbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoIWlzTmFOKGEgPSBudW1iZXIoZihhcnJheVtpXSwgaSwgYXJyYXkpKSkpIHMgKz0gYTsgZWxzZSAtLWo7XG4gIH1cblxuICBpZiAoaikgcmV0dXJuIHMgLyBqO1xufTtcblxudmFyIG1lZGlhbiA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBudW1iZXJzID0gW10sXG4gICAgICBuID0gYXJyYXkubGVuZ3RoLFxuICAgICAgYSxcbiAgICAgIGkgPSAtMTtcblxuICBpZiAoZiA9PSBudWxsKSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICghaXNOYU4oYSA9IG51bWJlcihhcnJheVtpXSkpKSBudW1iZXJzLnB1c2goYSk7XG4gIH1cblxuICBlbHNlIHtcbiAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFpc05hTihhID0gbnVtYmVyKGYoYXJyYXlbaV0sIGksIGFycmF5KSkpKSBudW1iZXJzLnB1c2goYSk7XG4gIH1cblxuICByZXR1cm4gdGhyZXNob2xkKG51bWJlcnMuc29ydChhc2NlbmRpbmcpLCAwLjUpO1xufTtcblxudmFyIG1lcmdlID0gZnVuY3Rpb24oYXJyYXlzKSB7XG4gIHZhciBuID0gYXJyYXlzLmxlbmd0aCxcbiAgICAgIG0sXG4gICAgICBpID0gLTEsXG4gICAgICBqID0gMCxcbiAgICAgIG1lcmdlZCxcbiAgICAgIGFycmF5O1xuXG4gIHdoaWxlICgrK2kgPCBuKSBqICs9IGFycmF5c1tpXS5sZW5ndGg7XG4gIG1lcmdlZCA9IG5ldyBBcnJheShqKTtcblxuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICBhcnJheSA9IGFycmF5c1tuXTtcbiAgICBtID0gYXJyYXkubGVuZ3RoO1xuICAgIHdoaWxlICgtLW0gPj0gMCkge1xuICAgICAgbWVyZ2VkWy0tal0gPSBhcnJheVttXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWVyZ2VkO1xufTtcblxudmFyIG1pbiA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBpID0gLTEsXG4gICAgICBuID0gYXJyYXkubGVuZ3RoLFxuICAgICAgYSxcbiAgICAgIGI7XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBhcnJheVtpXSkgIT0gbnVsbCAmJiBiID49IGIpIHsgYSA9IGI7IGJyZWFrOyB9XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGFycmF5W2ldKSAhPSBudWxsICYmIGEgPiBiKSBhID0gYjtcbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwgJiYgYiA+PSBiKSB7IGEgPSBiOyBicmVhazsgfVxuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwgJiYgYSA+IGIpIGEgPSBiO1xuICB9XG5cbiAgcmV0dXJuIGE7XG59O1xuXG52YXIgcGFpcnMgPSBmdW5jdGlvbihhcnJheSkge1xuICB2YXIgaSA9IDAsIG4gPSBhcnJheS5sZW5ndGggLSAxLCBwID0gYXJyYXlbMF0sIHBhaXJzID0gbmV3IEFycmF5KG4gPCAwID8gMCA6IG4pO1xuICB3aGlsZSAoaSA8IG4pIHBhaXJzW2ldID0gW3AsIHAgPSBhcnJheVsrK2ldXTtcbiAgcmV0dXJuIHBhaXJzO1xufTtcblxudmFyIHBlcm11dGUgPSBmdW5jdGlvbihhcnJheSwgaW5kZXhlcykge1xuICB2YXIgaSA9IGluZGV4ZXMubGVuZ3RoLCBwZXJtdXRlcyA9IG5ldyBBcnJheShpKTtcbiAgd2hpbGUgKGktLSkgcGVybXV0ZXNbaV0gPSBhcnJheVtpbmRleGVzW2ldXTtcbiAgcmV0dXJuIHBlcm11dGVzO1xufTtcblxudmFyIHNjYW4gPSBmdW5jdGlvbihhcnJheSwgY29tcGFyZSkge1xuICBpZiAoIShuID0gYXJyYXkubGVuZ3RoKSkgcmV0dXJuO1xuICB2YXIgaSA9IDAsXG4gICAgICBuLFxuICAgICAgaiA9IDAsXG4gICAgICB4aSxcbiAgICAgIHhqID0gYXJyYXlbal07XG5cbiAgaWYgKCFjb21wYXJlKSBjb21wYXJlID0gYXNjZW5kaW5nO1xuXG4gIHdoaWxlICgrK2kgPCBuKSBpZiAoY29tcGFyZSh4aSA9IGFycmF5W2ldLCB4aikgPCAwIHx8IGNvbXBhcmUoeGosIHhqKSAhPT0gMCkgeGogPSB4aSwgaiA9IGk7XG5cbiAgaWYgKGNvbXBhcmUoeGosIHhqKSA9PT0gMCkgcmV0dXJuIGo7XG59O1xuXG52YXIgc2h1ZmZsZSA9IGZ1bmN0aW9uKGFycmF5LCBpMCwgaTEpIHtcbiAgdmFyIG0gPSAoaTEgPT0gbnVsbCA/IGFycmF5Lmxlbmd0aCA6IGkxKSAtIChpMCA9IGkwID09IG51bGwgPyAwIDogK2kwKSxcbiAgICAgIHQsXG4gICAgICBpO1xuXG4gIHdoaWxlIChtKSB7XG4gICAgaSA9IE1hdGgucmFuZG9tKCkgKiBtLS0gfCAwO1xuICAgIHQgPSBhcnJheVttICsgaTBdO1xuICAgIGFycmF5W20gKyBpMF0gPSBhcnJheVtpICsgaTBdO1xuICAgIGFycmF5W2kgKyBpMF0gPSB0O1xuICB9XG5cbiAgcmV0dXJuIGFycmF5O1xufTtcblxudmFyIHN1bSA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBzID0gMCxcbiAgICAgIG4gPSBhcnJheS5sZW5ndGgsXG4gICAgICBhLFxuICAgICAgaSA9IC0xO1xuXG4gIGlmIChmID09IG51bGwpIHtcbiAgICB3aGlsZSAoKytpIDwgbikgaWYgKGEgPSArYXJyYXlbaV0pIHMgKz0gYTsgLy8gTm90ZTogemVybyBhbmQgbnVsbCBhcmUgZXF1aXZhbGVudC5cbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoYSA9ICtmKGFycmF5W2ldLCBpLCBhcnJheSkpIHMgKz0gYTtcbiAgfVxuXG4gIHJldHVybiBzO1xufTtcblxudmFyIHRyYW5zcG9zZSA9IGZ1bmN0aW9uKG1hdHJpeCkge1xuICBpZiAoIShuID0gbWF0cml4Lmxlbmd0aCkpIHJldHVybiBbXTtcbiAgZm9yICh2YXIgaSA9IC0xLCBtID0gbWluKG1hdHJpeCwgbGVuZ3RoKSwgdHJhbnNwb3NlID0gbmV3IEFycmF5KG0pOyArK2kgPCBtOykge1xuICAgIGZvciAodmFyIGogPSAtMSwgbiwgcm93ID0gdHJhbnNwb3NlW2ldID0gbmV3IEFycmF5KG4pOyArK2ogPCBuOykge1xuICAgICAgcm93W2pdID0gbWF0cml4W2pdW2ldO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJhbnNwb3NlO1xufTtcblxuZnVuY3Rpb24gbGVuZ3RoKGQpIHtcbiAgcmV0dXJuIGQubGVuZ3RoO1xufVxuXG52YXIgemlwID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0cmFuc3Bvc2UoYXJndW1lbnRzKTtcbn07XG5cbnZhciBwcmVmaXggPSBcIiRcIjtcblxuZnVuY3Rpb24gTWFwKCkge31cblxuTWFwLnByb3RvdHlwZSA9IG1hcCQxLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IE1hcCxcbiAgaGFzOiBmdW5jdGlvbihrZXkpIHtcbiAgICByZXR1cm4gKHByZWZpeCArIGtleSkgaW4gdGhpcztcbiAgfSxcbiAgZ2V0OiBmdW5jdGlvbihrZXkpIHtcbiAgICByZXR1cm4gdGhpc1twcmVmaXggKyBrZXldO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICB0aGlzW3ByZWZpeCArIGtleV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgcmVtb3ZlOiBmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgcHJvcGVydHkgPSBwcmVmaXggKyBrZXk7XG4gICAgcmV0dXJuIHByb3BlcnR5IGluIHRoaXMgJiYgZGVsZXRlIHRoaXNbcHJvcGVydHldO1xuICB9LFxuICBjbGVhcjogZnVuY3Rpb24oKSB7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpIGRlbGV0ZSB0aGlzW3Byb3BlcnR5XTtcbiAgfSxcbiAga2V5czogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiB0aGlzKSBpZiAocHJvcGVydHlbMF0gPT09IHByZWZpeCkga2V5cy5wdXNoKHByb3BlcnR5LnNsaWNlKDEpKTtcbiAgICByZXR1cm4ga2V5cztcbiAgfSxcbiAgdmFsdWVzOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpIHZhbHVlcy5wdXNoKHRoaXNbcHJvcGVydHldKTtcbiAgICByZXR1cm4gdmFsdWVzO1xuICB9LFxuICBlbnRyaWVzOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgZW50cmllcyA9IFtdO1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9wZXJ0eVswXSA9PT0gcHJlZml4KSBlbnRyaWVzLnB1c2goe2tleTogcHJvcGVydHkuc2xpY2UoMSksIHZhbHVlOiB0aGlzW3Byb3BlcnR5XX0pO1xuICAgIHJldHVybiBlbnRyaWVzO1xuICB9LFxuICBzaXplOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc2l6ZSA9IDA7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpICsrc2l6ZTtcbiAgICByZXR1cm4gc2l6ZTtcbiAgfSxcbiAgZW1wdHk6IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9wZXJ0eVswXSA9PT0gcHJlZml4KSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG4gIGVhY2g6IGZ1bmN0aW9uKGYpIHtcbiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiB0aGlzKSBpZiAocHJvcGVydHlbMF0gPT09IHByZWZpeCkgZih0aGlzW3Byb3BlcnR5XSwgcHJvcGVydHkuc2xpY2UoMSksIHRoaXMpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBtYXAkMShvYmplY3QsIGYpIHtcbiAgdmFyIG1hcCA9IG5ldyBNYXA7XG5cbiAgLy8gQ29weSBjb25zdHJ1Y3Rvci5cbiAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE1hcCkgb2JqZWN0LmVhY2goZnVuY3Rpb24odmFsdWUsIGtleSkgeyBtYXAuc2V0KGtleSwgdmFsdWUpOyB9KTtcblxuICAvLyBJbmRleCBhcnJheSBieSBudW1lcmljIGluZGV4IG9yIHNwZWNpZmllZCBrZXkgZnVuY3Rpb24uXG4gIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgIHZhciBpID0gLTEsXG4gICAgICAgIG4gPSBvYmplY3QubGVuZ3RoLFxuICAgICAgICBvO1xuXG4gICAgaWYgKGYgPT0gbnVsbCkgd2hpbGUgKCsraSA8IG4pIG1hcC5zZXQoaSwgb2JqZWN0W2ldKTtcbiAgICBlbHNlIHdoaWxlICgrK2kgPCBuKSBtYXAuc2V0KGYobyA9IG9iamVjdFtpXSwgaSwgb2JqZWN0KSwgbyk7XG4gIH1cblxuICAvLyBDb252ZXJ0IG9iamVjdCB0byBtYXAuXG4gIGVsc2UgaWYgKG9iamVjdCkgZm9yICh2YXIga2V5IGluIG9iamVjdCkgbWFwLnNldChrZXksIG9iamVjdFtrZXldKTtcblxuICByZXR1cm4gbWFwO1xufVxuXG52YXIgbmVzdCA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5cyA9IFtdLFxuICAgICAgc29ydEtleXMgPSBbXSxcbiAgICAgIHNvcnRWYWx1ZXMsXG4gICAgICByb2xsdXAsXG4gICAgICBuZXN0O1xuXG4gIGZ1bmN0aW9uIGFwcGx5KGFycmF5LCBkZXB0aCwgY3JlYXRlUmVzdWx0LCBzZXRSZXN1bHQpIHtcbiAgICBpZiAoZGVwdGggPj0ga2V5cy5sZW5ndGgpIHJldHVybiByb2xsdXAgIT0gbnVsbFxuICAgICAgICA/IHJvbGx1cChhcnJheSkgOiAoc29ydFZhbHVlcyAhPSBudWxsXG4gICAgICAgID8gYXJyYXkuc29ydChzb3J0VmFsdWVzKVxuICAgICAgICA6IGFycmF5KTtcblxuICAgIHZhciBpID0gLTEsXG4gICAgICAgIG4gPSBhcnJheS5sZW5ndGgsXG4gICAgICAgIGtleSA9IGtleXNbZGVwdGgrK10sXG4gICAgICAgIGtleVZhbHVlLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgdmFsdWVzQnlLZXkgPSBtYXAkMSgpLFxuICAgICAgICB2YWx1ZXMsXG4gICAgICAgIHJlc3VsdCA9IGNyZWF0ZVJlc3VsdCgpO1xuXG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIGlmICh2YWx1ZXMgPSB2YWx1ZXNCeUtleS5nZXQoa2V5VmFsdWUgPSBrZXkodmFsdWUgPSBhcnJheVtpXSkgKyBcIlwiKSkge1xuICAgICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZXNCeUtleS5zZXQoa2V5VmFsdWUsIFt2YWx1ZV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhbHVlc0J5S2V5LmVhY2goZnVuY3Rpb24odmFsdWVzLCBrZXkpIHtcbiAgICAgIHNldFJlc3VsdChyZXN1bHQsIGtleSwgYXBwbHkodmFsdWVzLCBkZXB0aCwgY3JlYXRlUmVzdWx0LCBzZXRSZXN1bHQpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBlbnRyaWVzKG1hcCwgZGVwdGgpIHtcbiAgICBpZiAoKytkZXB0aCA+IGtleXMubGVuZ3RoKSByZXR1cm4gbWFwO1xuICAgIHZhciBhcnJheSwgc29ydEtleSA9IHNvcnRLZXlzW2RlcHRoIC0gMV07XG4gICAgaWYgKHJvbGx1cCAhPSBudWxsICYmIGRlcHRoID49IGtleXMubGVuZ3RoKSBhcnJheSA9IG1hcC5lbnRyaWVzKCk7XG4gICAgZWxzZSBhcnJheSA9IFtdLCBtYXAuZWFjaChmdW5jdGlvbih2LCBrKSB7IGFycmF5LnB1c2goe2tleTogaywgdmFsdWVzOiBlbnRyaWVzKHYsIGRlcHRoKX0pOyB9KTtcbiAgICByZXR1cm4gc29ydEtleSAhPSBudWxsID8gYXJyYXkuc29ydChmdW5jdGlvbihhLCBiKSB7IHJldHVybiBzb3J0S2V5KGEua2V5LCBiLmtleSk7IH0pIDogYXJyYXk7XG4gIH1cblxuICByZXR1cm4gbmVzdCA9IHtcbiAgICBvYmplY3Q6IGZ1bmN0aW9uKGFycmF5KSB7IHJldHVybiBhcHBseShhcnJheSwgMCwgY3JlYXRlT2JqZWN0LCBzZXRPYmplY3QpOyB9LFxuICAgIG1hcDogZnVuY3Rpb24oYXJyYXkpIHsgcmV0dXJuIGFwcGx5KGFycmF5LCAwLCBjcmVhdGVNYXAsIHNldE1hcCk7IH0sXG4gICAgZW50cmllczogZnVuY3Rpb24oYXJyYXkpIHsgcmV0dXJuIGVudHJpZXMoYXBwbHkoYXJyYXksIDAsIGNyZWF0ZU1hcCwgc2V0TWFwKSwgMCk7IH0sXG4gICAga2V5OiBmdW5jdGlvbihkKSB7IGtleXMucHVzaChkKTsgcmV0dXJuIG5lc3Q7IH0sXG4gICAgc29ydEtleXM6IGZ1bmN0aW9uKG9yZGVyKSB7IHNvcnRLZXlzW2tleXMubGVuZ3RoIC0gMV0gPSBvcmRlcjsgcmV0dXJuIG5lc3Q7IH0sXG4gICAgc29ydFZhbHVlczogZnVuY3Rpb24ob3JkZXIpIHsgc29ydFZhbHVlcyA9IG9yZGVyOyByZXR1cm4gbmVzdDsgfSxcbiAgICByb2xsdXA6IGZ1bmN0aW9uKGYpIHsgcm9sbHVwID0gZjsgcmV0dXJuIG5lc3Q7IH1cbiAgfTtcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZU9iamVjdCgpIHtcbiAgcmV0dXJuIHt9O1xufVxuXG5mdW5jdGlvbiBzZXRPYmplY3Qob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU1hcCgpIHtcbiAgcmV0dXJuIG1hcCQxKCk7XG59XG5cbmZ1bmN0aW9uIHNldE1hcChtYXAsIGtleSwgdmFsdWUpIHtcbiAgbWFwLnNldChrZXksIHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gU2V0KCkge31cblxudmFyIHByb3RvID0gbWFwJDEucHJvdG90eXBlO1xuXG5TZXQucHJvdG90eXBlID0gc2V0LnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFNldCxcbiAgaGFzOiBwcm90by5oYXMsXG4gIGFkZDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICB2YWx1ZSArPSBcIlwiO1xuICAgIHRoaXNbcHJlZml4ICsgdmFsdWVdID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIHJlbW92ZTogcHJvdG8ucmVtb3ZlLFxuICBjbGVhcjogcHJvdG8uY2xlYXIsXG4gIHZhbHVlczogcHJvdG8ua2V5cyxcbiAgc2l6ZTogcHJvdG8uc2l6ZSxcbiAgZW1wdHk6IHByb3RvLmVtcHR5LFxuICBlYWNoOiBwcm90by5lYWNoXG59O1xuXG5mdW5jdGlvbiBzZXQob2JqZWN0LCBmKSB7XG4gIHZhciBzZXQgPSBuZXcgU2V0O1xuXG4gIC8vIENvcHkgY29uc3RydWN0b3IuXG4gIGlmIChvYmplY3QgaW5zdGFuY2VvZiBTZXQpIG9iamVjdC5lYWNoKGZ1bmN0aW9uKHZhbHVlKSB7IHNldC5hZGQodmFsdWUpOyB9KTtcblxuICAvLyBPdGhlcndpc2UsIGFzc3VtZSBpdOKAmXMgYW4gYXJyYXkuXG4gIGVsc2UgaWYgKG9iamVjdCkge1xuICAgIHZhciBpID0gLTEsIG4gPSBvYmplY3QubGVuZ3RoO1xuICAgIGlmIChmID09IG51bGwpIHdoaWxlICgrK2kgPCBuKSBzZXQuYWRkKG9iamVjdFtpXSk7XG4gICAgZWxzZSB3aGlsZSAoKytpIDwgbikgc2V0LmFkZChmKG9iamVjdFtpXSwgaSwgb2JqZWN0KSk7XG4gIH1cblxuICByZXR1cm4gc2V0O1xufVxuXG52YXIga2V5cyA9IGZ1bmN0aW9uKG1hcCkge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gbWFwKSBrZXlzLnB1c2goa2V5KTtcbiAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgdmFsdWVzID0gZnVuY3Rpb24obWFwKSB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG1hcCkgdmFsdWVzLnB1c2gobWFwW2tleV0pO1xuICByZXR1cm4gdmFsdWVzO1xufTtcblxudmFyIGVudHJpZXMgPSBmdW5jdGlvbihtYXApIHtcbiAgdmFyIGVudHJpZXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG1hcCkgZW50cmllcy5wdXNoKHtrZXk6IGtleSwgdmFsdWU6IG1hcFtrZXldfSk7XG4gIHJldHVybiBlbnRyaWVzO1xufTtcblxudmFyIHVuaWZvcm0gPSBmdW5jdGlvbihtaW4sIG1heCkge1xuICBtaW4gPSBtaW4gPT0gbnVsbCA/IDAgOiArbWluO1xuICBtYXggPSBtYXggPT0gbnVsbCA/IDEgOiArbWF4O1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkgbWF4ID0gbWluLCBtaW4gPSAwO1xuICBlbHNlIG1heCAtPSBtaW47XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gTWF0aC5yYW5kb20oKSAqIG1heCArIG1pbjtcbiAgfTtcbn07XG5cbnZhciBub3JtYWwgPSBmdW5jdGlvbihtdSwgc2lnbWEpIHtcbiAgdmFyIHgsIHI7XG4gIG11ID0gbXUgPT0gbnVsbCA/IDAgOiArbXU7XG4gIHNpZ21hID0gc2lnbWEgPT0gbnVsbCA/IDEgOiArc2lnbWE7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgeTtcblxuICAgIC8vIElmIGF2YWlsYWJsZSwgdXNlIHRoZSBzZWNvbmQgcHJldmlvdXNseS1nZW5lcmF0ZWQgdW5pZm9ybSByYW5kb20uXG4gICAgaWYgKHggIT0gbnVsbCkgeSA9IHgsIHggPSBudWxsO1xuXG4gICAgLy8gT3RoZXJ3aXNlLCBnZW5lcmF0ZSBhIG5ldyB4IGFuZCB5LlxuICAgIGVsc2UgZG8ge1xuICAgICAgeCA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgIHkgPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7XG4gICAgICByID0geCAqIHggKyB5ICogeTtcbiAgICB9IHdoaWxlICghciB8fCByID4gMSk7XG5cbiAgICByZXR1cm4gbXUgKyBzaWdtYSAqIHkgKiBNYXRoLnNxcnQoLTIgKiBNYXRoLmxvZyhyKSAvIHIpO1xuICB9O1xufTtcblxudmFyIGxvZ05vcm1hbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmFuZG9tTm9ybWFsID0gbm9ybWFsLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gTWF0aC5leHAocmFuZG9tTm9ybWFsKCkpO1xuICB9O1xufTtcblxudmFyIGlyd2luSGFsbCA9IGZ1bmN0aW9uKG4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIHN1bSA9IDAsIGkgPSAwOyBpIDwgbjsgKytpKSBzdW0gKz0gTWF0aC5yYW5kb20oKTtcbiAgICByZXR1cm4gc3VtO1xuICB9O1xufTtcblxudmFyIGJhdGVzID0gZnVuY3Rpb24obikge1xuICB2YXIgcmFuZG9tSXJ3aW5IYWxsID0gaXJ3aW5IYWxsKG4pO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHJhbmRvbUlyd2luSGFsbCgpIC8gbjtcbiAgfTtcbn07XG5cbnZhciBleHBvbmVudGlhbCA9IGZ1bmN0aW9uKGxhbWJkYSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIC1NYXRoLmxvZygxIC0gTWF0aC5yYW5kb20oKSkgLyBsYW1iZGE7XG4gIH07XG59O1xuXG5mdW5jdGlvbiBsaW5lYXIodCkge1xuICByZXR1cm4gK3Q7XG59XG5cbmZ1bmN0aW9uIHF1YWRJbih0KSB7XG4gIHJldHVybiB0ICogdDtcbn1cblxuZnVuY3Rpb24gcXVhZE91dCh0KSB7XG4gIHJldHVybiB0ICogKDIgLSB0KTtcbn1cblxuZnVuY3Rpb24gcXVhZEluT3V0KHQpIHtcbiAgcmV0dXJuICgodCAqPSAyKSA8PSAxID8gdCAqIHQgOiAtLXQgKiAoMiAtIHQpICsgMSkgLyAyO1xufVxuXG5mdW5jdGlvbiBjdWJpY0luKHQpIHtcbiAgcmV0dXJuIHQgKiB0ICogdDtcbn1cblxuZnVuY3Rpb24gY3ViaWNPdXQodCkge1xuICByZXR1cm4gLS10ICogdCAqIHQgKyAxO1xufVxuXG5mdW5jdGlvbiBjdWJpY0luT3V0KHQpIHtcbiAgcmV0dXJuICgodCAqPSAyKSA8PSAxID8gdCAqIHQgKiB0IDogKHQgLT0gMikgKiB0ICogdCArIDIpIC8gMjtcbn1cblxudmFyIGV4cG9uZW50ID0gMztcblxudmFyIHBvbHlJbiA9IChmdW5jdGlvbiBjdXN0b20oZSkge1xuICBlID0gK2U7XG5cbiAgZnVuY3Rpb24gcG9seUluKHQpIHtcbiAgICByZXR1cm4gTWF0aC5wb3codCwgZSk7XG4gIH1cblxuICBwb2x5SW4uZXhwb25lbnQgPSBjdXN0b207XG5cbiAgcmV0dXJuIHBvbHlJbjtcbn0pKGV4cG9uZW50KTtcblxudmFyIHBvbHlPdXQgPSAoZnVuY3Rpb24gY3VzdG9tKGUpIHtcbiAgZSA9ICtlO1xuXG4gIGZ1bmN0aW9uIHBvbHlPdXQodCkge1xuICAgIHJldHVybiAxIC0gTWF0aC5wb3coMSAtIHQsIGUpO1xuICB9XG5cbiAgcG9seU91dC5leHBvbmVudCA9IGN1c3RvbTtcblxuICByZXR1cm4gcG9seU91dDtcbn0pKGV4cG9uZW50KTtcblxudmFyIHBvbHlJbk91dCA9IChmdW5jdGlvbiBjdXN0b20oZSkge1xuICBlID0gK2U7XG5cbiAgZnVuY3Rpb24gcG9seUluT3V0KHQpIHtcbiAgICByZXR1cm4gKCh0ICo9IDIpIDw9IDEgPyBNYXRoLnBvdyh0LCBlKSA6IDIgLSBNYXRoLnBvdygyIC0gdCwgZSkpIC8gMjtcbiAgfVxuXG4gIHBvbHlJbk91dC5leHBvbmVudCA9IGN1c3RvbTtcblxuICByZXR1cm4gcG9seUluT3V0O1xufSkoZXhwb25lbnQpO1xuXG52YXIgcGkgPSBNYXRoLlBJO1xudmFyIGhhbGZQaSA9IHBpIC8gMjtcblxuZnVuY3Rpb24gc2luSW4odCkge1xuICByZXR1cm4gMSAtIE1hdGguY29zKHQgKiBoYWxmUGkpO1xufVxuXG5mdW5jdGlvbiBzaW5PdXQodCkge1xuICByZXR1cm4gTWF0aC5zaW4odCAqIGhhbGZQaSk7XG59XG5cbmZ1bmN0aW9uIHNpbkluT3V0KHQpIHtcbiAgcmV0dXJuICgxIC0gTWF0aC5jb3MocGkgKiB0KSkgLyAyO1xufVxuXG5mdW5jdGlvbiBleHBJbih0KSB7XG4gIHJldHVybiBNYXRoLnBvdygyLCAxMCAqIHQgLSAxMCk7XG59XG5cbmZ1bmN0aW9uIGV4cE91dCh0KSB7XG4gIHJldHVybiAxIC0gTWF0aC5wb3coMiwgLTEwICogdCk7XG59XG5cbmZ1bmN0aW9uIGV4cEluT3V0KHQpIHtcbiAgcmV0dXJuICgodCAqPSAyKSA8PSAxID8gTWF0aC5wb3coMiwgMTAgKiB0IC0gMTApIDogMiAtIE1hdGgucG93KDIsIDEwIC0gMTAgKiB0KSkgLyAyO1xufVxuXG5mdW5jdGlvbiBjaXJjbGVJbih0KSB7XG4gIHJldHVybiAxIC0gTWF0aC5zcXJ0KDEgLSB0ICogdCk7XG59XG5cbmZ1bmN0aW9uIGNpcmNsZU91dCh0KSB7XG4gIHJldHVybiBNYXRoLnNxcnQoMSAtIC0tdCAqIHQpO1xufVxuXG5mdW5jdGlvbiBjaXJjbGVJbk91dCh0KSB7XG4gIHJldHVybiAoKHQgKj0gMikgPD0gMSA/IDEgLSBNYXRoLnNxcnQoMSAtIHQgKiB0KSA6IE1hdGguc3FydCgxIC0gKHQgLT0gMikgKiB0KSArIDEpIC8gMjtcbn1cblxudmFyIGIxID0gNCAvIDExO1xudmFyIGIyID0gNiAvIDExO1xudmFyIGIzID0gOCAvIDExO1xudmFyIGI0ID0gMyAvIDQ7XG52YXIgYjUgPSA5IC8gMTE7XG52YXIgYjYgPSAxMCAvIDExO1xudmFyIGI3ID0gMTUgLyAxNjtcbnZhciBiOCA9IDIxIC8gMjI7XG52YXIgYjkgPSA2MyAvIDY0O1xudmFyIGIwID0gMSAvIGIxIC8gYjE7XG5cbmZ1bmN0aW9uIGJvdW5jZUluKHQpIHtcbiAgcmV0dXJuIDEgLSBib3VuY2VPdXQoMSAtIHQpO1xufVxuXG5mdW5jdGlvbiBib3VuY2VPdXQodCkge1xuICByZXR1cm4gKHQgPSArdCkgPCBiMSA/IGIwICogdCAqIHQgOiB0IDwgYjMgPyBiMCAqICh0IC09IGIyKSAqIHQgKyBiNCA6IHQgPCBiNiA/IGIwICogKHQgLT0gYjUpICogdCArIGI3IDogYjAgKiAodCAtPSBiOCkgKiB0ICsgYjk7XG59XG5cbmZ1bmN0aW9uIGJvdW5jZUluT3V0KHQpIHtcbiAgcmV0dXJuICgodCAqPSAyKSA8PSAxID8gMSAtIGJvdW5jZU91dCgxIC0gdCkgOiBib3VuY2VPdXQodCAtIDEpICsgMSkgLyAyO1xufVxuXG52YXIgb3ZlcnNob290ID0gMS43MDE1ODtcblxudmFyIGJhY2tJbiA9IChmdW5jdGlvbiBjdXN0b20ocykge1xuICBzID0gK3M7XG5cbiAgZnVuY3Rpb24gYmFja0luKHQpIHtcbiAgICByZXR1cm4gdCAqIHQgKiAoKHMgKyAxKSAqIHQgLSBzKTtcbiAgfVxuXG4gIGJhY2tJbi5vdmVyc2hvb3QgPSBjdXN0b207XG5cbiAgcmV0dXJuIGJhY2tJbjtcbn0pKG92ZXJzaG9vdCk7XG5cbnZhciBiYWNrT3V0ID0gKGZ1bmN0aW9uIGN1c3RvbShzKSB7XG4gIHMgPSArcztcblxuICBmdW5jdGlvbiBiYWNrT3V0KHQpIHtcbiAgICByZXR1cm4gLS10ICogdCAqICgocyArIDEpICogdCArIHMpICsgMTtcbiAgfVxuXG4gIGJhY2tPdXQub3ZlcnNob290ID0gY3VzdG9tO1xuXG4gIHJldHVybiBiYWNrT3V0O1xufSkob3ZlcnNob290KTtcblxudmFyIGJhY2tJbk91dCA9IChmdW5jdGlvbiBjdXN0b20ocykge1xuICBzID0gK3M7XG5cbiAgZnVuY3Rpb24gYmFja0luT3V0KHQpIHtcbiAgICByZXR1cm4gKCh0ICo9IDIpIDwgMSA/IHQgKiB0ICogKChzICsgMSkgKiB0IC0gcykgOiAodCAtPSAyKSAqIHQgKiAoKHMgKyAxKSAqIHQgKyBzKSArIDIpIC8gMjtcbiAgfVxuXG4gIGJhY2tJbk91dC5vdmVyc2hvb3QgPSBjdXN0b207XG5cbiAgcmV0dXJuIGJhY2tJbk91dDtcbn0pKG92ZXJzaG9vdCk7XG5cbnZhciB0YXUgPSAyICogTWF0aC5QSTtcbnZhciBhbXBsaXR1ZGUgPSAxO1xudmFyIHBlcmlvZCA9IDAuMztcblxudmFyIGVsYXN0aWNJbiA9IChmdW5jdGlvbiBjdXN0b20oYSwgcCkge1xuICB2YXIgcyA9IE1hdGguYXNpbigxIC8gKGEgPSBNYXRoLm1heCgxLCBhKSkpICogKHAgLz0gdGF1KTtcblxuICBmdW5jdGlvbiBlbGFzdGljSW4odCkge1xuICAgIHJldHVybiBhICogTWF0aC5wb3coMiwgMTAgKiAtLXQpICogTWF0aC5zaW4oKHMgLSB0KSAvIHApO1xuICB9XG5cbiAgZWxhc3RpY0luLmFtcGxpdHVkZSA9IGZ1bmN0aW9uKGEpIHsgcmV0dXJuIGN1c3RvbShhLCBwICogdGF1KTsgfTtcbiAgZWxhc3RpY0luLnBlcmlvZCA9IGZ1bmN0aW9uKHApIHsgcmV0dXJuIGN1c3RvbShhLCBwKTsgfTtcblxuICByZXR1cm4gZWxhc3RpY0luO1xufSkoYW1wbGl0dWRlLCBwZXJpb2QpO1xuXG52YXIgZWxhc3RpY091dCA9IChmdW5jdGlvbiBjdXN0b20oYSwgcCkge1xuICB2YXIgcyA9IE1hdGguYXNpbigxIC8gKGEgPSBNYXRoLm1heCgxLCBhKSkpICogKHAgLz0gdGF1KTtcblxuICBmdW5jdGlvbiBlbGFzdGljT3V0KHQpIHtcbiAgICByZXR1cm4gMSAtIGEgKiBNYXRoLnBvdygyLCAtMTAgKiAodCA9ICt0KSkgKiBNYXRoLnNpbigodCArIHMpIC8gcCk7XG4gIH1cblxuICBlbGFzdGljT3V0LmFtcGxpdHVkZSA9IGZ1bmN0aW9uKGEpIHsgcmV0dXJuIGN1c3RvbShhLCBwICogdGF1KTsgfTtcbiAgZWxhc3RpY091dC5wZXJpb2QgPSBmdW5jdGlvbihwKSB7IHJldHVybiBjdXN0b20oYSwgcCk7IH07XG5cbiAgcmV0dXJuIGVsYXN0aWNPdXQ7XG59KShhbXBsaXR1ZGUsIHBlcmlvZCk7XG5cbnZhciBlbGFzdGljSW5PdXQgPSAoZnVuY3Rpb24gY3VzdG9tKGEsIHApIHtcbiAgdmFyIHMgPSBNYXRoLmFzaW4oMSAvIChhID0gTWF0aC5tYXgoMSwgYSkpKSAqIChwIC89IHRhdSk7XG5cbiAgZnVuY3Rpb24gZWxhc3RpY0luT3V0KHQpIHtcbiAgICByZXR1cm4gKCh0ID0gdCAqIDIgLSAxKSA8IDBcbiAgICAgICAgPyBhICogTWF0aC5wb3coMiwgMTAgKiB0KSAqIE1hdGguc2luKChzIC0gdCkgLyBwKVxuICAgICAgICA6IDIgLSBhICogTWF0aC5wb3coMiwgLTEwICogdCkgKiBNYXRoLnNpbigocyArIHQpIC8gcCkpIC8gMjtcbiAgfVxuXG4gIGVsYXN0aWNJbk91dC5hbXBsaXR1ZGUgPSBmdW5jdGlvbihhKSB7IHJldHVybiBjdXN0b20oYSwgcCAqIHRhdSk7IH07XG4gIGVsYXN0aWNJbk91dC5wZXJpb2QgPSBmdW5jdGlvbihwKSB7IHJldHVybiBjdXN0b20oYSwgcCk7IH07XG5cbiAgcmV0dXJuIGVsYXN0aWNJbk91dDtcbn0pKGFtcGxpdHVkZSwgcGVyaW9kKTtcblxudmFyIGFyZWEgPSBmdW5jdGlvbihwb2x5Z29uKSB7XG4gIHZhciBpID0gLTEsXG4gICAgICBuID0gcG9seWdvbi5sZW5ndGgsXG4gICAgICBhLFxuICAgICAgYiA9IHBvbHlnb25bbiAtIDFdLFxuICAgICAgYXJlYSA9IDA7XG5cbiAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICBhID0gYjtcbiAgICBiID0gcG9seWdvbltpXTtcbiAgICBhcmVhICs9IGFbMV0gKiBiWzBdIC0gYVswXSAqIGJbMV07XG4gIH1cblxuICByZXR1cm4gYXJlYSAvIDI7XG59O1xuXG52YXIgY2VudHJvaWQgPSBmdW5jdGlvbihwb2x5Z29uKSB7XG4gIHZhciBpID0gLTEsXG4gICAgICBuID0gcG9seWdvbi5sZW5ndGgsXG4gICAgICB4ID0gMCxcbiAgICAgIHkgPSAwLFxuICAgICAgYSxcbiAgICAgIGIgPSBwb2x5Z29uW24gLSAxXSxcbiAgICAgIGMsXG4gICAgICBrID0gMDtcblxuICB3aGlsZSAoKytpIDwgbikge1xuICAgIGEgPSBiO1xuICAgIGIgPSBwb2x5Z29uW2ldO1xuICAgIGsgKz0gYyA9IGFbMF0gKiBiWzFdIC0gYlswXSAqIGFbMV07XG4gICAgeCArPSAoYVswXSArIGJbMF0pICogYztcbiAgICB5ICs9IChhWzFdICsgYlsxXSkgKiBjO1xuICB9XG5cbiAgcmV0dXJuIGsgKj0gMywgW3ggLyBrLCB5IC8ga107XG59O1xuXG4vLyBSZXR1cm5zIHRoZSAyRCBjcm9zcyBwcm9kdWN0IG9mIEFCIGFuZCBBQyB2ZWN0b3JzLCBpLmUuLCB0aGUgei1jb21wb25lbnQgb2Zcbi8vIHRoZSAzRCBjcm9zcyBwcm9kdWN0IGluIGEgcXVhZHJhbnQgSSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBzeXN0ZW0gKCt4IGlzXG4vLyByaWdodCwgK3kgaXMgdXApLiBSZXR1cm5zIGEgcG9zaXRpdmUgdmFsdWUgaWYgQUJDIGlzIGNvdW50ZXItY2xvY2t3aXNlLFxuLy8gbmVnYXRpdmUgaWYgY2xvY2t3aXNlLCBhbmQgemVybyBpZiB0aGUgcG9pbnRzIGFyZSBjb2xsaW5lYXIuXG52YXIgY3Jvc3MgPSBmdW5jdGlvbihhLCBiLCBjKSB7XG4gIHJldHVybiAoYlswXSAtIGFbMF0pICogKGNbMV0gLSBhWzFdKSAtIChiWzFdIC0gYVsxXSkgKiAoY1swXSAtIGFbMF0pO1xufTtcblxuZnVuY3Rpb24gbGV4aWNvZ3JhcGhpY09yZGVyKGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gLSBiWzBdIHx8IGFbMV0gLSBiWzFdO1xufVxuXG4vLyBDb21wdXRlcyB0aGUgdXBwZXIgY29udmV4IGh1bGwgcGVyIHRoZSBtb25vdG9uZSBjaGFpbiBhbGdvcml0aG0uXG4vLyBBc3N1bWVzIHBvaW50cy5sZW5ndGggPj0gMywgaXMgc29ydGVkIGJ5IHgsIHVuaXF1ZSBpbiB5LlxuLy8gUmV0dXJucyBhbiBhcnJheSBvZiBpbmRpY2VzIGludG8gcG9pbnRzIGluIGxlZnQtdG8tcmlnaHQgb3JkZXIuXG5mdW5jdGlvbiBjb21wdXRlVXBwZXJIdWxsSW5kZXhlcyhwb2ludHMpIHtcbiAgdmFyIG4gPSBwb2ludHMubGVuZ3RoLFxuICAgICAgaW5kZXhlcyA9IFswLCAxXSxcbiAgICAgIHNpemUgPSAyO1xuXG4gIGZvciAodmFyIGkgPSAyOyBpIDwgbjsgKytpKSB7XG4gICAgd2hpbGUgKHNpemUgPiAxICYmIGNyb3NzKHBvaW50c1tpbmRleGVzW3NpemUgLSAyXV0sIHBvaW50c1tpbmRleGVzW3NpemUgLSAxXV0sIHBvaW50c1tpXSkgPD0gMCkgLS1zaXplO1xuICAgIGluZGV4ZXNbc2l6ZSsrXSA9IGk7XG4gIH1cblxuICByZXR1cm4gaW5kZXhlcy5zbGljZSgwLCBzaXplKTsgLy8gcmVtb3ZlIHBvcHBlZCBwb2ludHNcbn1cblxudmFyIGh1bGwgPSBmdW5jdGlvbihwb2ludHMpIHtcbiAgaWYgKChuID0gcG9pbnRzLmxlbmd0aCkgPCAzKSByZXR1cm4gbnVsbDtcblxuICB2YXIgaSxcbiAgICAgIG4sXG4gICAgICBzb3J0ZWRQb2ludHMgPSBuZXcgQXJyYXkobiksXG4gICAgICBmbGlwcGVkUG9pbnRzID0gbmV3IEFycmF5KG4pO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHNvcnRlZFBvaW50c1tpXSA9IFsrcG9pbnRzW2ldWzBdLCArcG9pbnRzW2ldWzFdLCBpXTtcbiAgc29ydGVkUG9pbnRzLnNvcnQobGV4aWNvZ3JhcGhpY09yZGVyKTtcbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgZmxpcHBlZFBvaW50c1tpXSA9IFtzb3J0ZWRQb2ludHNbaV1bMF0sIC1zb3J0ZWRQb2ludHNbaV1bMV1dO1xuXG4gIHZhciB1cHBlckluZGV4ZXMgPSBjb21wdXRlVXBwZXJIdWxsSW5kZXhlcyhzb3J0ZWRQb2ludHMpLFxuICAgICAgbG93ZXJJbmRleGVzID0gY29tcHV0ZVVwcGVySHVsbEluZGV4ZXMoZmxpcHBlZFBvaW50cyk7XG5cbiAgLy8gQ29uc3RydWN0IHRoZSBodWxsIHBvbHlnb24sIHJlbW92aW5nIHBvc3NpYmxlIGR1cGxpY2F0ZSBlbmRwb2ludHMuXG4gIHZhciBza2lwTGVmdCA9IGxvd2VySW5kZXhlc1swXSA9PT0gdXBwZXJJbmRleGVzWzBdLFxuICAgICAgc2tpcFJpZ2h0ID0gbG93ZXJJbmRleGVzW2xvd2VySW5kZXhlcy5sZW5ndGggLSAxXSA9PT0gdXBwZXJJbmRleGVzW3VwcGVySW5kZXhlcy5sZW5ndGggLSAxXSxcbiAgICAgIGh1bGwgPSBbXTtcblxuICAvLyBBZGQgdXBwZXIgaHVsbCBpbiByaWdodC10by1sIG9yZGVyLlxuICAvLyBUaGVuIGFkZCBsb3dlciBodWxsIGluIGxlZnQtdG8tcmlnaHQgb3JkZXIuXG4gIGZvciAoaSA9IHVwcGVySW5kZXhlcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgaHVsbC5wdXNoKHBvaW50c1tzb3J0ZWRQb2ludHNbdXBwZXJJbmRleGVzW2ldXVsyXV0pO1xuICBmb3IgKGkgPSArc2tpcExlZnQ7IGkgPCBsb3dlckluZGV4ZXMubGVuZ3RoIC0gc2tpcFJpZ2h0OyArK2kpIGh1bGwucHVzaChwb2ludHNbc29ydGVkUG9pbnRzW2xvd2VySW5kZXhlc1tpXV1bMl1dKTtcblxuICByZXR1cm4gaHVsbDtcbn07XG5cbnZhciBjb250YWlucyA9IGZ1bmN0aW9uKHBvbHlnb24sIHBvaW50KSB7XG4gIHZhciBuID0gcG9seWdvbi5sZW5ndGgsXG4gICAgICBwID0gcG9seWdvbltuIC0gMV0sXG4gICAgICB4ID0gcG9pbnRbMF0sIHkgPSBwb2ludFsxXSxcbiAgICAgIHgwID0gcFswXSwgeTAgPSBwWzFdLFxuICAgICAgeDEsIHkxLFxuICAgICAgaW5zaWRlID0gZmFsc2U7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICBwID0gcG9seWdvbltpXSwgeDEgPSBwWzBdLCB5MSA9IHBbMV07XG4gICAgaWYgKCgoeTEgPiB5KSAhPT0gKHkwID4geSkpICYmICh4IDwgKHgwIC0geDEpICogKHkgLSB5MSkgLyAoeTAgLSB5MSkgKyB4MSkpIGluc2lkZSA9ICFpbnNpZGU7XG4gICAgeDAgPSB4MSwgeTAgPSB5MTtcbiAgfVxuXG4gIHJldHVybiBpbnNpZGU7XG59O1xuXG52YXIgbGVuZ3RoJDEgPSBmdW5jdGlvbihwb2x5Z29uKSB7XG4gIHZhciBpID0gLTEsXG4gICAgICBuID0gcG9seWdvbi5sZW5ndGgsXG4gICAgICBiID0gcG9seWdvbltuIC0gMV0sXG4gICAgICB4YSxcbiAgICAgIHlhLFxuICAgICAgeGIgPSBiWzBdLFxuICAgICAgeWIgPSBiWzFdLFxuICAgICAgcGVyaW1ldGVyID0gMDtcblxuICB3aGlsZSAoKytpIDwgbikge1xuICAgIHhhID0geGI7XG4gICAgeWEgPSB5YjtcbiAgICBiID0gcG9seWdvbltpXTtcbiAgICB4YiA9IGJbMF07XG4gICAgeWIgPSBiWzFdO1xuICAgIHhhIC09IHhiO1xuICAgIHlhIC09IHliO1xuICAgIHBlcmltZXRlciArPSBNYXRoLnNxcnQoeGEgKiB4YSArIHlhICogeWEpO1xuICB9XG5cbiAgcmV0dXJuIHBlcmltZXRlcjtcbn07XG5cbnZhciBwaSQxID0gTWF0aC5QSTtcbnZhciB0YXUkMSA9IDIgKiBwaSQxO1xudmFyIGVwc2lsb24gPSAxZS02O1xudmFyIHRhdUVwc2lsb24gPSB0YXUkMSAtIGVwc2lsb247XG5cbmZ1bmN0aW9uIFBhdGgoKSB7XG4gIHRoaXMuX3gwID0gdGhpcy5feTAgPSAvLyBzdGFydCBvZiBjdXJyZW50IHN1YnBhdGhcbiAgdGhpcy5feDEgPSB0aGlzLl95MSA9IG51bGw7IC8vIGVuZCBvZiBjdXJyZW50IHN1YnBhdGhcbiAgdGhpcy5fID0gXCJcIjtcbn1cblxuZnVuY3Rpb24gcGF0aCgpIHtcbiAgcmV0dXJuIG5ldyBQYXRoO1xufVxuXG5QYXRoLnByb3RvdHlwZSA9IHBhdGgucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogUGF0aCxcbiAgbW92ZVRvOiBmdW5jdGlvbih4LCB5KSB7XG4gICAgdGhpcy5fICs9IFwiTVwiICsgKHRoaXMuX3gwID0gdGhpcy5feDEgPSAreCkgKyBcIixcIiArICh0aGlzLl95MCA9IHRoaXMuX3kxID0gK3kpO1xuICB9LFxuICBjbG9zZVBhdGg6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl94MSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5feDEgPSB0aGlzLl94MCwgdGhpcy5feTEgPSB0aGlzLl95MDtcbiAgICAgIHRoaXMuXyArPSBcIlpcIjtcbiAgICB9XG4gIH0sXG4gIGxpbmVUbzogZnVuY3Rpb24oeCwgeSkge1xuICAgIHRoaXMuXyArPSBcIkxcIiArICh0aGlzLl94MSA9ICt4KSArIFwiLFwiICsgKHRoaXMuX3kxID0gK3kpO1xuICB9LFxuICBxdWFkcmF0aWNDdXJ2ZVRvOiBmdW5jdGlvbih4MSwgeTEsIHgsIHkpIHtcbiAgICB0aGlzLl8gKz0gXCJRXCIgKyAoK3gxKSArIFwiLFwiICsgKCt5MSkgKyBcIixcIiArICh0aGlzLl94MSA9ICt4KSArIFwiLFwiICsgKHRoaXMuX3kxID0gK3kpO1xuICB9LFxuICBiZXppZXJDdXJ2ZVRvOiBmdW5jdGlvbih4MSwgeTEsIHgyLCB5MiwgeCwgeSkge1xuICAgIHRoaXMuXyArPSBcIkNcIiArICgreDEpICsgXCIsXCIgKyAoK3kxKSArIFwiLFwiICsgKCt4MikgKyBcIixcIiArICgreTIpICsgXCIsXCIgKyAodGhpcy5feDEgPSAreCkgKyBcIixcIiArICh0aGlzLl95MSA9ICt5KTtcbiAgfSxcbiAgYXJjVG86IGZ1bmN0aW9uKHgxLCB5MSwgeDIsIHkyLCByKSB7XG4gICAgeDEgPSAreDEsIHkxID0gK3kxLCB4MiA9ICt4MiwgeTIgPSAreTIsIHIgPSArcjtcbiAgICB2YXIgeDAgPSB0aGlzLl94MSxcbiAgICAgICAgeTAgPSB0aGlzLl95MSxcbiAgICAgICAgeDIxID0geDIgLSB4MSxcbiAgICAgICAgeTIxID0geTIgLSB5MSxcbiAgICAgICAgeDAxID0geDAgLSB4MSxcbiAgICAgICAgeTAxID0geTAgLSB5MSxcbiAgICAgICAgbDAxXzIgPSB4MDEgKiB4MDEgKyB5MDEgKiB5MDE7XG5cbiAgICAvLyBJcyB0aGUgcmFkaXVzIG5lZ2F0aXZlPyBFcnJvci5cbiAgICBpZiAociA8IDApIHRocm93IG5ldyBFcnJvcihcIm5lZ2F0aXZlIHJhZGl1czogXCIgKyByKTtcblxuICAgIC8vIElzIHRoaXMgcGF0aCBlbXB0eT8gTW92ZSB0byAoeDEseTEpLlxuICAgIGlmICh0aGlzLl94MSA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5fICs9IFwiTVwiICsgKHRoaXMuX3gxID0geDEpICsgXCIsXCIgKyAodGhpcy5feTEgPSB5MSk7XG4gICAgfVxuXG4gICAgLy8gT3IsIGlzICh4MSx5MSkgY29pbmNpZGVudCB3aXRoICh4MCx5MCk/IERvIG5vdGhpbmcuXG4gICAgZWxzZSBpZiAoIShsMDFfMiA+IGVwc2lsb24pKSB7fVxuXG4gICAgLy8gT3IsIGFyZSAoeDAseTApLCAoeDEseTEpIGFuZCAoeDIseTIpIGNvbGxpbmVhcj9cbiAgICAvLyBFcXVpdmFsZW50bHksIGlzICh4MSx5MSkgY29pbmNpZGVudCB3aXRoICh4Mix5Mik/XG4gICAgLy8gT3IsIGlzIHRoZSByYWRpdXMgemVybz8gTGluZSB0byAoeDEseTEpLlxuICAgIGVsc2UgaWYgKCEoTWF0aC5hYnMoeTAxICogeDIxIC0geTIxICogeDAxKSA+IGVwc2lsb24pIHx8ICFyKSB7XG4gICAgICB0aGlzLl8gKz0gXCJMXCIgKyAodGhpcy5feDEgPSB4MSkgKyBcIixcIiArICh0aGlzLl95MSA9IHkxKTtcbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UsIGRyYXcgYW4gYXJjIVxuICAgIGVsc2Uge1xuICAgICAgdmFyIHgyMCA9IHgyIC0geDAsXG4gICAgICAgICAgeTIwID0geTIgLSB5MCxcbiAgICAgICAgICBsMjFfMiA9IHgyMSAqIHgyMSArIHkyMSAqIHkyMSxcbiAgICAgICAgICBsMjBfMiA9IHgyMCAqIHgyMCArIHkyMCAqIHkyMCxcbiAgICAgICAgICBsMjEgPSBNYXRoLnNxcnQobDIxXzIpLFxuICAgICAgICAgIGwwMSA9IE1hdGguc3FydChsMDFfMiksXG4gICAgICAgICAgbCA9IHIgKiBNYXRoLnRhbigocGkkMSAtIE1hdGguYWNvcygobDIxXzIgKyBsMDFfMiAtIGwyMF8yKSAvICgyICogbDIxICogbDAxKSkpIC8gMiksXG4gICAgICAgICAgdDAxID0gbCAvIGwwMSxcbiAgICAgICAgICB0MjEgPSBsIC8gbDIxO1xuXG4gICAgICAvLyBJZiB0aGUgc3RhcnQgdGFuZ2VudCBpcyBub3QgY29pbmNpZGVudCB3aXRoICh4MCx5MCksIGxpbmUgdG8uXG4gICAgICBpZiAoTWF0aC5hYnModDAxIC0gMSkgPiBlcHNpbG9uKSB7XG4gICAgICAgIHRoaXMuXyArPSBcIkxcIiArICh4MSArIHQwMSAqIHgwMSkgKyBcIixcIiArICh5MSArIHQwMSAqIHkwMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuXyArPSBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiwwLDAsXCIgKyAoKyh5MDEgKiB4MjAgPiB4MDEgKiB5MjApKSArIFwiLFwiICsgKHRoaXMuX3gxID0geDEgKyB0MjEgKiB4MjEpICsgXCIsXCIgKyAodGhpcy5feTEgPSB5MSArIHQyMSAqIHkyMSk7XG4gICAgfVxuICB9LFxuICBhcmM6IGZ1bmN0aW9uKHgsIHksIHIsIGEwLCBhMSwgY2N3KSB7XG4gICAgeCA9ICt4LCB5ID0gK3ksIHIgPSArcjtcbiAgICB2YXIgZHggPSByICogTWF0aC5jb3MoYTApLFxuICAgICAgICBkeSA9IHIgKiBNYXRoLnNpbihhMCksXG4gICAgICAgIHgwID0geCArIGR4LFxuICAgICAgICB5MCA9IHkgKyBkeSxcbiAgICAgICAgY3cgPSAxIF4gY2N3LFxuICAgICAgICBkYSA9IGNjdyA/IGEwIC0gYTEgOiBhMSAtIGEwO1xuXG4gICAgLy8gSXMgdGhlIHJhZGl1cyBuZWdhdGl2ZT8gRXJyb3IuXG4gICAgaWYgKHIgPCAwKSB0aHJvdyBuZXcgRXJyb3IoXCJuZWdhdGl2ZSByYWRpdXM6IFwiICsgcik7XG5cbiAgICAvLyBJcyB0aGlzIHBhdGggZW1wdHk/IE1vdmUgdG8gKHgwLHkwKS5cbiAgICBpZiAodGhpcy5feDEgPT09IG51bGwpIHtcbiAgICAgIHRoaXMuXyArPSBcIk1cIiArIHgwICsgXCIsXCIgKyB5MDtcbiAgICB9XG5cbiAgICAvLyBPciwgaXMgKHgwLHkwKSBub3QgY29pbmNpZGVudCB3aXRoIHRoZSBwcmV2aW91cyBwb2ludD8gTGluZSB0byAoeDAseTApLlxuICAgIGVsc2UgaWYgKE1hdGguYWJzKHRoaXMuX3gxIC0geDApID4gZXBzaWxvbiB8fCBNYXRoLmFicyh0aGlzLl95MSAtIHkwKSA+IGVwc2lsb24pIHtcbiAgICAgIHRoaXMuXyArPSBcIkxcIiArIHgwICsgXCIsXCIgKyB5MDtcbiAgICB9XG5cbiAgICAvLyBJcyB0aGlzIGFyYyBlbXB0eT8gV2XigJlyZSBkb25lLlxuICAgIGlmICghcikgcmV0dXJuO1xuXG4gICAgLy8gSXMgdGhpcyBhIGNvbXBsZXRlIGNpcmNsZT8gRHJhdyB0d28gYXJjcyB0byBjb21wbGV0ZSB0aGUgY2lyY2xlLlxuICAgIGlmIChkYSA+IHRhdUVwc2lsb24pIHtcbiAgICAgIHRoaXMuXyArPSBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiwwLDEsXCIgKyBjdyArIFwiLFwiICsgKHggLSBkeCkgKyBcIixcIiArICh5IC0gZHkpICsgXCJBXCIgKyByICsgXCIsXCIgKyByICsgXCIsMCwxLFwiICsgY3cgKyBcIixcIiArICh0aGlzLl94MSA9IHgwKSArIFwiLFwiICsgKHRoaXMuX3kxID0geTApO1xuICAgIH1cblxuICAgIC8vIE90aGVyd2lzZSwgZHJhdyBhbiBhcmMhXG4gICAgZWxzZSB7XG4gICAgICBpZiAoZGEgPCAwKSBkYSA9IGRhICUgdGF1JDEgKyB0YXUkMTtcbiAgICAgIHRoaXMuXyArPSBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiwwLFwiICsgKCsoZGEgPj0gcGkkMSkpICsgXCIsXCIgKyBjdyArIFwiLFwiICsgKHRoaXMuX3gxID0geCArIHIgKiBNYXRoLmNvcyhhMSkpICsgXCIsXCIgKyAodGhpcy5feTEgPSB5ICsgciAqIE1hdGguc2luKGExKSk7XG4gICAgfVxuICB9LFxuICByZWN0OiBmdW5jdGlvbih4LCB5LCB3LCBoKSB7XG4gICAgdGhpcy5fICs9IFwiTVwiICsgKHRoaXMuX3gwID0gdGhpcy5feDEgPSAreCkgKyBcIixcIiArICh0aGlzLl95MCA9IHRoaXMuX3kxID0gK3kpICsgXCJoXCIgKyAoK3cpICsgXCJ2XCIgKyAoK2gpICsgXCJoXCIgKyAoLXcpICsgXCJaXCI7XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fO1xuICB9XG59O1xuXG52YXIgdHJlZV9hZGQgPSBmdW5jdGlvbihkKSB7XG4gIHZhciB4ID0gK3RoaXMuX3guY2FsbChudWxsLCBkKSxcbiAgICAgIHkgPSArdGhpcy5feS5jYWxsKG51bGwsIGQpO1xuICByZXR1cm4gYWRkKHRoaXMuY292ZXIoeCwgeSksIHgsIHksIGQpO1xufTtcblxuZnVuY3Rpb24gYWRkKHRyZWUsIHgsIHksIGQpIHtcbiAgaWYgKGlzTmFOKHgpIHx8IGlzTmFOKHkpKSByZXR1cm4gdHJlZTsgLy8gaWdub3JlIGludmFsaWQgcG9pbnRzXG5cbiAgdmFyIHBhcmVudCxcbiAgICAgIG5vZGUgPSB0cmVlLl9yb290LFxuICAgICAgbGVhZiA9IHtkYXRhOiBkfSxcbiAgICAgIHgwID0gdHJlZS5feDAsXG4gICAgICB5MCA9IHRyZWUuX3kwLFxuICAgICAgeDEgPSB0cmVlLl94MSxcbiAgICAgIHkxID0gdHJlZS5feTEsXG4gICAgICB4bSxcbiAgICAgIHltLFxuICAgICAgeHAsXG4gICAgICB5cCxcbiAgICAgIHJpZ2h0LFxuICAgICAgYm90dG9tLFxuICAgICAgaSxcbiAgICAgIGo7XG5cbiAgLy8gSWYgdGhlIHRyZWUgaXMgZW1wdHksIGluaXRpYWxpemUgdGhlIHJvb3QgYXMgYSBsZWFmLlxuICBpZiAoIW5vZGUpIHJldHVybiB0cmVlLl9yb290ID0gbGVhZiwgdHJlZTtcblxuICAvLyBGaW5kIHRoZSBleGlzdGluZyBsZWFmIGZvciB0aGUgbmV3IHBvaW50LCBvciBhZGQgaXQuXG4gIHdoaWxlIChub2RlLmxlbmd0aCkge1xuICAgIGlmIChyaWdodCA9IHggPj0gKHhtID0gKHgwICsgeDEpIC8gMikpIHgwID0geG07IGVsc2UgeDEgPSB4bTtcbiAgICBpZiAoYm90dG9tID0geSA+PSAoeW0gPSAoeTAgKyB5MSkgLyAyKSkgeTAgPSB5bTsgZWxzZSB5MSA9IHltO1xuICAgIGlmIChwYXJlbnQgPSBub2RlLCAhKG5vZGUgPSBub2RlW2kgPSBib3R0b20gPDwgMSB8IHJpZ2h0XSkpIHJldHVybiBwYXJlbnRbaV0gPSBsZWFmLCB0cmVlO1xuICB9XG5cbiAgLy8gSXMgdGhlIG5ldyBwb2ludCBpcyBleGFjdGx5IGNvaW5jaWRlbnQgd2l0aCB0aGUgZXhpc3RpbmcgcG9pbnQ/XG4gIHhwID0gK3RyZWUuX3guY2FsbChudWxsLCBub2RlLmRhdGEpO1xuICB5cCA9ICt0cmVlLl95LmNhbGwobnVsbCwgbm9kZS5kYXRhKTtcbiAgaWYgKHggPT09IHhwICYmIHkgPT09IHlwKSByZXR1cm4gbGVhZi5uZXh0ID0gbm9kZSwgcGFyZW50ID8gcGFyZW50W2ldID0gbGVhZiA6IHRyZWUuX3Jvb3QgPSBsZWFmLCB0cmVlO1xuXG4gIC8vIE90aGVyd2lzZSwgc3BsaXQgdGhlIGxlYWYgbm9kZSB1bnRpbCB0aGUgb2xkIGFuZCBuZXcgcG9pbnQgYXJlIHNlcGFyYXRlZC5cbiAgZG8ge1xuICAgIHBhcmVudCA9IHBhcmVudCA/IHBhcmVudFtpXSA9IG5ldyBBcnJheSg0KSA6IHRyZWUuX3Jvb3QgPSBuZXcgQXJyYXkoNCk7XG4gICAgaWYgKHJpZ2h0ID0geCA+PSAoeG0gPSAoeDAgKyB4MSkgLyAyKSkgeDAgPSB4bTsgZWxzZSB4MSA9IHhtO1xuICAgIGlmIChib3R0b20gPSB5ID49ICh5bSA9ICh5MCArIHkxKSAvIDIpKSB5MCA9IHltOyBlbHNlIHkxID0geW07XG4gIH0gd2hpbGUgKChpID0gYm90dG9tIDw8IDEgfCByaWdodCkgPT09IChqID0gKHlwID49IHltKSA8PCAxIHwgKHhwID49IHhtKSkpO1xuICByZXR1cm4gcGFyZW50W2pdID0gbm9kZSwgcGFyZW50W2ldID0gbGVhZiwgdHJlZTtcbn1cblxuZnVuY3Rpb24gYWRkQWxsKGRhdGEpIHtcbiAgdmFyIGQsIGksIG4gPSBkYXRhLmxlbmd0aCxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgeHogPSBuZXcgQXJyYXkobiksXG4gICAgICB5eiA9IG5ldyBBcnJheShuKSxcbiAgICAgIHgwID0gSW5maW5pdHksXG4gICAgICB5MCA9IEluZmluaXR5LFxuICAgICAgeDEgPSAtSW5maW5pdHksXG4gICAgICB5MSA9IC1JbmZpbml0eTtcblxuICAvLyBDb21wdXRlIHRoZSBwb2ludHMgYW5kIHRoZWlyIGV4dGVudC5cbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgIGlmIChpc05hTih4ID0gK3RoaXMuX3guY2FsbChudWxsLCBkID0gZGF0YVtpXSkpIHx8IGlzTmFOKHkgPSArdGhpcy5feS5jYWxsKG51bGwsIGQpKSkgY29udGludWU7XG4gICAgeHpbaV0gPSB4O1xuICAgIHl6W2ldID0geTtcbiAgICBpZiAoeCA8IHgwKSB4MCA9IHg7XG4gICAgaWYgKHggPiB4MSkgeDEgPSB4O1xuICAgIGlmICh5IDwgeTApIHkwID0geTtcbiAgICBpZiAoeSA+IHkxKSB5MSA9IHk7XG4gIH1cblxuICAvLyBJZiB0aGVyZSB3ZXJlIG5vICh2YWxpZCkgcG9pbnRzLCBpbmhlcml0IHRoZSBleGlzdGluZyBleHRlbnQuXG4gIGlmICh4MSA8IHgwKSB4MCA9IHRoaXMuX3gwLCB4MSA9IHRoaXMuX3gxO1xuICBpZiAoeTEgPCB5MCkgeTAgPSB0aGlzLl95MCwgeTEgPSB0aGlzLl95MTtcblxuICAvLyBFeHBhbmQgdGhlIHRyZWUgdG8gY292ZXIgdGhlIG5ldyBwb2ludHMuXG4gIHRoaXMuY292ZXIoeDAsIHkwKS5jb3Zlcih4MSwgeTEpO1xuXG4gIC8vIEFkZCB0aGUgbmV3IHBvaW50cy5cbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgIGFkZCh0aGlzLCB4eltpXSwgeXpbaV0sIGRhdGFbaV0pO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbnZhciB0cmVlX2NvdmVyID0gZnVuY3Rpb24oeCwgeSkge1xuICBpZiAoaXNOYU4oeCA9ICt4KSB8fCBpc05hTih5ID0gK3kpKSByZXR1cm4gdGhpczsgLy8gaWdub3JlIGludmFsaWQgcG9pbnRzXG5cbiAgdmFyIHgwID0gdGhpcy5feDAsXG4gICAgICB5MCA9IHRoaXMuX3kwLFxuICAgICAgeDEgPSB0aGlzLl94MSxcbiAgICAgIHkxID0gdGhpcy5feTE7XG5cbiAgLy8gSWYgdGhlIHF1YWR0cmVlIGhhcyBubyBleHRlbnQsIGluaXRpYWxpemUgdGhlbS5cbiAgLy8gSW50ZWdlciBleHRlbnQgYXJlIG5lY2Vzc2FyeSBzbyB0aGF0IGlmIHdlIGxhdGVyIGRvdWJsZSB0aGUgZXh0ZW50LFxuICAvLyB0aGUgZXhpc3RpbmcgcXVhZHJhbnQgYm91bmRhcmllcyBkb27igJl0IGNoYW5nZSBkdWUgdG8gZmxvYXRpbmcgcG9pbnQgZXJyb3IhXG4gIGlmIChpc05hTih4MCkpIHtcbiAgICB4MSA9ICh4MCA9IE1hdGguZmxvb3IoeCkpICsgMTtcbiAgICB5MSA9ICh5MCA9IE1hdGguZmxvb3IoeSkpICsgMTtcbiAgfVxuXG4gIC8vIE90aGVyd2lzZSwgZG91YmxlIHJlcGVhdGVkbHkgdG8gY292ZXIuXG4gIGVsc2UgaWYgKHgwID4geCB8fCB4ID4geDEgfHwgeTAgPiB5IHx8IHkgPiB5MSkge1xuICAgIHZhciB6ID0geDEgLSB4MCxcbiAgICAgICAgbm9kZSA9IHRoaXMuX3Jvb3QsXG4gICAgICAgIHBhcmVudCxcbiAgICAgICAgaTtcblxuICAgIHN3aXRjaCAoaSA9ICh5IDwgKHkwICsgeTEpIC8gMikgPDwgMSB8ICh4IDwgKHgwICsgeDEpIC8gMikpIHtcbiAgICAgIGNhc2UgMDoge1xuICAgICAgICBkbyBwYXJlbnQgPSBuZXcgQXJyYXkoNCksIHBhcmVudFtpXSA9IG5vZGUsIG5vZGUgPSBwYXJlbnQ7XG4gICAgICAgIHdoaWxlICh6ICo9IDIsIHgxID0geDAgKyB6LCB5MSA9IHkwICsgeiwgeCA+IHgxIHx8IHkgPiB5MSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAxOiB7XG4gICAgICAgIGRvIHBhcmVudCA9IG5ldyBBcnJheSg0KSwgcGFyZW50W2ldID0gbm9kZSwgbm9kZSA9IHBhcmVudDtcbiAgICAgICAgd2hpbGUgKHogKj0gMiwgeDAgPSB4MSAtIHosIHkxID0geTAgKyB6LCB4MCA+IHggfHwgeSA+IHkxKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIDI6IHtcbiAgICAgICAgZG8gcGFyZW50ID0gbmV3IEFycmF5KDQpLCBwYXJlbnRbaV0gPSBub2RlLCBub2RlID0gcGFyZW50O1xuICAgICAgICB3aGlsZSAoeiAqPSAyLCB4MSA9IHgwICsgeiwgeTAgPSB5MSAtIHosIHggPiB4MSB8fCB5MCA+IHkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMzoge1xuICAgICAgICBkbyBwYXJlbnQgPSBuZXcgQXJyYXkoNCksIHBhcmVudFtpXSA9IG5vZGUsIG5vZGUgPSBwYXJlbnQ7XG4gICAgICAgIHdoaWxlICh6ICo9IDIsIHgwID0geDEgLSB6LCB5MCA9IHkxIC0geiwgeDAgPiB4IHx8IHkwID4geSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9yb290ICYmIHRoaXMuX3Jvb3QubGVuZ3RoKSB0aGlzLl9yb290ID0gbm9kZTtcbiAgfVxuXG4gIC8vIElmIHRoZSBxdWFkdHJlZSBjb3ZlcnMgdGhlIHBvaW50IGFscmVhZHksIGp1c3QgcmV0dXJuLlxuICBlbHNlIHJldHVybiB0aGlzO1xuXG4gIHRoaXMuX3gwID0geDA7XG4gIHRoaXMuX3kwID0geTA7XG4gIHRoaXMuX3gxID0geDE7XG4gIHRoaXMuX3kxID0geTE7XG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIHRyZWVfZGF0YSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZGF0YSA9IFtdO1xuICB0aGlzLnZpc2l0KGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUubGVuZ3RoKSBkbyBkYXRhLnB1c2gobm9kZS5kYXRhKTsgd2hpbGUgKG5vZGUgPSBub2RlLm5leHQpXG4gIH0pO1xuICByZXR1cm4gZGF0YTtcbn07XG5cbnZhciB0cmVlX2V4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGhcbiAgICAgID8gdGhpcy5jb3ZlcigrX1swXVswXSwgK19bMF1bMV0pLmNvdmVyKCtfWzFdWzBdLCArX1sxXVsxXSlcbiAgICAgIDogaXNOYU4odGhpcy5feDApID8gdW5kZWZpbmVkIDogW1t0aGlzLl94MCwgdGhpcy5feTBdLCBbdGhpcy5feDEsIHRoaXMuX3kxXV07XG59O1xuXG52YXIgUXVhZCA9IGZ1bmN0aW9uKG5vZGUsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHRoaXMubm9kZSA9IG5vZGU7XG4gIHRoaXMueDAgPSB4MDtcbiAgdGhpcy55MCA9IHkwO1xuICB0aGlzLngxID0geDE7XG4gIHRoaXMueTEgPSB5MTtcbn07XG5cbnZhciB0cmVlX2ZpbmQgPSBmdW5jdGlvbih4LCB5LCByYWRpdXMpIHtcbiAgdmFyIGRhdGEsXG4gICAgICB4MCA9IHRoaXMuX3gwLFxuICAgICAgeTAgPSB0aGlzLl95MCxcbiAgICAgIHgxLFxuICAgICAgeTEsXG4gICAgICB4MixcbiAgICAgIHkyLFxuICAgICAgeDMgPSB0aGlzLl94MSxcbiAgICAgIHkzID0gdGhpcy5feTEsXG4gICAgICBxdWFkcyA9IFtdLFxuICAgICAgbm9kZSA9IHRoaXMuX3Jvb3QsXG4gICAgICBxLFxuICAgICAgaTtcblxuICBpZiAobm9kZSkgcXVhZHMucHVzaChuZXcgUXVhZChub2RlLCB4MCwgeTAsIHgzLCB5MykpO1xuICBpZiAocmFkaXVzID09IG51bGwpIHJhZGl1cyA9IEluZmluaXR5O1xuICBlbHNlIHtcbiAgICB4MCA9IHggLSByYWRpdXMsIHkwID0geSAtIHJhZGl1cztcbiAgICB4MyA9IHggKyByYWRpdXMsIHkzID0geSArIHJhZGl1cztcbiAgICByYWRpdXMgKj0gcmFkaXVzO1xuICB9XG5cbiAgd2hpbGUgKHEgPSBxdWFkcy5wb3AoKSkge1xuXG4gICAgLy8gU3RvcCBzZWFyY2hpbmcgaWYgdGhpcyBxdWFkcmFudCBjYW7igJl0IGNvbnRhaW4gYSBjbG9zZXIgbm9kZS5cbiAgICBpZiAoIShub2RlID0gcS5ub2RlKVxuICAgICAgICB8fCAoeDEgPSBxLngwKSA+IHgzXG4gICAgICAgIHx8ICh5MSA9IHEueTApID4geTNcbiAgICAgICAgfHwgKHgyID0gcS54MSkgPCB4MFxuICAgICAgICB8fCAoeTIgPSBxLnkxKSA8IHkwKSBjb250aW51ZTtcblxuICAgIC8vIEJpc2VjdCB0aGUgY3VycmVudCBxdWFkcmFudC5cbiAgICBpZiAobm9kZS5sZW5ndGgpIHtcbiAgICAgIHZhciB4bSA9ICh4MSArIHgyKSAvIDIsXG4gICAgICAgICAgeW0gPSAoeTEgKyB5MikgLyAyO1xuXG4gICAgICBxdWFkcy5wdXNoKFxuICAgICAgICBuZXcgUXVhZChub2RlWzNdLCB4bSwgeW0sIHgyLCB5MiksXG4gICAgICAgIG5ldyBRdWFkKG5vZGVbMl0sIHgxLCB5bSwgeG0sIHkyKSxcbiAgICAgICAgbmV3IFF1YWQobm9kZVsxXSwgeG0sIHkxLCB4MiwgeW0pLFxuICAgICAgICBuZXcgUXVhZChub2RlWzBdLCB4MSwgeTEsIHhtLCB5bSlcbiAgICAgICk7XG5cbiAgICAgIC8vIFZpc2l0IHRoZSBjbG9zZXN0IHF1YWRyYW50IGZpcnN0LlxuICAgICAgaWYgKGkgPSAoeSA+PSB5bSkgPDwgMSB8ICh4ID49IHhtKSkge1xuICAgICAgICBxID0gcXVhZHNbcXVhZHMubGVuZ3RoIC0gMV07XG4gICAgICAgIHF1YWRzW3F1YWRzLmxlbmd0aCAtIDFdID0gcXVhZHNbcXVhZHMubGVuZ3RoIC0gMSAtIGldO1xuICAgICAgICBxdWFkc1txdWFkcy5sZW5ndGggLSAxIC0gaV0gPSBxO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFZpc2l0IHRoaXMgcG9pbnQuIChWaXNpdGluZyBjb2luY2lkZW50IHBvaW50cyBpc27igJl0IG5lY2Vzc2FyeSEpXG4gICAgZWxzZSB7XG4gICAgICB2YXIgZHggPSB4IC0gK3RoaXMuX3guY2FsbChudWxsLCBub2RlLmRhdGEpLFxuICAgICAgICAgIGR5ID0geSAtICt0aGlzLl95LmNhbGwobnVsbCwgbm9kZS5kYXRhKSxcbiAgICAgICAgICBkMiA9IGR4ICogZHggKyBkeSAqIGR5O1xuICAgICAgaWYgKGQyIDwgcmFkaXVzKSB7XG4gICAgICAgIHZhciBkID0gTWF0aC5zcXJ0KHJhZGl1cyA9IGQyKTtcbiAgICAgICAgeDAgPSB4IC0gZCwgeTAgPSB5IC0gZDtcbiAgICAgICAgeDMgPSB4ICsgZCwgeTMgPSB5ICsgZDtcbiAgICAgICAgZGF0YSA9IG5vZGUuZGF0YTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGF0YTtcbn07XG5cbnZhciB0cmVlX3JlbW92ZSA9IGZ1bmN0aW9uKGQpIHtcbiAgaWYgKGlzTmFOKHggPSArdGhpcy5feC5jYWxsKG51bGwsIGQpKSB8fCBpc05hTih5ID0gK3RoaXMuX3kuY2FsbChudWxsLCBkKSkpIHJldHVybiB0aGlzOyAvLyBpZ25vcmUgaW52YWxpZCBwb2ludHNcblxuICB2YXIgcGFyZW50LFxuICAgICAgbm9kZSA9IHRoaXMuX3Jvb3QsXG4gICAgICByZXRhaW5lcixcbiAgICAgIHByZXZpb3VzLFxuICAgICAgbmV4dCxcbiAgICAgIHgwID0gdGhpcy5feDAsXG4gICAgICB5MCA9IHRoaXMuX3kwLFxuICAgICAgeDEgPSB0aGlzLl94MSxcbiAgICAgIHkxID0gdGhpcy5feTEsXG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHhtLFxuICAgICAgeW0sXG4gICAgICByaWdodCxcbiAgICAgIGJvdHRvbSxcbiAgICAgIGksXG4gICAgICBqO1xuXG4gIC8vIElmIHRoZSB0cmVlIGlzIGVtcHR5LCBpbml0aWFsaXplIHRoZSByb290IGFzIGEgbGVhZi5cbiAgaWYgKCFub2RlKSByZXR1cm4gdGhpcztcblxuICAvLyBGaW5kIHRoZSBsZWFmIG5vZGUgZm9yIHRoZSBwb2ludC5cbiAgLy8gV2hpbGUgZGVzY2VuZGluZywgYWxzbyByZXRhaW4gdGhlIGRlZXBlc3QgcGFyZW50IHdpdGggYSBub24tcmVtb3ZlZCBzaWJsaW5nLlxuICBpZiAobm9kZS5sZW5ndGgpIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKHJpZ2h0ID0geCA+PSAoeG0gPSAoeDAgKyB4MSkgLyAyKSkgeDAgPSB4bTsgZWxzZSB4MSA9IHhtO1xuICAgIGlmIChib3R0b20gPSB5ID49ICh5bSA9ICh5MCArIHkxKSAvIDIpKSB5MCA9IHltOyBlbHNlIHkxID0geW07XG4gICAgaWYgKCEocGFyZW50ID0gbm9kZSwgbm9kZSA9IG5vZGVbaSA9IGJvdHRvbSA8PCAxIHwgcmlnaHRdKSkgcmV0dXJuIHRoaXM7XG4gICAgaWYgKCFub2RlLmxlbmd0aCkgYnJlYWs7XG4gICAgaWYgKHBhcmVudFsoaSArIDEpICYgM10gfHwgcGFyZW50WyhpICsgMikgJiAzXSB8fCBwYXJlbnRbKGkgKyAzKSAmIDNdKSByZXRhaW5lciA9IHBhcmVudCwgaiA9IGk7XG4gIH1cblxuICAvLyBGaW5kIHRoZSBwb2ludCB0byByZW1vdmUuXG4gIHdoaWxlIChub2RlLmRhdGEgIT09IGQpIGlmICghKHByZXZpb3VzID0gbm9kZSwgbm9kZSA9IG5vZGUubmV4dCkpIHJldHVybiB0aGlzO1xuICBpZiAobmV4dCA9IG5vZGUubmV4dCkgZGVsZXRlIG5vZGUubmV4dDtcblxuICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgY29pbmNpZGVudCBwb2ludHMsIHJlbW92ZSBqdXN0IHRoZSBwb2ludC5cbiAgaWYgKHByZXZpb3VzKSByZXR1cm4gKG5leHQgPyBwcmV2aW91cy5uZXh0ID0gbmV4dCA6IGRlbGV0ZSBwcmV2aW91cy5uZXh0KSwgdGhpcztcblxuICAvLyBJZiB0aGlzIGlzIHRoZSByb290IHBvaW50LCByZW1vdmUgaXQuXG4gIGlmICghcGFyZW50KSByZXR1cm4gdGhpcy5fcm9vdCA9IG5leHQsIHRoaXM7XG5cbiAgLy8gUmVtb3ZlIHRoaXMgbGVhZi5cbiAgbmV4dCA/IHBhcmVudFtpXSA9IG5leHQgOiBkZWxldGUgcGFyZW50W2ldO1xuXG4gIC8vIElmIHRoZSBwYXJlbnQgbm93IGNvbnRhaW5zIGV4YWN0bHkgb25lIGxlYWYsIGNvbGxhcHNlIHN1cGVyZmx1b3VzIHBhcmVudHMuXG4gIGlmICgobm9kZSA9IHBhcmVudFswXSB8fCBwYXJlbnRbMV0gfHwgcGFyZW50WzJdIHx8IHBhcmVudFszXSlcbiAgICAgICYmIG5vZGUgPT09IChwYXJlbnRbM10gfHwgcGFyZW50WzJdIHx8IHBhcmVudFsxXSB8fCBwYXJlbnRbMF0pXG4gICAgICAmJiAhbm9kZS5sZW5ndGgpIHtcbiAgICBpZiAocmV0YWluZXIpIHJldGFpbmVyW2pdID0gbm9kZTtcbiAgICBlbHNlIHRoaXMuX3Jvb3QgPSBub2RlO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiByZW1vdmVBbGwoZGF0YSkge1xuICBmb3IgKHZhciBpID0gMCwgbiA9IGRhdGEubGVuZ3RoOyBpIDwgbjsgKytpKSB0aGlzLnJlbW92ZShkYXRhW2ldKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbnZhciB0cmVlX3Jvb3QgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3Jvb3Q7XG59O1xuXG52YXIgdHJlZV9zaXplID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzaXplID0gMDtcbiAgdGhpcy52aXNpdChmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKCFub2RlLmxlbmd0aCkgZG8gKytzaXplOyB3aGlsZSAobm9kZSA9IG5vZGUubmV4dClcbiAgfSk7XG4gIHJldHVybiBzaXplO1xufTtcblxudmFyIHRyZWVfdmlzaXQgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgcXVhZHMgPSBbXSwgcSwgbm9kZSA9IHRoaXMuX3Jvb3QsIGNoaWxkLCB4MCwgeTAsIHgxLCB5MTtcbiAgaWYgKG5vZGUpIHF1YWRzLnB1c2gobmV3IFF1YWQobm9kZSwgdGhpcy5feDAsIHRoaXMuX3kwLCB0aGlzLl94MSwgdGhpcy5feTEpKTtcbiAgd2hpbGUgKHEgPSBxdWFkcy5wb3AoKSkge1xuICAgIGlmICghY2FsbGJhY2sobm9kZSA9IHEubm9kZSwgeDAgPSBxLngwLCB5MCA9IHEueTAsIHgxID0gcS54MSwgeTEgPSBxLnkxKSAmJiBub2RlLmxlbmd0aCkge1xuICAgICAgdmFyIHhtID0gKHgwICsgeDEpIC8gMiwgeW0gPSAoeTAgKyB5MSkgLyAyO1xuICAgICAgaWYgKGNoaWxkID0gbm9kZVszXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeG0sIHltLCB4MSwgeTEpKTtcbiAgICAgIGlmIChjaGlsZCA9IG5vZGVbMl0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hpbGQsIHgwLCB5bSwgeG0sIHkxKSk7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzFdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4bSwgeTAsIHgxLCB5bSkpO1xuICAgICAgaWYgKGNoaWxkID0gbm9kZVswXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeDAsIHkwLCB4bSwgeW0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG52YXIgdHJlZV92aXNpdEFmdGVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIHF1YWRzID0gW10sIG5leHQgPSBbXSwgcTtcbiAgaWYgKHRoaXMuX3Jvb3QpIHF1YWRzLnB1c2gobmV3IFF1YWQodGhpcy5fcm9vdCwgdGhpcy5feDAsIHRoaXMuX3kwLCB0aGlzLl94MSwgdGhpcy5feTEpKTtcbiAgd2hpbGUgKHEgPSBxdWFkcy5wb3AoKSkge1xuICAgIHZhciBub2RlID0gcS5ub2RlO1xuICAgIGlmIChub2RlLmxlbmd0aCkge1xuICAgICAgdmFyIGNoaWxkLCB4MCA9IHEueDAsIHkwID0gcS55MCwgeDEgPSBxLngxLCB5MSA9IHEueTEsIHhtID0gKHgwICsgeDEpIC8gMiwgeW0gPSAoeTAgKyB5MSkgLyAyO1xuICAgICAgaWYgKGNoaWxkID0gbm9kZVswXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeDAsIHkwLCB4bSwgeW0pKTtcbiAgICAgIGlmIChjaGlsZCA9IG5vZGVbMV0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hpbGQsIHhtLCB5MCwgeDEsIHltKSk7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzJdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4MCwgeW0sIHhtLCB5MSkpO1xuICAgICAgaWYgKGNoaWxkID0gbm9kZVszXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeG0sIHltLCB4MSwgeTEpKTtcbiAgICB9XG4gICAgbmV4dC5wdXNoKHEpO1xuICB9XG4gIHdoaWxlIChxID0gbmV4dC5wb3AoKSkge1xuICAgIGNhbGxiYWNrKHEubm9kZSwgcS54MCwgcS55MCwgcS54MSwgcS55MSk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBkZWZhdWx0WChkKSB7XG4gIHJldHVybiBkWzBdO1xufVxuXG52YXIgdHJlZV94ID0gZnVuY3Rpb24oXykge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aGlzLl94ID0gXywgdGhpcykgOiB0aGlzLl94O1xufTtcblxuZnVuY3Rpb24gZGVmYXVsdFkoZCkge1xuICByZXR1cm4gZFsxXTtcbn1cblxudmFyIHRyZWVfeSA9IGZ1bmN0aW9uKF8pIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGhpcy5feSA9IF8sIHRoaXMpIDogdGhpcy5feTtcbn07XG5cbmZ1bmN0aW9uIHF1YWR0cmVlKG5vZGVzLCB4LCB5KSB7XG4gIHZhciB0cmVlID0gbmV3IFF1YWR0cmVlKHggPT0gbnVsbCA/IGRlZmF1bHRYIDogeCwgeSA9PSBudWxsID8gZGVmYXVsdFkgOiB5LCBOYU4sIE5hTiwgTmFOLCBOYU4pO1xuICByZXR1cm4gbm9kZXMgPT0gbnVsbCA/IHRyZWUgOiB0cmVlLmFkZEFsbChub2Rlcyk7XG59XG5cbmZ1bmN0aW9uIFF1YWR0cmVlKHgsIHksIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHRoaXMuX3ggPSB4O1xuICB0aGlzLl95ID0geTtcbiAgdGhpcy5feDAgPSB4MDtcbiAgdGhpcy5feTAgPSB5MDtcbiAgdGhpcy5feDEgPSB4MTtcbiAgdGhpcy5feTEgPSB5MTtcbiAgdGhpcy5fcm9vdCA9IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gbGVhZl9jb3B5KGxlYWYpIHtcbiAgdmFyIGNvcHkgPSB7ZGF0YTogbGVhZi5kYXRhfSwgbmV4dCA9IGNvcHk7XG4gIHdoaWxlIChsZWFmID0gbGVhZi5uZXh0KSBuZXh0ID0gbmV4dC5uZXh0ID0ge2RhdGE6IGxlYWYuZGF0YX07XG4gIHJldHVybiBjb3B5O1xufVxuXG52YXIgdHJlZVByb3RvID0gcXVhZHRyZWUucHJvdG90eXBlID0gUXVhZHRyZWUucHJvdG90eXBlO1xuXG50cmVlUHJvdG8uY29weSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29weSA9IG5ldyBRdWFkdHJlZSh0aGlzLl94LCB0aGlzLl95LCB0aGlzLl94MCwgdGhpcy5feTAsIHRoaXMuX3gxLCB0aGlzLl95MSksXG4gICAgICBub2RlID0gdGhpcy5fcm9vdCxcbiAgICAgIG5vZGVzLFxuICAgICAgY2hpbGQ7XG5cbiAgaWYgKCFub2RlKSByZXR1cm4gY29weTtcblxuICBpZiAoIW5vZGUubGVuZ3RoKSByZXR1cm4gY29weS5fcm9vdCA9IGxlYWZfY29weShub2RlKSwgY29weTtcblxuICBub2RlcyA9IFt7c291cmNlOiBub2RlLCB0YXJnZXQ6IGNvcHkuX3Jvb3QgPSBuZXcgQXJyYXkoNCl9XTtcbiAgd2hpbGUgKG5vZGUgPSBub2Rlcy5wb3AoKSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgKytpKSB7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlLnNvdXJjZVtpXSkge1xuICAgICAgICBpZiAoY2hpbGQubGVuZ3RoKSBub2Rlcy5wdXNoKHtzb3VyY2U6IGNoaWxkLCB0YXJnZXQ6IG5vZGUudGFyZ2V0W2ldID0gbmV3IEFycmF5KDQpfSk7XG4gICAgICAgIGVsc2Ugbm9kZS50YXJnZXRbaV0gPSBsZWFmX2NvcHkoY2hpbGQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb3B5O1xufTtcblxudHJlZVByb3RvLmFkZCA9IHRyZWVfYWRkO1xudHJlZVByb3RvLmFkZEFsbCA9IGFkZEFsbDtcbnRyZWVQcm90by5jb3ZlciA9IHRyZWVfY292ZXI7XG50cmVlUHJvdG8uZGF0YSA9IHRyZWVfZGF0YTtcbnRyZWVQcm90by5leHRlbnQgPSB0cmVlX2V4dGVudDtcbnRyZWVQcm90by5maW5kID0gdHJlZV9maW5kO1xudHJlZVByb3RvLnJlbW92ZSA9IHRyZWVfcmVtb3ZlO1xudHJlZVByb3RvLnJlbW92ZUFsbCA9IHJlbW92ZUFsbDtcbnRyZWVQcm90by5yb290ID0gdHJlZV9yb290O1xudHJlZVByb3RvLnNpemUgPSB0cmVlX3NpemU7XG50cmVlUHJvdG8udmlzaXQgPSB0cmVlX3Zpc2l0O1xudHJlZVByb3RvLnZpc2l0QWZ0ZXIgPSB0cmVlX3Zpc2l0QWZ0ZXI7XG50cmVlUHJvdG8ueCA9IHRyZWVfeDtcbnRyZWVQcm90by55ID0gdHJlZV95O1xuXG52YXIgc2xpY2UkMSA9IFtdLnNsaWNlO1xuXG52YXIgbm9hYm9ydCA9IHt9O1xuXG5mdW5jdGlvbiBRdWV1ZShzaXplKSB7XG4gIGlmICghKHNpemUgPj0gMSkpIHRocm93IG5ldyBFcnJvcjtcbiAgdGhpcy5fc2l6ZSA9IHNpemU7XG4gIHRoaXMuX2NhbGwgPVxuICB0aGlzLl9lcnJvciA9IG51bGw7XG4gIHRoaXMuX3Rhc2tzID0gW107XG4gIHRoaXMuX2RhdGEgPSBbXTtcbiAgdGhpcy5fd2FpdGluZyA9XG4gIHRoaXMuX2FjdGl2ZSA9XG4gIHRoaXMuX2VuZGVkID1cbiAgdGhpcy5fc3RhcnQgPSAwOyAvLyBpbnNpZGUgYSBzeW5jaHJvbm91cyB0YXNrIGNhbGxiYWNrP1xufVxuXG5RdWV1ZS5wcm90b3R5cGUgPSBxdWV1ZS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBRdWV1ZSxcbiAgZGVmZXI6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiIHx8IHRoaXMuX2NhbGwpIHRocm93IG5ldyBFcnJvcjtcbiAgICBpZiAodGhpcy5fZXJyb3IgIT0gbnVsbCkgcmV0dXJuIHRoaXM7XG4gICAgdmFyIHQgPSBzbGljZSQxLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICB0LnB1c2goY2FsbGJhY2spO1xuICAgICsrdGhpcy5fd2FpdGluZywgdGhpcy5fdGFza3MucHVzaCh0KTtcbiAgICBwb2tlKHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBhYm9ydDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2Vycm9yID09IG51bGwpIGFib3J0KHRoaXMsIG5ldyBFcnJvcihcImFib3J0XCIpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgYXdhaXQ6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiIHx8IHRoaXMuX2NhbGwpIHRocm93IG5ldyBFcnJvcjtcbiAgICB0aGlzLl9jYWxsID0gZnVuY3Rpb24oZXJyb3IsIHJlc3VsdHMpIHsgY2FsbGJhY2suYXBwbHkobnVsbCwgW2Vycm9yXS5jb25jYXQocmVzdWx0cykpOyB9O1xuICAgIG1heWJlTm90aWZ5KHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBhd2FpdEFsbDogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIgfHwgdGhpcy5fY2FsbCkgdGhyb3cgbmV3IEVycm9yO1xuICAgIHRoaXMuX2NhbGwgPSBjYWxsYmFjaztcbiAgICBtYXliZU5vdGlmeSh0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufTtcblxuZnVuY3Rpb24gcG9rZShxKSB7XG4gIGlmICghcS5fc3RhcnQpIHtcbiAgICB0cnkgeyBzdGFydChxKTsgfSAvLyBsZXQgdGhlIGN1cnJlbnQgdGFzayBjb21wbGV0ZVxuICAgIGNhdGNoIChlKSB7XG4gICAgICBpZiAocS5fdGFza3NbcS5fZW5kZWQgKyBxLl9hY3RpdmUgLSAxXSkgYWJvcnQocSwgZSk7IC8vIHRhc2sgZXJyb3JlZCBzeW5jaHJvbm91c2x5XG4gICAgICBlbHNlIGlmICghcS5fZGF0YSkgdGhyb3cgZTsgLy8gYXdhaXQgY2FsbGJhY2sgZXJyb3JlZCBzeW5jaHJvbm91c2x5XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHN0YXJ0KHEpIHtcbiAgd2hpbGUgKHEuX3N0YXJ0ID0gcS5fd2FpdGluZyAmJiBxLl9hY3RpdmUgPCBxLl9zaXplKSB7XG4gICAgdmFyIGkgPSBxLl9lbmRlZCArIHEuX2FjdGl2ZSxcbiAgICAgICAgdCA9IHEuX3Rhc2tzW2ldLFxuICAgICAgICBqID0gdC5sZW5ndGggLSAxLFxuICAgICAgICBjID0gdFtqXTtcbiAgICB0W2pdID0gZW5kKHEsIGkpO1xuICAgIC0tcS5fd2FpdGluZywgKytxLl9hY3RpdmU7XG4gICAgdCA9IGMuYXBwbHkobnVsbCwgdCk7XG4gICAgaWYgKCFxLl90YXNrc1tpXSkgY29udGludWU7IC8vIHRhc2sgZmluaXNoZWQgc3luY2hyb25vdXNseVxuICAgIHEuX3Rhc2tzW2ldID0gdCB8fCBub2Fib3J0O1xuICB9XG59XG5cbmZ1bmN0aW9uIGVuZChxLCBpKSB7XG4gIHJldHVybiBmdW5jdGlvbihlLCByKSB7XG4gICAgaWYgKCFxLl90YXNrc1tpXSkgcmV0dXJuOyAvLyBpZ25vcmUgbXVsdGlwbGUgY2FsbGJhY2tzXG4gICAgLS1xLl9hY3RpdmUsICsrcS5fZW5kZWQ7XG4gICAgcS5fdGFza3NbaV0gPSBudWxsO1xuICAgIGlmIChxLl9lcnJvciAhPSBudWxsKSByZXR1cm47IC8vIGlnbm9yZSBzZWNvbmRhcnkgZXJyb3JzXG4gICAgaWYgKGUgIT0gbnVsbCkge1xuICAgICAgYWJvcnQocSwgZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHEuX2RhdGFbaV0gPSByO1xuICAgICAgaWYgKHEuX3dhaXRpbmcpIHBva2UocSk7XG4gICAgICBlbHNlIG1heWJlTm90aWZ5KHEpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gYWJvcnQocSwgZSkge1xuICB2YXIgaSA9IHEuX3Rhc2tzLmxlbmd0aCwgdDtcbiAgcS5fZXJyb3IgPSBlOyAvLyBpZ25vcmUgYWN0aXZlIGNhbGxiYWNrc1xuICBxLl9kYXRhID0gdW5kZWZpbmVkOyAvLyBhbGxvdyBnY1xuICBxLl93YWl0aW5nID0gTmFOOyAvLyBwcmV2ZW50IHN0YXJ0aW5nXG5cbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgaWYgKHQgPSBxLl90YXNrc1tpXSkge1xuICAgICAgcS5fdGFza3NbaV0gPSBudWxsO1xuICAgICAgaWYgKHQuYWJvcnQpIHtcbiAgICAgICAgdHJ5IHsgdC5hYm9ydCgpOyB9XG4gICAgICAgIGNhdGNoIChlKSB7IC8qIGlnbm9yZSAqLyB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcS5fYWN0aXZlID0gTmFOOyAvLyBhbGxvdyBub3RpZmljYXRpb25cbiAgbWF5YmVOb3RpZnkocSk7XG59XG5cbmZ1bmN0aW9uIG1heWJlTm90aWZ5KHEpIHtcbiAgaWYgKCFxLl9hY3RpdmUgJiYgcS5fY2FsbCkge1xuICAgIHZhciBkID0gcS5fZGF0YTtcbiAgICBxLl9kYXRhID0gdW5kZWZpbmVkOyAvLyBhbGxvdyBnY1xuICAgIHEuX2NhbGwocS5fZXJyb3IsIGQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHF1ZXVlKGNvbmN1cnJlbmN5KSB7XG4gIHJldHVybiBuZXcgUXVldWUoYXJndW1lbnRzLmxlbmd0aCA/ICtjb25jdXJyZW5jeSA6IEluZmluaXR5KTtcbn1cblxudmFyIGNvbnN0YW50JDIgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiBmdW5jdGlvbiBjb25zdGFudCgpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn07XG5cbnZhciBlcHNpbG9uJDEgPSAxZS0xMjtcbnZhciBwaSQyID0gTWF0aC5QSTtcbnZhciBoYWxmUGkkMSA9IHBpJDIgLyAyO1xudmFyIHRhdSQyID0gMiAqIHBpJDI7XG5cbmZ1bmN0aW9uIGFyY0lubmVyUmFkaXVzKGQpIHtcbiAgcmV0dXJuIGQuaW5uZXJSYWRpdXM7XG59XG5cbmZ1bmN0aW9uIGFyY091dGVyUmFkaXVzKGQpIHtcbiAgcmV0dXJuIGQub3V0ZXJSYWRpdXM7XG59XG5cbmZ1bmN0aW9uIGFyY1N0YXJ0QW5nbGUoZCkge1xuICByZXR1cm4gZC5zdGFydEFuZ2xlO1xufVxuXG5mdW5jdGlvbiBhcmNFbmRBbmdsZShkKSB7XG4gIHJldHVybiBkLmVuZEFuZ2xlO1xufVxuXG5mdW5jdGlvbiBhcmNQYWRBbmdsZShkKSB7XG4gIHJldHVybiBkICYmIGQucGFkQW5nbGU7IC8vIE5vdGU6IG9wdGlvbmFsIVxufVxuXG5mdW5jdGlvbiBhc2luKHgpIHtcbiAgcmV0dXJuIHggPj0gMSA/IGhhbGZQaSQxIDogeCA8PSAtMSA/IC1oYWxmUGkkMSA6IE1hdGguYXNpbih4KTtcbn1cblxuZnVuY3Rpb24gaW50ZXJzZWN0KHgwLCB5MCwgeDEsIHkxLCB4MiwgeTIsIHgzLCB5Mykge1xuICB2YXIgeDEwID0geDEgLSB4MCwgeTEwID0geTEgLSB5MCxcbiAgICAgIHgzMiA9IHgzIC0geDIsIHkzMiA9IHkzIC0geTIsXG4gICAgICB0ID0gKHgzMiAqICh5MCAtIHkyKSAtIHkzMiAqICh4MCAtIHgyKSkgLyAoeTMyICogeDEwIC0geDMyICogeTEwKTtcbiAgcmV0dXJuIFt4MCArIHQgKiB4MTAsIHkwICsgdCAqIHkxMF07XG59XG5cbi8vIENvbXB1dGUgcGVycGVuZGljdWxhciBvZmZzZXQgbGluZSBvZiBsZW5ndGggcmMuXG4vLyBodHRwOi8vbWF0aHdvcmxkLndvbGZyYW0uY29tL0NpcmNsZS1MaW5lSW50ZXJzZWN0aW9uLmh0bWxcbmZ1bmN0aW9uIGNvcm5lclRhbmdlbnRzKHgwLCB5MCwgeDEsIHkxLCByMSwgcmMsIGN3KSB7XG4gIHZhciB4MDEgPSB4MCAtIHgxLFxuICAgICAgeTAxID0geTAgLSB5MSxcbiAgICAgIGxvID0gKGN3ID8gcmMgOiAtcmMpIC8gTWF0aC5zcXJ0KHgwMSAqIHgwMSArIHkwMSAqIHkwMSksXG4gICAgICBveCA9IGxvICogeTAxLFxuICAgICAgb3kgPSAtbG8gKiB4MDEsXG4gICAgICB4MTEgPSB4MCArIG94LFxuICAgICAgeTExID0geTAgKyBveSxcbiAgICAgIHgxMCA9IHgxICsgb3gsXG4gICAgICB5MTAgPSB5MSArIG95LFxuICAgICAgeDAwID0gKHgxMSArIHgxMCkgLyAyLFxuICAgICAgeTAwID0gKHkxMSArIHkxMCkgLyAyLFxuICAgICAgZHggPSB4MTAgLSB4MTEsXG4gICAgICBkeSA9IHkxMCAtIHkxMSxcbiAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHksXG4gICAgICByID0gcjEgLSByYyxcbiAgICAgIEQgPSB4MTEgKiB5MTAgLSB4MTAgKiB5MTEsXG4gICAgICBkID0gKGR5IDwgMCA/IC0xIDogMSkgKiBNYXRoLnNxcnQoTWF0aC5tYXgoMCwgciAqIHIgKiBkMiAtIEQgKiBEKSksXG4gICAgICBjeDAgPSAoRCAqIGR5IC0gZHggKiBkKSAvIGQyLFxuICAgICAgY3kwID0gKC1EICogZHggLSBkeSAqIGQpIC8gZDIsXG4gICAgICBjeDEgPSAoRCAqIGR5ICsgZHggKiBkKSAvIGQyLFxuICAgICAgY3kxID0gKC1EICogZHggKyBkeSAqIGQpIC8gZDIsXG4gICAgICBkeDAgPSBjeDAgLSB4MDAsXG4gICAgICBkeTAgPSBjeTAgLSB5MDAsXG4gICAgICBkeDEgPSBjeDEgLSB4MDAsXG4gICAgICBkeTEgPSBjeTEgLSB5MDA7XG5cbiAgLy8gUGljayB0aGUgY2xvc2VyIG9mIHRoZSB0d28gaW50ZXJzZWN0aW9uIHBvaW50cy5cbiAgLy8gVE9ETyBJcyB0aGVyZSBhIGZhc3RlciB3YXkgdG8gZGV0ZXJtaW5lIHdoaWNoIGludGVyc2VjdGlvbiB0byB1c2U/XG4gIGlmIChkeDAgKiBkeDAgKyBkeTAgKiBkeTAgPiBkeDEgKiBkeDEgKyBkeTEgKiBkeTEpIGN4MCA9IGN4MSwgY3kwID0gY3kxO1xuXG4gIHJldHVybiB7XG4gICAgY3g6IGN4MCxcbiAgICBjeTogY3kwLFxuICAgIHgwMTogLW94LFxuICAgIHkwMTogLW95LFxuICAgIHgxMTogY3gwICogKHIxIC8gciAtIDEpLFxuICAgIHkxMTogY3kwICogKHIxIC8gciAtIDEpXG4gIH07XG59XG5cbnZhciBhcmMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGlubmVyUmFkaXVzID0gYXJjSW5uZXJSYWRpdXMsXG4gICAgICBvdXRlclJhZGl1cyA9IGFyY091dGVyUmFkaXVzLFxuICAgICAgY29ybmVyUmFkaXVzID0gY29uc3RhbnQkMigwKSxcbiAgICAgIHBhZFJhZGl1cyA9IG51bGwsXG4gICAgICBzdGFydEFuZ2xlID0gYXJjU3RhcnRBbmdsZSxcbiAgICAgIGVuZEFuZ2xlID0gYXJjRW5kQW5nbGUsXG4gICAgICBwYWRBbmdsZSA9IGFyY1BhZEFuZ2xlLFxuICAgICAgY29udGV4dCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gYXJjKCkge1xuICAgIHZhciBidWZmZXIsXG4gICAgICAgIHIsXG4gICAgICAgIHIwID0gK2lubmVyUmFkaXVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksXG4gICAgICAgIHIxID0gK291dGVyUmFkaXVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksXG4gICAgICAgIGEwID0gc3RhcnRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIC0gaGFsZlBpJDEsXG4gICAgICAgIGExID0gZW5kQW5nbGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSAtIGhhbGZQaSQxLFxuICAgICAgICBkYSA9IE1hdGguYWJzKGExIC0gYTApLFxuICAgICAgICBjdyA9IGExID4gYTA7XG5cbiAgICBpZiAoIWNvbnRleHQpIGNvbnRleHQgPSBidWZmZXIgPSBwYXRoKCk7XG5cbiAgICAvLyBFbnN1cmUgdGhhdCB0aGUgb3V0ZXIgcmFkaXVzIGlzIGFsd2F5cyBsYXJnZXIgdGhhbiB0aGUgaW5uZXIgcmFkaXVzLlxuICAgIGlmIChyMSA8IHIwKSByID0gcjEsIHIxID0gcjAsIHIwID0gcjtcblxuICAgIC8vIElzIGl0IGEgcG9pbnQ/XG4gICAgaWYgKCEocjEgPiBlcHNpbG9uJDEpKSBjb250ZXh0Lm1vdmVUbygwLCAwKTtcblxuICAgIC8vIE9yIGlzIGl0IGEgY2lyY2xlIG9yIGFubnVsdXM/XG4gICAgZWxzZSBpZiAoZGEgPiB0YXUkMiAtIGVwc2lsb24kMSkge1xuICAgICAgY29udGV4dC5tb3ZlVG8ocjEgKiBNYXRoLmNvcyhhMCksIHIxICogTWF0aC5zaW4oYTApKTtcbiAgICAgIGNvbnRleHQuYXJjKDAsIDAsIHIxLCBhMCwgYTEsICFjdyk7XG4gICAgICBpZiAocjAgPiBlcHNpbG9uJDEpIHtcbiAgICAgICAgY29udGV4dC5tb3ZlVG8ocjAgKiBNYXRoLmNvcyhhMSksIHIwICogTWF0aC5zaW4oYTEpKTtcbiAgICAgICAgY29udGV4dC5hcmMoMCwgMCwgcjAsIGExLCBhMCwgY3cpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE9yIGlzIGl0IGEgY2lyY3VsYXIgb3IgYW5udWxhciBzZWN0b3I/XG4gICAgZWxzZSB7XG4gICAgICB2YXIgYTAxID0gYTAsXG4gICAgICAgICAgYTExID0gYTEsXG4gICAgICAgICAgYTAwID0gYTAsXG4gICAgICAgICAgYTEwID0gYTEsXG4gICAgICAgICAgZGEwID0gZGEsXG4gICAgICAgICAgZGExID0gZGEsXG4gICAgICAgICAgYXAgPSBwYWRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIC8gMixcbiAgICAgICAgICBycCA9IChhcCA+IGVwc2lsb24kMSkgJiYgKHBhZFJhZGl1cyA/ICtwYWRSYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IE1hdGguc3FydChyMCAqIHIwICsgcjEgKiByMSkpLFxuICAgICAgICAgIHJjID0gTWF0aC5taW4oTWF0aC5hYnMocjEgLSByMCkgLyAyLCArY29ybmVyUmFkaXVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpLFxuICAgICAgICAgIHJjMCA9IHJjLFxuICAgICAgICAgIHJjMSA9IHJjLFxuICAgICAgICAgIHQwLFxuICAgICAgICAgIHQxO1xuXG4gICAgICAvLyBBcHBseSBwYWRkaW5nPyBOb3RlIHRoYXQgc2luY2UgcjEg4omlIHIwLCBkYTEg4omlIGRhMC5cbiAgICAgIGlmIChycCA+IGVwc2lsb24kMSkge1xuICAgICAgICB2YXIgcDAgPSBhc2luKHJwIC8gcjAgKiBNYXRoLnNpbihhcCkpLFxuICAgICAgICAgICAgcDEgPSBhc2luKHJwIC8gcjEgKiBNYXRoLnNpbihhcCkpO1xuICAgICAgICBpZiAoKGRhMCAtPSBwMCAqIDIpID4gZXBzaWxvbiQxKSBwMCAqPSAoY3cgPyAxIDogLTEpLCBhMDAgKz0gcDAsIGExMCAtPSBwMDtcbiAgICAgICAgZWxzZSBkYTAgPSAwLCBhMDAgPSBhMTAgPSAoYTAgKyBhMSkgLyAyO1xuICAgICAgICBpZiAoKGRhMSAtPSBwMSAqIDIpID4gZXBzaWxvbiQxKSBwMSAqPSAoY3cgPyAxIDogLTEpLCBhMDEgKz0gcDEsIGExMSAtPSBwMTtcbiAgICAgICAgZWxzZSBkYTEgPSAwLCBhMDEgPSBhMTEgPSAoYTAgKyBhMSkgLyAyO1xuICAgICAgfVxuXG4gICAgICB2YXIgeDAxID0gcjEgKiBNYXRoLmNvcyhhMDEpLFxuICAgICAgICAgIHkwMSA9IHIxICogTWF0aC5zaW4oYTAxKSxcbiAgICAgICAgICB4MTAgPSByMCAqIE1hdGguY29zKGExMCksXG4gICAgICAgICAgeTEwID0gcjAgKiBNYXRoLnNpbihhMTApO1xuXG4gICAgICAvLyBBcHBseSByb3VuZGVkIGNvcm5lcnM/XG4gICAgICBpZiAocmMgPiBlcHNpbG9uJDEpIHtcbiAgICAgICAgdmFyIHgxMSA9IHIxICogTWF0aC5jb3MoYTExKSxcbiAgICAgICAgICAgIHkxMSA9IHIxICogTWF0aC5zaW4oYTExKSxcbiAgICAgICAgICAgIHgwMCA9IHIwICogTWF0aC5jb3MoYTAwKSxcbiAgICAgICAgICAgIHkwMCA9IHIwICogTWF0aC5zaW4oYTAwKTtcblxuICAgICAgICAvLyBSZXN0cmljdCB0aGUgY29ybmVyIHJhZGl1cyBhY2NvcmRpbmcgdG8gdGhlIHNlY3RvciBhbmdsZS5cbiAgICAgICAgaWYgKGRhIDwgcGkkMikge1xuICAgICAgICAgIHZhciBvYyA9IGRhMCA+IGVwc2lsb24kMSA/IGludGVyc2VjdCh4MDEsIHkwMSwgeDAwLCB5MDAsIHgxMSwgeTExLCB4MTAsIHkxMCkgOiBbeDEwLCB5MTBdLFxuICAgICAgICAgICAgICBheCA9IHgwMSAtIG9jWzBdLFxuICAgICAgICAgICAgICBheSA9IHkwMSAtIG9jWzFdLFxuICAgICAgICAgICAgICBieCA9IHgxMSAtIG9jWzBdLFxuICAgICAgICAgICAgICBieSA9IHkxMSAtIG9jWzFdLFxuICAgICAgICAgICAgICBrYyA9IDEgLyBNYXRoLnNpbihNYXRoLmFjb3MoKGF4ICogYnggKyBheSAqIGJ5KSAvIChNYXRoLnNxcnQoYXggKiBheCArIGF5ICogYXkpICogTWF0aC5zcXJ0KGJ4ICogYnggKyBieSAqIGJ5KSkpIC8gMiksXG4gICAgICAgICAgICAgIGxjID0gTWF0aC5zcXJ0KG9jWzBdICogb2NbMF0gKyBvY1sxXSAqIG9jWzFdKTtcbiAgICAgICAgICByYzAgPSBNYXRoLm1pbihyYywgKHIwIC0gbGMpIC8gKGtjIC0gMSkpO1xuICAgICAgICAgIHJjMSA9IE1hdGgubWluKHJjLCAocjEgLSBsYykgLyAoa2MgKyAxKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSXMgdGhlIHNlY3RvciBjb2xsYXBzZWQgdG8gYSBsaW5lP1xuICAgICAgaWYgKCEoZGExID4gZXBzaWxvbiQxKSkgY29udGV4dC5tb3ZlVG8oeDAxLCB5MDEpO1xuXG4gICAgICAvLyBEb2VzIHRoZSBzZWN0b3LigJlzIG91dGVyIHJpbmcgaGF2ZSByb3VuZGVkIGNvcm5lcnM/XG4gICAgICBlbHNlIGlmIChyYzEgPiBlcHNpbG9uJDEpIHtcbiAgICAgICAgdDAgPSBjb3JuZXJUYW5nZW50cyh4MDAsIHkwMCwgeDAxLCB5MDEsIHIxLCByYzEsIGN3KTtcbiAgICAgICAgdDEgPSBjb3JuZXJUYW5nZW50cyh4MTEsIHkxMSwgeDEwLCB5MTAsIHIxLCByYzEsIGN3KTtcblxuICAgICAgICBjb250ZXh0Lm1vdmVUbyh0MC5jeCArIHQwLngwMSwgdDAuY3kgKyB0MC55MDEpO1xuXG4gICAgICAgIC8vIEhhdmUgdGhlIGNvcm5lcnMgbWVyZ2VkP1xuICAgICAgICBpZiAocmMxIDwgcmMpIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMxLCBNYXRoLmF0YW4yKHQwLnkwMSwgdDAueDAxKSwgTWF0aC5hdGFuMih0MS55MDEsIHQxLngwMSksICFjdyk7XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBkcmF3IHRoZSB0d28gY29ybmVycyBhbmQgdGhlIHJpbmcuXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMxLCBNYXRoLmF0YW4yKHQwLnkwMSwgdDAueDAxKSwgTWF0aC5hdGFuMih0MC55MTEsIHQwLngxMSksICFjdyk7XG4gICAgICAgICAgY29udGV4dC5hcmMoMCwgMCwgcjEsIE1hdGguYXRhbjIodDAuY3kgKyB0MC55MTEsIHQwLmN4ICsgdDAueDExKSwgTWF0aC5hdGFuMih0MS5jeSArIHQxLnkxMSwgdDEuY3ggKyB0MS54MTEpLCAhY3cpO1xuICAgICAgICAgIGNvbnRleHQuYXJjKHQxLmN4LCB0MS5jeSwgcmMxLCBNYXRoLmF0YW4yKHQxLnkxMSwgdDEueDExKSwgTWF0aC5hdGFuMih0MS55MDEsIHQxLngwMSksICFjdyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT3IgaXMgdGhlIG91dGVyIHJpbmcganVzdCBhIGNpcmN1bGFyIGFyYz9cbiAgICAgIGVsc2UgY29udGV4dC5tb3ZlVG8oeDAxLCB5MDEpLCBjb250ZXh0LmFyYygwLCAwLCByMSwgYTAxLCBhMTEsICFjdyk7XG5cbiAgICAgIC8vIElzIHRoZXJlIG5vIGlubmVyIHJpbmcsIGFuZCBpdOKAmXMgYSBjaXJjdWxhciBzZWN0b3I/XG4gICAgICAvLyBPciBwZXJoYXBzIGl04oCZcyBhbiBhbm51bGFyIHNlY3RvciBjb2xsYXBzZWQgZHVlIHRvIHBhZGRpbmc/XG4gICAgICBpZiAoIShyMCA+IGVwc2lsb24kMSkgfHwgIShkYTAgPiBlcHNpbG9uJDEpKSBjb250ZXh0LmxpbmVUbyh4MTAsIHkxMCk7XG5cbiAgICAgIC8vIERvZXMgdGhlIHNlY3RvcuKAmXMgaW5uZXIgcmluZyAob3IgcG9pbnQpIGhhdmUgcm91bmRlZCBjb3JuZXJzP1xuICAgICAgZWxzZSBpZiAocmMwID4gZXBzaWxvbiQxKSB7XG4gICAgICAgIHQwID0gY29ybmVyVGFuZ2VudHMoeDEwLCB5MTAsIHgxMSwgeTExLCByMCwgLXJjMCwgY3cpO1xuICAgICAgICB0MSA9IGNvcm5lclRhbmdlbnRzKHgwMSwgeTAxLCB4MDAsIHkwMCwgcjAsIC1yYzAsIGN3KTtcblxuICAgICAgICBjb250ZXh0LmxpbmVUbyh0MC5jeCArIHQwLngwMSwgdDAuY3kgKyB0MC55MDEpO1xuXG4gICAgICAgIC8vIEhhdmUgdGhlIGNvcm5lcnMgbWVyZ2VkP1xuICAgICAgICBpZiAocmMwIDwgcmMpIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMwLCBNYXRoLmF0YW4yKHQwLnkwMSwgdDAueDAxKSwgTWF0aC5hdGFuMih0MS55MDEsIHQxLngwMSksICFjdyk7XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBkcmF3IHRoZSB0d28gY29ybmVycyBhbmQgdGhlIHJpbmcuXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMwLCBNYXRoLmF0YW4yKHQwLnkwMSwgdDAueDAxKSwgTWF0aC5hdGFuMih0MC55MTEsIHQwLngxMSksICFjdyk7XG4gICAgICAgICAgY29udGV4dC5hcmMoMCwgMCwgcjAsIE1hdGguYXRhbjIodDAuY3kgKyB0MC55MTEsIHQwLmN4ICsgdDAueDExKSwgTWF0aC5hdGFuMih0MS5jeSArIHQxLnkxMSwgdDEuY3ggKyB0MS54MTEpLCBjdyk7XG4gICAgICAgICAgY29udGV4dC5hcmModDEuY3gsIHQxLmN5LCByYzAsIE1hdGguYXRhbjIodDEueTExLCB0MS54MTEpLCBNYXRoLmF0YW4yKHQxLnkwMSwgdDEueDAxKSwgIWN3KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBPciBpcyB0aGUgaW5uZXIgcmluZyBqdXN0IGEgY2lyY3VsYXIgYXJjP1xuICAgICAgZWxzZSBjb250ZXh0LmFyYygwLCAwLCByMCwgYTEwLCBhMDAsIGN3KTtcbiAgICB9XG5cbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuXG4gICAgaWYgKGJ1ZmZlcikgcmV0dXJuIGNvbnRleHQgPSBudWxsLCBidWZmZXIgKyBcIlwiIHx8IG51bGw7XG4gIH1cblxuICBhcmMuY2VudHJvaWQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgciA9ICgraW5uZXJSYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSArICtvdXRlclJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSAvIDIsXG4gICAgICAgIGEgPSAoK3N0YXJ0QW5nbGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSArICtlbmRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSAvIDIgLSBwaSQyIC8gMjtcbiAgICByZXR1cm4gW01hdGguY29zKGEpICogciwgTWF0aC5zaW4oYSkgKiByXTtcbiAgfTtcblxuICBhcmMuaW5uZXJSYWRpdXMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaW5uZXJSYWRpdXMgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBhcmMpIDogaW5uZXJSYWRpdXM7XG4gIH07XG5cbiAgYXJjLm91dGVyUmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG91dGVyUmFkaXVzID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJjKSA6IG91dGVyUmFkaXVzO1xuICB9O1xuXG4gIGFyYy5jb3JuZXJSYWRpdXMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoY29ybmVyUmFkaXVzID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJjKSA6IGNvcm5lclJhZGl1cztcbiAgfTtcblxuICBhcmMucGFkUmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZFJhZGl1cyA9IF8gPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBhcmMpIDogcGFkUmFkaXVzO1xuICB9O1xuXG4gIGFyYy5zdGFydEFuZ2xlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0YXJ0QW5nbGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBhcmMpIDogc3RhcnRBbmdsZTtcbiAgfTtcblxuICBhcmMuZW5kQW5nbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZW5kQW5nbGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBhcmMpIDogZW5kQW5nbGU7XG4gIH07XG5cbiAgYXJjLnBhZEFuZ2xlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZEFuZ2xlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJjKSA6IHBhZEFuZ2xlO1xuICB9O1xuXG4gIGFyYy5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKChjb250ZXh0ID0gXyA9PSBudWxsID8gbnVsbCA6IF8pLCBhcmMpIDogY29udGV4dDtcbiAgfTtcblxuICByZXR1cm4gYXJjO1xufTtcblxuZnVuY3Rpb24gTGluZWFyKGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG59XG5cbkxpbmVhci5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiB0aGlzLl9wb2ludCA9PT0gMSkpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHggPSAreCwgeSA9ICt5O1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDogdGhpcy5fcG9pbnQgPSAxOyB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8oeCwgeSkgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4LCB5KTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgLy8gcHJvY2VlZFxuICAgICAgZGVmYXVsdDogdGhpcy5fY29udGV4dC5saW5lVG8oeCwgeSk7IGJyZWFrO1xuICAgIH1cbiAgfVxufTtcblxudmFyIGN1cnZlTGluZWFyID0gZnVuY3Rpb24oY29udGV4dCkge1xuICByZXR1cm4gbmV3IExpbmVhcihjb250ZXh0KTtcbn07XG5cbmZ1bmN0aW9uIHgocCkge1xuICByZXR1cm4gcFswXTtcbn1cblxuZnVuY3Rpb24geShwKSB7XG4gIHJldHVybiBwWzFdO1xufVxuXG52YXIgbGluZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgeCQkMSA9IHgsXG4gICAgICB5JCQxID0geSxcbiAgICAgIGRlZmluZWQgPSBjb25zdGFudCQyKHRydWUpLFxuICAgICAgY29udGV4dCA9IG51bGwsXG4gICAgICBjdXJ2ZSA9IGN1cnZlTGluZWFyLFxuICAgICAgb3V0cHV0ID0gbnVsbDtcblxuICBmdW5jdGlvbiBsaW5lKGRhdGEpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgICBkLFxuICAgICAgICBkZWZpbmVkMCA9IGZhbHNlLFxuICAgICAgICBidWZmZXI7XG5cbiAgICBpZiAoY29udGV4dCA9PSBudWxsKSBvdXRwdXQgPSBjdXJ2ZShidWZmZXIgPSBwYXRoKCkpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8PSBuOyArK2kpIHtcbiAgICAgIGlmICghKGkgPCBuICYmIGRlZmluZWQoZCA9IGRhdGFbaV0sIGksIGRhdGEpKSA9PT0gZGVmaW5lZDApIHtcbiAgICAgICAgaWYgKGRlZmluZWQwID0gIWRlZmluZWQwKSBvdXRwdXQubGluZVN0YXJ0KCk7XG4gICAgICAgIGVsc2Ugb3V0cHV0LmxpbmVFbmQoKTtcbiAgICAgIH1cbiAgICAgIGlmIChkZWZpbmVkMCkgb3V0cHV0LnBvaW50KCt4JCQxKGQsIGksIGRhdGEpLCAreSQkMShkLCBpLCBkYXRhKSk7XG4gICAgfVxuXG4gICAgaWYgKGJ1ZmZlcikgcmV0dXJuIG91dHB1dCA9IG51bGwsIGJ1ZmZlciArIFwiXCIgfHwgbnVsbDtcbiAgfVxuXG4gIGxpbmUueCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4JCQxID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgbGluZSkgOiB4JCQxO1xuICB9O1xuXG4gIGxpbmUueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5JCQxID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgbGluZSkgOiB5JCQxO1xuICB9O1xuXG4gIGxpbmUuZGVmaW5lZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkZWZpbmVkID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCEhXyksIGxpbmUpIDogZGVmaW5lZDtcbiAgfTtcblxuICBsaW5lLmN1cnZlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGN1cnZlID0gXywgY29udGV4dCAhPSBudWxsICYmIChvdXRwdXQgPSBjdXJ2ZShjb250ZXh0KSksIGxpbmUpIDogY3VydmU7XG4gIH07XG5cbiAgbGluZS5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKF8gPT0gbnVsbCA/IGNvbnRleHQgPSBvdXRwdXQgPSBudWxsIDogb3V0cHV0ID0gY3VydmUoY29udGV4dCA9IF8pLCBsaW5lKSA6IGNvbnRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIGxpbmU7XG59O1xuXG52YXIgYXJlYSQxID0gZnVuY3Rpb24oKSB7XG4gIHZhciB4MCA9IHgsXG4gICAgICB4MSA9IG51bGwsXG4gICAgICB5MCA9IGNvbnN0YW50JDIoMCksXG4gICAgICB5MSA9IHksXG4gICAgICBkZWZpbmVkID0gY29uc3RhbnQkMih0cnVlKSxcbiAgICAgIGNvbnRleHQgPSBudWxsLFxuICAgICAgY3VydmUgPSBjdXJ2ZUxpbmVhcixcbiAgICAgIG91dHB1dCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gYXJlYShkYXRhKSB7XG4gICAgdmFyIGksXG4gICAgICAgIGosXG4gICAgICAgIGssXG4gICAgICAgIG4gPSBkYXRhLmxlbmd0aCxcbiAgICAgICAgZCxcbiAgICAgICAgZGVmaW5lZDAgPSBmYWxzZSxcbiAgICAgICAgYnVmZmVyLFxuICAgICAgICB4MHogPSBuZXcgQXJyYXkobiksXG4gICAgICAgIHkweiA9IG5ldyBBcnJheShuKTtcblxuICAgIGlmIChjb250ZXh0ID09IG51bGwpIG91dHB1dCA9IGN1cnZlKGJ1ZmZlciA9IHBhdGgoKSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDw9IG47ICsraSkge1xuICAgICAgaWYgKCEoaSA8IG4gJiYgZGVmaW5lZChkID0gZGF0YVtpXSwgaSwgZGF0YSkpID09PSBkZWZpbmVkMCkge1xuICAgICAgICBpZiAoZGVmaW5lZDAgPSAhZGVmaW5lZDApIHtcbiAgICAgICAgICBqID0gaTtcbiAgICAgICAgICBvdXRwdXQuYXJlYVN0YXJ0KCk7XG4gICAgICAgICAgb3V0cHV0LmxpbmVTdGFydCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dHB1dC5saW5lRW5kKCk7XG4gICAgICAgICAgb3V0cHV0LmxpbmVTdGFydCgpO1xuICAgICAgICAgIGZvciAoayA9IGkgLSAxOyBrID49IGo7IC0taykge1xuICAgICAgICAgICAgb3V0cHV0LnBvaW50KHgweltrXSwgeTB6W2tdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb3V0cHV0LmxpbmVFbmQoKTtcbiAgICAgICAgICBvdXRwdXQuYXJlYUVuZCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZGVmaW5lZDApIHtcbiAgICAgICAgeDB6W2ldID0gK3gwKGQsIGksIGRhdGEpLCB5MHpbaV0gPSAreTAoZCwgaSwgZGF0YSk7XG4gICAgICAgIG91dHB1dC5wb2ludCh4MSA/ICt4MShkLCBpLCBkYXRhKSA6IHgweltpXSwgeTEgPyAreTEoZCwgaSwgZGF0YSkgOiB5MHpbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChidWZmZXIpIHJldHVybiBvdXRwdXQgPSBudWxsLCBidWZmZXIgKyBcIlwiIHx8IG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiBhcmVhbGluZSgpIHtcbiAgICByZXR1cm4gbGluZSgpLmRlZmluZWQoZGVmaW5lZCkuY3VydmUoY3VydmUpLmNvbnRleHQoY29udGV4dCk7XG4gIH1cblxuICBhcmVhLnggPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeDAgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCB4MSA9IG51bGwsIGFyZWEpIDogeDA7XG4gIH07XG5cbiAgYXJlYS54MCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIGFyZWEpIDogeDA7XG4gIH07XG5cbiAgYXJlYS54MSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MSA9IF8gPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBhcmVhKSA6IHgxO1xuICB9O1xuXG4gIGFyZWEueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5MCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIHkxID0gbnVsbCwgYXJlYSkgOiB5MDtcbiAgfTtcblxuICBhcmVhLnkwID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkwID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJlYSkgOiB5MDtcbiAgfTtcblxuICBhcmVhLnkxID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkxID0gXyA9PSBudWxsID8gbnVsbCA6IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIGFyZWEpIDogeTE7XG4gIH07XG5cbiAgYXJlYS5saW5lWDAgPVxuICBhcmVhLmxpbmVZMCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhcmVhbGluZSgpLngoeDApLnkoeTApO1xuICB9O1xuXG4gIGFyZWEubGluZVkxID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGFyZWFsaW5lKCkueCh4MCkueSh5MSk7XG4gIH07XG5cbiAgYXJlYS5saW5lWDEgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXJlYWxpbmUoKS54KHgxKS55KHkwKTtcbiAgfTtcblxuICBhcmVhLmRlZmluZWQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZGVmaW5lZCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMighIV8pLCBhcmVhKSA6IGRlZmluZWQ7XG4gIH07XG5cbiAgYXJlYS5jdXJ2ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjdXJ2ZSA9IF8sIGNvbnRleHQgIT0gbnVsbCAmJiAob3V0cHV0ID0gY3VydmUoY29udGV4dCkpLCBhcmVhKSA6IGN1cnZlO1xuICB9O1xuXG4gIGFyZWEuY29udGV4dCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChfID09IG51bGwgPyBjb250ZXh0ID0gb3V0cHV0ID0gbnVsbCA6IG91dHB1dCA9IGN1cnZlKGNvbnRleHQgPSBfKSwgYXJlYSkgOiBjb250ZXh0O1xuICB9O1xuXG4gIHJldHVybiBhcmVhO1xufTtcblxudmFyIGRlc2NlbmRpbmckMSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGIgPCBhID8gLTEgOiBiID4gYSA/IDEgOiBiID49IGEgPyAwIDogTmFOO1xufTtcblxudmFyIGlkZW50aXR5JDEgPSBmdW5jdGlvbihkKSB7XG4gIHJldHVybiBkO1xufTtcblxudmFyIHBpZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdmFsdWUgPSBpZGVudGl0eSQxLFxuICAgICAgc29ydFZhbHVlcyA9IGRlc2NlbmRpbmckMSxcbiAgICAgIHNvcnQgPSBudWxsLFxuICAgICAgc3RhcnRBbmdsZSA9IGNvbnN0YW50JDIoMCksXG4gICAgICBlbmRBbmdsZSA9IGNvbnN0YW50JDIodGF1JDIpLFxuICAgICAgcGFkQW5nbGUgPSBjb25zdGFudCQyKDApO1xuXG4gIGZ1bmN0aW9uIHBpZShkYXRhKSB7XG4gICAgdmFyIGksXG4gICAgICAgIG4gPSBkYXRhLmxlbmd0aCxcbiAgICAgICAgaixcbiAgICAgICAgayxcbiAgICAgICAgc3VtID0gMCxcbiAgICAgICAgaW5kZXggPSBuZXcgQXJyYXkobiksXG4gICAgICAgIGFyY3MgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIGEwID0gK3N0YXJ0QW5nbGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgZGEgPSBNYXRoLm1pbih0YXUkMiwgTWF0aC5tYXgoLXRhdSQyLCBlbmRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIC0gYTApKSxcbiAgICAgICAgYTEsXG4gICAgICAgIHAgPSBNYXRoLm1pbihNYXRoLmFicyhkYSkgLyBuLCBwYWRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSxcbiAgICAgICAgcGEgPSBwICogKGRhIDwgMCA/IC0xIDogMSksXG4gICAgICAgIHY7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKHYgPSBhcmNzW2luZGV4W2ldID0gaV0gPSArdmFsdWUoZGF0YVtpXSwgaSwgZGF0YSkpID4gMCkge1xuICAgICAgICBzdW0gKz0gdjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBPcHRpb25hbGx5IHNvcnQgdGhlIGFyY3MgYnkgcHJldmlvdXNseS1jb21wdXRlZCB2YWx1ZXMgb3IgYnkgZGF0YS5cbiAgICBpZiAoc29ydFZhbHVlcyAhPSBudWxsKSBpbmRleC5zb3J0KGZ1bmN0aW9uKGksIGopIHsgcmV0dXJuIHNvcnRWYWx1ZXMoYXJjc1tpXSwgYXJjc1tqXSk7IH0pO1xuICAgIGVsc2UgaWYgKHNvcnQgIT0gbnVsbCkgaW5kZXguc29ydChmdW5jdGlvbihpLCBqKSB7IHJldHVybiBzb3J0KGRhdGFbaV0sIGRhdGFbal0pOyB9KTtcblxuICAgIC8vIENvbXB1dGUgdGhlIGFyY3MhIFRoZXkgYXJlIHN0b3JlZCBpbiB0aGUgb3JpZ2luYWwgZGF0YSdzIG9yZGVyLlxuICAgIGZvciAoaSA9IDAsIGsgPSBzdW0gPyAoZGEgLSBuICogcGEpIC8gc3VtIDogMDsgaSA8IG47ICsraSwgYTAgPSBhMSkge1xuICAgICAgaiA9IGluZGV4W2ldLCB2ID0gYXJjc1tqXSwgYTEgPSBhMCArICh2ID4gMCA/IHYgKiBrIDogMCkgKyBwYSwgYXJjc1tqXSA9IHtcbiAgICAgICAgZGF0YTogZGF0YVtqXSxcbiAgICAgICAgaW5kZXg6IGksXG4gICAgICAgIHZhbHVlOiB2LFxuICAgICAgICBzdGFydEFuZ2xlOiBhMCxcbiAgICAgICAgZW5kQW5nbGU6IGExLFxuICAgICAgICBwYWRBbmdsZTogcFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJjcztcbiAgfVxuXG4gIHBpZS52YWx1ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh2YWx1ZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIHBpZSkgOiB2YWx1ZTtcbiAgfTtcblxuICBwaWUuc29ydFZhbHVlcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzb3J0VmFsdWVzID0gXywgc29ydCA9IG51bGwsIHBpZSkgOiBzb3J0VmFsdWVzO1xuICB9O1xuXG4gIHBpZS5zb3J0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNvcnQgPSBfLCBzb3J0VmFsdWVzID0gbnVsbCwgcGllKSA6IHNvcnQ7XG4gIH07XG5cbiAgcGllLnN0YXJ0QW5nbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc3RhcnRBbmdsZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIHBpZSkgOiBzdGFydEFuZ2xlO1xuICB9O1xuXG4gIHBpZS5lbmRBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChlbmRBbmdsZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIHBpZSkgOiBlbmRBbmdsZTtcbiAgfTtcblxuICBwaWUucGFkQW5nbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkQW5nbGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBwaWUpIDogcGFkQW5nbGU7XG4gIH07XG5cbiAgcmV0dXJuIHBpZTtcbn07XG5cbnZhciBjdXJ2ZVJhZGlhbExpbmVhciA9IGN1cnZlUmFkaWFsKGN1cnZlTGluZWFyKTtcblxuZnVuY3Rpb24gUmFkaWFsKGN1cnZlKSB7XG4gIHRoaXMuX2N1cnZlID0gY3VydmU7XG59XG5cblJhZGlhbC5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fY3VydmUuYXJlYVN0YXJ0KCk7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2N1cnZlLmFyZWFFbmQoKTtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9jdXJ2ZS5saW5lU3RhcnQoKTtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fY3VydmUubGluZUVuZCgpO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oYSwgcikge1xuICAgIHRoaXMuX2N1cnZlLnBvaW50KHIgKiBNYXRoLnNpbihhKSwgciAqIC1NYXRoLmNvcyhhKSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGN1cnZlUmFkaWFsKGN1cnZlKSB7XG5cbiAgZnVuY3Rpb24gcmFkaWFsKGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFJhZGlhbChjdXJ2ZShjb250ZXh0KSk7XG4gIH1cblxuICByYWRpYWwuX2N1cnZlID0gY3VydmU7XG5cbiAgcmV0dXJuIHJhZGlhbDtcbn1cblxuZnVuY3Rpb24gcmFkaWFsTGluZShsKSB7XG4gIHZhciBjID0gbC5jdXJ2ZTtcblxuICBsLmFuZ2xlID0gbC54LCBkZWxldGUgbC54O1xuICBsLnJhZGl1cyA9IGwueSwgZGVsZXRlIGwueTtcblxuICBsLmN1cnZlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gYyhjdXJ2ZVJhZGlhbChfKSkgOiBjKCkuX2N1cnZlO1xuICB9O1xuXG4gIHJldHVybiBsO1xufVxuXG52YXIgcmFkaWFsTGluZSQxID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiByYWRpYWxMaW5lKGxpbmUoKS5jdXJ2ZShjdXJ2ZVJhZGlhbExpbmVhcikpO1xufTtcblxudmFyIHJhZGlhbEFyZWEgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGEgPSBhcmVhJDEoKS5jdXJ2ZShjdXJ2ZVJhZGlhbExpbmVhciksXG4gICAgICBjID0gYS5jdXJ2ZSxcbiAgICAgIHgwID0gYS5saW5lWDAsXG4gICAgICB4MSA9IGEubGluZVgxLFxuICAgICAgeTAgPSBhLmxpbmVZMCxcbiAgICAgIHkxID0gYS5saW5lWTE7XG5cbiAgYS5hbmdsZSA9IGEueCwgZGVsZXRlIGEueDtcbiAgYS5zdGFydEFuZ2xlID0gYS54MCwgZGVsZXRlIGEueDA7XG4gIGEuZW5kQW5nbGUgPSBhLngxLCBkZWxldGUgYS54MTtcbiAgYS5yYWRpdXMgPSBhLnksIGRlbGV0ZSBhLnk7XG4gIGEuaW5uZXJSYWRpdXMgPSBhLnkwLCBkZWxldGUgYS55MDtcbiAgYS5vdXRlclJhZGl1cyA9IGEueTEsIGRlbGV0ZSBhLnkxO1xuICBhLmxpbmVTdGFydEFuZ2xlID0gZnVuY3Rpb24oKSB7IHJldHVybiByYWRpYWxMaW5lKHgwKCkpOyB9LCBkZWxldGUgYS5saW5lWDA7XG4gIGEubGluZUVuZEFuZ2xlID0gZnVuY3Rpb24oKSB7IHJldHVybiByYWRpYWxMaW5lKHgxKCkpOyB9LCBkZWxldGUgYS5saW5lWDE7XG4gIGEubGluZUlubmVyUmFkaXVzID0gZnVuY3Rpb24oKSB7IHJldHVybiByYWRpYWxMaW5lKHkwKCkpOyB9LCBkZWxldGUgYS5saW5lWTA7XG4gIGEubGluZU91dGVyUmFkaXVzID0gZnVuY3Rpb24oKSB7IHJldHVybiByYWRpYWxMaW5lKHkxKCkpOyB9LCBkZWxldGUgYS5saW5lWTE7XG5cbiAgYS5jdXJ2ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IGMoY3VydmVSYWRpYWwoXykpIDogYygpLl9jdXJ2ZTtcbiAgfTtcblxuICByZXR1cm4gYTtcbn07XG5cbnZhciBjaXJjbGUgPSB7XG4gIGRyYXc6IGZ1bmN0aW9uKGNvbnRleHQsIHNpemUpIHtcbiAgICB2YXIgciA9IE1hdGguc3FydChzaXplIC8gcGkkMik7XG4gICAgY29udGV4dC5tb3ZlVG8ociwgMCk7XG4gICAgY29udGV4dC5hcmMoMCwgMCwgciwgMCwgdGF1JDIpO1xuICB9XG59O1xuXG52YXIgY3Jvc3MkMSA9IHtcbiAgZHJhdzogZnVuY3Rpb24oY29udGV4dCwgc2l6ZSkge1xuICAgIHZhciByID0gTWF0aC5zcXJ0KHNpemUgLyA1KSAvIDI7XG4gICAgY29udGV4dC5tb3ZlVG8oLTMgKiByLCAtcik7XG4gICAgY29udGV4dC5saW5lVG8oLXIsIC1yKTtcbiAgICBjb250ZXh0LmxpbmVUbygtciwgLTMgKiByKTtcbiAgICBjb250ZXh0LmxpbmVUbyhyLCAtMyAqIHIpO1xuICAgIGNvbnRleHQubGluZVRvKHIsIC1yKTtcbiAgICBjb250ZXh0LmxpbmVUbygzICogciwgLXIpO1xuICAgIGNvbnRleHQubGluZVRvKDMgKiByLCByKTtcbiAgICBjb250ZXh0LmxpbmVUbyhyLCByKTtcbiAgICBjb250ZXh0LmxpbmVUbyhyLCAzICogcik7XG4gICAgY29udGV4dC5saW5lVG8oLXIsIDMgKiByKTtcbiAgICBjb250ZXh0LmxpbmVUbygtciwgcik7XG4gICAgY29udGV4dC5saW5lVG8oLTMgKiByLCByKTtcbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICB9XG59O1xuXG52YXIgdGFuMzAgPSBNYXRoLnNxcnQoMSAvIDMpO1xudmFyIHRhbjMwXzIgPSB0YW4zMCAqIDI7XG5cbnZhciBkaWFtb25kID0ge1xuICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgdmFyIHkgPSBNYXRoLnNxcnQoc2l6ZSAvIHRhbjMwXzIpLFxuICAgICAgICB4ID0geSAqIHRhbjMwO1xuICAgIGNvbnRleHQubW92ZVRvKDAsIC15KTtcbiAgICBjb250ZXh0LmxpbmVUbyh4LCAwKTtcbiAgICBjb250ZXh0LmxpbmVUbygwLCB5KTtcbiAgICBjb250ZXh0LmxpbmVUbygteCwgMCk7XG4gICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgfVxufTtcblxudmFyIGthID0gMC44OTA4MTMwOTE1MjkyODUyMjgxMDtcbnZhciBrciA9IE1hdGguc2luKHBpJDIgLyAxMCkgLyBNYXRoLnNpbig3ICogcGkkMiAvIDEwKTtcbnZhciBreCA9IE1hdGguc2luKHRhdSQyIC8gMTApICoga3I7XG52YXIga3kgPSAtTWF0aC5jb3ModGF1JDIgLyAxMCkgKiBrcjtcblxudmFyIHN0YXIgPSB7XG4gIGRyYXc6IGZ1bmN0aW9uKGNvbnRleHQsIHNpemUpIHtcbiAgICB2YXIgciA9IE1hdGguc3FydChzaXplICoga2EpLFxuICAgICAgICB4ID0ga3ggKiByLFxuICAgICAgICB5ID0ga3kgKiByO1xuICAgIGNvbnRleHQubW92ZVRvKDAsIC1yKTtcbiAgICBjb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IDU7ICsraSkge1xuICAgICAgdmFyIGEgPSB0YXUkMiAqIGkgLyA1LFxuICAgICAgICAgIGMgPSBNYXRoLmNvcyhhKSxcbiAgICAgICAgICBzID0gTWF0aC5zaW4oYSk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhzICogciwgLWMgKiByKTtcbiAgICAgIGNvbnRleHQubGluZVRvKGMgKiB4IC0gcyAqIHksIHMgKiB4ICsgYyAqIHkpO1xuICAgIH1cbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICB9XG59O1xuXG52YXIgc3F1YXJlID0ge1xuICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgdmFyIHcgPSBNYXRoLnNxcnQoc2l6ZSksXG4gICAgICAgIHggPSAtdyAvIDI7XG4gICAgY29udGV4dC5yZWN0KHgsIHgsIHcsIHcpO1xuICB9XG59O1xuXG52YXIgc3FydDMgPSBNYXRoLnNxcnQoMyk7XG5cbnZhciB0cmlhbmdsZSA9IHtcbiAgZHJhdzogZnVuY3Rpb24oY29udGV4dCwgc2l6ZSkge1xuICAgIHZhciB5ID0gLU1hdGguc3FydChzaXplIC8gKHNxcnQzICogMykpO1xuICAgIGNvbnRleHQubW92ZVRvKDAsIHkgKiAyKTtcbiAgICBjb250ZXh0LmxpbmVUbygtc3FydDMgKiB5LCAteSk7XG4gICAgY29udGV4dC5saW5lVG8oc3FydDMgKiB5LCAteSk7XG4gICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgfVxufTtcblxudmFyIGMgPSAtMC41O1xudmFyIHMgPSBNYXRoLnNxcnQoMykgLyAyO1xudmFyIGsgPSAxIC8gTWF0aC5zcXJ0KDEyKTtcbnZhciBhID0gKGsgLyAyICsgMSkgKiAzO1xuXG52YXIgd3llID0ge1xuICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgdmFyIHIgPSBNYXRoLnNxcnQoc2l6ZSAvIGEpLFxuICAgICAgICB4MCA9IHIgLyAyLFxuICAgICAgICB5MCA9IHIgKiBrLFxuICAgICAgICB4MSA9IHgwLFxuICAgICAgICB5MSA9IHIgKiBrICsgcixcbiAgICAgICAgeDIgPSAteDEsXG4gICAgICAgIHkyID0geTE7XG4gICAgY29udGV4dC5tb3ZlVG8oeDAsIHkwKTtcbiAgICBjb250ZXh0LmxpbmVUbyh4MSwgeTEpO1xuICAgIGNvbnRleHQubGluZVRvKHgyLCB5Mik7XG4gICAgY29udGV4dC5saW5lVG8oYyAqIHgwIC0gcyAqIHkwLCBzICogeDAgKyBjICogeTApO1xuICAgIGNvbnRleHQubGluZVRvKGMgKiB4MSAtIHMgKiB5MSwgcyAqIHgxICsgYyAqIHkxKTtcbiAgICBjb250ZXh0LmxpbmVUbyhjICogeDIgLSBzICogeTIsIHMgKiB4MiArIGMgKiB5Mik7XG4gICAgY29udGV4dC5saW5lVG8oYyAqIHgwICsgcyAqIHkwLCBjICogeTAgLSBzICogeDApO1xuICAgIGNvbnRleHQubGluZVRvKGMgKiB4MSArIHMgKiB5MSwgYyAqIHkxIC0gcyAqIHgxKTtcbiAgICBjb250ZXh0LmxpbmVUbyhjICogeDIgKyBzICogeTIsIGMgKiB5MiAtIHMgKiB4Mik7XG4gICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgfVxufTtcblxudmFyIHN5bWJvbHMgPSBbXG4gIGNpcmNsZSxcbiAgY3Jvc3MkMSxcbiAgZGlhbW9uZCxcbiAgc3F1YXJlLFxuICBzdGFyLFxuICB0cmlhbmdsZSxcbiAgd3llXG5dO1xuXG52YXIgc3ltYm9sID0gZnVuY3Rpb24oKSB7XG4gIHZhciB0eXBlID0gY29uc3RhbnQkMihjaXJjbGUpLFxuICAgICAgc2l6ZSA9IGNvbnN0YW50JDIoNjQpLFxuICAgICAgY29udGV4dCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gc3ltYm9sKCkge1xuICAgIHZhciBidWZmZXI7XG4gICAgaWYgKCFjb250ZXh0KSBjb250ZXh0ID0gYnVmZmVyID0gcGF0aCgpO1xuICAgIHR5cGUuYXBwbHkodGhpcywgYXJndW1lbnRzKS5kcmF3KGNvbnRleHQsICtzaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuICAgIGlmIChidWZmZXIpIHJldHVybiBjb250ZXh0ID0gbnVsbCwgYnVmZmVyICsgXCJcIiB8fCBudWxsO1xuICB9XG5cbiAgc3ltYm9sLnR5cGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodHlwZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMihfKSwgc3ltYm9sKSA6IHR5cGU7XG4gIH07XG5cbiAgc3ltYm9sLnNpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc2l6ZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIHN5bWJvbCkgOiBzaXplO1xuICB9O1xuXG4gIHN5bWJvbC5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNvbnRleHQgPSBfID09IG51bGwgPyBudWxsIDogXywgc3ltYm9sKSA6IGNvbnRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIHN5bWJvbDtcbn07XG5cbnZhciBub29wID0gZnVuY3Rpb24oKSB7fTtcblxuZnVuY3Rpb24gcG9pbnQodGhhdCwgeCwgeSkge1xuICB0aGF0Ll9jb250ZXh0LmJlemllckN1cnZlVG8oXG4gICAgKDIgKiB0aGF0Ll94MCArIHRoYXQuX3gxKSAvIDMsXG4gICAgKDIgKiB0aGF0Ll95MCArIHRoYXQuX3kxKSAvIDMsXG4gICAgKHRoYXQuX3gwICsgMiAqIHRoYXQuX3gxKSAvIDMsXG4gICAgKHRoYXQuX3kwICsgMiAqIHRoYXQuX3kxKSAvIDMsXG4gICAgKHRoYXQuX3gwICsgNCAqIHRoYXQuX3gxICsgeCkgLyA2LFxuICAgICh0aGF0Ll95MCArIDQgKiB0aGF0Ll95MSArIHkpIC8gNlxuICApO1xufVxuXG5mdW5jdGlvbiBCYXNpcyhjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5CYXNpcy5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMzogcG9pbnQodGhpcywgdGhpcy5feDEsIHRoaXMuX3kxKTsgLy8gcHJvY2VlZFxuICAgICAgY2FzZSAyOiB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MSwgdGhpcy5feTEpOyBicmVhaztcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpIDogdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IGJyZWFrO1xuICAgICAgY2FzZSAyOiB0aGlzLl9wb2ludCA9IDM7IHRoaXMuX2NvbnRleHQubGluZVRvKCg1ICogdGhpcy5feDAgKyB0aGlzLl94MSkgLyA2LCAoNSAqIHRoaXMuX3kwICsgdGhpcy5feTEpIC8gNik7IC8vIHByb2NlZWRcbiAgICAgIGRlZmF1bHQ6IHBvaW50KHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0geTtcbiAgfVxufTtcblxudmFyIGJhc2lzID0gZnVuY3Rpb24oY29udGV4dCkge1xuICByZXR1cm4gbmV3IEJhc2lzKGNvbnRleHQpO1xufTtcblxuZnVuY3Rpb24gQmFzaXNDbG9zZWQoY29udGV4dCkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbn1cblxuQmFzaXNDbG9zZWQucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IG5vb3AsXG4gIGFyZWFFbmQ6IG5vb3AsXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9IHRoaXMuX3gyID0gdGhpcy5feDMgPSB0aGlzLl94NCA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gdGhpcy5feTMgPSB0aGlzLl95NCA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MiwgdGhpcy5feTIpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbygodGhpcy5feDIgKyAyICogdGhpcy5feDMpIC8gMywgKHRoaXMuX3kyICsgMiAqIHRoaXMuX3kzKSAvIDMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbygodGhpcy5feDMgKyAyICogdGhpcy5feDIpIC8gMywgKHRoaXMuX3kzICsgMiAqIHRoaXMuX3kyKSAvIDMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMzoge1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3gyLCB0aGlzLl95Mik7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDMsIHRoaXMuX3kzKTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NCwgdGhpcy5feTQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX3gyID0geCwgdGhpcy5feTIgPSB5OyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl94MyA9IHgsIHRoaXMuX3kzID0geTsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgdGhpcy5feDQgPSB4LCB0aGlzLl95NCA9IHk7IHRoaXMuX2NvbnRleHQubW92ZVRvKCh0aGlzLl94MCArIDQgKiB0aGlzLl94MSArIHgpIC8gNiwgKHRoaXMuX3kwICsgNCAqIHRoaXMuX3kxICsgeSkgLyA2KTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBwb2ludCh0aGlzLCB4LCB5KTsgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHk7XG4gIH1cbn07XG5cbnZhciBiYXNpc0Nsb3NlZCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBCYXNpc0Nsb3NlZChjb250ZXh0KTtcbn07XG5cbmZ1bmN0aW9uIEJhc2lzT3Blbihjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5CYXNpc09wZW4ucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPSBOYU47XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiB0aGlzLl9wb2ludCA9PT0gMykpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHggPSAreCwgeSA9ICt5O1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDogdGhpcy5fcG9pbnQgPSAxOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyB2YXIgeDAgPSAodGhpcy5feDAgKyA0ICogdGhpcy5feDEgKyB4KSAvIDYsIHkwID0gKHRoaXMuX3kwICsgNCAqIHRoaXMuX3kxICsgeSkgLyA2OyB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8oeDAsIHkwKSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgwLCB5MCk7IGJyZWFrO1xuICAgICAgY2FzZSAzOiB0aGlzLl9wb2ludCA9IDQ7IC8vIHByb2NlZWRcbiAgICAgIGRlZmF1bHQ6IHBvaW50KHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0geTtcbiAgfVxufTtcblxudmFyIGJhc2lzT3BlbiA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBCYXNpc09wZW4oY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiBCdW5kbGUoY29udGV4dCwgYmV0YSkge1xuICB0aGlzLl9iYXNpcyA9IG5ldyBCYXNpcyhjb250ZXh0KTtcbiAgdGhpcy5fYmV0YSA9IGJldGE7XG59XG5cbkJ1bmRsZS5wcm90b3R5cGUgPSB7XG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feCA9IFtdO1xuICAgIHRoaXMuX3kgPSBbXTtcbiAgICB0aGlzLl9iYXNpcy5saW5lU3RhcnQoKTtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHggPSB0aGlzLl94LFxuICAgICAgICB5ID0gdGhpcy5feSxcbiAgICAgICAgaiA9IHgubGVuZ3RoIC0gMTtcblxuICAgIGlmIChqID4gMCkge1xuICAgICAgdmFyIHgwID0geFswXSxcbiAgICAgICAgICB5MCA9IHlbMF0sXG4gICAgICAgICAgZHggPSB4W2pdIC0geDAsXG4gICAgICAgICAgZHkgPSB5W2pdIC0geTAsXG4gICAgICAgICAgaSA9IC0xLFxuICAgICAgICAgIHQ7XG5cbiAgICAgIHdoaWxlICgrK2kgPD0gaikge1xuICAgICAgICB0ID0gaSAvIGo7XG4gICAgICAgIHRoaXMuX2Jhc2lzLnBvaW50KFxuICAgICAgICAgIHRoaXMuX2JldGEgKiB4W2ldICsgKDEgLSB0aGlzLl9iZXRhKSAqICh4MCArIHQgKiBkeCksXG4gICAgICAgICAgdGhpcy5fYmV0YSAqIHlbaV0gKyAoMSAtIHRoaXMuX2JldGEpICogKHkwICsgdCAqIGR5KVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3ggPSB0aGlzLl95ID0gbnVsbDtcbiAgICB0aGlzLl9iYXNpcy5saW5lRW5kKCk7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgdGhpcy5feC5wdXNoKCt4KTtcbiAgICB0aGlzLl95LnB1c2goK3kpO1xuICB9XG59O1xuXG52YXIgYnVuZGxlID0gKGZ1bmN0aW9uIGN1c3RvbShiZXRhKSB7XG5cbiAgZnVuY3Rpb24gYnVuZGxlKGNvbnRleHQpIHtcbiAgICByZXR1cm4gYmV0YSA9PT0gMSA/IG5ldyBCYXNpcyhjb250ZXh0KSA6IG5ldyBCdW5kbGUoY29udGV4dCwgYmV0YSk7XG4gIH1cblxuICBidW5kbGUuYmV0YSA9IGZ1bmN0aW9uKGJldGEpIHtcbiAgICByZXR1cm4gY3VzdG9tKCtiZXRhKTtcbiAgfTtcblxuICByZXR1cm4gYnVuZGxlO1xufSkoMC44NSk7XG5cbmZ1bmN0aW9uIHBvaW50JDEodGhhdCwgeCwgeSkge1xuICB0aGF0Ll9jb250ZXh0LmJlemllckN1cnZlVG8oXG4gICAgdGhhdC5feDEgKyB0aGF0Ll9rICogKHRoYXQuX3gyIC0gdGhhdC5feDApLFxuICAgIHRoYXQuX3kxICsgdGhhdC5fayAqICh0aGF0Ll95MiAtIHRoYXQuX3kwKSxcbiAgICB0aGF0Ll94MiArIHRoYXQuX2sgKiAodGhhdC5feDEgLSB4KSxcbiAgICB0aGF0Ll95MiArIHRoYXQuX2sgKiAodGhhdC5feTEgLSB5KSxcbiAgICB0aGF0Ll94MixcbiAgICB0aGF0Ll95MlxuICApO1xufVxuXG5mdW5jdGlvbiBDYXJkaW5hbChjb250ZXh0LCB0ZW5zaW9uKSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xuICB0aGlzLl9rID0gKDEgLSB0ZW5zaW9uKSAvIDY7XG59XG5cbkNhcmRpbmFsLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID0gdGhpcy5feDIgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPSB0aGlzLl95MiA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMjogdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feDIsIHRoaXMuX3kyKTsgYnJlYWs7XG4gICAgICBjYXNlIDM6IHBvaW50JDEodGhpcywgdGhpcy5feDEsIHRoaXMuX3kxKTsgYnJlYWs7XG4gICAgfVxuICAgIGlmICh0aGlzLl9saW5lIHx8ICh0aGlzLl9saW5lICE9PSAwICYmIHRoaXMuX3BvaW50ID09PSAxKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl94MSA9IHgsIHRoaXMuX3kxID0geTsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgLy8gcHJvY2VlZFxuICAgICAgZGVmYXVsdDogcG9pbnQkMSh0aGlzLCB4LCB5KTsgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjYXJkaW5hbCA9IChmdW5jdGlvbiBjdXN0b20odGVuc2lvbikge1xuXG4gIGZ1bmN0aW9uIGNhcmRpbmFsKGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IENhcmRpbmFsKGNvbnRleHQsIHRlbnNpb24pO1xuICB9XG5cbiAgY2FyZGluYWwudGVuc2lvbiA9IGZ1bmN0aW9uKHRlbnNpb24pIHtcbiAgICByZXR1cm4gY3VzdG9tKCt0ZW5zaW9uKTtcbiAgfTtcblxuICByZXR1cm4gY2FyZGluYWw7XG59KSgwKTtcblxuZnVuY3Rpb24gQ2FyZGluYWxDbG9zZWQoY29udGV4dCwgdGVuc2lvbikge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgdGhpcy5fayA9ICgxIC0gdGVuc2lvbikgLyA2O1xufVxuXG5DYXJkaW5hbENsb3NlZC5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogbm9vcCxcbiAgYXJlYUVuZDogbm9vcCxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID0gdGhpcy5feDIgPSB0aGlzLl94MyA9IHRoaXMuX3g0ID0gdGhpcy5feDUgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPSB0aGlzLl95MiA9IHRoaXMuX3kzID0gdGhpcy5feTQgPSB0aGlzLl95NSA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MywgdGhpcy5feTMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MywgdGhpcy5feTMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMzoge1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDQsIHRoaXMuX3k0KTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NSwgdGhpcy5feTUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX3gzID0geCwgdGhpcy5feTMgPSB5OyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94NCA9IHgsIHRoaXMuX3k0ID0geSk7IGJyZWFrO1xuICAgICAgY2FzZSAyOiB0aGlzLl9wb2ludCA9IDM7IHRoaXMuX3g1ID0geCwgdGhpcy5feTUgPSB5OyBicmVhaztcbiAgICAgIGRlZmF1bHQ6IHBvaW50JDEodGhpcywgeCwgeSk7IGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxLCB0aGlzLl94MSA9IHRoaXMuX3gyLCB0aGlzLl94MiA9IHg7XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSwgdGhpcy5feTEgPSB0aGlzLl95MiwgdGhpcy5feTIgPSB5O1xuICB9XG59O1xuXG52YXIgY2FyZGluYWxDbG9zZWQgPSAoZnVuY3Rpb24gY3VzdG9tKHRlbnNpb24pIHtcblxuICBmdW5jdGlvbiBjYXJkaW5hbChjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBDYXJkaW5hbENsb3NlZChjb250ZXh0LCB0ZW5zaW9uKTtcbiAgfVxuXG4gIGNhcmRpbmFsLnRlbnNpb24gPSBmdW5jdGlvbih0ZW5zaW9uKSB7XG4gICAgcmV0dXJuIGN1c3RvbSgrdGVuc2lvbik7XG4gIH07XG5cbiAgcmV0dXJuIGNhcmRpbmFsO1xufSkoMCk7XG5cbmZ1bmN0aW9uIENhcmRpbmFsT3Blbihjb250ZXh0LCB0ZW5zaW9uKSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xuICB0aGlzLl9rID0gKDEgLSB0ZW5zaW9uKSAvIDY7XG59XG5cbkNhcmRpbmFsT3Blbi5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9IHRoaXMuX3gyID1cbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxID0gdGhpcy5feTIgPSBOYU47XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiB0aGlzLl9wb2ludCA9PT0gMykpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHggPSAreCwgeSA9ICt5O1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDogdGhpcy5fcG9pbnQgPSAxOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feDIsIHRoaXMuX3kyKSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHRoaXMuX3gyLCB0aGlzLl95Mik7IGJyZWFrO1xuICAgICAgY2FzZSAzOiB0aGlzLl9wb2ludCA9IDQ7IC8vIHByb2NlZWRcbiAgICAgIGRlZmF1bHQ6IHBvaW50JDEodGhpcywgeCwgeSk7IGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxLCB0aGlzLl94MSA9IHRoaXMuX3gyLCB0aGlzLl94MiA9IHg7XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSwgdGhpcy5feTEgPSB0aGlzLl95MiwgdGhpcy5feTIgPSB5O1xuICB9XG59O1xuXG52YXIgY2FyZGluYWxPcGVuID0gKGZ1bmN0aW9uIGN1c3RvbSh0ZW5zaW9uKSB7XG5cbiAgZnVuY3Rpb24gY2FyZGluYWwoY29udGV4dCkge1xuICAgIHJldHVybiBuZXcgQ2FyZGluYWxPcGVuKGNvbnRleHQsIHRlbnNpb24pO1xuICB9XG5cbiAgY2FyZGluYWwudGVuc2lvbiA9IGZ1bmN0aW9uKHRlbnNpb24pIHtcbiAgICByZXR1cm4gY3VzdG9tKCt0ZW5zaW9uKTtcbiAgfTtcblxuICByZXR1cm4gY2FyZGluYWw7XG59KSgwKTtcblxuZnVuY3Rpb24gcG9pbnQkMih0aGF0LCB4LCB5KSB7XG4gIHZhciB4MSA9IHRoYXQuX3gxLFxuICAgICAgeTEgPSB0aGF0Ll95MSxcbiAgICAgIHgyID0gdGhhdC5feDIsXG4gICAgICB5MiA9IHRoYXQuX3kyO1xuXG4gIGlmICh0aGF0Ll9sMDFfYSA+IGVwc2lsb24kMSkge1xuICAgIHZhciBhID0gMiAqIHRoYXQuX2wwMV8yYSArIDMgKiB0aGF0Ll9sMDFfYSAqIHRoYXQuX2wxMl9hICsgdGhhdC5fbDEyXzJhLFxuICAgICAgICBuID0gMyAqIHRoYXQuX2wwMV9hICogKHRoYXQuX2wwMV9hICsgdGhhdC5fbDEyX2EpO1xuICAgIHgxID0gKHgxICogYSAtIHRoYXQuX3gwICogdGhhdC5fbDEyXzJhICsgdGhhdC5feDIgKiB0aGF0Ll9sMDFfMmEpIC8gbjtcbiAgICB5MSA9ICh5MSAqIGEgLSB0aGF0Ll95MCAqIHRoYXQuX2wxMl8yYSArIHRoYXQuX3kyICogdGhhdC5fbDAxXzJhKSAvIG47XG4gIH1cblxuICBpZiAodGhhdC5fbDIzX2EgPiBlcHNpbG9uJDEpIHtcbiAgICB2YXIgYiA9IDIgKiB0aGF0Ll9sMjNfMmEgKyAzICogdGhhdC5fbDIzX2EgKiB0aGF0Ll9sMTJfYSArIHRoYXQuX2wxMl8yYSxcbiAgICAgICAgbSA9IDMgKiB0aGF0Ll9sMjNfYSAqICh0aGF0Ll9sMjNfYSArIHRoYXQuX2wxMl9hKTtcbiAgICB4MiA9ICh4MiAqIGIgKyB0aGF0Ll94MSAqIHRoYXQuX2wyM18yYSAtIHggKiB0aGF0Ll9sMTJfMmEpIC8gbTtcbiAgICB5MiA9ICh5MiAqIGIgKyB0aGF0Ll95MSAqIHRoYXQuX2wyM18yYSAtIHkgKiB0aGF0Ll9sMTJfMmEpIC8gbTtcbiAgfVxuXG4gIHRoYXQuX2NvbnRleHQuYmV6aWVyQ3VydmVUbyh4MSwgeTEsIHgyLCB5MiwgdGhhdC5feDIsIHRoYXQuX3kyKTtcbn1cblxuZnVuY3Rpb24gQ2F0bXVsbFJvbShjb250ZXh0LCBhbHBoYSkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgdGhpcy5fYWxwaGEgPSBhbHBoYTtcbn1cblxuQ2F0bXVsbFJvbS5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9IHRoaXMuX3gyID1cbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxID0gdGhpcy5feTIgPSBOYU47XG4gICAgdGhpcy5fbDAxX2EgPSB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hID1cbiAgICB0aGlzLl9sMDFfMmEgPSB0aGlzLl9sMTJfMmEgPSB0aGlzLl9sMjNfMmEgPVxuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAyOiB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MiwgdGhpcy5feTIpOyBicmVhaztcbiAgICAgIGNhc2UgMzogdGhpcy5wb2ludCh0aGlzLl94MiwgdGhpcy5feTIpOyBicmVhaztcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcblxuICAgIGlmICh0aGlzLl9wb2ludCkge1xuICAgICAgdmFyIHgyMyA9IHRoaXMuX3gyIC0geCxcbiAgICAgICAgICB5MjMgPSB0aGlzLl95MiAtIHk7XG4gICAgICB0aGlzLl9sMjNfYSA9IE1hdGguc3FydCh0aGlzLl9sMjNfMmEgPSBNYXRoLnBvdyh4MjMgKiB4MjMgKyB5MjMgKiB5MjMsIHRoaXMuX2FscGhhKSk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiBwb2ludCQyKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLl9sMDFfYSA9IHRoaXMuX2wxMl9hLCB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hO1xuICAgIHRoaXMuX2wwMV8yYSA9IHRoaXMuX2wxMl8yYSwgdGhpcy5fbDEyXzJhID0gdGhpcy5fbDIzXzJhO1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjYXRtdWxsUm9tID0gKGZ1bmN0aW9uIGN1c3RvbShhbHBoYSkge1xuXG4gIGZ1bmN0aW9uIGNhdG11bGxSb20oY29udGV4dCkge1xuICAgIHJldHVybiBhbHBoYSA/IG5ldyBDYXRtdWxsUm9tKGNvbnRleHQsIGFscGhhKSA6IG5ldyBDYXJkaW5hbChjb250ZXh0LCAwKTtcbiAgfVxuXG4gIGNhdG11bGxSb20uYWxwaGEgPSBmdW5jdGlvbihhbHBoYSkge1xuICAgIHJldHVybiBjdXN0b20oK2FscGhhKTtcbiAgfTtcblxuICByZXR1cm4gY2F0bXVsbFJvbTtcbn0pKDAuNSk7XG5cbmZ1bmN0aW9uIENhdG11bGxSb21DbG9zZWQoY29udGV4dCwgYWxwaGEpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX2FscGhhID0gYWxwaGE7XG59XG5cbkNhdG11bGxSb21DbG9zZWQucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IG5vb3AsXG4gIGFyZWFFbmQ6IG5vb3AsXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9IHRoaXMuX3gyID0gdGhpcy5feDMgPSB0aGlzLl94NCA9IHRoaXMuX3g1ID1cbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxID0gdGhpcy5feTIgPSB0aGlzLl95MyA9IHRoaXMuX3k0ID0gdGhpcy5feTUgPSBOYU47XG4gICAgdGhpcy5fbDAxX2EgPSB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hID1cbiAgICB0aGlzLl9sMDFfMmEgPSB0aGlzLl9sMTJfMmEgPSB0aGlzLl9sMjNfMmEgPVxuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAxOiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubW92ZVRvKHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAyOiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAzOiB7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDMsIHRoaXMuX3kzKTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NCwgdGhpcy5feTQpO1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3g1LCB0aGlzLl95NSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcblxuICAgIGlmICh0aGlzLl9wb2ludCkge1xuICAgICAgdmFyIHgyMyA9IHRoaXMuX3gyIC0geCxcbiAgICAgICAgICB5MjMgPSB0aGlzLl95MiAtIHk7XG4gICAgICB0aGlzLl9sMjNfYSA9IE1hdGguc3FydCh0aGlzLl9sMjNfMmEgPSBNYXRoLnBvdyh4MjMgKiB4MjMgKyB5MjMgKiB5MjMsIHRoaXMuX2FscGhhKSk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX3gzID0geCwgdGhpcy5feTMgPSB5OyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94NCA9IHgsIHRoaXMuX3k0ID0geSk7IGJyZWFrO1xuICAgICAgY2FzZSAyOiB0aGlzLl9wb2ludCA9IDM7IHRoaXMuX3g1ID0geCwgdGhpcy5feTUgPSB5OyBicmVhaztcbiAgICAgIGRlZmF1bHQ6IHBvaW50JDIodGhpcywgeCwgeSk7IGJyZWFrO1xuICAgIH1cblxuICAgIHRoaXMuX2wwMV9hID0gdGhpcy5fbDEyX2EsIHRoaXMuX2wxMl9hID0gdGhpcy5fbDIzX2E7XG4gICAgdGhpcy5fbDAxXzJhID0gdGhpcy5fbDEyXzJhLCB0aGlzLl9sMTJfMmEgPSB0aGlzLl9sMjNfMmE7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB0aGlzLl94MiwgdGhpcy5feDIgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0gdGhpcy5feTIsIHRoaXMuX3kyID0geTtcbiAgfVxufTtcblxudmFyIGNhdG11bGxSb21DbG9zZWQgPSAoZnVuY3Rpb24gY3VzdG9tKGFscGhhKSB7XG5cbiAgZnVuY3Rpb24gY2F0bXVsbFJvbShjb250ZXh0KSB7XG4gICAgcmV0dXJuIGFscGhhID8gbmV3IENhdG11bGxSb21DbG9zZWQoY29udGV4dCwgYWxwaGEpIDogbmV3IENhcmRpbmFsQ2xvc2VkKGNvbnRleHQsIDApO1xuICB9XG5cbiAgY2F0bXVsbFJvbS5hbHBoYSA9IGZ1bmN0aW9uKGFscGhhKSB7XG4gICAgcmV0dXJuIGN1c3RvbSgrYWxwaGEpO1xuICB9O1xuXG4gIHJldHVybiBjYXRtdWxsUm9tO1xufSkoMC41KTtcblxuZnVuY3Rpb24gQ2F0bXVsbFJvbU9wZW4oY29udGV4dCwgYWxwaGEpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX2FscGhhID0gYWxwaGE7XG59XG5cbkNhdG11bGxSb21PcGVuLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID0gdGhpcy5feDIgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPSB0aGlzLl95MiA9IE5hTjtcbiAgICB0aGlzLl9sMDFfYSA9IHRoaXMuX2wxMl9hID0gdGhpcy5fbDIzX2EgPVxuICAgIHRoaXMuX2wwMV8yYSA9IHRoaXMuX2wxMl8yYSA9IHRoaXMuX2wyM18yYSA9XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiB0aGlzLl9wb2ludCA9PT0gMykpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHggPSAreCwgeSA9ICt5O1xuXG4gICAgaWYgKHRoaXMuX3BvaW50KSB7XG4gICAgICB2YXIgeDIzID0gdGhpcy5feDIgLSB4LFxuICAgICAgICAgIHkyMyA9IHRoaXMuX3kyIC0geTtcbiAgICAgIHRoaXMuX2wyM19hID0gTWF0aC5zcXJ0KHRoaXMuX2wyM18yYSA9IE1hdGgucG93KHgyMyAqIHgyMyArIHkyMyAqIHkyMywgdGhpcy5fYWxwaGEpKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHRoaXMuX3gyLCB0aGlzLl95MikgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MiwgdGhpcy5feTIpOyBicmVhaztcbiAgICAgIGNhc2UgMzogdGhpcy5fcG9pbnQgPSA0OyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiBwb2ludCQyKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLl9sMDFfYSA9IHRoaXMuX2wxMl9hLCB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hO1xuICAgIHRoaXMuX2wwMV8yYSA9IHRoaXMuX2wxMl8yYSwgdGhpcy5fbDEyXzJhID0gdGhpcy5fbDIzXzJhO1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjYXRtdWxsUm9tT3BlbiA9IChmdW5jdGlvbiBjdXN0b20oYWxwaGEpIHtcblxuICBmdW5jdGlvbiBjYXRtdWxsUm9tKGNvbnRleHQpIHtcbiAgICByZXR1cm4gYWxwaGEgPyBuZXcgQ2F0bXVsbFJvbU9wZW4oY29udGV4dCwgYWxwaGEpIDogbmV3IENhcmRpbmFsT3Blbihjb250ZXh0LCAwKTtcbiAgfVxuXG4gIGNhdG11bGxSb20uYWxwaGEgPSBmdW5jdGlvbihhbHBoYSkge1xuICAgIHJldHVybiBjdXN0b20oK2FscGhhKTtcbiAgfTtcblxuICByZXR1cm4gY2F0bXVsbFJvbTtcbn0pKDAuNSk7XG5cbmZ1bmN0aW9uIExpbmVhckNsb3NlZChjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5MaW5lYXJDbG9zZWQucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IG5vb3AsXG4gIGFyZWFFbmQ6IG5vb3AsXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fcG9pbnQpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgaWYgKHRoaXMuX3BvaW50KSB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICBlbHNlIHRoaXMuX3BvaW50ID0gMSwgdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7XG4gIH1cbn07XG5cbnZhciBsaW5lYXJDbG9zZWQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgTGluZWFyQ2xvc2VkKGNvbnRleHQpO1xufTtcblxuZnVuY3Rpb24gc2lnbih4KSB7XG4gIHJldHVybiB4IDwgMCA/IC0xIDogMTtcbn1cblxuLy8gQ2FsY3VsYXRlIHRoZSBzbG9wZXMgb2YgdGhlIHRhbmdlbnRzIChIZXJtaXRlLXR5cGUgaW50ZXJwb2xhdGlvbikgYmFzZWQgb25cbi8vIHRoZSBmb2xsb3dpbmcgcGFwZXI6IFN0ZWZmZW4sIE0uIDE5OTAuIEEgU2ltcGxlIE1ldGhvZCBmb3IgTW9ub3RvbmljXG4vLyBJbnRlcnBvbGF0aW9uIGluIE9uZSBEaW1lbnNpb24uIEFzdHJvbm9teSBhbmQgQXN0cm9waHlzaWNzLCBWb2wuIDIzOSwgTk8uXG4vLyBOT1YoSUkpLCBQLiA0NDMsIDE5OTAuXG5mdW5jdGlvbiBzbG9wZTModGhhdCwgeDIsIHkyKSB7XG4gIHZhciBoMCA9IHRoYXQuX3gxIC0gdGhhdC5feDAsXG4gICAgICBoMSA9IHgyIC0gdGhhdC5feDEsXG4gICAgICBzMCA9ICh0aGF0Ll95MSAtIHRoYXQuX3kwKSAvIChoMCB8fCBoMSA8IDAgJiYgLTApLFxuICAgICAgczEgPSAoeTIgLSB0aGF0Ll95MSkgLyAoaDEgfHwgaDAgPCAwICYmIC0wKSxcbiAgICAgIHAgPSAoczAgKiBoMSArIHMxICogaDApIC8gKGgwICsgaDEpO1xuICByZXR1cm4gKHNpZ24oczApICsgc2lnbihzMSkpICogTWF0aC5taW4oTWF0aC5hYnMoczApLCBNYXRoLmFicyhzMSksIDAuNSAqIE1hdGguYWJzKHApKSB8fCAwO1xufVxuXG4vLyBDYWxjdWxhdGUgYSBvbmUtc2lkZWQgc2xvcGUuXG5mdW5jdGlvbiBzbG9wZTIodGhhdCwgdCkge1xuICB2YXIgaCA9IHRoYXQuX3gxIC0gdGhhdC5feDA7XG4gIHJldHVybiBoID8gKDMgKiAodGhhdC5feTEgLSB0aGF0Ll95MCkgLyBoIC0gdCkgLyAyIDogdDtcbn1cblxuLy8gQWNjb3JkaW5nIHRvIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0N1YmljX0hlcm1pdGVfc3BsaW5lI1JlcHJlc2VudGF0aW9uc1xuLy8gXCJ5b3UgY2FuIGV4cHJlc3MgY3ViaWMgSGVybWl0ZSBpbnRlcnBvbGF0aW9uIGluIHRlcm1zIG9mIGN1YmljIELDqXppZXIgY3VydmVzXG4vLyB3aXRoIHJlc3BlY3QgdG8gdGhlIGZvdXIgdmFsdWVzIHAwLCBwMCArIG0wIC8gMywgcDEgLSBtMSAvIDMsIHAxXCIuXG5mdW5jdGlvbiBwb2ludCQzKHRoYXQsIHQwLCB0MSkge1xuICB2YXIgeDAgPSB0aGF0Ll94MCxcbiAgICAgIHkwID0gdGhhdC5feTAsXG4gICAgICB4MSA9IHRoYXQuX3gxLFxuICAgICAgeTEgPSB0aGF0Ll95MSxcbiAgICAgIGR4ID0gKHgxIC0geDApIC8gMztcbiAgdGhhdC5fY29udGV4dC5iZXppZXJDdXJ2ZVRvKHgwICsgZHgsIHkwICsgZHggKiB0MCwgeDEgLSBkeCwgeTEgLSBkeCAqIHQxLCB4MSwgeTEpO1xufVxuXG5mdW5jdGlvbiBNb25vdG9uZVgoY29udGV4dCkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbn1cblxuTW9ub3RvbmVYLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID1cbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxID1cbiAgICB0aGlzLl90MCA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMjogdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feDEsIHRoaXMuX3kxKTsgYnJlYWs7XG4gICAgICBjYXNlIDM6IHBvaW50JDModGhpcywgdGhpcy5fdDAsIHNsb3BlMih0aGlzLCB0aGlzLl90MCkpOyBicmVhaztcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB2YXIgdDEgPSBOYU47XG5cbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBpZiAoeCA9PT0gdGhpcy5feDEgJiYgeSA9PT0gdGhpcy5feTEpIHJldHVybjsgLy8gSWdub3JlIGNvaW5jaWRlbnQgcG9pbnRzLlxuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDogdGhpcy5fcG9pbnQgPSAxOyB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8oeCwgeSkgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4LCB5KTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgcG9pbnQkMyh0aGlzLCBzbG9wZTIodGhpcywgdDEgPSBzbG9wZTModGhpcywgeCwgeSkpLCB0MSk7IGJyZWFrO1xuICAgICAgZGVmYXVsdDogcG9pbnQkMyh0aGlzLCB0aGlzLl90MCwgdDEgPSBzbG9wZTModGhpcywgeCwgeSkpOyBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxLCB0aGlzLl94MSA9IHg7XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSwgdGhpcy5feTEgPSB5O1xuICAgIHRoaXMuX3QwID0gdDE7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIE1vbm90b25lWShjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBuZXcgUmVmbGVjdENvbnRleHQoY29udGV4dCk7XG59XG5cbihNb25vdG9uZVkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShNb25vdG9uZVgucHJvdG90eXBlKSkucG9pbnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gIE1vbm90b25lWC5wcm90b3R5cGUucG9pbnQuY2FsbCh0aGlzLCB5LCB4KTtcbn07XG5cbmZ1bmN0aW9uIFJlZmxlY3RDb250ZXh0KGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG59XG5cblJlZmxlY3RDb250ZXh0LnByb3RvdHlwZSA9IHtcbiAgbW92ZVRvOiBmdW5jdGlvbih4LCB5KSB7IHRoaXMuX2NvbnRleHQubW92ZVRvKHksIHgpOyB9LFxuICBjbG9zZVBhdGg6IGZ1bmN0aW9uKCkgeyB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpOyB9LFxuICBsaW5lVG86IGZ1bmN0aW9uKHgsIHkpIHsgdGhpcy5fY29udGV4dC5saW5lVG8oeSwgeCk7IH0sXG4gIGJlemllckN1cnZlVG86IGZ1bmN0aW9uKHgxLCB5MSwgeDIsIHkyLCB4LCB5KSB7IHRoaXMuX2NvbnRleHQuYmV6aWVyQ3VydmVUbyh5MSwgeDEsIHkyLCB4MiwgeSwgeCk7IH1cbn07XG5cbmZ1bmN0aW9uIG1vbm90b25lWChjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgTW9ub3RvbmVYKGNvbnRleHQpO1xufVxuXG5mdW5jdGlvbiBtb25vdG9uZVkoY29udGV4dCkge1xuICByZXR1cm4gbmV3IE1vbm90b25lWShjb250ZXh0KTtcbn1cblxuZnVuY3Rpb24gTmF0dXJhbChjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5OYXR1cmFsLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94ID0gW107XG4gICAgdGhpcy5feSA9IFtdO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgeCA9IHRoaXMuX3gsXG4gICAgICAgIHkgPSB0aGlzLl95LFxuICAgICAgICBuID0geC5sZW5ndGg7XG5cbiAgICBpZiAobikge1xuICAgICAgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHhbMF0sIHlbMF0pIDogdGhpcy5fY29udGV4dC5tb3ZlVG8oeFswXSwgeVswXSk7XG4gICAgICBpZiAobiA9PT0gMikge1xuICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh4WzFdLCB5WzFdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBweCA9IGNvbnRyb2xQb2ludHMoeCksXG4gICAgICAgICAgICBweSA9IGNvbnRyb2xQb2ludHMoeSk7XG4gICAgICAgIGZvciAodmFyIGkwID0gMCwgaTEgPSAxOyBpMSA8IG47ICsraTAsICsraTEpIHtcbiAgICAgICAgICB0aGlzLl9jb250ZXh0LmJlemllckN1cnZlVG8ocHhbMF1baTBdLCBweVswXVtpMF0sIHB4WzFdW2kwXSwgcHlbMV1baTBdLCB4W2kxXSwgeVtpMV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgbiA9PT0gMSkpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICAgIHRoaXMuX3ggPSB0aGlzLl95ID0gbnVsbDtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB0aGlzLl94LnB1c2goK3gpO1xuICAgIHRoaXMuX3kucHVzaCgreSk7XG4gIH1cbn07XG5cbi8vIFNlZSBodHRwczovL3d3dy5wYXJ0aWNsZWluY2VsbC5jb20vMjAxMi9iZXppZXItc3BsaW5lcy8gZm9yIGRlcml2YXRpb24uXG5mdW5jdGlvbiBjb250cm9sUG9pbnRzKHgpIHtcbiAgdmFyIGksXG4gICAgICBuID0geC5sZW5ndGggLSAxLFxuICAgICAgbSxcbiAgICAgIGEgPSBuZXcgQXJyYXkobiksXG4gICAgICBiID0gbmV3IEFycmF5KG4pLFxuICAgICAgciA9IG5ldyBBcnJheShuKTtcbiAgYVswXSA9IDAsIGJbMF0gPSAyLCByWzBdID0geFswXSArIDIgKiB4WzFdO1xuICBmb3IgKGkgPSAxOyBpIDwgbiAtIDE7ICsraSkgYVtpXSA9IDEsIGJbaV0gPSA0LCByW2ldID0gNCAqIHhbaV0gKyAyICogeFtpICsgMV07XG4gIGFbbiAtIDFdID0gMiwgYltuIC0gMV0gPSA3LCByW24gLSAxXSA9IDggKiB4W24gLSAxXSArIHhbbl07XG4gIGZvciAoaSA9IDE7IGkgPCBuOyArK2kpIG0gPSBhW2ldIC8gYltpIC0gMV0sIGJbaV0gLT0gbSwgcltpXSAtPSBtICogcltpIC0gMV07XG4gIGFbbiAtIDFdID0gcltuIC0gMV0gLyBiW24gLSAxXTtcbiAgZm9yIChpID0gbiAtIDI7IGkgPj0gMDsgLS1pKSBhW2ldID0gKHJbaV0gLSBhW2kgKyAxXSkgLyBiW2ldO1xuICBiW24gLSAxXSA9ICh4W25dICsgYVtuIC0gMV0pIC8gMjtcbiAgZm9yIChpID0gMDsgaSA8IG4gLSAxOyArK2kpIGJbaV0gPSAyICogeFtpICsgMV0gLSBhW2kgKyAxXTtcbiAgcmV0dXJuIFthLCBiXTtcbn1cblxudmFyIG5hdHVyYWwgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgTmF0dXJhbChjb250ZXh0KTtcbn07XG5cbmZ1bmN0aW9uIFN0ZXAoY29udGV4dCwgdCkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgdGhpcy5fdCA9IHQ7XG59XG5cblN0ZXAucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3ggPSB0aGlzLl95ID0gTmFOO1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKDAgPCB0aGlzLl90ICYmIHRoaXMuX3QgPCAxICYmIHRoaXMuX3BvaW50ID09PSAyKSB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94LCB0aGlzLl95KTtcbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiB0aGlzLl9wb2ludCA9PT0gMSkpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgaWYgKHRoaXMuX2xpbmUgPj0gMCkgdGhpcy5fdCA9IDEgLSB0aGlzLl90LCB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGlmICh0aGlzLl90IDw9IDApIHtcbiAgICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94LCB5KTtcbiAgICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgeDEgPSB0aGlzLl94ICogKDEgLSB0aGlzLl90KSArIHggKiB0aGlzLl90O1xuICAgICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHgxLCB0aGlzLl95KTtcbiAgICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh4MSwgeSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX3ggPSB4LCB0aGlzLl95ID0geTtcbiAgfVxufTtcblxudmFyIHN0ZXAgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgU3RlcChjb250ZXh0LCAwLjUpO1xufTtcblxuZnVuY3Rpb24gc3RlcEJlZm9yZShjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgU3RlcChjb250ZXh0LCAwKTtcbn1cblxuZnVuY3Rpb24gc3RlcEFmdGVyKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBTdGVwKGNvbnRleHQsIDEpO1xufVxuXG52YXIgc2xpY2UkMiA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcblxudmFyIG5vbmUgPSBmdW5jdGlvbihzZXJpZXMsIG9yZGVyKSB7XG4gIGlmICghKChuID0gc2VyaWVzLmxlbmd0aCkgPiAxKSkgcmV0dXJuO1xuICBmb3IgKHZhciBpID0gMSwgczAsIHMxID0gc2VyaWVzW29yZGVyWzBdXSwgbiwgbSA9IHMxLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgIHMwID0gczEsIHMxID0gc2VyaWVzW29yZGVyW2ldXTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IG07ICsraikge1xuICAgICAgczFbal1bMV0gKz0gczFbal1bMF0gPSBpc05hTihzMFtqXVsxXSkgPyBzMFtqXVswXSA6IHMwW2pdWzFdO1xuICAgIH1cbiAgfVxufTtcblxudmFyIG5vbmUkMSA9IGZ1bmN0aW9uKHNlcmllcykge1xuICB2YXIgbiA9IHNlcmllcy5sZW5ndGgsIG8gPSBuZXcgQXJyYXkobik7XG4gIHdoaWxlICgtLW4gPj0gMCkgb1tuXSA9IG47XG4gIHJldHVybiBvO1xufTtcblxuZnVuY3Rpb24gc3RhY2tWYWx1ZShkLCBrZXkpIHtcbiAgcmV0dXJuIGRba2V5XTtcbn1cblxudmFyIHN0YWNrID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrZXlzID0gY29uc3RhbnQkMihbXSksXG4gICAgICBvcmRlciA9IG5vbmUkMSxcbiAgICAgIG9mZnNldCA9IG5vbmUsXG4gICAgICB2YWx1ZSA9IHN0YWNrVmFsdWU7XG5cbiAgZnVuY3Rpb24gc3RhY2soZGF0YSkge1xuICAgIHZhciBreiA9IGtleXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgaSxcbiAgICAgICAgbSA9IGRhdGEubGVuZ3RoLFxuICAgICAgICBuID0ga3oubGVuZ3RoLFxuICAgICAgICBzeiA9IG5ldyBBcnJheShuKSxcbiAgICAgICAgb3o7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBmb3IgKHZhciBraSA9IGt6W2ldLCBzaSA9IHN6W2ldID0gbmV3IEFycmF5KG0pLCBqID0gMCwgc2lqOyBqIDwgbTsgKytqKSB7XG4gICAgICAgIHNpW2pdID0gc2lqID0gWzAsICt2YWx1ZShkYXRhW2pdLCBraSwgaiwgZGF0YSldO1xuICAgICAgICBzaWouZGF0YSA9IGRhdGFbal07XG4gICAgICB9XG4gICAgICBzaS5rZXkgPSBraTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwLCBveiA9IG9yZGVyKHN6KTsgaSA8IG47ICsraSkge1xuICAgICAgc3pbb3pbaV1dLmluZGV4ID0gaTtcbiAgICB9XG5cbiAgICBvZmZzZXQoc3osIG96KTtcbiAgICByZXR1cm4gc3o7XG4gIH1cblxuICBzdGFjay5rZXlzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGtleXMgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoc2xpY2UkMi5jYWxsKF8pKSwgc3RhY2spIDoga2V5cztcbiAgfTtcblxuICBzdGFjay52YWx1ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh2YWx1ZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIHN0YWNrKSA6IHZhbHVlO1xuICB9O1xuXG4gIHN0YWNrLm9yZGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG9yZGVyID0gXyA9PSBudWxsID8gbm9uZSQxIDogdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKHNsaWNlJDIuY2FsbChfKSksIHN0YWNrKSA6IG9yZGVyO1xuICB9O1xuXG4gIHN0YWNrLm9mZnNldCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChvZmZzZXQgPSBfID09IG51bGwgPyBub25lIDogXywgc3RhY2spIDogb2Zmc2V0O1xuICB9O1xuXG4gIHJldHVybiBzdGFjaztcbn07XG5cbnZhciBleHBhbmQgPSBmdW5jdGlvbihzZXJpZXMsIG9yZGVyKSB7XG4gIGlmICghKChuID0gc2VyaWVzLmxlbmd0aCkgPiAwKSkgcmV0dXJuO1xuICBmb3IgKHZhciBpLCBuLCBqID0gMCwgbSA9IHNlcmllc1swXS5sZW5ndGgsIHk7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHkgPSBpID0gMDsgaSA8IG47ICsraSkgeSArPSBzZXJpZXNbaV1bal1bMV0gfHwgMDtcbiAgICBpZiAoeSkgZm9yIChpID0gMDsgaSA8IG47ICsraSkgc2VyaWVzW2ldW2pdWzFdIC89IHk7XG4gIH1cbiAgbm9uZShzZXJpZXMsIG9yZGVyKTtcbn07XG5cbnZhciBzaWxob3VldHRlID0gZnVuY3Rpb24oc2VyaWVzLCBvcmRlcikge1xuICBpZiAoISgobiA9IHNlcmllcy5sZW5ndGgpID4gMCkpIHJldHVybjtcbiAgZm9yICh2YXIgaiA9IDAsIHMwID0gc2VyaWVzW29yZGVyWzBdXSwgbiwgbSA9IHMwLmxlbmd0aDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGkgPSAwLCB5ID0gMDsgaSA8IG47ICsraSkgeSArPSBzZXJpZXNbaV1bal1bMV0gfHwgMDtcbiAgICBzMFtqXVsxXSArPSBzMFtqXVswXSA9IC15IC8gMjtcbiAgfVxuICBub25lKHNlcmllcywgb3JkZXIpO1xufTtcblxudmFyIHdpZ2dsZSA9IGZ1bmN0aW9uKHNlcmllcywgb3JkZXIpIHtcbiAgaWYgKCEoKG4gPSBzZXJpZXMubGVuZ3RoKSA+IDApIHx8ICEoKG0gPSAoczAgPSBzZXJpZXNbb3JkZXJbMF1dKS5sZW5ndGgpID4gMCkpIHJldHVybjtcbiAgZm9yICh2YXIgeSA9IDAsIGogPSAxLCBzMCwgbSwgbjsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGkgPSAwLCBzMSA9IDAsIHMyID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgdmFyIHNpID0gc2VyaWVzW29yZGVyW2ldXSxcbiAgICAgICAgICBzaWowID0gc2lbal1bMV0gfHwgMCxcbiAgICAgICAgICBzaWoxID0gc2lbaiAtIDFdWzFdIHx8IDAsXG4gICAgICAgICAgczMgPSAoc2lqMCAtIHNpajEpIC8gMjtcbiAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgaTsgKytrKSB7XG4gICAgICAgIHZhciBzayA9IHNlcmllc1tvcmRlcltrXV0sXG4gICAgICAgICAgICBza2owID0gc2tbal1bMV0gfHwgMCxcbiAgICAgICAgICAgIHNrajEgPSBza1tqIC0gMV1bMV0gfHwgMDtcbiAgICAgICAgczMgKz0gc2tqMCAtIHNrajE7XG4gICAgICB9XG4gICAgICBzMSArPSBzaWowLCBzMiArPSBzMyAqIHNpajA7XG4gICAgfVxuICAgIHMwW2ogLSAxXVsxXSArPSBzMFtqIC0gMV1bMF0gPSB5O1xuICAgIGlmIChzMSkgeSAtPSBzMiAvIHMxO1xuICB9XG4gIHMwW2ogLSAxXVsxXSArPSBzMFtqIC0gMV1bMF0gPSB5O1xuICBub25lKHNlcmllcywgb3JkZXIpO1xufTtcblxudmFyIGFzY2VuZGluZyQxID0gZnVuY3Rpb24oc2VyaWVzKSB7XG4gIHZhciBzdW1zID0gc2VyaWVzLm1hcChzdW0kMSk7XG4gIHJldHVybiBub25lJDEoc2VyaWVzKS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIHN1bXNbYV0gLSBzdW1zW2JdOyB9KTtcbn07XG5cbmZ1bmN0aW9uIHN1bSQxKHNlcmllcykge1xuICB2YXIgcyA9IDAsIGkgPSAtMSwgbiA9IHNlcmllcy5sZW5ndGgsIHY7XG4gIHdoaWxlICgrK2kgPCBuKSBpZiAodiA9ICtzZXJpZXNbaV1bMV0pIHMgKz0gdjtcbiAgcmV0dXJuIHM7XG59XG5cbnZhciBkZXNjZW5kaW5nJDIgPSBmdW5jdGlvbihzZXJpZXMpIHtcbiAgcmV0dXJuIGFzY2VuZGluZyQxKHNlcmllcykucmV2ZXJzZSgpO1xufTtcblxudmFyIGluc2lkZU91dCA9IGZ1bmN0aW9uKHNlcmllcykge1xuICB2YXIgbiA9IHNlcmllcy5sZW5ndGgsXG4gICAgICBpLFxuICAgICAgaixcbiAgICAgIHN1bXMgPSBzZXJpZXMubWFwKHN1bSQxKSxcbiAgICAgIG9yZGVyID0gbm9uZSQxKHNlcmllcykuc29ydChmdW5jdGlvbihhLCBiKSB7IHJldHVybiBzdW1zW2JdIC0gc3Vtc1thXTsgfSksXG4gICAgICB0b3AgPSAwLFxuICAgICAgYm90dG9tID0gMCxcbiAgICAgIHRvcHMgPSBbXSxcbiAgICAgIGJvdHRvbXMgPSBbXTtcblxuICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgaiA9IG9yZGVyW2ldO1xuICAgIGlmICh0b3AgPCBib3R0b20pIHtcbiAgICAgIHRvcCArPSBzdW1zW2pdO1xuICAgICAgdG9wcy5wdXNoKGopO1xuICAgIH0gZWxzZSB7XG4gICAgICBib3R0b20gKz0gc3Vtc1tqXTtcbiAgICAgIGJvdHRvbXMucHVzaChqKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYm90dG9tcy5yZXZlcnNlKCkuY29uY2F0KHRvcHMpO1xufTtcblxudmFyIHJldmVyc2UgPSBmdW5jdGlvbihzZXJpZXMpIHtcbiAgcmV0dXJuIG5vbmUkMShzZXJpZXMpLnJldmVyc2UoKTtcbn07XG5cbnZhciBkZWZpbmUgPSBmdW5jdGlvbihjb25zdHJ1Y3RvciwgZmFjdG9yeSwgcHJvdG90eXBlKSB7XG4gIGNvbnN0cnVjdG9yLnByb3RvdHlwZSA9IGZhY3RvcnkucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICBwcm90b3R5cGUuY29uc3RydWN0b3IgPSBjb25zdHJ1Y3Rvcjtcbn07XG5cbmZ1bmN0aW9uIGV4dGVuZChwYXJlbnQsIGRlZmluaXRpb24pIHtcbiAgdmFyIHByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUocGFyZW50LnByb3RvdHlwZSk7XG4gIGZvciAodmFyIGtleSBpbiBkZWZpbml0aW9uKSBwcm90b3R5cGVba2V5XSA9IGRlZmluaXRpb25ba2V5XTtcbiAgcmV0dXJuIHByb3RvdHlwZTtcbn1cblxuZnVuY3Rpb24gQ29sb3IoKSB7fVxuXG52YXIgZGFya2VyID0gMC43O1xudmFyIGJyaWdodGVyID0gMSAvIGRhcmtlcjtcblxudmFyIHJlSSA9IFwiXFxcXHMqKFsrLV0/XFxcXGQrKVxcXFxzKlwiO1xudmFyIHJlTiA9IFwiXFxcXHMqKFsrLV0/XFxcXGQqXFxcXC4/XFxcXGQrKD86W2VFXVsrLV0/XFxcXGQrKT8pXFxcXHMqXCI7XG52YXIgcmVQID0gXCJcXFxccyooWystXT9cXFxcZCpcXFxcLj9cXFxcZCsoPzpbZUVdWystXT9cXFxcZCspPyklXFxcXHMqXCI7XG52YXIgcmVIZXgzID0gL14jKFswLTlhLWZdezN9KSQvO1xudmFyIHJlSGV4NiA9IC9eIyhbMC05YS1mXXs2fSkkLztcbnZhciByZVJnYkludGVnZXIgPSBuZXcgUmVnRXhwKFwiXnJnYlxcXFwoXCIgKyBbcmVJLCByZUksIHJlSV0gKyBcIlxcXFwpJFwiKTtcbnZhciByZVJnYlBlcmNlbnQgPSBuZXcgUmVnRXhwKFwiXnJnYlxcXFwoXCIgKyBbcmVQLCByZVAsIHJlUF0gKyBcIlxcXFwpJFwiKTtcbnZhciByZVJnYmFJbnRlZ2VyID0gbmV3IFJlZ0V4cChcIl5yZ2JhXFxcXChcIiArIFtyZUksIHJlSSwgcmVJLCByZU5dICsgXCJcXFxcKSRcIik7XG52YXIgcmVSZ2JhUGVyY2VudCA9IG5ldyBSZWdFeHAoXCJecmdiYVxcXFwoXCIgKyBbcmVQLCByZVAsIHJlUCwgcmVOXSArIFwiXFxcXCkkXCIpO1xudmFyIHJlSHNsUGVyY2VudCA9IG5ldyBSZWdFeHAoXCJeaHNsXFxcXChcIiArIFtyZU4sIHJlUCwgcmVQXSArIFwiXFxcXCkkXCIpO1xudmFyIHJlSHNsYVBlcmNlbnQgPSBuZXcgUmVnRXhwKFwiXmhzbGFcXFxcKFwiICsgW3JlTiwgcmVQLCByZVAsIHJlTl0gKyBcIlxcXFwpJFwiKTtcblxudmFyIG5hbWVkID0ge1xuICBhbGljZWJsdWU6IDB4ZjBmOGZmLFxuICBhbnRpcXVld2hpdGU6IDB4ZmFlYmQ3LFxuICBhcXVhOiAweDAwZmZmZixcbiAgYXF1YW1hcmluZTogMHg3ZmZmZDQsXG4gIGF6dXJlOiAweGYwZmZmZixcbiAgYmVpZ2U6IDB4ZjVmNWRjLFxuICBiaXNxdWU6IDB4ZmZlNGM0LFxuICBibGFjazogMHgwMDAwMDAsXG4gIGJsYW5jaGVkYWxtb25kOiAweGZmZWJjZCxcbiAgYmx1ZTogMHgwMDAwZmYsXG4gIGJsdWV2aW9sZXQ6IDB4OGEyYmUyLFxuICBicm93bjogMHhhNTJhMmEsXG4gIGJ1cmx5d29vZDogMHhkZWI4ODcsXG4gIGNhZGV0Ymx1ZTogMHg1ZjllYTAsXG4gIGNoYXJ0cmV1c2U6IDB4N2ZmZjAwLFxuICBjaG9jb2xhdGU6IDB4ZDI2OTFlLFxuICBjb3JhbDogMHhmZjdmNTAsXG4gIGNvcm5mbG93ZXJibHVlOiAweDY0OTVlZCxcbiAgY29ybnNpbGs6IDB4ZmZmOGRjLFxuICBjcmltc29uOiAweGRjMTQzYyxcbiAgY3lhbjogMHgwMGZmZmYsXG4gIGRhcmtibHVlOiAweDAwMDA4YixcbiAgZGFya2N5YW46IDB4MDA4YjhiLFxuICBkYXJrZ29sZGVucm9kOiAweGI4ODYwYixcbiAgZGFya2dyYXk6IDB4YTlhOWE5LFxuICBkYXJrZ3JlZW46IDB4MDA2NDAwLFxuICBkYXJrZ3JleTogMHhhOWE5YTksXG4gIGRhcmtraGFraTogMHhiZGI3NmIsXG4gIGRhcmttYWdlbnRhOiAweDhiMDA4YixcbiAgZGFya29saXZlZ3JlZW46IDB4NTU2YjJmLFxuICBkYXJrb3JhbmdlOiAweGZmOGMwMCxcbiAgZGFya29yY2hpZDogMHg5OTMyY2MsXG4gIGRhcmtyZWQ6IDB4OGIwMDAwLFxuICBkYXJrc2FsbW9uOiAweGU5OTY3YSxcbiAgZGFya3NlYWdyZWVuOiAweDhmYmM4ZixcbiAgZGFya3NsYXRlYmx1ZTogMHg0ODNkOGIsXG4gIGRhcmtzbGF0ZWdyYXk6IDB4MmY0ZjRmLFxuICBkYXJrc2xhdGVncmV5OiAweDJmNGY0ZixcbiAgZGFya3R1cnF1b2lzZTogMHgwMGNlZDEsXG4gIGRhcmt2aW9sZXQ6IDB4OTQwMGQzLFxuICBkZWVwcGluazogMHhmZjE0OTMsXG4gIGRlZXBza3libHVlOiAweDAwYmZmZixcbiAgZGltZ3JheTogMHg2OTY5NjksXG4gIGRpbWdyZXk6IDB4Njk2OTY5LFxuICBkb2RnZXJibHVlOiAweDFlOTBmZixcbiAgZmlyZWJyaWNrOiAweGIyMjIyMixcbiAgZmxvcmFsd2hpdGU6IDB4ZmZmYWYwLFxuICBmb3Jlc3RncmVlbjogMHgyMjhiMjIsXG4gIGZ1Y2hzaWE6IDB4ZmYwMGZmLFxuICBnYWluc2Jvcm86IDB4ZGNkY2RjLFxuICBnaG9zdHdoaXRlOiAweGY4ZjhmZixcbiAgZ29sZDogMHhmZmQ3MDAsXG4gIGdvbGRlbnJvZDogMHhkYWE1MjAsXG4gIGdyYXk6IDB4ODA4MDgwLFxuICBncmVlbjogMHgwMDgwMDAsXG4gIGdyZWVueWVsbG93OiAweGFkZmYyZixcbiAgZ3JleTogMHg4MDgwODAsXG4gIGhvbmV5ZGV3OiAweGYwZmZmMCxcbiAgaG90cGluazogMHhmZjY5YjQsXG4gIGluZGlhbnJlZDogMHhjZDVjNWMsXG4gIGluZGlnbzogMHg0YjAwODIsXG4gIGl2b3J5OiAweGZmZmZmMCxcbiAga2hha2k6IDB4ZjBlNjhjLFxuICBsYXZlbmRlcjogMHhlNmU2ZmEsXG4gIGxhdmVuZGVyYmx1c2g6IDB4ZmZmMGY1LFxuICBsYXduZ3JlZW46IDB4N2NmYzAwLFxuICBsZW1vbmNoaWZmb246IDB4ZmZmYWNkLFxuICBsaWdodGJsdWU6IDB4YWRkOGU2LFxuICBsaWdodGNvcmFsOiAweGYwODA4MCxcbiAgbGlnaHRjeWFuOiAweGUwZmZmZixcbiAgbGlnaHRnb2xkZW5yb2R5ZWxsb3c6IDB4ZmFmYWQyLFxuICBsaWdodGdyYXk6IDB4ZDNkM2QzLFxuICBsaWdodGdyZWVuOiAweDkwZWU5MCxcbiAgbGlnaHRncmV5OiAweGQzZDNkMyxcbiAgbGlnaHRwaW5rOiAweGZmYjZjMSxcbiAgbGlnaHRzYWxtb246IDB4ZmZhMDdhLFxuICBsaWdodHNlYWdyZWVuOiAweDIwYjJhYSxcbiAgbGlnaHRza3libHVlOiAweDg3Y2VmYSxcbiAgbGlnaHRzbGF0ZWdyYXk6IDB4Nzc4ODk5LFxuICBsaWdodHNsYXRlZ3JleTogMHg3Nzg4OTksXG4gIGxpZ2h0c3RlZWxibHVlOiAweGIwYzRkZSxcbiAgbGlnaHR5ZWxsb3c6IDB4ZmZmZmUwLFxuICBsaW1lOiAweDAwZmYwMCxcbiAgbGltZWdyZWVuOiAweDMyY2QzMixcbiAgbGluZW46IDB4ZmFmMGU2LFxuICBtYWdlbnRhOiAweGZmMDBmZixcbiAgbWFyb29uOiAweDgwMDAwMCxcbiAgbWVkaXVtYXF1YW1hcmluZTogMHg2NmNkYWEsXG4gIG1lZGl1bWJsdWU6IDB4MDAwMGNkLFxuICBtZWRpdW1vcmNoaWQ6IDB4YmE1NWQzLFxuICBtZWRpdW1wdXJwbGU6IDB4OTM3MGRiLFxuICBtZWRpdW1zZWFncmVlbjogMHgzY2IzNzEsXG4gIG1lZGl1bXNsYXRlYmx1ZTogMHg3YjY4ZWUsXG4gIG1lZGl1bXNwcmluZ2dyZWVuOiAweDAwZmE5YSxcbiAgbWVkaXVtdHVycXVvaXNlOiAweDQ4ZDFjYyxcbiAgbWVkaXVtdmlvbGV0cmVkOiAweGM3MTU4NSxcbiAgbWlkbmlnaHRibHVlOiAweDE5MTk3MCxcbiAgbWludGNyZWFtOiAweGY1ZmZmYSxcbiAgbWlzdHlyb3NlOiAweGZmZTRlMSxcbiAgbW9jY2FzaW46IDB4ZmZlNGI1LFxuICBuYXZham93aGl0ZTogMHhmZmRlYWQsXG4gIG5hdnk6IDB4MDAwMDgwLFxuICBvbGRsYWNlOiAweGZkZjVlNixcbiAgb2xpdmU6IDB4ODA4MDAwLFxuICBvbGl2ZWRyYWI6IDB4NmI4ZTIzLFxuICBvcmFuZ2U6IDB4ZmZhNTAwLFxuICBvcmFuZ2VyZWQ6IDB4ZmY0NTAwLFxuICBvcmNoaWQ6IDB4ZGE3MGQ2LFxuICBwYWxlZ29sZGVucm9kOiAweGVlZThhYSxcbiAgcGFsZWdyZWVuOiAweDk4ZmI5OCxcbiAgcGFsZXR1cnF1b2lzZTogMHhhZmVlZWUsXG4gIHBhbGV2aW9sZXRyZWQ6IDB4ZGI3MDkzLFxuICBwYXBheWF3aGlwOiAweGZmZWZkNSxcbiAgcGVhY2hwdWZmOiAweGZmZGFiOSxcbiAgcGVydTogMHhjZDg1M2YsXG4gIHBpbms6IDB4ZmZjMGNiLFxuICBwbHVtOiAweGRkYTBkZCxcbiAgcG93ZGVyYmx1ZTogMHhiMGUwZTYsXG4gIHB1cnBsZTogMHg4MDAwODAsXG4gIHJlYmVjY2FwdXJwbGU6IDB4NjYzMzk5LFxuICByZWQ6IDB4ZmYwMDAwLFxuICByb3N5YnJvd246IDB4YmM4ZjhmLFxuICByb3lhbGJsdWU6IDB4NDE2OWUxLFxuICBzYWRkbGVicm93bjogMHg4YjQ1MTMsXG4gIHNhbG1vbjogMHhmYTgwNzIsXG4gIHNhbmR5YnJvd246IDB4ZjRhNDYwLFxuICBzZWFncmVlbjogMHgyZThiNTcsXG4gIHNlYXNoZWxsOiAweGZmZjVlZSxcbiAgc2llbm5hOiAweGEwNTIyZCxcbiAgc2lsdmVyOiAweGMwYzBjMCxcbiAgc2t5Ymx1ZTogMHg4N2NlZWIsXG4gIHNsYXRlYmx1ZTogMHg2YTVhY2QsXG4gIHNsYXRlZ3JheTogMHg3MDgwOTAsXG4gIHNsYXRlZ3JleTogMHg3MDgwOTAsXG4gIHNub3c6IDB4ZmZmYWZhLFxuICBzcHJpbmdncmVlbjogMHgwMGZmN2YsXG4gIHN0ZWVsYmx1ZTogMHg0NjgyYjQsXG4gIHRhbjogMHhkMmI0OGMsXG4gIHRlYWw6IDB4MDA4MDgwLFxuICB0aGlzdGxlOiAweGQ4YmZkOCxcbiAgdG9tYXRvOiAweGZmNjM0NyxcbiAgdHVycXVvaXNlOiAweDQwZTBkMCxcbiAgdmlvbGV0OiAweGVlODJlZSxcbiAgd2hlYXQ6IDB4ZjVkZWIzLFxuICB3aGl0ZTogMHhmZmZmZmYsXG4gIHdoaXRlc21va2U6IDB4ZjVmNWY1LFxuICB5ZWxsb3c6IDB4ZmZmZjAwLFxuICB5ZWxsb3dncmVlbjogMHg5YWNkMzJcbn07XG5cbmRlZmluZShDb2xvciwgY29sb3IsIHtcbiAgZGlzcGxheWFibGU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnJnYigpLmRpc3BsYXlhYmxlKCk7XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5yZ2IoKSArIFwiXCI7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBjb2xvcihmb3JtYXQpIHtcbiAgdmFyIG07XG4gIGZvcm1hdCA9IChmb3JtYXQgKyBcIlwiKS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIChtID0gcmVIZXgzLmV4ZWMoZm9ybWF0KSkgPyAobSA9IHBhcnNlSW50KG1bMV0sIDE2KSwgbmV3IFJnYigobSA+PiA4ICYgMHhmKSB8IChtID4+IDQgJiAweDBmMCksIChtID4+IDQgJiAweGYpIHwgKG0gJiAweGYwKSwgKChtICYgMHhmKSA8PCA0KSB8IChtICYgMHhmKSwgMSkpIC8vICNmMDBcbiAgICAgIDogKG0gPSByZUhleDYuZXhlYyhmb3JtYXQpKSA/IHJnYm4ocGFyc2VJbnQobVsxXSwgMTYpKSAvLyAjZmYwMDAwXG4gICAgICA6IChtID0gcmVSZ2JJbnRlZ2VyLmV4ZWMoZm9ybWF0KSkgPyBuZXcgUmdiKG1bMV0sIG1bMl0sIG1bM10sIDEpIC8vIHJnYigyNTUsIDAsIDApXG4gICAgICA6IChtID0gcmVSZ2JQZXJjZW50LmV4ZWMoZm9ybWF0KSkgPyBuZXcgUmdiKG1bMV0gKiAyNTUgLyAxMDAsIG1bMl0gKiAyNTUgLyAxMDAsIG1bM10gKiAyNTUgLyAxMDAsIDEpIC8vIHJnYigxMDAlLCAwJSwgMCUpXG4gICAgICA6IChtID0gcmVSZ2JhSW50ZWdlci5leGVjKGZvcm1hdCkpID8gcmdiYShtWzFdLCBtWzJdLCBtWzNdLCBtWzRdKSAvLyByZ2JhKDI1NSwgMCwgMCwgMSlcbiAgICAgIDogKG0gPSByZVJnYmFQZXJjZW50LmV4ZWMoZm9ybWF0KSkgPyByZ2JhKG1bMV0gKiAyNTUgLyAxMDAsIG1bMl0gKiAyNTUgLyAxMDAsIG1bM10gKiAyNTUgLyAxMDAsIG1bNF0pIC8vIHJnYigxMDAlLCAwJSwgMCUsIDEpXG4gICAgICA6IChtID0gcmVIc2xQZXJjZW50LmV4ZWMoZm9ybWF0KSkgPyBoc2xhKG1bMV0sIG1bMl0gLyAxMDAsIG1bM10gLyAxMDAsIDEpIC8vIGhzbCgxMjAsIDUwJSwgNTAlKVxuICAgICAgOiAobSA9IHJlSHNsYVBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IGhzbGEobVsxXSwgbVsyXSAvIDEwMCwgbVszXSAvIDEwMCwgbVs0XSkgLy8gaHNsYSgxMjAsIDUwJSwgNTAlLCAxKVxuICAgICAgOiBuYW1lZC5oYXNPd25Qcm9wZXJ0eShmb3JtYXQpID8gcmdibihuYW1lZFtmb3JtYXRdKVxuICAgICAgOiBmb3JtYXQgPT09IFwidHJhbnNwYXJlbnRcIiA/IG5ldyBSZ2IoTmFOLCBOYU4sIE5hTiwgMClcbiAgICAgIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gcmdibihuKSB7XG4gIHJldHVybiBuZXcgUmdiKG4gPj4gMTYgJiAweGZmLCBuID4+IDggJiAweGZmLCBuICYgMHhmZiwgMSk7XG59XG5cbmZ1bmN0aW9uIHJnYmEociwgZywgYiwgYSkge1xuICBpZiAoYSA8PSAwKSByID0gZyA9IGIgPSBOYU47XG4gIHJldHVybiBuZXcgUmdiKHIsIGcsIGIsIGEpO1xufVxuXG5mdW5jdGlvbiByZ2JDb252ZXJ0KG8pIHtcbiAgaWYgKCEobyBpbnN0YW5jZW9mIENvbG9yKSkgbyA9IGNvbG9yKG8pO1xuICBpZiAoIW8pIHJldHVybiBuZXcgUmdiO1xuICBvID0gby5yZ2IoKTtcbiAgcmV0dXJuIG5ldyBSZ2Ioby5yLCBvLmcsIG8uYiwgby5vcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gcmdiKHIsIGcsIGIsIG9wYWNpdHkpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyByZ2JDb252ZXJ0KHIpIDogbmV3IFJnYihyLCBnLCBiLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIFJnYihyLCBnLCBiLCBvcGFjaXR5KSB7XG4gIHRoaXMuciA9ICtyO1xuICB0aGlzLmcgPSArZztcbiAgdGhpcy5iID0gK2I7XG4gIHRoaXMub3BhY2l0eSA9ICtvcGFjaXR5O1xufVxuXG5kZWZpbmUoUmdiLCByZ2IsIGV4dGVuZChDb2xvciwge1xuICBicmlnaHRlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBicmlnaHRlciA6IE1hdGgucG93KGJyaWdodGVyLCBrKTtcbiAgICByZXR1cm4gbmV3IFJnYih0aGlzLnIgKiBrLCB0aGlzLmcgKiBrLCB0aGlzLmIgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICBkYXJrZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gZGFya2VyIDogTWF0aC5wb3coZGFya2VyLCBrKTtcbiAgICByZXR1cm4gbmV3IFJnYih0aGlzLnIgKiBrLCB0aGlzLmcgKiBrLCB0aGlzLmIgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICByZ2I6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBkaXNwbGF5YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuICgwIDw9IHRoaXMuciAmJiB0aGlzLnIgPD0gMjU1KVxuICAgICAgICAmJiAoMCA8PSB0aGlzLmcgJiYgdGhpcy5nIDw9IDI1NSlcbiAgICAgICAgJiYgKDAgPD0gdGhpcy5iICYmIHRoaXMuYiA8PSAyNTUpXG4gICAgICAgICYmICgwIDw9IHRoaXMub3BhY2l0eSAmJiB0aGlzLm9wYWNpdHkgPD0gMSk7XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgYSA9IHRoaXMub3BhY2l0eTsgYSA9IGlzTmFOKGEpID8gMSA6IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIGEpKTtcbiAgICByZXR1cm4gKGEgPT09IDEgPyBcInJnYihcIiA6IFwicmdiYShcIilcbiAgICAgICAgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5yKSB8fCAwKSkgKyBcIiwgXCJcbiAgICAgICAgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5nKSB8fCAwKSkgKyBcIiwgXCJcbiAgICAgICAgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5iKSB8fCAwKSlcbiAgICAgICAgKyAoYSA9PT0gMSA/IFwiKVwiIDogXCIsIFwiICsgYSArIFwiKVwiKTtcbiAgfVxufSkpO1xuXG5mdW5jdGlvbiBoc2xhKGgsIHMsIGwsIGEpIHtcbiAgaWYgKGEgPD0gMCkgaCA9IHMgPSBsID0gTmFOO1xuICBlbHNlIGlmIChsIDw9IDAgfHwgbCA+PSAxKSBoID0gcyA9IE5hTjtcbiAgZWxzZSBpZiAocyA8PSAwKSBoID0gTmFOO1xuICByZXR1cm4gbmV3IEhzbChoLCBzLCBsLCBhKTtcbn1cblxuZnVuY3Rpb24gaHNsQ29udmVydChvKSB7XG4gIGlmIChvIGluc3RhbmNlb2YgSHNsKSByZXR1cm4gbmV3IEhzbChvLmgsIG8ucywgby5sLCBvLm9wYWNpdHkpO1xuICBpZiAoIShvIGluc3RhbmNlb2YgQ29sb3IpKSBvID0gY29sb3Iobyk7XG4gIGlmICghbykgcmV0dXJuIG5ldyBIc2w7XG4gIGlmIChvIGluc3RhbmNlb2YgSHNsKSByZXR1cm4gbztcbiAgbyA9IG8ucmdiKCk7XG4gIHZhciByID0gby5yIC8gMjU1LFxuICAgICAgZyA9IG8uZyAvIDI1NSxcbiAgICAgIGIgPSBvLmIgLyAyNTUsXG4gICAgICBtaW4gPSBNYXRoLm1pbihyLCBnLCBiKSxcbiAgICAgIG1heCA9IE1hdGgubWF4KHIsIGcsIGIpLFxuICAgICAgaCA9IE5hTixcbiAgICAgIHMgPSBtYXggLSBtaW4sXG4gICAgICBsID0gKG1heCArIG1pbikgLyAyO1xuICBpZiAocykge1xuICAgIGlmIChyID09PSBtYXgpIGggPSAoZyAtIGIpIC8gcyArIChnIDwgYikgKiA2O1xuICAgIGVsc2UgaWYgKGcgPT09IG1heCkgaCA9IChiIC0gcikgLyBzICsgMjtcbiAgICBlbHNlIGggPSAociAtIGcpIC8gcyArIDQ7XG4gICAgcyAvPSBsIDwgMC41ID8gbWF4ICsgbWluIDogMiAtIG1heCAtIG1pbjtcbiAgICBoICo9IDYwO1xuICB9IGVsc2Uge1xuICAgIHMgPSBsID4gMCAmJiBsIDwgMSA/IDAgOiBoO1xuICB9XG4gIHJldHVybiBuZXcgSHNsKGgsIHMsIGwsIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGhzbChoLCBzLCBsLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gaHNsQ29udmVydChoKSA6IG5ldyBIc2woaCwgcywgbCwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBIc2woaCwgcywgbCwgb3BhY2l0eSkge1xuICB0aGlzLmggPSAraDtcbiAgdGhpcy5zID0gK3M7XG4gIHRoaXMubCA9ICtsO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKEhzbCwgaHNsLCBleHRlbmQoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gYnJpZ2h0ZXIgOiBNYXRoLnBvdyhicmlnaHRlciwgayk7XG4gICAgcmV0dXJuIG5ldyBIc2wodGhpcy5oLCB0aGlzLnMsIHRoaXMubCAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBkYXJrZXIgOiBNYXRoLnBvdyhkYXJrZXIsIGspO1xuICAgIHJldHVybiBuZXcgSHNsKHRoaXMuaCwgdGhpcy5zLCB0aGlzLmwgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICByZ2I6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBoID0gdGhpcy5oICUgMzYwICsgKHRoaXMuaCA8IDApICogMzYwLFxuICAgICAgICBzID0gaXNOYU4oaCkgfHwgaXNOYU4odGhpcy5zKSA/IDAgOiB0aGlzLnMsXG4gICAgICAgIGwgPSB0aGlzLmwsXG4gICAgICAgIG0yID0gbCArIChsIDwgMC41ID8gbCA6IDEgLSBsKSAqIHMsXG4gICAgICAgIG0xID0gMiAqIGwgLSBtMjtcbiAgICByZXR1cm4gbmV3IFJnYihcbiAgICAgIGhzbDJyZ2IoaCA+PSAyNDAgPyBoIC0gMjQwIDogaCArIDEyMCwgbTEsIG0yKSxcbiAgICAgIGhzbDJyZ2IoaCwgbTEsIG0yKSxcbiAgICAgIGhzbDJyZ2IoaCA8IDEyMCA/IGggKyAyNDAgOiBoIC0gMTIwLCBtMSwgbTIpLFxuICAgICAgdGhpcy5vcGFjaXR5XG4gICAgKTtcbiAgfSxcbiAgZGlzcGxheWFibGU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAoMCA8PSB0aGlzLnMgJiYgdGhpcy5zIDw9IDEgfHwgaXNOYU4odGhpcy5zKSlcbiAgICAgICAgJiYgKDAgPD0gdGhpcy5sICYmIHRoaXMubCA8PSAxKVxuICAgICAgICAmJiAoMCA8PSB0aGlzLm9wYWNpdHkgJiYgdGhpcy5vcGFjaXR5IDw9IDEpO1xuICB9XG59KSk7XG5cbi8qIEZyb20gRnZEIDEzLjM3LCBDU1MgQ29sb3IgTW9kdWxlIExldmVsIDMgKi9cbmZ1bmN0aW9uIGhzbDJyZ2IoaCwgbTEsIG0yKSB7XG4gIHJldHVybiAoaCA8IDYwID8gbTEgKyAobTIgLSBtMSkgKiBoIC8gNjBcbiAgICAgIDogaCA8IDE4MCA/IG0yXG4gICAgICA6IGggPCAyNDAgPyBtMSArIChtMiAtIG0xKSAqICgyNDAgLSBoKSAvIDYwXG4gICAgICA6IG0xKSAqIDI1NTtcbn1cblxudmFyIGRlZzJyYWQgPSBNYXRoLlBJIC8gMTgwO1xudmFyIHJhZDJkZWcgPSAxODAgLyBNYXRoLlBJO1xuXG52YXIgS24gPSAxODtcbnZhciBYbiA9IDAuOTUwNDcwO1xudmFyIFluID0gMTtcbnZhciBabiA9IDEuMDg4ODMwO1xudmFyIHQwID0gNCAvIDI5O1xudmFyIHQxID0gNiAvIDI5O1xudmFyIHQyID0gMyAqIHQxICogdDE7XG52YXIgdDMgPSB0MSAqIHQxICogdDE7XG5cbmZ1bmN0aW9uIGxhYkNvbnZlcnQobykge1xuICBpZiAobyBpbnN0YW5jZW9mIExhYikgcmV0dXJuIG5ldyBMYWIoby5sLCBvLmEsIG8uYiwgby5vcGFjaXR5KTtcbiAgaWYgKG8gaW5zdGFuY2VvZiBIY2wpIHtcbiAgICB2YXIgaCA9IG8uaCAqIGRlZzJyYWQ7XG4gICAgcmV0dXJuIG5ldyBMYWIoby5sLCBNYXRoLmNvcyhoKSAqIG8uYywgTWF0aC5zaW4oaCkgKiBvLmMsIG8ub3BhY2l0eSk7XG4gIH1cbiAgaWYgKCEobyBpbnN0YW5jZW9mIFJnYikpIG8gPSByZ2JDb252ZXJ0KG8pO1xuICB2YXIgYiA9IHJnYjJ4eXooby5yKSxcbiAgICAgIGEgPSByZ2IyeHl6KG8uZyksXG4gICAgICBsID0gcmdiMnh5eihvLmIpLFxuICAgICAgeCA9IHh5ejJsYWIoKDAuNDEyNDU2NCAqIGIgKyAwLjM1NzU3NjEgKiBhICsgMC4xODA0Mzc1ICogbCkgLyBYbiksXG4gICAgICB5ID0geHl6MmxhYigoMC4yMTI2NzI5ICogYiArIDAuNzE1MTUyMiAqIGEgKyAwLjA3MjE3NTAgKiBsKSAvIFluKSxcbiAgICAgIHogPSB4eXoybGFiKCgwLjAxOTMzMzkgKiBiICsgMC4xMTkxOTIwICogYSArIDAuOTUwMzA0MSAqIGwpIC8gWm4pO1xuICByZXR1cm4gbmV3IExhYigxMTYgKiB5IC0gMTYsIDUwMCAqICh4IC0geSksIDIwMCAqICh5IC0geiksIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGxhYihsLCBhLCBiLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gbGFiQ29udmVydChsKSA6IG5ldyBMYWIobCwgYSwgYiwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBMYWIobCwgYSwgYiwgb3BhY2l0eSkge1xuICB0aGlzLmwgPSArbDtcbiAgdGhpcy5hID0gK2E7XG4gIHRoaXMuYiA9ICtiO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKExhYiwgbGFiLCBleHRlbmQoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHtcbiAgICByZXR1cm4gbmV3IExhYih0aGlzLmwgKyBLbiAqIChrID09IG51bGwgPyAxIDogayksIHRoaXMuYSwgdGhpcy5iLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICBkYXJrZXI6IGZ1bmN0aW9uKGspIHtcbiAgICByZXR1cm4gbmV3IExhYih0aGlzLmwgLSBLbiAqIChrID09IG51bGwgPyAxIDogayksIHRoaXMuYSwgdGhpcy5iLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICByZ2I6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB5ID0gKHRoaXMubCArIDE2KSAvIDExNixcbiAgICAgICAgeCA9IGlzTmFOKHRoaXMuYSkgPyB5IDogeSArIHRoaXMuYSAvIDUwMCxcbiAgICAgICAgeiA9IGlzTmFOKHRoaXMuYikgPyB5IDogeSAtIHRoaXMuYiAvIDIwMDtcbiAgICB5ID0gWW4gKiBsYWIyeHl6KHkpO1xuICAgIHggPSBYbiAqIGxhYjJ4eXooeCk7XG4gICAgeiA9IFpuICogbGFiMnh5eih6KTtcbiAgICByZXR1cm4gbmV3IFJnYihcbiAgICAgIHh5ejJyZ2IoIDMuMjQwNDU0MiAqIHggLSAxLjUzNzEzODUgKiB5IC0gMC40OTg1MzE0ICogeiksIC8vIEQ2NSAtPiBzUkdCXG4gICAgICB4eXoycmdiKC0wLjk2OTI2NjAgKiB4ICsgMS44NzYwMTA4ICogeSArIDAuMDQxNTU2MCAqIHopLFxuICAgICAgeHl6MnJnYiggMC4wNTU2NDM0ICogeCAtIDAuMjA0MDI1OSAqIHkgKyAxLjA1NzIyNTIgKiB6KSxcbiAgICAgIHRoaXMub3BhY2l0eVxuICAgICk7XG4gIH1cbn0pKTtcblxuZnVuY3Rpb24geHl6MmxhYih0KSB7XG4gIHJldHVybiB0ID4gdDMgPyBNYXRoLnBvdyh0LCAxIC8gMykgOiB0IC8gdDIgKyB0MDtcbn1cblxuZnVuY3Rpb24gbGFiMnh5eih0KSB7XG4gIHJldHVybiB0ID4gdDEgPyB0ICogdCAqIHQgOiB0MiAqICh0IC0gdDApO1xufVxuXG5mdW5jdGlvbiB4eXoycmdiKHgpIHtcbiAgcmV0dXJuIDI1NSAqICh4IDw9IDAuMDAzMTMwOCA/IDEyLjkyICogeCA6IDEuMDU1ICogTWF0aC5wb3coeCwgMSAvIDIuNCkgLSAwLjA1NSk7XG59XG5cbmZ1bmN0aW9uIHJnYjJ4eXooeCkge1xuICByZXR1cm4gKHggLz0gMjU1KSA8PSAwLjA0MDQ1ID8geCAvIDEyLjkyIDogTWF0aC5wb3coKHggKyAwLjA1NSkgLyAxLjA1NSwgMi40KTtcbn1cblxuZnVuY3Rpb24gaGNsQ29udmVydChvKSB7XG4gIGlmIChvIGluc3RhbmNlb2YgSGNsKSByZXR1cm4gbmV3IEhjbChvLmgsIG8uYywgby5sLCBvLm9wYWNpdHkpO1xuICBpZiAoIShvIGluc3RhbmNlb2YgTGFiKSkgbyA9IGxhYkNvbnZlcnQobyk7XG4gIHZhciBoID0gTWF0aC5hdGFuMihvLmIsIG8uYSkgKiByYWQyZGVnO1xuICByZXR1cm4gbmV3IEhjbChoIDwgMCA/IGggKyAzNjAgOiBoLCBNYXRoLnNxcnQoby5hICogby5hICsgby5iICogby5iKSwgby5sLCBvLm9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBoY2woaCwgYywgbCwgb3BhY2l0eSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IGhjbENvbnZlcnQoaCkgOiBuZXcgSGNsKGgsIGMsIGwsIG9wYWNpdHkgPT0gbnVsbCA/IDEgOiBvcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gSGNsKGgsIGMsIGwsIG9wYWNpdHkpIHtcbiAgdGhpcy5oID0gK2g7XG4gIHRoaXMuYyA9ICtjO1xuICB0aGlzLmwgPSArbDtcbiAgdGhpcy5vcGFjaXR5ID0gK29wYWNpdHk7XG59XG5cbmRlZmluZShIY2wsIGhjbCwgZXh0ZW5kKENvbG9yLCB7XG4gIGJyaWdodGVyOiBmdW5jdGlvbihrKSB7XG4gICAgcmV0dXJuIG5ldyBIY2wodGhpcy5oLCB0aGlzLmMsIHRoaXMubCArIEtuICogKGsgPT0gbnVsbCA/IDEgOiBrKSwgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgZGFya2VyOiBmdW5jdGlvbihrKSB7XG4gICAgcmV0dXJuIG5ldyBIY2wodGhpcy5oLCB0aGlzLmMsIHRoaXMubCAtIEtuICogKGsgPT0gbnVsbCA/IDEgOiBrKSwgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgcmdiOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbGFiQ29udmVydCh0aGlzKS5yZ2IoKTtcbiAgfVxufSkpO1xuXG52YXIgQSA9IC0wLjE0ODYxO1xudmFyIEIgPSArMS43ODI3NztcbnZhciBDID0gLTAuMjkyMjc7XG52YXIgRCA9IC0wLjkwNjQ5O1xudmFyIEUgPSArMS45NzI5NDtcbnZhciBFRCA9IEUgKiBEO1xudmFyIEVCID0gRSAqIEI7XG52YXIgQkNfREEgPSBCICogQyAtIEQgKiBBO1xuXG5mdW5jdGlvbiBjdWJlaGVsaXhDb252ZXJ0KG8pIHtcbiAgaWYgKG8gaW5zdGFuY2VvZiBDdWJlaGVsaXgpIHJldHVybiBuZXcgQ3ViZWhlbGl4KG8uaCwgby5zLCBvLmwsIG8ub3BhY2l0eSk7XG4gIGlmICghKG8gaW5zdGFuY2VvZiBSZ2IpKSBvID0gcmdiQ29udmVydChvKTtcbiAgdmFyIHIgPSBvLnIgLyAyNTUsXG4gICAgICBnID0gby5nIC8gMjU1LFxuICAgICAgYiA9IG8uYiAvIDI1NSxcbiAgICAgIGwgPSAoQkNfREEgKiBiICsgRUQgKiByIC0gRUIgKiBnKSAvIChCQ19EQSArIEVEIC0gRUIpLFxuICAgICAgYmwgPSBiIC0gbCxcbiAgICAgIGsgPSAoRSAqIChnIC0gbCkgLSBDICogYmwpIC8gRCxcbiAgICAgIHMgPSBNYXRoLnNxcnQoayAqIGsgKyBibCAqIGJsKSAvIChFICogbCAqICgxIC0gbCkpLCAvLyBOYU4gaWYgbD0wIG9yIGw9MVxuICAgICAgaCA9IHMgPyBNYXRoLmF0YW4yKGssIGJsKSAqIHJhZDJkZWcgLSAxMjAgOiBOYU47XG4gIHJldHVybiBuZXcgQ3ViZWhlbGl4KGggPCAwID8gaCArIDM2MCA6IGgsIHMsIGwsIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGN1YmVoZWxpeChoLCBzLCBsLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gY3ViZWhlbGl4Q29udmVydChoKSA6IG5ldyBDdWJlaGVsaXgoaCwgcywgbCwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBDdWJlaGVsaXgoaCwgcywgbCwgb3BhY2l0eSkge1xuICB0aGlzLmggPSAraDtcbiAgdGhpcy5zID0gK3M7XG4gIHRoaXMubCA9ICtsO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKEN1YmVoZWxpeCwgY3ViZWhlbGl4LCBleHRlbmQoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gYnJpZ2h0ZXIgOiBNYXRoLnBvdyhicmlnaHRlciwgayk7XG4gICAgcmV0dXJuIG5ldyBDdWJlaGVsaXgodGhpcy5oLCB0aGlzLnMsIHRoaXMubCAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBkYXJrZXIgOiBNYXRoLnBvdyhkYXJrZXIsIGspO1xuICAgIHJldHVybiBuZXcgQ3ViZWhlbGl4KHRoaXMuaCwgdGhpcy5zLCB0aGlzLmwgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICByZ2I6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBoID0gaXNOYU4odGhpcy5oKSA/IDAgOiAodGhpcy5oICsgMTIwKSAqIGRlZzJyYWQsXG4gICAgICAgIGwgPSArdGhpcy5sLFxuICAgICAgICBhID0gaXNOYU4odGhpcy5zKSA/IDAgOiB0aGlzLnMgKiBsICogKDEgLSBsKSxcbiAgICAgICAgY29zaCA9IE1hdGguY29zKGgpLFxuICAgICAgICBzaW5oID0gTWF0aC5zaW4oaCk7XG4gICAgcmV0dXJuIG5ldyBSZ2IoXG4gICAgICAyNTUgKiAobCArIGEgKiAoQSAqIGNvc2ggKyBCICogc2luaCkpLFxuICAgICAgMjU1ICogKGwgKyBhICogKEMgKiBjb3NoICsgRCAqIHNpbmgpKSxcbiAgICAgIDI1NSAqIChsICsgYSAqIChFICogY29zaCkpLFxuICAgICAgdGhpcy5vcGFjaXR5XG4gICAgKTtcbiAgfVxufSkpO1xuXG5mdW5jdGlvbiBiYXNpcyQxKHQxLCB2MCwgdjEsIHYyLCB2Mykge1xuICB2YXIgdDIgPSB0MSAqIHQxLCB0MyA9IHQyICogdDE7XG4gIHJldHVybiAoKDEgLSAzICogdDEgKyAzICogdDIgLSB0MykgKiB2MFxuICAgICAgKyAoNCAtIDYgKiB0MiArIDMgKiB0MykgKiB2MVxuICAgICAgKyAoMSArIDMgKiB0MSArIDMgKiB0MiAtIDMgKiB0MykgKiB2MlxuICAgICAgKyB0MyAqIHYzKSAvIDY7XG59XG5cbnZhciBiYXNpcyQyID0gZnVuY3Rpb24odmFsdWVzKSB7XG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGkgPSB0IDw9IDAgPyAodCA9IDApIDogdCA+PSAxID8gKHQgPSAxLCBuIC0gMSkgOiBNYXRoLmZsb29yKHQgKiBuKSxcbiAgICAgICAgdjEgPSB2YWx1ZXNbaV0sXG4gICAgICAgIHYyID0gdmFsdWVzW2kgKyAxXSxcbiAgICAgICAgdjAgPSBpID4gMCA/IHZhbHVlc1tpIC0gMV0gOiAyICogdjEgLSB2MixcbiAgICAgICAgdjMgPSBpIDwgbiAtIDEgPyB2YWx1ZXNbaSArIDJdIDogMiAqIHYyIC0gdjE7XG4gICAgcmV0dXJuIGJhc2lzJDEoKHQgLSBpIC8gbikgKiBuLCB2MCwgdjEsIHYyLCB2Myk7XG4gIH07XG59O1xuXG52YXIgYmFzaXNDbG9zZWQkMSA9IGZ1bmN0aW9uKHZhbHVlcykge1xuICB2YXIgbiA9IHZhbHVlcy5sZW5ndGg7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGkgPSBNYXRoLmZsb29yKCgodCAlPSAxKSA8IDAgPyArK3QgOiB0KSAqIG4pLFxuICAgICAgICB2MCA9IHZhbHVlc1soaSArIG4gLSAxKSAlIG5dLFxuICAgICAgICB2MSA9IHZhbHVlc1tpICUgbl0sXG4gICAgICAgIHYyID0gdmFsdWVzWyhpICsgMSkgJSBuXSxcbiAgICAgICAgdjMgPSB2YWx1ZXNbKGkgKyAyKSAlIG5dO1xuICAgIHJldHVybiBiYXNpcyQxKCh0IC0gaSAvIG4pICogbiwgdjAsIHYxLCB2MiwgdjMpO1xuICB9O1xufTtcblxudmFyIGNvbnN0YW50JDMgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIGxpbmVhciQxKGEsIGQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gYSArIHQgKiBkO1xuICB9O1xufVxuXG5mdW5jdGlvbiBleHBvbmVudGlhbCQxKGEsIGIsIHkpIHtcbiAgcmV0dXJuIGEgPSBNYXRoLnBvdyhhLCB5KSwgYiA9IE1hdGgucG93KGIsIHkpIC0gYSwgeSA9IDEgLyB5LCBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIE1hdGgucG93KGEgKyB0ICogYiwgeSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGh1ZShhLCBiKSB7XG4gIHZhciBkID0gYiAtIGE7XG4gIHJldHVybiBkID8gbGluZWFyJDEoYSwgZCA+IDE4MCB8fCBkIDwgLTE4MCA/IGQgLSAzNjAgKiBNYXRoLnJvdW5kKGQgLyAzNjApIDogZCkgOiBjb25zdGFudCQzKGlzTmFOKGEpID8gYiA6IGEpO1xufVxuXG5mdW5jdGlvbiBnYW1tYSh5KSB7XG4gIHJldHVybiAoeSA9ICt5KSA9PT0gMSA/IG5vZ2FtbWEgOiBmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGIgLSBhID8gZXhwb25lbnRpYWwkMShhLCBiLCB5KSA6IGNvbnN0YW50JDMoaXNOYU4oYSkgPyBiIDogYSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vZ2FtbWEoYSwgYikge1xuICB2YXIgZCA9IGIgLSBhO1xuICByZXR1cm4gZCA/IGxpbmVhciQxKGEsIGQpIDogY29uc3RhbnQkMyhpc05hTihhKSA/IGIgOiBhKTtcbn1cblxudmFyIGludGVycG9sYXRlUmdiID0gKGZ1bmN0aW9uIHJnYkdhbW1hKHkpIHtcbiAgdmFyIGNvbG9yJCQxID0gZ2FtbWEoeSk7XG5cbiAgZnVuY3Rpb24gcmdiJCQxKHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgciA9IGNvbG9yJCQxKChzdGFydCA9IHJnYihzdGFydCkpLnIsIChlbmQgPSByZ2IoZW5kKSkuciksXG4gICAgICAgIGcgPSBjb2xvciQkMShzdGFydC5nLCBlbmQuZyksXG4gICAgICAgIGIgPSBjb2xvciQkMShzdGFydC5iLCBlbmQuYiksXG4gICAgICAgIG9wYWNpdHkgPSBjb2xvciQkMShzdGFydC5vcGFjaXR5LCBlbmQub3BhY2l0eSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHN0YXJ0LnIgPSByKHQpO1xuICAgICAgc3RhcnQuZyA9IGcodCk7XG4gICAgICBzdGFydC5iID0gYih0KTtcbiAgICAgIHN0YXJ0Lm9wYWNpdHkgPSBvcGFjaXR5KHQpO1xuICAgICAgcmV0dXJuIHN0YXJ0ICsgXCJcIjtcbiAgICB9O1xuICB9XG5cbiAgcmdiJCQxLmdhbW1hID0gcmdiR2FtbWE7XG5cbiAgcmV0dXJuIHJnYiQkMTtcbn0pKDEpO1xuXG5mdW5jdGlvbiByZ2JTcGxpbmUoc3BsaW5lKSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xvcnMpIHtcbiAgICB2YXIgbiA9IGNvbG9ycy5sZW5ndGgsXG4gICAgICAgIHIgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIGcgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIGIgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIGksIGNvbG9yJCQxO1xuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGNvbG9yJCQxID0gcmdiKGNvbG9yc1tpXSk7XG4gICAgICByW2ldID0gY29sb3IkJDEuciB8fCAwO1xuICAgICAgZ1tpXSA9IGNvbG9yJCQxLmcgfHwgMDtcbiAgICAgIGJbaV0gPSBjb2xvciQkMS5iIHx8IDA7XG4gICAgfVxuICAgIHIgPSBzcGxpbmUocik7XG4gICAgZyA9IHNwbGluZShnKTtcbiAgICBiID0gc3BsaW5lKGIpO1xuICAgIGNvbG9yJCQxLm9wYWNpdHkgPSAxO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICBjb2xvciQkMS5yID0gcih0KTtcbiAgICAgIGNvbG9yJCQxLmcgPSBnKHQpO1xuICAgICAgY29sb3IkJDEuYiA9IGIodCk7XG4gICAgICByZXR1cm4gY29sb3IkJDEgKyBcIlwiO1xuICAgIH07XG4gIH07XG59XG5cbnZhciByZ2JCYXNpcyA9IHJnYlNwbGluZShiYXNpcyQyKTtcbnZhciByZ2JCYXNpc0Nsb3NlZCA9IHJnYlNwbGluZShiYXNpc0Nsb3NlZCQxKTtcblxudmFyIGFycmF5JDEgPSBmdW5jdGlvbihhLCBiKSB7XG4gIHZhciBuYiA9IGIgPyBiLmxlbmd0aCA6IDAsXG4gICAgICBuYSA9IGEgPyBNYXRoLm1pbihuYiwgYS5sZW5ndGgpIDogMCxcbiAgICAgIHggPSBuZXcgQXJyYXkobmIpLFxuICAgICAgYyA9IG5ldyBBcnJheShuYiksXG4gICAgICBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBuYTsgKytpKSB4W2ldID0gaW50ZXJwb2xhdGUoYVtpXSwgYltpXSk7XG4gIGZvciAoOyBpIDwgbmI7ICsraSkgY1tpXSA9IGJbaV07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbmE7ICsraSkgY1tpXSA9IHhbaV0odCk7XG4gICAgcmV0dXJuIGM7XG4gIH07XG59O1xuXG52YXIgZGF0ZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZTtcbiAgcmV0dXJuIGEgPSArYSwgYiAtPSBhLCBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIGQuc2V0VGltZShhICsgYiAqIHQpLCBkO1xuICB9O1xufTtcblxudmFyIGludGVycG9sYXRlTnVtYmVyID0gZnVuY3Rpb24oYSwgYikge1xuICByZXR1cm4gYSA9ICthLCBiIC09IGEsIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gYSArIGIgKiB0O1xuICB9O1xufTtcblxudmFyIG9iamVjdCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIGkgPSB7fSxcbiAgICAgIGMgPSB7fSxcbiAgICAgIGs7XG5cbiAgaWYgKGEgPT09IG51bGwgfHwgdHlwZW9mIGEgIT09IFwib2JqZWN0XCIpIGEgPSB7fTtcbiAgaWYgKGIgPT09IG51bGwgfHwgdHlwZW9mIGIgIT09IFwib2JqZWN0XCIpIGIgPSB7fTtcblxuICBmb3IgKGsgaW4gYikge1xuICAgIGlmIChrIGluIGEpIHtcbiAgICAgIGlba10gPSBpbnRlcnBvbGF0ZShhW2tdLCBiW2tdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY1trXSA9IGJba107XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICBmb3IgKGsgaW4gaSkgY1trXSA9IGlba10odCk7XG4gICAgcmV0dXJuIGM7XG4gIH07XG59O1xuXG52YXIgcmVBID0gL1stK10/KD86XFxkK1xcLj9cXGQqfFxcLj9cXGQrKSg/OltlRV1bLStdP1xcZCspPy9nO1xudmFyIHJlQiA9IG5ldyBSZWdFeHAocmVBLnNvdXJjZSwgXCJnXCIpO1xuXG5mdW5jdGlvbiB6ZXJvKGIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBiO1xuICB9O1xufVxuXG5mdW5jdGlvbiBvbmUoYikge1xuICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgIHJldHVybiBiKHQpICsgXCJcIjtcbiAgfTtcbn1cblxudmFyIGludGVycG9sYXRlU3RyaW5nID0gZnVuY3Rpb24oYSwgYikge1xuICB2YXIgYmkgPSByZUEubGFzdEluZGV4ID0gcmVCLmxhc3RJbmRleCA9IDAsIC8vIHNjYW4gaW5kZXggZm9yIG5leHQgbnVtYmVyIGluIGJcbiAgICAgIGFtLCAvLyBjdXJyZW50IG1hdGNoIGluIGFcbiAgICAgIGJtLCAvLyBjdXJyZW50IG1hdGNoIGluIGJcbiAgICAgIGJzLCAvLyBzdHJpbmcgcHJlY2VkaW5nIGN1cnJlbnQgbnVtYmVyIGluIGIsIGlmIGFueVxuICAgICAgaSA9IC0xLCAvLyBpbmRleCBpbiBzXG4gICAgICBzID0gW10sIC8vIHN0cmluZyBjb25zdGFudHMgYW5kIHBsYWNlaG9sZGVyc1xuICAgICAgcSA9IFtdOyAvLyBudW1iZXIgaW50ZXJwb2xhdG9yc1xuXG4gIC8vIENvZXJjZSBpbnB1dHMgdG8gc3RyaW5ncy5cbiAgYSA9IGEgKyBcIlwiLCBiID0gYiArIFwiXCI7XG5cbiAgLy8gSW50ZXJwb2xhdGUgcGFpcnMgb2YgbnVtYmVycyBpbiBhICYgYi5cbiAgd2hpbGUgKChhbSA9IHJlQS5leGVjKGEpKVxuICAgICAgJiYgKGJtID0gcmVCLmV4ZWMoYikpKSB7XG4gICAgaWYgKChicyA9IGJtLmluZGV4KSA+IGJpKSB7IC8vIGEgc3RyaW5nIHByZWNlZGVzIHRoZSBuZXh0IG51bWJlciBpbiBiXG4gICAgICBicyA9IGIuc2xpY2UoYmksIGJzKTtcbiAgICAgIGlmIChzW2ldKSBzW2ldICs9IGJzOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZ1xuICAgICAgZWxzZSBzWysraV0gPSBicztcbiAgICB9XG4gICAgaWYgKChhbSA9IGFtWzBdKSA9PT0gKGJtID0gYm1bMF0pKSB7IC8vIG51bWJlcnMgaW4gYSAmIGIgbWF0Y2hcbiAgICAgIGlmIChzW2ldKSBzW2ldICs9IGJtOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZ1xuICAgICAgZWxzZSBzWysraV0gPSBibTtcbiAgICB9IGVsc2UgeyAvLyBpbnRlcnBvbGF0ZSBub24tbWF0Y2hpbmcgbnVtYmVyc1xuICAgICAgc1srK2ldID0gbnVsbDtcbiAgICAgIHEucHVzaCh7aTogaSwgeDogaW50ZXJwb2xhdGVOdW1iZXIoYW0sIGJtKX0pO1xuICAgIH1cbiAgICBiaSA9IHJlQi5sYXN0SW5kZXg7XG4gIH1cblxuICAvLyBBZGQgcmVtYWlucyBvZiBiLlxuICBpZiAoYmkgPCBiLmxlbmd0aCkge1xuICAgIGJzID0gYi5zbGljZShiaSk7XG4gICAgaWYgKHNbaV0pIHNbaV0gKz0gYnM7IC8vIGNvYWxlc2NlIHdpdGggcHJldmlvdXMgc3RyaW5nXG4gICAgZWxzZSBzWysraV0gPSBicztcbiAgfVxuXG4gIC8vIFNwZWNpYWwgb3B0aW1pemF0aW9uIGZvciBvbmx5IGEgc2luZ2xlIG1hdGNoLlxuICAvLyBPdGhlcndpc2UsIGludGVycG9sYXRlIGVhY2ggb2YgdGhlIG51bWJlcnMgYW5kIHJlam9pbiB0aGUgc3RyaW5nLlxuICByZXR1cm4gcy5sZW5ndGggPCAyID8gKHFbMF1cbiAgICAgID8gb25lKHFbMF0ueClcbiAgICAgIDogemVybyhiKSlcbiAgICAgIDogKGIgPSBxLmxlbmd0aCwgZnVuY3Rpb24odCkge1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgYjsgKytpKSBzWyhvID0gcVtpXSkuaV0gPSBvLngodCk7XG4gICAgICAgICAgcmV0dXJuIHMuam9pbihcIlwiKTtcbiAgICAgICAgfSk7XG59O1xuXG52YXIgaW50ZXJwb2xhdGUgPSBmdW5jdGlvbihhLCBiKSB7XG4gIHZhciB0ID0gdHlwZW9mIGIsIGM7XG4gIHJldHVybiBiID09IG51bGwgfHwgdCA9PT0gXCJib29sZWFuXCIgPyBjb25zdGFudCQzKGIpXG4gICAgICA6ICh0ID09PSBcIm51bWJlclwiID8gaW50ZXJwb2xhdGVOdW1iZXJcbiAgICAgIDogdCA9PT0gXCJzdHJpbmdcIiA/ICgoYyA9IGNvbG9yKGIpKSA/IChiID0gYywgaW50ZXJwb2xhdGVSZ2IpIDogaW50ZXJwb2xhdGVTdHJpbmcpXG4gICAgICA6IGIgaW5zdGFuY2VvZiBjb2xvciA/IGludGVycG9sYXRlUmdiXG4gICAgICA6IGIgaW5zdGFuY2VvZiBEYXRlID8gZGF0ZVxuICAgICAgOiBBcnJheS5pc0FycmF5KGIpID8gYXJyYXkkMVxuICAgICAgOiBpc05hTihiKSA/IG9iamVjdFxuICAgICAgOiBpbnRlcnBvbGF0ZU51bWJlcikoYSwgYik7XG59O1xuXG52YXIgaW50ZXJwb2xhdGVSb3VuZCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGEgPSArYSwgYiAtPSBhLCBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoYSArIGIgKiB0KTtcbiAgfTtcbn07XG5cbnZhciBkZWdyZWVzID0gMTgwIC8gTWF0aC5QSTtcblxudmFyIGlkZW50aXR5JDIgPSB7XG4gIHRyYW5zbGF0ZVg6IDAsXG4gIHRyYW5zbGF0ZVk6IDAsXG4gIHJvdGF0ZTogMCxcbiAgc2tld1g6IDAsXG4gIHNjYWxlWDogMSxcbiAgc2NhbGVZOiAxXG59O1xuXG52YXIgZGVjb21wb3NlID0gZnVuY3Rpb24oYSwgYiwgYywgZCwgZSwgZikge1xuICB2YXIgc2NhbGVYLCBzY2FsZVksIHNrZXdYO1xuICBpZiAoc2NhbGVYID0gTWF0aC5zcXJ0KGEgKiBhICsgYiAqIGIpKSBhIC89IHNjYWxlWCwgYiAvPSBzY2FsZVg7XG4gIGlmIChza2V3WCA9IGEgKiBjICsgYiAqIGQpIGMgLT0gYSAqIHNrZXdYLCBkIC09IGIgKiBza2V3WDtcbiAgaWYgKHNjYWxlWSA9IE1hdGguc3FydChjICogYyArIGQgKiBkKSkgYyAvPSBzY2FsZVksIGQgLz0gc2NhbGVZLCBza2V3WCAvPSBzY2FsZVk7XG4gIGlmIChhICogZCA8IGIgKiBjKSBhID0gLWEsIGIgPSAtYiwgc2tld1ggPSAtc2tld1gsIHNjYWxlWCA9IC1zY2FsZVg7XG4gIHJldHVybiB7XG4gICAgdHJhbnNsYXRlWDogZSxcbiAgICB0cmFuc2xhdGVZOiBmLFxuICAgIHJvdGF0ZTogTWF0aC5hdGFuMihiLCBhKSAqIGRlZ3JlZXMsXG4gICAgc2tld1g6IE1hdGguYXRhbihza2V3WCkgKiBkZWdyZWVzLFxuICAgIHNjYWxlWDogc2NhbGVYLFxuICAgIHNjYWxlWTogc2NhbGVZXG4gIH07XG59O1xuXG52YXIgY3NzTm9kZTtcbnZhciBjc3NSb290O1xudmFyIGNzc1ZpZXc7XG52YXIgc3ZnTm9kZTtcblxuZnVuY3Rpb24gcGFyc2VDc3ModmFsdWUpIHtcbiAgaWYgKHZhbHVlID09PSBcIm5vbmVcIikgcmV0dXJuIGlkZW50aXR5JDI7XG4gIGlmICghY3NzTm9kZSkgY3NzTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJESVZcIiksIGNzc1Jvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIGNzc1ZpZXcgPSBkb2N1bWVudC5kZWZhdWx0VmlldztcbiAgY3NzTm9kZS5zdHlsZS50cmFuc2Zvcm0gPSB2YWx1ZTtcbiAgdmFsdWUgPSBjc3NWaWV3LmdldENvbXB1dGVkU3R5bGUoY3NzUm9vdC5hcHBlbmRDaGlsZChjc3NOb2RlKSwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShcInRyYW5zZm9ybVwiKTtcbiAgY3NzUm9vdC5yZW1vdmVDaGlsZChjc3NOb2RlKTtcbiAgdmFsdWUgPSB2YWx1ZS5zbGljZSg3LCAtMSkuc3BsaXQoXCIsXCIpO1xuICByZXR1cm4gZGVjb21wb3NlKCt2YWx1ZVswXSwgK3ZhbHVlWzFdLCArdmFsdWVbMl0sICt2YWx1ZVszXSwgK3ZhbHVlWzRdLCArdmFsdWVbNV0pO1xufVxuXG5mdW5jdGlvbiBwYXJzZVN2Zyh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIGlkZW50aXR5JDI7XG4gIGlmICghc3ZnTm9kZSkgc3ZnTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwiZ1wiKTtcbiAgc3ZnTm9kZS5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgdmFsdWUpO1xuICBpZiAoISh2YWx1ZSA9IHN2Z05vZGUudHJhbnNmb3JtLmJhc2VWYWwuY29uc29saWRhdGUoKSkpIHJldHVybiBpZGVudGl0eSQyO1xuICB2YWx1ZSA9IHZhbHVlLm1hdHJpeDtcbiAgcmV0dXJuIGRlY29tcG9zZSh2YWx1ZS5hLCB2YWx1ZS5iLCB2YWx1ZS5jLCB2YWx1ZS5kLCB2YWx1ZS5lLCB2YWx1ZS5mKTtcbn1cblxuZnVuY3Rpb24gaW50ZXJwb2xhdGVUcmFuc2Zvcm0ocGFyc2UsIHB4Q29tbWEsIHB4UGFyZW4sIGRlZ1BhcmVuKSB7XG5cbiAgZnVuY3Rpb24gcG9wKHMpIHtcbiAgICByZXR1cm4gcy5sZW5ndGggPyBzLnBvcCgpICsgXCIgXCIgOiBcIlwiO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhbnNsYXRlKHhhLCB5YSwgeGIsIHliLCBzLCBxKSB7XG4gICAgaWYgKHhhICE9PSB4YiB8fCB5YSAhPT0geWIpIHtcbiAgICAgIHZhciBpID0gcy5wdXNoKFwidHJhbnNsYXRlKFwiLCBudWxsLCBweENvbW1hLCBudWxsLCBweFBhcmVuKTtcbiAgICAgIHEucHVzaCh7aTogaSAtIDQsIHg6IGludGVycG9sYXRlTnVtYmVyKHhhLCB4Yil9LCB7aTogaSAtIDIsIHg6IGludGVycG9sYXRlTnVtYmVyKHlhLCB5Yil9KTtcbiAgICB9IGVsc2UgaWYgKHhiIHx8IHliKSB7XG4gICAgICBzLnB1c2goXCJ0cmFuc2xhdGUoXCIgKyB4YiArIHB4Q29tbWEgKyB5YiArIHB4UGFyZW4pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJvdGF0ZShhLCBiLCBzLCBxKSB7XG4gICAgaWYgKGEgIT09IGIpIHtcbiAgICAgIGlmIChhIC0gYiA+IDE4MCkgYiArPSAzNjA7IGVsc2UgaWYgKGIgLSBhID4gMTgwKSBhICs9IDM2MDsgLy8gc2hvcnRlc3QgcGF0aFxuICAgICAgcS5wdXNoKHtpOiBzLnB1c2gocG9wKHMpICsgXCJyb3RhdGUoXCIsIG51bGwsIGRlZ1BhcmVuKSAtIDIsIHg6IGludGVycG9sYXRlTnVtYmVyKGEsIGIpfSk7XG4gICAgfSBlbHNlIGlmIChiKSB7XG4gICAgICBzLnB1c2gocG9wKHMpICsgXCJyb3RhdGUoXCIgKyBiICsgZGVnUGFyZW4pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNrZXdYKGEsIGIsIHMsIHEpIHtcbiAgICBpZiAoYSAhPT0gYikge1xuICAgICAgcS5wdXNoKHtpOiBzLnB1c2gocG9wKHMpICsgXCJza2V3WChcIiwgbnVsbCwgZGVnUGFyZW4pIC0gMiwgeDogaW50ZXJwb2xhdGVOdW1iZXIoYSwgYil9KTtcbiAgICB9IGVsc2UgaWYgKGIpIHtcbiAgICAgIHMucHVzaChwb3AocykgKyBcInNrZXdYKFwiICsgYiArIGRlZ1BhcmVuKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzY2FsZSh4YSwgeWEsIHhiLCB5YiwgcywgcSkge1xuICAgIGlmICh4YSAhPT0geGIgfHwgeWEgIT09IHliKSB7XG4gICAgICB2YXIgaSA9IHMucHVzaChwb3AocykgKyBcInNjYWxlKFwiLCBudWxsLCBcIixcIiwgbnVsbCwgXCIpXCIpO1xuICAgICAgcS5wdXNoKHtpOiBpIC0gNCwgeDogaW50ZXJwb2xhdGVOdW1iZXIoeGEsIHhiKX0sIHtpOiBpIC0gMiwgeDogaW50ZXJwb2xhdGVOdW1iZXIoeWEsIHliKX0pO1xuICAgIH0gZWxzZSBpZiAoeGIgIT09IDEgfHwgeWIgIT09IDEpIHtcbiAgICAgIHMucHVzaChwb3AocykgKyBcInNjYWxlKFwiICsgeGIgKyBcIixcIiArIHliICsgXCIpXCIpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbihhLCBiKSB7XG4gICAgdmFyIHMgPSBbXSwgLy8gc3RyaW5nIGNvbnN0YW50cyBhbmQgcGxhY2Vob2xkZXJzXG4gICAgICAgIHEgPSBbXTsgLy8gbnVtYmVyIGludGVycG9sYXRvcnNcbiAgICBhID0gcGFyc2UoYSksIGIgPSBwYXJzZShiKTtcbiAgICB0cmFuc2xhdGUoYS50cmFuc2xhdGVYLCBhLnRyYW5zbGF0ZVksIGIudHJhbnNsYXRlWCwgYi50cmFuc2xhdGVZLCBzLCBxKTtcbiAgICByb3RhdGUoYS5yb3RhdGUsIGIucm90YXRlLCBzLCBxKTtcbiAgICBza2V3WChhLnNrZXdYLCBiLnNrZXdYLCBzLCBxKTtcbiAgICBzY2FsZShhLnNjYWxlWCwgYS5zY2FsZVksIGIuc2NhbGVYLCBiLnNjYWxlWSwgcywgcSk7XG4gICAgYSA9IGIgPSBudWxsOyAvLyBnY1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgaSA9IC0xLCBuID0gcS5sZW5ndGgsIG87XG4gICAgICB3aGlsZSAoKytpIDwgbikgc1sobyA9IHFbaV0pLmldID0gby54KHQpO1xuICAgICAgcmV0dXJuIHMuam9pbihcIlwiKTtcbiAgICB9O1xuICB9O1xufVxuXG52YXIgaW50ZXJwb2xhdGVUcmFuc2Zvcm1Dc3MgPSBpbnRlcnBvbGF0ZVRyYW5zZm9ybShwYXJzZUNzcywgXCJweCwgXCIsIFwicHgpXCIsIFwiZGVnKVwiKTtcbnZhciBpbnRlcnBvbGF0ZVRyYW5zZm9ybVN2ZyA9IGludGVycG9sYXRlVHJhbnNmb3JtKHBhcnNlU3ZnLCBcIiwgXCIsIFwiKVwiLCBcIilcIik7XG5cbnZhciByaG8gPSBNYXRoLlNRUlQyO1xudmFyIHJobzIgPSAyO1xudmFyIHJobzQgPSA0O1xudmFyIGVwc2lsb24yID0gMWUtMTI7XG5cbmZ1bmN0aW9uIGNvc2goeCkge1xuICByZXR1cm4gKCh4ID0gTWF0aC5leHAoeCkpICsgMSAvIHgpIC8gMjtcbn1cblxuZnVuY3Rpb24gc2luaCh4KSB7XG4gIHJldHVybiAoKHggPSBNYXRoLmV4cCh4KSkgLSAxIC8geCkgLyAyO1xufVxuXG5mdW5jdGlvbiB0YW5oKHgpIHtcbiAgcmV0dXJuICgoeCA9IE1hdGguZXhwKDIgKiB4KSkgLSAxKSAvICh4ICsgMSk7XG59XG5cbi8vIHAwID0gW3V4MCwgdXkwLCB3MF1cbi8vIHAxID0gW3V4MSwgdXkxLCB3MV1cbnZhciBpbnRlcnBvbGF0ZVpvb20gPSBmdW5jdGlvbihwMCwgcDEpIHtcbiAgdmFyIHV4MCA9IHAwWzBdLCB1eTAgPSBwMFsxXSwgdzAgPSBwMFsyXSxcbiAgICAgIHV4MSA9IHAxWzBdLCB1eTEgPSBwMVsxXSwgdzEgPSBwMVsyXSxcbiAgICAgIGR4ID0gdXgxIC0gdXgwLFxuICAgICAgZHkgPSB1eTEgLSB1eTAsXG4gICAgICBkMiA9IGR4ICogZHggKyBkeSAqIGR5LFxuICAgICAgaSxcbiAgICAgIFM7XG5cbiAgLy8gU3BlY2lhbCBjYXNlIGZvciB1MCDiiYUgdTEuXG4gIGlmIChkMiA8IGVwc2lsb24yKSB7XG4gICAgUyA9IE1hdGgubG9nKHcxIC8gdzApIC8gcmhvO1xuICAgIGkgPSBmdW5jdGlvbih0KSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB1eDAgKyB0ICogZHgsXG4gICAgICAgIHV5MCArIHQgKiBkeSxcbiAgICAgICAgdzAgKiBNYXRoLmV4cChyaG8gKiB0ICogUylcbiAgICAgIF07XG4gICAgfTtcbiAgfVxuXG4gIC8vIEdlbmVyYWwgY2FzZS5cbiAgZWxzZSB7XG4gICAgdmFyIGQxID0gTWF0aC5zcXJ0KGQyKSxcbiAgICAgICAgYjAgPSAodzEgKiB3MSAtIHcwICogdzAgKyByaG80ICogZDIpIC8gKDIgKiB3MCAqIHJobzIgKiBkMSksXG4gICAgICAgIGIxID0gKHcxICogdzEgLSB3MCAqIHcwIC0gcmhvNCAqIGQyKSAvICgyICogdzEgKiByaG8yICogZDEpLFxuICAgICAgICByMCA9IE1hdGgubG9nKE1hdGguc3FydChiMCAqIGIwICsgMSkgLSBiMCksXG4gICAgICAgIHIxID0gTWF0aC5sb2coTWF0aC5zcXJ0KGIxICogYjEgKyAxKSAtIGIxKTtcbiAgICBTID0gKHIxIC0gcjApIC8gcmhvO1xuICAgIGkgPSBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgcyA9IHQgKiBTLFxuICAgICAgICAgIGNvc2hyMCA9IGNvc2gocjApLFxuICAgICAgICAgIHUgPSB3MCAvIChyaG8yICogZDEpICogKGNvc2hyMCAqIHRhbmgocmhvICogcyArIHIwKSAtIHNpbmgocjApKTtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHV4MCArIHUgKiBkeCxcbiAgICAgICAgdXkwICsgdSAqIGR5LFxuICAgICAgICB3MCAqIGNvc2hyMCAvIGNvc2gocmhvICogcyArIHIwKVxuICAgICAgXTtcbiAgICB9O1xuICB9XG5cbiAgaS5kdXJhdGlvbiA9IFMgKiAxMDAwO1xuXG4gIHJldHVybiBpO1xufTtcblxuZnVuY3Rpb24gaHNsJDEoaHVlJCQxKSB7XG4gIHJldHVybiBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgdmFyIGggPSBodWUkJDEoKHN0YXJ0ID0gaHNsKHN0YXJ0KSkuaCwgKGVuZCA9IGhzbChlbmQpKS5oKSxcbiAgICAgICAgcyA9IG5vZ2FtbWEoc3RhcnQucywgZW5kLnMpLFxuICAgICAgICBsID0gbm9nYW1tYShzdGFydC5sLCBlbmQubCksXG4gICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgc3RhcnQuaCA9IGgodCk7XG4gICAgICBzdGFydC5zID0gcyh0KTtcbiAgICAgIHN0YXJ0LmwgPSBsKHQpO1xuICAgICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgIH07XG4gIH1cbn1cblxudmFyIGhzbCQyID0gaHNsJDEoaHVlKTtcbnZhciBoc2xMb25nID0gaHNsJDEobm9nYW1tYSk7XG5cbmZ1bmN0aW9uIGxhYiQxKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGwgPSBub2dhbW1hKChzdGFydCA9IGxhYihzdGFydCkpLmwsIChlbmQgPSBsYWIoZW5kKSkubCksXG4gICAgICBhID0gbm9nYW1tYShzdGFydC5hLCBlbmQuYSksXG4gICAgICBiID0gbm9nYW1tYShzdGFydC5iLCBlbmQuYiksXG4gICAgICBvcGFjaXR5ID0gbm9nYW1tYShzdGFydC5vcGFjaXR5LCBlbmQub3BhY2l0eSk7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgc3RhcnQubCA9IGwodCk7XG4gICAgc3RhcnQuYSA9IGEodCk7XG4gICAgc3RhcnQuYiA9IGIodCk7XG4gICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgcmV0dXJuIHN0YXJ0ICsgXCJcIjtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaGNsJDEoaHVlJCQxKSB7XG4gIHJldHVybiBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgdmFyIGggPSBodWUkJDEoKHN0YXJ0ID0gaGNsKHN0YXJ0KSkuaCwgKGVuZCA9IGhjbChlbmQpKS5oKSxcbiAgICAgICAgYyA9IG5vZ2FtbWEoc3RhcnQuYywgZW5kLmMpLFxuICAgICAgICBsID0gbm9nYW1tYShzdGFydC5sLCBlbmQubCksXG4gICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgc3RhcnQuaCA9IGgodCk7XG4gICAgICBzdGFydC5jID0gYyh0KTtcbiAgICAgIHN0YXJ0LmwgPSBsKHQpO1xuICAgICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgIH07XG4gIH1cbn1cblxudmFyIGhjbCQyID0gaGNsJDEoaHVlKTtcbnZhciBoY2xMb25nID0gaGNsJDEobm9nYW1tYSk7XG5cbmZ1bmN0aW9uIGN1YmVoZWxpeCQxKGh1ZSQkMSkge1xuICByZXR1cm4gKGZ1bmN0aW9uIGN1YmVoZWxpeEdhbW1hKHkpIHtcbiAgICB5ID0gK3k7XG5cbiAgICBmdW5jdGlvbiBjdWJlaGVsaXgkJDEoc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGggPSBodWUkJDEoKHN0YXJ0ID0gY3ViZWhlbGl4KHN0YXJ0KSkuaCwgKGVuZCA9IGN1YmVoZWxpeChlbmQpKS5oKSxcbiAgICAgICAgICBzID0gbm9nYW1tYShzdGFydC5zLCBlbmQucyksXG4gICAgICAgICAgbCA9IG5vZ2FtbWEoc3RhcnQubCwgZW5kLmwpLFxuICAgICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICAgIHN0YXJ0LmggPSBoKHQpO1xuICAgICAgICBzdGFydC5zID0gcyh0KTtcbiAgICAgICAgc3RhcnQubCA9IGwoTWF0aC5wb3codCwgeSkpO1xuICAgICAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTtcbiAgICAgICAgcmV0dXJuIHN0YXJ0ICsgXCJcIjtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY3ViZWhlbGl4JCQxLmdhbW1hID0gY3ViZWhlbGl4R2FtbWE7XG5cbiAgICByZXR1cm4gY3ViZWhlbGl4JCQxO1xuICB9KSgxKTtcbn1cblxudmFyIGN1YmVoZWxpeCQyID0gY3ViZWhlbGl4JDEoaHVlKTtcbnZhciBjdWJlaGVsaXhMb25nID0gY3ViZWhlbGl4JDEobm9nYW1tYSk7XG5cbnZhciBxdWFudGl6ZSA9IGZ1bmN0aW9uKGludGVycG9sYXRvciwgbikge1xuICB2YXIgc2FtcGxlcyA9IG5ldyBBcnJheShuKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpIHNhbXBsZXNbaV0gPSBpbnRlcnBvbGF0b3IoaSAvIChuIC0gMSkpO1xuICByZXR1cm4gc2FtcGxlcztcbn07XG5cbnZhciBub29wJDEgPSB7dmFsdWU6IGZ1bmN0aW9uKCkge319O1xuXG5mdW5jdGlvbiBkaXNwYXRjaCgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSBhcmd1bWVudHMubGVuZ3RoLCBfID0ge30sIHQ7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoISh0ID0gYXJndW1lbnRzW2ldICsgXCJcIikgfHwgKHQgaW4gXykpIHRocm93IG5ldyBFcnJvcihcImlsbGVnYWwgdHlwZTogXCIgKyB0KTtcbiAgICBfW3RdID0gW107XG4gIH1cbiAgcmV0dXJuIG5ldyBEaXNwYXRjaChfKTtcbn1cblxuZnVuY3Rpb24gRGlzcGF0Y2goXykge1xuICB0aGlzLl8gPSBfO1xufVxuXG5mdW5jdGlvbiBwYXJzZVR5cGVuYW1lcyh0eXBlbmFtZXMsIHR5cGVzKSB7XG4gIHJldHVybiB0eXBlbmFtZXMudHJpbSgpLnNwbGl0KC9efFxccysvKS5tYXAoZnVuY3Rpb24odCkge1xuICAgIHZhciBuYW1lID0gXCJcIiwgaSA9IHQuaW5kZXhPZihcIi5cIik7XG4gICAgaWYgKGkgPj0gMCkgbmFtZSA9IHQuc2xpY2UoaSArIDEpLCB0ID0gdC5zbGljZSgwLCBpKTtcbiAgICBpZiAodCAmJiAhdHlwZXMuaGFzT3duUHJvcGVydHkodCkpIHRocm93IG5ldyBFcnJvcihcInVua25vd24gdHlwZTogXCIgKyB0KTtcbiAgICByZXR1cm4ge3R5cGU6IHQsIG5hbWU6IG5hbWV9O1xuICB9KTtcbn1cblxuRGlzcGF0Y2gucHJvdG90eXBlID0gZGlzcGF0Y2gucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogRGlzcGF0Y2gsXG4gIG9uOiBmdW5jdGlvbih0eXBlbmFtZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgXyA9IHRoaXMuXyxcbiAgICAgICAgVCA9IHBhcnNlVHlwZW5hbWVzKHR5cGVuYW1lICsgXCJcIiwgXyksXG4gICAgICAgIHQsXG4gICAgICAgIGkgPSAtMSxcbiAgICAgICAgbiA9IFQubGVuZ3RoO1xuXG4gICAgLy8gSWYgbm8gY2FsbGJhY2sgd2FzIHNwZWNpZmllZCwgcmV0dXJuIHRoZSBjYWxsYmFjayBvZiB0aGUgZ2l2ZW4gdHlwZSBhbmQgbmFtZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKHQgPSAodHlwZW5hbWUgPSBUW2ldKS50eXBlKSAmJiAodCA9IGdldChfW3RdLCB0eXBlbmFtZS5uYW1lKSkpIHJldHVybiB0O1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIElmIGEgdHlwZSB3YXMgc3BlY2lmaWVkLCBzZXQgdGhlIGNhbGxiYWNrIGZvciB0aGUgZ2l2ZW4gdHlwZSBhbmQgbmFtZS5cbiAgICAvLyBPdGhlcndpc2UsIGlmIGEgbnVsbCBjYWxsYmFjayB3YXMgc3BlY2lmaWVkLCByZW1vdmUgY2FsbGJhY2tzIG9mIHRoZSBnaXZlbiBuYW1lLlxuICAgIGlmIChjYWxsYmFjayAhPSBudWxsICYmIHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGNhbGxiYWNrOiBcIiArIGNhbGxiYWNrKTtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKHQgPSAodHlwZW5hbWUgPSBUW2ldKS50eXBlKSBfW3RdID0gc2V0JDIoX1t0XSwgdHlwZW5hbWUubmFtZSwgY2FsbGJhY2spO1xuICAgICAgZWxzZSBpZiAoY2FsbGJhY2sgPT0gbnVsbCkgZm9yICh0IGluIF8pIF9bdF0gPSBzZXQkMihfW3RdLCB0eXBlbmFtZS5uYW1lLCBudWxsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgY29weTogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvcHkgPSB7fSwgXyA9IHRoaXMuXztcbiAgICBmb3IgKHZhciB0IGluIF8pIGNvcHlbdF0gPSBfW3RdLnNsaWNlKCk7XG4gICAgcmV0dXJuIG5ldyBEaXNwYXRjaChjb3B5KTtcbiAgfSxcbiAgY2FsbDogZnVuY3Rpb24odHlwZSwgdGhhdCkge1xuICAgIGlmICgobiA9IGFyZ3VtZW50cy5sZW5ndGggLSAyKSA+IDApIGZvciAodmFyIGFyZ3MgPSBuZXcgQXJyYXkobiksIGkgPSAwLCBuLCB0OyBpIDwgbjsgKytpKSBhcmdzW2ldID0gYXJndW1lbnRzW2kgKyAyXTtcbiAgICBpZiAoIXRoaXMuXy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkgdGhyb3cgbmV3IEVycm9yKFwidW5rbm93biB0eXBlOiBcIiArIHR5cGUpO1xuICAgIGZvciAodCA9IHRoaXMuX1t0eXBlXSwgaSA9IDAsIG4gPSB0Lmxlbmd0aDsgaSA8IG47ICsraSkgdFtpXS52YWx1ZS5hcHBseSh0aGF0LCBhcmdzKTtcbiAgfSxcbiAgYXBwbHk6IGZ1bmN0aW9uKHR5cGUsIHRoYXQsIGFyZ3MpIHtcbiAgICBpZiAoIXRoaXMuXy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkgdGhyb3cgbmV3IEVycm9yKFwidW5rbm93biB0eXBlOiBcIiArIHR5cGUpO1xuICAgIGZvciAodmFyIHQgPSB0aGlzLl9bdHlwZV0sIGkgPSAwLCBuID0gdC5sZW5ndGg7IGkgPCBuOyArK2kpIHRbaV0udmFsdWUuYXBwbHkodGhhdCwgYXJncyk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGdldCh0eXBlLCBuYW1lKSB7XG4gIGZvciAodmFyIGkgPSAwLCBuID0gdHlwZS5sZW5ndGgsIGM7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoKGMgPSB0eXBlW2ldKS5uYW1lID09PSBuYW1lKSB7XG4gICAgICByZXR1cm4gYy52YWx1ZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0JDIodHlwZSwgbmFtZSwgY2FsbGJhY2spIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0eXBlLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgIGlmICh0eXBlW2ldLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgIHR5cGVbaV0gPSBub29wJDEsIHR5cGUgPSB0eXBlLnNsaWNlKDAsIGkpLmNvbmNhdCh0eXBlLnNsaWNlKGkgKyAxKSk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHR5cGUucHVzaCh7bmFtZTogbmFtZSwgdmFsdWU6IGNhbGxiYWNrfSk7XG4gIHJldHVybiB0eXBlO1xufVxuXG5mdW5jdGlvbiBvYmplY3RDb252ZXJ0ZXIoY29sdW1ucykge1xuICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwiZFwiLCBcInJldHVybiB7XCIgKyBjb2x1bW5zLm1hcChmdW5jdGlvbihuYW1lLCBpKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG5hbWUpICsgXCI6IGRbXCIgKyBpICsgXCJdXCI7XG4gIH0pLmpvaW4oXCIsXCIpICsgXCJ9XCIpO1xufVxuXG5mdW5jdGlvbiBjdXN0b21Db252ZXJ0ZXIoY29sdW1ucywgZikge1xuICB2YXIgb2JqZWN0ID0gb2JqZWN0Q29udmVydGVyKGNvbHVtbnMpO1xuICByZXR1cm4gZnVuY3Rpb24ocm93LCBpKSB7XG4gICAgcmV0dXJuIGYob2JqZWN0KHJvdyksIGksIGNvbHVtbnMpO1xuICB9O1xufVxuXG4vLyBDb21wdXRlIHVuaXF1ZSBjb2x1bW5zIGluIG9yZGVyIG9mIGRpc2NvdmVyeS5cbmZ1bmN0aW9uIGluZmVyQ29sdW1ucyhyb3dzKSB7XG4gIHZhciBjb2x1bW5TZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgY29sdW1ucyA9IFtdO1xuXG4gIHJvd3MuZm9yRWFjaChmdW5jdGlvbihyb3cpIHtcbiAgICBmb3IgKHZhciBjb2x1bW4gaW4gcm93KSB7XG4gICAgICBpZiAoIShjb2x1bW4gaW4gY29sdW1uU2V0KSkge1xuICAgICAgICBjb2x1bW5zLnB1c2goY29sdW1uU2V0W2NvbHVtbl0gPSBjb2x1bW4pO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGNvbHVtbnM7XG59XG5cbnZhciBkc3YgPSBmdW5jdGlvbihkZWxpbWl0ZXIpIHtcbiAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cChcIltcXFwiXCIgKyBkZWxpbWl0ZXIgKyBcIlxcbl1cIiksXG4gICAgICBkZWxpbWl0ZXJDb2RlID0gZGVsaW1pdGVyLmNoYXJDb2RlQXQoMCk7XG5cbiAgZnVuY3Rpb24gcGFyc2UodGV4dCwgZikge1xuICAgIHZhciBjb252ZXJ0LCBjb2x1bW5zLCByb3dzID0gcGFyc2VSb3dzKHRleHQsIGZ1bmN0aW9uKHJvdywgaSkge1xuICAgICAgaWYgKGNvbnZlcnQpIHJldHVybiBjb252ZXJ0KHJvdywgaSAtIDEpO1xuICAgICAgY29sdW1ucyA9IHJvdywgY29udmVydCA9IGYgPyBjdXN0b21Db252ZXJ0ZXIocm93LCBmKSA6IG9iamVjdENvbnZlcnRlcihyb3cpO1xuICAgIH0pO1xuICAgIHJvd3MuY29sdW1ucyA9IGNvbHVtbnM7XG4gICAgcmV0dXJuIHJvd3M7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVJvd3ModGV4dCwgZikge1xuICAgIHZhciBFT0wgPSB7fSwgLy8gc2VudGluZWwgdmFsdWUgZm9yIGVuZC1vZi1saW5lXG4gICAgICAgIEVPRiA9IHt9LCAvLyBzZW50aW5lbCB2YWx1ZSBmb3IgZW5kLW9mLWZpbGVcbiAgICAgICAgcm93cyA9IFtdLCAvLyBvdXRwdXQgcm93c1xuICAgICAgICBOID0gdGV4dC5sZW5ndGgsXG4gICAgICAgIEkgPSAwLCAvLyBjdXJyZW50IGNoYXJhY3RlciBpbmRleFxuICAgICAgICBuID0gMCwgLy8gdGhlIGN1cnJlbnQgbGluZSBudW1iZXJcbiAgICAgICAgdCwgLy8gdGhlIGN1cnJlbnQgdG9rZW5cbiAgICAgICAgZW9sOyAvLyBpcyB0aGUgY3VycmVudCB0b2tlbiBmb2xsb3dlZCBieSBFT0w/XG5cbiAgICBmdW5jdGlvbiB0b2tlbigpIHtcbiAgICAgIGlmIChJID49IE4pIHJldHVybiBFT0Y7IC8vIHNwZWNpYWwgY2FzZTogZW5kIG9mIGZpbGVcbiAgICAgIGlmIChlb2wpIHJldHVybiBlb2wgPSBmYWxzZSwgRU9MOyAvLyBzcGVjaWFsIGNhc2U6IGVuZCBvZiBsaW5lXG5cbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogcXVvdGVzXG4gICAgICB2YXIgaiA9IEksIGM7XG4gICAgICBpZiAodGV4dC5jaGFyQ29kZUF0KGopID09PSAzNCkge1xuICAgICAgICB2YXIgaSA9IGo7XG4gICAgICAgIHdoaWxlIChpKysgPCBOKSB7XG4gICAgICAgICAgaWYgKHRleHQuY2hhckNvZGVBdChpKSA9PT0gMzQpIHtcbiAgICAgICAgICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoaSArIDEpICE9PSAzNCkgYnJlYWs7XG4gICAgICAgICAgICArK2k7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIEkgPSBpICsgMjtcbiAgICAgICAgYyA9IHRleHQuY2hhckNvZGVBdChpICsgMSk7XG4gICAgICAgIGlmIChjID09PSAxMykge1xuICAgICAgICAgIGVvbCA9IHRydWU7XG4gICAgICAgICAgaWYgKHRleHQuY2hhckNvZGVBdChpICsgMikgPT09IDEwKSArK0k7XG4gICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gMTApIHtcbiAgICAgICAgICBlb2wgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0ZXh0LnNsaWNlKGogKyAxLCBpKS5yZXBsYWNlKC9cIlwiL2csIFwiXFxcIlwiKTtcbiAgICAgIH1cblxuICAgICAgLy8gY29tbW9uIGNhc2U6IGZpbmQgbmV4dCBkZWxpbWl0ZXIgb3IgbmV3bGluZVxuICAgICAgd2hpbGUgKEkgPCBOKSB7XG4gICAgICAgIHZhciBrID0gMTtcbiAgICAgICAgYyA9IHRleHQuY2hhckNvZGVBdChJKyspO1xuICAgICAgICBpZiAoYyA9PT0gMTApIGVvbCA9IHRydWU7IC8vIFxcblxuICAgICAgICBlbHNlIGlmIChjID09PSAxMykgeyBlb2wgPSB0cnVlOyBpZiAodGV4dC5jaGFyQ29kZUF0KEkpID09PSAxMCkgKytJLCArK2s7IH0gLy8gXFxyfFxcclxcblxuICAgICAgICBlbHNlIGlmIChjICE9PSBkZWxpbWl0ZXJDb2RlKSBjb250aW51ZTtcbiAgICAgICAgcmV0dXJuIHRleHQuc2xpY2UoaiwgSSAtIGspO1xuICAgICAgfVxuXG4gICAgICAvLyBzcGVjaWFsIGNhc2U6IGxhc3QgdG9rZW4gYmVmb3JlIEVPRlxuICAgICAgcmV0dXJuIHRleHQuc2xpY2Uoaik7XG4gICAgfVxuXG4gICAgd2hpbGUgKCh0ID0gdG9rZW4oKSkgIT09IEVPRikge1xuICAgICAgdmFyIGEgPSBbXTtcbiAgICAgIHdoaWxlICh0ICE9PSBFT0wgJiYgdCAhPT0gRU9GKSB7XG4gICAgICAgIGEucHVzaCh0KTtcbiAgICAgICAgdCA9IHRva2VuKCk7XG4gICAgICB9XG4gICAgICBpZiAoZiAmJiAoYSA9IGYoYSwgbisrKSkgPT0gbnVsbCkgY29udGludWU7XG4gICAgICByb3dzLnB1c2goYSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJvd3M7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXQocm93cywgY29sdW1ucykge1xuICAgIGlmIChjb2x1bW5zID09IG51bGwpIGNvbHVtbnMgPSBpbmZlckNvbHVtbnMocm93cyk7XG4gICAgcmV0dXJuIFtjb2x1bW5zLm1hcChmb3JtYXRWYWx1ZSkuam9pbihkZWxpbWl0ZXIpXS5jb25jYXQocm93cy5tYXAoZnVuY3Rpb24ocm93KSB7XG4gICAgICByZXR1cm4gY29sdW1ucy5tYXAoZnVuY3Rpb24oY29sdW1uKSB7XG4gICAgICAgIHJldHVybiBmb3JtYXRWYWx1ZShyb3dbY29sdW1uXSk7XG4gICAgICB9KS5qb2luKGRlbGltaXRlcik7XG4gICAgfSkpLmpvaW4oXCJcXG5cIik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRSb3dzKHJvd3MpIHtcbiAgICByZXR1cm4gcm93cy5tYXAoZm9ybWF0Um93KS5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0Um93KHJvdykge1xuICAgIHJldHVybiByb3cubWFwKGZvcm1hdFZhbHVlKS5qb2luKGRlbGltaXRlcik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRWYWx1ZSh0ZXh0KSB7XG4gICAgcmV0dXJuIHRleHQgPT0gbnVsbCA/IFwiXCJcbiAgICAgICAgOiByZUZvcm1hdC50ZXN0KHRleHQgKz0gXCJcIikgPyBcIlxcXCJcIiArIHRleHQucmVwbGFjZSgvXFxcIi9nLCBcIlxcXCJcXFwiXCIpICsgXCJcXFwiXCJcbiAgICAgICAgOiB0ZXh0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwYXJzZTogcGFyc2UsXG4gICAgcGFyc2VSb3dzOiBwYXJzZVJvd3MsXG4gICAgZm9ybWF0OiBmb3JtYXQsXG4gICAgZm9ybWF0Um93czogZm9ybWF0Um93c1xuICB9O1xufTtcblxudmFyIGNzdiA9IGRzdihcIixcIik7XG5cbnZhciBjc3ZQYXJzZSA9IGNzdi5wYXJzZTtcbnZhciBjc3ZQYXJzZVJvd3MgPSBjc3YucGFyc2VSb3dzO1xudmFyIGNzdkZvcm1hdCA9IGNzdi5mb3JtYXQ7XG52YXIgY3N2Rm9ybWF0Um93cyA9IGNzdi5mb3JtYXRSb3dzO1xuXG52YXIgdHN2ID0gZHN2KFwiXFx0XCIpO1xuXG52YXIgdHN2UGFyc2UgPSB0c3YucGFyc2U7XG52YXIgdHN2UGFyc2VSb3dzID0gdHN2LnBhcnNlUm93cztcbnZhciB0c3ZGb3JtYXQgPSB0c3YuZm9ybWF0O1xudmFyIHRzdkZvcm1hdFJvd3MgPSB0c3YuZm9ybWF0Um93cztcblxudmFyIHJlcXVlc3QgPSBmdW5jdGlvbih1cmwsIGNhbGxiYWNrKSB7XG4gIHZhciByZXF1ZXN0LFxuICAgICAgZXZlbnQgPSBkaXNwYXRjaChcImJlZm9yZXNlbmRcIiwgXCJwcm9ncmVzc1wiLCBcImxvYWRcIiwgXCJlcnJvclwiKSxcbiAgICAgIG1pbWVUeXBlLFxuICAgICAgaGVhZGVycyA9IG1hcCQxKCksXG4gICAgICB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QsXG4gICAgICB1c2VyID0gbnVsbCxcbiAgICAgIHBhc3N3b3JkID0gbnVsbCxcbiAgICAgIHJlc3BvbnNlLFxuICAgICAgcmVzcG9uc2VUeXBlLFxuICAgICAgdGltZW91dCA9IDA7XG5cbiAgLy8gSWYgSUUgZG9lcyBub3Qgc3VwcG9ydCBDT1JTLCB1c2UgWERvbWFpblJlcXVlc3QuXG4gIGlmICh0eXBlb2YgWERvbWFpblJlcXVlc3QgIT09IFwidW5kZWZpbmVkXCJcbiAgICAgICYmICEoXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHIpXG4gICAgICAmJiAvXihodHRwKHMpPzopP1xcL1xcLy8udGVzdCh1cmwpKSB4aHIgPSBuZXcgWERvbWFpblJlcXVlc3Q7XG5cbiAgXCJvbmxvYWRcIiBpbiB4aHJcbiAgICAgID8geGhyLm9ubG9hZCA9IHhoci5vbmVycm9yID0geGhyLm9udGltZW91dCA9IHJlc3BvbmRcbiAgICAgIDogeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKG8pIHsgeGhyLnJlYWR5U3RhdGUgPiAzICYmIHJlc3BvbmQobyk7IH07XG5cbiAgZnVuY3Rpb24gcmVzcG9uZChvKSB7XG4gICAgdmFyIHN0YXR1cyA9IHhoci5zdGF0dXMsIHJlc3VsdDtcbiAgICBpZiAoIXN0YXR1cyAmJiBoYXNSZXNwb25zZSh4aHIpXG4gICAgICAgIHx8IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwXG4gICAgICAgIHx8IHN0YXR1cyA9PT0gMzA0KSB7XG4gICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXN1bHQgPSByZXNwb25zZS5jYWxsKHJlcXVlc3QsIHhocik7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBldmVudC5jYWxsKFwiZXJyb3JcIiwgcmVxdWVzdCwgZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSB4aHI7XG4gICAgICB9XG4gICAgICBldmVudC5jYWxsKFwibG9hZFwiLCByZXF1ZXN0LCByZXN1bHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBldmVudC5jYWxsKFwiZXJyb3JcIiwgcmVxdWVzdCwgbyk7XG4gICAgfVxuICB9XG5cbiAgeGhyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbihlKSB7XG4gICAgZXZlbnQuY2FsbChcInByb2dyZXNzXCIsIHJlcXVlc3QsIGUpO1xuICB9O1xuXG4gIHJlcXVlc3QgPSB7XG4gICAgaGVhZGVyOiBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgbmFtZSA9IChuYW1lICsgXCJcIikudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikgcmV0dXJuIGhlYWRlcnMuZ2V0KG5hbWUpO1xuICAgICAgaWYgKHZhbHVlID09IG51bGwpIGhlYWRlcnMucmVtb3ZlKG5hbWUpO1xuICAgICAgZWxzZSBoZWFkZXJzLnNldChuYW1lLCB2YWx1ZSArIFwiXCIpO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfSxcblxuICAgIC8vIElmIG1pbWVUeXBlIGlzIG5vbi1udWxsIGFuZCBubyBBY2NlcHQgaGVhZGVyIGlzIHNldCwgYSBkZWZhdWx0IGlzIHVzZWQuXG4gICAgbWltZVR5cGU6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBtaW1lVHlwZTtcbiAgICAgIG1pbWVUeXBlID0gdmFsdWUgPT0gbnVsbCA/IG51bGwgOiB2YWx1ZSArIFwiXCI7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgLy8gU3BlY2lmaWVzIHdoYXQgdHlwZSB0aGUgcmVzcG9uc2UgdmFsdWUgc2hvdWxkIHRha2U7XG4gICAgLy8gZm9yIGluc3RhbmNlLCBhcnJheWJ1ZmZlciwgYmxvYiwgZG9jdW1lbnQsIG9yIHRleHQuXG4gICAgcmVzcG9uc2VUeXBlOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcmVzcG9uc2VUeXBlO1xuICAgICAgcmVzcG9uc2VUeXBlID0gdmFsdWU7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgdGltZW91dDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRpbWVvdXQ7XG4gICAgICB0aW1lb3V0ID0gK3ZhbHVlO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfSxcblxuICAgIHVzZXI6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA8IDEgPyB1c2VyIDogKHVzZXIgPSB2YWx1ZSA9PSBudWxsID8gbnVsbCA6IHZhbHVlICsgXCJcIiwgcmVxdWVzdCk7XG4gICAgfSxcblxuICAgIHBhc3N3b3JkOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPCAxID8gcGFzc3dvcmQgOiAocGFzc3dvcmQgPSB2YWx1ZSA9PSBudWxsID8gbnVsbCA6IHZhbHVlICsgXCJcIiwgcmVxdWVzdCk7XG4gICAgfSxcblxuICAgIC8vIFNwZWNpZnkgaG93IHRvIGNvbnZlcnQgdGhlIHJlc3BvbnNlIGNvbnRlbnQgdG8gYSBzcGVjaWZpYyB0eXBlO1xuICAgIC8vIGNoYW5nZXMgdGhlIGNhbGxiYWNrIHZhbHVlIG9uIFwibG9hZFwiIGV2ZW50cy5cbiAgICByZXNwb25zZTogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJlc3BvbnNlID0gdmFsdWU7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgLy8gQWxpYXMgZm9yIHNlbmQoXCJHRVRcIiwg4oCmKS5cbiAgICBnZXQ6IGZ1bmN0aW9uKGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgICByZXR1cm4gcmVxdWVzdC5zZW5kKFwiR0VUXCIsIGRhdGEsIGNhbGxiYWNrKTtcbiAgICB9LFxuXG4gICAgLy8gQWxpYXMgZm9yIHNlbmQoXCJQT1NUXCIsIOKApikuXG4gICAgcG9zdDogZnVuY3Rpb24oZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgIHJldHVybiByZXF1ZXN0LnNlbmQoXCJQT1NUXCIsIGRhdGEsIGNhbGxiYWNrKTtcbiAgICB9LFxuXG4gICAgLy8gSWYgY2FsbGJhY2sgaXMgbm9uLW51bGwsIGl0IHdpbGwgYmUgdXNlZCBmb3IgZXJyb3IgYW5kIGxvYWQgZXZlbnRzLlxuICAgIHNlbmQ6IGZ1bmN0aW9uKG1ldGhvZCwgZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgIHhoci5vcGVuKG1ldGhvZCwgdXJsLCB0cnVlLCB1c2VyLCBwYXNzd29yZCk7XG4gICAgICBpZiAobWltZVR5cGUgIT0gbnVsbCAmJiAhaGVhZGVycy5oYXMoXCJhY2NlcHRcIikpIGhlYWRlcnMuc2V0KFwiYWNjZXB0XCIsIG1pbWVUeXBlICsgXCIsKi8qXCIpO1xuICAgICAgaWYgKHhoci5zZXRSZXF1ZXN0SGVhZGVyKSBoZWFkZXJzLmVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHsgeGhyLnNldFJlcXVlc3RIZWFkZXIobmFtZSwgdmFsdWUpOyB9KTtcbiAgICAgIGlmIChtaW1lVHlwZSAhPSBudWxsICYmIHhoci5vdmVycmlkZU1pbWVUeXBlKSB4aHIub3ZlcnJpZGVNaW1lVHlwZShtaW1lVHlwZSk7XG4gICAgICBpZiAocmVzcG9uc2VUeXBlICE9IG51bGwpIHhoci5yZXNwb25zZVR5cGUgPSByZXNwb25zZVR5cGU7XG4gICAgICBpZiAodGltZW91dCA+IDApIHhoci50aW1lb3V0ID0gdGltZW91dDtcbiAgICAgIGlmIChjYWxsYmFjayA9PSBudWxsICYmIHR5cGVvZiBkYXRhID09PSBcImZ1bmN0aW9uXCIpIGNhbGxiYWNrID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gICAgICBpZiAoY2FsbGJhY2sgIT0gbnVsbCAmJiBjYWxsYmFjay5sZW5ndGggPT09IDEpIGNhbGxiYWNrID0gZml4Q2FsbGJhY2soY2FsbGJhY2spO1xuICAgICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHJlcXVlc3Qub24oXCJlcnJvclwiLCBjYWxsYmFjaykub24oXCJsb2FkXCIsIGZ1bmN0aW9uKHhocikgeyBjYWxsYmFjayhudWxsLCB4aHIpOyB9KTtcbiAgICAgIGV2ZW50LmNhbGwoXCJiZWZvcmVzZW5kXCIsIHJlcXVlc3QsIHhocik7XG4gICAgICB4aHIuc2VuZChkYXRhID09IG51bGwgPyBudWxsIDogZGF0YSk7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgYWJvcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgeGhyLmFib3J0KCk7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgb246IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHZhbHVlID0gZXZlbnQub24uYXBwbHkoZXZlbnQsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IGV2ZW50ID8gcmVxdWVzdCA6IHZhbHVlO1xuICAgIH1cbiAgfTtcblxuICBpZiAoY2FsbGJhY2sgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBjYWxsYmFjazogXCIgKyBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHJlcXVlc3QuZ2V0KGNhbGxiYWNrKTtcbiAgfVxuXG4gIHJldHVybiByZXF1ZXN0O1xufTtcblxuZnVuY3Rpb24gZml4Q2FsbGJhY2soY2FsbGJhY2spIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGVycm9yLCB4aHIpIHtcbiAgICBjYWxsYmFjayhlcnJvciA9PSBudWxsID8geGhyIDogbnVsbCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGhhc1Jlc3BvbnNlKHhocikge1xuICB2YXIgdHlwZSA9IHhoci5yZXNwb25zZVR5cGU7XG4gIHJldHVybiB0eXBlICYmIHR5cGUgIT09IFwidGV4dFwiXG4gICAgICA/IHhoci5yZXNwb25zZSAvLyBudWxsIG9uIGVycm9yXG4gICAgICA6IHhoci5yZXNwb25zZVRleHQ7IC8vIFwiXCIgb24gZXJyb3Jcbn1cblxudmFyIHR5cGUgPSBmdW5jdGlvbihkZWZhdWx0TWltZVR5cGUsIHJlc3BvbnNlKSB7XG4gIHJldHVybiBmdW5jdGlvbih1cmwsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHIgPSByZXF1ZXN0KHVybCkubWltZVR5cGUoZGVmYXVsdE1pbWVUeXBlKS5yZXNwb25zZShyZXNwb25zZSk7XG4gICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHtcbiAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBjYWxsYmFjazogXCIgKyBjYWxsYmFjayk7XG4gICAgICByZXR1cm4gci5nZXQoY2FsbGJhY2spO1xuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfTtcbn07XG5cbnZhciBodG1sID0gdHlwZShcInRleHQvaHRtbFwiLCBmdW5jdGlvbih4aHIpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVJhbmdlKCkuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KHhoci5yZXNwb25zZVRleHQpO1xufSk7XG5cbnZhciBqc29uID0gdHlwZShcImFwcGxpY2F0aW9uL2pzb25cIiwgZnVuY3Rpb24oeGhyKSB7XG4gIHJldHVybiBKU09OLnBhcnNlKHhoci5yZXNwb25zZVRleHQpO1xufSk7XG5cbnZhciB0ZXh0ID0gdHlwZShcInRleHQvcGxhaW5cIiwgZnVuY3Rpb24oeGhyKSB7XG4gIHJldHVybiB4aHIucmVzcG9uc2VUZXh0O1xufSk7XG5cbnZhciB4bWwgPSB0eXBlKFwiYXBwbGljYXRpb24veG1sXCIsIGZ1bmN0aW9uKHhocikge1xuICB2YXIgeG1sID0geGhyLnJlc3BvbnNlWE1MO1xuICBpZiAoIXhtbCkgdGhyb3cgbmV3IEVycm9yKFwicGFyc2UgZXJyb3JcIik7XG4gIHJldHVybiB4bWw7XG59KTtcblxudmFyIGRzdiQxID0gZnVuY3Rpb24oZGVmYXVsdE1pbWVUeXBlLCBwYXJzZSkge1xuICByZXR1cm4gZnVuY3Rpb24odXJsLCByb3csIGNhbGxiYWNrKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSBjYWxsYmFjayA9IHJvdywgcm93ID0gbnVsbDtcbiAgICB2YXIgciA9IHJlcXVlc3QodXJsKS5taW1lVHlwZShkZWZhdWx0TWltZVR5cGUpO1xuICAgIHIucm93ID0gZnVuY3Rpb24oXykgeyByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHIucmVzcG9uc2UocmVzcG9uc2VPZihwYXJzZSwgcm93ID0gXykpIDogcm93OyB9O1xuICAgIHIucm93KHJvdyk7XG4gICAgcmV0dXJuIGNhbGxiYWNrID8gci5nZXQoY2FsbGJhY2spIDogcjtcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIHJlc3BvbnNlT2YocGFyc2UsIHJvdykge1xuICByZXR1cm4gZnVuY3Rpb24ocmVxdWVzdCQkMSkge1xuICAgIHJldHVybiBwYXJzZShyZXF1ZXN0JCQxLnJlc3BvbnNlVGV4dCwgcm93KTtcbiAgfTtcbn1cblxudmFyIGNzdiQxID0gZHN2JDEoXCJ0ZXh0L2NzdlwiLCBjc3ZQYXJzZSk7XG5cbnZhciB0c3YkMSA9IGRzdiQxKFwidGV4dC90YWItc2VwYXJhdGVkLXZhbHVlc1wiLCB0c3ZQYXJzZSk7XG5cbnZhciBmcmFtZSA9IDA7XG52YXIgdGltZW91dCA9IDA7XG52YXIgaW50ZXJ2YWwgPSAwO1xudmFyIHBva2VEZWxheSA9IDEwMDA7XG52YXIgdGFza0hlYWQ7XG52YXIgdGFza1RhaWw7XG52YXIgY2xvY2tMYXN0ID0gMDtcbnZhciBjbG9ja05vdyA9IDA7XG52YXIgY2xvY2tTa2V3ID0gMDtcbnZhciBjbG9jayA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gXCJvYmplY3RcIiAmJiBwZXJmb3JtYW5jZS5ub3cgPyBwZXJmb3JtYW5jZSA6IERhdGU7XG52YXIgc2V0RnJhbWUgPSB0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSBcImZ1bmN0aW9uXCIgPyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgOiBmdW5jdGlvbihmKSB7IHNldFRpbWVvdXQoZiwgMTcpOyB9O1xuXG5mdW5jdGlvbiBub3coKSB7XG4gIHJldHVybiBjbG9ja05vdyB8fCAoc2V0RnJhbWUoY2xlYXJOb3cpLCBjbG9ja05vdyA9IGNsb2NrLm5vdygpICsgY2xvY2tTa2V3KTtcbn1cblxuZnVuY3Rpb24gY2xlYXJOb3coKSB7XG4gIGNsb2NrTm93ID0gMDtcbn1cblxuZnVuY3Rpb24gVGltZXIoKSB7XG4gIHRoaXMuX2NhbGwgPVxuICB0aGlzLl90aW1lID1cbiAgdGhpcy5fbmV4dCA9IG51bGw7XG59XG5cblRpbWVyLnByb3RvdHlwZSA9IHRpbWVyLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFRpbWVyLFxuICByZXN0YXJ0OiBmdW5jdGlvbihjYWxsYmFjaywgZGVsYXksIHRpbWUpIHtcbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYWxsYmFjayBpcyBub3QgYSBmdW5jdGlvblwiKTtcbiAgICB0aW1lID0gKHRpbWUgPT0gbnVsbCA/IG5vdygpIDogK3RpbWUpICsgKGRlbGF5ID09IG51bGwgPyAwIDogK2RlbGF5KTtcbiAgICBpZiAoIXRoaXMuX25leHQgJiYgdGFza1RhaWwgIT09IHRoaXMpIHtcbiAgICAgIGlmICh0YXNrVGFpbCkgdGFza1RhaWwuX25leHQgPSB0aGlzO1xuICAgICAgZWxzZSB0YXNrSGVhZCA9IHRoaXM7XG4gICAgICB0YXNrVGFpbCA9IHRoaXM7XG4gICAgfVxuICAgIHRoaXMuX2NhbGwgPSBjYWxsYmFjaztcbiAgICB0aGlzLl90aW1lID0gdGltZTtcbiAgICBzbGVlcCgpO1xuICB9LFxuICBzdG9wOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fY2FsbCkge1xuICAgICAgdGhpcy5fY2FsbCA9IG51bGw7XG4gICAgICB0aGlzLl90aW1lID0gSW5maW5pdHk7XG4gICAgICBzbGVlcCgpO1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gdGltZXIoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSB7XG4gIHZhciB0ID0gbmV3IFRpbWVyO1xuICB0LnJlc3RhcnQoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKTtcbiAgcmV0dXJuIHQ7XG59XG5cbmZ1bmN0aW9uIHRpbWVyRmx1c2goKSB7XG4gIG5vdygpOyAvLyBHZXQgdGhlIGN1cnJlbnQgdGltZSwgaWYgbm90IGFscmVhZHkgc2V0LlxuICArK2ZyYW1lOyAvLyBQcmV0ZW5kIHdl4oCZdmUgc2V0IGFuIGFsYXJtLCBpZiB3ZSBoYXZlbuKAmXQgYWxyZWFkeS5cbiAgdmFyIHQgPSB0YXNrSGVhZCwgZTtcbiAgd2hpbGUgKHQpIHtcbiAgICBpZiAoKGUgPSBjbG9ja05vdyAtIHQuX3RpbWUpID49IDApIHQuX2NhbGwuY2FsbChudWxsLCBlKTtcbiAgICB0ID0gdC5fbmV4dDtcbiAgfVxuICAtLWZyYW1lO1xufVxuXG5mdW5jdGlvbiB3YWtlKCkge1xuICBjbG9ja05vdyA9IChjbG9ja0xhc3QgPSBjbG9jay5ub3coKSkgKyBjbG9ja1NrZXc7XG4gIGZyYW1lID0gdGltZW91dCA9IDA7XG4gIHRyeSB7XG4gICAgdGltZXJGbHVzaCgpO1xuICB9IGZpbmFsbHkge1xuICAgIGZyYW1lID0gMDtcbiAgICBuYXAoKTtcbiAgICBjbG9ja05vdyA9IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gcG9rZSQxKCkge1xuICB2YXIgbm93ID0gY2xvY2subm93KCksIGRlbGF5ID0gbm93IC0gY2xvY2tMYXN0O1xuICBpZiAoZGVsYXkgPiBwb2tlRGVsYXkpIGNsb2NrU2tldyAtPSBkZWxheSwgY2xvY2tMYXN0ID0gbm93O1xufVxuXG5mdW5jdGlvbiBuYXAoKSB7XG4gIHZhciB0MCwgdDEgPSB0YXNrSGVhZCwgdDIsIHRpbWUgPSBJbmZpbml0eTtcbiAgd2hpbGUgKHQxKSB7XG4gICAgaWYgKHQxLl9jYWxsKSB7XG4gICAgICBpZiAodGltZSA+IHQxLl90aW1lKSB0aW1lID0gdDEuX3RpbWU7XG4gICAgICB0MCA9IHQxLCB0MSA9IHQxLl9uZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0MiA9IHQxLl9uZXh0LCB0MS5fbmV4dCA9IG51bGw7XG4gICAgICB0MSA9IHQwID8gdDAuX25leHQgPSB0MiA6IHRhc2tIZWFkID0gdDI7XG4gICAgfVxuICB9XG4gIHRhc2tUYWlsID0gdDA7XG4gIHNsZWVwKHRpbWUpO1xufVxuXG5mdW5jdGlvbiBzbGVlcCh0aW1lKSB7XG4gIGlmIChmcmFtZSkgcmV0dXJuOyAvLyBTb29uZXN0IGFsYXJtIGFscmVhZHkgc2V0LCBvciB3aWxsIGJlLlxuICBpZiAodGltZW91dCkgdGltZW91dCA9IGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgdmFyIGRlbGF5ID0gdGltZSAtIGNsb2NrTm93O1xuICBpZiAoZGVsYXkgPiAyNCkge1xuICAgIGlmICh0aW1lIDwgSW5maW5pdHkpIHRpbWVvdXQgPSBzZXRUaW1lb3V0KHdha2UsIGRlbGF5KTtcbiAgICBpZiAoaW50ZXJ2YWwpIGludGVydmFsID0gY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFpbnRlcnZhbCkgaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChwb2tlJDEsIHBva2VEZWxheSk7XG4gICAgZnJhbWUgPSAxLCBzZXRGcmFtZSh3YWtlKTtcbiAgfVxufVxuXG52YXIgdGltZW91dCQxID0gZnVuY3Rpb24oY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSB7XG4gIHZhciB0ID0gbmV3IFRpbWVyO1xuICBkZWxheSA9IGRlbGF5ID09IG51bGwgPyAwIDogK2RlbGF5O1xuICB0LnJlc3RhcnQoZnVuY3Rpb24oZWxhcHNlZCkge1xuICAgIHQuc3RvcCgpO1xuICAgIGNhbGxiYWNrKGVsYXBzZWQgKyBkZWxheSk7XG4gIH0sIGRlbGF5LCB0aW1lKTtcbiAgcmV0dXJuIHQ7XG59O1xuXG52YXIgaW50ZXJ2YWwkMSA9IGZ1bmN0aW9uKGNhbGxiYWNrLCBkZWxheSwgdGltZSkge1xuICB2YXIgdCA9IG5ldyBUaW1lciwgdG90YWwgPSBkZWxheTtcbiAgaWYgKGRlbGF5ID09IG51bGwpIHJldHVybiB0LnJlc3RhcnQoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSwgdDtcbiAgZGVsYXkgPSArZGVsYXksIHRpbWUgPSB0aW1lID09IG51bGwgPyBub3coKSA6ICt0aW1lO1xuICB0LnJlc3RhcnQoZnVuY3Rpb24gdGljayhlbGFwc2VkKSB7XG4gICAgZWxhcHNlZCArPSB0b3RhbDtcbiAgICB0LnJlc3RhcnQodGljaywgdG90YWwgKz0gZGVsYXksIHRpbWUpO1xuICAgIGNhbGxiYWNrKGVsYXBzZWQpO1xuICB9LCBkZWxheSwgdGltZSk7XG4gIHJldHVybiB0O1xufTtcblxudmFyIHQwJDEgPSBuZXcgRGF0ZTtcbnZhciB0MSQxID0gbmV3IERhdGU7XG5cbmZ1bmN0aW9uIG5ld0ludGVydmFsKGZsb29yaSwgb2Zmc2V0aSwgY291bnQsIGZpZWxkKSB7XG5cbiAgZnVuY3Rpb24gaW50ZXJ2YWwoZGF0ZSkge1xuICAgIHJldHVybiBmbG9vcmkoZGF0ZSA9IG5ldyBEYXRlKCtkYXRlKSksIGRhdGU7XG4gIH1cblxuICBpbnRlcnZhbC5mbG9vciA9IGludGVydmFsO1xuXG4gIGludGVydmFsLmNlaWwgPSBmdW5jdGlvbihkYXRlKSB7XG4gICAgcmV0dXJuIGZsb29yaShkYXRlID0gbmV3IERhdGUoZGF0ZSAtIDEpKSwgb2Zmc2V0aShkYXRlLCAxKSwgZmxvb3JpKGRhdGUpLCBkYXRlO1xuICB9O1xuXG4gIGludGVydmFsLnJvdW5kID0gZnVuY3Rpb24oZGF0ZSkge1xuICAgIHZhciBkMCA9IGludGVydmFsKGRhdGUpLFxuICAgICAgICBkMSA9IGludGVydmFsLmNlaWwoZGF0ZSk7XG4gICAgcmV0dXJuIGRhdGUgLSBkMCA8IGQxIC0gZGF0ZSA/IGQwIDogZDE7XG4gIH07XG5cbiAgaW50ZXJ2YWwub2Zmc2V0ID0gZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIHJldHVybiBvZmZzZXRpKGRhdGUgPSBuZXcgRGF0ZSgrZGF0ZSksIHN0ZXAgPT0gbnVsbCA/IDEgOiBNYXRoLmZsb29yKHN0ZXApKSwgZGF0ZTtcbiAgfTtcblxuICBpbnRlcnZhbC5yYW5nZSA9IGZ1bmN0aW9uKHN0YXJ0LCBzdG9wLCBzdGVwKSB7XG4gICAgdmFyIHJhbmdlID0gW107XG4gICAgc3RhcnQgPSBpbnRlcnZhbC5jZWlsKHN0YXJ0KTtcbiAgICBzdGVwID0gc3RlcCA9PSBudWxsID8gMSA6IE1hdGguZmxvb3Ioc3RlcCk7XG4gICAgaWYgKCEoc3RhcnQgPCBzdG9wKSB8fCAhKHN0ZXAgPiAwKSkgcmV0dXJuIHJhbmdlOyAvLyBhbHNvIGhhbmRsZXMgSW52YWxpZCBEYXRlXG4gICAgZG8gcmFuZ2UucHVzaChuZXcgRGF0ZSgrc3RhcnQpKTsgd2hpbGUgKG9mZnNldGkoc3RhcnQsIHN0ZXApLCBmbG9vcmkoc3RhcnQpLCBzdGFydCA8IHN0b3ApXG4gICAgcmV0dXJuIHJhbmdlO1xuICB9O1xuXG4gIGludGVydmFsLmZpbHRlciA9IGZ1bmN0aW9uKHRlc3QpIHtcbiAgICByZXR1cm4gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgICAgaWYgKGRhdGUgPj0gZGF0ZSkgd2hpbGUgKGZsb29yaShkYXRlKSwgIXRlc3QoZGF0ZSkpIGRhdGUuc2V0VGltZShkYXRlIC0gMSk7XG4gICAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgICAgaWYgKGRhdGUgPj0gZGF0ZSkgd2hpbGUgKC0tc3RlcCA+PSAwKSB3aGlsZSAob2Zmc2V0aShkYXRlLCAxKSwgIXRlc3QoZGF0ZSkpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZW1wdHlcbiAgICB9KTtcbiAgfTtcblxuICBpZiAoY291bnQpIHtcbiAgICBpbnRlcnZhbC5jb3VudCA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICAgIHQwJDEuc2V0VGltZSgrc3RhcnQpLCB0MSQxLnNldFRpbWUoK2VuZCk7XG4gICAgICBmbG9vcmkodDAkMSksIGZsb29yaSh0MSQxKTtcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKGNvdW50KHQwJDEsIHQxJDEpKTtcbiAgICB9O1xuXG4gICAgaW50ZXJ2YWwuZXZlcnkgPSBmdW5jdGlvbihzdGVwKSB7XG4gICAgICBzdGVwID0gTWF0aC5mbG9vcihzdGVwKTtcbiAgICAgIHJldHVybiAhaXNGaW5pdGUoc3RlcCkgfHwgIShzdGVwID4gMCkgPyBudWxsXG4gICAgICAgICAgOiAhKHN0ZXAgPiAxKSA/IGludGVydmFsXG4gICAgICAgICAgOiBpbnRlcnZhbC5maWx0ZXIoZmllbGRcbiAgICAgICAgICAgICAgPyBmdW5jdGlvbihkKSB7IHJldHVybiBmaWVsZChkKSAlIHN0ZXAgPT09IDA7IH1cbiAgICAgICAgICAgICAgOiBmdW5jdGlvbihkKSB7IHJldHVybiBpbnRlcnZhbC5jb3VudCgwLCBkKSAlIHN0ZXAgPT09IDA7IH0pO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gaW50ZXJ2YWw7XG59XG5cbnZhciBtaWxsaXNlY29uZCA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKCkge1xuICAvLyBub29wXG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXApO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gZW5kIC0gc3RhcnQ7XG59KTtcblxuLy8gQW4gb3B0aW1pemVkIGltcGxlbWVudGF0aW9uIGZvciB0aGlzIHNpbXBsZSBjYXNlLlxubWlsbGlzZWNvbmQuZXZlcnkgPSBmdW5jdGlvbihrKSB7XG4gIGsgPSBNYXRoLmZsb29yKGspO1xuICBpZiAoIWlzRmluaXRlKGspIHx8ICEoayA+IDApKSByZXR1cm4gbnVsbDtcbiAgaWYgKCEoayA+IDEpKSByZXR1cm4gbWlsbGlzZWNvbmQ7XG4gIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgZGF0ZS5zZXRUaW1lKE1hdGguZmxvb3IoZGF0ZSAvIGspICogayk7XG4gIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogayk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIGs7XG4gIH0pO1xufTtcblxudmFyIG1pbGxpc2Vjb25kcyA9IG1pbGxpc2Vjb25kLnJhbmdlO1xuXG52YXIgZHVyYXRpb25TZWNvbmQgPSAxZTM7XG52YXIgZHVyYXRpb25NaW51dGUgPSA2ZTQ7XG52YXIgZHVyYXRpb25Ib3VyID0gMzZlNTtcbnZhciBkdXJhdGlvbkRheSA9IDg2NGU1O1xudmFyIGR1cmF0aW9uV2VlayA9IDYwNDhlNTtcblxudmFyIHNlY29uZCA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRUaW1lKE1hdGguZmxvb3IoZGF0ZSAvIGR1cmF0aW9uU2Vjb25kKSAqIGR1cmF0aW9uU2Vjb25kKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgc3RlcCAqIGR1cmF0aW9uU2Vjb25kKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBkdXJhdGlvblNlY29uZDtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0VVRDU2Vjb25kcygpO1xufSk7XG5cbnZhciBzZWNvbmRzID0gc2Vjb25kLnJhbmdlO1xuXG52YXIgbWludXRlID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldFRpbWUoTWF0aC5mbG9vcihkYXRlIC8gZHVyYXRpb25NaW51dGUpICogZHVyYXRpb25NaW51dGUpO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogZHVyYXRpb25NaW51dGUpO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIGR1cmF0aW9uTWludXRlO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXRNaW51dGVzKCk7XG59KTtcblxudmFyIG1pbnV0ZXMgPSBtaW51dGUucmFuZ2U7XG5cbnZhciBob3VyID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICB2YXIgb2Zmc2V0ID0gZGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpICogZHVyYXRpb25NaW51dGUgJSBkdXJhdGlvbkhvdXI7XG4gIGlmIChvZmZzZXQgPCAwKSBvZmZzZXQgKz0gZHVyYXRpb25Ib3VyO1xuICBkYXRlLnNldFRpbWUoTWF0aC5mbG9vcigoK2RhdGUgLSBvZmZzZXQpIC8gZHVyYXRpb25Ib3VyKSAqIGR1cmF0aW9uSG91ciArIG9mZnNldCk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXAgKiBkdXJhdGlvbkhvdXIpO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIGR1cmF0aW9uSG91cjtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0SG91cnMoKTtcbn0pO1xuXG52YXIgaG91cnMgPSBob3VyLnJhbmdlO1xuXG52YXIgZGF5ID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCAtIChlbmQuZ2V0VGltZXpvbmVPZmZzZXQoKSAtIHN0YXJ0LmdldFRpbWV6b25lT2Zmc2V0KCkpICogZHVyYXRpb25NaW51dGUpIC8gZHVyYXRpb25EYXk7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldERhdGUoKSAtIDE7XG59KTtcblxudmFyIGRheXMgPSBkYXkucmFuZ2U7XG5cbmZ1bmN0aW9uIHdlZWtkYXkoaSkge1xuICByZXR1cm4gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSAtIChkYXRlLmdldERheSgpICsgNyAtIGkpICUgNyk7XG4gICAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIHN0ZXAgKiA3KTtcbiAgfSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiAoZW5kIC0gc3RhcnQgLSAoZW5kLmdldFRpbWV6b25lT2Zmc2V0KCkgLSBzdGFydC5nZXRUaW1lem9uZU9mZnNldCgpKSAqIGR1cmF0aW9uTWludXRlKSAvIGR1cmF0aW9uV2VlaztcbiAgfSk7XG59XG5cbnZhciBzdW5kYXkgPSB3ZWVrZGF5KDApO1xudmFyIG1vbmRheSA9IHdlZWtkYXkoMSk7XG52YXIgdHVlc2RheSA9IHdlZWtkYXkoMik7XG52YXIgd2VkbmVzZGF5ID0gd2Vla2RheSgzKTtcbnZhciB0aHVyc2RheSA9IHdlZWtkYXkoNCk7XG52YXIgZnJpZGF5ID0gd2Vla2RheSg1KTtcbnZhciBzYXR1cmRheSA9IHdlZWtkYXkoNik7XG5cbnZhciBzdW5kYXlzID0gc3VuZGF5LnJhbmdlO1xudmFyIG1vbmRheXMgPSBtb25kYXkucmFuZ2U7XG52YXIgdHVlc2RheXMgPSB0dWVzZGF5LnJhbmdlO1xudmFyIHdlZG5lc2RheXMgPSB3ZWRuZXNkYXkucmFuZ2U7XG52YXIgdGh1cnNkYXlzID0gdGh1cnNkYXkucmFuZ2U7XG52YXIgZnJpZGF5cyA9IGZyaWRheS5yYW5nZTtcbnZhciBzYXR1cmRheXMgPSBzYXR1cmRheS5yYW5nZTtcblxudmFyIG1vbnRoID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldERhdGUoMSk7XG4gIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0TW9udGgoZGF0ZS5nZXRNb250aCgpICsgc3RlcCk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiBlbmQuZ2V0TW9udGgoKSAtIHN0YXJ0LmdldE1vbnRoKCkgKyAoZW5kLmdldEZ1bGxZZWFyKCkgLSBzdGFydC5nZXRGdWxsWWVhcigpKSAqIDEyO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXRNb250aCgpO1xufSk7XG5cbnZhciBtb250aHMgPSBtb250aC5yYW5nZTtcblxudmFyIHllYXIgPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gIGRhdGUuc2V0TW9udGgoMCwgMSk7XG4gIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0RnVsbFllYXIoZGF0ZS5nZXRGdWxsWWVhcigpICsgc3RlcCk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiBlbmQuZ2V0RnVsbFllYXIoKSAtIHN0YXJ0LmdldEZ1bGxZZWFyKCk7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldEZ1bGxZZWFyKCk7XG59KTtcblxuLy8gQW4gb3B0aW1pemVkIGltcGxlbWVudGF0aW9uIGZvciB0aGlzIHNpbXBsZSBjYXNlLlxueWVhci5ldmVyeSA9IGZ1bmN0aW9uKGspIHtcbiAgcmV0dXJuICFpc0Zpbml0ZShrID0gTWF0aC5mbG9vcihrKSkgfHwgIShrID4gMCkgPyBudWxsIDogbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0RnVsbFllYXIoTWF0aC5mbG9vcihkYXRlLmdldEZ1bGxZZWFyKCkgLyBrKSAqIGspO1xuICAgIGRhdGUuc2V0TW9udGgoMCwgMSk7XG4gICAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0RnVsbFllYXIoZGF0ZS5nZXRGdWxsWWVhcigpICsgc3RlcCAqIGspO1xuICB9KTtcbn07XG5cbnZhciB5ZWFycyA9IHllYXIucmFuZ2U7XG5cbnZhciB1dGNNaW51dGUgPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gIGRhdGUuc2V0VVRDU2Vjb25kcygwLCAwKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgc3RlcCAqIGR1cmF0aW9uTWludXRlKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBkdXJhdGlvbk1pbnV0ZTtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0VVRDTWludXRlcygpO1xufSk7XG5cbnZhciB1dGNNaW51dGVzID0gdXRjTWludXRlLnJhbmdlO1xuXG52YXIgdXRjSG91ciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRVVENNaW51dGVzKDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogZHVyYXRpb25Ib3VyKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBkdXJhdGlvbkhvdXI7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ0hvdXJzKCk7XG59KTtcblxudmFyIHV0Y0hvdXJzID0gdXRjSG91ci5yYW5nZTtcblxudmFyIHV0Y0RheSA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRVVENEYXRlKGRhdGUuZ2V0VVRDRGF0ZSgpICsgc3RlcCk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gZHVyYXRpb25EYXk7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ0RhdGUoKSAtIDE7XG59KTtcblxudmFyIHV0Y0RheXMgPSB1dGNEYXkucmFuZ2U7XG5cbmZ1bmN0aW9uIHV0Y1dlZWtkYXkoaSkge1xuICByZXR1cm4gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0VVRDRGF0ZShkYXRlLmdldFVUQ0RhdGUoKSAtIChkYXRlLmdldFVUQ0RheSgpICsgNyAtIGkpICUgNyk7XG4gICAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VVRDRGF0ZShkYXRlLmdldFVUQ0RhdGUoKSArIHN0ZXAgKiA3KTtcbiAgfSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gZHVyYXRpb25XZWVrO1xuICB9KTtcbn1cblxudmFyIHV0Y1N1bmRheSA9IHV0Y1dlZWtkYXkoMCk7XG52YXIgdXRjTW9uZGF5ID0gdXRjV2Vla2RheSgxKTtcbnZhciB1dGNUdWVzZGF5ID0gdXRjV2Vla2RheSgyKTtcbnZhciB1dGNXZWRuZXNkYXkgPSB1dGNXZWVrZGF5KDMpO1xudmFyIHV0Y1RodXJzZGF5ID0gdXRjV2Vla2RheSg0KTtcbnZhciB1dGNGcmlkYXkgPSB1dGNXZWVrZGF5KDUpO1xudmFyIHV0Y1NhdHVyZGF5ID0gdXRjV2Vla2RheSg2KTtcblxudmFyIHV0Y1N1bmRheXMgPSB1dGNTdW5kYXkucmFuZ2U7XG52YXIgdXRjTW9uZGF5cyA9IHV0Y01vbmRheS5yYW5nZTtcbnZhciB1dGNUdWVzZGF5cyA9IHV0Y1R1ZXNkYXkucmFuZ2U7XG52YXIgdXRjV2VkbmVzZGF5cyA9IHV0Y1dlZG5lc2RheS5yYW5nZTtcbnZhciB1dGNUaHVyc2RheXMgPSB1dGNUaHVyc2RheS5yYW5nZTtcbnZhciB1dGNGcmlkYXlzID0gdXRjRnJpZGF5LnJhbmdlO1xudmFyIHV0Y1NhdHVyZGF5cyA9IHV0Y1NhdHVyZGF5LnJhbmdlO1xuXG52YXIgdXRjTW9udGggPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gIGRhdGUuc2V0VVRDRGF0ZSgxKTtcbiAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRVVENNb250aChkYXRlLmdldFVUQ01vbnRoKCkgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIGVuZC5nZXRVVENNb250aCgpIC0gc3RhcnQuZ2V0VVRDTW9udGgoKSArIChlbmQuZ2V0VVRDRnVsbFllYXIoKSAtIHN0YXJ0LmdldFVUQ0Z1bGxZZWFyKCkpICogMTI7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ01vbnRoKCk7XG59KTtcblxudmFyIHV0Y01vbnRocyA9IHV0Y01vbnRoLnJhbmdlO1xuXG52YXIgdXRjWWVhciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRVVENNb250aCgwLCAxKTtcbiAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRVVENGdWxsWWVhcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIGVuZC5nZXRVVENGdWxsWWVhcigpIC0gc3RhcnQuZ2V0VVRDRnVsbFllYXIoKTtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0VVRDRnVsbFllYXIoKTtcbn0pO1xuXG4vLyBBbiBvcHRpbWl6ZWQgaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgc2ltcGxlIGNhc2UuXG51dGNZZWFyLmV2ZXJ5ID0gZnVuY3Rpb24oaykge1xuICByZXR1cm4gIWlzRmluaXRlKGsgPSBNYXRoLmZsb29yKGspKSB8fCAhKGsgPiAwKSA/IG51bGwgOiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgZGF0ZS5zZXRVVENGdWxsWWVhcihNYXRoLmZsb29yKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSAvIGspICogayk7XG4gICAgZGF0ZS5zZXRVVENNb250aCgwLCAxKTtcbiAgICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRVVENGdWxsWWVhcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkgKyBzdGVwICogayk7XG4gIH0pO1xufTtcblxudmFyIHV0Y1llYXJzID0gdXRjWWVhci5yYW5nZTtcblxuLy8gQ29tcHV0ZXMgdGhlIGRlY2ltYWwgY29lZmZpY2llbnQgYW5kIGV4cG9uZW50IG9mIHRoZSBzcGVjaWZpZWQgbnVtYmVyIHggd2l0aFxuLy8gc2lnbmlmaWNhbnQgZGlnaXRzIHAsIHdoZXJlIHggaXMgcG9zaXRpdmUgYW5kIHAgaXMgaW4gWzEsIDIxXSBvciB1bmRlZmluZWQuXG4vLyBGb3IgZXhhbXBsZSwgZm9ybWF0RGVjaW1hbCgxLjIzKSByZXR1cm5zIFtcIjEyM1wiLCAwXS5cbnZhciBmb3JtYXREZWNpbWFsID0gZnVuY3Rpb24oeCwgcCkge1xuICBpZiAoKGkgPSAoeCA9IHAgPyB4LnRvRXhwb25lbnRpYWwocCAtIDEpIDogeC50b0V4cG9uZW50aWFsKCkpLmluZGV4T2YoXCJlXCIpKSA8IDApIHJldHVybiBudWxsOyAvLyBOYU4sIMKxSW5maW5pdHlcbiAgdmFyIGksIGNvZWZmaWNpZW50ID0geC5zbGljZSgwLCBpKTtcblxuICAvLyBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRvRXhwb25lbnRpYWwgZWl0aGVyIGhhcyB0aGUgZm9ybSBcXGRcXC5cXGQrZVstK11cXGQrXG4gIC8vIChlLmcuLCAxLjJlKzMpIG9yIHRoZSBmb3JtIFxcZGVbLStdXFxkKyAoZS5nLiwgMWUrMykuXG4gIHJldHVybiBbXG4gICAgY29lZmZpY2llbnQubGVuZ3RoID4gMSA/IGNvZWZmaWNpZW50WzBdICsgY29lZmZpY2llbnQuc2xpY2UoMikgOiBjb2VmZmljaWVudCxcbiAgICAreC5zbGljZShpICsgMSlcbiAgXTtcbn07XG5cbnZhciBleHBvbmVudCQxID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4geCA9IGZvcm1hdERlY2ltYWwoTWF0aC5hYnMoeCkpLCB4ID8geFsxXSA6IE5hTjtcbn07XG5cbnZhciBmb3JtYXRHcm91cCA9IGZ1bmN0aW9uKGdyb3VwaW5nLCB0aG91c2FuZHMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCB3aWR0aCkge1xuICAgIHZhciBpID0gdmFsdWUubGVuZ3RoLFxuICAgICAgICB0ID0gW10sXG4gICAgICAgIGogPSAwLFxuICAgICAgICBnID0gZ3JvdXBpbmdbMF0sXG4gICAgICAgIGxlbmd0aCA9IDA7XG5cbiAgICB3aGlsZSAoaSA+IDAgJiYgZyA+IDApIHtcbiAgICAgIGlmIChsZW5ndGggKyBnICsgMSA+IHdpZHRoKSBnID0gTWF0aC5tYXgoMSwgd2lkdGggLSBsZW5ndGgpO1xuICAgICAgdC5wdXNoKHZhbHVlLnN1YnN0cmluZyhpIC09IGcsIGkgKyBnKSk7XG4gICAgICBpZiAoKGxlbmd0aCArPSBnICsgMSkgPiB3aWR0aCkgYnJlYWs7XG4gICAgICBnID0gZ3JvdXBpbmdbaiA9IChqICsgMSkgJSBncm91cGluZy5sZW5ndGhdO1xuICAgIH1cblxuICAgIHJldHVybiB0LnJldmVyc2UoKS5qb2luKHRob3VzYW5kcyk7XG4gIH07XG59O1xuXG52YXIgZm9ybWF0RGVmYXVsdCA9IGZ1bmN0aW9uKHgsIHApIHtcbiAgeCA9IHgudG9QcmVjaXNpb24ocCk7XG5cbiAgb3V0OiBmb3IgKHZhciBuID0geC5sZW5ndGgsIGkgPSAxLCBpMCA9IC0xLCBpMTsgaSA8IG47ICsraSkge1xuICAgIHN3aXRjaCAoeFtpXSkge1xuICAgICAgY2FzZSBcIi5cIjogaTAgPSBpMSA9IGk7IGJyZWFrO1xuICAgICAgY2FzZSBcIjBcIjogaWYgKGkwID09PSAwKSBpMCA9IGk7IGkxID0gaTsgYnJlYWs7XG4gICAgICBjYXNlIFwiZVwiOiBicmVhayBvdXQ7XG4gICAgICBkZWZhdWx0OiBpZiAoaTAgPiAwKSBpMCA9IDA7IGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBpMCA+IDAgPyB4LnNsaWNlKDAsIGkwKSArIHguc2xpY2UoaTEgKyAxKSA6IHg7XG59O1xuXG52YXIgcHJlZml4RXhwb25lbnQ7XG5cbnZhciBmb3JtYXRQcmVmaXhBdXRvID0gZnVuY3Rpb24oeCwgcCkge1xuICB2YXIgZCA9IGZvcm1hdERlY2ltYWwoeCwgcCk7XG4gIGlmICghZCkgcmV0dXJuIHggKyBcIlwiO1xuICB2YXIgY29lZmZpY2llbnQgPSBkWzBdLFxuICAgICAgZXhwb25lbnQgPSBkWzFdLFxuICAgICAgaSA9IGV4cG9uZW50IC0gKHByZWZpeEV4cG9uZW50ID0gTWF0aC5tYXgoLTgsIE1hdGgubWluKDgsIE1hdGguZmxvb3IoZXhwb25lbnQgLyAzKSkpICogMykgKyAxLFxuICAgICAgbiA9IGNvZWZmaWNpZW50Lmxlbmd0aDtcbiAgcmV0dXJuIGkgPT09IG4gPyBjb2VmZmljaWVudFxuICAgICAgOiBpID4gbiA/IGNvZWZmaWNpZW50ICsgbmV3IEFycmF5KGkgLSBuICsgMSkuam9pbihcIjBcIilcbiAgICAgIDogaSA+IDAgPyBjb2VmZmljaWVudC5zbGljZSgwLCBpKSArIFwiLlwiICsgY29lZmZpY2llbnQuc2xpY2UoaSlcbiAgICAgIDogXCIwLlwiICsgbmV3IEFycmF5KDEgLSBpKS5qb2luKFwiMFwiKSArIGZvcm1hdERlY2ltYWwoeCwgTWF0aC5tYXgoMCwgcCArIGkgLSAxKSlbMF07IC8vIGxlc3MgdGhhbiAxeSFcbn07XG5cbnZhciBmb3JtYXRSb3VuZGVkID0gZnVuY3Rpb24oeCwgcCkge1xuICB2YXIgZCA9IGZvcm1hdERlY2ltYWwoeCwgcCk7XG4gIGlmICghZCkgcmV0dXJuIHggKyBcIlwiO1xuICB2YXIgY29lZmZpY2llbnQgPSBkWzBdLFxuICAgICAgZXhwb25lbnQgPSBkWzFdO1xuICByZXR1cm4gZXhwb25lbnQgPCAwID8gXCIwLlwiICsgbmV3IEFycmF5KC1leHBvbmVudCkuam9pbihcIjBcIikgKyBjb2VmZmljaWVudFxuICAgICAgOiBjb2VmZmljaWVudC5sZW5ndGggPiBleHBvbmVudCArIDEgPyBjb2VmZmljaWVudC5zbGljZSgwLCBleHBvbmVudCArIDEpICsgXCIuXCIgKyBjb2VmZmljaWVudC5zbGljZShleHBvbmVudCArIDEpXG4gICAgICA6IGNvZWZmaWNpZW50ICsgbmV3IEFycmF5KGV4cG9uZW50IC0gY29lZmZpY2llbnQubGVuZ3RoICsgMikuam9pbihcIjBcIik7XG59O1xuXG52YXIgZm9ybWF0VHlwZXMgPSB7XG4gIFwiXCI6IGZvcm1hdERlZmF1bHQsXG4gIFwiJVwiOiBmdW5jdGlvbih4LCBwKSB7IHJldHVybiAoeCAqIDEwMCkudG9GaXhlZChwKTsgfSxcbiAgXCJiXCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoMik7IH0sXG4gIFwiY1wiOiBmdW5jdGlvbih4KSB7IHJldHVybiB4ICsgXCJcIjsgfSxcbiAgXCJkXCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoMTApOyB9LFxuICBcImVcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b0V4cG9uZW50aWFsKHApOyB9LFxuICBcImZcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b0ZpeGVkKHApOyB9LFxuICBcImdcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b1ByZWNpc2lvbihwKTsgfSxcbiAgXCJvXCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoOCk7IH0sXG4gIFwicFwiOiBmdW5jdGlvbih4LCBwKSB7IHJldHVybiBmb3JtYXRSb3VuZGVkKHggKiAxMDAsIHApOyB9LFxuICBcInJcIjogZm9ybWF0Um91bmRlZCxcbiAgXCJzXCI6IGZvcm1hdFByZWZpeEF1dG8sXG4gIFwiWFwiOiBmdW5jdGlvbih4KSB7IHJldHVybiBNYXRoLnJvdW5kKHgpLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpOyB9LFxuICBcInhcIjogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZygxNik7IH1cbn07XG5cbi8vIFtbZmlsbF1hbGlnbl1bc2lnbl1bc3ltYm9sXVswXVt3aWR0aF1bLF1bLnByZWNpc2lvbl1bdHlwZV1cbnZhciByZSA9IC9eKD86KC4pPyhbPD49Xl0pKT8oWytcXC1cXCggXSk/KFskI10pPygwKT8oXFxkKyk/KCwpPyhcXC5cXGQrKT8oW2EteiVdKT8kL2k7XG5cbnZhciBmb3JtYXRTcGVjaWZpZXIgPSBmdW5jdGlvbihzcGVjaWZpZXIpIHtcbiAgcmV0dXJuIG5ldyBGb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyKTtcbn07XG5cbmZ1bmN0aW9uIEZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpIHtcbiAgaWYgKCEobWF0Y2ggPSByZS5leGVjKHNwZWNpZmllcikpKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGZvcm1hdDogXCIgKyBzcGVjaWZpZXIpO1xuXG4gIHZhciBtYXRjaCxcbiAgICAgIGZpbGwgPSBtYXRjaFsxXSB8fCBcIiBcIixcbiAgICAgIGFsaWduID0gbWF0Y2hbMl0gfHwgXCI+XCIsXG4gICAgICBzaWduID0gbWF0Y2hbM10gfHwgXCItXCIsXG4gICAgICBzeW1ib2wgPSBtYXRjaFs0XSB8fCBcIlwiLFxuICAgICAgemVybyA9ICEhbWF0Y2hbNV0sXG4gICAgICB3aWR0aCA9IG1hdGNoWzZdICYmICttYXRjaFs2XSxcbiAgICAgIGNvbW1hID0gISFtYXRjaFs3XSxcbiAgICAgIHByZWNpc2lvbiA9IG1hdGNoWzhdICYmICttYXRjaFs4XS5zbGljZSgxKSxcbiAgICAgIHR5cGUgPSBtYXRjaFs5XSB8fCBcIlwiO1xuXG4gIC8vIFRoZSBcIm5cIiB0eXBlIGlzIGFuIGFsaWFzIGZvciBcIixnXCIuXG4gIGlmICh0eXBlID09PSBcIm5cIikgY29tbWEgPSB0cnVlLCB0eXBlID0gXCJnXCI7XG5cbiAgLy8gTWFwIGludmFsaWQgdHlwZXMgdG8gdGhlIGRlZmF1bHQgZm9ybWF0LlxuICBlbHNlIGlmICghZm9ybWF0VHlwZXNbdHlwZV0pIHR5cGUgPSBcIlwiO1xuXG4gIC8vIElmIHplcm8gZmlsbCBpcyBzcGVjaWZpZWQsIHBhZGRpbmcgZ29lcyBhZnRlciBzaWduIGFuZCBiZWZvcmUgZGlnaXRzLlxuICBpZiAoemVybyB8fCAoZmlsbCA9PT0gXCIwXCIgJiYgYWxpZ24gPT09IFwiPVwiKSkgemVybyA9IHRydWUsIGZpbGwgPSBcIjBcIiwgYWxpZ24gPSBcIj1cIjtcblxuICB0aGlzLmZpbGwgPSBmaWxsO1xuICB0aGlzLmFsaWduID0gYWxpZ247XG4gIHRoaXMuc2lnbiA9IHNpZ247XG4gIHRoaXMuc3ltYm9sID0gc3ltYm9sO1xuICB0aGlzLnplcm8gPSB6ZXJvO1xuICB0aGlzLndpZHRoID0gd2lkdGg7XG4gIHRoaXMuY29tbWEgPSBjb21tYTtcbiAgdGhpcy5wcmVjaXNpb24gPSBwcmVjaXNpb247XG4gIHRoaXMudHlwZSA9IHR5cGU7XG59XG5cbkZvcm1hdFNwZWNpZmllci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuZmlsbFxuICAgICAgKyB0aGlzLmFsaWduXG4gICAgICArIHRoaXMuc2lnblxuICAgICAgKyB0aGlzLnN5bWJvbFxuICAgICAgKyAodGhpcy56ZXJvID8gXCIwXCIgOiBcIlwiKVxuICAgICAgKyAodGhpcy53aWR0aCA9PSBudWxsID8gXCJcIiA6IE1hdGgubWF4KDEsIHRoaXMud2lkdGggfCAwKSlcbiAgICAgICsgKHRoaXMuY29tbWEgPyBcIixcIiA6IFwiXCIpXG4gICAgICArICh0aGlzLnByZWNpc2lvbiA9PSBudWxsID8gXCJcIiA6IFwiLlwiICsgTWF0aC5tYXgoMCwgdGhpcy5wcmVjaXNpb24gfCAwKSlcbiAgICAgICsgdGhpcy50eXBlO1xufTtcblxudmFyIHByZWZpeGVzID0gW1wieVwiLFwielwiLFwiYVwiLFwiZlwiLFwicFwiLFwiblwiLFwiXFx4QjVcIixcIm1cIixcIlwiLFwia1wiLFwiTVwiLFwiR1wiLFwiVFwiLFwiUFwiLFwiRVwiLFwiWlwiLFwiWVwiXTtcblxuZnVuY3Rpb24gaWRlbnRpdHkkMyh4KSB7XG4gIHJldHVybiB4O1xufVxuXG52YXIgZm9ybWF0TG9jYWxlID0gZnVuY3Rpb24obG9jYWxlKSB7XG4gIHZhciBncm91cCA9IGxvY2FsZS5ncm91cGluZyAmJiBsb2NhbGUudGhvdXNhbmRzID8gZm9ybWF0R3JvdXAobG9jYWxlLmdyb3VwaW5nLCBsb2NhbGUudGhvdXNhbmRzKSA6IGlkZW50aXR5JDMsXG4gICAgICBjdXJyZW5jeSA9IGxvY2FsZS5jdXJyZW5jeSxcbiAgICAgIGRlY2ltYWwgPSBsb2NhbGUuZGVjaW1hbDtcblxuICBmdW5jdGlvbiBuZXdGb3JtYXQoc3BlY2lmaWVyKSB7XG4gICAgc3BlY2lmaWVyID0gZm9ybWF0U3BlY2lmaWVyKHNwZWNpZmllcik7XG5cbiAgICB2YXIgZmlsbCA9IHNwZWNpZmllci5maWxsLFxuICAgICAgICBhbGlnbiA9IHNwZWNpZmllci5hbGlnbixcbiAgICAgICAgc2lnbiA9IHNwZWNpZmllci5zaWduLFxuICAgICAgICBzeW1ib2wgPSBzcGVjaWZpZXIuc3ltYm9sLFxuICAgICAgICB6ZXJvID0gc3BlY2lmaWVyLnplcm8sXG4gICAgICAgIHdpZHRoID0gc3BlY2lmaWVyLndpZHRoLFxuICAgICAgICBjb21tYSA9IHNwZWNpZmllci5jb21tYSxcbiAgICAgICAgcHJlY2lzaW9uID0gc3BlY2lmaWVyLnByZWNpc2lvbixcbiAgICAgICAgdHlwZSA9IHNwZWNpZmllci50eXBlO1xuXG4gICAgLy8gQ29tcHV0ZSB0aGUgcHJlZml4IGFuZCBzdWZmaXguXG4gICAgLy8gRm9yIFNJLXByZWZpeCwgdGhlIHN1ZmZpeCBpcyBsYXppbHkgY29tcHV0ZWQuXG4gICAgdmFyIHByZWZpeCA9IHN5bWJvbCA9PT0gXCIkXCIgPyBjdXJyZW5jeVswXSA6IHN5bWJvbCA9PT0gXCIjXCIgJiYgL1tib3hYXS8udGVzdCh0eXBlKSA/IFwiMFwiICsgdHlwZS50b0xvd2VyQ2FzZSgpIDogXCJcIixcbiAgICAgICAgc3VmZml4ID0gc3ltYm9sID09PSBcIiRcIiA/IGN1cnJlbmN5WzFdIDogL1slcF0vLnRlc3QodHlwZSkgPyBcIiVcIiA6IFwiXCI7XG5cbiAgICAvLyBXaGF0IGZvcm1hdCBmdW5jdGlvbiBzaG91bGQgd2UgdXNlP1xuICAgIC8vIElzIHRoaXMgYW4gaW50ZWdlciB0eXBlP1xuICAgIC8vIENhbiB0aGlzIHR5cGUgZ2VuZXJhdGUgZXhwb25lbnRpYWwgbm90YXRpb24/XG4gICAgdmFyIGZvcm1hdFR5cGUgPSBmb3JtYXRUeXBlc1t0eXBlXSxcbiAgICAgICAgbWF5YmVTdWZmaXggPSAhdHlwZSB8fCAvW2RlZmdwcnMlXS8udGVzdCh0eXBlKTtcblxuICAgIC8vIFNldCB0aGUgZGVmYXVsdCBwcmVjaXNpb24gaWYgbm90IHNwZWNpZmllZCxcbiAgICAvLyBvciBjbGFtcCB0aGUgc3BlY2lmaWVkIHByZWNpc2lvbiB0byB0aGUgc3VwcG9ydGVkIHJhbmdlLlxuICAgIC8vIEZvciBzaWduaWZpY2FudCBwcmVjaXNpb24sIGl0IG11c3QgYmUgaW4gWzEsIDIxXS5cbiAgICAvLyBGb3IgZml4ZWQgcHJlY2lzaW9uLCBpdCBtdXN0IGJlIGluIFswLCAyMF0uXG4gICAgcHJlY2lzaW9uID0gcHJlY2lzaW9uID09IG51bGwgPyAodHlwZSA/IDYgOiAxMilcbiAgICAgICAgOiAvW2dwcnNdLy50ZXN0KHR5cGUpID8gTWF0aC5tYXgoMSwgTWF0aC5taW4oMjEsIHByZWNpc2lvbikpXG4gICAgICAgIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oMjAsIHByZWNpc2lvbikpO1xuXG4gICAgZnVuY3Rpb24gZm9ybWF0KHZhbHVlKSB7XG4gICAgICB2YXIgdmFsdWVQcmVmaXggPSBwcmVmaXgsXG4gICAgICAgICAgdmFsdWVTdWZmaXggPSBzdWZmaXgsXG4gICAgICAgICAgaSwgbiwgYztcblxuICAgICAgaWYgKHR5cGUgPT09IFwiY1wiKSB7XG4gICAgICAgIHZhbHVlU3VmZml4ID0gZm9ybWF0VHlwZSh2YWx1ZSkgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgICAgdmFsdWUgPSBcIlwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSArdmFsdWU7XG5cbiAgICAgICAgLy8gQ29udmVydCBuZWdhdGl2ZSB0byBwb3NpdGl2ZSwgYW5kIGNvbXB1dGUgdGhlIHByZWZpeC5cbiAgICAgICAgLy8gTm90ZSB0aGF0IC0wIGlzIG5vdCBsZXNzIHRoYW4gMCwgYnV0IDEgLyAtMCBpcyFcbiAgICAgICAgdmFyIHZhbHVlTmVnYXRpdmUgPSAodmFsdWUgPCAwIHx8IDEgLyB2YWx1ZSA8IDApICYmICh2YWx1ZSAqPSAtMSwgdHJ1ZSk7XG5cbiAgICAgICAgLy8gUGVyZm9ybSB0aGUgaW5pdGlhbCBmb3JtYXR0aW5nLlxuICAgICAgICB2YWx1ZSA9IGZvcm1hdFR5cGUodmFsdWUsIHByZWNpc2lvbik7XG5cbiAgICAgICAgLy8gSWYgdGhlIG9yaWdpbmFsIHZhbHVlIHdhcyBuZWdhdGl2ZSwgaXQgbWF5IGJlIHJvdW5kZWQgdG8gemVybyBkdXJpbmdcbiAgICAgICAgLy8gZm9ybWF0dGluZzsgdHJlYXQgdGhpcyBhcyAocG9zaXRpdmUpIHplcm8uXG4gICAgICAgIGlmICh2YWx1ZU5lZ2F0aXZlKSB7XG4gICAgICAgICAgaSA9IC0xLCBuID0gdmFsdWUubGVuZ3RoO1xuICAgICAgICAgIHZhbHVlTmVnYXRpdmUgPSBmYWxzZTtcbiAgICAgICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAgICAgaWYgKGMgPSB2YWx1ZS5jaGFyQ29kZUF0KGkpLCAoNDggPCBjICYmIGMgPCA1OClcbiAgICAgICAgICAgICAgICB8fCAodHlwZSA9PT0gXCJ4XCIgJiYgOTYgPCBjICYmIGMgPCAxMDMpXG4gICAgICAgICAgICAgICAgfHwgKHR5cGUgPT09IFwiWFwiICYmIDY0IDwgYyAmJiBjIDwgNzEpKSB7XG4gICAgICAgICAgICAgIHZhbHVlTmVnYXRpdmUgPSB0cnVlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb21wdXRlIHRoZSBwcmVmaXggYW5kIHN1ZmZpeC5cbiAgICAgICAgdmFsdWVQcmVmaXggPSAodmFsdWVOZWdhdGl2ZSA/IChzaWduID09PSBcIihcIiA/IHNpZ24gOiBcIi1cIikgOiBzaWduID09PSBcIi1cIiB8fCBzaWduID09PSBcIihcIiA/IFwiXCIgOiBzaWduKSArIHZhbHVlUHJlZml4O1xuICAgICAgICB2YWx1ZVN1ZmZpeCA9IHZhbHVlU3VmZml4ICsgKHR5cGUgPT09IFwic1wiID8gcHJlZml4ZXNbOCArIHByZWZpeEV4cG9uZW50IC8gM10gOiBcIlwiKSArICh2YWx1ZU5lZ2F0aXZlICYmIHNpZ24gPT09IFwiKFwiID8gXCIpXCIgOiBcIlwiKTtcblxuICAgICAgICAvLyBCcmVhayB0aGUgZm9ybWF0dGVkIHZhbHVlIGludG8gdGhlIGludGVnZXIg4oCcdmFsdWXigJ0gcGFydCB0aGF0IGNhbiBiZVxuICAgICAgICAvLyBncm91cGVkLCBhbmQgZnJhY3Rpb25hbCBvciBleHBvbmVudGlhbCDigJxzdWZmaXjigJ0gcGFydCB0aGF0IGlzIG5vdC5cbiAgICAgICAgaWYgKG1heWJlU3VmZml4KSB7XG4gICAgICAgICAgaSA9IC0xLCBuID0gdmFsdWUubGVuZ3RoO1xuICAgICAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgICBpZiAoYyA9IHZhbHVlLmNoYXJDb2RlQXQoaSksIDQ4ID4gYyB8fCBjID4gNTcpIHtcbiAgICAgICAgICAgICAgdmFsdWVTdWZmaXggPSAoYyA9PT0gNDYgPyBkZWNpbWFsICsgdmFsdWUuc2xpY2UoaSArIDEpIDogdmFsdWUuc2xpY2UoaSkpICsgdmFsdWVTdWZmaXg7XG4gICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMCwgaSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBJZiB0aGUgZmlsbCBjaGFyYWN0ZXIgaXMgbm90IFwiMFwiLCBncm91cGluZyBpcyBhcHBsaWVkIGJlZm9yZSBwYWRkaW5nLlxuICAgICAgaWYgKGNvbW1hICYmICF6ZXJvKSB2YWx1ZSA9IGdyb3VwKHZhbHVlLCBJbmZpbml0eSk7XG5cbiAgICAgIC8vIENvbXB1dGUgdGhlIHBhZGRpbmcuXG4gICAgICB2YXIgbGVuZ3RoID0gdmFsdWVQcmVmaXgubGVuZ3RoICsgdmFsdWUubGVuZ3RoICsgdmFsdWVTdWZmaXgubGVuZ3RoLFxuICAgICAgICAgIHBhZGRpbmcgPSBsZW5ndGggPCB3aWR0aCA/IG5ldyBBcnJheSh3aWR0aCAtIGxlbmd0aCArIDEpLmpvaW4oZmlsbCkgOiBcIlwiO1xuXG4gICAgICAvLyBJZiB0aGUgZmlsbCBjaGFyYWN0ZXIgaXMgXCIwXCIsIGdyb3VwaW5nIGlzIGFwcGxpZWQgYWZ0ZXIgcGFkZGluZy5cbiAgICAgIGlmIChjb21tYSAmJiB6ZXJvKSB2YWx1ZSA9IGdyb3VwKHBhZGRpbmcgKyB2YWx1ZSwgcGFkZGluZy5sZW5ndGggPyB3aWR0aCAtIHZhbHVlU3VmZml4Lmxlbmd0aCA6IEluZmluaXR5KSwgcGFkZGluZyA9IFwiXCI7XG5cbiAgICAgIC8vIFJlY29uc3RydWN0IHRoZSBmaW5hbCBvdXRwdXQgYmFzZWQgb24gdGhlIGRlc2lyZWQgYWxpZ25tZW50LlxuICAgICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgICBjYXNlIFwiPFwiOiByZXR1cm4gdmFsdWVQcmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4ICsgcGFkZGluZztcbiAgICAgICAgY2FzZSBcIj1cIjogcmV0dXJuIHZhbHVlUHJlZml4ICsgcGFkZGluZyArIHZhbHVlICsgdmFsdWVTdWZmaXg7XG4gICAgICAgIGNhc2UgXCJeXCI6IHJldHVybiBwYWRkaW5nLnNsaWNlKDAsIGxlbmd0aCA9IHBhZGRpbmcubGVuZ3RoID4+IDEpICsgdmFsdWVQcmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4ICsgcGFkZGluZy5zbGljZShsZW5ndGgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBhZGRpbmcgKyB2YWx1ZVByZWZpeCArIHZhbHVlICsgdmFsdWVTdWZmaXg7XG4gICAgfVxuXG4gICAgZm9ybWF0LnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gc3BlY2lmaWVyICsgXCJcIjtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGZvcm1hdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFByZWZpeChzcGVjaWZpZXIsIHZhbHVlKSB7XG4gICAgdmFyIGYgPSBuZXdGb3JtYXQoKHNwZWNpZmllciA9IGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpLCBzcGVjaWZpZXIudHlwZSA9IFwiZlwiLCBzcGVjaWZpZXIpKSxcbiAgICAgICAgZSA9IE1hdGgubWF4KC04LCBNYXRoLm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50JDEodmFsdWUpIC8gMykpKSAqIDMsXG4gICAgICAgIGsgPSBNYXRoLnBvdygxMCwgLWUpLFxuICAgICAgICBwcmVmaXggPSBwcmVmaXhlc1s4ICsgZSAvIDNdO1xuICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGYoayAqIHZhbHVlKSArIHByZWZpeDtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBmb3JtYXQ6IG5ld0Zvcm1hdCxcbiAgICBmb3JtYXRQcmVmaXg6IGZvcm1hdFByZWZpeFxuICB9O1xufTtcblxudmFyIGxvY2FsZSQxO1xuXG5cblxuZGVmYXVsdExvY2FsZSh7XG4gIGRlY2ltYWw6IFwiLlwiLFxuICB0aG91c2FuZHM6IFwiLFwiLFxuICBncm91cGluZzogWzNdLFxuICBjdXJyZW5jeTogW1wiJFwiLCBcIlwiXVxufSk7XG5cbmZ1bmN0aW9uIGRlZmF1bHRMb2NhbGUoZGVmaW5pdGlvbikge1xuICBsb2NhbGUkMSA9IGZvcm1hdExvY2FsZShkZWZpbml0aW9uKTtcbiAgZXhwb3J0cy5mb3JtYXQgPSBsb2NhbGUkMS5mb3JtYXQ7XG4gIGV4cG9ydHMuZm9ybWF0UHJlZml4ID0gbG9jYWxlJDEuZm9ybWF0UHJlZml4O1xuICByZXR1cm4gbG9jYWxlJDE7XG59XG5cbnZhciBwcmVjaXNpb25GaXhlZCA9IGZ1bmN0aW9uKHN0ZXApIHtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIC1leHBvbmVudCQxKE1hdGguYWJzKHN0ZXApKSk7XG59O1xuXG52YXIgcHJlY2lzaW9uUHJlZml4ID0gZnVuY3Rpb24oc3RlcCwgdmFsdWUpIHtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWF4KC04LCBNYXRoLm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50JDEodmFsdWUpIC8gMykpKSAqIDMgLSBleHBvbmVudCQxKE1hdGguYWJzKHN0ZXApKSk7XG59O1xuXG52YXIgcHJlY2lzaW9uUm91bmQgPSBmdW5jdGlvbihzdGVwLCBtYXgpIHtcbiAgc3RlcCA9IE1hdGguYWJzKHN0ZXApLCBtYXggPSBNYXRoLmFicyhtYXgpIC0gc3RlcDtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIGV4cG9uZW50JDEobWF4KSAtIGV4cG9uZW50JDEoc3RlcCkpICsgMTtcbn07XG5cbmZ1bmN0aW9uIGxvY2FsRGF0ZShkKSB7XG4gIGlmICgwIDw9IGQueSAmJiBkLnkgPCAxMDApIHtcbiAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKC0xLCBkLm0sIGQuZCwgZC5ILCBkLk0sIGQuUywgZC5MKTtcbiAgICBkYXRlLnNldEZ1bGxZZWFyKGQueSk7XG4gICAgcmV0dXJuIGRhdGU7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRlKGQueSwgZC5tLCBkLmQsIGQuSCwgZC5NLCBkLlMsIGQuTCk7XG59XG5cbmZ1bmN0aW9uIHV0Y0RhdGUoZCkge1xuICBpZiAoMCA8PSBkLnkgJiYgZC55IDwgMTAwKSB7XG4gICAgdmFyIGRhdGUgPSBuZXcgRGF0ZShEYXRlLlVUQygtMSwgZC5tLCBkLmQsIGQuSCwgZC5NLCBkLlMsIGQuTCkpO1xuICAgIGRhdGUuc2V0VVRDRnVsbFllYXIoZC55KTtcbiAgICByZXR1cm4gZGF0ZTtcbiAgfVxuICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoZC55LCBkLm0sIGQuZCwgZC5ILCBkLk0sIGQuUywgZC5MKSk7XG59XG5cbmZ1bmN0aW9uIG5ld1llYXIoeSkge1xuICByZXR1cm4ge3k6IHksIG06IDAsIGQ6IDEsIEg6IDAsIE06IDAsIFM6IDAsIEw6IDB9O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRMb2NhbGUkMShsb2NhbGUpIHtcbiAgdmFyIGxvY2FsZV9kYXRlVGltZSA9IGxvY2FsZS5kYXRlVGltZSxcbiAgICAgIGxvY2FsZV9kYXRlID0gbG9jYWxlLmRhdGUsXG4gICAgICBsb2NhbGVfdGltZSA9IGxvY2FsZS50aW1lLFxuICAgICAgbG9jYWxlX3BlcmlvZHMgPSBsb2NhbGUucGVyaW9kcyxcbiAgICAgIGxvY2FsZV93ZWVrZGF5cyA9IGxvY2FsZS5kYXlzLFxuICAgICAgbG9jYWxlX3Nob3J0V2Vla2RheXMgPSBsb2NhbGUuc2hvcnREYXlzLFxuICAgICAgbG9jYWxlX21vbnRocyA9IGxvY2FsZS5tb250aHMsXG4gICAgICBsb2NhbGVfc2hvcnRNb250aHMgPSBsb2NhbGUuc2hvcnRNb250aHM7XG5cbiAgdmFyIHBlcmlvZFJlID0gZm9ybWF0UmUobG9jYWxlX3BlcmlvZHMpLFxuICAgICAgcGVyaW9kTG9va3VwID0gZm9ybWF0TG9va3VwKGxvY2FsZV9wZXJpb2RzKSxcbiAgICAgIHdlZWtkYXlSZSA9IGZvcm1hdFJlKGxvY2FsZV93ZWVrZGF5cyksXG4gICAgICB3ZWVrZGF5TG9va3VwID0gZm9ybWF0TG9va3VwKGxvY2FsZV93ZWVrZGF5cyksXG4gICAgICBzaG9ydFdlZWtkYXlSZSA9IGZvcm1hdFJlKGxvY2FsZV9zaG9ydFdlZWtkYXlzKSxcbiAgICAgIHNob3J0V2Vla2RheUxvb2t1cCA9IGZvcm1hdExvb2t1cChsb2NhbGVfc2hvcnRXZWVrZGF5cyksXG4gICAgICBtb250aFJlID0gZm9ybWF0UmUobG9jYWxlX21vbnRocyksXG4gICAgICBtb250aExvb2t1cCA9IGZvcm1hdExvb2t1cChsb2NhbGVfbW9udGhzKSxcbiAgICAgIHNob3J0TW9udGhSZSA9IGZvcm1hdFJlKGxvY2FsZV9zaG9ydE1vbnRocyksXG4gICAgICBzaG9ydE1vbnRoTG9va3VwID0gZm9ybWF0TG9va3VwKGxvY2FsZV9zaG9ydE1vbnRocyk7XG5cbiAgdmFyIGZvcm1hdHMgPSB7XG4gICAgXCJhXCI6IGZvcm1hdFNob3J0V2Vla2RheSxcbiAgICBcIkFcIjogZm9ybWF0V2Vla2RheSxcbiAgICBcImJcIjogZm9ybWF0U2hvcnRNb250aCxcbiAgICBcIkJcIjogZm9ybWF0TW9udGgsXG4gICAgXCJjXCI6IG51bGwsXG4gICAgXCJkXCI6IGZvcm1hdERheU9mTW9udGgsXG4gICAgXCJlXCI6IGZvcm1hdERheU9mTW9udGgsXG4gICAgXCJIXCI6IGZvcm1hdEhvdXIyNCxcbiAgICBcIklcIjogZm9ybWF0SG91cjEyLFxuICAgIFwialwiOiBmb3JtYXREYXlPZlllYXIsXG4gICAgXCJMXCI6IGZvcm1hdE1pbGxpc2Vjb25kcyxcbiAgICBcIm1cIjogZm9ybWF0TW9udGhOdW1iZXIsXG4gICAgXCJNXCI6IGZvcm1hdE1pbnV0ZXMsXG4gICAgXCJwXCI6IGZvcm1hdFBlcmlvZCxcbiAgICBcIlNcIjogZm9ybWF0U2Vjb25kcyxcbiAgICBcIlVcIjogZm9ybWF0V2Vla051bWJlclN1bmRheSxcbiAgICBcIndcIjogZm9ybWF0V2Vla2RheU51bWJlcixcbiAgICBcIldcIjogZm9ybWF0V2Vla051bWJlck1vbmRheSxcbiAgICBcInhcIjogbnVsbCxcbiAgICBcIlhcIjogbnVsbCxcbiAgICBcInlcIjogZm9ybWF0WWVhcixcbiAgICBcIllcIjogZm9ybWF0RnVsbFllYXIsXG4gICAgXCJaXCI6IGZvcm1hdFpvbmUsXG4gICAgXCIlXCI6IGZvcm1hdExpdGVyYWxQZXJjZW50XG4gIH07XG5cbiAgdmFyIHV0Y0Zvcm1hdHMgPSB7XG4gICAgXCJhXCI6IGZvcm1hdFVUQ1Nob3J0V2Vla2RheSxcbiAgICBcIkFcIjogZm9ybWF0VVRDV2Vla2RheSxcbiAgICBcImJcIjogZm9ybWF0VVRDU2hvcnRNb250aCxcbiAgICBcIkJcIjogZm9ybWF0VVRDTW9udGgsXG4gICAgXCJjXCI6IG51bGwsXG4gICAgXCJkXCI6IGZvcm1hdFVUQ0RheU9mTW9udGgsXG4gICAgXCJlXCI6IGZvcm1hdFVUQ0RheU9mTW9udGgsXG4gICAgXCJIXCI6IGZvcm1hdFVUQ0hvdXIyNCxcbiAgICBcIklcIjogZm9ybWF0VVRDSG91cjEyLFxuICAgIFwialwiOiBmb3JtYXRVVENEYXlPZlllYXIsXG4gICAgXCJMXCI6IGZvcm1hdFVUQ01pbGxpc2Vjb25kcyxcbiAgICBcIm1cIjogZm9ybWF0VVRDTW9udGhOdW1iZXIsXG4gICAgXCJNXCI6IGZvcm1hdFVUQ01pbnV0ZXMsXG4gICAgXCJwXCI6IGZvcm1hdFVUQ1BlcmlvZCxcbiAgICBcIlNcIjogZm9ybWF0VVRDU2Vjb25kcyxcbiAgICBcIlVcIjogZm9ybWF0VVRDV2Vla051bWJlclN1bmRheSxcbiAgICBcIndcIjogZm9ybWF0VVRDV2Vla2RheU51bWJlcixcbiAgICBcIldcIjogZm9ybWF0VVRDV2Vla051bWJlck1vbmRheSxcbiAgICBcInhcIjogbnVsbCxcbiAgICBcIlhcIjogbnVsbCxcbiAgICBcInlcIjogZm9ybWF0VVRDWWVhcixcbiAgICBcIllcIjogZm9ybWF0VVRDRnVsbFllYXIsXG4gICAgXCJaXCI6IGZvcm1hdFVUQ1pvbmUsXG4gICAgXCIlXCI6IGZvcm1hdExpdGVyYWxQZXJjZW50XG4gIH07XG5cbiAgdmFyIHBhcnNlcyA9IHtcbiAgICBcImFcIjogcGFyc2VTaG9ydFdlZWtkYXksXG4gICAgXCJBXCI6IHBhcnNlV2Vla2RheSxcbiAgICBcImJcIjogcGFyc2VTaG9ydE1vbnRoLFxuICAgIFwiQlwiOiBwYXJzZU1vbnRoLFxuICAgIFwiY1wiOiBwYXJzZUxvY2FsZURhdGVUaW1lLFxuICAgIFwiZFwiOiBwYXJzZURheU9mTW9udGgsXG4gICAgXCJlXCI6IHBhcnNlRGF5T2ZNb250aCxcbiAgICBcIkhcIjogcGFyc2VIb3VyMjQsXG4gICAgXCJJXCI6IHBhcnNlSG91cjI0LFxuICAgIFwialwiOiBwYXJzZURheU9mWWVhcixcbiAgICBcIkxcIjogcGFyc2VNaWxsaXNlY29uZHMsXG4gICAgXCJtXCI6IHBhcnNlTW9udGhOdW1iZXIsXG4gICAgXCJNXCI6IHBhcnNlTWludXRlcyxcbiAgICBcInBcIjogcGFyc2VQZXJpb2QsXG4gICAgXCJTXCI6IHBhcnNlU2Vjb25kcyxcbiAgICBcIlVcIjogcGFyc2VXZWVrTnVtYmVyU3VuZGF5LFxuICAgIFwid1wiOiBwYXJzZVdlZWtkYXlOdW1iZXIsXG4gICAgXCJXXCI6IHBhcnNlV2Vla051bWJlck1vbmRheSxcbiAgICBcInhcIjogcGFyc2VMb2NhbGVEYXRlLFxuICAgIFwiWFwiOiBwYXJzZUxvY2FsZVRpbWUsXG4gICAgXCJ5XCI6IHBhcnNlWWVhcixcbiAgICBcIllcIjogcGFyc2VGdWxsWWVhcixcbiAgICBcIlpcIjogcGFyc2Vab25lLFxuICAgIFwiJVwiOiBwYXJzZUxpdGVyYWxQZXJjZW50XG4gIH07XG5cbiAgLy8gVGhlc2UgcmVjdXJzaXZlIGRpcmVjdGl2ZSBkZWZpbml0aW9ucyBtdXN0IGJlIGRlZmVycmVkLlxuICBmb3JtYXRzLnggPSBuZXdGb3JtYXQobG9jYWxlX2RhdGUsIGZvcm1hdHMpO1xuICBmb3JtYXRzLlggPSBuZXdGb3JtYXQobG9jYWxlX3RpbWUsIGZvcm1hdHMpO1xuICBmb3JtYXRzLmMgPSBuZXdGb3JtYXQobG9jYWxlX2RhdGVUaW1lLCBmb3JtYXRzKTtcbiAgdXRjRm9ybWF0cy54ID0gbmV3Rm9ybWF0KGxvY2FsZV9kYXRlLCB1dGNGb3JtYXRzKTtcbiAgdXRjRm9ybWF0cy5YID0gbmV3Rm9ybWF0KGxvY2FsZV90aW1lLCB1dGNGb3JtYXRzKTtcbiAgdXRjRm9ybWF0cy5jID0gbmV3Rm9ybWF0KGxvY2FsZV9kYXRlVGltZSwgdXRjRm9ybWF0cyk7XG5cbiAgZnVuY3Rpb24gbmV3Rm9ybWF0KHNwZWNpZmllciwgZm9ybWF0cykge1xuICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICB2YXIgc3RyaW5nID0gW10sXG4gICAgICAgICAgaSA9IC0xLFxuICAgICAgICAgIGogPSAwLFxuICAgICAgICAgIG4gPSBzcGVjaWZpZXIubGVuZ3RoLFxuICAgICAgICAgIGMsXG4gICAgICAgICAgcGFkLFxuICAgICAgICAgIGZvcm1hdDtcblxuICAgICAgaWYgKCEoZGF0ZSBpbnN0YW5jZW9mIERhdGUpKSBkYXRlID0gbmV3IERhdGUoK2RhdGUpO1xuXG4gICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICBpZiAoc3BlY2lmaWVyLmNoYXJDb2RlQXQoaSkgPT09IDM3KSB7XG4gICAgICAgICAgc3RyaW5nLnB1c2goc3BlY2lmaWVyLnNsaWNlKGosIGkpKTtcbiAgICAgICAgICBpZiAoKHBhZCA9IHBhZHNbYyA9IHNwZWNpZmllci5jaGFyQXQoKytpKV0pICE9IG51bGwpIGMgPSBzcGVjaWZpZXIuY2hhckF0KCsraSk7XG4gICAgICAgICAgZWxzZSBwYWQgPSBjID09PSBcImVcIiA/IFwiIFwiIDogXCIwXCI7XG4gICAgICAgICAgaWYgKGZvcm1hdCA9IGZvcm1hdHNbY10pIGMgPSBmb3JtYXQoZGF0ZSwgcGFkKTtcbiAgICAgICAgICBzdHJpbmcucHVzaChjKTtcbiAgICAgICAgICBqID0gaSArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RyaW5nLnB1c2goc3BlY2lmaWVyLnNsaWNlKGosIGkpKTtcbiAgICAgIHJldHVybiBzdHJpbmcuam9pbihcIlwiKTtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gbmV3UGFyc2Uoc3BlY2lmaWVyLCBuZXdEYXRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHN0cmluZykge1xuICAgICAgdmFyIGQgPSBuZXdZZWFyKDE5MDApLFxuICAgICAgICAgIGkgPSBwYXJzZVNwZWNpZmllcihkLCBzcGVjaWZpZXIsIHN0cmluZyArPSBcIlwiLCAwKTtcbiAgICAgIGlmIChpICE9IHN0cmluZy5sZW5ndGgpIHJldHVybiBudWxsO1xuXG4gICAgICAvLyBUaGUgYW0tcG0gZmxhZyBpcyAwIGZvciBBTSwgYW5kIDEgZm9yIFBNLlxuICAgICAgaWYgKFwicFwiIGluIGQpIGQuSCA9IGQuSCAlIDEyICsgZC5wICogMTI7XG5cbiAgICAgIC8vIENvbnZlcnQgZGF5LW9mLXdlZWsgYW5kIHdlZWstb2YteWVhciB0byBkYXktb2YteWVhci5cbiAgICAgIGlmIChcIldcIiBpbiBkIHx8IFwiVVwiIGluIGQpIHtcbiAgICAgICAgaWYgKCEoXCJ3XCIgaW4gZCkpIGQudyA9IFwiV1wiIGluIGQgPyAxIDogMDtcbiAgICAgICAgdmFyIGRheSQkMSA9IFwiWlwiIGluIGQgPyB1dGNEYXRlKG5ld1llYXIoZC55KSkuZ2V0VVRDRGF5KCkgOiBuZXdEYXRlKG5ld1llYXIoZC55KSkuZ2V0RGF5KCk7XG4gICAgICAgIGQubSA9IDA7XG4gICAgICAgIGQuZCA9IFwiV1wiIGluIGQgPyAoZC53ICsgNikgJSA3ICsgZC5XICogNyAtIChkYXkkJDEgKyA1KSAlIDcgOiBkLncgKyBkLlUgKiA3IC0gKGRheSQkMSArIDYpICUgNztcbiAgICAgIH1cblxuICAgICAgLy8gSWYgYSB0aW1lIHpvbmUgaXMgc3BlY2lmaWVkLCBhbGwgZmllbGRzIGFyZSBpbnRlcnByZXRlZCBhcyBVVEMgYW5kIHRoZW5cbiAgICAgIC8vIG9mZnNldCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCB0aW1lIHpvbmUuXG4gICAgICBpZiAoXCJaXCIgaW4gZCkge1xuICAgICAgICBkLkggKz0gZC5aIC8gMTAwIHwgMDtcbiAgICAgICAgZC5NICs9IGQuWiAlIDEwMDtcbiAgICAgICAgcmV0dXJuIHV0Y0RhdGUoZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIE90aGVyd2lzZSwgYWxsIGZpZWxkcyBhcmUgaW4gbG9jYWwgdGltZS5cbiAgICAgIHJldHVybiBuZXdEYXRlKGQpO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVNwZWNpZmllcihkLCBzcGVjaWZpZXIsIHN0cmluZywgaikge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbiA9IHNwZWNpZmllci5sZW5ndGgsXG4gICAgICAgIG0gPSBzdHJpbmcubGVuZ3RoLFxuICAgICAgICBjLFxuICAgICAgICBwYXJzZTtcblxuICAgIHdoaWxlIChpIDwgbikge1xuICAgICAgaWYgKGogPj0gbSkgcmV0dXJuIC0xO1xuICAgICAgYyA9IHNwZWNpZmllci5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICBpZiAoYyA9PT0gMzcpIHtcbiAgICAgICAgYyA9IHNwZWNpZmllci5jaGFyQXQoaSsrKTtcbiAgICAgICAgcGFyc2UgPSBwYXJzZXNbYyBpbiBwYWRzID8gc3BlY2lmaWVyLmNoYXJBdChpKyspIDogY107XG4gICAgICAgIGlmICghcGFyc2UgfHwgKChqID0gcGFyc2UoZCwgc3RyaW5nLCBqKSkgPCAwKSkgcmV0dXJuIC0xO1xuICAgICAgfSBlbHNlIGlmIChjICE9IHN0cmluZy5jaGFyQ29kZUF0KGorKykpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBqO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VQZXJpb2QoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSBwZXJpb2RSZS5leGVjKHN0cmluZy5zbGljZShpKSk7XG4gICAgcmV0dXJuIG4gPyAoZC5wID0gcGVyaW9kTG9va3VwW25bMF0udG9Mb3dlckNhc2UoKV0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlU2hvcnRXZWVrZGF5KGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gc2hvcnRXZWVrZGF5UmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICAgIHJldHVybiBuID8gKGQudyA9IHNob3J0V2Vla2RheUxvb2t1cFtuWzBdLnRvTG93ZXJDYXNlKCldLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVdlZWtkYXkoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSB3ZWVrZGF5UmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICAgIHJldHVybiBuID8gKGQudyA9IHdlZWtkYXlMb29rdXBbblswXS50b0xvd2VyQ2FzZSgpXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VTaG9ydE1vbnRoKGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gc2hvcnRNb250aFJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgICByZXR1cm4gbiA/IChkLm0gPSBzaG9ydE1vbnRoTG9va3VwW25bMF0udG9Mb3dlckNhc2UoKV0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTW9udGgoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSBtb250aFJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgICByZXR1cm4gbiA/IChkLm0gPSBtb250aExvb2t1cFtuWzBdLnRvTG93ZXJDYXNlKCldLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZUxvY2FsZURhdGVUaW1lKGQsIHN0cmluZywgaSkge1xuICAgIHJldHVybiBwYXJzZVNwZWNpZmllcihkLCBsb2NhbGVfZGF0ZVRpbWUsIHN0cmluZywgaSk7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZUxvY2FsZURhdGUoZCwgc3RyaW5nLCBpKSB7XG4gICAgcmV0dXJuIHBhcnNlU3BlY2lmaWVyKGQsIGxvY2FsZV9kYXRlLCBzdHJpbmcsIGkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VMb2NhbGVUaW1lKGQsIHN0cmluZywgaSkge1xuICAgIHJldHVybiBwYXJzZVNwZWNpZmllcihkLCBsb2NhbGVfdGltZSwgc3RyaW5nLCBpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFNob3J0V2Vla2RheShkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV9zaG9ydFdlZWtkYXlzW2QuZ2V0RGF5KCldO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0V2Vla2RheShkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV93ZWVrZGF5c1tkLmdldERheSgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFNob3J0TW9udGgoZCkge1xuICAgIHJldHVybiBsb2NhbGVfc2hvcnRNb250aHNbZC5nZXRNb250aCgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdE1vbnRoKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX21vbnRoc1tkLmdldE1vbnRoKCldO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0UGVyaW9kKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX3BlcmlvZHNbKyhkLmdldEhvdXJzKCkgPj0gMTIpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1Nob3J0V2Vla2RheShkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV9zaG9ydFdlZWtkYXlzW2QuZ2V0VVRDRGF5KCldO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0VVRDV2Vla2RheShkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV93ZWVrZGF5c1tkLmdldFVUQ0RheSgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1Nob3J0TW9udGgoZCkge1xuICAgIHJldHVybiBsb2NhbGVfc2hvcnRNb250aHNbZC5nZXRVVENNb250aCgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ01vbnRoKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX21vbnRoc1tkLmdldFVUQ01vbnRoKCldO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0VVRDUGVyaW9kKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX3BlcmlvZHNbKyhkLmdldFVUQ0hvdXJzKCkgPj0gMTIpXTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZm9ybWF0OiBmdW5jdGlvbihzcGVjaWZpZXIpIHtcbiAgICAgIHZhciBmID0gbmV3Rm9ybWF0KHNwZWNpZmllciArPSBcIlwiLCBmb3JtYXRzKTtcbiAgICAgIGYudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHNwZWNpZmllcjsgfTtcbiAgICAgIHJldHVybiBmO1xuICAgIH0sXG4gICAgcGFyc2U6IGZ1bmN0aW9uKHNwZWNpZmllcikge1xuICAgICAgdmFyIHAgPSBuZXdQYXJzZShzcGVjaWZpZXIgKz0gXCJcIiwgbG9jYWxEYXRlKTtcbiAgICAgIHAudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHNwZWNpZmllcjsgfTtcbiAgICAgIHJldHVybiBwO1xuICAgIH0sXG4gICAgdXRjRm9ybWF0OiBmdW5jdGlvbihzcGVjaWZpZXIpIHtcbiAgICAgIHZhciBmID0gbmV3Rm9ybWF0KHNwZWNpZmllciArPSBcIlwiLCB1dGNGb3JtYXRzKTtcbiAgICAgIGYudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHNwZWNpZmllcjsgfTtcbiAgICAgIHJldHVybiBmO1xuICAgIH0sXG4gICAgdXRjUGFyc2U6IGZ1bmN0aW9uKHNwZWNpZmllcikge1xuICAgICAgdmFyIHAgPSBuZXdQYXJzZShzcGVjaWZpZXIsIHV0Y0RhdGUpO1xuICAgICAgcC50b1N0cmluZyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gc3BlY2lmaWVyOyB9O1xuICAgICAgcmV0dXJuIHA7XG4gICAgfVxuICB9O1xufVxuXG52YXIgcGFkcyA9IHtcIi1cIjogXCJcIiwgXCJfXCI6IFwiIFwiLCBcIjBcIjogXCIwXCJ9O1xudmFyIG51bWJlclJlID0gL15cXHMqXFxkKy87XG52YXIgcGVyY2VudFJlID0gL14lLztcbnZhciByZXF1b3RlUmUgPSAvW1xcXFxcXF5cXCRcXCpcXCtcXD9cXHxcXFtcXF1cXChcXClcXC5cXHtcXH1dL2c7XG5cbmZ1bmN0aW9uIHBhZCh2YWx1ZSwgZmlsbCwgd2lkdGgpIHtcbiAgdmFyIHNpZ24gPSB2YWx1ZSA8IDAgPyBcIi1cIiA6IFwiXCIsXG4gICAgICBzdHJpbmcgPSAoc2lnbiA/IC12YWx1ZSA6IHZhbHVlKSArIFwiXCIsXG4gICAgICBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuICByZXR1cm4gc2lnbiArIChsZW5ndGggPCB3aWR0aCA/IG5ldyBBcnJheSh3aWR0aCAtIGxlbmd0aCArIDEpLmpvaW4oZmlsbCkgKyBzdHJpbmcgOiBzdHJpbmcpO1xufVxuXG5mdW5jdGlvbiByZXF1b3RlKHMpIHtcbiAgcmV0dXJuIHMucmVwbGFjZShyZXF1b3RlUmUsIFwiXFxcXCQmXCIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRSZShuYW1lcykge1xuICByZXR1cm4gbmV3IFJlZ0V4cChcIl4oPzpcIiArIG5hbWVzLm1hcChyZXF1b3RlKS5qb2luKFwifFwiKSArIFwiKVwiLCBcImlcIik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdExvb2t1cChuYW1lcykge1xuICB2YXIgbWFwID0ge30sIGkgPSAtMSwgbiA9IG5hbWVzLmxlbmd0aDtcbiAgd2hpbGUgKCsraSA8IG4pIG1hcFtuYW1lc1tpXS50b0xvd2VyQ2FzZSgpXSA9IGk7XG4gIHJldHVybiBtYXA7XG59XG5cbmZ1bmN0aW9uIHBhcnNlV2Vla2RheU51bWJlcihkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMSkpO1xuICByZXR1cm4gbiA/IChkLncgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZVdlZWtOdW1iZXJTdW5kYXkoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICByZXR1cm4gbiA/IChkLlUgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZVdlZWtOdW1iZXJNb25kYXkoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICByZXR1cm4gbiA/IChkLlcgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZUZ1bGxZZWFyKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyA0KSk7XG4gIHJldHVybiBuID8gKGQueSA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlWWVhcihkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLnkgPSArblswXSArICgrblswXSA+IDY4ID8gMTkwMCA6IDIwMDApLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlWm9uZShkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSAvXihaKXwoWystXVxcZFxcZCkoPzpcXDo/KFxcZFxcZCkpPy8uZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDYpKTtcbiAgcmV0dXJuIG4gPyAoZC5aID0gblsxXSA/IDAgOiAtKG5bMl0gKyAoblszXSB8fCBcIjAwXCIpKSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZU1vbnRoTnVtYmVyKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAyKSk7XG4gIHJldHVybiBuID8gKGQubSA9IG5bMF0gLSAxLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRGF5T2ZNb250aChkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLmQgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZURheU9mWWVhcihkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMykpO1xuICByZXR1cm4gbiA/IChkLm0gPSAwLCBkLmQgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZUhvdXIyNChkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLkggPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZU1pbnV0ZXMoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgcmV0dXJuIG4gPyAoZC5NID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VTZWNvbmRzKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAyKSk7XG4gIHJldHVybiBuID8gKGQuUyA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlTWlsbGlzZWNvbmRzKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAzKSk7XG4gIHJldHVybiBuID8gKGQuTCA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlTGl0ZXJhbFBlcmNlbnQoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gcGVyY2VudFJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAxKSk7XG4gIHJldHVybiBuID8gaSArIG5bMF0ubGVuZ3RoIDogLTE7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdERheU9mTW9udGgoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0RGF0ZSgpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0SG91cjI0KGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldEhvdXJzKCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRIb3VyMTIoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0SG91cnMoKSAlIDEyIHx8IDEyLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RGF5T2ZZZWFyKGQsIHApIHtcbiAgcmV0dXJuIHBhZCgxICsgZGF5LmNvdW50KHllYXIoZCksIGQpLCBwLCAzKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0TWlsbGlzZWNvbmRzKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldE1pbGxpc2Vjb25kcygpLCBwLCAzKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0TW9udGhOdW1iZXIoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0TW9udGgoKSArIDEsIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRNaW51dGVzKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldE1pbnV0ZXMoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFNlY29uZHMoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0U2Vjb25kcygpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0V2Vla051bWJlclN1bmRheShkLCBwKSB7XG4gIHJldHVybiBwYWQoc3VuZGF5LmNvdW50KHllYXIoZCksIGQpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0V2Vla2RheU51bWJlcihkKSB7XG4gIHJldHVybiBkLmdldERheSgpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRXZWVrTnVtYmVyTW9uZGF5KGQsIHApIHtcbiAgcmV0dXJuIHBhZChtb25kYXkuY291bnQoeWVhcihkKSwgZCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRZZWFyKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldEZ1bGxZZWFyKCkgJSAxMDAsIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRGdWxsWWVhcihkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRGdWxsWWVhcigpICUgMTAwMDAsIHAsIDQpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRab25lKGQpIHtcbiAgdmFyIHogPSBkLmdldFRpbWV6b25lT2Zmc2V0KCk7XG4gIHJldHVybiAoeiA+IDAgPyBcIi1cIiA6ICh6ICo9IC0xLCBcIitcIikpXG4gICAgICArIHBhZCh6IC8gNjAgfCAwLCBcIjBcIiwgMilcbiAgICAgICsgcGFkKHogJSA2MCwgXCIwXCIsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENEYXlPZk1vbnRoKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldFVUQ0RhdGUoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ0hvdXIyNChkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRVVENIb3VycygpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDSG91cjEyKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldFVUQ0hvdXJzKCkgJSAxMiB8fCAxMiwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ0RheU9mWWVhcihkLCBwKSB7XG4gIHJldHVybiBwYWQoMSArIHV0Y0RheS5jb3VudCh1dGNZZWFyKGQpLCBkKSwgcCwgMyk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ01pbGxpc2Vjb25kcyhkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRVVENNaWxsaXNlY29uZHMoKSwgcCwgMyk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ01vbnRoTnVtYmVyKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldFVUQ01vbnRoKCkgKyAxLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDTWludXRlcyhkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRVVENNaW51dGVzKCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENTZWNvbmRzKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldFVUQ1NlY29uZHMoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1dlZWtOdW1iZXJTdW5kYXkoZCwgcCkge1xuICByZXR1cm4gcGFkKHV0Y1N1bmRheS5jb3VudCh1dGNZZWFyKGQpLCBkKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1dlZWtkYXlOdW1iZXIoZCkge1xuICByZXR1cm4gZC5nZXRVVENEYXkoKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDV2Vla051bWJlck1vbmRheShkLCBwKSB7XG4gIHJldHVybiBwYWQodXRjTW9uZGF5LmNvdW50KHV0Y1llYXIoZCksIGQpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDWWVhcihkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRVVENGdWxsWWVhcigpICUgMTAwLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDRnVsbFllYXIoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0VVRDRnVsbFllYXIoKSAlIDEwMDAwLCBwLCA0KTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDWm9uZSgpIHtcbiAgcmV0dXJuIFwiKzAwMDBcIjtcbn1cblxuZnVuY3Rpb24gZm9ybWF0TGl0ZXJhbFBlcmNlbnQoKSB7XG4gIHJldHVybiBcIiVcIjtcbn1cblxudmFyIGxvY2FsZSQyO1xuXG5cblxuXG5cbmRlZmF1bHRMb2NhbGUkMSh7XG4gIGRhdGVUaW1lOiBcIiV4LCAlWFwiLFxuICBkYXRlOiBcIiUtbS8lLWQvJVlcIixcbiAgdGltZTogXCIlLUk6JU06JVMgJXBcIixcbiAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgZGF5czogW1wiU3VuZGF5XCIsIFwiTW9uZGF5XCIsIFwiVHVlc2RheVwiLCBcIldlZG5lc2RheVwiLCBcIlRodXJzZGF5XCIsIFwiRnJpZGF5XCIsIFwiU2F0dXJkYXlcIl0sXG4gIHNob3J0RGF5czogW1wiU3VuXCIsIFwiTW9uXCIsIFwiVHVlXCIsIFwiV2VkXCIsIFwiVGh1XCIsIFwiRnJpXCIsIFwiU2F0XCJdLFxuICBtb250aHM6IFtcIkphbnVhcnlcIiwgXCJGZWJydWFyeVwiLCBcIk1hcmNoXCIsIFwiQXByaWxcIiwgXCJNYXlcIiwgXCJKdW5lXCIsIFwiSnVseVwiLCBcIkF1Z3VzdFwiLCBcIlNlcHRlbWJlclwiLCBcIk9jdG9iZXJcIiwgXCJOb3ZlbWJlclwiLCBcIkRlY2VtYmVyXCJdLFxuICBzaG9ydE1vbnRoczogW1wiSmFuXCIsIFwiRmViXCIsIFwiTWFyXCIsIFwiQXByXCIsIFwiTWF5XCIsIFwiSnVuXCIsIFwiSnVsXCIsIFwiQXVnXCIsIFwiU2VwXCIsIFwiT2N0XCIsIFwiTm92XCIsIFwiRGVjXCJdXG59KTtcblxuZnVuY3Rpb24gZGVmYXVsdExvY2FsZSQxKGRlZmluaXRpb24pIHtcbiAgbG9jYWxlJDIgPSBmb3JtYXRMb2NhbGUkMShkZWZpbml0aW9uKTtcbiAgZXhwb3J0cy50aW1lRm9ybWF0ID0gbG9jYWxlJDIuZm9ybWF0O1xuICBleHBvcnRzLnRpbWVQYXJzZSA9IGxvY2FsZSQyLnBhcnNlO1xuICBleHBvcnRzLnV0Y0Zvcm1hdCA9IGxvY2FsZSQyLnV0Y0Zvcm1hdDtcbiAgZXhwb3J0cy51dGNQYXJzZSA9IGxvY2FsZSQyLnV0Y1BhcnNlO1xuICByZXR1cm4gbG9jYWxlJDI7XG59XG5cbnZhciBpc29TcGVjaWZpZXIgPSBcIiVZLSVtLSVkVCVIOiVNOiVTLiVMWlwiO1xuXG5mdW5jdGlvbiBmb3JtYXRJc29OYXRpdmUoZGF0ZSkge1xuICByZXR1cm4gZGF0ZS50b0lTT1N0cmluZygpO1xufVxuXG52YXIgZm9ybWF0SXNvID0gRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmdcbiAgICA/IGZvcm1hdElzb05hdGl2ZVxuICAgIDogZXhwb3J0cy51dGNGb3JtYXQoaXNvU3BlY2lmaWVyKTtcblxuZnVuY3Rpb24gcGFyc2VJc29OYXRpdmUoc3RyaW5nKSB7XG4gIHZhciBkYXRlID0gbmV3IERhdGUoc3RyaW5nKTtcbiAgcmV0dXJuIGlzTmFOKGRhdGUpID8gbnVsbCA6IGRhdGU7XG59XG5cbnZhciBwYXJzZUlzbyA9ICtuZXcgRGF0ZShcIjIwMDAtMDEtMDFUMDA6MDA6MDAuMDAwWlwiKVxuICAgID8gcGFyc2VJc29OYXRpdmVcbiAgICA6IGV4cG9ydHMudXRjUGFyc2UoaXNvU3BlY2lmaWVyKTtcblxudmFyIGFycmF5JDIgPSBBcnJheS5wcm90b3R5cGU7XG5cbnZhciBtYXAkMyA9IGFycmF5JDIubWFwO1xudmFyIHNsaWNlJDMgPSBhcnJheSQyLnNsaWNlO1xuXG52YXIgaW1wbGljaXQgPSB7bmFtZTogXCJpbXBsaWNpdFwifTtcblxuZnVuY3Rpb24gb3JkaW5hbChyYW5nZSkge1xuICB2YXIgaW5kZXggPSBtYXAkMSgpLFxuICAgICAgZG9tYWluID0gW10sXG4gICAgICB1bmtub3duID0gaW1wbGljaXQ7XG5cbiAgcmFuZ2UgPSByYW5nZSA9PSBudWxsID8gW10gOiBzbGljZSQzLmNhbGwocmFuZ2UpO1xuXG4gIGZ1bmN0aW9uIHNjYWxlKGQpIHtcbiAgICB2YXIga2V5ID0gZCArIFwiXCIsIGkgPSBpbmRleC5nZXQoa2V5KTtcbiAgICBpZiAoIWkpIHtcbiAgICAgIGlmICh1bmtub3duICE9PSBpbXBsaWNpdCkgcmV0dXJuIHVua25vd247XG4gICAgICBpbmRleC5zZXQoa2V5LCBpID0gZG9tYWluLnB1c2goZCkpO1xuICAgIH1cbiAgICByZXR1cm4gcmFuZ2VbKGkgLSAxKSAlIHJhbmdlLmxlbmd0aF07XG4gIH1cblxuICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZG9tYWluLnNsaWNlKCk7XG4gICAgZG9tYWluID0gW10sIGluZGV4ID0gbWFwJDEoKTtcbiAgICB2YXIgaSA9IC0xLCBuID0gXy5sZW5ndGgsIGQsIGtleTtcbiAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFpbmRleC5oYXMoa2V5ID0gKGQgPSBfW2ldKSArIFwiXCIpKSBpbmRleC5zZXQoa2V5LCBkb21haW4ucHVzaChkKSk7XG4gICAgcmV0dXJuIHNjYWxlO1xuICB9O1xuXG4gIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJhbmdlID0gc2xpY2UkMy5jYWxsKF8pLCBzY2FsZSkgOiByYW5nZS5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLnVua25vd24gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodW5rbm93biA9IF8sIHNjYWxlKSA6IHVua25vd247XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBvcmRpbmFsKClcbiAgICAgICAgLmRvbWFpbihkb21haW4pXG4gICAgICAgIC5yYW5nZShyYW5nZSlcbiAgICAgICAgLnVua25vd24odW5rbm93bik7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG5mdW5jdGlvbiBiYW5kKCkge1xuICB2YXIgc2NhbGUgPSBvcmRpbmFsKCkudW5rbm93bih1bmRlZmluZWQpLFxuICAgICAgZG9tYWluID0gc2NhbGUuZG9tYWluLFxuICAgICAgb3JkaW5hbFJhbmdlID0gc2NhbGUucmFuZ2UsXG4gICAgICByYW5nZSQkMSA9IFswLCAxXSxcbiAgICAgIHN0ZXAsXG4gICAgICBiYW5kd2lkdGgsXG4gICAgICByb3VuZCA9IGZhbHNlLFxuICAgICAgcGFkZGluZ0lubmVyID0gMCxcbiAgICAgIHBhZGRpbmdPdXRlciA9IDAsXG4gICAgICBhbGlnbiA9IDAuNTtcblxuICBkZWxldGUgc2NhbGUudW5rbm93bjtcblxuICBmdW5jdGlvbiByZXNjYWxlKCkge1xuICAgIHZhciBuID0gZG9tYWluKCkubGVuZ3RoLFxuICAgICAgICByZXZlcnNlID0gcmFuZ2UkJDFbMV0gPCByYW5nZSQkMVswXSxcbiAgICAgICAgc3RhcnQgPSByYW5nZSQkMVtyZXZlcnNlIC0gMF0sXG4gICAgICAgIHN0b3AgPSByYW5nZSQkMVsxIC0gcmV2ZXJzZV07XG4gICAgc3RlcCA9IChzdG9wIC0gc3RhcnQpIC8gTWF0aC5tYXgoMSwgbiAtIHBhZGRpbmdJbm5lciArIHBhZGRpbmdPdXRlciAqIDIpO1xuICAgIGlmIChyb3VuZCkgc3RlcCA9IE1hdGguZmxvb3Ioc3RlcCk7XG4gICAgc3RhcnQgKz0gKHN0b3AgLSBzdGFydCAtIHN0ZXAgKiAobiAtIHBhZGRpbmdJbm5lcikpICogYWxpZ247XG4gICAgYmFuZHdpZHRoID0gc3RlcCAqICgxIC0gcGFkZGluZ0lubmVyKTtcbiAgICBpZiAocm91bmQpIHN0YXJ0ID0gTWF0aC5yb3VuZChzdGFydCksIGJhbmR3aWR0aCA9IE1hdGgucm91bmQoYmFuZHdpZHRoKTtcbiAgICB2YXIgdmFsdWVzID0gcmFuZ2UobikubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIHN0YXJ0ICsgc3RlcCAqIGk7IH0pO1xuICAgIHJldHVybiBvcmRpbmFsUmFuZ2UocmV2ZXJzZSA/IHZhbHVlcy5yZXZlcnNlKCkgOiB2YWx1ZXMpO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbihfKSwgcmVzY2FsZSgpKSA6IGRvbWFpbigpO1xuICB9O1xuXG4gIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJhbmdlJCQxID0gWytfWzBdLCArX1sxXV0sIHJlc2NhbGUoKSkgOiByYW5nZSQkMS5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLnJhbmdlUm91bmQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIHJhbmdlJCQxID0gWytfWzBdLCArX1sxXV0sIHJvdW5kID0gdHJ1ZSwgcmVzY2FsZSgpO1xuICB9O1xuXG4gIHNjYWxlLmJhbmR3aWR0aCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBiYW5kd2lkdGg7XG4gIH07XG5cbiAgc2NhbGUuc3RlcCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBzdGVwO1xuICB9O1xuXG4gIHNjYWxlLnJvdW5kID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJvdW5kID0gISFfLCByZXNjYWxlKCkpIDogcm91bmQ7XG4gIH07XG5cbiAgc2NhbGUucGFkZGluZyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nSW5uZXIgPSBwYWRkaW5nT3V0ZXIgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBfKSksIHJlc2NhbGUoKSkgOiBwYWRkaW5nSW5uZXI7XG4gIH07XG5cbiAgc2NhbGUucGFkZGluZ0lubmVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdJbm5lciA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIF8pKSwgcmVzY2FsZSgpKSA6IHBhZGRpbmdJbm5lcjtcbiAgfTtcblxuICBzY2FsZS5wYWRkaW5nT3V0ZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ091dGVyID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgXykpLCByZXNjYWxlKCkpIDogcGFkZGluZ091dGVyO1xuICB9O1xuXG4gIHNjYWxlLmFsaWduID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFsaWduID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgXykpLCByZXNjYWxlKCkpIDogYWxpZ247XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBiYW5kKClcbiAgICAgICAgLmRvbWFpbihkb21haW4oKSlcbiAgICAgICAgLnJhbmdlKHJhbmdlJCQxKVxuICAgICAgICAucm91bmQocm91bmQpXG4gICAgICAgIC5wYWRkaW5nSW5uZXIocGFkZGluZ0lubmVyKVxuICAgICAgICAucGFkZGluZ091dGVyKHBhZGRpbmdPdXRlcilcbiAgICAgICAgLmFsaWduKGFsaWduKTtcbiAgfTtcblxuICByZXR1cm4gcmVzY2FsZSgpO1xufVxuXG5mdW5jdGlvbiBwb2ludGlzaChzY2FsZSkge1xuICB2YXIgY29weSA9IHNjYWxlLmNvcHk7XG5cbiAgc2NhbGUucGFkZGluZyA9IHNjYWxlLnBhZGRpbmdPdXRlcjtcbiAgZGVsZXRlIHNjYWxlLnBhZGRpbmdJbm5lcjtcbiAgZGVsZXRlIHNjYWxlLnBhZGRpbmdPdXRlcjtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHBvaW50aXNoKGNvcHkoKSk7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG5mdW5jdGlvbiBwb2ludCQ0KCkge1xuICByZXR1cm4gcG9pbnRpc2goYmFuZCgpLnBhZGRpbmdJbm5lcigxKSk7XG59XG5cbnZhciBjb25zdGFudCQ0ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG52YXIgbnVtYmVyJDEgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiAreDtcbn07XG5cbnZhciB1bml0ID0gWzAsIDFdO1xuXG5mdW5jdGlvbiBkZWludGVycG9sYXRlTGluZWFyKGEsIGIpIHtcbiAgcmV0dXJuIChiIC09IChhID0gK2EpKVxuICAgICAgPyBmdW5jdGlvbih4KSB7IHJldHVybiAoeCAtIGEpIC8gYjsgfVxuICAgICAgOiBjb25zdGFudCQ0KGIpO1xufVxuXG5mdW5jdGlvbiBkZWludGVycG9sYXRlQ2xhbXAoZGVpbnRlcnBvbGF0ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oYSwgYikge1xuICAgIHZhciBkID0gZGVpbnRlcnBvbGF0ZShhID0gK2EsIGIgPSArYik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHggPD0gYSA/IDAgOiB4ID49IGIgPyAxIDogZCh4KTsgfTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVpbnRlcnBvbGF0ZUNsYW1wKHJlaW50ZXJwb2xhdGUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgciA9IHJlaW50ZXJwb2xhdGUoYSA9ICthLCBiID0gK2IpO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7IHJldHVybiB0IDw9IDAgPyBhIDogdCA+PSAxID8gYiA6IHIodCk7IH07XG4gIH07XG59XG5cbmZ1bmN0aW9uIGJpbWFwKGRvbWFpbiwgcmFuZ2UkJDEsIGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUpIHtcbiAgdmFyIGQwID0gZG9tYWluWzBdLCBkMSA9IGRvbWFpblsxXSwgcjAgPSByYW5nZSQkMVswXSwgcjEgPSByYW5nZSQkMVsxXTtcbiAgaWYgKGQxIDwgZDApIGQwID0gZGVpbnRlcnBvbGF0ZShkMSwgZDApLCByMCA9IHJlaW50ZXJwb2xhdGUocjEsIHIwKTtcbiAgZWxzZSBkMCA9IGRlaW50ZXJwb2xhdGUoZDAsIGQxKSwgcjAgPSByZWludGVycG9sYXRlKHIwLCByMSk7XG4gIHJldHVybiBmdW5jdGlvbih4KSB7IHJldHVybiByMChkMCh4KSk7IH07XG59XG5cbmZ1bmN0aW9uIHBvbHltYXAoZG9tYWluLCByYW5nZSQkMSwgZGVpbnRlcnBvbGF0ZSwgcmVpbnRlcnBvbGF0ZSkge1xuICB2YXIgaiA9IE1hdGgubWluKGRvbWFpbi5sZW5ndGgsIHJhbmdlJCQxLmxlbmd0aCkgLSAxLFxuICAgICAgZCA9IG5ldyBBcnJheShqKSxcbiAgICAgIHIgPSBuZXcgQXJyYXkoaiksXG4gICAgICBpID0gLTE7XG5cbiAgLy8gUmV2ZXJzZSBkZXNjZW5kaW5nIGRvbWFpbnMuXG4gIGlmIChkb21haW5bal0gPCBkb21haW5bMF0pIHtcbiAgICBkb21haW4gPSBkb21haW4uc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgcmFuZ2UkJDEgPSByYW5nZSQkMS5zbGljZSgpLnJldmVyc2UoKTtcbiAgfVxuXG4gIHdoaWxlICgrK2kgPCBqKSB7XG4gICAgZFtpXSA9IGRlaW50ZXJwb2xhdGUoZG9tYWluW2ldLCBkb21haW5baSArIDFdKTtcbiAgICByW2ldID0gcmVpbnRlcnBvbGF0ZShyYW5nZSQkMVtpXSwgcmFuZ2UkJDFbaSArIDFdKTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbih4KSB7XG4gICAgdmFyIGkgPSBiaXNlY3RSaWdodChkb21haW4sIHgsIDEsIGopIC0gMTtcbiAgICByZXR1cm4gcltpXShkW2ldKHgpKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29weShzb3VyY2UsIHRhcmdldCkge1xuICByZXR1cm4gdGFyZ2V0XG4gICAgICAuZG9tYWluKHNvdXJjZS5kb21haW4oKSlcbiAgICAgIC5yYW5nZShzb3VyY2UucmFuZ2UoKSlcbiAgICAgIC5pbnRlcnBvbGF0ZShzb3VyY2UuaW50ZXJwb2xhdGUoKSlcbiAgICAgIC5jbGFtcChzb3VyY2UuY2xhbXAoKSk7XG59XG5cbi8vIGRlaW50ZXJwb2xhdGUoYSwgYikoeCkgdGFrZXMgYSBkb21haW4gdmFsdWUgeCBpbiBbYSxiXSBhbmQgcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXIgdCBpbiBbMCwxXS5cbi8vIHJlaW50ZXJwb2xhdGUoYSwgYikodCkgdGFrZXMgYSBwYXJhbWV0ZXIgdCBpbiBbMCwxXSBhbmQgcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyBkb21haW4gdmFsdWUgeCBpbiBbYSxiXS5cbmZ1bmN0aW9uIGNvbnRpbnVvdXMoZGVpbnRlcnBvbGF0ZSwgcmVpbnRlcnBvbGF0ZSkge1xuICB2YXIgZG9tYWluID0gdW5pdCxcbiAgICAgIHJhbmdlJCQxID0gdW5pdCxcbiAgICAgIGludGVycG9sYXRlJCQxID0gaW50ZXJwb2xhdGUsXG4gICAgICBjbGFtcCA9IGZhbHNlLFxuICAgICAgcGllY2V3aXNlLFxuICAgICAgb3V0cHV0LFxuICAgICAgaW5wdXQ7XG5cbiAgZnVuY3Rpb24gcmVzY2FsZSgpIHtcbiAgICBwaWVjZXdpc2UgPSBNYXRoLm1pbihkb21haW4ubGVuZ3RoLCByYW5nZSQkMS5sZW5ndGgpID4gMiA/IHBvbHltYXAgOiBiaW1hcDtcbiAgICBvdXRwdXQgPSBpbnB1dCA9IG51bGw7XG4gICAgcmV0dXJuIHNjYWxlO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIHJldHVybiAob3V0cHV0IHx8IChvdXRwdXQgPSBwaWVjZXdpc2UoZG9tYWluLCByYW5nZSQkMSwgY2xhbXAgPyBkZWludGVycG9sYXRlQ2xhbXAoZGVpbnRlcnBvbGF0ZSkgOiBkZWludGVycG9sYXRlLCBpbnRlcnBvbGF0ZSQkMSkpKSgreCk7XG4gIH1cblxuICBzY2FsZS5pbnZlcnQgPSBmdW5jdGlvbih5KSB7XG4gICAgcmV0dXJuIChpbnB1dCB8fCAoaW5wdXQgPSBwaWVjZXdpc2UocmFuZ2UkJDEsIGRvbWFpbiwgZGVpbnRlcnBvbGF0ZUxpbmVhciwgY2xhbXAgPyByZWludGVycG9sYXRlQ2xhbXAocmVpbnRlcnBvbGF0ZSkgOiByZWludGVycG9sYXRlKSkpKCt5KTtcbiAgfTtcblxuICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZG9tYWluID0gbWFwJDMuY2FsbChfLCBudW1iZXIkMSksIHJlc2NhbGUoKSkgOiBkb21haW4uc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSQkMSA9IHNsaWNlJDMuY2FsbChfKSwgcmVzY2FsZSgpKSA6IHJhbmdlJCQxLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUucmFuZ2VSb3VuZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gcmFuZ2UkJDEgPSBzbGljZSQzLmNhbGwoXyksIGludGVycG9sYXRlJCQxID0gaW50ZXJwb2xhdGVSb3VuZCwgcmVzY2FsZSgpO1xuICB9O1xuXG4gIHNjYWxlLmNsYW1wID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNsYW1wID0gISFfLCByZXNjYWxlKCkpIDogY2xhbXA7XG4gIH07XG5cbiAgc2NhbGUuaW50ZXJwb2xhdGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaW50ZXJwb2xhdGUkJDEgPSBfLCByZXNjYWxlKCkpIDogaW50ZXJwb2xhdGUkJDE7XG4gIH07XG5cbiAgcmV0dXJuIHJlc2NhbGUoKTtcbn1cblxudmFyIHRpY2tGb3JtYXQgPSBmdW5jdGlvbihkb21haW4sIGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgdmFyIHN0YXJ0ID0gZG9tYWluWzBdLFxuICAgICAgc3RvcCA9IGRvbWFpbltkb21haW4ubGVuZ3RoIC0gMV0sXG4gICAgICBzdGVwID0gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIGNvdW50ID09IG51bGwgPyAxMCA6IGNvdW50KSxcbiAgICAgIHByZWNpc2lvbjtcbiAgc3BlY2lmaWVyID0gZm9ybWF0U3BlY2lmaWVyKHNwZWNpZmllciA9PSBudWxsID8gXCIsZlwiIDogc3BlY2lmaWVyKTtcbiAgc3dpdGNoIChzcGVjaWZpZXIudHlwZSkge1xuICAgIGNhc2UgXCJzXCI6IHtcbiAgICAgIHZhciB2YWx1ZSA9IE1hdGgubWF4KE1hdGguYWJzKHN0YXJ0KSwgTWF0aC5hYnMoc3RvcCkpO1xuICAgICAgaWYgKHNwZWNpZmllci5wcmVjaXNpb24gPT0gbnVsbCAmJiAhaXNOYU4ocHJlY2lzaW9uID0gcHJlY2lzaW9uUHJlZml4KHN0ZXAsIHZhbHVlKSkpIHNwZWNpZmllci5wcmVjaXNpb24gPSBwcmVjaXNpb247XG4gICAgICByZXR1cm4gZXhwb3J0cy5mb3JtYXRQcmVmaXgoc3BlY2lmaWVyLCB2YWx1ZSk7XG4gICAgfVxuICAgIGNhc2UgXCJcIjpcbiAgICBjYXNlIFwiZVwiOlxuICAgIGNhc2UgXCJnXCI6XG4gICAgY2FzZSBcInBcIjpcbiAgICBjYXNlIFwiclwiOiB7XG4gICAgICBpZiAoc3BlY2lmaWVyLnByZWNpc2lvbiA9PSBudWxsICYmICFpc05hTihwcmVjaXNpb24gPSBwcmVjaXNpb25Sb3VuZChzdGVwLCBNYXRoLm1heChNYXRoLmFicyhzdGFydCksIE1hdGguYWJzKHN0b3ApKSkpKSBzcGVjaWZpZXIucHJlY2lzaW9uID0gcHJlY2lzaW9uIC0gKHNwZWNpZmllci50eXBlID09PSBcImVcIik7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSBcImZcIjpcbiAgICBjYXNlIFwiJVwiOiB7XG4gICAgICBpZiAoc3BlY2lmaWVyLnByZWNpc2lvbiA9PSBudWxsICYmICFpc05hTihwcmVjaXNpb24gPSBwcmVjaXNpb25GaXhlZChzdGVwKSkpIHNwZWNpZmllci5wcmVjaXNpb24gPSBwcmVjaXNpb24gLSAoc3BlY2lmaWVyLnR5cGUgPT09IFwiJVwiKSAqIDI7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4cG9ydHMuZm9ybWF0KHNwZWNpZmllcik7XG59O1xuXG5mdW5jdGlvbiBsaW5lYXJpc2goc2NhbGUpIHtcbiAgdmFyIGRvbWFpbiA9IHNjYWxlLmRvbWFpbjtcblxuICBzY2FsZS50aWNrcyA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgdmFyIGQgPSBkb21haW4oKTtcbiAgICByZXR1cm4gdGlja3MoZFswXSwgZFtkLmxlbmd0aCAtIDFdLCBjb3VudCA9PSBudWxsID8gMTAgOiBjb3VudCk7XG4gIH07XG5cbiAgc2NhbGUudGlja0Zvcm1hdCA9IGZ1bmN0aW9uKGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgICByZXR1cm4gdGlja0Zvcm1hdChkb21haW4oKSwgY291bnQsIHNwZWNpZmllcik7XG4gIH07XG5cbiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgdmFyIGQgPSBkb21haW4oKSxcbiAgICAgICAgaSA9IGQubGVuZ3RoIC0gMSxcbiAgICAgICAgbiA9IGNvdW50ID09IG51bGwgPyAxMCA6IGNvdW50LFxuICAgICAgICBzdGFydCA9IGRbMF0sXG4gICAgICAgIHN0b3AgPSBkW2ldLFxuICAgICAgICBzdGVwID0gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIG4pO1xuXG4gICAgaWYgKHN0ZXApIHtcbiAgICAgIHN0ZXAgPSB0aWNrU3RlcChNYXRoLmZsb29yKHN0YXJ0IC8gc3RlcCkgKiBzdGVwLCBNYXRoLmNlaWwoc3RvcCAvIHN0ZXApICogc3RlcCwgbik7XG4gICAgICBkWzBdID0gTWF0aC5mbG9vcihzdGFydCAvIHN0ZXApICogc3RlcDtcbiAgICAgIGRbaV0gPSBNYXRoLmNlaWwoc3RvcCAvIHN0ZXApICogc3RlcDtcbiAgICAgIGRvbWFpbihkKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2NhbGU7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG5mdW5jdGlvbiBsaW5lYXIkMigpIHtcbiAgdmFyIHNjYWxlID0gY29udGludW91cyhkZWludGVycG9sYXRlTGluZWFyLCBpbnRlcnBvbGF0ZU51bWJlcik7XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBjb3B5KHNjYWxlLCBsaW5lYXIkMigpKTtcbiAgfTtcblxuICByZXR1cm4gbGluZWFyaXNoKHNjYWxlKTtcbn1cblxuZnVuY3Rpb24gaWRlbnRpdHkkNCgpIHtcbiAgdmFyIGRvbWFpbiA9IFswLCAxXTtcblxuICBmdW5jdGlvbiBzY2FsZSh4KSB7XG4gICAgcmV0dXJuICt4O1xuICB9XG5cbiAgc2NhbGUuaW52ZXJ0ID0gc2NhbGU7XG5cbiAgc2NhbGUuZG9tYWluID0gc2NhbGUucmFuZ2UgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZG9tYWluID0gbWFwJDMuY2FsbChfLCBudW1iZXIkMSksIHNjYWxlKSA6IGRvbWFpbi5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gaWRlbnRpdHkkNCgpLmRvbWFpbihkb21haW4pO1xuICB9O1xuXG4gIHJldHVybiBsaW5lYXJpc2goc2NhbGUpO1xufVxuXG52YXIgbmljZSA9IGZ1bmN0aW9uKGRvbWFpbiwgaW50ZXJ2YWwpIHtcbiAgZG9tYWluID0gZG9tYWluLnNsaWNlKCk7XG5cbiAgdmFyIGkwID0gMCxcbiAgICAgIGkxID0gZG9tYWluLmxlbmd0aCAtIDEsXG4gICAgICB4MCA9IGRvbWFpbltpMF0sXG4gICAgICB4MSA9IGRvbWFpbltpMV0sXG4gICAgICB0O1xuXG4gIGlmICh4MSA8IHgwKSB7XG4gICAgdCA9IGkwLCBpMCA9IGkxLCBpMSA9IHQ7XG4gICAgdCA9IHgwLCB4MCA9IHgxLCB4MSA9IHQ7XG4gIH1cblxuICBkb21haW5baTBdID0gaW50ZXJ2YWwuZmxvb3IoeDApO1xuICBkb21haW5baTFdID0gaW50ZXJ2YWwuY2VpbCh4MSk7XG4gIHJldHVybiBkb21haW47XG59O1xuXG5mdW5jdGlvbiBkZWludGVycG9sYXRlKGEsIGIpIHtcbiAgcmV0dXJuIChiID0gTWF0aC5sb2coYiAvIGEpKVxuICAgICAgPyBmdW5jdGlvbih4KSB7IHJldHVybiBNYXRoLmxvZyh4IC8gYSkgLyBiOyB9XG4gICAgICA6IGNvbnN0YW50JDQoYik7XG59XG5cbmZ1bmN0aW9uIHJlaW50ZXJwb2xhdGUoYSwgYikge1xuICByZXR1cm4gYSA8IDBcbiAgICAgID8gZnVuY3Rpb24odCkgeyByZXR1cm4gLU1hdGgucG93KC1iLCB0KSAqIE1hdGgucG93KC1hLCAxIC0gdCk7IH1cbiAgICAgIDogZnVuY3Rpb24odCkgeyByZXR1cm4gTWF0aC5wb3coYiwgdCkgKiBNYXRoLnBvdyhhLCAxIC0gdCk7IH07XG59XG5cbmZ1bmN0aW9uIHBvdzEwKHgpIHtcbiAgcmV0dXJuIGlzRmluaXRlKHgpID8gKyhcIjFlXCIgKyB4KSA6IHggPCAwID8gMCA6IHg7XG59XG5cbmZ1bmN0aW9uIHBvd3AoYmFzZSkge1xuICByZXR1cm4gYmFzZSA9PT0gMTAgPyBwb3cxMFxuICAgICAgOiBiYXNlID09PSBNYXRoLkUgPyBNYXRoLmV4cFxuICAgICAgOiBmdW5jdGlvbih4KSB7IHJldHVybiBNYXRoLnBvdyhiYXNlLCB4KTsgfTtcbn1cblxuZnVuY3Rpb24gbG9ncChiYXNlKSB7XG4gIHJldHVybiBiYXNlID09PSBNYXRoLkUgPyBNYXRoLmxvZ1xuICAgICAgOiBiYXNlID09PSAxMCAmJiBNYXRoLmxvZzEwXG4gICAgICB8fCBiYXNlID09PSAyICYmIE1hdGgubG9nMlxuICAgICAgfHwgKGJhc2UgPSBNYXRoLmxvZyhiYXNlKSwgZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5sb2coeCkgLyBiYXNlOyB9KTtcbn1cblxuZnVuY3Rpb24gcmVmbGVjdChmKSB7XG4gIHJldHVybiBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIC1mKC14KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9nKCkge1xuICB2YXIgc2NhbGUgPSBjb250aW51b3VzKGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUpLmRvbWFpbihbMSwgMTBdKSxcbiAgICAgIGRvbWFpbiA9IHNjYWxlLmRvbWFpbixcbiAgICAgIGJhc2UgPSAxMCxcbiAgICAgIGxvZ3MgPSBsb2dwKDEwKSxcbiAgICAgIHBvd3MgPSBwb3dwKDEwKTtcblxuICBmdW5jdGlvbiByZXNjYWxlKCkge1xuICAgIGxvZ3MgPSBsb2dwKGJhc2UpLCBwb3dzID0gcG93cChiYXNlKTtcbiAgICBpZiAoZG9tYWluKClbMF0gPCAwKSBsb2dzID0gcmVmbGVjdChsb2dzKSwgcG93cyA9IHJlZmxlY3QocG93cyk7XG4gICAgcmV0dXJuIHNjYWxlO1xuICB9XG5cbiAgc2NhbGUuYmFzZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChiYXNlID0gK18sIHJlc2NhbGUoKSkgOiBiYXNlO1xuICB9O1xuXG4gIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4oXyksIHJlc2NhbGUoKSkgOiBkb21haW4oKTtcbiAgfTtcblxuICBzY2FsZS50aWNrcyA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgdmFyIGQgPSBkb21haW4oKSxcbiAgICAgICAgdSA9IGRbMF0sXG4gICAgICAgIHYgPSBkW2QubGVuZ3RoIC0gMV0sXG4gICAgICAgIHI7XG5cbiAgICBpZiAociA9IHYgPCB1KSBpID0gdSwgdSA9IHYsIHYgPSBpO1xuXG4gICAgdmFyIGkgPSBsb2dzKHUpLFxuICAgICAgICBqID0gbG9ncyh2KSxcbiAgICAgICAgcCxcbiAgICAgICAgayxcbiAgICAgICAgdCxcbiAgICAgICAgbiA9IGNvdW50ID09IG51bGwgPyAxMCA6ICtjb3VudCxcbiAgICAgICAgeiA9IFtdO1xuXG4gICAgaWYgKCEoYmFzZSAlIDEpICYmIGogLSBpIDwgbikge1xuICAgICAgaSA9IE1hdGgucm91bmQoaSkgLSAxLCBqID0gTWF0aC5yb3VuZChqKSArIDE7XG4gICAgICBpZiAodSA+IDApIGZvciAoOyBpIDwgajsgKytpKSB7XG4gICAgICAgIGZvciAoayA9IDEsIHAgPSBwb3dzKGkpOyBrIDwgYmFzZTsgKytrKSB7XG4gICAgICAgICAgdCA9IHAgKiBrO1xuICAgICAgICAgIGlmICh0IDwgdSkgY29udGludWU7XG4gICAgICAgICAgaWYgKHQgPiB2KSBicmVhaztcbiAgICAgICAgICB6LnB1c2godCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBmb3IgKDsgaSA8IGo7ICsraSkge1xuICAgICAgICBmb3IgKGsgPSBiYXNlIC0gMSwgcCA9IHBvd3MoaSk7IGsgPj0gMTsgLS1rKSB7XG4gICAgICAgICAgdCA9IHAgKiBrO1xuICAgICAgICAgIGlmICh0IDwgdSkgY29udGludWU7XG4gICAgICAgICAgaWYgKHQgPiB2KSBicmVhaztcbiAgICAgICAgICB6LnB1c2godCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgeiA9IHRpY2tzKGksIGosIE1hdGgubWluKGogLSBpLCBuKSkubWFwKHBvd3MpO1xuICAgIH1cblxuICAgIHJldHVybiByID8gei5yZXZlcnNlKCkgOiB6O1xuICB9O1xuXG4gIHNjYWxlLnRpY2tGb3JtYXQgPSBmdW5jdGlvbihjb3VudCwgc3BlY2lmaWVyKSB7XG4gICAgaWYgKHNwZWNpZmllciA9PSBudWxsKSBzcGVjaWZpZXIgPSBiYXNlID09PSAxMCA/IFwiLjBlXCIgOiBcIixcIjtcbiAgICBpZiAodHlwZW9mIHNwZWNpZmllciAhPT0gXCJmdW5jdGlvblwiKSBzcGVjaWZpZXIgPSBleHBvcnRzLmZvcm1hdChzcGVjaWZpZXIpO1xuICAgIGlmIChjb3VudCA9PT0gSW5maW5pdHkpIHJldHVybiBzcGVjaWZpZXI7XG4gICAgaWYgKGNvdW50ID09IG51bGwpIGNvdW50ID0gMTA7XG4gICAgdmFyIGsgPSBNYXRoLm1heCgxLCBiYXNlICogY291bnQgLyBzY2FsZS50aWNrcygpLmxlbmd0aCk7IC8vIFRPRE8gZmFzdCBlc3RpbWF0ZT9cbiAgICByZXR1cm4gZnVuY3Rpb24oZCkge1xuICAgICAgdmFyIGkgPSBkIC8gcG93cyhNYXRoLnJvdW5kKGxvZ3MoZCkpKTtcbiAgICAgIGlmIChpICogYmFzZSA8IGJhc2UgLSAwLjUpIGkgKj0gYmFzZTtcbiAgICAgIHJldHVybiBpIDw9IGsgPyBzcGVjaWZpZXIoZCkgOiBcIlwiO1xuICAgIH07XG4gIH07XG5cbiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkb21haW4obmljZShkb21haW4oKSwge1xuICAgICAgZmxvb3I6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHBvd3MoTWF0aC5mbG9vcihsb2dzKHgpKSk7IH0sXG4gICAgICBjZWlsOiBmdW5jdGlvbih4KSB7IHJldHVybiBwb3dzKE1hdGguY2VpbChsb2dzKHgpKSk7IH1cbiAgICB9KSk7XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBjb3B5KHNjYWxlLCBsb2coKS5iYXNlKGJhc2UpKTtcbiAgfTtcblxuICByZXR1cm4gc2NhbGU7XG59XG5cbmZ1bmN0aW9uIHJhaXNlKHgsIGV4cG9uZW50KSB7XG4gIHJldHVybiB4IDwgMCA/IC1NYXRoLnBvdygteCwgZXhwb25lbnQpIDogTWF0aC5wb3coeCwgZXhwb25lbnQpO1xufVxuXG5mdW5jdGlvbiBwb3coKSB7XG4gIHZhciBleHBvbmVudCA9IDEsXG4gICAgICBzY2FsZSA9IGNvbnRpbnVvdXMoZGVpbnRlcnBvbGF0ZSwgcmVpbnRlcnBvbGF0ZSksXG4gICAgICBkb21haW4gPSBzY2FsZS5kb21haW47XG5cbiAgZnVuY3Rpb24gZGVpbnRlcnBvbGF0ZShhLCBiKSB7XG4gICAgcmV0dXJuIChiID0gcmFpc2UoYiwgZXhwb25lbnQpIC0gKGEgPSByYWlzZShhLCBleHBvbmVudCkpKVxuICAgICAgICA/IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIChyYWlzZSh4LCBleHBvbmVudCkgLSBhKSAvIGI7IH1cbiAgICAgICAgOiBjb25zdGFudCQ0KGIpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVpbnRlcnBvbGF0ZShhLCBiKSB7XG4gICAgYiA9IHJhaXNlKGIsIGV4cG9uZW50KSAtIChhID0gcmFpc2UoYSwgZXhwb25lbnQpKTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkgeyByZXR1cm4gcmFpc2UoYSArIGIgKiB0LCAxIC8gZXhwb25lbnQpOyB9O1xuICB9XG5cbiAgc2NhbGUuZXhwb25lbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZXhwb25lbnQgPSArXywgZG9tYWluKGRvbWFpbigpKSkgOiBleHBvbmVudDtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGNvcHkoc2NhbGUsIHBvdygpLmV4cG9uZW50KGV4cG9uZW50KSk7XG4gIH07XG5cbiAgcmV0dXJuIGxpbmVhcmlzaChzY2FsZSk7XG59XG5cbmZ1bmN0aW9uIHNxcnQoKSB7XG4gIHJldHVybiBwb3coKS5leHBvbmVudCgwLjUpO1xufVxuXG5mdW5jdGlvbiBxdWFudGlsZSQkMSgpIHtcbiAgdmFyIGRvbWFpbiA9IFtdLFxuICAgICAgcmFuZ2UkJDEgPSBbXSxcbiAgICAgIHRocmVzaG9sZHMgPSBbXTtcblxuICBmdW5jdGlvbiByZXNjYWxlKCkge1xuICAgIHZhciBpID0gMCwgbiA9IE1hdGgubWF4KDEsIHJhbmdlJCQxLmxlbmd0aCk7XG4gICAgdGhyZXNob2xkcyA9IG5ldyBBcnJheShuIC0gMSk7XG4gICAgd2hpbGUgKCsraSA8IG4pIHRocmVzaG9sZHNbaSAtIDFdID0gdGhyZXNob2xkKGRvbWFpbiwgaSAvIG4pO1xuICAgIHJldHVybiBzY2FsZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICBpZiAoIWlzTmFOKHggPSAreCkpIHJldHVybiByYW5nZSQkMVtiaXNlY3RSaWdodCh0aHJlc2hvbGRzLCB4KV07XG4gIH1cblxuICBzY2FsZS5pbnZlcnRFeHRlbnQgPSBmdW5jdGlvbih5KSB7XG4gICAgdmFyIGkgPSByYW5nZSQkMS5pbmRleE9mKHkpO1xuICAgIHJldHVybiBpIDwgMCA/IFtOYU4sIE5hTl0gOiBbXG4gICAgICBpID4gMCA/IHRocmVzaG9sZHNbaSAtIDFdIDogZG9tYWluWzBdLFxuICAgICAgaSA8IHRocmVzaG9sZHMubGVuZ3RoID8gdGhyZXNob2xkc1tpXSA6IGRvbWFpbltkb21haW4ubGVuZ3RoIC0gMV1cbiAgICBdO1xuICB9O1xuXG4gIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBkb21haW4uc2xpY2UoKTtcbiAgICBkb21haW4gPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IF8ubGVuZ3RoLCBkOyBpIDwgbjsgKytpKSBpZiAoZCA9IF9baV0sIGQgIT0gbnVsbCAmJiAhaXNOYU4oZCA9ICtkKSkgZG9tYWluLnB1c2goZCk7XG4gICAgZG9tYWluLnNvcnQoYXNjZW5kaW5nKTtcbiAgICByZXR1cm4gcmVzY2FsZSgpO1xuICB9O1xuXG4gIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJhbmdlJCQxID0gc2xpY2UkMy5jYWxsKF8pLCByZXNjYWxlKCkpIDogcmFuZ2UkJDEuc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5xdWFudGlsZXMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhyZXNob2xkcy5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gcXVhbnRpbGUkJDEoKVxuICAgICAgICAuZG9tYWluKGRvbWFpbilcbiAgICAgICAgLnJhbmdlKHJhbmdlJCQxKTtcbiAgfTtcblxuICByZXR1cm4gc2NhbGU7XG59XG5cbmZ1bmN0aW9uIHF1YW50aXplJDEoKSB7XG4gIHZhciB4MCA9IDAsXG4gICAgICB4MSA9IDEsXG4gICAgICBuID0gMSxcbiAgICAgIGRvbWFpbiA9IFswLjVdLFxuICAgICAgcmFuZ2UkJDEgPSBbMCwgMV07XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIGlmICh4IDw9IHgpIHJldHVybiByYW5nZSQkMVtiaXNlY3RSaWdodChkb21haW4sIHgsIDAsIG4pXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2NhbGUoKSB7XG4gICAgdmFyIGkgPSAtMTtcbiAgICBkb21haW4gPSBuZXcgQXJyYXkobik7XG4gICAgd2hpbGUgKCsraSA8IG4pIGRvbWFpbltpXSA9ICgoaSArIDEpICogeDEgLSAoaSAtIG4pICogeDApIC8gKG4gKyAxKTtcbiAgICByZXR1cm4gc2NhbGU7XG4gIH1cblxuICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeDAgPSArX1swXSwgeDEgPSArX1sxXSwgcmVzY2FsZSgpKSA6IFt4MCwgeDFdO1xuICB9O1xuXG4gIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG4gPSAocmFuZ2UkJDEgPSBzbGljZSQzLmNhbGwoXykpLmxlbmd0aCAtIDEsIHJlc2NhbGUoKSkgOiByYW5nZSQkMS5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLmludmVydEV4dGVudCA9IGZ1bmN0aW9uKHkpIHtcbiAgICB2YXIgaSA9IHJhbmdlJCQxLmluZGV4T2YoeSk7XG4gICAgcmV0dXJuIGkgPCAwID8gW05hTiwgTmFOXVxuICAgICAgICA6IGkgPCAxID8gW3gwLCBkb21haW5bMF1dXG4gICAgICAgIDogaSA+PSBuID8gW2RvbWFpbltuIC0gMV0sIHgxXVxuICAgICAgICA6IFtkb21haW5baSAtIDFdLCBkb21haW5baV1dO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gcXVhbnRpemUkMSgpXG4gICAgICAgIC5kb21haW4oW3gwLCB4MV0pXG4gICAgICAgIC5yYW5nZShyYW5nZSQkMSk7XG4gIH07XG5cbiAgcmV0dXJuIGxpbmVhcmlzaChzY2FsZSk7XG59XG5cbmZ1bmN0aW9uIHRocmVzaG9sZCQxKCkge1xuICB2YXIgZG9tYWluID0gWzAuNV0sXG4gICAgICByYW5nZSQkMSA9IFswLCAxXSxcbiAgICAgIG4gPSAxO1xuXG4gIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICBpZiAoeCA8PSB4KSByZXR1cm4gcmFuZ2UkJDFbYmlzZWN0UmlnaHQoZG9tYWluLCB4LCAwLCBuKV07XG4gIH1cblxuICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZG9tYWluID0gc2xpY2UkMy5jYWxsKF8pLCBuID0gTWF0aC5taW4oZG9tYWluLmxlbmd0aCwgcmFuZ2UkJDEubGVuZ3RoIC0gMSksIHNjYWxlKSA6IGRvbWFpbi5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJhbmdlJCQxID0gc2xpY2UkMy5jYWxsKF8pLCBuID0gTWF0aC5taW4oZG9tYWluLmxlbmd0aCwgcmFuZ2UkJDEubGVuZ3RoIC0gMSksIHNjYWxlKSA6IHJhbmdlJCQxLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUuaW52ZXJ0RXh0ZW50ID0gZnVuY3Rpb24oeSkge1xuICAgIHZhciBpID0gcmFuZ2UkJDEuaW5kZXhPZih5KTtcbiAgICByZXR1cm4gW2RvbWFpbltpIC0gMV0sIGRvbWFpbltpXV07XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aHJlc2hvbGQkMSgpXG4gICAgICAgIC5kb21haW4oZG9tYWluKVxuICAgICAgICAucmFuZ2UocmFuZ2UkJDEpO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxudmFyIGR1cmF0aW9uU2Vjb25kJDEgPSAxMDAwO1xudmFyIGR1cmF0aW9uTWludXRlJDEgPSBkdXJhdGlvblNlY29uZCQxICogNjA7XG52YXIgZHVyYXRpb25Ib3VyJDEgPSBkdXJhdGlvbk1pbnV0ZSQxICogNjA7XG52YXIgZHVyYXRpb25EYXkkMSA9IGR1cmF0aW9uSG91ciQxICogMjQ7XG52YXIgZHVyYXRpb25XZWVrJDEgPSBkdXJhdGlvbkRheSQxICogNztcbnZhciBkdXJhdGlvbk1vbnRoID0gZHVyYXRpb25EYXkkMSAqIDMwO1xudmFyIGR1cmF0aW9uWWVhciA9IGR1cmF0aW9uRGF5JDEgKiAzNjU7XG5cbmZ1bmN0aW9uIGRhdGUkMSh0KSB7XG4gIHJldHVybiBuZXcgRGF0ZSh0KTtcbn1cblxuZnVuY3Rpb24gbnVtYmVyJDIodCkge1xuICByZXR1cm4gdCBpbnN0YW5jZW9mIERhdGUgPyArdCA6ICtuZXcgRGF0ZSgrdCk7XG59XG5cbmZ1bmN0aW9uIGNhbGVuZGFyKHllYXIkJDEsIG1vbnRoJCQxLCB3ZWVrLCBkYXkkJDEsIGhvdXIkJDEsIG1pbnV0ZSQkMSwgc2Vjb25kJCQxLCBtaWxsaXNlY29uZCQkMSwgZm9ybWF0KSB7XG4gIHZhciBzY2FsZSA9IGNvbnRpbnVvdXMoZGVpbnRlcnBvbGF0ZUxpbmVhciwgaW50ZXJwb2xhdGVOdW1iZXIpLFxuICAgICAgaW52ZXJ0ID0gc2NhbGUuaW52ZXJ0LFxuICAgICAgZG9tYWluID0gc2NhbGUuZG9tYWluO1xuXG4gIHZhciBmb3JtYXRNaWxsaXNlY29uZCA9IGZvcm1hdChcIi4lTFwiKSxcbiAgICAgIGZvcm1hdFNlY29uZCA9IGZvcm1hdChcIjolU1wiKSxcbiAgICAgIGZvcm1hdE1pbnV0ZSA9IGZvcm1hdChcIiVJOiVNXCIpLFxuICAgICAgZm9ybWF0SG91ciA9IGZvcm1hdChcIiVJICVwXCIpLFxuICAgICAgZm9ybWF0RGF5ID0gZm9ybWF0KFwiJWEgJWRcIiksXG4gICAgICBmb3JtYXRXZWVrID0gZm9ybWF0KFwiJWIgJWRcIiksXG4gICAgICBmb3JtYXRNb250aCA9IGZvcm1hdChcIiVCXCIpLFxuICAgICAgZm9ybWF0WWVhciA9IGZvcm1hdChcIiVZXCIpO1xuXG4gIHZhciB0aWNrSW50ZXJ2YWxzID0gW1xuICAgIFtzZWNvbmQkJDEsICAxLCAgICAgIGR1cmF0aW9uU2Vjb25kJDFdLFxuICAgIFtzZWNvbmQkJDEsICA1LCAgNSAqIGR1cmF0aW9uU2Vjb25kJDFdLFxuICAgIFtzZWNvbmQkJDEsIDE1LCAxNSAqIGR1cmF0aW9uU2Vjb25kJDFdLFxuICAgIFtzZWNvbmQkJDEsIDMwLCAzMCAqIGR1cmF0aW9uU2Vjb25kJDFdLFxuICAgIFttaW51dGUkJDEsICAxLCAgICAgIGR1cmF0aW9uTWludXRlJDFdLFxuICAgIFttaW51dGUkJDEsICA1LCAgNSAqIGR1cmF0aW9uTWludXRlJDFdLFxuICAgIFttaW51dGUkJDEsIDE1LCAxNSAqIGR1cmF0aW9uTWludXRlJDFdLFxuICAgIFttaW51dGUkJDEsIDMwLCAzMCAqIGR1cmF0aW9uTWludXRlJDFdLFxuICAgIFsgIGhvdXIkJDEsICAxLCAgICAgIGR1cmF0aW9uSG91ciQxICBdLFxuICAgIFsgIGhvdXIkJDEsICAzLCAgMyAqIGR1cmF0aW9uSG91ciQxICBdLFxuICAgIFsgIGhvdXIkJDEsICA2LCAgNiAqIGR1cmF0aW9uSG91ciQxICBdLFxuICAgIFsgIGhvdXIkJDEsIDEyLCAxMiAqIGR1cmF0aW9uSG91ciQxICBdLFxuICAgIFsgICBkYXkkJDEsICAxLCAgICAgIGR1cmF0aW9uRGF5JDEgICBdLFxuICAgIFsgICBkYXkkJDEsICAyLCAgMiAqIGR1cmF0aW9uRGF5JDEgICBdLFxuICAgIFsgIHdlZWssICAxLCAgICAgIGR1cmF0aW9uV2VlayQxICBdLFxuICAgIFsgbW9udGgkJDEsICAxLCAgICAgIGR1cmF0aW9uTW9udGggXSxcbiAgICBbIG1vbnRoJCQxLCAgMywgIDMgKiBkdXJhdGlvbk1vbnRoIF0sXG4gICAgWyAgeWVhciQkMSwgIDEsICAgICAgZHVyYXRpb25ZZWFyICBdXG4gIF07XG5cbiAgZnVuY3Rpb24gdGlja0Zvcm1hdChkYXRlKSB7XG4gICAgcmV0dXJuIChzZWNvbmQkJDEoZGF0ZSkgPCBkYXRlID8gZm9ybWF0TWlsbGlzZWNvbmRcbiAgICAgICAgOiBtaW51dGUkJDEoZGF0ZSkgPCBkYXRlID8gZm9ybWF0U2Vjb25kXG4gICAgICAgIDogaG91ciQkMShkYXRlKSA8IGRhdGUgPyBmb3JtYXRNaW51dGVcbiAgICAgICAgOiBkYXkkJDEoZGF0ZSkgPCBkYXRlID8gZm9ybWF0SG91clxuICAgICAgICA6IG1vbnRoJCQxKGRhdGUpIDwgZGF0ZSA/ICh3ZWVrKGRhdGUpIDwgZGF0ZSA/IGZvcm1hdERheSA6IGZvcm1hdFdlZWspXG4gICAgICAgIDogeWVhciQkMShkYXRlKSA8IGRhdGUgPyBmb3JtYXRNb250aFxuICAgICAgICA6IGZvcm1hdFllYXIpKGRhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGlja0ludGVydmFsKGludGVydmFsLCBzdGFydCwgc3RvcCwgc3RlcCkge1xuICAgIGlmIChpbnRlcnZhbCA9PSBudWxsKSBpbnRlcnZhbCA9IDEwO1xuXG4gICAgLy8gSWYgYSBkZXNpcmVkIHRpY2sgY291bnQgaXMgc3BlY2lmaWVkLCBwaWNrIGEgcmVhc29uYWJsZSB0aWNrIGludGVydmFsXG4gICAgLy8gYmFzZWQgb24gdGhlIGV4dGVudCBvZiB0aGUgZG9tYWluIGFuZCBhIHJvdWdoIGVzdGltYXRlIG9mIHRpY2sgc2l6ZS5cbiAgICAvLyBPdGhlcndpc2UsIGFzc3VtZSBpbnRlcnZhbCBpcyBhbHJlYWR5IGEgdGltZSBpbnRlcnZhbCBhbmQgdXNlIGl0LlxuICAgIGlmICh0eXBlb2YgaW50ZXJ2YWwgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHZhciB0YXJnZXQgPSBNYXRoLmFicyhzdG9wIC0gc3RhcnQpIC8gaW50ZXJ2YWwsXG4gICAgICAgICAgaSA9IGJpc2VjdG9yKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIGlbMl07IH0pLnJpZ2h0KHRpY2tJbnRlcnZhbHMsIHRhcmdldCk7XG4gICAgICBpZiAoaSA9PT0gdGlja0ludGVydmFscy5sZW5ndGgpIHtcbiAgICAgICAgc3RlcCA9IHRpY2tTdGVwKHN0YXJ0IC8gZHVyYXRpb25ZZWFyLCBzdG9wIC8gZHVyYXRpb25ZZWFyLCBpbnRlcnZhbCk7XG4gICAgICAgIGludGVydmFsID0geWVhciQkMTtcbiAgICAgIH0gZWxzZSBpZiAoaSkge1xuICAgICAgICBpID0gdGlja0ludGVydmFsc1t0YXJnZXQgLyB0aWNrSW50ZXJ2YWxzW2kgLSAxXVsyXSA8IHRpY2tJbnRlcnZhbHNbaV1bMl0gLyB0YXJnZXQgPyBpIC0gMSA6IGldO1xuICAgICAgICBzdGVwID0gaVsxXTtcbiAgICAgICAgaW50ZXJ2YWwgPSBpWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RlcCA9IHRpY2tTdGVwKHN0YXJ0LCBzdG9wLCBpbnRlcnZhbCk7XG4gICAgICAgIGludGVydmFsID0gbWlsbGlzZWNvbmQkJDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0ZXAgPT0gbnVsbCA/IGludGVydmFsIDogaW50ZXJ2YWwuZXZlcnkoc3RlcCk7XG4gIH1cblxuICBzY2FsZS5pbnZlcnQgPSBmdW5jdGlvbih5KSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGludmVydCh5KSk7XG4gIH07XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gZG9tYWluKG1hcCQzLmNhbGwoXywgbnVtYmVyJDIpKSA6IGRvbWFpbigpLm1hcChkYXRlJDEpO1xuICB9O1xuXG4gIHNjYWxlLnRpY2tzID0gZnVuY3Rpb24oaW50ZXJ2YWwsIHN0ZXApIHtcbiAgICB2YXIgZCA9IGRvbWFpbigpLFxuICAgICAgICB0MCA9IGRbMF0sXG4gICAgICAgIHQxID0gZFtkLmxlbmd0aCAtIDFdLFxuICAgICAgICByID0gdDEgPCB0MCxcbiAgICAgICAgdDtcbiAgICBpZiAocikgdCA9IHQwLCB0MCA9IHQxLCB0MSA9IHQ7XG4gICAgdCA9IHRpY2tJbnRlcnZhbChpbnRlcnZhbCwgdDAsIHQxLCBzdGVwKTtcbiAgICB0ID0gdCA/IHQucmFuZ2UodDAsIHQxICsgMSkgOiBbXTsgLy8gaW5jbHVzaXZlIHN0b3BcbiAgICByZXR1cm4gciA/IHQucmV2ZXJzZSgpIDogdDtcbiAgfTtcblxuICBzY2FsZS50aWNrRm9ybWF0ID0gZnVuY3Rpb24oY291bnQsIHNwZWNpZmllcikge1xuICAgIHJldHVybiBzcGVjaWZpZXIgPT0gbnVsbCA/IHRpY2tGb3JtYXQgOiBmb3JtYXQoc3BlY2lmaWVyKTtcbiAgfTtcblxuICBzY2FsZS5uaWNlID0gZnVuY3Rpb24oaW50ZXJ2YWwsIHN0ZXApIHtcbiAgICB2YXIgZCA9IGRvbWFpbigpO1xuICAgIHJldHVybiAoaW50ZXJ2YWwgPSB0aWNrSW50ZXJ2YWwoaW50ZXJ2YWwsIGRbMF0sIGRbZC5sZW5ndGggLSAxXSwgc3RlcCkpXG4gICAgICAgID8gZG9tYWluKG5pY2UoZCwgaW50ZXJ2YWwpKVxuICAgICAgICA6IHNjYWxlO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gY29weShzY2FsZSwgY2FsZW5kYXIoeWVhciQkMSwgbW9udGgkJDEsIHdlZWssIGRheSQkMSwgaG91ciQkMSwgbWludXRlJCQxLCBzZWNvbmQkJDEsIG1pbGxpc2Vjb25kJCQxLCBmb3JtYXQpKTtcbiAgfTtcblxuICByZXR1cm4gc2NhbGU7XG59XG5cbnZhciB0aW1lID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBjYWxlbmRhcih5ZWFyLCBtb250aCwgc3VuZGF5LCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBtaWxsaXNlY29uZCwgZXhwb3J0cy50aW1lRm9ybWF0KS5kb21haW4oW25ldyBEYXRlKDIwMDAsIDAsIDEpLCBuZXcgRGF0ZSgyMDAwLCAwLCAyKV0pO1xufTtcblxudmFyIHV0Y1RpbWUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGNhbGVuZGFyKHV0Y1llYXIsIHV0Y01vbnRoLCB1dGNTdW5kYXksIHV0Y0RheSwgdXRjSG91ciwgdXRjTWludXRlLCBzZWNvbmQsIG1pbGxpc2Vjb25kLCBleHBvcnRzLnV0Y0Zvcm1hdCkuZG9tYWluKFtEYXRlLlVUQygyMDAwLCAwLCAxKSwgRGF0ZS5VVEMoMjAwMCwgMCwgMildKTtcbn07XG5cbnZhciBjb2xvcnMgPSBmdW5jdGlvbihzKSB7XG4gIHJldHVybiBzLm1hdGNoKC8uezZ9L2cpLm1hcChmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIFwiI1wiICsgeDtcbiAgfSk7XG59O1xuXG52YXIgY2F0ZWdvcnkxMCA9IGNvbG9ycyhcIjFmNzdiNGZmN2YwZTJjYTAyY2Q2MjcyODk0NjdiZDhjNTY0YmUzNzdjMjdmN2Y3ZmJjYmQyMjE3YmVjZlwiKTtcblxudmFyIGNhdGVnb3J5MjBiID0gY29sb3JzKFwiMzkzYjc5NTI1NGEzNmI2ZWNmOWM5ZWRlNjM3OTM5OGNhMjUyYjVjZjZiY2VkYjljOGM2ZDMxYmQ5ZTM5ZTdiYTUyZTdjYjk0ODQzYzM5YWQ0OTRhZDY2MTZiZTc5NjljN2I0MTczYTU1MTk0Y2U2ZGJkZGU5ZWQ2XCIpO1xuXG52YXIgY2F0ZWdvcnkyMGMgPSBjb2xvcnMoXCIzMTgyYmQ2YmFlZDY5ZWNhZTFjNmRiZWZlNjU1MGRmZDhkM2NmZGFlNmJmZGQwYTIzMWEzNTQ3NGM0NzZhMWQ5OWJjN2U5YzA3NTZiYjE5ZTlhYzhiY2JkZGNkYWRhZWI2MzYzNjM5Njk2OTZiZGJkYmRkOWQ5ZDlcIik7XG5cbnZhciBjYXRlZ29yeTIwID0gY29sb3JzKFwiMWY3N2I0YWVjN2U4ZmY3ZjBlZmZiYjc4MmNhMDJjOThkZjhhZDYyNzI4ZmY5ODk2OTQ2N2JkYzViMGQ1OGM1NjRiYzQ5Yzk0ZTM3N2MyZjdiNmQyN2Y3ZjdmYzdjN2M3YmNiZDIyZGJkYjhkMTdiZWNmOWVkYWU1XCIpO1xuXG52YXIgY3ViZWhlbGl4JDMgPSBjdWJlaGVsaXhMb25nKGN1YmVoZWxpeCgzMDAsIDAuNSwgMC4wKSwgY3ViZWhlbGl4KC0yNDAsIDAuNSwgMS4wKSk7XG5cbnZhciB3YXJtID0gY3ViZWhlbGl4TG9uZyhjdWJlaGVsaXgoLTEwMCwgMC43NSwgMC4zNSksIGN1YmVoZWxpeCg4MCwgMS41MCwgMC44KSk7XG5cbnZhciBjb29sID0gY3ViZWhlbGl4TG9uZyhjdWJlaGVsaXgoMjYwLCAwLjc1LCAwLjM1KSwgY3ViZWhlbGl4KDgwLCAxLjUwLCAwLjgpKTtcblxudmFyIHJhaW5ib3cgPSBjdWJlaGVsaXgoKTtcblxudmFyIHJhaW5ib3ckMSA9IGZ1bmN0aW9uKHQpIHtcbiAgaWYgKHQgPCAwIHx8IHQgPiAxKSB0IC09IE1hdGguZmxvb3IodCk7XG4gIHZhciB0cyA9IE1hdGguYWJzKHQgLSAwLjUpO1xuICByYWluYm93LmggPSAzNjAgKiB0IC0gMTAwO1xuICByYWluYm93LnMgPSAxLjUgLSAxLjUgKiB0cztcbiAgcmFpbmJvdy5sID0gMC44IC0gMC45ICogdHM7XG4gIHJldHVybiByYWluYm93ICsgXCJcIjtcbn07XG5cbmZ1bmN0aW9uIHJhbXAocmFuZ2UpIHtcbiAgdmFyIG4gPSByYW5nZS5sZW5ndGg7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIHJhbmdlW01hdGgubWF4KDAsIE1hdGgubWluKG4gLSAxLCBNYXRoLmZsb29yKHQgKiBuKSkpXTtcbiAgfTtcbn1cblxudmFyIHZpcmlkaXMgPSByYW1wKGNvbG9ycyhcIjQ0MDE1NDQ0MDI1NjQ1MDQ1NzQ1MDU1OTQ2MDc1YTQ2MDg1YzQ2MGE1ZDQ2MGI1ZTQ3MGQ2MDQ3MGU2MTQ3MTA2MzQ3MTE2NDQ3MTM2NTQ4MTQ2NzQ4MTY2ODQ4MTc2OTQ4MTg2YTQ4MWE2YzQ4MWI2ZDQ4MWM2ZTQ4MWQ2ZjQ4MWY3MDQ4MjA3MTQ4MjE3MzQ4MjM3NDQ4MjQ3NTQ4MjU3NjQ4MjY3NzQ4Mjg3ODQ4Mjk3OTQ3MmE3YTQ3MmM3YTQ3MmQ3YjQ3MmU3YzQ3MmY3ZDQ2MzA3ZTQ2MzI3ZTQ2MzM3ZjQ2MzQ4MDQ1MzU4MTQ1Mzc4MTQ1Mzg4MjQ0Mzk4MzQ0M2E4MzQ0M2I4NDQzM2Q4NDQzM2U4NTQyM2Y4NTQyNDA4NjQyNDE4NjQxNDI4NzQxNDQ4NzQwNDU4ODQwNDY4ODNmNDc4ODNmNDg4OTNlNDk4OTNlNGE4OTNlNGM4YTNkNGQ4YTNkNGU4YTNjNGY4YTNjNTA4YjNiNTE4YjNiNTI4YjNhNTM4YjNhNTQ4YzM5NTU4YzM5NTY4YzM4NTg4YzM4NTk4YzM3NWE4YzM3NWI4ZDM2NWM4ZDM2NWQ4ZDM1NWU4ZDM1NWY4ZDM0NjA4ZDM0NjE4ZDMzNjI4ZDMzNjM4ZDMyNjQ4ZTMyNjU4ZTMxNjY4ZTMxNjc4ZTMxNjg4ZTMwNjk4ZTMwNmE4ZTJmNmI4ZTJmNmM4ZTJlNmQ4ZTJlNmU4ZTJlNmY4ZTJkNzA4ZTJkNzE4ZTJjNzE4ZTJjNzI4ZTJjNzM4ZTJiNzQ4ZTJiNzU4ZTJhNzY4ZTJhNzc4ZTJhNzg4ZTI5Nzk4ZTI5N2E4ZTI5N2I4ZTI4N2M4ZTI4N2Q4ZTI3N2U4ZTI3N2Y4ZTI3ODA4ZTI2ODE4ZTI2ODI4ZTI2ODI4ZTI1ODM4ZTI1ODQ4ZTI1ODU4ZTI0ODY4ZTI0ODc4ZTIzODg4ZTIzODk4ZTIzOGE4ZDIyOGI4ZDIyOGM4ZDIyOGQ4ZDIxOGU4ZDIxOGY4ZDIxOTA4ZDIxOTE4YzIwOTI4YzIwOTI4YzIwOTM4YzFmOTQ4YzFmOTU4YjFmOTY4YjFmOTc4YjFmOTg4YjFmOTk4YTFmOWE4YTFlOWI4YTFlOWM4OTFlOWQ4OTFmOWU4OTFmOWY4ODFmYTA4ODFmYTE4ODFmYTE4NzFmYTI4NzIwYTM4NjIwYTQ4NjIxYTU4NTIxYTY4NTIyYTc4NTIyYTg4NDIzYTk4MzI0YWE4MzI1YWI4MjI1YWM4MjI2YWQ4MTI3YWQ4MTI4YWU4MDI5YWY3ZjJhYjA3ZjJjYjE3ZTJkYjI3ZDJlYjM3YzJmYjQ3YzMxYjU3YjMyYjY3YTM0YjY3OTM1Yjc3OTM3Yjg3ODM4Yjk3NzNhYmE3NjNiYmI3NTNkYmM3NDNmYmM3MzQwYmQ3MjQyYmU3MTQ0YmY3MDQ2YzA2ZjQ4YzE2ZTRhYzE2ZDRjYzI2YzRlYzM2YjUwYzQ2YTUyYzU2OTU0YzU2ODU2YzY2NzU4Yzc2NTVhYzg2NDVjYzg2MzVlYzk2MjYwY2E2MDYzY2I1ZjY1Y2I1ZTY3Y2M1YzY5Y2Q1YjZjY2Q1YTZlY2U1ODcwY2Y1NzczZDA1Njc1ZDA1NDc3ZDE1MzdhZDE1MTdjZDI1MDdmZDM0ZTgxZDM0ZDg0ZDQ0Yjg2ZDU0OTg5ZDU0ODhiZDY0NjhlZDY0NTkwZDc0MzkzZDc0MTk1ZDg0MDk4ZDgzZTliZDkzYzlkZDkzYmEwZGEzOWEyZGEzN2E1ZGIzNmE4ZGIzNGFhZGMzMmFkZGMzMGIwZGQyZmIyZGQyZGI1ZGUyYmI4ZGUyOWJhZGUyOGJkZGYyNmMwZGYyNWMyZGYyM2M1ZTAyMWM4ZTAyMGNhZTExZmNkZTExZGQwZTExY2QyZTIxYmQ1ZTIxYWQ4ZTIxOWRhZTMxOWRkZTMxOGRmZTMxOGUyZTQxOGU1ZTQxOWU3ZTQxOWVhZTUxYWVjZTUxYmVmZTUxY2YxZTUxZGY0ZTYxZWY2ZTYyMGY4ZTYyMWZiZTcyM2ZkZTcyNVwiKSk7XG5cbnZhciBtYWdtYSA9IHJhbXAoY29sb3JzKFwiMDAwMDA0MDEwMDA1MDEwMTA2MDEwMTA4MDIwMTA5MDIwMjBiMDIwMjBkMDMwMzBmMDMwMzEyMDQwNDE0MDUwNDE2MDYwNTE4MDYwNTFhMDcwNjFjMDgwNzFlMDkwNzIwMGEwODIyMGIwOTI0MGMwOTI2MGQwYTI5MGUwYjJiMTAwYjJkMTEwYzJmMTIwZDMxMTMwZDM0MTQwZTM2MTUwZTM4MTYwZjNiMTgwZjNkMTkxMDNmMWExMDQyMWMxMDQ0MWQxMTQ3MWUxMTQ5MjAxMTRiMjExMTRlMjIxMTUwMjQxMjUzMjUxMjU1MjcxMjU4MjkxMTVhMmExMTVjMmMxMTVmMmQxMTYxMmYxMTYzMzExMTY1MzMxMDY3MzQxMDY5MzYxMDZiMzgxMDZjMzkwZjZlM2IwZjcwM2QwZjcxM2YwZjcyNDAwZjc0NDIwZjc1NDQwZjc2NDUxMDc3NDcxMDc4NDkxMDc4NGExMDc5NGMxMTdhNGUxMTdiNGYxMjdiNTExMjdjNTIxMzdjNTQxMzdkNTYxNDdkNTcxNTdlNTkxNTdlNWExNjdlNWMxNjdmNWQxNzdmNWYxODdmNjAxODgwNjIxOTgwNjQxYTgwNjUxYTgwNjcxYjgwNjgxYzgxNmExYzgxNmIxZDgxNmQxZDgxNmUxZTgxNzAxZjgxNzIxZjgxNzMyMDgxNzUyMTgxNzYyMTgxNzgyMjgxNzkyMjgyN2IyMzgyN2MyMzgyN2UyNDgyODAyNTgyODEyNTgxODMyNjgxODQyNjgxODYyNzgxODgyNzgxODkyODgxOGIyOTgxOGMyOTgxOGUyYTgxOTAyYTgxOTEyYjgxOTMyYjgwOTQyYzgwOTYyYzgwOTgyZDgwOTkyZDgwOWIyZTdmOWMyZTdmOWUyZjdmYTAyZjdmYTEzMDdlYTMzMDdlYTUzMTdlYTYzMTdkYTgzMjdkYWEzMzdkYWIzMzdjYWQzNDdjYWUzNDdiYjAzNTdiYjIzNTdiYjMzNjdhYjUzNjdhYjczNzc5YjgzNzc5YmEzODc4YmMzOTc4YmQzOTc3YmYzYTc3YzAzYTc2YzIzYjc1YzQzYzc1YzUzYzc0YzczZDczYzgzZTczY2EzZTcyY2MzZjcxY2Q0MDcxY2Y0MDcwZDA0MTZmZDI0MjZmZDM0MzZlZDU0NDZkZDY0NTZjZDg0NTZjZDk0NjZiZGI0NzZhZGM0ODY5ZGU0OTY4ZGY0YTY4ZTA0YzY3ZTI0ZDY2ZTM0ZTY1ZTQ0ZjY0ZTU1MDY0ZTc1MjYzZTg1MzYyZTk1NDYyZWE1NjYxZWI1NzYwZWM1ODYwZWQ1YTVmZWU1YjVlZWY1ZDVlZjA1ZjVlZjE2MDVkZjI2MjVkZjI2NDVjZjM2NTVjZjQ2NzVjZjQ2OTVjZjU2YjVjZjY2YzVjZjY2ZTVjZjc3MDVjZjc3MjVjZjg3NDVjZjg3NjVjZjk3ODVkZjk3OTVkZjk3YjVkZmE3ZDVlZmE3ZjVlZmE4MTVmZmI4MzVmZmI4NTYwZmI4NzYxZmM4OTYxZmM4YTYyZmM4YzYzZmM4ZTY0ZmM5MDY1ZmQ5MjY2ZmQ5NDY3ZmQ5NjY4ZmQ5ODY5ZmQ5YTZhZmQ5YjZiZmU5ZDZjZmU5ZjZkZmVhMTZlZmVhMzZmZmVhNTcxZmVhNzcyZmVhOTczZmVhYTc0ZmVhYzc2ZmVhZTc3ZmViMDc4ZmViMjdhZmViNDdiZmViNjdjZmViNzdlZmViOTdmZmViYjgxZmViZDgyZmViZjg0ZmVjMTg1ZmVjMjg3ZmVjNDg4ZmVjNjhhZmVjODhjZmVjYThkZmVjYzhmZmVjZDkwZmVjZjkyZmVkMTk0ZmVkMzk1ZmVkNTk3ZmVkNzk5ZmVkODlhZmRkYTljZmRkYzllZmRkZWEwZmRlMGExZmRlMmEzZmRlM2E1ZmRlNWE3ZmRlN2E5ZmRlOWFhZmRlYmFjZmNlY2FlZmNlZWIwZmNmMGIyZmNmMmI0ZmNmNGI2ZmNmNmI4ZmNmN2I5ZmNmOWJiZmNmYmJkZmNmZGJmXCIpKTtcblxudmFyIGluZmVybm8gPSByYW1wKGNvbG9ycyhcIjAwMDAwNDAxMDAwNTAxMDEwNjAxMDEwODAyMDEwYTAyMDIwYzAyMDIwZTAzMDIxMDA0MDMxMjA0MDMxNDA1MDQxNzA2MDQxOTA3MDUxYjA4MDUxZDA5MDYxZjBhMDcyMjBiMDcyNDBjMDgyNjBkMDgyOTBlMDkyYjEwMDkyZDExMGEzMDEyMGEzMjE0MGIzNDE1MGIzNzE2MGIzOTE4MGMzYzE5MGMzZTFiMGM0MTFjMGM0MzFlMGM0NTFmMGM0ODIxMGM0YTIzMGM0YzI0MGM0ZjI2MGM1MTI4MGI1MzI5MGI1NTJiMGI1NzJkMGI1OTJmMGE1YjMxMGE1YzMyMGE1ZTM0MGE1ZjM2MDk2MTM4MDk2MjM5MDk2MzNiMDk2NDNkMDk2NTNlMDk2NjQwMGE2NzQyMGE2ODQ0MGE2ODQ1MGE2OTQ3MGI2YTQ5MGI2YTRhMGM2YjRjMGM2YjRkMGQ2YzRmMGQ2YzUxMGU2YzUyMGU2ZDU0MGY2ZDU1MGY2ZDU3MTA2ZTU5MTA2ZTVhMTE2ZTVjMTI2ZTVkMTI2ZTVmMTM2ZTYxMTM2ZTYyMTQ2ZTY0MTU2ZTY1MTU2ZTY3MTY2ZTY5MTY2ZTZhMTc2ZTZjMTg2ZTZkMTg2ZTZmMTk2ZTcxMTk2ZTcyMWE2ZTc0MWE2ZTc1MWI2ZTc3MWM2ZDc4MWM2ZDdhMWQ2ZDdjMWQ2ZDdkMWU2ZDdmMWU2YzgwMWY2YzgyMjA2Yzg0MjA2Yjg1MjE2Yjg3MjE2Yjg4MjI2YThhMjI2YThjMjM2OThkMjM2OThmMjQ2OTkwMjU2ODkyMjU2ODkzMjY2Nzk1MjY2Nzk3Mjc2Njk4Mjc2NjlhMjg2NTliMjk2NDlkMjk2NDlmMmE2M2EwMmE2M2EyMmI2MmEzMmM2MWE1MmM2MGE2MmQ2MGE4MmU1ZmE5MmU1ZWFiMmY1ZWFkMzA1ZGFlMzA1Y2IwMzE1YmIxMzI1YWIzMzI1YWI0MzM1OWI2MzQ1OGI3MzU1N2I5MzU1NmJhMzY1NWJjMzc1NGJkMzg1M2JmMzk1MmMwM2E1MWMxM2E1MGMzM2I0ZmM0M2M0ZWM2M2Q0ZGM3M2U0Y2M4M2Y0YmNhNDA0YWNiNDE0OWNjNDI0OGNlNDM0N2NmNDQ0NmQwNDU0NWQyNDY0NGQzNDc0M2Q0NDg0MmQ1NGE0MWQ3NGIzZmQ4NGMzZWQ5NGQzZGRhNGUzY2RiNTAzYmRkNTEzYWRlNTIzOGRmNTMzN2UwNTUzNmUxNTYzNWUyNTczNGUzNTkzM2U0NWEzMWU1NWMzMGU2NWQyZmU3NWUyZWU4NjAyZGU5NjEyYmVhNjMyYWViNjQyOWViNjYyOGVjNjcyNmVkNjkyNWVlNmEyNGVmNmMyM2VmNmUyMWYwNmYyMGYxNzExZmYxNzMxZGYyNzQxY2YzNzYxYmYzNzgxOWY0NzkxOGY1N2IxN2Y1N2QxNWY2N2UxNGY2ODAxM2Y3ODIxMmY3ODQxMGY4ODUwZmY4ODcwZWY4ODkwY2Y5OGIwYmY5OGMwYWY5OGUwOWZhOTAwOGZhOTIwN2ZhOTQwN2ZiOTYwNmZiOTcwNmZiOTkwNmZiOWIwNmZiOWQwN2ZjOWYwN2ZjYTEwOGZjYTMwOWZjYTUwYWZjYTYwY2ZjYTgwZGZjYWEwZmZjYWMxMWZjYWUxMmZjYjAxNGZjYjIxNmZjYjQxOGZiYjYxYWZiYjgxZGZiYmExZmZiYmMyMWZiYmUyM2ZhYzAyNmZhYzIyOGZhYzQyYWZhYzYyZGY5YzcyZmY5YzkzMmY5Y2IzNWY4Y2QzN2Y4Y2YzYWY3ZDEzZGY3ZDM0MGY2ZDU0M2Y2ZDc0NmY1ZDk0OWY1ZGI0Y2Y0ZGQ0ZmY0ZGY1M2Y0ZTE1NmYzZTM1YWYzZTU1ZGYyZTY2MWYyZTg2NWYyZWE2OWYxZWM2ZGYxZWQ3MWYxZWY3NWYxZjE3OWYyZjI3ZGYyZjQ4MmYzZjU4NmYzZjY4YWY0Zjg4ZWY1Zjk5MmY2ZmE5NmY4ZmI5YWY5ZmM5ZGZhZmRhMWZjZmZhNFwiKSk7XG5cbnZhciBwbGFzbWEgPSByYW1wKGNvbG9ycyhcIjBkMDg4NzEwMDc4ODEzMDc4OTE2MDc4YTE5MDY4YzFiMDY4ZDFkMDY4ZTIwMDY4ZjIyMDY5MDI0MDY5MTI2MDU5MTI4MDU5MjJhMDU5MzJjMDU5NDJlMDU5NTJmMDU5NjMxMDU5NzMzMDU5NzM1MDQ5ODM3MDQ5OTM4MDQ5YTNhMDQ5YTNjMDQ5YjNlMDQ5YzNmMDQ5YzQxMDQ5ZDQzMDM5ZTQ0MDM5ZTQ2MDM5ZjQ4MDM5ZjQ5MDNhMDRiMDNhMTRjMDJhMTRlMDJhMjUwMDJhMjUxMDJhMzUzMDJhMzU1MDJhNDU2MDFhNDU4MDFhNDU5MDFhNTViMDFhNTVjMDFhNjVlMDFhNjYwMDFhNjYxMDBhNzYzMDBhNzY0MDBhNzY2MDBhNzY3MDBhODY5MDBhODZhMDBhODZjMDBhODZlMDBhODZmMDBhODcxMDBhODcyMDFhODc0MDFhODc1MDFhODc3MDFhODc4MDFhODdhMDJhODdiMDJhODdkMDNhODdlMDNhODgwMDRhODgxMDRhNzgzMDVhNzg0MDVhNzg2MDZhNjg3MDdhNjg4MDhhNjhhMDlhNThiMGFhNThkMGJhNThlMGNhNDhmMGRhNDkxMGVhMzkyMGZhMzk0MTBhMjk1MTFhMTk2MTNhMTk4MTRhMDk5MTU5ZjlhMTY5ZjljMTc5ZTlkMTg5ZDllMTk5ZGEwMWE5Y2ExMWI5YmEyMWQ5YWEzMWU5YWE1MWY5OWE2MjA5OGE3MjE5N2E4MjI5NmFhMjM5NWFiMjQ5NGFjMjY5NGFkMjc5M2FlMjg5MmIwMjk5MWIxMmE5MGIyMmI4ZmIzMmM4ZWI0MmU4ZGI1MmY4Y2I2MzA4YmI3MzE4YWI4MzI4OWJhMzM4OGJiMzQ4OGJjMzU4N2JkMzc4NmJlMzg4NWJmMzk4NGMwM2E4M2MxM2I4MmMyM2M4MWMzM2Q4MGM0M2U3ZmM1NDA3ZWM2NDE3ZGM3NDI3Y2M4NDM3YmM5NDQ3YWNhNDU3YWNiNDY3OWNjNDc3OGNjNDk3N2NkNGE3NmNlNGI3NWNmNGM3NGQwNGQ3M2QxNGU3MmQyNGY3MWQzNTE3MWQ0NTI3MGQ1NTM2ZmQ1NTQ2ZWQ2NTU2ZGQ3NTY2Y2Q4NTc2YmQ5NTg2YWRhNWE2YWRhNWI2OWRiNWM2OGRjNWQ2N2RkNWU2NmRlNWY2NWRlNjE2NGRmNjI2M2UwNjM2M2UxNjQ2MmUyNjU2MWUyNjY2MGUzNjg1ZmU0Njk1ZWU1NmE1ZGU1NmI1ZGU2NmM1Y2U3NmU1YmU3NmY1YWU4NzA1OWU5NzE1OGU5NzI1N2VhNzQ1N2ViNzU1NmViNzY1NWVjNzc1NGVkNzk1M2VkN2E1MmVlN2I1MWVmN2M1MWVmN2U1MGYwN2Y0ZmYwODA0ZWYxODE0ZGYxODM0Y2YyODQ0YmYzODU0YmYzODc0YWY0ODg0OWY0ODk0OGY1OGI0N2Y1OGM0NmY2OGQ0NWY2OGY0NGY3OTA0NGY3OTE0M2Y3OTM0MmY4OTQ0MWY4OTU0MGY5OTczZmY5OTgzZWY5OWEzZWZhOWIzZGZhOWMzY2ZhOWUzYmZiOWYzYWZiYTEzOWZiYTIzOGZjYTMzOGZjYTUzN2ZjYTYzNmZjYTgzNWZjYTkzNGZkYWIzM2ZkYWMzM2ZkYWUzMmZkYWYzMWZkYjEzMGZkYjIyZmZkYjQyZmZkYjUyZWZlYjcyZGZlYjgyY2ZlYmEyY2ZlYmIyYmZlYmQyYWZlYmUyYWZlYzAyOWZkYzIyOWZkYzMyOGZkYzUyN2ZkYzYyN2ZkYzgyN2ZkY2EyNmZkY2IyNmZjY2QyNWZjY2UyNWZjZDAyNWZjZDIyNWZiZDMyNGZiZDUyNGZiZDcyNGZhZDgyNGZhZGEyNGY5ZGMyNGY5ZGQyNWY4ZGYyNWY4ZTEyNWY3ZTIyNWY3ZTQyNWY2ZTYyNmY2ZTgyNmY1ZTkyNmY1ZWIyN2Y0ZWQyN2YzZWUyN2YzZjAyN2YyZjIyN2YxZjQyNmYxZjUyNWYwZjcyNGYwZjkyMVwiKSk7XG5cbmZ1bmN0aW9uIHNlcXVlbnRpYWwoaW50ZXJwb2xhdG9yKSB7XG4gIHZhciB4MCA9IDAsXG4gICAgICB4MSA9IDEsXG4gICAgICBjbGFtcCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICB2YXIgdCA9ICh4IC0geDApIC8gKHgxIC0geDApO1xuICAgIHJldHVybiBpbnRlcnBvbGF0b3IoY2xhbXAgPyBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCB0KSkgOiB0KTtcbiAgfVxuXG4gIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MCA9ICtfWzBdLCB4MSA9ICtfWzFdLCBzY2FsZSkgOiBbeDAsIHgxXTtcbiAgfTtcblxuICBzY2FsZS5jbGFtcCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjbGFtcCA9ICEhXywgc2NhbGUpIDogY2xhbXA7XG4gIH07XG5cbiAgc2NhbGUuaW50ZXJwb2xhdG9yID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGludGVycG9sYXRvciA9IF8sIHNjYWxlKSA6IGludGVycG9sYXRvcjtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNlcXVlbnRpYWwoaW50ZXJwb2xhdG9yKS5kb21haW4oW3gwLCB4MV0pLmNsYW1wKGNsYW1wKTtcbiAgfTtcblxuICByZXR1cm4gbGluZWFyaXNoKHNjYWxlKTtcbn1cblxudmFyIHhodG1sID0gXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI7XG5cbnZhciBuYW1lc3BhY2VzID0ge1xuICBzdmc6IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIixcbiAgeGh0bWw6IHhodG1sLFxuICB4bGluazogXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIsXG4gIHhtbDogXCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VcIixcbiAgeG1sbnM6IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy9cIlxufTtcblxudmFyIG5hbWVzcGFjZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIHByZWZpeCA9IG5hbWUgKz0gXCJcIiwgaSA9IHByZWZpeC5pbmRleE9mKFwiOlwiKTtcbiAgaWYgKGkgPj0gMCAmJiAocHJlZml4ID0gbmFtZS5zbGljZSgwLCBpKSkgIT09IFwieG1sbnNcIikgbmFtZSA9IG5hbWUuc2xpY2UoaSArIDEpO1xuICByZXR1cm4gbmFtZXNwYWNlcy5oYXNPd25Qcm9wZXJ0eShwcmVmaXgpID8ge3NwYWNlOiBuYW1lc3BhY2VzW3ByZWZpeF0sIGxvY2FsOiBuYW1lfSA6IG5hbWU7XG59O1xuXG5mdW5jdGlvbiBjcmVhdG9ySW5oZXJpdChuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgZG9jdW1lbnQgPSB0aGlzLm93bmVyRG9jdW1lbnQsXG4gICAgICAgIHVyaSA9IHRoaXMubmFtZXNwYWNlVVJJO1xuICAgIHJldHVybiB1cmkgPT09IHhodG1sICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5uYW1lc3BhY2VVUkkgPT09IHhodG1sXG4gICAgICAgID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChuYW1lKVxuICAgICAgICA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyh1cmksIG5hbWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdG9yRml4ZWQoZnVsbG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7XG4gIH07XG59XG5cbnZhciBjcmVhdG9yID0gZnVuY3Rpb24obmFtZSkge1xuICB2YXIgZnVsbG5hbWUgPSBuYW1lc3BhY2UobmFtZSk7XG4gIHJldHVybiAoZnVsbG5hbWUubG9jYWxcbiAgICAgID8gY3JlYXRvckZpeGVkXG4gICAgICA6IGNyZWF0b3JJbmhlcml0KShmdWxsbmFtZSk7XG59O1xuXG52YXIgbmV4dElkID0gMDtcblxuZnVuY3Rpb24gbG9jYWwoKSB7XG4gIHJldHVybiBuZXcgTG9jYWw7XG59XG5cbmZ1bmN0aW9uIExvY2FsKCkge1xuICB0aGlzLl8gPSBcIkBcIiArICgrK25leHRJZCkudG9TdHJpbmcoMzYpO1xufVxuXG5Mb2NhbC5wcm90b3R5cGUgPSBsb2NhbC5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBMb2NhbCxcbiAgZ2V0OiBmdW5jdGlvbihub2RlKSB7XG4gICAgdmFyIGlkID0gdGhpcy5fO1xuICAgIHdoaWxlICghKGlkIGluIG5vZGUpKSBpZiAoIShub2RlID0gbm9kZS5wYXJlbnROb2RlKSkgcmV0dXJuO1xuICAgIHJldHVybiBub2RlW2lkXTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihub2RlLCB2YWx1ZSkge1xuICAgIHJldHVybiBub2RlW3RoaXMuX10gPSB2YWx1ZTtcbiAgfSxcbiAgcmVtb3ZlOiBmdW5jdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIHRoaXMuXyBpbiBub2RlICYmIGRlbGV0ZSBub2RlW3RoaXMuX107XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fO1xuICB9XG59O1xuXG52YXIgbWF0Y2hlciA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaGVzKHNlbGVjdG9yKTtcbiAgfTtcbn07XG5cbmlmICh0eXBlb2YgZG9jdW1lbnQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gIGlmICghZWxlbWVudC5tYXRjaGVzKSB7XG4gICAgdmFyIHZlbmRvck1hdGNoZXMgPSBlbGVtZW50LndlYmtpdE1hdGNoZXNTZWxlY3RvclxuICAgICAgICB8fCBlbGVtZW50Lm1zTWF0Y2hlc1NlbGVjdG9yXG4gICAgICAgIHx8IGVsZW1lbnQubW96TWF0Y2hlc1NlbGVjdG9yXG4gICAgICAgIHx8IGVsZW1lbnQub01hdGNoZXNTZWxlY3RvcjtcbiAgICBtYXRjaGVyID0gZnVuY3Rpb24oc2VsZWN0b3IpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHZlbmRvck1hdGNoZXMuY2FsbCh0aGlzLCBzZWxlY3Rvcik7XG4gICAgICB9O1xuICAgIH07XG4gIH1cbn1cblxudmFyIG1hdGNoZXIkMSA9IG1hdGNoZXI7XG5cbnZhciBmaWx0ZXJFdmVudHMgPSB7fTtcblxuZXhwb3J0cy5ldmVudCA9IG51bGw7XG5cbmlmICh0eXBlb2YgZG9jdW1lbnQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgdmFyIGVsZW1lbnQkMSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgaWYgKCEoXCJvbm1vdXNlZW50ZXJcIiBpbiBlbGVtZW50JDEpKSB7XG4gICAgZmlsdGVyRXZlbnRzID0ge21vdXNlZW50ZXI6IFwibW91c2VvdmVyXCIsIG1vdXNlbGVhdmU6IFwibW91c2VvdXRcIn07XG4gIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyQ29udGV4dExpc3RlbmVyKGxpc3RlbmVyLCBpbmRleCwgZ3JvdXApIHtcbiAgbGlzdGVuZXIgPSBjb250ZXh0TGlzdGVuZXIobGlzdGVuZXIsIGluZGV4LCBncm91cCk7XG4gIHJldHVybiBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciByZWxhdGVkID0gZXZlbnQucmVsYXRlZFRhcmdldDtcbiAgICBpZiAoIXJlbGF0ZWQgfHwgKHJlbGF0ZWQgIT09IHRoaXMgJiYgIShyZWxhdGVkLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKHRoaXMpICYgOCkpKSB7XG4gICAgICBsaXN0ZW5lci5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbnRleHRMaXN0ZW5lcihsaXN0ZW5lciwgaW5kZXgsIGdyb3VwKSB7XG4gIHJldHVybiBmdW5jdGlvbihldmVudDEpIHtcbiAgICB2YXIgZXZlbnQwID0gZXhwb3J0cy5ldmVudDsgLy8gRXZlbnRzIGNhbiBiZSByZWVudHJhbnQgKGUuZy4sIGZvY3VzKS5cbiAgICBleHBvcnRzLmV2ZW50ID0gZXZlbnQxO1xuICAgIHRyeSB7XG4gICAgICBsaXN0ZW5lci5jYWxsKHRoaXMsIHRoaXMuX19kYXRhX18sIGluZGV4LCBncm91cCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGV4cG9ydHMuZXZlbnQgPSBldmVudDA7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZVR5cGVuYW1lcyQxKHR5cGVuYW1lcykge1xuICByZXR1cm4gdHlwZW5hbWVzLnRyaW0oKS5zcGxpdCgvXnxcXHMrLykubWFwKGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgbmFtZSA9IFwiXCIsIGkgPSB0LmluZGV4T2YoXCIuXCIpO1xuICAgIGlmIChpID49IDApIG5hbWUgPSB0LnNsaWNlKGkgKyAxKSwgdCA9IHQuc2xpY2UoMCwgaSk7XG4gICAgcmV0dXJuIHt0eXBlOiB0LCBuYW1lOiBuYW1lfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG9uUmVtb3ZlKHR5cGVuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgb24gPSB0aGlzLl9fb247XG4gICAgaWYgKCFvbikgcmV0dXJuO1xuICAgIGZvciAodmFyIGogPSAwLCBpID0gLTEsIG0gPSBvbi5sZW5ndGgsIG87IGogPCBtOyArK2opIHtcbiAgICAgIGlmIChvID0gb25bal0sICghdHlwZW5hbWUudHlwZSB8fCBvLnR5cGUgPT09IHR5cGVuYW1lLnR5cGUpICYmIG8ubmFtZSA9PT0gdHlwZW5hbWUubmFtZSkge1xuICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoby50eXBlLCBvLmxpc3RlbmVyLCBvLmNhcHR1cmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb25bKytpXSA9IG87XG4gICAgICB9XG4gICAgfVxuICAgIGlmICgrK2kpIG9uLmxlbmd0aCA9IGk7XG4gICAgZWxzZSBkZWxldGUgdGhpcy5fX29uO1xuICB9O1xufVxuXG5mdW5jdGlvbiBvbkFkZCh0eXBlbmFtZSwgdmFsdWUsIGNhcHR1cmUpIHtcbiAgdmFyIHdyYXAgPSBmaWx0ZXJFdmVudHMuaGFzT3duUHJvcGVydHkodHlwZW5hbWUudHlwZSkgPyBmaWx0ZXJDb250ZXh0TGlzdGVuZXIgOiBjb250ZXh0TGlzdGVuZXI7XG4gIHJldHVybiBmdW5jdGlvbihkLCBpLCBncm91cCkge1xuICAgIHZhciBvbiA9IHRoaXMuX19vbiwgbywgbGlzdGVuZXIgPSB3cmFwKHZhbHVlLCBpLCBncm91cCk7XG4gICAgaWYgKG9uKSBmb3IgKHZhciBqID0gMCwgbSA9IG9uLmxlbmd0aDsgaiA8IG07ICsraikge1xuICAgICAgaWYgKChvID0gb25bal0pLnR5cGUgPT09IHR5cGVuYW1lLnR5cGUgJiYgby5uYW1lID09PSB0eXBlbmFtZS5uYW1lKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihvLnR5cGUsIG8ubGlzdGVuZXIsIG8uY2FwdHVyZSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihvLnR5cGUsIG8ubGlzdGVuZXIgPSBsaXN0ZW5lciwgby5jYXB0dXJlID0gY2FwdHVyZSk7XG4gICAgICAgIG8udmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIodHlwZW5hbWUudHlwZSwgbGlzdGVuZXIsIGNhcHR1cmUpO1xuICAgIG8gPSB7dHlwZTogdHlwZW5hbWUudHlwZSwgbmFtZTogdHlwZW5hbWUubmFtZSwgdmFsdWU6IHZhbHVlLCBsaXN0ZW5lcjogbGlzdGVuZXIsIGNhcHR1cmU6IGNhcHR1cmV9O1xuICAgIGlmICghb24pIHRoaXMuX19vbiA9IFtvXTtcbiAgICBlbHNlIG9uLnB1c2gobyk7XG4gIH07XG59XG5cbnZhciBzZWxlY3Rpb25fb24gPSBmdW5jdGlvbih0eXBlbmFtZSwgdmFsdWUsIGNhcHR1cmUpIHtcbiAgdmFyIHR5cGVuYW1lcyA9IHBhcnNlVHlwZW5hbWVzJDEodHlwZW5hbWUgKyBcIlwiKSwgaSwgbiA9IHR5cGVuYW1lcy5sZW5ndGgsIHQ7XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgdmFyIG9uID0gdGhpcy5ub2RlKCkuX19vbjtcbiAgICBpZiAob24pIGZvciAodmFyIGogPSAwLCBtID0gb24ubGVuZ3RoLCBvOyBqIDwgbTsgKytqKSB7XG4gICAgICBmb3IgKGkgPSAwLCBvID0gb25bal07IGkgPCBuOyArK2kpIHtcbiAgICAgICAgaWYgKCh0ID0gdHlwZW5hbWVzW2ldKS50eXBlID09PSBvLnR5cGUgJiYgdC5uYW1lID09PSBvLm5hbWUpIHtcbiAgICAgICAgICByZXR1cm4gby52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBvbiA9IHZhbHVlID8gb25BZGQgOiBvblJlbW92ZTtcbiAgaWYgKGNhcHR1cmUgPT0gbnVsbCkgY2FwdHVyZSA9IGZhbHNlO1xuICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB0aGlzLmVhY2gob24odHlwZW5hbWVzW2ldLCB2YWx1ZSwgY2FwdHVyZSkpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGN1c3RvbUV2ZW50KGV2ZW50MSwgbGlzdGVuZXIsIHRoYXQsIGFyZ3MpIHtcbiAgdmFyIGV2ZW50MCA9IGV4cG9ydHMuZXZlbnQ7XG4gIGV2ZW50MS5zb3VyY2VFdmVudCA9IGV4cG9ydHMuZXZlbnQ7XG4gIGV4cG9ydHMuZXZlbnQgPSBldmVudDE7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyLmFwcGx5KHRoYXQsIGFyZ3MpO1xuICB9IGZpbmFsbHkge1xuICAgIGV4cG9ydHMuZXZlbnQgPSBldmVudDA7XG4gIH1cbn1cblxudmFyIHNvdXJjZUV2ZW50ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjdXJyZW50ID0gZXhwb3J0cy5ldmVudCwgc291cmNlO1xuICB3aGlsZSAoc291cmNlID0gY3VycmVudC5zb3VyY2VFdmVudCkgY3VycmVudCA9IHNvdXJjZTtcbiAgcmV0dXJuIGN1cnJlbnQ7XG59O1xuXG52YXIgcG9pbnQkNSA9IGZ1bmN0aW9uKG5vZGUsIGV2ZW50KSB7XG4gIHZhciBzdmcgPSBub2RlLm93bmVyU1ZHRWxlbWVudCB8fCBub2RlO1xuXG4gIGlmIChzdmcuY3JlYXRlU1ZHUG9pbnQpIHtcbiAgICB2YXIgcG9pbnQgPSBzdmcuY3JlYXRlU1ZHUG9pbnQoKTtcbiAgICBwb2ludC54ID0gZXZlbnQuY2xpZW50WCwgcG9pbnQueSA9IGV2ZW50LmNsaWVudFk7XG4gICAgcG9pbnQgPSBwb2ludC5tYXRyaXhUcmFuc2Zvcm0obm9kZS5nZXRTY3JlZW5DVE0oKS5pbnZlcnNlKCkpO1xuICAgIHJldHVybiBbcG9pbnQueCwgcG9pbnQueV07XG4gIH1cblxuICB2YXIgcmVjdCA9IG5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIHJldHVybiBbZXZlbnQuY2xpZW50WCAtIHJlY3QubGVmdCAtIG5vZGUuY2xpZW50TGVmdCwgZXZlbnQuY2xpZW50WSAtIHJlY3QudG9wIC0gbm9kZS5jbGllbnRUb3BdO1xufTtcblxudmFyIG1vdXNlID0gZnVuY3Rpb24obm9kZSkge1xuICB2YXIgZXZlbnQgPSBzb3VyY2VFdmVudCgpO1xuICBpZiAoZXZlbnQuY2hhbmdlZFRvdWNoZXMpIGV2ZW50ID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XG4gIHJldHVybiBwb2ludCQ1KG5vZGUsIGV2ZW50KTtcbn07XG5cbmZ1bmN0aW9uIG5vbmUkMigpIHt9XG5cbnZhciBzZWxlY3RvciA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gIHJldHVybiBzZWxlY3RvciA9PSBudWxsID8gbm9uZSQyIDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gIH07XG59O1xuXG52YXIgc2VsZWN0aW9uX3NlbGVjdCA9IGZ1bmN0aW9uKHNlbGVjdCkge1xuICBpZiAodHlwZW9mIHNlbGVjdCAhPT0gXCJmdW5jdGlvblwiKSBzZWxlY3QgPSBzZWxlY3RvcihzZWxlY3QpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHN1Ymdyb3VwcyA9IG5ldyBBcnJheShtKSwgaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgc3ViZ3JvdXAgPSBzdWJncm91cHNbal0gPSBuZXcgQXJyYXkobiksIG5vZGUsIHN1Ym5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKG5vZGUgPSBncm91cFtpXSkgJiYgKHN1Ym5vZGUgPSBzZWxlY3QuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpKSB7XG4gICAgICAgIGlmIChcIl9fZGF0YV9fXCIgaW4gbm9kZSkgc3Vibm9kZS5fX2RhdGFfXyA9IG5vZGUuX19kYXRhX187XG4gICAgICAgIHN1Ymdyb3VwW2ldID0gc3Vibm9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFNlbGVjdGlvbihzdWJncm91cHMsIHRoaXMuX3BhcmVudHMpO1xufTtcblxuZnVuY3Rpb24gZW1wdHkoKSB7XG4gIHJldHVybiBbXTtcbn1cblxudmFyIHNlbGVjdG9yQWxsID0gZnVuY3Rpb24oc2VsZWN0b3IpIHtcbiAgcmV0dXJuIHNlbGVjdG9yID09IG51bGwgPyBlbXB0eSA6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICB9O1xufTtcblxudmFyIHNlbGVjdGlvbl9zZWxlY3RBbGwgPSBmdW5jdGlvbihzZWxlY3QpIHtcbiAgaWYgKHR5cGVvZiBzZWxlY3QgIT09IFwiZnVuY3Rpb25cIikgc2VsZWN0ID0gc2VsZWN0b3JBbGwoc2VsZWN0KTtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzdWJncm91cHMgPSBbXSwgcGFyZW50cyA9IFtdLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBzdWJncm91cHMucHVzaChzZWxlY3QuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpO1xuICAgICAgICBwYXJlbnRzLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oc3ViZ3JvdXBzLCBwYXJlbnRzKTtcbn07XG5cbnZhciBzZWxlY3Rpb25fZmlsdGVyID0gZnVuY3Rpb24obWF0Y2gpIHtcbiAgaWYgKHR5cGVvZiBtYXRjaCAhPT0gXCJmdW5jdGlvblwiKSBtYXRjaCA9IG1hdGNoZXIkMShtYXRjaCk7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzdWJncm91cCA9IHN1Ymdyb3Vwc1tqXSA9IFtdLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKChub2RlID0gZ3JvdXBbaV0pICYmIG1hdGNoLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgZ3JvdXApKSB7XG4gICAgICAgIHN1Ymdyb3VwLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oc3ViZ3JvdXBzLCB0aGlzLl9wYXJlbnRzKTtcbn07XG5cbnZhciBzcGFyc2UgPSBmdW5jdGlvbih1cGRhdGUpIHtcbiAgcmV0dXJuIG5ldyBBcnJheSh1cGRhdGUubGVuZ3RoKTtcbn07XG5cbnZhciBzZWxlY3Rpb25fZW50ZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24odGhpcy5fZW50ZXIgfHwgdGhpcy5fZ3JvdXBzLm1hcChzcGFyc2UpLCB0aGlzLl9wYXJlbnRzKTtcbn07XG5cbmZ1bmN0aW9uIEVudGVyTm9kZShwYXJlbnQsIGRhdHVtKSB7XG4gIHRoaXMub3duZXJEb2N1bWVudCA9IHBhcmVudC5vd25lckRvY3VtZW50O1xuICB0aGlzLm5hbWVzcGFjZVVSSSA9IHBhcmVudC5uYW1lc3BhY2VVUkk7XG4gIHRoaXMuX25leHQgPSBudWxsO1xuICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMuX19kYXRhX18gPSBkYXR1bTtcbn1cblxuRW50ZXJOb2RlLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IEVudGVyTm9kZSxcbiAgYXBwZW5kQ2hpbGQ6IGZ1bmN0aW9uKGNoaWxkKSB7IHJldHVybiB0aGlzLl9wYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCB0aGlzLl9uZXh0KTsgfSxcbiAgaW5zZXJ0QmVmb3JlOiBmdW5jdGlvbihjaGlsZCwgbmV4dCkgeyByZXR1cm4gdGhpcy5fcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgbmV4dCk7IH0sXG4gIHF1ZXJ5U2VsZWN0b3I6IGZ1bmN0aW9uKHNlbGVjdG9yKSB7IHJldHVybiB0aGlzLl9wYXJlbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7IH0sXG4gIHF1ZXJ5U2VsZWN0b3JBbGw6IGZ1bmN0aW9uKHNlbGVjdG9yKSB7IHJldHVybiB0aGlzLl9wYXJlbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7IH1cbn07XG5cbnZhciBjb25zdGFudCQ1ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG52YXIga2V5UHJlZml4ID0gXCIkXCI7IC8vIFByb3RlY3QgYWdhaW5zdCBrZXlzIGxpa2Ug4oCcX19wcm90b19f4oCdLlxuXG5mdW5jdGlvbiBiaW5kSW5kZXgocGFyZW50LCBncm91cCwgZW50ZXIsIHVwZGF0ZSwgZXhpdCwgZGF0YSkge1xuICB2YXIgaSA9IDAsXG4gICAgICBub2RlLFxuICAgICAgZ3JvdXBMZW5ndGggPSBncm91cC5sZW5ndGgsXG4gICAgICBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGg7XG5cbiAgLy8gUHV0IGFueSBub24tbnVsbCBub2RlcyB0aGF0IGZpdCBpbnRvIHVwZGF0ZS5cbiAgLy8gUHV0IGFueSBudWxsIG5vZGVzIGludG8gZW50ZXIuXG4gIC8vIFB1dCBhbnkgcmVtYWluaW5nIGRhdGEgaW50byBlbnRlci5cbiAgZm9yICg7IGkgPCBkYXRhTGVuZ3RoOyArK2kpIHtcbiAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICBub2RlLl9fZGF0YV9fID0gZGF0YVtpXTtcbiAgICAgIHVwZGF0ZVtpXSA9IG5vZGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudGVyW2ldID0gbmV3IEVudGVyTm9kZShwYXJlbnQsIGRhdGFbaV0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIFB1dCBhbnkgbm9uLW51bGwgbm9kZXMgdGhhdCBkb27igJl0IGZpdCBpbnRvIGV4aXQuXG4gIGZvciAoOyBpIDwgZ3JvdXBMZW5ndGg7ICsraSkge1xuICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgIGV4aXRbaV0gPSBub2RlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBiaW5kS2V5KHBhcmVudCwgZ3JvdXAsIGVudGVyLCB1cGRhdGUsIGV4aXQsIGRhdGEsIGtleSkge1xuICB2YXIgaSxcbiAgICAgIG5vZGUsXG4gICAgICBub2RlQnlLZXlWYWx1ZSA9IHt9LFxuICAgICAgZ3JvdXBMZW5ndGggPSBncm91cC5sZW5ndGgsXG4gICAgICBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGgsXG4gICAgICBrZXlWYWx1ZXMgPSBuZXcgQXJyYXkoZ3JvdXBMZW5ndGgpLFxuICAgICAga2V5VmFsdWU7XG5cbiAgLy8gQ29tcHV0ZSB0aGUga2V5IGZvciBlYWNoIG5vZGUuXG4gIC8vIElmIG11bHRpcGxlIG5vZGVzIGhhdmUgdGhlIHNhbWUga2V5LCB0aGUgZHVwbGljYXRlcyBhcmUgYWRkZWQgdG8gZXhpdC5cbiAgZm9yIChpID0gMDsgaSA8IGdyb3VwTGVuZ3RoOyArK2kpIHtcbiAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICBrZXlWYWx1ZXNbaV0gPSBrZXlWYWx1ZSA9IGtleVByZWZpeCArIGtleS5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKTtcbiAgICAgIGlmIChrZXlWYWx1ZSBpbiBub2RlQnlLZXlWYWx1ZSkge1xuICAgICAgICBleGl0W2ldID0gbm9kZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGVCeUtleVZhbHVlW2tleVZhbHVlXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ29tcHV0ZSB0aGUga2V5IGZvciBlYWNoIGRhdHVtLlxuICAvLyBJZiB0aGVyZSBhIG5vZGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMga2V5LCBqb2luIGFuZCBhZGQgaXQgdG8gdXBkYXRlLlxuICAvLyBJZiB0aGVyZSBpcyBub3QgKG9yIHRoZSBrZXkgaXMgYSBkdXBsaWNhdGUpLCBhZGQgaXQgdG8gZW50ZXIuXG4gIGZvciAoaSA9IDA7IGkgPCBkYXRhTGVuZ3RoOyArK2kpIHtcbiAgICBrZXlWYWx1ZSA9IGtleVByZWZpeCArIGtleS5jYWxsKHBhcmVudCwgZGF0YVtpXSwgaSwgZGF0YSk7XG4gICAgaWYgKG5vZGUgPSBub2RlQnlLZXlWYWx1ZVtrZXlWYWx1ZV0pIHtcbiAgICAgIHVwZGF0ZVtpXSA9IG5vZGU7XG4gICAgICBub2RlLl9fZGF0YV9fID0gZGF0YVtpXTtcbiAgICAgIG5vZGVCeUtleVZhbHVlW2tleVZhbHVlXSA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudGVyW2ldID0gbmV3IEVudGVyTm9kZShwYXJlbnQsIGRhdGFbaV0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFkZCBhbnkgcmVtYWluaW5nIG5vZGVzIHRoYXQgd2VyZSBub3QgYm91bmQgdG8gZGF0YSB0byBleGl0LlxuICBmb3IgKGkgPSAwOyBpIDwgZ3JvdXBMZW5ndGg7ICsraSkge1xuICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiAobm9kZUJ5S2V5VmFsdWVba2V5VmFsdWVzW2ldXSA9PT0gbm9kZSkpIHtcbiAgICAgIGV4aXRbaV0gPSBub2RlO1xuICAgIH1cbiAgfVxufVxuXG52YXIgc2VsZWN0aW9uX2RhdGEgPSBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gIGlmICghdmFsdWUpIHtcbiAgICBkYXRhID0gbmV3IEFycmF5KHRoaXMuc2l6ZSgpKSwgaiA9IC0xO1xuICAgIHRoaXMuZWFjaChmdW5jdGlvbihkKSB7IGRhdGFbKytqXSA9IGQ7IH0pO1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgdmFyIGJpbmQgPSBrZXkgPyBiaW5kS2V5IDogYmluZEluZGV4LFxuICAgICAgcGFyZW50cyA9IHRoaXMuX3BhcmVudHMsXG4gICAgICBncm91cHMgPSB0aGlzLl9ncm91cHM7XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB2YWx1ZSA9IGNvbnN0YW50JDUodmFsdWUpO1xuXG4gIGZvciAodmFyIG0gPSBncm91cHMubGVuZ3RoLCB1cGRhdGUgPSBuZXcgQXJyYXkobSksIGVudGVyID0gbmV3IEFycmF5KG0pLCBleGl0ID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIHZhciBwYXJlbnQgPSBwYXJlbnRzW2pdLFxuICAgICAgICBncm91cCA9IGdyb3Vwc1tqXSxcbiAgICAgICAgZ3JvdXBMZW5ndGggPSBncm91cC5sZW5ndGgsXG4gICAgICAgIGRhdGEgPSB2YWx1ZS5jYWxsKHBhcmVudCwgcGFyZW50ICYmIHBhcmVudC5fX2RhdGFfXywgaiwgcGFyZW50cyksXG4gICAgICAgIGRhdGFMZW5ndGggPSBkYXRhLmxlbmd0aCxcbiAgICAgICAgZW50ZXJHcm91cCA9IGVudGVyW2pdID0gbmV3IEFycmF5KGRhdGFMZW5ndGgpLFxuICAgICAgICB1cGRhdGVHcm91cCA9IHVwZGF0ZVtqXSA9IG5ldyBBcnJheShkYXRhTGVuZ3RoKSxcbiAgICAgICAgZXhpdEdyb3VwID0gZXhpdFtqXSA9IG5ldyBBcnJheShncm91cExlbmd0aCk7XG5cbiAgICBiaW5kKHBhcmVudCwgZ3JvdXAsIGVudGVyR3JvdXAsIHVwZGF0ZUdyb3VwLCBleGl0R3JvdXAsIGRhdGEsIGtleSk7XG5cbiAgICAvLyBOb3cgY29ubmVjdCB0aGUgZW50ZXIgbm9kZXMgdG8gdGhlaXIgZm9sbG93aW5nIHVwZGF0ZSBub2RlLCBzdWNoIHRoYXRcbiAgICAvLyBhcHBlbmRDaGlsZCBjYW4gaW5zZXJ0IHRoZSBtYXRlcmlhbGl6ZWQgZW50ZXIgbm9kZSBiZWZvcmUgdGhpcyBub2RlLFxuICAgIC8vIHJhdGhlciB0aGFuIGF0IHRoZSBlbmQgb2YgdGhlIHBhcmVudCBub2RlLlxuICAgIGZvciAodmFyIGkwID0gMCwgaTEgPSAwLCBwcmV2aW91cywgbmV4dDsgaTAgPCBkYXRhTGVuZ3RoOyArK2kwKSB7XG4gICAgICBpZiAocHJldmlvdXMgPSBlbnRlckdyb3VwW2kwXSkge1xuICAgICAgICBpZiAoaTAgPj0gaTEpIGkxID0gaTAgKyAxO1xuICAgICAgICB3aGlsZSAoIShuZXh0ID0gdXBkYXRlR3JvdXBbaTFdKSAmJiArK2kxIDwgZGF0YUxlbmd0aCk7XG4gICAgICAgIHByZXZpb3VzLl9uZXh0ID0gbmV4dCB8fCBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZSA9IG5ldyBTZWxlY3Rpb24odXBkYXRlLCBwYXJlbnRzKTtcbiAgdXBkYXRlLl9lbnRlciA9IGVudGVyO1xuICB1cGRhdGUuX2V4aXQgPSBleGl0O1xuICByZXR1cm4gdXBkYXRlO1xufTtcblxudmFyIHNlbGVjdGlvbl9leGl0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHRoaXMuX2V4aXQgfHwgdGhpcy5fZ3JvdXBzLm1hcChzcGFyc2UpLCB0aGlzLl9wYXJlbnRzKTtcbn07XG5cbnZhciBzZWxlY3Rpb25fbWVyZ2UgPSBmdW5jdGlvbihzZWxlY3Rpb24pIHtcblxuICBmb3IgKHZhciBncm91cHMwID0gdGhpcy5fZ3JvdXBzLCBncm91cHMxID0gc2VsZWN0aW9uLl9ncm91cHMsIG0wID0gZ3JvdXBzMC5sZW5ndGgsIG0xID0gZ3JvdXBzMS5sZW5ndGgsIG0gPSBNYXRoLm1pbihtMCwgbTEpLCBtZXJnZXMgPSBuZXcgQXJyYXkobTApLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwMCA9IGdyb3VwczBbal0sIGdyb3VwMSA9IGdyb3VwczFbal0sIG4gPSBncm91cDAubGVuZ3RoLCBtZXJnZSA9IG1lcmdlc1tqXSA9IG5ldyBBcnJheShuKSwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmIChub2RlID0gZ3JvdXAwW2ldIHx8IGdyb3VwMVtpXSkge1xuICAgICAgICBtZXJnZVtpXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IGogPCBtMDsgKytqKSB7XG4gICAgbWVyZ2VzW2pdID0gZ3JvdXBzMFtqXTtcbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKG1lcmdlcywgdGhpcy5fcGFyZW50cyk7XG59O1xuXG52YXIgc2VsZWN0aW9uX29yZGVyID0gZnVuY3Rpb24oKSB7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBqID0gLTEsIG0gPSBncm91cHMubGVuZ3RoOyArK2ogPCBtOykge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBpID0gZ3JvdXAubGVuZ3RoIC0gMSwgbmV4dCA9IGdyb3VwW2ldLCBub2RlOyAtLWkgPj0gMDspIHtcbiAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgICAgaWYgKG5leHQgJiYgbmV4dCAhPT0gbm9kZS5uZXh0U2libGluZykgbmV4dC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShub2RlLCBuZXh0KTtcbiAgICAgICAgbmV4dCA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG52YXIgc2VsZWN0aW9uX3NvcnQgPSBmdW5jdGlvbihjb21wYXJlKSB7XG4gIGlmICghY29tcGFyZSkgY29tcGFyZSA9IGFzY2VuZGluZyQyO1xuXG4gIGZ1bmN0aW9uIGNvbXBhcmVOb2RlKGEsIGIpIHtcbiAgICByZXR1cm4gYSAmJiBiID8gY29tcGFyZShhLl9fZGF0YV9fLCBiLl9fZGF0YV9fKSA6ICFhIC0gIWI7XG4gIH1cblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzb3J0Z3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzb3J0Z3JvdXAgPSBzb3J0Z3JvdXBzW2pdID0gbmV3IEFycmF5KG4pLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBzb3J0Z3JvdXBbaV0gPSBub2RlO1xuICAgICAgfVxuICAgIH1cbiAgICBzb3J0Z3JvdXAuc29ydChjb21wYXJlTm9kZSk7XG4gIH1cblxuICByZXR1cm4gbmV3IFNlbGVjdGlvbihzb3J0Z3JvdXBzLCB0aGlzLl9wYXJlbnRzKS5vcmRlcigpO1xufTtcblxuZnVuY3Rpb24gYXNjZW5kaW5nJDIoYSwgYikge1xuICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IGEgPj0gYiA/IDAgOiBOYU47XG59XG5cbnZhciBzZWxlY3Rpb25fY2FsbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY2FsbGJhY2sgPSBhcmd1bWVudHNbMF07XG4gIGFyZ3VtZW50c1swXSA9IHRoaXM7XG4gIGNhbGxiYWNrLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIHNlbGVjdGlvbl9ub2RlcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZXMgPSBuZXcgQXJyYXkodGhpcy5zaXplKCkpLCBpID0gLTE7XG4gIHRoaXMuZWFjaChmdW5jdGlvbigpIHsgbm9kZXNbKytpXSA9IHRoaXM7IH0pO1xuICByZXR1cm4gbm9kZXM7XG59O1xuXG52YXIgc2VsZWN0aW9uX25vZGUgPSBmdW5jdGlvbigpIHtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIGogPSAwLCBtID0gZ3JvdXBzLmxlbmd0aDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBpID0gMCwgbiA9IGdyb3VwLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgdmFyIG5vZGUgPSBncm91cFtpXTtcbiAgICAgIGlmIChub2RlKSByZXR1cm4gbm9kZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn07XG5cbnZhciBzZWxlY3Rpb25fc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2l6ZSA9IDA7XG4gIHRoaXMuZWFjaChmdW5jdGlvbigpIHsgKytzaXplOyB9KTtcbiAgcmV0dXJuIHNpemU7XG59O1xuXG52YXIgc2VsZWN0aW9uX2VtcHR5ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAhdGhpcy5ub2RlKCk7XG59O1xuXG52YXIgc2VsZWN0aW9uX2VhY2ggPSBmdW5jdGlvbihjYWxsYmFjaykge1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgaiA9IDAsIG0gPSBncm91cHMubGVuZ3RoOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIGkgPSAwLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSBjYWxsYmFjay5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGF0dHJSZW1vdmUobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJSZW1vdmVOUyhmdWxsbmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyQ29uc3RhbnQobmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckNvbnN0YW50TlMoZnVsbG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnNldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCwgdmFsdWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyRnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAodiA9PSBudWxsKSB0aGlzLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICBlbHNlIHRoaXMuc2V0QXR0cmlidXRlKG5hbWUsIHYpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyRnVuY3Rpb25OUyhmdWxsbmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAodiA9PSBudWxsKSB0aGlzLnJlbW92ZUF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7XG4gICAgZWxzZSB0aGlzLnNldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCwgdik7XG4gIH07XG59XG5cbnZhciBzZWxlY3Rpb25fYXR0ciA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHZhciBmdWxsbmFtZSA9IG5hbWVzcGFjZShuYW1lKTtcblxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMubm9kZSgpO1xuICAgIHJldHVybiBmdWxsbmFtZS5sb2NhbFxuICAgICAgICA/IG5vZGUuZ2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKVxuICAgICAgICA6IG5vZGUuZ2V0QXR0cmlidXRlKGZ1bGxuYW1lKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmVhY2goKHZhbHVlID09IG51bGxcbiAgICAgID8gKGZ1bGxuYW1lLmxvY2FsID8gYXR0clJlbW92ZU5TIDogYXR0clJlbW92ZSkgOiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gKGZ1bGxuYW1lLmxvY2FsID8gYXR0ckZ1bmN0aW9uTlMgOiBhdHRyRnVuY3Rpb24pXG4gICAgICA6IChmdWxsbmFtZS5sb2NhbCA/IGF0dHJDb25zdGFudE5TIDogYXR0ckNvbnN0YW50KSkpKGZ1bGxuYW1lLCB2YWx1ZSkpO1xufTtcblxudmFyIHdpbmRvdyA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgcmV0dXJuIChub2RlLm93bmVyRG9jdW1lbnQgJiYgbm9kZS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3KSAvLyBub2RlIGlzIGEgTm9kZVxuICAgICAgfHwgKG5vZGUuZG9jdW1lbnQgJiYgbm9kZSkgLy8gbm9kZSBpcyBhIFdpbmRvd1xuICAgICAgfHwgbm9kZS5kZWZhdWx0VmlldzsgLy8gbm9kZSBpcyBhIERvY3VtZW50XG59O1xuXG5mdW5jdGlvbiBzdHlsZVJlbW92ZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnN0eWxlLnJlbW92ZVByb3BlcnR5KG5hbWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdHlsZUNvbnN0YW50KG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5zdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdHlsZUZ1bmN0aW9uKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh2ID09IG51bGwpIHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVydHkobmFtZSk7XG4gICAgZWxzZSB0aGlzLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHYsIHByaW9yaXR5KTtcbiAgfTtcbn1cblxudmFyIHNlbGVjdGlvbl9zdHlsZSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICB2YXIgbm9kZTtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAxXG4gICAgICA/IHRoaXMuZWFjaCgodmFsdWUgPT0gbnVsbFxuICAgICAgICAgICAgPyBzdHlsZVJlbW92ZSA6IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IHN0eWxlRnVuY3Rpb25cbiAgICAgICAgICAgIDogc3R5bGVDb25zdGFudCkobmFtZSwgdmFsdWUsIHByaW9yaXR5ID09IG51bGwgPyBcIlwiIDogcHJpb3JpdHkpKVxuICAgICAgOiB3aW5kb3cobm9kZSA9IHRoaXMubm9kZSgpKVxuICAgICAgICAgIC5nZXRDb21wdXRlZFN0eWxlKG5vZGUsIG51bGwpXG4gICAgICAgICAgLmdldFByb3BlcnR5VmFsdWUobmFtZSk7XG59O1xuXG5mdW5jdGlvbiBwcm9wZXJ0eVJlbW92ZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBkZWxldGUgdGhpc1tuYW1lXTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcHJvcGVydHlDb25zdGFudChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpc1tuYW1lXSA9IHZhbHVlO1xuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9wZXJ0eUZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHYgPT0gbnVsbCkgZGVsZXRlIHRoaXNbbmFtZV07XG4gICAgZWxzZSB0aGlzW25hbWVdID0gdjtcbiAgfTtcbn1cblxudmFyIHNlbGVjdGlvbl9wcm9wZXJ0eSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMVxuICAgICAgPyB0aGlzLmVhY2goKHZhbHVlID09IG51bGxcbiAgICAgICAgICA/IHByb3BlcnR5UmVtb3ZlIDogdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IHByb3BlcnR5RnVuY3Rpb25cbiAgICAgICAgICA6IHByb3BlcnR5Q29uc3RhbnQpKG5hbWUsIHZhbHVlKSlcbiAgICAgIDogdGhpcy5ub2RlKClbbmFtZV07XG59O1xuXG5mdW5jdGlvbiBjbGFzc0FycmF5KHN0cmluZykge1xuICByZXR1cm4gc3RyaW5nLnRyaW0oKS5zcGxpdCgvXnxcXHMrLyk7XG59XG5cbmZ1bmN0aW9uIGNsYXNzTGlzdChub2RlKSB7XG4gIHJldHVybiBub2RlLmNsYXNzTGlzdCB8fCBuZXcgQ2xhc3NMaXN0KG5vZGUpO1xufVxuXG5mdW5jdGlvbiBDbGFzc0xpc3Qobm9kZSkge1xuICB0aGlzLl9ub2RlID0gbm9kZTtcbiAgdGhpcy5fbmFtZXMgPSBjbGFzc0FycmF5KG5vZGUuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIikgfHwgXCJcIik7XG59XG5cbkNsYXNzTGlzdC5wcm90b3R5cGUgPSB7XG4gIGFkZDogZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBpID0gdGhpcy5fbmFtZXMuaW5kZXhPZihuYW1lKTtcbiAgICBpZiAoaSA8IDApIHtcbiAgICAgIHRoaXMuX25hbWVzLnB1c2gobmFtZSk7XG4gICAgICB0aGlzLl9ub2RlLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIHRoaXMuX25hbWVzLmpvaW4oXCIgXCIpKTtcbiAgICB9XG4gIH0sXG4gIHJlbW92ZTogZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBpID0gdGhpcy5fbmFtZXMuaW5kZXhPZihuYW1lKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLl9uYW1lcy5zcGxpY2UoaSwgMSk7XG4gICAgICB0aGlzLl9ub2RlLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIHRoaXMuX25hbWVzLmpvaW4oXCIgXCIpKTtcbiAgICB9XG4gIH0sXG4gIGNvbnRhaW5zOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuX25hbWVzLmluZGV4T2YobmFtZSkgPj0gMDtcbiAgfVxufTtcblxuZnVuY3Rpb24gY2xhc3NlZEFkZChub2RlLCBuYW1lcykge1xuICB2YXIgbGlzdCA9IGNsYXNzTGlzdChub2RlKSwgaSA9IC0xLCBuID0gbmFtZXMubGVuZ3RoO1xuICB3aGlsZSAoKytpIDwgbikgbGlzdC5hZGQobmFtZXNbaV0pO1xufVxuXG5mdW5jdGlvbiBjbGFzc2VkUmVtb3ZlKG5vZGUsIG5hbWVzKSB7XG4gIHZhciBsaXN0ID0gY2xhc3NMaXN0KG5vZGUpLCBpID0gLTEsIG4gPSBuYW1lcy5sZW5ndGg7XG4gIHdoaWxlICgrK2kgPCBuKSBsaXN0LnJlbW92ZShuYW1lc1tpXSk7XG59XG5cbmZ1bmN0aW9uIGNsYXNzZWRUcnVlKG5hbWVzKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBjbGFzc2VkQWRkKHRoaXMsIG5hbWVzKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2xhc3NlZEZhbHNlKG5hbWVzKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBjbGFzc2VkUmVtb3ZlKHRoaXMsIG5hbWVzKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2xhc3NlZEZ1bmN0aW9uKG5hbWVzLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgKHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgPyBjbGFzc2VkQWRkIDogY2xhc3NlZFJlbW92ZSkodGhpcywgbmFtZXMpO1xuICB9O1xufVxuXG52YXIgc2VsZWN0aW9uX2NsYXNzZWQgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICB2YXIgbmFtZXMgPSBjbGFzc0FycmF5KG5hbWUgKyBcIlwiKTtcblxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICB2YXIgbGlzdCA9IGNsYXNzTGlzdCh0aGlzLm5vZGUoKSksIGkgPSAtMSwgbiA9IG5hbWVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFsaXN0LmNvbnRhaW5zKG5hbWVzW2ldKSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuZWFjaCgodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gY2xhc3NlZEZ1bmN0aW9uIDogdmFsdWVcbiAgICAgID8gY2xhc3NlZFRydWVcbiAgICAgIDogY2xhc3NlZEZhbHNlKShuYW1lcywgdmFsdWUpKTtcbn07XG5cbmZ1bmN0aW9uIHRleHRSZW1vdmUoKSB7XG4gIHRoaXMudGV4dENvbnRlbnQgPSBcIlwiO1xufVxuXG5mdW5jdGlvbiB0ZXh0Q29uc3RhbnQodmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMudGV4dENvbnRlbnQgPSB2YWx1ZTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gdGV4dEZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy50ZXh0Q29udGVudCA9IHYgPT0gbnVsbCA/IFwiXCIgOiB2O1xuICB9O1xufVxuXG52YXIgc2VsZWN0aW9uX3RleHQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgPyB0aGlzLmVhY2godmFsdWUgPT0gbnVsbFxuICAgICAgICAgID8gdGV4dFJlbW92ZSA6ICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgID8gdGV4dEZ1bmN0aW9uXG4gICAgICAgICAgOiB0ZXh0Q29uc3RhbnQpKHZhbHVlKSlcbiAgICAgIDogdGhpcy5ub2RlKCkudGV4dENvbnRlbnQ7XG59O1xuXG5mdW5jdGlvbiBodG1sUmVtb3ZlKCkge1xuICB0aGlzLmlubmVySFRNTCA9IFwiXCI7XG59XG5cbmZ1bmN0aW9uIGh0bWxDb25zdGFudCh2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaHRtbEZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5pbm5lckhUTUwgPSB2ID09IG51bGwgPyBcIlwiIDogdjtcbiAgfTtcbn1cblxudmFyIHNlbGVjdGlvbl9odG1sID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGhcbiAgICAgID8gdGhpcy5lYWNoKHZhbHVlID09IG51bGxcbiAgICAgICAgICA/IGh0bWxSZW1vdmUgOiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IGh0bWxGdW5jdGlvblxuICAgICAgICAgIDogaHRtbENvbnN0YW50KSh2YWx1ZSkpXG4gICAgICA6IHRoaXMubm9kZSgpLmlubmVySFRNTDtcbn07XG5cbmZ1bmN0aW9uIHJhaXNlJDEoKSB7XG4gIGlmICh0aGlzLm5leHRTaWJsaW5nKSB0aGlzLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcyk7XG59XG5cbnZhciBzZWxlY3Rpb25fcmFpc2UgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaChyYWlzZSQxKTtcbn07XG5cbmZ1bmN0aW9uIGxvd2VyKCkge1xuICBpZiAodGhpcy5wcmV2aW91c1NpYmxpbmcpIHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUodGhpcywgdGhpcy5wYXJlbnROb2RlLmZpcnN0Q2hpbGQpO1xufVxuXG52YXIgc2VsZWN0aW9uX2xvd2VyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmVhY2gobG93ZXIpO1xufTtcblxudmFyIHNlbGVjdGlvbl9hcHBlbmQgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHZhciBjcmVhdGUgPSB0eXBlb2YgbmFtZSA9PT0gXCJmdW5jdGlvblwiID8gbmFtZSA6IGNyZWF0b3IobmFtZSk7XG4gIHJldHVybiB0aGlzLnNlbGVjdChmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5hcHBlbmRDaGlsZChjcmVhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gIH0pO1xufTtcblxuZnVuY3Rpb24gY29uc3RhbnROdWxsKCkge1xuICByZXR1cm4gbnVsbDtcbn1cblxudmFyIHNlbGVjdGlvbl9pbnNlcnQgPSBmdW5jdGlvbihuYW1lLCBiZWZvcmUpIHtcbiAgdmFyIGNyZWF0ZSA9IHR5cGVvZiBuYW1lID09PSBcImZ1bmN0aW9uXCIgPyBuYW1lIDogY3JlYXRvcihuYW1lKSxcbiAgICAgIHNlbGVjdCA9IGJlZm9yZSA9PSBudWxsID8gY29uc3RhbnROdWxsIDogdHlwZW9mIGJlZm9yZSA9PT0gXCJmdW5jdGlvblwiID8gYmVmb3JlIDogc2VsZWN0b3IoYmVmb3JlKTtcbiAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmluc2VydEJlZm9yZShjcmVhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSwgc2VsZWN0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgbnVsbCk7XG4gIH0pO1xufTtcblxuZnVuY3Rpb24gcmVtb3ZlKCkge1xuICB2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xuICBpZiAocGFyZW50KSBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcyk7XG59XG5cbnZhciBzZWxlY3Rpb25fcmVtb3ZlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmVhY2gocmVtb3ZlKTtcbn07XG5cbnZhciBzZWxlY3Rpb25fZGF0dW0gPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgPyB0aGlzLnByb3BlcnR5KFwiX19kYXRhX19cIiwgdmFsdWUpXG4gICAgICA6IHRoaXMubm9kZSgpLl9fZGF0YV9fO1xufTtcblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudChub2RlLCB0eXBlLCBwYXJhbXMpIHtcbiAgdmFyIHdpbmRvdyQkMSA9IHdpbmRvdyhub2RlKSxcbiAgICAgIGV2ZW50ID0gd2luZG93JCQxLkN1c3RvbUV2ZW50O1xuXG4gIGlmIChldmVudCkge1xuICAgIGV2ZW50ID0gbmV3IGV2ZW50KHR5cGUsIHBhcmFtcyk7XG4gIH0gZWxzZSB7XG4gICAgZXZlbnQgPSB3aW5kb3ckJDEuZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJFdmVudFwiKTtcbiAgICBpZiAocGFyYW1zKSBldmVudC5pbml0RXZlbnQodHlwZSwgcGFyYW1zLmJ1YmJsZXMsIHBhcmFtcy5jYW5jZWxhYmxlKSwgZXZlbnQuZGV0YWlsID0gcGFyYW1zLmRldGFpbDtcbiAgICBlbHNlIGV2ZW50LmluaXRFdmVudCh0eXBlLCBmYWxzZSwgZmFsc2UpO1xuICB9XG5cbiAgbm9kZS5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hDb25zdGFudCh0eXBlLCBwYXJhbXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkaXNwYXRjaEV2ZW50KHRoaXMsIHR5cGUsIHBhcmFtcyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGRpc3BhdGNoRnVuY3Rpb24odHlwZSwgcGFyYW1zKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGlzcGF0Y2hFdmVudCh0aGlzLCB0eXBlLCBwYXJhbXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gIH07XG59XG5cbnZhciBzZWxlY3Rpb25fZGlzcGF0Y2ggPSBmdW5jdGlvbih0eXBlLCBwYXJhbXMpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaCgodHlwZW9mIHBhcmFtcyA9PT0gXCJmdW5jdGlvblwiXG4gICAgICA/IGRpc3BhdGNoRnVuY3Rpb25cbiAgICAgIDogZGlzcGF0Y2hDb25zdGFudCkodHlwZSwgcGFyYW1zKSk7XG59O1xuXG52YXIgcm9vdCA9IFtudWxsXTtcblxuZnVuY3Rpb24gU2VsZWN0aW9uKGdyb3VwcywgcGFyZW50cykge1xuICB0aGlzLl9ncm91cHMgPSBncm91cHM7XG4gIHRoaXMuX3BhcmVudHMgPSBwYXJlbnRzO1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKFtbZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50XV0sIHJvb3QpO1xufVxuXG5TZWxlY3Rpb24ucHJvdG90eXBlID0gc2VsZWN0aW9uLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFNlbGVjdGlvbixcbiAgc2VsZWN0OiBzZWxlY3Rpb25fc2VsZWN0LFxuICBzZWxlY3RBbGw6IHNlbGVjdGlvbl9zZWxlY3RBbGwsXG4gIGZpbHRlcjogc2VsZWN0aW9uX2ZpbHRlcixcbiAgZGF0YTogc2VsZWN0aW9uX2RhdGEsXG4gIGVudGVyOiBzZWxlY3Rpb25fZW50ZXIsXG4gIGV4aXQ6IHNlbGVjdGlvbl9leGl0LFxuICBtZXJnZTogc2VsZWN0aW9uX21lcmdlLFxuICBvcmRlcjogc2VsZWN0aW9uX29yZGVyLFxuICBzb3J0OiBzZWxlY3Rpb25fc29ydCxcbiAgY2FsbDogc2VsZWN0aW9uX2NhbGwsXG4gIG5vZGVzOiBzZWxlY3Rpb25fbm9kZXMsXG4gIG5vZGU6IHNlbGVjdGlvbl9ub2RlLFxuICBzaXplOiBzZWxlY3Rpb25fc2l6ZSxcbiAgZW1wdHk6IHNlbGVjdGlvbl9lbXB0eSxcbiAgZWFjaDogc2VsZWN0aW9uX2VhY2gsXG4gIGF0dHI6IHNlbGVjdGlvbl9hdHRyLFxuICBzdHlsZTogc2VsZWN0aW9uX3N0eWxlLFxuICBwcm9wZXJ0eTogc2VsZWN0aW9uX3Byb3BlcnR5LFxuICBjbGFzc2VkOiBzZWxlY3Rpb25fY2xhc3NlZCxcbiAgdGV4dDogc2VsZWN0aW9uX3RleHQsXG4gIGh0bWw6IHNlbGVjdGlvbl9odG1sLFxuICByYWlzZTogc2VsZWN0aW9uX3JhaXNlLFxuICBsb3dlcjogc2VsZWN0aW9uX2xvd2VyLFxuICBhcHBlbmQ6IHNlbGVjdGlvbl9hcHBlbmQsXG4gIGluc2VydDogc2VsZWN0aW9uX2luc2VydCxcbiAgcmVtb3ZlOiBzZWxlY3Rpb25fcmVtb3ZlLFxuICBkYXR1bTogc2VsZWN0aW9uX2RhdHVtLFxuICBvbjogc2VsZWN0aW9uX29uLFxuICBkaXNwYXRjaDogc2VsZWN0aW9uX2Rpc3BhdGNoXG59O1xuXG52YXIgc2VsZWN0ID0gZnVuY3Rpb24oc2VsZWN0b3IpIHtcbiAgcmV0dXJuIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIlxuICAgICAgPyBuZXcgU2VsZWN0aW9uKFtbZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcildXSwgW2RvY3VtZW50LmRvY3VtZW50RWxlbWVudF0pXG4gICAgICA6IG5ldyBTZWxlY3Rpb24oW1tzZWxlY3Rvcl1dLCByb290KTtcbn07XG5cbnZhciBzZWxlY3RBbGwgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xuICByZXR1cm4gdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiXG4gICAgICA/IG5ldyBTZWxlY3Rpb24oW2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpXSwgW2RvY3VtZW50LmRvY3VtZW50RWxlbWVudF0pXG4gICAgICA6IG5ldyBTZWxlY3Rpb24oW3NlbGVjdG9yID09IG51bGwgPyBbXSA6IHNlbGVjdG9yXSwgcm9vdCk7XG59O1xuXG52YXIgdG91Y2ggPSBmdW5jdGlvbihub2RlLCB0b3VjaGVzLCBpZGVudGlmaWVyKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykgaWRlbnRpZmllciA9IHRvdWNoZXMsIHRvdWNoZXMgPSBzb3VyY2VFdmVudCgpLmNoYW5nZWRUb3VjaGVzO1xuXG4gIGZvciAodmFyIGkgPSAwLCBuID0gdG91Y2hlcyA/IHRvdWNoZXMubGVuZ3RoIDogMCwgdG91Y2g7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoKHRvdWNoID0gdG91Y2hlc1tpXSkuaWRlbnRpZmllciA9PT0gaWRlbnRpZmllcikge1xuICAgICAgcmV0dXJuIHBvaW50JDUobm9kZSwgdG91Y2gpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxudmFyIHRvdWNoZXMgPSBmdW5jdGlvbihub2RlLCB0b3VjaGVzKSB7XG4gIGlmICh0b3VjaGVzID09IG51bGwpIHRvdWNoZXMgPSBzb3VyY2VFdmVudCgpLnRvdWNoZXM7XG5cbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0b3VjaGVzID8gdG91Y2hlcy5sZW5ndGggOiAwLCBwb2ludHMgPSBuZXcgQXJyYXkobik7IGkgPCBuOyArK2kpIHtcbiAgICBwb2ludHNbaV0gPSBwb2ludCQ1KG5vZGUsIHRvdWNoZXNbaV0pO1xuICB9XG5cbiAgcmV0dXJuIHBvaW50cztcbn07XG5cbnZhciBlbXB0eU9uID0gZGlzcGF0Y2goXCJzdGFydFwiLCBcImVuZFwiLCBcImludGVycnVwdFwiKTtcbnZhciBlbXB0eVR3ZWVuID0gW107XG5cbnZhciBDUkVBVEVEID0gMDtcbnZhciBTQ0hFRFVMRUQgPSAxO1xudmFyIFNUQVJUSU5HID0gMjtcbnZhciBTVEFSVEVEID0gMztcbnZhciBSVU5OSU5HID0gNDtcbnZhciBFTkRJTkcgPSA1O1xudmFyIEVOREVEID0gNjtcblxudmFyIHNjaGVkdWxlID0gZnVuY3Rpb24obm9kZSwgbmFtZSwgaWQsIGluZGV4LCBncm91cCwgdGltaW5nKSB7XG4gIHZhciBzY2hlZHVsZXMgPSBub2RlLl9fdHJhbnNpdGlvbjtcbiAgaWYgKCFzY2hlZHVsZXMpIG5vZGUuX190cmFuc2l0aW9uID0ge307XG4gIGVsc2UgaWYgKGlkIGluIHNjaGVkdWxlcykgcmV0dXJuO1xuICBjcmVhdGUobm9kZSwgaWQsIHtcbiAgICBuYW1lOiBuYW1lLFxuICAgIGluZGV4OiBpbmRleCwgLy8gRm9yIGNvbnRleHQgZHVyaW5nIGNhbGxiYWNrLlxuICAgIGdyb3VwOiBncm91cCwgLy8gRm9yIGNvbnRleHQgZHVyaW5nIGNhbGxiYWNrLlxuICAgIG9uOiBlbXB0eU9uLFxuICAgIHR3ZWVuOiBlbXB0eVR3ZWVuLFxuICAgIHRpbWU6IHRpbWluZy50aW1lLFxuICAgIGRlbGF5OiB0aW1pbmcuZGVsYXksXG4gICAgZHVyYXRpb246IHRpbWluZy5kdXJhdGlvbixcbiAgICBlYXNlOiB0aW1pbmcuZWFzZSxcbiAgICB0aW1lcjogbnVsbCxcbiAgICBzdGF0ZTogQ1JFQVRFRFxuICB9KTtcbn07XG5cbmZ1bmN0aW9uIGluaXQobm9kZSwgaWQpIHtcbiAgdmFyIHNjaGVkdWxlID0gbm9kZS5fX3RyYW5zaXRpb247XG4gIGlmICghc2NoZWR1bGUgfHwgIShzY2hlZHVsZSA9IHNjaGVkdWxlW2lkXSkgfHwgc2NoZWR1bGUuc3RhdGUgPiBDUkVBVEVEKSB0aHJvdyBuZXcgRXJyb3IoXCJ0b28gbGF0ZVwiKTtcbiAgcmV0dXJuIHNjaGVkdWxlO1xufVxuXG5mdW5jdGlvbiBzZXQkMyhub2RlLCBpZCkge1xuICB2YXIgc2NoZWR1bGUgPSBub2RlLl9fdHJhbnNpdGlvbjtcbiAgaWYgKCFzY2hlZHVsZSB8fCAhKHNjaGVkdWxlID0gc2NoZWR1bGVbaWRdKSB8fCBzY2hlZHVsZS5zdGF0ZSA+IFNUQVJUSU5HKSB0aHJvdyBuZXcgRXJyb3IoXCJ0b28gbGF0ZVwiKTtcbiAgcmV0dXJuIHNjaGVkdWxlO1xufVxuXG5mdW5jdGlvbiBnZXQkMShub2RlLCBpZCkge1xuICB2YXIgc2NoZWR1bGUgPSBub2RlLl9fdHJhbnNpdGlvbjtcbiAgaWYgKCFzY2hlZHVsZSB8fCAhKHNjaGVkdWxlID0gc2NoZWR1bGVbaWRdKSkgdGhyb3cgbmV3IEVycm9yKFwidG9vIGxhdGVcIik7XG4gIHJldHVybiBzY2hlZHVsZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlKG5vZGUsIGlkLCBzZWxmKSB7XG4gIHZhciBzY2hlZHVsZXMgPSBub2RlLl9fdHJhbnNpdGlvbixcbiAgICAgIHR3ZWVuO1xuXG4gIC8vIEluaXRpYWxpemUgdGhlIHNlbGYgdGltZXIgd2hlbiB0aGUgdHJhbnNpdGlvbiBpcyBjcmVhdGVkLlxuICAvLyBOb3RlIHRoZSBhY3R1YWwgZGVsYXkgaXMgbm90IGtub3duIHVudGlsIHRoZSBmaXJzdCBjYWxsYmFjayFcbiAgc2NoZWR1bGVzW2lkXSA9IHNlbGY7XG4gIHNlbGYudGltZXIgPSB0aW1lcihzY2hlZHVsZSwgMCwgc2VsZi50aW1lKTtcblxuICBmdW5jdGlvbiBzY2hlZHVsZShlbGFwc2VkKSB7XG4gICAgc2VsZi5zdGF0ZSA9IFNDSEVEVUxFRDtcbiAgICBzZWxmLnRpbWVyLnJlc3RhcnQoc3RhcnQsIHNlbGYuZGVsYXksIHNlbGYudGltZSk7XG5cbiAgICAvLyBJZiB0aGUgZWxhcHNlZCBkZWxheSBpcyBsZXNzIHRoYW4gb3VyIGZpcnN0IHNsZWVwLCBzdGFydCBpbW1lZGlhdGVseS5cbiAgICBpZiAoc2VsZi5kZWxheSA8PSBlbGFwc2VkKSBzdGFydChlbGFwc2VkIC0gc2VsZi5kZWxheSk7XG4gIH1cblxuICBmdW5jdGlvbiBzdGFydChlbGFwc2VkKSB7XG4gICAgdmFyIGksIGosIG4sIG87XG5cbiAgICAvLyBJZiB0aGUgc3RhdGUgaXMgbm90IFNDSEVEVUxFRCwgdGhlbiB3ZSBwcmV2aW91c2x5IGVycm9yZWQgb24gc3RhcnQuXG4gICAgaWYgKHNlbGYuc3RhdGUgIT09IFNDSEVEVUxFRCkgcmV0dXJuIHN0b3AoKTtcblxuICAgIGZvciAoaSBpbiBzY2hlZHVsZXMpIHtcbiAgICAgIG8gPSBzY2hlZHVsZXNbaV07XG4gICAgICBpZiAoby5uYW1lICE9PSBzZWxmLm5hbWUpIGNvbnRpbnVlO1xuXG4gICAgICAvLyBXaGlsZSB0aGlzIGVsZW1lbnQgYWxyZWFkeSBoYXMgYSBzdGFydGluZyB0cmFuc2l0aW9uIGR1cmluZyB0aGlzIGZyYW1lLFxuICAgICAgLy8gZGVmZXIgc3RhcnRpbmcgYW4gaW50ZXJydXB0aW5nIHRyYW5zaXRpb24gdW50aWwgdGhhdCB0cmFuc2l0aW9uIGhhcyBhXG4gICAgICAvLyBjaGFuY2UgdG8gdGljayAoYW5kIHBvc3NpYmx5IGVuZCk7IHNlZSBkMy9kMy10cmFuc2l0aW9uIzU0IVxuICAgICAgaWYgKG8uc3RhdGUgPT09IFNUQVJURUQpIHJldHVybiB0aW1lb3V0JDEoc3RhcnQpO1xuXG4gICAgICAvLyBJbnRlcnJ1cHQgdGhlIGFjdGl2ZSB0cmFuc2l0aW9uLCBpZiBhbnkuXG4gICAgICAvLyBEaXNwYXRjaCB0aGUgaW50ZXJydXB0IGV2ZW50LlxuICAgICAgaWYgKG8uc3RhdGUgPT09IFJVTk5JTkcpIHtcbiAgICAgICAgby5zdGF0ZSA9IEVOREVEO1xuICAgICAgICBvLnRpbWVyLnN0b3AoKTtcbiAgICAgICAgby5vbi5jYWxsKFwiaW50ZXJydXB0XCIsIG5vZGUsIG5vZGUuX19kYXRhX18sIG8uaW5kZXgsIG8uZ3JvdXApO1xuICAgICAgICBkZWxldGUgc2NoZWR1bGVzW2ldO1xuICAgICAgfVxuXG4gICAgICAvLyBDYW5jZWwgYW55IHByZS1lbXB0ZWQgdHJhbnNpdGlvbnMuIE5vIGludGVycnVwdCBldmVudCBpcyBkaXNwYXRjaGVkXG4gICAgICAvLyBiZWNhdXNlIHRoZSBjYW5jZWxsZWQgdHJhbnNpdGlvbnMgbmV2ZXIgc3RhcnRlZC4gTm90ZSB0aGF0IHRoaXMgYWxzb1xuICAgICAgLy8gcmVtb3ZlcyB0aGlzIHRyYW5zaXRpb24gZnJvbSB0aGUgcGVuZGluZyBsaXN0IVxuICAgICAgZWxzZSBpZiAoK2kgPCBpZCkge1xuICAgICAgICBvLnN0YXRlID0gRU5ERUQ7XG4gICAgICAgIG8udGltZXIuc3RvcCgpO1xuICAgICAgICBkZWxldGUgc2NoZWR1bGVzW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIERlZmVyIHRoZSBmaXJzdCB0aWNrIHRvIGVuZCBvZiB0aGUgY3VycmVudCBmcmFtZTsgc2VlIGQzL2QzIzE1NzYuXG4gICAgLy8gTm90ZSB0aGUgdHJhbnNpdGlvbiBtYXkgYmUgY2FuY2VsZWQgYWZ0ZXIgc3RhcnQgYW5kIGJlZm9yZSB0aGUgZmlyc3QgdGljayFcbiAgICAvLyBOb3RlIHRoaXMgbXVzdCBiZSBzY2hlZHVsZWQgYmVmb3JlIHRoZSBzdGFydCBldmVudDsgc2VlIGQzL2QzLXRyYW5zaXRpb24jMTYhXG4gICAgLy8gQXNzdW1pbmcgdGhpcyBpcyBzdWNjZXNzZnVsLCBzdWJzZXF1ZW50IGNhbGxiYWNrcyBnbyBzdHJhaWdodCB0byB0aWNrLlxuICAgIHRpbWVvdXQkMShmdW5jdGlvbigpIHtcbiAgICAgIGlmIChzZWxmLnN0YXRlID09PSBTVEFSVEVEKSB7XG4gICAgICAgIHNlbGYuc3RhdGUgPSBSVU5OSU5HO1xuICAgICAgICBzZWxmLnRpbWVyLnJlc3RhcnQodGljaywgc2VsZi5kZWxheSwgc2VsZi50aW1lKTtcbiAgICAgICAgdGljayhlbGFwc2VkKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIERpc3BhdGNoIHRoZSBzdGFydCBldmVudC5cbiAgICAvLyBOb3RlIHRoaXMgbXVzdCBiZSBkb25lIGJlZm9yZSB0aGUgdHdlZW4gYXJlIGluaXRpYWxpemVkLlxuICAgIHNlbGYuc3RhdGUgPSBTVEFSVElORztcbiAgICBzZWxmLm9uLmNhbGwoXCJzdGFydFwiLCBub2RlLCBub2RlLl9fZGF0YV9fLCBzZWxmLmluZGV4LCBzZWxmLmdyb3VwKTtcbiAgICBpZiAoc2VsZi5zdGF0ZSAhPT0gU1RBUlRJTkcpIHJldHVybjsgLy8gaW50ZXJydXB0ZWRcbiAgICBzZWxmLnN0YXRlID0gU1RBUlRFRDtcblxuICAgIC8vIEluaXRpYWxpemUgdGhlIHR3ZWVuLCBkZWxldGluZyBudWxsIHR3ZWVuLlxuICAgIHR3ZWVuID0gbmV3IEFycmF5KG4gPSBzZWxmLnR3ZWVuLmxlbmd0aCk7XG4gICAgZm9yIChpID0gMCwgaiA9IC0xOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobyA9IHNlbGYudHdlZW5baV0udmFsdWUuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBzZWxmLmluZGV4LCBzZWxmLmdyb3VwKSkge1xuICAgICAgICB0d2VlblsrK2pdID0gbztcbiAgICAgIH1cbiAgICB9XG4gICAgdHdlZW4ubGVuZ3RoID0gaiArIDE7XG4gIH1cblxuICBmdW5jdGlvbiB0aWNrKGVsYXBzZWQpIHtcbiAgICB2YXIgdCA9IGVsYXBzZWQgPCBzZWxmLmR1cmF0aW9uID8gc2VsZi5lYXNlLmNhbGwobnVsbCwgZWxhcHNlZCAvIHNlbGYuZHVyYXRpb24pIDogKHNlbGYudGltZXIucmVzdGFydChzdG9wKSwgc2VsZi5zdGF0ZSA9IEVORElORywgMSksXG4gICAgICAgIGkgPSAtMSxcbiAgICAgICAgbiA9IHR3ZWVuLmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICB0d2VlbltpXS5jYWxsKG51bGwsIHQpO1xuICAgIH1cblxuICAgIC8vIERpc3BhdGNoIHRoZSBlbmQgZXZlbnQuXG4gICAgaWYgKHNlbGYuc3RhdGUgPT09IEVORElORykge1xuICAgICAgc2VsZi5vbi5jYWxsKFwiZW5kXCIsIG5vZGUsIG5vZGUuX19kYXRhX18sIHNlbGYuaW5kZXgsIHNlbGYuZ3JvdXApO1xuICAgICAgc3RvcCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0b3AoKSB7XG4gICAgc2VsZi5zdGF0ZSA9IEVOREVEO1xuICAgIHNlbGYudGltZXIuc3RvcCgpO1xuICAgIGRlbGV0ZSBzY2hlZHVsZXNbaWRdO1xuICAgIGZvciAodmFyIGkgaW4gc2NoZWR1bGVzKSByZXR1cm47IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICBkZWxldGUgbm9kZS5fX3RyYW5zaXRpb247XG4gIH1cbn1cblxudmFyIGludGVycnVwdCA9IGZ1bmN0aW9uKG5vZGUsIG5hbWUpIHtcbiAgdmFyIHNjaGVkdWxlcyA9IG5vZGUuX190cmFuc2l0aW9uLFxuICAgICAgc2NoZWR1bGUsXG4gICAgICBhY3RpdmUsXG4gICAgICBlbXB0eSA9IHRydWUsXG4gICAgICBpO1xuXG4gIGlmICghc2NoZWR1bGVzKSByZXR1cm47XG5cbiAgbmFtZSA9IG5hbWUgPT0gbnVsbCA/IG51bGwgOiBuYW1lICsgXCJcIjtcblxuICBmb3IgKGkgaW4gc2NoZWR1bGVzKSB7XG4gICAgaWYgKChzY2hlZHVsZSA9IHNjaGVkdWxlc1tpXSkubmFtZSAhPT0gbmFtZSkgeyBlbXB0eSA9IGZhbHNlOyBjb250aW51ZTsgfVxuICAgIGFjdGl2ZSA9IHNjaGVkdWxlLnN0YXRlID4gU1RBUlRJTkcgJiYgc2NoZWR1bGUuc3RhdGUgPCBFTkRJTkc7XG4gICAgc2NoZWR1bGUuc3RhdGUgPSBFTkRFRDtcbiAgICBzY2hlZHVsZS50aW1lci5zdG9wKCk7XG4gICAgaWYgKGFjdGl2ZSkgc2NoZWR1bGUub24uY2FsbChcImludGVycnVwdFwiLCBub2RlLCBub2RlLl9fZGF0YV9fLCBzY2hlZHVsZS5pbmRleCwgc2NoZWR1bGUuZ3JvdXApO1xuICAgIGRlbGV0ZSBzY2hlZHVsZXNbaV07XG4gIH1cblxuICBpZiAoZW1wdHkpIGRlbGV0ZSBub2RlLl9fdHJhbnNpdGlvbjtcbn07XG5cbnZhciBzZWxlY3Rpb25faW50ZXJydXB0ID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuICAgIGludGVycnVwdCh0aGlzLCBuYW1lKTtcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiB0d2VlblJlbW92ZShpZCwgbmFtZSkge1xuICB2YXIgdHdlZW4wLCB0d2VlbjE7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc2NoZWR1bGUgPSBzZXQkMyh0aGlzLCBpZCksXG4gICAgICAgIHR3ZWVuID0gc2NoZWR1bGUudHdlZW47XG5cbiAgICAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIHR3ZWVuIHdpdGggdGhlIHByZXZpb3VzIG5vZGUsXG4gICAgLy8ganVzdCBhc3NpZ24gdGhlIHVwZGF0ZWQgc2hhcmVkIHR3ZWVuIGFuZCB3ZeKAmXJlIGRvbmUhXG4gICAgLy8gT3RoZXJ3aXNlLCBjb3B5LW9uLXdyaXRlLlxuICAgIGlmICh0d2VlbiAhPT0gdHdlZW4wKSB7XG4gICAgICB0d2VlbjEgPSB0d2VlbjAgPSB0d2VlbjtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBuID0gdHdlZW4xLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgICBpZiAodHdlZW4xW2ldLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgICB0d2VlbjEgPSB0d2VlbjEuc2xpY2UoKTtcbiAgICAgICAgICB0d2VlbjEuc3BsaWNlKGksIDEpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2NoZWR1bGUudHdlZW4gPSB0d2VlbjE7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHR3ZWVuRnVuY3Rpb24oaWQsIG5hbWUsIHZhbHVlKSB7XG4gIHZhciB0d2VlbjAsIHR3ZWVuMTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3I7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc2NoZWR1bGUgPSBzZXQkMyh0aGlzLCBpZCksXG4gICAgICAgIHR3ZWVuID0gc2NoZWR1bGUudHdlZW47XG5cbiAgICAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIHR3ZWVuIHdpdGggdGhlIHByZXZpb3VzIG5vZGUsXG4gICAgLy8ganVzdCBhc3NpZ24gdGhlIHVwZGF0ZWQgc2hhcmVkIHR3ZWVuIGFuZCB3ZeKAmXJlIGRvbmUhXG4gICAgLy8gT3RoZXJ3aXNlLCBjb3B5LW9uLXdyaXRlLlxuICAgIGlmICh0d2VlbiAhPT0gdHdlZW4wKSB7XG4gICAgICB0d2VlbjEgPSAodHdlZW4wID0gdHdlZW4pLnNsaWNlKCk7XG4gICAgICBmb3IgKHZhciB0ID0ge25hbWU6IG5hbWUsIHZhbHVlOiB2YWx1ZX0sIGkgPSAwLCBuID0gdHdlZW4xLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgICBpZiAodHdlZW4xW2ldLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgICB0d2VlbjFbaV0gPSB0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaSA9PT0gbikgdHdlZW4xLnB1c2godCk7XG4gICAgfVxuXG4gICAgc2NoZWR1bGUudHdlZW4gPSB0d2VlbjE7XG4gIH07XG59XG5cbnZhciB0cmFuc2l0aW9uX3R3ZWVuID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgdmFyIGlkID0gdGhpcy5faWQ7XG5cbiAgbmFtZSArPSBcIlwiO1xuXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgIHZhciB0d2VlbiA9IGdldCQxKHRoaXMubm9kZSgpLCBpZCkudHdlZW47XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSB0d2Vlbi5sZW5ndGgsIHQ7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmICgodCA9IHR3ZWVuW2ldKS5uYW1lID09PSBuYW1lKSB7XG4gICAgICAgIHJldHVybiB0LnZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmVhY2goKHZhbHVlID09IG51bGwgPyB0d2VlblJlbW92ZSA6IHR3ZWVuRnVuY3Rpb24pKGlkLCBuYW1lLCB2YWx1ZSkpO1xufTtcblxuZnVuY3Rpb24gdHdlZW5WYWx1ZSh0cmFuc2l0aW9uLCBuYW1lLCB2YWx1ZSkge1xuICB2YXIgaWQgPSB0cmFuc2l0aW9uLl9pZDtcblxuICB0cmFuc2l0aW9uLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNjaGVkdWxlID0gc2V0JDModGhpcywgaWQpO1xuICAgIChzY2hlZHVsZS52YWx1ZSB8fCAoc2NoZWR1bGUudmFsdWUgPSB7fSkpW25hbWVdID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfSk7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICByZXR1cm4gZ2V0JDEobm9kZSwgaWQpLnZhbHVlW25hbWVdO1xuICB9O1xufVxuXG52YXIgaW50ZXJwb2xhdGUkMSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIGM7XG4gIHJldHVybiAodHlwZW9mIGIgPT09IFwibnVtYmVyXCIgPyBpbnRlcnBvbGF0ZU51bWJlclxuICAgICAgOiBiIGluc3RhbmNlb2YgY29sb3IgPyBpbnRlcnBvbGF0ZVJnYlxuICAgICAgOiAoYyA9IGNvbG9yKGIpKSA/IChiID0gYywgaW50ZXJwb2xhdGVSZ2IpXG4gICAgICA6IGludGVycG9sYXRlU3RyaW5nKShhLCBiKTtcbn07XG5cbmZ1bmN0aW9uIGF0dHJSZW1vdmUkMShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0clJlbW92ZU5TJDEoZnVsbG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckNvbnN0YW50JDEobmFtZSwgaW50ZXJwb2xhdGUkJDEsIHZhbHVlMSkge1xuICB2YXIgdmFsdWUwMCxcbiAgICAgIGludGVycG9sYXRlMDtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2YWx1ZTAgPSB0aGlzLmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgICByZXR1cm4gdmFsdWUwID09PSB2YWx1ZTEgPyBudWxsXG4gICAgICAgIDogdmFsdWUwID09PSB2YWx1ZTAwID8gaW50ZXJwb2xhdGUwXG4gICAgICAgIDogaW50ZXJwb2xhdGUwID0gaW50ZXJwb2xhdGUkJDEodmFsdWUwMCA9IHZhbHVlMCwgdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckNvbnN0YW50TlMkMShmdWxsbmFtZSwgaW50ZXJwb2xhdGUkJDEsIHZhbHVlMSkge1xuICB2YXIgdmFsdWUwMCxcbiAgICAgIGludGVycG9sYXRlMDtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2YWx1ZTAgPSB0aGlzLmdldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7XG4gICAgcmV0dXJuIHZhbHVlMCA9PT0gdmFsdWUxID8gbnVsbFxuICAgICAgICA6IHZhbHVlMCA9PT0gdmFsdWUwMCA/IGludGVycG9sYXRlMFxuICAgICAgICA6IGludGVycG9sYXRlMCA9IGludGVycG9sYXRlJCQxKHZhbHVlMDAgPSB2YWx1ZTAsIHZhbHVlMSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJGdW5jdGlvbiQxKG5hbWUsIGludGVycG9sYXRlJCQxLCB2YWx1ZSkge1xuICB2YXIgdmFsdWUwMCxcbiAgICAgIHZhbHVlMTAsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWUwLCB2YWx1ZTEgPSB2YWx1ZSh0aGlzKTtcbiAgICBpZiAodmFsdWUxID09IG51bGwpIHJldHVybiB2b2lkIHRoaXMucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIHZhbHVlMCA9IHRoaXMuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgIHJldHVybiB2YWx1ZTAgPT09IHZhbHVlMSA/IG51bGxcbiAgICAgICAgOiB2YWx1ZTAgPT09IHZhbHVlMDAgJiYgdmFsdWUxID09PSB2YWx1ZTEwID8gaW50ZXJwb2xhdGUwXG4gICAgICAgIDogaW50ZXJwb2xhdGUwID0gaW50ZXJwb2xhdGUkJDEodmFsdWUwMCA9IHZhbHVlMCwgdmFsdWUxMCA9IHZhbHVlMSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJGdW5jdGlvbk5TJDEoZnVsbG5hbWUsIGludGVycG9sYXRlJCQxLCB2YWx1ZSkge1xuICB2YXIgdmFsdWUwMCxcbiAgICAgIHZhbHVlMTAsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWUwLCB2YWx1ZTEgPSB2YWx1ZSh0aGlzKTtcbiAgICBpZiAodmFsdWUxID09IG51bGwpIHJldHVybiB2b2lkIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgICB2YWx1ZTAgPSB0aGlzLmdldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7XG4gICAgcmV0dXJuIHZhbHVlMCA9PT0gdmFsdWUxID8gbnVsbFxuICAgICAgICA6IHZhbHVlMCA9PT0gdmFsdWUwMCAmJiB2YWx1ZTEgPT09IHZhbHVlMTAgPyBpbnRlcnBvbGF0ZTBcbiAgICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZSQkMSh2YWx1ZTAwID0gdmFsdWUwLCB2YWx1ZTEwID0gdmFsdWUxKTtcbiAgfTtcbn1cblxudmFyIHRyYW5zaXRpb25fYXR0ciA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHZhciBmdWxsbmFtZSA9IG5hbWVzcGFjZShuYW1lKSwgaSA9IGZ1bGxuYW1lID09PSBcInRyYW5zZm9ybVwiID8gaW50ZXJwb2xhdGVUcmFuc2Zvcm1TdmcgOiBpbnRlcnBvbGF0ZSQxO1xuICByZXR1cm4gdGhpcy5hdHRyVHdlZW4obmFtZSwgdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gKGZ1bGxuYW1lLmxvY2FsID8gYXR0ckZ1bmN0aW9uTlMkMSA6IGF0dHJGdW5jdGlvbiQxKShmdWxsbmFtZSwgaSwgdHdlZW5WYWx1ZSh0aGlzLCBcImF0dHIuXCIgKyBuYW1lLCB2YWx1ZSkpXG4gICAgICA6IHZhbHVlID09IG51bGwgPyAoZnVsbG5hbWUubG9jYWwgPyBhdHRyUmVtb3ZlTlMkMSA6IGF0dHJSZW1vdmUkMSkoZnVsbG5hbWUpXG4gICAgICA6IChmdWxsbmFtZS5sb2NhbCA/IGF0dHJDb25zdGFudE5TJDEgOiBhdHRyQ29uc3RhbnQkMSkoZnVsbG5hbWUsIGksIHZhbHVlKSk7XG59O1xuXG5mdW5jdGlvbiBhdHRyVHdlZW5OUyhmdWxsbmFtZSwgdmFsdWUpIHtcbiAgZnVuY3Rpb24gdHdlZW4oKSB7XG4gICAgdmFyIG5vZGUgPSB0aGlzLCBpID0gdmFsdWUuYXBwbHkobm9kZSwgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gaSAmJiBmdW5jdGlvbih0KSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCwgaSh0KSk7XG4gICAgfTtcbiAgfVxuICB0d2Vlbi5fdmFsdWUgPSB2YWx1ZTtcbiAgcmV0dXJuIHR3ZWVuO1xufVxuXG5mdW5jdGlvbiBhdHRyVHdlZW4obmFtZSwgdmFsdWUpIHtcbiAgZnVuY3Rpb24gdHdlZW4oKSB7XG4gICAgdmFyIG5vZGUgPSB0aGlzLCBpID0gdmFsdWUuYXBwbHkobm9kZSwgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gaSAmJiBmdW5jdGlvbih0KSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZShuYW1lLCBpKHQpKTtcbiAgICB9O1xuICB9XG4gIHR3ZWVuLl92YWx1ZSA9IHZhbHVlO1xuICByZXR1cm4gdHdlZW47XG59XG5cbnZhciB0cmFuc2l0aW9uX2F0dHJUd2VlbiA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHZhciBrZXkgPSBcImF0dHIuXCIgKyBuYW1lO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHJldHVybiAoa2V5ID0gdGhpcy50d2VlbihrZXkpKSAmJiBrZXkuX3ZhbHVlO1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIHRoaXMudHdlZW4oa2V5LCBudWxsKTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3I7XG4gIHZhciBmdWxsbmFtZSA9IG5hbWVzcGFjZShuYW1lKTtcbiAgcmV0dXJuIHRoaXMudHdlZW4oa2V5LCAoZnVsbG5hbWUubG9jYWwgPyBhdHRyVHdlZW5OUyA6IGF0dHJUd2VlbikoZnVsbG5hbWUsIHZhbHVlKSk7XG59O1xuXG5mdW5jdGlvbiBkZWxheUZ1bmN0aW9uKGlkLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgaW5pdCh0aGlzLCBpZCkuZGVsYXkgPSArdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVsYXlDb25zdGFudChpZCwgdmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID0gK3ZhbHVlLCBmdW5jdGlvbigpIHtcbiAgICBpbml0KHRoaXMsIGlkKS5kZWxheSA9IHZhbHVlO1xuICB9O1xufVxuXG52YXIgdHJhbnNpdGlvbl9kZWxheSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHZhciBpZCA9IHRoaXMuX2lkO1xuXG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoXG4gICAgICA/IHRoaXMuZWFjaCgodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IGRlbGF5RnVuY3Rpb25cbiAgICAgICAgICA6IGRlbGF5Q29uc3RhbnQpKGlkLCB2YWx1ZSkpXG4gICAgICA6IGdldCQxKHRoaXMubm9kZSgpLCBpZCkuZGVsYXk7XG59O1xuXG5mdW5jdGlvbiBkdXJhdGlvbkZ1bmN0aW9uKGlkLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgc2V0JDModGhpcywgaWQpLmR1cmF0aW9uID0gK3ZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGR1cmF0aW9uQ29uc3RhbnQoaWQsIHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9ICt2YWx1ZSwgZnVuY3Rpb24oKSB7XG4gICAgc2V0JDModGhpcywgaWQpLmR1cmF0aW9uID0gdmFsdWU7XG4gIH07XG59XG5cbnZhciB0cmFuc2l0aW9uX2R1cmF0aW9uID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdmFyIGlkID0gdGhpcy5faWQ7XG5cbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGhcbiAgICAgID8gdGhpcy5lYWNoKCh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgID8gZHVyYXRpb25GdW5jdGlvblxuICAgICAgICAgIDogZHVyYXRpb25Db25zdGFudCkoaWQsIHZhbHVlKSlcbiAgICAgIDogZ2V0JDEodGhpcy5ub2RlKCksIGlkKS5kdXJhdGlvbjtcbn07XG5cbmZ1bmN0aW9uIGVhc2VDb25zdGFudChpZCwgdmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3I7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBzZXQkMyh0aGlzLCBpZCkuZWFzZSA9IHZhbHVlO1xuICB9O1xufVxuXG52YXIgdHJhbnNpdGlvbl9lYXNlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdmFyIGlkID0gdGhpcy5faWQ7XG5cbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGhcbiAgICAgID8gdGhpcy5lYWNoKGVhc2VDb25zdGFudChpZCwgdmFsdWUpKVxuICAgICAgOiBnZXQkMSh0aGlzLm5vZGUoKSwgaWQpLmVhc2U7XG59O1xuXG52YXIgdHJhbnNpdGlvbl9maWx0ZXIgPSBmdW5jdGlvbihtYXRjaCkge1xuICBpZiAodHlwZW9mIG1hdGNoICE9PSBcImZ1bmN0aW9uXCIpIG1hdGNoID0gbWF0Y2hlciQxKG1hdGNoKTtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzdWJncm91cHMgPSBuZXcgQXJyYXkobSksIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIHN1Ymdyb3VwID0gc3ViZ3JvdXBzW2pdID0gW10sIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKG5vZGUgPSBncm91cFtpXSkgJiYgbWF0Y2guY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpIHtcbiAgICAgICAgc3ViZ3JvdXAucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFRyYW5zaXRpb24oc3ViZ3JvdXBzLCB0aGlzLl9wYXJlbnRzLCB0aGlzLl9uYW1lLCB0aGlzLl9pZCk7XG59O1xuXG52YXIgdHJhbnNpdGlvbl9tZXJnZSA9IGZ1bmN0aW9uKHRyYW5zaXRpb24pIHtcbiAgaWYgKHRyYW5zaXRpb24uX2lkICE9PSB0aGlzLl9pZCkgdGhyb3cgbmV3IEVycm9yO1xuXG4gIGZvciAodmFyIGdyb3VwczAgPSB0aGlzLl9ncm91cHMsIGdyb3VwczEgPSB0cmFuc2l0aW9uLl9ncm91cHMsIG0wID0gZ3JvdXBzMC5sZW5ndGgsIG0xID0gZ3JvdXBzMS5sZW5ndGgsIG0gPSBNYXRoLm1pbihtMCwgbTEpLCBtZXJnZXMgPSBuZXcgQXJyYXkobTApLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwMCA9IGdyb3VwczBbal0sIGdyb3VwMSA9IGdyb3VwczFbal0sIG4gPSBncm91cDAubGVuZ3RoLCBtZXJnZSA9IG1lcmdlc1tqXSA9IG5ldyBBcnJheShuKSwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmIChub2RlID0gZ3JvdXAwW2ldIHx8IGdyb3VwMVtpXSkge1xuICAgICAgICBtZXJnZVtpXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IGogPCBtMDsgKytqKSB7XG4gICAgbWVyZ2VzW2pdID0gZ3JvdXBzMFtqXTtcbiAgfVxuXG4gIHJldHVybiBuZXcgVHJhbnNpdGlvbihtZXJnZXMsIHRoaXMuX3BhcmVudHMsIHRoaXMuX25hbWUsIHRoaXMuX2lkKTtcbn07XG5cbmZ1bmN0aW9uIHN0YXJ0JDEobmFtZSkge1xuICByZXR1cm4gKG5hbWUgKyBcIlwiKS50cmltKCkuc3BsaXQoL158XFxzKy8pLmV2ZXJ5KGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgaSA9IHQuaW5kZXhPZihcIi5cIik7XG4gICAgaWYgKGkgPj0gMCkgdCA9IHQuc2xpY2UoMCwgaSk7XG4gICAgcmV0dXJuICF0IHx8IHQgPT09IFwic3RhcnRcIjtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG9uRnVuY3Rpb24oaWQsIG5hbWUsIGxpc3RlbmVyKSB7XG4gIHZhciBvbjAsIG9uMSwgc2l0ID0gc3RhcnQkMShuYW1lKSA/IGluaXQgOiBzZXQkMztcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBzY2hlZHVsZSA9IHNpdCh0aGlzLCBpZCksXG4gICAgICAgIG9uID0gc2NoZWR1bGUub247XG5cbiAgICAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIGEgZGlzcGF0Y2ggd2l0aCB0aGUgcHJldmlvdXMgbm9kZSxcbiAgICAvLyBqdXN0IGFzc2lnbiB0aGUgdXBkYXRlZCBzaGFyZWQgZGlzcGF0Y2ggYW5kIHdl4oCZcmUgZG9uZSFcbiAgICAvLyBPdGhlcndpc2UsIGNvcHktb24td3JpdGUuXG4gICAgaWYgKG9uICE9PSBvbjApIChvbjEgPSAob24wID0gb24pLmNvcHkoKSkub24obmFtZSwgbGlzdGVuZXIpO1xuXG4gICAgc2NoZWR1bGUub24gPSBvbjE7XG4gIH07XG59XG5cbnZhciB0cmFuc2l0aW9uX29uID0gZnVuY3Rpb24obmFtZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGlkID0gdGhpcy5faWQ7XG5cbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPCAyXG4gICAgICA/IGdldCQxKHRoaXMubm9kZSgpLCBpZCkub24ub24obmFtZSlcbiAgICAgIDogdGhpcy5lYWNoKG9uRnVuY3Rpb24oaWQsIG5hbWUsIGxpc3RlbmVyKSk7XG59O1xuXG5mdW5jdGlvbiByZW1vdmVGdW5jdGlvbihpZCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50Tm9kZTtcbiAgICBmb3IgKHZhciBpIGluIHRoaXMuX190cmFuc2l0aW9uKSBpZiAoK2kgIT09IGlkKSByZXR1cm47XG4gICAgaWYgKHBhcmVudCkgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMpO1xuICB9O1xufVxuXG52YXIgdHJhbnNpdGlvbl9yZW1vdmUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMub24oXCJlbmQucmVtb3ZlXCIsIHJlbW92ZUZ1bmN0aW9uKHRoaXMuX2lkKSk7XG59O1xuXG52YXIgdHJhbnNpdGlvbl9zZWxlY3QgPSBmdW5jdGlvbihzZWxlY3QkJDEpIHtcbiAgdmFyIG5hbWUgPSB0aGlzLl9uYW1lLFxuICAgICAgaWQgPSB0aGlzLl9pZDtcblxuICBpZiAodHlwZW9mIHNlbGVjdCQkMSAhPT0gXCJmdW5jdGlvblwiKSBzZWxlY3QkJDEgPSBzZWxlY3RvcihzZWxlY3QkJDEpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHN1Ymdyb3VwcyA9IG5ldyBBcnJheShtKSwgaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgc3ViZ3JvdXAgPSBzdWJncm91cHNbal0gPSBuZXcgQXJyYXkobiksIG5vZGUsIHN1Ym5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKG5vZGUgPSBncm91cFtpXSkgJiYgKHN1Ym5vZGUgPSBzZWxlY3QkJDEuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpKSB7XG4gICAgICAgIGlmIChcIl9fZGF0YV9fXCIgaW4gbm9kZSkgc3Vibm9kZS5fX2RhdGFfXyA9IG5vZGUuX19kYXRhX187XG4gICAgICAgIHN1Ymdyb3VwW2ldID0gc3Vibm9kZTtcbiAgICAgICAgc2NoZWR1bGUoc3ViZ3JvdXBbaV0sIG5hbWUsIGlkLCBpLCBzdWJncm91cCwgZ2V0JDEobm9kZSwgaWQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFRyYW5zaXRpb24oc3ViZ3JvdXBzLCB0aGlzLl9wYXJlbnRzLCBuYW1lLCBpZCk7XG59O1xuXG52YXIgdHJhbnNpdGlvbl9zZWxlY3RBbGwgPSBmdW5jdGlvbihzZWxlY3QkJDEpIHtcbiAgdmFyIG5hbWUgPSB0aGlzLl9uYW1lLFxuICAgICAgaWQgPSB0aGlzLl9pZDtcblxuICBpZiAodHlwZW9mIHNlbGVjdCQkMSAhPT0gXCJmdW5jdGlvblwiKSBzZWxlY3QkJDEgPSBzZWxlY3RvckFsbChzZWxlY3QkJDEpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHN1Ymdyb3VwcyA9IFtdLCBwYXJlbnRzID0gW10sIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgIGZvciAodmFyIGNoaWxkcmVuID0gc2VsZWN0JCQxLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgZ3JvdXApLCBjaGlsZCwgaW5oZXJpdCA9IGdldCQxKG5vZGUsIGlkKSwgayA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spIHtcbiAgICAgICAgICBpZiAoY2hpbGQgPSBjaGlsZHJlbltrXSkge1xuICAgICAgICAgICAgc2NoZWR1bGUoY2hpbGQsIG5hbWUsIGlkLCBrLCBjaGlsZHJlbiwgaW5oZXJpdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN1Ymdyb3Vwcy5wdXNoKGNoaWxkcmVuKTtcbiAgICAgICAgcGFyZW50cy5wdXNoKG5vZGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXcgVHJhbnNpdGlvbihzdWJncm91cHMsIHBhcmVudHMsIG5hbWUsIGlkKTtcbn07XG5cbnZhciBTZWxlY3Rpb24kMSA9IHNlbGVjdGlvbi5wcm90b3R5cGUuY29uc3RydWN0b3I7XG5cbnZhciB0cmFuc2l0aW9uX3NlbGVjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFNlbGVjdGlvbiQxKHRoaXMuX2dyb3VwcywgdGhpcy5fcGFyZW50cyk7XG59O1xuXG5mdW5jdGlvbiBzdHlsZVJlbW92ZSQxKG5hbWUsIGludGVycG9sYXRlJCQxKSB7XG4gIHZhciB2YWx1ZTAwLFxuICAgICAgdmFsdWUxMCxcbiAgICAgIGludGVycG9sYXRlMDtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBzdHlsZSA9IHdpbmRvdyh0aGlzKS5nZXRDb21wdXRlZFN0eWxlKHRoaXMsIG51bGwpLFxuICAgICAgICB2YWx1ZTAgPSBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKG5hbWUpLFxuICAgICAgICB2YWx1ZTEgPSAodGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKSwgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSk7XG4gICAgcmV0dXJuIHZhbHVlMCA9PT0gdmFsdWUxID8gbnVsbFxuICAgICAgICA6IHZhbHVlMCA9PT0gdmFsdWUwMCAmJiB2YWx1ZTEgPT09IHZhbHVlMTAgPyBpbnRlcnBvbGF0ZTBcbiAgICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZSQkMSh2YWx1ZTAwID0gdmFsdWUwLCB2YWx1ZTEwID0gdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVSZW1vdmVFbmQobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVDb25zdGFudCQxKG5hbWUsIGludGVycG9sYXRlJCQxLCB2YWx1ZTEpIHtcbiAgdmFyIHZhbHVlMDAsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWUwID0gd2luZG93KHRoaXMpLmdldENvbXB1dGVkU3R5bGUodGhpcywgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKTtcbiAgICByZXR1cm4gdmFsdWUwID09PSB2YWx1ZTEgPyBudWxsXG4gICAgICAgIDogdmFsdWUwID09PSB2YWx1ZTAwID8gaW50ZXJwb2xhdGUwXG4gICAgICAgIDogaW50ZXJwb2xhdGUwID0gaW50ZXJwb2xhdGUkJDEodmFsdWUwMCA9IHZhbHVlMCwgdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVGdW5jdGlvbiQxKG5hbWUsIGludGVycG9sYXRlJCQxLCB2YWx1ZSkge1xuICB2YXIgdmFsdWUwMCxcbiAgICAgIHZhbHVlMTAsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc3R5bGUgPSB3aW5kb3codGhpcykuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLCBudWxsKSxcbiAgICAgICAgdmFsdWUwID0gc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSxcbiAgICAgICAgdmFsdWUxID0gdmFsdWUodGhpcyk7XG4gICAgaWYgKHZhbHVlMSA9PSBudWxsKSB2YWx1ZTEgPSAodGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKSwgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSk7XG4gICAgcmV0dXJuIHZhbHVlMCA9PT0gdmFsdWUxID8gbnVsbFxuICAgICAgICA6IHZhbHVlMCA9PT0gdmFsdWUwMCAmJiB2YWx1ZTEgPT09IHZhbHVlMTAgPyBpbnRlcnBvbGF0ZTBcbiAgICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZSQkMSh2YWx1ZTAwID0gdmFsdWUwLCB2YWx1ZTEwID0gdmFsdWUxKTtcbiAgfTtcbn1cblxudmFyIHRyYW5zaXRpb25fc3R5bGUgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpIHtcbiAgdmFyIGkgPSAobmFtZSArPSBcIlwiKSA9PT0gXCJ0cmFuc2Zvcm1cIiA/IGludGVycG9sYXRlVHJhbnNmb3JtQ3NzIDogaW50ZXJwb2xhdGUkMTtcbiAgcmV0dXJuIHZhbHVlID09IG51bGwgPyB0aGlzXG4gICAgICAgICAgLnN0eWxlVHdlZW4obmFtZSwgc3R5bGVSZW1vdmUkMShuYW1lLCBpKSlcbiAgICAgICAgICAub24oXCJlbmQuc3R5bGUuXCIgKyBuYW1lLCBzdHlsZVJlbW92ZUVuZChuYW1lKSlcbiAgICAgIDogdGhpcy5zdHlsZVR3ZWVuKG5hbWUsIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgPyBzdHlsZUZ1bmN0aW9uJDEobmFtZSwgaSwgdHdlZW5WYWx1ZSh0aGlzLCBcInN0eWxlLlwiICsgbmFtZSwgdmFsdWUpKVxuICAgICAgICAgIDogc3R5bGVDb25zdGFudCQxKG5hbWUsIGksIHZhbHVlKSwgcHJpb3JpdHkpO1xufTtcblxuZnVuY3Rpb24gc3R5bGVUd2VlbihuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpIHtcbiAgZnVuY3Rpb24gdHdlZW4oKSB7XG4gICAgdmFyIG5vZGUgPSB0aGlzLCBpID0gdmFsdWUuYXBwbHkobm9kZSwgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gaSAmJiBmdW5jdGlvbih0KSB7XG4gICAgICBub2RlLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIGkodCksIHByaW9yaXR5KTtcbiAgICB9O1xuICB9XG4gIHR3ZWVuLl92YWx1ZSA9IHZhbHVlO1xuICByZXR1cm4gdHdlZW47XG59XG5cbnZhciB0cmFuc2l0aW9uX3N0eWxlVHdlZW4gPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpIHtcbiAgdmFyIGtleSA9IFwic3R5bGUuXCIgKyAobmFtZSArPSBcIlwiKTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSByZXR1cm4gKGtleSA9IHRoaXMudHdlZW4oa2V5KSkgJiYga2V5Ll92YWx1ZTtcbiAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiB0aGlzLnR3ZWVuKGtleSwgbnVsbCk7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yO1xuICByZXR1cm4gdGhpcy50d2VlbihrZXksIHN0eWxlVHdlZW4obmFtZSwgdmFsdWUsIHByaW9yaXR5ID09IG51bGwgPyBcIlwiIDogcHJpb3JpdHkpKTtcbn07XG5cbmZ1bmN0aW9uIHRleHRDb25zdGFudCQxKHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnRleHRDb250ZW50ID0gdmFsdWU7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHRleHRGdW5jdGlvbiQxKHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWUxID0gdmFsdWUodGhpcyk7XG4gICAgdGhpcy50ZXh0Q29udGVudCA9IHZhbHVlMSA9PSBudWxsID8gXCJcIiA6IHZhbHVlMTtcbiAgfTtcbn1cblxudmFyIHRyYW5zaXRpb25fdGV4dCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB0aGlzLnR3ZWVuKFwidGV4dFwiLCB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgPyB0ZXh0RnVuY3Rpb24kMSh0d2VlblZhbHVlKHRoaXMsIFwidGV4dFwiLCB2YWx1ZSkpXG4gICAgICA6IHRleHRDb25zdGFudCQxKHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKyBcIlwiKSk7XG59O1xuXG52YXIgdHJhbnNpdGlvbl90cmFuc2l0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHZhciBuYW1lID0gdGhpcy5fbmFtZSxcbiAgICAgIGlkMCA9IHRoaXMuX2lkLFxuICAgICAgaWQxID0gbmV3SWQoKTtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICB2YXIgaW5oZXJpdCA9IGdldCQxKG5vZGUsIGlkMCk7XG4gICAgICAgIHNjaGVkdWxlKG5vZGUsIG5hbWUsIGlkMSwgaSwgZ3JvdXAsIHtcbiAgICAgICAgICB0aW1lOiBpbmhlcml0LnRpbWUgKyBpbmhlcml0LmRlbGF5ICsgaW5oZXJpdC5kdXJhdGlvbixcbiAgICAgICAgICBkZWxheTogMCxcbiAgICAgICAgICBkdXJhdGlvbjogaW5oZXJpdC5kdXJhdGlvbixcbiAgICAgICAgICBlYXNlOiBpbmhlcml0LmVhc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKGdyb3VwcywgdGhpcy5fcGFyZW50cywgbmFtZSwgaWQxKTtcbn07XG5cbnZhciBpZCA9IDA7XG5cbmZ1bmN0aW9uIFRyYW5zaXRpb24oZ3JvdXBzLCBwYXJlbnRzLCBuYW1lLCBpZCkge1xuICB0aGlzLl9ncm91cHMgPSBncm91cHM7XG4gIHRoaXMuX3BhcmVudHMgPSBwYXJlbnRzO1xuICB0aGlzLl9uYW1lID0gbmFtZTtcbiAgdGhpcy5faWQgPSBpZDtcbn1cblxuZnVuY3Rpb24gdHJhbnNpdGlvbihuYW1lKSB7XG4gIHJldHVybiBzZWxlY3Rpb24oKS50cmFuc2l0aW9uKG5hbWUpO1xufVxuXG5mdW5jdGlvbiBuZXdJZCgpIHtcbiAgcmV0dXJuICsraWQ7XG59XG5cbnZhciBzZWxlY3Rpb25fcHJvdG90eXBlID0gc2VsZWN0aW9uLnByb3RvdHlwZTtcblxuVHJhbnNpdGlvbi5wcm90b3R5cGUgPSB0cmFuc2l0aW9uLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFRyYW5zaXRpb24sXG4gIHNlbGVjdDogdHJhbnNpdGlvbl9zZWxlY3QsXG4gIHNlbGVjdEFsbDogdHJhbnNpdGlvbl9zZWxlY3RBbGwsXG4gIGZpbHRlcjogdHJhbnNpdGlvbl9maWx0ZXIsXG4gIG1lcmdlOiB0cmFuc2l0aW9uX21lcmdlLFxuICBzZWxlY3Rpb246IHRyYW5zaXRpb25fc2VsZWN0aW9uLFxuICB0cmFuc2l0aW9uOiB0cmFuc2l0aW9uX3RyYW5zaXRpb24sXG4gIGNhbGw6IHNlbGVjdGlvbl9wcm90b3R5cGUuY2FsbCxcbiAgbm9kZXM6IHNlbGVjdGlvbl9wcm90b3R5cGUubm9kZXMsXG4gIG5vZGU6IHNlbGVjdGlvbl9wcm90b3R5cGUubm9kZSxcbiAgc2l6ZTogc2VsZWN0aW9uX3Byb3RvdHlwZS5zaXplLFxuICBlbXB0eTogc2VsZWN0aW9uX3Byb3RvdHlwZS5lbXB0eSxcbiAgZWFjaDogc2VsZWN0aW9uX3Byb3RvdHlwZS5lYWNoLFxuICBvbjogdHJhbnNpdGlvbl9vbixcbiAgYXR0cjogdHJhbnNpdGlvbl9hdHRyLFxuICBhdHRyVHdlZW46IHRyYW5zaXRpb25fYXR0clR3ZWVuLFxuICBzdHlsZTogdHJhbnNpdGlvbl9zdHlsZSxcbiAgc3R5bGVUd2VlbjogdHJhbnNpdGlvbl9zdHlsZVR3ZWVuLFxuICB0ZXh0OiB0cmFuc2l0aW9uX3RleHQsXG4gIHJlbW92ZTogdHJhbnNpdGlvbl9yZW1vdmUsXG4gIHR3ZWVuOiB0cmFuc2l0aW9uX3R3ZWVuLFxuICBkZWxheTogdHJhbnNpdGlvbl9kZWxheSxcbiAgZHVyYXRpb246IHRyYW5zaXRpb25fZHVyYXRpb24sXG4gIGVhc2U6IHRyYW5zaXRpb25fZWFzZVxufTtcblxudmFyIGRlZmF1bHRUaW1pbmcgPSB7XG4gIHRpbWU6IG51bGwsIC8vIFNldCBvbiB1c2UuXG4gIGRlbGF5OiAwLFxuICBkdXJhdGlvbjogMjUwLFxuICBlYXNlOiBjdWJpY0luT3V0XG59O1xuXG5mdW5jdGlvbiBpbmhlcml0KG5vZGUsIGlkKSB7XG4gIHZhciB0aW1pbmc7XG4gIHdoaWxlICghKHRpbWluZyA9IG5vZGUuX190cmFuc2l0aW9uKSB8fCAhKHRpbWluZyA9IHRpbWluZ1tpZF0pKSB7XG4gICAgaWYgKCEobm9kZSA9IG5vZGUucGFyZW50Tm9kZSkpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0VGltaW5nLnRpbWUgPSBub3coKSwgZGVmYXVsdFRpbWluZztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRpbWluZztcbn1cblxudmFyIHNlbGVjdGlvbl90cmFuc2l0aW9uID0gZnVuY3Rpb24obmFtZSkge1xuICB2YXIgaWQsXG4gICAgICB0aW1pbmc7XG5cbiAgaWYgKG5hbWUgaW5zdGFuY2VvZiBUcmFuc2l0aW9uKSB7XG4gICAgaWQgPSBuYW1lLl9pZCwgbmFtZSA9IG5hbWUuX25hbWU7XG4gIH0gZWxzZSB7XG4gICAgaWQgPSBuZXdJZCgpLCAodGltaW5nID0gZGVmYXVsdFRpbWluZykudGltZSA9IG5vdygpLCBuYW1lID0gbmFtZSA9PSBudWxsID8gbnVsbCA6IG5hbWUgKyBcIlwiO1xuICB9XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgICAgc2NoZWR1bGUobm9kZSwgbmFtZSwgaWQsIGksIGdyb3VwLCB0aW1pbmcgfHwgaW5oZXJpdChub2RlLCBpZCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXcgVHJhbnNpdGlvbihncm91cHMsIHRoaXMuX3BhcmVudHMsIG5hbWUsIGlkKTtcbn07XG5cbnNlbGVjdGlvbi5wcm90b3R5cGUuaW50ZXJydXB0ID0gc2VsZWN0aW9uX2ludGVycnVwdDtcbnNlbGVjdGlvbi5wcm90b3R5cGUudHJhbnNpdGlvbiA9IHNlbGVjdGlvbl90cmFuc2l0aW9uO1xuXG52YXIgcm9vdCQxID0gW251bGxdO1xuXG52YXIgYWN0aXZlID0gZnVuY3Rpb24obm9kZSwgbmFtZSkge1xuICB2YXIgc2NoZWR1bGVzID0gbm9kZS5fX3RyYW5zaXRpb24sXG4gICAgICBzY2hlZHVsZSxcbiAgICAgIGk7XG5cbiAgaWYgKHNjaGVkdWxlcykge1xuICAgIG5hbWUgPSBuYW1lID09IG51bGwgPyBudWxsIDogbmFtZSArIFwiXCI7XG4gICAgZm9yIChpIGluIHNjaGVkdWxlcykge1xuICAgICAgaWYgKChzY2hlZHVsZSA9IHNjaGVkdWxlc1tpXSkuc3RhdGUgPiBTQ0hFRFVMRUQgJiYgc2NoZWR1bGUubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICByZXR1cm4gbmV3IFRyYW5zaXRpb24oW1tub2RlXV0sIHJvb3QkMSwgbmFtZSwgK2kpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxudmFyIHNsaWNlJDQgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbnZhciBpZGVudGl0eSQ1ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4geDtcbn07XG5cbnZhciB0b3AgPSAxO1xudmFyIHJpZ2h0ID0gMjtcbnZhciBib3R0b20gPSAzO1xudmFyIGxlZnQgPSA0O1xudmFyIGVwc2lsb24kMiA9IDFlLTY7XG5cbmZ1bmN0aW9uIHRyYW5zbGF0ZVgoc2NhbGUwLCBzY2FsZTEsIGQpIHtcbiAgdmFyIHggPSBzY2FsZTAoZCk7XG4gIHJldHVybiBcInRyYW5zbGF0ZShcIiArIChpc0Zpbml0ZSh4KSA/IHggOiBzY2FsZTEoZCkpICsgXCIsMClcIjtcbn1cblxuZnVuY3Rpb24gdHJhbnNsYXRlWShzY2FsZTAsIHNjYWxlMSwgZCkge1xuICB2YXIgeSA9IHNjYWxlMChkKTtcbiAgcmV0dXJuIFwidHJhbnNsYXRlKDAsXCIgKyAoaXNGaW5pdGUoeSkgPyB5IDogc2NhbGUxKGQpKSArIFwiKVwiO1xufVxuXG5mdW5jdGlvbiBjZW50ZXIoc2NhbGUpIHtcbiAgdmFyIG9mZnNldCA9IHNjYWxlLmJhbmR3aWR0aCgpIC8gMjtcbiAgaWYgKHNjYWxlLnJvdW5kKCkpIG9mZnNldCA9IE1hdGgucm91bmQob2Zmc2V0KTtcbiAgcmV0dXJuIGZ1bmN0aW9uKGQpIHtcbiAgICByZXR1cm4gc2NhbGUoZCkgKyBvZmZzZXQ7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGVudGVyaW5nKCkge1xuICByZXR1cm4gIXRoaXMuX19heGlzO1xufVxuXG5mdW5jdGlvbiBheGlzKG9yaWVudCwgc2NhbGUpIHtcbiAgdmFyIHRpY2tBcmd1bWVudHMgPSBbXSxcbiAgICAgIHRpY2tWYWx1ZXMgPSBudWxsLFxuICAgICAgdGlja0Zvcm1hdCA9IG51bGwsXG4gICAgICB0aWNrU2l6ZUlubmVyID0gNixcbiAgICAgIHRpY2tTaXplT3V0ZXIgPSA2LFxuICAgICAgdGlja1BhZGRpbmcgPSAzO1xuXG4gIGZ1bmN0aW9uIGF4aXMoY29udGV4dCkge1xuICAgIHZhciB2YWx1ZXMgPSB0aWNrVmFsdWVzID09IG51bGwgPyAoc2NhbGUudGlja3MgPyBzY2FsZS50aWNrcy5hcHBseShzY2FsZSwgdGlja0FyZ3VtZW50cykgOiBzY2FsZS5kb21haW4oKSkgOiB0aWNrVmFsdWVzLFxuICAgICAgICBmb3JtYXQgPSB0aWNrRm9ybWF0ID09IG51bGwgPyAoc2NhbGUudGlja0Zvcm1hdCA/IHNjYWxlLnRpY2tGb3JtYXQuYXBwbHkoc2NhbGUsIHRpY2tBcmd1bWVudHMpIDogaWRlbnRpdHkkNSkgOiB0aWNrRm9ybWF0LFxuICAgICAgICBzcGFjaW5nID0gTWF0aC5tYXgodGlja1NpemVJbm5lciwgMCkgKyB0aWNrUGFkZGluZyxcbiAgICAgICAgdHJhbnNmb3JtID0gb3JpZW50ID09PSB0b3AgfHwgb3JpZW50ID09PSBib3R0b20gPyB0cmFuc2xhdGVYIDogdHJhbnNsYXRlWSxcbiAgICAgICAgcmFuZ2UgPSBzY2FsZS5yYW5nZSgpLFxuICAgICAgICByYW5nZTAgPSByYW5nZVswXSArIDAuNSxcbiAgICAgICAgcmFuZ2UxID0gcmFuZ2VbcmFuZ2UubGVuZ3RoIC0gMV0gKyAwLjUsXG4gICAgICAgIHBvc2l0aW9uID0gKHNjYWxlLmJhbmR3aWR0aCA/IGNlbnRlciA6IGlkZW50aXR5JDUpKHNjYWxlLmNvcHkoKSksXG4gICAgICAgIHNlbGVjdGlvbiA9IGNvbnRleHQuc2VsZWN0aW9uID8gY29udGV4dC5zZWxlY3Rpb24oKSA6IGNvbnRleHQsXG4gICAgICAgIHBhdGggPSBzZWxlY3Rpb24uc2VsZWN0QWxsKFwiLmRvbWFpblwiKS5kYXRhKFtudWxsXSksXG4gICAgICAgIHRpY2sgPSBzZWxlY3Rpb24uc2VsZWN0QWxsKFwiLnRpY2tcIikuZGF0YSh2YWx1ZXMsIHNjYWxlKS5vcmRlcigpLFxuICAgICAgICB0aWNrRXhpdCA9IHRpY2suZXhpdCgpLFxuICAgICAgICB0aWNrRW50ZXIgPSB0aWNrLmVudGVyKCkuYXBwZW5kKFwiZ1wiKS5hdHRyKFwiY2xhc3NcIiwgXCJ0aWNrXCIpLFxuICAgICAgICBsaW5lID0gdGljay5zZWxlY3QoXCJsaW5lXCIpLFxuICAgICAgICB0ZXh0ID0gdGljay5zZWxlY3QoXCJ0ZXh0XCIpLFxuICAgICAgICBrID0gb3JpZW50ID09PSB0b3AgfHwgb3JpZW50ID09PSBsZWZ0ID8gLTEgOiAxLFxuICAgICAgICB4LCB5ID0gb3JpZW50ID09PSBsZWZ0IHx8IG9yaWVudCA9PT0gcmlnaHQgPyAoeCA9IFwieFwiLCBcInlcIikgOiAoeCA9IFwieVwiLCBcInhcIik7XG5cbiAgICBwYXRoID0gcGF0aC5tZXJnZShwYXRoLmVudGVyKCkuaW5zZXJ0KFwicGF0aFwiLCBcIi50aWNrXCIpXG4gICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJkb21haW5cIilcbiAgICAgICAgLmF0dHIoXCJzdHJva2VcIiwgXCIjMDAwXCIpKTtcblxuICAgIHRpY2sgPSB0aWNrLm1lcmdlKHRpY2tFbnRlcik7XG5cbiAgICBsaW5lID0gbGluZS5tZXJnZSh0aWNrRW50ZXIuYXBwZW5kKFwibGluZVwiKVxuICAgICAgICAuYXR0cihcInN0cm9rZVwiLCBcIiMwMDBcIilcbiAgICAgICAgLmF0dHIoeCArIFwiMlwiLCBrICogdGlja1NpemVJbm5lcilcbiAgICAgICAgLmF0dHIoeSArIFwiMVwiLCAwLjUpXG4gICAgICAgIC5hdHRyKHkgKyBcIjJcIiwgMC41KSk7XG5cbiAgICB0ZXh0ID0gdGV4dC5tZXJnZSh0aWNrRW50ZXIuYXBwZW5kKFwidGV4dFwiKVxuICAgICAgICAuYXR0cihcImZpbGxcIiwgXCIjMDAwXCIpXG4gICAgICAgIC5hdHRyKHgsIGsgKiBzcGFjaW5nKVxuICAgICAgICAuYXR0cih5LCAwLjUpXG4gICAgICAgIC5hdHRyKFwiZHlcIiwgb3JpZW50ID09PSB0b3AgPyBcIjBlbVwiIDogb3JpZW50ID09PSBib3R0b20gPyBcIjAuNzFlbVwiIDogXCIwLjMyZW1cIikpO1xuXG4gICAgaWYgKGNvbnRleHQgIT09IHNlbGVjdGlvbikge1xuICAgICAgcGF0aCA9IHBhdGgudHJhbnNpdGlvbihjb250ZXh0KTtcbiAgICAgIHRpY2sgPSB0aWNrLnRyYW5zaXRpb24oY29udGV4dCk7XG4gICAgICBsaW5lID0gbGluZS50cmFuc2l0aW9uKGNvbnRleHQpO1xuICAgICAgdGV4dCA9IHRleHQudHJhbnNpdGlvbihjb250ZXh0KTtcblxuICAgICAgdGlja0V4aXQgPSB0aWNrRXhpdC50cmFuc2l0aW9uKGNvbnRleHQpXG4gICAgICAgICAgLmF0dHIoXCJvcGFjaXR5XCIsIGVwc2lsb24kMilcbiAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiB0cmFuc2Zvcm0ocG9zaXRpb24sIHRoaXMucGFyZW50Tm9kZS5fX2F4aXMgfHwgcG9zaXRpb24sIGQpOyB9KTtcblxuICAgICAgdGlja0VudGVyXG4gICAgICAgICAgLmF0dHIoXCJvcGFjaXR5XCIsIGVwc2lsb24kMilcbiAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiB0cmFuc2Zvcm0odGhpcy5wYXJlbnROb2RlLl9fYXhpcyB8fCBwb3NpdGlvbiwgcG9zaXRpb24sIGQpOyB9KTtcbiAgICB9XG5cbiAgICB0aWNrRXhpdC5yZW1vdmUoKTtcblxuICAgIHBhdGhcbiAgICAgICAgLmF0dHIoXCJkXCIsIG9yaWVudCA9PT0gbGVmdCB8fCBvcmllbnQgPT0gcmlnaHRcbiAgICAgICAgICAgID8gXCJNXCIgKyBrICogdGlja1NpemVPdXRlciArIFwiLFwiICsgcmFuZ2UwICsgXCJIMC41VlwiICsgcmFuZ2UxICsgXCJIXCIgKyBrICogdGlja1NpemVPdXRlclxuICAgICAgICAgICAgOiBcIk1cIiArIHJhbmdlMCArIFwiLFwiICsgayAqIHRpY2tTaXplT3V0ZXIgKyBcIlYwLjVIXCIgKyByYW5nZTEgKyBcIlZcIiArIGsgKiB0aWNrU2l6ZU91dGVyKTtcblxuICAgIHRpY2tcbiAgICAgICAgLmF0dHIoXCJvcGFjaXR5XCIsIDEpXG4gICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHRyYW5zZm9ybShwb3NpdGlvbiwgcG9zaXRpb24sIGQpOyB9KTtcblxuICAgIGxpbmVcbiAgICAgICAgLmF0dHIoeCArIFwiMlwiLCBrICogdGlja1NpemVJbm5lcik7XG5cbiAgICB0ZXh0XG4gICAgICAgIC5hdHRyKHgsIGsgKiBzcGFjaW5nKVxuICAgICAgICAudGV4dChmb3JtYXQpO1xuXG4gICAgc2VsZWN0aW9uLmZpbHRlcihlbnRlcmluZylcbiAgICAgICAgLmF0dHIoXCJmaWxsXCIsIFwibm9uZVwiKVxuICAgICAgICAuYXR0cihcImZvbnQtc2l6ZVwiLCAxMClcbiAgICAgICAgLmF0dHIoXCJmb250LWZhbWlseVwiLCBcInNhbnMtc2VyaWZcIilcbiAgICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBvcmllbnQgPT09IHJpZ2h0ID8gXCJzdGFydFwiIDogb3JpZW50ID09PSBsZWZ0ID8gXCJlbmRcIiA6IFwibWlkZGxlXCIpO1xuXG4gICAgc2VsZWN0aW9uXG4gICAgICAgIC5lYWNoKGZ1bmN0aW9uKCkgeyB0aGlzLl9fYXhpcyA9IHBvc2l0aW9uOyB9KTtcbiAgfVxuXG4gIGF4aXMuc2NhbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc2NhbGUgPSBfLCBheGlzKSA6IHNjYWxlO1xuICB9O1xuXG4gIGF4aXMudGlja3MgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGlja0FyZ3VtZW50cyA9IHNsaWNlJDQuY2FsbChhcmd1bWVudHMpLCBheGlzO1xuICB9O1xuXG4gIGF4aXMudGlja0FyZ3VtZW50cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aWNrQXJndW1lbnRzID0gXyA9PSBudWxsID8gW10gOiBzbGljZSQ0LmNhbGwoXyksIGF4aXMpIDogdGlja0FyZ3VtZW50cy5zbGljZSgpO1xuICB9O1xuXG4gIGF4aXMudGlja1ZhbHVlcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aWNrVmFsdWVzID0gXyA9PSBudWxsID8gbnVsbCA6IHNsaWNlJDQuY2FsbChfKSwgYXhpcykgOiB0aWNrVmFsdWVzICYmIHRpY2tWYWx1ZXMuc2xpY2UoKTtcbiAgfTtcblxuICBheGlzLnRpY2tGb3JtYXQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGlja0Zvcm1hdCA9IF8sIGF4aXMpIDogdGlja0Zvcm1hdDtcbiAgfTtcblxuICBheGlzLnRpY2tTaXplID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRpY2tTaXplSW5uZXIgPSB0aWNrU2l6ZU91dGVyID0gK18sIGF4aXMpIDogdGlja1NpemVJbm5lcjtcbiAgfTtcblxuICBheGlzLnRpY2tTaXplSW5uZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGlja1NpemVJbm5lciA9ICtfLCBheGlzKSA6IHRpY2tTaXplSW5uZXI7XG4gIH07XG5cbiAgYXhpcy50aWNrU2l6ZU91dGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRpY2tTaXplT3V0ZXIgPSArXywgYXhpcykgOiB0aWNrU2l6ZU91dGVyO1xuICB9O1xuXG4gIGF4aXMudGlja1BhZGRpbmcgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGlja1BhZGRpbmcgPSArXywgYXhpcykgOiB0aWNrUGFkZGluZztcbiAgfTtcblxuICByZXR1cm4gYXhpcztcbn1cblxuZnVuY3Rpb24gYXhpc1RvcChzY2FsZSkge1xuICByZXR1cm4gYXhpcyh0b3AsIHNjYWxlKTtcbn1cblxuZnVuY3Rpb24gYXhpc1JpZ2h0KHNjYWxlKSB7XG4gIHJldHVybiBheGlzKHJpZ2h0LCBzY2FsZSk7XG59XG5cbmZ1bmN0aW9uIGF4aXNCb3R0b20oc2NhbGUpIHtcbiAgcmV0dXJuIGF4aXMoYm90dG9tLCBzY2FsZSk7XG59XG5cbmZ1bmN0aW9uIGF4aXNMZWZ0KHNjYWxlKSB7XG4gIHJldHVybiBheGlzKGxlZnQsIHNjYWxlKTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFNlcGFyYXRpb24oYSwgYikge1xuICByZXR1cm4gYS5wYXJlbnQgPT09IGIucGFyZW50ID8gMSA6IDI7XG59XG5cbmZ1bmN0aW9uIG1lYW5YKGNoaWxkcmVuKSB7XG4gIHJldHVybiBjaGlsZHJlbi5yZWR1Y2UobWVhblhSZWR1Y2UsIDApIC8gY2hpbGRyZW4ubGVuZ3RoO1xufVxuXG5mdW5jdGlvbiBtZWFuWFJlZHVjZSh4LCBjKSB7XG4gIHJldHVybiB4ICsgYy54O1xufVxuXG5mdW5jdGlvbiBtYXhZKGNoaWxkcmVuKSB7XG4gIHJldHVybiAxICsgY2hpbGRyZW4ucmVkdWNlKG1heFlSZWR1Y2UsIDApO1xufVxuXG5mdW5jdGlvbiBtYXhZUmVkdWNlKHksIGMpIHtcbiAgcmV0dXJuIE1hdGgubWF4KHksIGMueSk7XG59XG5cbmZ1bmN0aW9uIGxlYWZMZWZ0KG5vZGUpIHtcbiAgdmFyIGNoaWxkcmVuO1xuICB3aGlsZSAoY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuKSBub2RlID0gY2hpbGRyZW5bMF07XG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBsZWFmUmlnaHQobm9kZSkge1xuICB2YXIgY2hpbGRyZW47XG4gIHdoaWxlIChjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4pIG5vZGUgPSBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbnZhciBjbHVzdGVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzZXBhcmF0aW9uID0gZGVmYXVsdFNlcGFyYXRpb24sXG4gICAgICBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICBub2RlU2l6ZSA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGNsdXN0ZXIocm9vdCkge1xuICAgIHZhciBwcmV2aW91c05vZGUsXG4gICAgICAgIHggPSAwO1xuXG4gICAgLy8gRmlyc3Qgd2FsaywgY29tcHV0aW5nIHRoZSBpbml0aWFsIHggJiB5IHZhbHVlcy5cbiAgICByb290LmVhY2hBZnRlcihmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xuICAgICAgaWYgKGNoaWxkcmVuKSB7XG4gICAgICAgIG5vZGUueCA9IG1lYW5YKGNoaWxkcmVuKTtcbiAgICAgICAgbm9kZS55ID0gbWF4WShjaGlsZHJlbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlLnggPSBwcmV2aW91c05vZGUgPyB4ICs9IHNlcGFyYXRpb24obm9kZSwgcHJldmlvdXNOb2RlKSA6IDA7XG4gICAgICAgIG5vZGUueSA9IDA7XG4gICAgICAgIHByZXZpb3VzTm9kZSA9IG5vZGU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB2YXIgbGVmdCA9IGxlYWZMZWZ0KHJvb3QpLFxuICAgICAgICByaWdodCA9IGxlYWZSaWdodChyb290KSxcbiAgICAgICAgeDAgPSBsZWZ0LnggLSBzZXBhcmF0aW9uKGxlZnQsIHJpZ2h0KSAvIDIsXG4gICAgICAgIHgxID0gcmlnaHQueCArIHNlcGFyYXRpb24ocmlnaHQsIGxlZnQpIC8gMjtcblxuICAgIC8vIFNlY29uZCB3YWxrLCBub3JtYWxpemluZyB4ICYgeSB0byB0aGUgZGVzaXJlZCBzaXplLlxuICAgIHJldHVybiByb290LmVhY2hBZnRlcihub2RlU2l6ZSA/IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIG5vZGUueCA9IChub2RlLnggLSByb290LngpICogZHg7XG4gICAgICBub2RlLnkgPSAocm9vdC55IC0gbm9kZS55KSAqIGR5O1xuICAgIH0gOiBmdW5jdGlvbihub2RlKSB7XG4gICAgICBub2RlLnggPSAobm9kZS54IC0geDApIC8gKHgxIC0geDApICogZHg7XG4gICAgICBub2RlLnkgPSAoMSAtIChyb290LnkgPyBub2RlLnkgLyByb290LnkgOiAxKSkgKiBkeTtcbiAgICB9KTtcbiAgfVxuXG4gIGNsdXN0ZXIuc2VwYXJhdGlvbiA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzZXBhcmF0aW9uID0geCwgY2x1c3RlcikgOiBzZXBhcmF0aW9uO1xuICB9O1xuXG4gIGNsdXN0ZXIuc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IGZhbHNlLCBkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCBjbHVzdGVyKSA6IChub2RlU2l6ZSA/IG51bGwgOiBbZHgsIGR5XSk7XG4gIH07XG5cbiAgY2x1c3Rlci5ub2RlU2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IHRydWUsIGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIGNsdXN0ZXIpIDogKG5vZGVTaXplID8gW2R4LCBkeV0gOiBudWxsKTtcbiAgfTtcblxuICByZXR1cm4gY2x1c3Rlcjtcbn07XG5cbnZhciBub2RlX2VhY2ggPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgbm9kZSA9IHRoaXMsIGN1cnJlbnQsIG5leHQgPSBbbm9kZV0sIGNoaWxkcmVuLCBpLCBuO1xuICBkbyB7XG4gICAgY3VycmVudCA9IG5leHQucmV2ZXJzZSgpLCBuZXh0ID0gW107XG4gICAgd2hpbGUgKG5vZGUgPSBjdXJyZW50LnBvcCgpKSB7XG4gICAgICBjYWxsYmFjayhub2RlKSwgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xuICAgICAgaWYgKGNoaWxkcmVuKSBmb3IgKGkgPSAwLCBuID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIG5leHQucHVzaChjaGlsZHJlbltpXSk7XG4gICAgICB9XG4gICAgfVxuICB9IHdoaWxlIChuZXh0Lmxlbmd0aCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIG5vZGVfZWFjaEJlZm9yZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHZhciBub2RlID0gdGhpcywgbm9kZXMgPSBbbm9kZV0sIGNoaWxkcmVuLCBpO1xuICB3aGlsZSAobm9kZSA9IG5vZGVzLnBvcCgpKSB7XG4gICAgY2FsbGJhY2sobm9kZSksIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjtcbiAgICBpZiAoY2hpbGRyZW4pIGZvciAoaSA9IGNoaWxkcmVuLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBub2Rlcy5wdXNoKGNoaWxkcmVuW2ldKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG52YXIgbm9kZV9lYWNoQWZ0ZXIgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgbm9kZSA9IHRoaXMsIG5vZGVzID0gW25vZGVdLCBuZXh0ID0gW10sIGNoaWxkcmVuLCBpLCBuO1xuICB3aGlsZSAobm9kZSA9IG5vZGVzLnBvcCgpKSB7XG4gICAgbmV4dC5wdXNoKG5vZGUpLCBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW47XG4gICAgaWYgKGNoaWxkcmVuKSBmb3IgKGkgPSAwLCBuID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICBub2Rlcy5wdXNoKGNoaWxkcmVuW2ldKTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKG5vZGUgPSBuZXh0LnBvcCgpKSB7XG4gICAgY2FsbGJhY2sobm9kZSk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG52YXIgbm9kZV9zdW0gPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdGhpcy5lYWNoQWZ0ZXIoZnVuY3Rpb24obm9kZSkge1xuICAgIHZhciBzdW0gPSArdmFsdWUobm9kZS5kYXRhKSB8fCAwLFxuICAgICAgICBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4sXG4gICAgICAgIGkgPSBjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGg7XG4gICAgd2hpbGUgKC0taSA+PSAwKSBzdW0gKz0gY2hpbGRyZW5baV0udmFsdWU7XG4gICAgbm9kZS52YWx1ZSA9IHN1bTtcbiAgfSk7XG59O1xuXG52YXIgbm9kZV9zb3J0ID0gZnVuY3Rpb24oY29tcGFyZSkge1xuICByZXR1cm4gdGhpcy5lYWNoQmVmb3JlKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgbm9kZS5jaGlsZHJlbi5zb3J0KGNvbXBhcmUpO1xuICAgIH1cbiAgfSk7XG59O1xuXG52YXIgbm9kZV9wYXRoID0gZnVuY3Rpb24oZW5kKSB7XG4gIHZhciBzdGFydCA9IHRoaXMsXG4gICAgICBhbmNlc3RvciA9IGxlYXN0Q29tbW9uQW5jZXN0b3Ioc3RhcnQsIGVuZCksXG4gICAgICBub2RlcyA9IFtzdGFydF07XG4gIHdoaWxlIChzdGFydCAhPT0gYW5jZXN0b3IpIHtcbiAgICBzdGFydCA9IHN0YXJ0LnBhcmVudDtcbiAgICBub2Rlcy5wdXNoKHN0YXJ0KTtcbiAgfVxuICB2YXIgayA9IG5vZGVzLmxlbmd0aDtcbiAgd2hpbGUgKGVuZCAhPT0gYW5jZXN0b3IpIHtcbiAgICBub2Rlcy5zcGxpY2UoaywgMCwgZW5kKTtcbiAgICBlbmQgPSBlbmQucGFyZW50O1xuICB9XG4gIHJldHVybiBub2Rlcztcbn07XG5cbmZ1bmN0aW9uIGxlYXN0Q29tbW9uQW5jZXN0b3IoYSwgYikge1xuICBpZiAoYSA9PT0gYikgcmV0dXJuIGE7XG4gIHZhciBhTm9kZXMgPSBhLmFuY2VzdG9ycygpLFxuICAgICAgYk5vZGVzID0gYi5hbmNlc3RvcnMoKSxcbiAgICAgIGMgPSBudWxsO1xuICBhID0gYU5vZGVzLnBvcCgpO1xuICBiID0gYk5vZGVzLnBvcCgpO1xuICB3aGlsZSAoYSA9PT0gYikge1xuICAgIGMgPSBhO1xuICAgIGEgPSBhTm9kZXMucG9wKCk7XG4gICAgYiA9IGJOb2Rlcy5wb3AoKTtcbiAgfVxuICByZXR1cm4gYztcbn1cblxudmFyIG5vZGVfYW5jZXN0b3JzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBub2RlID0gdGhpcywgbm9kZXMgPSBbbm9kZV07XG4gIHdoaWxlIChub2RlID0gbm9kZS5wYXJlbnQpIHtcbiAgICBub2Rlcy5wdXNoKG5vZGUpO1xuICB9XG4gIHJldHVybiBub2Rlcztcbn07XG5cbnZhciBub2RlX2Rlc2NlbmRhbnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBub2RlcyA9IFtdO1xuICB0aGlzLmVhY2goZnVuY3Rpb24obm9kZSkge1xuICAgIG5vZGVzLnB1c2gobm9kZSk7XG4gIH0pO1xuICByZXR1cm4gbm9kZXM7XG59O1xuXG52YXIgbm9kZV9sZWF2ZXMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGxlYXZlcyA9IFtdO1xuICB0aGlzLmVhY2hCZWZvcmUoZnVuY3Rpb24obm9kZSkge1xuICAgIGlmICghbm9kZS5jaGlsZHJlbikge1xuICAgICAgbGVhdmVzLnB1c2gobm9kZSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGxlYXZlcztcbn07XG5cbnZhciBub2RlX2xpbmtzID0gZnVuY3Rpb24oKSB7XG4gIHZhciByb290ID0gdGhpcywgbGlua3MgPSBbXTtcbiAgcm9vdC5lYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAobm9kZSAhPT0gcm9vdCkgeyAvLyBEb27igJl0IGluY2x1ZGUgdGhlIHJvb3TigJlzIHBhcmVudCwgaWYgYW55LlxuICAgICAgbGlua3MucHVzaCh7c291cmNlOiBub2RlLnBhcmVudCwgdGFyZ2V0OiBub2RlfSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGxpbmtzO1xufTtcblxuZnVuY3Rpb24gaGllcmFyY2h5KGRhdGEsIGNoaWxkcmVuKSB7XG4gIHZhciByb290ID0gbmV3IE5vZGUoZGF0YSksXG4gICAgICB2YWx1ZWQgPSArZGF0YS52YWx1ZSAmJiAocm9vdC52YWx1ZSA9IGRhdGEudmFsdWUpLFxuICAgICAgbm9kZSxcbiAgICAgIG5vZGVzID0gW3Jvb3RdLFxuICAgICAgY2hpbGQsXG4gICAgICBjaGlsZHMsXG4gICAgICBpLFxuICAgICAgbjtcblxuICBpZiAoY2hpbGRyZW4gPT0gbnVsbCkgY2hpbGRyZW4gPSBkZWZhdWx0Q2hpbGRyZW47XG5cbiAgd2hpbGUgKG5vZGUgPSBub2Rlcy5wb3AoKSkge1xuICAgIGlmICh2YWx1ZWQpIG5vZGUudmFsdWUgPSArbm9kZS5kYXRhLnZhbHVlO1xuICAgIGlmICgoY2hpbGRzID0gY2hpbGRyZW4obm9kZS5kYXRhKSkgJiYgKG4gPSBjaGlsZHMubGVuZ3RoKSkge1xuICAgICAgbm9kZS5jaGlsZHJlbiA9IG5ldyBBcnJheShuKTtcbiAgICAgIGZvciAoaSA9IG4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICBub2Rlcy5wdXNoKGNoaWxkID0gbm9kZS5jaGlsZHJlbltpXSA9IG5ldyBOb2RlKGNoaWxkc1tpXSkpO1xuICAgICAgICBjaGlsZC5wYXJlbnQgPSBub2RlO1xuICAgICAgICBjaGlsZC5kZXB0aCA9IG5vZGUuZGVwdGggKyAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByb290LmVhY2hCZWZvcmUoY29tcHV0ZUhlaWdodCk7XG59XG5cbmZ1bmN0aW9uIG5vZGVfY29weSgpIHtcbiAgcmV0dXJuIGhpZXJhcmNoeSh0aGlzKS5lYWNoQmVmb3JlKGNvcHlEYXRhKTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdENoaWxkcmVuKGQpIHtcbiAgcmV0dXJuIGQuY2hpbGRyZW47XG59XG5cbmZ1bmN0aW9uIGNvcHlEYXRhKG5vZGUpIHtcbiAgbm9kZS5kYXRhID0gbm9kZS5kYXRhLmRhdGE7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVIZWlnaHQobm9kZSkge1xuICB2YXIgaGVpZ2h0ID0gMDtcbiAgZG8gbm9kZS5oZWlnaHQgPSBoZWlnaHQ7XG4gIHdoaWxlICgobm9kZSA9IG5vZGUucGFyZW50KSAmJiAobm9kZS5oZWlnaHQgPCArK2hlaWdodCkpO1xufVxuXG5mdW5jdGlvbiBOb2RlKGRhdGEpIHtcbiAgdGhpcy5kYXRhID0gZGF0YTtcbiAgdGhpcy5kZXB0aCA9XG4gIHRoaXMuaGVpZ2h0ID0gMDtcbiAgdGhpcy5wYXJlbnQgPSBudWxsO1xufVxuXG5Ob2RlLnByb3RvdHlwZSA9IGhpZXJhcmNoeS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBOb2RlLFxuICBlYWNoOiBub2RlX2VhY2gsXG4gIGVhY2hBZnRlcjogbm9kZV9lYWNoQWZ0ZXIsXG4gIGVhY2hCZWZvcmU6IG5vZGVfZWFjaEJlZm9yZSxcbiAgc3VtOiBub2RlX3N1bSxcbiAgc29ydDogbm9kZV9zb3J0LFxuICBwYXRoOiBub2RlX3BhdGgsXG4gIGFuY2VzdG9yczogbm9kZV9hbmNlc3RvcnMsXG4gIGRlc2NlbmRhbnRzOiBub2RlX2Rlc2NlbmRhbnRzLFxuICBsZWF2ZXM6IG5vZGVfbGVhdmVzLFxuICBsaW5rczogbm9kZV9saW5rcyxcbiAgY29weTogbm9kZV9jb3B5XG59O1xuXG5mdW5jdGlvbiBOb2RlJDIodmFsdWUpIHtcbiAgdGhpcy5fID0gdmFsdWU7XG4gIHRoaXMubmV4dCA9IG51bGw7XG59XG5cbnZhciBzaHVmZmxlJDEgPSBmdW5jdGlvbihhcnJheSkge1xuICB2YXIgaSxcbiAgICAgIG4gPSAoYXJyYXkgPSBhcnJheS5zbGljZSgpKS5sZW5ndGgsXG4gICAgICBoZWFkID0gbnVsbCxcbiAgICAgIG5vZGUgPSBoZWFkO1xuXG4gIHdoaWxlIChuKSB7XG4gICAgdmFyIG5leHQgPSBuZXcgTm9kZSQyKGFycmF5W24gLSAxXSk7XG4gICAgaWYgKG5vZGUpIG5vZGUgPSBub2RlLm5leHQgPSBuZXh0O1xuICAgIGVsc2Ugbm9kZSA9IGhlYWQgPSBuZXh0O1xuICAgIGFycmF5W2ldID0gYXJyYXlbLS1uXTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaGVhZDogaGVhZCxcbiAgICB0YWlsOiBub2RlXG4gIH07XG59O1xuXG52YXIgZW5jbG9zZSA9IGZ1bmN0aW9uKGNpcmNsZXMpIHtcbiAgcmV0dXJuIGVuY2xvc2VOKHNodWZmbGUkMShjaXJjbGVzKSwgW10pO1xufTtcblxuZnVuY3Rpb24gZW5jbG9zZXMoYSwgYikge1xuICB2YXIgZHggPSBiLnggLSBhLngsXG4gICAgICBkeSA9IGIueSAtIGEueSxcbiAgICAgIGRyID0gYS5yIC0gYi5yO1xuICByZXR1cm4gZHIgKiBkciArIDFlLTYgPiBkeCAqIGR4ICsgZHkgKiBkeTtcbn1cblxuLy8gUmV0dXJucyB0aGUgc21hbGxlc3QgY2lyY2xlIHRoYXQgY29udGFpbnMgY2lyY2xlcyBMIGFuZCBpbnRlcnNlY3RzIGNpcmNsZXMgQi5cbmZ1bmN0aW9uIGVuY2xvc2VOKEwsIEIpIHtcbiAgdmFyIGNpcmNsZSxcbiAgICAgIGwwID0gbnVsbCxcbiAgICAgIGwxID0gTC5oZWFkLFxuICAgICAgbDIsXG4gICAgICBwMTtcblxuICBzd2l0Y2ggKEIubGVuZ3RoKSB7XG4gICAgY2FzZSAxOiBjaXJjbGUgPSBlbmNsb3NlMShCWzBdKTsgYnJlYWs7XG4gICAgY2FzZSAyOiBjaXJjbGUgPSBlbmNsb3NlMihCWzBdLCBCWzFdKTsgYnJlYWs7XG4gICAgY2FzZSAzOiBjaXJjbGUgPSBlbmNsb3NlMyhCWzBdLCBCWzFdLCBCWzJdKTsgYnJlYWs7XG4gIH1cblxuICB3aGlsZSAobDEpIHtcbiAgICBwMSA9IGwxLl8sIGwyID0gbDEubmV4dDtcbiAgICBpZiAoIWNpcmNsZSB8fCAhZW5jbG9zZXMoY2lyY2xlLCBwMSkpIHtcblxuICAgICAgLy8gVGVtcG9yYXJpbHkgdHJ1bmNhdGUgTCBiZWZvcmUgbDEuXG4gICAgICBpZiAobDApIEwudGFpbCA9IGwwLCBsMC5uZXh0ID0gbnVsbDtcbiAgICAgIGVsc2UgTC5oZWFkID0gTC50YWlsID0gbnVsbDtcblxuICAgICAgQi5wdXNoKHAxKTtcbiAgICAgIGNpcmNsZSA9IGVuY2xvc2VOKEwsIEIpOyAvLyBOb3RlOiByZW9yZGVycyBMIVxuICAgICAgQi5wb3AoKTtcblxuICAgICAgLy8gTW92ZSBsMSB0byB0aGUgZnJvbnQgb2YgTCBhbmQgcmVjb25uZWN0IHRoZSB0cnVuY2F0ZWQgbGlzdCBMLlxuICAgICAgaWYgKEwuaGVhZCkgbDEubmV4dCA9IEwuaGVhZCwgTC5oZWFkID0gbDE7XG4gICAgICBlbHNlIGwxLm5leHQgPSBudWxsLCBMLmhlYWQgPSBMLnRhaWwgPSBsMTtcbiAgICAgIGwwID0gTC50YWlsLCBsMC5uZXh0ID0gbDI7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgbDAgPSBsMTtcbiAgICB9XG4gICAgbDEgPSBsMjtcbiAgfVxuXG4gIEwudGFpbCA9IGwwO1xuICByZXR1cm4gY2lyY2xlO1xufVxuXG5mdW5jdGlvbiBlbmNsb3NlMShhKSB7XG4gIHJldHVybiB7XG4gICAgeDogYS54LFxuICAgIHk6IGEueSxcbiAgICByOiBhLnJcbiAgfTtcbn1cblxuZnVuY3Rpb24gZW5jbG9zZTIoYSwgYikge1xuICB2YXIgeDEgPSBhLngsIHkxID0gYS55LCByMSA9IGEucixcbiAgICAgIHgyID0gYi54LCB5MiA9IGIueSwgcjIgPSBiLnIsXG4gICAgICB4MjEgPSB4MiAtIHgxLCB5MjEgPSB5MiAtIHkxLCByMjEgPSByMiAtIHIxLFxuICAgICAgbCA9IE1hdGguc3FydCh4MjEgKiB4MjEgKyB5MjEgKiB5MjEpO1xuICByZXR1cm4ge1xuICAgIHg6ICh4MSArIHgyICsgeDIxIC8gbCAqIHIyMSkgLyAyLFxuICAgIHk6ICh5MSArIHkyICsgeTIxIC8gbCAqIHIyMSkgLyAyLFxuICAgIHI6IChsICsgcjEgKyByMikgLyAyXG4gIH07XG59XG5cbmZ1bmN0aW9uIGVuY2xvc2UzKGEsIGIsIGMpIHtcbiAgdmFyIHgxID0gYS54LCB5MSA9IGEueSwgcjEgPSBhLnIsXG4gICAgICB4MiA9IGIueCwgeTIgPSBiLnksIHIyID0gYi5yLFxuICAgICAgeDMgPSBjLngsIHkzID0gYy55LCByMyA9IGMucixcbiAgICAgIGEyID0gMiAqICh4MSAtIHgyKSxcbiAgICAgIGIyID0gMiAqICh5MSAtIHkyKSxcbiAgICAgIGMyID0gMiAqIChyMiAtIHIxKSxcbiAgICAgIGQyID0geDEgKiB4MSArIHkxICogeTEgLSByMSAqIHIxIC0geDIgKiB4MiAtIHkyICogeTIgKyByMiAqIHIyLFxuICAgICAgYTMgPSAyICogKHgxIC0geDMpLFxuICAgICAgYjMgPSAyICogKHkxIC0geTMpLFxuICAgICAgYzMgPSAyICogKHIzIC0gcjEpLFxuICAgICAgZDMgPSB4MSAqIHgxICsgeTEgKiB5MSAtIHIxICogcjEgLSB4MyAqIHgzIC0geTMgKiB5MyArIHIzICogcjMsXG4gICAgICBhYiA9IGEzICogYjIgLSBhMiAqIGIzLFxuICAgICAgeGEgPSAoYjIgKiBkMyAtIGIzICogZDIpIC8gYWIgLSB4MSxcbiAgICAgIHhiID0gKGIzICogYzIgLSBiMiAqIGMzKSAvIGFiLFxuICAgICAgeWEgPSAoYTMgKiBkMiAtIGEyICogZDMpIC8gYWIgLSB5MSxcbiAgICAgIHliID0gKGEyICogYzMgLSBhMyAqIGMyKSAvIGFiLFxuICAgICAgQSA9IHhiICogeGIgKyB5YiAqIHliIC0gMSxcbiAgICAgIEIgPSAyICogKHhhICogeGIgKyB5YSAqIHliICsgcjEpLFxuICAgICAgQyA9IHhhICogeGEgKyB5YSAqIHlhIC0gcjEgKiByMSxcbiAgICAgIHIgPSAoLUIgLSBNYXRoLnNxcnQoQiAqIEIgLSA0ICogQSAqIEMpKSAvICgyICogQSk7XG4gIHJldHVybiB7XG4gICAgeDogeGEgKyB4YiAqIHIgKyB4MSxcbiAgICB5OiB5YSArIHliICogciArIHkxLFxuICAgIHI6IHJcbiAgfTtcbn1cblxuZnVuY3Rpb24gcGxhY2UoYSwgYiwgYykge1xuICB2YXIgYXggPSBhLngsXG4gICAgICBheSA9IGEueSxcbiAgICAgIGRhID0gYi5yICsgYy5yLFxuICAgICAgZGIgPSBhLnIgKyBjLnIsXG4gICAgICBkeCA9IGIueCAtIGF4LFxuICAgICAgZHkgPSBiLnkgLSBheSxcbiAgICAgIGRjID0gZHggKiBkeCArIGR5ICogZHk7XG4gIGlmIChkYykge1xuICAgIHZhciB4ID0gMC41ICsgKChkYiAqPSBkYikgLSAoZGEgKj0gZGEpKSAvICgyICogZGMpLFxuICAgICAgICB5ID0gTWF0aC5zcXJ0KE1hdGgubWF4KDAsIDIgKiBkYSAqIChkYiArIGRjKSAtIChkYiAtPSBkYykgKiBkYiAtIGRhICogZGEpKSAvICgyICogZGMpO1xuICAgIGMueCA9IGF4ICsgeCAqIGR4ICsgeSAqIGR5O1xuICAgIGMueSA9IGF5ICsgeCAqIGR5IC0geSAqIGR4O1xuICB9IGVsc2Uge1xuICAgIGMueCA9IGF4ICsgZGI7XG4gICAgYy55ID0gYXk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW50ZXJzZWN0cyhhLCBiKSB7XG4gIHZhciBkeCA9IGIueCAtIGEueCxcbiAgICAgIGR5ID0gYi55IC0gYS55LFxuICAgICAgZHIgPSBhLnIgKyBiLnI7XG4gIHJldHVybiBkciAqIGRyID4gZHggKiBkeCArIGR5ICogZHk7XG59XG5cbmZ1bmN0aW9uIGRpc3RhbmNlMihjaXJjbGUsIHgsIHkpIHtcbiAgdmFyIGR4ID0gY2lyY2xlLnggLSB4LFxuICAgICAgZHkgPSBjaXJjbGUueSAtIHk7XG4gIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTtcbn1cblxuZnVuY3Rpb24gTm9kZSQxKGNpcmNsZSkge1xuICB0aGlzLl8gPSBjaXJjbGU7XG4gIHRoaXMubmV4dCA9IG51bGw7XG4gIHRoaXMucHJldmlvdXMgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBwYWNrRW5jbG9zZShjaXJjbGVzKSB7XG4gIGlmICghKG4gPSBjaXJjbGVzLmxlbmd0aCkpIHJldHVybiAwO1xuXG4gIHZhciBhLCBiLCBjLCBuO1xuXG4gIC8vIFBsYWNlIHRoZSBmaXJzdCBjaXJjbGUuXG4gIGEgPSBjaXJjbGVzWzBdLCBhLnggPSAwLCBhLnkgPSAwO1xuICBpZiAoIShuID4gMSkpIHJldHVybiBhLnI7XG5cbiAgLy8gUGxhY2UgdGhlIHNlY29uZCBjaXJjbGUuXG4gIGIgPSBjaXJjbGVzWzFdLCBhLnggPSAtYi5yLCBiLnggPSBhLnIsIGIueSA9IDA7XG4gIGlmICghKG4gPiAyKSkgcmV0dXJuIGEuciArIGIucjtcblxuICAvLyBQbGFjZSB0aGUgdGhpcmQgY2lyY2xlLlxuICBwbGFjZShiLCBhLCBjID0gY2lyY2xlc1syXSk7XG5cbiAgLy8gSW5pdGlhbGl6ZSB0aGUgd2VpZ2h0ZWQgY2VudHJvaWQuXG4gIHZhciBhYSA9IGEuciAqIGEucixcbiAgICAgIGJhID0gYi5yICogYi5yLFxuICAgICAgY2EgPSBjLnIgKiBjLnIsXG4gICAgICBvYSA9IGFhICsgYmEgKyBjYSxcbiAgICAgIG94ID0gYWEgKiBhLnggKyBiYSAqIGIueCArIGNhICogYy54LFxuICAgICAgb3kgPSBhYSAqIGEueSArIGJhICogYi55ICsgY2EgKiBjLnksXG4gICAgICBjeCwgY3ksIGksIGosIGssIHNqLCBzaztcblxuICAvLyBJbml0aWFsaXplIHRoZSBmcm9udC1jaGFpbiB1c2luZyB0aGUgZmlyc3QgdGhyZWUgY2lyY2xlcyBhLCBiIGFuZCBjLlxuICBhID0gbmV3IE5vZGUkMShhKSwgYiA9IG5ldyBOb2RlJDEoYiksIGMgPSBuZXcgTm9kZSQxKGMpO1xuICBhLm5leHQgPSBjLnByZXZpb3VzID0gYjtcbiAgYi5uZXh0ID0gYS5wcmV2aW91cyA9IGM7XG4gIGMubmV4dCA9IGIucHJldmlvdXMgPSBhO1xuXG4gIC8vIEF0dGVtcHQgdG8gcGxhY2UgZWFjaCByZW1haW5pbmcgY2lyY2xl4oCmXG4gIHBhY2s6IGZvciAoaSA9IDM7IGkgPCBuOyArK2kpIHtcbiAgICBwbGFjZShhLl8sIGIuXywgYyA9IGNpcmNsZXNbaV0pLCBjID0gbmV3IE5vZGUkMShjKTtcblxuICAgIC8vIElmIHRoZXJlIGFyZSBvbmx5IHRocmVlIGVsZW1lbnRzIGluIHRoZSBmcm9udC1jaGFpbuKAplxuICAgIGlmICgoayA9IGEucHJldmlvdXMpID09PSAoaiA9IGIubmV4dCkpIHtcbiAgICAgIC8vIElmIHRoZSBuZXcgY2lyY2xlIGludGVyc2VjdHMgdGhlIHRoaXJkIGNpcmNsZSxcbiAgICAgIC8vIHJvdGF0ZSB0aGUgZnJvbnQgY2hhaW4gdG8gdHJ5IHRoZSBuZXh0IHBvc2l0aW9uLlxuICAgICAgaWYgKGludGVyc2VjdHMoai5fLCBjLl8pKSB7XG4gICAgICAgIGEgPSBiLCBiID0gaiwgLS1pO1xuICAgICAgICBjb250aW51ZSBwYWNrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZpbmQgdGhlIGNsb3Nlc3QgaW50ZXJzZWN0aW5nIGNpcmNsZSBvbiB0aGUgZnJvbnQtY2hhaW4sIGlmIGFueS5cbiAgICBlbHNlIHtcbiAgICAgIHNqID0gai5fLnIsIHNrID0gay5fLnI7XG4gICAgICBkbyB7XG4gICAgICAgIGlmIChzaiA8PSBzaykge1xuICAgICAgICAgIGlmIChpbnRlcnNlY3RzKGouXywgYy5fKSkge1xuICAgICAgICAgICAgYiA9IGosIGEubmV4dCA9IGIsIGIucHJldmlvdXMgPSBhLCAtLWk7XG4gICAgICAgICAgICBjb250aW51ZSBwYWNrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBqID0gai5uZXh0LCBzaiArPSBqLl8ucjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoaW50ZXJzZWN0cyhrLl8sIGMuXykpIHtcbiAgICAgICAgICAgIGEgPSBrLCBhLm5leHQgPSBiLCBiLnByZXZpb3VzID0gYSwgLS1pO1xuICAgICAgICAgICAgY29udGludWUgcGFjaztcbiAgICAgICAgICB9XG4gICAgICAgICAgayA9IGsucHJldmlvdXMsIHNrICs9IGsuXy5yO1xuICAgICAgICB9XG4gICAgICB9IHdoaWxlIChqICE9PSBrLm5leHQpO1xuICAgIH1cblxuICAgIC8vIFN1Y2Nlc3MhIEluc2VydCB0aGUgbmV3IGNpcmNsZSBjIGJldHdlZW4gYSBhbmQgYi5cbiAgICBjLnByZXZpb3VzID0gYSwgYy5uZXh0ID0gYiwgYS5uZXh0ID0gYi5wcmV2aW91cyA9IGIgPSBjO1xuXG4gICAgLy8gVXBkYXRlIHRoZSB3ZWlnaHRlZCBjZW50cm9pZC5cbiAgICBvYSArPSBjYSA9IGMuXy5yICogYy5fLnI7XG4gICAgb3ggKz0gY2EgKiBjLl8ueDtcbiAgICBveSArPSBjYSAqIGMuXy55O1xuXG4gICAgLy8gQ29tcHV0ZSB0aGUgbmV3IGNsb3Nlc3QgY2lyY2xlIGEgdG8gY2VudHJvaWQuXG4gICAgYWEgPSBkaXN0YW5jZTIoYS5fLCBjeCA9IG94IC8gb2EsIGN5ID0gb3kgLyBvYSk7XG4gICAgd2hpbGUgKChjID0gYy5uZXh0KSAhPT0gYikge1xuICAgICAgaWYgKChjYSA9IGRpc3RhbmNlMihjLl8sIGN4LCBjeSkpIDwgYWEpIHtcbiAgICAgICAgYSA9IGMsIGFhID0gY2E7XG4gICAgICB9XG4gICAgfVxuICAgIGIgPSBhLm5leHQ7XG4gIH1cblxuICAvLyBDb21wdXRlIHRoZSBlbmNsb3NpbmcgY2lyY2xlIG9mIHRoZSBmcm9udCBjaGFpbi5cbiAgYSA9IFtiLl9dLCBjID0gYjsgd2hpbGUgKChjID0gYy5uZXh0KSAhPT0gYikgYS5wdXNoKGMuXyk7IGMgPSBlbmNsb3NlKGEpO1xuXG4gIC8vIFRyYW5zbGF0ZSB0aGUgY2lyY2xlcyB0byBwdXQgdGhlIGVuY2xvc2luZyBjaXJjbGUgYXJvdW5kIHRoZSBvcmlnaW4uXG4gIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIGEgPSBjaXJjbGVzW2ldLCBhLnggLT0gYy54LCBhLnkgLT0gYy55O1xuXG4gIHJldHVybiBjLnI7XG59XG5cbnZhciBzaWJsaW5ncyA9IGZ1bmN0aW9uKGNpcmNsZXMpIHtcbiAgcGFja0VuY2xvc2UoY2lyY2xlcyk7XG4gIHJldHVybiBjaXJjbGVzO1xufTtcblxuZnVuY3Rpb24gb3B0aW9uYWwoZikge1xuICByZXR1cm4gZiA9PSBudWxsID8gbnVsbCA6IHJlcXVpcmVkKGYpO1xufVxuXG5mdW5jdGlvbiByZXF1aXJlZChmKSB7XG4gIGlmICh0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3I7XG4gIHJldHVybiBmO1xufVxuXG5mdW5jdGlvbiBjb25zdGFudFplcm8oKSB7XG4gIHJldHVybiAwO1xufVxuXG52YXIgY29uc3RhbnQkNiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxuZnVuY3Rpb24gZGVmYXVsdFJhZGl1cyhkKSB7XG4gIHJldHVybiBNYXRoLnNxcnQoZC52YWx1ZSk7XG59XG5cbnZhciBpbmRleCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmFkaXVzID0gbnVsbCxcbiAgICAgIGR4ID0gMSxcbiAgICAgIGR5ID0gMSxcbiAgICAgIHBhZGRpbmcgPSBjb25zdGFudFplcm87XG5cbiAgZnVuY3Rpb24gcGFjayhyb290KSB7XG4gICAgcm9vdC54ID0gZHggLyAyLCByb290LnkgPSBkeSAvIDI7XG4gICAgaWYgKHJhZGl1cykge1xuICAgICAgcm9vdC5lYWNoQmVmb3JlKHJhZGl1c0xlYWYocmFkaXVzKSlcbiAgICAgICAgICAuZWFjaEFmdGVyKHBhY2tDaGlsZHJlbihwYWRkaW5nLCAwLjUpKVxuICAgICAgICAgIC5lYWNoQmVmb3JlKHRyYW5zbGF0ZUNoaWxkKDEpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcm9vdC5lYWNoQmVmb3JlKHJhZGl1c0xlYWYoZGVmYXVsdFJhZGl1cykpXG4gICAgICAgICAgLmVhY2hBZnRlcihwYWNrQ2hpbGRyZW4oY29uc3RhbnRaZXJvLCAxKSlcbiAgICAgICAgICAuZWFjaEFmdGVyKHBhY2tDaGlsZHJlbihwYWRkaW5nLCByb290LnIgLyBNYXRoLm1pbihkeCwgZHkpKSlcbiAgICAgICAgICAuZWFjaEJlZm9yZSh0cmFuc2xhdGVDaGlsZChNYXRoLm1pbihkeCwgZHkpIC8gKDIgKiByb290LnIpKSk7XG4gICAgfVxuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgcGFjay5yYWRpdXMgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFkaXVzID0gb3B0aW9uYWwoeCksIHBhY2spIDogcmFkaXVzO1xuICB9O1xuXG4gIHBhY2suc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCBwYWNrKSA6IFtkeCwgZHldO1xuICB9O1xuXG4gIHBhY2sucGFkZGluZyA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiBjb25zdGFudCQ2KCt4KSwgcGFjaykgOiBwYWRkaW5nO1xuICB9O1xuXG4gIHJldHVybiBwYWNrO1xufTtcblxuZnVuY3Rpb24gcmFkaXVzTGVhZihyYWRpdXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIG5vZGUuciA9IE1hdGgubWF4KDAsICtyYWRpdXMobm9kZSkgfHwgMCk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBwYWNrQ2hpbGRyZW4ocGFkZGluZywgaykge1xuICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgIGlmIChjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIHZhciBjaGlsZHJlbixcbiAgICAgICAgICBpLFxuICAgICAgICAgIG4gPSBjaGlsZHJlbi5sZW5ndGgsXG4gICAgICAgICAgciA9IHBhZGRpbmcobm9kZSkgKiBrIHx8IDAsXG4gICAgICAgICAgZTtcblxuICAgICAgaWYgKHIpIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIGNoaWxkcmVuW2ldLnIgKz0gcjtcbiAgICAgIGUgPSBwYWNrRW5jbG9zZShjaGlsZHJlbik7XG4gICAgICBpZiAocikgZm9yIChpID0gMDsgaSA8IG47ICsraSkgY2hpbGRyZW5baV0uciAtPSByO1xuICAgICAgbm9kZS5yID0gZSArIHI7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiB0cmFuc2xhdGVDaGlsZChrKSB7XG4gIHJldHVybiBmdW5jdGlvbihub2RlKSB7XG4gICAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50O1xuICAgIG5vZGUuciAqPSBrO1xuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgIG5vZGUueCA9IHBhcmVudC54ICsgayAqIG5vZGUueDtcbiAgICAgIG5vZGUueSA9IHBhcmVudC55ICsgayAqIG5vZGUueTtcbiAgICB9XG4gIH07XG59XG5cbnZhciByb3VuZE5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gIG5vZGUueDAgPSBNYXRoLnJvdW5kKG5vZGUueDApO1xuICBub2RlLnkwID0gTWF0aC5yb3VuZChub2RlLnkwKTtcbiAgbm9kZS54MSA9IE1hdGgucm91bmQobm9kZS54MSk7XG4gIG5vZGUueTEgPSBNYXRoLnJvdW5kKG5vZGUueTEpO1xufTtcblxudmFyIHRyZWVtYXBEaWNlID0gZnVuY3Rpb24ocGFyZW50LCB4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgbm9kZXMgPSBwYXJlbnQuY2hpbGRyZW4sXG4gICAgICBub2RlLFxuICAgICAgaSA9IC0xLFxuICAgICAgbiA9IG5vZGVzLmxlbmd0aCxcbiAgICAgIGsgPSBwYXJlbnQudmFsdWUgJiYgKHgxIC0geDApIC8gcGFyZW50LnZhbHVlO1xuXG4gIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgbm9kZSA9IG5vZGVzW2ldLCBub2RlLnkwID0geTAsIG5vZGUueTEgPSB5MTtcbiAgICBub2RlLngwID0geDAsIG5vZGUueDEgPSB4MCArPSBub2RlLnZhbHVlICogaztcbiAgfVxufTtcblxudmFyIHBhcnRpdGlvbiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZHggPSAxLFxuICAgICAgZHkgPSAxLFxuICAgICAgcGFkZGluZyA9IDAsXG4gICAgICByb3VuZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIHBhcnRpdGlvbihyb290KSB7XG4gICAgdmFyIG4gPSByb290LmhlaWdodCArIDE7XG4gICAgcm9vdC54MCA9XG4gICAgcm9vdC55MCA9IHBhZGRpbmc7XG4gICAgcm9vdC54MSA9IGR4O1xuICAgIHJvb3QueTEgPSBkeSAvIG47XG4gICAgcm9vdC5lYWNoQmVmb3JlKHBvc2l0aW9uTm9kZShkeSwgbikpO1xuICAgIGlmIChyb3VuZCkgcm9vdC5lYWNoQmVmb3JlKHJvdW5kTm9kZSk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH1cblxuICBmdW5jdGlvbiBwb3NpdGlvbk5vZGUoZHksIG4pIHtcbiAgICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgdHJlZW1hcERpY2Uobm9kZSwgbm9kZS54MCwgZHkgKiAobm9kZS5kZXB0aCArIDEpIC8gbiwgbm9kZS54MSwgZHkgKiAobm9kZS5kZXB0aCArIDIpIC8gbik7XG4gICAgICB9XG4gICAgICB2YXIgeDAgPSBub2RlLngwLFxuICAgICAgICAgIHkwID0gbm9kZS55MCxcbiAgICAgICAgICB4MSA9IG5vZGUueDEgLSBwYWRkaW5nLFxuICAgICAgICAgIHkxID0gbm9kZS55MSAtIHBhZGRpbmc7XG4gICAgICBpZiAoeDEgPCB4MCkgeDAgPSB4MSA9ICh4MCArIHgxKSAvIDI7XG4gICAgICBpZiAoeTEgPCB5MCkgeTAgPSB5MSA9ICh5MCArIHkxKSAvIDI7XG4gICAgICBub2RlLngwID0geDA7XG4gICAgICBub2RlLnkwID0geTA7XG4gICAgICBub2RlLngxID0geDE7XG4gICAgICBub2RlLnkxID0geTE7XG4gICAgfTtcbiAgfVxuXG4gIHBhcnRpdGlvbi5yb3VuZCA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyb3VuZCA9ICEheCwgcGFydGl0aW9uKSA6IHJvdW5kO1xuICB9O1xuXG4gIHBhcnRpdGlvbi5zaXplID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIHBhcnRpdGlvbikgOiBbZHgsIGR5XTtcbiAgfTtcblxuICBwYXJ0aXRpb24ucGFkZGluZyA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nID0gK3gsIHBhcnRpdGlvbikgOiBwYWRkaW5nO1xuICB9O1xuXG4gIHJldHVybiBwYXJ0aXRpb247XG59O1xuXG52YXIga2V5UHJlZml4JDEgPSBcIiRcIjtcbnZhciBwcmVyb290ID0ge2RlcHRoOiAtMX07XG52YXIgYW1iaWd1b3VzID0ge307XG5cbmZ1bmN0aW9uIGRlZmF1bHRJZChkKSB7XG4gIHJldHVybiBkLmlkO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0UGFyZW50SWQoZCkge1xuICByZXR1cm4gZC5wYXJlbnRJZDtcbn1cblxudmFyIHN0cmF0aWZ5ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBpZCA9IGRlZmF1bHRJZCxcbiAgICAgIHBhcmVudElkID0gZGVmYXVsdFBhcmVudElkO1xuXG4gIGZ1bmN0aW9uIHN0cmF0aWZ5KGRhdGEpIHtcbiAgICB2YXIgZCxcbiAgICAgICAgaSxcbiAgICAgICAgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgICByb290LFxuICAgICAgICBwYXJlbnQsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIG5vZGVzID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBub2RlSWQsXG4gICAgICAgIG5vZGVLZXksXG4gICAgICAgIG5vZGVCeUtleSA9IHt9O1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgZCA9IGRhdGFbaV0sIG5vZGUgPSBub2Rlc1tpXSA9IG5ldyBOb2RlKGQpO1xuICAgICAgaWYgKChub2RlSWQgPSBpZChkLCBpLCBkYXRhKSkgIT0gbnVsbCAmJiAobm9kZUlkICs9IFwiXCIpKSB7XG4gICAgICAgIG5vZGVLZXkgPSBrZXlQcmVmaXgkMSArIChub2RlLmlkID0gbm9kZUlkKTtcbiAgICAgICAgbm9kZUJ5S2V5W25vZGVLZXldID0gbm9kZUtleSBpbiBub2RlQnlLZXkgPyBhbWJpZ3VvdXMgOiBub2RlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZUlkID0gcGFyZW50SWQoZGF0YVtpXSwgaSwgZGF0YSk7XG4gICAgICBpZiAobm9kZUlkID09IG51bGwgfHwgIShub2RlSWQgKz0gXCJcIikpIHtcbiAgICAgICAgaWYgKHJvb3QpIHRocm93IG5ldyBFcnJvcihcIm11bHRpcGxlIHJvb3RzXCIpO1xuICAgICAgICByb290ID0gbm9kZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmVudCA9IG5vZGVCeUtleVtrZXlQcmVmaXgkMSArIG5vZGVJZF07XG4gICAgICAgIGlmICghcGFyZW50KSB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nOiBcIiArIG5vZGVJZCk7XG4gICAgICAgIGlmIChwYXJlbnQgPT09IGFtYmlndW91cykgdGhyb3cgbmV3IEVycm9yKFwiYW1iaWd1b3VzOiBcIiArIG5vZGVJZCk7XG4gICAgICAgIGlmIChwYXJlbnQuY2hpbGRyZW4pIHBhcmVudC5jaGlsZHJlbi5wdXNoKG5vZGUpO1xuICAgICAgICBlbHNlIHBhcmVudC5jaGlsZHJlbiA9IFtub2RlXTtcbiAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFyb290KSB0aHJvdyBuZXcgRXJyb3IoXCJubyByb290XCIpO1xuICAgIHJvb3QucGFyZW50ID0gcHJlcm9vdDtcbiAgICByb290LmVhY2hCZWZvcmUoZnVuY3Rpb24obm9kZSkgeyBub2RlLmRlcHRoID0gbm9kZS5wYXJlbnQuZGVwdGggKyAxOyAtLW47IH0pLmVhY2hCZWZvcmUoY29tcHV0ZUhlaWdodCk7XG4gICAgcm9vdC5wYXJlbnQgPSBudWxsO1xuICAgIGlmIChuID4gMCkgdGhyb3cgbmV3IEVycm9yKFwiY3ljbGVcIik7XG5cbiAgICByZXR1cm4gcm9vdDtcbiAgfVxuXG4gIHN0cmF0aWZ5LmlkID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGlkID0gcmVxdWlyZWQoeCksIHN0cmF0aWZ5KSA6IGlkO1xuICB9O1xuXG4gIHN0cmF0aWZ5LnBhcmVudElkID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhcmVudElkID0gcmVxdWlyZWQoeCksIHN0cmF0aWZ5KSA6IHBhcmVudElkO1xuICB9O1xuXG4gIHJldHVybiBzdHJhdGlmeTtcbn07XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXBhcmF0aW9uJDEoYSwgYikge1xuICByZXR1cm4gYS5wYXJlbnQgPT09IGIucGFyZW50ID8gMSA6IDI7XG59XG5cbi8vIGZ1bmN0aW9uIHJhZGlhbFNlcGFyYXRpb24oYSwgYikge1xuLy8gICByZXR1cm4gKGEucGFyZW50ID09PSBiLnBhcmVudCA/IDEgOiAyKSAvIGEuZGVwdGg7XG4vLyB9XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byB0cmF2ZXJzZSB0aGUgbGVmdCBjb250b3VyIG9mIGEgc3VidHJlZSAob3Jcbi8vIHN1YmZvcmVzdCkuIEl0IHJldHVybnMgdGhlIHN1Y2Nlc3NvciBvZiB2IG9uIHRoaXMgY29udG91ci4gVGhpcyBzdWNjZXNzb3IgaXNcbi8vIGVpdGhlciBnaXZlbiBieSB0aGUgbGVmdG1vc3QgY2hpbGQgb2YgdiBvciBieSB0aGUgdGhyZWFkIG9mIHYuIFRoZSBmdW5jdGlvblxuLy8gcmV0dXJucyBudWxsIGlmIGFuZCBvbmx5IGlmIHYgaXMgb24gdGhlIGhpZ2hlc3QgbGV2ZWwgb2YgaXRzIHN1YnRyZWUuXG5mdW5jdGlvbiBuZXh0TGVmdCh2KSB7XG4gIHZhciBjaGlsZHJlbiA9IHYuY2hpbGRyZW47XG4gIHJldHVybiBjaGlsZHJlbiA/IGNoaWxkcmVuWzBdIDogdi50O1xufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIHdvcmtzIGFuYWxvZ291c2x5IHRvIG5leHRMZWZ0LlxuZnVuY3Rpb24gbmV4dFJpZ2h0KHYpIHtcbiAgdmFyIGNoaWxkcmVuID0gdi5jaGlsZHJlbjtcbiAgcmV0dXJuIGNoaWxkcmVuID8gY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoIC0gMV0gOiB2LnQ7XG59XG5cbi8vIFNoaWZ0cyB0aGUgY3VycmVudCBzdWJ0cmVlIHJvb3RlZCBhdCB3Ky4gVGhpcyBpcyBkb25lIGJ5IGluY3JlYXNpbmdcbi8vIHByZWxpbSh3KykgYW5kIG1vZCh3KykgYnkgc2hpZnQuXG5mdW5jdGlvbiBtb3ZlU3VidHJlZSh3bSwgd3AsIHNoaWZ0KSB7XG4gIHZhciBjaGFuZ2UgPSBzaGlmdCAvICh3cC5pIC0gd20uaSk7XG4gIHdwLmMgLT0gY2hhbmdlO1xuICB3cC5zICs9IHNoaWZ0O1xuICB3bS5jICs9IGNoYW5nZTtcbiAgd3AueiArPSBzaGlmdDtcbiAgd3AubSArPSBzaGlmdDtcbn1cblxuLy8gQWxsIG90aGVyIHNoaWZ0cywgYXBwbGllZCB0byB0aGUgc21hbGxlciBzdWJ0cmVlcyBiZXR3ZWVuIHctIGFuZCB3KywgYXJlXG4vLyBwZXJmb3JtZWQgYnkgdGhpcyBmdW5jdGlvbi4gVG8gcHJlcGFyZSB0aGUgc2hpZnRzLCB3ZSBoYXZlIHRvIGFkanVzdFxuLy8gY2hhbmdlKHcrKSwgc2hpZnQodyspLCBhbmQgY2hhbmdlKHctKS5cbmZ1bmN0aW9uIGV4ZWN1dGVTaGlmdHModikge1xuICB2YXIgc2hpZnQgPSAwLFxuICAgICAgY2hhbmdlID0gMCxcbiAgICAgIGNoaWxkcmVuID0gdi5jaGlsZHJlbixcbiAgICAgIGkgPSBjaGlsZHJlbi5sZW5ndGgsXG4gICAgICB3O1xuICB3aGlsZSAoLS1pID49IDApIHtcbiAgICB3ID0gY2hpbGRyZW5baV07XG4gICAgdy56ICs9IHNoaWZ0O1xuICAgIHcubSArPSBzaGlmdDtcbiAgICBzaGlmdCArPSB3LnMgKyAoY2hhbmdlICs9IHcuYyk7XG4gIH1cbn1cblxuLy8gSWYgdmkt4oCZcyBhbmNlc3RvciBpcyBhIHNpYmxpbmcgb2YgdiwgcmV0dXJucyB2aS3igJlzIGFuY2VzdG9yLiBPdGhlcndpc2UsXG4vLyByZXR1cm5zIHRoZSBzcGVjaWZpZWQgKGRlZmF1bHQpIGFuY2VzdG9yLlxuZnVuY3Rpb24gbmV4dEFuY2VzdG9yKHZpbSwgdiwgYW5jZXN0b3IpIHtcbiAgcmV0dXJuIHZpbS5hLnBhcmVudCA9PT0gdi5wYXJlbnQgPyB2aW0uYSA6IGFuY2VzdG9yO1xufVxuXG5mdW5jdGlvbiBUcmVlTm9kZShub2RlLCBpKSB7XG4gIHRoaXMuXyA9IG5vZGU7XG4gIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgdGhpcy5jaGlsZHJlbiA9IG51bGw7XG4gIHRoaXMuQSA9IG51bGw7IC8vIGRlZmF1bHQgYW5jZXN0b3JcbiAgdGhpcy5hID0gdGhpczsgLy8gYW5jZXN0b3JcbiAgdGhpcy56ID0gMDsgLy8gcHJlbGltXG4gIHRoaXMubSA9IDA7IC8vIG1vZFxuICB0aGlzLmMgPSAwOyAvLyBjaGFuZ2VcbiAgdGhpcy5zID0gMDsgLy8gc2hpZnRcbiAgdGhpcy50ID0gbnVsbDsgLy8gdGhyZWFkXG4gIHRoaXMuaSA9IGk7IC8vIG51bWJlclxufVxuXG5UcmVlTm9kZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKE5vZGUucHJvdG90eXBlKTtcblxuZnVuY3Rpb24gdHJlZVJvb3Qocm9vdCkge1xuICB2YXIgdHJlZSA9IG5ldyBUcmVlTm9kZShyb290LCAwKSxcbiAgICAgIG5vZGUsXG4gICAgICBub2RlcyA9IFt0cmVlXSxcbiAgICAgIGNoaWxkLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBpLFxuICAgICAgbjtcblxuICB3aGlsZSAobm9kZSA9IG5vZGVzLnBvcCgpKSB7XG4gICAgaWYgKGNoaWxkcmVuID0gbm9kZS5fLmNoaWxkcmVuKSB7XG4gICAgICBub2RlLmNoaWxkcmVuID0gbmV3IEFycmF5KG4gPSBjaGlsZHJlbi5sZW5ndGgpO1xuICAgICAgZm9yIChpID0gbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIG5vZGVzLnB1c2goY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldID0gbmV3IFRyZWVOb2RlKGNoaWxkcmVuW2ldLCBpKSk7XG4gICAgICAgIGNoaWxkLnBhcmVudCA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgKHRyZWUucGFyZW50ID0gbmV3IFRyZWVOb2RlKG51bGwsIDApKS5jaGlsZHJlbiA9IFt0cmVlXTtcbiAgcmV0dXJuIHRyZWU7XG59XG5cbi8vIE5vZGUtbGluayB0cmVlIGRpYWdyYW0gdXNpbmcgdGhlIFJlaW5nb2xkLVRpbGZvcmQgXCJ0aWR5XCIgYWxnb3JpdGhtXG52YXIgdHJlZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VwYXJhdGlvbiA9IGRlZmF1bHRTZXBhcmF0aW9uJDEsXG4gICAgICBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICBub2RlU2l6ZSA9IG51bGw7XG5cbiAgZnVuY3Rpb24gdHJlZShyb290KSB7XG4gICAgdmFyIHQgPSB0cmVlUm9vdChyb290KTtcblxuICAgIC8vIENvbXB1dGUgdGhlIGxheW91dCB1c2luZyBCdWNoaGVpbSBldCBhbC7igJlzIGFsZ29yaXRobS5cbiAgICB0LmVhY2hBZnRlcihmaXJzdFdhbGspLCB0LnBhcmVudC5tID0gLXQuejtcbiAgICB0LmVhY2hCZWZvcmUoc2Vjb25kV2Fsayk7XG5cbiAgICAvLyBJZiBhIGZpeGVkIG5vZGUgc2l6ZSBpcyBzcGVjaWZpZWQsIHNjYWxlIHggYW5kIHkuXG4gICAgaWYgKG5vZGVTaXplKSByb290LmVhY2hCZWZvcmUoc2l6ZU5vZGUpO1xuXG4gICAgLy8gSWYgYSBmaXhlZCB0cmVlIHNpemUgaXMgc3BlY2lmaWVkLCBzY2FsZSB4IGFuZCB5IGJhc2VkIG9uIHRoZSBleHRlbnQuXG4gICAgLy8gQ29tcHV0ZSB0aGUgbGVmdC1tb3N0LCByaWdodC1tb3N0LCBhbmQgZGVwdGgtbW9zdCBub2RlcyBmb3IgZXh0ZW50cy5cbiAgICBlbHNlIHtcbiAgICAgIHZhciBsZWZ0ID0gcm9vdCxcbiAgICAgICAgICByaWdodCA9IHJvb3QsXG4gICAgICAgICAgYm90dG9tID0gcm9vdDtcbiAgICAgIHJvb3QuZWFjaEJlZm9yZShmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIGlmIChub2RlLnggPCBsZWZ0LngpIGxlZnQgPSBub2RlO1xuICAgICAgICBpZiAobm9kZS54ID4gcmlnaHQueCkgcmlnaHQgPSBub2RlO1xuICAgICAgICBpZiAobm9kZS5kZXB0aCA+IGJvdHRvbS5kZXB0aCkgYm90dG9tID0gbm9kZTtcbiAgICAgIH0pO1xuICAgICAgdmFyIHMgPSBsZWZ0ID09PSByaWdodCA/IDEgOiBzZXBhcmF0aW9uKGxlZnQsIHJpZ2h0KSAvIDIsXG4gICAgICAgICAgdHggPSBzIC0gbGVmdC54LFxuICAgICAgICAgIGt4ID0gZHggLyAocmlnaHQueCArIHMgKyB0eCksXG4gICAgICAgICAga3kgPSBkeSAvIChib3R0b20uZGVwdGggfHwgMSk7XG4gICAgICByb290LmVhY2hCZWZvcmUoZnVuY3Rpb24obm9kZSkge1xuICAgICAgICBub2RlLnggPSAobm9kZS54ICsgdHgpICoga3g7XG4gICAgICAgIG5vZGUueSA9IG5vZGUuZGVwdGggKiBreTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgLy8gQ29tcHV0ZXMgYSBwcmVsaW1pbmFyeSB4LWNvb3JkaW5hdGUgZm9yIHYuIEJlZm9yZSB0aGF0LCBGSVJTVCBXQUxLIGlzXG4gIC8vIGFwcGxpZWQgcmVjdXJzaXZlbHkgdG8gdGhlIGNoaWxkcmVuIG9mIHYsIGFzIHdlbGwgYXMgdGhlIGZ1bmN0aW9uXG4gIC8vIEFQUE9SVElPTi4gQWZ0ZXIgc3BhY2luZyBvdXQgdGhlIGNoaWxkcmVuIGJ5IGNhbGxpbmcgRVhFQ1VURSBTSElGVFMsIHRoZVxuICAvLyBub2RlIHYgaXMgcGxhY2VkIHRvIHRoZSBtaWRwb2ludCBvZiBpdHMgb3V0ZXJtb3N0IGNoaWxkcmVuLlxuICBmdW5jdGlvbiBmaXJzdFdhbGsodikge1xuICAgIHZhciBjaGlsZHJlbiA9IHYuY2hpbGRyZW4sXG4gICAgICAgIHNpYmxpbmdzID0gdi5wYXJlbnQuY2hpbGRyZW4sXG4gICAgICAgIHcgPSB2LmkgPyBzaWJsaW5nc1t2LmkgLSAxXSA6IG51bGw7XG4gICAgaWYgKGNoaWxkcmVuKSB7XG4gICAgICBleGVjdXRlU2hpZnRzKHYpO1xuICAgICAgdmFyIG1pZHBvaW50ID0gKGNoaWxkcmVuWzBdLnogKyBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXS56KSAvIDI7XG4gICAgICBpZiAodykge1xuICAgICAgICB2LnogPSB3LnogKyBzZXBhcmF0aW9uKHYuXywgdy5fKTtcbiAgICAgICAgdi5tID0gdi56IC0gbWlkcG9pbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2LnogPSBtaWRwb2ludDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHcpIHtcbiAgICAgIHYueiA9IHcueiArIHNlcGFyYXRpb24odi5fLCB3Ll8pO1xuICAgIH1cbiAgICB2LnBhcmVudC5BID0gYXBwb3J0aW9uKHYsIHcsIHYucGFyZW50LkEgfHwgc2libGluZ3NbMF0pO1xuICB9XG5cbiAgLy8gQ29tcHV0ZXMgYWxsIHJlYWwgeC1jb29yZGluYXRlcyBieSBzdW1taW5nIHVwIHRoZSBtb2RpZmllcnMgcmVjdXJzaXZlbHkuXG4gIGZ1bmN0aW9uIHNlY29uZFdhbGsodikge1xuICAgIHYuXy54ID0gdi56ICsgdi5wYXJlbnQubTtcbiAgICB2Lm0gKz0gdi5wYXJlbnQubTtcbiAgfVxuXG4gIC8vIFRoZSBjb3JlIG9mIHRoZSBhbGdvcml0aG0uIEhlcmUsIGEgbmV3IHN1YnRyZWUgaXMgY29tYmluZWQgd2l0aCB0aGVcbiAgLy8gcHJldmlvdXMgc3VidHJlZXMuIFRocmVhZHMgYXJlIHVzZWQgdG8gdHJhdmVyc2UgdGhlIGluc2lkZSBhbmQgb3V0c2lkZVxuICAvLyBjb250b3VycyBvZiB0aGUgbGVmdCBhbmQgcmlnaHQgc3VidHJlZSB1cCB0byB0aGUgaGlnaGVzdCBjb21tb24gbGV2ZWwuIFRoZVxuICAvLyB2ZXJ0aWNlcyB1c2VkIGZvciB0aGUgdHJhdmVyc2FscyBhcmUgdmkrLCB2aS0sIHZvLSwgYW5kIHZvKywgd2hlcmUgdGhlXG4gIC8vIHN1cGVyc2NyaXB0IG8gbWVhbnMgb3V0c2lkZSBhbmQgaSBtZWFucyBpbnNpZGUsIHRoZSBzdWJzY3JpcHQgLSBtZWFucyBsZWZ0XG4gIC8vIHN1YnRyZWUgYW5kICsgbWVhbnMgcmlnaHQgc3VidHJlZS4gRm9yIHN1bW1pbmcgdXAgdGhlIG1vZGlmaWVycyBhbG9uZyB0aGVcbiAgLy8gY29udG91ciwgd2UgdXNlIHJlc3BlY3RpdmUgdmFyaWFibGVzIHNpKywgc2ktLCBzby0sIGFuZCBzbysuIFdoZW5ldmVyIHR3b1xuICAvLyBub2RlcyBvZiB0aGUgaW5zaWRlIGNvbnRvdXJzIGNvbmZsaWN0LCB3ZSBjb21wdXRlIHRoZSBsZWZ0IG9uZSBvZiB0aGVcbiAgLy8gZ3JlYXRlc3QgdW5jb21tb24gYW5jZXN0b3JzIHVzaW5nIHRoZSBmdW5jdGlvbiBBTkNFU1RPUiBhbmQgY2FsbCBNT1ZFXG4gIC8vIFNVQlRSRUUgdG8gc2hpZnQgdGhlIHN1YnRyZWUgYW5kIHByZXBhcmUgdGhlIHNoaWZ0cyBvZiBzbWFsbGVyIHN1YnRyZWVzLlxuICAvLyBGaW5hbGx5LCB3ZSBhZGQgYSBuZXcgdGhyZWFkIChpZiBuZWNlc3NhcnkpLlxuICBmdW5jdGlvbiBhcHBvcnRpb24odiwgdywgYW5jZXN0b3IpIHtcbiAgICBpZiAodykge1xuICAgICAgdmFyIHZpcCA9IHYsXG4gICAgICAgICAgdm9wID0gdixcbiAgICAgICAgICB2aW0gPSB3LFxuICAgICAgICAgIHZvbSA9IHZpcC5wYXJlbnQuY2hpbGRyZW5bMF0sXG4gICAgICAgICAgc2lwID0gdmlwLm0sXG4gICAgICAgICAgc29wID0gdm9wLm0sXG4gICAgICAgICAgc2ltID0gdmltLm0sXG4gICAgICAgICAgc29tID0gdm9tLm0sXG4gICAgICAgICAgc2hpZnQ7XG4gICAgICB3aGlsZSAodmltID0gbmV4dFJpZ2h0KHZpbSksIHZpcCA9IG5leHRMZWZ0KHZpcCksIHZpbSAmJiB2aXApIHtcbiAgICAgICAgdm9tID0gbmV4dExlZnQodm9tKTtcbiAgICAgICAgdm9wID0gbmV4dFJpZ2h0KHZvcCk7XG4gICAgICAgIHZvcC5hID0gdjtcbiAgICAgICAgc2hpZnQgPSB2aW0ueiArIHNpbSAtIHZpcC56IC0gc2lwICsgc2VwYXJhdGlvbih2aW0uXywgdmlwLl8pO1xuICAgICAgICBpZiAoc2hpZnQgPiAwKSB7XG4gICAgICAgICAgbW92ZVN1YnRyZWUobmV4dEFuY2VzdG9yKHZpbSwgdiwgYW5jZXN0b3IpLCB2LCBzaGlmdCk7XG4gICAgICAgICAgc2lwICs9IHNoaWZ0O1xuICAgICAgICAgIHNvcCArPSBzaGlmdDtcbiAgICAgICAgfVxuICAgICAgICBzaW0gKz0gdmltLm07XG4gICAgICAgIHNpcCArPSB2aXAubTtcbiAgICAgICAgc29tICs9IHZvbS5tO1xuICAgICAgICBzb3AgKz0gdm9wLm07XG4gICAgICB9XG4gICAgICBpZiAodmltICYmICFuZXh0UmlnaHQodm9wKSkge1xuICAgICAgICB2b3AudCA9IHZpbTtcbiAgICAgICAgdm9wLm0gKz0gc2ltIC0gc29wO1xuICAgICAgfVxuICAgICAgaWYgKHZpcCAmJiAhbmV4dExlZnQodm9tKSkge1xuICAgICAgICB2b20udCA9IHZpcDtcbiAgICAgICAgdm9tLm0gKz0gc2lwIC0gc29tO1xuICAgICAgICBhbmNlc3RvciA9IHY7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhbmNlc3RvcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNpemVOb2RlKG5vZGUpIHtcbiAgICBub2RlLnggKj0gZHg7XG4gICAgbm9kZS55ID0gbm9kZS5kZXB0aCAqIGR5O1xuICB9XG5cbiAgdHJlZS5zZXBhcmF0aW9uID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNlcGFyYXRpb24gPSB4LCB0cmVlKSA6IHNlcGFyYXRpb247XG4gIH07XG5cbiAgdHJlZS5zaXplID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG5vZGVTaXplID0gZmFsc2UsIGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIHRyZWUpIDogKG5vZGVTaXplID8gbnVsbCA6IFtkeCwgZHldKTtcbiAgfTtcblxuICB0cmVlLm5vZGVTaXplID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG5vZGVTaXplID0gdHJ1ZSwgZHggPSAreFswXSwgZHkgPSAreFsxXSwgdHJlZSkgOiAobm9kZVNpemUgPyBbZHgsIGR5XSA6IG51bGwpO1xuICB9O1xuXG4gIHJldHVybiB0cmVlO1xufTtcblxudmFyIHRyZWVtYXBTbGljZSA9IGZ1bmN0aW9uKHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgdmFyIG5vZGVzID0gcGFyZW50LmNoaWxkcmVuLFxuICAgICAgbm9kZSxcbiAgICAgIGkgPSAtMSxcbiAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICBrID0gcGFyZW50LnZhbHVlICYmICh5MSAtIHkwKSAvIHBhcmVudC52YWx1ZTtcblxuICB3aGlsZSAoKytpIDwgbikge1xuICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZS54MCA9IHgwLCBub2RlLngxID0geDE7XG4gICAgbm9kZS55MCA9IHkwLCBub2RlLnkxID0geTAgKz0gbm9kZS52YWx1ZSAqIGs7XG4gIH1cbn07XG5cbnZhciBwaGkgPSAoMSArIE1hdGguc3FydCg1KSkgLyAyO1xuXG5mdW5jdGlvbiBzcXVhcmlmeVJhdGlvKHJhdGlvLCBwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciByb3dzID0gW10sXG4gICAgICBub2RlcyA9IHBhcmVudC5jaGlsZHJlbixcbiAgICAgIHJvdyxcbiAgICAgIG5vZGVWYWx1ZSxcbiAgICAgIGkwID0gMCxcbiAgICAgIGkxID0gMCxcbiAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICBkeCwgZHksXG4gICAgICB2YWx1ZSA9IHBhcmVudC52YWx1ZSxcbiAgICAgIHN1bVZhbHVlLFxuICAgICAgbWluVmFsdWUsXG4gICAgICBtYXhWYWx1ZSxcbiAgICAgIG5ld1JhdGlvLFxuICAgICAgbWluUmF0aW8sXG4gICAgICBhbHBoYSxcbiAgICAgIGJldGE7XG5cbiAgd2hpbGUgKGkwIDwgbikge1xuICAgIGR4ID0geDEgLSB4MCwgZHkgPSB5MSAtIHkwO1xuXG4gICAgLy8gRmluZCB0aGUgbmV4dCBub24tZW1wdHkgbm9kZS5cbiAgICBkbyBzdW1WYWx1ZSA9IG5vZGVzW2kxKytdLnZhbHVlOyB3aGlsZSAoIXN1bVZhbHVlICYmIGkxIDwgbik7XG4gICAgbWluVmFsdWUgPSBtYXhWYWx1ZSA9IHN1bVZhbHVlO1xuICAgIGFscGhhID0gTWF0aC5tYXgoZHkgLyBkeCwgZHggLyBkeSkgLyAodmFsdWUgKiByYXRpbyk7XG4gICAgYmV0YSA9IHN1bVZhbHVlICogc3VtVmFsdWUgKiBhbHBoYTtcbiAgICBtaW5SYXRpbyA9IE1hdGgubWF4KG1heFZhbHVlIC8gYmV0YSwgYmV0YSAvIG1pblZhbHVlKTtcblxuICAgIC8vIEtlZXAgYWRkaW5nIG5vZGVzIHdoaWxlIHRoZSBhc3BlY3QgcmF0aW8gbWFpbnRhaW5zIG9yIGltcHJvdmVzLlxuICAgIGZvciAoOyBpMSA8IG47ICsraTEpIHtcbiAgICAgIHN1bVZhbHVlICs9IG5vZGVWYWx1ZSA9IG5vZGVzW2kxXS52YWx1ZTtcbiAgICAgIGlmIChub2RlVmFsdWUgPCBtaW5WYWx1ZSkgbWluVmFsdWUgPSBub2RlVmFsdWU7XG4gICAgICBpZiAobm9kZVZhbHVlID4gbWF4VmFsdWUpIG1heFZhbHVlID0gbm9kZVZhbHVlO1xuICAgICAgYmV0YSA9IHN1bVZhbHVlICogc3VtVmFsdWUgKiBhbHBoYTtcbiAgICAgIG5ld1JhdGlvID0gTWF0aC5tYXgobWF4VmFsdWUgLyBiZXRhLCBiZXRhIC8gbWluVmFsdWUpO1xuICAgICAgaWYgKG5ld1JhdGlvID4gbWluUmF0aW8pIHsgc3VtVmFsdWUgLT0gbm9kZVZhbHVlOyBicmVhazsgfVxuICAgICAgbWluUmF0aW8gPSBuZXdSYXRpbztcbiAgICB9XG5cbiAgICAvLyBQb3NpdGlvbiBhbmQgcmVjb3JkIHRoZSByb3cgb3JpZW50YXRpb24uXG4gICAgcm93cy5wdXNoKHJvdyA9IHt2YWx1ZTogc3VtVmFsdWUsIGRpY2U6IGR4IDwgZHksIGNoaWxkcmVuOiBub2Rlcy5zbGljZShpMCwgaTEpfSk7XG4gICAgaWYgKHJvdy5kaWNlKSB0cmVlbWFwRGljZShyb3csIHgwLCB5MCwgeDEsIHZhbHVlID8geTAgKz0gZHkgKiBzdW1WYWx1ZSAvIHZhbHVlIDogeTEpO1xuICAgIGVsc2UgdHJlZW1hcFNsaWNlKHJvdywgeDAsIHkwLCB2YWx1ZSA/IHgwICs9IGR4ICogc3VtVmFsdWUgLyB2YWx1ZSA6IHgxLCB5MSk7XG4gICAgdmFsdWUgLT0gc3VtVmFsdWUsIGkwID0gaTE7XG4gIH1cblxuICByZXR1cm4gcm93cztcbn1cblxudmFyIHNxdWFyaWZ5ID0gKGZ1bmN0aW9uIGN1c3RvbShyYXRpbykge1xuXG4gIGZ1bmN0aW9uIHNxdWFyaWZ5KHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgICBzcXVhcmlmeVJhdGlvKHJhdGlvLCBwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKTtcbiAgfVxuXG4gIHNxdWFyaWZ5LnJhdGlvID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBjdXN0b20oKHggPSAreCkgPiAxID8geCA6IDEpO1xuICB9O1xuXG4gIHJldHVybiBzcXVhcmlmeTtcbn0pKHBoaSk7XG5cbnZhciBpbmRleCQxID0gZnVuY3Rpb24oKSB7XG4gIHZhciB0aWxlID0gc3F1YXJpZnksXG4gICAgICByb3VuZCA9IGZhbHNlLFxuICAgICAgZHggPSAxLFxuICAgICAgZHkgPSAxLFxuICAgICAgcGFkZGluZ1N0YWNrID0gWzBdLFxuICAgICAgcGFkZGluZ0lubmVyID0gY29uc3RhbnRaZXJvLFxuICAgICAgcGFkZGluZ1RvcCA9IGNvbnN0YW50WmVybyxcbiAgICAgIHBhZGRpbmdSaWdodCA9IGNvbnN0YW50WmVybyxcbiAgICAgIHBhZGRpbmdCb3R0b20gPSBjb25zdGFudFplcm8sXG4gICAgICBwYWRkaW5nTGVmdCA9IGNvbnN0YW50WmVybztcblxuICBmdW5jdGlvbiB0cmVlbWFwKHJvb3QpIHtcbiAgICByb290LngwID1cbiAgICByb290LnkwID0gMDtcbiAgICByb290LngxID0gZHg7XG4gICAgcm9vdC55MSA9IGR5O1xuICAgIHJvb3QuZWFjaEJlZm9yZShwb3NpdGlvbk5vZGUpO1xuICAgIHBhZGRpbmdTdGFjayA9IFswXTtcbiAgICBpZiAocm91bmQpIHJvb3QuZWFjaEJlZm9yZShyb3VuZE5vZGUpO1xuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgZnVuY3Rpb24gcG9zaXRpb25Ob2RlKG5vZGUpIHtcbiAgICB2YXIgcCA9IHBhZGRpbmdTdGFja1tub2RlLmRlcHRoXSxcbiAgICAgICAgeDAgPSBub2RlLngwICsgcCxcbiAgICAgICAgeTAgPSBub2RlLnkwICsgcCxcbiAgICAgICAgeDEgPSBub2RlLngxIC0gcCxcbiAgICAgICAgeTEgPSBub2RlLnkxIC0gcDtcbiAgICBpZiAoeDEgPCB4MCkgeDAgPSB4MSA9ICh4MCArIHgxKSAvIDI7XG4gICAgaWYgKHkxIDwgeTApIHkwID0geTEgPSAoeTAgKyB5MSkgLyAyO1xuICAgIG5vZGUueDAgPSB4MDtcbiAgICBub2RlLnkwID0geTA7XG4gICAgbm9kZS54MSA9IHgxO1xuICAgIG5vZGUueTEgPSB5MTtcbiAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgcCA9IHBhZGRpbmdTdGFja1tub2RlLmRlcHRoICsgMV0gPSBwYWRkaW5nSW5uZXIobm9kZSkgLyAyO1xuICAgICAgeDAgKz0gcGFkZGluZ0xlZnQobm9kZSkgLSBwO1xuICAgICAgeTAgKz0gcGFkZGluZ1RvcChub2RlKSAtIHA7XG4gICAgICB4MSAtPSBwYWRkaW5nUmlnaHQobm9kZSkgLSBwO1xuICAgICAgeTEgLT0gcGFkZGluZ0JvdHRvbShub2RlKSAtIHA7XG4gICAgICBpZiAoeDEgPCB4MCkgeDAgPSB4MSA9ICh4MCArIHgxKSAvIDI7XG4gICAgICBpZiAoeTEgPCB5MCkgeTAgPSB5MSA9ICh5MCArIHkxKSAvIDI7XG4gICAgICB0aWxlKG5vZGUsIHgwLCB5MCwgeDEsIHkxKTtcbiAgICB9XG4gIH1cblxuICB0cmVlbWFwLnJvdW5kID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJvdW5kID0gISF4LCB0cmVlbWFwKSA6IHJvdW5kO1xuICB9O1xuXG4gIHRyZWVtYXAuc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCB0cmVlbWFwKSA6IFtkeCwgZHldO1xuICB9O1xuXG4gIHRyZWVtYXAudGlsZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aWxlID0gcmVxdWlyZWQoeCksIHRyZWVtYXApIDogdGlsZTtcbiAgfTtcblxuICB0cmVlbWFwLnBhZGRpbmcgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0cmVlbWFwLnBhZGRpbmdJbm5lcih4KS5wYWRkaW5nT3V0ZXIoeCkgOiB0cmVlbWFwLnBhZGRpbmdJbm5lcigpO1xuICB9O1xuXG4gIHRyZWVtYXAucGFkZGluZ0lubmVyID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdJbm5lciA9IHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIgPyB4IDogY29uc3RhbnQkNigreCksIHRyZWVtYXApIDogcGFkZGluZ0lubmVyO1xuICB9O1xuXG4gIHRyZWVtYXAucGFkZGluZ091dGVyID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdHJlZW1hcC5wYWRkaW5nVG9wKHgpLnBhZGRpbmdSaWdodCh4KS5wYWRkaW5nQm90dG9tKHgpLnBhZGRpbmdMZWZ0KHgpIDogdHJlZW1hcC5wYWRkaW5nVG9wKCk7XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nVG9wID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdUb3AgPSB0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiID8geCA6IGNvbnN0YW50JDYoK3gpLCB0cmVlbWFwKSA6IHBhZGRpbmdUb3A7XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nUmlnaHQgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ1JpZ2h0ID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiBjb25zdGFudCQ2KCt4KSwgdHJlZW1hcCkgOiBwYWRkaW5nUmlnaHQ7XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nQm90dG9tID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdCb3R0b20gPSB0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiID8geCA6IGNvbnN0YW50JDYoK3gpLCB0cmVlbWFwKSA6IHBhZGRpbmdCb3R0b207XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nTGVmdCA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nTGVmdCA9IHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIgPyB4IDogY29uc3RhbnQkNigreCksIHRyZWVtYXApIDogcGFkZGluZ0xlZnQ7XG4gIH07XG5cbiAgcmV0dXJuIHRyZWVtYXA7XG59O1xuXG52YXIgYmluYXJ5ID0gZnVuY3Rpb24ocGFyZW50LCB4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgbm9kZXMgPSBwYXJlbnQuY2hpbGRyZW4sXG4gICAgICBpLCBuID0gbm9kZXMubGVuZ3RoLFxuICAgICAgc3VtLCBzdW1zID0gbmV3IEFycmF5KG4gKyAxKTtcblxuICBmb3IgKHN1bXNbMF0gPSBzdW0gPSBpID0gMDsgaSA8IG47ICsraSkge1xuICAgIHN1bXNbaSArIDFdID0gc3VtICs9IG5vZGVzW2ldLnZhbHVlO1xuICB9XG5cbiAgcGFydGl0aW9uKDAsIG4sIHBhcmVudC52YWx1ZSwgeDAsIHkwLCB4MSwgeTEpO1xuXG4gIGZ1bmN0aW9uIHBhcnRpdGlvbihpLCBqLCB2YWx1ZSwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgICBpZiAoaSA+PSBqIC0gMSkge1xuICAgICAgdmFyIG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgIG5vZGUueDAgPSB4MCwgbm9kZS55MCA9IHkwO1xuICAgICAgbm9kZS54MSA9IHgxLCBub2RlLnkxID0geTE7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlT2Zmc2V0ID0gc3Vtc1tpXSxcbiAgICAgICAgdmFsdWVUYXJnZXQgPSAodmFsdWUgLyAyKSArIHZhbHVlT2Zmc2V0LFxuICAgICAgICBrID0gaSArIDEsXG4gICAgICAgIGhpID0gaiAtIDE7XG5cbiAgICB3aGlsZSAoayA8IGhpKSB7XG4gICAgICB2YXIgbWlkID0gayArIGhpID4+PiAxO1xuICAgICAgaWYgKHN1bXNbbWlkXSA8IHZhbHVlVGFyZ2V0KSBrID0gbWlkICsgMTtcbiAgICAgIGVsc2UgaGkgPSBtaWQ7XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlTGVmdCA9IHN1bXNba10gLSB2YWx1ZU9mZnNldCxcbiAgICAgICAgdmFsdWVSaWdodCA9IHZhbHVlIC0gdmFsdWVMZWZ0O1xuXG4gICAgaWYgKCh5MSAtIHkwKSA+ICh4MSAtIHgwKSkge1xuICAgICAgdmFyIHlrID0gKHkwICogdmFsdWVSaWdodCArIHkxICogdmFsdWVMZWZ0KSAvIHZhbHVlO1xuICAgICAgcGFydGl0aW9uKGksIGssIHZhbHVlTGVmdCwgeDAsIHkwLCB4MSwgeWspO1xuICAgICAgcGFydGl0aW9uKGssIGosIHZhbHVlUmlnaHQsIHgwLCB5aywgeDEsIHkxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHhrID0gKHgwICogdmFsdWVSaWdodCArIHgxICogdmFsdWVMZWZ0KSAvIHZhbHVlO1xuICAgICAgcGFydGl0aW9uKGksIGssIHZhbHVlTGVmdCwgeDAsIHkwLCB4aywgeTEpO1xuICAgICAgcGFydGl0aW9uKGssIGosIHZhbHVlUmlnaHQsIHhrLCB5MCwgeDEsIHkxKTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBzbGljZURpY2UgPSBmdW5jdGlvbihwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIChwYXJlbnQuZGVwdGggJiAxID8gdHJlZW1hcFNsaWNlIDogdHJlZW1hcERpY2UpKHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpO1xufTtcblxudmFyIHJlc3F1YXJpZnkgPSAoZnVuY3Rpb24gY3VzdG9tKHJhdGlvKSB7XG5cbiAgZnVuY3Rpb24gcmVzcXVhcmlmeShwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgaWYgKChyb3dzID0gcGFyZW50Ll9zcXVhcmlmeSkgJiYgKHJvd3MucmF0aW8gPT09IHJhdGlvKSkge1xuICAgICAgdmFyIHJvd3MsXG4gICAgICAgICAgcm93LFxuICAgICAgICAgIG5vZGVzLFxuICAgICAgICAgIGksXG4gICAgICAgICAgaiA9IC0xLFxuICAgICAgICAgIG4sXG4gICAgICAgICAgbSA9IHJvd3MubGVuZ3RoLFxuICAgICAgICAgIHZhbHVlID0gcGFyZW50LnZhbHVlO1xuXG4gICAgICB3aGlsZSAoKytqIDwgbSkge1xuICAgICAgICByb3cgPSByb3dzW2pdLCBub2RlcyA9IHJvdy5jaGlsZHJlbjtcbiAgICAgICAgZm9yIChpID0gcm93LnZhbHVlID0gMCwgbiA9IG5vZGVzLmxlbmd0aDsgaSA8IG47ICsraSkgcm93LnZhbHVlICs9IG5vZGVzW2ldLnZhbHVlO1xuICAgICAgICBpZiAocm93LmRpY2UpIHRyZWVtYXBEaWNlKHJvdywgeDAsIHkwLCB4MSwgeTAgKz0gKHkxIC0geTApICogcm93LnZhbHVlIC8gdmFsdWUpO1xuICAgICAgICBlbHNlIHRyZWVtYXBTbGljZShyb3csIHgwLCB5MCwgeDAgKz0gKHgxIC0geDApICogcm93LnZhbHVlIC8gdmFsdWUsIHkxKTtcbiAgICAgICAgdmFsdWUgLT0gcm93LnZhbHVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYXJlbnQuX3NxdWFyaWZ5ID0gcm93cyA9IHNxdWFyaWZ5UmF0aW8ocmF0aW8sIHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpO1xuICAgICAgcm93cy5yYXRpbyA9IHJhdGlvO1xuICAgIH1cbiAgfVxuXG4gIHJlc3F1YXJpZnkucmF0aW8gPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGN1c3RvbSgoeCA9ICt4KSA+IDEgPyB4IDogMSk7XG4gIH07XG5cbiAgcmV0dXJuIHJlc3F1YXJpZnk7XG59KShwaGkpO1xuXG52YXIgY2VudGVyJDEgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHZhciBub2RlcztcblxuICBpZiAoeCA9PSBudWxsKSB4ID0gMDtcbiAgaWYgKHkgPT0gbnVsbCkgeSA9IDA7XG5cbiAgZnVuY3Rpb24gZm9yY2UoKSB7XG4gICAgdmFyIGksXG4gICAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIHN4ID0gMCxcbiAgICAgICAgc3kgPSAwO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZSA9IG5vZGVzW2ldLCBzeCArPSBub2RlLngsIHN5ICs9IG5vZGUueTtcbiAgICB9XG5cbiAgICBmb3IgKHN4ID0gc3ggLyBuIC0geCwgc3kgPSBzeSAvIG4gLSB5LCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZSA9IG5vZGVzW2ldLCBub2RlLnggLT0gc3gsIG5vZGUueSAtPSBzeTtcbiAgICB9XG4gIH1cblxuICBmb3JjZS5pbml0aWFsaXplID0gZnVuY3Rpb24oXykge1xuICAgIG5vZGVzID0gXztcbiAgfTtcblxuICBmb3JjZS54ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSArXywgZm9yY2UpIDogeDtcbiAgfTtcblxuICBmb3JjZS55ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkgPSArXywgZm9yY2UpIDogeTtcbiAgfTtcblxuICByZXR1cm4gZm9yY2U7XG59O1xuXG52YXIgY29uc3RhbnQkNyA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxudmFyIGppZ2dsZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gKE1hdGgucmFuZG9tKCkgLSAwLjUpICogMWUtNjtcbn07XG5cbmZ1bmN0aW9uIHgkMShkKSB7XG4gIHJldHVybiBkLnggKyBkLnZ4O1xufVxuXG5mdW5jdGlvbiB5JDEoZCkge1xuICByZXR1cm4gZC55ICsgZC52eTtcbn1cblxudmFyIGNvbGxpZGUgPSBmdW5jdGlvbihyYWRpdXMpIHtcbiAgdmFyIG5vZGVzLFxuICAgICAgcmFkaWksXG4gICAgICBzdHJlbmd0aCA9IDEsXG4gICAgICBpdGVyYXRpb25zID0gMTtcblxuICBpZiAodHlwZW9mIHJhZGl1cyAhPT0gXCJmdW5jdGlvblwiKSByYWRpdXMgPSBjb25zdGFudCQ3KHJhZGl1cyA9PSBudWxsID8gMSA6ICtyYWRpdXMpO1xuXG4gIGZ1bmN0aW9uIGZvcmNlKCkge1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLFxuICAgICAgICB0cmVlLFxuICAgICAgICBub2RlLFxuICAgICAgICB4aSxcbiAgICAgICAgeWksXG4gICAgICAgIHJpLFxuICAgICAgICByaTI7XG5cbiAgICBmb3IgKHZhciBrID0gMDsgayA8IGl0ZXJhdGlvbnM7ICsraykge1xuICAgICAgdHJlZSA9IHF1YWR0cmVlKG5vZGVzLCB4JDEsIHkkMSkudmlzaXRBZnRlcihwcmVwYXJlKTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICByaSA9IHJhZGlpW25vZGUuaW5kZXhdLCByaTIgPSByaSAqIHJpO1xuICAgICAgICB4aSA9IG5vZGUueCArIG5vZGUudng7XG4gICAgICAgIHlpID0gbm9kZS55ICsgbm9kZS52eTtcbiAgICAgICAgdHJlZS52aXNpdChhcHBseSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYXBwbHkocXVhZCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgICAgIHZhciBkYXRhID0gcXVhZC5kYXRhLCByaiA9IHF1YWQuciwgciA9IHJpICsgcmo7XG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBpZiAoZGF0YS5pbmRleCA+IG5vZGUuaW5kZXgpIHtcbiAgICAgICAgICB2YXIgeCA9IHhpIC0gZGF0YS54IC0gZGF0YS52eCxcbiAgICAgICAgICAgICAgeSA9IHlpIC0gZGF0YS55IC0gZGF0YS52eSxcbiAgICAgICAgICAgICAgbCA9IHggKiB4ICsgeSAqIHk7XG4gICAgICAgICAgaWYgKGwgPCByICogcikge1xuICAgICAgICAgICAgaWYgKHggPT09IDApIHggPSBqaWdnbGUoKSwgbCArPSB4ICogeDtcbiAgICAgICAgICAgIGlmICh5ID09PSAwKSB5ID0gamlnZ2xlKCksIGwgKz0geSAqIHk7XG4gICAgICAgICAgICBsID0gKHIgLSAobCA9IE1hdGguc3FydChsKSkpIC8gbCAqIHN0cmVuZ3RoO1xuICAgICAgICAgICAgbm9kZS52eCArPSAoeCAqPSBsKSAqIChyID0gKHJqICo9IHJqKSAvIChyaTIgKyByaikpO1xuICAgICAgICAgICAgbm9kZS52eSArPSAoeSAqPSBsKSAqIHI7XG4gICAgICAgICAgICBkYXRhLnZ4IC09IHggKiAociA9IDEgLSByKTtcbiAgICAgICAgICAgIGRhdGEudnkgLT0geSAqIHI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB4MCA+IHhpICsgciB8fCB4MSA8IHhpIC0gciB8fCB5MCA+IHlpICsgciB8fCB5MSA8IHlpIC0gcjtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBwcmVwYXJlKHF1YWQpIHtcbiAgICBpZiAocXVhZC5kYXRhKSByZXR1cm4gcXVhZC5yID0gcmFkaWlbcXVhZC5kYXRhLmluZGV4XTtcbiAgICBmb3IgKHZhciBpID0gcXVhZC5yID0gMDsgaSA8IDQ7ICsraSkge1xuICAgICAgaWYgKHF1YWRbaV0gJiYgcXVhZFtpXS5yID4gcXVhZC5yKSB7XG4gICAgICAgIHF1YWQuciA9IHF1YWRbaV0ucjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplKCkge1xuICAgIGlmICghbm9kZXMpIHJldHVybjtcbiAgICB2YXIgaSwgbiA9IG5vZGVzLmxlbmd0aCwgbm9kZTtcbiAgICByYWRpaSA9IG5ldyBBcnJheShuKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBub2RlID0gbm9kZXNbaV0sIHJhZGlpW25vZGUuaW5kZXhdID0gK3JhZGl1cyhub2RlLCBpLCBub2Rlcyk7XG4gIH1cblxuICBmb3JjZS5pbml0aWFsaXplID0gZnVuY3Rpb24oXykge1xuICAgIG5vZGVzID0gXztcbiAgICBpbml0aWFsaXplKCk7XG4gIH07XG5cbiAgZm9yY2UuaXRlcmF0aW9ucyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChpdGVyYXRpb25zID0gK18sIGZvcmNlKSA6IGl0ZXJhdGlvbnM7XG4gIH07XG5cbiAgZm9yY2Uuc3RyZW5ndGggPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc3RyZW5ndGggPSArXywgZm9yY2UpIDogc3RyZW5ndGg7XG4gIH07XG5cbiAgZm9yY2UucmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxpemUoKSwgZm9yY2UpIDogcmFkaXVzO1xuICB9O1xuXG4gIHJldHVybiBmb3JjZTtcbn07XG5cbmZ1bmN0aW9uIGluZGV4JDIoZCkge1xuICByZXR1cm4gZC5pbmRleDtcbn1cblxuZnVuY3Rpb24gZmluZChub2RlQnlJZCwgbm9kZUlkKSB7XG4gIHZhciBub2RlID0gbm9kZUJ5SWQuZ2V0KG5vZGVJZCk7XG4gIGlmICghbm9kZSkgdGhyb3cgbmV3IEVycm9yKFwibWlzc2luZzogXCIgKyBub2RlSWQpO1xuICByZXR1cm4gbm9kZTtcbn1cblxudmFyIGxpbmsgPSBmdW5jdGlvbihsaW5rcykge1xuICB2YXIgaWQgPSBpbmRleCQyLFxuICAgICAgc3RyZW5ndGggPSBkZWZhdWx0U3RyZW5ndGgsXG4gICAgICBzdHJlbmd0aHMsXG4gICAgICBkaXN0YW5jZSA9IGNvbnN0YW50JDcoMzApLFxuICAgICAgZGlzdGFuY2VzLFxuICAgICAgbm9kZXMsXG4gICAgICBjb3VudCxcbiAgICAgIGJpYXMsXG4gICAgICBpdGVyYXRpb25zID0gMTtcblxuICBpZiAobGlua3MgPT0gbnVsbCkgbGlua3MgPSBbXTtcblxuICBmdW5jdGlvbiBkZWZhdWx0U3RyZW5ndGgobGluaykge1xuICAgIHJldHVybiAxIC8gTWF0aC5taW4oY291bnRbbGluay5zb3VyY2UuaW5kZXhdLCBjb3VudFtsaW5rLnRhcmdldC5pbmRleF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9yY2UoYWxwaGEpIHtcbiAgICBmb3IgKHZhciBrID0gMCwgbiA9IGxpbmtzLmxlbmd0aDsgayA8IGl0ZXJhdGlvbnM7ICsraykge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxpbmssIHNvdXJjZSwgdGFyZ2V0LCB4LCB5LCBsLCBiOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGxpbmsgPSBsaW5rc1tpXSwgc291cmNlID0gbGluay5zb3VyY2UsIHRhcmdldCA9IGxpbmsudGFyZ2V0O1xuICAgICAgICB4ID0gdGFyZ2V0LnggKyB0YXJnZXQudnggLSBzb3VyY2UueCAtIHNvdXJjZS52eCB8fCBqaWdnbGUoKTtcbiAgICAgICAgeSA9IHRhcmdldC55ICsgdGFyZ2V0LnZ5IC0gc291cmNlLnkgLSBzb3VyY2UudnkgfHwgamlnZ2xlKCk7XG4gICAgICAgIGwgPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7XG4gICAgICAgIGwgPSAobCAtIGRpc3RhbmNlc1tpXSkgLyBsICogYWxwaGEgKiBzdHJlbmd0aHNbaV07XG4gICAgICAgIHggKj0gbCwgeSAqPSBsO1xuICAgICAgICB0YXJnZXQudnggLT0geCAqIChiID0gYmlhc1tpXSk7XG4gICAgICAgIHRhcmdldC52eSAtPSB5ICogYjtcbiAgICAgICAgc291cmNlLnZ4ICs9IHggKiAoYiA9IDEgLSBiKTtcbiAgICAgICAgc291cmNlLnZ5ICs9IHkgKiBiO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuXG4gICAgdmFyIGksXG4gICAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICAgIG0gPSBsaW5rcy5sZW5ndGgsXG4gICAgICAgIG5vZGVCeUlkID0gbWFwJDEobm9kZXMsIGlkKSxcbiAgICAgICAgbGluaztcblxuICAgIGZvciAoaSA9IDAsIGNvdW50ID0gbmV3IEFycmF5KG4pOyBpIDwgbTsgKytpKSB7XG4gICAgICBsaW5rID0gbGlua3NbaV0sIGxpbmsuaW5kZXggPSBpO1xuICAgICAgaWYgKHR5cGVvZiBsaW5rLnNvdXJjZSAhPT0gXCJvYmplY3RcIikgbGluay5zb3VyY2UgPSBmaW5kKG5vZGVCeUlkLCBsaW5rLnNvdXJjZSk7XG4gICAgICBpZiAodHlwZW9mIGxpbmsudGFyZ2V0ICE9PSBcIm9iamVjdFwiKSBsaW5rLnRhcmdldCA9IGZpbmQobm9kZUJ5SWQsIGxpbmsudGFyZ2V0KTtcbiAgICAgIGNvdW50W2xpbmsuc291cmNlLmluZGV4XSA9IChjb3VudFtsaW5rLnNvdXJjZS5pbmRleF0gfHwgMCkgKyAxO1xuICAgICAgY291bnRbbGluay50YXJnZXQuaW5kZXhdID0gKGNvdW50W2xpbmsudGFyZ2V0LmluZGV4XSB8fCAwKSArIDE7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMCwgYmlhcyA9IG5ldyBBcnJheShtKTsgaSA8IG07ICsraSkge1xuICAgICAgbGluayA9IGxpbmtzW2ldLCBiaWFzW2ldID0gY291bnRbbGluay5zb3VyY2UuaW5kZXhdIC8gKGNvdW50W2xpbmsuc291cmNlLmluZGV4XSArIGNvdW50W2xpbmsudGFyZ2V0LmluZGV4XSk7XG4gICAgfVxuXG4gICAgc3RyZW5ndGhzID0gbmV3IEFycmF5KG0pLCBpbml0aWFsaXplU3RyZW5ndGgoKTtcbiAgICBkaXN0YW5jZXMgPSBuZXcgQXJyYXkobSksIGluaXRpYWxpemVEaXN0YW5jZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5pdGlhbGl6ZVN0cmVuZ3RoKCkge1xuICAgIGlmICghbm9kZXMpIHJldHVybjtcblxuICAgIGZvciAodmFyIGkgPSAwLCBuID0gbGlua3MubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICBzdHJlbmd0aHNbaV0gPSArc3RyZW5ndGgobGlua3NbaV0sIGksIGxpbmtzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplRGlzdGFuY2UoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBsaW5rcy5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICAgIGRpc3RhbmNlc1tpXSA9ICtkaXN0YW5jZShsaW5rc1tpXSwgaSwgbGlua3MpO1xuICAgIH1cbiAgfVxuXG4gIGZvcmNlLmluaXRpYWxpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgbm9kZXMgPSBfO1xuICAgIGluaXRpYWxpemUoKTtcbiAgfTtcblxuICBmb3JjZS5saW5rcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChsaW5rcyA9IF8sIGluaXRpYWxpemUoKSwgZm9yY2UpIDogbGlua3M7XG4gIH07XG5cbiAgZm9yY2UuaWQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaWQgPSBfLCBmb3JjZSkgOiBpZDtcbiAgfTtcblxuICBmb3JjZS5pdGVyYXRpb25zID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGl0ZXJhdGlvbnMgPSArXywgZm9yY2UpIDogaXRlcmF0aW9ucztcbiAgfTtcblxuICBmb3JjZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdHJlbmd0aCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxpemVTdHJlbmd0aCgpLCBmb3JjZSkgOiBzdHJlbmd0aDtcbiAgfTtcblxuICBmb3JjZS5kaXN0YW5jZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkaXN0YW5jZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxpemVEaXN0YW5jZSgpLCBmb3JjZSkgOiBkaXN0YW5jZTtcbiAgfTtcblxuICByZXR1cm4gZm9yY2U7XG59O1xuXG5mdW5jdGlvbiB4JDIoZCkge1xuICByZXR1cm4gZC54O1xufVxuXG5mdW5jdGlvbiB5JDIoZCkge1xuICByZXR1cm4gZC55O1xufVxuXG52YXIgaW5pdGlhbFJhZGl1cyA9IDEwO1xudmFyIGluaXRpYWxBbmdsZSA9IE1hdGguUEkgKiAoMyAtIE1hdGguc3FydCg1KSk7XG5cbnZhciBzaW11bGF0aW9uID0gZnVuY3Rpb24obm9kZXMpIHtcbiAgdmFyIHNpbXVsYXRpb24sXG4gICAgICBhbHBoYSA9IDEsXG4gICAgICBhbHBoYU1pbiA9IDAuMDAxLFxuICAgICAgYWxwaGFEZWNheSA9IDEgLSBNYXRoLnBvdyhhbHBoYU1pbiwgMSAvIDMwMCksXG4gICAgICBhbHBoYVRhcmdldCA9IDAsXG4gICAgICB2ZWxvY2l0eURlY2F5ID0gMC42LFxuICAgICAgZm9yY2VzID0gbWFwJDEoKSxcbiAgICAgIHN0ZXBwZXIgPSB0aW1lcihzdGVwKSxcbiAgICAgIGV2ZW50ID0gZGlzcGF0Y2goXCJ0aWNrXCIsIFwiZW5kXCIpO1xuXG4gIGlmIChub2RlcyA9PSBudWxsKSBub2RlcyA9IFtdO1xuXG4gIGZ1bmN0aW9uIHN0ZXAoKSB7XG4gICAgdGljaygpO1xuICAgIGV2ZW50LmNhbGwoXCJ0aWNrXCIsIHNpbXVsYXRpb24pO1xuICAgIGlmIChhbHBoYSA8IGFscGhhTWluKSB7XG4gICAgICBzdGVwcGVyLnN0b3AoKTtcbiAgICAgIGV2ZW50LmNhbGwoXCJlbmRcIiwgc2ltdWxhdGlvbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdGljaygpIHtcbiAgICB2YXIgaSwgbiA9IG5vZGVzLmxlbmd0aCwgbm9kZTtcblxuICAgIGFscGhhICs9IChhbHBoYVRhcmdldCAtIGFscGhhKSAqIGFscGhhRGVjYXk7XG5cbiAgICBmb3JjZXMuZWFjaChmdW5jdGlvbihmb3JjZSkge1xuICAgICAgZm9yY2UoYWxwaGEpO1xuICAgIH0pO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgaWYgKG5vZGUuZnggPT0gbnVsbCkgbm9kZS54ICs9IG5vZGUudnggKj0gdmVsb2NpdHlEZWNheTtcbiAgICAgIGVsc2Ugbm9kZS54ID0gbm9kZS5meCwgbm9kZS52eCA9IDA7XG4gICAgICBpZiAobm9kZS5meSA9PSBudWxsKSBub2RlLnkgKz0gbm9kZS52eSAqPSB2ZWxvY2l0eURlY2F5O1xuICAgICAgZWxzZSBub2RlLnkgPSBub2RlLmZ5LCBub2RlLnZ5ID0gMDtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplTm9kZXMoKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBub2Rlcy5sZW5ndGgsIG5vZGU7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZS5pbmRleCA9IGk7XG4gICAgICBpZiAoaXNOYU4obm9kZS54KSB8fCBpc05hTihub2RlLnkpKSB7XG4gICAgICAgIHZhciByYWRpdXMgPSBpbml0aWFsUmFkaXVzICogTWF0aC5zcXJ0KGkpLCBhbmdsZSA9IGkgKiBpbml0aWFsQW5nbGU7XG4gICAgICAgIG5vZGUueCA9IHJhZGl1cyAqIE1hdGguY29zKGFuZ2xlKTtcbiAgICAgICAgbm9kZS55ID0gcmFkaXVzICogTWF0aC5zaW4oYW5nbGUpO1xuICAgICAgfVxuICAgICAgaWYgKGlzTmFOKG5vZGUudngpIHx8IGlzTmFOKG5vZGUudnkpKSB7XG4gICAgICAgIG5vZGUudnggPSBub2RlLnZ5ID0gMDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplRm9yY2UoZm9yY2UpIHtcbiAgICBpZiAoZm9yY2UuaW5pdGlhbGl6ZSkgZm9yY2UuaW5pdGlhbGl6ZShub2Rlcyk7XG4gICAgcmV0dXJuIGZvcmNlO1xuICB9XG5cbiAgaW5pdGlhbGl6ZU5vZGVzKCk7XG5cbiAgcmV0dXJuIHNpbXVsYXRpb24gPSB7XG4gICAgdGljazogdGljayxcblxuICAgIHJlc3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHN0ZXBwZXIucmVzdGFydChzdGVwKSwgc2ltdWxhdGlvbjtcbiAgICB9LFxuXG4gICAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gc3RlcHBlci5zdG9wKCksIHNpbXVsYXRpb247XG4gICAgfSxcblxuICAgIG5vZGVzOiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlcyA9IF8sIGluaXRpYWxpemVOb2RlcygpLCBmb3JjZXMuZWFjaChpbml0aWFsaXplRm9yY2UpLCBzaW11bGF0aW9uKSA6IG5vZGVzO1xuICAgIH0sXG5cbiAgICBhbHBoYTogZnVuY3Rpb24oXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoYWxwaGEgPSArXywgc2ltdWxhdGlvbikgOiBhbHBoYTtcbiAgICB9LFxuXG4gICAgYWxwaGFNaW46IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFscGhhTWluID0gK18sIHNpbXVsYXRpb24pIDogYWxwaGFNaW47XG4gICAgfSxcblxuICAgIGFscGhhRGVjYXk6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFscGhhRGVjYXkgPSArXywgc2ltdWxhdGlvbikgOiArYWxwaGFEZWNheTtcbiAgICB9LFxuXG4gICAgYWxwaGFUYXJnZXQ6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFscGhhVGFyZ2V0ID0gK18sIHNpbXVsYXRpb24pIDogYWxwaGFUYXJnZXQ7XG4gICAgfSxcblxuICAgIHZlbG9jaXR5RGVjYXk6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHZlbG9jaXR5RGVjYXkgPSAxIC0gXywgc2ltdWxhdGlvbikgOiAxIC0gdmVsb2NpdHlEZWNheTtcbiAgICB9LFxuXG4gICAgZm9yY2U6IGZ1bmN0aW9uKG5hbWUsIF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMSA/ICgoXyA9PSBudWxsID8gZm9yY2VzLnJlbW92ZShuYW1lKSA6IGZvcmNlcy5zZXQobmFtZSwgaW5pdGlhbGl6ZUZvcmNlKF8pKSksIHNpbXVsYXRpb24pIDogZm9yY2VzLmdldChuYW1lKTtcbiAgICB9LFxuXG4gICAgZmluZDogZnVuY3Rpb24oeCwgeSwgcmFkaXVzKSB7XG4gICAgICB2YXIgaSA9IDAsXG4gICAgICAgICAgbiA9IG5vZGVzLmxlbmd0aCxcbiAgICAgICAgICBkeCxcbiAgICAgICAgICBkeSxcbiAgICAgICAgICBkMixcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIGNsb3Nlc3Q7XG5cbiAgICAgIGlmIChyYWRpdXMgPT0gbnVsbCkgcmFkaXVzID0gSW5maW5pdHk7XG4gICAgICBlbHNlIHJhZGl1cyAqPSByYWRpdXM7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICBkeCA9IHggLSBub2RlLng7XG4gICAgICAgIGR5ID0geSAtIG5vZGUueTtcbiAgICAgICAgZDIgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgICAgaWYgKGQyIDwgcmFkaXVzKSBjbG9zZXN0ID0gbm9kZSwgcmFkaXVzID0gZDI7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjbG9zZXN0O1xuICAgIH0sXG5cbiAgICBvbjogZnVuY3Rpb24obmFtZSwgXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gKGV2ZW50Lm9uKG5hbWUsIF8pLCBzaW11bGF0aW9uKSA6IGV2ZW50Lm9uKG5hbWUpO1xuICAgIH1cbiAgfTtcbn07XG5cbnZhciBtYW55Qm9keSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZXMsXG4gICAgICBub2RlLFxuICAgICAgYWxwaGEsXG4gICAgICBzdHJlbmd0aCA9IGNvbnN0YW50JDcoLTMwKSxcbiAgICAgIHN0cmVuZ3RocyxcbiAgICAgIGRpc3RhbmNlTWluMiA9IDEsXG4gICAgICBkaXN0YW5jZU1heDIgPSBJbmZpbml0eSxcbiAgICAgIHRoZXRhMiA9IDAuODE7XG5cbiAgZnVuY3Rpb24gZm9yY2UoXykge1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLCB0cmVlID0gcXVhZHRyZWUobm9kZXMsIHgkMiwgeSQyKS52aXNpdEFmdGVyKGFjY3VtdWxhdGUpO1xuICAgIGZvciAoYWxwaGEgPSBfLCBpID0gMDsgaSA8IG47ICsraSkgbm9kZSA9IG5vZGVzW2ldLCB0cmVlLnZpc2l0KGFwcGx5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLCBub2RlO1xuICAgIHN0cmVuZ3RocyA9IG5ldyBBcnJheShuKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBub2RlID0gbm9kZXNbaV0sIHN0cmVuZ3Roc1tub2RlLmluZGV4XSA9ICtzdHJlbmd0aChub2RlLCBpLCBub2Rlcyk7XG4gIH1cblxuICBmdW5jdGlvbiBhY2N1bXVsYXRlKHF1YWQpIHtcbiAgICB2YXIgc3RyZW5ndGggPSAwLCBxLCBjLCB4JCQxLCB5JCQxLCBpO1xuXG4gICAgLy8gRm9yIGludGVybmFsIG5vZGVzLCBhY2N1bXVsYXRlIGZvcmNlcyBmcm9tIGNoaWxkIHF1YWRyYW50cy5cbiAgICBpZiAocXVhZC5sZW5ndGgpIHtcbiAgICAgIGZvciAoeCQkMSA9IHkkJDEgPSBpID0gMDsgaSA8IDQ7ICsraSkge1xuICAgICAgICBpZiAoKHEgPSBxdWFkW2ldKSAmJiAoYyA9IHEudmFsdWUpKSB7XG4gICAgICAgICAgc3RyZW5ndGggKz0gYywgeCQkMSArPSBjICogcS54LCB5JCQxICs9IGMgKiBxLnk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHF1YWQueCA9IHgkJDEgLyBzdHJlbmd0aDtcbiAgICAgIHF1YWQueSA9IHkkJDEgLyBzdHJlbmd0aDtcbiAgICB9XG5cbiAgICAvLyBGb3IgbGVhZiBub2RlcywgYWNjdW11bGF0ZSBmb3JjZXMgZnJvbSBjb2luY2lkZW50IHF1YWRyYW50cy5cbiAgICBlbHNlIHtcbiAgICAgIHEgPSBxdWFkO1xuICAgICAgcS54ID0gcS5kYXRhLng7XG4gICAgICBxLnkgPSBxLmRhdGEueTtcbiAgICAgIGRvIHN0cmVuZ3RoICs9IHN0cmVuZ3Roc1txLmRhdGEuaW5kZXhdO1xuICAgICAgd2hpbGUgKHEgPSBxLm5leHQpO1xuICAgIH1cblxuICAgIHF1YWQudmFsdWUgPSBzdHJlbmd0aDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGx5KHF1YWQsIHgxLCBfLCB4Mikge1xuICAgIGlmICghcXVhZC52YWx1ZSkgcmV0dXJuIHRydWU7XG5cbiAgICB2YXIgeCQkMSA9IHF1YWQueCAtIG5vZGUueCxcbiAgICAgICAgeSQkMSA9IHF1YWQueSAtIG5vZGUueSxcbiAgICAgICAgdyA9IHgyIC0geDEsXG4gICAgICAgIGwgPSB4JCQxICogeCQkMSArIHkkJDEgKiB5JCQxO1xuXG4gICAgLy8gQXBwbHkgdGhlIEJhcm5lcy1IdXQgYXBwcm94aW1hdGlvbiBpZiBwb3NzaWJsZS5cbiAgICAvLyBMaW1pdCBmb3JjZXMgZm9yIHZlcnkgY2xvc2Ugbm9kZXM7IHJhbmRvbWl6ZSBkaXJlY3Rpb24gaWYgY29pbmNpZGVudC5cbiAgICBpZiAodyAqIHcgLyB0aGV0YTIgPCBsKSB7XG4gICAgICBpZiAobCA8IGRpc3RhbmNlTWF4Mikge1xuICAgICAgICBpZiAoeCQkMSA9PT0gMCkgeCQkMSA9IGppZ2dsZSgpLCBsICs9IHgkJDEgKiB4JCQxO1xuICAgICAgICBpZiAoeSQkMSA9PT0gMCkgeSQkMSA9IGppZ2dsZSgpLCBsICs9IHkkJDEgKiB5JCQxO1xuICAgICAgICBpZiAobCA8IGRpc3RhbmNlTWluMikgbCA9IE1hdGguc3FydChkaXN0YW5jZU1pbjIgKiBsKTtcbiAgICAgICAgbm9kZS52eCArPSB4JCQxICogcXVhZC52YWx1ZSAqIGFscGhhIC8gbDtcbiAgICAgICAgbm9kZS52eSArPSB5JCQxICogcXVhZC52YWx1ZSAqIGFscGhhIC8gbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIE90aGVyd2lzZSwgcHJvY2VzcyBwb2ludHMgZGlyZWN0bHkuXG4gICAgZWxzZSBpZiAocXVhZC5sZW5ndGggfHwgbCA+PSBkaXN0YW5jZU1heDIpIHJldHVybjtcblxuICAgIC8vIExpbWl0IGZvcmNlcyBmb3IgdmVyeSBjbG9zZSBub2RlczsgcmFuZG9taXplIGRpcmVjdGlvbiBpZiBjb2luY2lkZW50LlxuICAgIGlmIChxdWFkLmRhdGEgIT09IG5vZGUgfHwgcXVhZC5uZXh0KSB7XG4gICAgICBpZiAoeCQkMSA9PT0gMCkgeCQkMSA9IGppZ2dsZSgpLCBsICs9IHgkJDEgKiB4JCQxO1xuICAgICAgaWYgKHkkJDEgPT09IDApIHkkJDEgPSBqaWdnbGUoKSwgbCArPSB5JCQxICogeSQkMTtcbiAgICAgIGlmIChsIDwgZGlzdGFuY2VNaW4yKSBsID0gTWF0aC5zcXJ0KGRpc3RhbmNlTWluMiAqIGwpO1xuICAgIH1cblxuICAgIGRvIGlmIChxdWFkLmRhdGEgIT09IG5vZGUpIHtcbiAgICAgIHcgPSBzdHJlbmd0aHNbcXVhZC5kYXRhLmluZGV4XSAqIGFscGhhIC8gbDtcbiAgICAgIG5vZGUudnggKz0geCQkMSAqIHc7XG4gICAgICBub2RlLnZ5ICs9IHkkJDEgKiB3O1xuICAgIH0gd2hpbGUgKHF1YWQgPSBxdWFkLm5leHQpO1xuICB9XG5cbiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBub2RlcyA9IF87XG4gICAgaW5pdGlhbGl6ZSgpO1xuICB9O1xuXG4gIGZvcmNlLnN0cmVuZ3RoID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3RoID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ3KCtfKSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiBzdHJlbmd0aDtcbiAgfTtcblxuICBmb3JjZS5kaXN0YW5jZU1pbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkaXN0YW5jZU1pbjIgPSBfICogXywgZm9yY2UpIDogTWF0aC5zcXJ0KGRpc3RhbmNlTWluMik7XG4gIH07XG5cbiAgZm9yY2UuZGlzdGFuY2VNYXggPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZGlzdGFuY2VNYXgyID0gXyAqIF8sIGZvcmNlKSA6IE1hdGguc3FydChkaXN0YW5jZU1heDIpO1xuICB9O1xuXG4gIGZvcmNlLnRoZXRhID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRoZXRhMiA9IF8gKiBfLCBmb3JjZSkgOiBNYXRoLnNxcnQodGhldGEyKTtcbiAgfTtcblxuICByZXR1cm4gZm9yY2U7XG59O1xuXG52YXIgeCQzID0gZnVuY3Rpb24oeCkge1xuICB2YXIgc3RyZW5ndGggPSBjb25zdGFudCQ3KDAuMSksXG4gICAgICBub2RlcyxcbiAgICAgIHN0cmVuZ3RocyxcbiAgICAgIHh6O1xuXG4gIGlmICh0eXBlb2YgeCAhPT0gXCJmdW5jdGlvblwiKSB4ID0gY29uc3RhbnQkNyh4ID09IG51bGwgPyAwIDogK3gpO1xuXG4gIGZ1bmN0aW9uIGZvcmNlKGFscGhhKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBub2Rlcy5sZW5ndGgsIG5vZGU7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZS52eCArPSAoeHpbaV0gLSBub2RlLngpICogc3RyZW5ndGhzW2ldICogYWxwaGE7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpIHtcbiAgICBpZiAoIW5vZGVzKSByZXR1cm47XG4gICAgdmFyIGksIG4gPSBub2Rlcy5sZW5ndGg7XG4gICAgc3RyZW5ndGhzID0gbmV3IEFycmF5KG4pO1xuICAgIHh6ID0gbmV3IEFycmF5KG4pO1xuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIHN0cmVuZ3Roc1tpXSA9IGlzTmFOKHh6W2ldID0gK3gobm9kZXNbaV0sIGksIG5vZGVzKSkgPyAwIDogK3N0cmVuZ3RoKG5vZGVzW2ldLCBpLCBub2Rlcyk7XG4gICAgfVxuICB9XG5cbiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBub2RlcyA9IF87XG4gICAgaW5pdGlhbGl6ZSgpO1xuICB9O1xuXG4gIGZvcmNlLnN0cmVuZ3RoID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3RoID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ3KCtfKSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiBzdHJlbmd0aDtcbiAgfTtcblxuICBmb3JjZS54ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDcoK18pLCBpbml0aWFsaXplKCksIGZvcmNlKSA6IHg7XG4gIH07XG5cbiAgcmV0dXJuIGZvcmNlO1xufTtcblxudmFyIHkkMyA9IGZ1bmN0aW9uKHkpIHtcbiAgdmFyIHN0cmVuZ3RoID0gY29uc3RhbnQkNygwLjEpLFxuICAgICAgbm9kZXMsXG4gICAgICBzdHJlbmd0aHMsXG4gICAgICB5ejtcblxuICBpZiAodHlwZW9mIHkgIT09IFwiZnVuY3Rpb25cIikgeSA9IGNvbnN0YW50JDcoeSA9PSBudWxsID8gMCA6ICt5KTtcblxuICBmdW5jdGlvbiBmb3JjZShhbHBoYSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gbm9kZXMubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7XG4gICAgICBub2RlID0gbm9kZXNbaV0sIG5vZGUudnkgKz0gKHl6W2ldIC0gbm9kZS55KSAqIHN0cmVuZ3Roc1tpXSAqIGFscGhhO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoO1xuICAgIHN0cmVuZ3RocyA9IG5ldyBBcnJheShuKTtcbiAgICB5eiA9IG5ldyBBcnJheShuKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBzdHJlbmd0aHNbaV0gPSBpc05hTih5eltpXSA9ICt5KG5vZGVzW2ldLCBpLCBub2RlcykpID8gMCA6ICtzdHJlbmd0aChub2Rlc1tpXSwgaSwgbm9kZXMpO1xuICAgIH1cbiAgfVxuXG4gIGZvcmNlLmluaXRpYWxpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgbm9kZXMgPSBfO1xuICAgIGluaXRpYWxpemUoKTtcbiAgfTtcblxuICBmb3JjZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdHJlbmd0aCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNygrXyksIGluaXRpYWxpemUoKSwgZm9yY2UpIDogc3RyZW5ndGg7XG4gIH07XG5cbiAgZm9yY2UueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5ID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ3KCtfKSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiB5O1xuICB9O1xuXG4gIHJldHVybiBmb3JjZTtcbn07XG5cbmZ1bmN0aW9uIG5vcHJvcGFnYXRpb24oKSB7XG4gIGV4cG9ydHMuZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG59XG5cbnZhciBub2V2ZW50ID0gZnVuY3Rpb24oKSB7XG4gIGV4cG9ydHMuZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgZXhwb3J0cy5ldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbn07XG5cbnZhciBkcmFnRGlzYWJsZSA9IGZ1bmN0aW9uKHZpZXcpIHtcbiAgdmFyIHJvb3QgPSB2aWV3LmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcbiAgICAgIHNlbGVjdGlvbiQkMSA9IHNlbGVjdCh2aWV3KS5vbihcImRyYWdzdGFydC5kcmFnXCIsIG5vZXZlbnQsIHRydWUpO1xuICBpZiAoXCJvbnNlbGVjdHN0YXJ0XCIgaW4gcm9vdCkge1xuICAgIHNlbGVjdGlvbiQkMS5vbihcInNlbGVjdHN0YXJ0LmRyYWdcIiwgbm9ldmVudCwgdHJ1ZSk7XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5fX25vc2VsZWN0ID0gcm9vdC5zdHlsZS5Nb3pVc2VyU2VsZWN0O1xuICAgIHJvb3Quc3R5bGUuTW96VXNlclNlbGVjdCA9IFwibm9uZVwiO1xuICB9XG59O1xuXG5mdW5jdGlvbiB5ZXNkcmFnKHZpZXcsIG5vY2xpY2spIHtcbiAgdmFyIHJvb3QgPSB2aWV3LmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcbiAgICAgIHNlbGVjdGlvbiQkMSA9IHNlbGVjdCh2aWV3KS5vbihcImRyYWdzdGFydC5kcmFnXCIsIG51bGwpO1xuICBpZiAobm9jbGljaykge1xuICAgIHNlbGVjdGlvbiQkMS5vbihcImNsaWNrLmRyYWdcIiwgbm9ldmVudCwgdHJ1ZSk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgc2VsZWN0aW9uJCQxLm9uKFwiY2xpY2suZHJhZ1wiLCBudWxsKTsgfSwgMCk7XG4gIH1cbiAgaWYgKFwib25zZWxlY3RzdGFydFwiIGluIHJvb3QpIHtcbiAgICBzZWxlY3Rpb24kJDEub24oXCJzZWxlY3RzdGFydC5kcmFnXCIsIG51bGwpO1xuICB9IGVsc2Uge1xuICAgIHJvb3Quc3R5bGUuTW96VXNlclNlbGVjdCA9IHJvb3QuX19ub3NlbGVjdDtcbiAgICBkZWxldGUgcm9vdC5fX25vc2VsZWN0O1xuICB9XG59XG5cbnZhciBjb25zdGFudCQ4ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG5mdW5jdGlvbiBEcmFnRXZlbnQodGFyZ2V0LCB0eXBlLCBzdWJqZWN0LCBpZCwgYWN0aXZlLCB4LCB5LCBkeCwgZHksIGRpc3BhdGNoKSB7XG4gIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICB0aGlzLnR5cGUgPSB0eXBlO1xuICB0aGlzLnN1YmplY3QgPSBzdWJqZWN0O1xuICB0aGlzLmlkZW50aWZpZXIgPSBpZDtcbiAgdGhpcy5hY3RpdmUgPSBhY3RpdmU7XG4gIHRoaXMueCA9IHg7XG4gIHRoaXMueSA9IHk7XG4gIHRoaXMuZHggPSBkeDtcbiAgdGhpcy5keSA9IGR5O1xuICB0aGlzLl8gPSBkaXNwYXRjaDtcbn1cblxuRHJhZ0V2ZW50LnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdmFsdWUgPSB0aGlzLl8ub24uYXBwbHkodGhpcy5fLCBhcmd1bWVudHMpO1xuICByZXR1cm4gdmFsdWUgPT09IHRoaXMuXyA/IHRoaXMgOiB2YWx1ZTtcbn07XG5cbi8vIElnbm9yZSByaWdodC1jbGljaywgc2luY2UgdGhhdCBzaG91bGQgb3BlbiB0aGUgY29udGV4dCBtZW51LlxuZnVuY3Rpb24gZGVmYXVsdEZpbHRlcigpIHtcbiAgcmV0dXJuICFleHBvcnRzLmV2ZW50LmJ1dHRvbjtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdENvbnRhaW5lcigpIHtcbiAgcmV0dXJuIHRoaXMucGFyZW50Tm9kZTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFN1YmplY3QoZCkge1xuICByZXR1cm4gZCA9PSBudWxsID8ge3g6IGV4cG9ydHMuZXZlbnQueCwgeTogZXhwb3J0cy5ldmVudC55fSA6IGQ7XG59XG5cbnZhciBkcmFnID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmaWx0ZXIgPSBkZWZhdWx0RmlsdGVyLFxuICAgICAgY29udGFpbmVyID0gZGVmYXVsdENvbnRhaW5lcixcbiAgICAgIHN1YmplY3QgPSBkZWZhdWx0U3ViamVjdCxcbiAgICAgIGdlc3R1cmVzID0ge30sXG4gICAgICBsaXN0ZW5lcnMgPSBkaXNwYXRjaChcInN0YXJ0XCIsIFwiZHJhZ1wiLCBcImVuZFwiKSxcbiAgICAgIGFjdGl2ZSA9IDAsXG4gICAgICBtb3VzZW1vdmluZyxcbiAgICAgIHRvdWNoZW5kaW5nO1xuXG4gIGZ1bmN0aW9uIGRyYWcoc2VsZWN0aW9uJCQxKSB7XG4gICAgc2VsZWN0aW9uJCQxXG4gICAgICAgIC5vbihcIm1vdXNlZG93bi5kcmFnXCIsIG1vdXNlZG93bmVkKVxuICAgICAgICAub24oXCJ0b3VjaHN0YXJ0LmRyYWdcIiwgdG91Y2hzdGFydGVkKVxuICAgICAgICAub24oXCJ0b3VjaG1vdmUuZHJhZ1wiLCB0b3VjaG1vdmVkKVxuICAgICAgICAub24oXCJ0b3VjaGVuZC5kcmFnIHRvdWNoY2FuY2VsLmRyYWdcIiwgdG91Y2hlbmRlZClcbiAgICAgICAgLnN0eWxlKFwiLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yXCIsIFwicmdiYSgwLDAsMCwwKVwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdXNlZG93bmVkKCkge1xuICAgIGlmICh0b3VjaGVuZGluZyB8fCAhZmlsdGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIHJldHVybjtcbiAgICB2YXIgZ2VzdHVyZSA9IGJlZm9yZXN0YXJ0KFwibW91c2VcIiwgY29udGFpbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIG1vdXNlLCB0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICghZ2VzdHVyZSkgcmV0dXJuO1xuICAgIHNlbGVjdChleHBvcnRzLmV2ZW50LnZpZXcpLm9uKFwibW91c2Vtb3ZlLmRyYWdcIiwgbW91c2Vtb3ZlZCwgdHJ1ZSkub24oXCJtb3VzZXVwLmRyYWdcIiwgbW91c2V1cHBlZCwgdHJ1ZSk7XG4gICAgZHJhZ0Rpc2FibGUoZXhwb3J0cy5ldmVudC52aWV3KTtcbiAgICBub3Byb3BhZ2F0aW9uKCk7XG4gICAgbW91c2Vtb3ZpbmcgPSBmYWxzZTtcbiAgICBnZXN0dXJlKFwic3RhcnRcIik7XG4gIH1cblxuICBmdW5jdGlvbiBtb3VzZW1vdmVkKCkge1xuICAgIG5vZXZlbnQoKTtcbiAgICBtb3VzZW1vdmluZyA9IHRydWU7XG4gICAgZ2VzdHVyZXMubW91c2UoXCJkcmFnXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gbW91c2V1cHBlZCgpIHtcbiAgICBzZWxlY3QoZXhwb3J0cy5ldmVudC52aWV3KS5vbihcIm1vdXNlbW92ZS5kcmFnIG1vdXNldXAuZHJhZ1wiLCBudWxsKTtcbiAgICB5ZXNkcmFnKGV4cG9ydHMuZXZlbnQudmlldywgbW91c2Vtb3ZpbmcpO1xuICAgIG5vZXZlbnQoKTtcbiAgICBnZXN0dXJlcy5tb3VzZShcImVuZFwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvdWNoc3RhcnRlZCgpIHtcbiAgICBpZiAoIWZpbHRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm47XG4gICAgdmFyIHRvdWNoZXMkJDEgPSBleHBvcnRzLmV2ZW50LmNoYW5nZWRUb3VjaGVzLFxuICAgICAgICBjID0gY29udGFpbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksXG4gICAgICAgIG4gPSB0b3VjaGVzJCQxLmxlbmd0aCwgaSwgZ2VzdHVyZTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmIChnZXN0dXJlID0gYmVmb3Jlc3RhcnQodG91Y2hlcyQkMVtpXS5pZGVudGlmaWVyLCBjLCB0b3VjaCwgdGhpcywgYXJndW1lbnRzKSkge1xuICAgICAgICBub3Byb3BhZ2F0aW9uKCk7XG4gICAgICAgIGdlc3R1cmUoXCJzdGFydFwiKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0b3VjaG1vdmVkKCkge1xuICAgIHZhciB0b3VjaGVzJCQxID0gZXhwb3J0cy5ldmVudC5jaGFuZ2VkVG91Y2hlcyxcbiAgICAgICAgbiA9IHRvdWNoZXMkJDEubGVuZ3RoLCBpLCBnZXN0dXJlO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKGdlc3R1cmUgPSBnZXN0dXJlc1t0b3VjaGVzJCQxW2ldLmlkZW50aWZpZXJdKSB7XG4gICAgICAgIG5vZXZlbnQoKTtcbiAgICAgICAgZ2VzdHVyZShcImRyYWdcIik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG91Y2hlbmRlZCgpIHtcbiAgICB2YXIgdG91Y2hlcyQkMSA9IGV4cG9ydHMuZXZlbnQuY2hhbmdlZFRvdWNoZXMsXG4gICAgICAgIG4gPSB0b3VjaGVzJCQxLmxlbmd0aCwgaSwgZ2VzdHVyZTtcblxuICAgIGlmICh0b3VjaGVuZGluZykgY2xlYXJUaW1lb3V0KHRvdWNoZW5kaW5nKTtcbiAgICB0b3VjaGVuZGluZyA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHRvdWNoZW5kaW5nID0gbnVsbDsgfSwgNTAwKTsgLy8gR2hvc3QgY2xpY2tzIGFyZSBkZWxheWVkIVxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmIChnZXN0dXJlID0gZ2VzdHVyZXNbdG91Y2hlcyQkMVtpXS5pZGVudGlmaWVyXSkge1xuICAgICAgICBub3Byb3BhZ2F0aW9uKCk7XG4gICAgICAgIGdlc3R1cmUoXCJlbmRcIik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYmVmb3Jlc3RhcnQoaWQsIGNvbnRhaW5lciwgcG9pbnQsIHRoYXQsIGFyZ3MpIHtcbiAgICB2YXIgcCA9IHBvaW50KGNvbnRhaW5lciwgaWQpLCBzLCBkeCwgZHksXG4gICAgICAgIHN1Ymxpc3RlbmVycyA9IGxpc3RlbmVycy5jb3B5KCk7XG5cbiAgICBpZiAoIWN1c3RvbUV2ZW50KG5ldyBEcmFnRXZlbnQoZHJhZywgXCJiZWZvcmVzdGFydFwiLCBzLCBpZCwgYWN0aXZlLCBwWzBdLCBwWzFdLCAwLCAwLCBzdWJsaXN0ZW5lcnMpLCBmdW5jdGlvbigpIHtcbiAgICAgIGlmICgoZXhwb3J0cy5ldmVudC5zdWJqZWN0ID0gcyA9IHN1YmplY3QuYXBwbHkodGhhdCwgYXJncykpID09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICAgIGR4ID0gcy54IC0gcFswXSB8fCAwO1xuICAgICAgZHkgPSBzLnkgLSBwWzFdIHx8IDA7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KSkgcmV0dXJuO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGdlc3R1cmUodHlwZSkge1xuICAgICAgdmFyIHAwID0gcCwgbjtcbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIFwic3RhcnRcIjogZ2VzdHVyZXNbaWRdID0gZ2VzdHVyZSwgbiA9IGFjdGl2ZSsrOyBicmVhaztcbiAgICAgICAgY2FzZSBcImVuZFwiOiBkZWxldGUgZ2VzdHVyZXNbaWRdLCAtLWFjdGl2ZTsgLy8gbm9icmVha1xuICAgICAgICBjYXNlIFwiZHJhZ1wiOiBwID0gcG9pbnQoY29udGFpbmVyLCBpZCksIG4gPSBhY3RpdmU7IGJyZWFrO1xuICAgICAgfVxuICAgICAgY3VzdG9tRXZlbnQobmV3IERyYWdFdmVudChkcmFnLCB0eXBlLCBzLCBpZCwgbiwgcFswXSArIGR4LCBwWzFdICsgZHksIHBbMF0gLSBwMFswXSwgcFsxXSAtIHAwWzFdLCBzdWJsaXN0ZW5lcnMpLCBzdWJsaXN0ZW5lcnMuYXBwbHksIHN1Ymxpc3RlbmVycywgW3R5cGUsIHRoYXQsIGFyZ3NdKTtcbiAgICB9O1xuICB9XG5cbiAgZHJhZy5maWx0ZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZmlsdGVyID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ4KCEhXyksIGRyYWcpIDogZmlsdGVyO1xuICB9O1xuXG4gIGRyYWcuY29udGFpbmVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNvbnRhaW5lciA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkOChfKSwgZHJhZykgOiBjb250YWluZXI7XG4gIH07XG5cbiAgZHJhZy5zdWJqZWN0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN1YmplY3QgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDgoXyksIGRyYWcpIDogc3ViamVjdDtcbiAgfTtcblxuICBkcmFnLm9uID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZhbHVlID0gbGlzdGVuZXJzLm9uLmFwcGx5KGxpc3RlbmVycywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gdmFsdWUgPT09IGxpc3RlbmVycyA/IGRyYWcgOiB2YWx1ZTtcbiAgfTtcblxuICByZXR1cm4gZHJhZztcbn07XG5cbnZhciBjb25zdGFudCQ5ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG5mdW5jdGlvbiB4JDQoZCkge1xuICByZXR1cm4gZFswXTtcbn1cblxuZnVuY3Rpb24geSQ0KGQpIHtcbiAgcmV0dXJuIGRbMV07XG59XG5cbmZ1bmN0aW9uIFJlZEJsYWNrVHJlZSgpIHtcbiAgdGhpcy5fID0gbnVsbDsgLy8gcm9vdCBub2RlXG59XG5cbmZ1bmN0aW9uIFJlZEJsYWNrTm9kZShub2RlKSB7XG4gIG5vZGUuVSA9IC8vIHBhcmVudCBub2RlXG4gIG5vZGUuQyA9IC8vIGNvbG9yIC0gdHJ1ZSBmb3IgcmVkLCBmYWxzZSBmb3IgYmxhY2tcbiAgbm9kZS5MID0gLy8gbGVmdCBub2RlXG4gIG5vZGUuUiA9IC8vIHJpZ2h0IG5vZGVcbiAgbm9kZS5QID0gLy8gcHJldmlvdXMgbm9kZVxuICBub2RlLk4gPSBudWxsOyAvLyBuZXh0IG5vZGVcbn1cblxuUmVkQmxhY2tUcmVlLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFJlZEJsYWNrVHJlZSxcblxuICBpbnNlcnQ6IGZ1bmN0aW9uKGFmdGVyLCBub2RlKSB7XG4gICAgdmFyIHBhcmVudCwgZ3JhbmRwYSwgdW5jbGU7XG5cbiAgICBpZiAoYWZ0ZXIpIHtcbiAgICAgIG5vZGUuUCA9IGFmdGVyO1xuICAgICAgbm9kZS5OID0gYWZ0ZXIuTjtcbiAgICAgIGlmIChhZnRlci5OKSBhZnRlci5OLlAgPSBub2RlO1xuICAgICAgYWZ0ZXIuTiA9IG5vZGU7XG4gICAgICBpZiAoYWZ0ZXIuUikge1xuICAgICAgICBhZnRlciA9IGFmdGVyLlI7XG4gICAgICAgIHdoaWxlIChhZnRlci5MKSBhZnRlciA9IGFmdGVyLkw7XG4gICAgICAgIGFmdGVyLkwgPSBub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWZ0ZXIuUiA9IG5vZGU7XG4gICAgICB9XG4gICAgICBwYXJlbnQgPSBhZnRlcjtcbiAgICB9IGVsc2UgaWYgKHRoaXMuXykge1xuICAgICAgYWZ0ZXIgPSBSZWRCbGFja0ZpcnN0KHRoaXMuXyk7XG4gICAgICBub2RlLlAgPSBudWxsO1xuICAgICAgbm9kZS5OID0gYWZ0ZXI7XG4gICAgICBhZnRlci5QID0gYWZ0ZXIuTCA9IG5vZGU7XG4gICAgICBwYXJlbnQgPSBhZnRlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZS5QID0gbm9kZS5OID0gbnVsbDtcbiAgICAgIHRoaXMuXyA9IG5vZGU7XG4gICAgICBwYXJlbnQgPSBudWxsO1xuICAgIH1cbiAgICBub2RlLkwgPSBub2RlLlIgPSBudWxsO1xuICAgIG5vZGUuVSA9IHBhcmVudDtcbiAgICBub2RlLkMgPSB0cnVlO1xuXG4gICAgYWZ0ZXIgPSBub2RlO1xuICAgIHdoaWxlIChwYXJlbnQgJiYgcGFyZW50LkMpIHtcbiAgICAgIGdyYW5kcGEgPSBwYXJlbnQuVTtcbiAgICAgIGlmIChwYXJlbnQgPT09IGdyYW5kcGEuTCkge1xuICAgICAgICB1bmNsZSA9IGdyYW5kcGEuUjtcbiAgICAgICAgaWYgKHVuY2xlICYmIHVuY2xlLkMpIHtcbiAgICAgICAgICBwYXJlbnQuQyA9IHVuY2xlLkMgPSBmYWxzZTtcbiAgICAgICAgICBncmFuZHBhLkMgPSB0cnVlO1xuICAgICAgICAgIGFmdGVyID0gZ3JhbmRwYTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoYWZ0ZXIgPT09IHBhcmVudC5SKSB7XG4gICAgICAgICAgICBSZWRCbGFja1JvdGF0ZUxlZnQodGhpcywgcGFyZW50KTtcbiAgICAgICAgICAgIGFmdGVyID0gcGFyZW50O1xuICAgICAgICAgICAgcGFyZW50ID0gYWZ0ZXIuVTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFyZW50LkMgPSBmYWxzZTtcbiAgICAgICAgICBncmFuZHBhLkMgPSB0cnVlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlUmlnaHQodGhpcywgZ3JhbmRwYSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVuY2xlID0gZ3JhbmRwYS5MO1xuICAgICAgICBpZiAodW5jbGUgJiYgdW5jbGUuQykge1xuICAgICAgICAgIHBhcmVudC5DID0gdW5jbGUuQyA9IGZhbHNlO1xuICAgICAgICAgIGdyYW5kcGEuQyA9IHRydWU7XG4gICAgICAgICAgYWZ0ZXIgPSBncmFuZHBhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhZnRlciA9PT0gcGFyZW50LkwpIHtcbiAgICAgICAgICAgIFJlZEJsYWNrUm90YXRlUmlnaHQodGhpcywgcGFyZW50KTtcbiAgICAgICAgICAgIGFmdGVyID0gcGFyZW50O1xuICAgICAgICAgICAgcGFyZW50ID0gYWZ0ZXIuVTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFyZW50LkMgPSBmYWxzZTtcbiAgICAgICAgICBncmFuZHBhLkMgPSB0cnVlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlTGVmdCh0aGlzLCBncmFuZHBhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcGFyZW50ID0gYWZ0ZXIuVTtcbiAgICB9XG4gICAgdGhpcy5fLkMgPSBmYWxzZTtcbiAgfSxcblxuICByZW1vdmU6IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAobm9kZS5OKSBub2RlLk4uUCA9IG5vZGUuUDtcbiAgICBpZiAobm9kZS5QKSBub2RlLlAuTiA9IG5vZGUuTjtcbiAgICBub2RlLk4gPSBub2RlLlAgPSBudWxsO1xuXG4gICAgdmFyIHBhcmVudCA9IG5vZGUuVSxcbiAgICAgICAgc2libGluZyxcbiAgICAgICAgbGVmdCA9IG5vZGUuTCxcbiAgICAgICAgcmlnaHQgPSBub2RlLlIsXG4gICAgICAgIG5leHQsXG4gICAgICAgIHJlZDtcblxuICAgIGlmICghbGVmdCkgbmV4dCA9IHJpZ2h0O1xuICAgIGVsc2UgaWYgKCFyaWdodCkgbmV4dCA9IGxlZnQ7XG4gICAgZWxzZSBuZXh0ID0gUmVkQmxhY2tGaXJzdChyaWdodCk7XG5cbiAgICBpZiAocGFyZW50KSB7XG4gICAgICBpZiAocGFyZW50LkwgPT09IG5vZGUpIHBhcmVudC5MID0gbmV4dDtcbiAgICAgIGVsc2UgcGFyZW50LlIgPSBuZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl8gPSBuZXh0O1xuICAgIH1cblxuICAgIGlmIChsZWZ0ICYmIHJpZ2h0KSB7XG4gICAgICByZWQgPSBuZXh0LkM7XG4gICAgICBuZXh0LkMgPSBub2RlLkM7XG4gICAgICBuZXh0LkwgPSBsZWZ0O1xuICAgICAgbGVmdC5VID0gbmV4dDtcbiAgICAgIGlmIChuZXh0ICE9PSByaWdodCkge1xuICAgICAgICBwYXJlbnQgPSBuZXh0LlU7XG4gICAgICAgIG5leHQuVSA9IG5vZGUuVTtcbiAgICAgICAgbm9kZSA9IG5leHQuUjtcbiAgICAgICAgcGFyZW50LkwgPSBub2RlO1xuICAgICAgICBuZXh0LlIgPSByaWdodDtcbiAgICAgICAgcmlnaHQuVSA9IG5leHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXh0LlUgPSBwYXJlbnQ7XG4gICAgICAgIHBhcmVudCA9IG5leHQ7XG4gICAgICAgIG5vZGUgPSBuZXh0LlI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZCA9IG5vZGUuQztcbiAgICAgIG5vZGUgPSBuZXh0O1xuICAgIH1cblxuICAgIGlmIChub2RlKSBub2RlLlUgPSBwYXJlbnQ7XG4gICAgaWYgKHJlZCkgcmV0dXJuO1xuICAgIGlmIChub2RlICYmIG5vZGUuQykgeyBub2RlLkMgPSBmYWxzZTsgcmV0dXJuOyB9XG5cbiAgICBkbyB7XG4gICAgICBpZiAobm9kZSA9PT0gdGhpcy5fKSBicmVhaztcbiAgICAgIGlmIChub2RlID09PSBwYXJlbnQuTCkge1xuICAgICAgICBzaWJsaW5nID0gcGFyZW50LlI7XG4gICAgICAgIGlmIChzaWJsaW5nLkMpIHtcbiAgICAgICAgICBzaWJsaW5nLkMgPSBmYWxzZTtcbiAgICAgICAgICBwYXJlbnQuQyA9IHRydWU7XG4gICAgICAgICAgUmVkQmxhY2tSb3RhdGVMZWZ0KHRoaXMsIHBhcmVudCk7XG4gICAgICAgICAgc2libGluZyA9IHBhcmVudC5SO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoc2libGluZy5MICYmIHNpYmxpbmcuTC5DKVxuICAgICAgICAgICAgfHwgKHNpYmxpbmcuUiAmJiBzaWJsaW5nLlIuQykpIHtcbiAgICAgICAgICBpZiAoIXNpYmxpbmcuUiB8fCAhc2libGluZy5SLkMpIHtcbiAgICAgICAgICAgIHNpYmxpbmcuTC5DID0gZmFsc2U7XG4gICAgICAgICAgICBzaWJsaW5nLkMgPSB0cnVlO1xuICAgICAgICAgICAgUmVkQmxhY2tSb3RhdGVSaWdodCh0aGlzLCBzaWJsaW5nKTtcbiAgICAgICAgICAgIHNpYmxpbmcgPSBwYXJlbnQuUjtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2libGluZy5DID0gcGFyZW50LkM7XG4gICAgICAgICAgcGFyZW50LkMgPSBzaWJsaW5nLlIuQyA9IGZhbHNlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlTGVmdCh0aGlzLCBwYXJlbnQpO1xuICAgICAgICAgIG5vZGUgPSB0aGlzLl87XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNpYmxpbmcgPSBwYXJlbnQuTDtcbiAgICAgICAgaWYgKHNpYmxpbmcuQykge1xuICAgICAgICAgIHNpYmxpbmcuQyA9IGZhbHNlO1xuICAgICAgICAgIHBhcmVudC5DID0gdHJ1ZTtcbiAgICAgICAgICBSZWRCbGFja1JvdGF0ZVJpZ2h0KHRoaXMsIHBhcmVudCk7XG4gICAgICAgICAgc2libGluZyA9IHBhcmVudC5MO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoc2libGluZy5MICYmIHNpYmxpbmcuTC5DKVxuICAgICAgICAgIHx8IChzaWJsaW5nLlIgJiYgc2libGluZy5SLkMpKSB7XG4gICAgICAgICAgaWYgKCFzaWJsaW5nLkwgfHwgIXNpYmxpbmcuTC5DKSB7XG4gICAgICAgICAgICBzaWJsaW5nLlIuQyA9IGZhbHNlO1xuICAgICAgICAgICAgc2libGluZy5DID0gdHJ1ZTtcbiAgICAgICAgICAgIFJlZEJsYWNrUm90YXRlTGVmdCh0aGlzLCBzaWJsaW5nKTtcbiAgICAgICAgICAgIHNpYmxpbmcgPSBwYXJlbnQuTDtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2libGluZy5DID0gcGFyZW50LkM7XG4gICAgICAgICAgcGFyZW50LkMgPSBzaWJsaW5nLkwuQyA9IGZhbHNlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlUmlnaHQodGhpcywgcGFyZW50KTtcbiAgICAgICAgICBub2RlID0gdGhpcy5fO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzaWJsaW5nLkMgPSB0cnVlO1xuICAgICAgbm9kZSA9IHBhcmVudDtcbiAgICAgIHBhcmVudCA9IHBhcmVudC5VO1xuICAgIH0gd2hpbGUgKCFub2RlLkMpO1xuXG4gICAgaWYgKG5vZGUpIG5vZGUuQyA9IGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBSZWRCbGFja1JvdGF0ZUxlZnQodHJlZSwgbm9kZSkge1xuICB2YXIgcCA9IG5vZGUsXG4gICAgICBxID0gbm9kZS5SLFxuICAgICAgcGFyZW50ID0gcC5VO1xuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBpZiAocGFyZW50LkwgPT09IHApIHBhcmVudC5MID0gcTtcbiAgICBlbHNlIHBhcmVudC5SID0gcTtcbiAgfSBlbHNlIHtcbiAgICB0cmVlLl8gPSBxO1xuICB9XG5cbiAgcS5VID0gcGFyZW50O1xuICBwLlUgPSBxO1xuICBwLlIgPSBxLkw7XG4gIGlmIChwLlIpIHAuUi5VID0gcDtcbiAgcS5MID0gcDtcbn1cblxuZnVuY3Rpb24gUmVkQmxhY2tSb3RhdGVSaWdodCh0cmVlLCBub2RlKSB7XG4gIHZhciBwID0gbm9kZSxcbiAgICAgIHEgPSBub2RlLkwsXG4gICAgICBwYXJlbnQgPSBwLlU7XG5cbiAgaWYgKHBhcmVudCkge1xuICAgIGlmIChwYXJlbnQuTCA9PT0gcCkgcGFyZW50LkwgPSBxO1xuICAgIGVsc2UgcGFyZW50LlIgPSBxO1xuICB9IGVsc2Uge1xuICAgIHRyZWUuXyA9IHE7XG4gIH1cblxuICBxLlUgPSBwYXJlbnQ7XG4gIHAuVSA9IHE7XG4gIHAuTCA9IHEuUjtcbiAgaWYgKHAuTCkgcC5MLlUgPSBwO1xuICBxLlIgPSBwO1xufVxuXG5mdW5jdGlvbiBSZWRCbGFja0ZpcnN0KG5vZGUpIHtcbiAgd2hpbGUgKG5vZGUuTCkgbm9kZSA9IG5vZGUuTDtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUVkZ2UobGVmdCwgcmlnaHQsIHYwLCB2MSkge1xuICB2YXIgZWRnZSA9IFtudWxsLCBudWxsXSxcbiAgICAgIGluZGV4ID0gZWRnZXMucHVzaChlZGdlKSAtIDE7XG4gIGVkZ2UubGVmdCA9IGxlZnQ7XG4gIGVkZ2UucmlnaHQgPSByaWdodDtcbiAgaWYgKHYwKSBzZXRFZGdlRW5kKGVkZ2UsIGxlZnQsIHJpZ2h0LCB2MCk7XG4gIGlmICh2MSkgc2V0RWRnZUVuZChlZGdlLCByaWdodCwgbGVmdCwgdjEpO1xuICBjZWxsc1tsZWZ0LmluZGV4XS5oYWxmZWRnZXMucHVzaChpbmRleCk7XG4gIGNlbGxzW3JpZ2h0LmluZGV4XS5oYWxmZWRnZXMucHVzaChpbmRleCk7XG4gIHJldHVybiBlZGdlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVCb3JkZXJFZGdlKGxlZnQsIHYwLCB2MSkge1xuICB2YXIgZWRnZSA9IFt2MCwgdjFdO1xuICBlZGdlLmxlZnQgPSBsZWZ0O1xuICByZXR1cm4gZWRnZTtcbn1cblxuZnVuY3Rpb24gc2V0RWRnZUVuZChlZGdlLCBsZWZ0LCByaWdodCwgdmVydGV4KSB7XG4gIGlmICghZWRnZVswXSAmJiAhZWRnZVsxXSkge1xuICAgIGVkZ2VbMF0gPSB2ZXJ0ZXg7XG4gICAgZWRnZS5sZWZ0ID0gbGVmdDtcbiAgICBlZGdlLnJpZ2h0ID0gcmlnaHQ7XG4gIH0gZWxzZSBpZiAoZWRnZS5sZWZ0ID09PSByaWdodCkge1xuICAgIGVkZ2VbMV0gPSB2ZXJ0ZXg7XG4gIH0gZWxzZSB7XG4gICAgZWRnZVswXSA9IHZlcnRleDtcbiAgfVxufVxuXG4vLyBMaWFuZ+KAk0JhcnNreSBsaW5lIGNsaXBwaW5nLlxuZnVuY3Rpb24gY2xpcEVkZ2UoZWRnZSwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgdmFyIGEgPSBlZGdlWzBdLFxuICAgICAgYiA9IGVkZ2VbMV0sXG4gICAgICBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBieCA9IGJbMF0sXG4gICAgICBieSA9IGJbMV0sXG4gICAgICB0MCA9IDAsXG4gICAgICB0MSA9IDEsXG4gICAgICBkeCA9IGJ4IC0gYXgsXG4gICAgICBkeSA9IGJ5IC0gYXksXG4gICAgICByO1xuXG4gIHIgPSB4MCAtIGF4O1xuICBpZiAoIWR4ICYmIHIgPiAwKSByZXR1cm47XG4gIHIgLz0gZHg7XG4gIGlmIChkeCA8IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9IGVsc2UgaWYgKGR4ID4gMCkge1xuICAgIGlmIChyID4gdDEpIHJldHVybjtcbiAgICBpZiAociA+IHQwKSB0MCA9IHI7XG4gIH1cblxuICByID0geDEgLSBheDtcbiAgaWYgKCFkeCAmJiByIDwgMCkgcmV0dXJuO1xuICByIC89IGR4O1xuICBpZiAoZHggPCAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfSBlbHNlIGlmIChkeCA+IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9XG5cbiAgciA9IHkwIC0gYXk7XG4gIGlmICghZHkgJiYgciA+IDApIHJldHVybjtcbiAgciAvPSBkeTtcbiAgaWYgKGR5IDwgMCkge1xuICAgIGlmIChyIDwgdDApIHJldHVybjtcbiAgICBpZiAociA8IHQxKSB0MSA9IHI7XG4gIH0gZWxzZSBpZiAoZHkgPiAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfVxuXG4gIHIgPSB5MSAtIGF5O1xuICBpZiAoIWR5ICYmIHIgPCAwKSByZXR1cm47XG4gIHIgLz0gZHk7XG4gIGlmIChkeSA8IDApIHtcbiAgICBpZiAociA+IHQxKSByZXR1cm47XG4gICAgaWYgKHIgPiB0MCkgdDAgPSByO1xuICB9IGVsc2UgaWYgKGR5ID4gMCkge1xuICAgIGlmIChyIDwgdDApIHJldHVybjtcbiAgICBpZiAociA8IHQxKSB0MSA9IHI7XG4gIH1cblxuICBpZiAoISh0MCA+IDApICYmICEodDEgPCAxKSkgcmV0dXJuIHRydWU7IC8vIFRPRE8gQmV0dGVyIGNoZWNrP1xuXG4gIGlmICh0MCA+IDApIGVkZ2VbMF0gPSBbYXggKyB0MCAqIGR4LCBheSArIHQwICogZHldO1xuICBpZiAodDEgPCAxKSBlZGdlWzFdID0gW2F4ICsgdDEgKiBkeCwgYXkgKyB0MSAqIGR5XTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbm5lY3RFZGdlKGVkZ2UsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciB2MSA9IGVkZ2VbMV07XG4gIGlmICh2MSkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIHYwID0gZWRnZVswXSxcbiAgICAgIGxlZnQgPSBlZGdlLmxlZnQsXG4gICAgICByaWdodCA9IGVkZ2UucmlnaHQsXG4gICAgICBseCA9IGxlZnRbMF0sXG4gICAgICBseSA9IGxlZnRbMV0sXG4gICAgICByeCA9IHJpZ2h0WzBdLFxuICAgICAgcnkgPSByaWdodFsxXSxcbiAgICAgIGZ4ID0gKGx4ICsgcngpIC8gMixcbiAgICAgIGZ5ID0gKGx5ICsgcnkpIC8gMixcbiAgICAgIGZtLFxuICAgICAgZmI7XG5cbiAgaWYgKHJ5ID09PSBseSkge1xuICAgIGlmIChmeCA8IHgwIHx8IGZ4ID49IHgxKSByZXR1cm47XG4gICAgaWYgKGx4ID4gcngpIHtcbiAgICAgIGlmICghdjApIHYwID0gW2Z4LCB5MF07XG4gICAgICBlbHNlIGlmICh2MFsxXSA+PSB5MSkgcmV0dXJuO1xuICAgICAgdjEgPSBbZngsIHkxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF2MCkgdjAgPSBbZngsIHkxXTtcbiAgICAgIGVsc2UgaWYgKHYwWzFdIDwgeTApIHJldHVybjtcbiAgICAgIHYxID0gW2Z4LCB5MF07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZtID0gKGx4IC0gcngpIC8gKHJ5IC0gbHkpO1xuICAgIGZiID0gZnkgLSBmbSAqIGZ4O1xuICAgIGlmIChmbSA8IC0xIHx8IGZtID4gMSkge1xuICAgICAgaWYgKGx4ID4gcngpIHtcbiAgICAgICAgaWYgKCF2MCkgdjAgPSBbKHkwIC0gZmIpIC8gZm0sIHkwXTtcbiAgICAgICAgZWxzZSBpZiAodjBbMV0gPj0geTEpIHJldHVybjtcbiAgICAgICAgdjEgPSBbKHkxIC0gZmIpIC8gZm0sIHkxXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghdjApIHYwID0gWyh5MSAtIGZiKSAvIGZtLCB5MV07XG4gICAgICAgIGVsc2UgaWYgKHYwWzFdIDwgeTApIHJldHVybjtcbiAgICAgICAgdjEgPSBbKHkwIC0gZmIpIC8gZm0sIHkwXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGx5IDwgcnkpIHtcbiAgICAgICAgaWYgKCF2MCkgdjAgPSBbeDAsIGZtICogeDAgKyBmYl07XG4gICAgICAgIGVsc2UgaWYgKHYwWzBdID49IHgxKSByZXR1cm47XG4gICAgICAgIHYxID0gW3gxLCBmbSAqIHgxICsgZmJdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCF2MCkgdjAgPSBbeDEsIGZtICogeDEgKyBmYl07XG4gICAgICAgIGVsc2UgaWYgKHYwWzBdIDwgeDApIHJldHVybjtcbiAgICAgICAgdjEgPSBbeDAsIGZtICogeDAgKyBmYl07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZWRnZVswXSA9IHYwO1xuICBlZGdlWzFdID0gdjE7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjbGlwRWRnZXMoeDAsIHkwLCB4MSwgeTEpIHtcbiAgdmFyIGkgPSBlZGdlcy5sZW5ndGgsXG4gICAgICBlZGdlO1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICBpZiAoIWNvbm5lY3RFZGdlKGVkZ2UgPSBlZGdlc1tpXSwgeDAsIHkwLCB4MSwgeTEpXG4gICAgICAgIHx8ICFjbGlwRWRnZShlZGdlLCB4MCwgeTAsIHgxLCB5MSlcbiAgICAgICAgfHwgIShNYXRoLmFicyhlZGdlWzBdWzBdIC0gZWRnZVsxXVswXSkgPiBlcHNpbG9uJDNcbiAgICAgICAgICAgIHx8IE1hdGguYWJzKGVkZ2VbMF1bMV0gLSBlZGdlWzFdWzFdKSA+IGVwc2lsb24kMykpIHtcbiAgICAgIGRlbGV0ZSBlZGdlc1tpXTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2VsbChzaXRlKSB7XG4gIHJldHVybiBjZWxsc1tzaXRlLmluZGV4XSA9IHtcbiAgICBzaXRlOiBzaXRlLFxuICAgIGhhbGZlZGdlczogW11cbiAgfTtcbn1cblxuZnVuY3Rpb24gY2VsbEhhbGZlZGdlQW5nbGUoY2VsbCwgZWRnZSkge1xuICB2YXIgc2l0ZSA9IGNlbGwuc2l0ZSxcbiAgICAgIHZhID0gZWRnZS5sZWZ0LFxuICAgICAgdmIgPSBlZGdlLnJpZ2h0O1xuICBpZiAoc2l0ZSA9PT0gdmIpIHZiID0gdmEsIHZhID0gc2l0ZTtcbiAgaWYgKHZiKSByZXR1cm4gTWF0aC5hdGFuMih2YlsxXSAtIHZhWzFdLCB2YlswXSAtIHZhWzBdKTtcbiAgaWYgKHNpdGUgPT09IHZhKSB2YSA9IGVkZ2VbMV0sIHZiID0gZWRnZVswXTtcbiAgZWxzZSB2YSA9IGVkZ2VbMF0sIHZiID0gZWRnZVsxXTtcbiAgcmV0dXJuIE1hdGguYXRhbjIodmFbMF0gLSB2YlswXSwgdmJbMV0gLSB2YVsxXSk7XG59XG5cbmZ1bmN0aW9uIGNlbGxIYWxmZWRnZVN0YXJ0KGNlbGwsIGVkZ2UpIHtcbiAgcmV0dXJuIGVkZ2VbKyhlZGdlLmxlZnQgIT09IGNlbGwuc2l0ZSldO1xufVxuXG5mdW5jdGlvbiBjZWxsSGFsZmVkZ2VFbmQoY2VsbCwgZWRnZSkge1xuICByZXR1cm4gZWRnZVsrKGVkZ2UubGVmdCA9PT0gY2VsbC5zaXRlKV07XG59XG5cbmZ1bmN0aW9uIHNvcnRDZWxsSGFsZmVkZ2VzKCkge1xuICBmb3IgKHZhciBpID0gMCwgbiA9IGNlbGxzLmxlbmd0aCwgY2VsbCwgaGFsZmVkZ2VzLCBqLCBtOyBpIDwgbjsgKytpKSB7XG4gICAgaWYgKChjZWxsID0gY2VsbHNbaV0pICYmIChtID0gKGhhbGZlZGdlcyA9IGNlbGwuaGFsZmVkZ2VzKS5sZW5ndGgpKSB7XG4gICAgICB2YXIgaW5kZXggPSBuZXcgQXJyYXkobSksXG4gICAgICAgICAgYXJyYXkgPSBuZXcgQXJyYXkobSk7XG4gICAgICBmb3IgKGogPSAwOyBqIDwgbTsgKytqKSBpbmRleFtqXSA9IGosIGFycmF5W2pdID0gY2VsbEhhbGZlZGdlQW5nbGUoY2VsbCwgZWRnZXNbaGFsZmVkZ2VzW2pdXSk7XG4gICAgICBpbmRleC5zb3J0KGZ1bmN0aW9uKGksIGopIHsgcmV0dXJuIGFycmF5W2pdIC0gYXJyYXlbaV07IH0pO1xuICAgICAgZm9yIChqID0gMDsgaiA8IG07ICsraikgYXJyYXlbal0gPSBoYWxmZWRnZXNbaW5kZXhbal1dO1xuICAgICAgZm9yIChqID0gMDsgaiA8IG07ICsraikgaGFsZmVkZ2VzW2pdID0gYXJyYXlbal07XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNsaXBDZWxscyh4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgbkNlbGxzID0gY2VsbHMubGVuZ3RoLFxuICAgICAgaUNlbGwsXG4gICAgICBjZWxsLFxuICAgICAgc2l0ZSxcbiAgICAgIGlIYWxmZWRnZSxcbiAgICAgIGhhbGZlZGdlcyxcbiAgICAgIG5IYWxmZWRnZXMsXG4gICAgICBzdGFydCxcbiAgICAgIHN0YXJ0WCxcbiAgICAgIHN0YXJ0WSxcbiAgICAgIGVuZCxcbiAgICAgIGVuZFgsXG4gICAgICBlbmRZLFxuICAgICAgY292ZXIgPSB0cnVlO1xuXG4gIGZvciAoaUNlbGwgPSAwOyBpQ2VsbCA8IG5DZWxsczsgKytpQ2VsbCkge1xuICAgIGlmIChjZWxsID0gY2VsbHNbaUNlbGxdKSB7XG4gICAgICBzaXRlID0gY2VsbC5zaXRlO1xuICAgICAgaGFsZmVkZ2VzID0gY2VsbC5oYWxmZWRnZXM7XG4gICAgICBpSGFsZmVkZ2UgPSBoYWxmZWRnZXMubGVuZ3RoO1xuXG4gICAgICAvLyBSZW1vdmUgYW55IGRhbmdsaW5nIGNsaXBwZWQgZWRnZXMuXG4gICAgICB3aGlsZSAoaUhhbGZlZGdlLS0pIHtcbiAgICAgICAgaWYgKCFlZGdlc1toYWxmZWRnZXNbaUhhbGZlZGdlXV0pIHtcbiAgICAgICAgICBoYWxmZWRnZXMuc3BsaWNlKGlIYWxmZWRnZSwgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSW5zZXJ0IGFueSBib3JkZXIgZWRnZXMgYXMgbmVjZXNzYXJ5LlxuICAgICAgaUhhbGZlZGdlID0gMCwgbkhhbGZlZGdlcyA9IGhhbGZlZGdlcy5sZW5ndGg7XG4gICAgICB3aGlsZSAoaUhhbGZlZGdlIDwgbkhhbGZlZGdlcykge1xuICAgICAgICBlbmQgPSBjZWxsSGFsZmVkZ2VFbmQoY2VsbCwgZWRnZXNbaGFsZmVkZ2VzW2lIYWxmZWRnZV1dKSwgZW5kWCA9IGVuZFswXSwgZW5kWSA9IGVuZFsxXTtcbiAgICAgICAgc3RhcnQgPSBjZWxsSGFsZmVkZ2VTdGFydChjZWxsLCBlZGdlc1toYWxmZWRnZXNbKytpSGFsZmVkZ2UgJSBuSGFsZmVkZ2VzXV0pLCBzdGFydFggPSBzdGFydFswXSwgc3RhcnRZID0gc3RhcnRbMV07XG4gICAgICAgIGlmIChNYXRoLmFicyhlbmRYIC0gc3RhcnRYKSA+IGVwc2lsb24kMyB8fCBNYXRoLmFicyhlbmRZIC0gc3RhcnRZKSA+IGVwc2lsb24kMykge1xuICAgICAgICAgIGhhbGZlZGdlcy5zcGxpY2UoaUhhbGZlZGdlLCAwLCBlZGdlcy5wdXNoKGNyZWF0ZUJvcmRlckVkZ2Uoc2l0ZSwgZW5kLFxuICAgICAgICAgICAgICBNYXRoLmFicyhlbmRYIC0geDApIDwgZXBzaWxvbiQzICYmIHkxIC0gZW5kWSA+IGVwc2lsb24kMyA/IFt4MCwgTWF0aC5hYnMoc3RhcnRYIC0geDApIDwgZXBzaWxvbiQzID8gc3RhcnRZIDogeTFdXG4gICAgICAgICAgICAgIDogTWF0aC5hYnMoZW5kWSAtIHkxKSA8IGVwc2lsb24kMyAmJiB4MSAtIGVuZFggPiBlcHNpbG9uJDMgPyBbTWF0aC5hYnMoc3RhcnRZIC0geTEpIDwgZXBzaWxvbiQzID8gc3RhcnRYIDogeDEsIHkxXVxuICAgICAgICAgICAgICA6IE1hdGguYWJzKGVuZFggLSB4MSkgPCBlcHNpbG9uJDMgJiYgZW5kWSAtIHkwID4gZXBzaWxvbiQzID8gW3gxLCBNYXRoLmFicyhzdGFydFggLSB4MSkgPCBlcHNpbG9uJDMgPyBzdGFydFkgOiB5MF1cbiAgICAgICAgICAgICAgOiBNYXRoLmFicyhlbmRZIC0geTApIDwgZXBzaWxvbiQzICYmIGVuZFggLSB4MCA+IGVwc2lsb24kMyA/IFtNYXRoLmFicyhzdGFydFkgLSB5MCkgPCBlcHNpbG9uJDMgPyBzdGFydFggOiB4MCwgeTBdXG4gICAgICAgICAgICAgIDogbnVsbCkpIC0gMSk7XG4gICAgICAgICAgKytuSGFsZmVkZ2VzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChuSGFsZmVkZ2VzKSBjb3ZlciA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8vIElmIHRoZXJlIHdlcmVu4oCZdCBhbnkgZWRnZXMsIGhhdmUgdGhlIGNsb3Nlc3Qgc2l0ZSBjb3ZlciB0aGUgZXh0ZW50LlxuICAvLyBJdCBkb2VzbuKAmXQgbWF0dGVyIHdoaWNoIGNvcm5lciBvZiB0aGUgZXh0ZW50IHdlIG1lYXN1cmUhXG4gIGlmIChjb3Zlcikge1xuICAgIHZhciBkeCwgZHksIGQyLCBkYyA9IEluZmluaXR5O1xuXG4gICAgZm9yIChpQ2VsbCA9IDAsIGNvdmVyID0gbnVsbDsgaUNlbGwgPCBuQ2VsbHM7ICsraUNlbGwpIHtcbiAgICAgIGlmIChjZWxsID0gY2VsbHNbaUNlbGxdKSB7XG4gICAgICAgIHNpdGUgPSBjZWxsLnNpdGU7XG4gICAgICAgIGR4ID0gc2l0ZVswXSAtIHgwO1xuICAgICAgICBkeSA9IHNpdGVbMV0gLSB5MDtcbiAgICAgICAgZDIgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgICAgaWYgKGQyIDwgZGMpIGRjID0gZDIsIGNvdmVyID0gY2VsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY292ZXIpIHtcbiAgICAgIHZhciB2MDAgPSBbeDAsIHkwXSwgdjAxID0gW3gwLCB5MV0sIHYxMSA9IFt4MSwgeTFdLCB2MTAgPSBbeDEsIHkwXTtcbiAgICAgIGNvdmVyLmhhbGZlZGdlcy5wdXNoKFxuICAgICAgICBlZGdlcy5wdXNoKGNyZWF0ZUJvcmRlckVkZ2Uoc2l0ZSA9IGNvdmVyLnNpdGUsIHYwMCwgdjAxKSkgLSAxLFxuICAgICAgICBlZGdlcy5wdXNoKGNyZWF0ZUJvcmRlckVkZ2Uoc2l0ZSwgdjAxLCB2MTEpKSAtIDEsXG4gICAgICAgIGVkZ2VzLnB1c2goY3JlYXRlQm9yZGVyRWRnZShzaXRlLCB2MTEsIHYxMCkpIC0gMSxcbiAgICAgICAgZWRnZXMucHVzaChjcmVhdGVCb3JkZXJFZGdlKHNpdGUsIHYxMCwgdjAwKSkgLSAxXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIExhc3RseSBkZWxldGUgYW55IGNlbGxzIHdpdGggbm8gZWRnZXM7IHRoZXNlIHdlcmUgZW50aXJlbHkgY2xpcHBlZC5cbiAgZm9yIChpQ2VsbCA9IDA7IGlDZWxsIDwgbkNlbGxzOyArK2lDZWxsKSB7XG4gICAgaWYgKGNlbGwgPSBjZWxsc1tpQ2VsbF0pIHtcbiAgICAgIGlmICghY2VsbC5oYWxmZWRnZXMubGVuZ3RoKSB7XG4gICAgICAgIGRlbGV0ZSBjZWxsc1tpQ2VsbF07XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBjaXJjbGVQb29sID0gW107XG5cbnZhciBmaXJzdENpcmNsZTtcblxuZnVuY3Rpb24gQ2lyY2xlKCkge1xuICBSZWRCbGFja05vZGUodGhpcyk7XG4gIHRoaXMueCA9XG4gIHRoaXMueSA9XG4gIHRoaXMuYXJjID1cbiAgdGhpcy5zaXRlID1cbiAgdGhpcy5jeSA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGF0dGFjaENpcmNsZShhcmMpIHtcbiAgdmFyIGxBcmMgPSBhcmMuUCxcbiAgICAgIHJBcmMgPSBhcmMuTjtcblxuICBpZiAoIWxBcmMgfHwgIXJBcmMpIHJldHVybjtcblxuICB2YXIgbFNpdGUgPSBsQXJjLnNpdGUsXG4gICAgICBjU2l0ZSA9IGFyYy5zaXRlLFxuICAgICAgclNpdGUgPSByQXJjLnNpdGU7XG5cbiAgaWYgKGxTaXRlID09PSByU2l0ZSkgcmV0dXJuO1xuXG4gIHZhciBieCA9IGNTaXRlWzBdLFxuICAgICAgYnkgPSBjU2l0ZVsxXSxcbiAgICAgIGF4ID0gbFNpdGVbMF0gLSBieCxcbiAgICAgIGF5ID0gbFNpdGVbMV0gLSBieSxcbiAgICAgIGN4ID0gclNpdGVbMF0gLSBieCxcbiAgICAgIGN5ID0gclNpdGVbMV0gLSBieTtcblxuICB2YXIgZCA9IDIgKiAoYXggKiBjeSAtIGF5ICogY3gpO1xuICBpZiAoZCA+PSAtZXBzaWxvbjIkMSkgcmV0dXJuO1xuXG4gIHZhciBoYSA9IGF4ICogYXggKyBheSAqIGF5LFxuICAgICAgaGMgPSBjeCAqIGN4ICsgY3kgKiBjeSxcbiAgICAgIHggPSAoY3kgKiBoYSAtIGF5ICogaGMpIC8gZCxcbiAgICAgIHkgPSAoYXggKiBoYyAtIGN4ICogaGEpIC8gZDtcblxuICB2YXIgY2lyY2xlID0gY2lyY2xlUG9vbC5wb3AoKSB8fCBuZXcgQ2lyY2xlO1xuICBjaXJjbGUuYXJjID0gYXJjO1xuICBjaXJjbGUuc2l0ZSA9IGNTaXRlO1xuICBjaXJjbGUueCA9IHggKyBieDtcbiAgY2lyY2xlLnkgPSAoY2lyY2xlLmN5ID0geSArIGJ5KSArIE1hdGguc3FydCh4ICogeCArIHkgKiB5KTsgLy8geSBib3R0b21cblxuICBhcmMuY2lyY2xlID0gY2lyY2xlO1xuXG4gIHZhciBiZWZvcmUgPSBudWxsLFxuICAgICAgbm9kZSA9IGNpcmNsZXMuXztcblxuICB3aGlsZSAobm9kZSkge1xuICAgIGlmIChjaXJjbGUueSA8IG5vZGUueSB8fCAoY2lyY2xlLnkgPT09IG5vZGUueSAmJiBjaXJjbGUueCA8PSBub2RlLngpKSB7XG4gICAgICBpZiAobm9kZS5MKSBub2RlID0gbm9kZS5MO1xuICAgICAgZWxzZSB7IGJlZm9yZSA9IG5vZGUuUDsgYnJlYWs7IH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG5vZGUuUikgbm9kZSA9IG5vZGUuUjtcbiAgICAgIGVsc2UgeyBiZWZvcmUgPSBub2RlOyBicmVhazsgfVxuICAgIH1cbiAgfVxuXG4gIGNpcmNsZXMuaW5zZXJ0KGJlZm9yZSwgY2lyY2xlKTtcbiAgaWYgKCFiZWZvcmUpIGZpcnN0Q2lyY2xlID0gY2lyY2xlO1xufVxuXG5mdW5jdGlvbiBkZXRhY2hDaXJjbGUoYXJjKSB7XG4gIHZhciBjaXJjbGUgPSBhcmMuY2lyY2xlO1xuICBpZiAoY2lyY2xlKSB7XG4gICAgaWYgKCFjaXJjbGUuUCkgZmlyc3RDaXJjbGUgPSBjaXJjbGUuTjtcbiAgICBjaXJjbGVzLnJlbW92ZShjaXJjbGUpO1xuICAgIGNpcmNsZVBvb2wucHVzaChjaXJjbGUpO1xuICAgIFJlZEJsYWNrTm9kZShjaXJjbGUpO1xuICAgIGFyYy5jaXJjbGUgPSBudWxsO1xuICB9XG59XG5cbnZhciBiZWFjaFBvb2wgPSBbXTtcblxuZnVuY3Rpb24gQmVhY2goKSB7XG4gIFJlZEJsYWNrTm9kZSh0aGlzKTtcbiAgdGhpcy5lZGdlID1cbiAgdGhpcy5zaXRlID1cbiAgdGhpcy5jaXJjbGUgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVCZWFjaChzaXRlKSB7XG4gIHZhciBiZWFjaCA9IGJlYWNoUG9vbC5wb3AoKSB8fCBuZXcgQmVhY2g7XG4gIGJlYWNoLnNpdGUgPSBzaXRlO1xuICByZXR1cm4gYmVhY2g7XG59XG5cbmZ1bmN0aW9uIGRldGFjaEJlYWNoKGJlYWNoKSB7XG4gIGRldGFjaENpcmNsZShiZWFjaCk7XG4gIGJlYWNoZXMucmVtb3ZlKGJlYWNoKTtcbiAgYmVhY2hQb29sLnB1c2goYmVhY2gpO1xuICBSZWRCbGFja05vZGUoYmVhY2gpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVCZWFjaChiZWFjaCkge1xuICB2YXIgY2lyY2xlID0gYmVhY2guY2lyY2xlLFxuICAgICAgeCA9IGNpcmNsZS54LFxuICAgICAgeSA9IGNpcmNsZS5jeSxcbiAgICAgIHZlcnRleCA9IFt4LCB5XSxcbiAgICAgIHByZXZpb3VzID0gYmVhY2guUCxcbiAgICAgIG5leHQgPSBiZWFjaC5OLFxuICAgICAgZGlzYXBwZWFyaW5nID0gW2JlYWNoXTtcblxuICBkZXRhY2hCZWFjaChiZWFjaCk7XG5cbiAgdmFyIGxBcmMgPSBwcmV2aW91cztcbiAgd2hpbGUgKGxBcmMuY2lyY2xlXG4gICAgICAmJiBNYXRoLmFicyh4IC0gbEFyYy5jaXJjbGUueCkgPCBlcHNpbG9uJDNcbiAgICAgICYmIE1hdGguYWJzKHkgLSBsQXJjLmNpcmNsZS5jeSkgPCBlcHNpbG9uJDMpIHtcbiAgICBwcmV2aW91cyA9IGxBcmMuUDtcbiAgICBkaXNhcHBlYXJpbmcudW5zaGlmdChsQXJjKTtcbiAgICBkZXRhY2hCZWFjaChsQXJjKTtcbiAgICBsQXJjID0gcHJldmlvdXM7XG4gIH1cblxuICBkaXNhcHBlYXJpbmcudW5zaGlmdChsQXJjKTtcbiAgZGV0YWNoQ2lyY2xlKGxBcmMpO1xuXG4gIHZhciByQXJjID0gbmV4dDtcbiAgd2hpbGUgKHJBcmMuY2lyY2xlXG4gICAgICAmJiBNYXRoLmFicyh4IC0gckFyYy5jaXJjbGUueCkgPCBlcHNpbG9uJDNcbiAgICAgICYmIE1hdGguYWJzKHkgLSByQXJjLmNpcmNsZS5jeSkgPCBlcHNpbG9uJDMpIHtcbiAgICBuZXh0ID0gckFyYy5OO1xuICAgIGRpc2FwcGVhcmluZy5wdXNoKHJBcmMpO1xuICAgIGRldGFjaEJlYWNoKHJBcmMpO1xuICAgIHJBcmMgPSBuZXh0O1xuICB9XG5cbiAgZGlzYXBwZWFyaW5nLnB1c2gockFyYyk7XG4gIGRldGFjaENpcmNsZShyQXJjKTtcblxuICB2YXIgbkFyY3MgPSBkaXNhcHBlYXJpbmcubGVuZ3RoLFxuICAgICAgaUFyYztcbiAgZm9yIChpQXJjID0gMTsgaUFyYyA8IG5BcmNzOyArK2lBcmMpIHtcbiAgICByQXJjID0gZGlzYXBwZWFyaW5nW2lBcmNdO1xuICAgIGxBcmMgPSBkaXNhcHBlYXJpbmdbaUFyYyAtIDFdO1xuICAgIHNldEVkZ2VFbmQockFyYy5lZGdlLCBsQXJjLnNpdGUsIHJBcmMuc2l0ZSwgdmVydGV4KTtcbiAgfVxuXG4gIGxBcmMgPSBkaXNhcHBlYXJpbmdbMF07XG4gIHJBcmMgPSBkaXNhcHBlYXJpbmdbbkFyY3MgLSAxXTtcbiAgckFyYy5lZGdlID0gY3JlYXRlRWRnZShsQXJjLnNpdGUsIHJBcmMuc2l0ZSwgbnVsbCwgdmVydGV4KTtcblxuICBhdHRhY2hDaXJjbGUobEFyYyk7XG4gIGF0dGFjaENpcmNsZShyQXJjKTtcbn1cblxuZnVuY3Rpb24gYWRkQmVhY2goc2l0ZSkge1xuICB2YXIgeCA9IHNpdGVbMF0sXG4gICAgICBkaXJlY3RyaXggPSBzaXRlWzFdLFxuICAgICAgbEFyYyxcbiAgICAgIHJBcmMsXG4gICAgICBkeGwsXG4gICAgICBkeHIsXG4gICAgICBub2RlID0gYmVhY2hlcy5fO1xuXG4gIHdoaWxlIChub2RlKSB7XG4gICAgZHhsID0gbGVmdEJyZWFrUG9pbnQobm9kZSwgZGlyZWN0cml4KSAtIHg7XG4gICAgaWYgKGR4bCA+IGVwc2lsb24kMykgbm9kZSA9IG5vZGUuTDsgZWxzZSB7XG4gICAgICBkeHIgPSB4IC0gcmlnaHRCcmVha1BvaW50KG5vZGUsIGRpcmVjdHJpeCk7XG4gICAgICBpZiAoZHhyID4gZXBzaWxvbiQzKSB7XG4gICAgICAgIGlmICghbm9kZS5SKSB7XG4gICAgICAgICAgbEFyYyA9IG5vZGU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZSA9IG5vZGUuUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChkeGwgPiAtZXBzaWxvbiQzKSB7XG4gICAgICAgICAgbEFyYyA9IG5vZGUuUDtcbiAgICAgICAgICByQXJjID0gbm9kZTtcbiAgICAgICAgfSBlbHNlIGlmIChkeHIgPiAtZXBzaWxvbiQzKSB7XG4gICAgICAgICAgbEFyYyA9IG5vZGU7XG4gICAgICAgICAgckFyYyA9IG5vZGUuTjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsQXJjID0gckFyYyA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlQ2VsbChzaXRlKTtcbiAgdmFyIG5ld0FyYyA9IGNyZWF0ZUJlYWNoKHNpdGUpO1xuICBiZWFjaGVzLmluc2VydChsQXJjLCBuZXdBcmMpO1xuXG4gIGlmICghbEFyYyAmJiAhckFyYykgcmV0dXJuO1xuXG4gIGlmIChsQXJjID09PSByQXJjKSB7XG4gICAgZGV0YWNoQ2lyY2xlKGxBcmMpO1xuICAgIHJBcmMgPSBjcmVhdGVCZWFjaChsQXJjLnNpdGUpO1xuICAgIGJlYWNoZXMuaW5zZXJ0KG5ld0FyYywgckFyYyk7XG4gICAgbmV3QXJjLmVkZ2UgPSByQXJjLmVkZ2UgPSBjcmVhdGVFZGdlKGxBcmMuc2l0ZSwgbmV3QXJjLnNpdGUpO1xuICAgIGF0dGFjaENpcmNsZShsQXJjKTtcbiAgICBhdHRhY2hDaXJjbGUockFyYyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCFyQXJjKSB7IC8vICYmIGxBcmNcbiAgICBuZXdBcmMuZWRnZSA9IGNyZWF0ZUVkZ2UobEFyYy5zaXRlLCBuZXdBcmMuc2l0ZSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZWxzZSBsQXJjICE9PSByQXJjXG4gIGRldGFjaENpcmNsZShsQXJjKTtcbiAgZGV0YWNoQ2lyY2xlKHJBcmMpO1xuXG4gIHZhciBsU2l0ZSA9IGxBcmMuc2l0ZSxcbiAgICAgIGF4ID0gbFNpdGVbMF0sXG4gICAgICBheSA9IGxTaXRlWzFdLFxuICAgICAgYnggPSBzaXRlWzBdIC0gYXgsXG4gICAgICBieSA9IHNpdGVbMV0gLSBheSxcbiAgICAgIHJTaXRlID0gckFyYy5zaXRlLFxuICAgICAgY3ggPSByU2l0ZVswXSAtIGF4LFxuICAgICAgY3kgPSByU2l0ZVsxXSAtIGF5LFxuICAgICAgZCA9IDIgKiAoYnggKiBjeSAtIGJ5ICogY3gpLFxuICAgICAgaGIgPSBieCAqIGJ4ICsgYnkgKiBieSxcbiAgICAgIGhjID0gY3ggKiBjeCArIGN5ICogY3ksXG4gICAgICB2ZXJ0ZXggPSBbKGN5ICogaGIgLSBieSAqIGhjKSAvIGQgKyBheCwgKGJ4ICogaGMgLSBjeCAqIGhiKSAvIGQgKyBheV07XG5cbiAgc2V0RWRnZUVuZChyQXJjLmVkZ2UsIGxTaXRlLCByU2l0ZSwgdmVydGV4KTtcbiAgbmV3QXJjLmVkZ2UgPSBjcmVhdGVFZGdlKGxTaXRlLCBzaXRlLCBudWxsLCB2ZXJ0ZXgpO1xuICByQXJjLmVkZ2UgPSBjcmVhdGVFZGdlKHNpdGUsIHJTaXRlLCBudWxsLCB2ZXJ0ZXgpO1xuICBhdHRhY2hDaXJjbGUobEFyYyk7XG4gIGF0dGFjaENpcmNsZShyQXJjKTtcbn1cblxuZnVuY3Rpb24gbGVmdEJyZWFrUG9pbnQoYXJjLCBkaXJlY3RyaXgpIHtcbiAgdmFyIHNpdGUgPSBhcmMuc2l0ZSxcbiAgICAgIHJmb2N4ID0gc2l0ZVswXSxcbiAgICAgIHJmb2N5ID0gc2l0ZVsxXSxcbiAgICAgIHBieTIgPSByZm9jeSAtIGRpcmVjdHJpeDtcblxuICBpZiAoIXBieTIpIHJldHVybiByZm9jeDtcblxuICB2YXIgbEFyYyA9IGFyYy5QO1xuICBpZiAoIWxBcmMpIHJldHVybiAtSW5maW5pdHk7XG5cbiAgc2l0ZSA9IGxBcmMuc2l0ZTtcbiAgdmFyIGxmb2N4ID0gc2l0ZVswXSxcbiAgICAgIGxmb2N5ID0gc2l0ZVsxXSxcbiAgICAgIHBsYnkyID0gbGZvY3kgLSBkaXJlY3RyaXg7XG5cbiAgaWYgKCFwbGJ5MikgcmV0dXJuIGxmb2N4O1xuXG4gIHZhciBobCA9IGxmb2N4IC0gcmZvY3gsXG4gICAgICBhYnkyID0gMSAvIHBieTIgLSAxIC8gcGxieTIsXG4gICAgICBiID0gaGwgLyBwbGJ5MjtcblxuICBpZiAoYWJ5MikgcmV0dXJuICgtYiArIE1hdGguc3FydChiICogYiAtIDIgKiBhYnkyICogKGhsICogaGwgLyAoLTIgKiBwbGJ5MikgLSBsZm9jeSArIHBsYnkyIC8gMiArIHJmb2N5IC0gcGJ5MiAvIDIpKSkgLyBhYnkyICsgcmZvY3g7XG5cbiAgcmV0dXJuIChyZm9jeCArIGxmb2N4KSAvIDI7XG59XG5cbmZ1bmN0aW9uIHJpZ2h0QnJlYWtQb2ludChhcmMsIGRpcmVjdHJpeCkge1xuICB2YXIgckFyYyA9IGFyYy5OO1xuICBpZiAockFyYykgcmV0dXJuIGxlZnRCcmVha1BvaW50KHJBcmMsIGRpcmVjdHJpeCk7XG4gIHZhciBzaXRlID0gYXJjLnNpdGU7XG4gIHJldHVybiBzaXRlWzFdID09PSBkaXJlY3RyaXggPyBzaXRlWzBdIDogSW5maW5pdHk7XG59XG5cbnZhciBlcHNpbG9uJDMgPSAxZS02O1xudmFyIGVwc2lsb24yJDEgPSAxZS0xMjtcbnZhciBiZWFjaGVzO1xudmFyIGNlbGxzO1xudmFyIGNpcmNsZXM7XG52YXIgZWRnZXM7XG5cbmZ1bmN0aW9uIHRyaWFuZ2xlQXJlYShhLCBiLCBjKSB7XG4gIHJldHVybiAoYVswXSAtIGNbMF0pICogKGJbMV0gLSBhWzFdKSAtIChhWzBdIC0gYlswXSkgKiAoY1sxXSAtIGFbMV0pO1xufVxuXG5mdW5jdGlvbiBsZXhpY29ncmFwaGljKGEsIGIpIHtcbiAgcmV0dXJuIGJbMV0gLSBhWzFdXG4gICAgICB8fCBiWzBdIC0gYVswXTtcbn1cblxuZnVuY3Rpb24gRGlhZ3JhbShzaXRlcywgZXh0ZW50KSB7XG4gIHZhciBzaXRlID0gc2l0ZXMuc29ydChsZXhpY29ncmFwaGljKS5wb3AoKSxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgY2lyY2xlO1xuXG4gIGVkZ2VzID0gW107XG4gIGNlbGxzID0gbmV3IEFycmF5KHNpdGVzLmxlbmd0aCk7XG4gIGJlYWNoZXMgPSBuZXcgUmVkQmxhY2tUcmVlO1xuICBjaXJjbGVzID0gbmV3IFJlZEJsYWNrVHJlZTtcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNpcmNsZSA9IGZpcnN0Q2lyY2xlO1xuICAgIGlmIChzaXRlICYmICghY2lyY2xlIHx8IHNpdGVbMV0gPCBjaXJjbGUueSB8fCAoc2l0ZVsxXSA9PT0gY2lyY2xlLnkgJiYgc2l0ZVswXSA8IGNpcmNsZS54KSkpIHtcbiAgICAgIGlmIChzaXRlWzBdICE9PSB4IHx8IHNpdGVbMV0gIT09IHkpIHtcbiAgICAgICAgYWRkQmVhY2goc2l0ZSk7XG4gICAgICAgIHggPSBzaXRlWzBdLCB5ID0gc2l0ZVsxXTtcbiAgICAgIH1cbiAgICAgIHNpdGUgPSBzaXRlcy5wb3AoKTtcbiAgICB9IGVsc2UgaWYgKGNpcmNsZSkge1xuICAgICAgcmVtb3ZlQmVhY2goY2lyY2xlLmFyYyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNvcnRDZWxsSGFsZmVkZ2VzKCk7XG5cbiAgaWYgKGV4dGVudCkge1xuICAgIHZhciB4MCA9ICtleHRlbnRbMF1bMF0sXG4gICAgICAgIHkwID0gK2V4dGVudFswXVsxXSxcbiAgICAgICAgeDEgPSArZXh0ZW50WzFdWzBdLFxuICAgICAgICB5MSA9ICtleHRlbnRbMV1bMV07XG4gICAgY2xpcEVkZ2VzKHgwLCB5MCwgeDEsIHkxKTtcbiAgICBjbGlwQ2VsbHMoeDAsIHkwLCB4MSwgeTEpO1xuICB9XG5cbiAgdGhpcy5lZGdlcyA9IGVkZ2VzO1xuICB0aGlzLmNlbGxzID0gY2VsbHM7XG5cbiAgYmVhY2hlcyA9XG4gIGNpcmNsZXMgPVxuICBlZGdlcyA9XG4gIGNlbGxzID0gbnVsbDtcbn1cblxuRGlhZ3JhbS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBEaWFncmFtLFxuXG4gIHBvbHlnb25zOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgZWRnZXMgPSB0aGlzLmVkZ2VzO1xuXG4gICAgcmV0dXJuIHRoaXMuY2VsbHMubWFwKGZ1bmN0aW9uKGNlbGwpIHtcbiAgICAgIHZhciBwb2x5Z29uID0gY2VsbC5oYWxmZWRnZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIGNlbGxIYWxmZWRnZVN0YXJ0KGNlbGwsIGVkZ2VzW2ldKTsgfSk7XG4gICAgICBwb2x5Z29uLmRhdGEgPSBjZWxsLnNpdGUuZGF0YTtcbiAgICAgIHJldHVybiBwb2x5Z29uO1xuICAgIH0pO1xuICB9LFxuXG4gIHRyaWFuZ2xlczogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHRyaWFuZ2xlcyA9IFtdLFxuICAgICAgICBlZGdlcyA9IHRoaXMuZWRnZXM7XG5cbiAgICB0aGlzLmNlbGxzLmZvckVhY2goZnVuY3Rpb24oY2VsbCwgaSkge1xuICAgICAgdmFyIHNpdGUgPSBjZWxsLnNpdGUsXG4gICAgICAgICAgaGFsZmVkZ2VzID0gY2VsbC5oYWxmZWRnZXMsXG4gICAgICAgICAgaiA9IC0xLFxuICAgICAgICAgIG0gPSBoYWxmZWRnZXMubGVuZ3RoLFxuICAgICAgICAgIHMwLFxuICAgICAgICAgIGUxID0gZWRnZXNbaGFsZmVkZ2VzW20gLSAxXV0sXG4gICAgICAgICAgczEgPSBlMS5sZWZ0ID09PSBzaXRlID8gZTEucmlnaHQgOiBlMS5sZWZ0O1xuXG4gICAgICB3aGlsZSAoKytqIDwgbSkge1xuICAgICAgICBzMCA9IHMxO1xuICAgICAgICBlMSA9IGVkZ2VzW2hhbGZlZGdlc1tqXV07XG4gICAgICAgIHMxID0gZTEubGVmdCA9PT0gc2l0ZSA/IGUxLnJpZ2h0IDogZTEubGVmdDtcbiAgICAgICAgaWYgKHMwICYmIHMxICYmIGkgPCBzMC5pbmRleCAmJiBpIDwgczEuaW5kZXggJiYgdHJpYW5nbGVBcmVhKHNpdGUsIHMwLCBzMSkgPCAwKSB7XG4gICAgICAgICAgdHJpYW5nbGVzLnB1c2goW3NpdGUuZGF0YSwgczAuZGF0YSwgczEuZGF0YV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdHJpYW5nbGVzO1xuICB9LFxuXG4gIGxpbmtzOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5lZGdlcy5maWx0ZXIoZnVuY3Rpb24oZWRnZSkge1xuICAgICAgcmV0dXJuIGVkZ2UucmlnaHQ7XG4gICAgfSkubWFwKGZ1bmN0aW9uKGVkZ2UpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNvdXJjZTogZWRnZS5sZWZ0LmRhdGEsXG4gICAgICAgIHRhcmdldDogZWRnZS5yaWdodC5kYXRhXG4gICAgICB9O1xuICAgIH0pO1xuICB9LFxuXG4gIGZpbmQ6IGZ1bmN0aW9uKHgsIHksIHJhZGl1cykge1xuICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgaTAsIGkxID0gdGhhdC5fZm91bmQgfHwgMCxcbiAgICAgICAgY2VsbCA9IHRoYXQuY2VsbHNbaTFdIHx8IHRoYXQuY2VsbHNbaTEgPSAwXSxcbiAgICAgICAgZHggPSB4IC0gY2VsbC5zaXRlWzBdLFxuICAgICAgICBkeSA9IHkgLSBjZWxsLnNpdGVbMV0sXG4gICAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHk7XG5cbiAgICBkbyB7XG4gICAgICBjZWxsID0gdGhhdC5jZWxsc1tpMCA9IGkxXSwgaTEgPSBudWxsO1xuICAgICAgY2VsbC5oYWxmZWRnZXMuZm9yRWFjaChmdW5jdGlvbihlKSB7XG4gICAgICAgIHZhciBlZGdlID0gdGhhdC5lZGdlc1tlXSwgdiA9IGVkZ2UubGVmdDtcbiAgICAgICAgaWYgKCh2ID09PSBjZWxsLnNpdGUgfHwgIXYpICYmICEodiA9IGVkZ2UucmlnaHQpKSByZXR1cm47XG4gICAgICAgIHZhciB2eCA9IHggLSB2WzBdLFxuICAgICAgICAgICAgdnkgPSB5IC0gdlsxXSxcbiAgICAgICAgICAgIHYyID0gdnggKiB2eCArIHZ5ICogdnk7XG4gICAgICAgIGlmICh2MiA8IGQyKSBkMiA9IHYyLCBpMSA9IHYuaW5kZXg7XG4gICAgICB9KTtcbiAgICB9IHdoaWxlIChpMSAhPT0gbnVsbCk7XG5cbiAgICB0aGF0Ll9mb3VuZCA9IGkwO1xuXG4gICAgcmV0dXJuIHJhZGl1cyA9PSBudWxsIHx8IGQyIDw9IHJhZGl1cyAqIHJhZGl1cyA/IGNlbGwuc2l0ZSA6IG51bGw7XG4gIH1cbn07XG5cbnZhciB2b3Jvbm9pID0gZnVuY3Rpb24oKSB7XG4gIHZhciB4JCQxID0geCQ0LFxuICAgICAgeSQkMSA9IHkkNCxcbiAgICAgIGV4dGVudCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gdm9yb25vaShkYXRhKSB7XG4gICAgcmV0dXJuIG5ldyBEaWFncmFtKGRhdGEubWFwKGZ1bmN0aW9uKGQsIGkpIHtcbiAgICAgIHZhciBzID0gW01hdGgucm91bmQoeCQkMShkLCBpLCBkYXRhKSAvIGVwc2lsb24kMykgKiBlcHNpbG9uJDMsIE1hdGgucm91bmQoeSQkMShkLCBpLCBkYXRhKSAvIGVwc2lsb24kMykgKiBlcHNpbG9uJDNdO1xuICAgICAgcy5pbmRleCA9IGk7XG4gICAgICBzLmRhdGEgPSBkO1xuICAgICAgcmV0dXJuIHM7XG4gICAgfSksIGV4dGVudCk7XG4gIH1cblxuICB2b3Jvbm9pLnBvbHlnb25zID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIHJldHVybiB2b3Jvbm9pKGRhdGEpLnBvbHlnb25zKCk7XG4gIH07XG5cbiAgdm9yb25vaS5saW5rcyA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICByZXR1cm4gdm9yb25vaShkYXRhKS5saW5rcygpO1xuICB9O1xuXG4gIHZvcm9ub2kudHJpYW5nbGVzID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIHJldHVybiB2b3Jvbm9pKGRhdGEpLnRyaWFuZ2xlcygpO1xuICB9O1xuXG4gIHZvcm9ub2kueCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4JCQxID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ5KCtfKSwgdm9yb25vaSkgOiB4JCQxO1xuICB9O1xuXG4gIHZvcm9ub2kueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5JCQxID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ5KCtfKSwgdm9yb25vaSkgOiB5JCQxO1xuICB9O1xuXG4gIHZvcm9ub2kuZXh0ZW50ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGV4dGVudCA9IF8gPT0gbnVsbCA/IG51bGwgOiBbWytfWzBdWzBdLCArX1swXVsxXV0sIFsrX1sxXVswXSwgK19bMV1bMV1dXSwgdm9yb25vaSkgOiBleHRlbnQgJiYgW1tleHRlbnRbMF1bMF0sIGV4dGVudFswXVsxXV0sIFtleHRlbnRbMV1bMF0sIGV4dGVudFsxXVsxXV1dO1xuICB9O1xuXG4gIHZvcm9ub2kuc2l6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChleHRlbnQgPSBfID09IG51bGwgPyBudWxsIDogW1swLCAwXSwgWytfWzBdLCArX1sxXV1dLCB2b3Jvbm9pKSA6IGV4dGVudCAmJiBbZXh0ZW50WzFdWzBdIC0gZXh0ZW50WzBdWzBdLCBleHRlbnRbMV1bMV0gLSBleHRlbnRbMF1bMV1dO1xuICB9O1xuXG4gIHJldHVybiB2b3Jvbm9pO1xufTtcblxudmFyIGNvbnN0YW50JDEwID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG5mdW5jdGlvbiBab29tRXZlbnQodGFyZ2V0LCB0eXBlLCB0cmFuc2Zvcm0pIHtcbiAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG4gIHRoaXMudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xufVxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0oaywgeCwgeSkge1xuICB0aGlzLmsgPSBrO1xuICB0aGlzLnggPSB4O1xuICB0aGlzLnkgPSB5O1xufVxuXG5UcmFuc2Zvcm0ucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogVHJhbnNmb3JtLFxuICBzY2FsZTogZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBrID09PSAxID8gdGhpcyA6IG5ldyBUcmFuc2Zvcm0odGhpcy5rICogaywgdGhpcy54LCB0aGlzLnkpO1xuICB9LFxuICB0cmFuc2xhdGU6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICByZXR1cm4geCA9PT0gMCAmIHkgPT09IDAgPyB0aGlzIDogbmV3IFRyYW5zZm9ybSh0aGlzLmssIHRoaXMueCArIHRoaXMuayAqIHgsIHRoaXMueSArIHRoaXMuayAqIHkpO1xuICB9LFxuICBhcHBseTogZnVuY3Rpb24ocG9pbnQpIHtcbiAgICByZXR1cm4gW3BvaW50WzBdICogdGhpcy5rICsgdGhpcy54LCBwb2ludFsxXSAqIHRoaXMuayArIHRoaXMueV07XG4gIH0sXG4gIGFwcGx5WDogZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiB4ICogdGhpcy5rICsgdGhpcy54O1xuICB9LFxuICBhcHBseVk6IGZ1bmN0aW9uKHkpIHtcbiAgICByZXR1cm4geSAqIHRoaXMuayArIHRoaXMueTtcbiAgfSxcbiAgaW52ZXJ0OiBmdW5jdGlvbihsb2NhdGlvbikge1xuICAgIHJldHVybiBbKGxvY2F0aW9uWzBdIC0gdGhpcy54KSAvIHRoaXMuaywgKGxvY2F0aW9uWzFdIC0gdGhpcy55KSAvIHRoaXMua107XG4gIH0sXG4gIGludmVydFg6IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gKHggLSB0aGlzLngpIC8gdGhpcy5rO1xuICB9LFxuICBpbnZlcnRZOiBmdW5jdGlvbih5KSB7XG4gICAgcmV0dXJuICh5IC0gdGhpcy55KSAvIHRoaXMuaztcbiAgfSxcbiAgcmVzY2FsZVg6IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4geC5jb3B5KCkuZG9tYWluKHgucmFuZ2UoKS5tYXAodGhpcy5pbnZlcnRYLCB0aGlzKS5tYXAoeC5pbnZlcnQsIHgpKTtcbiAgfSxcbiAgcmVzY2FsZVk6IGZ1bmN0aW9uKHkpIHtcbiAgICByZXR1cm4geS5jb3B5KCkuZG9tYWluKHkucmFuZ2UoKS5tYXAodGhpcy5pbnZlcnRZLCB0aGlzKS5tYXAoeS5pbnZlcnQsIHkpKTtcbiAgfSxcbiAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBcInRyYW5zbGF0ZShcIiArIHRoaXMueCArIFwiLFwiICsgdGhpcy55ICsgXCIpIHNjYWxlKFwiICsgdGhpcy5rICsgXCIpXCI7XG4gIH1cbn07XG5cbnZhciBpZGVudGl0eSQ2ID0gbmV3IFRyYW5zZm9ybSgxLCAwLCAwKTtcblxudHJhbnNmb3JtLnByb3RvdHlwZSA9IFRyYW5zZm9ybS5wcm90b3R5cGU7XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybShub2RlKSB7XG4gIHJldHVybiBub2RlLl9fem9vbSB8fCBpZGVudGl0eSQ2O1xufVxuXG5mdW5jdGlvbiBub3Byb3BhZ2F0aW9uJDEoKSB7XG4gIGV4cG9ydHMuZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG59XG5cbnZhciBub2V2ZW50JDEgPSBmdW5jdGlvbigpIHtcbiAgZXhwb3J0cy5ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICBleHBvcnRzLmV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xufTtcblxuLy8gSWdub3JlIHJpZ2h0LWNsaWNrLCBzaW5jZSB0aGF0IHNob3VsZCBvcGVuIHRoZSBjb250ZXh0IG1lbnUuXG5mdW5jdGlvbiBkZWZhdWx0RmlsdGVyJDEoKSB7XG4gIHJldHVybiAhZXhwb3J0cy5ldmVudC5idXR0b247XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRFeHRlbnQoKSB7XG4gIHZhciBlID0gdGhpcywgdywgaDtcbiAgaWYgKGUgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSB7XG4gICAgZSA9IGUub3duZXJTVkdFbGVtZW50IHx8IGU7XG4gICAgdyA9IGUud2lkdGguYmFzZVZhbC52YWx1ZTtcbiAgICBoID0gZS5oZWlnaHQuYmFzZVZhbC52YWx1ZTtcbiAgfSBlbHNlIHtcbiAgICB3ID0gZS5jbGllbnRXaWR0aDtcbiAgICBoID0gZS5jbGllbnRIZWlnaHQ7XG4gIH1cbiAgcmV0dXJuIFtbMCwgMF0sIFt3LCBoXV07XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRUcmFuc2Zvcm0oKSB7XG4gIHJldHVybiB0aGlzLl9fem9vbSB8fCBpZGVudGl0eSQ2O1xufVxuXG52YXIgem9vbSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZmlsdGVyID0gZGVmYXVsdEZpbHRlciQxLFxuICAgICAgZXh0ZW50ID0gZGVmYXVsdEV4dGVudCxcbiAgICAgIGswID0gMCxcbiAgICAgIGsxID0gSW5maW5pdHksXG4gICAgICB4MCA9IC1rMSxcbiAgICAgIHgxID0gazEsXG4gICAgICB5MCA9IHgwLFxuICAgICAgeTEgPSB4MSxcbiAgICAgIGR1cmF0aW9uID0gMjUwLFxuICAgICAgaW50ZXJwb2xhdGUkJDEgPSBpbnRlcnBvbGF0ZVpvb20sXG4gICAgICBnZXN0dXJlcyA9IFtdLFxuICAgICAgbGlzdGVuZXJzID0gZGlzcGF0Y2goXCJzdGFydFwiLCBcInpvb21cIiwgXCJlbmRcIiksXG4gICAgICB0b3VjaHN0YXJ0aW5nLFxuICAgICAgdG91Y2hlbmRpbmcsXG4gICAgICB0b3VjaERlbGF5ID0gNTAwLFxuICAgICAgd2hlZWxEZWxheSA9IDE1MDtcblxuICBmdW5jdGlvbiB6b29tKHNlbGVjdGlvbiQkMSkge1xuICAgIHNlbGVjdGlvbiQkMVxuICAgICAgICAub24oXCJ3aGVlbC56b29tXCIsIHdoZWVsZWQpXG4gICAgICAgIC5vbihcIm1vdXNlZG93bi56b29tXCIsIG1vdXNlZG93bmVkKVxuICAgICAgICAub24oXCJkYmxjbGljay56b29tXCIsIGRibGNsaWNrZWQpXG4gICAgICAgIC5vbihcInRvdWNoc3RhcnQuem9vbVwiLCB0b3VjaHN0YXJ0ZWQpXG4gICAgICAgIC5vbihcInRvdWNobW92ZS56b29tXCIsIHRvdWNobW92ZWQpXG4gICAgICAgIC5vbihcInRvdWNoZW5kLnpvb20gdG91Y2hjYW5jZWwuem9vbVwiLCB0b3VjaGVuZGVkKVxuICAgICAgICAuc3R5bGUoXCItd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3JcIiwgXCJyZ2JhKDAsMCwwLDApXCIpXG4gICAgICAgIC5wcm9wZXJ0eShcIl9fem9vbVwiLCBkZWZhdWx0VHJhbnNmb3JtKTtcbiAgfVxuXG4gIHpvb20udHJhbnNmb3JtID0gZnVuY3Rpb24oY29sbGVjdGlvbiwgdHJhbnNmb3JtKSB7XG4gICAgdmFyIHNlbGVjdGlvbiQkMSA9IGNvbGxlY3Rpb24uc2VsZWN0aW9uID8gY29sbGVjdGlvbi5zZWxlY3Rpb24oKSA6IGNvbGxlY3Rpb247XG4gICAgc2VsZWN0aW9uJCQxLnByb3BlcnR5KFwiX196b29tXCIsIGRlZmF1bHRUcmFuc2Zvcm0pO1xuICAgIGlmIChjb2xsZWN0aW9uICE9PSBzZWxlY3Rpb24kJDEpIHtcbiAgICAgIHNjaGVkdWxlKGNvbGxlY3Rpb24sIHRyYW5zZm9ybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGlvbiQkMS5pbnRlcnJ1cHQoKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICBnZXN0dXJlKHRoaXMsIGFyZ3VtZW50cylcbiAgICAgICAgICAgIC5zdGFydCgpXG4gICAgICAgICAgICAuem9vbShudWxsLCB0eXBlb2YgdHJhbnNmb3JtID09PSBcImZ1bmN0aW9uXCIgPyB0cmFuc2Zvcm0uYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IHRyYW5zZm9ybSlcbiAgICAgICAgICAgIC5lbmQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICB6b29tLnNjYWxlQnkgPSBmdW5jdGlvbihzZWxlY3Rpb24kJDEsIGspIHtcbiAgICB6b29tLnNjYWxlVG8oc2VsZWN0aW9uJCQxLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBrMCA9IHRoaXMuX196b29tLmssXG4gICAgICAgICAgazEgPSB0eXBlb2YgayA9PT0gXCJmdW5jdGlvblwiID8gay5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogaztcbiAgICAgIHJldHVybiBrMCAqIGsxO1xuICAgIH0pO1xuICB9O1xuXG4gIHpvb20uc2NhbGVUbyA9IGZ1bmN0aW9uKHNlbGVjdGlvbiQkMSwgaykge1xuICAgIHpvb20udHJhbnNmb3JtKHNlbGVjdGlvbiQkMSwgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZSA9IGV4dGVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICAgIHQwID0gdGhpcy5fX3pvb20sXG4gICAgICAgICAgcDAgPSBjZW50cm9pZChlKSxcbiAgICAgICAgICBwMSA9IHQwLmludmVydChwMCksXG4gICAgICAgICAgazEgPSB0eXBlb2YgayA9PT0gXCJmdW5jdGlvblwiID8gay5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogaztcbiAgICAgIHJldHVybiBjb25zdHJhaW4odHJhbnNsYXRlKHNjYWxlKHQwLCBrMSksIHAwLCBwMSksIGUpO1xuICAgIH0pO1xuICB9O1xuXG4gIHpvb20udHJhbnNsYXRlQnkgPSBmdW5jdGlvbihzZWxlY3Rpb24kJDEsIHgsIHkpIHtcbiAgICB6b29tLnRyYW5zZm9ybShzZWxlY3Rpb24kJDEsIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGNvbnN0cmFpbih0aGlzLl9fem9vbS50cmFuc2xhdGUoXG4gICAgICAgIHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIgPyB4LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiB4LFxuICAgICAgICB0eXBlb2YgeSA9PT0gXCJmdW5jdGlvblwiID8geS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogeVxuICAgICAgKSwgZXh0ZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuICAgIH0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHNjYWxlKHRyYW5zZm9ybSwgaykge1xuICAgIGsgPSBNYXRoLm1heChrMCwgTWF0aC5taW4oazEsIGspKTtcbiAgICByZXR1cm4gayA9PT0gdHJhbnNmb3JtLmsgPyB0cmFuc2Zvcm0gOiBuZXcgVHJhbnNmb3JtKGssIHRyYW5zZm9ybS54LCB0cmFuc2Zvcm0ueSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2xhdGUodHJhbnNmb3JtLCBwMCwgcDEpIHtcbiAgICB2YXIgeCA9IHAwWzBdIC0gcDFbMF0gKiB0cmFuc2Zvcm0uaywgeSA9IHAwWzFdIC0gcDFbMV0gKiB0cmFuc2Zvcm0uaztcbiAgICByZXR1cm4geCA9PT0gdHJhbnNmb3JtLnggJiYgeSA9PT0gdHJhbnNmb3JtLnkgPyB0cmFuc2Zvcm0gOiBuZXcgVHJhbnNmb3JtKHRyYW5zZm9ybS5rLCB4LCB5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnN0cmFpbih0cmFuc2Zvcm0sIGV4dGVudCkge1xuICAgIHZhciBkeDAgPSB0cmFuc2Zvcm0uaW52ZXJ0WChleHRlbnRbMF1bMF0pIC0geDAsXG4gICAgICAgIGR4MSA9IHRyYW5zZm9ybS5pbnZlcnRYKGV4dGVudFsxXVswXSkgLSB4MSxcbiAgICAgICAgZHkwID0gdHJhbnNmb3JtLmludmVydFkoZXh0ZW50WzBdWzFdKSAtIHkwLFxuICAgICAgICBkeTEgPSB0cmFuc2Zvcm0uaW52ZXJ0WShleHRlbnRbMV1bMV0pIC0geTE7XG4gICAgcmV0dXJuIHRyYW5zZm9ybS50cmFuc2xhdGUoXG4gICAgICBkeDEgPiBkeDAgPyAoZHgwICsgZHgxKSAvIDIgOiBNYXRoLm1pbigwLCBkeDApIHx8IE1hdGgubWF4KDAsIGR4MSksXG4gICAgICBkeTEgPiBkeTAgPyAoZHkwICsgZHkxKSAvIDIgOiBNYXRoLm1pbigwLCBkeTApIHx8IE1hdGgubWF4KDAsIGR5MSlcbiAgICApO1xuICB9XG5cbiAgZnVuY3Rpb24gY2VudHJvaWQoZXh0ZW50KSB7XG4gICAgcmV0dXJuIFsoK2V4dGVudFswXVswXSArICtleHRlbnRbMV1bMF0pIC8gMiwgKCtleHRlbnRbMF1bMV0gKyArZXh0ZW50WzFdWzFdKSAvIDJdO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NoZWR1bGUodHJhbnNpdGlvbiQkMSwgdHJhbnNmb3JtLCBjZW50ZXIpIHtcbiAgICB0cmFuc2l0aW9uJCQxXG4gICAgICAgIC5vbihcInN0YXJ0Lnpvb21cIiwgZnVuY3Rpb24oKSB7IGdlc3R1cmUodGhpcywgYXJndW1lbnRzKS5zdGFydCgpOyB9KVxuICAgICAgICAub24oXCJpbnRlcnJ1cHQuem9vbSBlbmQuem9vbVwiLCBmdW5jdGlvbigpIHsgZ2VzdHVyZSh0aGlzLCBhcmd1bWVudHMpLmVuZCgpOyB9KVxuICAgICAgICAudHdlZW4oXCJ6b29tXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICAgICAgZyA9IGdlc3R1cmUodGhhdCwgYXJncyksXG4gICAgICAgICAgICAgIGUgPSBleHRlbnQuYXBwbHkodGhhdCwgYXJncyksXG4gICAgICAgICAgICAgIHAgPSBjZW50ZXIgfHwgY2VudHJvaWQoZSksXG4gICAgICAgICAgICAgIHcgPSBNYXRoLm1heChlWzFdWzBdIC0gZVswXVswXSwgZVsxXVsxXSAtIGVbMF1bMV0pLFxuICAgICAgICAgICAgICBhID0gdGhhdC5fX3pvb20sXG4gICAgICAgICAgICAgIGIgPSB0eXBlb2YgdHJhbnNmb3JtID09PSBcImZ1bmN0aW9uXCIgPyB0cmFuc2Zvcm0uYXBwbHkodGhhdCwgYXJncykgOiB0cmFuc2Zvcm0sXG4gICAgICAgICAgICAgIGkgPSBpbnRlcnBvbGF0ZSQkMShhLmludmVydChwKS5jb25jYXQodyAvIGEuayksIGIuaW52ZXJ0KHApLmNvbmNhdCh3IC8gYi5rKSk7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgICAgIGlmICh0ID09PSAxKSB0ID0gYjsgLy8gQXZvaWQgcm91bmRpbmcgZXJyb3Igb24gZW5kLlxuICAgICAgICAgICAgZWxzZSB7IHZhciBsID0gaSh0KSwgayA9IHcgLyBsWzJdOyB0ID0gbmV3IFRyYW5zZm9ybShrLCBwWzBdIC0gbFswXSAqIGssIHBbMV0gLSBsWzFdICogayk7IH1cbiAgICAgICAgICAgIGcuem9vbShudWxsLCB0KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdlc3R1cmUodGhhdCwgYXJncykge1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gZ2VzdHVyZXMubGVuZ3RoLCBnOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKGcgPSBnZXN0dXJlc1tpXSkudGhhdCA9PT0gdGhhdCkge1xuICAgICAgICByZXR1cm4gZztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBHZXN0dXJlKHRoYXQsIGFyZ3MpO1xuICB9XG5cbiAgZnVuY3Rpb24gR2VzdHVyZSh0aGF0LCBhcmdzKSB7XG4gICAgdGhpcy50aGF0ID0gdGhhdDtcbiAgICB0aGlzLmFyZ3MgPSBhcmdzO1xuICAgIHRoaXMuaW5kZXggPSAtMTtcbiAgICB0aGlzLmFjdGl2ZSA9IDA7XG4gICAgdGhpcy5leHRlbnQgPSBleHRlbnQuYXBwbHkodGhhdCwgYXJncyk7XG4gIH1cblxuICBHZXN0dXJlLnByb3RvdHlwZSA9IHtcbiAgICBzdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoKyt0aGlzLmFjdGl2ZSA9PT0gMSkge1xuICAgICAgICB0aGlzLmluZGV4ID0gZ2VzdHVyZXMucHVzaCh0aGlzKSAtIDE7XG4gICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICB6b29tOiBmdW5jdGlvbihrZXksIHRyYW5zZm9ybSkge1xuICAgICAgaWYgKHRoaXMubW91c2UgJiYga2V5ICE9PSBcIm1vdXNlXCIpIHRoaXMubW91c2VbMV0gPSB0cmFuc2Zvcm0uaW52ZXJ0KHRoaXMubW91c2VbMF0pO1xuICAgICAgaWYgKHRoaXMudG91Y2gwICYmIGtleSAhPT0gXCJ0b3VjaFwiKSB0aGlzLnRvdWNoMFsxXSA9IHRyYW5zZm9ybS5pbnZlcnQodGhpcy50b3VjaDBbMF0pO1xuICAgICAgaWYgKHRoaXMudG91Y2gxICYmIGtleSAhPT0gXCJ0b3VjaFwiKSB0aGlzLnRvdWNoMVsxXSA9IHRyYW5zZm9ybS5pbnZlcnQodGhpcy50b3VjaDFbMF0pO1xuICAgICAgdGhpcy50aGF0Ll9fem9vbSA9IHRyYW5zZm9ybTtcbiAgICAgIHRoaXMuZW1pdChcInpvb21cIik7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGVuZDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoLS10aGlzLmFjdGl2ZSA9PT0gMCkge1xuICAgICAgICBnZXN0dXJlcy5zcGxpY2UodGhpcy5pbmRleCwgMSk7XG4gICAgICAgIHRoaXMuaW5kZXggPSAtMTtcbiAgICAgICAgdGhpcy5lbWl0KFwiZW5kXCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBlbWl0OiBmdW5jdGlvbih0eXBlKSB7XG4gICAgICBjdXN0b21FdmVudChuZXcgWm9vbUV2ZW50KHpvb20sIHR5cGUsIHRoaXMudGhhdC5fX3pvb20pLCBsaXN0ZW5lcnMuYXBwbHksIGxpc3RlbmVycywgW3R5cGUsIHRoaXMudGhhdCwgdGhpcy5hcmdzXSk7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIHdoZWVsZWQoKSB7XG4gICAgaWYgKCFmaWx0ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuO1xuICAgIHZhciBnID0gZ2VzdHVyZSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICB0ID0gdGhpcy5fX3pvb20sXG4gICAgICAgIGsgPSBNYXRoLm1heChrMCwgTWF0aC5taW4oazEsIHQuayAqIE1hdGgucG93KDIsIC1leHBvcnRzLmV2ZW50LmRlbHRhWSAqIChleHBvcnRzLmV2ZW50LmRlbHRhTW9kZSA/IDEyMCA6IDEpIC8gNTAwKSkpLFxuICAgICAgICBwID0gbW91c2UodGhpcyk7XG5cbiAgICAvLyBJZiB0aGUgbW91c2UgaXMgaW4gdGhlIHNhbWUgbG9jYXRpb24gYXMgYmVmb3JlLCByZXVzZSBpdC5cbiAgICAvLyBJZiB0aGVyZSB3ZXJlIHJlY2VudCB3aGVlbCBldmVudHMsIHJlc2V0IHRoZSB3aGVlbCBpZGxlIHRpbWVvdXQuXG4gICAgaWYgKGcud2hlZWwpIHtcbiAgICAgIGlmIChnLm1vdXNlWzBdWzBdICE9PSBwWzBdIHx8IGcubW91c2VbMF1bMV0gIT09IHBbMV0pIHtcbiAgICAgICAgZy5tb3VzZVsxXSA9IHQuaW52ZXJ0KGcubW91c2VbMF0gPSBwKTtcbiAgICAgIH1cbiAgICAgIGNsZWFyVGltZW91dChnLndoZWVsKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGlzIHdoZWVsIGV2ZW50IHdvbuKAmXQgdHJpZ2dlciBhIHRyYW5zZm9ybSBjaGFuZ2UsIGlnbm9yZSBpdC5cbiAgICBlbHNlIGlmICh0LmsgPT09IGspIHJldHVybjtcblxuICAgIC8vIE90aGVyd2lzZSwgY2FwdHVyZSB0aGUgbW91c2UgcG9pbnQgYW5kIGxvY2F0aW9uIGF0IHRoZSBzdGFydC5cbiAgICBlbHNlIHtcbiAgICAgIGcubW91c2UgPSBbcCwgdC5pbnZlcnQocCldO1xuICAgICAgaW50ZXJydXB0KHRoaXMpO1xuICAgICAgZy5zdGFydCgpO1xuICAgIH1cblxuICAgIG5vZXZlbnQkMSgpO1xuICAgIGcud2hlZWwgPSBzZXRUaW1lb3V0KHdoZWVsaWRsZWQsIHdoZWVsRGVsYXkpO1xuICAgIGcuem9vbShcIm1vdXNlXCIsIGNvbnN0cmFpbih0cmFuc2xhdGUoc2NhbGUodCwgayksIGcubW91c2VbMF0sIGcubW91c2VbMV0pLCBnLmV4dGVudCkpO1xuXG4gICAgZnVuY3Rpb24gd2hlZWxpZGxlZCgpIHtcbiAgICAgIGcud2hlZWwgPSBudWxsO1xuICAgICAgZy5lbmQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBtb3VzZWRvd25lZCgpIHtcbiAgICBpZiAodG91Y2hlbmRpbmcgfHwgIWZpbHRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm47XG4gICAgdmFyIGcgPSBnZXN0dXJlKHRoaXMsIGFyZ3VtZW50cyksXG4gICAgICAgIHYgPSBzZWxlY3QoZXhwb3J0cy5ldmVudC52aWV3KS5vbihcIm1vdXNlbW92ZS56b29tXCIsIG1vdXNlbW92ZWQsIHRydWUpLm9uKFwibW91c2V1cC56b29tXCIsIG1vdXNldXBwZWQsIHRydWUpLFxuICAgICAgICBwID0gbW91c2UodGhpcyk7XG5cbiAgICBkcmFnRGlzYWJsZShleHBvcnRzLmV2ZW50LnZpZXcpO1xuICAgIG5vcHJvcGFnYXRpb24kMSgpO1xuICAgIGcubW91c2UgPSBbcCwgdGhpcy5fX3pvb20uaW52ZXJ0KHApXTtcbiAgICBpbnRlcnJ1cHQodGhpcyk7XG4gICAgZy5zdGFydCgpO1xuXG4gICAgZnVuY3Rpb24gbW91c2Vtb3ZlZCgpIHtcbiAgICAgIG5vZXZlbnQkMSgpO1xuICAgICAgZy5tb3ZlZCA9IHRydWU7XG4gICAgICBnLnpvb20oXCJtb3VzZVwiLCBjb25zdHJhaW4odHJhbnNsYXRlKGcudGhhdC5fX3pvb20sIGcubW91c2VbMF0gPSBtb3VzZShnLnRoYXQpLCBnLm1vdXNlWzFdKSwgZy5leHRlbnQpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3VzZXVwcGVkKCkge1xuICAgICAgdi5vbihcIm1vdXNlbW92ZS56b29tIG1vdXNldXAuem9vbVwiLCBudWxsKTtcbiAgICAgIHllc2RyYWcoZXhwb3J0cy5ldmVudC52aWV3LCBnLm1vdmVkKTtcbiAgICAgIG5vZXZlbnQkMSgpO1xuICAgICAgZy5lbmQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkYmxjbGlja2VkKCkge1xuICAgIGlmICghZmlsdGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIHJldHVybjtcbiAgICB2YXIgdDAgPSB0aGlzLl9fem9vbSxcbiAgICAgICAgcDAgPSBtb3VzZSh0aGlzKSxcbiAgICAgICAgcDEgPSB0MC5pbnZlcnQocDApLFxuICAgICAgICBrMSA9IHQwLmsgKiAoZXhwb3J0cy5ldmVudC5zaGlmdEtleSA/IDAuNSA6IDIpLFxuICAgICAgICB0MSA9IGNvbnN0cmFpbih0cmFuc2xhdGUoc2NhbGUodDAsIGsxKSwgcDAsIHAxKSwgZXh0ZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuXG4gICAgbm9ldmVudCQxKCk7XG4gICAgaWYgKGR1cmF0aW9uID4gMCkgc2VsZWN0KHRoaXMpLnRyYW5zaXRpb24oKS5kdXJhdGlvbihkdXJhdGlvbikuY2FsbChzY2hlZHVsZSwgdDEsIHAwKTtcbiAgICBlbHNlIHNlbGVjdCh0aGlzKS5jYWxsKHpvb20udHJhbnNmb3JtLCB0MSk7XG4gIH1cblxuICBmdW5jdGlvbiB0b3VjaHN0YXJ0ZWQoKSB7XG4gICAgaWYgKCFmaWx0ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuO1xuICAgIHZhciBnID0gZ2VzdHVyZSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICB0b3VjaGVzJCQxID0gZXhwb3J0cy5ldmVudC5jaGFuZ2VkVG91Y2hlcyxcbiAgICAgICAgbiA9IHRvdWNoZXMkJDEubGVuZ3RoLCBpLCB0LCBwO1xuXG4gICAgbm9wcm9wYWdhdGlvbiQxKCk7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgdCA9IHRvdWNoZXMkJDFbaV0sIHAgPSB0b3VjaCh0aGlzLCB0b3VjaGVzJCQxLCB0LmlkZW50aWZpZXIpO1xuICAgICAgcCA9IFtwLCB0aGlzLl9fem9vbS5pbnZlcnQocCksIHQuaWRlbnRpZmllcl07XG4gICAgICBpZiAoIWcudG91Y2gwKSBnLnRvdWNoMCA9IHA7XG4gICAgICBlbHNlIGlmICghZy50b3VjaDEpIGcudG91Y2gxID0gcDtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGlzIGlzIGEgZGJsdGFwLCByZXJvdXRlIHRvIHRoZSAob3B0aW9uYWwpIGRibGNsaWNrLnpvb20gaGFuZGxlci5cbiAgICBpZiAodG91Y2hzdGFydGluZykge1xuICAgICAgdG91Y2hzdGFydGluZyA9IGNsZWFyVGltZW91dCh0b3VjaHN0YXJ0aW5nKTtcbiAgICAgIGlmICghZy50b3VjaDEpIHtcbiAgICAgICAgZy5lbmQoKTtcbiAgICAgICAgcCA9IHNlbGVjdCh0aGlzKS5vbihcImRibGNsaWNrLnpvb21cIik7XG4gICAgICAgIGlmIChwKSBwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXhwb3J0cy5ldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gbikge1xuICAgICAgdG91Y2hzdGFydGluZyA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHRvdWNoc3RhcnRpbmcgPSBudWxsOyB9LCB0b3VjaERlbGF5KTtcbiAgICAgIGludGVycnVwdCh0aGlzKTtcbiAgICAgIGcuc3RhcnQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0b3VjaG1vdmVkKCkge1xuICAgIHZhciBnID0gZ2VzdHVyZSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICB0b3VjaGVzJCQxID0gZXhwb3J0cy5ldmVudC5jaGFuZ2VkVG91Y2hlcyxcbiAgICAgICAgbiA9IHRvdWNoZXMkJDEubGVuZ3RoLCBpLCB0LCBwLCBsO1xuXG4gICAgbm9ldmVudCQxKCk7XG4gICAgaWYgKHRvdWNoc3RhcnRpbmcpIHRvdWNoc3RhcnRpbmcgPSBjbGVhclRpbWVvdXQodG91Y2hzdGFydGluZyk7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgdCA9IHRvdWNoZXMkJDFbaV0sIHAgPSB0b3VjaCh0aGlzLCB0b3VjaGVzJCQxLCB0LmlkZW50aWZpZXIpO1xuICAgICAgaWYgKGcudG91Y2gwICYmIGcudG91Y2gwWzJdID09PSB0LmlkZW50aWZpZXIpIGcudG91Y2gwWzBdID0gcDtcbiAgICAgIGVsc2UgaWYgKGcudG91Y2gxICYmIGcudG91Y2gxWzJdID09PSB0LmlkZW50aWZpZXIpIGcudG91Y2gxWzBdID0gcDtcbiAgICB9XG4gICAgdCA9IGcudGhhdC5fX3pvb207XG4gICAgaWYgKGcudG91Y2gxKSB7XG4gICAgICB2YXIgcDAgPSBnLnRvdWNoMFswXSwgbDAgPSBnLnRvdWNoMFsxXSxcbiAgICAgICAgICBwMSA9IGcudG91Y2gxWzBdLCBsMSA9IGcudG91Y2gxWzFdLFxuICAgICAgICAgIGRwID0gKGRwID0gcDFbMF0gLSBwMFswXSkgKiBkcCArIChkcCA9IHAxWzFdIC0gcDBbMV0pICogZHAsXG4gICAgICAgICAgZGwgPSAoZGwgPSBsMVswXSAtIGwwWzBdKSAqIGRsICsgKGRsID0gbDFbMV0gLSBsMFsxXSkgKiBkbDtcbiAgICAgIHQgPSBzY2FsZSh0LCBNYXRoLnNxcnQoZHAgLyBkbCkpO1xuICAgICAgcCA9IFsocDBbMF0gKyBwMVswXSkgLyAyLCAocDBbMV0gKyBwMVsxXSkgLyAyXTtcbiAgICAgIGwgPSBbKGwwWzBdICsgbDFbMF0pIC8gMiwgKGwwWzFdICsgbDFbMV0pIC8gMl07XG4gICAgfVxuICAgIGVsc2UgaWYgKGcudG91Y2gwKSBwID0gZy50b3VjaDBbMF0sIGwgPSBnLnRvdWNoMFsxXTtcbiAgICBlbHNlIHJldHVybjtcbiAgICBnLnpvb20oXCJ0b3VjaFwiLCBjb25zdHJhaW4odHJhbnNsYXRlKHQsIHAsIGwpLCBnLmV4dGVudCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdG91Y2hlbmRlZCgpIHtcbiAgICB2YXIgZyA9IGdlc3R1cmUodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgdG91Y2hlcyQkMSA9IGV4cG9ydHMuZXZlbnQuY2hhbmdlZFRvdWNoZXMsXG4gICAgICAgIG4gPSB0b3VjaGVzJCQxLmxlbmd0aCwgaSwgdDtcblxuICAgIG5vcHJvcGFnYXRpb24kMSgpO1xuICAgIGlmICh0b3VjaGVuZGluZykgY2xlYXJUaW1lb3V0KHRvdWNoZW5kaW5nKTtcbiAgICB0b3VjaGVuZGluZyA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHRvdWNoZW5kaW5nID0gbnVsbDsgfSwgdG91Y2hEZWxheSk7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgdCA9IHRvdWNoZXMkJDFbaV07XG4gICAgICBpZiAoZy50b3VjaDAgJiYgZy50b3VjaDBbMl0gPT09IHQuaWRlbnRpZmllcikgZGVsZXRlIGcudG91Y2gwO1xuICAgICAgZWxzZSBpZiAoZy50b3VjaDEgJiYgZy50b3VjaDFbMl0gPT09IHQuaWRlbnRpZmllcikgZGVsZXRlIGcudG91Y2gxO1xuICAgIH1cbiAgICBpZiAoZy50b3VjaDEgJiYgIWcudG91Y2gwKSBnLnRvdWNoMCA9IGcudG91Y2gxLCBkZWxldGUgZy50b3VjaDE7XG4gICAgaWYgKCFnLnRvdWNoMCkgZy5lbmQoKTtcbiAgfVxuXG4gIHpvb20uZmlsdGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGZpbHRlciA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoISFfKSwgem9vbSkgOiBmaWx0ZXI7XG4gIH07XG5cbiAgem9vbS5leHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZXh0ZW50ID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMChbWytfWzBdWzBdLCArX1swXVsxXV0sIFsrX1sxXVswXSwgK19bMV1bMV1dXSksIHpvb20pIDogZXh0ZW50O1xuICB9O1xuXG4gIHpvb20uc2NhbGVFeHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoazAgPSArX1swXSwgazEgPSArX1sxXSwgem9vbSkgOiBbazAsIGsxXTtcbiAgfTtcblxuICB6b29tLnRyYW5zbGF0ZUV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MCA9ICtfWzBdWzBdLCB4MSA9ICtfWzFdWzBdLCB5MCA9ICtfWzBdWzFdLCB5MSA9ICtfWzFdWzFdLCB6b29tKSA6IFtbeDAsIHkwXSwgW3gxLCB5MV1dO1xuICB9O1xuXG4gIHpvb20uZHVyYXRpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZHVyYXRpb24gPSArXywgem9vbSkgOiBkdXJhdGlvbjtcbiAgfTtcblxuICB6b29tLmludGVycG9sYXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGludGVycG9sYXRlJCQxID0gXywgem9vbSkgOiBpbnRlcnBvbGF0ZSQkMTtcbiAgfTtcblxuICB6b29tLm9uID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZhbHVlID0gbGlzdGVuZXJzLm9uLmFwcGx5KGxpc3RlbmVycywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gdmFsdWUgPT09IGxpc3RlbmVycyA/IHpvb20gOiB2YWx1ZTtcbiAgfTtcblxuICByZXR1cm4gem9vbTtcbn07XG5cbnZhciBjb25zdGFudCQxMSA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxudmFyIEJydXNoRXZlbnQgPSBmdW5jdGlvbih0YXJnZXQsIHR5cGUsIHNlbGVjdGlvbikge1xuICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5zZWxlY3Rpb24gPSBzZWxlY3Rpb247XG59O1xuXG5mdW5jdGlvbiBub3Byb3BhZ2F0aW9uJDIoKSB7XG4gIGV4cG9ydHMuZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG59XG5cbnZhciBub2V2ZW50JDIgPSBmdW5jdGlvbigpIHtcbiAgZXhwb3J0cy5ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICBleHBvcnRzLmV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xufTtcblxudmFyIE1PREVfRFJBRyA9IHtuYW1lOiBcImRyYWdcIn07XG52YXIgTU9ERV9TUEFDRSA9IHtuYW1lOiBcInNwYWNlXCJ9O1xudmFyIE1PREVfSEFORExFID0ge25hbWU6IFwiaGFuZGxlXCJ9O1xudmFyIE1PREVfQ0VOVEVSID0ge25hbWU6IFwiY2VudGVyXCJ9O1xuXG52YXIgWCA9IHtcbiAgbmFtZTogXCJ4XCIsXG4gIGhhbmRsZXM6IFtcImVcIiwgXCJ3XCJdLm1hcCh0eXBlJDEpLFxuICBpbnB1dDogZnVuY3Rpb24oeCwgZSkgeyByZXR1cm4geCAmJiBbW3hbMF0sIGVbMF1bMV1dLCBbeFsxXSwgZVsxXVsxXV1dOyB9LFxuICBvdXRwdXQ6IGZ1bmN0aW9uKHh5KSB7IHJldHVybiB4eSAmJiBbeHlbMF1bMF0sIHh5WzFdWzBdXTsgfVxufTtcblxudmFyIFkgPSB7XG4gIG5hbWU6IFwieVwiLFxuICBoYW5kbGVzOiBbXCJuXCIsIFwic1wiXS5tYXAodHlwZSQxKSxcbiAgaW5wdXQ6IGZ1bmN0aW9uKHksIGUpIHsgcmV0dXJuIHkgJiYgW1tlWzBdWzBdLCB5WzBdXSwgW2VbMV1bMF0sIHlbMV1dXTsgfSxcbiAgb3V0cHV0OiBmdW5jdGlvbih4eSkgeyByZXR1cm4geHkgJiYgW3h5WzBdWzFdLCB4eVsxXVsxXV07IH1cbn07XG5cbnZhciBYWSA9IHtcbiAgbmFtZTogXCJ4eVwiLFxuICBoYW5kbGVzOiBbXCJuXCIsIFwiZVwiLCBcInNcIiwgXCJ3XCIsIFwibndcIiwgXCJuZVwiLCBcInNlXCIsIFwic3dcIl0ubWFwKHR5cGUkMSksXG4gIGlucHV0OiBmdW5jdGlvbih4eSkgeyByZXR1cm4geHk7IH0sXG4gIG91dHB1dDogZnVuY3Rpb24oeHkpIHsgcmV0dXJuIHh5OyB9XG59O1xuXG52YXIgY3Vyc29ycyA9IHtcbiAgb3ZlcmxheTogXCJjcm9zc2hhaXJcIixcbiAgc2VsZWN0aW9uOiBcIm1vdmVcIixcbiAgbjogXCJucy1yZXNpemVcIixcbiAgZTogXCJldy1yZXNpemVcIixcbiAgczogXCJucy1yZXNpemVcIixcbiAgdzogXCJldy1yZXNpemVcIixcbiAgbnc6IFwibndzZS1yZXNpemVcIixcbiAgbmU6IFwibmVzdy1yZXNpemVcIixcbiAgc2U6IFwibndzZS1yZXNpemVcIixcbiAgc3c6IFwibmVzdy1yZXNpemVcIlxufTtcblxudmFyIGZsaXBYID0ge1xuICBlOiBcIndcIixcbiAgdzogXCJlXCIsXG4gIG53OiBcIm5lXCIsXG4gIG5lOiBcIm53XCIsXG4gIHNlOiBcInN3XCIsXG4gIHN3OiBcInNlXCJcbn07XG5cbnZhciBmbGlwWSA9IHtcbiAgbjogXCJzXCIsXG4gIHM6IFwiblwiLFxuICBudzogXCJzd1wiLFxuICBuZTogXCJzZVwiLFxuICBzZTogXCJuZVwiLFxuICBzdzogXCJud1wiXG59O1xuXG52YXIgc2lnbnNYID0ge1xuICBvdmVybGF5OiArMSxcbiAgc2VsZWN0aW9uOiArMSxcbiAgbjogbnVsbCxcbiAgZTogKzEsXG4gIHM6IG51bGwsXG4gIHc6IC0xLFxuICBudzogLTEsXG4gIG5lOiArMSxcbiAgc2U6ICsxLFxuICBzdzogLTFcbn07XG5cbnZhciBzaWduc1kgPSB7XG4gIG92ZXJsYXk6ICsxLFxuICBzZWxlY3Rpb246ICsxLFxuICBuOiAtMSxcbiAgZTogbnVsbCxcbiAgczogKzEsXG4gIHc6IG51bGwsXG4gIG53OiAtMSxcbiAgbmU6IC0xLFxuICBzZTogKzEsXG4gIHN3OiArMVxufTtcblxuZnVuY3Rpb24gdHlwZSQxKHQpIHtcbiAgcmV0dXJuIHt0eXBlOiB0fTtcbn1cblxuLy8gSWdub3JlIHJpZ2h0LWNsaWNrLCBzaW5jZSB0aGF0IHNob3VsZCBvcGVuIHRoZSBjb250ZXh0IG1lbnUuXG5mdW5jdGlvbiBkZWZhdWx0RmlsdGVyJDIoKSB7XG4gIHJldHVybiAhZXhwb3J0cy5ldmVudC5idXR0b247XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRFeHRlbnQkMSgpIHtcbiAgdmFyIHN2ZyA9IHRoaXMub3duZXJTVkdFbGVtZW50IHx8IHRoaXM7XG4gIHJldHVybiBbWzAsIDBdLCBbc3ZnLndpZHRoLmJhc2VWYWwudmFsdWUsIHN2Zy5oZWlnaHQuYmFzZVZhbC52YWx1ZV1dO1xufVxuXG4vLyBMaWtlIGQzLmxvY2FsLCBidXQgd2l0aCB0aGUgbmFtZSDigJxfX2JydXNo4oCdIHJhdGhlciB0aGFuIGF1dG8tZ2VuZXJhdGVkLlxuZnVuY3Rpb24gbG9jYWwkMShub2RlKSB7XG4gIHdoaWxlICghbm9kZS5fX2JydXNoKSBpZiAoIShub2RlID0gbm9kZS5wYXJlbnROb2RlKSkgcmV0dXJuO1xuICByZXR1cm4gbm9kZS5fX2JydXNoO1xufVxuXG5mdW5jdGlvbiBlbXB0eSQxKGV4dGVudCkge1xuICByZXR1cm4gZXh0ZW50WzBdWzBdID09PSBleHRlbnRbMV1bMF1cbiAgICAgIHx8IGV4dGVudFswXVsxXSA9PT0gZXh0ZW50WzFdWzFdO1xufVxuXG5mdW5jdGlvbiBicnVzaFNlbGVjdGlvbihub2RlKSB7XG4gIHZhciBzdGF0ZSA9IG5vZGUuX19icnVzaDtcbiAgcmV0dXJuIHN0YXRlID8gc3RhdGUuZGltLm91dHB1dChzdGF0ZS5zZWxlY3Rpb24pIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gYnJ1c2hYKCkge1xuICByZXR1cm4gYnJ1c2gkMShYKTtcbn1cblxuZnVuY3Rpb24gYnJ1c2hZKCkge1xuICByZXR1cm4gYnJ1c2gkMShZKTtcbn1cblxudmFyIGJydXNoID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBicnVzaCQxKFhZKTtcbn07XG5cbmZ1bmN0aW9uIGJydXNoJDEoZGltKSB7XG4gIHZhciBleHRlbnQgPSBkZWZhdWx0RXh0ZW50JDEsXG4gICAgICBmaWx0ZXIgPSBkZWZhdWx0RmlsdGVyJDIsXG4gICAgICBsaXN0ZW5lcnMgPSBkaXNwYXRjaChicnVzaCwgXCJzdGFydFwiLCBcImJydXNoXCIsIFwiZW5kXCIpLFxuICAgICAgaGFuZGxlU2l6ZSA9IDYsXG4gICAgICB0b3VjaGVuZGluZztcblxuICBmdW5jdGlvbiBicnVzaChncm91cCkge1xuICAgIHZhciBvdmVybGF5ID0gZ3JvdXBcbiAgICAgICAgLnByb3BlcnR5KFwiX19icnVzaFwiLCBpbml0aWFsaXplKVxuICAgICAgLnNlbGVjdEFsbChcIi5vdmVybGF5XCIpXG4gICAgICAuZGF0YShbdHlwZSQxKFwib3ZlcmxheVwiKV0pO1xuXG4gICAgb3ZlcmxheS5lbnRlcigpLmFwcGVuZChcInJlY3RcIilcbiAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcIm92ZXJsYXlcIilcbiAgICAgICAgLmF0dHIoXCJwb2ludGVyLWV2ZW50c1wiLCBcImFsbFwiKVxuICAgICAgICAuYXR0cihcImN1cnNvclwiLCBjdXJzb3JzLm92ZXJsYXkpXG4gICAgICAubWVyZ2Uob3ZlcmxheSlcbiAgICAgICAgLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIGV4dGVudCA9IGxvY2FsJDEodGhpcykuZXh0ZW50O1xuICAgICAgICAgIHNlbGVjdCh0aGlzKVxuICAgICAgICAgICAgICAuYXR0cihcInhcIiwgZXh0ZW50WzBdWzBdKVxuICAgICAgICAgICAgICAuYXR0cihcInlcIiwgZXh0ZW50WzBdWzFdKVxuICAgICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGV4dGVudFsxXVswXSAtIGV4dGVudFswXVswXSlcbiAgICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgZXh0ZW50WzFdWzFdIC0gZXh0ZW50WzBdWzFdKTtcbiAgICAgICAgfSk7XG5cbiAgICBncm91cC5zZWxlY3RBbGwoXCIuc2VsZWN0aW9uXCIpXG4gICAgICAuZGF0YShbdHlwZSQxKFwic2VsZWN0aW9uXCIpXSlcbiAgICAgIC5lbnRlcigpLmFwcGVuZChcInJlY3RcIilcbiAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcInNlbGVjdGlvblwiKVxuICAgICAgICAuYXR0cihcImN1cnNvclwiLCBjdXJzb3JzLnNlbGVjdGlvbilcbiAgICAgICAgLmF0dHIoXCJmaWxsXCIsIFwiIzc3N1wiKVxuICAgICAgICAuYXR0cihcImZpbGwtb3BhY2l0eVwiLCAwLjMpXG4gICAgICAgIC5hdHRyKFwic3Ryb2tlXCIsIFwiI2ZmZlwiKVxuICAgICAgICAuYXR0cihcInNoYXBlLXJlbmRlcmluZ1wiLCBcImNyaXNwRWRnZXNcIik7XG5cbiAgICB2YXIgaGFuZGxlID0gZ3JvdXAuc2VsZWN0QWxsKFwiLmhhbmRsZVwiKVxuICAgICAgLmRhdGEoZGltLmhhbmRsZXMsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQudHlwZTsgfSk7XG5cbiAgICBoYW5kbGUuZXhpdCgpLnJlbW92ZSgpO1xuXG4gICAgaGFuZGxlLmVudGVyKCkuYXBwZW5kKFwicmVjdFwiKVxuICAgICAgICAuYXR0cihcImNsYXNzXCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIFwiaGFuZGxlIGhhbmRsZS0tXCIgKyBkLnR5cGU7IH0pXG4gICAgICAgIC5hdHRyKFwiY3Vyc29yXCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGN1cnNvcnNbZC50eXBlXTsgfSk7XG5cbiAgICBncm91cFxuICAgICAgICAuZWFjaChyZWRyYXcpXG4gICAgICAgIC5hdHRyKFwiZmlsbFwiLCBcIm5vbmVcIilcbiAgICAgICAgLmF0dHIoXCJwb2ludGVyLWV2ZW50c1wiLCBcImFsbFwiKVxuICAgICAgICAuc3R5bGUoXCItd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3JcIiwgXCJyZ2JhKDAsMCwwLDApXCIpXG4gICAgICAgIC5vbihcIm1vdXNlZG93bi5icnVzaCB0b3VjaHN0YXJ0LmJydXNoXCIsIHN0YXJ0ZWQpO1xuICB9XG5cbiAgYnJ1c2gubW92ZSA9IGZ1bmN0aW9uKGdyb3VwLCBzZWxlY3Rpb24kJDEpIHtcbiAgICBpZiAoZ3JvdXAuc2VsZWN0aW9uKSB7XG4gICAgICBncm91cFxuICAgICAgICAgIC5vbihcInN0YXJ0LmJydXNoXCIsIGZ1bmN0aW9uKCkgeyBlbWl0dGVyKHRoaXMsIGFyZ3VtZW50cykuYmVmb3Jlc3RhcnQoKS5zdGFydCgpOyB9KVxuICAgICAgICAgIC5vbihcImludGVycnVwdC5icnVzaCBlbmQuYnJ1c2hcIiwgZnVuY3Rpb24oKSB7IGVtaXR0ZXIodGhpcywgYXJndW1lbnRzKS5lbmQoKTsgfSlcbiAgICAgICAgICAudHdlZW4oXCJicnVzaFwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICBzdGF0ZSA9IHRoYXQuX19icnVzaCxcbiAgICAgICAgICAgICAgICBlbWl0ID0gZW1pdHRlcih0aGF0LCBhcmd1bWVudHMpLFxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbjAgPSBzdGF0ZS5zZWxlY3Rpb24sXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uMSA9IGRpbS5pbnB1dCh0eXBlb2Ygc2VsZWN0aW9uJCQxID09PSBcImZ1bmN0aW9uXCIgPyBzZWxlY3Rpb24kJDEuYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IHNlbGVjdGlvbiQkMSwgc3RhdGUuZXh0ZW50KSxcbiAgICAgICAgICAgICAgICBpID0gaW50ZXJwb2xhdGUoc2VsZWN0aW9uMCwgc2VsZWN0aW9uMSk7XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHR3ZWVuKHQpIHtcbiAgICAgICAgICAgICAgc3RhdGUuc2VsZWN0aW9uID0gdCA9PT0gMSAmJiBlbXB0eSQxKHNlbGVjdGlvbjEpID8gbnVsbCA6IGkodCk7XG4gICAgICAgICAgICAgIHJlZHJhdy5jYWxsKHRoYXQpO1xuICAgICAgICAgICAgICBlbWl0LmJydXNoKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBzZWxlY3Rpb24wICYmIHNlbGVjdGlvbjEgPyB0d2VlbiA6IHR3ZWVuKDEpO1xuICAgICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBncm91cFxuICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLFxuICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgICAgICAgc3RhdGUgPSB0aGF0Ll9fYnJ1c2gsXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uMSA9IGRpbS5pbnB1dCh0eXBlb2Ygc2VsZWN0aW9uJCQxID09PSBcImZ1bmN0aW9uXCIgPyBzZWxlY3Rpb24kJDEuYXBwbHkodGhhdCwgYXJncykgOiBzZWxlY3Rpb24kJDEsIHN0YXRlLmV4dGVudCksXG4gICAgICAgICAgICAgICAgZW1pdCA9IGVtaXR0ZXIodGhhdCwgYXJncykuYmVmb3Jlc3RhcnQoKTtcblxuICAgICAgICAgICAgaW50ZXJydXB0KHRoYXQpO1xuICAgICAgICAgICAgc3RhdGUuc2VsZWN0aW9uID0gc2VsZWN0aW9uMSA9PSBudWxsIHx8IGVtcHR5JDEoc2VsZWN0aW9uMSkgPyBudWxsIDogc2VsZWN0aW9uMTtcbiAgICAgICAgICAgIHJlZHJhdy5jYWxsKHRoYXQpO1xuICAgICAgICAgICAgZW1pdC5zdGFydCgpLmJydXNoKCkuZW5kKCk7XG4gICAgICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIHJlZHJhdygpIHtcbiAgICB2YXIgZ3JvdXAgPSBzZWxlY3QodGhpcyksXG4gICAgICAgIHNlbGVjdGlvbiQkMSA9IGxvY2FsJDEodGhpcykuc2VsZWN0aW9uO1xuXG4gICAgaWYgKHNlbGVjdGlvbiQkMSkge1xuICAgICAgZ3JvdXAuc2VsZWN0QWxsKFwiLnNlbGVjdGlvblwiKVxuICAgICAgICAgIC5zdHlsZShcImRpc3BsYXlcIiwgbnVsbClcbiAgICAgICAgICAuYXR0cihcInhcIiwgc2VsZWN0aW9uJCQxWzBdWzBdKVxuICAgICAgICAgIC5hdHRyKFwieVwiLCBzZWxlY3Rpb24kJDFbMF1bMV0pXG4gICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBzZWxlY3Rpb24kJDFbMV1bMF0gLSBzZWxlY3Rpb24kJDFbMF1bMF0pXG4gICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgc2VsZWN0aW9uJCQxWzFdWzFdIC0gc2VsZWN0aW9uJCQxWzBdWzFdKTtcblxuICAgICAgZ3JvdXAuc2VsZWN0QWxsKFwiLmhhbmRsZVwiKVxuICAgICAgICAgIC5zdHlsZShcImRpc3BsYXlcIiwgbnVsbClcbiAgICAgICAgICAuYXR0cihcInhcIiwgZnVuY3Rpb24oZCkgeyByZXR1cm4gZC50eXBlW2QudHlwZS5sZW5ndGggLSAxXSA9PT0gXCJlXCIgPyBzZWxlY3Rpb24kJDFbMV1bMF0gLSBoYW5kbGVTaXplIC8gMiA6IHNlbGVjdGlvbiQkMVswXVswXSAtIGhhbmRsZVNpemUgLyAyOyB9KVxuICAgICAgICAgIC5hdHRyKFwieVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBkLnR5cGVbMF0gPT09IFwic1wiID8gc2VsZWN0aW9uJCQxWzFdWzFdIC0gaGFuZGxlU2l6ZSAvIDIgOiBzZWxlY3Rpb24kJDFbMF1bMV0gLSBoYW5kbGVTaXplIC8gMjsgfSlcbiAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQudHlwZSA9PT0gXCJuXCIgfHwgZC50eXBlID09PSBcInNcIiA/IHNlbGVjdGlvbiQkMVsxXVswXSAtIHNlbGVjdGlvbiQkMVswXVswXSArIGhhbmRsZVNpemUgOiBoYW5kbGVTaXplOyB9KVxuICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQudHlwZSA9PT0gXCJlXCIgfHwgZC50eXBlID09PSBcIndcIiA/IHNlbGVjdGlvbiQkMVsxXVsxXSAtIHNlbGVjdGlvbiQkMVswXVsxXSArIGhhbmRsZVNpemUgOiBoYW5kbGVTaXplOyB9KTtcbiAgICB9XG5cbiAgICBlbHNlIHtcbiAgICAgIGdyb3VwLnNlbGVjdEFsbChcIi5zZWxlY3Rpb24sLmhhbmRsZVwiKVxuICAgICAgICAgIC5zdHlsZShcImRpc3BsYXlcIiwgXCJub25lXCIpXG4gICAgICAgICAgLmF0dHIoXCJ4XCIsIG51bGwpXG4gICAgICAgICAgLmF0dHIoXCJ5XCIsIG51bGwpXG4gICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBudWxsKVxuICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGVtaXR0ZXIodGhhdCwgYXJncykge1xuICAgIHJldHVybiB0aGF0Ll9fYnJ1c2guZW1pdHRlciB8fCBuZXcgRW1pdHRlcih0aGF0LCBhcmdzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIEVtaXR0ZXIodGhhdCwgYXJncykge1xuICAgIHRoaXMudGhhdCA9IHRoYXQ7XG4gICAgdGhpcy5hcmdzID0gYXJncztcbiAgICB0aGlzLnN0YXRlID0gdGhhdC5fX2JydXNoO1xuICAgIHRoaXMuYWN0aXZlID0gMDtcbiAgfVxuXG4gIEVtaXR0ZXIucHJvdG90eXBlID0ge1xuICAgIGJlZm9yZXN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICgrK3RoaXMuYWN0aXZlID09PSAxKSB0aGlzLnN0YXRlLmVtaXR0ZXIgPSB0aGlzLCB0aGlzLnN0YXJ0aW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgc3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc3RhcnRpbmcpIHRoaXMuc3RhcnRpbmcgPSBmYWxzZSwgdGhpcy5lbWl0KFwic3RhcnRcIik7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGJydXNoOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZW1pdChcImJydXNoXCIpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBlbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKC0tdGhpcy5hY3RpdmUgPT09IDApIGRlbGV0ZSB0aGlzLnN0YXRlLmVtaXR0ZXIsIHRoaXMuZW1pdChcImVuZFwiKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgZW1pdDogZnVuY3Rpb24odHlwZSkge1xuICAgICAgY3VzdG9tRXZlbnQobmV3IEJydXNoRXZlbnQoYnJ1c2gsIHR5cGUsIGRpbS5vdXRwdXQodGhpcy5zdGF0ZS5zZWxlY3Rpb24pKSwgbGlzdGVuZXJzLmFwcGx5LCBsaXN0ZW5lcnMsIFt0eXBlLCB0aGlzLnRoYXQsIHRoaXMuYXJnc10pO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBzdGFydGVkKCkge1xuICAgIGlmIChleHBvcnRzLmV2ZW50LnRvdWNoZXMpIHsgaWYgKGV4cG9ydHMuZXZlbnQuY2hhbmdlZFRvdWNoZXMubGVuZ3RoIDwgZXhwb3J0cy5ldmVudC50b3VjaGVzLmxlbmd0aCkgcmV0dXJuIG5vZXZlbnQkMigpOyB9XG4gICAgZWxzZSBpZiAodG91Y2hlbmRpbmcpIHJldHVybjtcbiAgICBpZiAoIWZpbHRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm47XG5cbiAgICB2YXIgdGhhdCA9IHRoaXMsXG4gICAgICAgIHR5cGUgPSBleHBvcnRzLmV2ZW50LnRhcmdldC5fX2RhdGFfXy50eXBlLFxuICAgICAgICBtb2RlID0gKGV4cG9ydHMuZXZlbnQubWV0YUtleSA/IHR5cGUgPSBcIm92ZXJsYXlcIiA6IHR5cGUpID09PSBcInNlbGVjdGlvblwiID8gTU9ERV9EUkFHIDogKGV4cG9ydHMuZXZlbnQuYWx0S2V5ID8gTU9ERV9DRU5URVIgOiBNT0RFX0hBTkRMRSksXG4gICAgICAgIHNpZ25YID0gZGltID09PSBZID8gbnVsbCA6IHNpZ25zWFt0eXBlXSxcbiAgICAgICAgc2lnblkgPSBkaW0gPT09IFggPyBudWxsIDogc2lnbnNZW3R5cGVdLFxuICAgICAgICBzdGF0ZSA9IGxvY2FsJDEodGhhdCksXG4gICAgICAgIGV4dGVudCA9IHN0YXRlLmV4dGVudCxcbiAgICAgICAgc2VsZWN0aW9uJCQxID0gc3RhdGUuc2VsZWN0aW9uLFxuICAgICAgICBXID0gZXh0ZW50WzBdWzBdLCB3MCwgdzEsXG4gICAgICAgIE4gPSBleHRlbnRbMF1bMV0sIG4wLCBuMSxcbiAgICAgICAgRSA9IGV4dGVudFsxXVswXSwgZTAsIGUxLFxuICAgICAgICBTID0gZXh0ZW50WzFdWzFdLCBzMCwgczEsXG4gICAgICAgIGR4LFxuICAgICAgICBkeSxcbiAgICAgICAgbW92aW5nLFxuICAgICAgICBzaGlmdGluZyA9IHNpZ25YICYmIHNpZ25ZICYmIGV4cG9ydHMuZXZlbnQuc2hpZnRLZXksXG4gICAgICAgIGxvY2tYLFxuICAgICAgICBsb2NrWSxcbiAgICAgICAgcG9pbnQwID0gbW91c2UodGhhdCksXG4gICAgICAgIHBvaW50ID0gcG9pbnQwLFxuICAgICAgICBlbWl0ID0gZW1pdHRlcih0aGF0LCBhcmd1bWVudHMpLmJlZm9yZXN0YXJ0KCk7XG5cbiAgICBpZiAodHlwZSA9PT0gXCJvdmVybGF5XCIpIHtcbiAgICAgIHN0YXRlLnNlbGVjdGlvbiA9IHNlbGVjdGlvbiQkMSA9IFtcbiAgICAgICAgW3cwID0gZGltID09PSBZID8gVyA6IHBvaW50MFswXSwgbjAgPSBkaW0gPT09IFggPyBOIDogcG9pbnQwWzFdXSxcbiAgICAgICAgW2UwID0gZGltID09PSBZID8gRSA6IHcwLCBzMCA9IGRpbSA9PT0gWCA/IFMgOiBuMF1cbiAgICAgIF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHcwID0gc2VsZWN0aW9uJCQxWzBdWzBdO1xuICAgICAgbjAgPSBzZWxlY3Rpb24kJDFbMF1bMV07XG4gICAgICBlMCA9IHNlbGVjdGlvbiQkMVsxXVswXTtcbiAgICAgIHMwID0gc2VsZWN0aW9uJCQxWzFdWzFdO1xuICAgIH1cblxuICAgIHcxID0gdzA7XG4gICAgbjEgPSBuMDtcbiAgICBlMSA9IGUwO1xuICAgIHMxID0gczA7XG5cbiAgICB2YXIgZ3JvdXAgPSBzZWxlY3QodGhhdClcbiAgICAgICAgLmF0dHIoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG5cbiAgICB2YXIgb3ZlcmxheSA9IGdyb3VwLnNlbGVjdEFsbChcIi5vdmVybGF5XCIpXG4gICAgICAgIC5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnNbdHlwZV0pO1xuXG4gICAgaWYgKGV4cG9ydHMuZXZlbnQudG91Y2hlcykge1xuICAgICAgZ3JvdXBcbiAgICAgICAgICAub24oXCJ0b3VjaG1vdmUuYnJ1c2hcIiwgbW92ZWQsIHRydWUpXG4gICAgICAgICAgLm9uKFwidG91Y2hlbmQuYnJ1c2ggdG91Y2hjYW5jZWwuYnJ1c2hcIiwgZW5kZWQsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdmlldyA9IHNlbGVjdChleHBvcnRzLmV2ZW50LnZpZXcpXG4gICAgICAgICAgLm9uKFwia2V5ZG93bi5icnVzaFwiLCBrZXlkb3duZWQsIHRydWUpXG4gICAgICAgICAgLm9uKFwia2V5dXAuYnJ1c2hcIiwga2V5dXBwZWQsIHRydWUpXG4gICAgICAgICAgLm9uKFwibW91c2Vtb3ZlLmJydXNoXCIsIG1vdmVkLCB0cnVlKVxuICAgICAgICAgIC5vbihcIm1vdXNldXAuYnJ1c2hcIiwgZW5kZWQsIHRydWUpO1xuXG4gICAgICBkcmFnRGlzYWJsZShleHBvcnRzLmV2ZW50LnZpZXcpO1xuICAgIH1cblxuICAgIG5vcHJvcGFnYXRpb24kMigpO1xuICAgIGludGVycnVwdCh0aGF0KTtcbiAgICByZWRyYXcuY2FsbCh0aGF0KTtcbiAgICBlbWl0LnN0YXJ0KCk7XG5cbiAgICBmdW5jdGlvbiBtb3ZlZCgpIHtcbiAgICAgIHZhciBwb2ludDEgPSBtb3VzZSh0aGF0KTtcbiAgICAgIGlmIChzaGlmdGluZyAmJiAhbG9ja1ggJiYgIWxvY2tZKSB7XG4gICAgICAgIGlmIChNYXRoLmFicyhwb2ludDFbMF0gLSBwb2ludFswXSkgPiBNYXRoLmFicyhwb2ludDFbMV0gLSBwb2ludFsxXSkpIGxvY2tZID0gdHJ1ZTtcbiAgICAgICAgZWxzZSBsb2NrWCA9IHRydWU7XG4gICAgICB9XG4gICAgICBwb2ludCA9IHBvaW50MTtcbiAgICAgIG1vdmluZyA9IHRydWU7XG4gICAgICBub2V2ZW50JDIoKTtcbiAgICAgIG1vdmUoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3ZlKCkge1xuICAgICAgdmFyIHQ7XG5cbiAgICAgIGR4ID0gcG9pbnRbMF0gLSBwb2ludDBbMF07XG4gICAgICBkeSA9IHBvaW50WzFdIC0gcG9pbnQwWzFdO1xuXG4gICAgICBzd2l0Y2ggKG1vZGUpIHtcbiAgICAgICAgY2FzZSBNT0RFX1NQQUNFOlxuICAgICAgICBjYXNlIE1PREVfRFJBRzoge1xuICAgICAgICAgIGlmIChzaWduWCkgZHggPSBNYXRoLm1heChXIC0gdzAsIE1hdGgubWluKEUgLSBlMCwgZHgpKSwgdzEgPSB3MCArIGR4LCBlMSA9IGUwICsgZHg7XG4gICAgICAgICAgaWYgKHNpZ25ZKSBkeSA9IE1hdGgubWF4KE4gLSBuMCwgTWF0aC5taW4oUyAtIHMwLCBkeSkpLCBuMSA9IG4wICsgZHksIHMxID0gczAgKyBkeTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIE1PREVfSEFORExFOiB7XG4gICAgICAgICAgaWYgKHNpZ25YIDwgMCkgZHggPSBNYXRoLm1heChXIC0gdzAsIE1hdGgubWluKEUgLSB3MCwgZHgpKSwgdzEgPSB3MCArIGR4LCBlMSA9IGUwO1xuICAgICAgICAgIGVsc2UgaWYgKHNpZ25YID4gMCkgZHggPSBNYXRoLm1heChXIC0gZTAsIE1hdGgubWluKEUgLSBlMCwgZHgpKSwgdzEgPSB3MCwgZTEgPSBlMCArIGR4O1xuICAgICAgICAgIGlmIChzaWduWSA8IDApIGR5ID0gTWF0aC5tYXgoTiAtIG4wLCBNYXRoLm1pbihTIC0gbjAsIGR5KSksIG4xID0gbjAgKyBkeSwgczEgPSBzMDtcbiAgICAgICAgICBlbHNlIGlmIChzaWduWSA+IDApIGR5ID0gTWF0aC5tYXgoTiAtIHMwLCBNYXRoLm1pbihTIC0gczAsIGR5KSksIG4xID0gbjAsIHMxID0gczAgKyBkeTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIE1PREVfQ0VOVEVSOiB7XG4gICAgICAgICAgaWYgKHNpZ25YKSB3MSA9IE1hdGgubWF4KFcsIE1hdGgubWluKEUsIHcwIC0gZHggKiBzaWduWCkpLCBlMSA9IE1hdGgubWF4KFcsIE1hdGgubWluKEUsIGUwICsgZHggKiBzaWduWCkpO1xuICAgICAgICAgIGlmIChzaWduWSkgbjEgPSBNYXRoLm1heChOLCBNYXRoLm1pbihTLCBuMCAtIGR5ICogc2lnblkpKSwgczEgPSBNYXRoLm1heChOLCBNYXRoLm1pbihTLCBzMCArIGR5ICogc2lnblkpKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZTEgPCB3MSkge1xuICAgICAgICBzaWduWCAqPSAtMTtcbiAgICAgICAgdCA9IHcwLCB3MCA9IGUwLCBlMCA9IHQ7XG4gICAgICAgIHQgPSB3MSwgdzEgPSBlMSwgZTEgPSB0O1xuICAgICAgICBpZiAodHlwZSBpbiBmbGlwWCkgb3ZlcmxheS5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnNbdHlwZSA9IGZsaXBYW3R5cGVdXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzMSA8IG4xKSB7XG4gICAgICAgIHNpZ25ZICo9IC0xO1xuICAgICAgICB0ID0gbjAsIG4wID0gczAsIHMwID0gdDtcbiAgICAgICAgdCA9IG4xLCBuMSA9IHMxLCBzMSA9IHQ7XG4gICAgICAgIGlmICh0eXBlIGluIGZsaXBZKSBvdmVybGF5LmF0dHIoXCJjdXJzb3JcIiwgY3Vyc29yc1t0eXBlID0gZmxpcFlbdHlwZV1dKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlLnNlbGVjdGlvbikgc2VsZWN0aW9uJCQxID0gc3RhdGUuc2VsZWN0aW9uOyAvLyBNYXkgYmUgc2V0IGJ5IGJydXNoLm1vdmUhXG4gICAgICBpZiAobG9ja1gpIHcxID0gc2VsZWN0aW9uJCQxWzBdWzBdLCBlMSA9IHNlbGVjdGlvbiQkMVsxXVswXTtcbiAgICAgIGlmIChsb2NrWSkgbjEgPSBzZWxlY3Rpb24kJDFbMF1bMV0sIHMxID0gc2VsZWN0aW9uJCQxWzFdWzFdO1xuXG4gICAgICBpZiAoc2VsZWN0aW9uJCQxWzBdWzBdICE9PSB3MVxuICAgICAgICAgIHx8IHNlbGVjdGlvbiQkMVswXVsxXSAhPT0gbjFcbiAgICAgICAgICB8fCBzZWxlY3Rpb24kJDFbMV1bMF0gIT09IGUxXG4gICAgICAgICAgfHwgc2VsZWN0aW9uJCQxWzFdWzFdICE9PSBzMSkge1xuICAgICAgICBzdGF0ZS5zZWxlY3Rpb24gPSBbW3cxLCBuMV0sIFtlMSwgczFdXTtcbiAgICAgICAgcmVkcmF3LmNhbGwodGhhdCk7XG4gICAgICAgIGVtaXQuYnJ1c2goKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlbmRlZCgpIHtcbiAgICAgIG5vcHJvcGFnYXRpb24kMigpO1xuICAgICAgaWYgKGV4cG9ydHMuZXZlbnQudG91Y2hlcykge1xuICAgICAgICBpZiAoZXhwb3J0cy5ldmVudC50b3VjaGVzLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICBpZiAodG91Y2hlbmRpbmcpIGNsZWFyVGltZW91dCh0b3VjaGVuZGluZyk7XG4gICAgICAgIHRvdWNoZW5kaW5nID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsgdG91Y2hlbmRpbmcgPSBudWxsOyB9LCA1MDApOyAvLyBHaG9zdCBjbGlja3MgYXJlIGRlbGF5ZWQhXG4gICAgICAgIGdyb3VwLm9uKFwidG91Y2htb3ZlLmJydXNoIHRvdWNoZW5kLmJydXNoIHRvdWNoY2FuY2VsLmJydXNoXCIsIG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeWVzZHJhZyhleHBvcnRzLmV2ZW50LnZpZXcsIG1vdmluZyk7XG4gICAgICAgIHZpZXcub24oXCJrZXlkb3duLmJydXNoIGtleXVwLmJydXNoIG1vdXNlbW92ZS5icnVzaCBtb3VzZXVwLmJydXNoXCIsIG51bGwpO1xuICAgICAgfVxuICAgICAgZ3JvdXAuYXR0cihcInBvaW50ZXItZXZlbnRzXCIsIFwiYWxsXCIpO1xuICAgICAgb3ZlcmxheS5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnMub3ZlcmxheSk7XG4gICAgICBpZiAoc3RhdGUuc2VsZWN0aW9uKSBzZWxlY3Rpb24kJDEgPSBzdGF0ZS5zZWxlY3Rpb247IC8vIE1heSBiZSBzZXQgYnkgYnJ1c2gubW92ZSAob24gc3RhcnQpIVxuICAgICAgaWYgKGVtcHR5JDEoc2VsZWN0aW9uJCQxKSkgc3RhdGUuc2VsZWN0aW9uID0gbnVsbCwgcmVkcmF3LmNhbGwodGhhdCk7XG4gICAgICBlbWl0LmVuZCgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGtleWRvd25lZCgpIHtcbiAgICAgIHN3aXRjaCAoZXhwb3J0cy5ldmVudC5rZXlDb2RlKSB7XG4gICAgICAgIGNhc2UgMTY6IHsgLy8gU0hJRlRcbiAgICAgICAgICBzaGlmdGluZyA9IHNpZ25YICYmIHNpZ25ZO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMTg6IHsgLy8gQUxUXG4gICAgICAgICAgaWYgKG1vZGUgPT09IE1PREVfSEFORExFKSB7XG4gICAgICAgICAgICBpZiAoc2lnblgpIGUwID0gZTEgLSBkeCAqIHNpZ25YLCB3MCA9IHcxICsgZHggKiBzaWduWDtcbiAgICAgICAgICAgIGlmIChzaWduWSkgczAgPSBzMSAtIGR5ICogc2lnblksIG4wID0gbjEgKyBkeSAqIHNpZ25ZO1xuICAgICAgICAgICAgbW9kZSA9IE1PREVfQ0VOVEVSO1xuICAgICAgICAgICAgbW92ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIDMyOiB7IC8vIFNQQUNFOyB0YWtlcyBwcmlvcml0eSBvdmVyIEFMVFxuICAgICAgICAgIGlmIChtb2RlID09PSBNT0RFX0hBTkRMRSB8fCBtb2RlID09PSBNT0RFX0NFTlRFUikge1xuICAgICAgICAgICAgaWYgKHNpZ25YIDwgMCkgZTAgPSBlMSAtIGR4OyBlbHNlIGlmIChzaWduWCA+IDApIHcwID0gdzEgLSBkeDtcbiAgICAgICAgICAgIGlmIChzaWduWSA8IDApIHMwID0gczEgLSBkeTsgZWxzZSBpZiAoc2lnblkgPiAwKSBuMCA9IG4xIC0gZHk7XG4gICAgICAgICAgICBtb2RlID0gTU9ERV9TUEFDRTtcbiAgICAgICAgICAgIG92ZXJsYXkuYXR0cihcImN1cnNvclwiLCBjdXJzb3JzLnNlbGVjdGlvbik7XG4gICAgICAgICAgICBtb3ZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6IHJldHVybjtcbiAgICAgIH1cbiAgICAgIG5vZXZlbnQkMigpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGtleXVwcGVkKCkge1xuICAgICAgc3dpdGNoIChleHBvcnRzLmV2ZW50LmtleUNvZGUpIHtcbiAgICAgICAgY2FzZSAxNjogeyAvLyBTSElGVFxuICAgICAgICAgIGlmIChzaGlmdGluZykge1xuICAgICAgICAgICAgbG9ja1ggPSBsb2NrWSA9IHNoaWZ0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICBtb3ZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMTg6IHsgLy8gQUxUXG4gICAgICAgICAgaWYgKG1vZGUgPT09IE1PREVfQ0VOVEVSKSB7XG4gICAgICAgICAgICBpZiAoc2lnblggPCAwKSBlMCA9IGUxOyBlbHNlIGlmIChzaWduWCA+IDApIHcwID0gdzE7XG4gICAgICAgICAgICBpZiAoc2lnblkgPCAwKSBzMCA9IHMxOyBlbHNlIGlmIChzaWduWSA+IDApIG4wID0gbjE7XG4gICAgICAgICAgICBtb2RlID0gTU9ERV9IQU5ETEU7XG4gICAgICAgICAgICBtb3ZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMzI6IHsgLy8gU1BBQ0VcbiAgICAgICAgICBpZiAobW9kZSA9PT0gTU9ERV9TUEFDRSkge1xuICAgICAgICAgICAgaWYgKGV4cG9ydHMuZXZlbnQuYWx0S2V5KSB7XG4gICAgICAgICAgICAgIGlmIChzaWduWCkgZTAgPSBlMSAtIGR4ICogc2lnblgsIHcwID0gdzEgKyBkeCAqIHNpZ25YO1xuICAgICAgICAgICAgICBpZiAoc2lnblkpIHMwID0gczEgLSBkeSAqIHNpZ25ZLCBuMCA9IG4xICsgZHkgKiBzaWduWTtcbiAgICAgICAgICAgICAgbW9kZSA9IE1PREVfQ0VOVEVSO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKHNpZ25YIDwgMCkgZTAgPSBlMTsgZWxzZSBpZiAoc2lnblggPiAwKSB3MCA9IHcxO1xuICAgICAgICAgICAgICBpZiAoc2lnblkgPCAwKSBzMCA9IHMxOyBlbHNlIGlmIChzaWduWSA+IDApIG4wID0gbjE7XG4gICAgICAgICAgICAgIG1vZGUgPSBNT0RFX0hBTkRMRTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG92ZXJsYXkuYXR0cihcImN1cnNvclwiLCBjdXJzb3JzW3R5cGVdKTtcbiAgICAgICAgICAgIG1vdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogcmV0dXJuO1xuICAgICAgfVxuICAgICAgbm9ldmVudCQyKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLl9fYnJ1c2ggfHwge3NlbGVjdGlvbjogbnVsbH07XG4gICAgc3RhdGUuZXh0ZW50ID0gZXh0ZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgc3RhdGUuZGltID0gZGltO1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIGJydXNoLmV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChleHRlbnQgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDExKFtbK19bMF1bMF0sICtfWzBdWzFdXSwgWytfWzFdWzBdLCArX1sxXVsxXV1dKSwgYnJ1c2gpIDogZXh0ZW50O1xuICB9O1xuXG4gIGJydXNoLmZpbHRlciA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChmaWx0ZXIgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDExKCEhXyksIGJydXNoKSA6IGZpbHRlcjtcbiAgfTtcblxuICBicnVzaC5oYW5kbGVTaXplID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGhhbmRsZVNpemUgPSArXywgYnJ1c2gpIDogaGFuZGxlU2l6ZTtcbiAgfTtcblxuICBicnVzaC5vbiA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB2YWx1ZSA9IGxpc3RlbmVycy5vbi5hcHBseShsaXN0ZW5lcnMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHZhbHVlID09PSBsaXN0ZW5lcnMgPyBicnVzaCA6IHZhbHVlO1xuICB9O1xuXG4gIHJldHVybiBicnVzaDtcbn1cblxudmFyIGNvcyA9IE1hdGguY29zO1xudmFyIHNpbiA9IE1hdGguc2luO1xudmFyIHBpJDMgPSBNYXRoLlBJO1xudmFyIGhhbGZQaSQyID0gcGkkMyAvIDI7XG52YXIgdGF1JDMgPSBwaSQzICogMjtcbnZhciBtYXgkMSA9IE1hdGgubWF4O1xuXG5mdW5jdGlvbiBjb21wYXJlVmFsdWUoY29tcGFyZSkge1xuICByZXR1cm4gZnVuY3Rpb24oYSwgYikge1xuICAgIHJldHVybiBjb21wYXJlKFxuICAgICAgYS5zb3VyY2UudmFsdWUgKyBhLnRhcmdldC52YWx1ZSxcbiAgICAgIGIuc291cmNlLnZhbHVlICsgYi50YXJnZXQudmFsdWVcbiAgICApO1xuICB9O1xufVxuXG52YXIgY2hvcmQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhZEFuZ2xlID0gMCxcbiAgICAgIHNvcnRHcm91cHMgPSBudWxsLFxuICAgICAgc29ydFN1Ymdyb3VwcyA9IG51bGwsXG4gICAgICBzb3J0Q2hvcmRzID0gbnVsbDtcblxuICBmdW5jdGlvbiBjaG9yZChtYXRyaXgpIHtcbiAgICB2YXIgbiA9IG1hdHJpeC5sZW5ndGgsXG4gICAgICAgIGdyb3VwU3VtcyA9IFtdLFxuICAgICAgICBncm91cEluZGV4ID0gcmFuZ2UobiksXG4gICAgICAgIHN1Ymdyb3VwSW5kZXggPSBbXSxcbiAgICAgICAgY2hvcmRzID0gW10sXG4gICAgICAgIGdyb3VwcyA9IGNob3Jkcy5ncm91cHMgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIHN1Ymdyb3VwcyA9IG5ldyBBcnJheShuICogbiksXG4gICAgICAgIGssXG4gICAgICAgIHgsXG4gICAgICAgIHgwLFxuICAgICAgICBkeCxcbiAgICAgICAgaSxcbiAgICAgICAgajtcblxuICAgIC8vIENvbXB1dGUgdGhlIHN1bS5cbiAgICBrID0gMCwgaSA9IC0xOyB3aGlsZSAoKytpIDwgbikge1xuICAgICAgeCA9IDAsIGogPSAtMTsgd2hpbGUgKCsraiA8IG4pIHtcbiAgICAgICAgeCArPSBtYXRyaXhbaV1bal07XG4gICAgICB9XG4gICAgICBncm91cFN1bXMucHVzaCh4KTtcbiAgICAgIHN1Ymdyb3VwSW5kZXgucHVzaChyYW5nZShuKSk7XG4gICAgICBrICs9IHg7XG4gICAgfVxuXG4gICAgLy8gU29ydCBncm91cHPigKZcbiAgICBpZiAoc29ydEdyb3VwcykgZ3JvdXBJbmRleC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgIHJldHVybiBzb3J0R3JvdXBzKGdyb3VwU3Vtc1thXSwgZ3JvdXBTdW1zW2JdKTtcbiAgICB9KTtcblxuICAgIC8vIFNvcnQgc3ViZ3JvdXBz4oCmXG4gICAgaWYgKHNvcnRTdWJncm91cHMpIHN1Ymdyb3VwSW5kZXguZm9yRWFjaChmdW5jdGlvbihkLCBpKSB7XG4gICAgICBkLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICByZXR1cm4gc29ydFN1Ymdyb3VwcyhtYXRyaXhbaV1bYV0sIG1hdHJpeFtpXVtiXSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIENvbnZlcnQgdGhlIHN1bSB0byBzY2FsaW5nIGZhY3RvciBmb3IgWzAsIDJwaV0uXG4gICAgLy8gVE9ETyBBbGxvdyBzdGFydCBhbmQgZW5kIGFuZ2xlIHRvIGJlIHNwZWNpZmllZD9cbiAgICAvLyBUT0RPIEFsbG93IHBhZGRpbmcgdG8gYmUgc3BlY2lmaWVkIGFzIHBlcmNlbnRhZ2U/XG4gICAgayA9IG1heCQxKDAsIHRhdSQzIC0gcGFkQW5nbGUgKiBuKSAvIGs7XG4gICAgZHggPSBrID8gcGFkQW5nbGUgOiB0YXUkMyAvIG47XG5cbiAgICAvLyBDb21wdXRlIHRoZSBzdGFydCBhbmQgZW5kIGFuZ2xlIGZvciBlYWNoIGdyb3VwIGFuZCBzdWJncm91cC5cbiAgICAvLyBOb3RlOiBPcGVyYSBoYXMgYSBidWcgcmVvcmRlcmluZyBvYmplY3QgbGl0ZXJhbCBwcm9wZXJ0aWVzIVxuICAgIHggPSAwLCBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICB4MCA9IHgsIGogPSAtMTsgd2hpbGUgKCsraiA8IG4pIHtcbiAgICAgICAgdmFyIGRpID0gZ3JvdXBJbmRleFtpXSxcbiAgICAgICAgICAgIGRqID0gc3ViZ3JvdXBJbmRleFtkaV1bal0sXG4gICAgICAgICAgICB2ID0gbWF0cml4W2RpXVtkal0sXG4gICAgICAgICAgICBhMCA9IHgsXG4gICAgICAgICAgICBhMSA9IHggKz0gdiAqIGs7XG4gICAgICAgIHN1Ymdyb3Vwc1tkaiAqIG4gKyBkaV0gPSB7XG4gICAgICAgICAgaW5kZXg6IGRpLFxuICAgICAgICAgIHN1YmluZGV4OiBkaixcbiAgICAgICAgICBzdGFydEFuZ2xlOiBhMCxcbiAgICAgICAgICBlbmRBbmdsZTogYTEsXG4gICAgICAgICAgdmFsdWU6IHZcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGdyb3Vwc1tkaV0gPSB7XG4gICAgICAgIGluZGV4OiBkaSxcbiAgICAgICAgc3RhcnRBbmdsZTogeDAsXG4gICAgICAgIGVuZEFuZ2xlOiB4LFxuICAgICAgICB2YWx1ZTogZ3JvdXBTdW1zW2RpXVxuICAgICAgfTtcbiAgICAgIHggKz0gZHg7XG4gICAgfVxuXG4gICAgLy8gR2VuZXJhdGUgY2hvcmRzIGZvciBlYWNoIChub24tZW1wdHkpIHN1Ymdyb3VwLXN1Ymdyb3VwIGxpbmsuXG4gICAgaSA9IC0xOyB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaiA9IGkgLSAxOyB3aGlsZSAoKytqIDwgbikge1xuICAgICAgICB2YXIgc291cmNlID0gc3ViZ3JvdXBzW2ogKiBuICsgaV0sXG4gICAgICAgICAgICB0YXJnZXQgPSBzdWJncm91cHNbaSAqIG4gKyBqXTtcbiAgICAgICAgaWYgKHNvdXJjZS52YWx1ZSB8fCB0YXJnZXQudmFsdWUpIHtcbiAgICAgICAgICBjaG9yZHMucHVzaChzb3VyY2UudmFsdWUgPCB0YXJnZXQudmFsdWVcbiAgICAgICAgICAgICAgPyB7c291cmNlOiB0YXJnZXQsIHRhcmdldDogc291cmNlfVxuICAgICAgICAgICAgICA6IHtzb3VyY2U6IHNvdXJjZSwgdGFyZ2V0OiB0YXJnZXR9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzb3J0Q2hvcmRzID8gY2hvcmRzLnNvcnQoc29ydENob3JkcykgOiBjaG9yZHM7XG4gIH1cblxuICBjaG9yZC5wYWRBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRBbmdsZSA9IG1heCQxKDAsIF8pLCBjaG9yZCkgOiBwYWRBbmdsZTtcbiAgfTtcblxuICBjaG9yZC5zb3J0R3JvdXBzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNvcnRHcm91cHMgPSBfLCBjaG9yZCkgOiBzb3J0R3JvdXBzO1xuICB9O1xuXG4gIGNob3JkLnNvcnRTdWJncm91cHMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc29ydFN1Ymdyb3VwcyA9IF8sIGNob3JkKSA6IHNvcnRTdWJncm91cHM7XG4gIH07XG5cbiAgY2hvcmQuc29ydENob3JkcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChfID09IG51bGwgPyBzb3J0Q2hvcmRzID0gbnVsbCA6IChzb3J0Q2hvcmRzID0gY29tcGFyZVZhbHVlKF8pKS5fID0gXywgY2hvcmQpIDogc29ydENob3JkcyAmJiBzb3J0Q2hvcmRzLl87XG4gIH07XG5cbiAgcmV0dXJuIGNob3JkO1xufTtcblxudmFyIHNsaWNlJDUgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbnZhciBjb25zdGFudCQxMiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxuZnVuY3Rpb24gZGVmYXVsdFNvdXJjZShkKSB7XG4gIHJldHVybiBkLnNvdXJjZTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFRhcmdldChkKSB7XG4gIHJldHVybiBkLnRhcmdldDtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFJhZGl1cyQxKGQpIHtcbiAgcmV0dXJuIGQucmFkaXVzO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0U3RhcnRBbmdsZShkKSB7XG4gIHJldHVybiBkLnN0YXJ0QW5nbGU7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRFbmRBbmdsZShkKSB7XG4gIHJldHVybiBkLmVuZEFuZ2xlO1xufVxuXG52YXIgcmliYm9uID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzb3VyY2UgPSBkZWZhdWx0U291cmNlLFxuICAgICAgdGFyZ2V0ID0gZGVmYXVsdFRhcmdldCxcbiAgICAgIHJhZGl1cyA9IGRlZmF1bHRSYWRpdXMkMSxcbiAgICAgIHN0YXJ0QW5nbGUgPSBkZWZhdWx0U3RhcnRBbmdsZSxcbiAgICAgIGVuZEFuZ2xlID0gZGVmYXVsdEVuZEFuZ2xlLFxuICAgICAgY29udGV4dCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gcmliYm9uKCkge1xuICAgIHZhciBidWZmZXIsXG4gICAgICAgIGFyZ3YgPSBzbGljZSQ1LmNhbGwoYXJndW1lbnRzKSxcbiAgICAgICAgcyA9IHNvdXJjZS5hcHBseSh0aGlzLCBhcmd2KSxcbiAgICAgICAgdCA9IHRhcmdldC5hcHBseSh0aGlzLCBhcmd2KSxcbiAgICAgICAgc3IgPSArcmFkaXVzLmFwcGx5KHRoaXMsIChhcmd2WzBdID0gcywgYXJndikpLFxuICAgICAgICBzYTAgPSBzdGFydEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3YpIC0gaGFsZlBpJDIsXG4gICAgICAgIHNhMSA9IGVuZEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3YpIC0gaGFsZlBpJDIsXG4gICAgICAgIHN4MCA9IHNyICogY29zKHNhMCksXG4gICAgICAgIHN5MCA9IHNyICogc2luKHNhMCksXG4gICAgICAgIHRyID0gK3JhZGl1cy5hcHBseSh0aGlzLCAoYXJndlswXSA9IHQsIGFyZ3YpKSxcbiAgICAgICAgdGEwID0gc3RhcnRBbmdsZS5hcHBseSh0aGlzLCBhcmd2KSAtIGhhbGZQaSQyLFxuICAgICAgICB0YTEgPSBlbmRBbmdsZS5hcHBseSh0aGlzLCBhcmd2KSAtIGhhbGZQaSQyO1xuXG4gICAgaWYgKCFjb250ZXh0KSBjb250ZXh0ID0gYnVmZmVyID0gcGF0aCgpO1xuXG4gICAgY29udGV4dC5tb3ZlVG8oc3gwLCBzeTApO1xuICAgIGNvbnRleHQuYXJjKDAsIDAsIHNyLCBzYTAsIHNhMSk7XG4gICAgaWYgKHNhMCAhPT0gdGEwIHx8IHNhMSAhPT0gdGExKSB7IC8vIFRPRE8gc3IgIT09IHRyP1xuICAgICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKDAsIDAsIHRyICogY29zKHRhMCksIHRyICogc2luKHRhMCkpO1xuICAgICAgY29udGV4dC5hcmMoMCwgMCwgdHIsIHRhMCwgdGExKTtcbiAgICB9XG4gICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKDAsIDAsIHN4MCwgc3kwKTtcbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuXG4gICAgaWYgKGJ1ZmZlcikgcmV0dXJuIGNvbnRleHQgPSBudWxsLCBidWZmZXIgKyBcIlwiIHx8IG51bGw7XG4gIH1cblxuICByaWJib24ucmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTIoK18pLCByaWJib24pIDogcmFkaXVzO1xuICB9O1xuXG4gIHJpYmJvbi5zdGFydEFuZ2xlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0YXJ0QW5nbGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEyKCtfKSwgcmliYm9uKSA6IHN0YXJ0QW5nbGU7XG4gIH07XG5cbiAgcmliYm9uLmVuZEFuZ2xlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGVuZEFuZ2xlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMigrXyksIHJpYmJvbikgOiBlbmRBbmdsZTtcbiAgfTtcblxuICByaWJib24uc291cmNlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNvdXJjZSA9IF8sIHJpYmJvbikgOiBzb3VyY2U7XG4gIH07XG5cbiAgcmliYm9uLnRhcmdldCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0YXJnZXQgPSBfLCByaWJib24pIDogdGFyZ2V0O1xuICB9O1xuXG4gIHJpYmJvbi5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKChjb250ZXh0ID0gXyA9PSBudWxsID8gbnVsbCA6IF8pLCByaWJib24pIDogY29udGV4dDtcbiAgfTtcblxuICByZXR1cm4gcmliYm9uO1xufTtcblxuLy8gQWRkcyBmbG9hdGluZyBwb2ludCBudW1iZXJzIHdpdGggdHdpY2UgdGhlIG5vcm1hbCBwcmVjaXNpb24uXG4vLyBSZWZlcmVuY2U6IEouIFIuIFNoZXdjaHVrLCBBZGFwdGl2ZSBQcmVjaXNpb24gRmxvYXRpbmctUG9pbnQgQXJpdGhtZXRpYyBhbmRcbi8vIEZhc3QgUm9idXN0IEdlb21ldHJpYyBQcmVkaWNhdGVzLCBEaXNjcmV0ZSAmIENvbXB1dGF0aW9uYWwgR2VvbWV0cnkgMTgoMylcbi8vIDMwNeKAkzM2MyAoMTk5NykuXG4vLyBDb2RlIGFkYXB0ZWQgZnJvbSBHZW9ncmFwaGljTGliIGJ5IENoYXJsZXMgRi4gRi4gS2FybmV5LFxuLy8gaHR0cDovL2dlb2dyYXBoaWNsaWIuc291cmNlZm9yZ2UubmV0L1xuXG52YXIgYWRkZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBBZGRlcjtcbn07XG5cbmZ1bmN0aW9uIEFkZGVyKCkge1xuICB0aGlzLnJlc2V0KCk7XG59XG5cbkFkZGVyLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IEFkZGVyLFxuICByZXNldDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5zID0gLy8gcm91bmRlZCB2YWx1ZVxuICAgIHRoaXMudCA9IDA7IC8vIGV4YWN0IGVycm9yXG4gIH0sXG4gIGFkZDogZnVuY3Rpb24oeSkge1xuICAgIGFkZCQxKHRlbXAsIHksIHRoaXMudCk7XG4gICAgYWRkJDEodGhpcywgdGVtcC5zLCB0aGlzLnMpO1xuICAgIGlmICh0aGlzLnMpIHRoaXMudCArPSB0ZW1wLnQ7XG4gICAgZWxzZSB0aGlzLnMgPSB0ZW1wLnQ7XG4gIH0sXG4gIHZhbHVlT2Y6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnM7XG4gIH1cbn07XG5cbnZhciB0ZW1wID0gbmV3IEFkZGVyO1xuXG5mdW5jdGlvbiBhZGQkMShhZGRlciwgYSwgYikge1xuICB2YXIgeCA9IGFkZGVyLnMgPSBhICsgYixcbiAgICAgIGJ2ID0geCAtIGEsXG4gICAgICBhdiA9IHggLSBidjtcbiAgYWRkZXIudCA9IChhIC0gYXYpICsgKGIgLSBidik7XG59XG5cbnZhciBlcHNpbG9uJDQgPSAxZS02O1xudmFyIGVwc2lsb24yJDIgPSAxZS0xMjtcbnZhciBwaSQ0ID0gTWF0aC5QSTtcbnZhciBoYWxmUGkkMyA9IHBpJDQgLyAyO1xudmFyIHF1YXJ0ZXJQaSA9IHBpJDQgLyA0O1xudmFyIHRhdSQ0ID0gcGkkNCAqIDI7XG5cbnZhciBkZWdyZWVzJDEgPSAxODAgLyBwaSQ0O1xudmFyIHJhZGlhbnMgPSBwaSQ0IC8gMTgwO1xuXG52YXIgYWJzID0gTWF0aC5hYnM7XG52YXIgYXRhbiA9IE1hdGguYXRhbjtcbnZhciBhdGFuMiA9IE1hdGguYXRhbjI7XG52YXIgY29zJDEgPSBNYXRoLmNvcztcbnZhciBjZWlsID0gTWF0aC5jZWlsO1xudmFyIGV4cCA9IE1hdGguZXhwO1xuXG52YXIgbG9nJDEgPSBNYXRoLmxvZztcbnZhciBwb3ckMSA9IE1hdGgucG93O1xudmFyIHNpbiQxID0gTWF0aC5zaW47XG52YXIgc2lnbiQxID0gTWF0aC5zaWduIHx8IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHggPiAwID8gMSA6IHggPCAwID8gLTEgOiAwOyB9O1xudmFyIHNxcnQkMSA9IE1hdGguc3FydDtcbnZhciB0YW4gPSBNYXRoLnRhbjtcblxuZnVuY3Rpb24gYWNvcyh4KSB7XG4gIHJldHVybiB4ID4gMSA/IDAgOiB4IDwgLTEgPyBwaSQ0IDogTWF0aC5hY29zKHgpO1xufVxuXG5mdW5jdGlvbiBhc2luJDEoeCkge1xuICByZXR1cm4geCA+IDEgPyBoYWxmUGkkMyA6IHggPCAtMSA/IC1oYWxmUGkkMyA6IE1hdGguYXNpbih4KTtcbn1cblxuZnVuY3Rpb24gaGF2ZXJzaW4oeCkge1xuICByZXR1cm4gKHggPSBzaW4kMSh4IC8gMikpICogeDtcbn1cblxuZnVuY3Rpb24gbm9vcCQyKCkge31cblxuZnVuY3Rpb24gc3RyZWFtR2VvbWV0cnkoZ2VvbWV0cnksIHN0cmVhbSkge1xuICBpZiAoZ2VvbWV0cnkgJiYgc3RyZWFtR2VvbWV0cnlUeXBlLmhhc093blByb3BlcnR5KGdlb21ldHJ5LnR5cGUpKSB7XG4gICAgc3RyZWFtR2VvbWV0cnlUeXBlW2dlb21ldHJ5LnR5cGVdKGdlb21ldHJ5LCBzdHJlYW0pO1xuICB9XG59XG5cbnZhciBzdHJlYW1PYmplY3RUeXBlID0ge1xuICBGZWF0dXJlOiBmdW5jdGlvbihmZWF0dXJlLCBzdHJlYW0pIHtcbiAgICBzdHJlYW1HZW9tZXRyeShmZWF0dXJlLmdlb21ldHJ5LCBzdHJlYW0pO1xuICB9LFxuICBGZWF0dXJlQ29sbGVjdGlvbjogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICB2YXIgZmVhdHVyZXMgPSBvYmplY3QuZmVhdHVyZXMsIGkgPSAtMSwgbiA9IGZlYXR1cmVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgc3RyZWFtR2VvbWV0cnkoZmVhdHVyZXNbaV0uZ2VvbWV0cnksIHN0cmVhbSk7XG4gIH1cbn07XG5cbnZhciBzdHJlYW1HZW9tZXRyeVR5cGUgPSB7XG4gIFNwaGVyZTogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICBzdHJlYW0uc3BoZXJlKCk7XG4gIH0sXG4gIFBvaW50OiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIG9iamVjdCA9IG9iamVjdC5jb29yZGluYXRlcztcbiAgICBzdHJlYW0ucG9pbnQob2JqZWN0WzBdLCBvYmplY3RbMV0sIG9iamVjdFsyXSk7XG4gIH0sXG4gIE11bHRpUG9pbnQ6IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgdmFyIGNvb3JkaW5hdGVzID0gb2JqZWN0LmNvb3JkaW5hdGVzLCBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIG9iamVjdCA9IGNvb3JkaW5hdGVzW2ldLCBzdHJlYW0ucG9pbnQob2JqZWN0WzBdLCBvYmplY3RbMV0sIG9iamVjdFsyXSk7XG4gIH0sXG4gIExpbmVTdHJpbmc6IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgc3RyZWFtTGluZShvYmplY3QuY29vcmRpbmF0ZXMsIHN0cmVhbSwgMCk7XG4gIH0sXG4gIE11bHRpTGluZVN0cmluZzogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICB2YXIgY29vcmRpbmF0ZXMgPSBvYmplY3QuY29vcmRpbmF0ZXMsIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgc3RyZWFtTGluZShjb29yZGluYXRlc1tpXSwgc3RyZWFtLCAwKTtcbiAgfSxcbiAgUG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICBzdHJlYW1Qb2x5Z29uKG9iamVjdC5jb29yZGluYXRlcywgc3RyZWFtKTtcbiAgfSxcbiAgTXVsdGlQb2x5Z29uOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHZhciBjb29yZGluYXRlcyA9IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBzdHJlYW1Qb2x5Z29uKGNvb3JkaW5hdGVzW2ldLCBzdHJlYW0pO1xuICB9LFxuICBHZW9tZXRyeUNvbGxlY3Rpb246IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgdmFyIGdlb21ldHJpZXMgPSBvYmplY3QuZ2VvbWV0cmllcywgaSA9IC0xLCBuID0gZ2VvbWV0cmllcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIHN0cmVhbUdlb21ldHJ5KGdlb21ldHJpZXNbaV0sIHN0cmVhbSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHN0cmVhbUxpbmUoY29vcmRpbmF0ZXMsIHN0cmVhbSwgY2xvc2VkKSB7XG4gIHZhciBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGggLSBjbG9zZWQsIGNvb3JkaW5hdGU7XG4gIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgd2hpbGUgKCsraSA8IG4pIGNvb3JkaW5hdGUgPSBjb29yZGluYXRlc1tpXSwgc3RyZWFtLnBvaW50KGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0sIGNvb3JkaW5hdGVbMl0pO1xuICBzdHJlYW0ubGluZUVuZCgpO1xufVxuXG5mdW5jdGlvbiBzdHJlYW1Qb2x5Z29uKGNvb3JkaW5hdGVzLCBzdHJlYW0pIHtcbiAgdmFyIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgc3RyZWFtLnBvbHlnb25TdGFydCgpO1xuICB3aGlsZSAoKytpIDwgbikgc3RyZWFtTGluZShjb29yZGluYXRlc1tpXSwgc3RyZWFtLCAxKTtcbiAgc3RyZWFtLnBvbHlnb25FbmQoKTtcbn1cblxudmFyIGdlb1N0cmVhbSA9IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gIGlmIChvYmplY3QgJiYgc3RyZWFtT2JqZWN0VHlwZS5oYXNPd25Qcm9wZXJ0eShvYmplY3QudHlwZSkpIHtcbiAgICBzdHJlYW1PYmplY3RUeXBlW29iamVjdC50eXBlXShvYmplY3QsIHN0cmVhbSk7XG4gIH0gZWxzZSB7XG4gICAgc3RyZWFtR2VvbWV0cnkob2JqZWN0LCBzdHJlYW0pO1xuICB9XG59O1xuXG52YXIgYXJlYVJpbmdTdW0gPSBhZGRlcigpO1xuXG52YXIgYXJlYVN1bSA9IGFkZGVyKCk7XG52YXIgbGFtYmRhMDA7XG52YXIgcGhpMDA7XG52YXIgbGFtYmRhMDtcbnZhciBjb3NQaGkwO1xudmFyIHNpblBoaTA7XG5cbnZhciBhcmVhU3RyZWFtID0ge1xuICBwb2ludDogbm9vcCQyLFxuICBsaW5lU3RhcnQ6IG5vb3AkMixcbiAgbGluZUVuZDogbm9vcCQyLFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIGFyZWFSaW5nU3VtLnJlc2V0KCk7XG4gICAgYXJlYVN0cmVhbS5saW5lU3RhcnQgPSBhcmVhUmluZ1N0YXJ0O1xuICAgIGFyZWFTdHJlYW0ubGluZUVuZCA9IGFyZWFSaW5nRW5kO1xuICB9LFxuICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgYXJlYVJpbmcgPSArYXJlYVJpbmdTdW07XG4gICAgYXJlYVN1bS5hZGQoYXJlYVJpbmcgPCAwID8gdGF1JDQgKyBhcmVhUmluZyA6IGFyZWFSaW5nKTtcbiAgICB0aGlzLmxpbmVTdGFydCA9IHRoaXMubGluZUVuZCA9IHRoaXMucG9pbnQgPSBub29wJDI7XG4gIH0sXG4gIHNwaGVyZTogZnVuY3Rpb24oKSB7XG4gICAgYXJlYVN1bS5hZGQodGF1JDQpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBhcmVhUmluZ1N0YXJ0KCkge1xuICBhcmVhU3RyZWFtLnBvaW50ID0gYXJlYVBvaW50Rmlyc3Q7XG59XG5cbmZ1bmN0aW9uIGFyZWFSaW5nRW5kKCkge1xuICBhcmVhUG9pbnQobGFtYmRhMDAsIHBoaTAwKTtcbn1cblxuZnVuY3Rpb24gYXJlYVBvaW50Rmlyc3QobGFtYmRhLCBwaGkpIHtcbiAgYXJlYVN0cmVhbS5wb2ludCA9IGFyZWFQb2ludDtcbiAgbGFtYmRhMDAgPSBsYW1iZGEsIHBoaTAwID0gcGhpO1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIGxhbWJkYTAgPSBsYW1iZGEsIGNvc1BoaTAgPSBjb3MkMShwaGkgPSBwaGkgLyAyICsgcXVhcnRlclBpKSwgc2luUGhpMCA9IHNpbiQxKHBoaSk7XG59XG5cbmZ1bmN0aW9uIGFyZWFQb2ludChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIHBoaSA9IHBoaSAvIDIgKyBxdWFydGVyUGk7IC8vIGhhbGYgdGhlIGFuZ3VsYXIgZGlzdGFuY2UgZnJvbSBzb3V0aCBwb2xlXG5cbiAgLy8gU3BoZXJpY2FsIGV4Y2VzcyBFIGZvciBhIHNwaGVyaWNhbCB0cmlhbmdsZSB3aXRoIHZlcnRpY2VzOiBzb3V0aCBwb2xlLFxuICAvLyBwcmV2aW91cyBwb2ludCwgY3VycmVudCBwb2ludC4gIFVzZXMgYSBmb3JtdWxhIGRlcml2ZWQgZnJvbSBDYWdub2xp4oCZc1xuICAvLyB0aGVvcmVtLiAgU2VlIFRvZGh1bnRlciwgU3BoZXJpY2FsIFRyaWcuICgxODcxKSwgU2VjLiAxMDMsIEVxLiAoMikuXG4gIHZhciBkTGFtYmRhID0gbGFtYmRhIC0gbGFtYmRhMCxcbiAgICAgIHNkTGFtYmRhID0gZExhbWJkYSA+PSAwID8gMSA6IC0xLFxuICAgICAgYWRMYW1iZGEgPSBzZExhbWJkYSAqIGRMYW1iZGEsXG4gICAgICBjb3NQaGkgPSBjb3MkMShwaGkpLFxuICAgICAgc2luUGhpID0gc2luJDEocGhpKSxcbiAgICAgIGsgPSBzaW5QaGkwICogc2luUGhpLFxuICAgICAgdSA9IGNvc1BoaTAgKiBjb3NQaGkgKyBrICogY29zJDEoYWRMYW1iZGEpLFxuICAgICAgdiA9IGsgKiBzZExhbWJkYSAqIHNpbiQxKGFkTGFtYmRhKTtcbiAgYXJlYVJpbmdTdW0uYWRkKGF0YW4yKHYsIHUpKTtcblxuICAvLyBBZHZhbmNlIHRoZSBwcmV2aW91cyBwb2ludHMuXG4gIGxhbWJkYTAgPSBsYW1iZGEsIGNvc1BoaTAgPSBjb3NQaGksIHNpblBoaTAgPSBzaW5QaGk7XG59XG5cbnZhciBhcmVhJDIgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgYXJlYVN1bS5yZXNldCgpO1xuICBnZW9TdHJlYW0ob2JqZWN0LCBhcmVhU3RyZWFtKTtcbiAgcmV0dXJuIGFyZWFTdW0gKiAyO1xufTtcblxuZnVuY3Rpb24gc3BoZXJpY2FsKGNhcnRlc2lhbikge1xuICByZXR1cm4gW2F0YW4yKGNhcnRlc2lhblsxXSwgY2FydGVzaWFuWzBdKSwgYXNpbiQxKGNhcnRlc2lhblsyXSldO1xufVxuXG5mdW5jdGlvbiBjYXJ0ZXNpYW4oc3BoZXJpY2FsKSB7XG4gIHZhciBsYW1iZGEgPSBzcGhlcmljYWxbMF0sIHBoaSA9IHNwaGVyaWNhbFsxXSwgY29zUGhpID0gY29zJDEocGhpKTtcbiAgcmV0dXJuIFtjb3NQaGkgKiBjb3MkMShsYW1iZGEpLCBjb3NQaGkgKiBzaW4kMShsYW1iZGEpLCBzaW4kMShwaGkpXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuRG90KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuQ3Jvc3MoYSwgYikge1xuICByZXR1cm4gW2FbMV0gKiBiWzJdIC0gYVsyXSAqIGJbMV0sIGFbMl0gKiBiWzBdIC0gYVswXSAqIGJbMl0sIGFbMF0gKiBiWzFdIC0gYVsxXSAqIGJbMF1dO1xufVxuXG4vLyBUT0RPIHJldHVybiBhXG5mdW5jdGlvbiBjYXJ0ZXNpYW5BZGRJblBsYWNlKGEsIGIpIHtcbiAgYVswXSArPSBiWzBdLCBhWzFdICs9IGJbMV0sIGFbMl0gKz0gYlsyXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuU2NhbGUodmVjdG9yLCBrKSB7XG4gIHJldHVybiBbdmVjdG9yWzBdICogaywgdmVjdG9yWzFdICogaywgdmVjdG9yWzJdICoga107XG59XG5cbi8vIFRPRE8gcmV0dXJuIGRcbmZ1bmN0aW9uIGNhcnRlc2lhbk5vcm1hbGl6ZUluUGxhY2UoZCkge1xuICB2YXIgbCA9IHNxcnQkMShkWzBdICogZFswXSArIGRbMV0gKiBkWzFdICsgZFsyXSAqIGRbMl0pO1xuICBkWzBdIC89IGwsIGRbMV0gLz0gbCwgZFsyXSAvPSBsO1xufVxuXG52YXIgbGFtYmRhMCQxO1xudmFyIHBoaTA7XG52YXIgbGFtYmRhMTtcbnZhciBwaGkxO1xudmFyIGxhbWJkYTI7XG52YXIgbGFtYmRhMDAkMTtcbnZhciBwaGkwMCQxO1xudmFyIHAwO1xudmFyIGRlbHRhU3VtID0gYWRkZXIoKTtcbnZhciByYW5nZXM7XG52YXIgcmFuZ2UkMTtcblxudmFyIGJvdW5kc1N0cmVhbSA9IHtcbiAgcG9pbnQ6IGJvdW5kc1BvaW50LFxuICBsaW5lU3RhcnQ6IGJvdW5kc0xpbmVTdGFydCxcbiAgbGluZUVuZDogYm91bmRzTGluZUVuZCxcbiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICBib3VuZHNTdHJlYW0ucG9pbnQgPSBib3VuZHNSaW5nUG9pbnQ7XG4gICAgYm91bmRzU3RyZWFtLmxpbmVTdGFydCA9IGJvdW5kc1JpbmdTdGFydDtcbiAgICBib3VuZHNTdHJlYW0ubGluZUVuZCA9IGJvdW5kc1JpbmdFbmQ7XG4gICAgZGVsdGFTdW0ucmVzZXQoKTtcbiAgICBhcmVhU3RyZWFtLnBvbHlnb25TdGFydCgpO1xuICB9LFxuICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICBhcmVhU3RyZWFtLnBvbHlnb25FbmQoKTtcbiAgICBib3VuZHNTdHJlYW0ucG9pbnQgPSBib3VuZHNQb2ludDtcbiAgICBib3VuZHNTdHJlYW0ubGluZVN0YXJ0ID0gYm91bmRzTGluZVN0YXJ0O1xuICAgIGJvdW5kc1N0cmVhbS5saW5lRW5kID0gYm91bmRzTGluZUVuZDtcbiAgICBpZiAoYXJlYVJpbmdTdW0gPCAwKSBsYW1iZGEwJDEgPSAtKGxhbWJkYTEgPSAxODApLCBwaGkwID0gLShwaGkxID0gOTApO1xuICAgIGVsc2UgaWYgKGRlbHRhU3VtID4gZXBzaWxvbiQ0KSBwaGkxID0gOTA7XG4gICAgZWxzZSBpZiAoZGVsdGFTdW0gPCAtZXBzaWxvbiQ0KSBwaGkwID0gLTkwO1xuICAgIHJhbmdlJDFbMF0gPSBsYW1iZGEwJDEsIHJhbmdlJDFbMV0gPSBsYW1iZGExO1xuICB9XG59O1xuXG5mdW5jdGlvbiBib3VuZHNQb2ludChsYW1iZGEsIHBoaSkge1xuICByYW5nZXMucHVzaChyYW5nZSQxID0gW2xhbWJkYTAkMSA9IGxhbWJkYSwgbGFtYmRhMSA9IGxhbWJkYV0pO1xuICBpZiAocGhpIDwgcGhpMCkgcGhpMCA9IHBoaTtcbiAgaWYgKHBoaSA+IHBoaTEpIHBoaTEgPSBwaGk7XG59XG5cbmZ1bmN0aW9uIGxpbmVQb2ludChsYW1iZGEsIHBoaSkge1xuICB2YXIgcCA9IGNhcnRlc2lhbihbbGFtYmRhICogcmFkaWFucywgcGhpICogcmFkaWFuc10pO1xuICBpZiAocDApIHtcbiAgICB2YXIgbm9ybWFsID0gY2FydGVzaWFuQ3Jvc3MocDAsIHApLFxuICAgICAgICBlcXVhdG9yaWFsID0gW25vcm1hbFsxXSwgLW5vcm1hbFswXSwgMF0sXG4gICAgICAgIGluZmxlY3Rpb24gPSBjYXJ0ZXNpYW5Dcm9zcyhlcXVhdG9yaWFsLCBub3JtYWwpO1xuICAgIGNhcnRlc2lhbk5vcm1hbGl6ZUluUGxhY2UoaW5mbGVjdGlvbik7XG4gICAgaW5mbGVjdGlvbiA9IHNwaGVyaWNhbChpbmZsZWN0aW9uKTtcbiAgICB2YXIgZGVsdGEgPSBsYW1iZGEgLSBsYW1iZGEyLFxuICAgICAgICBzaWduJCQxID0gZGVsdGEgPiAwID8gMSA6IC0xLFxuICAgICAgICBsYW1iZGFpID0gaW5mbGVjdGlvblswXSAqIGRlZ3JlZXMkMSAqIHNpZ24kJDEsXG4gICAgICAgIHBoaWksXG4gICAgICAgIGFudGltZXJpZGlhbiA9IGFicyhkZWx0YSkgPiAxODA7XG4gICAgaWYgKGFudGltZXJpZGlhbiBeIChzaWduJCQxICogbGFtYmRhMiA8IGxhbWJkYWkgJiYgbGFtYmRhaSA8IHNpZ24kJDEgKiBsYW1iZGEpKSB7XG4gICAgICBwaGlpID0gaW5mbGVjdGlvblsxXSAqIGRlZ3JlZXMkMTtcbiAgICAgIGlmIChwaGlpID4gcGhpMSkgcGhpMSA9IHBoaWk7XG4gICAgfSBlbHNlIGlmIChsYW1iZGFpID0gKGxhbWJkYWkgKyAzNjApICUgMzYwIC0gMTgwLCBhbnRpbWVyaWRpYW4gXiAoc2lnbiQkMSAqIGxhbWJkYTIgPCBsYW1iZGFpICYmIGxhbWJkYWkgPCBzaWduJCQxICogbGFtYmRhKSkge1xuICAgICAgcGhpaSA9IC1pbmZsZWN0aW9uWzFdICogZGVncmVlcyQxO1xuICAgICAgaWYgKHBoaWkgPCBwaGkwKSBwaGkwID0gcGhpaTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHBoaSA8IHBoaTApIHBoaTAgPSBwaGk7XG4gICAgICBpZiAocGhpID4gcGhpMSkgcGhpMSA9IHBoaTtcbiAgICB9XG4gICAgaWYgKGFudGltZXJpZGlhbikge1xuICAgICAgaWYgKGxhbWJkYSA8IGxhbWJkYTIpIHtcbiAgICAgICAgaWYgKGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhKSA+IGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhMSkpIGxhbWJkYTEgPSBsYW1iZGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoYW5nbGUobGFtYmRhLCBsYW1iZGExKSA+IGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhMSkpIGxhbWJkYTAkMSA9IGxhbWJkYTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGxhbWJkYTEgPj0gbGFtYmRhMCQxKSB7XG4gICAgICAgIGlmIChsYW1iZGEgPCBsYW1iZGEwJDEpIGxhbWJkYTAkMSA9IGxhbWJkYTtcbiAgICAgICAgaWYgKGxhbWJkYSA+IGxhbWJkYTEpIGxhbWJkYTEgPSBsYW1iZGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobGFtYmRhID4gbGFtYmRhMikge1xuICAgICAgICAgIGlmIChhbmdsZShsYW1iZGEwJDEsIGxhbWJkYSkgPiBhbmdsZShsYW1iZGEwJDEsIGxhbWJkYTEpKSBsYW1iZGExID0gbGFtYmRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhbmdsZShsYW1iZGEsIGxhbWJkYTEpID4gYW5nbGUobGFtYmRhMCQxLCBsYW1iZGExKSkgbGFtYmRhMCQxID0gbGFtYmRhO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGJvdW5kc1BvaW50KGxhbWJkYSwgcGhpKTtcbiAgfVxuICBwMCA9IHAsIGxhbWJkYTIgPSBsYW1iZGE7XG59XG5cbmZ1bmN0aW9uIGJvdW5kc0xpbmVTdGFydCgpIHtcbiAgYm91bmRzU3RyZWFtLnBvaW50ID0gbGluZVBvaW50O1xufVxuXG5mdW5jdGlvbiBib3VuZHNMaW5lRW5kKCkge1xuICByYW5nZSQxWzBdID0gbGFtYmRhMCQxLCByYW5nZSQxWzFdID0gbGFtYmRhMTtcbiAgYm91bmRzU3RyZWFtLnBvaW50ID0gYm91bmRzUG9pbnQ7XG4gIHAwID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYm91bmRzUmluZ1BvaW50KGxhbWJkYSwgcGhpKSB7XG4gIGlmIChwMCkge1xuICAgIHZhciBkZWx0YSA9IGxhbWJkYSAtIGxhbWJkYTI7XG4gICAgZGVsdGFTdW0uYWRkKGFicyhkZWx0YSkgPiAxODAgPyBkZWx0YSArIChkZWx0YSA+IDAgPyAzNjAgOiAtMzYwKSA6IGRlbHRhKTtcbiAgfSBlbHNlIHtcbiAgICBsYW1iZGEwMCQxID0gbGFtYmRhLCBwaGkwMCQxID0gcGhpO1xuICB9XG4gIGFyZWFTdHJlYW0ucG9pbnQobGFtYmRhLCBwaGkpO1xuICBsaW5lUG9pbnQobGFtYmRhLCBwaGkpO1xufVxuXG5mdW5jdGlvbiBib3VuZHNSaW5nU3RhcnQoKSB7XG4gIGFyZWFTdHJlYW0ubGluZVN0YXJ0KCk7XG59XG5cbmZ1bmN0aW9uIGJvdW5kc1JpbmdFbmQoKSB7XG4gIGJvdW5kc1JpbmdQb2ludChsYW1iZGEwMCQxLCBwaGkwMCQxKTtcbiAgYXJlYVN0cmVhbS5saW5lRW5kKCk7XG4gIGlmIChhYnMoZGVsdGFTdW0pID4gZXBzaWxvbiQ0KSBsYW1iZGEwJDEgPSAtKGxhbWJkYTEgPSAxODApO1xuICByYW5nZSQxWzBdID0gbGFtYmRhMCQxLCByYW5nZSQxWzFdID0gbGFtYmRhMTtcbiAgcDAgPSBudWxsO1xufVxuXG4vLyBGaW5kcyB0aGUgbGVmdC1yaWdodCBkaXN0YW5jZSBiZXR3ZWVuIHR3byBsb25naXR1ZGVzLlxuLy8gVGhpcyBpcyBhbG1vc3QgdGhlIHNhbWUgYXMgKGxhbWJkYTEgLSBsYW1iZGEwICsgMzYwwrApICUgMzYwwrAsIGV4Y2VwdCB0aGF0IHdlIHdhbnRcbi8vIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIMKxMTgwwrAgdG8gYmUgMzYwwrAuXG5mdW5jdGlvbiBhbmdsZShsYW1iZGEwLCBsYW1iZGExKSB7XG4gIHJldHVybiAobGFtYmRhMSAtPSBsYW1iZGEwKSA8IDAgPyBsYW1iZGExICsgMzYwIDogbGFtYmRhMTtcbn1cblxuZnVuY3Rpb24gcmFuZ2VDb21wYXJlKGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gLSBiWzBdO1xufVxuXG5mdW5jdGlvbiByYW5nZUNvbnRhaW5zKHJhbmdlLCB4KSB7XG4gIHJldHVybiByYW5nZVswXSA8PSByYW5nZVsxXSA/IHJhbmdlWzBdIDw9IHggJiYgeCA8PSByYW5nZVsxXSA6IHggPCByYW5nZVswXSB8fCByYW5nZVsxXSA8IHg7XG59XG5cbnZhciBib3VuZHMgPSBmdW5jdGlvbihmZWF0dXJlKSB7XG4gIHZhciBpLCBuLCBhLCBiLCBtZXJnZWQsIGRlbHRhTWF4LCBkZWx0YTtcblxuICBwaGkxID0gbGFtYmRhMSA9IC0obGFtYmRhMCQxID0gcGhpMCA9IEluZmluaXR5KTtcbiAgcmFuZ2VzID0gW107XG4gIGdlb1N0cmVhbShmZWF0dXJlLCBib3VuZHNTdHJlYW0pO1xuXG4gIC8vIEZpcnN0LCBzb3J0IHJhbmdlcyBieSB0aGVpciBtaW5pbXVtIGxvbmdpdHVkZXMuXG4gIGlmIChuID0gcmFuZ2VzLmxlbmd0aCkge1xuICAgIHJhbmdlcy5zb3J0KHJhbmdlQ29tcGFyZSk7XG5cbiAgICAvLyBUaGVuLCBtZXJnZSBhbnkgcmFuZ2VzIHRoYXQgb3ZlcmxhcC5cbiAgICBmb3IgKGkgPSAxLCBhID0gcmFuZ2VzWzBdLCBtZXJnZWQgPSBbYV07IGkgPCBuOyArK2kpIHtcbiAgICAgIGIgPSByYW5nZXNbaV07XG4gICAgICBpZiAocmFuZ2VDb250YWlucyhhLCBiWzBdKSB8fCByYW5nZUNvbnRhaW5zKGEsIGJbMV0pKSB7XG4gICAgICAgIGlmIChhbmdsZShhWzBdLCBiWzFdKSA+IGFuZ2xlKGFbMF0sIGFbMV0pKSBhWzFdID0gYlsxXTtcbiAgICAgICAgaWYgKGFuZ2xlKGJbMF0sIGFbMV0pID4gYW5nbGUoYVswXSwgYVsxXSkpIGFbMF0gPSBiWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWVyZ2VkLnB1c2goYSA9IGIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZpbmFsbHksIGZpbmQgdGhlIGxhcmdlc3QgZ2FwIGJldHdlZW4gdGhlIG1lcmdlZCByYW5nZXMuXG4gICAgLy8gVGhlIGZpbmFsIGJvdW5kaW5nIGJveCB3aWxsIGJlIHRoZSBpbnZlcnNlIG9mIHRoaXMgZ2FwLlxuICAgIGZvciAoZGVsdGFNYXggPSAtSW5maW5pdHksIG4gPSBtZXJnZWQubGVuZ3RoIC0gMSwgaSA9IDAsIGEgPSBtZXJnZWRbbl07IGkgPD0gbjsgYSA9IGIsICsraSkge1xuICAgICAgYiA9IG1lcmdlZFtpXTtcbiAgICAgIGlmICgoZGVsdGEgPSBhbmdsZShhWzFdLCBiWzBdKSkgPiBkZWx0YU1heCkgZGVsdGFNYXggPSBkZWx0YSwgbGFtYmRhMCQxID0gYlswXSwgbGFtYmRhMSA9IGFbMV07XG4gICAgfVxuICB9XG5cbiAgcmFuZ2VzID0gcmFuZ2UkMSA9IG51bGw7XG5cbiAgcmV0dXJuIGxhbWJkYTAkMSA9PT0gSW5maW5pdHkgfHwgcGhpMCA9PT0gSW5maW5pdHlcbiAgICAgID8gW1tOYU4sIE5hTl0sIFtOYU4sIE5hTl1dXG4gICAgICA6IFtbbGFtYmRhMCQxLCBwaGkwXSwgW2xhbWJkYTEsIHBoaTFdXTtcbn07XG5cbnZhciBXMDtcbnZhciBXMTtcbnZhciBYMDtcbnZhciBZMDtcbnZhciBaMDtcbnZhciBYMTtcbnZhciBZMTtcbnZhciBaMTtcbnZhciBYMjtcbnZhciBZMjtcbnZhciBaMjtcbnZhciBsYW1iZGEwMCQyO1xudmFyIHBoaTAwJDI7XG52YXIgeDA7XG52YXIgeTA7XG52YXIgejA7IC8vIHByZXZpb3VzIHBvaW50XG5cbnZhciBjZW50cm9pZFN0cmVhbSA9IHtcbiAgc3BoZXJlOiBub29wJDIsXG4gIHBvaW50OiBjZW50cm9pZFBvaW50LFxuICBsaW5lU3RhcnQ6IGNlbnRyb2lkTGluZVN0YXJ0LFxuICBsaW5lRW5kOiBjZW50cm9pZExpbmVFbmQsXG4gIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgY2VudHJvaWRTdHJlYW0ubGluZVN0YXJ0ID0gY2VudHJvaWRSaW5nU3RhcnQ7XG4gICAgY2VudHJvaWRTdHJlYW0ubGluZUVuZCA9IGNlbnRyb2lkUmluZ0VuZDtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgY2VudHJvaWRTdHJlYW0ubGluZVN0YXJ0ID0gY2VudHJvaWRMaW5lU3RhcnQ7XG4gICAgY2VudHJvaWRTdHJlYW0ubGluZUVuZCA9IGNlbnRyb2lkTGluZUVuZDtcbiAgfVxufTtcblxuLy8gQXJpdGhtZXRpYyBtZWFuIG9mIENhcnRlc2lhbiB2ZWN0b3JzLlxuZnVuY3Rpb24gY2VudHJvaWRQb2ludChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpO1xuICBjZW50cm9pZFBvaW50Q2FydGVzaWFuKGNvc1BoaSAqIGNvcyQxKGxhbWJkYSksIGNvc1BoaSAqIHNpbiQxKGxhbWJkYSksIHNpbiQxKHBoaSkpO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFBvaW50Q2FydGVzaWFuKHgsIHksIHopIHtcbiAgKytXMDtcbiAgWDAgKz0gKHggLSBYMCkgLyBXMDtcbiAgWTAgKz0gKHkgLSBZMCkgLyBXMDtcbiAgWjAgKz0gKHogLSBaMCkgLyBXMDtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRMaW5lU3RhcnQoKSB7XG4gIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJvaWRMaW5lUG9pbnRGaXJzdDtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRMaW5lUG9pbnRGaXJzdChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpO1xuICB4MCA9IGNvc1BoaSAqIGNvcyQxKGxhbWJkYSk7XG4gIHkwID0gY29zUGhpICogc2luJDEobGFtYmRhKTtcbiAgejAgPSBzaW4kMShwaGkpO1xuICBjZW50cm9pZFN0cmVhbS5wb2ludCA9IGNlbnRyb2lkTGluZVBvaW50O1xuICBjZW50cm9pZFBvaW50Q2FydGVzaWFuKHgwLCB5MCwgejApO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZExpbmVQb2ludChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpLFxuICAgICAgeCA9IGNvc1BoaSAqIGNvcyQxKGxhbWJkYSksXG4gICAgICB5ID0gY29zUGhpICogc2luJDEobGFtYmRhKSxcbiAgICAgIHogPSBzaW4kMShwaGkpLFxuICAgICAgdyA9IGF0YW4yKHNxcnQkMSgodyA9IHkwICogeiAtIHowICogeSkgKiB3ICsgKHcgPSB6MCAqIHggLSB4MCAqIHopICogdyArICh3ID0geDAgKiB5IC0geTAgKiB4KSAqIHcpLCB4MCAqIHggKyB5MCAqIHkgKyB6MCAqIHopO1xuICBXMSArPSB3O1xuICBYMSArPSB3ICogKHgwICsgKHgwID0geCkpO1xuICBZMSArPSB3ICogKHkwICsgKHkwID0geSkpO1xuICBaMSArPSB3ICogKHowICsgKHowID0geikpO1xuICBjZW50cm9pZFBvaW50Q2FydGVzaWFuKHgwLCB5MCwgejApO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZExpbmVFbmQoKSB7XG4gIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJvaWRQb2ludDtcbn1cblxuLy8gU2VlIEouIEUuIEJyb2NrLCBUaGUgSW5lcnRpYSBUZW5zb3IgZm9yIGEgU3BoZXJpY2FsIFRyaWFuZ2xlLFxuLy8gSi4gQXBwbGllZCBNZWNoYW5pY3MgNDIsIDIzOSAoMTk3NSkuXG5mdW5jdGlvbiBjZW50cm9pZFJpbmdTdGFydCgpIHtcbiAgY2VudHJvaWRTdHJlYW0ucG9pbnQgPSBjZW50cm9pZFJpbmdQb2ludEZpcnN0O1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFJpbmdFbmQoKSB7XG4gIGNlbnRyb2lkUmluZ1BvaW50KGxhbWJkYTAwJDIsIHBoaTAwJDIpO1xuICBjZW50cm9pZFN0cmVhbS5wb2ludCA9IGNlbnRyb2lkUG9pbnQ7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUmluZ1BvaW50Rmlyc3QobGFtYmRhLCBwaGkpIHtcbiAgbGFtYmRhMDAkMiA9IGxhbWJkYSwgcGhpMDAkMiA9IHBoaTtcbiAgbGFtYmRhICo9IHJhZGlhbnMsIHBoaSAqPSByYWRpYW5zO1xuICBjZW50cm9pZFN0cmVhbS5wb2ludCA9IGNlbnRyb2lkUmluZ1BvaW50O1xuICB2YXIgY29zUGhpID0gY29zJDEocGhpKTtcbiAgeDAgPSBjb3NQaGkgKiBjb3MkMShsYW1iZGEpO1xuICB5MCA9IGNvc1BoaSAqIHNpbiQxKGxhbWJkYSk7XG4gIHowID0gc2luJDEocGhpKTtcbiAgY2VudHJvaWRQb2ludENhcnRlc2lhbih4MCwgeTAsIHowKTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRSaW5nUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgbGFtYmRhICo9IHJhZGlhbnMsIHBoaSAqPSByYWRpYW5zO1xuICB2YXIgY29zUGhpID0gY29zJDEocGhpKSxcbiAgICAgIHggPSBjb3NQaGkgKiBjb3MkMShsYW1iZGEpLFxuICAgICAgeSA9IGNvc1BoaSAqIHNpbiQxKGxhbWJkYSksXG4gICAgICB6ID0gc2luJDEocGhpKSxcbiAgICAgIGN4ID0geTAgKiB6IC0gejAgKiB5LFxuICAgICAgY3kgPSB6MCAqIHggLSB4MCAqIHosXG4gICAgICBjeiA9IHgwICogeSAtIHkwICogeCxcbiAgICAgIG0gPSBzcXJ0JDEoY3ggKiBjeCArIGN5ICogY3kgKyBjeiAqIGN6KSxcbiAgICAgIHUgPSB4MCAqIHggKyB5MCAqIHkgKyB6MCAqIHosXG4gICAgICB2ID0gbSAmJiAtYWNvcyh1KSAvIG0sIC8vIGFyZWEgd2VpZ2h0XG4gICAgICB3ID0gYXRhbjIobSwgdSk7IC8vIGxpbmUgd2VpZ2h0XG4gIFgyICs9IHYgKiBjeDtcbiAgWTIgKz0gdiAqIGN5O1xuICBaMiArPSB2ICogY3o7XG4gIFcxICs9IHc7XG4gIFgxICs9IHcgKiAoeDAgKyAoeDAgPSB4KSk7XG4gIFkxICs9IHcgKiAoeTAgKyAoeTAgPSB5KSk7XG4gIFoxICs9IHcgKiAoejAgKyAoejAgPSB6KSk7XG4gIGNlbnRyb2lkUG9pbnRDYXJ0ZXNpYW4oeDAsIHkwLCB6MCk7XG59XG5cbnZhciBjZW50cm9pZCQxID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gIFcwID0gVzEgPVxuICBYMCA9IFkwID0gWjAgPVxuICBYMSA9IFkxID0gWjEgPVxuICBYMiA9IFkyID0gWjIgPSAwO1xuICBnZW9TdHJlYW0ob2JqZWN0LCBjZW50cm9pZFN0cmVhbSk7XG5cbiAgdmFyIHggPSBYMixcbiAgICAgIHkgPSBZMixcbiAgICAgIHogPSBaMixcbiAgICAgIG0gPSB4ICogeCArIHkgKiB5ICsgeiAqIHo7XG5cbiAgLy8gSWYgdGhlIGFyZWEtd2VpZ2h0ZWQgY2NlbnRyb2lkIGlzIHVuZGVmaW5lZCwgZmFsbCBiYWNrIHRvIGxlbmd0aC13ZWlnaHRlZCBjY2VudHJvaWQuXG4gIGlmIChtIDwgZXBzaWxvbjIkMikge1xuICAgIHggPSBYMSwgeSA9IFkxLCB6ID0gWjE7XG4gICAgLy8gSWYgdGhlIGZlYXR1cmUgaGFzIHplcm8gbGVuZ3RoLCBmYWxsIGJhY2sgdG8gYXJpdGhtZXRpYyBtZWFuIG9mIHBvaW50IHZlY3RvcnMuXG4gICAgaWYgKFcxIDwgZXBzaWxvbiQ0KSB4ID0gWDAsIHkgPSBZMCwgeiA9IFowO1xuICAgIG0gPSB4ICogeCArIHkgKiB5ICsgeiAqIHo7XG4gICAgLy8gSWYgdGhlIGZlYXR1cmUgc3RpbGwgaGFzIGFuIHVuZGVmaW5lZCBjY2VudHJvaWQsIHRoZW4gcmV0dXJuLlxuICAgIGlmIChtIDwgZXBzaWxvbjIkMikgcmV0dXJuIFtOYU4sIE5hTl07XG4gIH1cblxuICByZXR1cm4gW2F0YW4yKHksIHgpICogZGVncmVlcyQxLCBhc2luJDEoeiAvIHNxcnQkMShtKSkgKiBkZWdyZWVzJDFdO1xufTtcblxudmFyIGNvbnN0YW50JDEzID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG52YXIgY29tcG9zZSA9IGZ1bmN0aW9uKGEsIGIpIHtcblxuICBmdW5jdGlvbiBjb21wb3NlKHgsIHkpIHtcbiAgICByZXR1cm4geCA9IGEoeCwgeSksIGIoeFswXSwgeFsxXSk7XG4gIH1cblxuICBpZiAoYS5pbnZlcnQgJiYgYi5pbnZlcnQpIGNvbXBvc2UuaW52ZXJ0ID0gZnVuY3Rpb24oeCwgeSkge1xuICAgIHJldHVybiB4ID0gYi5pbnZlcnQoeCwgeSksIHggJiYgYS5pbnZlcnQoeFswXSwgeFsxXSk7XG4gIH07XG5cbiAgcmV0dXJuIGNvbXBvc2U7XG59O1xuXG5mdW5jdGlvbiByb3RhdGlvbklkZW50aXR5KGxhbWJkYSwgcGhpKSB7XG4gIHJldHVybiBbbGFtYmRhID4gcGkkNCA/IGxhbWJkYSAtIHRhdSQ0IDogbGFtYmRhIDwgLXBpJDQgPyBsYW1iZGEgKyB0YXUkNCA6IGxhbWJkYSwgcGhpXTtcbn1cblxucm90YXRpb25JZGVudGl0eS5pbnZlcnQgPSByb3RhdGlvbklkZW50aXR5O1xuXG5mdW5jdGlvbiByb3RhdGVSYWRpYW5zKGRlbHRhTGFtYmRhLCBkZWx0YVBoaSwgZGVsdGFHYW1tYSkge1xuICByZXR1cm4gKGRlbHRhTGFtYmRhICU9IHRhdSQ0KSA/IChkZWx0YVBoaSB8fCBkZWx0YUdhbW1hID8gY29tcG9zZShyb3RhdGlvbkxhbWJkYShkZWx0YUxhbWJkYSksIHJvdGF0aW9uUGhpR2FtbWEoZGVsdGFQaGksIGRlbHRhR2FtbWEpKVxuICAgIDogcm90YXRpb25MYW1iZGEoZGVsdGFMYW1iZGEpKVxuICAgIDogKGRlbHRhUGhpIHx8IGRlbHRhR2FtbWEgPyByb3RhdGlvblBoaUdhbW1hKGRlbHRhUGhpLCBkZWx0YUdhbW1hKVxuICAgIDogcm90YXRpb25JZGVudGl0eSk7XG59XG5cbmZ1bmN0aW9uIGZvcndhcmRSb3RhdGlvbkxhbWJkYShkZWx0YUxhbWJkYSkge1xuICByZXR1cm4gZnVuY3Rpb24obGFtYmRhLCBwaGkpIHtcbiAgICByZXR1cm4gbGFtYmRhICs9IGRlbHRhTGFtYmRhLCBbbGFtYmRhID4gcGkkNCA/IGxhbWJkYSAtIHRhdSQ0IDogbGFtYmRhIDwgLXBpJDQgPyBsYW1iZGEgKyB0YXUkNCA6IGxhbWJkYSwgcGhpXTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcm90YXRpb25MYW1iZGEoZGVsdGFMYW1iZGEpIHtcbiAgdmFyIHJvdGF0aW9uID0gZm9yd2FyZFJvdGF0aW9uTGFtYmRhKGRlbHRhTGFtYmRhKTtcbiAgcm90YXRpb24uaW52ZXJ0ID0gZm9yd2FyZFJvdGF0aW9uTGFtYmRhKC1kZWx0YUxhbWJkYSk7XG4gIHJldHVybiByb3RhdGlvbjtcbn1cblxuZnVuY3Rpb24gcm90YXRpb25QaGlHYW1tYShkZWx0YVBoaSwgZGVsdGFHYW1tYSkge1xuICB2YXIgY29zRGVsdGFQaGkgPSBjb3MkMShkZWx0YVBoaSksXG4gICAgICBzaW5EZWx0YVBoaSA9IHNpbiQxKGRlbHRhUGhpKSxcbiAgICAgIGNvc0RlbHRhR2FtbWEgPSBjb3MkMShkZWx0YUdhbW1hKSxcbiAgICAgIHNpbkRlbHRhR2FtbWEgPSBzaW4kMShkZWx0YUdhbW1hKTtcblxuICBmdW5jdGlvbiByb3RhdGlvbihsYW1iZGEsIHBoaSkge1xuICAgIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpLFxuICAgICAgICB4ID0gY29zJDEobGFtYmRhKSAqIGNvc1BoaSxcbiAgICAgICAgeSA9IHNpbiQxKGxhbWJkYSkgKiBjb3NQaGksXG4gICAgICAgIHogPSBzaW4kMShwaGkpLFxuICAgICAgICBrID0geiAqIGNvc0RlbHRhUGhpICsgeCAqIHNpbkRlbHRhUGhpO1xuICAgIHJldHVybiBbXG4gICAgICBhdGFuMih5ICogY29zRGVsdGFHYW1tYSAtIGsgKiBzaW5EZWx0YUdhbW1hLCB4ICogY29zRGVsdGFQaGkgLSB6ICogc2luRGVsdGFQaGkpLFxuICAgICAgYXNpbiQxKGsgKiBjb3NEZWx0YUdhbW1hICsgeSAqIHNpbkRlbHRhR2FtbWEpXG4gICAgXTtcbiAgfVxuXG4gIHJvdGF0aW9uLmludmVydCA9IGZ1bmN0aW9uKGxhbWJkYSwgcGhpKSB7XG4gICAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSksXG4gICAgICAgIHggPSBjb3MkMShsYW1iZGEpICogY29zUGhpLFxuICAgICAgICB5ID0gc2luJDEobGFtYmRhKSAqIGNvc1BoaSxcbiAgICAgICAgeiA9IHNpbiQxKHBoaSksXG4gICAgICAgIGsgPSB6ICogY29zRGVsdGFHYW1tYSAtIHkgKiBzaW5EZWx0YUdhbW1hO1xuICAgIHJldHVybiBbXG4gICAgICBhdGFuMih5ICogY29zRGVsdGFHYW1tYSArIHogKiBzaW5EZWx0YUdhbW1hLCB4ICogY29zRGVsdGFQaGkgKyBrICogc2luRGVsdGFQaGkpLFxuICAgICAgYXNpbiQxKGsgKiBjb3NEZWx0YVBoaSAtIHggKiBzaW5EZWx0YVBoaSlcbiAgICBdO1xuICB9O1xuXG4gIHJldHVybiByb3RhdGlvbjtcbn1cblxudmFyIHJvdGF0aW9uID0gZnVuY3Rpb24ocm90YXRlKSB7XG4gIHJvdGF0ZSA9IHJvdGF0ZVJhZGlhbnMocm90YXRlWzBdICogcmFkaWFucywgcm90YXRlWzFdICogcmFkaWFucywgcm90YXRlLmxlbmd0aCA+IDIgPyByb3RhdGVbMl0gKiByYWRpYW5zIDogMCk7XG5cbiAgZnVuY3Rpb24gZm9yd2FyZChjb29yZGluYXRlcykge1xuICAgIGNvb3JkaW5hdGVzID0gcm90YXRlKGNvb3JkaW5hdGVzWzBdICogcmFkaWFucywgY29vcmRpbmF0ZXNbMV0gKiByYWRpYW5zKTtcbiAgICByZXR1cm4gY29vcmRpbmF0ZXNbMF0gKj0gZGVncmVlcyQxLCBjb29yZGluYXRlc1sxXSAqPSBkZWdyZWVzJDEsIGNvb3JkaW5hdGVzO1xuICB9XG5cbiAgZm9yd2FyZC5pbnZlcnQgPSBmdW5jdGlvbihjb29yZGluYXRlcykge1xuICAgIGNvb3JkaW5hdGVzID0gcm90YXRlLmludmVydChjb29yZGluYXRlc1swXSAqIHJhZGlhbnMsIGNvb3JkaW5hdGVzWzFdICogcmFkaWFucyk7XG4gICAgcmV0dXJuIGNvb3JkaW5hdGVzWzBdICo9IGRlZ3JlZXMkMSwgY29vcmRpbmF0ZXNbMV0gKj0gZGVncmVlcyQxLCBjb29yZGluYXRlcztcbiAgfTtcblxuICByZXR1cm4gZm9yd2FyZDtcbn07XG5cbi8vIEdlbmVyYXRlcyBhIGNpcmNsZSBjZW50ZXJlZCBhdCBbMMKwLCAwwrBdLCB3aXRoIGEgZ2l2ZW4gcmFkaXVzIGFuZCBwcmVjaXNpb24uXG5mdW5jdGlvbiBjaXJjbGVTdHJlYW0oc3RyZWFtLCByYWRpdXMsIGRlbHRhLCBkaXJlY3Rpb24sIHQwLCB0MSkge1xuICBpZiAoIWRlbHRhKSByZXR1cm47XG4gIHZhciBjb3NSYWRpdXMgPSBjb3MkMShyYWRpdXMpLFxuICAgICAgc2luUmFkaXVzID0gc2luJDEocmFkaXVzKSxcbiAgICAgIHN0ZXAgPSBkaXJlY3Rpb24gKiBkZWx0YTtcbiAgaWYgKHQwID09IG51bGwpIHtcbiAgICB0MCA9IHJhZGl1cyArIGRpcmVjdGlvbiAqIHRhdSQ0O1xuICAgIHQxID0gcmFkaXVzIC0gc3RlcCAvIDI7XG4gIH0gZWxzZSB7XG4gICAgdDAgPSBjaXJjbGVSYWRpdXMoY29zUmFkaXVzLCB0MCk7XG4gICAgdDEgPSBjaXJjbGVSYWRpdXMoY29zUmFkaXVzLCB0MSk7XG4gICAgaWYgKGRpcmVjdGlvbiA+IDAgPyB0MCA8IHQxIDogdDAgPiB0MSkgdDAgKz0gZGlyZWN0aW9uICogdGF1JDQ7XG4gIH1cbiAgZm9yICh2YXIgcG9pbnQsIHQgPSB0MDsgZGlyZWN0aW9uID4gMCA/IHQgPiB0MSA6IHQgPCB0MTsgdCAtPSBzdGVwKSB7XG4gICAgcG9pbnQgPSBzcGhlcmljYWwoW2Nvc1JhZGl1cywgLXNpblJhZGl1cyAqIGNvcyQxKHQpLCAtc2luUmFkaXVzICogc2luJDEodCldKTtcbiAgICBzdHJlYW0ucG9pbnQocG9pbnRbMF0sIHBvaW50WzFdKTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIHRoZSBzaWduZWQgYW5nbGUgb2YgYSBjYXJ0ZXNpYW4gcG9pbnQgcmVsYXRpdmUgdG8gW2Nvc1JhZGl1cywgMCwgMF0uXG5mdW5jdGlvbiBjaXJjbGVSYWRpdXMoY29zUmFkaXVzLCBwb2ludCkge1xuICBwb2ludCA9IGNhcnRlc2lhbihwb2ludCksIHBvaW50WzBdIC09IGNvc1JhZGl1cztcbiAgY2FydGVzaWFuTm9ybWFsaXplSW5QbGFjZShwb2ludCk7XG4gIHZhciByYWRpdXMgPSBhY29zKC1wb2ludFsxXSk7XG4gIHJldHVybiAoKC1wb2ludFsyXSA8IDAgPyAtcmFkaXVzIDogcmFkaXVzKSArIHRhdSQ0IC0gZXBzaWxvbiQ0KSAlIHRhdSQ0O1xufVxuXG52YXIgY2lyY2xlJDEgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGNlbnRlciA9IGNvbnN0YW50JDEzKFswLCAwXSksXG4gICAgICByYWRpdXMgPSBjb25zdGFudCQxMyg5MCksXG4gICAgICBwcmVjaXNpb24gPSBjb25zdGFudCQxMyg2KSxcbiAgICAgIHJpbmcsXG4gICAgICByb3RhdGUsXG4gICAgICBzdHJlYW0gPSB7cG9pbnQ6IHBvaW50fTtcblxuICBmdW5jdGlvbiBwb2ludCh4LCB5KSB7XG4gICAgcmluZy5wdXNoKHggPSByb3RhdGUoeCwgeSkpO1xuICAgIHhbMF0gKj0gZGVncmVlcyQxLCB4WzFdICo9IGRlZ3JlZXMkMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNpcmNsZSgpIHtcbiAgICB2YXIgYyA9IGNlbnRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICByID0gcmFkaXVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgKiByYWRpYW5zLFxuICAgICAgICBwID0gcHJlY2lzaW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgKiByYWRpYW5zO1xuICAgIHJpbmcgPSBbXTtcbiAgICByb3RhdGUgPSByb3RhdGVSYWRpYW5zKC1jWzBdICogcmFkaWFucywgLWNbMV0gKiByYWRpYW5zLCAwKS5pbnZlcnQ7XG4gICAgY2lyY2xlU3RyZWFtKHN0cmVhbSwgciwgcCwgMSk7XG4gICAgYyA9IHt0eXBlOiBcIlBvbHlnb25cIiwgY29vcmRpbmF0ZXM6IFtyaW5nXX07XG4gICAgcmluZyA9IHJvdGF0ZSA9IG51bGw7XG4gICAgcmV0dXJuIGM7XG4gIH1cblxuICBjaXJjbGUuY2VudGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNlbnRlciA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTMoWytfWzBdLCArX1sxXV0pLCBjaXJjbGUpIDogY2VudGVyO1xuICB9O1xuXG4gIGNpcmNsZS5yYWRpdXMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFkaXVzID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMygrXyksIGNpcmNsZSkgOiByYWRpdXM7XG4gIH07XG5cbiAgY2lyY2xlLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcmVjaXNpb24gPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEzKCtfKSwgY2lyY2xlKSA6IHByZWNpc2lvbjtcbiAgfTtcblxuICByZXR1cm4gY2lyY2xlO1xufTtcblxudmFyIGNsaXBCdWZmZXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGxpbmVzID0gW10sXG4gICAgICBsaW5lO1xuICByZXR1cm4ge1xuICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgICBsaW5lLnB1c2goW3gsIHldKTtcbiAgICB9LFxuICAgIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICBsaW5lcy5wdXNoKGxpbmUgPSBbXSk7XG4gICAgfSxcbiAgICBsaW5lRW5kOiBub29wJDIsXG4gICAgcmVqb2luOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChsaW5lcy5sZW5ndGggPiAxKSBsaW5lcy5wdXNoKGxpbmVzLnBvcCgpLmNvbmNhdChsaW5lcy5zaGlmdCgpKSk7XG4gICAgfSxcbiAgICByZXN1bHQ6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdCA9IGxpbmVzO1xuICAgICAgbGluZXMgPSBbXTtcbiAgICAgIGxpbmUgPSBudWxsO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH07XG59O1xuXG52YXIgY2xpcExpbmUgPSBmdW5jdGlvbihhLCBiLCB4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYnggPSBiWzBdLFxuICAgICAgYnkgPSBiWzFdLFxuICAgICAgdDAgPSAwLFxuICAgICAgdDEgPSAxLFxuICAgICAgZHggPSBieCAtIGF4LFxuICAgICAgZHkgPSBieSAtIGF5LFxuICAgICAgcjtcblxuICByID0geDAgLSBheDtcbiAgaWYgKCFkeCAmJiByID4gMCkgcmV0dXJuO1xuICByIC89IGR4O1xuICBpZiAoZHggPCAwKSB7XG4gICAgaWYgKHIgPCB0MCkgcmV0dXJuO1xuICAgIGlmIChyIDwgdDEpIHQxID0gcjtcbiAgfSBlbHNlIGlmIChkeCA+IDApIHtcbiAgICBpZiAociA+IHQxKSByZXR1cm47XG4gICAgaWYgKHIgPiB0MCkgdDAgPSByO1xuICB9XG5cbiAgciA9IHgxIC0gYXg7XG4gIGlmICghZHggJiYgciA8IDApIHJldHVybjtcbiAgciAvPSBkeDtcbiAgaWYgKGR4IDwgMCkge1xuICAgIGlmIChyID4gdDEpIHJldHVybjtcbiAgICBpZiAociA+IHQwKSB0MCA9IHI7XG4gIH0gZWxzZSBpZiAoZHggPiAwKSB7XG4gICAgaWYgKHIgPCB0MCkgcmV0dXJuO1xuICAgIGlmIChyIDwgdDEpIHQxID0gcjtcbiAgfVxuXG4gIHIgPSB5MCAtIGF5O1xuICBpZiAoIWR5ICYmIHIgPiAwKSByZXR1cm47XG4gIHIgLz0gZHk7XG4gIGlmIChkeSA8IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9IGVsc2UgaWYgKGR5ID4gMCkge1xuICAgIGlmIChyID4gdDEpIHJldHVybjtcbiAgICBpZiAociA+IHQwKSB0MCA9IHI7XG4gIH1cblxuICByID0geTEgLSBheTtcbiAgaWYgKCFkeSAmJiByIDwgMCkgcmV0dXJuO1xuICByIC89IGR5O1xuICBpZiAoZHkgPCAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfSBlbHNlIGlmIChkeSA+IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9XG5cbiAgaWYgKHQwID4gMCkgYVswXSA9IGF4ICsgdDAgKiBkeCwgYVsxXSA9IGF5ICsgdDAgKiBkeTtcbiAgaWYgKHQxIDwgMSkgYlswXSA9IGF4ICsgdDEgKiBkeCwgYlsxXSA9IGF5ICsgdDEgKiBkeTtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG52YXIgcG9pbnRFcXVhbCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGFicyhhWzBdIC0gYlswXSkgPCBlcHNpbG9uJDQgJiYgYWJzKGFbMV0gLSBiWzFdKSA8IGVwc2lsb24kNDtcbn07XG5cbmZ1bmN0aW9uIEludGVyc2VjdGlvbihwb2ludCwgcG9pbnRzLCBvdGhlciwgZW50cnkpIHtcbiAgdGhpcy54ID0gcG9pbnQ7XG4gIHRoaXMueiA9IHBvaW50cztcbiAgdGhpcy5vID0gb3RoZXI7IC8vIGFub3RoZXIgaW50ZXJzZWN0aW9uXG4gIHRoaXMuZSA9IGVudHJ5OyAvLyBpcyBhbiBlbnRyeT9cbiAgdGhpcy52ID0gZmFsc2U7IC8vIHZpc2l0ZWRcbiAgdGhpcy5uID0gdGhpcy5wID0gbnVsbDsgLy8gbmV4dCAmIHByZXZpb3VzXG59XG5cbi8vIEEgZ2VuZXJhbGl6ZWQgcG9seWdvbiBjbGlwcGluZyBhbGdvcml0aG06IGdpdmVuIGEgcG9seWdvbiB0aGF0IGhhcyBiZWVuIGN1dFxuLy8gaW50byBpdHMgdmlzaWJsZSBsaW5lIHNlZ21lbnRzLCBhbmQgcmVqb2lucyB0aGUgc2VnbWVudHMgYnkgaW50ZXJwb2xhdGluZ1xuLy8gYWxvbmcgdGhlIGNsaXAgZWRnZS5cbnZhciBjbGlwUG9seWdvbiA9IGZ1bmN0aW9uKHNlZ21lbnRzLCBjb21wYXJlSW50ZXJzZWN0aW9uLCBzdGFydEluc2lkZSwgaW50ZXJwb2xhdGUsIHN0cmVhbSkge1xuICB2YXIgc3ViamVjdCA9IFtdLFxuICAgICAgY2xpcCA9IFtdLFxuICAgICAgaSxcbiAgICAgIG47XG5cbiAgc2VnbWVudHMuZm9yRWFjaChmdW5jdGlvbihzZWdtZW50KSB7XG4gICAgaWYgKChuID0gc2VnbWVudC5sZW5ndGggLSAxKSA8PSAwKSByZXR1cm47XG4gICAgdmFyIG4sIHAwID0gc2VnbWVudFswXSwgcDEgPSBzZWdtZW50W25dLCB4O1xuXG4gICAgLy8gSWYgdGhlIGZpcnN0IGFuZCBsYXN0IHBvaW50cyBvZiBhIHNlZ21lbnQgYXJlIGNvaW5jaWRlbnQsIHRoZW4gdHJlYXQgYXMgYVxuICAgIC8vIGNsb3NlZCByaW5nLiBUT0RPIGlmIGFsbCByaW5ncyBhcmUgY2xvc2VkLCB0aGVuIHRoZSB3aW5kaW5nIG9yZGVyIG9mIHRoZVxuICAgIC8vIGV4dGVyaW9yIHJpbmcgc2hvdWxkIGJlIGNoZWNrZWQuXG4gICAgaWYgKHBvaW50RXF1YWwocDAsIHAxKSkge1xuICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgc3RyZWFtLnBvaW50KChwMCA9IHNlZ21lbnRbaV0pWzBdLCBwMFsxXSk7XG4gICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN1YmplY3QucHVzaCh4ID0gbmV3IEludGVyc2VjdGlvbihwMCwgc2VnbWVudCwgbnVsbCwgdHJ1ZSkpO1xuICAgIGNsaXAucHVzaCh4Lm8gPSBuZXcgSW50ZXJzZWN0aW9uKHAwLCBudWxsLCB4LCBmYWxzZSkpO1xuICAgIHN1YmplY3QucHVzaCh4ID0gbmV3IEludGVyc2VjdGlvbihwMSwgc2VnbWVudCwgbnVsbCwgZmFsc2UpKTtcbiAgICBjbGlwLnB1c2goeC5vID0gbmV3IEludGVyc2VjdGlvbihwMSwgbnVsbCwgeCwgdHJ1ZSkpO1xuICB9KTtcblxuICBpZiAoIXN1YmplY3QubGVuZ3RoKSByZXR1cm47XG5cbiAgY2xpcC5zb3J0KGNvbXBhcmVJbnRlcnNlY3Rpb24pO1xuICBsaW5rJDEoc3ViamVjdCk7XG4gIGxpbmskMShjbGlwKTtcblxuICBmb3IgKGkgPSAwLCBuID0gY2xpcC5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICBjbGlwW2ldLmUgPSBzdGFydEluc2lkZSA9ICFzdGFydEluc2lkZTtcbiAgfVxuXG4gIHZhciBzdGFydCA9IHN1YmplY3RbMF0sXG4gICAgICBwb2ludHMsXG4gICAgICBwb2ludDtcblxuICB3aGlsZSAoMSkge1xuICAgIC8vIEZpbmQgZmlyc3QgdW52aXNpdGVkIGludGVyc2VjdGlvbi5cbiAgICB2YXIgY3VycmVudCA9IHN0YXJ0LFxuICAgICAgICBpc1N1YmplY3QgPSB0cnVlO1xuICAgIHdoaWxlIChjdXJyZW50LnYpIGlmICgoY3VycmVudCA9IGN1cnJlbnQubikgPT09IHN0YXJ0KSByZXR1cm47XG4gICAgcG9pbnRzID0gY3VycmVudC56O1xuICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICBkbyB7XG4gICAgICBjdXJyZW50LnYgPSBjdXJyZW50Lm8udiA9IHRydWU7XG4gICAgICBpZiAoY3VycmVudC5lKSB7XG4gICAgICAgIGlmIChpc1N1YmplY3QpIHtcbiAgICAgICAgICBmb3IgKGkgPSAwLCBuID0gcG9pbnRzLmxlbmd0aDsgaSA8IG47ICsraSkgc3RyZWFtLnBvaW50KChwb2ludCA9IHBvaW50c1tpXSlbMF0sIHBvaW50WzFdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbnRlcnBvbGF0ZShjdXJyZW50LngsIGN1cnJlbnQubi54LCAxLCBzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNTdWJqZWN0KSB7XG4gICAgICAgICAgcG9pbnRzID0gY3VycmVudC5wLno7XG4gICAgICAgICAgZm9yIChpID0gcG9pbnRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSBzdHJlYW0ucG9pbnQoKHBvaW50ID0gcG9pbnRzW2ldKVswXSwgcG9pbnRbMV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGludGVycG9sYXRlKGN1cnJlbnQueCwgY3VycmVudC5wLngsIC0xLCBzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnA7XG4gICAgICB9XG4gICAgICBjdXJyZW50ID0gY3VycmVudC5vO1xuICAgICAgcG9pbnRzID0gY3VycmVudC56O1xuICAgICAgaXNTdWJqZWN0ID0gIWlzU3ViamVjdDtcbiAgICB9IHdoaWxlICghY3VycmVudC52KTtcbiAgICBzdHJlYW0ubGluZUVuZCgpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBsaW5rJDEoYXJyYXkpIHtcbiAgaWYgKCEobiA9IGFycmF5Lmxlbmd0aCkpIHJldHVybjtcbiAgdmFyIG4sXG4gICAgICBpID0gMCxcbiAgICAgIGEgPSBhcnJheVswXSxcbiAgICAgIGI7XG4gIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgYS5uID0gYiA9IGFycmF5W2ldO1xuICAgIGIucCA9IGE7XG4gICAgYSA9IGI7XG4gIH1cbiAgYS5uID0gYiA9IGFycmF5WzBdO1xuICBiLnAgPSBhO1xufVxuXG52YXIgY2xpcE1heCA9IDFlOTtcbnZhciBjbGlwTWluID0gLWNsaXBNYXg7XG5cbi8vIFRPRE8gVXNlIGQzLXBvbHlnb27igJlzIHBvbHlnb25Db250YWlucyBoZXJlIGZvciB0aGUgcmluZyBjaGVjaz9cbi8vIFRPRE8gRWxpbWluYXRlIGR1cGxpY2F0ZSBidWZmZXJpbmcgaW4gY2xpcEJ1ZmZlciBhbmQgcG9seWdvbi5wdXNoP1xuXG5mdW5jdGlvbiBjbGlwRXh0ZW50KHgwLCB5MCwgeDEsIHkxKSB7XG5cbiAgZnVuY3Rpb24gdmlzaWJsZSh4LCB5KSB7XG4gICAgcmV0dXJuIHgwIDw9IHggJiYgeCA8PSB4MSAmJiB5MCA8PSB5ICYmIHkgPD0geTE7XG4gIH1cblxuICBmdW5jdGlvbiBpbnRlcnBvbGF0ZShmcm9tLCB0bywgZGlyZWN0aW9uLCBzdHJlYW0pIHtcbiAgICB2YXIgYSA9IDAsIGExID0gMDtcbiAgICBpZiAoZnJvbSA9PSBudWxsXG4gICAgICAgIHx8IChhID0gY29ybmVyKGZyb20sIGRpcmVjdGlvbikpICE9PSAoYTEgPSBjb3JuZXIodG8sIGRpcmVjdGlvbikpXG4gICAgICAgIHx8IGNvbXBhcmVQb2ludChmcm9tLCB0bykgPCAwIF4gZGlyZWN0aW9uID4gMCkge1xuICAgICAgZG8gc3RyZWFtLnBvaW50KGEgPT09IDAgfHwgYSA9PT0gMyA/IHgwIDogeDEsIGEgPiAxID8geTEgOiB5MCk7XG4gICAgICB3aGlsZSAoKGEgPSAoYSArIGRpcmVjdGlvbiArIDQpICUgNCkgIT09IGExKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyZWFtLnBvaW50KHRvWzBdLCB0b1sxXSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY29ybmVyKHAsIGRpcmVjdGlvbikge1xuICAgIHJldHVybiBhYnMocFswXSAtIHgwKSA8IGVwc2lsb24kNCA/IGRpcmVjdGlvbiA+IDAgPyAwIDogM1xuICAgICAgICA6IGFicyhwWzBdIC0geDEpIDwgZXBzaWxvbiQ0ID8gZGlyZWN0aW9uID4gMCA/IDIgOiAxXG4gICAgICAgIDogYWJzKHBbMV0gLSB5MCkgPCBlcHNpbG9uJDQgPyBkaXJlY3Rpb24gPiAwID8gMSA6IDBcbiAgICAgICAgOiBkaXJlY3Rpb24gPiAwID8gMyA6IDI7IC8vIGFicyhwWzFdIC0geTEpIDwgZXBzaWxvblxuICB9XG5cbiAgZnVuY3Rpb24gY29tcGFyZUludGVyc2VjdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGNvbXBhcmVQb2ludChhLngsIGIueCk7XG4gIH1cblxuICBmdW5jdGlvbiBjb21wYXJlUG9pbnQoYSwgYikge1xuICAgIHZhciBjYSA9IGNvcm5lcihhLCAxKSxcbiAgICAgICAgY2IgPSBjb3JuZXIoYiwgMSk7XG4gICAgcmV0dXJuIGNhICE9PSBjYiA/IGNhIC0gY2JcbiAgICAgICAgOiBjYSA9PT0gMCA/IGJbMV0gLSBhWzFdXG4gICAgICAgIDogY2EgPT09IDEgPyBhWzBdIC0gYlswXVxuICAgICAgICA6IGNhID09PSAyID8gYVsxXSAtIGJbMV1cbiAgICAgICAgOiBiWzBdIC0gYVswXTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICB2YXIgYWN0aXZlU3RyZWFtID0gc3RyZWFtLFxuICAgICAgICBidWZmZXJTdHJlYW0gPSBjbGlwQnVmZmVyKCksXG4gICAgICAgIHNlZ21lbnRzLFxuICAgICAgICBwb2x5Z29uLFxuICAgICAgICByaW5nLFxuICAgICAgICB4X18sIHlfXywgdl9fLCAvLyBmaXJzdCBwb2ludFxuICAgICAgICB4XywgeV8sIHZfLCAvLyBwcmV2aW91cyBwb2ludFxuICAgICAgICBmaXJzdCxcbiAgICAgICAgY2xlYW47XG5cbiAgICB2YXIgY2xpcFN0cmVhbSA9IHtcbiAgICAgIHBvaW50OiBwb2ludCxcbiAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgbGluZUVuZDogbGluZUVuZCxcbiAgICAgIHBvbHlnb25TdGFydDogcG9seWdvblN0YXJ0LFxuICAgICAgcG9seWdvbkVuZDogcG9seWdvbkVuZFxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwb2ludCh4LCB5KSB7XG4gICAgICBpZiAodmlzaWJsZSh4LCB5KSkgYWN0aXZlU3RyZWFtLnBvaW50KHgsIHkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBvbHlnb25JbnNpZGUoKSB7XG4gICAgICB2YXIgd2luZGluZyA9IDA7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBuID0gcG9seWdvbi5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgZm9yICh2YXIgcmluZyA9IHBvbHlnb25baV0sIGogPSAxLCBtID0gcmluZy5sZW5ndGgsIHBvaW50ID0gcmluZ1swXSwgYTAsIGExLCBiMCA9IHBvaW50WzBdLCBiMSA9IHBvaW50WzFdOyBqIDwgbTsgKytqKSB7XG4gICAgICAgICAgYTAgPSBiMCwgYTEgPSBiMSwgcG9pbnQgPSByaW5nW2pdLCBiMCA9IHBvaW50WzBdLCBiMSA9IHBvaW50WzFdO1xuICAgICAgICAgIGlmIChhMSA8PSB5MSkgeyBpZiAoYjEgPiB5MSAmJiAoYjAgLSBhMCkgKiAoeTEgLSBhMSkgPiAoYjEgLSBhMSkgKiAoeDAgLSBhMCkpICsrd2luZGluZzsgfVxuICAgICAgICAgIGVsc2UgeyBpZiAoYjEgPD0geTEgJiYgKGIwIC0gYTApICogKHkxIC0gYTEpIDwgKGIxIC0gYTEpICogKHgwIC0gYTApKSAtLXdpbmRpbmc7IH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gd2luZGluZztcbiAgICB9XG5cbiAgICAvLyBCdWZmZXIgZ2VvbWV0cnkgd2l0aGluIGEgcG9seWdvbiBhbmQgdGhlbiBjbGlwIGl0IGVuIG1hc3NlLlxuICAgIGZ1bmN0aW9uIHBvbHlnb25TdGFydCgpIHtcbiAgICAgIGFjdGl2ZVN0cmVhbSA9IGJ1ZmZlclN0cmVhbSwgc2VnbWVudHMgPSBbXSwgcG9seWdvbiA9IFtdLCBjbGVhbiA9IHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9seWdvbkVuZCgpIHtcbiAgICAgIHZhciBzdGFydEluc2lkZSA9IHBvbHlnb25JbnNpZGUoKSxcbiAgICAgICAgICBjbGVhbkluc2lkZSA9IGNsZWFuICYmIHN0YXJ0SW5zaWRlLFxuICAgICAgICAgIHZpc2libGUgPSAoc2VnbWVudHMgPSBtZXJnZShzZWdtZW50cykpLmxlbmd0aDtcbiAgICAgIGlmIChjbGVhbkluc2lkZSB8fCB2aXNpYmxlKSB7XG4gICAgICAgIHN0cmVhbS5wb2x5Z29uU3RhcnQoKTtcbiAgICAgICAgaWYgKGNsZWFuSW5zaWRlKSB7XG4gICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgIGludGVycG9sYXRlKG51bGwsIG51bGwsIDEsIHN0cmVhbSk7XG4gICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmlzaWJsZSkge1xuICAgICAgICAgIGNsaXBQb2x5Z29uKHNlZ21lbnRzLCBjb21wYXJlSW50ZXJzZWN0aW9uLCBzdGFydEluc2lkZSwgaW50ZXJwb2xhdGUsIHN0cmVhbSk7XG4gICAgICAgIH1cbiAgICAgICAgc3RyZWFtLnBvbHlnb25FbmQoKTtcbiAgICAgIH1cbiAgICAgIGFjdGl2ZVN0cmVhbSA9IHN0cmVhbSwgc2VnbWVudHMgPSBwb2x5Z29uID0gcmluZyA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGluZVN0YXJ0KCkge1xuICAgICAgY2xpcFN0cmVhbS5wb2ludCA9IGxpbmVQb2ludDtcbiAgICAgIGlmIChwb2x5Z29uKSBwb2x5Z29uLnB1c2gocmluZyA9IFtdKTtcbiAgICAgIGZpcnN0ID0gdHJ1ZTtcbiAgICAgIHZfID0gZmFsc2U7XG4gICAgICB4XyA9IHlfID0gTmFOO1xuICAgIH1cblxuICAgIC8vIFRPRE8gcmF0aGVyIHRoYW4gc3BlY2lhbC1jYXNlIHBvbHlnb25zLCBzaW1wbHkgaGFuZGxlIHRoZW0gc2VwYXJhdGVseS5cbiAgICAvLyBJZGVhbGx5LCBjb2luY2lkZW50IGludGVyc2VjdGlvbiBwb2ludHMgc2hvdWxkIGJlIGppdHRlcmVkIHRvIGF2b2lkXG4gICAgLy8gY2xpcHBpbmcgaXNzdWVzLlxuICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7XG4gICAgICBpZiAoc2VnbWVudHMpIHtcbiAgICAgICAgbGluZVBvaW50KHhfXywgeV9fKTtcbiAgICAgICAgaWYgKHZfXyAmJiB2XykgYnVmZmVyU3RyZWFtLnJlam9pbigpO1xuICAgICAgICBzZWdtZW50cy5wdXNoKGJ1ZmZlclN0cmVhbS5yZXN1bHQoKSk7XG4gICAgICB9XG4gICAgICBjbGlwU3RyZWFtLnBvaW50ID0gcG9pbnQ7XG4gICAgICBpZiAodl8pIGFjdGl2ZVN0cmVhbS5saW5lRW5kKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGluZVBvaW50KHgsIHkpIHtcbiAgICAgIHZhciB2ID0gdmlzaWJsZSh4LCB5KTtcbiAgICAgIGlmIChwb2x5Z29uKSByaW5nLnB1c2goW3gsIHldKTtcbiAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICB4X18gPSB4LCB5X18gPSB5LCB2X18gPSB2O1xuICAgICAgICBmaXJzdCA9IGZhbHNlO1xuICAgICAgICBpZiAodikge1xuICAgICAgICAgIGFjdGl2ZVN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICBhY3RpdmVTdHJlYW0ucG9pbnQoeCwgeSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh2ICYmIHZfKSBhY3RpdmVTdHJlYW0ucG9pbnQoeCwgeSk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBhID0gW3hfID0gTWF0aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeF8pKSwgeV8gPSBNYXRoLm1heChjbGlwTWluLCBNYXRoLm1pbihjbGlwTWF4LCB5XykpXSxcbiAgICAgICAgICAgICAgYiA9IFt4ID0gTWF0aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeCkpLCB5ID0gTWF0aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeSkpXTtcbiAgICAgICAgICBpZiAoY2xpcExpbmUoYSwgYiwgeDAsIHkwLCB4MSwgeTEpKSB7XG4gICAgICAgICAgICBpZiAoIXZfKSB7XG4gICAgICAgICAgICAgIGFjdGl2ZVN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgICAgYWN0aXZlU3RyZWFtLnBvaW50KGFbMF0sIGFbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWN0aXZlU3RyZWFtLnBvaW50KGJbMF0sIGJbMV0pO1xuICAgICAgICAgICAgaWYgKCF2KSBhY3RpdmVTdHJlYW0ubGluZUVuZCgpO1xuICAgICAgICAgICAgY2xlYW4gPSBmYWxzZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHYpIHtcbiAgICAgICAgICAgIGFjdGl2ZVN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgIGFjdGl2ZVN0cmVhbS5wb2ludCh4LCB5KTtcbiAgICAgICAgICAgIGNsZWFuID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB4XyA9IHgsIHlfID0geSwgdl8gPSB2O1xuICAgIH1cblxuICAgIHJldHVybiBjbGlwU3RyZWFtO1xuICB9O1xufVxuXG52YXIgZXh0ZW50JDEgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHgwID0gMCxcbiAgICAgIHkwID0gMCxcbiAgICAgIHgxID0gOTYwLFxuICAgICAgeTEgPSA1MDAsXG4gICAgICBjYWNoZSxcbiAgICAgIGNhY2hlU3RyZWFtLFxuICAgICAgY2xpcDtcblxuICByZXR1cm4gY2xpcCA9IHtcbiAgICBzdHJlYW06IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgcmV0dXJuIGNhY2hlICYmIGNhY2hlU3RyZWFtID09PSBzdHJlYW0gPyBjYWNoZSA6IGNhY2hlID0gY2xpcEV4dGVudCh4MCwgeTAsIHgxLCB5MSkoY2FjaGVTdHJlYW0gPSBzdHJlYW0pO1xuICAgIH0sXG4gICAgZXh0ZW50OiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MCA9ICtfWzBdWzBdLCB5MCA9ICtfWzBdWzFdLCB4MSA9ICtfWzFdWzBdLCB5MSA9ICtfWzFdWzFdLCBjYWNoZSA9IGNhY2hlU3RyZWFtID0gbnVsbCwgY2xpcCkgOiBbW3gwLCB5MF0sIFt4MSwgeTFdXTtcbiAgICB9XG4gIH07XG59O1xuXG52YXIgbGVuZ3RoU3VtID0gYWRkZXIoKTtcbnZhciBsYW1iZGEwJDI7XG52YXIgc2luUGhpMCQxO1xudmFyIGNvc1BoaTAkMTtcblxudmFyIGxlbmd0aFN0cmVhbSA9IHtcbiAgc3BoZXJlOiBub29wJDIsXG4gIHBvaW50OiBub29wJDIsXG4gIGxpbmVTdGFydDogbGVuZ3RoTGluZVN0YXJ0LFxuICBsaW5lRW5kOiBub29wJDIsXG4gIHBvbHlnb25TdGFydDogbm9vcCQyLFxuICBwb2x5Z29uRW5kOiBub29wJDJcbn07XG5cbmZ1bmN0aW9uIGxlbmd0aExpbmVTdGFydCgpIHtcbiAgbGVuZ3RoU3RyZWFtLnBvaW50ID0gbGVuZ3RoUG9pbnRGaXJzdDtcbiAgbGVuZ3RoU3RyZWFtLmxpbmVFbmQgPSBsZW5ndGhMaW5lRW5kO1xufVxuXG5mdW5jdGlvbiBsZW5ndGhMaW5lRW5kKCkge1xuICBsZW5ndGhTdHJlYW0ucG9pbnQgPSBsZW5ndGhTdHJlYW0ubGluZUVuZCA9IG5vb3AkMjtcbn1cblxuZnVuY3Rpb24gbGVuZ3RoUG9pbnRGaXJzdChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIGxhbWJkYTAkMiA9IGxhbWJkYSwgc2luUGhpMCQxID0gc2luJDEocGhpKSwgY29zUGhpMCQxID0gY29zJDEocGhpKTtcbiAgbGVuZ3RoU3RyZWFtLnBvaW50ID0gbGVuZ3RoUG9pbnQ7XG59XG5cbmZ1bmN0aW9uIGxlbmd0aFBvaW50KGxhbWJkYSwgcGhpKSB7XG4gIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFucztcbiAgdmFyIHNpblBoaSA9IHNpbiQxKHBoaSksXG4gICAgICBjb3NQaGkgPSBjb3MkMShwaGkpLFxuICAgICAgZGVsdGEgPSBhYnMobGFtYmRhIC0gbGFtYmRhMCQyKSxcbiAgICAgIGNvc0RlbHRhID0gY29zJDEoZGVsdGEpLFxuICAgICAgc2luRGVsdGEgPSBzaW4kMShkZWx0YSksXG4gICAgICB4ID0gY29zUGhpICogc2luRGVsdGEsXG4gICAgICB5ID0gY29zUGhpMCQxICogc2luUGhpIC0gc2luUGhpMCQxICogY29zUGhpICogY29zRGVsdGEsXG4gICAgICB6ID0gc2luUGhpMCQxICogc2luUGhpICsgY29zUGhpMCQxICogY29zUGhpICogY29zRGVsdGE7XG4gIGxlbmd0aFN1bS5hZGQoYXRhbjIoc3FydCQxKHggKiB4ICsgeSAqIHkpLCB6KSk7XG4gIGxhbWJkYTAkMiA9IGxhbWJkYSwgc2luUGhpMCQxID0gc2luUGhpLCBjb3NQaGkwJDEgPSBjb3NQaGk7XG59XG5cbnZhciBsZW5ndGgkMiA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICBsZW5ndGhTdW0ucmVzZXQoKTtcbiAgZ2VvU3RyZWFtKG9iamVjdCwgbGVuZ3RoU3RyZWFtKTtcbiAgcmV0dXJuICtsZW5ndGhTdW07XG59O1xuXG52YXIgY29vcmRpbmF0ZXMgPSBbbnVsbCwgbnVsbF07XG52YXIgb2JqZWN0JDEgPSB7dHlwZTogXCJMaW5lU3RyaW5nXCIsIGNvb3JkaW5hdGVzOiBjb29yZGluYXRlc307XG5cbnZhciBkaXN0YW5jZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgY29vcmRpbmF0ZXNbMF0gPSBhO1xuICBjb29yZGluYXRlc1sxXSA9IGI7XG4gIHJldHVybiBsZW5ndGgkMihvYmplY3QkMSk7XG59O1xuXG5mdW5jdGlvbiBncmF0aWN1bGVYKHkwLCB5MSwgZHkpIHtcbiAgdmFyIHkgPSByYW5nZSh5MCwgeTEgLSBlcHNpbG9uJDQsIGR5KS5jb25jYXQoeTEpO1xuICByZXR1cm4gZnVuY3Rpb24oeCkgeyByZXR1cm4geS5tYXAoZnVuY3Rpb24oeSkgeyByZXR1cm4gW3gsIHldOyB9KTsgfTtcbn1cblxuZnVuY3Rpb24gZ3JhdGljdWxlWSh4MCwgeDEsIGR4KSB7XG4gIHZhciB4ID0gcmFuZ2UoeDAsIHgxIC0gZXBzaWxvbiQ0LCBkeCkuY29uY2F0KHgxKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKHkpIHsgcmV0dXJuIHgubWFwKGZ1bmN0aW9uKHgpIHsgcmV0dXJuIFt4LCB5XTsgfSk7IH07XG59XG5cbmZ1bmN0aW9uIGdyYXRpY3VsZSgpIHtcbiAgdmFyIHgxLCB4MCwgWDEsIFgwLFxuICAgICAgeTEsIHkwLCBZMSwgWTAsXG4gICAgICBkeCA9IDEwLCBkeSA9IGR4LCBEWCA9IDkwLCBEWSA9IDM2MCxcbiAgICAgIHgsIHksIFgsIFksXG4gICAgICBwcmVjaXNpb24gPSAyLjU7XG5cbiAgZnVuY3Rpb24gZ3JhdGljdWxlKCkge1xuICAgIHJldHVybiB7dHlwZTogXCJNdWx0aUxpbmVTdHJpbmdcIiwgY29vcmRpbmF0ZXM6IGxpbmVzKCl9O1xuICB9XG5cbiAgZnVuY3Rpb24gbGluZXMoKSB7XG4gICAgcmV0dXJuIHJhbmdlKGNlaWwoWDAgLyBEWCkgKiBEWCwgWDEsIERYKS5tYXAoWClcbiAgICAgICAgLmNvbmNhdChyYW5nZShjZWlsKFkwIC8gRFkpICogRFksIFkxLCBEWSkubWFwKFkpKVxuICAgICAgICAuY29uY2F0KHJhbmdlKGNlaWwoeDAgLyBkeCkgKiBkeCwgeDEsIGR4KS5maWx0ZXIoZnVuY3Rpb24oeCkgeyByZXR1cm4gYWJzKHggJSBEWCkgPiBlcHNpbG9uJDQ7IH0pLm1hcCh4KSlcbiAgICAgICAgLmNvbmNhdChyYW5nZShjZWlsKHkwIC8gZHkpICogZHksIHkxLCBkeSkuZmlsdGVyKGZ1bmN0aW9uKHkpIHsgcmV0dXJuIGFicyh5ICUgRFkpID4gZXBzaWxvbiQ0OyB9KS5tYXAoeSkpO1xuICB9XG5cbiAgZ3JhdGljdWxlLmxpbmVzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGxpbmVzKCkubWFwKGZ1bmN0aW9uKGNvb3JkaW5hdGVzKSB7IHJldHVybiB7dHlwZTogXCJMaW5lU3RyaW5nXCIsIGNvb3JkaW5hdGVzOiBjb29yZGluYXRlc307IH0pO1xuICB9O1xuXG4gIGdyYXRpY3VsZS5vdXRsaW5lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFwiUG9seWdvblwiLFxuICAgICAgY29vcmRpbmF0ZXM6IFtcbiAgICAgICAgWChYMCkuY29uY2F0KFxuICAgICAgICBZKFkxKS5zbGljZSgxKSxcbiAgICAgICAgWChYMSkucmV2ZXJzZSgpLnNsaWNlKDEpLFxuICAgICAgICBZKFkwKS5yZXZlcnNlKCkuc2xpY2UoMSkpXG4gICAgICBdXG4gICAgfTtcbiAgfTtcblxuICBncmF0aWN1bGUuZXh0ZW50ID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGdyYXRpY3VsZS5leHRlbnRNaW5vcigpO1xuICAgIHJldHVybiBncmF0aWN1bGUuZXh0ZW50TWFqb3IoXykuZXh0ZW50TWlub3IoXyk7XG4gIH07XG5cbiAgZ3JhdGljdWxlLmV4dGVudE1ham9yID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFtbWDAsIFkwXSwgW1gxLCBZMV1dO1xuICAgIFgwID0gK19bMF1bMF0sIFgxID0gK19bMV1bMF07XG4gICAgWTAgPSArX1swXVsxXSwgWTEgPSArX1sxXVsxXTtcbiAgICBpZiAoWDAgPiBYMSkgXyA9IFgwLCBYMCA9IFgxLCBYMSA9IF87XG4gICAgaWYgKFkwID4gWTEpIF8gPSBZMCwgWTAgPSBZMSwgWTEgPSBfO1xuICAgIHJldHVybiBncmF0aWN1bGUucHJlY2lzaW9uKHByZWNpc2lvbik7XG4gIH07XG5cbiAgZ3JhdGljdWxlLmV4dGVudE1pbm9yID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFtbeDAsIHkwXSwgW3gxLCB5MV1dO1xuICAgIHgwID0gK19bMF1bMF0sIHgxID0gK19bMV1bMF07XG4gICAgeTAgPSArX1swXVsxXSwgeTEgPSArX1sxXVsxXTtcbiAgICBpZiAoeDAgPiB4MSkgXyA9IHgwLCB4MCA9IHgxLCB4MSA9IF87XG4gICAgaWYgKHkwID4geTEpIF8gPSB5MCwgeTAgPSB5MSwgeTEgPSBfO1xuICAgIHJldHVybiBncmF0aWN1bGUucHJlY2lzaW9uKHByZWNpc2lvbik7XG4gIH07XG5cbiAgZ3JhdGljdWxlLnN0ZXAgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZ3JhdGljdWxlLnN0ZXBNaW5vcigpO1xuICAgIHJldHVybiBncmF0aWN1bGUuc3RlcE1ham9yKF8pLnN0ZXBNaW5vcihfKTtcbiAgfTtcblxuICBncmF0aWN1bGUuc3RlcE1ham9yID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFtEWCwgRFldO1xuICAgIERYID0gK19bMF0sIERZID0gK19bMV07XG4gICAgcmV0dXJuIGdyYXRpY3VsZTtcbiAgfTtcblxuICBncmF0aWN1bGUuc3RlcE1pbm9yID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFtkeCwgZHldO1xuICAgIGR4ID0gK19bMF0sIGR5ID0gK19bMV07XG4gICAgcmV0dXJuIGdyYXRpY3VsZTtcbiAgfTtcblxuICBncmF0aWN1bGUucHJlY2lzaW9uID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHByZWNpc2lvbjtcbiAgICBwcmVjaXNpb24gPSArXztcbiAgICB4ID0gZ3JhdGljdWxlWCh5MCwgeTEsIDkwKTtcbiAgICB5ID0gZ3JhdGljdWxlWSh4MCwgeDEsIHByZWNpc2lvbik7XG4gICAgWCA9IGdyYXRpY3VsZVgoWTAsIFkxLCA5MCk7XG4gICAgWSA9IGdyYXRpY3VsZVkoWDAsIFgxLCBwcmVjaXNpb24pO1xuICAgIHJldHVybiBncmF0aWN1bGU7XG4gIH07XG5cbiAgcmV0dXJuIGdyYXRpY3VsZVxuICAgICAgLmV4dGVudE1ham9yKFtbLTE4MCwgLTkwICsgZXBzaWxvbiQ0XSwgWzE4MCwgOTAgLSBlcHNpbG9uJDRdXSlcbiAgICAgIC5leHRlbnRNaW5vcihbWy0xODAsIC04MCAtIGVwc2lsb24kNF0sIFsxODAsIDgwICsgZXBzaWxvbiQ0XV0pO1xufVxuXG5mdW5jdGlvbiBncmF0aWN1bGUxMCgpIHtcbiAgcmV0dXJuIGdyYXRpY3VsZSgpKCk7XG59XG5cbnZhciBpbnRlcnBvbGF0ZSQyID0gZnVuY3Rpb24oYSwgYikge1xuICB2YXIgeDAgPSBhWzBdICogcmFkaWFucyxcbiAgICAgIHkwID0gYVsxXSAqIHJhZGlhbnMsXG4gICAgICB4MSA9IGJbMF0gKiByYWRpYW5zLFxuICAgICAgeTEgPSBiWzFdICogcmFkaWFucyxcbiAgICAgIGN5MCA9IGNvcyQxKHkwKSxcbiAgICAgIHN5MCA9IHNpbiQxKHkwKSxcbiAgICAgIGN5MSA9IGNvcyQxKHkxKSxcbiAgICAgIHN5MSA9IHNpbiQxKHkxKSxcbiAgICAgIGt4MCA9IGN5MCAqIGNvcyQxKHgwKSxcbiAgICAgIGt5MCA9IGN5MCAqIHNpbiQxKHgwKSxcbiAgICAgIGt4MSA9IGN5MSAqIGNvcyQxKHgxKSxcbiAgICAgIGt5MSA9IGN5MSAqIHNpbiQxKHgxKSxcbiAgICAgIGQgPSAyICogYXNpbiQxKHNxcnQkMShoYXZlcnNpbih5MSAtIHkwKSArIGN5MCAqIGN5MSAqIGhhdmVyc2luKHgxIC0geDApKSksXG4gICAgICBrID0gc2luJDEoZCk7XG5cbiAgdmFyIGludGVycG9sYXRlID0gZCA/IGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgQiA9IHNpbiQxKHQgKj0gZCkgLyBrLFxuICAgICAgICBBID0gc2luJDEoZCAtIHQpIC8gayxcbiAgICAgICAgeCA9IEEgKiBreDAgKyBCICoga3gxLFxuICAgICAgICB5ID0gQSAqIGt5MCArIEIgKiBreTEsXG4gICAgICAgIHogPSBBICogc3kwICsgQiAqIHN5MTtcbiAgICByZXR1cm4gW1xuICAgICAgYXRhbjIoeSwgeCkgKiBkZWdyZWVzJDEsXG4gICAgICBhdGFuMih6LCBzcXJ0JDEoeCAqIHggKyB5ICogeSkpICogZGVncmVlcyQxXG4gICAgXTtcbiAgfSA6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBbeDAgKiBkZWdyZWVzJDEsIHkwICogZGVncmVlcyQxXTtcbiAgfTtcblxuICBpbnRlcnBvbGF0ZS5kaXN0YW5jZSA9IGQ7XG5cbiAgcmV0dXJuIGludGVycG9sYXRlO1xufTtcblxudmFyIGlkZW50aXR5JDcgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiB4O1xufTtcblxudmFyIGFyZWFTdW0kMSA9IGFkZGVyKCk7XG52YXIgYXJlYVJpbmdTdW0kMSA9IGFkZGVyKCk7XG52YXIgeDAwO1xudmFyIHkwMDtcbnZhciB4MCQxO1xudmFyIHkwJDE7XG5cbnZhciBhcmVhU3RyZWFtJDEgPSB7XG4gIHBvaW50OiBub29wJDIsXG4gIGxpbmVTdGFydDogbm9vcCQyLFxuICBsaW5lRW5kOiBub29wJDIsXG4gIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgYXJlYVN0cmVhbSQxLmxpbmVTdGFydCA9IGFyZWFSaW5nU3RhcnQkMTtcbiAgICBhcmVhU3RyZWFtJDEubGluZUVuZCA9IGFyZWFSaW5nRW5kJDE7XG4gIH0sXG4gIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGFyZWFTdHJlYW0kMS5saW5lU3RhcnQgPSBhcmVhU3RyZWFtJDEubGluZUVuZCA9IGFyZWFTdHJlYW0kMS5wb2ludCA9IG5vb3AkMjtcbiAgICBhcmVhU3VtJDEuYWRkKGFicyhhcmVhUmluZ1N1bSQxKSk7XG4gICAgYXJlYVJpbmdTdW0kMS5yZXNldCgpO1xuICB9LFxuICByZXN1bHQ6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmVhID0gYXJlYVN1bSQxIC8gMjtcbiAgICBhcmVhU3VtJDEucmVzZXQoKTtcbiAgICByZXR1cm4gYXJlYTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYXJlYVJpbmdTdGFydCQxKCkge1xuICBhcmVhU3RyZWFtJDEucG9pbnQgPSBhcmVhUG9pbnRGaXJzdCQxO1xufVxuXG5mdW5jdGlvbiBhcmVhUG9pbnRGaXJzdCQxKHgsIHkpIHtcbiAgYXJlYVN0cmVhbSQxLnBvaW50ID0gYXJlYVBvaW50JDE7XG4gIHgwMCA9IHgwJDEgPSB4LCB5MDAgPSB5MCQxID0geTtcbn1cblxuZnVuY3Rpb24gYXJlYVBvaW50JDEoeCwgeSkge1xuICBhcmVhUmluZ1N1bSQxLmFkZCh5MCQxICogeCAtIHgwJDEgKiB5KTtcbiAgeDAkMSA9IHgsIHkwJDEgPSB5O1xufVxuXG5mdW5jdGlvbiBhcmVhUmluZ0VuZCQxKCkge1xuICBhcmVhUG9pbnQkMSh4MDAsIHkwMCk7XG59XG5cbnZhciB4MCQyID0gSW5maW5pdHk7XG52YXIgeTAkMiA9IHgwJDI7XG52YXIgeDEgPSAteDAkMjtcbnZhciB5MSA9IHgxO1xuXG52YXIgYm91bmRzU3RyZWFtJDEgPSB7XG4gIHBvaW50OiBib3VuZHNQb2ludCQxLFxuICBsaW5lU3RhcnQ6IG5vb3AkMixcbiAgbGluZUVuZDogbm9vcCQyLFxuICBwb2x5Z29uU3RhcnQ6IG5vb3AkMixcbiAgcG9seWdvbkVuZDogbm9vcCQyLFxuICByZXN1bHQ6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBib3VuZHMgPSBbW3gwJDIsIHkwJDJdLCBbeDEsIHkxXV07XG4gICAgeDEgPSB5MSA9IC0oeTAkMiA9IHgwJDIgPSBJbmZpbml0eSk7XG4gICAgcmV0dXJuIGJvdW5kcztcbiAgfVxufTtcblxuZnVuY3Rpb24gYm91bmRzUG9pbnQkMSh4LCB5KSB7XG4gIGlmICh4IDwgeDAkMikgeDAkMiA9IHg7XG4gIGlmICh4ID4geDEpIHgxID0geDtcbiAgaWYgKHkgPCB5MCQyKSB5MCQyID0geTtcbiAgaWYgKHkgPiB5MSkgeTEgPSB5O1xufVxuXG4vLyBUT0RPIEVuZm9yY2UgcG9zaXRpdmUgYXJlYSBmb3IgZXh0ZXJpb3IsIG5lZ2F0aXZlIGFyZWEgZm9yIGludGVyaW9yP1xuXG52YXIgWDAkMSA9IDA7XG52YXIgWTAkMSA9IDA7XG52YXIgWjAkMSA9IDA7XG52YXIgWDEkMSA9IDA7XG52YXIgWTEkMSA9IDA7XG52YXIgWjEkMSA9IDA7XG52YXIgWDIkMSA9IDA7XG52YXIgWTIkMSA9IDA7XG52YXIgWjIkMSA9IDA7XG52YXIgeDAwJDE7XG52YXIgeTAwJDE7XG52YXIgeDAkMztcbnZhciB5MCQzO1xuXG52YXIgY2VudHJvaWRTdHJlYW0kMSA9IHtcbiAgcG9pbnQ6IGNlbnRyb2lkUG9pbnQkMSxcbiAgbGluZVN0YXJ0OiBjZW50cm9pZExpbmVTdGFydCQxLFxuICBsaW5lRW5kOiBjZW50cm9pZExpbmVFbmQkMSxcbiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICBjZW50cm9pZFN0cmVhbSQxLmxpbmVTdGFydCA9IGNlbnRyb2lkUmluZ1N0YXJ0JDE7XG4gICAgY2VudHJvaWRTdHJlYW0kMS5saW5lRW5kID0gY2VudHJvaWRSaW5nRW5kJDE7XG4gIH0sXG4gIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50JDE7XG4gICAgY2VudHJvaWRTdHJlYW0kMS5saW5lU3RhcnQgPSBjZW50cm9pZExpbmVTdGFydCQxO1xuICAgIGNlbnRyb2lkU3RyZWFtJDEubGluZUVuZCA9IGNlbnRyb2lkTGluZUVuZCQxO1xuICB9LFxuICByZXN1bHQ6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBjZW50cm9pZCA9IFoyJDEgPyBbWDIkMSAvIFoyJDEsIFkyJDEgLyBaMiQxXVxuICAgICAgICA6IFoxJDEgPyBbWDEkMSAvIFoxJDEsIFkxJDEgLyBaMSQxXVxuICAgICAgICA6IFowJDEgPyBbWDAkMSAvIFowJDEsIFkwJDEgLyBaMCQxXVxuICAgICAgICA6IFtOYU4sIE5hTl07XG4gICAgWDAkMSA9IFkwJDEgPSBaMCQxID1cbiAgICBYMSQxID0gWTEkMSA9IFoxJDEgPVxuICAgIFgyJDEgPSBZMiQxID0gWjIkMSA9IDA7XG4gICAgcmV0dXJuIGNlbnRyb2lkO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjZW50cm9pZFBvaW50JDEoeCwgeSkge1xuICBYMCQxICs9IHg7XG4gIFkwJDEgKz0geTtcbiAgKytaMCQxO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZExpbmVTdGFydCQxKCkge1xuICBjZW50cm9pZFN0cmVhbSQxLnBvaW50ID0gY2VudHJvaWRQb2ludEZpcnN0TGluZTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRQb2ludEZpcnN0TGluZSh4LCB5KSB7XG4gIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50TGluZTtcbiAgY2VudHJvaWRQb2ludCQxKHgwJDMgPSB4LCB5MCQzID0geSk7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUG9pbnRMaW5lKHgsIHkpIHtcbiAgdmFyIGR4ID0geCAtIHgwJDMsIGR5ID0geSAtIHkwJDMsIHogPSBzcXJ0JDEoZHggKiBkeCArIGR5ICogZHkpO1xuICBYMSQxICs9IHogKiAoeDAkMyArIHgpIC8gMjtcbiAgWTEkMSArPSB6ICogKHkwJDMgKyB5KSAvIDI7XG4gIFoxJDEgKz0gejtcbiAgY2VudHJvaWRQb2ludCQxKHgwJDMgPSB4LCB5MCQzID0geSk7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkTGluZUVuZCQxKCkge1xuICBjZW50cm9pZFN0cmVhbSQxLnBvaW50ID0gY2VudHJvaWRQb2ludCQxO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFJpbmdTdGFydCQxKCkge1xuICBjZW50cm9pZFN0cmVhbSQxLnBvaW50ID0gY2VudHJvaWRQb2ludEZpcnN0UmluZztcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRSaW5nRW5kJDEoKSB7XG4gIGNlbnRyb2lkUG9pbnRSaW5nKHgwMCQxLCB5MDAkMSk7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUG9pbnRGaXJzdFJpbmcoeCwgeSkge1xuICBjZW50cm9pZFN0cmVhbSQxLnBvaW50ID0gY2VudHJvaWRQb2ludFJpbmc7XG4gIGNlbnRyb2lkUG9pbnQkMSh4MDAkMSA9IHgwJDMgPSB4LCB5MDAkMSA9IHkwJDMgPSB5KTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRQb2ludFJpbmcoeCwgeSkge1xuICB2YXIgZHggPSB4IC0geDAkMyxcbiAgICAgIGR5ID0geSAtIHkwJDMsXG4gICAgICB6ID0gc3FydCQxKGR4ICogZHggKyBkeSAqIGR5KTtcblxuICBYMSQxICs9IHogKiAoeDAkMyArIHgpIC8gMjtcbiAgWTEkMSArPSB6ICogKHkwJDMgKyB5KSAvIDI7XG4gIFoxJDEgKz0gejtcblxuICB6ID0geTAkMyAqIHggLSB4MCQzICogeTtcbiAgWDIkMSArPSB6ICogKHgwJDMgKyB4KTtcbiAgWTIkMSArPSB6ICogKHkwJDMgKyB5KTtcbiAgWjIkMSArPSB6ICogMztcbiAgY2VudHJvaWRQb2ludCQxKHgwJDMgPSB4LCB5MCQzID0geSk7XG59XG5cbmZ1bmN0aW9uIFBhdGhDb250ZXh0KGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG59XG5cblBhdGhDb250ZXh0LnByb3RvdHlwZSA9IHtcbiAgX3JhZGl1czogNC41LFxuICBwb2ludFJhZGl1czogZnVuY3Rpb24oXykge1xuICAgIHJldHVybiB0aGlzLl9yYWRpdXMgPSBfLCB0aGlzO1xuICB9LFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2xpbmUgPT09IDApIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fcG9pbnQgPSBOYU47XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpO1xuICAgICAgICB0aGlzLl9wb2ludCA9IDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAxOiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgdGhpcy5fY29udGV4dC5tb3ZlVG8oeCArIHRoaXMuX3JhZGl1cywgeSk7XG4gICAgICAgIHRoaXMuX2NvbnRleHQuYXJjKHgsIHksIHRoaXMuX3JhZGl1cywgMCwgdGF1JDQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHJlc3VsdDogbm9vcCQyXG59O1xuXG5mdW5jdGlvbiBQYXRoU3RyaW5nKCkge1xuICB0aGlzLl9zdHJpbmcgPSBbXTtcbn1cblxuUGF0aFN0cmluZy5wcm90b3R5cGUgPSB7XG4gIF9jaXJjbGU6IGNpcmNsZSQyKDQuNSksXG4gIHBvaW50UmFkaXVzOiBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NpcmNsZSA9IGNpcmNsZSQyKF8pLCB0aGlzO1xuICB9LFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2xpbmUgPT09IDApIHRoaXMuX3N0cmluZy5wdXNoKFwiWlwiKTtcbiAgICB0aGlzLl9wb2ludCA9IE5hTjtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHtcbiAgICAgICAgdGhpcy5fc3RyaW5nLnB1c2goXCJNXCIsIHgsIFwiLFwiLCB5KTtcbiAgICAgICAgdGhpcy5fcG9pbnQgPSAxO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9zdHJpbmcucHVzaChcIkxcIiwgeCwgXCIsXCIsIHkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgdGhpcy5fc3RyaW5nLnB1c2goXCJNXCIsIHgsIFwiLFwiLCB5LCB0aGlzLl9jaXJjbGUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX3N0cmluZy5sZW5ndGgpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9zdHJpbmcuam9pbihcIlwiKTtcbiAgICAgIHRoaXMuX3N0cmluZyA9IFtdO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNpcmNsZSQyKHJhZGl1cykge1xuICByZXR1cm4gXCJtMCxcIiArIHJhZGl1c1xuICAgICAgKyBcImFcIiArIHJhZGl1cyArIFwiLFwiICsgcmFkaXVzICsgXCIgMCAxLDEgMCxcIiArIC0yICogcmFkaXVzXG4gICAgICArIFwiYVwiICsgcmFkaXVzICsgXCIsXCIgKyByYWRpdXMgKyBcIiAwIDEsMSAwLFwiICsgMiAqIHJhZGl1c1xuICAgICAgKyBcInpcIjtcbn1cblxudmFyIGluZGV4JDMgPSBmdW5jdGlvbihwcm9qZWN0aW9uLCBjb250ZXh0KSB7XG4gIHZhciBwb2ludFJhZGl1cyA9IDQuNSxcbiAgICAgIHByb2plY3Rpb25TdHJlYW0sXG4gICAgICBjb250ZXh0U3RyZWFtO1xuXG4gIGZ1bmN0aW9uIHBhdGgob2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdCkge1xuICAgICAgaWYgKHR5cGVvZiBwb2ludFJhZGl1cyA9PT0gXCJmdW5jdGlvblwiKSBjb250ZXh0U3RyZWFtLnBvaW50UmFkaXVzKCtwb2ludFJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oY29udGV4dFN0cmVhbSkpO1xuICAgIH1cbiAgICByZXR1cm4gY29udGV4dFN0cmVhbS5yZXN1bHQoKTtcbiAgfVxuXG4gIHBhdGguYXJlYSA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oYXJlYVN0cmVhbSQxKSk7XG4gICAgcmV0dXJuIGFyZWFTdHJlYW0kMS5yZXN1bHQoKTtcbiAgfTtcblxuICBwYXRoLmJvdW5kcyA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oYm91bmRzU3RyZWFtJDEpKTtcbiAgICByZXR1cm4gYm91bmRzU3RyZWFtJDEucmVzdWx0KCk7XG4gIH07XG5cbiAgcGF0aC5jZW50cm9pZCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oY2VudHJvaWRTdHJlYW0kMSkpO1xuICAgIHJldHVybiBjZW50cm9pZFN0cmVhbSQxLnJlc3VsdCgpO1xuICB9O1xuXG4gIHBhdGgucHJvamVjdGlvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcm9qZWN0aW9uU3RyZWFtID0gXyA9PSBudWxsID8gKHByb2plY3Rpb24gPSBudWxsLCBpZGVudGl0eSQ3KSA6IChwcm9qZWN0aW9uID0gXykuc3RyZWFtLCBwYXRoKSA6IHByb2plY3Rpb247XG4gIH07XG5cbiAgcGF0aC5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGNvbnRleHQ7XG4gICAgY29udGV4dFN0cmVhbSA9IF8gPT0gbnVsbCA/IChjb250ZXh0ID0gbnVsbCwgbmV3IFBhdGhTdHJpbmcpIDogbmV3IFBhdGhDb250ZXh0KGNvbnRleHQgPSBfKTtcbiAgICBpZiAodHlwZW9mIHBvaW50UmFkaXVzICE9PSBcImZ1bmN0aW9uXCIpIGNvbnRleHRTdHJlYW0ucG9pbnRSYWRpdXMocG9pbnRSYWRpdXMpO1xuICAgIHJldHVybiBwYXRoO1xuICB9O1xuXG4gIHBhdGgucG9pbnRSYWRpdXMgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcG9pbnRSYWRpdXM7XG4gICAgcG9pbnRSYWRpdXMgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IChjb250ZXh0U3RyZWFtLnBvaW50UmFkaXVzKCtfKSwgK18pO1xuICAgIHJldHVybiBwYXRoO1xuICB9O1xuXG4gIHJldHVybiBwYXRoLnByb2plY3Rpb24ocHJvamVjdGlvbikuY29udGV4dChjb250ZXh0KTtcbn07XG5cbnZhciBzdW0kMiA9IGFkZGVyKCk7XG5cbnZhciBwb2x5Z29uQ29udGFpbnMgPSBmdW5jdGlvbihwb2x5Z29uLCBwb2ludCkge1xuICB2YXIgbGFtYmRhID0gcG9pbnRbMF0sXG4gICAgICBwaGkgPSBwb2ludFsxXSxcbiAgICAgIG5vcm1hbCA9IFtzaW4kMShsYW1iZGEpLCAtY29zJDEobGFtYmRhKSwgMF0sXG4gICAgICBhbmdsZSA9IDAsXG4gICAgICB3aW5kaW5nID0gMDtcblxuICBzdW0kMi5yZXNldCgpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBuID0gcG9seWdvbi5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoIShtID0gKHJpbmcgPSBwb2x5Z29uW2ldKS5sZW5ndGgpKSBjb250aW51ZTtcbiAgICB2YXIgcmluZyxcbiAgICAgICAgbSxcbiAgICAgICAgcG9pbnQwID0gcmluZ1ttIC0gMV0sXG4gICAgICAgIGxhbWJkYTAgPSBwb2ludDBbMF0sXG4gICAgICAgIHBoaTAgPSBwb2ludDBbMV0gLyAyICsgcXVhcnRlclBpLFxuICAgICAgICBzaW5QaGkwID0gc2luJDEocGhpMCksXG4gICAgICAgIGNvc1BoaTAgPSBjb3MkMShwaGkwKTtcblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbTsgKytqLCBsYW1iZGEwID0gbGFtYmRhMSwgc2luUGhpMCA9IHNpblBoaTEsIGNvc1BoaTAgPSBjb3NQaGkxLCBwb2ludDAgPSBwb2ludDEpIHtcbiAgICAgIHZhciBwb2ludDEgPSByaW5nW2pdLFxuICAgICAgICAgIGxhbWJkYTEgPSBwb2ludDFbMF0sXG4gICAgICAgICAgcGhpMSA9IHBvaW50MVsxXSAvIDIgKyBxdWFydGVyUGksXG4gICAgICAgICAgc2luUGhpMSA9IHNpbiQxKHBoaTEpLFxuICAgICAgICAgIGNvc1BoaTEgPSBjb3MkMShwaGkxKSxcbiAgICAgICAgICBkZWx0YSA9IGxhbWJkYTEgLSBsYW1iZGEwLFxuICAgICAgICAgIHNpZ24kJDEgPSBkZWx0YSA+PSAwID8gMSA6IC0xLFxuICAgICAgICAgIGFic0RlbHRhID0gc2lnbiQkMSAqIGRlbHRhLFxuICAgICAgICAgIGFudGltZXJpZGlhbiA9IGFic0RlbHRhID4gcGkkNCxcbiAgICAgICAgICBrID0gc2luUGhpMCAqIHNpblBoaTE7XG5cbiAgICAgIHN1bSQyLmFkZChhdGFuMihrICogc2lnbiQkMSAqIHNpbiQxKGFic0RlbHRhKSwgY29zUGhpMCAqIGNvc1BoaTEgKyBrICogY29zJDEoYWJzRGVsdGEpKSk7XG4gICAgICBhbmdsZSArPSBhbnRpbWVyaWRpYW4gPyBkZWx0YSArIHNpZ24kJDEgKiB0YXUkNCA6IGRlbHRhO1xuXG4gICAgICAvLyBBcmUgdGhlIGxvbmdpdHVkZXMgZWl0aGVyIHNpZGUgb2YgdGhlIHBvaW504oCZcyBtZXJpZGlhbiAobGFtYmRhKSxcbiAgICAgIC8vIGFuZCBhcmUgdGhlIGxhdGl0dWRlcyBzbWFsbGVyIHRoYW4gdGhlIHBhcmFsbGVsIChwaGkpP1xuICAgICAgaWYgKGFudGltZXJpZGlhbiBeIGxhbWJkYTAgPj0gbGFtYmRhIF4gbGFtYmRhMSA+PSBsYW1iZGEpIHtcbiAgICAgICAgdmFyIGFyYyA9IGNhcnRlc2lhbkNyb3NzKGNhcnRlc2lhbihwb2ludDApLCBjYXJ0ZXNpYW4ocG9pbnQxKSk7XG4gICAgICAgIGNhcnRlc2lhbk5vcm1hbGl6ZUluUGxhY2UoYXJjKTtcbiAgICAgICAgdmFyIGludGVyc2VjdGlvbiA9IGNhcnRlc2lhbkNyb3NzKG5vcm1hbCwgYXJjKTtcbiAgICAgICAgY2FydGVzaWFuTm9ybWFsaXplSW5QbGFjZShpbnRlcnNlY3Rpb24pO1xuICAgICAgICB2YXIgcGhpQXJjID0gKGFudGltZXJpZGlhbiBeIGRlbHRhID49IDAgPyAtMSA6IDEpICogYXNpbiQxKGludGVyc2VjdGlvblsyXSk7XG4gICAgICAgIGlmIChwaGkgPiBwaGlBcmMgfHwgcGhpID09PSBwaGlBcmMgJiYgKGFyY1swXSB8fCBhcmNbMV0pKSB7XG4gICAgICAgICAgd2luZGluZyArPSBhbnRpbWVyaWRpYW4gXiBkZWx0YSA+PSAwID8gMSA6IC0xO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gRmlyc3QsIGRldGVybWluZSB3aGV0aGVyIHRoZSBTb3V0aCBwb2xlIGlzIGluc2lkZSBvciBvdXRzaWRlOlxuICAvL1xuICAvLyBJdCBpcyBpbnNpZGUgaWY6XG4gIC8vICogdGhlIHBvbHlnb24gd2luZHMgYXJvdW5kIGl0IGluIGEgY2xvY2t3aXNlIGRpcmVjdGlvbi5cbiAgLy8gKiB0aGUgcG9seWdvbiBkb2VzIG5vdCAoY3VtdWxhdGl2ZWx5KSB3aW5kIGFyb3VuZCBpdCwgYnV0IGhhcyBhIG5lZ2F0aXZlXG4gIC8vICAgKGNvdW50ZXItY2xvY2t3aXNlKSBhcmVhLlxuICAvL1xuICAvLyBTZWNvbmQsIGNvdW50IHRoZSAoc2lnbmVkKSBudW1iZXIgb2YgdGltZXMgYSBzZWdtZW50IGNyb3NzZXMgYSBsYW1iZGFcbiAgLy8gZnJvbSB0aGUgcG9pbnQgdG8gdGhlIFNvdXRoIHBvbGUuICBJZiBpdCBpcyB6ZXJvLCB0aGVuIHRoZSBwb2ludCBpcyB0aGVcbiAgLy8gc2FtZSBzaWRlIGFzIHRoZSBTb3V0aCBwb2xlLlxuXG4gIHJldHVybiAoYW5nbGUgPCAtZXBzaWxvbiQ0IHx8IGFuZ2xlIDwgZXBzaWxvbiQ0ICYmIHN1bSQyIDwgLWVwc2lsb24kNCkgXiAod2luZGluZyAmIDEpO1xufTtcblxudmFyIGNsaXAgPSBmdW5jdGlvbihwb2ludFZpc2libGUsIGNsaXBMaW5lLCBpbnRlcnBvbGF0ZSwgc3RhcnQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHJvdGF0ZSwgc2luaykge1xuICAgIHZhciBsaW5lID0gY2xpcExpbmUoc2luayksXG4gICAgICAgIHJvdGF0ZWRTdGFydCA9IHJvdGF0ZS5pbnZlcnQoc3RhcnRbMF0sIHN0YXJ0WzFdKSxcbiAgICAgICAgcmluZ0J1ZmZlciA9IGNsaXBCdWZmZXIoKSxcbiAgICAgICAgcmluZ1NpbmsgPSBjbGlwTGluZShyaW5nQnVmZmVyKSxcbiAgICAgICAgcG9seWdvblN0YXJ0ZWQgPSBmYWxzZSxcbiAgICAgICAgcG9seWdvbixcbiAgICAgICAgc2VnbWVudHMsXG4gICAgICAgIHJpbmc7XG5cbiAgICB2YXIgY2xpcCA9IHtcbiAgICAgIHBvaW50OiBwb2ludCxcbiAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgbGluZUVuZDogbGluZUVuZCxcbiAgICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGNsaXAucG9pbnQgPSBwb2ludFJpbmc7XG4gICAgICAgIGNsaXAubGluZVN0YXJ0ID0gcmluZ1N0YXJ0O1xuICAgICAgICBjbGlwLmxpbmVFbmQgPSByaW5nRW5kO1xuICAgICAgICBzZWdtZW50cyA9IFtdO1xuICAgICAgICBwb2x5Z29uID0gW107XG4gICAgICB9LFxuICAgICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGNsaXAucG9pbnQgPSBwb2ludDtcbiAgICAgICAgY2xpcC5saW5lU3RhcnQgPSBsaW5lU3RhcnQ7XG4gICAgICAgIGNsaXAubGluZUVuZCA9IGxpbmVFbmQ7XG4gICAgICAgIHNlZ21lbnRzID0gbWVyZ2Uoc2VnbWVudHMpO1xuICAgICAgICB2YXIgc3RhcnRJbnNpZGUgPSBwb2x5Z29uQ29udGFpbnMocG9seWdvbiwgcm90YXRlZFN0YXJ0KTtcbiAgICAgICAgaWYgKHNlZ21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgIGlmICghcG9seWdvblN0YXJ0ZWQpIHNpbmsucG9seWdvblN0YXJ0KCksIHBvbHlnb25TdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgICBjbGlwUG9seWdvbihzZWdtZW50cywgY29tcGFyZUludGVyc2VjdGlvbiwgc3RhcnRJbnNpZGUsIGludGVycG9sYXRlLCBzaW5rKTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGFydEluc2lkZSkge1xuICAgICAgICAgIGlmICghcG9seWdvblN0YXJ0ZWQpIHNpbmsucG9seWdvblN0YXJ0KCksIHBvbHlnb25TdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgICBzaW5rLmxpbmVTdGFydCgpO1xuICAgICAgICAgIGludGVycG9sYXRlKG51bGwsIG51bGwsIDEsIHNpbmspO1xuICAgICAgICAgIHNpbmsubGluZUVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb2x5Z29uU3RhcnRlZCkgc2luay5wb2x5Z29uRW5kKCksIHBvbHlnb25TdGFydGVkID0gZmFsc2U7XG4gICAgICAgIHNlZ21lbnRzID0gcG9seWdvbiA9IG51bGw7XG4gICAgICB9LFxuICAgICAgc3BoZXJlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgc2luay5wb2x5Z29uU3RhcnQoKTtcbiAgICAgICAgc2luay5saW5lU3RhcnQoKTtcbiAgICAgICAgaW50ZXJwb2xhdGUobnVsbCwgbnVsbCwgMSwgc2luayk7XG4gICAgICAgIHNpbmsubGluZUVuZCgpO1xuICAgICAgICBzaW5rLnBvbHlnb25FbmQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgICAgIHZhciBwb2ludCA9IHJvdGF0ZShsYW1iZGEsIHBoaSk7XG4gICAgICBpZiAocG9pbnRWaXNpYmxlKGxhbWJkYSA9IHBvaW50WzBdLCBwaGkgPSBwb2ludFsxXSkpIHNpbmsucG9pbnQobGFtYmRhLCBwaGkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBvaW50TGluZShsYW1iZGEsIHBoaSkge1xuICAgICAgdmFyIHBvaW50ID0gcm90YXRlKGxhbWJkYSwgcGhpKTtcbiAgICAgIGxpbmUucG9pbnQocG9pbnRbMF0sIHBvaW50WzFdKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lU3RhcnQoKSB7XG4gICAgICBjbGlwLnBvaW50ID0gcG9pbnRMaW5lO1xuICAgICAgbGluZS5saW5lU3RhcnQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lRW5kKCkge1xuICAgICAgY2xpcC5wb2ludCA9IHBvaW50O1xuICAgICAgbGluZS5saW5lRW5kKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9pbnRSaW5nKGxhbWJkYSwgcGhpKSB7XG4gICAgICByaW5nLnB1c2goW2xhbWJkYSwgcGhpXSk7XG4gICAgICB2YXIgcG9pbnQgPSByb3RhdGUobGFtYmRhLCBwaGkpO1xuICAgICAgcmluZ1NpbmsucG9pbnQocG9pbnRbMF0sIHBvaW50WzFdKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByaW5nU3RhcnQoKSB7XG4gICAgICByaW5nU2luay5saW5lU3RhcnQoKTtcbiAgICAgIHJpbmcgPSBbXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByaW5nRW5kKCkge1xuICAgICAgcG9pbnRSaW5nKHJpbmdbMF1bMF0sIHJpbmdbMF1bMV0pO1xuICAgICAgcmluZ1NpbmsubGluZUVuZCgpO1xuXG4gICAgICB2YXIgY2xlYW4gPSByaW5nU2luay5jbGVhbigpLFxuICAgICAgICAgIHJpbmdTZWdtZW50cyA9IHJpbmdCdWZmZXIucmVzdWx0KCksXG4gICAgICAgICAgaSwgbiA9IHJpbmdTZWdtZW50cy5sZW5ndGgsIG0sXG4gICAgICAgICAgc2VnbWVudCxcbiAgICAgICAgICBwb2ludDtcblxuICAgICAgcmluZy5wb3AoKTtcbiAgICAgIHBvbHlnb24ucHVzaChyaW5nKTtcbiAgICAgIHJpbmcgPSBudWxsO1xuXG4gICAgICBpZiAoIW4pIHJldHVybjtcblxuICAgICAgLy8gTm8gaW50ZXJzZWN0aW9ucy5cbiAgICAgIGlmIChjbGVhbiAmIDEpIHtcbiAgICAgICAgc2VnbWVudCA9IHJpbmdTZWdtZW50c1swXTtcbiAgICAgICAgaWYgKChtID0gc2VnbWVudC5sZW5ndGggLSAxKSA+IDApIHtcbiAgICAgICAgICBpZiAoIXBvbHlnb25TdGFydGVkKSBzaW5rLnBvbHlnb25TdGFydCgpLCBwb2x5Z29uU3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgc2luay5saW5lU3RhcnQoKTtcbiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbTsgKytpKSBzaW5rLnBvaW50KChwb2ludCA9IHNlZ21lbnRbaV0pWzBdLCBwb2ludFsxXSk7XG4gICAgICAgICAgc2luay5saW5lRW5kKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBSZWpvaW4gY29ubmVjdGVkIHNlZ21lbnRzLlxuICAgICAgLy8gVE9ETyByZXVzZSByaW5nQnVmZmVyLnJlam9pbigpP1xuICAgICAgaWYgKG4gPiAxICYmIGNsZWFuICYgMikgcmluZ1NlZ21lbnRzLnB1c2gocmluZ1NlZ21lbnRzLnBvcCgpLmNvbmNhdChyaW5nU2VnbWVudHMuc2hpZnQoKSkpO1xuXG4gICAgICBzZWdtZW50cy5wdXNoKHJpbmdTZWdtZW50cy5maWx0ZXIodmFsaWRTZWdtZW50KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsaXA7XG4gIH07XG59O1xuXG5mdW5jdGlvbiB2YWxpZFNlZ21lbnQoc2VnbWVudCkge1xuICByZXR1cm4gc2VnbWVudC5sZW5ndGggPiAxO1xufVxuXG4vLyBJbnRlcnNlY3Rpb25zIGFyZSBzb3J0ZWQgYWxvbmcgdGhlIGNsaXAgZWRnZS4gRm9yIGJvdGggYW50aW1lcmlkaWFuIGN1dHRpbmdcbi8vIGFuZCBjaXJjbGUgY2xpcHBpbmcsIHRoZSBzYW1lIGNvbXBhcmlzb24gaXMgdXNlZC5cbmZ1bmN0aW9uIGNvbXBhcmVJbnRlcnNlY3Rpb24oYSwgYikge1xuICByZXR1cm4gKChhID0gYS54KVswXSA8IDAgPyBhWzFdIC0gaGFsZlBpJDMgLSBlcHNpbG9uJDQgOiBoYWxmUGkkMyAtIGFbMV0pXG4gICAgICAgLSAoKGIgPSBiLngpWzBdIDwgMCA/IGJbMV0gLSBoYWxmUGkkMyAtIGVwc2lsb24kNCA6IGhhbGZQaSQzIC0gYlsxXSk7XG59XG5cbnZhciBjbGlwQW50aW1lcmlkaWFuID0gY2xpcChcbiAgZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9LFxuICBjbGlwQW50aW1lcmlkaWFuTGluZSxcbiAgY2xpcEFudGltZXJpZGlhbkludGVycG9sYXRlLFxuICBbLXBpJDQsIC1oYWxmUGkkM11cbik7XG5cbi8vIFRha2VzIGEgbGluZSBhbmQgY3V0cyBpbnRvIHZpc2libGUgc2VnbWVudHMuIFJldHVybiB2YWx1ZXM6IDAgLSB0aGVyZSB3ZXJlXG4vLyBpbnRlcnNlY3Rpb25zIG9yIHRoZSBsaW5lIHdhcyBlbXB0eTsgMSAtIG5vIGludGVyc2VjdGlvbnM7IDIgLSB0aGVyZSB3ZXJlXG4vLyBpbnRlcnNlY3Rpb25zLCBhbmQgdGhlIGZpcnN0IGFuZCBsYXN0IHNlZ21lbnRzIHNob3VsZCBiZSByZWpvaW5lZC5cbmZ1bmN0aW9uIGNsaXBBbnRpbWVyaWRpYW5MaW5lKHN0cmVhbSkge1xuICB2YXIgbGFtYmRhMCA9IE5hTixcbiAgICAgIHBoaTAgPSBOYU4sXG4gICAgICBzaWduMCA9IE5hTixcbiAgICAgIGNsZWFuOyAvLyBubyBpbnRlcnNlY3Rpb25zXG5cbiAgcmV0dXJuIHtcbiAgICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgY2xlYW4gPSAxO1xuICAgIH0sXG4gICAgcG9pbnQ6IGZ1bmN0aW9uKGxhbWJkYTEsIHBoaTEpIHtcbiAgICAgIHZhciBzaWduMSA9IGxhbWJkYTEgPiAwID8gcGkkNCA6IC1waSQ0LFxuICAgICAgICAgIGRlbHRhID0gYWJzKGxhbWJkYTEgLSBsYW1iZGEwKTtcbiAgICAgIGlmIChhYnMoZGVsdGEgLSBwaSQ0KSA8IGVwc2lsb24kNCkgeyAvLyBsaW5lIGNyb3NzZXMgYSBwb2xlXG4gICAgICAgIHN0cmVhbS5wb2ludChsYW1iZGEwLCBwaGkwID0gKHBoaTAgKyBwaGkxKSAvIDIgPiAwID8gaGFsZlBpJDMgOiAtaGFsZlBpJDMpO1xuICAgICAgICBzdHJlYW0ucG9pbnQoc2lnbjAsIHBoaTApO1xuICAgICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgICAgIHN0cmVhbS5wb2ludChzaWduMSwgcGhpMCk7XG4gICAgICAgIHN0cmVhbS5wb2ludChsYW1iZGExLCBwaGkwKTtcbiAgICAgICAgY2xlYW4gPSAwO1xuICAgICAgfSBlbHNlIGlmIChzaWduMCAhPT0gc2lnbjEgJiYgZGVsdGEgPj0gcGkkNCkgeyAvLyBsaW5lIGNyb3NzZXMgYW50aW1lcmlkaWFuXG4gICAgICAgIGlmIChhYnMobGFtYmRhMCAtIHNpZ24wKSA8IGVwc2lsb24kNCkgbGFtYmRhMCAtPSBzaWduMCAqIGVwc2lsb24kNDsgLy8gaGFuZGxlIGRlZ2VuZXJhY2llc1xuICAgICAgICBpZiAoYWJzKGxhbWJkYTEgLSBzaWduMSkgPCBlcHNpbG9uJDQpIGxhbWJkYTEgLT0gc2lnbjEgKiBlcHNpbG9uJDQ7XG4gICAgICAgIHBoaTAgPSBjbGlwQW50aW1lcmlkaWFuSW50ZXJzZWN0KGxhbWJkYTAsIHBoaTAsIGxhbWJkYTEsIHBoaTEpO1xuICAgICAgICBzdHJlYW0ucG9pbnQoc2lnbjAsIHBoaTApO1xuICAgICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgICAgIHN0cmVhbS5wb2ludChzaWduMSwgcGhpMCk7XG4gICAgICAgIGNsZWFuID0gMDtcbiAgICAgIH1cbiAgICAgIHN0cmVhbS5wb2ludChsYW1iZGEwID0gbGFtYmRhMSwgcGhpMCA9IHBoaTEpO1xuICAgICAgc2lnbjAgPSBzaWduMTtcbiAgICB9LFxuICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgIGxhbWJkYTAgPSBwaGkwID0gTmFOO1xuICAgIH0sXG4gICAgY2xlYW46IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIDIgLSBjbGVhbjsgLy8gaWYgaW50ZXJzZWN0aW9ucywgcmVqb2luIGZpcnN0IGFuZCBsYXN0IHNlZ21lbnRzXG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBjbGlwQW50aW1lcmlkaWFuSW50ZXJzZWN0KGxhbWJkYTAsIHBoaTAsIGxhbWJkYTEsIHBoaTEpIHtcbiAgdmFyIGNvc1BoaTAsXG4gICAgICBjb3NQaGkxLFxuICAgICAgc2luTGFtYmRhMExhbWJkYTEgPSBzaW4kMShsYW1iZGEwIC0gbGFtYmRhMSk7XG4gIHJldHVybiBhYnMoc2luTGFtYmRhMExhbWJkYTEpID4gZXBzaWxvbiQ0XG4gICAgICA/IGF0YW4oKHNpbiQxKHBoaTApICogKGNvc1BoaTEgPSBjb3MkMShwaGkxKSkgKiBzaW4kMShsYW1iZGExKVxuICAgICAgICAgIC0gc2luJDEocGhpMSkgKiAoY29zUGhpMCA9IGNvcyQxKHBoaTApKSAqIHNpbiQxKGxhbWJkYTApKVxuICAgICAgICAgIC8gKGNvc1BoaTAgKiBjb3NQaGkxICogc2luTGFtYmRhMExhbWJkYTEpKVxuICAgICAgOiAocGhpMCArIHBoaTEpIC8gMjtcbn1cblxuZnVuY3Rpb24gY2xpcEFudGltZXJpZGlhbkludGVycG9sYXRlKGZyb20sIHRvLCBkaXJlY3Rpb24sIHN0cmVhbSkge1xuICB2YXIgcGhpO1xuICBpZiAoZnJvbSA9PSBudWxsKSB7XG4gICAgcGhpID0gZGlyZWN0aW9uICogaGFsZlBpJDM7XG4gICAgc3RyZWFtLnBvaW50KC1waSQ0LCBwaGkpO1xuICAgIHN0cmVhbS5wb2ludCgwLCBwaGkpO1xuICAgIHN0cmVhbS5wb2ludChwaSQ0LCBwaGkpO1xuICAgIHN0cmVhbS5wb2ludChwaSQ0LCAwKTtcbiAgICBzdHJlYW0ucG9pbnQocGkkNCwgLXBoaSk7XG4gICAgc3RyZWFtLnBvaW50KDAsIC1waGkpO1xuICAgIHN0cmVhbS5wb2ludCgtcGkkNCwgLXBoaSk7XG4gICAgc3RyZWFtLnBvaW50KC1waSQ0LCAwKTtcbiAgICBzdHJlYW0ucG9pbnQoLXBpJDQsIHBoaSk7XG4gIH0gZWxzZSBpZiAoYWJzKGZyb21bMF0gLSB0b1swXSkgPiBlcHNpbG9uJDQpIHtcbiAgICB2YXIgbGFtYmRhID0gZnJvbVswXSA8IHRvWzBdID8gcGkkNCA6IC1waSQ0O1xuICAgIHBoaSA9IGRpcmVjdGlvbiAqIGxhbWJkYSAvIDI7XG4gICAgc3RyZWFtLnBvaW50KC1sYW1iZGEsIHBoaSk7XG4gICAgc3RyZWFtLnBvaW50KDAsIHBoaSk7XG4gICAgc3RyZWFtLnBvaW50KGxhbWJkYSwgcGhpKTtcbiAgfSBlbHNlIHtcbiAgICBzdHJlYW0ucG9pbnQodG9bMF0sIHRvWzFdKTtcbiAgfVxufVxuXG52YXIgY2xpcENpcmNsZSA9IGZ1bmN0aW9uKHJhZGl1cywgZGVsdGEpIHtcbiAgdmFyIGNyID0gY29zJDEocmFkaXVzKSxcbiAgICAgIHNtYWxsUmFkaXVzID0gY3IgPiAwLFxuICAgICAgbm90SGVtaXNwaGVyZSA9IGFicyhjcikgPiBlcHNpbG9uJDQ7IC8vIFRPRE8gb3B0aW1pc2UgZm9yIHRoaXMgY29tbW9uIGNhc2VcblxuICBmdW5jdGlvbiBpbnRlcnBvbGF0ZShmcm9tLCB0bywgZGlyZWN0aW9uLCBzdHJlYW0pIHtcbiAgICBjaXJjbGVTdHJlYW0oc3RyZWFtLCByYWRpdXMsIGRlbHRhLCBkaXJlY3Rpb24sIGZyb20sIHRvKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZpc2libGUobGFtYmRhLCBwaGkpIHtcbiAgICByZXR1cm4gY29zJDEobGFtYmRhKSAqIGNvcyQxKHBoaSkgPiBjcjtcbiAgfVxuXG4gIC8vIFRha2VzIGEgbGluZSBhbmQgY3V0cyBpbnRvIHZpc2libGUgc2VnbWVudHMuIFJldHVybiB2YWx1ZXMgdXNlZCBmb3IgcG9seWdvblxuICAvLyBjbGlwcGluZzogMCAtIHRoZXJlIHdlcmUgaW50ZXJzZWN0aW9ucyBvciB0aGUgbGluZSB3YXMgZW1wdHk7IDEgLSBub1xuICAvLyBpbnRlcnNlY3Rpb25zIDIgLSB0aGVyZSB3ZXJlIGludGVyc2VjdGlvbnMsIGFuZCB0aGUgZmlyc3QgYW5kIGxhc3Qgc2VnbWVudHNcbiAgLy8gc2hvdWxkIGJlIHJlam9pbmVkLlxuICBmdW5jdGlvbiBjbGlwTGluZShzdHJlYW0pIHtcbiAgICB2YXIgcG9pbnQwLCAvLyBwcmV2aW91cyBwb2ludFxuICAgICAgICBjMCwgLy8gY29kZSBmb3IgcHJldmlvdXMgcG9pbnRcbiAgICAgICAgdjAsIC8vIHZpc2liaWxpdHkgb2YgcHJldmlvdXMgcG9pbnRcbiAgICAgICAgdjAwLCAvLyB2aXNpYmlsaXR5IG9mIGZpcnN0IHBvaW50XG4gICAgICAgIGNsZWFuOyAvLyBubyBpbnRlcnNlY3Rpb25zXG4gICAgcmV0dXJuIHtcbiAgICAgIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHYwMCA9IHYwID0gZmFsc2U7XG4gICAgICAgIGNsZWFuID0gMTtcbiAgICAgIH0sXG4gICAgICBwb2ludDogZnVuY3Rpb24obGFtYmRhLCBwaGkpIHtcbiAgICAgICAgdmFyIHBvaW50MSA9IFtsYW1iZGEsIHBoaV0sXG4gICAgICAgICAgICBwb2ludDIsXG4gICAgICAgICAgICB2ID0gdmlzaWJsZShsYW1iZGEsIHBoaSksXG4gICAgICAgICAgICBjID0gc21hbGxSYWRpdXNcbiAgICAgICAgICAgICAgPyB2ID8gMCA6IGNvZGUobGFtYmRhLCBwaGkpXG4gICAgICAgICAgICAgIDogdiA/IGNvZGUobGFtYmRhICsgKGxhbWJkYSA8IDAgPyBwaSQ0IDogLXBpJDQpLCBwaGkpIDogMDtcbiAgICAgICAgaWYgKCFwb2ludDAgJiYgKHYwMCA9IHYwID0gdikpIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgLy8gSGFuZGxlIGRlZ2VuZXJhY2llcy5cbiAgICAgICAgLy8gVE9ETyBpZ25vcmUgaWYgbm90IGNsaXBwaW5nIHBvbHlnb25zLlxuICAgICAgICBpZiAodiAhPT0gdjApIHtcbiAgICAgICAgICBwb2ludDIgPSBpbnRlcnNlY3QocG9pbnQwLCBwb2ludDEpO1xuICAgICAgICAgIGlmIChwb2ludEVxdWFsKHBvaW50MCwgcG9pbnQyKSB8fCBwb2ludEVxdWFsKHBvaW50MSwgcG9pbnQyKSkge1xuICAgICAgICAgICAgcG9pbnQxWzBdICs9IGVwc2lsb24kNDtcbiAgICAgICAgICAgIHBvaW50MVsxXSArPSBlcHNpbG9uJDQ7XG4gICAgICAgICAgICB2ID0gdmlzaWJsZShwb2ludDFbMF0sIHBvaW50MVsxXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh2ICE9PSB2MCkge1xuICAgICAgICAgIGNsZWFuID0gMDtcbiAgICAgICAgICBpZiAodikge1xuICAgICAgICAgICAgLy8gb3V0c2lkZSBnb2luZyBpblxuICAgICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgcG9pbnQyID0gaW50ZXJzZWN0KHBvaW50MSwgcG9pbnQwKTtcbiAgICAgICAgICAgIHN0cmVhbS5wb2ludChwb2ludDJbMF0sIHBvaW50MlsxXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGluc2lkZSBnb2luZyBvdXRcbiAgICAgICAgICAgIHBvaW50MiA9IGludGVyc2VjdChwb2ludDAsIHBvaW50MSk7XG4gICAgICAgICAgICBzdHJlYW0ucG9pbnQocG9pbnQyWzBdLCBwb2ludDJbMV0pO1xuICAgICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcG9pbnQwID0gcG9pbnQyO1xuICAgICAgICB9IGVsc2UgaWYgKG5vdEhlbWlzcGhlcmUgJiYgcG9pbnQwICYmIHNtYWxsUmFkaXVzIF4gdikge1xuICAgICAgICAgIHZhciB0O1xuICAgICAgICAgIC8vIElmIHRoZSBjb2RlcyBmb3IgdHdvIHBvaW50cyBhcmUgZGlmZmVyZW50LCBvciBhcmUgYm90aCB6ZXJvLFxuICAgICAgICAgIC8vIGFuZCB0aGVyZSB0aGlzIHNlZ21lbnQgaW50ZXJzZWN0cyB3aXRoIHRoZSBzbWFsbCBjaXJjbGUuXG4gICAgICAgICAgaWYgKCEoYyAmIGMwKSAmJiAodCA9IGludGVyc2VjdChwb2ludDEsIHBvaW50MCwgdHJ1ZSkpKSB7XG4gICAgICAgICAgICBjbGVhbiA9IDA7XG4gICAgICAgICAgICBpZiAoc21hbGxSYWRpdXMpIHtcbiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgICBzdHJlYW0ucG9pbnQodFswXVswXSwgdFswXVsxXSk7XG4gICAgICAgICAgICAgIHN0cmVhbS5wb2ludCh0WzFdWzBdLCB0WzFdWzFdKTtcbiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHN0cmVhbS5wb2ludCh0WzFdWzBdLCB0WzFdWzFdKTtcbiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgICBzdHJlYW0ucG9pbnQodFswXVswXSwgdFswXVsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh2ICYmICghcG9pbnQwIHx8ICFwb2ludEVxdWFsKHBvaW50MCwgcG9pbnQxKSkpIHtcbiAgICAgICAgICBzdHJlYW0ucG9pbnQocG9pbnQxWzBdLCBwb2ludDFbMV0pO1xuICAgICAgICB9XG4gICAgICAgIHBvaW50MCA9IHBvaW50MSwgdjAgPSB2LCBjMCA9IGM7XG4gICAgICB9LFxuICAgICAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh2MCkgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgcG9pbnQwID0gbnVsbDtcbiAgICAgIH0sXG4gICAgICAvLyBSZWpvaW4gZmlyc3QgYW5kIGxhc3Qgc2VnbWVudHMgaWYgdGhlcmUgd2VyZSBpbnRlcnNlY3Rpb25zIGFuZCB0aGUgZmlyc3RcbiAgICAgIC8vIGFuZCBsYXN0IHBvaW50cyB3ZXJlIHZpc2libGUuXG4gICAgICBjbGVhbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBjbGVhbiB8ICgodjAwICYmIHYwKSA8PCAxKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gSW50ZXJzZWN0cyB0aGUgZ3JlYXQgY2lyY2xlIGJldHdlZW4gYSBhbmQgYiB3aXRoIHRoZSBjbGlwIGNpcmNsZS5cbiAgZnVuY3Rpb24gaW50ZXJzZWN0KGEsIGIsIHR3bykge1xuICAgIHZhciBwYSA9IGNhcnRlc2lhbihhKSxcbiAgICAgICAgcGIgPSBjYXJ0ZXNpYW4oYik7XG5cbiAgICAvLyBXZSBoYXZlIHR3byBwbGFuZXMsIG4xLnAgPSBkMSBhbmQgbjIucCA9IGQyLlxuICAgIC8vIEZpbmQgaW50ZXJzZWN0aW9uIGxpbmUgcCh0KSA9IGMxIG4xICsgYzIgbjIgKyB0IChuMSDiqK8gbjIpLlxuICAgIHZhciBuMSA9IFsxLCAwLCAwXSwgLy8gbm9ybWFsXG4gICAgICAgIG4yID0gY2FydGVzaWFuQ3Jvc3MocGEsIHBiKSxcbiAgICAgICAgbjJuMiA9IGNhcnRlc2lhbkRvdChuMiwgbjIpLFxuICAgICAgICBuMW4yID0gbjJbMF0sIC8vIGNhcnRlc2lhbkRvdChuMSwgbjIpLFxuICAgICAgICBkZXRlcm1pbmFudCA9IG4ybjIgLSBuMW4yICogbjFuMjtcblxuICAgIC8vIFR3byBwb2xhciBwb2ludHMuXG4gICAgaWYgKCFkZXRlcm1pbmFudCkgcmV0dXJuICF0d28gJiYgYTtcblxuICAgIHZhciBjMSA9ICBjciAqIG4ybjIgLyBkZXRlcm1pbmFudCxcbiAgICAgICAgYzIgPSAtY3IgKiBuMW4yIC8gZGV0ZXJtaW5hbnQsXG4gICAgICAgIG4xeG4yID0gY2FydGVzaWFuQ3Jvc3MobjEsIG4yKSxcbiAgICAgICAgQSA9IGNhcnRlc2lhblNjYWxlKG4xLCBjMSksXG4gICAgICAgIEIgPSBjYXJ0ZXNpYW5TY2FsZShuMiwgYzIpO1xuICAgIGNhcnRlc2lhbkFkZEluUGxhY2UoQSwgQik7XG5cbiAgICAvLyBTb2x2ZSB8cCh0KXxeMiA9IDEuXG4gICAgdmFyIHUgPSBuMXhuMixcbiAgICAgICAgdyA9IGNhcnRlc2lhbkRvdChBLCB1KSxcbiAgICAgICAgdXUgPSBjYXJ0ZXNpYW5Eb3QodSwgdSksXG4gICAgICAgIHQyID0gdyAqIHcgLSB1dSAqIChjYXJ0ZXNpYW5Eb3QoQSwgQSkgLSAxKTtcblxuICAgIGlmICh0MiA8IDApIHJldHVybjtcblxuICAgIHZhciB0ID0gc3FydCQxKHQyKSxcbiAgICAgICAgcSA9IGNhcnRlc2lhblNjYWxlKHUsICgtdyAtIHQpIC8gdXUpO1xuICAgIGNhcnRlc2lhbkFkZEluUGxhY2UocSwgQSk7XG4gICAgcSA9IHNwaGVyaWNhbChxKTtcblxuICAgIGlmICghdHdvKSByZXR1cm4gcTtcblxuICAgIC8vIFR3byBpbnRlcnNlY3Rpb24gcG9pbnRzLlxuICAgIHZhciBsYW1iZGEwID0gYVswXSxcbiAgICAgICAgbGFtYmRhMSA9IGJbMF0sXG4gICAgICAgIHBoaTAgPSBhWzFdLFxuICAgICAgICBwaGkxID0gYlsxXSxcbiAgICAgICAgejtcblxuICAgIGlmIChsYW1iZGExIDwgbGFtYmRhMCkgeiA9IGxhbWJkYTAsIGxhbWJkYTAgPSBsYW1iZGExLCBsYW1iZGExID0gejtcblxuICAgIHZhciBkZWx0YSA9IGxhbWJkYTEgLSBsYW1iZGEwLFxuICAgICAgICBwb2xhciA9IGFicyhkZWx0YSAtIHBpJDQpIDwgZXBzaWxvbiQ0LFxuICAgICAgICBtZXJpZGlhbiA9IHBvbGFyIHx8IGRlbHRhIDwgZXBzaWxvbiQ0O1xuXG4gICAgaWYgKCFwb2xhciAmJiBwaGkxIDwgcGhpMCkgeiA9IHBoaTAsIHBoaTAgPSBwaGkxLCBwaGkxID0gejtcblxuICAgIC8vIENoZWNrIHRoYXQgdGhlIGZpcnN0IHBvaW50IGlzIGJldHdlZW4gYSBhbmQgYi5cbiAgICBpZiAobWVyaWRpYW5cbiAgICAgICAgPyBwb2xhclxuICAgICAgICAgID8gcGhpMCArIHBoaTEgPiAwIF4gcVsxXSA8IChhYnMocVswXSAtIGxhbWJkYTApIDwgZXBzaWxvbiQ0ID8gcGhpMCA6IHBoaTEpXG4gICAgICAgICAgOiBwaGkwIDw9IHFbMV0gJiYgcVsxXSA8PSBwaGkxXG4gICAgICAgIDogZGVsdGEgPiBwaSQ0IF4gKGxhbWJkYTAgPD0gcVswXSAmJiBxWzBdIDw9IGxhbWJkYTEpKSB7XG4gICAgICB2YXIgcTEgPSBjYXJ0ZXNpYW5TY2FsZSh1LCAoLXcgKyB0KSAvIHV1KTtcbiAgICAgIGNhcnRlc2lhbkFkZEluUGxhY2UocTEsIEEpO1xuICAgICAgcmV0dXJuIFtxLCBzcGhlcmljYWwocTEpXTtcbiAgICB9XG4gIH1cblxuICAvLyBHZW5lcmF0ZXMgYSA0LWJpdCB2ZWN0b3IgcmVwcmVzZW50aW5nIHRoZSBsb2NhdGlvbiBvZiBhIHBvaW50IHJlbGF0aXZlIHRvXG4gIC8vIHRoZSBzbWFsbCBjaXJjbGUncyBib3VuZGluZyBib3guXG4gIGZ1bmN0aW9uIGNvZGUobGFtYmRhLCBwaGkpIHtcbiAgICB2YXIgciA9IHNtYWxsUmFkaXVzID8gcmFkaXVzIDogcGkkNCAtIHJhZGl1cyxcbiAgICAgICAgY29kZSA9IDA7XG4gICAgaWYgKGxhbWJkYSA8IC1yKSBjb2RlIHw9IDE7IC8vIGxlZnRcbiAgICBlbHNlIGlmIChsYW1iZGEgPiByKSBjb2RlIHw9IDI7IC8vIHJpZ2h0XG4gICAgaWYgKHBoaSA8IC1yKSBjb2RlIHw9IDQ7IC8vIGJlbG93XG4gICAgZWxzZSBpZiAocGhpID4gcikgY29kZSB8PSA4OyAvLyBhYm92ZVxuICAgIHJldHVybiBjb2RlO1xuICB9XG5cbiAgcmV0dXJuIGNsaXAodmlzaWJsZSwgY2xpcExpbmUsIGludGVycG9sYXRlLCBzbWFsbFJhZGl1cyA/IFswLCAtcmFkaXVzXSA6IFstcGkkNCwgcmFkaXVzIC0gcGkkNF0pO1xufTtcblxudmFyIHRyYW5zZm9ybSQxID0gZnVuY3Rpb24obWV0aG9kcykge1xuICByZXR1cm4ge1xuICAgIHN0cmVhbTogdHJhbnNmb3JtZXIobWV0aG9kcylcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybWVyKG1ldGhvZHMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIHZhciBzID0gbmV3IFRyYW5zZm9ybVN0cmVhbTtcbiAgICBmb3IgKHZhciBrZXkgaW4gbWV0aG9kcykgc1trZXldID0gbWV0aG9kc1trZXldO1xuICAgIHMuc3RyZWFtID0gc3RyZWFtO1xuICAgIHJldHVybiBzO1xuICB9O1xufVxuXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW0oKSB7fVxuXG5UcmFuc2Zvcm1TdHJlYW0ucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogVHJhbnNmb3JtU3RyZWFtLFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkgeyB0aGlzLnN0cmVhbS5wb2ludCh4LCB5KTsgfSxcbiAgc3BoZXJlOiBmdW5jdGlvbigpIHsgdGhpcy5zdHJlYW0uc3BoZXJlKCk7IH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7IHRoaXMuc3RyZWFtLmxpbmVTdGFydCgpOyB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHsgdGhpcy5zdHJlYW0ubGluZUVuZCgpOyB9LFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkgeyB0aGlzLnN0cmVhbS5wb2x5Z29uU3RhcnQoKTsgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7IHRoaXMuc3RyZWFtLnBvbHlnb25FbmQoKTsgfVxufTtcblxuZnVuY3Rpb24gZml0RXh0ZW50KHByb2plY3Rpb24sIGV4dGVudCwgb2JqZWN0KSB7XG4gIHZhciB3ID0gZXh0ZW50WzFdWzBdIC0gZXh0ZW50WzBdWzBdLFxuICAgICAgaCA9IGV4dGVudFsxXVsxXSAtIGV4dGVudFswXVsxXSxcbiAgICAgIGNsaXAgPSBwcm9qZWN0aW9uLmNsaXBFeHRlbnQgJiYgcHJvamVjdGlvbi5jbGlwRXh0ZW50KCk7XG5cbiAgcHJvamVjdGlvblxuICAgICAgLnNjYWxlKDE1MClcbiAgICAgIC50cmFuc2xhdGUoWzAsIDBdKTtcblxuICBpZiAoY2xpcCAhPSBudWxsKSBwcm9qZWN0aW9uLmNsaXBFeHRlbnQobnVsbCk7XG5cbiAgZ2VvU3RyZWFtKG9iamVjdCwgcHJvamVjdGlvbi5zdHJlYW0oYm91bmRzU3RyZWFtJDEpKTtcblxuICB2YXIgYiA9IGJvdW5kc1N0cmVhbSQxLnJlc3VsdCgpLFxuICAgICAgayA9IE1hdGgubWluKHcgLyAoYlsxXVswXSAtIGJbMF1bMF0pLCBoIC8gKGJbMV1bMV0gLSBiWzBdWzFdKSksXG4gICAgICB4ID0gK2V4dGVudFswXVswXSArICh3IC0gayAqIChiWzFdWzBdICsgYlswXVswXSkpIC8gMixcbiAgICAgIHkgPSArZXh0ZW50WzBdWzFdICsgKGggLSBrICogKGJbMV1bMV0gKyBiWzBdWzFdKSkgLyAyO1xuXG4gIGlmIChjbGlwICE9IG51bGwpIHByb2plY3Rpb24uY2xpcEV4dGVudChjbGlwKTtcblxuICByZXR1cm4gcHJvamVjdGlvblxuICAgICAgLnNjYWxlKGsgKiAxNTApXG4gICAgICAudHJhbnNsYXRlKFt4LCB5XSk7XG59XG5cbmZ1bmN0aW9uIGZpdFNpemUocHJvamVjdGlvbiwgc2l6ZSwgb2JqZWN0KSB7XG4gIHJldHVybiBmaXRFeHRlbnQocHJvamVjdGlvbiwgW1swLCAwXSwgc2l6ZV0sIG9iamVjdCk7XG59XG5cbnZhciBtYXhEZXB0aCA9IDE2O1xudmFyIGNvc01pbkRpc3RhbmNlID0gY29zJDEoMzAgKiByYWRpYW5zKTsgLy8gY29zKG1pbmltdW0gYW5ndWxhciBkaXN0YW5jZSlcblxudmFyIHJlc2FtcGxlID0gZnVuY3Rpb24ocHJvamVjdCwgZGVsdGEyKSB7XG4gIHJldHVybiArZGVsdGEyID8gcmVzYW1wbGUkMShwcm9qZWN0LCBkZWx0YTIpIDogcmVzYW1wbGVOb25lKHByb2plY3QpO1xufTtcblxuZnVuY3Rpb24gcmVzYW1wbGVOb25lKHByb2plY3QpIHtcbiAgcmV0dXJuIHRyYW5zZm9ybWVyKHtcbiAgICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgICAgeCA9IHByb2plY3QoeCwgeSk7XG4gICAgICB0aGlzLnN0cmVhbS5wb2ludCh4WzBdLCB4WzFdKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZXNhbXBsZSQxKHByb2plY3QsIGRlbHRhMikge1xuXG4gIGZ1bmN0aW9uIHJlc2FtcGxlTGluZVRvKHgwLCB5MCwgbGFtYmRhMCwgYTAsIGIwLCBjMCwgeDEsIHkxLCBsYW1iZGExLCBhMSwgYjEsIGMxLCBkZXB0aCwgc3RyZWFtKSB7XG4gICAgdmFyIGR4ID0geDEgLSB4MCxcbiAgICAgICAgZHkgPSB5MSAtIHkwLFxuICAgICAgICBkMiA9IGR4ICogZHggKyBkeSAqIGR5O1xuICAgIGlmIChkMiA+IDQgKiBkZWx0YTIgJiYgZGVwdGgtLSkge1xuICAgICAgdmFyIGEgPSBhMCArIGExLFxuICAgICAgICAgIGIgPSBiMCArIGIxLFxuICAgICAgICAgIGMgPSBjMCArIGMxLFxuICAgICAgICAgIG0gPSBzcXJ0JDEoYSAqIGEgKyBiICogYiArIGMgKiBjKSxcbiAgICAgICAgICBwaGkyID0gYXNpbiQxKGMgLz0gbSksXG4gICAgICAgICAgbGFtYmRhMiA9IGFicyhhYnMoYykgLSAxKSA8IGVwc2lsb24kNCB8fCBhYnMobGFtYmRhMCAtIGxhbWJkYTEpIDwgZXBzaWxvbiQ0ID8gKGxhbWJkYTAgKyBsYW1iZGExKSAvIDIgOiBhdGFuMihiLCBhKSxcbiAgICAgICAgICBwID0gcHJvamVjdChsYW1iZGEyLCBwaGkyKSxcbiAgICAgICAgICB4MiA9IHBbMF0sXG4gICAgICAgICAgeTIgPSBwWzFdLFxuICAgICAgICAgIGR4MiA9IHgyIC0geDAsXG4gICAgICAgICAgZHkyID0geTIgLSB5MCxcbiAgICAgICAgICBkeiA9IGR5ICogZHgyIC0gZHggKiBkeTI7XG4gICAgICBpZiAoZHogKiBkeiAvIGQyID4gZGVsdGEyIC8vIHBlcnBlbmRpY3VsYXIgcHJvamVjdGVkIGRpc3RhbmNlXG4gICAgICAgICAgfHwgYWJzKChkeCAqIGR4MiArIGR5ICogZHkyKSAvIGQyIC0gMC41KSA+IDAuMyAvLyBtaWRwb2ludCBjbG9zZSB0byBhbiBlbmRcbiAgICAgICAgICB8fCBhMCAqIGExICsgYjAgKiBiMSArIGMwICogYzEgPCBjb3NNaW5EaXN0YW5jZSkgeyAvLyBhbmd1bGFyIGRpc3RhbmNlXG4gICAgICAgIHJlc2FtcGxlTGluZVRvKHgwLCB5MCwgbGFtYmRhMCwgYTAsIGIwLCBjMCwgeDIsIHkyLCBsYW1iZGEyLCBhIC89IG0sIGIgLz0gbSwgYywgZGVwdGgsIHN0cmVhbSk7XG4gICAgICAgIHN0cmVhbS5wb2ludCh4MiwgeTIpO1xuICAgICAgICByZXNhbXBsZUxpbmVUbyh4MiwgeTIsIGxhbWJkYTIsIGEsIGIsIGMsIHgxLCB5MSwgbGFtYmRhMSwgYTEsIGIxLCBjMSwgZGVwdGgsIHN0cmVhbSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICB2YXIgbGFtYmRhMDAsIHgwMCwgeTAwLCBhMDAsIGIwMCwgYzAwLCAvLyBmaXJzdCBwb2ludFxuICAgICAgICBsYW1iZGEwLCB4MCwgeTAsIGEwLCBiMCwgYzA7IC8vIHByZXZpb3VzIHBvaW50XG5cbiAgICB2YXIgcmVzYW1wbGVTdHJlYW0gPSB7XG4gICAgICBwb2ludDogcG9pbnQsXG4gICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgIGxpbmVFbmQ6IGxpbmVFbmQsXG4gICAgICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkgeyBzdHJlYW0ucG9seWdvblN0YXJ0KCk7IHJlc2FtcGxlU3RyZWFtLmxpbmVTdGFydCA9IHJpbmdTdGFydDsgfSxcbiAgICAgIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkgeyBzdHJlYW0ucG9seWdvbkVuZCgpOyByZXNhbXBsZVN0cmVhbS5saW5lU3RhcnQgPSBsaW5lU3RhcnQ7IH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcG9pbnQoeCwgeSkge1xuICAgICAgeCA9IHByb2plY3QoeCwgeSk7XG4gICAgICBzdHJlYW0ucG9pbnQoeFswXSwgeFsxXSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGluZVN0YXJ0KCkge1xuICAgICAgeDAgPSBOYU47XG4gICAgICByZXNhbXBsZVN0cmVhbS5wb2ludCA9IGxpbmVQb2ludDtcbiAgICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgICAgIHZhciBjID0gY2FydGVzaWFuKFtsYW1iZGEsIHBoaV0pLCBwID0gcHJvamVjdChsYW1iZGEsIHBoaSk7XG4gICAgICByZXNhbXBsZUxpbmVUbyh4MCwgeTAsIGxhbWJkYTAsIGEwLCBiMCwgYzAsIHgwID0gcFswXSwgeTAgPSBwWzFdLCBsYW1iZGEwID0gbGFtYmRhLCBhMCA9IGNbMF0sIGIwID0gY1sxXSwgYzAgPSBjWzJdLCBtYXhEZXB0aCwgc3RyZWFtKTtcbiAgICAgIHN0cmVhbS5wb2ludCh4MCwgeTApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7XG4gICAgICByZXNhbXBsZVN0cmVhbS5wb2ludCA9IHBvaW50O1xuICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByaW5nU3RhcnQoKSB7XG4gICAgICBsaW5lU3RhcnQoKTtcbiAgICAgIHJlc2FtcGxlU3RyZWFtLnBvaW50ID0gcmluZ1BvaW50O1xuICAgICAgcmVzYW1wbGVTdHJlYW0ubGluZUVuZCA9IHJpbmdFbmQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmluZ1BvaW50KGxhbWJkYSwgcGhpKSB7XG4gICAgICBsaW5lUG9pbnQobGFtYmRhMDAgPSBsYW1iZGEsIHBoaSksIHgwMCA9IHgwLCB5MDAgPSB5MCwgYTAwID0gYTAsIGIwMCA9IGIwLCBjMDAgPSBjMDtcbiAgICAgIHJlc2FtcGxlU3RyZWFtLnBvaW50ID0gbGluZVBvaW50O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJpbmdFbmQoKSB7XG4gICAgICByZXNhbXBsZUxpbmVUbyh4MCwgeTAsIGxhbWJkYTAsIGEwLCBiMCwgYzAsIHgwMCwgeTAwLCBsYW1iZGEwMCwgYTAwLCBiMDAsIGMwMCwgbWF4RGVwdGgsIHN0cmVhbSk7XG4gICAgICByZXNhbXBsZVN0cmVhbS5saW5lRW5kID0gbGluZUVuZDtcbiAgICAgIGxpbmVFbmQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzYW1wbGVTdHJlYW07XG4gIH07XG59XG5cbnZhciB0cmFuc2Zvcm1SYWRpYW5zID0gdHJhbnNmb3JtZXIoe1xuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHRoaXMuc3RyZWFtLnBvaW50KHggKiByYWRpYW5zLCB5ICogcmFkaWFucyk7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBwcm9qZWN0aW9uKHByb2plY3QpIHtcbiAgcmV0dXJuIHByb2plY3Rpb25NdXRhdG9yKGZ1bmN0aW9uKCkgeyByZXR1cm4gcHJvamVjdDsgfSkoKTtcbn1cblxuZnVuY3Rpb24gcHJvamVjdGlvbk11dGF0b3IocHJvamVjdEF0KSB7XG4gIHZhciBwcm9qZWN0LFxuICAgICAgayA9IDE1MCwgLy8gc2NhbGVcbiAgICAgIHggPSA0ODAsIHkgPSAyNTAsIC8vIHRyYW5zbGF0ZVxuICAgICAgZHgsIGR5LCBsYW1iZGEgPSAwLCBwaGkgPSAwLCAvLyBjZW50ZXJcbiAgICAgIGRlbHRhTGFtYmRhID0gMCwgZGVsdGFQaGkgPSAwLCBkZWx0YUdhbW1hID0gMCwgcm90YXRlLCBwcm9qZWN0Um90YXRlLCAvLyByb3RhdGVcbiAgICAgIHRoZXRhID0gbnVsbCwgcHJlY2xpcCA9IGNsaXBBbnRpbWVyaWRpYW4sIC8vIGNsaXAgYW5nbGVcbiAgICAgIHgwID0gbnVsbCwgeTAsIHgxLCB5MSwgcG9zdGNsaXAgPSBpZGVudGl0eSQ3LCAvLyBjbGlwIGV4dGVudFxuICAgICAgZGVsdGEyID0gMC41LCBwcm9qZWN0UmVzYW1wbGUgPSByZXNhbXBsZShwcm9qZWN0VHJhbnNmb3JtLCBkZWx0YTIpLCAvLyBwcmVjaXNpb25cbiAgICAgIGNhY2hlLFxuICAgICAgY2FjaGVTdHJlYW07XG5cbiAgZnVuY3Rpb24gcHJvamVjdGlvbihwb2ludCkge1xuICAgIHBvaW50ID0gcHJvamVjdFJvdGF0ZShwb2ludFswXSAqIHJhZGlhbnMsIHBvaW50WzFdICogcmFkaWFucyk7XG4gICAgcmV0dXJuIFtwb2ludFswXSAqIGsgKyBkeCwgZHkgLSBwb2ludFsxXSAqIGtdO1xuICB9XG5cbiAgZnVuY3Rpb24gaW52ZXJ0KHBvaW50KSB7XG4gICAgcG9pbnQgPSBwcm9qZWN0Um90YXRlLmludmVydCgocG9pbnRbMF0gLSBkeCkgLyBrLCAoZHkgLSBwb2ludFsxXSkgLyBrKTtcbiAgICByZXR1cm4gcG9pbnQgJiYgW3BvaW50WzBdICogZGVncmVlcyQxLCBwb2ludFsxXSAqIGRlZ3JlZXMkMV07XG4gIH1cblxuICBmdW5jdGlvbiBwcm9qZWN0VHJhbnNmb3JtKHgsIHkpIHtcbiAgICByZXR1cm4geCA9IHByb2plY3QoeCwgeSksIFt4WzBdICogayArIGR4LCBkeSAtIHhbMV0gKiBrXTtcbiAgfVxuXG4gIHByb2plY3Rpb24uc3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgcmV0dXJuIGNhY2hlICYmIGNhY2hlU3RyZWFtID09PSBzdHJlYW0gPyBjYWNoZSA6IGNhY2hlID0gdHJhbnNmb3JtUmFkaWFucyhwcmVjbGlwKHJvdGF0ZSwgcHJvamVjdFJlc2FtcGxlKHBvc3RjbGlwKGNhY2hlU3RyZWFtID0gc3RyZWFtKSkpKTtcbiAgfTtcblxuICBwcm9qZWN0aW9uLmNsaXBBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcmVjbGlwID0gK18gPyBjbGlwQ2lyY2xlKHRoZXRhID0gXyAqIHJhZGlhbnMsIDYgKiByYWRpYW5zKSA6ICh0aGV0YSA9IG51bGwsIGNsaXBBbnRpbWVyaWRpYW4pLCByZXNldCgpKSA6IHRoZXRhICogZGVncmVlcyQxO1xuICB9O1xuXG4gIHByb2plY3Rpb24uY2xpcEV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwb3N0Y2xpcCA9IF8gPT0gbnVsbCA/ICh4MCA9IHkwID0geDEgPSB5MSA9IG51bGwsIGlkZW50aXR5JDcpIDogY2xpcEV4dGVudCh4MCA9ICtfWzBdWzBdLCB5MCA9ICtfWzBdWzFdLCB4MSA9ICtfWzFdWzBdLCB5MSA9ICtfWzFdWzFdKSwgcmVzZXQoKSkgOiB4MCA9PSBudWxsID8gbnVsbCA6IFtbeDAsIHkwXSwgW3gxLCB5MV1dO1xuICB9O1xuXG4gIHByb2plY3Rpb24uc2NhbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoayA9ICtfLCByZWNlbnRlcigpKSA6IGs7XG4gIH07XG5cbiAgcHJvamVjdGlvbi50cmFuc2xhdGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeCA9ICtfWzBdLCB5ID0gK19bMV0sIHJlY2VudGVyKCkpIDogW3gsIHldO1xuICB9O1xuXG4gIHByb2plY3Rpb24uY2VudGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGxhbWJkYSA9IF9bMF0gJSAzNjAgKiByYWRpYW5zLCBwaGkgPSBfWzFdICUgMzYwICogcmFkaWFucywgcmVjZW50ZXIoKSkgOiBbbGFtYmRhICogZGVncmVlcyQxLCBwaGkgKiBkZWdyZWVzJDFdO1xuICB9O1xuXG4gIHByb2plY3Rpb24ucm90YXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRlbHRhTGFtYmRhID0gX1swXSAlIDM2MCAqIHJhZGlhbnMsIGRlbHRhUGhpID0gX1sxXSAlIDM2MCAqIHJhZGlhbnMsIGRlbHRhR2FtbWEgPSBfLmxlbmd0aCA+IDIgPyBfWzJdICUgMzYwICogcmFkaWFucyA6IDAsIHJlY2VudGVyKCkpIDogW2RlbHRhTGFtYmRhICogZGVncmVlcyQxLCBkZWx0YVBoaSAqIGRlZ3JlZXMkMSwgZGVsdGFHYW1tYSAqIGRlZ3JlZXMkMV07XG4gIH07XG5cbiAgcHJvamVjdGlvbi5wcmVjaXNpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocHJvamVjdFJlc2FtcGxlID0gcmVzYW1wbGUocHJvamVjdFRyYW5zZm9ybSwgZGVsdGEyID0gXyAqIF8pLCByZXNldCgpKSA6IHNxcnQkMShkZWx0YTIpO1xuICB9O1xuXG4gIHByb2plY3Rpb24uZml0RXh0ZW50ID0gZnVuY3Rpb24oZXh0ZW50LCBvYmplY3QpIHtcbiAgICByZXR1cm4gZml0RXh0ZW50KHByb2plY3Rpb24sIGV4dGVudCwgb2JqZWN0KTtcbiAgfTtcblxuICBwcm9qZWN0aW9uLmZpdFNpemUgPSBmdW5jdGlvbihzaXplLCBvYmplY3QpIHtcbiAgICByZXR1cm4gZml0U2l6ZShwcm9qZWN0aW9uLCBzaXplLCBvYmplY3QpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlY2VudGVyKCkge1xuICAgIHByb2plY3RSb3RhdGUgPSBjb21wb3NlKHJvdGF0ZSA9IHJvdGF0ZVJhZGlhbnMoZGVsdGFMYW1iZGEsIGRlbHRhUGhpLCBkZWx0YUdhbW1hKSwgcHJvamVjdCk7XG4gICAgdmFyIGNlbnRlciA9IHByb2plY3QobGFtYmRhLCBwaGkpO1xuICAgIGR4ID0geCAtIGNlbnRlclswXSAqIGs7XG4gICAgZHkgPSB5ICsgY2VudGVyWzFdICogaztcbiAgICByZXR1cm4gcmVzZXQoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgIGNhY2hlID0gY2FjaGVTdHJlYW0gPSBudWxsO1xuICAgIHJldHVybiBwcm9qZWN0aW9uO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHByb2plY3QgPSBwcm9qZWN0QXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBwcm9qZWN0aW9uLmludmVydCA9IHByb2plY3QuaW52ZXJ0ICYmIGludmVydDtcbiAgICByZXR1cm4gcmVjZW50ZXIoKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29uaWNQcm9qZWN0aW9uKHByb2plY3RBdCkge1xuICB2YXIgcGhpMCA9IDAsXG4gICAgICBwaGkxID0gcGkkNCAvIDMsXG4gICAgICBtID0gcHJvamVjdGlvbk11dGF0b3IocHJvamVjdEF0KSxcbiAgICAgIHAgPSBtKHBoaTAsIHBoaTEpO1xuXG4gIHAucGFyYWxsZWxzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gbShwaGkwID0gX1swXSAqIHJhZGlhbnMsIHBoaTEgPSBfWzFdICogcmFkaWFucykgOiBbcGhpMCAqIGRlZ3JlZXMkMSwgcGhpMSAqIGRlZ3JlZXMkMV07XG4gIH07XG5cbiAgcmV0dXJuIHA7XG59XG5cbmZ1bmN0aW9uIGN5bGluZHJpY2FsRXF1YWxBcmVhUmF3KHBoaTApIHtcbiAgdmFyIGNvc1BoaTAgPSBjb3MkMShwaGkwKTtcblxuICBmdW5jdGlvbiBmb3J3YXJkKGxhbWJkYSwgcGhpKSB7XG4gICAgcmV0dXJuIFtsYW1iZGEgKiBjb3NQaGkwLCBzaW4kMShwaGkpIC8gY29zUGhpMF07XG4gIH1cblxuICBmb3J3YXJkLmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICByZXR1cm4gW3ggLyBjb3NQaGkwLCBhc2luJDEoeSAqIGNvc1BoaTApXTtcbiAgfTtcblxuICByZXR1cm4gZm9yd2FyZDtcbn1cblxuZnVuY3Rpb24gY29uaWNFcXVhbEFyZWFSYXcoeTAsIHkxKSB7XG4gIHZhciBzeTAgPSBzaW4kMSh5MCksIG4gPSAoc3kwICsgc2luJDEoeTEpKSAvIDI7XG5cbiAgLy8gQXJlIHRoZSBwYXJhbGxlbHMgc3ltbWV0cmljYWwgYXJvdW5kIHRoZSBFcXVhdG9yP1xuICBpZiAoYWJzKG4pIDwgZXBzaWxvbiQ0KSByZXR1cm4gY3lsaW5kcmljYWxFcXVhbEFyZWFSYXcoeTApO1xuXG4gIHZhciBjID0gMSArIHN5MCAqICgyICogbiAtIHN5MCksIHIwID0gc3FydCQxKGMpIC8gbjtcblxuICBmdW5jdGlvbiBwcm9qZWN0KHgsIHkpIHtcbiAgICB2YXIgciA9IHNxcnQkMShjIC0gMiAqIG4gKiBzaW4kMSh5KSkgLyBuO1xuICAgIHJldHVybiBbciAqIHNpbiQxKHggKj0gbiksIHIwIC0gciAqIGNvcyQxKHgpXTtcbiAgfVxuXG4gIHByb2plY3QuaW52ZXJ0ID0gZnVuY3Rpb24oeCwgeSkge1xuICAgIHZhciByMHkgPSByMCAtIHk7XG4gICAgcmV0dXJuIFthdGFuMih4LCBhYnMocjB5KSkgLyBuICogc2lnbiQxKHIweSksIGFzaW4kMSgoYyAtICh4ICogeCArIHIweSAqIHIweSkgKiBuICogbikgLyAoMiAqIG4pKV07XG4gIH07XG5cbiAgcmV0dXJuIHByb2plY3Q7XG59XG5cbnZhciBjb25pY0VxdWFsQXJlYSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY29uaWNQcm9qZWN0aW9uKGNvbmljRXF1YWxBcmVhUmF3KVxuICAgICAgLnNjYWxlKDE1NS40MjQpXG4gICAgICAuY2VudGVyKFswLCAzMy42NDQyXSk7XG59O1xuXG52YXIgYWxiZXJzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBjb25pY0VxdWFsQXJlYSgpXG4gICAgICAucGFyYWxsZWxzKFsyOS41LCA0NS41XSlcbiAgICAgIC5zY2FsZSgxMDcwKVxuICAgICAgLnRyYW5zbGF0ZShbNDgwLCAyNTBdKVxuICAgICAgLnJvdGF0ZShbOTYsIDBdKVxuICAgICAgLmNlbnRlcihbLTAuNiwgMzguN10pO1xufTtcblxuLy8gVGhlIHByb2plY3Rpb25zIG11c3QgaGF2ZSBtdXR1YWxseSBleGNsdXNpdmUgY2xpcCByZWdpb25zIG9uIHRoZSBzcGhlcmUsXG4vLyBhcyB0aGlzIHdpbGwgYXZvaWQgZW1pdHRpbmcgaW50ZXJsZWF2aW5nIGxpbmVzIGFuZCBwb2x5Z29ucy5cbmZ1bmN0aW9uIG11bHRpcGxleChzdHJlYW1zKSB7XG4gIHZhciBuID0gc3RyZWFtcy5sZW5ndGg7XG4gIHJldHVybiB7XG4gICAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0ucG9pbnQoeCwgeSk7IH0sXG4gICAgc3BoZXJlOiBmdW5jdGlvbigpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0uc3BoZXJlKCk7IH0sXG4gICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0ubGluZVN0YXJ0KCk7IH0sXG4gICAgbGluZUVuZDogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLmxpbmVFbmQoKTsgfSxcbiAgICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkgeyB2YXIgaSA9IC0xOyB3aGlsZSAoKytpIDwgbikgc3RyZWFtc1tpXS5wb2x5Z29uU3RhcnQoKTsgfSxcbiAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0ucG9seWdvbkVuZCgpOyB9XG4gIH07XG59XG5cbi8vIEEgY29tcG9zaXRlIHByb2plY3Rpb24gZm9yIHRoZSBVbml0ZWQgU3RhdGVzLCBjb25maWd1cmVkIGJ5IGRlZmF1bHQgZm9yXG4vLyA5NjDDlzUwMC4gVGhlIHByb2plY3Rpb24gYWxzbyB3b3JrcyBxdWl0ZSB3ZWxsIGF0IDk2MMOXNjAwIGlmIHlvdSBjaGFuZ2UgdGhlXG4vLyBzY2FsZSB0byAxMjg1IGFuZCBhZGp1c3QgdGhlIHRyYW5zbGF0ZSBhY2NvcmRpbmdseS4gVGhlIHNldCBvZiBzdGFuZGFyZFxuLy8gcGFyYWxsZWxzIGZvciBlYWNoIHJlZ2lvbiBjb21lcyBmcm9tIFVTR1MsIHdoaWNoIGlzIHB1Ymxpc2hlZCBoZXJlOlxuLy8gaHR0cDovL2Vnc2MudXNncy5nb3YvaXNiL3B1YnMvTWFwUHJvamVjdGlvbnMvcHJvamVjdGlvbnMuaHRtbCNhbGJlcnNcbnZhciBhbGJlcnNVc2EgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGNhY2hlLFxuICAgICAgY2FjaGVTdHJlYW0sXG4gICAgICBsb3dlcjQ4ID0gYWxiZXJzKCksIGxvd2VyNDhQb2ludCxcbiAgICAgIGFsYXNrYSA9IGNvbmljRXF1YWxBcmVhKCkucm90YXRlKFsxNTQsIDBdKS5jZW50ZXIoWy0yLCA1OC41XSkucGFyYWxsZWxzKFs1NSwgNjVdKSwgYWxhc2thUG9pbnQsIC8vIEVQU0c6MzMzOFxuICAgICAgaGF3YWlpID0gY29uaWNFcXVhbEFyZWEoKS5yb3RhdGUoWzE1NywgMF0pLmNlbnRlcihbLTMsIDE5LjldKS5wYXJhbGxlbHMoWzgsIDE4XSksIGhhd2FpaVBvaW50LCAvLyBFU1JJOjEwMjAwN1xuICAgICAgcG9pbnQsIHBvaW50U3RyZWFtID0ge3BvaW50OiBmdW5jdGlvbih4LCB5KSB7IHBvaW50ID0gW3gsIHldOyB9fTtcblxuICBmdW5jdGlvbiBhbGJlcnNVc2EoY29vcmRpbmF0ZXMpIHtcbiAgICB2YXIgeCA9IGNvb3JkaW5hdGVzWzBdLCB5ID0gY29vcmRpbmF0ZXNbMV07XG4gICAgcmV0dXJuIHBvaW50ID0gbnVsbCxcbiAgICAgICAgKGxvd2VyNDhQb2ludC5wb2ludCh4LCB5KSwgcG9pbnQpXG4gICAgICAgIHx8IChhbGFza2FQb2ludC5wb2ludCh4LCB5KSwgcG9pbnQpXG4gICAgICAgIHx8IChoYXdhaWlQb2ludC5wb2ludCh4LCB5KSwgcG9pbnQpO1xuICB9XG5cbiAgYWxiZXJzVXNhLmludmVydCA9IGZ1bmN0aW9uKGNvb3JkaW5hdGVzKSB7XG4gICAgdmFyIGsgPSBsb3dlcjQ4LnNjYWxlKCksXG4gICAgICAgIHQgPSBsb3dlcjQ4LnRyYW5zbGF0ZSgpLFxuICAgICAgICB4ID0gKGNvb3JkaW5hdGVzWzBdIC0gdFswXSkgLyBrLFxuICAgICAgICB5ID0gKGNvb3JkaW5hdGVzWzFdIC0gdFsxXSkgLyBrO1xuICAgIHJldHVybiAoeSA+PSAwLjEyMCAmJiB5IDwgMC4yMzQgJiYgeCA+PSAtMC40MjUgJiYgeCA8IC0wLjIxNCA/IGFsYXNrYVxuICAgICAgICA6IHkgPj0gMC4xNjYgJiYgeSA8IDAuMjM0ICYmIHggPj0gLTAuMjE0ICYmIHggPCAtMC4xMTUgPyBoYXdhaWlcbiAgICAgICAgOiBsb3dlcjQ4KS5pbnZlcnQoY29vcmRpbmF0ZXMpO1xuICB9O1xuXG4gIGFsYmVyc1VzYS5zdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICByZXR1cm4gY2FjaGUgJiYgY2FjaGVTdHJlYW0gPT09IHN0cmVhbSA/IGNhY2hlIDogY2FjaGUgPSBtdWx0aXBsZXgoW2xvd2VyNDguc3RyZWFtKGNhY2hlU3RyZWFtID0gc3RyZWFtKSwgYWxhc2thLnN0cmVhbShzdHJlYW0pLCBoYXdhaWkuc3RyZWFtKHN0cmVhbSldKTtcbiAgfTtcblxuICBhbGJlcnNVc2EucHJlY2lzaW9uID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxvd2VyNDgucHJlY2lzaW9uKCk7XG4gICAgbG93ZXI0OC5wcmVjaXNpb24oXyksIGFsYXNrYS5wcmVjaXNpb24oXyksIGhhd2FpaS5wcmVjaXNpb24oXyk7XG4gICAgcmV0dXJuIHJlc2V0KCk7XG4gIH07XG5cbiAgYWxiZXJzVXNhLnNjYWxlID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxvd2VyNDguc2NhbGUoKTtcbiAgICBsb3dlcjQ4LnNjYWxlKF8pLCBhbGFza2Euc2NhbGUoXyAqIDAuMzUpLCBoYXdhaWkuc2NhbGUoXyk7XG4gICAgcmV0dXJuIGFsYmVyc1VzYS50cmFuc2xhdGUobG93ZXI0OC50cmFuc2xhdGUoKSk7XG4gIH07XG5cbiAgYWxiZXJzVXNhLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsb3dlcjQ4LnRyYW5zbGF0ZSgpO1xuICAgIHZhciBrID0gbG93ZXI0OC5zY2FsZSgpLCB4ID0gK19bMF0sIHkgPSArX1sxXTtcblxuICAgIGxvd2VyNDhQb2ludCA9IGxvd2VyNDhcbiAgICAgICAgLnRyYW5zbGF0ZShfKVxuICAgICAgICAuY2xpcEV4dGVudChbW3ggLSAwLjQ1NSAqIGssIHkgLSAwLjIzOCAqIGtdLCBbeCArIDAuNDU1ICogaywgeSArIDAuMjM4ICoga11dKVxuICAgICAgICAuc3RyZWFtKHBvaW50U3RyZWFtKTtcblxuICAgIGFsYXNrYVBvaW50ID0gYWxhc2thXG4gICAgICAgIC50cmFuc2xhdGUoW3ggLSAwLjMwNyAqIGssIHkgKyAwLjIwMSAqIGtdKVxuICAgICAgICAuY2xpcEV4dGVudChbW3ggLSAwLjQyNSAqIGsgKyBlcHNpbG9uJDQsIHkgKyAwLjEyMCAqIGsgKyBlcHNpbG9uJDRdLCBbeCAtIDAuMjE0ICogayAtIGVwc2lsb24kNCwgeSArIDAuMjM0ICogayAtIGVwc2lsb24kNF1dKVxuICAgICAgICAuc3RyZWFtKHBvaW50U3RyZWFtKTtcblxuICAgIGhhd2FpaVBvaW50ID0gaGF3YWlpXG4gICAgICAgIC50cmFuc2xhdGUoW3ggLSAwLjIwNSAqIGssIHkgKyAwLjIxMiAqIGtdKVxuICAgICAgICAuY2xpcEV4dGVudChbW3ggLSAwLjIxNCAqIGsgKyBlcHNpbG9uJDQsIHkgKyAwLjE2NiAqIGsgKyBlcHNpbG9uJDRdLCBbeCAtIDAuMTE1ICogayAtIGVwc2lsb24kNCwgeSArIDAuMjM0ICogayAtIGVwc2lsb24kNF1dKVxuICAgICAgICAuc3RyZWFtKHBvaW50U3RyZWFtKTtcblxuICAgIHJldHVybiByZXNldCgpO1xuICB9O1xuXG4gIGFsYmVyc1VzYS5maXRFeHRlbnQgPSBmdW5jdGlvbihleHRlbnQsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRFeHRlbnQoYWxiZXJzVXNhLCBleHRlbnQsIG9iamVjdCk7XG4gIH07XG5cbiAgYWxiZXJzVXNhLmZpdFNpemUgPSBmdW5jdGlvbihzaXplLCBvYmplY3QpIHtcbiAgICByZXR1cm4gZml0U2l6ZShhbGJlcnNVc2EsIHNpemUsIG9iamVjdCk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgY2FjaGUgPSBjYWNoZVN0cmVhbSA9IG51bGw7XG4gICAgcmV0dXJuIGFsYmVyc1VzYTtcbiAgfVxuXG4gIHJldHVybiBhbGJlcnNVc2Euc2NhbGUoMTA3MCk7XG59O1xuXG5mdW5jdGlvbiBhemltdXRoYWxSYXcoc2NhbGUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB2YXIgY3ggPSBjb3MkMSh4KSxcbiAgICAgICAgY3kgPSBjb3MkMSh5KSxcbiAgICAgICAgayA9IHNjYWxlKGN4ICogY3kpO1xuICAgIHJldHVybiBbXG4gICAgICBrICogY3kgKiBzaW4kMSh4KSxcbiAgICAgIGsgKiBzaW4kMSh5KVxuICAgIF07XG4gIH1cbn1cblxuZnVuY3Rpb24gYXppbXV0aGFsSW52ZXJ0KGFuZ2xlKSB7XG4gIHJldHVybiBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIHogPSBzcXJ0JDEoeCAqIHggKyB5ICogeSksXG4gICAgICAgIGMgPSBhbmdsZSh6KSxcbiAgICAgICAgc2MgPSBzaW4kMShjKSxcbiAgICAgICAgY2MgPSBjb3MkMShjKTtcbiAgICByZXR1cm4gW1xuICAgICAgYXRhbjIoeCAqIHNjLCB6ICogY2MpLFxuICAgICAgYXNpbiQxKHogJiYgeSAqIHNjIC8geilcbiAgICBdO1xuICB9XG59XG5cbnZhciBhemltdXRoYWxFcXVhbEFyZWFSYXcgPSBhemltdXRoYWxSYXcoZnVuY3Rpb24oY3hjeSkge1xuICByZXR1cm4gc3FydCQxKDIgLyAoMSArIGN4Y3kpKTtcbn0pO1xuXG5hemltdXRoYWxFcXVhbEFyZWFSYXcuaW52ZXJ0ID0gYXppbXV0aGFsSW52ZXJ0KGZ1bmN0aW9uKHopIHtcbiAgcmV0dXJuIDIgKiBhc2luJDEoeiAvIDIpO1xufSk7XG5cbnZhciBhemltdXRoYWxFcXVhbEFyZWEgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHByb2plY3Rpb24oYXppbXV0aGFsRXF1YWxBcmVhUmF3KVxuICAgICAgLnNjYWxlKDEyNC43NSlcbiAgICAgIC5jbGlwQW5nbGUoMTgwIC0gMWUtMyk7XG59O1xuXG52YXIgYXppbXV0aGFsRXF1aWRpc3RhbnRSYXcgPSBhemltdXRoYWxSYXcoZnVuY3Rpb24oYykge1xuICByZXR1cm4gKGMgPSBhY29zKGMpKSAmJiBjIC8gc2luJDEoYyk7XG59KTtcblxuYXppbXV0aGFsRXF1aWRpc3RhbnRSYXcuaW52ZXJ0ID0gYXppbXV0aGFsSW52ZXJ0KGZ1bmN0aW9uKHopIHtcbiAgcmV0dXJuIHo7XG59KTtcblxudmFyIGF6aW11dGhhbEVxdWlkaXN0YW50ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwcm9qZWN0aW9uKGF6aW11dGhhbEVxdWlkaXN0YW50UmF3KVxuICAgICAgLnNjYWxlKDc5LjQxODgpXG4gICAgICAuY2xpcEFuZ2xlKDE4MCAtIDFlLTMpO1xufTtcblxuZnVuY3Rpb24gbWVyY2F0b3JSYXcobGFtYmRhLCBwaGkpIHtcbiAgcmV0dXJuIFtsYW1iZGEsIGxvZyQxKHRhbigoaGFsZlBpJDMgKyBwaGkpIC8gMikpXTtcbn1cblxubWVyY2F0b3JSYXcuaW52ZXJ0ID0gZnVuY3Rpb24oeCwgeSkge1xuICByZXR1cm4gW3gsIDIgKiBhdGFuKGV4cCh5KSkgLSBoYWxmUGkkM107XG59O1xuXG52YXIgbWVyY2F0b3IgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG1lcmNhdG9yUHJvamVjdGlvbihtZXJjYXRvclJhdylcbiAgICAgIC5zY2FsZSg5NjEgLyB0YXUkNCk7XG59O1xuXG5mdW5jdGlvbiBtZXJjYXRvclByb2plY3Rpb24ocHJvamVjdCkge1xuICB2YXIgbSA9IHByb2plY3Rpb24ocHJvamVjdCksXG4gICAgICBzY2FsZSA9IG0uc2NhbGUsXG4gICAgICB0cmFuc2xhdGUgPSBtLnRyYW5zbGF0ZSxcbiAgICAgIGNsaXBFeHRlbnQgPSBtLmNsaXBFeHRlbnQsXG4gICAgICBjbGlwQXV0bztcblxuICBtLnNjYWxlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNjYWxlKF8pLCBjbGlwQXV0byAmJiBtLmNsaXBFeHRlbnQobnVsbCksIG0pIDogc2NhbGUoKTtcbiAgfTtcblxuICBtLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0cmFuc2xhdGUoXyksIGNsaXBBdXRvICYmIG0uY2xpcEV4dGVudChudWxsKSwgbSkgOiB0cmFuc2xhdGUoKTtcbiAgfTtcblxuICBtLmNsaXBFeHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2xpcEF1dG8gPyBudWxsIDogY2xpcEV4dGVudCgpO1xuICAgIGlmIChjbGlwQXV0byA9IF8gPT0gbnVsbCkge1xuICAgICAgdmFyIGsgPSBwaSQ0ICogc2NhbGUoKSxcbiAgICAgICAgICB0ID0gdHJhbnNsYXRlKCk7XG4gICAgICBfID0gW1t0WzBdIC0gaywgdFsxXSAtIGtdLCBbdFswXSArIGssIHRbMV0gKyBrXV07XG4gICAgfVxuICAgIGNsaXBFeHRlbnQoXyk7XG4gICAgcmV0dXJuIG07XG4gIH07XG5cbiAgcmV0dXJuIG0uY2xpcEV4dGVudChudWxsKTtcbn1cblxuZnVuY3Rpb24gdGFueSh5KSB7XG4gIHJldHVybiB0YW4oKGhhbGZQaSQzICsgeSkgLyAyKTtcbn1cblxuZnVuY3Rpb24gY29uaWNDb25mb3JtYWxSYXcoeTAsIHkxKSB7XG4gIHZhciBjeTAgPSBjb3MkMSh5MCksXG4gICAgICBuID0geTAgPT09IHkxID8gc2luJDEoeTApIDogbG9nJDEoY3kwIC8gY29zJDEoeTEpKSAvIGxvZyQxKHRhbnkoeTEpIC8gdGFueSh5MCkpLFxuICAgICAgZiA9IGN5MCAqIHBvdyQxKHRhbnkoeTApLCBuKSAvIG47XG5cbiAgaWYgKCFuKSByZXR1cm4gbWVyY2F0b3JSYXc7XG5cbiAgZnVuY3Rpb24gcHJvamVjdCh4LCB5KSB7XG4gICAgaWYgKGYgPiAwKSB7IGlmICh5IDwgLWhhbGZQaSQzICsgZXBzaWxvbiQ0KSB5ID0gLWhhbGZQaSQzICsgZXBzaWxvbiQ0OyB9XG4gICAgZWxzZSB7IGlmICh5ID4gaGFsZlBpJDMgLSBlcHNpbG9uJDQpIHkgPSBoYWxmUGkkMyAtIGVwc2lsb24kNDsgfVxuICAgIHZhciByID0gZiAvIHBvdyQxKHRhbnkoeSksIG4pO1xuICAgIHJldHVybiBbciAqIHNpbiQxKG4gKiB4KSwgZiAtIHIgKiBjb3MkMShuICogeCldO1xuICB9XG5cbiAgcHJvamVjdC5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIGZ5ID0gZiAtIHksIHIgPSBzaWduJDEobikgKiBzcXJ0JDEoeCAqIHggKyBmeSAqIGZ5KTtcbiAgICByZXR1cm4gW2F0YW4yKHgsIGFicyhmeSkpIC8gbiAqIHNpZ24kMShmeSksIDIgKiBhdGFuKHBvdyQxKGYgLyByLCAxIC8gbikpIC0gaGFsZlBpJDNdO1xuICB9O1xuXG4gIHJldHVybiBwcm9qZWN0O1xufVxuXG52YXIgY29uaWNDb25mb3JtYWwgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGNvbmljUHJvamVjdGlvbihjb25pY0NvbmZvcm1hbFJhdylcbiAgICAgIC5zY2FsZSgxMDkuNSlcbiAgICAgIC5wYXJhbGxlbHMoWzMwLCAzMF0pO1xufTtcblxuZnVuY3Rpb24gZXF1aXJlY3Rhbmd1bGFyUmF3KGxhbWJkYSwgcGhpKSB7XG4gIHJldHVybiBbbGFtYmRhLCBwaGldO1xufVxuXG5lcXVpcmVjdGFuZ3VsYXJSYXcuaW52ZXJ0ID0gZXF1aXJlY3Rhbmd1bGFyUmF3O1xuXG52YXIgZXF1aXJlY3Rhbmd1bGFyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwcm9qZWN0aW9uKGVxdWlyZWN0YW5ndWxhclJhdylcbiAgICAgIC5zY2FsZSgxNTIuNjMpO1xufTtcblxuZnVuY3Rpb24gY29uaWNFcXVpZGlzdGFudFJhdyh5MCwgeTEpIHtcbiAgdmFyIGN5MCA9IGNvcyQxKHkwKSxcbiAgICAgIG4gPSB5MCA9PT0geTEgPyBzaW4kMSh5MCkgOiAoY3kwIC0gY29zJDEoeTEpKSAvICh5MSAtIHkwKSxcbiAgICAgIGcgPSBjeTAgLyBuICsgeTA7XG5cbiAgaWYgKGFicyhuKSA8IGVwc2lsb24kNCkgcmV0dXJuIGVxdWlyZWN0YW5ndWxhclJhdztcblxuICBmdW5jdGlvbiBwcm9qZWN0KHgsIHkpIHtcbiAgICB2YXIgZ3kgPSBnIC0geSwgbnggPSBuICogeDtcbiAgICByZXR1cm4gW2d5ICogc2luJDEobngpLCBnIC0gZ3kgKiBjb3MkMShueCldO1xuICB9XG5cbiAgcHJvamVjdC5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIGd5ID0gZyAtIHk7XG4gICAgcmV0dXJuIFthdGFuMih4LCBhYnMoZ3kpKSAvIG4gKiBzaWduJDEoZ3kpLCBnIC0gc2lnbiQxKG4pICogc3FydCQxKHggKiB4ICsgZ3kgKiBneSldO1xuICB9O1xuXG4gIHJldHVybiBwcm9qZWN0O1xufVxuXG52YXIgY29uaWNFcXVpZGlzdGFudCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY29uaWNQcm9qZWN0aW9uKGNvbmljRXF1aWRpc3RhbnRSYXcpXG4gICAgICAuc2NhbGUoMTMxLjE1NClcbiAgICAgIC5jZW50ZXIoWzAsIDEzLjkzODldKTtcbn07XG5cbmZ1bmN0aW9uIGdub21vbmljUmF3KHgsIHkpIHtcbiAgdmFyIGN5ID0gY29zJDEoeSksIGsgPSBjb3MkMSh4KSAqIGN5O1xuICByZXR1cm4gW2N5ICogc2luJDEoeCkgLyBrLCBzaW4kMSh5KSAvIGtdO1xufVxuXG5nbm9tb25pY1Jhdy5pbnZlcnQgPSBhemltdXRoYWxJbnZlcnQoYXRhbik7XG5cbnZhciBnbm9tb25pYyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gcHJvamVjdGlvbihnbm9tb25pY1JhdylcbiAgICAgIC5zY2FsZSgxNDQuMDQ5KVxuICAgICAgLmNsaXBBbmdsZSg2MCk7XG59O1xuXG5mdW5jdGlvbiBzY2FsZVRyYW5zbGF0ZShreCwga3ksIHR4LCB0eSkge1xuICByZXR1cm4ga3ggPT09IDEgJiYga3kgPT09IDEgJiYgdHggPT09IDAgJiYgdHkgPT09IDAgPyBpZGVudGl0eSQ3IDogdHJhbnNmb3JtZXIoe1xuICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgICB0aGlzLnN0cmVhbS5wb2ludCh4ICoga3ggKyB0eCwgeSAqIGt5ICsgdHkpO1xuICAgIH1cbiAgfSk7XG59XG5cbnZhciBpZGVudGl0eSQ4ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrID0gMSwgdHggPSAwLCB0eSA9IDAsIHN4ID0gMSwgc3kgPSAxLCB0cmFuc2Zvcm0gPSBpZGVudGl0eSQ3LCAvLyBzY2FsZSwgdHJhbnNsYXRlIGFuZCByZWZsZWN0XG4gICAgICB4MCA9IG51bGwsIHkwLCB4MSwgeTEsIGNsaXAgPSBpZGVudGl0eSQ3LCAvLyBjbGlwIGV4dGVudFxuICAgICAgY2FjaGUsXG4gICAgICBjYWNoZVN0cmVhbSxcbiAgICAgIHByb2plY3Rpb247XG5cbiAgZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgY2FjaGUgPSBjYWNoZVN0cmVhbSA9IG51bGw7XG4gICAgcmV0dXJuIHByb2plY3Rpb247XG4gIH1cblxuICByZXR1cm4gcHJvamVjdGlvbiA9IHtcbiAgICBzdHJlYW06IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgcmV0dXJuIGNhY2hlICYmIGNhY2hlU3RyZWFtID09PSBzdHJlYW0gPyBjYWNoZSA6IGNhY2hlID0gdHJhbnNmb3JtKGNsaXAoY2FjaGVTdHJlYW0gPSBzdHJlYW0pKTtcbiAgICB9LFxuICAgIGNsaXBFeHRlbnQ6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNsaXAgPSBfID09IG51bGwgPyAoeDAgPSB5MCA9IHgxID0geTEgPSBudWxsLCBpZGVudGl0eSQ3KSA6IGNsaXBFeHRlbnQoeDAgPSArX1swXVswXSwgeTAgPSArX1swXVsxXSwgeDEgPSArX1sxXVswXSwgeTEgPSArX1sxXVsxXSksIHJlc2V0KCkpIDogeDAgPT0gbnVsbCA/IG51bGwgOiBbW3gwLCB5MF0sIFt4MSwgeTFdXTtcbiAgICB9LFxuICAgIHNjYWxlOiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0cmFuc2Zvcm0gPSBzY2FsZVRyYW5zbGF0ZSgoayA9ICtfKSAqIHN4LCBrICogc3ksIHR4LCB0eSksIHJlc2V0KCkpIDogaztcbiAgICB9LFxuICAgIHRyYW5zbGF0ZTogZnVuY3Rpb24oXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodHJhbnNmb3JtID0gc2NhbGVUcmFuc2xhdGUoayAqIHN4LCBrICogc3ksIHR4ID0gK19bMF0sIHR5ID0gK19bMV0pLCByZXNldCgpKSA6IFt0eCwgdHldO1xuICAgIH0sXG4gICAgcmVmbGVjdFg6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRyYW5zZm9ybSA9IHNjYWxlVHJhbnNsYXRlKGsgKiAoc3ggPSBfID8gLTEgOiAxKSwgayAqIHN5LCB0eCwgdHkpLCByZXNldCgpKSA6IHN4IDwgMDtcbiAgICB9LFxuICAgIHJlZmxlY3RZOiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0cmFuc2Zvcm0gPSBzY2FsZVRyYW5zbGF0ZShrICogc3gsIGsgKiAoc3kgPSBfID8gLTEgOiAxKSwgdHgsIHR5KSwgcmVzZXQoKSkgOiBzeSA8IDA7XG4gICAgfSxcbiAgICBmaXRFeHRlbnQ6IGZ1bmN0aW9uKGV4dGVudCwgb2JqZWN0KSB7XG4gICAgICByZXR1cm4gZml0RXh0ZW50KHByb2plY3Rpb24sIGV4dGVudCwgb2JqZWN0KTtcbiAgICB9LFxuICAgIGZpdFNpemU6IGZ1bmN0aW9uKHNpemUsIG9iamVjdCkge1xuICAgICAgcmV0dXJuIGZpdFNpemUocHJvamVjdGlvbiwgc2l6ZSwgb2JqZWN0KTtcbiAgICB9XG4gIH07XG59O1xuXG5mdW5jdGlvbiBvcnRob2dyYXBoaWNSYXcoeCwgeSkge1xuICByZXR1cm4gW2NvcyQxKHkpICogc2luJDEoeCksIHNpbiQxKHkpXTtcbn1cblxub3J0aG9ncmFwaGljUmF3LmludmVydCA9IGF6aW11dGhhbEludmVydChhc2luJDEpO1xuXG52YXIgb3J0aG9ncmFwaGljID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwcm9qZWN0aW9uKG9ydGhvZ3JhcGhpY1JhdylcbiAgICAgIC5zY2FsZSgyNDkuNSlcbiAgICAgIC5jbGlwQW5nbGUoOTAgKyBlcHNpbG9uJDQpO1xufTtcblxuZnVuY3Rpb24gc3RlcmVvZ3JhcGhpY1Jhdyh4LCB5KSB7XG4gIHZhciBjeSA9IGNvcyQxKHkpLCBrID0gMSArIGNvcyQxKHgpICogY3k7XG4gIHJldHVybiBbY3kgKiBzaW4kMSh4KSAvIGssIHNpbiQxKHkpIC8ga107XG59XG5cbnN0ZXJlb2dyYXBoaWNSYXcuaW52ZXJ0ID0gYXppbXV0aGFsSW52ZXJ0KGZ1bmN0aW9uKHopIHtcbiAgcmV0dXJuIDIgKiBhdGFuKHopO1xufSk7XG5cbnZhciBzdGVyZW9ncmFwaGljID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwcm9qZWN0aW9uKHN0ZXJlb2dyYXBoaWNSYXcpXG4gICAgICAuc2NhbGUoMjUwKVxuICAgICAgLmNsaXBBbmdsZSgxNDIpO1xufTtcblxuZnVuY3Rpb24gdHJhbnN2ZXJzZU1lcmNhdG9yUmF3KGxhbWJkYSwgcGhpKSB7XG4gIHJldHVybiBbbG9nJDEodGFuKChoYWxmUGkkMyArIHBoaSkgLyAyKSksIC1sYW1iZGFdO1xufVxuXG50cmFuc3ZlcnNlTWVyY2F0b3JSYXcuaW52ZXJ0ID0gZnVuY3Rpb24oeCwgeSkge1xuICByZXR1cm4gWy15LCAyICogYXRhbihleHAoeCkpIC0gaGFsZlBpJDNdO1xufTtcblxudmFyIHRyYW5zdmVyc2VNZXJjYXRvciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbSA9IG1lcmNhdG9yUHJvamVjdGlvbih0cmFuc3ZlcnNlTWVyY2F0b3JSYXcpLFxuICAgICAgY2VudGVyID0gbS5jZW50ZXIsXG4gICAgICByb3RhdGUgPSBtLnJvdGF0ZTtcblxuICBtLmNlbnRlciA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IGNlbnRlcihbLV9bMV0sIF9bMF1dKSA6IChfID0gY2VudGVyKCksIFtfWzFdLCAtX1swXV0pO1xuICB9O1xuXG4gIG0ucm90YXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gcm90YXRlKFtfWzBdLCBfWzFdLCBfLmxlbmd0aCA+IDIgPyBfWzJdICsgOTAgOiA5MF0pIDogKF8gPSByb3RhdGUoKSwgW19bMF0sIF9bMV0sIF9bMl0gLSA5MF0pO1xuICB9O1xuXG4gIHJldHVybiByb3RhdGUoWzAsIDAsIDkwXSlcbiAgICAgIC5zY2FsZSgxNTkuMTU1KTtcbn07XG5cbmV4cG9ydHMudmVyc2lvbiA9IHZlcnNpb247XG5leHBvcnRzLmJpc2VjdCA9IGJpc2VjdFJpZ2h0O1xuZXhwb3J0cy5iaXNlY3RSaWdodCA9IGJpc2VjdFJpZ2h0O1xuZXhwb3J0cy5iaXNlY3RMZWZ0ID0gYmlzZWN0TGVmdDtcbmV4cG9ydHMuYXNjZW5kaW5nID0gYXNjZW5kaW5nO1xuZXhwb3J0cy5iaXNlY3RvciA9IGJpc2VjdG9yO1xuZXhwb3J0cy5kZXNjZW5kaW5nID0gZGVzY2VuZGluZztcbmV4cG9ydHMuZGV2aWF0aW9uID0gZGV2aWF0aW9uO1xuZXhwb3J0cy5leHRlbnQgPSBleHRlbnQ7XG5leHBvcnRzLmhpc3RvZ3JhbSA9IGhpc3RvZ3JhbTtcbmV4cG9ydHMudGhyZXNob2xkRnJlZWRtYW5EaWFjb25pcyA9IGZyZWVkbWFuRGlhY29uaXM7XG5leHBvcnRzLnRocmVzaG9sZFNjb3R0ID0gc2NvdHQ7XG5leHBvcnRzLnRocmVzaG9sZFN0dXJnZXMgPSBzdHVyZ2VzO1xuZXhwb3J0cy5tYXggPSBtYXg7XG5leHBvcnRzLm1lYW4gPSBtZWFuO1xuZXhwb3J0cy5tZWRpYW4gPSBtZWRpYW47XG5leHBvcnRzLm1lcmdlID0gbWVyZ2U7XG5leHBvcnRzLm1pbiA9IG1pbjtcbmV4cG9ydHMucGFpcnMgPSBwYWlycztcbmV4cG9ydHMucGVybXV0ZSA9IHBlcm11dGU7XG5leHBvcnRzLnF1YW50aWxlID0gdGhyZXNob2xkO1xuZXhwb3J0cy5yYW5nZSA9IHJhbmdlO1xuZXhwb3J0cy5zY2FuID0gc2NhbjtcbmV4cG9ydHMuc2h1ZmZsZSA9IHNodWZmbGU7XG5leHBvcnRzLnN1bSA9IHN1bTtcbmV4cG9ydHMudGlja3MgPSB0aWNrcztcbmV4cG9ydHMudGlja1N0ZXAgPSB0aWNrU3RlcDtcbmV4cG9ydHMudHJhbnNwb3NlID0gdHJhbnNwb3NlO1xuZXhwb3J0cy52YXJpYW5jZSA9IHZhcmlhbmNlO1xuZXhwb3J0cy56aXAgPSB6aXA7XG5leHBvcnRzLmVudHJpZXMgPSBlbnRyaWVzO1xuZXhwb3J0cy5rZXlzID0ga2V5cztcbmV4cG9ydHMudmFsdWVzID0gdmFsdWVzO1xuZXhwb3J0cy5tYXAgPSBtYXAkMTtcbmV4cG9ydHMuc2V0ID0gc2V0O1xuZXhwb3J0cy5uZXN0ID0gbmVzdDtcbmV4cG9ydHMucmFuZG9tVW5pZm9ybSA9IHVuaWZvcm07XG5leHBvcnRzLnJhbmRvbU5vcm1hbCA9IG5vcm1hbDtcbmV4cG9ydHMucmFuZG9tTG9nTm9ybWFsID0gbG9nTm9ybWFsO1xuZXhwb3J0cy5yYW5kb21CYXRlcyA9IGJhdGVzO1xuZXhwb3J0cy5yYW5kb21JcndpbkhhbGwgPSBpcndpbkhhbGw7XG5leHBvcnRzLnJhbmRvbUV4cG9uZW50aWFsID0gZXhwb25lbnRpYWw7XG5leHBvcnRzLmVhc2VMaW5lYXIgPSBsaW5lYXI7XG5leHBvcnRzLmVhc2VRdWFkID0gcXVhZEluT3V0O1xuZXhwb3J0cy5lYXNlUXVhZEluID0gcXVhZEluO1xuZXhwb3J0cy5lYXNlUXVhZE91dCA9IHF1YWRPdXQ7XG5leHBvcnRzLmVhc2VRdWFkSW5PdXQgPSBxdWFkSW5PdXQ7XG5leHBvcnRzLmVhc2VDdWJpYyA9IGN1YmljSW5PdXQ7XG5leHBvcnRzLmVhc2VDdWJpY0luID0gY3ViaWNJbjtcbmV4cG9ydHMuZWFzZUN1YmljT3V0ID0gY3ViaWNPdXQ7XG5leHBvcnRzLmVhc2VDdWJpY0luT3V0ID0gY3ViaWNJbk91dDtcbmV4cG9ydHMuZWFzZVBvbHkgPSBwb2x5SW5PdXQ7XG5leHBvcnRzLmVhc2VQb2x5SW4gPSBwb2x5SW47XG5leHBvcnRzLmVhc2VQb2x5T3V0ID0gcG9seU91dDtcbmV4cG9ydHMuZWFzZVBvbHlJbk91dCA9IHBvbHlJbk91dDtcbmV4cG9ydHMuZWFzZVNpbiA9IHNpbkluT3V0O1xuZXhwb3J0cy5lYXNlU2luSW4gPSBzaW5JbjtcbmV4cG9ydHMuZWFzZVNpbk91dCA9IHNpbk91dDtcbmV4cG9ydHMuZWFzZVNpbkluT3V0ID0gc2luSW5PdXQ7XG5leHBvcnRzLmVhc2VFeHAgPSBleHBJbk91dDtcbmV4cG9ydHMuZWFzZUV4cEluID0gZXhwSW47XG5leHBvcnRzLmVhc2VFeHBPdXQgPSBleHBPdXQ7XG5leHBvcnRzLmVhc2VFeHBJbk91dCA9IGV4cEluT3V0O1xuZXhwb3J0cy5lYXNlQ2lyY2xlID0gY2lyY2xlSW5PdXQ7XG5leHBvcnRzLmVhc2VDaXJjbGVJbiA9IGNpcmNsZUluO1xuZXhwb3J0cy5lYXNlQ2lyY2xlT3V0ID0gY2lyY2xlT3V0O1xuZXhwb3J0cy5lYXNlQ2lyY2xlSW5PdXQgPSBjaXJjbGVJbk91dDtcbmV4cG9ydHMuZWFzZUJvdW5jZSA9IGJvdW5jZU91dDtcbmV4cG9ydHMuZWFzZUJvdW5jZUluID0gYm91bmNlSW47XG5leHBvcnRzLmVhc2VCb3VuY2VPdXQgPSBib3VuY2VPdXQ7XG5leHBvcnRzLmVhc2VCb3VuY2VJbk91dCA9IGJvdW5jZUluT3V0O1xuZXhwb3J0cy5lYXNlQmFjayA9IGJhY2tJbk91dDtcbmV4cG9ydHMuZWFzZUJhY2tJbiA9IGJhY2tJbjtcbmV4cG9ydHMuZWFzZUJhY2tPdXQgPSBiYWNrT3V0O1xuZXhwb3J0cy5lYXNlQmFja0luT3V0ID0gYmFja0luT3V0O1xuZXhwb3J0cy5lYXNlRWxhc3RpYyA9IGVsYXN0aWNPdXQ7XG5leHBvcnRzLmVhc2VFbGFzdGljSW4gPSBlbGFzdGljSW47XG5leHBvcnRzLmVhc2VFbGFzdGljT3V0ID0gZWxhc3RpY091dDtcbmV4cG9ydHMuZWFzZUVsYXN0aWNJbk91dCA9IGVsYXN0aWNJbk91dDtcbmV4cG9ydHMucG9seWdvbkFyZWEgPSBhcmVhO1xuZXhwb3J0cy5wb2x5Z29uQ2VudHJvaWQgPSBjZW50cm9pZDtcbmV4cG9ydHMucG9seWdvbkh1bGwgPSBodWxsO1xuZXhwb3J0cy5wb2x5Z29uQ29udGFpbnMgPSBjb250YWlucztcbmV4cG9ydHMucG9seWdvbkxlbmd0aCA9IGxlbmd0aCQxO1xuZXhwb3J0cy5wYXRoID0gcGF0aDtcbmV4cG9ydHMucXVhZHRyZWUgPSBxdWFkdHJlZTtcbmV4cG9ydHMucXVldWUgPSBxdWV1ZTtcbmV4cG9ydHMuYXJjID0gYXJjO1xuZXhwb3J0cy5hcmVhID0gYXJlYSQxO1xuZXhwb3J0cy5saW5lID0gbGluZTtcbmV4cG9ydHMucGllID0gcGllO1xuZXhwb3J0cy5yYWRpYWxBcmVhID0gcmFkaWFsQXJlYTtcbmV4cG9ydHMucmFkaWFsTGluZSA9IHJhZGlhbExpbmUkMTtcbmV4cG9ydHMuc3ltYm9sID0gc3ltYm9sO1xuZXhwb3J0cy5zeW1ib2xzID0gc3ltYm9scztcbmV4cG9ydHMuc3ltYm9sQ2lyY2xlID0gY2lyY2xlO1xuZXhwb3J0cy5zeW1ib2xDcm9zcyA9IGNyb3NzJDE7XG5leHBvcnRzLnN5bWJvbERpYW1vbmQgPSBkaWFtb25kO1xuZXhwb3J0cy5zeW1ib2xTcXVhcmUgPSBzcXVhcmU7XG5leHBvcnRzLnN5bWJvbFN0YXIgPSBzdGFyO1xuZXhwb3J0cy5zeW1ib2xUcmlhbmdsZSA9IHRyaWFuZ2xlO1xuZXhwb3J0cy5zeW1ib2xXeWUgPSB3eWU7XG5leHBvcnRzLmN1cnZlQmFzaXNDbG9zZWQgPSBiYXNpc0Nsb3NlZDtcbmV4cG9ydHMuY3VydmVCYXNpc09wZW4gPSBiYXNpc09wZW47XG5leHBvcnRzLmN1cnZlQmFzaXMgPSBiYXNpcztcbmV4cG9ydHMuY3VydmVCdW5kbGUgPSBidW5kbGU7XG5leHBvcnRzLmN1cnZlQ2FyZGluYWxDbG9zZWQgPSBjYXJkaW5hbENsb3NlZDtcbmV4cG9ydHMuY3VydmVDYXJkaW5hbE9wZW4gPSBjYXJkaW5hbE9wZW47XG5leHBvcnRzLmN1cnZlQ2FyZGluYWwgPSBjYXJkaW5hbDtcbmV4cG9ydHMuY3VydmVDYXRtdWxsUm9tQ2xvc2VkID0gY2F0bXVsbFJvbUNsb3NlZDtcbmV4cG9ydHMuY3VydmVDYXRtdWxsUm9tT3BlbiA9IGNhdG11bGxSb21PcGVuO1xuZXhwb3J0cy5jdXJ2ZUNhdG11bGxSb20gPSBjYXRtdWxsUm9tO1xuZXhwb3J0cy5jdXJ2ZUxpbmVhckNsb3NlZCA9IGxpbmVhckNsb3NlZDtcbmV4cG9ydHMuY3VydmVMaW5lYXIgPSBjdXJ2ZUxpbmVhcjtcbmV4cG9ydHMuY3VydmVNb25vdG9uZVggPSBtb25vdG9uZVg7XG5leHBvcnRzLmN1cnZlTW9ub3RvbmVZID0gbW9ub3RvbmVZO1xuZXhwb3J0cy5jdXJ2ZU5hdHVyYWwgPSBuYXR1cmFsO1xuZXhwb3J0cy5jdXJ2ZVN0ZXAgPSBzdGVwO1xuZXhwb3J0cy5jdXJ2ZVN0ZXBBZnRlciA9IHN0ZXBBZnRlcjtcbmV4cG9ydHMuY3VydmVTdGVwQmVmb3JlID0gc3RlcEJlZm9yZTtcbmV4cG9ydHMuc3RhY2sgPSBzdGFjaztcbmV4cG9ydHMuc3RhY2tPZmZzZXRFeHBhbmQgPSBleHBhbmQ7XG5leHBvcnRzLnN0YWNrT2Zmc2V0Tm9uZSA9IG5vbmU7XG5leHBvcnRzLnN0YWNrT2Zmc2V0U2lsaG91ZXR0ZSA9IHNpbGhvdWV0dGU7XG5leHBvcnRzLnN0YWNrT2Zmc2V0V2lnZ2xlID0gd2lnZ2xlO1xuZXhwb3J0cy5zdGFja09yZGVyQXNjZW5kaW5nID0gYXNjZW5kaW5nJDE7XG5leHBvcnRzLnN0YWNrT3JkZXJEZXNjZW5kaW5nID0gZGVzY2VuZGluZyQyO1xuZXhwb3J0cy5zdGFja09yZGVySW5zaWRlT3V0ID0gaW5zaWRlT3V0O1xuZXhwb3J0cy5zdGFja09yZGVyTm9uZSA9IG5vbmUkMTtcbmV4cG9ydHMuc3RhY2tPcmRlclJldmVyc2UgPSByZXZlcnNlO1xuZXhwb3J0cy5jb2xvciA9IGNvbG9yO1xuZXhwb3J0cy5yZ2IgPSByZ2I7XG5leHBvcnRzLmhzbCA9IGhzbDtcbmV4cG9ydHMubGFiID0gbGFiO1xuZXhwb3J0cy5oY2wgPSBoY2w7XG5leHBvcnRzLmN1YmVoZWxpeCA9IGN1YmVoZWxpeDtcbmV4cG9ydHMuaW50ZXJwb2xhdGUgPSBpbnRlcnBvbGF0ZTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVBcnJheSA9IGFycmF5JDE7XG5leHBvcnRzLmludGVycG9sYXRlRGF0ZSA9IGRhdGU7XG5leHBvcnRzLmludGVycG9sYXRlTnVtYmVyID0gaW50ZXJwb2xhdGVOdW1iZXI7XG5leHBvcnRzLmludGVycG9sYXRlT2JqZWN0ID0gb2JqZWN0O1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJvdW5kID0gaW50ZXJwb2xhdGVSb3VuZDtcbmV4cG9ydHMuaW50ZXJwb2xhdGVTdHJpbmcgPSBpbnRlcnBvbGF0ZVN0cmluZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVUcmFuc2Zvcm1Dc3MgPSBpbnRlcnBvbGF0ZVRyYW5zZm9ybUNzcztcbmV4cG9ydHMuaW50ZXJwb2xhdGVUcmFuc2Zvcm1TdmcgPSBpbnRlcnBvbGF0ZVRyYW5zZm9ybVN2ZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVab29tID0gaW50ZXJwb2xhdGVab29tO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJnYiA9IGludGVycG9sYXRlUmdiO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJnYkJhc2lzID0gcmdiQmFzaXM7XG5leHBvcnRzLmludGVycG9sYXRlUmdiQmFzaXNDbG9zZWQgPSByZ2JCYXNpc0Nsb3NlZDtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIc2wgPSBoc2wkMjtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIc2xMb25nID0gaHNsTG9uZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVMYWIgPSBsYWIkMTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIY2wgPSBoY2wkMjtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIY2xMb25nID0gaGNsTG9uZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVDdWJlaGVsaXggPSBjdWJlaGVsaXgkMjtcbmV4cG9ydHMuaW50ZXJwb2xhdGVDdWJlaGVsaXhMb25nID0gY3ViZWhlbGl4TG9uZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVCYXNpcyA9IGJhc2lzJDI7XG5leHBvcnRzLmludGVycG9sYXRlQmFzaXNDbG9zZWQgPSBiYXNpc0Nsb3NlZCQxO1xuZXhwb3J0cy5xdWFudGl6ZSA9IHF1YW50aXplO1xuZXhwb3J0cy5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZXhwb3J0cy5kc3ZGb3JtYXQgPSBkc3Y7XG5leHBvcnRzLmNzdlBhcnNlID0gY3N2UGFyc2U7XG5leHBvcnRzLmNzdlBhcnNlUm93cyA9IGNzdlBhcnNlUm93cztcbmV4cG9ydHMuY3N2Rm9ybWF0ID0gY3N2Rm9ybWF0O1xuZXhwb3J0cy5jc3ZGb3JtYXRSb3dzID0gY3N2Rm9ybWF0Um93cztcbmV4cG9ydHMudHN2UGFyc2UgPSB0c3ZQYXJzZTtcbmV4cG9ydHMudHN2UGFyc2VSb3dzID0gdHN2UGFyc2VSb3dzO1xuZXhwb3J0cy50c3ZGb3JtYXQgPSB0c3ZGb3JtYXQ7XG5leHBvcnRzLnRzdkZvcm1hdFJvd3MgPSB0c3ZGb3JtYXRSb3dzO1xuZXhwb3J0cy5yZXF1ZXN0ID0gcmVxdWVzdDtcbmV4cG9ydHMuaHRtbCA9IGh0bWw7XG5leHBvcnRzLmpzb24gPSBqc29uO1xuZXhwb3J0cy50ZXh0ID0gdGV4dDtcbmV4cG9ydHMueG1sID0geG1sO1xuZXhwb3J0cy5jc3YgPSBjc3YkMTtcbmV4cG9ydHMudHN2ID0gdHN2JDE7XG5leHBvcnRzLm5vdyA9IG5vdztcbmV4cG9ydHMudGltZXIgPSB0aW1lcjtcbmV4cG9ydHMudGltZXJGbHVzaCA9IHRpbWVyRmx1c2g7XG5leHBvcnRzLnRpbWVvdXQgPSB0aW1lb3V0JDE7XG5leHBvcnRzLmludGVydmFsID0gaW50ZXJ2YWwkMTtcbmV4cG9ydHMudGltZUludGVydmFsID0gbmV3SW50ZXJ2YWw7XG5leHBvcnRzLnRpbWVNaWxsaXNlY29uZCA9IG1pbGxpc2Vjb25kO1xuZXhwb3J0cy50aW1lTWlsbGlzZWNvbmRzID0gbWlsbGlzZWNvbmRzO1xuZXhwb3J0cy50aW1lU2Vjb25kID0gc2Vjb25kO1xuZXhwb3J0cy50aW1lU2Vjb25kcyA9IHNlY29uZHM7XG5leHBvcnRzLnRpbWVNaW51dGUgPSBtaW51dGU7XG5leHBvcnRzLnRpbWVNaW51dGVzID0gbWludXRlcztcbmV4cG9ydHMudGltZUhvdXIgPSBob3VyO1xuZXhwb3J0cy50aW1lSG91cnMgPSBob3VycztcbmV4cG9ydHMudGltZURheSA9IGRheTtcbmV4cG9ydHMudGltZURheXMgPSBkYXlzO1xuZXhwb3J0cy50aW1lV2VlayA9IHN1bmRheTtcbmV4cG9ydHMudGltZVdlZWtzID0gc3VuZGF5cztcbmV4cG9ydHMudGltZVN1bmRheSA9IHN1bmRheTtcbmV4cG9ydHMudGltZVN1bmRheXMgPSBzdW5kYXlzO1xuZXhwb3J0cy50aW1lTW9uZGF5ID0gbW9uZGF5O1xuZXhwb3J0cy50aW1lTW9uZGF5cyA9IG1vbmRheXM7XG5leHBvcnRzLnRpbWVUdWVzZGF5ID0gdHVlc2RheTtcbmV4cG9ydHMudGltZVR1ZXNkYXlzID0gdHVlc2RheXM7XG5leHBvcnRzLnRpbWVXZWRuZXNkYXkgPSB3ZWRuZXNkYXk7XG5leHBvcnRzLnRpbWVXZWRuZXNkYXlzID0gd2VkbmVzZGF5cztcbmV4cG9ydHMudGltZVRodXJzZGF5ID0gdGh1cnNkYXk7XG5leHBvcnRzLnRpbWVUaHVyc2RheXMgPSB0aHVyc2RheXM7XG5leHBvcnRzLnRpbWVGcmlkYXkgPSBmcmlkYXk7XG5leHBvcnRzLnRpbWVGcmlkYXlzID0gZnJpZGF5cztcbmV4cG9ydHMudGltZVNhdHVyZGF5ID0gc2F0dXJkYXk7XG5leHBvcnRzLnRpbWVTYXR1cmRheXMgPSBzYXR1cmRheXM7XG5leHBvcnRzLnRpbWVNb250aCA9IG1vbnRoO1xuZXhwb3J0cy50aW1lTW9udGhzID0gbW9udGhzO1xuZXhwb3J0cy50aW1lWWVhciA9IHllYXI7XG5leHBvcnRzLnRpbWVZZWFycyA9IHllYXJzO1xuZXhwb3J0cy51dGNNaWxsaXNlY29uZCA9IG1pbGxpc2Vjb25kO1xuZXhwb3J0cy51dGNNaWxsaXNlY29uZHMgPSBtaWxsaXNlY29uZHM7XG5leHBvcnRzLnV0Y1NlY29uZCA9IHNlY29uZDtcbmV4cG9ydHMudXRjU2Vjb25kcyA9IHNlY29uZHM7XG5leHBvcnRzLnV0Y01pbnV0ZSA9IHV0Y01pbnV0ZTtcbmV4cG9ydHMudXRjTWludXRlcyA9IHV0Y01pbnV0ZXM7XG5leHBvcnRzLnV0Y0hvdXIgPSB1dGNIb3VyO1xuZXhwb3J0cy51dGNIb3VycyA9IHV0Y0hvdXJzO1xuZXhwb3J0cy51dGNEYXkgPSB1dGNEYXk7XG5leHBvcnRzLnV0Y0RheXMgPSB1dGNEYXlzO1xuZXhwb3J0cy51dGNXZWVrID0gdXRjU3VuZGF5O1xuZXhwb3J0cy51dGNXZWVrcyA9IHV0Y1N1bmRheXM7XG5leHBvcnRzLnV0Y1N1bmRheSA9IHV0Y1N1bmRheTtcbmV4cG9ydHMudXRjU3VuZGF5cyA9IHV0Y1N1bmRheXM7XG5leHBvcnRzLnV0Y01vbmRheSA9IHV0Y01vbmRheTtcbmV4cG9ydHMudXRjTW9uZGF5cyA9IHV0Y01vbmRheXM7XG5leHBvcnRzLnV0Y1R1ZXNkYXkgPSB1dGNUdWVzZGF5O1xuZXhwb3J0cy51dGNUdWVzZGF5cyA9IHV0Y1R1ZXNkYXlzO1xuZXhwb3J0cy51dGNXZWRuZXNkYXkgPSB1dGNXZWRuZXNkYXk7XG5leHBvcnRzLnV0Y1dlZG5lc2RheXMgPSB1dGNXZWRuZXNkYXlzO1xuZXhwb3J0cy51dGNUaHVyc2RheSA9IHV0Y1RodXJzZGF5O1xuZXhwb3J0cy51dGNUaHVyc2RheXMgPSB1dGNUaHVyc2RheXM7XG5leHBvcnRzLnV0Y0ZyaWRheSA9IHV0Y0ZyaWRheTtcbmV4cG9ydHMudXRjRnJpZGF5cyA9IHV0Y0ZyaWRheXM7XG5leHBvcnRzLnV0Y1NhdHVyZGF5ID0gdXRjU2F0dXJkYXk7XG5leHBvcnRzLnV0Y1NhdHVyZGF5cyA9IHV0Y1NhdHVyZGF5cztcbmV4cG9ydHMudXRjTW9udGggPSB1dGNNb250aDtcbmV4cG9ydHMudXRjTW9udGhzID0gdXRjTW9udGhzO1xuZXhwb3J0cy51dGNZZWFyID0gdXRjWWVhcjtcbmV4cG9ydHMudXRjWWVhcnMgPSB1dGNZZWFycztcbmV4cG9ydHMuZm9ybWF0TG9jYWxlID0gZm9ybWF0TG9jYWxlO1xuZXhwb3J0cy5mb3JtYXREZWZhdWx0TG9jYWxlID0gZGVmYXVsdExvY2FsZTtcbmV4cG9ydHMuZm9ybWF0U3BlY2lmaWVyID0gZm9ybWF0U3BlY2lmaWVyO1xuZXhwb3J0cy5wcmVjaXNpb25GaXhlZCA9IHByZWNpc2lvbkZpeGVkO1xuZXhwb3J0cy5wcmVjaXNpb25QcmVmaXggPSBwcmVjaXNpb25QcmVmaXg7XG5leHBvcnRzLnByZWNpc2lvblJvdW5kID0gcHJlY2lzaW9uUm91bmQ7XG5leHBvcnRzLmlzb0Zvcm1hdCA9IGZvcm1hdElzbztcbmV4cG9ydHMuaXNvUGFyc2UgPSBwYXJzZUlzbztcbmV4cG9ydHMudGltZUZvcm1hdExvY2FsZSA9IGZvcm1hdExvY2FsZSQxO1xuZXhwb3J0cy50aW1lRm9ybWF0RGVmYXVsdExvY2FsZSA9IGRlZmF1bHRMb2NhbGUkMTtcbmV4cG9ydHMuc2NhbGVCYW5kID0gYmFuZDtcbmV4cG9ydHMuc2NhbGVQb2ludCA9IHBvaW50JDQ7XG5leHBvcnRzLnNjYWxlSWRlbnRpdHkgPSBpZGVudGl0eSQ0O1xuZXhwb3J0cy5zY2FsZUxpbmVhciA9IGxpbmVhciQyO1xuZXhwb3J0cy5zY2FsZUxvZyA9IGxvZztcbmV4cG9ydHMuc2NhbGVPcmRpbmFsID0gb3JkaW5hbDtcbmV4cG9ydHMuc2NhbGVJbXBsaWNpdCA9IGltcGxpY2l0O1xuZXhwb3J0cy5zY2FsZVBvdyA9IHBvdztcbmV4cG9ydHMuc2NhbGVTcXJ0ID0gc3FydDtcbmV4cG9ydHMuc2NhbGVRdWFudGlsZSA9IHF1YW50aWxlJCQxO1xuZXhwb3J0cy5zY2FsZVF1YW50aXplID0gcXVhbnRpemUkMTtcbmV4cG9ydHMuc2NhbGVUaHJlc2hvbGQgPSB0aHJlc2hvbGQkMTtcbmV4cG9ydHMuc2NhbGVUaW1lID0gdGltZTtcbmV4cG9ydHMuc2NhbGVVdGMgPSB1dGNUaW1lO1xuZXhwb3J0cy5zY2hlbWVDYXRlZ29yeTEwID0gY2F0ZWdvcnkxMDtcbmV4cG9ydHMuc2NoZW1lQ2F0ZWdvcnkyMGIgPSBjYXRlZ29yeTIwYjtcbmV4cG9ydHMuc2NoZW1lQ2F0ZWdvcnkyMGMgPSBjYXRlZ29yeTIwYztcbmV4cG9ydHMuc2NoZW1lQ2F0ZWdvcnkyMCA9IGNhdGVnb3J5MjA7XG5leHBvcnRzLnNjYWxlU2VxdWVudGlhbCA9IHNlcXVlbnRpYWw7XG5leHBvcnRzLmludGVycG9sYXRlQ3ViZWhlbGl4RGVmYXVsdCA9IGN1YmVoZWxpeCQzO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJhaW5ib3cgPSByYWluYm93JDE7XG5leHBvcnRzLmludGVycG9sYXRlV2FybSA9IHdhcm07XG5leHBvcnRzLmludGVycG9sYXRlQ29vbCA9IGNvb2w7XG5leHBvcnRzLmludGVycG9sYXRlVmlyaWRpcyA9IHZpcmlkaXM7XG5leHBvcnRzLmludGVycG9sYXRlTWFnbWEgPSBtYWdtYTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVJbmZlcm5vID0gaW5mZXJubztcbmV4cG9ydHMuaW50ZXJwb2xhdGVQbGFzbWEgPSBwbGFzbWE7XG5leHBvcnRzLmNyZWF0b3IgPSBjcmVhdG9yO1xuZXhwb3J0cy5jdXN0b21FdmVudCA9IGN1c3RvbUV2ZW50O1xuZXhwb3J0cy5sb2NhbCA9IGxvY2FsO1xuZXhwb3J0cy5tYXRjaGVyID0gbWF0Y2hlciQxO1xuZXhwb3J0cy5tb3VzZSA9IG1vdXNlO1xuZXhwb3J0cy5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7XG5leHBvcnRzLm5hbWVzcGFjZXMgPSBuYW1lc3BhY2VzO1xuZXhwb3J0cy5zZWxlY3QgPSBzZWxlY3Q7XG5leHBvcnRzLnNlbGVjdEFsbCA9IHNlbGVjdEFsbDtcbmV4cG9ydHMuc2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuZXhwb3J0cy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuZXhwb3J0cy5zZWxlY3RvckFsbCA9IHNlbGVjdG9yQWxsO1xuZXhwb3J0cy50b3VjaCA9IHRvdWNoO1xuZXhwb3J0cy50b3VjaGVzID0gdG91Y2hlcztcbmV4cG9ydHMud2luZG93ID0gd2luZG93O1xuZXhwb3J0cy5hY3RpdmUgPSBhY3RpdmU7XG5leHBvcnRzLmludGVycnVwdCA9IGludGVycnVwdDtcbmV4cG9ydHMudHJhbnNpdGlvbiA9IHRyYW5zaXRpb247XG5leHBvcnRzLmF4aXNUb3AgPSBheGlzVG9wO1xuZXhwb3J0cy5heGlzUmlnaHQgPSBheGlzUmlnaHQ7XG5leHBvcnRzLmF4aXNCb3R0b20gPSBheGlzQm90dG9tO1xuZXhwb3J0cy5heGlzTGVmdCA9IGF4aXNMZWZ0O1xuZXhwb3J0cy5jbHVzdGVyID0gY2x1c3RlcjtcbmV4cG9ydHMuaGllcmFyY2h5ID0gaGllcmFyY2h5O1xuZXhwb3J0cy5wYWNrID0gaW5kZXg7XG5leHBvcnRzLnBhY2tTaWJsaW5ncyA9IHNpYmxpbmdzO1xuZXhwb3J0cy5wYWNrRW5jbG9zZSA9IGVuY2xvc2U7XG5leHBvcnRzLnBhcnRpdGlvbiA9IHBhcnRpdGlvbjtcbmV4cG9ydHMuc3RyYXRpZnkgPSBzdHJhdGlmeTtcbmV4cG9ydHMudHJlZSA9IHRyZWU7XG5leHBvcnRzLnRyZWVtYXAgPSBpbmRleCQxO1xuZXhwb3J0cy50cmVlbWFwQmluYXJ5ID0gYmluYXJ5O1xuZXhwb3J0cy50cmVlbWFwRGljZSA9IHRyZWVtYXBEaWNlO1xuZXhwb3J0cy50cmVlbWFwU2xpY2UgPSB0cmVlbWFwU2xpY2U7XG5leHBvcnRzLnRyZWVtYXBTbGljZURpY2UgPSBzbGljZURpY2U7XG5leHBvcnRzLnRyZWVtYXBTcXVhcmlmeSA9IHNxdWFyaWZ5O1xuZXhwb3J0cy50cmVlbWFwUmVzcXVhcmlmeSA9IHJlc3F1YXJpZnk7XG5leHBvcnRzLmZvcmNlQ2VudGVyID0gY2VudGVyJDE7XG5leHBvcnRzLmZvcmNlQ29sbGlkZSA9IGNvbGxpZGU7XG5leHBvcnRzLmZvcmNlTGluayA9IGxpbms7XG5leHBvcnRzLmZvcmNlTWFueUJvZHkgPSBtYW55Qm9keTtcbmV4cG9ydHMuZm9yY2VTaW11bGF0aW9uID0gc2ltdWxhdGlvbjtcbmV4cG9ydHMuZm9yY2VYID0geCQzO1xuZXhwb3J0cy5mb3JjZVkgPSB5JDM7XG5leHBvcnRzLmRyYWcgPSBkcmFnO1xuZXhwb3J0cy5kcmFnRGlzYWJsZSA9IGRyYWdEaXNhYmxlO1xuZXhwb3J0cy5kcmFnRW5hYmxlID0geWVzZHJhZztcbmV4cG9ydHMudm9yb25vaSA9IHZvcm9ub2k7XG5leHBvcnRzLnpvb20gPSB6b29tO1xuZXhwb3J0cy56b29tSWRlbnRpdHkgPSBpZGVudGl0eSQ2O1xuZXhwb3J0cy56b29tVHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuZXhwb3J0cy5icnVzaCA9IGJydXNoO1xuZXhwb3J0cy5icnVzaFggPSBicnVzaFg7XG5leHBvcnRzLmJydXNoWSA9IGJydXNoWTtcbmV4cG9ydHMuYnJ1c2hTZWxlY3Rpb24gPSBicnVzaFNlbGVjdGlvbjtcbmV4cG9ydHMuY2hvcmQgPSBjaG9yZDtcbmV4cG9ydHMucmliYm9uID0gcmliYm9uO1xuZXhwb3J0cy5nZW9BbGJlcnMgPSBhbGJlcnM7XG5leHBvcnRzLmdlb0FsYmVyc1VzYSA9IGFsYmVyc1VzYTtcbmV4cG9ydHMuZ2VvQXJlYSA9IGFyZWEkMjtcbmV4cG9ydHMuZ2VvQXppbXV0aGFsRXF1YWxBcmVhID0gYXppbXV0aGFsRXF1YWxBcmVhO1xuZXhwb3J0cy5nZW9BemltdXRoYWxFcXVhbEFyZWFSYXcgPSBhemltdXRoYWxFcXVhbEFyZWFSYXc7XG5leHBvcnRzLmdlb0F6aW11dGhhbEVxdWlkaXN0YW50ID0gYXppbXV0aGFsRXF1aWRpc3RhbnQ7XG5leHBvcnRzLmdlb0F6aW11dGhhbEVxdWlkaXN0YW50UmF3ID0gYXppbXV0aGFsRXF1aWRpc3RhbnRSYXc7XG5leHBvcnRzLmdlb0JvdW5kcyA9IGJvdW5kcztcbmV4cG9ydHMuZ2VvQ2VudHJvaWQgPSBjZW50cm9pZCQxO1xuZXhwb3J0cy5nZW9DaXJjbGUgPSBjaXJjbGUkMTtcbmV4cG9ydHMuZ2VvQ2xpcEV4dGVudCA9IGV4dGVudCQxO1xuZXhwb3J0cy5nZW9Db25pY0NvbmZvcm1hbCA9IGNvbmljQ29uZm9ybWFsO1xuZXhwb3J0cy5nZW9Db25pY0NvbmZvcm1hbFJhdyA9IGNvbmljQ29uZm9ybWFsUmF3O1xuZXhwb3J0cy5nZW9Db25pY0VxdWFsQXJlYSA9IGNvbmljRXF1YWxBcmVhO1xuZXhwb3J0cy5nZW9Db25pY0VxdWFsQXJlYVJhdyA9IGNvbmljRXF1YWxBcmVhUmF3O1xuZXhwb3J0cy5nZW9Db25pY0VxdWlkaXN0YW50ID0gY29uaWNFcXVpZGlzdGFudDtcbmV4cG9ydHMuZ2VvQ29uaWNFcXVpZGlzdGFudFJhdyA9IGNvbmljRXF1aWRpc3RhbnRSYXc7XG5leHBvcnRzLmdlb0Rpc3RhbmNlID0gZGlzdGFuY2U7XG5leHBvcnRzLmdlb0VxdWlyZWN0YW5ndWxhciA9IGVxdWlyZWN0YW5ndWxhcjtcbmV4cG9ydHMuZ2VvRXF1aXJlY3Rhbmd1bGFyUmF3ID0gZXF1aXJlY3Rhbmd1bGFyUmF3O1xuZXhwb3J0cy5nZW9Hbm9tb25pYyA9IGdub21vbmljO1xuZXhwb3J0cy5nZW9Hbm9tb25pY1JhdyA9IGdub21vbmljUmF3O1xuZXhwb3J0cy5nZW9HcmF0aWN1bGUgPSBncmF0aWN1bGU7XG5leHBvcnRzLmdlb0dyYXRpY3VsZTEwID0gZ3JhdGljdWxlMTA7XG5leHBvcnRzLmdlb0lkZW50aXR5ID0gaWRlbnRpdHkkODtcbmV4cG9ydHMuZ2VvSW50ZXJwb2xhdGUgPSBpbnRlcnBvbGF0ZSQyO1xuZXhwb3J0cy5nZW9MZW5ndGggPSBsZW5ndGgkMjtcbmV4cG9ydHMuZ2VvTWVyY2F0b3IgPSBtZXJjYXRvcjtcbmV4cG9ydHMuZ2VvTWVyY2F0b3JSYXcgPSBtZXJjYXRvclJhdztcbmV4cG9ydHMuZ2VvT3J0aG9ncmFwaGljID0gb3J0aG9ncmFwaGljO1xuZXhwb3J0cy5nZW9PcnRob2dyYXBoaWNSYXcgPSBvcnRob2dyYXBoaWNSYXc7XG5leHBvcnRzLmdlb1BhdGggPSBpbmRleCQzO1xuZXhwb3J0cy5nZW9Qcm9qZWN0aW9uID0gcHJvamVjdGlvbjtcbmV4cG9ydHMuZ2VvUHJvamVjdGlvbk11dGF0b3IgPSBwcm9qZWN0aW9uTXV0YXRvcjtcbmV4cG9ydHMuZ2VvUm90YXRpb24gPSByb3RhdGlvbjtcbmV4cG9ydHMuZ2VvU3RlcmVvZ3JhcGhpYyA9IHN0ZXJlb2dyYXBoaWM7XG5leHBvcnRzLmdlb1N0ZXJlb2dyYXBoaWNSYXcgPSBzdGVyZW9ncmFwaGljUmF3O1xuZXhwb3J0cy5nZW9TdHJlYW0gPSBnZW9TdHJlYW07XG5leHBvcnRzLmdlb1RyYW5zZm9ybSA9IHRyYW5zZm9ybSQxO1xuZXhwb3J0cy5nZW9UcmFuc3ZlcnNlTWVyY2F0b3IgPSB0cmFuc3ZlcnNlTWVyY2F0b3I7XG5leHBvcnRzLmdlb1RyYW5zdmVyc2VNZXJjYXRvclJhdyA9IHRyYW5zdmVyc2VNZXJjYXRvclJhdztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcblxufSkpKTtcbiIsIi8vIENvcHlyaWdodCDCqSAyMDE2IFJURSBSw6lzZWF1IGRlIHRyYW5zcG9ydCBk4oCZw6lsZWN0cmljaXTDqVxyXG4oZnVuY3Rpb24oKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICB2YXIgZDMgPSByZXF1aXJlKFwiZDNcIik7XHJcbiAgdmFyIENoYXJ0ID0gcmVxdWlyZShcIi4vY2hhcnQuanNcIik7XHJcblxyXG4gIG1vZHVsZS5leHBvcnRzID0gQmFyY2hhcnQ7XHJcblxyXG4gIC8vIEJhcmNoYXJ0IGluaGVyaXRzIGZyb20gQ2hhcnRcclxuICBCYXJjaGFydC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKENoYXJ0LnByb3RvdHlwZSk7XHJcbiAgQmFyY2hhcnQucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQmFyY2hhcnQ7XHJcblxyXG4gIC8qKlxyXG4gICAgKiBAY2xhc3MgQmFyY2hhcnRcclxuICAgICogQHN1bW1hcnkgUmVwcmVzZW50IGRhdGEgd2l0aCBhIGJhcmNoYXJ0XHJcbiAgICAqIEBkZXNjIEJhcmNoYXJ0cyBhcmUgcG9seXZhbGVudCBjaGFydHMgdGhhdCBzaG91bGQgYmUgdXNlZCBtb3N0IG9mIHRoZSB0aW1lLlxyXG4gICAgKiBJbiBhIGJhcmNoYXJ0IGluZGl2aWR1YWwgdmFsdWUgYXJlIHZpc3VhbGx5IGVhc3kgdG8gY29tcGFyZSBiZWNhdXNlIHRoZVxyXG4gICAgKiBodW1hbiBleWUgaXMgZ29vZCBhdCBjb21wYXJpbmcgbGVuZ3Rocy4gTW9yZW92ZXIgYmFyY2hhcnRzIGNhbiByZXByZXNlbnRcclxuICAgICogbmVnYXRpdmUgdmFsdWVzIHdoaWxlIHBvbGFyIGNoYXJ0cyBjYW4gb25seSByZXByZXNlbnQgcG9zaXRpdmUgdmFsdWVzOyBcclxuICAgICogQHBhcmFtIHtzdHJpbmd9IGVsIENTUyBzZWxlY3RvciByZXByZXNlbnRpbmcgdGhlIGVsZW1lbnQgdGhhdCB3aWxsIGhvbGQgdGhlIGNoYXJ0LlxyXG4gICAgKiBAcGFyYW0ge251bWJlcltdfSBkYXRhIERhdGEgdGhlIGNoYXJ0IGhhcyB0byByZXByZXNlbnQuXHJcbiAgICAqIEBwYXJhbSB7QmFyY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQHR5cGVkZWYge29iamVjdH0gQmFyY2hhcnRPcHRpb25zXHJcbiAgICAqIEBtZW1iZXJPZiBCYXJjaGFydFxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfFwiYXV0b1wifSBbbWluVmFsdWU9XCJhdXRvXCJdIE1pbmltdW0gdmFsdWUgZGF0YSBjb3VsZCB0YWtlLiBJdFxyXG4gICAgKiBpcyBpbXBvcnRhbnQgdG8gc2V0IHRoaXMgb3B0aW9uIGV4cGxpY2l0ZWx5IGlmIG9uZSB3YW50cyB0byBjb21wYXJlXHJcbiAgICAqIGNoYXJ0cyBhbmQgdXNlIHRoZSBzYW1lIHNjYWxlIG9uIGVhY2ggb25lLiBCeSBkZWZhdWx0IGBtaW5WYWx1ZWAgZXF1YWxzIHRvIDBcclxuICAgICogaWYgYWxsIGRhdGEgdmFsdWVzIGFyZSBwb3NpdGl2ZSBvciB0aGUgbWluaW11bSB2YWx1ZSBpZiBzb21lIHZhbHVlcyBhcmVcclxuICAgICogbmVnYXRpdmUuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ8XCJhdXRvXCJ9IFttYXhWYWx1ZT1cImF1dG9cIl0gTWF4aW11bSB2YWx1ZSBkYXRhIGNvdWxkIHRha2UuSXRcclxuICAgICogaXMgaW1wb3J0YW50IHRvIHNldCB0aGlzIG9wdGlvbiBleHBsaWNpdGVseSBpZiBvbmUgd2FudHMgdG8gY29tcGFyZVxyXG4gICAgKiBjaGFydHMgYW5kIHVzZSB0aGUgc2FtZSBzY2FsZSBvbiBlYWNoIG9uZS4gQnkgZGVmYXVsdCBpdCBlcXVhbHMgdG8gMCBpZiBhbGxcclxuICAgICogdmFsdWVzIGFyZSBuZWdhdGl2ZSBvciB0byBtYXhpbW11bSB2YWx1ZSBpZiBzb21lIHZhbHVlIGlzIHBvc2l0aXZlLlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbd2lkdGg9NjBdIFdpZHRoIG9mIHRoZSBjaGFydC5cclxuICAgICogQHByb3Age251bWJlcn0gW2hlaWdodD02MF0gSGVpZ2h0IG9mIHRoZSBjaGFydC5cclxuICAgICogQHByb3Age251bWJlcn0gW3RyYW5zaXRpb25UaW1lPTc1MF0gRHVyYXRpb24gb2YgdGhlIHRyYW5zaXRpb25zLCBpbiBtaWxsaXNlY29uZHMuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmdbXXxmdW5jdGlvbn1bY29sb3JzPWQzLnNjaGVtZUNhdGVnb3J5MTBdIEVpdGhlciBhbiBhcnJheSBvZlxyXG4gICAgKiBjb2xvcnMgb3IgYSBmdW5jdGlvbiBgKGQsIGkpIC0+IGNvbG9yYCB3aGVyZSBgZGAgaXMgYSBkYXRhIHZhbHVlIGFuZCBgaWBcclxuICAgICogaXMgdGhlIGluZGV4IG9mIHRoZSB2YWx1ZS5JZiBpdCBpcyBhbiBhcnJheSB3aXRoIGxlbmd0aCBsZXNzIHRoYW4gdGhlIGxlbmd0aFxyXG4gICAgKiBvZiBkYXRhLCB0aGVuIHRoZSBjb2xvcnMgYXJlIHJlY3ljbGVkLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nW118XCJub25lXCJ8XCJhdXRvXCJ8ZnVuY3Rpb259W2xhYmVscz1cIm5vbmVcIl0gTGFiZWxzIHRvIGRpc3BsYXkgaW4gYmFycy5cclxuICAgICogSXQgY2FuIGJlIGFuIGFycmF5IHdpdGggc2FtZSBsZW5ndGggYXMgdGhlIGRhdGEuIEl0IGNhbiBhbHNvIGJlIGEgZnVuY3Rpb25cclxuICAgICogYChkLCBpKSAtPiBsYWJlbFRleHRgIHdoZXJlIGBkYCBpcyBhIGRhdGEgdmFsdWUgYW5kIGBpYFxyXG4gICAgKiBpcyB0aGUgaW5kZXggb2YgdGhlIHZhbHVlLiBGaW5hbGx5IGl0IGNhbiBiZSBlcXVhbCB0byBcIm5vbmVcIiB0byBoaWRlIGxhYmVsc1xyXG4gICAgKiBvciBcImF1dG9cIiB0byBkaXNwbGF5IGluIGEgY29tcGFjdCB3YXkgdmFsdWVzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfHN0cmluZ1tdfFwiYXV0b1wifGZ1bmN0aW9ufVtsYWJlbENvbG9ycz1cImF1dG9cIl0gQ29sb3Igb2YgdGhlIGxhYmVscy5cclxuICAgICogSXQgY2FuIGJlIGEgc2luZ2xlIHZhbHVlIG9yIGFuIGFycmF5IHdpdGggc2FtZSBsZW5ndGggYXMgdGhlIGRhdGEuIEl0IGNhblxyXG4gICAgKiBhbHNvIGJlIGEgZnVuY3Rpb24gYChkLCBpKSAtPiBjb2xvcmAgd2hlcmUgYGRgIGlzIGEgZGF0YSB2YWx1ZSBhbmQgYGlgXHJcbiAgICAqIGlzIHRoZSBpbmRleCBvZiB0aGUgdmFsdWUuIEZpbmFsbHkgaXQgY2FuIGJlIGVxdWFsIHRvIFwiYXV0b1wiLiBJbiB0aGlzIGNhc2UsXHJcbiAgICAqIHRoZSBtb3N0IHJlYWRhYmxlIGNvbG9yIGlzIGNob29zZW4gZGVwZGluZyBvbiB0aGUgY29sb3Igb2YgdGhlIGJhci5cclxuICAgICogQHByb3Age251bWJlcn1bbGFiZWxNaW5TaXplPThdIExhYmVsIG1pbmltdW0gc2l6ZSBpbiBwaXhlbHMuIElmIHRoZXJlIGlzXHJcbiAgICAqIG5vdCBlbm91Z2ggc3BhY2UgZm9yIGEgZ2l2ZW4gbGFiZWwsIHRoZW4gaXQgaXMgaGlkZGVuLlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfVtsYWJlbE1heFNpemU9MjRdIExhYmVsIG1heGltdW0gc2l6ZSBpbiBwaXhlbHMuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9W2xhYmVsUGFkZGluZz0yXSBQYWRkaW5nIHRvIGFwcGx5IHRvIGFwcGx5IHRvIGxhYmVscy5cclxuICAgICogQHByb3Age3N0cmluZ31bbGFiZWxDbGFzcz1cIlwiXSBMYWJlbHMgQ1NTIGNsYXNzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfVtzaGFwZUNsYXNzPVwiXCJdIGJhcnMgQ1NTIGNsYXNzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfVt6ZXJvTGluZVN0eWxlPVwic3Ryb2tlOiMzMzM7c3Ryb2tlLXdpZHRoOjE7XCJdIENTUyBzdHlsZSBvZiB0aGVcclxuICAgICogbGluZSByZXByZXNlbnRpbmcgdGhlIHplcm8gdmFsdWUuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQG1ldGhvZCBzZXREYXRhXHJcbiAgICAqIEBkZXNjIFVwZGF0ZSB0aGUgZGF0YSByZXByZXNlbnRlZCBieSB0aGUgY2hhcnRcclxuICAgICogQGluc3RhbmNlXHJcbiAgICAqIEBtZW1iZXJPZiBCYXJjaGFydFxyXG4gICAgKiBAcGFyYW0ge251bWJlcltdfSBkYXRhIERhdGEgdGhlIGNoYXJ0IGhhcyB0byByZXByZXNlbnQuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQG1ldGhvZCBzZXRPcHRpb25zXHJcbiAgICAqIEBkZXNjIFVwZGF0ZSB0aGUgZ3JhcGhpY2FsIG9wdGlvbnMgb2YgYSBjaGFydFxyXG4gICAgKiBAaW5zdGFuY2VcclxuICAgICogQG1lbWJlck9mIEJhcmNoYXJ0XHJcbiAgICAqIEBwYXJhbSB7QmFyY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQG1ldGhvZCB1cGRhdGVcclxuICAgICogQGRlc2MgVXBkYXRlIHNpbXVsYXRlbm91c2x5IGRhdGEgYW5kIG9wdGlvbnMgb2YgYSBiYXJjaGFydC5cclxuICAgICogQGluc3RhbmNlXHJcbiAgICAqIEBtZW1iZXJPZiBCYXJjaGFydFxyXG4gICAgKiBAcGFyYW0ge251bWJlcltdfSBkYXRhIERhdGEgdGhlIGNoYXJ0IGhhcyB0byByZXByZXNlbnQuXHJcbiAgICAqIEBwYXJhbSB7QmFyY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG4gIGZ1bmN0aW9uIEJhcmNoYXJ0KGVsLCBkYXRhLCBvcHRpb25zKSB7XHJcbiAgICAvLyBEZWZhdWx0IG9wdGlvbnNcclxuICAgIHZhciBkZWZhdWx0cyA9IHtcclxuICAgICAgbWluVmFsdWU6IFwiYXV0b1wiLFxyXG4gICAgICBtYXhWYWx1ZTogXCJhdXRvXCIsXHJcbiAgICAgIHplcm9MaW5lU3R5bGU6IFwic3Ryb2tlOiMzMzM7c3Ryb2tlLXdpZHRoOjE7XCJcclxuICAgIH07XHJcblxyXG4gICAgLy8gQ2FsbCBzdXBlciBjb25zdHJ1Y3RvclxyXG4gICAgQ2hhcnQuY2FsbCh0aGlzLCBlbCwgZGF0YSwgb3B0aW9ucywgZGVmYXVsdHMpO1xyXG5cclxuICAgIC8vIEluaXRpYWxpemUgdGhlIHplcm8gbGluZVxyXG4gICAgdmFyIHNjYWxlRnVuID0gZDMuc2NhbGVMaW5lYXIoKVxyXG4gICAgICAuZG9tYWluKFt0aGlzLl9vcHRpb25zLm1pblZhbHVlLCB0aGlzLl9vcHRpb25zLm1heFZhbHVlXSlcclxuICAgICAgLnJhbmdlKFt0aGlzLl9vcHRpb25zLmhlaWdodCwgMF0pO1xyXG5cclxuICAgIHRoaXMuX3plcm9MaW5lID0gdGhpcy5fY29udGFpbmVyLmFwcGVuZChcImxpbmVcIilcclxuICAgICAgLmF0dHIoXCJ4MVwiLCAwKVxyXG4gICAgICAuYXR0cihcInkxXCIsIHNjYWxlRnVuKDApKVxyXG4gICAgICAuYXR0cihcIngyXCIsIHRoaXMuX29wdGlvbnMud2lkdGgpXHJcbiAgICAgIC5hdHRyKFwieTJcIiwgc2NhbGVGdW4oMCkpXHJcbiAgICAgIC5hdHRyKFwic3R5bGVcIiwgdGhpcy5fb3B0aW9ucy56ZXJvTGluZVN0eWxlKTtcclxuXHJcbiAgICB0aGlzLl9kcmF3KCk7XHJcbiAgfVxyXG5cclxuICAvLyBTZWUgY29tbWVudHMgaW4gY2hhcnQuanNcclxuICBCYXJjaGFydC5wcm90b3R5cGUuX3Byb2Nlc3NPcHRpb25zID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG4gICAgb3B0aW9ucyA9IENoYXJ0LnByb3RvdHlwZS5fcHJvY2Vzc09wdGlvbnMuY2FsbCh0aGlzLCBvcHRpb25zLCB0aGlzLl9vcHRpb25zKTtcclxuXHJcbiAgICAvLyBTZXQgbWluIHZhbHVlIGFuZCBtYXggdmFsdWUgaWYgbmVjZXNzYXJ5LlxyXG4gICAgaWYgKG9wdGlvbnMubWluVmFsdWUgPT09IFwiYXV0b1wiKSB7XHJcbiAgICAgIHZhciBtaW4gPSBkMy5taW4odGhpcy5fZGF0YSk7XHJcbiAgICAgIHZhciBtYXggPSBvcHRpb25zLm1heFZhbHVlID09PSBcImF1dG9cIj8gZDMubWF4KHRoaXMuX2RhdGEpOiBvcHRpb25zLm1heFZhbHVlO1xyXG5cclxuICAgICAgaWYgKG1heCA+IDAgJiYgbWluID4gMCkgb3B0aW9ucy5taW5WYWx1ZSA9IDA7XHJcbiAgICAgIGVsc2Ugb3B0aW9ucy5taW5WYWx1ZSA9IG1pbjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAob3B0aW9ucy5tYXhWYWx1ZSA9PT0gXCJhdXRvXCIpIHtcclxuICAgICAgdmFyIG1heCA9IG9wdGlvbnMubWluVmFsdWUgPT09IFwiYXV0b1wiPyBkMy5taW4odGhpcy5fZGF0YSk6IG9wdGlvbnMubWluVmFsdWU7XHJcbiAgICAgIHZhciBtYXggPSBkMy5tYXgodGhpcy5fZGF0YSk7XHJcblxyXG4gICAgICBpZiAobWF4IDwgMCAmJiBtaW4gPCAwKSBvcHRpb25zLm1heFZhbHVlID0gMDtcclxuICAgICAgZWxzZSBvcHRpb25zLm1heFZhbHVlID0gbWF4O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBvcHRpb25zO1xyXG4gIH07XHJcblxyXG4gIC8vIFNlZSBjb21tZW50cyBpbiBjaGFydC5qc1xyXG4gIEJhcmNoYXJ0LnByb3RvdHlwZS5fZHJhdyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgQ2hhcnQucHJvdG90eXBlLl9kcmF3LmNhbGwodGhpcyk7XHJcblxyXG4gICAgdmFyIGJhcldpZHRoID0gKHNlbGYuX29wdGlvbnMud2lkdGggLSA2KSAvIHNlbGYuX2RhdGEubGVuZ3RoO1xyXG4gICAgdmFyIHNjYWxlRnVuID0gZDMuc2NhbGVMaW5lYXIoKVxyXG4gICAgICAuZG9tYWluKFtzZWxmLl9vcHRpb25zLm1pblZhbHVlLCBzZWxmLl9vcHRpb25zLm1heFZhbHVlXSlcclxuICAgICAgLnJhbmdlKFtzZWxmLl9vcHRpb25zLmhlaWdodCwgMF0pO1xyXG5cclxuICAgIC8vIFVwZGF0ZSB0aGUgemVybyBsaW5lXHJcbiAgICBzZWxmLl96ZXJvTGluZVxyXG4gICAgICAudHJhbnNpdGlvbigpXHJcbiAgICAgIC5kdXJhdGlvbihzZWxmLl9vcHRpb25zLnRyYW5zaXRpb25UaW1lKVxyXG4gICAgICAuYXR0cihcIngxXCIsIDApXHJcbiAgICAgIC5hdHRyKFwieTFcIiwgc2NhbGVGdW4oMCkpXHJcbiAgICAgIC5hdHRyKFwieDJcIiwgc2VsZi5fb3B0aW9ucy53aWR0aClcclxuICAgICAgLmF0dHIoXCJ5MlwiLCBzY2FsZUZ1bigwKSlcclxuICAgICAgLmF0dHIoXCJzdHlsZVwiLCBzZWxmLl9vcHRpb25zLnplcm9MaW5lU3R5bGUpO1xyXG5cclxuICAgIC8vIFVwZGF0ZSBiYXJzXHJcbiAgICB2YXIgYmFyID0gc2VsZi5fY2hhcnQuc2VsZWN0QWxsKFwicGF0aFwiKS5kYXRhKHNlbGYuX2RhdGEpO1xyXG4gICAgLy8gQWRkIG5ldyBiYXJzXHJcbiAgICBmdW5jdGlvbiByZWN0UGF0aCh4LCB5LCB3LCBoKSB7XHJcbiAgICAgIHJldHVybiAoXCJNXCIgKyB4ICsgXCIgXCIgKyB5ICsgXCJsXCIgKyB3ICsgXCIgMGwwIFwiICsgaCArIFwibFwiICsgKC13KSArIFwiIDBaXCIpXHJcbiAgICB9XHJcblxyXG4gICAgYmFyLmVudGVyKClcclxuICAgICAgLmFwcGVuZChcInBhdGhcIilcclxuICAgICAgLmF0dHIoXCJkXCIsIGZ1bmN0aW9uKGQsIGkpIHtyZXR1cm4gcmVjdFBhdGgoKGkgKyAxKSAqIGJhcldpZHRoICsgMywgc2NhbGVGdW4oMCksIDAsIDApfSlcclxuICAgIC8vIFVwZGF0ZSBiYXJzXHJcbiAgICAgIC5tZXJnZShiYXIpXHJcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgc2VsZi5fb3B0aW9ucy5zaGFwZUNsYXNzKVxyXG4gICAgICAudHJhbnNpdGlvbigpXHJcbiAgICAgIC5kdXJhdGlvbihzZWxmLl9vcHRpb25zLnRyYW5zaXRpb25UaW1lKVxyXG4gICAgICAuYXR0cihcImRcIiwgZnVuY3Rpb24oZCwgaSkge3JldHVybiByZWN0UGF0aChpICogYmFyV2lkdGggKyAzLCBzY2FsZUZ1bigwKSwgYmFyV2lkdGgsIHNjYWxlRnVuKGQpIC0gc2NhbGVGdW4oMCkpfSlcclxuICAgICAgLmF0dHIoXCJmaWxsXCIsIHNlbGYuX29wdGlvbnMuY29sb3JGdW4pO1xyXG4gICAgLy8gUmVtb3ZlIGJhcnNcclxuICAgIGJhci5leGl0KClcclxuICAgICAgLnRyYW5zaXRpb24oKVxyXG4gICAgICAuZHVyYXRpb24oc2VsZi5fb3B0aW9ucy50cmFuc2l0aW9uVGltZSlcclxuICAgICAgLmF0dHIoXCJ4XCIsIGZ1bmN0aW9uKGQsIGkpIHtyZXR1cm4gaSAqIGJhcldpZHRoICsgMzt9KVxyXG4gICAgICAuYXR0cihcInlcIiwgMClcclxuICAgICAgLmF0dHIoXCJ3aWR0aFwiLCAwKVxyXG4gICAgICAuYXR0cihcImhlaWdodFwiLCAwKVxyXG4gICAgICAucmVtb3ZlKCk7XHJcblxyXG4gICAgLy8gQWRkLyB1cGRhdGUgbGFiZWxzXHJcbiAgICBmdW5jdGlvbiBpbml0TGFiZWwobGFiZWwsIGQsIGkpIHtcclxuICAgICAgbGFiZWwuZmlsbFJlY3QoXHJcbiAgICAgICAgaSAqIGJhcldpZHRoICsgMywgc2NhbGVGdW4oMCksXHJcbiAgICAgICAgYmFyV2lkdGgsIDAsXHJcbiAgICAgICAgc2VsZi5fb3B0aW9ucy5sYWJlbFBhZGRpbmcsXHJcbiAgICAgICAgXCJjZW50ZXJcIiwgZCA+PSAwPyBcInRvcFwiOiBcImJvdHRvbVwiLFxyXG4gICAgICAgIDBcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiB1cGRhdGVMYWJlbChsYWJlbCwgZCwgaSkge1xyXG4gICAgICBsYWJlbC5maWxsUmVjdChcclxuICAgICAgICBpICogYmFyV2lkdGggKyAzLCBkID49IDA/IHNjYWxlRnVuKGQpIDogc2NhbGVGdW4oMCksXHJcbiAgICAgICAgYmFyV2lkdGgsIE1hdGguYWJzKHNjYWxlRnVuKGQpIC0gc2NhbGVGdW4oMCkpLFxyXG4gICAgICAgIHNlbGYuX29wdGlvbnMubGFiZWxQYWRkaW5nLFxyXG4gICAgICAgIFwiY2VudGVyXCIsIGQgPj0gMD8gXCJ0b3BcIjogXCJib3R0b21cIixcclxuICAgICAgICBzZWxmLl9vcHRpb25zLnRyYW5zaXRpb25UaW1lKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9kcmF3TGFiZWxzKGluaXRMYWJlbCwgdXBkYXRlTGFiZWwpO1xyXG4gIH1cclxuXHJcbn0oKSk7XHJcbiIsIi8vIENvcHlyaWdodCDCqSAyMDE2IFJURSBSw6lzZWF1IGRlIHRyYW5zcG9ydCBk4oCZw6lsZWN0cmljaXTDqVxyXG4oZnVuY3Rpb24oKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICB2YXIgZDMgPSByZXF1aXJlKFwiZDNcIik7XHJcbiAgdmFyIHRpbnljb2xvciA9IHJlcXVpcmUoXCJ0aW55Y29sb3IyXCIpO1xyXG4gIHZhciB1dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xyXG4gIHZhciBMYWJlbCA9IHJlcXVpcmUoXCIuL2xhYmVsLmpzXCIpXHJcblxyXG4gIG1vZHVsZS5leHBvcnRzID0gQ2hhcnQ7XHJcblxyXG4gIC8qICBAY2xhc3MgQ2hhcnRcclxuICAgICogQWJzdHJhY3QgY2xhc3MgaW5oZXJpdGVkIGJ5IG90aGVyIGNsYXNzZXNcclxuICAgICogQHBhcmFte3N0cmluZ30gZWxcclxuICAgICogQHBhcmFte251bWJlcltdfSBkYXRhXHJcbiAgICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXHJcbiAgICAqIEBwYXJhbSB7b2JqZWN0fSBkZWZhdWx0c1xyXG4gICAgKlxyXG4gICAgKi9cclxuICBmdW5jdGlvbiBDaGFydChlbCwgZGF0YSwgb3B0aW9ucywgZGVmYXVsdHMpIHtcclxuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xyXG5cclxuICAgIC8vIE1lcmdlIG9wdGlvbnMgd2l0aCBkZWZhdWx0IG9wdGlvbnMgb2YgdGhpcyBjbGFzcyBhbmQgb2YgdGhlIGNoaWxkIGNsYXNzXHJcbiAgICAvKipcclxuICAgICogQHByb3Age251bWJlcn0gW2hlaWdodD02MF0gd2lkdGhcclxuICAgICogQHByb3Age251bWJlcn0gW3dpZHRoPTYwXSBoZWlnaHRcclxuICAgICogQHByb3Age251bWJlcn0gW3RyYW5zaXRpb25UaW1lPTc1MF0gdHJhbnNpdGlvblRpbWVcclxuICAgICogQHByb3Age3N0cmluZ1tdfGZ1bmN0aW9ufSBbY29sb3JzPWQzLnNjaGVtZUNhdGVnb3J5MTBdIGNvbG9yc1xyXG4gICAgKiBAcHJvcCB7c3RyaW5nW118XCJub25lXCJ8XCJhdXRvXCJ8ZnVuY3Rpb259IFtsYWJlbHM9XCJub25lXCJdIGxhYmVsc1xyXG4gICAgKiBAcHJvcCB7c3RyaW5nW118XCJhdXRvXCJ8ZnVuY3Rpb259IFtsYWJlbENvbG9ycz1cImF1dG9cIl0gbGFiZWxDb2xvcnNcclxuICAgICogQHByb3Age251bWJlcn0gW2xhYmVsTWluU2l6ZT04XSBsYWJlbE1pblNpemVcclxuICAgICogQHByb3Age251bWJlcn0gW2xhYmVsTWF4U2l6ZT0yNF0gbGFiZWxNYXhTaXplXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9IFtsYWJlbFBhZGRpbmc9Ml0gbGFiZWxQYWRkaW5nXHJcbiAgICAqIEBwcm9wIHtsYWJlbENsYXNzfSBbbGFiZWxDbGFzcz1cIlwiXWxhYmVsQ2xhc3NcclxuICAgICogQHByb3Age3NoYXBlQ2xhc3N9IFtzaGFwZUNsYXNzPVwiXCJdIHNoYXBlQ2xhc3NcclxuICAgICovXHJcbiAgICB0aGlzLl9vcHRpb25zID0ge1xyXG4gICAgICB3aWR0aDo2MCxcclxuICAgICAgaGVpZ2h0OiA2MCxcclxuICAgICAgdHJhbnNpdGlvblRpbWU6IDc1MCxcclxuICAgICAgY29sb3JzOiBkMy5zY2hlbWVDYXRlZ29yeTEwLFxyXG4gICAgICBsYWJlbHM6IFwibm9uZVwiLFxyXG4gICAgICBsYWJlbENvbG9yczogXCJhdXRvXCIsXHJcbiAgICAgIGxhYmVsTWluU2l6ZTogOCxcclxuICAgICAgbGFiZWxNYXhTaXplOiAyNCxcclxuICAgICAgbGFiZWxQYWRkaW5nOiAyLFxyXG4gICAgICBsYWJlbENsYXNzOiBcIlwiLFxyXG4gICAgICBzaGFwZUNsYXNzOiBcIlwiXHJcbiAgICB9O1xyXG4gICAgdGhpcy5fb3B0aW9ucyA9IHV0aWxzLm1lcmdlT3B0aW9ucyh0aGlzLl9vcHRpb25zLCBkZWZhdWx0cyB8fCB7fSk7XHJcbiAgICB0aGlzLl9vcHRpb25zID0gdGhpcy5fcHJvY2Vzc09wdGlvbnMob3B0aW9ucyk7XHJcblxyXG4gICAgLy8gUmVtb3ZlIGV2ZXJ5dGhpbmcgaW4gdGhlIGNvbnRhaW5lciBhbmQgY3JlYXRlIHJlcXVpcmVkIGVsZW1lbnRzXHJcbiAgICBkMy5zZWxlY3QoZWwpLnNlbGVjdChcIipcIikucmVtb3ZlKCk7XHJcbiAgICB0aGlzLl9jb250YWluZXIgPSBkMy5zZWxlY3QoZWwpLmFwcGVuZChcInN2Z1wiKVxyXG4gICAgICAuYXR0cihcIndpZHRoXCIsIHRoaXMuX29wdGlvbnMud2lkdGgpXHJcbiAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIHRoaXMuX29wdGlvbnMuaGVpZ2h0KTtcclxuICAgIHRoaXMuX2NoYXJ0ID0gdGhpcy5fY29udGFpbmVyLmFwcGVuZChcImdcIik7XHJcbiAgfVxyXG5cclxuICAvKiAgVXBkYXRlIGRhdGEgYW5kIG9wdGlvbnMgb2YgYSBjaGFydFxyXG4gICAgKlxyXG4gICAgKi9cclxuICBDaGFydC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24oZGF0YSwgb3B0aW9ucykge1xyXG4gICAgdGhpcy5fZGF0YSA9IGRhdGE7XHJcbiAgICB0aGlzLl9vcHRpb25zID0gdGhpcy5fcHJvY2Vzc09wdGlvbnMob3B0aW9ucyk7XHJcbiAgICB0aGlzLl9kcmF3KCk7XHJcbiAgfTtcclxuXHJcbiAgQ2hhcnQucHJvdG90eXBlLnNldE9wdGlvbnMgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgICB0aGlzLl9vcHRpb25zID0gdGhpcy5fcHJvY2Vzc09wdGlvbnMob3B0aW9ucyk7XHJcbiAgICB0aGlzLl9kcmF3KCk7XHJcbiAgfTtcclxuXHJcbiAgQ2hhcnQucHJvdG90eXBlLnNldERhdGEgPSBmdW5jdGlvbihkYXRhKSB7XHJcbiAgICB0aGlzLl9kYXRhID0gZGF0YTtcclxuICAgIHRoaXMuX2RyYXcoKTtcclxuICB9O1xyXG5cclxuICBDaGFydC5wcm90b3R5cGUuX2RyYXcgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgIC8vIFVwZGF0ZSBjb250YWluZXIgc2l6ZVxyXG4gICAgc2VsZi5fY29udGFpbmVyXHJcbiAgICAgIC50cmFuc2l0aW9uKClcclxuICAgICAgLmR1cmF0aW9uKHNlbGYuX29wdGlvbnMudHJhbnNpdGlvblRpbWUpXHJcbiAgICAgIC5hdHRyKFwid2lkdGhcIiwgc2VsZi5fb3B0aW9ucy53aWR0aClcclxuICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgc2VsZi5fb3B0aW9ucy5oZWlnaHQpO1xyXG4gIH07XHJcblxyXG4gIENoYXJ0LnByb3RvdHlwZS5fcHJvY2Vzc09wdGlvbnMgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgICBvcHRpb25zID0gdXRpbHMubWVyZ2VPcHRpb25zKG9wdGlvbnMsIHRoaXMuX29wdGlvbnMpO1xyXG5cclxuICAgIC8vIENvbnZlcnQgcGFyYW1ldGVycyBjb2xvcnMsIGxhYmVscyBhbmQgbGFiZWxDb2xvcnMgdG8gZnVuY3Rpb25zXHJcbiAgICBvcHRpb25zLmNvbG9yRnVuID0gdXRpbHMudG9GdW5jdGlvbihvcHRpb25zLmNvbG9ycyk7XHJcbiAgICBvcHRpb25zLmxhYmVsQ2xhc3MgPSB1dGlscy50b0Z1bmN0aW9uKG9wdGlvbnMubGFiZWxDbGFzcyk7XHJcbiAgICBvcHRpb25zLnNoYXBlQ2xhc3MgPSB1dGlscy50b0Z1bmN0aW9uKG9wdGlvbnMuc2hhcGVDbGFzcyk7XHJcblxyXG4gICAgaWYgKG9wdGlvbnMubGFiZWxzID09PSBcIm5vbmVcIikge1xyXG4gICAgICBvcHRpb25zLmxhYmVsVGV4dCA9IG51bGw7XHJcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMubGFiZWxzID09PSBcImF1dG9cIikge1xyXG4gICAgICBvcHRpb25zLmxhYmVsVGV4dCA9IHV0aWxzLnByZXR0eU51bWJlcjtcclxuICAgIH0gIGVsc2Uge1xyXG4gICAgICBvcHRpb25zLmxhYmVsVGV4dCA9IHV0aWxzLnRvRnVuY3Rpb24ob3B0aW9ucy5sYWJlbHMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChvcHRpb25zLmxhYmVsQ29sb3JzID09PSBcImF1dG9cIikge1xyXG4gICAgICBvcHRpb25zLmxhYmVsQ29sb3JGdW4gPSBmdW5jdGlvbihkLCBpKSB7XHJcbiAgICAgICAgcmV0dXJuIHRpbnljb2xvci5tb3N0UmVhZGFibGUob3B0aW9ucy5jb2xvckZ1bihkLCBpKSwgW1wid2hpdGVcIiwgXCJibGFja1wiXSkuX29yaWdpbmFsSW5wdXRcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG9wdGlvbnMubGFiZWxDb2xvckZ1biA9IHV0aWxzLnRvRnVuY3Rpb24ob3B0aW9ucy5sYWJlbENvbG9yRnVuKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gb3B0aW9ucztcclxuICB9XHJcblxyXG4gIENoYXJ0LnByb3RvdHlwZS5fZHJhd0xhYmVscyA9IGZ1bmN0aW9uKGluaXRGdW4sIHVwZGF0ZUZ1bikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIGlmIChzZWxmLl9vcHRpb25zLmxhYmVscyA9PT0gXCJub25lXCIpIHtcclxuICAgICAgc2VsZi5fY2hhcnQuc2VsZWN0QWxsKFwiLmxhYmVscy1jb250YWluZXJcIikucmVtb3ZlKCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcblxyXG4gICAgc2VsZi5fbGFiZWxzID0gc2VsZi5fY2hhcnQuc2VsZWN0QWxsKFwiLmxhYmVscy1jb250YWluZXJcIikuZGF0YShzZWxmLl9kYXRhKTtcclxuICAgIHNlbGYuX2xhYmVscy5lbnRlcigpXHJcbiAgICAgIC5hcHBlbmQoXCJnXCIpXHJcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJsYWJlbHMtY29udGFpbmVyXCIpXHJcbiAgICAgIC5lYWNoKGZ1bmN0aW9uKGQsIGkpIHtcclxuICAgICAgICB0aGlzLl9sYWJlbCA9IG5ldyBMYWJlbCh0aGlzLCBzZWxmLl9vcHRpb25zLmxhYmVsU3R5bGUsIHNlbGYuX29wdGlvbnMubGFiZWxDb2xvckZ1bihkLCBpKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9vcHRpb25zLmxhYmVsTWluU2l6ZSwgc2VsZi5fb3B0aW9ucy5sYWJlbE1heFNpemUpO1xyXG4gICAgICAgIHRoaXMuX2xhYmVsLnVwZGF0ZVRleHQoc2VsZi5fb3B0aW9ucy5sYWJlbFRleHQoZCwgaSkpXHJcbiAgICAgICAgaW5pdEZ1bih0aGlzLl9sYWJlbCwgZCwgaSk7XHJcbiAgICAgIH0pXHJcblxyXG4gICAgICAubWVyZ2Uoc2VsZi5fbGFiZWxzKVxyXG4gICAgICAuZWFjaChmdW5jdGlvbihkLCBpKSB7XHJcbiAgICAgICAgdGhpcy5fbGFiZWwudXBkYXRlVGV4dChzZWxmLl9vcHRpb25zLmxhYmVsVGV4dChkLCBpKSk7XHJcbiAgICAgICAgdGhpcy5fbGFiZWwuX3RleHRcclxuICAgICAgICAgIC5hdHRyKFwiZmlsbFwiLCBzZWxmLl9vcHRpb25zLmxhYmVsQ29sb3JGdW4oZCwgaSkpXHJcbiAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIHNlbGYuX29wdGlvbnMubGFiZWxDbGFzcyhkLCBpKSk7XHJcbiAgICAgICAgdXBkYXRlRnVuKHRoaXMuX2xhYmVsLCBkLCBpKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgc2VsZi5fbGFiZWxzLmV4aXQoKS5yZW1vdmUoKTtcclxuICB9XHJcblxyXG59KCkpO1xyXG4iLCIvLyBDb3B5cmlnaHQgwqkgMjAxNiBSVEUgUsOpc2VhdSBkZSB0cmFuc3BvcnQgZOKAmcOpbGVjdHJpY2l0w6lcclxuKGZ1bmN0aW9uKCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgbW9kdWxlLmV4cG9ydHMuUG9pbnQgPSBQb2ludDtcclxuICBtb2R1bGUuZXhwb3J0cy5MaW5lID0gTGluZTtcclxuICBtb2R1bGUuZXhwb3J0cy5pbnRlcnNlY3Rpb25PZlR3b0xpbmVzID0gaW50ZXJzZWN0aW9uT2ZUd29MaW5lcztcclxuICBtb2R1bGUuZXhwb3J0cy5pbnRlcnNlY3Rpb25MaW5lQW5kQ2lyY2xlID0gaW50ZXJzZWN0aW9uTGluZUFuZENpcmNsZTtcclxuICBtb2R1bGUuZXhwb3J0cy5wb2ludEluU2VnbWVudCA9IHBvaW50SW5TZWdtZW50O1xyXG4gIG1vZHVsZS5leHBvcnRzLmludGVyc2VjdGlvbkxpbmVSYWRpdXMgID0gaW50ZXJzZWN0aW9uTGluZVJhZGl1cyA7XHJcbiAgbW9kdWxlLmV4cG9ydHMuZGlzdGFuY2UgPSBkaXN0YW5jZTtcclxuXHJcbiAgZnVuY3Rpb24gUG9pbnQoeCwgeSkge1xyXG4gICAgdGhpcy54ID0geDtcclxuICAgIHRoaXMueSA9IHk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBMaW5lKGEsIGIpIHtcclxuICAgIHRoaXMuYSA9IGE7XHJcbiAgICB0aGlzLmIgPSBiXHJcbiAgfVxyXG4gIExpbmUucHJvdG90eXBlLmdldFkgPSBmdW5jdGlvbih4KSB7XHJcbiAgICByZXR1cm4gdGhpcy5hICsgdGhpcy5iICogeDtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGludGVyc2VjdGlvbk9mVHdvTGluZXMobDEsIGwyKSB7XHJcbiAgICBpZiAobDEuYiA9PSBsMi5iKSByZXR1cm4gW11cclxuICAgIHJldHVybiBbbmV3IFBvaW50KFxyXG4gICAgICAobDIuYSAtIGwxLmEpIC8gKGwxLmIgLSBsMi5iKSxcclxuICAgICAgKGwxLmIgKiBsMi5hIC0gbDEuYSAqIGwyLmIpIC8gKGwxLmIgLSBsMi5iKVxyXG4gICAgKV1cclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGludGVyc2VjdGlvbkxpbmVSYWRpdXMobCwgYW5nbGUsIHJhZGl1cykge1xyXG4gICAgdmFyIGwyID0gbmV3IExpbmUoMCwgTWF0aC50YW4oYW5nbGUpKTtcclxuICAgIHZhciBpbnRlcnNlY3QgPSBpbnRlcnNlY3Rpb25PZlR3b0xpbmVzKGwsIGwyKTtcclxuICAgIHZhciBzMSA9IG5ldyBQb2ludCgwLCAwKTtcclxuICAgIHZhciBzMiA9IG5ldyBQb2ludChyYWRpdXMgKiBNYXRoLmNvcyhhbmdsZSksIHJhZGl1cyAqIE1hdGguc2luKGFuZ2xlKSk7XHJcblxyXG4gICAgaWYgKGludGVyc2VjdC5sZW5ndGggPT0gMCB8fCAhcG9pbnRJblNlZ21lbnQoaW50ZXJzZWN0WzBdLCBzMSwgczIpKSB7XHJcbiAgICAgIHJldHVybiBbXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBpbnRlcnNlY3Q7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBpbnRlcnNlY3Rpb25MaW5lQW5kQ2lyY2xlKGwsIHIpIHtcclxuICAgIHZhciB4ID0gc29sdmVFcVNlY29uZERlZ3JlZShsLmIgKiBsLmIgKyAxLCAyICogbC5hICogbC5iLCBsLmEgKiBsLmEgLSByICogcik7XHJcbiAgICByZXR1cm4geC5tYXAoZnVuY3Rpb24oeCkge3JldHVybiBuZXcgUG9pbnQoeCwgbC5nZXRZKHgpKX0pO1xyXG4gIH1cclxuXHJcbiAgLy8gSXMgcG9pbnQgcCBpbnNpZGUgdGhlIHNlZ21lbnQgZGVmaW5lZCBieSBzMSBhbmQgczIuIEl0IGlzIGFzc3VtZWQgdGhhdCB0aGVcclxuICAvLyB0aHJlZSBwb2ludHMgYXJlIGFsaWduZWQuXHJcbiAgZnVuY3Rpb24gcG9pbnRJblNlZ21lbnQocCwgczEsIHMyKSB7XHJcbiAgICB2YXIga3AgPSBkb3RQcm9kKHBvaW50RGlmZihzMiwgczEpLCBwb2ludERpZmYocCwgczEpKTtcclxuICAgIHZhciBrcyA9IGRvdFByb2QocG9pbnREaWZmKHMyLCBzMSksIHBvaW50RGlmZihzMiwgczEpKTtcclxuICAgIHJldHVybiBrcCA+PSAwICYmIGtwIDw9IGtzO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gcG9pbnREaWZmKHAxLCBwMikge1xyXG4gICAgcmV0dXJuIG5ldyBQb2ludChwMS54IC0gcDIueCwgcDEueSAtIHAyLnkpO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZG90UHJvZChwMSwgcDIpIHtcclxuICAgIHJldHVybiBwMS54ICogcDIueCArIHAxLnkgKiBwMi55O1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gc29sdmVFcVNlY29uZERlZ3JlZShhLCBiLCBjKSB7XHJcbiAgICB2YXIgZGV0ID0gYiAqIGIgLSA0ICogYSAqIGNcclxuICAgIGlmIChkZXQgPCAwKSByZXR1cm4gW107XHJcbiAgICBpZiAoZGV0ID09IDApIHJldHVybiBbKC0gYikgLyAoMiAqIGEpXTtcclxuICAgIGVsc2UgcmV0dXJuIFtcclxuICAgICAgKC1iIC0gTWF0aC5zcXJ0KGRldCkpIC8gKDIgKiBhKSxcclxuICAgICAgKC1iICsgTWF0aC5zcXJ0KGRldCkpIC8gKDIgKiBhKVxyXG4gICAgXVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZGlzdGFuY2UocDEsIHAyKSB7XHJcbiAgICByZXR1cm4gTWF0aC5zcXJ0KCBNYXRoLnBvdyhwMS54IC0gcDIueCwgMikgKyBNYXRoLnBvdyhwMS55IC0gcDIueSwgMikpXHJcbiAgfVxyXG59KCkpO1xyXG4iLCIvLyBDb3B5cmlnaHQgwqkgMjAxNiBSVEUgUsOpc2VhdSBkZSB0cmFuc3BvcnQgZOKAmcOpbGVjdHJpY2l0w6lcclxuKGZ1bmN0aW9uKCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgdmFyIGQzID0gcmVxdWlyZShcImQzXCIpO1xyXG4gIHZhciBnID0gcmVxdWlyZShcIi4vZ2VvbWV0cnkuanNcIilcclxuXHJcbiAgbW9kdWxlLmV4cG9ydHMgPSBMYWJlbDtcclxuXHJcbiAgZnVuY3Rpb24gTGFiZWwoZWwsIHN0eWxlLCBjb2xvciwgbWluU2l6ZSwgbWF4U2l6ZSkge1xyXG4gICAgdGhpcy5fZWwgPSBlbDtcclxuICAgIHRoaXMuX21pblNpemUgPSBtaW5TaXplO1xyXG4gICAgdGhpcy5fbWF4U2l6ZSA9IG1heFNpemU7XHJcbiAgICB0aGlzLl9jb250YWluZXIgPSBkMy5zZWxlY3QoZWwpO1xyXG4gICAgdGhpcy5fbGFiZWwgPSB0aGlzLl9jb250YWluZXIuYXBwZW5kKFwiZ1wiKVxyXG4gICAgICAuYXR0cihcImNsYXNzXCIsIFwibGFiZWxcIik7XHJcblxyXG4gICAgdGhpcy5fdGV4dCA9IHRoaXMuX2xhYmVsLmFwcGVuZChcInRleHRcIilcclxuICAgICAgLmF0dHIoXCJkeVwiLCBcIjAuMzVlbVwiKVxyXG4gICAgICAuYXR0cihcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpXHJcbiAgICAgIC5hdHRyKFwic3R5bGVcIiwgc3R5bGUgfHwgXCJcIilcclxuICAgICAgLmF0dHIoXCJmaWxsXCIsIGNvbG9yIHx8IFwiYmxhY2tcIik7XHJcbiAgfVxyXG5cclxuICAvLyBTaXplIG9mIHRoZSBsYWJlbCBiZWZvcmUgc2NhbGluZ1xyXG4gIExhYmVsLnByb3RvdHlwZS5pbm5lclNpemUgPSBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLl90ZXh0Lm5vZGUoKS5nZXRCQm94KCk7XHJcbiAgfVxyXG5cclxuICBMYWJlbC5wcm90b3R5cGUuc2l6ZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIGJib3ggPSB0aGlzLmlubmVyU2l6ZSgpO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgd2lkdGg6IGJib3gud2lkdGggKiB0aGlzLl9zY2FsZSxcclxuICAgICAgaGVpZ2h0OiBiYm94LmhlaWdodCAqIHRoaXMuX3NjYWxlXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBMYWJlbC5wcm90b3R5cGUudXBkYXRlVGV4dCA9IGZ1bmN0aW9uKG5ld1RleHQpIHtcclxuICAgIC8vIE5ldyBsYWJlbCBzaG91bGQgZml0IGluIHRoZSBvbGQgYm91bmRpbmcgYmJveFxyXG4gICAgdmFyIG9sZFNpemUgPSB0aGlzLnNpemUoKTtcclxuICAgIHRoaXMuX3RleHQudGV4dChuZXdUZXh0KTtcclxuICAgIHZhciBuZXdTaXplID0gdGhpcy5zaXplKCk7XHJcblxyXG4gICAgdmFyIHNjYWxlID0gTWF0aC5taW4oXHJcbiAgICAgIG9sZFNpemUud2lkdGggLyBuZXdTaXplLndpZHRoLFxyXG4gICAgICBvbGRTaXplLmhlaWdodCAvIG5ld1NpemUuaGVpZ2h0XHJcbiAgICApO1xyXG4gICAgdGhpcy51cGRhdGVTY2FsZSh0aGlzLl9zY2FsZSAqIHNjYWxlLCAwKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgTGFiZWwucHJvdG90eXBlLnVwZGF0ZVBvc2l0aW9uID0gZnVuY3Rpb24oeCwgeSwgdHJhbnNpdGlvblRpbWUpIHtcclxuICAgIHRoaXMuX2NvbnRhaW5lclxyXG4gICAgICAudHJhbnNpdGlvbigpXHJcbiAgICAgIC5kdXJhdGlvbih0cmFuc2l0aW9uVGltZSB8fCAwKVxyXG4gICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIHggKyBcIixcIiArIHkgKyBcIilcIik7XHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgTGFiZWwucHJvdG90eXBlLnVwZGF0ZVNjYWxlID0gZnVuY3Rpb24obmV3U2NhbGUsIHRyYW5zaXRpb25UaW1lKSB7XHJcbiAgICBpZiAoIW5ld1NjYWxlIHx8IGlzTmFOKG5ld1NjYWxlKSB8fCAhaXNGaW5pdGUobmV3U2NhbGUpKSB7XHJcbiAgICAgIG5ld1NjYWxlID0gMDtcclxuICAgIH1cclxuICAgIHZhciBuZXdIZWlnaHQgPSB0aGlzLmlubmVyU2l6ZSgpLmhlaWdodCAqIG5ld1NjYWxlO1xyXG4gICAgaWYgKHRoaXMuX21pblNpemUgJiYgbmV3SGVpZ2h0IDwgdGhpcy5fbWluU2l6ZSkge1xyXG4gICAgICBuZXdTY2FsZSA9IDA7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5fbWF4U2l6ZSAmJiBuZXdIZWlnaHQgPiB0aGlzLl9tYXhTaXplKSB7XHJcbiAgICAgIG5ld1NjYWxlID0gdGhpcy5fbWF4U2l6ZSAvIHRoaXMuaW5uZXJTaXplKCkuaGVpZ2h0O1xyXG4gICAgfVxyXG4gICAgdGhpcy5fbGFiZWxcclxuICAgICAgLnRyYW5zaXRpb24oKVxyXG4gICAgICAuZHVyYXRpb24odHJhbnNpdGlvblRpbWUgfHwgMClcclxuICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJzY2FsZShcIiArIG5ld1NjYWxlICsgXCIpXCIpO1xyXG4gICAgdGhpcy5fc2NhbGUgPSBuZXdTY2FsZTtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIExhYmVsLnByb3RvdHlwZS5maWxsUmVjdCA9IGZ1bmN0aW9uKHgsIHksIHdpZHRoLCBoZWlnaHQsIHBhZGRpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFsaWduLCB2QWxpZ24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNpdGlvblRpbWUpIHtcclxuICAgICAgdmFyIGJib3ggPSB0aGlzLmlubmVyU2l6ZSgpO1xyXG4gICAgICB0aGlzLnVwZGF0ZVNjYWxlKE1hdGgubWluKFxyXG4gICAgICAgICh3aWR0aCAtIDIgKiBwYWRkaW5nKSAvIGJib3gud2lkdGgsXHJcbiAgICAgICAgKE1hdGguYWJzKGhlaWdodCkpIC8gYmJveC5oZWlnaHRcclxuICAgICAgKSwgdHJhbnNpdGlvblRpbWUpO1xyXG5cclxuICAgICAgdmFyIGxzaXplID0gdGhpcy5zaXplKCk7XHJcbiAgICAgIHZhciBseCwgbHk7XHJcbiAgICAgIHN3aXRjaCh2QWxpZ24pIHtcclxuICAgICAgICBjYXNlIFwidG9wXCI6XHJcbiAgICAgICAgICBseSA9IHkgKyBsc2l6ZS5oZWlnaHQgLyAyO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcImNlbnRlclwiOlxyXG4gICAgICAgICAgbHkgPSB5ICsgKGhlaWdodCkgLyAyO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcImJvdHRvbVwiOlxyXG4gICAgICAgICAgbHkgPSB5ICsgaGVpZ2h0IC0gbHNpemUuaGVpZ2h0IC8gMjtcclxuICAgICAgfVxyXG5cclxuICAgICAgc3dpdGNoKGhBbGlnbikge1xyXG4gICAgICAgIGNhc2UgXCJsZWZ0XCI6XHJcbiAgICAgICAgICBseCA9IHggKyBwYWRkaW5nICsgbHNpemUud2lkdGggLyAyO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcImNlbnRlclwiOlxyXG4gICAgICAgICAgbHggPSB4ICsgd2lkdGggLyAyO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcInJpZ2h0XCI6XHJcbiAgICAgICAgICBseCA9IHggKyB3aWR0aCAtIHBhZGRpbmcgLSBsc2l6ZS53aWR0aCAvIDI7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMudXBkYXRlUG9zaXRpb24obHgsIGx5LCB0cmFuc2l0aW9uVGltZSk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBMYWJlbC5wcm90b3R5cGUuZmlsbENpcmNsZSA9IGZ1bmN0aW9uKHJhZGl1cywgdHJhbnNpdGlvblRpbWUpIHtcclxuICAgIHRoaXMudXBkYXRlUG9zaXRpb24oMCwgMCwgdHJhbnNpdGlvblRpbWUpO1xyXG5cclxuICAgIHZhciBiYm94ID0gdGhpcy5pbm5lclNpemUoKTtcclxuICAgIHZhciByYXRpbyA9IGJib3guaGVpZ2h0IC8gYmJveC53aWR0aDtcclxuXHJcbiAgICB2YXIgbWF4SGVpZ2h0ID0gcmFkaXVzICogMiAqIE1hdGguY29zKE1hdGguUEkvMiAtIE1hdGguYXRhbihyYXRpbykpXHJcbiAgICB0aGlzLnVwZGF0ZVNjYWxlKG1heEhlaWdodCAvIGJib3guaGVpZ2h0LCB0cmFuc2l0aW9uVGltZSk7XHJcbiAgfVxyXG5cclxuICBMYWJlbC5wcm90b3R5cGUuZmlsbFNsaWNlID0gZnVuY3Rpb24oYXJjLCByYWRpdXMsIGQsIHRyYW5zaXRpb25UaW1lKSB7XHJcbiAgICB2YXIgYyA9IGFyYy5jZW50cm9pZChkKTtcclxuICAgIHRoaXMudXBkYXRlUG9zaXRpb24oY1swXSwgY1sxXSwgdHJhbnNpdGlvblRpbWUpO1xyXG5cclxuICAgIHZhciBiYm94ID0gdGhpcy5pbm5lclNpemUoKTtcclxuICAgIHZhciByYXRpbyA9IGJib3guaGVpZ2h0IC8gYmJveC53aWR0aDtcclxuXHJcbiAgICAvLyBHZXQgbWF4aW1hbCBzY2FsZSBzbyB0aGF0IGxhYmVsIGZpdHMgaW4gdGhlIHNsaWNlLlxyXG4gICAgdmFyIGRpYWcxID0gbmV3IGcuTGluZShjWzFdIC0gcmF0aW8gKiBjWzBdLCByYXRpbyk7XHJcbiAgICB2YXIgZGlhZzIgPSBuZXcgZy5MaW5lKGNbMV0gKyByYXRpbyAqIGNbMF0sIC1yYXRpbyk7XHJcbiAgICB2YXIgbGltaXQxID0gbmV3IGcuTGluZSgwLCBNYXRoLnRhbihkLnN0YXJ0QW5nbGUgKyBNYXRoLlBJLzIpKTtcclxuICAgIHZhciBsaW1pdDIgPSBuZXcgZy5MaW5lKDAsIE1hdGgudGFuKGQuZW5kQW5nbGUgKyBNYXRoLlBJLzIpKTtcclxuXHJcbiAgICAvLyBHZXQgYWxsIGludGVyc2VjdGlvbiBwb2ludHNcclxuICAgIHZhciBpbnRlcnNlY3RzID0gW107XHJcbiAgICBpbnRlcnNlY3RzID0gaW50ZXJzZWN0cy5jb25jYXQoZy5pbnRlcnNlY3Rpb25MaW5lUmFkaXVzKGRpYWcxLCBkLnN0YXJ0QW5nbGUgLSBNYXRoLlBJLzIsIHJhZGl1cykpO1xyXG4gICAgaW50ZXJzZWN0cyA9IGludGVyc2VjdHMuY29uY2F0KGcuaW50ZXJzZWN0aW9uTGluZVJhZGl1cyhkaWFnMSwgZC5lbmRBbmdsZSAtIE1hdGguUEkvMiwgcmFkaXVzKSk7XHJcbiAgICBpbnRlcnNlY3RzID0gaW50ZXJzZWN0cy5jb25jYXQoZy5pbnRlcnNlY3Rpb25MaW5lQW5kQ2lyY2xlKGRpYWcxLCByYWRpdXMpKTtcclxuICAgIGludGVyc2VjdHMgPSBpbnRlcnNlY3RzLmNvbmNhdChnLmludGVyc2VjdGlvbkxpbmVSYWRpdXMoZGlhZzIsIGQuc3RhcnRBbmdsZSAtIE1hdGguUEkvMiwgcmFkaXVzKSk7XHJcbiAgICBpbnRlcnNlY3RzID0gaW50ZXJzZWN0cy5jb25jYXQoZy5pbnRlcnNlY3Rpb25MaW5lUmFkaXVzKGRpYWcyLCBkLmVuZEFuZ2xlIC0gTWF0aC5QSS8yLCByYWRpdXMpKTtcclxuICAgIGludGVyc2VjdHMgPSBpbnRlcnNlY3RzLmNvbmNhdChnLmludGVyc2VjdGlvbkxpbmVBbmRDaXJjbGUoZGlhZzIsIHJhZGl1cykpO1xyXG5cclxuICAgIC8vIENvbXB1dGUgZGlzdGFuY2UgYmV0d2VlbiBhbGwgdGhlc2UgcG9pbnRzIGFuZCB0YWtlIHRoZSBtaW5pbXVtXHJcbiAgICB2YXIgY2VudGVyID0gbmV3IGcuUG9pbnQoY1swXSwgY1sxXSk7XHJcbiAgICB2YXIgZGlzdGFuY2VzID0gaW50ZXJzZWN0cy5tYXAoZnVuY3Rpb24oeCkge3JldHVybiBnLmRpc3RhbmNlKGNlbnRlciwgeCl9KTtcclxuICAgIHZhciBtaW5EaXN0ID0gZDMubWluKGRpc3RhbmNlcyk7XHJcbiAgICB2YXIgYWN0dWFsRGlzdCA9IE1hdGguc3FydCggTWF0aC5wb3coYmJveC5oZWlnaHQgLyAyLCAyKSArIE1hdGgucG93KGJib3gud2lkdGggLyAyLCAyKSk7XHJcblxyXG4gICAgdGhpcy51cGRhdGVTY2FsZShtaW5EaXN0IC8gYWN0dWFsRGlzdCwgdHJhbnNpdGlvblRpbWUpO1xyXG4gIH1cclxufSgpKTtcclxuIiwiLy8gQ29weXJpZ2h0IMKpIDIwMTYgUlRFIFLDqXNlYXUgZGUgdHJhbnNwb3J0IGTigJnDqWxlY3RyaWNpdMOpXHJcbihmdW5jdGlvbigpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIG1vZHVsZS5leHBvcnRzLkJhcmNoYXJ0ID0gcmVxdWlyZShcIi4vYmFyY2hhcnQuanNcIik7XHJcbiAgbW9kdWxlLmV4cG9ydHMuUG9sYXJjaGFydCA9IHJlcXVpcmUoXCIuL3BvbGFyY2hhcnQuanNcIik7XHJcbiAgbW9kdWxlLmV4cG9ydHMuUGllY2hhcnQgPSByZXF1aXJlKFwiLi9waWVjaGFydC5qc1wiKTtcclxuXHJcbiAgaWYgKHdpbmRvdykgd2luZG93Lm1pbmljaGFydHMgPSBtb2R1bGUuZXhwb3J0cztcclxufSgpKTtcclxuIiwiLy8gQ29weXJpZ2h0IMKpIDIwMTYgUlRFIFLDqXNlYXUgZGUgdHJhbnNwb3J0IGTigJnDqWxlY3RyaWNpdMOpXHJcbihmdW5jdGlvbigpIHtcclxuICAndXNlIHN0cmljdCc7XHJcbiAgdmFyIFBvbGFyY2hhcnQgPSByZXF1aXJlKFwiLi9wb2xhcmNoYXJ0LmpzXCIpO1xyXG4gIG1vZHVsZS5leHBvcnRzID0gUGllY2hhcnQ7XHJcblxyXG4gIFBpZWNoYXJ0LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoUG9sYXJjaGFydC5wcm90b3R5cGUpO1xyXG4gIFBpZWNoYXJ0LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFBpZWNoYXJ0O1xyXG5cclxuICAvKipcclxuICAgICogQGNsYXNzIFBpZWNoYXJ0XHJcbiAgICAqIEBzdW1tYXJ5IFJlcHJlc2VudCBkYXRhIHdpdGggYSBwaWUgY2hhcnRcclxuICAgICogQGRlc2MgQSBwaWUgY2hhcnQgaXMgYSBzcGVjaWFsIGNhc2Ugb2YgcG9sYXIgY2hhcnQgd2hlcmUgdGhlIGRhdGEgdmFsdWVzXHJcbiAgICAqIGFyZSByZXByZXNlbnRlZCBieSB0aGUgYW5nbGUgb2YgdGhlIHNsaWNlcy4gVGhleSBzaG91bGQgb25seSBiZSB1c2VkIHRvXHJcbiAgICAqIGNvbXBhcmUgcXVhbGl0YXRpdmVseSBwcm9wb3J0aW9ucyBhbmQgY29tcG9zaXRpb25zLiBJbmRlZWQsIGh1bWFuIGV5ZSBpc1xyXG4gICAgKiBub3QgZ29vZCBhdCBjb21wYXJpbmcgYW5nbGVzIHNvIG9ubHkgbGFyZ2UgZGlmZmVyZW5jZXMgYXJlIHZpc2libGUuXHJcbiAgICAqIEBwYXJhbSB7c3RyaW5nfSBlbCBDU1Mgc2VsZWN0b3IgcmVwcmVzZW50aW5nIHRoZSBlbGVtZW50IHRoYXQgd2lsbCBob2xkIHRoZSBjaGFydC5cclxuICAgICogQHBhcmFtIHtudW1iZXJbXX0gZGF0YSBEYXRhIHRoZSBjaGFydCBoYXMgdG8gcmVwcmVzZW50LlxyXG4gICAgKiBAcGFyYW0ge1BpZWNoYXJ0T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zIGNvbnRyb2xpbmcgZ3JhcGhpY2FsIGFzcGVjdHMgb2YgdGhlIGNoYXJ0LlxyXG4gICAgKi9cclxuXHJcbiAgLyoqIEB0eXBlZGVmIHtvYmplY3R9IFBpZWNoYXJ0T3B0aW9uc1xyXG4gICAgKiBAbWVtYmVyT2YgUGllY2hhcnRcclxuICAgICogQHByb3Age251bWJlcn0gW3dpZHRoPTYwXSBXaWR0aCBvZiB0aGUgY2hhcnQuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9IFtoZWlnaHQ9NjBdIEhlaWdodCBvZiB0aGUgY2hhcnQuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9IFt0cmFuc2l0aW9uVGltZT03NTBdIER1cmF0aW9uIG9mIHRoZSB0cmFuc2l0aW9ucywgaW4gbWlsbGlzZWNvbmRzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nW118ZnVuY3Rpb259W2NvbG9ycz1kMy5zY2hlbWVDYXRlZ29yeTEwXSBFaXRoZXIgYW4gYXJyYXkgb2ZcclxuICAgICogY29sb3JzIG9yIGEgZnVuY3Rpb24gYChkLCBpKSAtPiBjb2xvcmAgd2hlcmUgYGRgIGlzIGEgZGF0YSB2YWx1ZSBhbmQgYGlgXHJcbiAgICAqIGlzIHRoZSBpbmRleCBvZiB0aGUgdmFsdWUuSWYgaXQgaXMgYW4gYXJyYXkgd2l0aCBsZW5ndGggbGVzcyB0aGFuIHRoZSBsZW5ndGhcclxuICAgICogb2YgZGF0YSwgdGhlbiB0aGUgY29sb3JzIGFyZSByZWN5Y2xlZC5cclxuICAgICogQHByb3Age3N0cmluZ1tdfFwibm9uZVwifFwiYXV0b1wifGZ1bmN0aW9ufVtsYWJlbHM9XCJub25lXCJdIExhYmVscyB0byBkaXNwbGF5IGluIHNsaWNlcy5cclxuICAgICogSXQgY2FuIGJlIGFuIGFycmF5IHdpdGggc2FtZSBsZW5ndGggYXMgdGhlIGRhdGEuIEl0IGNhbiBhbHNvIGJlIGEgZnVuY3Rpb25cclxuICAgICogYChkLCBpKSAtPiBsYWJlbFRleHRgIHdoZXJlIGBkYCBpcyBhIGRhdGEgdmFsdWUgYW5kIGBpYFxyXG4gICAgKiBpcyB0aGUgaW5kZXggb2YgdGhlIHZhbHVlLiBGaW5hbGx5IGl0IGNhbiBiZSBlcXVhbCB0byBcIm5vbmVcIiB0byBoaWRlIGxhYmVsc1xyXG4gICAgKiBvciBcImF1dG9cIiB0byBkaXNwbGF5IGluIGEgY29tcGFjdCB3YXkgdmFsdWVzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfHN0cmluZ1tdfFwiYXV0b1wifGZ1bmN0aW9ufVtsYWJlbENvbG9ycz1cImF1dG9cIl0gQ29sb3Igb2YgdGhlIGxhYmVscy5cclxuICAgICogSXQgY2FuIGJlIGEgc2luZ2xlIHZhbHVlIG9yIGFuIGFycmF5IHdpdGggc2FtZSBsZW5ndGggYXMgdGhlIGRhdGEuIEl0IGNhblxyXG4gICAgKiBhbHNvIGJlIGEgZnVuY3Rpb24gYChkLCBpKSAtPiBjb2xvcmAgd2hlcmUgYGRgIGlzIGEgZGF0YSB2YWx1ZSBhbmQgYGlgXHJcbiAgICAqIGlzIHRoZSBpbmRleCBvZiB0aGUgdmFsdWUuIEZpbmFsbHkgaXQgY2FuIGJlIGVxdWFsIHRvIFwiYXV0b1wiLiBJbiB0aGlzIGNhc2UsXHJcbiAgICAqIHRoZSBtb3N0IHJlYWRhYmxlIGNvbG9yIGlzIGNob29zZW4gZGVwZGluZyBvbiB0aGUgY29sb3Igb2YgdGhlIHNsaWNlLlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfVtsYWJlbE1pblNpemU9OF0gTGFiZWwgbWluaW11bSBzaXplIGluIHBpeGVscy4gSWYgdGhlcmUgaXNcclxuICAgICogbm90IGVub3VnaCBzcGFjZSBmb3IgYSBnaXZlbiBsYWJlbCwgdGhlbiBpdCBpcyBoaWRkZW4uXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9W2xhYmVsTWF4U2l6ZT0yNF0gTGFiZWwgbWF4aW11bSBzaXplIGluIHBpeGVscy5cclxuICAgICogQHByb3Age3N0cmluZ31bbGFiZWxDbGFzcz1cIlwiXSBMYWJlbHMgQ1NTIGNsYXNzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfVtzaGFwZUNsYXNzPVwiXCJdIHNsaWNlcyBDU1MgY2xhc3MuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQG1ldGhvZCBzZXREYXRhXHJcbiAgICAqIEBkZXNjIFVwZGF0ZSB0aGUgZGF0YSByZXByZXNlbnRlZCBieSB0aGUgY2hhcnRcclxuICAgICogQGluc3RhbmNlXHJcbiAgICAqIEBtZW1iZXJPZiBQaWVjaGFydFxyXG4gICAgKiBAcGFyYW0ge251bWJlcltdfSBkYXRhIERhdGEgdGhlIGNoYXJ0IGhhcyB0byByZXByZXNlbnQuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQG1ldGhvZCBzZXRPcHRpb25zXHJcbiAgICAqIEBkZXNjIFVwZGF0ZSB0aGUgZ3JhcGhpY2FsIG9wdGlvbnMgb2YgYSBjaGFydFxyXG4gICAgKiBAaW5zdGFuY2VcclxuICAgICogQG1lbWJlck9mIFBpZWNoYXJ0XHJcbiAgICAqIEBwYXJhbSB7UGllY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQG1ldGhvZCB1cGRhdGVcclxuICAgICogQGRlc2MgVXBkYXRlIHNpbXVsYXRlbm91c2x5IGRhdGEgYW5kIG9wdGlvbnMgb2YgYSBwaWUgY2hhcnQuXHJcbiAgICAqIEBpbnN0YW5jZVxyXG4gICAgKiBAbWVtYmVyT2YgUGllY2hhcnRcclxuICAgICogQHBhcmFtIHtudW1iZXJbXX0gZGF0YSBEYXRhIHRoZSBjaGFydCBoYXMgdG8gcmVwcmVzZW50LlxyXG4gICAgKiBAcGFyYW0ge1BpZWNoYXJ0T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zIGNvbnRyb2xpbmcgZ3JhcGhpY2FsIGFzcGVjdHMgb2YgdGhlIGNoYXJ0LlxyXG4gICAgKi9cclxuICBmdW5jdGlvbiBQaWVjaGFydChlbCwgZGF0YSwgb3B0aW9ucykge1xyXG4gICAgUG9sYXJjaGFydC5jYWxsKHRoaXMsIGVsLCBkYXRhLCBvcHRpb25zKTtcclxuICB9XHJcblxyXG4gIFBpZWNoYXJ0LnByb3RvdHlwZS5fcHJvY2Vzc09wdGlvbnMgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgIG9wdGlvbnMudHlwZSA9IFwiYW5nbGVcIjtcclxuICAgIHJldHVybiBQb2xhcmNoYXJ0LnByb3RvdHlwZS5fcHJvY2Vzc09wdGlvbnMuY2FsbCh0aGlzLCBvcHRpb25zKTtcclxuICB9XHJcblxyXG59KCkpO1xyXG4iLCIvLyBDb3B5cmlnaHQgwqkgMjAxNiBSVEUgUsOpc2VhdSBkZSB0cmFuc3BvcnQgZOKAmcOpbGVjdHJpY2l0w6lcclxuKGZ1bmN0aW9uKCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgdmFyIGQzID0gcmVxdWlyZShcImQzXCIpO1xyXG4gIHZhciBDaGFydCA9IHJlcXVpcmUoXCIuL2NoYXJ0LmpzXCIpO1xyXG5cclxuICBtb2R1bGUuZXhwb3J0cyA9IFBvbGFyY2hhcnQ7XHJcblxyXG4gIFBvbGFyY2hhcnQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDaGFydC5wcm90b3R5cGUpO1xyXG4gIFBvbGFyY2hhcnQucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUG9sYXJjaGFydDtcclxuXHJcbiAgLyoqXHJcbiAgICAqIEBjbGFzcyBQb2xhcmNoYXJ0XHJcbiAgICAqIEBzdW1tYXJ5IFJlcHJlc2VudCBkYXRhIHdpdGggYSBwb2xhciBjaGFydFxyXG4gICAgKiBAZGVzYyBQb2xhciBjaGFydHMgYXJlIG5pY2UgbG9va2luZyBjaGFydHMgZXNwZWNpYWxseSBvbiBhIG1hcCxcclxuICAgICogYnV0IGluZGl2aWR1YWwgdmFsdWVzIGFyZSBoYXJkIHRvIGNvbXBhcmVcclxuICAgICogb24gdGhlc2UgY2hhcnRzOiB0aGUgaHVtYW4gZXllIGlzIGdvb2QgdG8gY29tcGFyZSBsZW5ndGhzLCBidXQgbm90XHJcbiAgICAqIHRvIGNvbXBhcmUgYWdubGVzLCByYWRpdXMgb3IgYXJlYXMuIFBvbGFyIGNoYXJ0cyBzaG91bGQgb25seSBiZSB1c2VkIHdoZW5cclxuICAgICogb25lIHdhbnRzIHRvIHBvaW50IG91dCBxdWFsaXRhdGl2ZSByZXN1bHRzIGFuZCBkb2VzIG5vdCBuZWVkIGEgcHJlY2lzZVxyXG4gICAgKiByZXByZXNlbnRhdGlvbiBvZiBkYXRhLiBBbm90aGVyIGxpbWl0YXRpb24gY29tcGFyZWQgdG8gYmFyY2hhcnRzIGlzIHRoYXRcclxuICAgICogcG9sYXIgY2hhcnRzIGNhbm5vdCByZXByZXNlbnQgbmVnYXRpdmUgdmFsdWVzLlxyXG4gICAgKiBAcGFyYW0ge3N0cmluZ30gZWwgQ1NTIHNlbGVjdG9yIHJlcHJlc2VudGluZyB0aGUgZWxlbWVudCB0aGF0IHdpbGwgaG9sZCB0aGUgY2hhcnQuXHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyW119IGRhdGEgRGF0YSB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cclxuICAgICogQHBhcmFtIHtQb2xhcmNoYXJ0T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zIGNvbnRyb2xpbmcgZ3JhcGhpY2FsIGFzcGVjdHMgb2YgdGhlIGNoYXJ0LlxyXG4gICAgKi9cclxuXHJcbiAgLyoqIEB0eXBlZGVmIHtvYmplY3R9IFBvbGFyY2hhcnRPcHRpb25zXHJcbiAgICAqIEBtZW1iZXJPZiBQb2xhcmNoYXJ0XHJcbiAgICAqIEBwcm9wIHtudW1iZXJ8XCJhdXRvXCJ9IFttYXhWYWx1ZT1cImF1dG9cIl0gTWF4aW11bSB2YWx1ZSBkYXRhIGNvdWxkIHRha2UuSXRcclxuICAgICogaXMgaW1wb3J0YW50IHRvIHNldCB0aGlzIG9wdGlvbiBleHBsaWNpdGVseSBpZiBvbmUgd2FudHMgdG8gY29tcGFyZVxyXG4gICAgKiBjaGFydHMgYW5kIHVzZSB0aGUgc2FtZSBzY2FsZSBvbiBlYWNoIG9uZS4gQnkgZGVmYXVsdCBpdCBlcXVhbHMgdG8gdGhlXHJcbiAgICAqIG1heGltdW0gdmFsdWUgb2YgdGhlIGRhdGEuXHJcbiAgICAqIEBwcm9wIHtcImFyZWFcInxcInJhZGl1c1wifFwiYW5nbGVcIn0gW3R5cGU9XCJhcmVhXCJdIFdoYXQga2luZCBvZiBzY2FsZSB0byB1c2UgdG9cclxuICAgICogcmVwcmVzZW50IHRoZSBkYXRhPyBgYW5nbGVgIHByb2R1Y2VzIGEgcGllIGNoYXJ0IGFuZCBzaG91bGQgYmUgdXNlZCBvbmx5IHRvIHZpc3VhbGl6ZVxyXG4gICAgKiBwcm9wb3J0aW9ucy4gSW4gb3RoZXIgY2FzZXMsIGBhcmVhYCAodGhlIGRlZmF1bHQpIHNob3VsZCBnZW5lcmFsbHkgYmVcclxuICAgICogcHJlZmVyZWQuIGByYWRpdXNgIHNob3VsZCBvbmx5IGJlIHVzZWQgd2hlbiBvbmUgd2FudHMgdG8gbWFnbmlmeSBkaWZmZXJlbmNlcy5cclxuICAgICogQHByb3Age251bWJlcn0gW3dpZHRoPTYwXSBXaWR0aCBvZiB0aGUgY2hhcnQuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9IFtoZWlnaHQ9NjBdIEhlaWdodCBvZiB0aGUgY2hhcnQuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9IFt0cmFuc2l0aW9uVGltZT03NTBdIER1cmF0aW9uIG9mIHRoZSB0cmFuc2l0aW9ucywgaW4gbWlsbGlzZWNvbmRzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nW118ZnVuY3Rpb259W2NvbG9ycz1kMy5zY2hlbWVDYXRlZ29yeTEwXSBFaXRoZXIgYW4gYXJyYXkgb2ZcclxuICAgICogY29sb3JzIG9yIGEgZnVuY3Rpb24gYChkLCBpKSAtPiBjb2xvcmAgd2hlcmUgYGRgIGlzIGEgZGF0YSB2YWx1ZSBhbmQgYGlgXHJcbiAgICAqIGlzIHRoZSBpbmRleCBvZiB0aGUgdmFsdWUuSWYgaXQgaXMgYW4gYXJyYXkgd2l0aCBsZW5ndGggbGVzcyB0aGFuIHRoZSBsZW5ndGhcclxuICAgICogb2YgZGF0YSwgdGhlbiB0aGUgY29sb3JzIGFyZSByZWN5Y2xlZC5cclxuICAgICogQHByb3Age3N0cmluZ1tdfFwibm9uZVwifFwiYXV0b1wifGZ1bmN0aW9ufVtsYWJlbHM9XCJub25lXCJdIExhYmVscyB0byBkaXNwbGF5IGluIHNsaWNlcy5cclxuICAgICogSXQgY2FuIGJlIGFuIGFycmF5IHdpdGggc2FtZSBsZW5ndGggYXMgdGhlIGRhdGEuIEl0IGNhbiBhbHNvIGJlIGEgZnVuY3Rpb25cclxuICAgICogYChkLCBpKSAtPiBsYWJlbFRleHRgIHdoZXJlIGBkYCBpcyBhIGRhdGEgdmFsdWUgYW5kIGBpYFxyXG4gICAgKiBpcyB0aGUgaW5kZXggb2YgdGhlIHZhbHVlLiBGaW5hbGx5IGl0IGNhbiBiZSBlcXVhbCB0byBcIm5vbmVcIiB0byBoaWRlIGxhYmVsc1xyXG4gICAgKiBvciBcImF1dG9cIiB0byBkaXNwbGF5IGluIGEgY29tcGFjdCB3YXkgdmFsdWVzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfHN0cmluZ1tdfFwiYXV0b1wifGZ1bmN0aW9ufVtsYWJlbENvbG9ycz1cImF1dG9cIl0gQ29sb3Igb2YgdGhlIGxhYmVscy5cclxuICAgICogSXQgY2FuIGJlIGEgc2luZ2xlIHZhbHVlIG9yIGFuIGFycmF5IHdpdGggc2FtZSBsZW5ndGggYXMgdGhlIGRhdGEuIEl0IGNhblxyXG4gICAgKiBhbHNvIGJlIGEgZnVuY3Rpb24gYChkLCBpKSAtPiBjb2xvcmAgd2hlcmUgYGRgIGlzIGEgZGF0YSB2YWx1ZSBhbmQgYGlgXHJcbiAgICAqIGlzIHRoZSBpbmRleCBvZiB0aGUgdmFsdWUuIEZpbmFsbHkgaXQgY2FuIGJlIGVxdWFsIHRvIFwiYXV0b1wiLiBJbiB0aGlzIGNhc2UsXHJcbiAgICAqIHRoZSBtb3N0IHJlYWRhYmxlIGNvbG9yIGlzIGNob29zZW4gZGVwZGluZyBvbiB0aGUgY29sb3Igb2YgdGhlIHNsaWNlLlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfVtsYWJlbE1pblNpemU9OF0gTGFiZWwgbWluaW11bSBzaXplIGluIHBpeGVscy4gSWYgdGhlcmUgaXNcclxuICAgICogbm90IGVub3VnaCBzcGFjZSBmb3IgYSBnaXZlbiBsYWJlbCwgdGhlbiBpdCBpcyBoaWRkZW4uXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9W2xhYmVsTWF4U2l6ZT0yNF0gTGFiZWwgbWF4aW11bSBzaXplIGluIHBpeGVscy5cclxuICAgICogQHByb3Age3N0cmluZ31bbGFiZWxDbGFzcz1cIlwiXSBMYWJlbHMgQ1NTIGNsYXNzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfVtzaGFwZUNsYXNzPVwiXCJdIHNsaWNlcyBDU1MgY2xhc3MuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQG1ldGhvZCBzZXREYXRhXHJcbiAgICAqIEBkZXNjIFVwZGF0ZSB0aGUgZGF0YSByZXByZXNlbnRlZCBieSB0aGUgY2hhcnRcclxuICAgICogQGluc3RhbmNlXHJcbiAgICAqIEBtZW1iZXJPZiBQb2xhcmNoYXJ0XHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyW119IGRhdGEgRGF0YSB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHNldE9wdGlvbnNcclxuICAgICogQGRlc2MgVXBkYXRlIHRoZSBncmFwaGljYWwgb3B0aW9ucyBvZiBhIGNoYXJ0XHJcbiAgICAqIEBpbnN0YW5jZVxyXG4gICAgKiBAbWVtYmVyT2YgUG9sYXJjaGFydFxyXG4gICAgKiBAcGFyYW0ge1BvbGFyY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQG1ldGhvZCB1cGRhdGVcclxuICAgICogQGRlc2MgVXBkYXRlIHNpbXVsYXRlbm91c2x5IGRhdGEgYW5kIG9wdGlvbnMgb2YgYSBwb2xhciBjaGFydC5cclxuICAgICogQGluc3RhbmNlXHJcbiAgICAqIEBtZW1iZXJPZiBQb2xhcmNoYXJ0XHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyW119IGRhdGEgRGF0YSB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cclxuICAgICogQHBhcmFtIHtQb2xhcmNoYXJ0T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zIGNvbnRyb2xpbmcgZ3JhcGhpY2FsIGFzcGVjdHMgb2YgdGhlIGNoYXJ0LlxyXG4gICAgKi9cclxuXHJcbiAgZnVuY3Rpb24gUG9sYXJjaGFydChlbCwgZGF0YSwgb3B0aW9ucykge1xyXG4gICAgdmFyIGRlZmF1bHRzID0ge1xyXG4gICAgICB0eXBlOiBcImFyZWFcIixcclxuICAgICAgbWF4VmFsdWU6IFwiYXV0b1wiLFxyXG4gICAgfVxyXG5cclxuICAgIENoYXJ0LmNhbGwodGhpcywgZWwsIGRhdGEsIG9wdGlvbnMsIGRlZmF1bHRzKTtcclxuXHJcbiAgICAvLyBDZW50ZXIgdGhlIGNoYXJ0IGdyb3VwIGluc2lkZSB0aGUgY29udGFpbmVyXHJcbiAgICB0aGlzLl9jaGFydFxyXG4gICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIHRoaXMuX29wdGlvbnMud2lkdGgvMiArIFwiLFwiICsgdGhpcy5fb3B0aW9ucy53aWR0aC8yICsgXCIpXCIpO1xyXG5cclxuICAgIHRoaXMuX2RyYXcoKTtcclxuICB9XHJcblxyXG4gIFBvbGFyY2hhcnQucHJvdG90eXBlLl9wcm9jZXNzT3B0aW9ucyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICAgIG9wdGlvbnMgPSBDaGFydC5wcm90b3R5cGUuX3Byb2Nlc3NPcHRpb25zLmNhbGwodGhpcywgb3B0aW9ucywgdGhpcy5fb3B0aW9ucyk7XHJcblxyXG4gICAgb3B0aW9ucy5oZWlnaHQgPSBvcHRpb25zLndpZHRoO1xyXG5cclxuICAgIGlmIChvcHRpb25zLm1heFZhbHVlID09PSBcImF1dG9cIikge1xyXG4gICAgICBvcHRpb25zLm1heFZhbHVlID0gZDMubWF4KHRoaXMuX2RhdGEpO1xyXG4gICAgfVxyXG4gICAgLy9kZWJ1Z2dlcjtcclxuICAgIHZhciByYWRpdXMgPSBvcHRpb25zLndpZHRoIC8gMjtcclxuICAgIHZhciBwaWUgPSBkMy5waWUoKS5zb3J0KG51bGwpO1xyXG4gICAgdmFyIGFyYyA9IGQzLmFyYygpLmlubmVyUmFkaXVzKDApO1xyXG4gICAgdmFyIHJhZGl1c0Z1bjtcclxuXHJcbiAgICBpZiAob3B0aW9ucy50eXBlID09PSBcImFuZ2xlXCIpIHtcclxuICAgICAgcmFkaXVzRnVuID0gZnVuY3Rpb24oZCkge3JldHVybiByYWRpdXN9XHJcbiAgICAgIHBpZS52YWx1ZShmdW5jdGlvbihkKSB7cmV0dXJuIGR9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJhZGl1c0Z1biA9IG9wdGlvbnMudHlwZSA9PSBcInJhZGl1c1wiID8gZDMuc2NhbGVMaW5lYXIoKSA6IGQzLnNjYWxlUG93KCkuZXhwb25lbnQoMC41KTtcclxuICAgICAgcmFkaXVzRnVuLnJhbmdlKFswLCByYWRpdXNdKVxyXG4gICAgICAgIC5kb21haW4oWzAsIG9wdGlvbnMubWF4VmFsdWVdKTtcclxuICAgICAgcGllLnZhbHVlKGZ1bmN0aW9uKGQpIHtyZXR1cm4gMX0pO1xyXG4gICAgfVxyXG5cclxuICAgIGFyYy5vdXRlclJhZGl1cyhmdW5jdGlvbihkLCBpKSB7cmV0dXJuIHJhZGl1c0Z1bihkLmRhdGEpfSk7XHJcblxyXG4gICAgb3B0aW9ucy5yYWRpdXMgPSByYWRpdXNGdW47XHJcbiAgICBvcHRpb25zLnBpZSA9IHBpZTtcclxuICAgIG9wdGlvbnMuIGFyYyA9IGFyYztcclxuICAgIHJldHVybiBvcHRpb25zO1xyXG4gIH1cclxuXHJcbiAgUG9sYXJjaGFydC5wcm90b3R5cGUuX2RyYXcgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgIENoYXJ0LnByb3RvdHlwZS5fZHJhdy5jYWxsKHRoaXMpO1xyXG5cclxuICAgIC8vIE1vdmUgY2VudGVyIG9mIHRoZSBjaGFydFxyXG4gICAgdGhpcy5fY2hhcnRcclxuICAgICAgLnRyYW5zaXRpb24oKVxyXG4gICAgICAuZHVyYXRpb24oc2VsZi5fb3B0aW9ucy50cmFuc2l0aW9uVGltZSlcclxuICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyBzZWxmLl9vcHRpb25zLndpZHRoLzIgKyBcIixcIiArIHNlbGYuX29wdGlvbnMud2lkdGgvMiArIFwiKVwiKTtcclxuXHJcbiAgICB2YXIgc2xpY2VzID0gdGhpcy5fY2hhcnQuc2VsZWN0QWxsKFwicGF0aFwiKS5kYXRhKHRoaXMuX29wdGlvbnMucGllKHRoaXMuX2RhdGEpKTtcclxuXHJcbiAgICAvLyBJbml0aWFsaXplIG5ldyBzbGljZXNcclxuICAgIHNsaWNlcy5lbnRlcigpXHJcbiAgICAgIC5hcHBlbmQoXCJwYXRoXCIpXHJcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJsZWFmbGV0LWNsaWNrYWJsZVwiKVxyXG4gICAgICAuYXR0cihcImRcIiwgdGhpcy5fb3B0aW9ucy5hcmMpXHJcbiAgICAgIC5hdHRyKFwiZmlsbFwiLCBmdW5jdGlvbihkLCBpKSB7cmV0dXJuIHNlbGYuX29wdGlvbnMuY29sb3JGdW4oZCwgaSl9KVxyXG4gICAgICAuZWFjaChmdW5jdGlvbihkLCBpKSB7XHJcbiAgICAgICAgaWYgKHNlbGYuX2RhdGEubGVuZ3RoID09IDEpIHRoaXMuX2N1cnJlbnQgPSB7c3RhcnRBbmdsZTpkLnN0YXJ0QW5nbGUsIGVuZEFuZ2xlOmQuZW5kQW5nbGUsIGRhdGE6MH1cclxuICAgICAgICBlbHNlIHRoaXMuX2N1cnJlbnQgPSB7c3RhcnRBbmdsZTpkLmVuZEFuZ2xlLCBlbmRBbmdsZTpkLmVuZEFuZ2xlfVxyXG4gICAgICB9KVxyXG4gICAgLy8gVXBkYXRlIHNsaWNlc1xyXG4gICAgICAubWVyZ2Uoc2xpY2VzKVxyXG4gICAgICAuYXR0cihcImNsYXNzXCIsIGZ1bmN0aW9uKGQsIGkpIHtyZXR1cm4gc2VsZi5fb3B0aW9ucy5zaGFwZUNsYXNzKGQuZGF0YSwgaSl9KVxyXG4gICAgICAudHJhbnNpdGlvbigpXHJcbiAgICAgIC5kdXJhdGlvbihzZWxmLl9vcHRpb25zLnRyYW5zaXRpb25UaW1lKVxyXG4gICAgICAuYXR0clR3ZWVuKFwiZFwiLCBhcmNUd2VlbilcclxuICAgICAgLmF0dHIoXCJmaWxsXCIsIGZ1bmN0aW9uKGQsIGkpIHtyZXR1cm4gc2VsZi5fb3B0aW9ucy5jb2xvckZ1bihkLCBpKX0pO1xyXG4gICAgLy8gUmVtb3ZlIHNsaWNlc1xyXG4gICAgc2xpY2VzLmV4aXQoKS5yZW1vdmUoKTtcclxuXHJcbiAgICBmdW5jdGlvbiBhcmNUd2VlbihhKSB7XHJcbiAgICAgIHZhciBpID0gZDMuaW50ZXJwb2xhdGUodGhpcy5fY3VycmVudCwgYSk7XHJcbiAgICAgIHRoaXMuX2N1cnJlbnQgPSBpKDApO1xyXG4gICAgICByZXR1cm4gZnVuY3Rpb24odCkge1xyXG4gICAgICAgIHJldHVybiBzZWxmLl9vcHRpb25zLmFyYyhpKHQpKTtcclxuICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBZGQvdXBkYXRlIGxhYmVsc1xyXG4gICAgLy8gZnVuY3Rpb24oYXJjLCByYWRpdXNGdW4sIGQsIHRyYW5zaXRpb25UaW1lKVxyXG4gICAgdmFyIGluaXRMYWJlbCwgdXBkYXRlTGFiZWw7XHJcbiAgICBpZiAodGhpcy5fZGF0YS5sZW5ndGggPiAxKSB7XHJcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fb3B0aW9ucy5waWUodGhpcy5fZGF0YSk7XHJcbiAgICAgIGluaXRMYWJlbCA9IGZ1bmN0aW9uKGxhYmVsLCBkLCBpKSB7XHJcbiAgICAgICAgbGFiZWwuZmlsbFNsaWNlKHNlbGYuX29wdGlvbnMuYXJjLCBzZWxmLl9vcHRpb25zLnJhZGl1cyhkKSwgZGF0YVtpXSwgMCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHVwZGF0ZUxhYmVsID0gZnVuY3Rpb24obGFiZWwsIGQsIGkpIHtcclxuICAgICAgICBsYWJlbC5maWxsU2xpY2Uoc2VsZi5fb3B0aW9ucy5hcmMsIHNlbGYuX29wdGlvbnMucmFkaXVzKGQpLCBkYXRhW2ldLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9vcHRpb25zLnRyYW5zaXRpb25UaW1lKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaW5pdExhYmVsID0gZnVuY3Rpb24obGFiZWwsIGQsIGkpIHtcclxuICAgICAgICBsYWJlbC5maWxsQ2lyY2xlKHNlbGYuX29wdGlvbnMucmFkaXVzKGQpLCAwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdXBkYXRlTGFiZWwgPSBmdW5jdGlvbihsYWJlbCwgZCwgaSkge1xyXG4gICAgICAgIGxhYmVsLmZpbGxDaXJjbGUoc2VsZi5fb3B0aW9ucy5yYWRpdXMoZCksIHNlbGYuX29wdGlvbnMudHJhbnNpdGlvblRpbWUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fZHJhd0xhYmVscyhpbml0TGFiZWwsIHVwZGF0ZUxhYmVsKTtcclxuICB9XHJcblxyXG59KCkpO1xyXG4iLCIvLyBDb3B5cmlnaHQgwqkgMjAxNiBSVEUgUsOpc2VhdSBkZSB0cmFuc3BvcnQgZOKAmcOpbGVjdHJpY2l0w6lcclxuKGZ1bmN0aW9uKCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgbW9kdWxlLmV4cG9ydHMubWVyZ2VPcHRpb25zID0gbWVyZ2VPcHRpb25zO1xyXG4gIG1vZHVsZS5leHBvcnRzLnRvQXJyYXkgPSB0b0FycmF5O1xyXG4gIG1vZHVsZS5leHBvcnRzLnRvRnVuY3Rpb24gPSB0b0Z1bmN0aW9uO1xyXG4gIG1vZHVsZS5leHBvcnRzLnByZXR0eU51bWJlciA9IHByZXR0eU51bWJlcjtcclxuXHJcbiAgLyoqIE1lcmdlIHRoZSBwcm9wZXJ0aWVzIG9mIHR3byBvYmplY3RzLiBNb3JlIHByZWNpc2VseSwgaWYgYSBwcm9wZXJ0eSBpc1xyXG4gICAgKiBwcmVzZW50IGluIFwiZGVmYXVsdHNcIiBidXQgbm90IGluIFwib3B0aW9uc1wiIGl0IGlzIGNvcGllZCBpbiBvcHRpb25zLiB0aGlzXHJcbiAgICAqIGZ1bmN0aW9uIGlzIHVzZWQgdG8gc3BlY2lmaWVkIGRlZmF1bHQgb3B0aW9ucyBmb3IgYSBmdW5jdGlvbi5cclxuICAgICpcclxuICAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgT3B0aW9uIG9iamVjdFxyXG4gICAgKiBAcGFyYW0ge29iamVjdH0gZGVmYXVsdHMgT2JqZWN0IGNvbnRhaW5pbmcgZGVmYXVsdCB2YWx1ZXMgb2Ygb3B0aW9uc1xyXG4gICAgKlxyXG4gICAgKiBAcmV0dXJuIHtvYmplY3R9IE1lcmdlZCBvYmplY3QuXHJcbiAgICAqL1xyXG4gIGZ1bmN0aW9uIG1lcmdlT3B0aW9ucyhvcHRpb25zLCBkZWZhdWx0cykge1xyXG4gICAgaWYgKG9wdGlvbnMpIG9wdGlvbnMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpKTtcclxuICAgIGVsc2Ugb3B0aW9ucyA9IHt9O1xyXG4gICAgZGVmYXVsdHMgPSBkZWZhdWx0cyB8fCB7fTtcclxuICAgIGZvciAodmFyIG9wdCBpbiBkZWZhdWx0cykge1xyXG4gICAgICBpZiAoZGVmYXVsdHMuaGFzT3duUHJvcGVydHkob3B0KSAmJiAhb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShvcHQpKSB7XHJcbiAgICAgICAgb3B0aW9uc1tvcHRdID0gZGVmYXVsdHNbb3B0XTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG9wdGlvbnM7XHJcbiAgfVxyXG5cclxuICAvKiogQ29udmVydHMgcGFyYW1ldGVyIHRvIEFycmF5LiBVc2VkIHdoZW4gdXNlciB3YW50cyB0byBwYXNzIGEgc2luZ2xlIHZhbHVlLFxyXG4gICAgKiBidXQgYSBmdW5jdGlvbiBleHBlY3RzIGFuIGFycmF5LlxyXG4gICAgKiBAcGFyYW0ge2FueX0geCBBbiBhcnJheSBvciBhIHNjYWxhciB2YWx1ZVxyXG4gICAgKiBAcmV0dXJuIHthbnlbXX1cclxuICAgICogJ3gnIGlmIGl0IGlzIGFuIGFycmF5LCBlbHNlIGFuIGFycmF5IHdpdGggJ3gnIGFzIGl0cyB1bmlxdWVcclxuICAgICogZWxlbWVudC5cclxuICAgICovXHJcbiAgZnVuY3Rpb24gdG9BcnJheSh4KSB7XHJcbiAgICBpZiAoeC5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpIHggPSBbeF07XHJcbiAgICByZXR1cm4geDtcclxuICB9XHJcblxyXG4gIC8qKiBDb252ZXJ0cyBpdHMgYXJndW1lbnQgaW4gYSBmdW5jdGlvbi5cclxuICAgICogQHBhcmFtIHthbnl9IHggQSBmdW5jdGlvbiwgYW4gYXJyYXksIG9yIGEgc2NhbGFyLlxyXG4gICAgKiBAcmV0dXJuIHtmdW5jdGlvbn1cclxuICAgICogLSAneCcgaWYgaXQgaXMgYSBmdW5jdGlvbi5cclxuICAgICogLSBJZiAneCcgaXMgYSBzY2FsYXIsIGl0IHJldHVybnMgYSBmdW5jdGlvbiB0aGF0IGFsd2F5cyByZXR1cm5zICd4J1xyXG4gICAgKiAtIElmICd4JyBpcyBhbiBhcnJheSBpdCByZXR1cm5zIHRoZSBmdW5jdGlvbiAoZCwgaSkgLT4geFtpXVxyXG4gICAgKi9cclxuICBmdW5jdGlvbiB0b0Z1bmN0aW9uKHgpIHtcclxuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gKHgpO1xyXG4gICAgeCA9IHRvQXJyYXkoeCk7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24oZCwgaSkge3JldHVybiB4W2kgJSB4Lmxlbmd0aF19O1xyXG4gIH1cclxuXHJcbiAgLyoqIFRyYW5zZm9ybXMgYSBudW1iZXIgaW4gYSBwcmV0dHkgYW5kIHNtYWxsIHN0cmluZ1xyXG4gICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyXHJcbiAgICAqIEByZXR1cm4ge3N0cmluZ31cclxuICAgICogQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBudW1iZXIuIEl0IG9ubHkga2VlcHMgYXQgbW9zdCAyIGRlY2ltYWxcclxuICAgICogZGlnaXRzIGFuZCBpdCBhZGRzIHN1ZmZpeGVzIFwiS1wiLCBcIk1cIiwgXCJCXCIsIFwiVFwiIGZvciBsYXJnZSB2YWx1ZXMuXHJcbiAgICAqL1xyXG4gIGZ1bmN0aW9uIHByZXR0eU51bWJlcihudW1iZXIpIHtcclxuICAgIGlmIChpc05hTihudW1iZXIpIHx8ICFpc0Zpbml0ZShudW1iZXIpKSByZXR1cm4gXCJcIjtcclxuXHJcbiAgICB2YXIgYWJzVmFsID0gTWF0aC5hYnMobnVtYmVyKTtcclxuICAgIHZhciBzaWduPSBudW1iZXIgPCAwPyBcIi1cIjogXCJcIjtcclxuICAgIHZhciBzY2FsZTtcclxuXHJcbiAgICBpZiggYWJzVmFsIDwgMTAwMCApIHtcclxuICAgICAgICBzY2FsZSA9ICcnO1xyXG4gICAgfSBlbHNlIGlmKCBhYnNWYWwgPCAxMDAwMDAwICkge1xyXG4gICAgICAgIHNjYWxlID0gJ0snO1xyXG4gICAgICAgIGFic1ZhbCA9IGFic1ZhbC8xMDAwO1xyXG5cclxuICAgIH0gZWxzZSBpZiggYWJzVmFsIDwgMTAwMDAwMDAwMCApIHtcclxuICAgICAgICBzY2FsZSA9ICdNJztcclxuICAgICAgICBhYnNWYWwgPSBhYnNWYWwvMTAwMDAwMDtcclxuXHJcbiAgICB9IGVsc2UgaWYoIGFic1ZhbCA8IDEwMDAwMDAwMDAwMDAgKSB7XHJcbiAgICAgICAgc2NhbGUgPSAnQic7XHJcbiAgICAgICAgYWJzVmFsID0gYWJzVmFsLzEwMDAwMDAwMDA7XHJcblxyXG4gICAgfSBlbHNlIGlmKCBhYnNWYWwgPCAxMDAwMDAwMDAwMDAwMDAwICkge1xyXG4gICAgICAgIHNjYWxlID0gJ1QnO1xyXG4gICAgICAgIGFic1ZhbCA9IGFic1ZhbC8xMDAwMDAwMDAwMDAwO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChhYnNWYWwgPiAxMCkgYWJzVmFsID0gcm91bmRUbyhhYnNWYWwpO1xyXG4gICAgZWxzZSBpZiAoYWJzVmFsID4gMSkgYWJzVmFsID0gcm91bmRUbyhhYnNWYWwsIDEwLCB0cnVlKTtcclxuICAgIGVsc2UgYWJzVmFsID0gcm91bmRUbyhhYnNWYWwsIDEwMCwgdHJ1ZSk7XHJcblxyXG4gICAgcmV0dXJuIHNpZ24gKyBhYnNWYWwgKyBzY2FsZTtcclxuICB9XHJcblxyXG4gIC8qKiBSb3VuZCBhIG51bWJlclxyXG4gICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyXHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSB0bzogZGVzaXJlZCBwcmVjaXNpb25cclxuICAgICogQHBhcmFtIHtib29sZWFufSBpbnZlcnNlIElmIHRydWUsIG51bWJlciBpcyByb3VuZGVkIGF0IHRoZSAxIC8gJ3RvJ1xyXG4gICAgKi9cclxuICBmdW5jdGlvbiByb3VuZFRvKG51bWJlciwgdG8sIGludmVyc2UpIHtcclxuICAgIHRvID0gdG8gfHwgMTtcclxuICAgIGlmIChpbnZlcnNlKSByZXR1cm4gTWF0aC5yb3VuZChudW1iZXIgKiB0bykgLyB0bztcclxuICAgIGVsc2UgcmV0dXJuIE1hdGgucm91bmQobnVtYmVyIC8gdG8pICogdG87XHJcbiAgfVxyXG59KCkpO1xyXG4iLCIvLyBUaW55Q29sb3IgdjEuNC4xXG4vLyBodHRwczovL2dpdGh1Yi5jb20vYmdyaW5zL1RpbnlDb2xvclxuLy8gQnJpYW4gR3JpbnN0ZWFkLCBNSVQgTGljZW5zZVxuXG4oZnVuY3Rpb24oTWF0aCkge1xuXG52YXIgdHJpbUxlZnQgPSAvXlxccysvLFxuICAgIHRyaW1SaWdodCA9IC9cXHMrJC8sXG4gICAgdGlueUNvdW50ZXIgPSAwLFxuICAgIG1hdGhSb3VuZCA9IE1hdGgucm91bmQsXG4gICAgbWF0aE1pbiA9IE1hdGgubWluLFxuICAgIG1hdGhNYXggPSBNYXRoLm1heCxcbiAgICBtYXRoUmFuZG9tID0gTWF0aC5yYW5kb207XG5cbmZ1bmN0aW9uIHRpbnljb2xvciAoY29sb3IsIG9wdHMpIHtcblxuICAgIGNvbG9yID0gKGNvbG9yKSA/IGNvbG9yIDogJyc7XG4gICAgb3B0cyA9IG9wdHMgfHwgeyB9O1xuXG4gICAgLy8gSWYgaW5wdXQgaXMgYWxyZWFkeSBhIHRpbnljb2xvciwgcmV0dXJuIGl0c2VsZlxuICAgIGlmIChjb2xvciBpbnN0YW5jZW9mIHRpbnljb2xvcikge1xuICAgICAgIHJldHVybiBjb2xvcjtcbiAgICB9XG4gICAgLy8gSWYgd2UgYXJlIGNhbGxlZCBhcyBhIGZ1bmN0aW9uLCBjYWxsIHVzaW5nIG5ldyBpbnN0ZWFkXG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIHRpbnljb2xvcikpIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aW55Y29sb3IoY29sb3IsIG9wdHMpO1xuICAgIH1cblxuICAgIHZhciByZ2IgPSBpbnB1dFRvUkdCKGNvbG9yKTtcbiAgICB0aGlzLl9vcmlnaW5hbElucHV0ID0gY29sb3IsXG4gICAgdGhpcy5fciA9IHJnYi5yLFxuICAgIHRoaXMuX2cgPSByZ2IuZyxcbiAgICB0aGlzLl9iID0gcmdiLmIsXG4gICAgdGhpcy5fYSA9IHJnYi5hLFxuICAgIHRoaXMuX3JvdW5kQSA9IG1hdGhSb3VuZCgxMDAqdGhpcy5fYSkgLyAxMDAsXG4gICAgdGhpcy5fZm9ybWF0ID0gb3B0cy5mb3JtYXQgfHwgcmdiLmZvcm1hdDtcbiAgICB0aGlzLl9ncmFkaWVudFR5cGUgPSBvcHRzLmdyYWRpZW50VHlwZTtcblxuICAgIC8vIERvbid0IGxldCB0aGUgcmFuZ2Ugb2YgWzAsMjU1XSBjb21lIGJhY2sgaW4gWzAsMV0uXG4gICAgLy8gUG90ZW50aWFsbHkgbG9zZSBhIGxpdHRsZSBiaXQgb2YgcHJlY2lzaW9uIGhlcmUsIGJ1dCB3aWxsIGZpeCBpc3N1ZXMgd2hlcmVcbiAgICAvLyAuNSBnZXRzIGludGVycHJldGVkIGFzIGhhbGYgb2YgdGhlIHRvdGFsLCBpbnN0ZWFkIG9mIGhhbGYgb2YgMVxuICAgIC8vIElmIGl0IHdhcyBzdXBwb3NlZCB0byBiZSAxMjgsIHRoaXMgd2FzIGFscmVhZHkgdGFrZW4gY2FyZSBvZiBieSBgaW5wdXRUb1JnYmBcbiAgICBpZiAodGhpcy5fciA8IDEpIHsgdGhpcy5fciA9IG1hdGhSb3VuZCh0aGlzLl9yKTsgfVxuICAgIGlmICh0aGlzLl9nIDwgMSkgeyB0aGlzLl9nID0gbWF0aFJvdW5kKHRoaXMuX2cpOyB9XG4gICAgaWYgKHRoaXMuX2IgPCAxKSB7IHRoaXMuX2IgPSBtYXRoUm91bmQodGhpcy5fYik7IH1cblxuICAgIHRoaXMuX29rID0gcmdiLm9rO1xuICAgIHRoaXMuX3RjX2lkID0gdGlueUNvdW50ZXIrKztcbn1cblxudGlueWNvbG9yLnByb3RvdHlwZSA9IHtcbiAgICBpc0Rhcms6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRCcmlnaHRuZXNzKCkgPCAxMjg7XG4gICAgfSxcbiAgICBpc0xpZ2h0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmlzRGFyaygpO1xuICAgIH0sXG4gICAgaXNWYWxpZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vaztcbiAgICB9LFxuICAgIGdldE9yaWdpbmFsSW5wdXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX29yaWdpbmFsSW5wdXQ7XG4gICAgfSxcbiAgICBnZXRGb3JtYXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZm9ybWF0O1xuICAgIH0sXG4gICAgZ2V0QWxwaGE6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYTtcbiAgICB9LFxuICAgIGdldEJyaWdodG5lc3M6IGZ1bmN0aW9uKCkge1xuICAgICAgICAvL2h0dHA6Ly93d3cudzMub3JnL1RSL0FFUlQjY29sb3ItY29udHJhc3RcbiAgICAgICAgdmFyIHJnYiA9IHRoaXMudG9SZ2IoKTtcbiAgICAgICAgcmV0dXJuIChyZ2IuciAqIDI5OSArIHJnYi5nICogNTg3ICsgcmdiLmIgKiAxMTQpIC8gMTAwMDtcbiAgICB9LFxuICAgIGdldEx1bWluYW5jZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vaHR0cDovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMtV0NBRzIwLTIwMDgxMjExLyNyZWxhdGl2ZWx1bWluYW5jZWRlZlxuICAgICAgICB2YXIgcmdiID0gdGhpcy50b1JnYigpO1xuICAgICAgICB2YXIgUnNSR0IsIEdzUkdCLCBCc1JHQiwgUiwgRywgQjtcbiAgICAgICAgUnNSR0IgPSByZ2Iuci8yNTU7XG4gICAgICAgIEdzUkdCID0gcmdiLmcvMjU1O1xuICAgICAgICBCc1JHQiA9IHJnYi5iLzI1NTtcblxuICAgICAgICBpZiAoUnNSR0IgPD0gMC4wMzkyOCkge1IgPSBSc1JHQiAvIDEyLjkyO30gZWxzZSB7UiA9IE1hdGgucG93KCgoUnNSR0IgKyAwLjA1NSkgLyAxLjA1NSksIDIuNCk7fVxuICAgICAgICBpZiAoR3NSR0IgPD0gMC4wMzkyOCkge0cgPSBHc1JHQiAvIDEyLjkyO30gZWxzZSB7RyA9IE1hdGgucG93KCgoR3NSR0IgKyAwLjA1NSkgLyAxLjA1NSksIDIuNCk7fVxuICAgICAgICBpZiAoQnNSR0IgPD0gMC4wMzkyOCkge0IgPSBCc1JHQiAvIDEyLjkyO30gZWxzZSB7QiA9IE1hdGgucG93KCgoQnNSR0IgKyAwLjA1NSkgLyAxLjA1NSksIDIuNCk7fVxuICAgICAgICByZXR1cm4gKDAuMjEyNiAqIFIpICsgKDAuNzE1MiAqIEcpICsgKDAuMDcyMiAqIEIpO1xuICAgIH0sXG4gICAgc2V0QWxwaGE6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2EgPSBib3VuZEFscGhhKHZhbHVlKTtcbiAgICAgICAgdGhpcy5fcm91bmRBID0gbWF0aFJvdW5kKDEwMCp0aGlzLl9hKSAvIDEwMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICB0b0hzdjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBoc3YgPSByZ2JUb0hzdih0aGlzLl9yLCB0aGlzLl9nLCB0aGlzLl9iKTtcbiAgICAgICAgcmV0dXJuIHsgaDogaHN2LmggKiAzNjAsIHM6IGhzdi5zLCB2OiBoc3YudiwgYTogdGhpcy5fYSB9O1xuICAgIH0sXG4gICAgdG9Ic3ZTdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgaHN2ID0gcmdiVG9Ic3YodGhpcy5fciwgdGhpcy5fZywgdGhpcy5fYik7XG4gICAgICAgIHZhciBoID0gbWF0aFJvdW5kKGhzdi5oICogMzYwKSwgcyA9IG1hdGhSb3VuZChoc3YucyAqIDEwMCksIHYgPSBtYXRoUm91bmQoaHN2LnYgKiAxMDApO1xuICAgICAgICByZXR1cm4gKHRoaXMuX2EgPT0gMSkgP1xuICAgICAgICAgIFwiaHN2KFwiICArIGggKyBcIiwgXCIgKyBzICsgXCIlLCBcIiArIHYgKyBcIiUpXCIgOlxuICAgICAgICAgIFwiaHN2YShcIiArIGggKyBcIiwgXCIgKyBzICsgXCIlLCBcIiArIHYgKyBcIiUsIFwiKyB0aGlzLl9yb3VuZEEgKyBcIilcIjtcbiAgICB9LFxuICAgIHRvSHNsOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGhzbCA9IHJnYlRvSHNsKHRoaXMuX3IsIHRoaXMuX2csIHRoaXMuX2IpO1xuICAgICAgICByZXR1cm4geyBoOiBoc2wuaCAqIDM2MCwgczogaHNsLnMsIGw6IGhzbC5sLCBhOiB0aGlzLl9hIH07XG4gICAgfSxcbiAgICB0b0hzbFN0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBoc2wgPSByZ2JUb0hzbCh0aGlzLl9yLCB0aGlzLl9nLCB0aGlzLl9iKTtcbiAgICAgICAgdmFyIGggPSBtYXRoUm91bmQoaHNsLmggKiAzNjApLCBzID0gbWF0aFJvdW5kKGhzbC5zICogMTAwKSwgbCA9IG1hdGhSb3VuZChoc2wubCAqIDEwMCk7XG4gICAgICAgIHJldHVybiAodGhpcy5fYSA9PSAxKSA/XG4gICAgICAgICAgXCJoc2woXCIgICsgaCArIFwiLCBcIiArIHMgKyBcIiUsIFwiICsgbCArIFwiJSlcIiA6XG4gICAgICAgICAgXCJoc2xhKFwiICsgaCArIFwiLCBcIiArIHMgKyBcIiUsIFwiICsgbCArIFwiJSwgXCIrIHRoaXMuX3JvdW5kQSArIFwiKVwiO1xuICAgIH0sXG4gICAgdG9IZXg6IGZ1bmN0aW9uKGFsbG93M0NoYXIpIHtcbiAgICAgICAgcmV0dXJuIHJnYlRvSGV4KHRoaXMuX3IsIHRoaXMuX2csIHRoaXMuX2IsIGFsbG93M0NoYXIpO1xuICAgIH0sXG4gICAgdG9IZXhTdHJpbmc6IGZ1bmN0aW9uKGFsbG93M0NoYXIpIHtcbiAgICAgICAgcmV0dXJuICcjJyArIHRoaXMudG9IZXgoYWxsb3czQ2hhcik7XG4gICAgfSxcbiAgICB0b0hleDg6IGZ1bmN0aW9uKGFsbG93NENoYXIpIHtcbiAgICAgICAgcmV0dXJuIHJnYmFUb0hleCh0aGlzLl9yLCB0aGlzLl9nLCB0aGlzLl9iLCB0aGlzLl9hLCBhbGxvdzRDaGFyKTtcbiAgICB9LFxuICAgIHRvSGV4OFN0cmluZzogZnVuY3Rpb24oYWxsb3c0Q2hhcikge1xuICAgICAgICByZXR1cm4gJyMnICsgdGhpcy50b0hleDgoYWxsb3c0Q2hhcik7XG4gICAgfSxcbiAgICB0b1JnYjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7IHI6IG1hdGhSb3VuZCh0aGlzLl9yKSwgZzogbWF0aFJvdW5kKHRoaXMuX2cpLCBiOiBtYXRoUm91bmQodGhpcy5fYiksIGE6IHRoaXMuX2EgfTtcbiAgICB9LFxuICAgIHRvUmdiU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9hID09IDEpID9cbiAgICAgICAgICBcInJnYihcIiAgKyBtYXRoUm91bmQodGhpcy5fcikgKyBcIiwgXCIgKyBtYXRoUm91bmQodGhpcy5fZykgKyBcIiwgXCIgKyBtYXRoUm91bmQodGhpcy5fYikgKyBcIilcIiA6XG4gICAgICAgICAgXCJyZ2JhKFwiICsgbWF0aFJvdW5kKHRoaXMuX3IpICsgXCIsIFwiICsgbWF0aFJvdW5kKHRoaXMuX2cpICsgXCIsIFwiICsgbWF0aFJvdW5kKHRoaXMuX2IpICsgXCIsIFwiICsgdGhpcy5fcm91bmRBICsgXCIpXCI7XG4gICAgfSxcbiAgICB0b1BlcmNlbnRhZ2VSZ2I6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4geyByOiBtYXRoUm91bmQoYm91bmQwMSh0aGlzLl9yLCAyNTUpICogMTAwKSArIFwiJVwiLCBnOiBtYXRoUm91bmQoYm91bmQwMSh0aGlzLl9nLCAyNTUpICogMTAwKSArIFwiJVwiLCBiOiBtYXRoUm91bmQoYm91bmQwMSh0aGlzLl9iLCAyNTUpICogMTAwKSArIFwiJVwiLCBhOiB0aGlzLl9hIH07XG4gICAgfSxcbiAgICB0b1BlcmNlbnRhZ2VSZ2JTdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gKHRoaXMuX2EgPT0gMSkgP1xuICAgICAgICAgIFwicmdiKFwiICArIG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX3IsIDI1NSkgKiAxMDApICsgXCIlLCBcIiArIG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX2csIDI1NSkgKiAxMDApICsgXCIlLCBcIiArIG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX2IsIDI1NSkgKiAxMDApICsgXCIlKVwiIDpcbiAgICAgICAgICBcInJnYmEoXCIgKyBtYXRoUm91bmQoYm91bmQwMSh0aGlzLl9yLCAyNTUpICogMTAwKSArIFwiJSwgXCIgKyBtYXRoUm91bmQoYm91bmQwMSh0aGlzLl9nLCAyNTUpICogMTAwKSArIFwiJSwgXCIgKyBtYXRoUm91bmQoYm91bmQwMSh0aGlzLl9iLCAyNTUpICogMTAwKSArIFwiJSwgXCIgKyB0aGlzLl9yb3VuZEEgKyBcIilcIjtcbiAgICB9LFxuICAgIHRvTmFtZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9hID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJ0cmFuc3BhcmVudFwiO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2EgPCAxKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaGV4TmFtZXNbcmdiVG9IZXgodGhpcy5fciwgdGhpcy5fZywgdGhpcy5fYiwgdHJ1ZSldIHx8IGZhbHNlO1xuICAgIH0sXG4gICAgdG9GaWx0ZXI6IGZ1bmN0aW9uKHNlY29uZENvbG9yKSB7XG4gICAgICAgIHZhciBoZXg4U3RyaW5nID0gJyMnICsgcmdiYVRvQXJnYkhleCh0aGlzLl9yLCB0aGlzLl9nLCB0aGlzLl9iLCB0aGlzLl9hKTtcbiAgICAgICAgdmFyIHNlY29uZEhleDhTdHJpbmcgPSBoZXg4U3RyaW5nO1xuICAgICAgICB2YXIgZ3JhZGllbnRUeXBlID0gdGhpcy5fZ3JhZGllbnRUeXBlID8gXCJHcmFkaWVudFR5cGUgPSAxLCBcIiA6IFwiXCI7XG5cbiAgICAgICAgaWYgKHNlY29uZENvbG9yKSB7XG4gICAgICAgICAgICB2YXIgcyA9IHRpbnljb2xvcihzZWNvbmRDb2xvcik7XG4gICAgICAgICAgICBzZWNvbmRIZXg4U3RyaW5nID0gJyMnICsgcmdiYVRvQXJnYkhleChzLl9yLCBzLl9nLCBzLl9iLCBzLl9hKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBcInByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChcIitncmFkaWVudFR5cGUrXCJzdGFydENvbG9yc3RyPVwiK2hleDhTdHJpbmcrXCIsZW5kQ29sb3JzdHI9XCIrc2Vjb25kSGV4OFN0cmluZytcIilcIjtcbiAgICB9LFxuICAgIHRvU3RyaW5nOiBmdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgdmFyIGZvcm1hdFNldCA9ICEhZm9ybWF0O1xuICAgICAgICBmb3JtYXQgPSBmb3JtYXQgfHwgdGhpcy5fZm9ybWF0O1xuXG4gICAgICAgIHZhciBmb3JtYXR0ZWRTdHJpbmcgPSBmYWxzZTtcbiAgICAgICAgdmFyIGhhc0FscGhhID0gdGhpcy5fYSA8IDEgJiYgdGhpcy5fYSA+PSAwO1xuICAgICAgICB2YXIgbmVlZHNBbHBoYUZvcm1hdCA9ICFmb3JtYXRTZXQgJiYgaGFzQWxwaGEgJiYgKGZvcm1hdCA9PT0gXCJoZXhcIiB8fCBmb3JtYXQgPT09IFwiaGV4NlwiIHx8IGZvcm1hdCA9PT0gXCJoZXgzXCIgfHwgZm9ybWF0ID09PSBcImhleDRcIiB8fCBmb3JtYXQgPT09IFwiaGV4OFwiIHx8IGZvcm1hdCA9PT0gXCJuYW1lXCIpO1xuXG4gICAgICAgIGlmIChuZWVkc0FscGhhRm9ybWF0KSB7XG4gICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIFwidHJhbnNwYXJlbnRcIiwgYWxsIG90aGVyIG5vbi1hbHBoYSBmb3JtYXRzXG4gICAgICAgICAgICAvLyB3aWxsIHJldHVybiByZ2JhIHdoZW4gdGhlcmUgaXMgdHJhbnNwYXJlbmN5LlxuICAgICAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJuYW1lXCIgJiYgdGhpcy5fYSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvTmFtZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9SZ2JTdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9ybWF0ID09PSBcInJnYlwiKSB7XG4gICAgICAgICAgICBmb3JtYXR0ZWRTdHJpbmcgPSB0aGlzLnRvUmdiU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJwcmdiXCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9QZXJjZW50YWdlUmdiU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJoZXhcIiB8fCBmb3JtYXQgPT09IFwiaGV4NlwiKSB7XG4gICAgICAgICAgICBmb3JtYXR0ZWRTdHJpbmcgPSB0aGlzLnRvSGV4U3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJoZXgzXCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9IZXhTdHJpbmcodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJoZXg0XCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9IZXg4U3RyaW5nKHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmb3JtYXQgPT09IFwiaGV4OFwiKSB7XG4gICAgICAgICAgICBmb3JtYXR0ZWRTdHJpbmcgPSB0aGlzLnRvSGV4OFN0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmb3JtYXQgPT09IFwibmFtZVwiKSB7XG4gICAgICAgICAgICBmb3JtYXR0ZWRTdHJpbmcgPSB0aGlzLnRvTmFtZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmb3JtYXQgPT09IFwiaHNsXCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9Ic2xTdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9ybWF0ID09PSBcImhzdlwiKSB7XG4gICAgICAgICAgICBmb3JtYXR0ZWRTdHJpbmcgPSB0aGlzLnRvSHN2U3RyaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm9ybWF0dGVkU3RyaW5nIHx8IHRoaXMudG9IZXhTdHJpbmcoKTtcbiAgICB9LFxuICAgIGNsb25lOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRpbnljb2xvcih0aGlzLnRvU3RyaW5nKCkpO1xuICAgIH0sXG5cbiAgICBfYXBwbHlNb2RpZmljYXRpb246IGZ1bmN0aW9uKGZuLCBhcmdzKSB7XG4gICAgICAgIHZhciBjb2xvciA9IGZuLmFwcGx5KG51bGwsIFt0aGlzXS5jb25jYXQoW10uc2xpY2UuY2FsbChhcmdzKSkpO1xuICAgICAgICB0aGlzLl9yID0gY29sb3IuX3I7XG4gICAgICAgIHRoaXMuX2cgPSBjb2xvci5fZztcbiAgICAgICAgdGhpcy5fYiA9IGNvbG9yLl9iO1xuICAgICAgICB0aGlzLnNldEFscGhhKGNvbG9yLl9hKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBsaWdodGVuOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5TW9kaWZpY2F0aW9uKGxpZ2h0ZW4sIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBicmlnaHRlbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseU1vZGlmaWNhdGlvbihicmlnaHRlbiwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGRhcmtlbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseU1vZGlmaWNhdGlvbihkYXJrZW4sIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBkZXNhdHVyYXRlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5TW9kaWZpY2F0aW9uKGRlc2F0dXJhdGUsIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBzYXR1cmF0ZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseU1vZGlmaWNhdGlvbihzYXR1cmF0ZSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGdyZXlzY2FsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseU1vZGlmaWNhdGlvbihncmV5c2NhbGUsIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBzcGluOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5TW9kaWZpY2F0aW9uKHNwaW4sIGFyZ3VtZW50cyk7XG4gICAgfSxcblxuICAgIF9hcHBseUNvbWJpbmF0aW9uOiBmdW5jdGlvbihmbiwgYXJncykge1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkobnVsbCwgW3RoaXNdLmNvbmNhdChbXS5zbGljZS5jYWxsKGFyZ3MpKSk7XG4gICAgfSxcbiAgICBhbmFsb2dvdXM6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlDb21iaW5hdGlvbihhbmFsb2dvdXMsIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBjb21wbGVtZW50OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5Q29tYmluYXRpb24oY29tcGxlbWVudCwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIG1vbm9jaHJvbWF0aWM6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlDb21iaW5hdGlvbihtb25vY2hyb21hdGljLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgc3BsaXRjb21wbGVtZW50OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5Q29tYmluYXRpb24oc3BsaXRjb21wbGVtZW50LCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgdHJpYWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlDb21iaW5hdGlvbih0cmlhZCwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHRldHJhZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUNvbWJpbmF0aW9uKHRldHJhZCwgYXJndW1lbnRzKTtcbiAgICB9XG59O1xuXG4vLyBJZiBpbnB1dCBpcyBhbiBvYmplY3QsIGZvcmNlIDEgaW50byBcIjEuMFwiIHRvIGhhbmRsZSByYXRpb3MgcHJvcGVybHlcbi8vIFN0cmluZyBpbnB1dCByZXF1aXJlcyBcIjEuMFwiIGFzIGlucHV0LCBzbyAxIHdpbGwgYmUgdHJlYXRlZCBhcyAxXG50aW55Y29sb3IuZnJvbVJhdGlvID0gZnVuY3Rpb24oY29sb3IsIG9wdHMpIHtcbiAgICBpZiAodHlwZW9mIGNvbG9yID09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgdmFyIG5ld0NvbG9yID0ge307XG4gICAgICAgIGZvciAodmFyIGkgaW4gY29sb3IpIHtcbiAgICAgICAgICAgIGlmIChjb2xvci5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgICAgICAgICAgIGlmIChpID09PSBcImFcIikge1xuICAgICAgICAgICAgICAgICAgICBuZXdDb2xvcltpXSA9IGNvbG9yW2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3Q29sb3JbaV0gPSBjb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29sb3IgPSBuZXdDb2xvcjtcbiAgICB9XG5cbiAgICByZXR1cm4gdGlueWNvbG9yKGNvbG9yLCBvcHRzKTtcbn07XG5cbi8vIEdpdmVuIGEgc3RyaW5nIG9yIG9iamVjdCwgY29udmVydCB0aGF0IGlucHV0IHRvIFJHQlxuLy8gUG9zc2libGUgc3RyaW5nIGlucHV0czpcbi8vXG4vLyAgICAgXCJyZWRcIlxuLy8gICAgIFwiI2YwMFwiIG9yIFwiZjAwXCJcbi8vICAgICBcIiNmZjAwMDBcIiBvciBcImZmMDAwMFwiXG4vLyAgICAgXCIjZmYwMDAwMDBcIiBvciBcImZmMDAwMDAwXCJcbi8vICAgICBcInJnYiAyNTUgMCAwXCIgb3IgXCJyZ2IgKDI1NSwgMCwgMClcIlxuLy8gICAgIFwicmdiIDEuMCAwIDBcIiBvciBcInJnYiAoMSwgMCwgMClcIlxuLy8gICAgIFwicmdiYSAoMjU1LCAwLCAwLCAxKVwiIG9yIFwicmdiYSAyNTUsIDAsIDAsIDFcIlxuLy8gICAgIFwicmdiYSAoMS4wLCAwLCAwLCAxKVwiIG9yIFwicmdiYSAxLjAsIDAsIDAsIDFcIlxuLy8gICAgIFwiaHNsKDAsIDEwMCUsIDUwJSlcIiBvciBcImhzbCAwIDEwMCUgNTAlXCJcbi8vICAgICBcImhzbGEoMCwgMTAwJSwgNTAlLCAxKVwiIG9yIFwiaHNsYSAwIDEwMCUgNTAlLCAxXCJcbi8vICAgICBcImhzdigwLCAxMDAlLCAxMDAlKVwiIG9yIFwiaHN2IDAgMTAwJSAxMDAlXCJcbi8vXG5mdW5jdGlvbiBpbnB1dFRvUkdCKGNvbG9yKSB7XG5cbiAgICB2YXIgcmdiID0geyByOiAwLCBnOiAwLCBiOiAwIH07XG4gICAgdmFyIGEgPSAxO1xuICAgIHZhciBzID0gbnVsbDtcbiAgICB2YXIgdiA9IG51bGw7XG4gICAgdmFyIGwgPSBudWxsO1xuICAgIHZhciBvayA9IGZhbHNlO1xuICAgIHZhciBmb3JtYXQgPSBmYWxzZTtcblxuICAgIGlmICh0eXBlb2YgY29sb3IgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICBjb2xvciA9IHN0cmluZ0lucHV0VG9PYmplY3QoY29sb3IpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY29sb3IgPT0gXCJvYmplY3RcIikge1xuICAgICAgICBpZiAoaXNWYWxpZENTU1VuaXQoY29sb3IucikgJiYgaXNWYWxpZENTU1VuaXQoY29sb3IuZykgJiYgaXNWYWxpZENTU1VuaXQoY29sb3IuYikpIHtcbiAgICAgICAgICAgIHJnYiA9IHJnYlRvUmdiKGNvbG9yLnIsIGNvbG9yLmcsIGNvbG9yLmIpO1xuICAgICAgICAgICAgb2sgPSB0cnVlO1xuICAgICAgICAgICAgZm9ybWF0ID0gU3RyaW5nKGNvbG9yLnIpLnN1YnN0cigtMSkgPT09IFwiJVwiID8gXCJwcmdiXCIgOiBcInJnYlwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzVmFsaWRDU1NVbml0KGNvbG9yLmgpICYmIGlzVmFsaWRDU1NVbml0KGNvbG9yLnMpICYmIGlzVmFsaWRDU1NVbml0KGNvbG9yLnYpKSB7XG4gICAgICAgICAgICBzID0gY29udmVydFRvUGVyY2VudGFnZShjb2xvci5zKTtcbiAgICAgICAgICAgIHYgPSBjb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yLnYpO1xuICAgICAgICAgICAgcmdiID0gaHN2VG9SZ2IoY29sb3IuaCwgcywgdik7XG4gICAgICAgICAgICBvayA9IHRydWU7XG4gICAgICAgICAgICBmb3JtYXQgPSBcImhzdlwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzVmFsaWRDU1NVbml0KGNvbG9yLmgpICYmIGlzVmFsaWRDU1NVbml0KGNvbG9yLnMpICYmIGlzVmFsaWRDU1NVbml0KGNvbG9yLmwpKSB7XG4gICAgICAgICAgICBzID0gY29udmVydFRvUGVyY2VudGFnZShjb2xvci5zKTtcbiAgICAgICAgICAgIGwgPSBjb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yLmwpO1xuICAgICAgICAgICAgcmdiID0gaHNsVG9SZ2IoY29sb3IuaCwgcywgbCk7XG4gICAgICAgICAgICBvayA9IHRydWU7XG4gICAgICAgICAgICBmb3JtYXQgPSBcImhzbFwiO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbG9yLmhhc093blByb3BlcnR5KFwiYVwiKSkge1xuICAgICAgICAgICAgYSA9IGNvbG9yLmE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhID0gYm91bmRBbHBoYShhKTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIG9rOiBvayxcbiAgICAgICAgZm9ybWF0OiBjb2xvci5mb3JtYXQgfHwgZm9ybWF0LFxuICAgICAgICByOiBtYXRoTWluKDI1NSwgbWF0aE1heChyZ2IuciwgMCkpLFxuICAgICAgICBnOiBtYXRoTWluKDI1NSwgbWF0aE1heChyZ2IuZywgMCkpLFxuICAgICAgICBiOiBtYXRoTWluKDI1NSwgbWF0aE1heChyZ2IuYiwgMCkpLFxuICAgICAgICBhOiBhXG4gICAgfTtcbn1cblxuXG4vLyBDb252ZXJzaW9uIEZ1bmN0aW9uc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gYHJnYlRvSHNsYCwgYHJnYlRvSHN2YCwgYGhzbFRvUmdiYCwgYGhzdlRvUmdiYCBtb2RpZmllZCBmcm9tOlxuLy8gPGh0dHA6Ly9tamlqYWNrc29uLmNvbS8yMDA4LzAyL3JnYi10by1oc2wtYW5kLXJnYi10by1oc3YtY29sb3ItbW9kZWwtY29udmVyc2lvbi1hbGdvcml0aG1zLWluLWphdmFzY3JpcHQ+XG5cbi8vIGByZ2JUb1JnYmBcbi8vIEhhbmRsZSBib3VuZHMgLyBwZXJjZW50YWdlIGNoZWNraW5nIHRvIGNvbmZvcm0gdG8gQ1NTIGNvbG9yIHNwZWNcbi8vIDxodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLWNvbG9yLz5cbi8vICpBc3N1bWVzOiogciwgZywgYiBpbiBbMCwgMjU1XSBvciBbMCwgMV1cbi8vICpSZXR1cm5zOiogeyByLCBnLCBiIH0gaW4gWzAsIDI1NV1cbmZ1bmN0aW9uIHJnYlRvUmdiKHIsIGcsIGIpe1xuICAgIHJldHVybiB7XG4gICAgICAgIHI6IGJvdW5kMDEociwgMjU1KSAqIDI1NSxcbiAgICAgICAgZzogYm91bmQwMShnLCAyNTUpICogMjU1LFxuICAgICAgICBiOiBib3VuZDAxKGIsIDI1NSkgKiAyNTVcbiAgICB9O1xufVxuXG4vLyBgcmdiVG9Ic2xgXG4vLyBDb252ZXJ0cyBhbiBSR0IgY29sb3IgdmFsdWUgdG8gSFNMLlxuLy8gKkFzc3VtZXM6KiByLCBnLCBhbmQgYiBhcmUgY29udGFpbmVkIGluIFswLCAyNTVdIG9yIFswLCAxXVxuLy8gKlJldHVybnM6KiB7IGgsIHMsIGwgfSBpbiBbMCwxXVxuZnVuY3Rpb24gcmdiVG9Ic2wociwgZywgYikge1xuXG4gICAgciA9IGJvdW5kMDEociwgMjU1KTtcbiAgICBnID0gYm91bmQwMShnLCAyNTUpO1xuICAgIGIgPSBib3VuZDAxKGIsIDI1NSk7XG5cbiAgICB2YXIgbWF4ID0gbWF0aE1heChyLCBnLCBiKSwgbWluID0gbWF0aE1pbihyLCBnLCBiKTtcbiAgICB2YXIgaCwgcywgbCA9IChtYXggKyBtaW4pIC8gMjtcblxuICAgIGlmKG1heCA9PSBtaW4pIHtcbiAgICAgICAgaCA9IHMgPSAwOyAvLyBhY2hyb21hdGljXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgZCA9IG1heCAtIG1pbjtcbiAgICAgICAgcyA9IGwgPiAwLjUgPyBkIC8gKDIgLSBtYXggLSBtaW4pIDogZCAvIChtYXggKyBtaW4pO1xuICAgICAgICBzd2l0Y2gobWF4KSB7XG4gICAgICAgICAgICBjYXNlIHI6IGggPSAoZyAtIGIpIC8gZCArIChnIDwgYiA/IDYgOiAwKTsgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGc6IGggPSAoYiAtIHIpIC8gZCArIDI7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBiOiBoID0gKHIgLSBnKSAvIGQgKyA0OyBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGggLz0gNjtcbiAgICB9XG5cbiAgICByZXR1cm4geyBoOiBoLCBzOiBzLCBsOiBsIH07XG59XG5cbi8vIGBoc2xUb1JnYmBcbi8vIENvbnZlcnRzIGFuIEhTTCBjb2xvciB2YWx1ZSB0byBSR0IuXG4vLyAqQXNzdW1lczoqIGggaXMgY29udGFpbmVkIGluIFswLCAxXSBvciBbMCwgMzYwXSBhbmQgcyBhbmQgbCBhcmUgY29udGFpbmVkIFswLCAxXSBvciBbMCwgMTAwXVxuLy8gKlJldHVybnM6KiB7IHIsIGcsIGIgfSBpbiB0aGUgc2V0IFswLCAyNTVdXG5mdW5jdGlvbiBoc2xUb1JnYihoLCBzLCBsKSB7XG4gICAgdmFyIHIsIGcsIGI7XG5cbiAgICBoID0gYm91bmQwMShoLCAzNjApO1xuICAgIHMgPSBib3VuZDAxKHMsIDEwMCk7XG4gICAgbCA9IGJvdW5kMDEobCwgMTAwKTtcblxuICAgIGZ1bmN0aW9uIGh1ZTJyZ2IocCwgcSwgdCkge1xuICAgICAgICBpZih0IDwgMCkgdCArPSAxO1xuICAgICAgICBpZih0ID4gMSkgdCAtPSAxO1xuICAgICAgICBpZih0IDwgMS82KSByZXR1cm4gcCArIChxIC0gcCkgKiA2ICogdDtcbiAgICAgICAgaWYodCA8IDEvMikgcmV0dXJuIHE7XG4gICAgICAgIGlmKHQgPCAyLzMpIHJldHVybiBwICsgKHEgLSBwKSAqICgyLzMgLSB0KSAqIDY7XG4gICAgICAgIHJldHVybiBwO1xuICAgIH1cblxuICAgIGlmKHMgPT09IDApIHtcbiAgICAgICAgciA9IGcgPSBiID0gbDsgLy8gYWNocm9tYXRpY1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIHEgPSBsIDwgMC41ID8gbCAqICgxICsgcykgOiBsICsgcyAtIGwgKiBzO1xuICAgICAgICB2YXIgcCA9IDIgKiBsIC0gcTtcbiAgICAgICAgciA9IGh1ZTJyZ2IocCwgcSwgaCArIDEvMyk7XG4gICAgICAgIGcgPSBodWUycmdiKHAsIHEsIGgpO1xuICAgICAgICBiID0gaHVlMnJnYihwLCBxLCBoIC0gMS8zKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByOiByICogMjU1LCBnOiBnICogMjU1LCBiOiBiICogMjU1IH07XG59XG5cbi8vIGByZ2JUb0hzdmBcbi8vIENvbnZlcnRzIGFuIFJHQiBjb2xvciB2YWx1ZSB0byBIU1Zcbi8vICpBc3N1bWVzOiogciwgZywgYW5kIGIgYXJlIGNvbnRhaW5lZCBpbiB0aGUgc2V0IFswLCAyNTVdIG9yIFswLCAxXVxuLy8gKlJldHVybnM6KiB7IGgsIHMsIHYgfSBpbiBbMCwxXVxuZnVuY3Rpb24gcmdiVG9Ic3YociwgZywgYikge1xuXG4gICAgciA9IGJvdW5kMDEociwgMjU1KTtcbiAgICBnID0gYm91bmQwMShnLCAyNTUpO1xuICAgIGIgPSBib3VuZDAxKGIsIDI1NSk7XG5cbiAgICB2YXIgbWF4ID0gbWF0aE1heChyLCBnLCBiKSwgbWluID0gbWF0aE1pbihyLCBnLCBiKTtcbiAgICB2YXIgaCwgcywgdiA9IG1heDtcblxuICAgIHZhciBkID0gbWF4IC0gbWluO1xuICAgIHMgPSBtYXggPT09IDAgPyAwIDogZCAvIG1heDtcblxuICAgIGlmKG1heCA9PSBtaW4pIHtcbiAgICAgICAgaCA9IDA7IC8vIGFjaHJvbWF0aWNcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHN3aXRjaChtYXgpIHtcbiAgICAgICAgICAgIGNhc2UgcjogaCA9IChnIC0gYikgLyBkICsgKGcgPCBiID8gNiA6IDApOyBicmVhaztcbiAgICAgICAgICAgIGNhc2UgZzogaCA9IChiIC0gcikgLyBkICsgMjsgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGI6IGggPSAociAtIGcpIC8gZCArIDQ7IGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGggLz0gNjtcbiAgICB9XG4gICAgcmV0dXJuIHsgaDogaCwgczogcywgdjogdiB9O1xufVxuXG4vLyBgaHN2VG9SZ2JgXG4vLyBDb252ZXJ0cyBhbiBIU1YgY29sb3IgdmFsdWUgdG8gUkdCLlxuLy8gKkFzc3VtZXM6KiBoIGlzIGNvbnRhaW5lZCBpbiBbMCwgMV0gb3IgWzAsIDM2MF0gYW5kIHMgYW5kIHYgYXJlIGNvbnRhaW5lZCBpbiBbMCwgMV0gb3IgWzAsIDEwMF1cbi8vICpSZXR1cm5zOiogeyByLCBnLCBiIH0gaW4gdGhlIHNldCBbMCwgMjU1XVxuIGZ1bmN0aW9uIGhzdlRvUmdiKGgsIHMsIHYpIHtcblxuICAgIGggPSBib3VuZDAxKGgsIDM2MCkgKiA2O1xuICAgIHMgPSBib3VuZDAxKHMsIDEwMCk7XG4gICAgdiA9IGJvdW5kMDEodiwgMTAwKTtcblxuICAgIHZhciBpID0gTWF0aC5mbG9vcihoKSxcbiAgICAgICAgZiA9IGggLSBpLFxuICAgICAgICBwID0gdiAqICgxIC0gcyksXG4gICAgICAgIHEgPSB2ICogKDEgLSBmICogcyksXG4gICAgICAgIHQgPSB2ICogKDEgLSAoMSAtIGYpICogcyksXG4gICAgICAgIG1vZCA9IGkgJSA2LFxuICAgICAgICByID0gW3YsIHEsIHAsIHAsIHQsIHZdW21vZF0sXG4gICAgICAgIGcgPSBbdCwgdiwgdiwgcSwgcCwgcF1bbW9kXSxcbiAgICAgICAgYiA9IFtwLCBwLCB0LCB2LCB2LCBxXVttb2RdO1xuXG4gICAgcmV0dXJuIHsgcjogciAqIDI1NSwgZzogZyAqIDI1NSwgYjogYiAqIDI1NSB9O1xufVxuXG4vLyBgcmdiVG9IZXhgXG4vLyBDb252ZXJ0cyBhbiBSR0IgY29sb3IgdG8gaGV4XG4vLyBBc3N1bWVzIHIsIGcsIGFuZCBiIGFyZSBjb250YWluZWQgaW4gdGhlIHNldCBbMCwgMjU1XVxuLy8gUmV0dXJucyBhIDMgb3IgNiBjaGFyYWN0ZXIgaGV4XG5mdW5jdGlvbiByZ2JUb0hleChyLCBnLCBiLCBhbGxvdzNDaGFyKSB7XG5cbiAgICB2YXIgaGV4ID0gW1xuICAgICAgICBwYWQyKG1hdGhSb3VuZChyKS50b1N0cmluZygxNikpLFxuICAgICAgICBwYWQyKG1hdGhSb3VuZChnKS50b1N0cmluZygxNikpLFxuICAgICAgICBwYWQyKG1hdGhSb3VuZChiKS50b1N0cmluZygxNikpXG4gICAgXTtcblxuICAgIC8vIFJldHVybiBhIDMgY2hhcmFjdGVyIGhleCBpZiBwb3NzaWJsZVxuICAgIGlmIChhbGxvdzNDaGFyICYmIGhleFswXS5jaGFyQXQoMCkgPT0gaGV4WzBdLmNoYXJBdCgxKSAmJiBoZXhbMV0uY2hhckF0KDApID09IGhleFsxXS5jaGFyQXQoMSkgJiYgaGV4WzJdLmNoYXJBdCgwKSA9PSBoZXhbMl0uY2hhckF0KDEpKSB7XG4gICAgICAgIHJldHVybiBoZXhbMF0uY2hhckF0KDApICsgaGV4WzFdLmNoYXJBdCgwKSArIGhleFsyXS5jaGFyQXQoMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhleC5qb2luKFwiXCIpO1xufVxuXG4vLyBgcmdiYVRvSGV4YFxuLy8gQ29udmVydHMgYW4gUkdCQSBjb2xvciBwbHVzIGFscGhhIHRyYW5zcGFyZW5jeSB0byBoZXhcbi8vIEFzc3VtZXMgciwgZywgYiBhcmUgY29udGFpbmVkIGluIHRoZSBzZXQgWzAsIDI1NV0gYW5kXG4vLyBhIGluIFswLCAxXS4gUmV0dXJucyBhIDQgb3IgOCBjaGFyYWN0ZXIgcmdiYSBoZXhcbmZ1bmN0aW9uIHJnYmFUb0hleChyLCBnLCBiLCBhLCBhbGxvdzRDaGFyKSB7XG5cbiAgICB2YXIgaGV4ID0gW1xuICAgICAgICBwYWQyKG1hdGhSb3VuZChyKS50b1N0cmluZygxNikpLFxuICAgICAgICBwYWQyKG1hdGhSb3VuZChnKS50b1N0cmluZygxNikpLFxuICAgICAgICBwYWQyKG1hdGhSb3VuZChiKS50b1N0cmluZygxNikpLFxuICAgICAgICBwYWQyKGNvbnZlcnREZWNpbWFsVG9IZXgoYSkpXG4gICAgXTtcblxuICAgIC8vIFJldHVybiBhIDQgY2hhcmFjdGVyIGhleCBpZiBwb3NzaWJsZVxuICAgIGlmIChhbGxvdzRDaGFyICYmIGhleFswXS5jaGFyQXQoMCkgPT0gaGV4WzBdLmNoYXJBdCgxKSAmJiBoZXhbMV0uY2hhckF0KDApID09IGhleFsxXS5jaGFyQXQoMSkgJiYgaGV4WzJdLmNoYXJBdCgwKSA9PSBoZXhbMl0uY2hhckF0KDEpICYmIGhleFszXS5jaGFyQXQoMCkgPT0gaGV4WzNdLmNoYXJBdCgxKSkge1xuICAgICAgICByZXR1cm4gaGV4WzBdLmNoYXJBdCgwKSArIGhleFsxXS5jaGFyQXQoMCkgKyBoZXhbMl0uY2hhckF0KDApICsgaGV4WzNdLmNoYXJBdCgwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaGV4LmpvaW4oXCJcIik7XG59XG5cbi8vIGByZ2JhVG9BcmdiSGV4YFxuLy8gQ29udmVydHMgYW4gUkdCQSBjb2xvciB0byBhbiBBUkdCIEhleDggc3RyaW5nXG4vLyBSYXJlbHkgdXNlZCwgYnV0IHJlcXVpcmVkIGZvciBcInRvRmlsdGVyKClcIlxuZnVuY3Rpb24gcmdiYVRvQXJnYkhleChyLCBnLCBiLCBhKSB7XG5cbiAgICB2YXIgaGV4ID0gW1xuICAgICAgICBwYWQyKGNvbnZlcnREZWNpbWFsVG9IZXgoYSkpLFxuICAgICAgICBwYWQyKG1hdGhSb3VuZChyKS50b1N0cmluZygxNikpLFxuICAgICAgICBwYWQyKG1hdGhSb3VuZChnKS50b1N0cmluZygxNikpLFxuICAgICAgICBwYWQyKG1hdGhSb3VuZChiKS50b1N0cmluZygxNikpXG4gICAgXTtcblxuICAgIHJldHVybiBoZXguam9pbihcIlwiKTtcbn1cblxuLy8gYGVxdWFsc2Bcbi8vIENhbiBiZSBjYWxsZWQgd2l0aCBhbnkgdGlueWNvbG9yIGlucHV0XG50aW55Y29sb3IuZXF1YWxzID0gZnVuY3Rpb24gKGNvbG9yMSwgY29sb3IyKSB7XG4gICAgaWYgKCFjb2xvcjEgfHwgIWNvbG9yMikgeyByZXR1cm4gZmFsc2U7IH1cbiAgICByZXR1cm4gdGlueWNvbG9yKGNvbG9yMSkudG9SZ2JTdHJpbmcoKSA9PSB0aW55Y29sb3IoY29sb3IyKS50b1JnYlN0cmluZygpO1xufTtcblxudGlueWNvbG9yLnJhbmRvbSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aW55Y29sb3IuZnJvbVJhdGlvKHtcbiAgICAgICAgcjogbWF0aFJhbmRvbSgpLFxuICAgICAgICBnOiBtYXRoUmFuZG9tKCksXG4gICAgICAgIGI6IG1hdGhSYW5kb20oKVxuICAgIH0pO1xufTtcblxuXG4vLyBNb2RpZmljYXRpb24gRnVuY3Rpb25zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUaGFua3MgdG8gbGVzcy5qcyBmb3Igc29tZSBvZiB0aGUgYmFzaWNzIGhlcmVcbi8vIDxodHRwczovL2dpdGh1Yi5jb20vY2xvdWRoZWFkL2xlc3MuanMvYmxvYi9tYXN0ZXIvbGliL2xlc3MvZnVuY3Rpb25zLmpzPlxuXG5mdW5jdGlvbiBkZXNhdHVyYXRlKGNvbG9yLCBhbW91bnQpIHtcbiAgICBhbW91bnQgPSAoYW1vdW50ID09PSAwKSA/IDAgOiAoYW1vdW50IHx8IDEwKTtcbiAgICB2YXIgaHNsID0gdGlueWNvbG9yKGNvbG9yKS50b0hzbCgpO1xuICAgIGhzbC5zIC09IGFtb3VudCAvIDEwMDtcbiAgICBoc2wucyA9IGNsYW1wMDEoaHNsLnMpO1xuICAgIHJldHVybiB0aW55Y29sb3IoaHNsKTtcbn1cblxuZnVuY3Rpb24gc2F0dXJhdGUoY29sb3IsIGFtb3VudCkge1xuICAgIGFtb3VudCA9IChhbW91bnQgPT09IDApID8gMCA6IChhbW91bnQgfHwgMTApO1xuICAgIHZhciBoc2wgPSB0aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7XG4gICAgaHNsLnMgKz0gYW1vdW50IC8gMTAwO1xuICAgIGhzbC5zID0gY2xhbXAwMShoc2wucyk7XG4gICAgcmV0dXJuIHRpbnljb2xvcihoc2wpO1xufVxuXG5mdW5jdGlvbiBncmV5c2NhbGUoY29sb3IpIHtcbiAgICByZXR1cm4gdGlueWNvbG9yKGNvbG9yKS5kZXNhdHVyYXRlKDEwMCk7XG59XG5cbmZ1bmN0aW9uIGxpZ2h0ZW4gKGNvbG9yLCBhbW91bnQpIHtcbiAgICBhbW91bnQgPSAoYW1vdW50ID09PSAwKSA/IDAgOiAoYW1vdW50IHx8IDEwKTtcbiAgICB2YXIgaHNsID0gdGlueWNvbG9yKGNvbG9yKS50b0hzbCgpO1xuICAgIGhzbC5sICs9IGFtb3VudCAvIDEwMDtcbiAgICBoc2wubCA9IGNsYW1wMDEoaHNsLmwpO1xuICAgIHJldHVybiB0aW55Y29sb3IoaHNsKTtcbn1cblxuZnVuY3Rpb24gYnJpZ2h0ZW4oY29sb3IsIGFtb3VudCkge1xuICAgIGFtb3VudCA9IChhbW91bnQgPT09IDApID8gMCA6IChhbW91bnQgfHwgMTApO1xuICAgIHZhciByZ2IgPSB0aW55Y29sb3IoY29sb3IpLnRvUmdiKCk7XG4gICAgcmdiLnIgPSBtYXRoTWF4KDAsIG1hdGhNaW4oMjU1LCByZ2IuciAtIG1hdGhSb3VuZCgyNTUgKiAtIChhbW91bnQgLyAxMDApKSkpO1xuICAgIHJnYi5nID0gbWF0aE1heCgwLCBtYXRoTWluKDI1NSwgcmdiLmcgLSBtYXRoUm91bmQoMjU1ICogLSAoYW1vdW50IC8gMTAwKSkpKTtcbiAgICByZ2IuYiA9IG1hdGhNYXgoMCwgbWF0aE1pbigyNTUsIHJnYi5iIC0gbWF0aFJvdW5kKDI1NSAqIC0gKGFtb3VudCAvIDEwMCkpKSk7XG4gICAgcmV0dXJuIHRpbnljb2xvcihyZ2IpO1xufVxuXG5mdW5jdGlvbiBkYXJrZW4gKGNvbG9yLCBhbW91bnQpIHtcbiAgICBhbW91bnQgPSAoYW1vdW50ID09PSAwKSA/IDAgOiAoYW1vdW50IHx8IDEwKTtcbiAgICB2YXIgaHNsID0gdGlueWNvbG9yKGNvbG9yKS50b0hzbCgpO1xuICAgIGhzbC5sIC09IGFtb3VudCAvIDEwMDtcbiAgICBoc2wubCA9IGNsYW1wMDEoaHNsLmwpO1xuICAgIHJldHVybiB0aW55Y29sb3IoaHNsKTtcbn1cblxuLy8gU3BpbiB0YWtlcyBhIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIGFtb3VudCB3aXRoaW4gWy0zNjAsIDM2MF0gaW5kaWNhdGluZyB0aGUgY2hhbmdlIG9mIGh1ZS5cbi8vIFZhbHVlcyBvdXRzaWRlIG9mIHRoaXMgcmFuZ2Ugd2lsbCBiZSB3cmFwcGVkIGludG8gdGhpcyByYW5nZS5cbmZ1bmN0aW9uIHNwaW4oY29sb3IsIGFtb3VudCkge1xuICAgIHZhciBoc2wgPSB0aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7XG4gICAgdmFyIGh1ZSA9IChoc2wuaCArIGFtb3VudCkgJSAzNjA7XG4gICAgaHNsLmggPSBodWUgPCAwID8gMzYwICsgaHVlIDogaHVlO1xuICAgIHJldHVybiB0aW55Y29sb3IoaHNsKTtcbn1cblxuLy8gQ29tYmluYXRpb24gRnVuY3Rpb25zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRoYW5rcyB0byBqUXVlcnkgeENvbG9yIGZvciBzb21lIG9mIHRoZSBpZGVhcyBiZWhpbmQgdGhlc2Vcbi8vIDxodHRwczovL2dpdGh1Yi5jb20vaW5mdXNpb24valF1ZXJ5LXhjb2xvci9ibG9iL21hc3Rlci9qcXVlcnkueGNvbG9yLmpzPlxuXG5mdW5jdGlvbiBjb21wbGVtZW50KGNvbG9yKSB7XG4gICAgdmFyIGhzbCA9IHRpbnljb2xvcihjb2xvcikudG9Ic2woKTtcbiAgICBoc2wuaCA9IChoc2wuaCArIDE4MCkgJSAzNjA7XG4gICAgcmV0dXJuIHRpbnljb2xvcihoc2wpO1xufVxuXG5mdW5jdGlvbiB0cmlhZChjb2xvcikge1xuICAgIHZhciBoc2wgPSB0aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7XG4gICAgdmFyIGggPSBoc2wuaDtcbiAgICByZXR1cm4gW1xuICAgICAgICB0aW55Y29sb3IoY29sb3IpLFxuICAgICAgICB0aW55Y29sb3IoeyBoOiAoaCArIDEyMCkgJSAzNjAsIHM6IGhzbC5zLCBsOiBoc2wubCB9KSxcbiAgICAgICAgdGlueWNvbG9yKHsgaDogKGggKyAyNDApICUgMzYwLCBzOiBoc2wucywgbDogaHNsLmwgfSlcbiAgICBdO1xufVxuXG5mdW5jdGlvbiB0ZXRyYWQoY29sb3IpIHtcbiAgICB2YXIgaHNsID0gdGlueWNvbG9yKGNvbG9yKS50b0hzbCgpO1xuICAgIHZhciBoID0gaHNsLmg7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgdGlueWNvbG9yKGNvbG9yKSxcbiAgICAgICAgdGlueWNvbG9yKHsgaDogKGggKyA5MCkgJSAzNjAsIHM6IGhzbC5zLCBsOiBoc2wubCB9KSxcbiAgICAgICAgdGlueWNvbG9yKHsgaDogKGggKyAxODApICUgMzYwLCBzOiBoc2wucywgbDogaHNsLmwgfSksXG4gICAgICAgIHRpbnljb2xvcih7IGg6IChoICsgMjcwKSAlIDM2MCwgczogaHNsLnMsIGw6IGhzbC5sIH0pXG4gICAgXTtcbn1cblxuZnVuY3Rpb24gc3BsaXRjb21wbGVtZW50KGNvbG9yKSB7XG4gICAgdmFyIGhzbCA9IHRpbnljb2xvcihjb2xvcikudG9Ic2woKTtcbiAgICB2YXIgaCA9IGhzbC5oO1xuICAgIHJldHVybiBbXG4gICAgICAgIHRpbnljb2xvcihjb2xvciksXG4gICAgICAgIHRpbnljb2xvcih7IGg6IChoICsgNzIpICUgMzYwLCBzOiBoc2wucywgbDogaHNsLmx9KSxcbiAgICAgICAgdGlueWNvbG9yKHsgaDogKGggKyAyMTYpICUgMzYwLCBzOiBoc2wucywgbDogaHNsLmx9KVxuICAgIF07XG59XG5cbmZ1bmN0aW9uIGFuYWxvZ291cyhjb2xvciwgcmVzdWx0cywgc2xpY2VzKSB7XG4gICAgcmVzdWx0cyA9IHJlc3VsdHMgfHwgNjtcbiAgICBzbGljZXMgPSBzbGljZXMgfHwgMzA7XG5cbiAgICB2YXIgaHNsID0gdGlueWNvbG9yKGNvbG9yKS50b0hzbCgpO1xuICAgIHZhciBwYXJ0ID0gMzYwIC8gc2xpY2VzO1xuICAgIHZhciByZXQgPSBbdGlueWNvbG9yKGNvbG9yKV07XG5cbiAgICBmb3IgKGhzbC5oID0gKChoc2wuaCAtIChwYXJ0ICogcmVzdWx0cyA+PiAxKSkgKyA3MjApICUgMzYwOyAtLXJlc3VsdHM7ICkge1xuICAgICAgICBoc2wuaCA9IChoc2wuaCArIHBhcnQpICUgMzYwO1xuICAgICAgICByZXQucHVzaCh0aW55Y29sb3IoaHNsKSk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIG1vbm9jaHJvbWF0aWMoY29sb3IsIHJlc3VsdHMpIHtcbiAgICByZXN1bHRzID0gcmVzdWx0cyB8fCA2O1xuICAgIHZhciBoc3YgPSB0aW55Y29sb3IoY29sb3IpLnRvSHN2KCk7XG4gICAgdmFyIGggPSBoc3YuaCwgcyA9IGhzdi5zLCB2ID0gaHN2LnY7XG4gICAgdmFyIHJldCA9IFtdO1xuICAgIHZhciBtb2RpZmljYXRpb24gPSAxIC8gcmVzdWx0cztcblxuICAgIHdoaWxlIChyZXN1bHRzLS0pIHtcbiAgICAgICAgcmV0LnB1c2godGlueWNvbG9yKHsgaDogaCwgczogcywgdjogdn0pKTtcbiAgICAgICAgdiA9ICh2ICsgbW9kaWZpY2F0aW9uKSAlIDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJldDtcbn1cblxuLy8gVXRpbGl0eSBGdW5jdGlvbnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG50aW55Y29sb3IubWl4ID0gZnVuY3Rpb24oY29sb3IxLCBjb2xvcjIsIGFtb3VudCkge1xuICAgIGFtb3VudCA9IChhbW91bnQgPT09IDApID8gMCA6IChhbW91bnQgfHwgNTApO1xuXG4gICAgdmFyIHJnYjEgPSB0aW55Y29sb3IoY29sb3IxKS50b1JnYigpO1xuICAgIHZhciByZ2IyID0gdGlueWNvbG9yKGNvbG9yMikudG9SZ2IoKTtcblxuICAgIHZhciBwID0gYW1vdW50IC8gMTAwO1xuXG4gICAgdmFyIHJnYmEgPSB7XG4gICAgICAgIHI6ICgocmdiMi5yIC0gcmdiMS5yKSAqIHApICsgcmdiMS5yLFxuICAgICAgICBnOiAoKHJnYjIuZyAtIHJnYjEuZykgKiBwKSArIHJnYjEuZyxcbiAgICAgICAgYjogKChyZ2IyLmIgLSByZ2IxLmIpICogcCkgKyByZ2IxLmIsXG4gICAgICAgIGE6ICgocmdiMi5hIC0gcmdiMS5hKSAqIHApICsgcmdiMS5hXG4gICAgfTtcblxuICAgIHJldHVybiB0aW55Y29sb3IocmdiYSk7XG59O1xuXG5cbi8vIFJlYWRhYmlsaXR5IEZ1bmN0aW9uc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyA8aHR0cDovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMtV0NBRzIwLTIwMDgxMjExLyNjb250cmFzdC1yYXRpb2RlZiAoV0NBRyBWZXJzaW9uIDIpXG5cbi8vIGBjb250cmFzdGBcbi8vIEFuYWx5emUgdGhlIDIgY29sb3JzIGFuZCByZXR1cm5zIHRoZSBjb2xvciBjb250cmFzdCBkZWZpbmVkIGJ5IChXQ0FHIFZlcnNpb24gMilcbnRpbnljb2xvci5yZWFkYWJpbGl0eSA9IGZ1bmN0aW9uKGNvbG9yMSwgY29sb3IyKSB7XG4gICAgdmFyIGMxID0gdGlueWNvbG9yKGNvbG9yMSk7XG4gICAgdmFyIGMyID0gdGlueWNvbG9yKGNvbG9yMik7XG4gICAgcmV0dXJuIChNYXRoLm1heChjMS5nZXRMdW1pbmFuY2UoKSxjMi5nZXRMdW1pbmFuY2UoKSkrMC4wNSkgLyAoTWF0aC5taW4oYzEuZ2V0THVtaW5hbmNlKCksYzIuZ2V0THVtaW5hbmNlKCkpKzAuMDUpO1xufTtcblxuLy8gYGlzUmVhZGFibGVgXG4vLyBFbnN1cmUgdGhhdCBmb3JlZ3JvdW5kIGFuZCBiYWNrZ3JvdW5kIGNvbG9yIGNvbWJpbmF0aW9ucyBtZWV0IFdDQUcyIGd1aWRlbGluZXMuXG4vLyBUaGUgdGhpcmQgYXJndW1lbnQgaXMgYW4gb3B0aW9uYWwgT2JqZWN0LlxuLy8gICAgICB0aGUgJ2xldmVsJyBwcm9wZXJ0eSBzdGF0ZXMgJ0FBJyBvciAnQUFBJyAtIGlmIG1pc3Npbmcgb3IgaW52YWxpZCwgaXQgZGVmYXVsdHMgdG8gJ0FBJztcbi8vICAgICAgdGhlICdzaXplJyBwcm9wZXJ0eSBzdGF0ZXMgJ2xhcmdlJyBvciAnc21hbGwnIC0gaWYgbWlzc2luZyBvciBpbnZhbGlkLCBpdCBkZWZhdWx0cyB0byAnc21hbGwnLlxuLy8gSWYgdGhlIGVudGlyZSBvYmplY3QgaXMgYWJzZW50LCBpc1JlYWRhYmxlIGRlZmF1bHRzIHRvIHtsZXZlbDpcIkFBXCIsc2l6ZTpcInNtYWxsXCJ9LlxuXG4vLyAqRXhhbXBsZSpcbi8vICAgIHRpbnljb2xvci5pc1JlYWRhYmxlKFwiIzAwMFwiLCBcIiMxMTFcIikgPT4gZmFsc2Vcbi8vICAgIHRpbnljb2xvci5pc1JlYWRhYmxlKFwiIzAwMFwiLCBcIiMxMTFcIix7bGV2ZWw6XCJBQVwiLHNpemU6XCJsYXJnZVwifSkgPT4gZmFsc2VcbnRpbnljb2xvci5pc1JlYWRhYmxlID0gZnVuY3Rpb24oY29sb3IxLCBjb2xvcjIsIHdjYWcyKSB7XG4gICAgdmFyIHJlYWRhYmlsaXR5ID0gdGlueWNvbG9yLnJlYWRhYmlsaXR5KGNvbG9yMSwgY29sb3IyKTtcbiAgICB2YXIgd2NhZzJQYXJtcywgb3V0O1xuXG4gICAgb3V0ID0gZmFsc2U7XG5cbiAgICB3Y2FnMlBhcm1zID0gdmFsaWRhdGVXQ0FHMlBhcm1zKHdjYWcyKTtcbiAgICBzd2l0Y2ggKHdjYWcyUGFybXMubGV2ZWwgKyB3Y2FnMlBhcm1zLnNpemUpIHtcbiAgICAgICAgY2FzZSBcIkFBc21hbGxcIjpcbiAgICAgICAgY2FzZSBcIkFBQWxhcmdlXCI6XG4gICAgICAgICAgICBvdXQgPSByZWFkYWJpbGl0eSA+PSA0LjU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkFBbGFyZ2VcIjpcbiAgICAgICAgICAgIG91dCA9IHJlYWRhYmlsaXR5ID49IDM7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkFBQXNtYWxsXCI6XG4gICAgICAgICAgICBvdXQgPSByZWFkYWJpbGl0eSA+PSA3O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG5cbn07XG5cbi8vIGBtb3N0UmVhZGFibGVgXG4vLyBHaXZlbiBhIGJhc2UgY29sb3IgYW5kIGEgbGlzdCBvZiBwb3NzaWJsZSBmb3JlZ3JvdW5kIG9yIGJhY2tncm91bmRcbi8vIGNvbG9ycyBmb3IgdGhhdCBiYXNlLCByZXR1cm5zIHRoZSBtb3N0IHJlYWRhYmxlIGNvbG9yLlxuLy8gT3B0aW9uYWxseSByZXR1cm5zIEJsYWNrIG9yIFdoaXRlIGlmIHRoZSBtb3N0IHJlYWRhYmxlIGNvbG9yIGlzIHVucmVhZGFibGUuXG4vLyAqRXhhbXBsZSpcbi8vICAgIHRpbnljb2xvci5tb3N0UmVhZGFibGUodGlueWNvbG9yLm1vc3RSZWFkYWJsZShcIiMxMjNcIiwgW1wiIzEyNFwiLCBcIiMxMjVcIl0se2luY2x1ZGVGYWxsYmFja0NvbG9yczpmYWxzZX0pLnRvSGV4U3RyaW5nKCk7IC8vIFwiIzExMjI1NVwiXG4vLyAgICB0aW55Y29sb3IubW9zdFJlYWRhYmxlKHRpbnljb2xvci5tb3N0UmVhZGFibGUoXCIjMTIzXCIsIFtcIiMxMjRcIiwgXCIjMTI1XCJdLHtpbmNsdWRlRmFsbGJhY2tDb2xvcnM6dHJ1ZX0pLnRvSGV4U3RyaW5nKCk7ICAvLyBcIiNmZmZmZmZcIlxuLy8gICAgdGlueWNvbG9yLm1vc3RSZWFkYWJsZShcIiNhODAxNWFcIiwgW1wiI2ZhZjNmM1wiXSx7aW5jbHVkZUZhbGxiYWNrQ29sb3JzOnRydWUsbGV2ZWw6XCJBQUFcIixzaXplOlwibGFyZ2VcIn0pLnRvSGV4U3RyaW5nKCk7IC8vIFwiI2ZhZjNmM1wiXG4vLyAgICB0aW55Y29sb3IubW9zdFJlYWRhYmxlKFwiI2E4MDE1YVwiLCBbXCIjZmFmM2YzXCJdLHtpbmNsdWRlRmFsbGJhY2tDb2xvcnM6dHJ1ZSxsZXZlbDpcIkFBQVwiLHNpemU6XCJzbWFsbFwifSkudG9IZXhTdHJpbmcoKTsgLy8gXCIjZmZmZmZmXCJcbnRpbnljb2xvci5tb3N0UmVhZGFibGUgPSBmdW5jdGlvbihiYXNlQ29sb3IsIGNvbG9yTGlzdCwgYXJncykge1xuICAgIHZhciBiZXN0Q29sb3IgPSBudWxsO1xuICAgIHZhciBiZXN0U2NvcmUgPSAwO1xuICAgIHZhciByZWFkYWJpbGl0eTtcbiAgICB2YXIgaW5jbHVkZUZhbGxiYWNrQ29sb3JzLCBsZXZlbCwgc2l6ZSA7XG4gICAgYXJncyA9IGFyZ3MgfHwge307XG4gICAgaW5jbHVkZUZhbGxiYWNrQ29sb3JzID0gYXJncy5pbmNsdWRlRmFsbGJhY2tDb2xvcnMgO1xuICAgIGxldmVsID0gYXJncy5sZXZlbDtcbiAgICBzaXplID0gYXJncy5zaXplO1xuXG4gICAgZm9yICh2YXIgaT0gMDsgaSA8IGNvbG9yTGlzdC5sZW5ndGggOyBpKyspIHtcbiAgICAgICAgcmVhZGFiaWxpdHkgPSB0aW55Y29sb3IucmVhZGFiaWxpdHkoYmFzZUNvbG9yLCBjb2xvckxpc3RbaV0pO1xuICAgICAgICBpZiAocmVhZGFiaWxpdHkgPiBiZXN0U2NvcmUpIHtcbiAgICAgICAgICAgIGJlc3RTY29yZSA9IHJlYWRhYmlsaXR5O1xuICAgICAgICAgICAgYmVzdENvbG9yID0gdGlueWNvbG9yKGNvbG9yTGlzdFtpXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGlueWNvbG9yLmlzUmVhZGFibGUoYmFzZUNvbG9yLCBiZXN0Q29sb3IsIHtcImxldmVsXCI6bGV2ZWwsXCJzaXplXCI6c2l6ZX0pIHx8ICFpbmNsdWRlRmFsbGJhY2tDb2xvcnMpIHtcbiAgICAgICAgcmV0dXJuIGJlc3RDb2xvcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGFyZ3MuaW5jbHVkZUZhbGxiYWNrQ29sb3JzPWZhbHNlO1xuICAgICAgICByZXR1cm4gdGlueWNvbG9yLm1vc3RSZWFkYWJsZShiYXNlQ29sb3IsW1wiI2ZmZlwiLCBcIiMwMDBcIl0sYXJncyk7XG4gICAgfVxufTtcblxuXG4vLyBCaWcgTGlzdCBvZiBDb2xvcnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gPGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtY29sb3IvI3N2Zy1jb2xvcj5cbnZhciBuYW1lcyA9IHRpbnljb2xvci5uYW1lcyA9IHtcbiAgICBhbGljZWJsdWU6IFwiZjBmOGZmXCIsXG4gICAgYW50aXF1ZXdoaXRlOiBcImZhZWJkN1wiLFxuICAgIGFxdWE6IFwiMGZmXCIsXG4gICAgYXF1YW1hcmluZTogXCI3ZmZmZDRcIixcbiAgICBhenVyZTogXCJmMGZmZmZcIixcbiAgICBiZWlnZTogXCJmNWY1ZGNcIixcbiAgICBiaXNxdWU6IFwiZmZlNGM0XCIsXG4gICAgYmxhY2s6IFwiMDAwXCIsXG4gICAgYmxhbmNoZWRhbG1vbmQ6IFwiZmZlYmNkXCIsXG4gICAgYmx1ZTogXCIwMGZcIixcbiAgICBibHVldmlvbGV0OiBcIjhhMmJlMlwiLFxuICAgIGJyb3duOiBcImE1MmEyYVwiLFxuICAgIGJ1cmx5d29vZDogXCJkZWI4ODdcIixcbiAgICBidXJudHNpZW5uYTogXCJlYTdlNWRcIixcbiAgICBjYWRldGJsdWU6IFwiNWY5ZWEwXCIsXG4gICAgY2hhcnRyZXVzZTogXCI3ZmZmMDBcIixcbiAgICBjaG9jb2xhdGU6IFwiZDI2OTFlXCIsXG4gICAgY29yYWw6IFwiZmY3ZjUwXCIsXG4gICAgY29ybmZsb3dlcmJsdWU6IFwiNjQ5NWVkXCIsXG4gICAgY29ybnNpbGs6IFwiZmZmOGRjXCIsXG4gICAgY3JpbXNvbjogXCJkYzE0M2NcIixcbiAgICBjeWFuOiBcIjBmZlwiLFxuICAgIGRhcmtibHVlOiBcIjAwMDA4YlwiLFxuICAgIGRhcmtjeWFuOiBcIjAwOGI4YlwiLFxuICAgIGRhcmtnb2xkZW5yb2Q6IFwiYjg4NjBiXCIsXG4gICAgZGFya2dyYXk6IFwiYTlhOWE5XCIsXG4gICAgZGFya2dyZWVuOiBcIjAwNjQwMFwiLFxuICAgIGRhcmtncmV5OiBcImE5YTlhOVwiLFxuICAgIGRhcmtraGFraTogXCJiZGI3NmJcIixcbiAgICBkYXJrbWFnZW50YTogXCI4YjAwOGJcIixcbiAgICBkYXJrb2xpdmVncmVlbjogXCI1NTZiMmZcIixcbiAgICBkYXJrb3JhbmdlOiBcImZmOGMwMFwiLFxuICAgIGRhcmtvcmNoaWQ6IFwiOTkzMmNjXCIsXG4gICAgZGFya3JlZDogXCI4YjAwMDBcIixcbiAgICBkYXJrc2FsbW9uOiBcImU5OTY3YVwiLFxuICAgIGRhcmtzZWFncmVlbjogXCI4ZmJjOGZcIixcbiAgICBkYXJrc2xhdGVibHVlOiBcIjQ4M2Q4YlwiLFxuICAgIGRhcmtzbGF0ZWdyYXk6IFwiMmY0ZjRmXCIsXG4gICAgZGFya3NsYXRlZ3JleTogXCIyZjRmNGZcIixcbiAgICBkYXJrdHVycXVvaXNlOiBcIjAwY2VkMVwiLFxuICAgIGRhcmt2aW9sZXQ6IFwiOTQwMGQzXCIsXG4gICAgZGVlcHBpbms6IFwiZmYxNDkzXCIsXG4gICAgZGVlcHNreWJsdWU6IFwiMDBiZmZmXCIsXG4gICAgZGltZ3JheTogXCI2OTY5NjlcIixcbiAgICBkaW1ncmV5OiBcIjY5Njk2OVwiLFxuICAgIGRvZGdlcmJsdWU6IFwiMWU5MGZmXCIsXG4gICAgZmlyZWJyaWNrOiBcImIyMjIyMlwiLFxuICAgIGZsb3JhbHdoaXRlOiBcImZmZmFmMFwiLFxuICAgIGZvcmVzdGdyZWVuOiBcIjIyOGIyMlwiLFxuICAgIGZ1Y2hzaWE6IFwiZjBmXCIsXG4gICAgZ2FpbnNib3JvOiBcImRjZGNkY1wiLFxuICAgIGdob3N0d2hpdGU6IFwiZjhmOGZmXCIsXG4gICAgZ29sZDogXCJmZmQ3MDBcIixcbiAgICBnb2xkZW5yb2Q6IFwiZGFhNTIwXCIsXG4gICAgZ3JheTogXCI4MDgwODBcIixcbiAgICBncmVlbjogXCIwMDgwMDBcIixcbiAgICBncmVlbnllbGxvdzogXCJhZGZmMmZcIixcbiAgICBncmV5OiBcIjgwODA4MFwiLFxuICAgIGhvbmV5ZGV3OiBcImYwZmZmMFwiLFxuICAgIGhvdHBpbms6IFwiZmY2OWI0XCIsXG4gICAgaW5kaWFucmVkOiBcImNkNWM1Y1wiLFxuICAgIGluZGlnbzogXCI0YjAwODJcIixcbiAgICBpdm9yeTogXCJmZmZmZjBcIixcbiAgICBraGFraTogXCJmMGU2OGNcIixcbiAgICBsYXZlbmRlcjogXCJlNmU2ZmFcIixcbiAgICBsYXZlbmRlcmJsdXNoOiBcImZmZjBmNVwiLFxuICAgIGxhd25ncmVlbjogXCI3Y2ZjMDBcIixcbiAgICBsZW1vbmNoaWZmb246IFwiZmZmYWNkXCIsXG4gICAgbGlnaHRibHVlOiBcImFkZDhlNlwiLFxuICAgIGxpZ2h0Y29yYWw6IFwiZjA4MDgwXCIsXG4gICAgbGlnaHRjeWFuOiBcImUwZmZmZlwiLFxuICAgIGxpZ2h0Z29sZGVucm9keWVsbG93OiBcImZhZmFkMlwiLFxuICAgIGxpZ2h0Z3JheTogXCJkM2QzZDNcIixcbiAgICBsaWdodGdyZWVuOiBcIjkwZWU5MFwiLFxuICAgIGxpZ2h0Z3JleTogXCJkM2QzZDNcIixcbiAgICBsaWdodHBpbms6IFwiZmZiNmMxXCIsXG4gICAgbGlnaHRzYWxtb246IFwiZmZhMDdhXCIsXG4gICAgbGlnaHRzZWFncmVlbjogXCIyMGIyYWFcIixcbiAgICBsaWdodHNreWJsdWU6IFwiODdjZWZhXCIsXG4gICAgbGlnaHRzbGF0ZWdyYXk6IFwiNzg5XCIsXG4gICAgbGlnaHRzbGF0ZWdyZXk6IFwiNzg5XCIsXG4gICAgbGlnaHRzdGVlbGJsdWU6IFwiYjBjNGRlXCIsXG4gICAgbGlnaHR5ZWxsb3c6IFwiZmZmZmUwXCIsXG4gICAgbGltZTogXCIwZjBcIixcbiAgICBsaW1lZ3JlZW46IFwiMzJjZDMyXCIsXG4gICAgbGluZW46IFwiZmFmMGU2XCIsXG4gICAgbWFnZW50YTogXCJmMGZcIixcbiAgICBtYXJvb246IFwiODAwMDAwXCIsXG4gICAgbWVkaXVtYXF1YW1hcmluZTogXCI2NmNkYWFcIixcbiAgICBtZWRpdW1ibHVlOiBcIjAwMDBjZFwiLFxuICAgIG1lZGl1bW9yY2hpZDogXCJiYTU1ZDNcIixcbiAgICBtZWRpdW1wdXJwbGU6IFwiOTM3MGRiXCIsXG4gICAgbWVkaXVtc2VhZ3JlZW46IFwiM2NiMzcxXCIsXG4gICAgbWVkaXVtc2xhdGVibHVlOiBcIjdiNjhlZVwiLFxuICAgIG1lZGl1bXNwcmluZ2dyZWVuOiBcIjAwZmE5YVwiLFxuICAgIG1lZGl1bXR1cnF1b2lzZTogXCI0OGQxY2NcIixcbiAgICBtZWRpdW12aW9sZXRyZWQ6IFwiYzcxNTg1XCIsXG4gICAgbWlkbmlnaHRibHVlOiBcIjE5MTk3MFwiLFxuICAgIG1pbnRjcmVhbTogXCJmNWZmZmFcIixcbiAgICBtaXN0eXJvc2U6IFwiZmZlNGUxXCIsXG4gICAgbW9jY2FzaW46IFwiZmZlNGI1XCIsXG4gICAgbmF2YWpvd2hpdGU6IFwiZmZkZWFkXCIsXG4gICAgbmF2eTogXCIwMDAwODBcIixcbiAgICBvbGRsYWNlOiBcImZkZjVlNlwiLFxuICAgIG9saXZlOiBcIjgwODAwMFwiLFxuICAgIG9saXZlZHJhYjogXCI2YjhlMjNcIixcbiAgICBvcmFuZ2U6IFwiZmZhNTAwXCIsXG4gICAgb3JhbmdlcmVkOiBcImZmNDUwMFwiLFxuICAgIG9yY2hpZDogXCJkYTcwZDZcIixcbiAgICBwYWxlZ29sZGVucm9kOiBcImVlZThhYVwiLFxuICAgIHBhbGVncmVlbjogXCI5OGZiOThcIixcbiAgICBwYWxldHVycXVvaXNlOiBcImFmZWVlZVwiLFxuICAgIHBhbGV2aW9sZXRyZWQ6IFwiZGI3MDkzXCIsXG4gICAgcGFwYXlhd2hpcDogXCJmZmVmZDVcIixcbiAgICBwZWFjaHB1ZmY6IFwiZmZkYWI5XCIsXG4gICAgcGVydTogXCJjZDg1M2ZcIixcbiAgICBwaW5rOiBcImZmYzBjYlwiLFxuICAgIHBsdW06IFwiZGRhMGRkXCIsXG4gICAgcG93ZGVyYmx1ZTogXCJiMGUwZTZcIixcbiAgICBwdXJwbGU6IFwiODAwMDgwXCIsXG4gICAgcmViZWNjYXB1cnBsZTogXCI2NjMzOTlcIixcbiAgICByZWQ6IFwiZjAwXCIsXG4gICAgcm9zeWJyb3duOiBcImJjOGY4ZlwiLFxuICAgIHJveWFsYmx1ZTogXCI0MTY5ZTFcIixcbiAgICBzYWRkbGVicm93bjogXCI4YjQ1MTNcIixcbiAgICBzYWxtb246IFwiZmE4MDcyXCIsXG4gICAgc2FuZHlicm93bjogXCJmNGE0NjBcIixcbiAgICBzZWFncmVlbjogXCIyZThiNTdcIixcbiAgICBzZWFzaGVsbDogXCJmZmY1ZWVcIixcbiAgICBzaWVubmE6IFwiYTA1MjJkXCIsXG4gICAgc2lsdmVyOiBcImMwYzBjMFwiLFxuICAgIHNreWJsdWU6IFwiODdjZWViXCIsXG4gICAgc2xhdGVibHVlOiBcIjZhNWFjZFwiLFxuICAgIHNsYXRlZ3JheTogXCI3MDgwOTBcIixcbiAgICBzbGF0ZWdyZXk6IFwiNzA4MDkwXCIsXG4gICAgc25vdzogXCJmZmZhZmFcIixcbiAgICBzcHJpbmdncmVlbjogXCIwMGZmN2ZcIixcbiAgICBzdGVlbGJsdWU6IFwiNDY4MmI0XCIsXG4gICAgdGFuOiBcImQyYjQ4Y1wiLFxuICAgIHRlYWw6IFwiMDA4MDgwXCIsXG4gICAgdGhpc3RsZTogXCJkOGJmZDhcIixcbiAgICB0b21hdG86IFwiZmY2MzQ3XCIsXG4gICAgdHVycXVvaXNlOiBcIjQwZTBkMFwiLFxuICAgIHZpb2xldDogXCJlZTgyZWVcIixcbiAgICB3aGVhdDogXCJmNWRlYjNcIixcbiAgICB3aGl0ZTogXCJmZmZcIixcbiAgICB3aGl0ZXNtb2tlOiBcImY1ZjVmNVwiLFxuICAgIHllbGxvdzogXCJmZjBcIixcbiAgICB5ZWxsb3dncmVlbjogXCI5YWNkMzJcIlxufTtcblxuLy8gTWFrZSBpdCBlYXN5IHRvIGFjY2VzcyBjb2xvcnMgdmlhIGBoZXhOYW1lc1toZXhdYFxudmFyIGhleE5hbWVzID0gdGlueWNvbG9yLmhleE5hbWVzID0gZmxpcChuYW1lcyk7XG5cblxuLy8gVXRpbGl0aWVzXG4vLyAtLS0tLS0tLS1cblxuLy8gYHsgJ25hbWUxJzogJ3ZhbDEnIH1gIGJlY29tZXMgYHsgJ3ZhbDEnOiAnbmFtZTEnIH1gXG5mdW5jdGlvbiBmbGlwKG8pIHtcbiAgICB2YXIgZmxpcHBlZCA9IHsgfTtcbiAgICBmb3IgKHZhciBpIGluIG8pIHtcbiAgICAgICAgaWYgKG8uaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgICAgICAgIGZsaXBwZWRbb1tpXV0gPSBpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmbGlwcGVkO1xufVxuXG4vLyBSZXR1cm4gYSB2YWxpZCBhbHBoYSB2YWx1ZSBbMCwxXSB3aXRoIGFsbCBpbnZhbGlkIHZhbHVlcyBiZWluZyBzZXQgdG8gMVxuZnVuY3Rpb24gYm91bmRBbHBoYShhKSB7XG4gICAgYSA9IHBhcnNlRmxvYXQoYSk7XG5cbiAgICBpZiAoaXNOYU4oYSkgfHwgYSA8IDAgfHwgYSA+IDEpIHtcbiAgICAgICAgYSA9IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIGE7XG59XG5cbi8vIFRha2UgaW5wdXQgZnJvbSBbMCwgbl0gYW5kIHJldHVybiBpdCBhcyBbMCwgMV1cbmZ1bmN0aW9uIGJvdW5kMDEobiwgbWF4KSB7XG4gICAgaWYgKGlzT25lUG9pbnRaZXJvKG4pKSB7IG4gPSBcIjEwMCVcIjsgfVxuXG4gICAgdmFyIHByb2Nlc3NQZXJjZW50ID0gaXNQZXJjZW50YWdlKG4pO1xuICAgIG4gPSBtYXRoTWluKG1heCwgbWF0aE1heCgwLCBwYXJzZUZsb2F0KG4pKSk7XG5cbiAgICAvLyBBdXRvbWF0aWNhbGx5IGNvbnZlcnQgcGVyY2VudGFnZSBpbnRvIG51bWJlclxuICAgIGlmIChwcm9jZXNzUGVyY2VudCkge1xuICAgICAgICBuID0gcGFyc2VJbnQobiAqIG1heCwgMTApIC8gMTAwO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBmbG9hdGluZyBwb2ludCByb3VuZGluZyBlcnJvcnNcbiAgICBpZiAoKE1hdGguYWJzKG4gLSBtYXgpIDwgMC4wMDAwMDEpKSB7XG4gICAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIC8vIENvbnZlcnQgaW50byBbMCwgMV0gcmFuZ2UgaWYgaXQgaXNuJ3QgYWxyZWFkeVxuICAgIHJldHVybiAobiAlIG1heCkgLyBwYXJzZUZsb2F0KG1heCk7XG59XG5cbi8vIEZvcmNlIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMVxuZnVuY3Rpb24gY2xhbXAwMSh2YWwpIHtcbiAgICByZXR1cm4gbWF0aE1pbigxLCBtYXRoTWF4KDAsIHZhbCkpO1xufVxuXG4vLyBQYXJzZSBhIGJhc2UtMTYgaGV4IHZhbHVlIGludG8gYSBiYXNlLTEwIGludGVnZXJcbmZ1bmN0aW9uIHBhcnNlSW50RnJvbUhleCh2YWwpIHtcbiAgICByZXR1cm4gcGFyc2VJbnQodmFsLCAxNik7XG59XG5cbi8vIE5lZWQgdG8gaGFuZGxlIDEuMCBhcyAxMDAlLCBzaW5jZSBvbmNlIGl0IGlzIGEgbnVtYmVyLCB0aGVyZSBpcyBubyBkaWZmZXJlbmNlIGJldHdlZW4gaXQgYW5kIDFcbi8vIDxodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzc0MjIwNzIvamF2YXNjcmlwdC1ob3ctdG8tZGV0ZWN0LW51bWJlci1hcy1hLWRlY2ltYWwtaW5jbHVkaW5nLTEtMD5cbmZ1bmN0aW9uIGlzT25lUG9pbnRaZXJvKG4pIHtcbiAgICByZXR1cm4gdHlwZW9mIG4gPT0gXCJzdHJpbmdcIiAmJiBuLmluZGV4T2YoJy4nKSAhPSAtMSAmJiBwYXJzZUZsb2F0KG4pID09PSAxO1xufVxuXG4vLyBDaGVjayB0byBzZWUgaWYgc3RyaW5nIHBhc3NlZCBpbiBpcyBhIHBlcmNlbnRhZ2VcbmZ1bmN0aW9uIGlzUGVyY2VudGFnZShuKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBuID09PSBcInN0cmluZ1wiICYmIG4uaW5kZXhPZignJScpICE9IC0xO1xufVxuXG4vLyBGb3JjZSBhIGhleCB2YWx1ZSB0byBoYXZlIDIgY2hhcmFjdGVyc1xuZnVuY3Rpb24gcGFkMihjKSB7XG4gICAgcmV0dXJuIGMubGVuZ3RoID09IDEgPyAnMCcgKyBjIDogJycgKyBjO1xufVxuXG4vLyBSZXBsYWNlIGEgZGVjaW1hbCB3aXRoIGl0J3MgcGVyY2VudGFnZSB2YWx1ZVxuZnVuY3Rpb24gY29udmVydFRvUGVyY2VudGFnZShuKSB7XG4gICAgaWYgKG4gPD0gMSkge1xuICAgICAgICBuID0gKG4gKiAxMDApICsgXCIlXCI7XG4gICAgfVxuXG4gICAgcmV0dXJuIG47XG59XG5cbi8vIENvbnZlcnRzIGEgZGVjaW1hbCB0byBhIGhleCB2YWx1ZVxuZnVuY3Rpb24gY29udmVydERlY2ltYWxUb0hleChkKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQocGFyc2VGbG9hdChkKSAqIDI1NSkudG9TdHJpbmcoMTYpO1xufVxuLy8gQ29udmVydHMgYSBoZXggdmFsdWUgdG8gYSBkZWNpbWFsXG5mdW5jdGlvbiBjb252ZXJ0SGV4VG9EZWNpbWFsKGgpIHtcbiAgICByZXR1cm4gKHBhcnNlSW50RnJvbUhleChoKSAvIDI1NSk7XG59XG5cbnZhciBtYXRjaGVycyA9IChmdW5jdGlvbigpIHtcblxuICAgIC8vIDxodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLXZhbHVlcy8jaW50ZWdlcnM+XG4gICAgdmFyIENTU19JTlRFR0VSID0gXCJbLVxcXFwrXT9cXFxcZCslP1wiO1xuXG4gICAgLy8gPGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtdmFsdWVzLyNudW1iZXItdmFsdWU+XG4gICAgdmFyIENTU19OVU1CRVIgPSBcIlstXFxcXCtdP1xcXFxkKlxcXFwuXFxcXGQrJT9cIjtcblxuICAgIC8vIEFsbG93IHBvc2l0aXZlL25lZ2F0aXZlIGludGVnZXIvbnVtYmVyLiAgRG9uJ3QgY2FwdHVyZSB0aGUgZWl0aGVyL29yLCBqdXN0IHRoZSBlbnRpcmUgb3V0Y29tZS5cbiAgICB2YXIgQ1NTX1VOSVQgPSBcIig/OlwiICsgQ1NTX05VTUJFUiArIFwiKXwoPzpcIiArIENTU19JTlRFR0VSICsgXCIpXCI7XG5cbiAgICAvLyBBY3R1YWwgbWF0Y2hpbmcuXG4gICAgLy8gUGFyZW50aGVzZXMgYW5kIGNvbW1hcyBhcmUgb3B0aW9uYWwsIGJ1dCBub3QgcmVxdWlyZWQuXG4gICAgLy8gV2hpdGVzcGFjZSBjYW4gdGFrZSB0aGUgcGxhY2Ugb2YgY29tbWFzIG9yIG9wZW5pbmcgcGFyZW5cbiAgICB2YXIgUEVSTUlTU0lWRV9NQVRDSDMgPSBcIltcXFxcc3xcXFxcKF0rKFwiICsgQ1NTX1VOSVQgKyBcIilbLHxcXFxcc10rKFwiICsgQ1NTX1VOSVQgKyBcIilbLHxcXFxcc10rKFwiICsgQ1NTX1VOSVQgKyBcIilcXFxccypcXFxcKT9cIjtcbiAgICB2YXIgUEVSTUlTU0lWRV9NQVRDSDQgPSBcIltcXFxcc3xcXFxcKF0rKFwiICsgQ1NTX1VOSVQgKyBcIilbLHxcXFxcc10rKFwiICsgQ1NTX1VOSVQgKyBcIilbLHxcXFxcc10rKFwiICsgQ1NTX1VOSVQgKyBcIilbLHxcXFxcc10rKFwiICsgQ1NTX1VOSVQgKyBcIilcXFxccypcXFxcKT9cIjtcblxuICAgIHJldHVybiB7XG4gICAgICAgIENTU19VTklUOiBuZXcgUmVnRXhwKENTU19VTklUKSxcbiAgICAgICAgcmdiOiBuZXcgUmVnRXhwKFwicmdiXCIgKyBQRVJNSVNTSVZFX01BVENIMyksXG4gICAgICAgIHJnYmE6IG5ldyBSZWdFeHAoXCJyZ2JhXCIgKyBQRVJNSVNTSVZFX01BVENINCksXG4gICAgICAgIGhzbDogbmV3IFJlZ0V4cChcImhzbFwiICsgUEVSTUlTU0lWRV9NQVRDSDMpLFxuICAgICAgICBoc2xhOiBuZXcgUmVnRXhwKFwiaHNsYVwiICsgUEVSTUlTU0lWRV9NQVRDSDQpLFxuICAgICAgICBoc3Y6IG5ldyBSZWdFeHAoXCJoc3ZcIiArIFBFUk1JU1NJVkVfTUFUQ0gzKSxcbiAgICAgICAgaHN2YTogbmV3IFJlZ0V4cChcImhzdmFcIiArIFBFUk1JU1NJVkVfTUFUQ0g0KSxcbiAgICAgICAgaGV4MzogL14jPyhbMC05YS1mQS1GXXsxfSkoWzAtOWEtZkEtRl17MX0pKFswLTlhLWZBLUZdezF9KSQvLFxuICAgICAgICBoZXg2OiAvXiM/KFswLTlhLWZBLUZdezJ9KShbMC05YS1mQS1GXXsyfSkoWzAtOWEtZkEtRl17Mn0pJC8sXG4gICAgICAgIGhleDQ6IC9eIz8oWzAtOWEtZkEtRl17MX0pKFswLTlhLWZBLUZdezF9KShbMC05YS1mQS1GXXsxfSkoWzAtOWEtZkEtRl17MX0pJC8sXG4gICAgICAgIGhleDg6IC9eIz8oWzAtOWEtZkEtRl17Mn0pKFswLTlhLWZBLUZdezJ9KShbMC05YS1mQS1GXXsyfSkoWzAtOWEtZkEtRl17Mn0pJC9cbiAgICB9O1xufSkoKTtcblxuLy8gYGlzVmFsaWRDU1NVbml0YFxuLy8gVGFrZSBpbiBhIHNpbmdsZSBzdHJpbmcgLyBudW1iZXIgYW5kIGNoZWNrIHRvIHNlZSBpZiBpdCBsb29rcyBsaWtlIGEgQ1NTIHVuaXRcbi8vIChzZWUgYG1hdGNoZXJzYCBhYm92ZSBmb3IgZGVmaW5pdGlvbikuXG5mdW5jdGlvbiBpc1ZhbGlkQ1NTVW5pdChjb2xvcikge1xuICAgIHJldHVybiAhIW1hdGNoZXJzLkNTU19VTklULmV4ZWMoY29sb3IpO1xufVxuXG4vLyBgc3RyaW5nSW5wdXRUb09iamVjdGBcbi8vIFBlcm1pc3NpdmUgc3RyaW5nIHBhcnNpbmcuICBUYWtlIGluIGEgbnVtYmVyIG9mIGZvcm1hdHMsIGFuZCBvdXRwdXQgYW4gb2JqZWN0XG4vLyBiYXNlZCBvbiBkZXRlY3RlZCBmb3JtYXQuICBSZXR1cm5zIGB7IHIsIGcsIGIgfWAgb3IgYHsgaCwgcywgbCB9YCBvciBgeyBoLCBzLCB2fWBcbmZ1bmN0aW9uIHN0cmluZ0lucHV0VG9PYmplY3QoY29sb3IpIHtcblxuICAgIGNvbG9yID0gY29sb3IucmVwbGFjZSh0cmltTGVmdCwnJykucmVwbGFjZSh0cmltUmlnaHQsICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBuYW1lZCA9IGZhbHNlO1xuICAgIGlmIChuYW1lc1tjb2xvcl0pIHtcbiAgICAgICAgY29sb3IgPSBuYW1lc1tjb2xvcl07XG4gICAgICAgIG5hbWVkID0gdHJ1ZTtcbiAgICB9XG4gICAgZWxzZSBpZiAoY29sb3IgPT0gJ3RyYW5zcGFyZW50Jykge1xuICAgICAgICByZXR1cm4geyByOiAwLCBnOiAwLCBiOiAwLCBhOiAwLCBmb3JtYXQ6IFwibmFtZVwiIH07XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIG1hdGNoIHN0cmluZyBpbnB1dCB1c2luZyByZWd1bGFyIGV4cHJlc3Npb25zLlxuICAgIC8vIEtlZXAgbW9zdCBvZiB0aGUgbnVtYmVyIGJvdW5kaW5nIG91dCBvZiB0aGlzIGZ1bmN0aW9uIC0gZG9uJ3Qgd29ycnkgYWJvdXQgWzAsMV0gb3IgWzAsMTAwXSBvciBbMCwzNjBdXG4gICAgLy8gSnVzdCByZXR1cm4gYW4gb2JqZWN0IGFuZCBsZXQgdGhlIGNvbnZlcnNpb24gZnVuY3Rpb25zIGhhbmRsZSB0aGF0LlxuICAgIC8vIFRoaXMgd2F5IHRoZSByZXN1bHQgd2lsbCBiZSB0aGUgc2FtZSB3aGV0aGVyIHRoZSB0aW55Y29sb3IgaXMgaW5pdGlhbGl6ZWQgd2l0aCBzdHJpbmcgb3Igb2JqZWN0LlxuICAgIHZhciBtYXRjaDtcbiAgICBpZiAoKG1hdGNoID0gbWF0Y2hlcnMucmdiLmV4ZWMoY29sb3IpKSkge1xuICAgICAgICByZXR1cm4geyByOiBtYXRjaFsxXSwgZzogbWF0Y2hbMl0sIGI6IG1hdGNoWzNdIH07XG4gICAgfVxuICAgIGlmICgobWF0Y2ggPSBtYXRjaGVycy5yZ2JhLmV4ZWMoY29sb3IpKSkge1xuICAgICAgICByZXR1cm4geyByOiBtYXRjaFsxXSwgZzogbWF0Y2hbMl0sIGI6IG1hdGNoWzNdLCBhOiBtYXRjaFs0XSB9O1xuICAgIH1cbiAgICBpZiAoKG1hdGNoID0gbWF0Y2hlcnMuaHNsLmV4ZWMoY29sb3IpKSkge1xuICAgICAgICByZXR1cm4geyBoOiBtYXRjaFsxXSwgczogbWF0Y2hbMl0sIGw6IG1hdGNoWzNdIH07XG4gICAgfVxuICAgIGlmICgobWF0Y2ggPSBtYXRjaGVycy5oc2xhLmV4ZWMoY29sb3IpKSkge1xuICAgICAgICByZXR1cm4geyBoOiBtYXRjaFsxXSwgczogbWF0Y2hbMl0sIGw6IG1hdGNoWzNdLCBhOiBtYXRjaFs0XSB9O1xuICAgIH1cbiAgICBpZiAoKG1hdGNoID0gbWF0Y2hlcnMuaHN2LmV4ZWMoY29sb3IpKSkge1xuICAgICAgICByZXR1cm4geyBoOiBtYXRjaFsxXSwgczogbWF0Y2hbMl0sIHY6IG1hdGNoWzNdIH07XG4gICAgfVxuICAgIGlmICgobWF0Y2ggPSBtYXRjaGVycy5oc3ZhLmV4ZWMoY29sb3IpKSkge1xuICAgICAgICByZXR1cm4geyBoOiBtYXRjaFsxXSwgczogbWF0Y2hbMl0sIHY6IG1hdGNoWzNdLCBhOiBtYXRjaFs0XSB9O1xuICAgIH1cbiAgICBpZiAoKG1hdGNoID0gbWF0Y2hlcnMuaGV4OC5leGVjKGNvbG9yKSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHI6IHBhcnNlSW50RnJvbUhleChtYXRjaFsxXSksXG4gICAgICAgICAgICBnOiBwYXJzZUludEZyb21IZXgobWF0Y2hbMl0pLFxuICAgICAgICAgICAgYjogcGFyc2VJbnRGcm9tSGV4KG1hdGNoWzNdKSxcbiAgICAgICAgICAgIGE6IGNvbnZlcnRIZXhUb0RlY2ltYWwobWF0Y2hbNF0pLFxuICAgICAgICAgICAgZm9ybWF0OiBuYW1lZCA/IFwibmFtZVwiIDogXCJoZXg4XCJcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKChtYXRjaCA9IG1hdGNoZXJzLmhleDYuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByOiBwYXJzZUludEZyb21IZXgobWF0Y2hbMV0pLFxuICAgICAgICAgICAgZzogcGFyc2VJbnRGcm9tSGV4KG1hdGNoWzJdKSxcbiAgICAgICAgICAgIGI6IHBhcnNlSW50RnJvbUhleChtYXRjaFszXSksXG4gICAgICAgICAgICBmb3JtYXQ6IG5hbWVkID8gXCJuYW1lXCIgOiBcImhleFwiXG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmICgobWF0Y2ggPSBtYXRjaGVycy5oZXg0LmV4ZWMoY29sb3IpKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcjogcGFyc2VJbnRGcm9tSGV4KG1hdGNoWzFdICsgJycgKyBtYXRjaFsxXSksXG4gICAgICAgICAgICBnOiBwYXJzZUludEZyb21IZXgobWF0Y2hbMl0gKyAnJyArIG1hdGNoWzJdKSxcbiAgICAgICAgICAgIGI6IHBhcnNlSW50RnJvbUhleChtYXRjaFszXSArICcnICsgbWF0Y2hbM10pLFxuICAgICAgICAgICAgYTogY29udmVydEhleFRvRGVjaW1hbChtYXRjaFs0XSArICcnICsgbWF0Y2hbNF0pLFxuICAgICAgICAgICAgZm9ybWF0OiBuYW1lZCA/IFwibmFtZVwiIDogXCJoZXg4XCJcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKChtYXRjaCA9IG1hdGNoZXJzLmhleDMuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByOiBwYXJzZUludEZyb21IZXgobWF0Y2hbMV0gKyAnJyArIG1hdGNoWzFdKSxcbiAgICAgICAgICAgIGc6IHBhcnNlSW50RnJvbUhleChtYXRjaFsyXSArICcnICsgbWF0Y2hbMl0pLFxuICAgICAgICAgICAgYjogcGFyc2VJbnRGcm9tSGV4KG1hdGNoWzNdICsgJycgKyBtYXRjaFszXSksXG4gICAgICAgICAgICBmb3JtYXQ6IG5hbWVkID8gXCJuYW1lXCIgOiBcImhleFwiXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVdDQUcyUGFybXMocGFybXMpIHtcbiAgICAvLyByZXR1cm4gdmFsaWQgV0NBRzIgcGFybXMgZm9yIGlzUmVhZGFibGUuXG4gICAgLy8gSWYgaW5wdXQgcGFybXMgYXJlIGludmFsaWQsIHJldHVybiB7XCJsZXZlbFwiOlwiQUFcIiwgXCJzaXplXCI6XCJzbWFsbFwifVxuICAgIHZhciBsZXZlbCwgc2l6ZTtcbiAgICBwYXJtcyA9IHBhcm1zIHx8IHtcImxldmVsXCI6XCJBQVwiLCBcInNpemVcIjpcInNtYWxsXCJ9O1xuICAgIGxldmVsID0gKHBhcm1zLmxldmVsIHx8IFwiQUFcIikudG9VcHBlckNhc2UoKTtcbiAgICBzaXplID0gKHBhcm1zLnNpemUgfHwgXCJzbWFsbFwiKS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChsZXZlbCAhPT0gXCJBQVwiICYmIGxldmVsICE9PSBcIkFBQVwiKSB7XG4gICAgICAgIGxldmVsID0gXCJBQVwiO1xuICAgIH1cbiAgICBpZiAoc2l6ZSAhPT0gXCJzbWFsbFwiICYmIHNpemUgIT09IFwibGFyZ2VcIikge1xuICAgICAgICBzaXplID0gXCJzbWFsbFwiO1xuICAgIH1cbiAgICByZXR1cm4ge1wibGV2ZWxcIjpsZXZlbCwgXCJzaXplXCI6c2l6ZX07XG59XG5cbi8vIE5vZGU6IEV4cG9ydCBmdW5jdGlvblxuaWYgKHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHRpbnljb2xvcjtcbn1cbi8vIEFNRC9yZXF1aXJlanM6IERlZmluZSB0aGUgbW9kdWxlXG5lbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICBkZWZpbmUoZnVuY3Rpb24gKCkge3JldHVybiB0aW55Y29sb3I7fSk7XG59XG4vLyBCcm93c2VyOiBFeHBvc2UgdG8gd2luZG93XG5lbHNlIHtcbiAgICB3aW5kb3cudGlueWNvbG9yID0gdGlueWNvbG9yO1xufVxuXG59KShNYXRoKTtcbiIsIi8vIENvcHlyaWdodCDCqSAyMDE2IFJURSBSw6lzZWF1IGRlIHRyYW5zcG9ydCBk4oCZw6lsZWN0cmljaXTDqVxyXG4oZnVuY3Rpb24oKSB7XHJcbiAgdmFyIGQzID0gcmVxdWlyZShcImQzXCIpO1xyXG4gIHZhciBtaW5pY2hhcnRzID0gcmVxdWlyZShcIm1pbmljaGFydHNcIik7XHJcbiAgdmFyIHV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHMuanNcIik7XHJcblxyXG4gIEwuTWluaWNoYXJ0ID0gTC5DaXJjbGVNYXJrZXIuZXh0ZW5kKHtcclxuICAgIC8qKiBPcHRpb25zIHVzZWQgdG8gaW5pdGlhbGl6ZS91cGRhdGUgYSBNaW5pY2hhcnQgb2JqZWN0LlxyXG4gICAgICAqIEB0eXBlZGVmIHtvYmplY3R9IE1pbmljaGFydE9wdGlvbnNcclxuICAgICAgKiBAbWVtYmVyT2YgJ0wuTWluaWNoYXJ0J1xyXG4gICAgICAqIEBwcm9wIHtzdHJpbmd9IFt0eXBlID0gXCJiYXJcIl1cclxuICAgICAgKiBUeXBlIG9mIGNoYXJ0IHRvIGNyZWF0ZS4gUG9zc2libGUgdmFsdWVzIGFyZSBcImJhclwiIGZvciBiYXJjaGFydHMsIFwicGllXCJcclxuICAgICAgKiBmb3IgcGllIGNoYXJ0cywgXCJwb2xhci1yYWRpdXNcIiBhbmQgXCJwb2xhci1hcmVhXCIgZm9yIHBvbGFyIGFyZWEgY2hhcnRzXHJcbiAgICAgICogd2hlcmUgdmFsdWVzIGFyZSByZXByZXNlbnRlZCBlaXRoZXIgYnkgdGhlIHJhZGl1cyBvciB0aGUgYXJlYSBvZiB0aGVcclxuICAgICAgKiBzbGljZXMuXHJcbiAgICAgICogQHByb3Age251bWJlcltdfSBbZGF0YSA9IFsxXV1cclxuICAgICAgKiBEYXRhIHZhbHVlcyB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cclxuICAgICAgKiBAcHJvcCB7bnVtYmVyW118XCJhdXRvXCJ9IFttYXhWYWx1ZXMgPSBcImF1dG9cIl1cclxuICAgICAgKiBtYXhpbWFsIGFic29sdXRlIHZhbHVlIHRoZSBkYXRhIGNvdWxkIHRha2UuIEl0IGNhbiBiZSBhIHNpbmdsZSBudW1lcmljXHJcbiAgICAgICogdmFsdWUgb3IgYW4gYXJyYXkgb2YgdmFsdWVzIHdpdGggc2FtZSBsZW5ndGggYXMgZGF0YS4gSW4gdGhlIGZpcnN0IGNhc2UsXHJcbiAgICAgICogYWxsIHZhbHVlcyB3aWxsIGJlIHJlcHJlc2VudGVkIHdpdGggdGhlIHNhbWUgc2NhbGUgd2hpbGUgaW4gdGhlIHNlY29uZFxyXG4gICAgICAqIGNhc2UsIGVhY2ggdmFsdWUgd2lsbCBoYXZlIGl0cyBvd24gc2NhbGUuIFRoaXMgaXMgdXNlZnVsIHdoZW4gb25lIHdhbnRzXHJcbiAgICAgICogdG8gcmVwcmVzZW50IG11bHRpcGxlIHZhcmlhYmxlcyB0aGF0IGFyZSBub3QgY29tcGFyYWJsZS4gSWYgaXQgZXF1YWxzIHRvXHJcbiAgICAgICogXCJhdXRvXCIgKHRoZSBkZWZhdWx0KSB0aGVuIHRoZSBtYXhpbXVtIGFic29sdXRlIHZhbHVlIGluIGRhdGEgaXMgdXNlZC5cclxuICAgICAgKiBAcHJvcCB7c3RyaW5nW119IFtjb2xvcnM9ZDMuc2NoZW1lQ2F0ZWdvcnkxMF0gQXJyYXkgb2YgY29sb3JzLiBJZiBpdHNcclxuICAgICAgKiBsZW5ndGggaXMgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2YgZGF0YSwgY29sb3JzIGFyZSByZWN5Y2xlZC5cclxuICAgICAgKiBAcHJvcCB7bnVtYmVyfSBbd2lkdGg9NjBdXHJcbiAgICAgICogV2lkdGggb2YgdGhlIGNoYXJ0IHdoZW4gYHR5cGVgIGVxdWFscyAnYmFyJyBvciBtYXhpbWFsIGRpYW1ldGVyIG9mIHRoZVxyXG4gICAgICAqIGNoYXJ0IGZvciBhbGwgb3RoZXIgdHlwZXMuXHJcbiAgICAgICogQHByb3Age251bWJlcn0gW2hlaWdodD02MF1cclxuICAgICAgKiBNYXhpbWFsIGhlaWdodCBvZiBiYXJjaGFydHMuXHJcbiAgICAgICogQHByb3Age3N0cmluZ1tdfFwibm9uZVwifFwiYXV0b1wifVtsYWJlbHM9XCJub25lXCJdXHJcbiAgICAgICogTGFiZWxzIHRvIGRpc3BsYXkgb24gdGhlIGNoYXJ0LiBJZiBpdCBlcXVhbHMgdG8gXCJhdXRvXCIgdGhlbiBkYXRhIHZhbHVlc1xyXG4gICAgICAqIGFyZSBkaXNwbGF5ZWQgaW4gYSBjb21wYWN0IHdheS5cclxuICAgICAgKiBAcHJvcCB7bnVtYmVyfSBbbGFiZWxNaW5TaXplPThdXHJcbiAgICAgICogTGFiZWxzIGFyZSBhdXRvbWF0aWNhbGx5IGhpZGRlbiBpZiB0aGUgbGFiZWwgaGVpZ2h0IGlzIGxlc3MgdGhhbiB0aGlzIG51bWJlci5cclxuICAgICAgKiBAcHJvcCB7bnVtYmVyfSBbbGFiZWxNYXhTaXplPTI0XVxyXG4gICAgICAqIE1heGltYWwgaGVpZ2h0IG9mIGxhYmVscyBpbiBwaXhlbHMuXHJcbiAgICAgICogQHByb3Age251bWJlcn0gW2xhYmVsUGFkZGluZz0yXVxyXG4gICAgICAqIFBhZGRpbmcgdG8gYXBwbHkgdG8gbGFiZWxzLlxyXG4gICAgICAqIEBwcm9wIHtzdHJpbmd9IFtsYWJlbFN0eWxlPVwiZm9udC1mYW1pbHk6c2Fucy1zZXJpZlwiXVxyXG4gICAgICAqIENTUyBzdHlsZSB0byBhcHBseSB0byBsYWJlbHNcclxuICAgICAgKiBAcHJvcCB7c3RyaW5nfSBbbGFiZWxDb2xvcj1cImF1dG9cIl1cclxuICAgICAgKiBDb2xvciB0byBhcHBseSB0byBsYWJlbHMuIElmIFwiYXV0b1wiLCB0ZXh0IHdpbGwgYmUgYmxhY2sgb3Igd2hpdGVcclxuICAgICAgKiBkZXBlbmRpbmcgb24gdGhlIGJhY2tncm91bmQgY29sb3IuXHJcbiAgICAgICogQHByb3Age251bWJlcn0gW3RyYW5zaXRpb25UaW1lPTc1MF1cclxuICAgICAgKiBEdXJhdGlvbiBpbiBtaWxsaXNlY29uZHEgb2YgdHJhbnNpdGlvbnMuXHJcbiAgICAgICpcclxuICAgICAgKi9cclxuICAgIG9wdGlvbnM6IHtcclxuICAgICAgdHlwZTogXCJiYXJcIixcclxuICAgICAgZGF0YTogWzFdLFxyXG4gICAgICBtYXhWYWx1ZXM6IFwiYXV0b1wiLFxyXG4gICAgICBjb2xvcnM6IGQzLnNjaGVtZUNhdGVnb3J5MTAsXHJcbiAgICAgIHdpZHRoOiA2MCxcclxuICAgICAgaGVpZ2h0OiA2MCxcclxuICAgICAgb3BhY2l0eTogMSxcclxuICAgICAgbGFiZWxzOlwibm9uZVwiLFxyXG4gICAgICBsYWJlbE1pblNpemU6IDgsXHJcbiAgICAgIGxhYmVsTWF4U2l6ZTogMjQsXHJcbiAgICAgIGxhYmVsUGFkZGluZzogMixcclxuICAgICAgbGFiZWxDb2xvcjogXCJhdXRvXCIsXHJcbiAgICAgIGxhYmVsU3R5bGU6IFwiZm9udC1mYW1pbHk6c2Fucy1zZXJpZlwiLFxyXG4gICAgICB0cmFuc2l0aW9uVGltZTogNzUwXHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICAqIEBjbGFzcyAnTC5NaW5pY2hhcnQnXHJcbiAgICAgICogQHN1bW1hcnkgYWRkIGFkZCBiYXIsIHBpZSBhbmQgcG9sYXIgY2hhcnRzIHRvIGEgbGVhZmxldCBtYXBcclxuICAgICAgKiBAZGVzYyBMLk1pbmljaGFydCBpcyB1c2VkIHRvIGFkZCBkeW5hbWljIGNoYXJ0cyBvbiBhIGxlYWZsZXQgbWFwLiBJdCBpcyBzcGVjaWFsbHlcclxuICAgICAgKiB1c2VmdWwgdG8gcmVwcmVzZW50IG11bHRpcGxlIGRhdGEgdmFsdWVzIGFzc29jaWF0ZWQgdG8gc29tZSBnZW9ncmFwaGljYWxcclxuICAgICAgKiBjb29yZGluYXRlcy5cclxuICAgICAgKlxyXG4gICAgICAqIEBleGFtcGxlXHJcbiAgICAgICpcclxuICAgICAgKiBMLm1pbmljaGFydChbMCwgMF0sIHtkYXRhOiBbMSwgMiwgM10sIG1heFZhbHVlczogM30pXHJcbiAgICAgICpcclxuICAgICAgKiBAcGFyYW0ge0wuUG9pbnR9IGNlbnRlclxyXG4gICAgICAqIEBwYXJhbSB7TWluaWNoYXJ0T3B0aW9uc30gb3B0aW9ucyAtIE9iamVjdCBjb250YWluaW5nXHJcbiAgICAgICogb3B0aW9ucyB0byBjb25zdHJ1Y3QgYSBjaGFydC5cclxuICAgICAgKi9cclxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKGNlbnRlciwgb3B0aW9ucykge1xyXG4gICAgICB0aGlzLl9jZW50ZXIgPSBjZW50ZXI7XHJcbiAgICAgIHRoaXMuX3pvb20gPSAwO1xyXG4gICAgICB0aGlzLm9wdGlvbnMgPSB1dGlscy5tZXJnZU9wdGlvbnMob3B0aW9ucywgdGhpcy5vcHRpb25zKTtcclxuICAgICAgTC5DaXJjbGVNYXJrZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbChcclxuICAgICAgICB0aGlzLFxyXG4gICAgICAgIGNlbnRlcixcclxuICAgICAgICB7cmFkaXVzOiB0aGlzLm9wdGlvbnMud2lkdGgvMiwgc3Ryb2tlOiBmYWxzZSwgZmlsbDogZmFsc2V9XHJcbiAgICAgICk7XHJcbiAgICB9LFxyXG5cclxuICAgIG9uQWRkOiBmdW5jdGlvbihtYXApIHtcclxuICAgICAgTC5DaXJjbGVNYXJrZXIucHJvdG90eXBlLm9uQWRkLmNhbGwodGhpcywgbWFwKTtcclxuICAgICAgLy8gQ2hhbmdlIGNsYXNzIG9mIGNvbnRhaW5lciBzbyB0aGF0IHRoZSBlbGVtZW50IGhpZGVzIHdoZW4gem9vbWluZ1xyXG4gICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyIHx8IHRoaXMuX3JlbmRlcmVyLl9jb250YWluZXI7XHJcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBcImxlYWZsZXQtem9vbS1oaWRlXCIpO1xyXG5cclxuICAgICAgLy8gY3JlYXRlIHRoZSBzdmcgZWxlbWVudCB0aGF0IGhvbGRzIHRoZSBjaGFydFxyXG4gICAgICB0aGlzLl9jaGFydCA9IGQzLnNlbGVjdChjb250YWluZXIpLmFwcGVuZChcImdcIik7XHJcblxyXG4gICAgICBtYXAub24oJ21vdmVlbmQnLCB0aGlzLl9vbk1vdmVlbmQsIHRoaXMpO1xyXG4gICAgICB0aGlzLl9yZWRyYXcodHJ1ZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIG9uUmVtb3ZlOiBmdW5jdGlvbihtYXApIHtcclxuICAgICAgLy8gcmVtb3ZlIGxheWVyJ3MgRE9NIGVsZW1lbnRzIGFuZCBsaXN0ZW5lcnNcclxuICAgICAgTC5DaXJjbGVNYXJrZXIucHJvdG90eXBlLm9uUmVtb3ZlLmNhbGwodGhpcywgbWFwKTtcclxuICAgICAgbWFwLm9mZignbW92ZWVuZCcsIHRoaXMuX29uTW92ZWVuZCwgdGhpcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIF9vbk1vdmVlbmQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAvLyBSZWRyYXcgY2hhcnQgb25seSBpZiB6b29tIGhhcyBjaGFuZ2VkXHJcbiAgICAgIHZhciBvbGRab29tID0gdGhpcy5fem9vbTtcclxuICAgICAgdGhpcy5fem9vbSA9IHRoaXMuX21hcC5nZXRab29tKCk7XHJcbiAgICAgIGlmIChvbGRab29tICE9IHRoaXMuX3pvb20pIHRoaXMuX3JlZHJhdygpIDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqIFVwZGF0ZSB0aGUgb3B0aW9ucyBvZiBhIG1pbmljaGFydCBvYmplY3QuXHJcbiAgICAgICogQG1ldGhvZCBzZXRPcHRpb25zXHJcbiAgICAgICogQGluc3RhbmNlXHJcbiAgICAgICogQG1lbWJlck9mICdMLk1pbmljaGFydCdcclxuICAgICAgKlxyXG4gICAgICAqIEBwYXJhbSB7TWluaWNoYXJ0T3B0aW9uc30gb3B0aW9ucyAtIE9iamVjdCBjb250YWluaW5nIG9wdGlvbnMgdG8gdXBkYXRlIHRoZSBjaGFydC5cclxuICAgICAgKi9cclxuICAgIHNldE9wdGlvbnM6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICAgICAgdmFyIG5ld0NoYXJ0ID0gb3B0aW9ucy50eXBlICYmIG9wdGlvbnMudHlwZSAhPSB0aGlzLm9wdGlvbnMudHlwZTtcclxuICAgICAgdGhpcy5vcHRpb25zID0gdXRpbHMubWVyZ2VPcHRpb25zKG9wdGlvbnMsIHRoaXMub3B0aW9ucyk7XHJcbiAgICAgIHRoaXMuX3JlZHJhdyhuZXdDaGFydCk7XHJcbiAgICB9LFxyXG5cclxuICAgIF9yZWRyYXc6IGZ1bmN0aW9uKG5ld0NoYXJ0KSB7XHJcbiAgICAgIC8vIE1vdmUgY29udGFpbmVyIG9uIHRoZSBtYXBcclxuICAgICAgdmFyIGMgPSB0aGlzLl9tYXAubGF0TG5nVG9MYXllclBvaW50KHRoaXMuX2NlbnRlcik7XHJcbiAgICAgIHZhciBoO1xyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnR5cGUgPT0gXCJiYXJcIikge1xyXG4gICAgICAgIGggPSB0aGlzLm9wdGlvbnMuaGVpZ2h0ICogMjtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBoID0gdGhpcy5vcHRpb25zLndpZHRoO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuX2NoYXJ0XHJcbiAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAoYy54IC0gdGhpcy5vcHRpb25zLndpZHRoIC8gMikgKyBcIixcIiArIChjLnkgLSBoIC8gMikgKyBcIilcIilcclxuICAgICAgICAudHJhbnNpdGlvbigpXHJcbiAgICAgICAgLmR1cmF0aW9uKHRoaXMub3B0aW9ucy50cmFuc2l0aW9uVGltZSlcclxuICAgICAgICAuYXR0cihcIm9wYWNpdHlcIiwgdGhpcy5vcHRpb25zLm9wYWNpdHkpO1xyXG5cclxuICAgICAgLy8gcHJlcGFyZSBkYXRhXHJcbiAgICAgIHZhciBkYXRhID0gdGhpcy5vcHRpb25zLmRhdGE7XHJcbiAgICAgIGRhdGEgPSB1dGlscy50b0FycmF5KGRhdGEpO1xyXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAoaXNOYU4oZGF0YVtpXSkgfHwgIWlzRmluaXRlKGRhdGFbaV0pKSBkYXRhW2ldID0gMDtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gTWF4IGFic29sdXRlIHZhbHVlIGZvciBlYWNoIHZhcmlhYmxlXHJcbiAgICAgIHZhciBtYXggPSB0aGlzLm9wdGlvbnMubWF4VmFsdWVzO1xyXG4gICAgICBpZiAobWF4ID09PSBcImF1dG9cIikge1xyXG4gICAgICAgIG1heCA9IE1hdGgubWF4KFxyXG4gICAgICAgICAgZDMubWF4KGRhdGEpLFxyXG4gICAgICAgICAgTWF0aC5hYnMoZDMubWluKGRhdGEpKVxyXG4gICAgICAgIClcclxuICAgICAgfVxyXG4gICAgICBtYXggPSB1dGlscy50b0FycmF5KG1heCk7XHJcblxyXG4gICAgICBpZihtYXgubGVuZ3RoICE9PSAxICYmIG1heC5sZW5ndGggIT0gZGF0YS5sZW5ndGgpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCInbWF4VmFsdWVzJyBzaG91bGQgYmUgYSBzaW5nbGUgbnVtYmVyIG9yIGhhdmUgc2FtZSBsZW5ndGggYXMgJ2RhdGEnXCIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBTY2FsZSBkYXRhLiBUaGlzIHN0ZXAgaXMgZXNzZW50aWFsIHRvIGhhdmUgZGlmZmVyZW50IHNjYWxlcyBmb3IgZWFjaFxyXG4gICAgICAvLyB2YXJpYWJsZS4gT25seSByZWxldmFudCBpZiBjaGFydCBpcyBub3QgYSBwaWUvXHJcbiAgICAgIHZhciBkYXRhU2NhbGVkID0gW107XHJcblxyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnR5cGUgPT0gXCJwaWVcIikge1xyXG4gICAgICAgIGRhdGFTY2FsZWQgPSBkYXRhO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgZGF0YVNjYWxlZC5wdXNoKGRhdGFbaV0gLyBtYXhbaSAlIG1heC5sZW5ndGhdKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIFByZXBhcmUgbGFiZWxzXHJcbiAgICAgIHZhciBsYWJlbHMgPSB0aGlzLm9wdGlvbnMubGFiZWxzO1xyXG4gICAgICBpZiAobGFiZWxzID09PSBcImF1dG9cIikge1xyXG4gICAgICAgIGxhYmVscyA9IHV0aWxzLnByZXR0eU51bWJlcnMoZGF0YSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEdlbmVyYXRvciBmdW5jdGlvblxyXG4gICAgICB2YXIgZ2VuZXJhdG9yLCB0eXBlO1xyXG4gICAgICBzd2l0Y2godGhpcy5vcHRpb25zLnR5cGUpIHtcclxuICAgICAgICBjYXNlIFwiYmFyXCI6XHJcbiAgICAgICAgICBnZW5lcmF0b3IgPSBtaW5pY2hhcnRzLkJhcmNoYXJ0O1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcInBpZVwiOlxyXG4gICAgICAgICAgZ2VuZXJhdG9yID0gbWluaWNoYXJ0cy5QaWVjaGFydDtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgXCJwb2xhci1yYWRpdXNcIjpcclxuICAgICAgICAgIGdlbmVyYXRvciA9IG1pbmljaGFydHMuUG9sYXJjaGFydDtcclxuICAgICAgICAgIHR5cGUgPSBcInJhZGl1c1wiO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcInBvbGFyLWFyZWFcIjpcclxuICAgICAgICAgIGdlbmVyYXRvciA9IG1pbmljaGFydHMuUG9sYXJjaGFydDtcclxuICAgICAgICAgIHR5cGUgPSBcImFyZWFcIjtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBHcmFwaGljYWwgb3B0aW9ucyBmb3IgdGhlIGdlbmVyYXRvciBmdW5jdGlvblxyXG4gICAgICB2YXIgY2hhcnRPcHRzID0ge1xyXG4gICAgICAgIHdpZHRoOiB0aGlzLm9wdGlvbnMud2lkdGgsXHJcbiAgICAgICAgaGVpZ2h0OiB0aGlzLm9wdGlvbnMuaGVpZ2h0ICogMiwgLy8gVXNlZCBvbmx5IGlmIHR5cGUgPSBcImJhclwiXHJcbiAgICAgICAgY29sb3JzOiB0aGlzLm9wdGlvbnMuY29sb3JzLFxyXG4gICAgICAgIHR5cGU6IHR5cGUsXHJcbiAgICAgICAgdHJhbnNpdGlvblRpbWU6IHRoaXMub3B0aW9ucy50cmFuc2l0aW9uVGltZSxcclxuICAgICAgICBtaW5WYWx1ZTogLTEsXHJcbiAgICAgICAgbWF4VmFsdWU6MSxcclxuICAgICAgICBsYWJlbHM6IGxhYmVscyxcclxuICAgICAgICBsYWJlbENvbG9yczogdGhpcy5vcHRpb25zLmxhYmVsQ29sb3IsXHJcbiAgICAgICAgbGFiZWxNaW5TaXplOiB0aGlzLm9wdGlvbnMubGFiZWxNaW5TaXplLFxyXG4gICAgICAgIGxhYmVsTWF4U2l6ZTogdGhpcy5vcHRpb25zLmxhYmVsTWF4U2l6ZSxcclxuICAgICAgICBsYWJlbFBhZGRpbmc6IHRoaXMub3B0aW9ucy5sYWJlbFBhZGRpbmcsXHJcbiAgICAgICAgbGFiZWxDbGFzczogXCJsZWFmbGV0LWNsaWNrYWJsZVwiLFxyXG4gICAgICAgIHNoYXBlQ2xhc3M6IFwibGVhZmxldC1jbGlja2FibGVcIlxyXG4gICAgICB9O1xyXG5cclxuICAgICAgLy8gQ3JlYXRlIG9mIHVwZGF0ZSBjaGFydFxyXG4gICAgICBpZiAobmV3Q2hhcnQgPT09IHRydWUpIHtcclxuICAgICAgICB0aGlzLl9jaGFydC5zZWxlY3RBbGwoXCIqXCIpLnJlbW92ZSgpO1xyXG4gICAgICAgIHRoaXMuX2NoYXJ0T2JqZWN0ID0gbmV3IGdlbmVyYXRvcih0aGlzLl9jaGFydC5ub2RlKCksIGRhdGFTY2FsZWQsIGNoYXJ0T3B0cyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fY2hhcnRPYmplY3QudXBkYXRlKGRhdGFTY2FsZWQsIGNoYXJ0T3B0cyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgTC5taW5pY2hhcnQgPSBmdW5jdGlvbihjZW50ZXIsIG9wdGlvbnMpIHtcclxuICByZXR1cm4gbmV3IEwuTWluaWNoYXJ0KGNlbnRlciwgb3B0aW9ucyk7XHJcbn07XHJcbn0pKCk7XHJcbiIsIihmdW5jdGlvbigpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIG1vZHVsZS5leHBvcnRzLm1lcmdlT3B0aW9ucyA9IG1lcmdlT3B0aW9ucztcclxuICBtb2R1bGUuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcclxuICBtb2R1bGUuZXhwb3J0cy50b0Z1bmN0aW9uID0gdG9GdW5jdGlvbjtcclxuICBtb2R1bGUuZXhwb3J0cy5wcmV0dHlOdW1iZXJzID0gZnVuY3Rpb24obnVtYmVycykge1xyXG4gICAgcmV0dXJuIG51bWJlcnMubWFwKHByZXR0eU51bWJlcik7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBtZXJnZU9wdGlvbnMob3B0aW9ucywgZGVmYXVsdHMpIHtcclxuICAgIGlmIChvcHRpb25zKSBvcHRpb25zID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvcHRpb25zKSk7XHJcbiAgICBlbHNlIG9wdGlvbnMgPSB7fTtcclxuICAgIGRlZmF1bHRzID0gZGVmYXVsdHMgfHwge307XHJcbiAgICBmb3IgKHZhciBvcHQgaW4gZGVmYXVsdHMpIHtcclxuICAgICAgaWYgKGRlZmF1bHRzLmhhc093blByb3BlcnR5KG9wdCkgJiYgIW9wdGlvbnMuaGFzT3duUHJvcGVydHkob3B0KSkge1xyXG4gICAgICAgIG9wdGlvbnNbb3B0XSA9IGRlZmF1bHRzW29wdF07XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBvcHRpb25zO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdG9BcnJheSh4KSB7XHJcbiAgICBpZiAoeC5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpIHggPSBbeF07XHJcbiAgICByZXR1cm4geDtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIHRvRnVuY3Rpb24oeCkge1xyXG4gICAgaWYgKHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAoeCk7XHJcbiAgICB4ID0gdG9BcnJheSh4KTtcclxuICAgIHJldHVybiBmdW5jdGlvbihkLCBpKSB7cmV0dXJuIHhbaSAlIHgubGVuZ3RoXX07XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBwcmV0dHlOdW1iZXIobnVtYmVyKSB7XHJcbiAgICBpZiAoaXNOYU4obnVtYmVyKSB8fCAhaXNGaW5pdGUobnVtYmVyKSkgcmV0dXJuIFwiXCI7XHJcblxyXG4gICAgdmFyIGFic1ZhbCA9IE1hdGguYWJzKG51bWJlcik7XHJcbiAgICB2YXIgc2lnbj0gbnVtYmVyIDwgMD8gXCItXCI6IFwiXCI7XHJcbiAgICB2YXIgc2NhbGU7XHJcblxyXG4gICAgaWYoIGFic1ZhbCA8IDEwMDAgKSB7XHJcbiAgICAgICAgc2NhbGUgPSAnJztcclxuICAgIH0gZWxzZSBpZiggYWJzVmFsIDwgMTAwMDAwMCApIHtcclxuICAgICAgICBzY2FsZSA9ICdLJztcclxuICAgICAgICBhYnNWYWwgPSBhYnNWYWwvMTAwMDtcclxuXHJcbiAgICB9IGVsc2UgaWYoIGFic1ZhbCA8IDEwMDAwMDAwMDAgKSB7XHJcbiAgICAgICAgc2NhbGUgPSAnTSc7XHJcbiAgICAgICAgYWJzVmFsID0gYWJzVmFsLzEwMDAwMDA7XHJcblxyXG4gICAgfSBlbHNlIGlmKCBhYnNWYWwgPCAxMDAwMDAwMDAwMDAwICkge1xyXG4gICAgICAgIHNjYWxlID0gJ0InO1xyXG4gICAgICAgIGFic1ZhbCA9IGFic1ZhbC8xMDAwMDAwMDAwO1xyXG5cclxuICAgIH0gZWxzZSBpZiggYWJzVmFsIDwgMTAwMDAwMDAwMDAwMDAwMCApIHtcclxuICAgICAgICBzY2FsZSA9ICdUJztcclxuICAgICAgICBhYnNWYWwgPSBhYnNWYWwvMTAwMDAwMDAwMDAwMDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYWJzVmFsID4gMTApIGFic1ZhbCA9IHJvdW5kVG8oYWJzVmFsKTtcclxuICAgIGVsc2UgaWYgKGFic1ZhbCA+IDEpIGFic1ZhbCA9IHJvdW5kVG8oYWJzVmFsLCAxMCwgdHJ1ZSk7XHJcbiAgICBlbHNlIGFic1ZhbCA9IHJvdW5kVG8oYWJzVmFsLCAxMDAsIHRydWUpO1xyXG5cclxuICAgIHJldHVybiBzaWduICsgYWJzVmFsICsgc2NhbGU7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiByb3VuZFRvKG51bWJlciwgdG8sIGludmVyc2UpIHtcclxuICAgIHRvID0gdG8gfHwgMTtcclxuICAgIGlmIChpbnZlcnNlKSByZXR1cm4gTWF0aC5yb3VuZChudW1iZXIgKiB0bykgLyB0bztcclxuICAgIGVsc2UgcmV0dXJuIE1hdGgucm91bmQobnVtYmVyIC8gdG8pICogdG87XHJcbiAgfVxyXG59KCkpO1xyXG4iXX0= +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvZDMvYnVpbGQvZDMuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvYmFyY2hhcnQuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvY2hhcnQuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvZ2VvbWV0cnkuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvbGFiZWwuanMiLCJub2RlX21vZHVsZXMvbWluaWNoYXJ0cy9zcmMvbWluaWNoYXJ0cy5qcyIsIm5vZGVfbW9kdWxlcy9taW5pY2hhcnRzL3NyYy9waWVjaGFydC5qcyIsIm5vZGVfbW9kdWxlcy9taW5pY2hhcnRzL3NyYy9wb2xhcmNoYXJ0LmpzIiwibm9kZV9tb2R1bGVzL21pbmljaGFydHMvc3JjL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL3Rpbnljb2xvcjIvdGlueWNvbG9yLmpzIiwic3JjL21pbmljaGFydC5qcyIsInNyYy91dGlscy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDanJnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM3FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL09BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIi8vIGh0dHBzOi8vZDNqcy5vcmcgVmVyc2lvbiA0LjcuNC4gQ29weXJpZ2h0IDIwMTcgTWlrZSBCb3N0b2NrLlxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG5cdHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSkgOlxuXHQoZmFjdG9yeSgoZ2xvYmFsLmQzID0gZ2xvYmFsLmQzIHx8IHt9KSkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG52YXIgdmVyc2lvbiA9IFwiNC43LjRcIjtcblxudmFyIGFzY2VuZGluZyA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiBhID49IGIgPyAwIDogTmFOO1xufTtcblxudmFyIGJpc2VjdG9yID0gZnVuY3Rpb24oY29tcGFyZSkge1xuICBpZiAoY29tcGFyZS5sZW5ndGggPT09IDEpIGNvbXBhcmUgPSBhc2NlbmRpbmdDb21wYXJhdG9yKGNvbXBhcmUpO1xuICByZXR1cm4ge1xuICAgIGxlZnQ6IGZ1bmN0aW9uKGEsIHgsIGxvLCBoaSkge1xuICAgICAgaWYgKGxvID09IG51bGwpIGxvID0gMDtcbiAgICAgIGlmIChoaSA9PSBudWxsKSBoaSA9IGEubGVuZ3RoO1xuICAgICAgd2hpbGUgKGxvIDwgaGkpIHtcbiAgICAgICAgdmFyIG1pZCA9IGxvICsgaGkgPj4+IDE7XG4gICAgICAgIGlmIChjb21wYXJlKGFbbWlkXSwgeCkgPCAwKSBsbyA9IG1pZCArIDE7XG4gICAgICAgIGVsc2UgaGkgPSBtaWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gbG87XG4gICAgfSxcbiAgICByaWdodDogZnVuY3Rpb24oYSwgeCwgbG8sIGhpKSB7XG4gICAgICBpZiAobG8gPT0gbnVsbCkgbG8gPSAwO1xuICAgICAgaWYgKGhpID09IG51bGwpIGhpID0gYS5sZW5ndGg7XG4gICAgICB3aGlsZSAobG8gPCBoaSkge1xuICAgICAgICB2YXIgbWlkID0gbG8gKyBoaSA+Pj4gMTtcbiAgICAgICAgaWYgKGNvbXBhcmUoYVttaWRdLCB4KSA+IDApIGhpID0gbWlkO1xuICAgICAgICBlbHNlIGxvID0gbWlkICsgMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBsbztcbiAgICB9XG4gIH07XG59O1xuXG5mdW5jdGlvbiBhc2NlbmRpbmdDb21wYXJhdG9yKGYpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGQsIHgpIHtcbiAgICByZXR1cm4gYXNjZW5kaW5nKGYoZCksIHgpO1xuICB9O1xufVxuXG52YXIgYXNjZW5kaW5nQmlzZWN0ID0gYmlzZWN0b3IoYXNjZW5kaW5nKTtcbnZhciBiaXNlY3RSaWdodCA9IGFzY2VuZGluZ0Jpc2VjdC5yaWdodDtcbnZhciBiaXNlY3RMZWZ0ID0gYXNjZW5kaW5nQmlzZWN0LmxlZnQ7XG5cbnZhciBwYWlycyA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIGlmIChmID09IG51bGwpIGYgPSBwYWlyO1xuICB2YXIgaSA9IDAsIG4gPSBhcnJheS5sZW5ndGggLSAxLCBwID0gYXJyYXlbMF0sIHBhaXJzID0gbmV3IEFycmF5KG4gPCAwID8gMCA6IG4pO1xuICB3aGlsZSAoaSA8IG4pIHBhaXJzW2ldID0gZihwLCBwID0gYXJyYXlbKytpXSk7XG4gIHJldHVybiBwYWlycztcbn07XG5cbmZ1bmN0aW9uIHBhaXIoYSwgYikge1xuICByZXR1cm4gW2EsIGJdO1xufVxuXG52YXIgY3Jvc3MgPSBmdW5jdGlvbihhLCBiLCBmKSB7XG4gIHZhciBuYSA9IGEubGVuZ3RoLCBuYiA9IGIubGVuZ3RoLCBjID0gbmV3IEFycmF5KG5hICogbmIpLCBpYSwgaWIsIGljLCB2YTtcbiAgaWYgKGYgPT0gbnVsbCkgZiA9IHBhaXI7XG4gIGZvciAoaWEgPSBpYyA9IDA7IGlhIDwgbmE7ICsraWEpIGZvciAodmEgPSBhW2lhXSwgaWIgPSAwOyBpYiA8IG5iOyArK2liLCArK2ljKSBjW2ljXSA9IGYodmEsIGJbaWJdKTtcbiAgcmV0dXJuIGM7XG59O1xuXG52YXIgZGVzY2VuZGluZyA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGIgPCBhID8gLTEgOiBiID4gYSA/IDEgOiBiID49IGEgPyAwIDogTmFOO1xufTtcblxudmFyIG51bWJlciA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIHggPT09IG51bGwgPyBOYU4gOiAreDtcbn07XG5cbnZhciB2YXJpYW5jZSA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBuID0gYXJyYXkubGVuZ3RoLFxuICAgICAgbSA9IDAsXG4gICAgICBhLFxuICAgICAgZCxcbiAgICAgIHMgPSAwLFxuICAgICAgaSA9IC0xLFxuICAgICAgaiA9IDA7XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBpZiAoIWlzTmFOKGEgPSBudW1iZXIoYXJyYXlbaV0pKSkge1xuICAgICAgICBkID0gYSAtIG07XG4gICAgICAgIG0gKz0gZCAvICsrajtcbiAgICAgICAgcyArPSBkICogKGEgLSBtKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBlbHNlIHtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKCFpc05hTihhID0gbnVtYmVyKGYoYXJyYXlbaV0sIGksIGFycmF5KSkpKSB7XG4gICAgICAgIGQgPSBhIC0gbTtcbiAgICAgICAgbSArPSBkIC8gKytqO1xuICAgICAgICBzICs9IGQgKiAoYSAtIG0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChqID4gMSkgcmV0dXJuIHMgLyAoaiAtIDEpO1xufTtcblxudmFyIGRldmlhdGlvbiA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciB2ID0gdmFyaWFuY2UoYXJyYXksIGYpO1xuICByZXR1cm4gdiA/IE1hdGguc3FydCh2KSA6IHY7XG59O1xuXG52YXIgZXh0ZW50ID0gZnVuY3Rpb24oYXJyYXksIGYpIHtcbiAgdmFyIGkgPSAtMSxcbiAgICAgIG4gPSBhcnJheS5sZW5ndGgsXG4gICAgICBhLFxuICAgICAgYixcbiAgICAgIGM7XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBhcnJheVtpXSkgIT0gbnVsbCAmJiBiID49IGIpIHsgYSA9IGMgPSBiOyBicmVhazsgfVxuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBhcnJheVtpXSkgIT0gbnVsbCkge1xuICAgICAgaWYgKGEgPiBiKSBhID0gYjtcbiAgICAgIGlmIChjIDwgYikgYyA9IGI7XG4gICAgfVxuICB9XG5cbiAgZWxzZSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGYoYXJyYXlbaV0sIGksIGFycmF5KSkgIT0gbnVsbCAmJiBiID49IGIpIHsgYSA9IGMgPSBiOyBicmVhazsgfVxuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwpIHtcbiAgICAgIGlmIChhID4gYikgYSA9IGI7XG4gICAgICBpZiAoYyA8IGIpIGMgPSBiO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBbYSwgY107XG59O1xuXG52YXIgYXJyYXkgPSBBcnJheS5wcm90b3R5cGU7XG5cbnZhciBzbGljZSA9IGFycmF5LnNsaWNlO1xudmFyIG1hcCA9IGFycmF5Lm1hcDtcblxudmFyIGNvbnN0YW50ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG52YXIgaWRlbnRpdHkgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiB4O1xufTtcblxudmFyIHNlcXVlbmNlID0gZnVuY3Rpb24oc3RhcnQsIHN0b3AsIHN0ZXApIHtcbiAgc3RhcnQgPSArc3RhcnQsIHN0b3AgPSArc3RvcCwgc3RlcCA9IChuID0gYXJndW1lbnRzLmxlbmd0aCkgPCAyID8gKHN0b3AgPSBzdGFydCwgc3RhcnQgPSAwLCAxKSA6IG4gPCAzID8gMSA6ICtzdGVwO1xuXG4gIHZhciBpID0gLTEsXG4gICAgICBuID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKChzdG9wIC0gc3RhcnQpIC8gc3RlcCkpIHwgMCxcbiAgICAgIHJhbmdlID0gbmV3IEFycmF5KG4pO1xuXG4gIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgcmFuZ2VbaV0gPSBzdGFydCArIGkgKiBzdGVwO1xuICB9XG5cbiAgcmV0dXJuIHJhbmdlO1xufTtcblxudmFyIGUxMCA9IE1hdGguc3FydCg1MCk7XG52YXIgZTUgPSBNYXRoLnNxcnQoMTApO1xudmFyIGUyID0gTWF0aC5zcXJ0KDIpO1xuXG52YXIgdGlja3MgPSBmdW5jdGlvbihzdGFydCwgc3RvcCwgY291bnQpIHtcbiAgdmFyIHN0ZXAgPSB0aWNrU3RlcChzdGFydCwgc3RvcCwgY291bnQpO1xuICByZXR1cm4gc2VxdWVuY2UoXG4gICAgTWF0aC5jZWlsKHN0YXJ0IC8gc3RlcCkgKiBzdGVwLFxuICAgIE1hdGguZmxvb3Ioc3RvcCAvIHN0ZXApICogc3RlcCArIHN0ZXAgLyAyLCAvLyBpbmNsdXNpdmVcbiAgICBzdGVwXG4gICk7XG59O1xuXG5mdW5jdGlvbiB0aWNrU3RlcChzdGFydCwgc3RvcCwgY291bnQpIHtcbiAgdmFyIHN0ZXAwID0gTWF0aC5hYnMoc3RvcCAtIHN0YXJ0KSAvIE1hdGgubWF4KDAsIGNvdW50KSxcbiAgICAgIHN0ZXAxID0gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoTWF0aC5sb2coc3RlcDApIC8gTWF0aC5MTjEwKSksXG4gICAgICBlcnJvciA9IHN0ZXAwIC8gc3RlcDE7XG4gIGlmIChlcnJvciA+PSBlMTApIHN0ZXAxICo9IDEwO1xuICBlbHNlIGlmIChlcnJvciA+PSBlNSkgc3RlcDEgKj0gNTtcbiAgZWxzZSBpZiAoZXJyb3IgPj0gZTIpIHN0ZXAxICo9IDI7XG4gIHJldHVybiBzdG9wIDwgc3RhcnQgPyAtc3RlcDEgOiBzdGVwMTtcbn1cblxudmFyIHN0dXJnZXMgPSBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgcmV0dXJuIE1hdGguY2VpbChNYXRoLmxvZyh2YWx1ZXMubGVuZ3RoKSAvIE1hdGguTE4yKSArIDE7XG59O1xuXG52YXIgaGlzdG9ncmFtID0gZnVuY3Rpb24oKSB7XG4gIHZhciB2YWx1ZSA9IGlkZW50aXR5LFxuICAgICAgZG9tYWluID0gZXh0ZW50LFxuICAgICAgdGhyZXNob2xkID0gc3R1cmdlcztcblxuICBmdW5jdGlvbiBoaXN0b2dyYW0oZGF0YSkge1xuICAgIHZhciBpLFxuICAgICAgICBuID0gZGF0YS5sZW5ndGgsXG4gICAgICAgIHgsXG4gICAgICAgIHZhbHVlcyA9IG5ldyBBcnJheShuKTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIHZhbHVlc1tpXSA9IHZhbHVlKGRhdGFbaV0sIGksIGRhdGEpO1xuICAgIH1cblxuICAgIHZhciB4eiA9IGRvbWFpbih2YWx1ZXMpLFxuICAgICAgICB4MCA9IHh6WzBdLFxuICAgICAgICB4MSA9IHh6WzFdLFxuICAgICAgICB0eiA9IHRocmVzaG9sZCh2YWx1ZXMsIHgwLCB4MSk7XG5cbiAgICAvLyBDb252ZXJ0IG51bWJlciBvZiB0aHJlc2hvbGRzIGludG8gdW5pZm9ybSB0aHJlc2hvbGRzLlxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0eikpIHR6ID0gdGlja3MoeDAsIHgxLCB0eik7XG5cbiAgICAvLyBSZW1vdmUgYW55IHRocmVzaG9sZHMgb3V0c2lkZSB0aGUgZG9tYWluLlxuICAgIHZhciBtID0gdHoubGVuZ3RoO1xuICAgIHdoaWxlICh0elswXSA8PSB4MCkgdHouc2hpZnQoKSwgLS1tO1xuICAgIHdoaWxlICh0elttIC0gMV0gPj0geDEpIHR6LnBvcCgpLCAtLW07XG5cbiAgICB2YXIgYmlucyA9IG5ldyBBcnJheShtICsgMSksXG4gICAgICAgIGJpbjtcblxuICAgIC8vIEluaXRpYWxpemUgYmlucy5cbiAgICBmb3IgKGkgPSAwOyBpIDw9IG07ICsraSkge1xuICAgICAgYmluID0gYmluc1tpXSA9IFtdO1xuICAgICAgYmluLngwID0gaSA+IDAgPyB0eltpIC0gMV0gOiB4MDtcbiAgICAgIGJpbi54MSA9IGkgPCBtID8gdHpbaV0gOiB4MTtcbiAgICB9XG5cbiAgICAvLyBBc3NpZ24gZGF0YSB0byBiaW5zIGJ5IHZhbHVlLCBpZ25vcmluZyBhbnkgb3V0c2lkZSB0aGUgZG9tYWluLlxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIHggPSB2YWx1ZXNbaV07XG4gICAgICBpZiAoeDAgPD0geCAmJiB4IDw9IHgxKSB7XG4gICAgICAgIGJpbnNbYmlzZWN0UmlnaHQodHosIHgsIDAsIG0pXS5wdXNoKGRhdGFbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBiaW5zO1xuICB9XG5cbiAgaGlzdG9ncmFtLnZhbHVlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHZhbHVlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudChfKSwgaGlzdG9ncmFtKSA6IHZhbHVlO1xuICB9O1xuXG4gIGhpc3RvZ3JhbS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZG9tYWluID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudChbX1swXSwgX1sxXV0pLCBoaXN0b2dyYW0pIDogZG9tYWluO1xuICB9O1xuXG4gIGhpc3RvZ3JhbS50aHJlc2hvbGRzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRocmVzaG9sZCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogQXJyYXkuaXNBcnJheShfKSA/IGNvbnN0YW50KHNsaWNlLmNhbGwoXykpIDogY29uc3RhbnQoXyksIGhpc3RvZ3JhbSkgOiB0aHJlc2hvbGQ7XG4gIH07XG5cbiAgcmV0dXJuIGhpc3RvZ3JhbTtcbn07XG5cbnZhciB0aHJlc2hvbGQgPSBmdW5jdGlvbihhcnJheSwgcCwgZikge1xuICBpZiAoZiA9PSBudWxsKSBmID0gbnVtYmVyO1xuICBpZiAoIShuID0gYXJyYXkubGVuZ3RoKSkgcmV0dXJuO1xuICBpZiAoKHAgPSArcCkgPD0gMCB8fCBuIDwgMikgcmV0dXJuICtmKGFycmF5WzBdLCAwLCBhcnJheSk7XG4gIGlmIChwID49IDEpIHJldHVybiArZihhcnJheVtuIC0gMV0sIG4gLSAxLCBhcnJheSk7XG4gIHZhciBuLFxuICAgICAgaCA9IChuIC0gMSkgKiBwLFxuICAgICAgaSA9IE1hdGguZmxvb3IoaCksXG4gICAgICBhID0gK2YoYXJyYXlbaV0sIGksIGFycmF5KSxcbiAgICAgIGIgPSArZihhcnJheVtpICsgMV0sIGkgKyAxLCBhcnJheSk7XG4gIHJldHVybiBhICsgKGIgLSBhKSAqIChoIC0gaSk7XG59O1xuXG52YXIgZnJlZWRtYW5EaWFjb25pcyA9IGZ1bmN0aW9uKHZhbHVlcywgbWluLCBtYXgpIHtcbiAgdmFsdWVzID0gbWFwLmNhbGwodmFsdWVzLCBudW1iZXIpLnNvcnQoYXNjZW5kaW5nKTtcbiAgcmV0dXJuIE1hdGguY2VpbCgobWF4IC0gbWluKSAvICgyICogKHRocmVzaG9sZCh2YWx1ZXMsIDAuNzUpIC0gdGhyZXNob2xkKHZhbHVlcywgMC4yNSkpICogTWF0aC5wb3codmFsdWVzLmxlbmd0aCwgLTEgLyAzKSkpO1xufTtcblxudmFyIHNjb3R0ID0gZnVuY3Rpb24odmFsdWVzLCBtaW4sIG1heCkge1xuICByZXR1cm4gTWF0aC5jZWlsKChtYXggLSBtaW4pIC8gKDMuNSAqIGRldmlhdGlvbih2YWx1ZXMpICogTWF0aC5wb3codmFsdWVzLmxlbmd0aCwgLTEgLyAzKSkpO1xufTtcblxudmFyIG1heCA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBpID0gLTEsXG4gICAgICBuID0gYXJyYXkubGVuZ3RoLFxuICAgICAgYSxcbiAgICAgIGI7XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBhcnJheVtpXSkgIT0gbnVsbCAmJiBiID49IGIpIHsgYSA9IGI7IGJyZWFrOyB9XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGFycmF5W2ldKSAhPSBudWxsICYmIGIgPiBhKSBhID0gYjtcbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwgJiYgYiA+PSBiKSB7IGEgPSBiOyBicmVhazsgfVxuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwgJiYgYiA+IGEpIGEgPSBiO1xuICB9XG5cbiAgcmV0dXJuIGE7XG59O1xuXG52YXIgbWVhbiA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBzID0gMCxcbiAgICAgIG4gPSBhcnJheS5sZW5ndGgsXG4gICAgICBhLFxuICAgICAgaSA9IC0xLFxuICAgICAgaiA9IG47XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoIWlzTmFOKGEgPSBudW1iZXIoYXJyYXlbaV0pKSkgcyArPSBhOyBlbHNlIC0tajtcbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoIWlzTmFOKGEgPSBudW1iZXIoZihhcnJheVtpXSwgaSwgYXJyYXkpKSkpIHMgKz0gYTsgZWxzZSAtLWo7XG4gIH1cblxuICBpZiAoaikgcmV0dXJuIHMgLyBqO1xufTtcblxudmFyIG1lZGlhbiA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBudW1iZXJzID0gW10sXG4gICAgICBuID0gYXJyYXkubGVuZ3RoLFxuICAgICAgYSxcbiAgICAgIGkgPSAtMTtcblxuICBpZiAoZiA9PSBudWxsKSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICghaXNOYU4oYSA9IG51bWJlcihhcnJheVtpXSkpKSBudW1iZXJzLnB1c2goYSk7XG4gIH1cblxuICBlbHNlIHtcbiAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFpc05hTihhID0gbnVtYmVyKGYoYXJyYXlbaV0sIGksIGFycmF5KSkpKSBudW1iZXJzLnB1c2goYSk7XG4gIH1cblxuICByZXR1cm4gdGhyZXNob2xkKG51bWJlcnMuc29ydChhc2NlbmRpbmcpLCAwLjUpO1xufTtcblxudmFyIG1lcmdlID0gZnVuY3Rpb24oYXJyYXlzKSB7XG4gIHZhciBuID0gYXJyYXlzLmxlbmd0aCxcbiAgICAgIG0sXG4gICAgICBpID0gLTEsXG4gICAgICBqID0gMCxcbiAgICAgIG1lcmdlZCxcbiAgICAgIGFycmF5O1xuXG4gIHdoaWxlICgrK2kgPCBuKSBqICs9IGFycmF5c1tpXS5sZW5ndGg7XG4gIG1lcmdlZCA9IG5ldyBBcnJheShqKTtcblxuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICBhcnJheSA9IGFycmF5c1tuXTtcbiAgICBtID0gYXJyYXkubGVuZ3RoO1xuICAgIHdoaWxlICgtLW0gPj0gMCkge1xuICAgICAgbWVyZ2VkWy0tal0gPSBhcnJheVttXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWVyZ2VkO1xufTtcblxudmFyIG1pbiA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIHZhciBpID0gLTEsXG4gICAgICBuID0gYXJyYXkubGVuZ3RoLFxuICAgICAgYSxcbiAgICAgIGI7XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBhcnJheVtpXSkgIT0gbnVsbCAmJiBiID49IGIpIHsgYSA9IGI7IGJyZWFrOyB9XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGFycmF5W2ldKSAhPSBudWxsICYmIGEgPiBiKSBhID0gYjtcbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwgJiYgYiA+PSBiKSB7IGEgPSBiOyBicmVhazsgfVxuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSkpICE9IG51bGwgJiYgYSA+IGIpIGEgPSBiO1xuICB9XG5cbiAgcmV0dXJuIGE7XG59O1xuXG52YXIgcGVybXV0ZSA9IGZ1bmN0aW9uKGFycmF5LCBpbmRleGVzKSB7XG4gIHZhciBpID0gaW5kZXhlcy5sZW5ndGgsIHBlcm11dGVzID0gbmV3IEFycmF5KGkpO1xuICB3aGlsZSAoaS0tKSBwZXJtdXRlc1tpXSA9IGFycmF5W2luZGV4ZXNbaV1dO1xuICByZXR1cm4gcGVybXV0ZXM7XG59O1xuXG52YXIgc2NhbiA9IGZ1bmN0aW9uKGFycmF5LCBjb21wYXJlKSB7XG4gIGlmICghKG4gPSBhcnJheS5sZW5ndGgpKSByZXR1cm47XG4gIHZhciBpID0gMCxcbiAgICAgIG4sXG4gICAgICBqID0gMCxcbiAgICAgIHhpLFxuICAgICAgeGogPSBhcnJheVtqXTtcblxuICBpZiAoIWNvbXBhcmUpIGNvbXBhcmUgPSBhc2NlbmRpbmc7XG5cbiAgd2hpbGUgKCsraSA8IG4pIGlmIChjb21wYXJlKHhpID0gYXJyYXlbaV0sIHhqKSA8IDAgfHwgY29tcGFyZSh4aiwgeGopICE9PSAwKSB4aiA9IHhpLCBqID0gaTtcblxuICBpZiAoY29tcGFyZSh4aiwgeGopID09PSAwKSByZXR1cm4gajtcbn07XG5cbnZhciBzaHVmZmxlID0gZnVuY3Rpb24oYXJyYXksIGkwLCBpMSkge1xuICB2YXIgbSA9IChpMSA9PSBudWxsID8gYXJyYXkubGVuZ3RoIDogaTEpIC0gKGkwID0gaTAgPT0gbnVsbCA/IDAgOiAraTApLFxuICAgICAgdCxcbiAgICAgIGk7XG5cbiAgd2hpbGUgKG0pIHtcbiAgICBpID0gTWF0aC5yYW5kb20oKSAqIG0tLSB8IDA7XG4gICAgdCA9IGFycmF5W20gKyBpMF07XG4gICAgYXJyYXlbbSArIGkwXSA9IGFycmF5W2kgKyBpMF07XG4gICAgYXJyYXlbaSArIGkwXSA9IHQ7XG4gIH1cblxuICByZXR1cm4gYXJyYXk7XG59O1xuXG52YXIgc3VtID0gZnVuY3Rpb24oYXJyYXksIGYpIHtcbiAgdmFyIHMgPSAwLFxuICAgICAgbiA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGEsXG4gICAgICBpID0gLTE7XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoYSA9ICthcnJheVtpXSkgcyArPSBhOyAvLyBOb3RlOiB6ZXJvIGFuZCBudWxsIGFyZSBlcXVpdmFsZW50LlxuICB9XG5cbiAgZWxzZSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmIChhID0gK2YoYXJyYXlbaV0sIGksIGFycmF5KSkgcyArPSBhO1xuICB9XG5cbiAgcmV0dXJuIHM7XG59O1xuXG52YXIgdHJhbnNwb3NlID0gZnVuY3Rpb24obWF0cml4KSB7XG4gIGlmICghKG4gPSBtYXRyaXgubGVuZ3RoKSkgcmV0dXJuIFtdO1xuICBmb3IgKHZhciBpID0gLTEsIG0gPSBtaW4obWF0cml4LCBsZW5ndGgpLCB0cmFuc3Bvc2UgPSBuZXcgQXJyYXkobSk7ICsraSA8IG07KSB7XG4gICAgZm9yICh2YXIgaiA9IC0xLCBuLCByb3cgPSB0cmFuc3Bvc2VbaV0gPSBuZXcgQXJyYXkobik7ICsraiA8IG47KSB7XG4gICAgICByb3dbal0gPSBtYXRyaXhbal1baV07XG4gICAgfVxuICB9XG4gIHJldHVybiB0cmFuc3Bvc2U7XG59O1xuXG5mdW5jdGlvbiBsZW5ndGgoZCkge1xuICByZXR1cm4gZC5sZW5ndGg7XG59XG5cbnZhciB6aXAgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRyYW5zcG9zZShhcmd1bWVudHMpO1xufTtcblxudmFyIHNsaWNlJDEgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbnZhciBpZGVudGl0eSQxID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4geDtcbn07XG5cbnZhciB0b3AgPSAxO1xudmFyIHJpZ2h0ID0gMjtcbnZhciBib3R0b20gPSAzO1xudmFyIGxlZnQgPSA0O1xudmFyIGVwc2lsb24gPSAxZS02O1xuXG5mdW5jdGlvbiB0cmFuc2xhdGVYKHgpIHtcbiAgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgeCArIFwiLDApXCI7XG59XG5cbmZ1bmN0aW9uIHRyYW5zbGF0ZVkoeSkge1xuICByZXR1cm4gXCJ0cmFuc2xhdGUoMCxcIiArIHkgKyBcIilcIjtcbn1cblxuZnVuY3Rpb24gY2VudGVyKHNjYWxlKSB7XG4gIHZhciBvZmZzZXQgPSBzY2FsZS5iYW5kd2lkdGgoKSAvIDI7XG4gIGlmIChzY2FsZS5yb3VuZCgpKSBvZmZzZXQgPSBNYXRoLnJvdW5kKG9mZnNldCk7XG4gIHJldHVybiBmdW5jdGlvbihkKSB7XG4gICAgcmV0dXJuIHNjYWxlKGQpICsgb2Zmc2V0O1xuICB9O1xufVxuXG5mdW5jdGlvbiBlbnRlcmluZygpIHtcbiAgcmV0dXJuICF0aGlzLl9fYXhpcztcbn1cblxuZnVuY3Rpb24gYXhpcyhvcmllbnQsIHNjYWxlKSB7XG4gIHZhciB0aWNrQXJndW1lbnRzID0gW10sXG4gICAgICB0aWNrVmFsdWVzID0gbnVsbCxcbiAgICAgIHRpY2tGb3JtYXQgPSBudWxsLFxuICAgICAgdGlja1NpemVJbm5lciA9IDYsXG4gICAgICB0aWNrU2l6ZU91dGVyID0gNixcbiAgICAgIHRpY2tQYWRkaW5nID0gMyxcbiAgICAgIGsgPSBvcmllbnQgPT09IHRvcCB8fCBvcmllbnQgPT09IGxlZnQgPyAtMSA6IDEsXG4gICAgICB4LCB5ID0gb3JpZW50ID09PSBsZWZ0IHx8IG9yaWVudCA9PT0gcmlnaHQgPyAoeCA9IFwieFwiLCBcInlcIikgOiAoeCA9IFwieVwiLCBcInhcIiksXG4gICAgICB0cmFuc2Zvcm0gPSBvcmllbnQgPT09IHRvcCB8fCBvcmllbnQgPT09IGJvdHRvbSA/IHRyYW5zbGF0ZVggOiB0cmFuc2xhdGVZO1xuXG4gIGZ1bmN0aW9uIGF4aXMoY29udGV4dCkge1xuICAgIHZhciB2YWx1ZXMgPSB0aWNrVmFsdWVzID09IG51bGwgPyAoc2NhbGUudGlja3MgPyBzY2FsZS50aWNrcy5hcHBseShzY2FsZSwgdGlja0FyZ3VtZW50cykgOiBzY2FsZS5kb21haW4oKSkgOiB0aWNrVmFsdWVzLFxuICAgICAgICBmb3JtYXQgPSB0aWNrRm9ybWF0ID09IG51bGwgPyAoc2NhbGUudGlja0Zvcm1hdCA/IHNjYWxlLnRpY2tGb3JtYXQuYXBwbHkoc2NhbGUsIHRpY2tBcmd1bWVudHMpIDogaWRlbnRpdHkkMSkgOiB0aWNrRm9ybWF0LFxuICAgICAgICBzcGFjaW5nID0gTWF0aC5tYXgodGlja1NpemVJbm5lciwgMCkgKyB0aWNrUGFkZGluZyxcbiAgICAgICAgcmFuZ2UgPSBzY2FsZS5yYW5nZSgpLFxuICAgICAgICByYW5nZTAgPSByYW5nZVswXSArIDAuNSxcbiAgICAgICAgcmFuZ2UxID0gcmFuZ2VbcmFuZ2UubGVuZ3RoIC0gMV0gKyAwLjUsXG4gICAgICAgIHBvc2l0aW9uID0gKHNjYWxlLmJhbmR3aWR0aCA/IGNlbnRlciA6IGlkZW50aXR5JDEpKHNjYWxlLmNvcHkoKSksXG4gICAgICAgIHNlbGVjdGlvbiA9IGNvbnRleHQuc2VsZWN0aW9uID8gY29udGV4dC5zZWxlY3Rpb24oKSA6IGNvbnRleHQsXG4gICAgICAgIHBhdGggPSBzZWxlY3Rpb24uc2VsZWN0QWxsKFwiLmRvbWFpblwiKS5kYXRhKFtudWxsXSksXG4gICAgICAgIHRpY2sgPSBzZWxlY3Rpb24uc2VsZWN0QWxsKFwiLnRpY2tcIikuZGF0YSh2YWx1ZXMsIHNjYWxlKS5vcmRlcigpLFxuICAgICAgICB0aWNrRXhpdCA9IHRpY2suZXhpdCgpLFxuICAgICAgICB0aWNrRW50ZXIgPSB0aWNrLmVudGVyKCkuYXBwZW5kKFwiZ1wiKS5hdHRyKFwiY2xhc3NcIiwgXCJ0aWNrXCIpLFxuICAgICAgICBsaW5lID0gdGljay5zZWxlY3QoXCJsaW5lXCIpLFxuICAgICAgICB0ZXh0ID0gdGljay5zZWxlY3QoXCJ0ZXh0XCIpO1xuXG4gICAgcGF0aCA9IHBhdGgubWVyZ2UocGF0aC5lbnRlcigpLmluc2VydChcInBhdGhcIiwgXCIudGlja1wiKVxuICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwiZG9tYWluXCIpXG4gICAgICAgIC5hdHRyKFwic3Ryb2tlXCIsIFwiIzAwMFwiKSk7XG5cbiAgICB0aWNrID0gdGljay5tZXJnZSh0aWNrRW50ZXIpO1xuXG4gICAgbGluZSA9IGxpbmUubWVyZ2UodGlja0VudGVyLmFwcGVuZChcImxpbmVcIilcbiAgICAgICAgLmF0dHIoXCJzdHJva2VcIiwgXCIjMDAwXCIpXG4gICAgICAgIC5hdHRyKHggKyBcIjJcIiwgayAqIHRpY2tTaXplSW5uZXIpXG4gICAgICAgIC5hdHRyKHkgKyBcIjFcIiwgMC41KVxuICAgICAgICAuYXR0cih5ICsgXCIyXCIsIDAuNSkpO1xuXG4gICAgdGV4dCA9IHRleHQubWVyZ2UodGlja0VudGVyLmFwcGVuZChcInRleHRcIilcbiAgICAgICAgLmF0dHIoXCJmaWxsXCIsIFwiIzAwMFwiKVxuICAgICAgICAuYXR0cih4LCBrICogc3BhY2luZylcbiAgICAgICAgLmF0dHIoeSwgMC41KVxuICAgICAgICAuYXR0cihcImR5XCIsIG9yaWVudCA9PT0gdG9wID8gXCIwZW1cIiA6IG9yaWVudCA9PT0gYm90dG9tID8gXCIwLjcxZW1cIiA6IFwiMC4zMmVtXCIpKTtcblxuICAgIGlmIChjb250ZXh0ICE9PSBzZWxlY3Rpb24pIHtcbiAgICAgIHBhdGggPSBwYXRoLnRyYW5zaXRpb24oY29udGV4dCk7XG4gICAgICB0aWNrID0gdGljay50cmFuc2l0aW9uKGNvbnRleHQpO1xuICAgICAgbGluZSA9IGxpbmUudHJhbnNpdGlvbihjb250ZXh0KTtcbiAgICAgIHRleHQgPSB0ZXh0LnRyYW5zaXRpb24oY29udGV4dCk7XG5cbiAgICAgIHRpY2tFeGl0ID0gdGlja0V4aXQudHJhbnNpdGlvbihjb250ZXh0KVxuICAgICAgICAgIC5hdHRyKFwib3BhY2l0eVwiLCBlcHNpbG9uKVxuICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGlzRmluaXRlKGQgPSBwb3NpdGlvbihkKSkgPyB0cmFuc2Zvcm0oZCkgOiB0aGlzLmdldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiKTsgfSk7XG5cbiAgICAgIHRpY2tFbnRlclxuICAgICAgICAgIC5hdHRyKFwib3BhY2l0eVwiLCBlcHNpbG9uKVxuICAgICAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIGZ1bmN0aW9uKGQpIHsgdmFyIHAgPSB0aGlzLnBhcmVudE5vZGUuX19heGlzOyByZXR1cm4gdHJhbnNmb3JtKHAgJiYgaXNGaW5pdGUocCA9IHAoZCkpID8gcCA6IHBvc2l0aW9uKGQpKTsgfSk7XG4gICAgfVxuXG4gICAgdGlja0V4aXQucmVtb3ZlKCk7XG5cbiAgICBwYXRoXG4gICAgICAgIC5hdHRyKFwiZFwiLCBvcmllbnQgPT09IGxlZnQgfHwgb3JpZW50ID09IHJpZ2h0XG4gICAgICAgICAgICA/IFwiTVwiICsgayAqIHRpY2tTaXplT3V0ZXIgKyBcIixcIiArIHJhbmdlMCArIFwiSDAuNVZcIiArIHJhbmdlMSArIFwiSFwiICsgayAqIHRpY2tTaXplT3V0ZXJcbiAgICAgICAgICAgIDogXCJNXCIgKyByYW5nZTAgKyBcIixcIiArIGsgKiB0aWNrU2l6ZU91dGVyICsgXCJWMC41SFwiICsgcmFuZ2UxICsgXCJWXCIgKyBrICogdGlja1NpemVPdXRlcik7XG5cbiAgICB0aWNrXG4gICAgICAgIC5hdHRyKFwib3BhY2l0eVwiLCAxKVxuICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiB0cmFuc2Zvcm0ocG9zaXRpb24oZCkpOyB9KTtcblxuICAgIGxpbmVcbiAgICAgICAgLmF0dHIoeCArIFwiMlwiLCBrICogdGlja1NpemVJbm5lcik7XG5cbiAgICB0ZXh0XG4gICAgICAgIC5hdHRyKHgsIGsgKiBzcGFjaW5nKVxuICAgICAgICAudGV4dChmb3JtYXQpO1xuXG4gICAgc2VsZWN0aW9uLmZpbHRlcihlbnRlcmluZylcbiAgICAgICAgLmF0dHIoXCJmaWxsXCIsIFwibm9uZVwiKVxuICAgICAgICAuYXR0cihcImZvbnQtc2l6ZVwiLCAxMClcbiAgICAgICAgLmF0dHIoXCJmb250LWZhbWlseVwiLCBcInNhbnMtc2VyaWZcIilcbiAgICAgICAgLmF0dHIoXCJ0ZXh0LWFuY2hvclwiLCBvcmllbnQgPT09IHJpZ2h0ID8gXCJzdGFydFwiIDogb3JpZW50ID09PSBsZWZ0ID8gXCJlbmRcIiA6IFwibWlkZGxlXCIpO1xuXG4gICAgc2VsZWN0aW9uXG4gICAgICAgIC5lYWNoKGZ1bmN0aW9uKCkgeyB0aGlzLl9fYXhpcyA9IHBvc2l0aW9uOyB9KTtcbiAgfVxuXG4gIGF4aXMuc2NhbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc2NhbGUgPSBfLCBheGlzKSA6IHNjYWxlO1xuICB9O1xuXG4gIGF4aXMudGlja3MgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGlja0FyZ3VtZW50cyA9IHNsaWNlJDEuY2FsbChhcmd1bWVudHMpLCBheGlzO1xuICB9O1xuXG4gIGF4aXMudGlja0FyZ3VtZW50cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aWNrQXJndW1lbnRzID0gXyA9PSBudWxsID8gW10gOiBzbGljZSQxLmNhbGwoXyksIGF4aXMpIDogdGlja0FyZ3VtZW50cy5zbGljZSgpO1xuICB9O1xuXG4gIGF4aXMudGlja1ZhbHVlcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aWNrVmFsdWVzID0gXyA9PSBudWxsID8gbnVsbCA6IHNsaWNlJDEuY2FsbChfKSwgYXhpcykgOiB0aWNrVmFsdWVzICYmIHRpY2tWYWx1ZXMuc2xpY2UoKTtcbiAgfTtcblxuICBheGlzLnRpY2tGb3JtYXQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGlja0Zvcm1hdCA9IF8sIGF4aXMpIDogdGlja0Zvcm1hdDtcbiAgfTtcblxuICBheGlzLnRpY2tTaXplID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRpY2tTaXplSW5uZXIgPSB0aWNrU2l6ZU91dGVyID0gK18sIGF4aXMpIDogdGlja1NpemVJbm5lcjtcbiAgfTtcblxuICBheGlzLnRpY2tTaXplSW5uZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGlja1NpemVJbm5lciA9ICtfLCBheGlzKSA6IHRpY2tTaXplSW5uZXI7XG4gIH07XG5cbiAgYXhpcy50aWNrU2l6ZU91dGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRpY2tTaXplT3V0ZXIgPSArXywgYXhpcykgOiB0aWNrU2l6ZU91dGVyO1xuICB9O1xuXG4gIGF4aXMudGlja1BhZGRpbmcgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGlja1BhZGRpbmcgPSArXywgYXhpcykgOiB0aWNrUGFkZGluZztcbiAgfTtcblxuICByZXR1cm4gYXhpcztcbn1cblxuZnVuY3Rpb24gYXhpc1RvcChzY2FsZSkge1xuICByZXR1cm4gYXhpcyh0b3AsIHNjYWxlKTtcbn1cblxuZnVuY3Rpb24gYXhpc1JpZ2h0KHNjYWxlKSB7XG4gIHJldHVybiBheGlzKHJpZ2h0LCBzY2FsZSk7XG59XG5cbmZ1bmN0aW9uIGF4aXNCb3R0b20oc2NhbGUpIHtcbiAgcmV0dXJuIGF4aXMoYm90dG9tLCBzY2FsZSk7XG59XG5cbmZ1bmN0aW9uIGF4aXNMZWZ0KHNjYWxlKSB7XG4gIHJldHVybiBheGlzKGxlZnQsIHNjYWxlKTtcbn1cblxudmFyIG5vb3AgPSB7dmFsdWU6IGZ1bmN0aW9uKCkge319O1xuXG5mdW5jdGlvbiBkaXNwYXRjaCgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSBhcmd1bWVudHMubGVuZ3RoLCBfID0ge30sIHQ7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoISh0ID0gYXJndW1lbnRzW2ldICsgXCJcIikgfHwgKHQgaW4gXykpIHRocm93IG5ldyBFcnJvcihcImlsbGVnYWwgdHlwZTogXCIgKyB0KTtcbiAgICBfW3RdID0gW107XG4gIH1cbiAgcmV0dXJuIG5ldyBEaXNwYXRjaChfKTtcbn1cblxuZnVuY3Rpb24gRGlzcGF0Y2goXykge1xuICB0aGlzLl8gPSBfO1xufVxuXG5mdW5jdGlvbiBwYXJzZVR5cGVuYW1lcyh0eXBlbmFtZXMsIHR5cGVzKSB7XG4gIHJldHVybiB0eXBlbmFtZXMudHJpbSgpLnNwbGl0KC9efFxccysvKS5tYXAoZnVuY3Rpb24odCkge1xuICAgIHZhciBuYW1lID0gXCJcIiwgaSA9IHQuaW5kZXhPZihcIi5cIik7XG4gICAgaWYgKGkgPj0gMCkgbmFtZSA9IHQuc2xpY2UoaSArIDEpLCB0ID0gdC5zbGljZSgwLCBpKTtcbiAgICBpZiAodCAmJiAhdHlwZXMuaGFzT3duUHJvcGVydHkodCkpIHRocm93IG5ldyBFcnJvcihcInVua25vd24gdHlwZTogXCIgKyB0KTtcbiAgICByZXR1cm4ge3R5cGU6IHQsIG5hbWU6IG5hbWV9O1xuICB9KTtcbn1cblxuRGlzcGF0Y2gucHJvdG90eXBlID0gZGlzcGF0Y2gucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogRGlzcGF0Y2gsXG4gIG9uOiBmdW5jdGlvbih0eXBlbmFtZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgXyA9IHRoaXMuXyxcbiAgICAgICAgVCA9IHBhcnNlVHlwZW5hbWVzKHR5cGVuYW1lICsgXCJcIiwgXyksXG4gICAgICAgIHQsXG4gICAgICAgIGkgPSAtMSxcbiAgICAgICAgbiA9IFQubGVuZ3RoO1xuXG4gICAgLy8gSWYgbm8gY2FsbGJhY2sgd2FzIHNwZWNpZmllZCwgcmV0dXJuIHRoZSBjYWxsYmFjayBvZiB0aGUgZ2l2ZW4gdHlwZSBhbmQgbmFtZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKHQgPSAodHlwZW5hbWUgPSBUW2ldKS50eXBlKSAmJiAodCA9IGdldChfW3RdLCB0eXBlbmFtZS5uYW1lKSkpIHJldHVybiB0O1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIElmIGEgdHlwZSB3YXMgc3BlY2lmaWVkLCBzZXQgdGhlIGNhbGxiYWNrIGZvciB0aGUgZ2l2ZW4gdHlwZSBhbmQgbmFtZS5cbiAgICAvLyBPdGhlcndpc2UsIGlmIGEgbnVsbCBjYWxsYmFjayB3YXMgc3BlY2lmaWVkLCByZW1vdmUgY2FsbGJhY2tzIG9mIHRoZSBnaXZlbiBuYW1lLlxuICAgIGlmIChjYWxsYmFjayAhPSBudWxsICYmIHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGNhbGxiYWNrOiBcIiArIGNhbGxiYWNrKTtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKHQgPSAodHlwZW5hbWUgPSBUW2ldKS50eXBlKSBfW3RdID0gc2V0KF9bdF0sIHR5cGVuYW1lLm5hbWUsIGNhbGxiYWNrKTtcbiAgICAgIGVsc2UgaWYgKGNhbGxiYWNrID09IG51bGwpIGZvciAodCBpbiBfKSBfW3RdID0gc2V0KF9bdF0sIHR5cGVuYW1lLm5hbWUsIG51bGwpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBjb3B5OiBmdW5jdGlvbigpIHtcbiAgICB2YXIgY29weSA9IHt9LCBfID0gdGhpcy5fO1xuICAgIGZvciAodmFyIHQgaW4gXykgY29weVt0XSA9IF9bdF0uc2xpY2UoKTtcbiAgICByZXR1cm4gbmV3IERpc3BhdGNoKGNvcHkpO1xuICB9LFxuICBjYWxsOiBmdW5jdGlvbih0eXBlLCB0aGF0KSB7XG4gICAgaWYgKChuID0gYXJndW1lbnRzLmxlbmd0aCAtIDIpID4gMCkgZm9yICh2YXIgYXJncyA9IG5ldyBBcnJheShuKSwgaSA9IDAsIG4sIHQ7IGkgPCBuOyArK2kpIGFyZ3NbaV0gPSBhcmd1bWVudHNbaSArIDJdO1xuICAgIGlmICghdGhpcy5fLmhhc093blByb3BlcnR5KHR5cGUpKSB0aHJvdyBuZXcgRXJyb3IoXCJ1bmtub3duIHR5cGU6IFwiICsgdHlwZSk7XG4gICAgZm9yICh0ID0gdGhpcy5fW3R5cGVdLCBpID0gMCwgbiA9IHQubGVuZ3RoOyBpIDwgbjsgKytpKSB0W2ldLnZhbHVlLmFwcGx5KHRoYXQsIGFyZ3MpO1xuICB9LFxuICBhcHBseTogZnVuY3Rpb24odHlwZSwgdGhhdCwgYXJncykge1xuICAgIGlmICghdGhpcy5fLmhhc093blByb3BlcnR5KHR5cGUpKSB0aHJvdyBuZXcgRXJyb3IoXCJ1bmtub3duIHR5cGU6IFwiICsgdHlwZSk7XG4gICAgZm9yICh2YXIgdCA9IHRoaXMuX1t0eXBlXSwgaSA9IDAsIG4gPSB0Lmxlbmd0aDsgaSA8IG47ICsraSkgdFtpXS52YWx1ZS5hcHBseSh0aGF0LCBhcmdzKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZ2V0KHR5cGUsIG5hbWUpIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0eXBlLmxlbmd0aCwgYzsgaSA8IG47ICsraSkge1xuICAgIGlmICgoYyA9IHR5cGVbaV0pLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgIHJldHVybiBjLnZhbHVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzZXQodHlwZSwgbmFtZSwgY2FsbGJhY2spIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0eXBlLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgIGlmICh0eXBlW2ldLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgIHR5cGVbaV0gPSBub29wLCB0eXBlID0gdHlwZS5zbGljZSgwLCBpKS5jb25jYXQodHlwZS5zbGljZShpICsgMSkpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChjYWxsYmFjayAhPSBudWxsKSB0eXBlLnB1c2goe25hbWU6IG5hbWUsIHZhbHVlOiBjYWxsYmFja30pO1xuICByZXR1cm4gdHlwZTtcbn1cblxudmFyIHhodG1sID0gXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI7XG5cbnZhciBuYW1lc3BhY2VzID0ge1xuICBzdmc6IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIixcbiAgeGh0bWw6IHhodG1sLFxuICB4bGluazogXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIsXG4gIHhtbDogXCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VcIixcbiAgeG1sbnM6IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy9cIlxufTtcblxudmFyIG5hbWVzcGFjZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIHByZWZpeCA9IG5hbWUgKz0gXCJcIiwgaSA9IHByZWZpeC5pbmRleE9mKFwiOlwiKTtcbiAgaWYgKGkgPj0gMCAmJiAocHJlZml4ID0gbmFtZS5zbGljZSgwLCBpKSkgIT09IFwieG1sbnNcIikgbmFtZSA9IG5hbWUuc2xpY2UoaSArIDEpO1xuICByZXR1cm4gbmFtZXNwYWNlcy5oYXNPd25Qcm9wZXJ0eShwcmVmaXgpID8ge3NwYWNlOiBuYW1lc3BhY2VzW3ByZWZpeF0sIGxvY2FsOiBuYW1lfSA6IG5hbWU7XG59O1xuXG5mdW5jdGlvbiBjcmVhdG9ySW5oZXJpdChuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgZG9jdW1lbnQgPSB0aGlzLm93bmVyRG9jdW1lbnQsXG4gICAgICAgIHVyaSA9IHRoaXMubmFtZXNwYWNlVVJJO1xuICAgIHJldHVybiB1cmkgPT09IHhodG1sICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5uYW1lc3BhY2VVUkkgPT09IHhodG1sXG4gICAgICAgID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChuYW1lKVxuICAgICAgICA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyh1cmksIG5hbWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdG9yRml4ZWQoZnVsbG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7XG4gIH07XG59XG5cbnZhciBjcmVhdG9yID0gZnVuY3Rpb24obmFtZSkge1xuICB2YXIgZnVsbG5hbWUgPSBuYW1lc3BhY2UobmFtZSk7XG4gIHJldHVybiAoZnVsbG5hbWUubG9jYWxcbiAgICAgID8gY3JlYXRvckZpeGVkXG4gICAgICA6IGNyZWF0b3JJbmhlcml0KShmdWxsbmFtZSk7XG59O1xuXG52YXIgbmV4dElkID0gMDtcblxuZnVuY3Rpb24gbG9jYWwkMSgpIHtcbiAgcmV0dXJuIG5ldyBMb2NhbDtcbn1cblxuZnVuY3Rpb24gTG9jYWwoKSB7XG4gIHRoaXMuXyA9IFwiQFwiICsgKCsrbmV4dElkKS50b1N0cmluZygzNik7XG59XG5cbkxvY2FsLnByb3RvdHlwZSA9IGxvY2FsJDEucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogTG9jYWwsXG4gIGdldDogZnVuY3Rpb24obm9kZSkge1xuICAgIHZhciBpZCA9IHRoaXMuXztcbiAgICB3aGlsZSAoIShpZCBpbiBub2RlKSkgaWYgKCEobm9kZSA9IG5vZGUucGFyZW50Tm9kZSkpIHJldHVybjtcbiAgICByZXR1cm4gbm9kZVtpZF07XG4gIH0sXG4gIHNldDogZnVuY3Rpb24obm9kZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gbm9kZVt0aGlzLl9dID0gdmFsdWU7XG4gIH0sXG4gIHJlbW92ZTogZnVuY3Rpb24obm9kZSkge1xuICAgIHJldHVybiB0aGlzLl8gaW4gbm9kZSAmJiBkZWxldGUgbm9kZVt0aGlzLl9dO1xuICB9LFxuICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuXztcbiAgfVxufTtcblxudmFyIG1hdGNoZXIgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMubWF0Y2hlcyhzZWxlY3Rvcik7XG4gIH07XG59O1xuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICBpZiAoIWVsZW1lbnQubWF0Y2hlcykge1xuICAgIHZhciB2ZW5kb3JNYXRjaGVzID0gZWxlbWVudC53ZWJraXRNYXRjaGVzU2VsZWN0b3JcbiAgICAgICAgfHwgZWxlbWVudC5tc01hdGNoZXNTZWxlY3RvclxuICAgICAgICB8fCBlbGVtZW50Lm1vek1hdGNoZXNTZWxlY3RvclxuICAgICAgICB8fCBlbGVtZW50Lm9NYXRjaGVzU2VsZWN0b3I7XG4gICAgbWF0Y2hlciA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB2ZW5kb3JNYXRjaGVzLmNhbGwodGhpcywgc2VsZWN0b3IpO1xuICAgICAgfTtcbiAgICB9O1xuICB9XG59XG5cbnZhciBtYXRjaGVyJDEgPSBtYXRjaGVyO1xuXG52YXIgZmlsdGVyRXZlbnRzID0ge307XG5cbmV4cG9ydHMuZXZlbnQgPSBudWxsO1xuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gIHZhciBlbGVtZW50JDEgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gIGlmICghKFwib25tb3VzZWVudGVyXCIgaW4gZWxlbWVudCQxKSkge1xuICAgIGZpbHRlckV2ZW50cyA9IHttb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLCBtb3VzZWxlYXZlOiBcIm1vdXNlb3V0XCJ9O1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbHRlckNvbnRleHRMaXN0ZW5lcihsaXN0ZW5lciwgaW5kZXgsIGdyb3VwKSB7XG4gIGxpc3RlbmVyID0gY29udGV4dExpc3RlbmVyKGxpc3RlbmVyLCBpbmRleCwgZ3JvdXApO1xuICByZXR1cm4gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgcmVsYXRlZCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7XG4gICAgaWYgKCFyZWxhdGVkIHx8IChyZWxhdGVkICE9PSB0aGlzICYmICEocmVsYXRlZC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbih0aGlzKSAmIDgpKSkge1xuICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudCk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBjb250ZXh0TGlzdGVuZXIobGlzdGVuZXIsIGluZGV4LCBncm91cCkge1xuICByZXR1cm4gZnVuY3Rpb24oZXZlbnQxKSB7XG4gICAgdmFyIGV2ZW50MCA9IGV4cG9ydHMuZXZlbnQ7IC8vIEV2ZW50cyBjYW4gYmUgcmVlbnRyYW50IChlLmcuLCBmb2N1cykuXG4gICAgZXhwb3J0cy5ldmVudCA9IGV2ZW50MTtcbiAgICB0cnkge1xuICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCB0aGlzLl9fZGF0YV9fLCBpbmRleCwgZ3JvdXApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBleHBvcnRzLmV2ZW50ID0gZXZlbnQwO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gcGFyc2VUeXBlbmFtZXMkMSh0eXBlbmFtZXMpIHtcbiAgcmV0dXJuIHR5cGVuYW1lcy50cmltKCkuc3BsaXQoL158XFxzKy8pLm1hcChmdW5jdGlvbih0KSB7XG4gICAgdmFyIG5hbWUgPSBcIlwiLCBpID0gdC5pbmRleE9mKFwiLlwiKTtcbiAgICBpZiAoaSA+PSAwKSBuYW1lID0gdC5zbGljZShpICsgMSksIHQgPSB0LnNsaWNlKDAsIGkpO1xuICAgIHJldHVybiB7dHlwZTogdCwgbmFtZTogbmFtZX07XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBvblJlbW92ZSh0eXBlbmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9uID0gdGhpcy5fX29uO1xuICAgIGlmICghb24pIHJldHVybjtcbiAgICBmb3IgKHZhciBqID0gMCwgaSA9IC0xLCBtID0gb24ubGVuZ3RoLCBvOyBqIDwgbTsgKytqKSB7XG4gICAgICBpZiAobyA9IG9uW2pdLCAoIXR5cGVuYW1lLnR5cGUgfHwgby50eXBlID09PSB0eXBlbmFtZS50eXBlKSAmJiBvLm5hbWUgPT09IHR5cGVuYW1lLm5hbWUpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKG8udHlwZSwgby5saXN0ZW5lciwgby5jYXB0dXJlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9uWysraV0gPSBvO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoKytpKSBvbi5sZW5ndGggPSBpO1xuICAgIGVsc2UgZGVsZXRlIHRoaXMuX19vbjtcbiAgfTtcbn1cblxuZnVuY3Rpb24gb25BZGQodHlwZW5hbWUsIHZhbHVlLCBjYXB0dXJlKSB7XG4gIHZhciB3cmFwID0gZmlsdGVyRXZlbnRzLmhhc093blByb3BlcnR5KHR5cGVuYW1lLnR5cGUpID8gZmlsdGVyQ29udGV4dExpc3RlbmVyIDogY29udGV4dExpc3RlbmVyO1xuICByZXR1cm4gZnVuY3Rpb24oZCwgaSwgZ3JvdXApIHtcbiAgICB2YXIgb24gPSB0aGlzLl9fb24sIG8sIGxpc3RlbmVyID0gd3JhcCh2YWx1ZSwgaSwgZ3JvdXApO1xuICAgIGlmIChvbikgZm9yICh2YXIgaiA9IDAsIG0gPSBvbi5sZW5ndGg7IGogPCBtOyArK2opIHtcbiAgICAgIGlmICgobyA9IG9uW2pdKS50eXBlID09PSB0eXBlbmFtZS50eXBlICYmIG8ubmFtZSA9PT0gdHlwZW5hbWUubmFtZSkge1xuICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoby50eXBlLCBvLmxpc3RlbmVyLCBvLmNhcHR1cmUpO1xuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoby50eXBlLCBvLmxpc3RlbmVyID0gbGlzdGVuZXIsIG8uY2FwdHVyZSA9IGNhcHR1cmUpO1xuICAgICAgICBvLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKHR5cGVuYW1lLnR5cGUsIGxpc3RlbmVyLCBjYXB0dXJlKTtcbiAgICBvID0ge3R5cGU6IHR5cGVuYW1lLnR5cGUsIG5hbWU6IHR5cGVuYW1lLm5hbWUsIHZhbHVlOiB2YWx1ZSwgbGlzdGVuZXI6IGxpc3RlbmVyLCBjYXB0dXJlOiBjYXB0dXJlfTtcbiAgICBpZiAoIW9uKSB0aGlzLl9fb24gPSBbb107XG4gICAgZWxzZSBvbi5wdXNoKG8pO1xuICB9O1xufVxuXG52YXIgc2VsZWN0aW9uX29uID0gZnVuY3Rpb24odHlwZW5hbWUsIHZhbHVlLCBjYXB0dXJlKSB7XG4gIHZhciB0eXBlbmFtZXMgPSBwYXJzZVR5cGVuYW1lcyQxKHR5cGVuYW1lICsgXCJcIiksIGksIG4gPSB0eXBlbmFtZXMubGVuZ3RoLCB0O1xuXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgIHZhciBvbiA9IHRoaXMubm9kZSgpLl9fb247XG4gICAgaWYgKG9uKSBmb3IgKHZhciBqID0gMCwgbSA9IG9uLmxlbmd0aCwgbzsgaiA8IG07ICsraikge1xuICAgICAgZm9yIChpID0gMCwgbyA9IG9uW2pdOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmICgodCA9IHR5cGVuYW1lc1tpXSkudHlwZSA9PT0gby50eXBlICYmIHQubmFtZSA9PT0gby5uYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIG8udmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgb24gPSB2YWx1ZSA/IG9uQWRkIDogb25SZW1vdmU7XG4gIGlmIChjYXB0dXJlID09IG51bGwpIGNhcHR1cmUgPSBmYWxzZTtcbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgdGhpcy5lYWNoKG9uKHR5cGVuYW1lc1tpXSwgdmFsdWUsIGNhcHR1cmUpKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBjdXN0b21FdmVudChldmVudDEsIGxpc3RlbmVyLCB0aGF0LCBhcmdzKSB7XG4gIHZhciBldmVudDAgPSBleHBvcnRzLmV2ZW50O1xuICBldmVudDEuc291cmNlRXZlbnQgPSBleHBvcnRzLmV2ZW50O1xuICBleHBvcnRzLmV2ZW50ID0gZXZlbnQxO1xuICB0cnkge1xuICAgIHJldHVybiBsaXN0ZW5lci5hcHBseSh0aGF0LCBhcmdzKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBleHBvcnRzLmV2ZW50ID0gZXZlbnQwO1xuICB9XG59XG5cbnZhciBzb3VyY2VFdmVudCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY3VycmVudCA9IGV4cG9ydHMuZXZlbnQsIHNvdXJjZTtcbiAgd2hpbGUgKHNvdXJjZSA9IGN1cnJlbnQuc291cmNlRXZlbnQpIGN1cnJlbnQgPSBzb3VyY2U7XG4gIHJldHVybiBjdXJyZW50O1xufTtcblxudmFyIHBvaW50ID0gZnVuY3Rpb24obm9kZSwgZXZlbnQpIHtcbiAgdmFyIHN2ZyA9IG5vZGUub3duZXJTVkdFbGVtZW50IHx8IG5vZGU7XG5cbiAgaWYgKHN2Zy5jcmVhdGVTVkdQb2ludCkge1xuICAgIHZhciBwb2ludCA9IHN2Zy5jcmVhdGVTVkdQb2ludCgpO1xuICAgIHBvaW50LnggPSBldmVudC5jbGllbnRYLCBwb2ludC55ID0gZXZlbnQuY2xpZW50WTtcbiAgICBwb2ludCA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShub2RlLmdldFNjcmVlbkNUTSgpLmludmVyc2UoKSk7XG4gICAgcmV0dXJuIFtwb2ludC54LCBwb2ludC55XTtcbiAgfVxuXG4gIHZhciByZWN0ID0gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgcmV0dXJuIFtldmVudC5jbGllbnRYIC0gcmVjdC5sZWZ0IC0gbm9kZS5jbGllbnRMZWZ0LCBldmVudC5jbGllbnRZIC0gcmVjdC50b3AgLSBub2RlLmNsaWVudFRvcF07XG59O1xuXG52YXIgbW91c2UgPSBmdW5jdGlvbihub2RlKSB7XG4gIHZhciBldmVudCA9IHNvdXJjZUV2ZW50KCk7XG4gIGlmIChldmVudC5jaGFuZ2VkVG91Y2hlcykgZXZlbnQgPSBldmVudC5jaGFuZ2VkVG91Y2hlc1swXTtcbiAgcmV0dXJuIHBvaW50KG5vZGUsIGV2ZW50KTtcbn07XG5cbmZ1bmN0aW9uIG5vbmUoKSB7fVxuXG52YXIgc2VsZWN0b3IgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xuICByZXR1cm4gc2VsZWN0b3IgPT0gbnVsbCA/IG5vbmUgOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgfTtcbn07XG5cbnZhciBzZWxlY3Rpb25fc2VsZWN0ID0gZnVuY3Rpb24oc2VsZWN0KSB7XG4gIGlmICh0eXBlb2Ygc2VsZWN0ICE9PSBcImZ1bmN0aW9uXCIpIHNlbGVjdCA9IHNlbGVjdG9yKHNlbGVjdCk7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzdWJncm91cCA9IHN1Ymdyb3Vwc1tqXSA9IG5ldyBBcnJheShuKSwgbm9kZSwgc3Vibm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiAoc3Vibm9kZSA9IHNlbGVjdC5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKSkpIHtcbiAgICAgICAgaWYgKFwiX19kYXRhX19cIiBpbiBub2RlKSBzdWJub2RlLl9fZGF0YV9fID0gbm9kZS5fX2RhdGFfXztcbiAgICAgICAgc3ViZ3JvdXBbaV0gPSBzdWJub2RlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHN1Ymdyb3VwcywgdGhpcy5fcGFyZW50cyk7XG59O1xuXG5mdW5jdGlvbiBlbXB0eSQxKCkge1xuICByZXR1cm4gW107XG59XG5cbnZhciBzZWxlY3RvckFsbCA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gIHJldHVybiBzZWxlY3RvciA9PSBudWxsID8gZW1wdHkkMSA6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICB9O1xufTtcblxudmFyIHNlbGVjdGlvbl9zZWxlY3RBbGwgPSBmdW5jdGlvbihzZWxlY3QpIHtcbiAgaWYgKHR5cGVvZiBzZWxlY3QgIT09IFwiZnVuY3Rpb25cIikgc2VsZWN0ID0gc2VsZWN0b3JBbGwoc2VsZWN0KTtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzdWJncm91cHMgPSBbXSwgcGFyZW50cyA9IFtdLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBzdWJncm91cHMucHVzaChzZWxlY3QuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpO1xuICAgICAgICBwYXJlbnRzLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oc3ViZ3JvdXBzLCBwYXJlbnRzKTtcbn07XG5cbnZhciBzZWxlY3Rpb25fZmlsdGVyID0gZnVuY3Rpb24obWF0Y2gpIHtcbiAgaWYgKHR5cGVvZiBtYXRjaCAhPT0gXCJmdW5jdGlvblwiKSBtYXRjaCA9IG1hdGNoZXIkMShtYXRjaCk7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzdWJncm91cCA9IHN1Ymdyb3Vwc1tqXSA9IFtdLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKChub2RlID0gZ3JvdXBbaV0pICYmIG1hdGNoLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgZ3JvdXApKSB7XG4gICAgICAgIHN1Ymdyb3VwLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oc3ViZ3JvdXBzLCB0aGlzLl9wYXJlbnRzKTtcbn07XG5cbnZhciBzcGFyc2UgPSBmdW5jdGlvbih1cGRhdGUpIHtcbiAgcmV0dXJuIG5ldyBBcnJheSh1cGRhdGUubGVuZ3RoKTtcbn07XG5cbnZhciBzZWxlY3Rpb25fZW50ZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24odGhpcy5fZW50ZXIgfHwgdGhpcy5fZ3JvdXBzLm1hcChzcGFyc2UpLCB0aGlzLl9wYXJlbnRzKTtcbn07XG5cbmZ1bmN0aW9uIEVudGVyTm9kZShwYXJlbnQsIGRhdHVtKSB7XG4gIHRoaXMub3duZXJEb2N1bWVudCA9IHBhcmVudC5vd25lckRvY3VtZW50O1xuICB0aGlzLm5hbWVzcGFjZVVSSSA9IHBhcmVudC5uYW1lc3BhY2VVUkk7XG4gIHRoaXMuX25leHQgPSBudWxsO1xuICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMuX19kYXRhX18gPSBkYXR1bTtcbn1cblxuRW50ZXJOb2RlLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IEVudGVyTm9kZSxcbiAgYXBwZW5kQ2hpbGQ6IGZ1bmN0aW9uKGNoaWxkKSB7IHJldHVybiB0aGlzLl9wYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCB0aGlzLl9uZXh0KTsgfSxcbiAgaW5zZXJ0QmVmb3JlOiBmdW5jdGlvbihjaGlsZCwgbmV4dCkgeyByZXR1cm4gdGhpcy5fcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgbmV4dCk7IH0sXG4gIHF1ZXJ5U2VsZWN0b3I6IGZ1bmN0aW9uKHNlbGVjdG9yKSB7IHJldHVybiB0aGlzLl9wYXJlbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7IH0sXG4gIHF1ZXJ5U2VsZWN0b3JBbGw6IGZ1bmN0aW9uKHNlbGVjdG9yKSB7IHJldHVybiB0aGlzLl9wYXJlbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7IH1cbn07XG5cbnZhciBjb25zdGFudCQxID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG52YXIga2V5UHJlZml4ID0gXCIkXCI7IC8vIFByb3RlY3QgYWdhaW5zdCBrZXlzIGxpa2Ug4oCcX19wcm90b19f4oCdLlxuXG5mdW5jdGlvbiBiaW5kSW5kZXgocGFyZW50LCBncm91cCwgZW50ZXIsIHVwZGF0ZSwgZXhpdCwgZGF0YSkge1xuICB2YXIgaSA9IDAsXG4gICAgICBub2RlLFxuICAgICAgZ3JvdXBMZW5ndGggPSBncm91cC5sZW5ndGgsXG4gICAgICBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGg7XG5cbiAgLy8gUHV0IGFueSBub24tbnVsbCBub2RlcyB0aGF0IGZpdCBpbnRvIHVwZGF0ZS5cbiAgLy8gUHV0IGFueSBudWxsIG5vZGVzIGludG8gZW50ZXIuXG4gIC8vIFB1dCBhbnkgcmVtYWluaW5nIGRhdGEgaW50byBlbnRlci5cbiAgZm9yICg7IGkgPCBkYXRhTGVuZ3RoOyArK2kpIHtcbiAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICBub2RlLl9fZGF0YV9fID0gZGF0YVtpXTtcbiAgICAgIHVwZGF0ZVtpXSA9IG5vZGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudGVyW2ldID0gbmV3IEVudGVyTm9kZShwYXJlbnQsIGRhdGFbaV0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIFB1dCBhbnkgbm9uLW51bGwgbm9kZXMgdGhhdCBkb27igJl0IGZpdCBpbnRvIGV4aXQuXG4gIGZvciAoOyBpIDwgZ3JvdXBMZW5ndGg7ICsraSkge1xuICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgIGV4aXRbaV0gPSBub2RlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBiaW5kS2V5KHBhcmVudCwgZ3JvdXAsIGVudGVyLCB1cGRhdGUsIGV4aXQsIGRhdGEsIGtleSkge1xuICB2YXIgaSxcbiAgICAgIG5vZGUsXG4gICAgICBub2RlQnlLZXlWYWx1ZSA9IHt9LFxuICAgICAgZ3JvdXBMZW5ndGggPSBncm91cC5sZW5ndGgsXG4gICAgICBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGgsXG4gICAgICBrZXlWYWx1ZXMgPSBuZXcgQXJyYXkoZ3JvdXBMZW5ndGgpLFxuICAgICAga2V5VmFsdWU7XG5cbiAgLy8gQ29tcHV0ZSB0aGUga2V5IGZvciBlYWNoIG5vZGUuXG4gIC8vIElmIG11bHRpcGxlIG5vZGVzIGhhdmUgdGhlIHNhbWUga2V5LCB0aGUgZHVwbGljYXRlcyBhcmUgYWRkZWQgdG8gZXhpdC5cbiAgZm9yIChpID0gMDsgaSA8IGdyb3VwTGVuZ3RoOyArK2kpIHtcbiAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICBrZXlWYWx1ZXNbaV0gPSBrZXlWYWx1ZSA9IGtleVByZWZpeCArIGtleS5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKTtcbiAgICAgIGlmIChrZXlWYWx1ZSBpbiBub2RlQnlLZXlWYWx1ZSkge1xuICAgICAgICBleGl0W2ldID0gbm9kZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGVCeUtleVZhbHVlW2tleVZhbHVlXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ29tcHV0ZSB0aGUga2V5IGZvciBlYWNoIGRhdHVtLlxuICAvLyBJZiB0aGVyZSBhIG5vZGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMga2V5LCBqb2luIGFuZCBhZGQgaXQgdG8gdXBkYXRlLlxuICAvLyBJZiB0aGVyZSBpcyBub3QgKG9yIHRoZSBrZXkgaXMgYSBkdXBsaWNhdGUpLCBhZGQgaXQgdG8gZW50ZXIuXG4gIGZvciAoaSA9IDA7IGkgPCBkYXRhTGVuZ3RoOyArK2kpIHtcbiAgICBrZXlWYWx1ZSA9IGtleVByZWZpeCArIGtleS5jYWxsKHBhcmVudCwgZGF0YVtpXSwgaSwgZGF0YSk7XG4gICAgaWYgKG5vZGUgPSBub2RlQnlLZXlWYWx1ZVtrZXlWYWx1ZV0pIHtcbiAgICAgIHVwZGF0ZVtpXSA9IG5vZGU7XG4gICAgICBub2RlLl9fZGF0YV9fID0gZGF0YVtpXTtcbiAgICAgIG5vZGVCeUtleVZhbHVlW2tleVZhbHVlXSA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudGVyW2ldID0gbmV3IEVudGVyTm9kZShwYXJlbnQsIGRhdGFbaV0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFkZCBhbnkgcmVtYWluaW5nIG5vZGVzIHRoYXQgd2VyZSBub3QgYm91bmQgdG8gZGF0YSB0byBleGl0LlxuICBmb3IgKGkgPSAwOyBpIDwgZ3JvdXBMZW5ndGg7ICsraSkge1xuICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiAobm9kZUJ5S2V5VmFsdWVba2V5VmFsdWVzW2ldXSA9PT0gbm9kZSkpIHtcbiAgICAgIGV4aXRbaV0gPSBub2RlO1xuICAgIH1cbiAgfVxufVxuXG52YXIgc2VsZWN0aW9uX2RhdGEgPSBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gIGlmICghdmFsdWUpIHtcbiAgICBkYXRhID0gbmV3IEFycmF5KHRoaXMuc2l6ZSgpKSwgaiA9IC0xO1xuICAgIHRoaXMuZWFjaChmdW5jdGlvbihkKSB7IGRhdGFbKytqXSA9IGQ7IH0pO1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgdmFyIGJpbmQgPSBrZXkgPyBiaW5kS2V5IDogYmluZEluZGV4LFxuICAgICAgcGFyZW50cyA9IHRoaXMuX3BhcmVudHMsXG4gICAgICBncm91cHMgPSB0aGlzLl9ncm91cHM7XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB2YWx1ZSA9IGNvbnN0YW50JDEodmFsdWUpO1xuXG4gIGZvciAodmFyIG0gPSBncm91cHMubGVuZ3RoLCB1cGRhdGUgPSBuZXcgQXJyYXkobSksIGVudGVyID0gbmV3IEFycmF5KG0pLCBleGl0ID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIHZhciBwYXJlbnQgPSBwYXJlbnRzW2pdLFxuICAgICAgICBncm91cCA9IGdyb3Vwc1tqXSxcbiAgICAgICAgZ3JvdXBMZW5ndGggPSBncm91cC5sZW5ndGgsXG4gICAgICAgIGRhdGEgPSB2YWx1ZS5jYWxsKHBhcmVudCwgcGFyZW50ICYmIHBhcmVudC5fX2RhdGFfXywgaiwgcGFyZW50cyksXG4gICAgICAgIGRhdGFMZW5ndGggPSBkYXRhLmxlbmd0aCxcbiAgICAgICAgZW50ZXJHcm91cCA9IGVudGVyW2pdID0gbmV3IEFycmF5KGRhdGFMZW5ndGgpLFxuICAgICAgICB1cGRhdGVHcm91cCA9IHVwZGF0ZVtqXSA9IG5ldyBBcnJheShkYXRhTGVuZ3RoKSxcbiAgICAgICAgZXhpdEdyb3VwID0gZXhpdFtqXSA9IG5ldyBBcnJheShncm91cExlbmd0aCk7XG5cbiAgICBiaW5kKHBhcmVudCwgZ3JvdXAsIGVudGVyR3JvdXAsIHVwZGF0ZUdyb3VwLCBleGl0R3JvdXAsIGRhdGEsIGtleSk7XG5cbiAgICAvLyBOb3cgY29ubmVjdCB0aGUgZW50ZXIgbm9kZXMgdG8gdGhlaXIgZm9sbG93aW5nIHVwZGF0ZSBub2RlLCBzdWNoIHRoYXRcbiAgICAvLyBhcHBlbmRDaGlsZCBjYW4gaW5zZXJ0IHRoZSBtYXRlcmlhbGl6ZWQgZW50ZXIgbm9kZSBiZWZvcmUgdGhpcyBub2RlLFxuICAgIC8vIHJhdGhlciB0aGFuIGF0IHRoZSBlbmQgb2YgdGhlIHBhcmVudCBub2RlLlxuICAgIGZvciAodmFyIGkwID0gMCwgaTEgPSAwLCBwcmV2aW91cywgbmV4dDsgaTAgPCBkYXRhTGVuZ3RoOyArK2kwKSB7XG4gICAgICBpZiAocHJldmlvdXMgPSBlbnRlckdyb3VwW2kwXSkge1xuICAgICAgICBpZiAoaTAgPj0gaTEpIGkxID0gaTAgKyAxO1xuICAgICAgICB3aGlsZSAoIShuZXh0ID0gdXBkYXRlR3JvdXBbaTFdKSAmJiArK2kxIDwgZGF0YUxlbmd0aCk7XG4gICAgICAgIHByZXZpb3VzLl9uZXh0ID0gbmV4dCB8fCBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZSA9IG5ldyBTZWxlY3Rpb24odXBkYXRlLCBwYXJlbnRzKTtcbiAgdXBkYXRlLl9lbnRlciA9IGVudGVyO1xuICB1cGRhdGUuX2V4aXQgPSBleGl0O1xuICByZXR1cm4gdXBkYXRlO1xufTtcblxudmFyIHNlbGVjdGlvbl9leGl0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHRoaXMuX2V4aXQgfHwgdGhpcy5fZ3JvdXBzLm1hcChzcGFyc2UpLCB0aGlzLl9wYXJlbnRzKTtcbn07XG5cbnZhciBzZWxlY3Rpb25fbWVyZ2UgPSBmdW5jdGlvbihzZWxlY3Rpb24pIHtcblxuICBmb3IgKHZhciBncm91cHMwID0gdGhpcy5fZ3JvdXBzLCBncm91cHMxID0gc2VsZWN0aW9uLl9ncm91cHMsIG0wID0gZ3JvdXBzMC5sZW5ndGgsIG0xID0gZ3JvdXBzMS5sZW5ndGgsIG0gPSBNYXRoLm1pbihtMCwgbTEpLCBtZXJnZXMgPSBuZXcgQXJyYXkobTApLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwMCA9IGdyb3VwczBbal0sIGdyb3VwMSA9IGdyb3VwczFbal0sIG4gPSBncm91cDAubGVuZ3RoLCBtZXJnZSA9IG1lcmdlc1tqXSA9IG5ldyBBcnJheShuKSwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmIChub2RlID0gZ3JvdXAwW2ldIHx8IGdyb3VwMVtpXSkge1xuICAgICAgICBtZXJnZVtpXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IGogPCBtMDsgKytqKSB7XG4gICAgbWVyZ2VzW2pdID0gZ3JvdXBzMFtqXTtcbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKG1lcmdlcywgdGhpcy5fcGFyZW50cyk7XG59O1xuXG52YXIgc2VsZWN0aW9uX29yZGVyID0gZnVuY3Rpb24oKSB7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBqID0gLTEsIG0gPSBncm91cHMubGVuZ3RoOyArK2ogPCBtOykge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBpID0gZ3JvdXAubGVuZ3RoIC0gMSwgbmV4dCA9IGdyb3VwW2ldLCBub2RlOyAtLWkgPj0gMDspIHtcbiAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgICAgaWYgKG5leHQgJiYgbmV4dCAhPT0gbm9kZS5uZXh0U2libGluZykgbmV4dC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShub2RlLCBuZXh0KTtcbiAgICAgICAgbmV4dCA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG52YXIgc2VsZWN0aW9uX3NvcnQgPSBmdW5jdGlvbihjb21wYXJlKSB7XG4gIGlmICghY29tcGFyZSkgY29tcGFyZSA9IGFzY2VuZGluZyQxO1xuXG4gIGZ1bmN0aW9uIGNvbXBhcmVOb2RlKGEsIGIpIHtcbiAgICByZXR1cm4gYSAmJiBiID8gY29tcGFyZShhLl9fZGF0YV9fLCBiLl9fZGF0YV9fKSA6ICFhIC0gIWI7XG4gIH1cblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzb3J0Z3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzb3J0Z3JvdXAgPSBzb3J0Z3JvdXBzW2pdID0gbmV3IEFycmF5KG4pLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBzb3J0Z3JvdXBbaV0gPSBub2RlO1xuICAgICAgfVxuICAgIH1cbiAgICBzb3J0Z3JvdXAuc29ydChjb21wYXJlTm9kZSk7XG4gIH1cblxuICByZXR1cm4gbmV3IFNlbGVjdGlvbihzb3J0Z3JvdXBzLCB0aGlzLl9wYXJlbnRzKS5vcmRlcigpO1xufTtcblxuZnVuY3Rpb24gYXNjZW5kaW5nJDEoYSwgYikge1xuICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IGEgPj0gYiA/IDAgOiBOYU47XG59XG5cbnZhciBzZWxlY3Rpb25fY2FsbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY2FsbGJhY2sgPSBhcmd1bWVudHNbMF07XG4gIGFyZ3VtZW50c1swXSA9IHRoaXM7XG4gIGNhbGxiYWNrLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIHNlbGVjdGlvbl9ub2RlcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZXMgPSBuZXcgQXJyYXkodGhpcy5zaXplKCkpLCBpID0gLTE7XG4gIHRoaXMuZWFjaChmdW5jdGlvbigpIHsgbm9kZXNbKytpXSA9IHRoaXM7IH0pO1xuICByZXR1cm4gbm9kZXM7XG59O1xuXG52YXIgc2VsZWN0aW9uX25vZGUgPSBmdW5jdGlvbigpIHtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIGogPSAwLCBtID0gZ3JvdXBzLmxlbmd0aDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBpID0gMCwgbiA9IGdyb3VwLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgdmFyIG5vZGUgPSBncm91cFtpXTtcbiAgICAgIGlmIChub2RlKSByZXR1cm4gbm9kZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn07XG5cbnZhciBzZWxlY3Rpb25fc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2l6ZSA9IDA7XG4gIHRoaXMuZWFjaChmdW5jdGlvbigpIHsgKytzaXplOyB9KTtcbiAgcmV0dXJuIHNpemU7XG59O1xuXG52YXIgc2VsZWN0aW9uX2VtcHR5ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAhdGhpcy5ub2RlKCk7XG59O1xuXG52YXIgc2VsZWN0aW9uX2VhY2ggPSBmdW5jdGlvbihjYWxsYmFjaykge1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgaiA9IDAsIG0gPSBncm91cHMubGVuZ3RoOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIGkgPSAwLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSBjYWxsYmFjay5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGF0dHJSZW1vdmUobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJSZW1vdmVOUyhmdWxsbmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyQ29uc3RhbnQobmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckNvbnN0YW50TlMoZnVsbG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnNldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCwgdmFsdWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyRnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAodiA9PSBudWxsKSB0aGlzLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICBlbHNlIHRoaXMuc2V0QXR0cmlidXRlKG5hbWUsIHYpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyRnVuY3Rpb25OUyhmdWxsbmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAodiA9PSBudWxsKSB0aGlzLnJlbW92ZUF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7XG4gICAgZWxzZSB0aGlzLnNldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCwgdik7XG4gIH07XG59XG5cbnZhciBzZWxlY3Rpb25fYXR0ciA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHZhciBmdWxsbmFtZSA9IG5hbWVzcGFjZShuYW1lKTtcblxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMubm9kZSgpO1xuICAgIHJldHVybiBmdWxsbmFtZS5sb2NhbFxuICAgICAgICA/IG5vZGUuZ2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKVxuICAgICAgICA6IG5vZGUuZ2V0QXR0cmlidXRlKGZ1bGxuYW1lKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmVhY2goKHZhbHVlID09IG51bGxcbiAgICAgID8gKGZ1bGxuYW1lLmxvY2FsID8gYXR0clJlbW92ZU5TIDogYXR0clJlbW92ZSkgOiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gKGZ1bGxuYW1lLmxvY2FsID8gYXR0ckZ1bmN0aW9uTlMgOiBhdHRyRnVuY3Rpb24pXG4gICAgICA6IChmdWxsbmFtZS5sb2NhbCA/IGF0dHJDb25zdGFudE5TIDogYXR0ckNvbnN0YW50KSkpKGZ1bGxuYW1lLCB2YWx1ZSkpO1xufTtcblxudmFyIHdpbmRvdyA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgcmV0dXJuIChub2RlLm93bmVyRG9jdW1lbnQgJiYgbm9kZS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3KSAvLyBub2RlIGlzIGEgTm9kZVxuICAgICAgfHwgKG5vZGUuZG9jdW1lbnQgJiYgbm9kZSkgLy8gbm9kZSBpcyBhIFdpbmRvd1xuICAgICAgfHwgbm9kZS5kZWZhdWx0VmlldzsgLy8gbm9kZSBpcyBhIERvY3VtZW50XG59O1xuXG5mdW5jdGlvbiBzdHlsZVJlbW92ZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnN0eWxlLnJlbW92ZVByb3BlcnR5KG5hbWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdHlsZUNvbnN0YW50KG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5zdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdHlsZUZ1bmN0aW9uKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh2ID09IG51bGwpIHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVydHkobmFtZSk7XG4gICAgZWxzZSB0aGlzLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHYsIHByaW9yaXR5KTtcbiAgfTtcbn1cblxudmFyIHNlbGVjdGlvbl9zdHlsZSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICB2YXIgbm9kZTtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAxXG4gICAgICA/IHRoaXMuZWFjaCgodmFsdWUgPT0gbnVsbFxuICAgICAgICAgICAgPyBzdHlsZVJlbW92ZSA6IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IHN0eWxlRnVuY3Rpb25cbiAgICAgICAgICAgIDogc3R5bGVDb25zdGFudCkobmFtZSwgdmFsdWUsIHByaW9yaXR5ID09IG51bGwgPyBcIlwiIDogcHJpb3JpdHkpKVxuICAgICAgOiB3aW5kb3cobm9kZSA9IHRoaXMubm9kZSgpKVxuICAgICAgICAgIC5nZXRDb21wdXRlZFN0eWxlKG5vZGUsIG51bGwpXG4gICAgICAgICAgLmdldFByb3BlcnR5VmFsdWUobmFtZSk7XG59O1xuXG5mdW5jdGlvbiBwcm9wZXJ0eVJlbW92ZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBkZWxldGUgdGhpc1tuYW1lXTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcHJvcGVydHlDb25zdGFudChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpc1tuYW1lXSA9IHZhbHVlO1xuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9wZXJ0eUZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHYgPT0gbnVsbCkgZGVsZXRlIHRoaXNbbmFtZV07XG4gICAgZWxzZSB0aGlzW25hbWVdID0gdjtcbiAgfTtcbn1cblxudmFyIHNlbGVjdGlvbl9wcm9wZXJ0eSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMVxuICAgICAgPyB0aGlzLmVhY2goKHZhbHVlID09IG51bGxcbiAgICAgICAgICA/IHByb3BlcnR5UmVtb3ZlIDogdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IHByb3BlcnR5RnVuY3Rpb25cbiAgICAgICAgICA6IHByb3BlcnR5Q29uc3RhbnQpKG5hbWUsIHZhbHVlKSlcbiAgICAgIDogdGhpcy5ub2RlKClbbmFtZV07XG59O1xuXG5mdW5jdGlvbiBjbGFzc0FycmF5KHN0cmluZykge1xuICByZXR1cm4gc3RyaW5nLnRyaW0oKS5zcGxpdCgvXnxcXHMrLyk7XG59XG5cbmZ1bmN0aW9uIGNsYXNzTGlzdChub2RlKSB7XG4gIHJldHVybiBub2RlLmNsYXNzTGlzdCB8fCBuZXcgQ2xhc3NMaXN0KG5vZGUpO1xufVxuXG5mdW5jdGlvbiBDbGFzc0xpc3Qobm9kZSkge1xuICB0aGlzLl9ub2RlID0gbm9kZTtcbiAgdGhpcy5fbmFtZXMgPSBjbGFzc0FycmF5KG5vZGUuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIikgfHwgXCJcIik7XG59XG5cbkNsYXNzTGlzdC5wcm90b3R5cGUgPSB7XG4gIGFkZDogZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBpID0gdGhpcy5fbmFtZXMuaW5kZXhPZihuYW1lKTtcbiAgICBpZiAoaSA8IDApIHtcbiAgICAgIHRoaXMuX25hbWVzLnB1c2gobmFtZSk7XG4gICAgICB0aGlzLl9ub2RlLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIHRoaXMuX25hbWVzLmpvaW4oXCIgXCIpKTtcbiAgICB9XG4gIH0sXG4gIHJlbW92ZTogZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBpID0gdGhpcy5fbmFtZXMuaW5kZXhPZihuYW1lKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLl9uYW1lcy5zcGxpY2UoaSwgMSk7XG4gICAgICB0aGlzLl9ub2RlLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIHRoaXMuX25hbWVzLmpvaW4oXCIgXCIpKTtcbiAgICB9XG4gIH0sXG4gIGNvbnRhaW5zOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuX25hbWVzLmluZGV4T2YobmFtZSkgPj0gMDtcbiAgfVxufTtcblxuZnVuY3Rpb24gY2xhc3NlZEFkZChub2RlLCBuYW1lcykge1xuICB2YXIgbGlzdCA9IGNsYXNzTGlzdChub2RlKSwgaSA9IC0xLCBuID0gbmFtZXMubGVuZ3RoO1xuICB3aGlsZSAoKytpIDwgbikgbGlzdC5hZGQobmFtZXNbaV0pO1xufVxuXG5mdW5jdGlvbiBjbGFzc2VkUmVtb3ZlKG5vZGUsIG5hbWVzKSB7XG4gIHZhciBsaXN0ID0gY2xhc3NMaXN0KG5vZGUpLCBpID0gLTEsIG4gPSBuYW1lcy5sZW5ndGg7XG4gIHdoaWxlICgrK2kgPCBuKSBsaXN0LnJlbW92ZShuYW1lc1tpXSk7XG59XG5cbmZ1bmN0aW9uIGNsYXNzZWRUcnVlKG5hbWVzKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBjbGFzc2VkQWRkKHRoaXMsIG5hbWVzKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2xhc3NlZEZhbHNlKG5hbWVzKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBjbGFzc2VkUmVtb3ZlKHRoaXMsIG5hbWVzKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2xhc3NlZEZ1bmN0aW9uKG5hbWVzLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgKHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgPyBjbGFzc2VkQWRkIDogY2xhc3NlZFJlbW92ZSkodGhpcywgbmFtZXMpO1xuICB9O1xufVxuXG52YXIgc2VsZWN0aW9uX2NsYXNzZWQgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICB2YXIgbmFtZXMgPSBjbGFzc0FycmF5KG5hbWUgKyBcIlwiKTtcblxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICB2YXIgbGlzdCA9IGNsYXNzTGlzdCh0aGlzLm5vZGUoKSksIGkgPSAtMSwgbiA9IG5hbWVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFsaXN0LmNvbnRhaW5zKG5hbWVzW2ldKSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuZWFjaCgodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gY2xhc3NlZEZ1bmN0aW9uIDogdmFsdWVcbiAgICAgID8gY2xhc3NlZFRydWVcbiAgICAgIDogY2xhc3NlZEZhbHNlKShuYW1lcywgdmFsdWUpKTtcbn07XG5cbmZ1bmN0aW9uIHRleHRSZW1vdmUoKSB7XG4gIHRoaXMudGV4dENvbnRlbnQgPSBcIlwiO1xufVxuXG5mdW5jdGlvbiB0ZXh0Q29uc3RhbnQodmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMudGV4dENvbnRlbnQgPSB2YWx1ZTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gdGV4dEZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy50ZXh0Q29udGVudCA9IHYgPT0gbnVsbCA/IFwiXCIgOiB2O1xuICB9O1xufVxuXG52YXIgc2VsZWN0aW9uX3RleHQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgPyB0aGlzLmVhY2godmFsdWUgPT0gbnVsbFxuICAgICAgICAgID8gdGV4dFJlbW92ZSA6ICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgID8gdGV4dEZ1bmN0aW9uXG4gICAgICAgICAgOiB0ZXh0Q29uc3RhbnQpKHZhbHVlKSlcbiAgICAgIDogdGhpcy5ub2RlKCkudGV4dENvbnRlbnQ7XG59O1xuXG5mdW5jdGlvbiBodG1sUmVtb3ZlKCkge1xuICB0aGlzLmlubmVySFRNTCA9IFwiXCI7XG59XG5cbmZ1bmN0aW9uIGh0bWxDb25zdGFudCh2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaHRtbEZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5pbm5lckhUTUwgPSB2ID09IG51bGwgPyBcIlwiIDogdjtcbiAgfTtcbn1cblxudmFyIHNlbGVjdGlvbl9odG1sID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGhcbiAgICAgID8gdGhpcy5lYWNoKHZhbHVlID09IG51bGxcbiAgICAgICAgICA/IGh0bWxSZW1vdmUgOiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IGh0bWxGdW5jdGlvblxuICAgICAgICAgIDogaHRtbENvbnN0YW50KSh2YWx1ZSkpXG4gICAgICA6IHRoaXMubm9kZSgpLmlubmVySFRNTDtcbn07XG5cbmZ1bmN0aW9uIHJhaXNlKCkge1xuICBpZiAodGhpcy5uZXh0U2libGluZykgdGhpcy5wYXJlbnROb2RlLmFwcGVuZENoaWxkKHRoaXMpO1xufVxuXG52YXIgc2VsZWN0aW9uX3JhaXNlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmVhY2gocmFpc2UpO1xufTtcblxuZnVuY3Rpb24gbG93ZXIoKSB7XG4gIGlmICh0aGlzLnByZXZpb3VzU2libGluZykgdGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLCB0aGlzLnBhcmVudE5vZGUuZmlyc3RDaGlsZCk7XG59XG5cbnZhciBzZWxlY3Rpb25fbG93ZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaChsb3dlcik7XG59O1xuXG52YXIgc2VsZWN0aW9uX2FwcGVuZCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIGNyZWF0ZSA9IHR5cGVvZiBuYW1lID09PSBcImZ1bmN0aW9uXCIgPyBuYW1lIDogY3JlYXRvcihuYW1lKTtcbiAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmFwcGVuZENoaWxkKGNyZWF0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBjb25zdGFudE51bGwoKSB7XG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgc2VsZWN0aW9uX2luc2VydCA9IGZ1bmN0aW9uKG5hbWUsIGJlZm9yZSkge1xuICB2YXIgY3JlYXRlID0gdHlwZW9mIG5hbWUgPT09IFwiZnVuY3Rpb25cIiA/IG5hbWUgOiBjcmVhdG9yKG5hbWUpLFxuICAgICAgc2VsZWN0ID0gYmVmb3JlID09IG51bGwgPyBjb25zdGFudE51bGwgOiB0eXBlb2YgYmVmb3JlID09PSBcImZ1bmN0aW9uXCIgPyBiZWZvcmUgOiBzZWxlY3RvcihiZWZvcmUpO1xuICByZXR1cm4gdGhpcy5zZWxlY3QoZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zZXJ0QmVmb3JlKGNyZWF0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpLCBzZWxlY3QuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCBudWxsKTtcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiByZW1vdmUoKSB7XG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XG4gIGlmIChwYXJlbnQpIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTtcbn1cblxudmFyIHNlbGVjdGlvbl9yZW1vdmUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaChyZW1vdmUpO1xufTtcblxudmFyIHNlbGVjdGlvbl9kYXR1bSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoXG4gICAgICA/IHRoaXMucHJvcGVydHkoXCJfX2RhdGFfX1wiLCB2YWx1ZSlcbiAgICAgIDogdGhpcy5ub2RlKCkuX19kYXRhX187XG59O1xuXG5mdW5jdGlvbiBkaXNwYXRjaEV2ZW50KG5vZGUsIHR5cGUsIHBhcmFtcykge1xuICB2YXIgd2luZG93JCQxID0gd2luZG93KG5vZGUpLFxuICAgICAgZXZlbnQgPSB3aW5kb3ckJDEuQ3VzdG9tRXZlbnQ7XG5cbiAgaWYgKGV2ZW50KSB7XG4gICAgZXZlbnQgPSBuZXcgZXZlbnQodHlwZSwgcGFyYW1zKTtcbiAgfSBlbHNlIHtcbiAgICBldmVudCA9IHdpbmRvdyQkMS5kb2N1bWVudC5jcmVhdGVFdmVudChcIkV2ZW50XCIpO1xuICAgIGlmIChwYXJhbXMpIGV2ZW50LmluaXRFdmVudCh0eXBlLCBwYXJhbXMuYnViYmxlcywgcGFyYW1zLmNhbmNlbGFibGUpLCBldmVudC5kZXRhaWwgPSBwYXJhbXMuZGV0YWlsO1xuICAgIGVsc2UgZXZlbnQuaW5pdEV2ZW50KHR5cGUsIGZhbHNlLCBmYWxzZSk7XG4gIH1cblxuICBub2RlLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaENvbnN0YW50KHR5cGUsIHBhcmFtcykge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGRpc3BhdGNoRXZlbnQodGhpcywgdHlwZSwgcGFyYW1zKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hGdW5jdGlvbih0eXBlLCBwYXJhbXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkaXNwYXRjaEV2ZW50KHRoaXMsIHR5cGUsIHBhcmFtcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgfTtcbn1cblxudmFyIHNlbGVjdGlvbl9kaXNwYXRjaCA9IGZ1bmN0aW9uKHR5cGUsIHBhcmFtcykge1xuICByZXR1cm4gdGhpcy5lYWNoKCh0eXBlb2YgcGFyYW1zID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gZGlzcGF0Y2hGdW5jdGlvblxuICAgICAgOiBkaXNwYXRjaENvbnN0YW50KSh0eXBlLCBwYXJhbXMpKTtcbn07XG5cbnZhciByb290ID0gW251bGxdO1xuXG5mdW5jdGlvbiBTZWxlY3Rpb24oZ3JvdXBzLCBwYXJlbnRzKSB7XG4gIHRoaXMuX2dyb3VwcyA9IGdyb3VwcztcbiAgdGhpcy5fcGFyZW50cyA9IHBhcmVudHM7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oW1tkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRdXSwgcm9vdCk7XG59XG5cblNlbGVjdGlvbi5wcm90b3R5cGUgPSBzZWxlY3Rpb24ucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogU2VsZWN0aW9uLFxuICBzZWxlY3Q6IHNlbGVjdGlvbl9zZWxlY3QsXG4gIHNlbGVjdEFsbDogc2VsZWN0aW9uX3NlbGVjdEFsbCxcbiAgZmlsdGVyOiBzZWxlY3Rpb25fZmlsdGVyLFxuICBkYXRhOiBzZWxlY3Rpb25fZGF0YSxcbiAgZW50ZXI6IHNlbGVjdGlvbl9lbnRlcixcbiAgZXhpdDogc2VsZWN0aW9uX2V4aXQsXG4gIG1lcmdlOiBzZWxlY3Rpb25fbWVyZ2UsXG4gIG9yZGVyOiBzZWxlY3Rpb25fb3JkZXIsXG4gIHNvcnQ6IHNlbGVjdGlvbl9zb3J0LFxuICBjYWxsOiBzZWxlY3Rpb25fY2FsbCxcbiAgbm9kZXM6IHNlbGVjdGlvbl9ub2RlcyxcbiAgbm9kZTogc2VsZWN0aW9uX25vZGUsXG4gIHNpemU6IHNlbGVjdGlvbl9zaXplLFxuICBlbXB0eTogc2VsZWN0aW9uX2VtcHR5LFxuICBlYWNoOiBzZWxlY3Rpb25fZWFjaCxcbiAgYXR0cjogc2VsZWN0aW9uX2F0dHIsXG4gIHN0eWxlOiBzZWxlY3Rpb25fc3R5bGUsXG4gIHByb3BlcnR5OiBzZWxlY3Rpb25fcHJvcGVydHksXG4gIGNsYXNzZWQ6IHNlbGVjdGlvbl9jbGFzc2VkLFxuICB0ZXh0OiBzZWxlY3Rpb25fdGV4dCxcbiAgaHRtbDogc2VsZWN0aW9uX2h0bWwsXG4gIHJhaXNlOiBzZWxlY3Rpb25fcmFpc2UsXG4gIGxvd2VyOiBzZWxlY3Rpb25fbG93ZXIsXG4gIGFwcGVuZDogc2VsZWN0aW9uX2FwcGVuZCxcbiAgaW5zZXJ0OiBzZWxlY3Rpb25faW5zZXJ0LFxuICByZW1vdmU6IHNlbGVjdGlvbl9yZW1vdmUsXG4gIGRhdHVtOiBzZWxlY3Rpb25fZGF0dW0sXG4gIG9uOiBzZWxlY3Rpb25fb24sXG4gIGRpc3BhdGNoOiBzZWxlY3Rpb25fZGlzcGF0Y2hcbn07XG5cbnZhciBzZWxlY3QgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xuICByZXR1cm4gdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiXG4gICAgICA/IG5ldyBTZWxlY3Rpb24oW1tkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKV1dLCBbZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50XSlcbiAgICAgIDogbmV3IFNlbGVjdGlvbihbW3NlbGVjdG9yXV0sIHJvb3QpO1xufTtcblxudmFyIHNlbGVjdEFsbCA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gIHJldHVybiB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCJcbiAgICAgID8gbmV3IFNlbGVjdGlvbihbZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcildLCBbZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50XSlcbiAgICAgIDogbmV3IFNlbGVjdGlvbihbc2VsZWN0b3IgPT0gbnVsbCA/IFtdIDogc2VsZWN0b3JdLCByb290KTtcbn07XG5cbnZhciB0b3VjaCA9IGZ1bmN0aW9uKG5vZGUsIHRvdWNoZXMsIGlkZW50aWZpZXIpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSBpZGVudGlmaWVyID0gdG91Y2hlcywgdG91Y2hlcyA9IHNvdXJjZUV2ZW50KCkuY2hhbmdlZFRvdWNoZXM7XG5cbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0b3VjaGVzID8gdG91Y2hlcy5sZW5ndGggOiAwLCB0b3VjaDsgaSA8IG47ICsraSkge1xuICAgIGlmICgodG91Y2ggPSB0b3VjaGVzW2ldKS5pZGVudGlmaWVyID09PSBpZGVudGlmaWVyKSB7XG4gICAgICByZXR1cm4gcG9pbnQobm9kZSwgdG91Y2gpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxudmFyIHRvdWNoZXMgPSBmdW5jdGlvbihub2RlLCB0b3VjaGVzKSB7XG4gIGlmICh0b3VjaGVzID09IG51bGwpIHRvdWNoZXMgPSBzb3VyY2VFdmVudCgpLnRvdWNoZXM7XG5cbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0b3VjaGVzID8gdG91Y2hlcy5sZW5ndGggOiAwLCBwb2ludHMgPSBuZXcgQXJyYXkobik7IGkgPCBuOyArK2kpIHtcbiAgICBwb2ludHNbaV0gPSBwb2ludChub2RlLCB0b3VjaGVzW2ldKTtcbiAgfVxuXG4gIHJldHVybiBwb2ludHM7XG59O1xuXG5mdW5jdGlvbiBub3Byb3BhZ2F0aW9uKCkge1xuICBleHBvcnRzLmV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xufVxuXG52YXIgbm9ldmVudCA9IGZ1bmN0aW9uKCkge1xuICBleHBvcnRzLmV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIGV4cG9ydHMuZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG59O1xuXG52YXIgZHJhZ0Rpc2FibGUgPSBmdW5jdGlvbih2aWV3KSB7XG4gIHZhciByb290ID0gdmlldy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsXG4gICAgICBzZWxlY3Rpb24kJDEgPSBzZWxlY3Qodmlldykub24oXCJkcmFnc3RhcnQuZHJhZ1wiLCBub2V2ZW50LCB0cnVlKTtcbiAgaWYgKFwib25zZWxlY3RzdGFydFwiIGluIHJvb3QpIHtcbiAgICBzZWxlY3Rpb24kJDEub24oXCJzZWxlY3RzdGFydC5kcmFnXCIsIG5vZXZlbnQsIHRydWUpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuX19ub3NlbGVjdCA9IHJvb3Quc3R5bGUuTW96VXNlclNlbGVjdDtcbiAgICByb290LnN0eWxlLk1velVzZXJTZWxlY3QgPSBcIm5vbmVcIjtcbiAgfVxufTtcblxuZnVuY3Rpb24geWVzZHJhZyh2aWV3LCBub2NsaWNrKSB7XG4gIHZhciByb290ID0gdmlldy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsXG4gICAgICBzZWxlY3Rpb24kJDEgPSBzZWxlY3Qodmlldykub24oXCJkcmFnc3RhcnQuZHJhZ1wiLCBudWxsKTtcbiAgaWYgKG5vY2xpY2spIHtcbiAgICBzZWxlY3Rpb24kJDEub24oXCJjbGljay5kcmFnXCIsIG5vZXZlbnQsIHRydWUpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHNlbGVjdGlvbiQkMS5vbihcImNsaWNrLmRyYWdcIiwgbnVsbCk7IH0sIDApO1xuICB9XG4gIGlmIChcIm9uc2VsZWN0c3RhcnRcIiBpbiByb290KSB7XG4gICAgc2VsZWN0aW9uJCQxLm9uKFwic2VsZWN0c3RhcnQuZHJhZ1wiLCBudWxsKTtcbiAgfSBlbHNlIHtcbiAgICByb290LnN0eWxlLk1velVzZXJTZWxlY3QgPSByb290Ll9fbm9zZWxlY3Q7XG4gICAgZGVsZXRlIHJvb3QuX19ub3NlbGVjdDtcbiAgfVxufVxuXG52YXIgY29uc3RhbnQkMiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxuZnVuY3Rpb24gRHJhZ0V2ZW50KHRhcmdldCwgdHlwZSwgc3ViamVjdCwgaWQsIGFjdGl2ZSwgeCwgeSwgZHgsIGR5LCBkaXNwYXRjaCkge1xuICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5zdWJqZWN0ID0gc3ViamVjdDtcbiAgdGhpcy5pZGVudGlmaWVyID0gaWQ7XG4gIHRoaXMuYWN0aXZlID0gYWN0aXZlO1xuICB0aGlzLnggPSB4O1xuICB0aGlzLnkgPSB5O1xuICB0aGlzLmR4ID0gZHg7XG4gIHRoaXMuZHkgPSBkeTtcbiAgdGhpcy5fID0gZGlzcGF0Y2g7XG59XG5cbkRyYWdFdmVudC5wcm90b3R5cGUub24gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHZhbHVlID0gdGhpcy5fLm9uLmFwcGx5KHRoaXMuXywgYXJndW1lbnRzKTtcbiAgcmV0dXJuIHZhbHVlID09PSB0aGlzLl8gPyB0aGlzIDogdmFsdWU7XG59O1xuXG4vLyBJZ25vcmUgcmlnaHQtY2xpY2ssIHNpbmNlIHRoYXQgc2hvdWxkIG9wZW4gdGhlIGNvbnRleHQgbWVudS5cbmZ1bmN0aW9uIGRlZmF1bHRGaWx0ZXIkMSgpIHtcbiAgcmV0dXJuICFleHBvcnRzLmV2ZW50LmJ1dHRvbjtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdENvbnRhaW5lcigpIHtcbiAgcmV0dXJuIHRoaXMucGFyZW50Tm9kZTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFN1YmplY3QoZCkge1xuICByZXR1cm4gZCA9PSBudWxsID8ge3g6IGV4cG9ydHMuZXZlbnQueCwgeTogZXhwb3J0cy5ldmVudC55fSA6IGQ7XG59XG5cbnZhciBkcmFnID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmaWx0ZXIgPSBkZWZhdWx0RmlsdGVyJDEsXG4gICAgICBjb250YWluZXIgPSBkZWZhdWx0Q29udGFpbmVyLFxuICAgICAgc3ViamVjdCA9IGRlZmF1bHRTdWJqZWN0LFxuICAgICAgZ2VzdHVyZXMgPSB7fSxcbiAgICAgIGxpc3RlbmVycyA9IGRpc3BhdGNoKFwic3RhcnRcIiwgXCJkcmFnXCIsIFwiZW5kXCIpLFxuICAgICAgYWN0aXZlID0gMCxcbiAgICAgIG1vdXNlbW92aW5nLFxuICAgICAgdG91Y2hlbmRpbmc7XG5cbiAgZnVuY3Rpb24gZHJhZyhzZWxlY3Rpb24kJDEpIHtcbiAgICBzZWxlY3Rpb24kJDFcbiAgICAgICAgLm9uKFwibW91c2Vkb3duLmRyYWdcIiwgbW91c2Vkb3duZWQpXG4gICAgICAgIC5vbihcInRvdWNoc3RhcnQuZHJhZ1wiLCB0b3VjaHN0YXJ0ZWQpXG4gICAgICAgIC5vbihcInRvdWNobW92ZS5kcmFnXCIsIHRvdWNobW92ZWQpXG4gICAgICAgIC5vbihcInRvdWNoZW5kLmRyYWcgdG91Y2hjYW5jZWwuZHJhZ1wiLCB0b3VjaGVuZGVkKVxuICAgICAgICAuc3R5bGUoXCItd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3JcIiwgXCJyZ2JhKDAsMCwwLDApXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gbW91c2Vkb3duZWQoKSB7XG4gICAgaWYgKHRvdWNoZW5kaW5nIHx8ICFmaWx0ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuO1xuICAgIHZhciBnZXN0dXJlID0gYmVmb3Jlc3RhcnQoXCJtb3VzZVwiLCBjb250YWluZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSwgbW91c2UsIHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKCFnZXN0dXJlKSByZXR1cm47XG4gICAgc2VsZWN0KGV4cG9ydHMuZXZlbnQudmlldykub24oXCJtb3VzZW1vdmUuZHJhZ1wiLCBtb3VzZW1vdmVkLCB0cnVlKS5vbihcIm1vdXNldXAuZHJhZ1wiLCBtb3VzZXVwcGVkLCB0cnVlKTtcbiAgICBkcmFnRGlzYWJsZShleHBvcnRzLmV2ZW50LnZpZXcpO1xuICAgIG5vcHJvcGFnYXRpb24oKTtcbiAgICBtb3VzZW1vdmluZyA9IGZhbHNlO1xuICAgIGdlc3R1cmUoXCJzdGFydFwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdXNlbW92ZWQoKSB7XG4gICAgbm9ldmVudCgpO1xuICAgIG1vdXNlbW92aW5nID0gdHJ1ZTtcbiAgICBnZXN0dXJlcy5tb3VzZShcImRyYWdcIik7XG4gIH1cblxuICBmdW5jdGlvbiBtb3VzZXVwcGVkKCkge1xuICAgIHNlbGVjdChleHBvcnRzLmV2ZW50LnZpZXcpLm9uKFwibW91c2Vtb3ZlLmRyYWcgbW91c2V1cC5kcmFnXCIsIG51bGwpO1xuICAgIHllc2RyYWcoZXhwb3J0cy5ldmVudC52aWV3LCBtb3VzZW1vdmluZyk7XG4gICAgbm9ldmVudCgpO1xuICAgIGdlc3R1cmVzLm1vdXNlKFwiZW5kXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gdG91Y2hzdGFydGVkKCkge1xuICAgIGlmICghZmlsdGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIHJldHVybjtcbiAgICB2YXIgdG91Y2hlcyQkMSA9IGV4cG9ydHMuZXZlbnQuY2hhbmdlZFRvdWNoZXMsXG4gICAgICAgIGMgPSBjb250YWluZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgbiA9IHRvdWNoZXMkJDEubGVuZ3RoLCBpLCBnZXN0dXJlO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKGdlc3R1cmUgPSBiZWZvcmVzdGFydCh0b3VjaGVzJCQxW2ldLmlkZW50aWZpZXIsIGMsIHRvdWNoLCB0aGlzLCBhcmd1bWVudHMpKSB7XG4gICAgICAgIG5vcHJvcGFnYXRpb24oKTtcbiAgICAgICAgZ2VzdHVyZShcInN0YXJ0XCIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRvdWNobW92ZWQoKSB7XG4gICAgdmFyIHRvdWNoZXMkJDEgPSBleHBvcnRzLmV2ZW50LmNoYW5nZWRUb3VjaGVzLFxuICAgICAgICBuID0gdG91Y2hlcyQkMS5sZW5ndGgsIGksIGdlc3R1cmU7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoZ2VzdHVyZSA9IGdlc3R1cmVzW3RvdWNoZXMkJDFbaV0uaWRlbnRpZmllcl0pIHtcbiAgICAgICAgbm9ldmVudCgpO1xuICAgICAgICBnZXN0dXJlKFwiZHJhZ1wiKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0b3VjaGVuZGVkKCkge1xuICAgIHZhciB0b3VjaGVzJCQxID0gZXhwb3J0cy5ldmVudC5jaGFuZ2VkVG91Y2hlcyxcbiAgICAgICAgbiA9IHRvdWNoZXMkJDEubGVuZ3RoLCBpLCBnZXN0dXJlO1xuXG4gICAgaWYgKHRvdWNoZW5kaW5nKSBjbGVhclRpbWVvdXQodG91Y2hlbmRpbmcpO1xuICAgIHRvdWNoZW5kaW5nID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsgdG91Y2hlbmRpbmcgPSBudWxsOyB9LCA1MDApOyAvLyBHaG9zdCBjbGlja3MgYXJlIGRlbGF5ZWQhXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKGdlc3R1cmUgPSBnZXN0dXJlc1t0b3VjaGVzJCQxW2ldLmlkZW50aWZpZXJdKSB7XG4gICAgICAgIG5vcHJvcGFnYXRpb24oKTtcbiAgICAgICAgZ2VzdHVyZShcImVuZFwiKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBiZWZvcmVzdGFydChpZCwgY29udGFpbmVyLCBwb2ludCwgdGhhdCwgYXJncykge1xuICAgIHZhciBwID0gcG9pbnQoY29udGFpbmVyLCBpZCksIHMsIGR4LCBkeSxcbiAgICAgICAgc3VibGlzdGVuZXJzID0gbGlzdGVuZXJzLmNvcHkoKTtcblxuICAgIGlmICghY3VzdG9tRXZlbnQobmV3IERyYWdFdmVudChkcmFnLCBcImJlZm9yZXN0YXJ0XCIsIHMsIGlkLCBhY3RpdmUsIHBbMF0sIHBbMV0sIDAsIDAsIHN1Ymxpc3RlbmVycyksIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKChleHBvcnRzLmV2ZW50LnN1YmplY3QgPSBzID0gc3ViamVjdC5hcHBseSh0aGF0LCBhcmdzKSkgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgICAgZHggPSBzLnggLSBwWzBdIHx8IDA7XG4gICAgICBkeSA9IHMueSAtIHBbMV0gfHwgMDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pKSByZXR1cm47XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gZ2VzdHVyZSh0eXBlKSB7XG4gICAgICB2YXIgcDAgPSBwLCBuO1xuICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgXCJzdGFydFwiOiBnZXN0dXJlc1tpZF0gPSBnZXN0dXJlLCBuID0gYWN0aXZlKys7IGJyZWFrO1xuICAgICAgICBjYXNlIFwiZW5kXCI6IGRlbGV0ZSBnZXN0dXJlc1tpZF0sIC0tYWN0aXZlOyAvLyBub2JyZWFrXG4gICAgICAgIGNhc2UgXCJkcmFnXCI6IHAgPSBwb2ludChjb250YWluZXIsIGlkKSwgbiA9IGFjdGl2ZTsgYnJlYWs7XG4gICAgICB9XG4gICAgICBjdXN0b21FdmVudChuZXcgRHJhZ0V2ZW50KGRyYWcsIHR5cGUsIHMsIGlkLCBuLCBwWzBdICsgZHgsIHBbMV0gKyBkeSwgcFswXSAtIHAwWzBdLCBwWzFdIC0gcDBbMV0sIHN1Ymxpc3RlbmVycyksIHN1Ymxpc3RlbmVycy5hcHBseSwgc3VibGlzdGVuZXJzLCBbdHlwZSwgdGhhdCwgYXJnc10pO1xuICAgIH07XG4gIH1cblxuICBkcmFnLmZpbHRlciA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChmaWx0ZXIgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoISFfKSwgZHJhZykgOiBmaWx0ZXI7XG4gIH07XG5cbiAgZHJhZy5jb250YWluZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoY29udGFpbmVyID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKF8pLCBkcmFnKSA6IGNvbnRhaW5lcjtcbiAgfTtcblxuICBkcmFnLnN1YmplY3QgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc3ViamVjdCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMihfKSwgZHJhZykgOiBzdWJqZWN0O1xuICB9O1xuXG4gIGRyYWcub24gPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWUgPSBsaXN0ZW5lcnMub24uYXBwbHkobGlzdGVuZXJzLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiB2YWx1ZSA9PT0gbGlzdGVuZXJzID8gZHJhZyA6IHZhbHVlO1xuICB9O1xuXG4gIHJldHVybiBkcmFnO1xufTtcblxudmFyIGRlZmluZSA9IGZ1bmN0aW9uKGNvbnN0cnVjdG9yLCBmYWN0b3J5LCBwcm90b3R5cGUpIHtcbiAgY29uc3RydWN0b3IucHJvdG90eXBlID0gZmFjdG9yeS5wcm90b3R5cGUgPSBwcm90b3R5cGU7XG4gIHByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGNvbnN0cnVjdG9yO1xufTtcblxuZnVuY3Rpb24gZXh0ZW5kKHBhcmVudCwgZGVmaW5pdGlvbikge1xuICB2YXIgcHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShwYXJlbnQucHJvdG90eXBlKTtcbiAgZm9yICh2YXIga2V5IGluIGRlZmluaXRpb24pIHByb3RvdHlwZVtrZXldID0gZGVmaW5pdGlvbltrZXldO1xuICByZXR1cm4gcHJvdG90eXBlO1xufVxuXG5mdW5jdGlvbiBDb2xvcigpIHt9XG5cbnZhciBkYXJrZXIgPSAwLjc7XG52YXIgYnJpZ2h0ZXIgPSAxIC8gZGFya2VyO1xuXG52YXIgcmVJID0gXCJcXFxccyooWystXT9cXFxcZCspXFxcXHMqXCI7XG52YXIgcmVOID0gXCJcXFxccyooWystXT9cXFxcZCpcXFxcLj9cXFxcZCsoPzpbZUVdWystXT9cXFxcZCspPylcXFxccypcIjtcbnZhciByZVAgPSBcIlxcXFxzKihbKy1dP1xcXFxkKlxcXFwuP1xcXFxkKyg/OltlRV1bKy1dP1xcXFxkKyk/KSVcXFxccypcIjtcbnZhciByZUhleDMgPSAvXiMoWzAtOWEtZl17M30pJC87XG52YXIgcmVIZXg2ID0gL14jKFswLTlhLWZdezZ9KSQvO1xudmFyIHJlUmdiSW50ZWdlciA9IG5ldyBSZWdFeHAoXCJecmdiXFxcXChcIiArIFtyZUksIHJlSSwgcmVJXSArIFwiXFxcXCkkXCIpO1xudmFyIHJlUmdiUGVyY2VudCA9IG5ldyBSZWdFeHAoXCJecmdiXFxcXChcIiArIFtyZVAsIHJlUCwgcmVQXSArIFwiXFxcXCkkXCIpO1xudmFyIHJlUmdiYUludGVnZXIgPSBuZXcgUmVnRXhwKFwiXnJnYmFcXFxcKFwiICsgW3JlSSwgcmVJLCByZUksIHJlTl0gKyBcIlxcXFwpJFwiKTtcbnZhciByZVJnYmFQZXJjZW50ID0gbmV3IFJlZ0V4cChcIl5yZ2JhXFxcXChcIiArIFtyZVAsIHJlUCwgcmVQLCByZU5dICsgXCJcXFxcKSRcIik7XG52YXIgcmVIc2xQZXJjZW50ID0gbmV3IFJlZ0V4cChcIl5oc2xcXFxcKFwiICsgW3JlTiwgcmVQLCByZVBdICsgXCJcXFxcKSRcIik7XG52YXIgcmVIc2xhUGVyY2VudCA9IG5ldyBSZWdFeHAoXCJeaHNsYVxcXFwoXCIgKyBbcmVOLCByZVAsIHJlUCwgcmVOXSArIFwiXFxcXCkkXCIpO1xuXG52YXIgbmFtZWQgPSB7XG4gIGFsaWNlYmx1ZTogMHhmMGY4ZmYsXG4gIGFudGlxdWV3aGl0ZTogMHhmYWViZDcsXG4gIGFxdWE6IDB4MDBmZmZmLFxuICBhcXVhbWFyaW5lOiAweDdmZmZkNCxcbiAgYXp1cmU6IDB4ZjBmZmZmLFxuICBiZWlnZTogMHhmNWY1ZGMsXG4gIGJpc3F1ZTogMHhmZmU0YzQsXG4gIGJsYWNrOiAweDAwMDAwMCxcbiAgYmxhbmNoZWRhbG1vbmQ6IDB4ZmZlYmNkLFxuICBibHVlOiAweDAwMDBmZixcbiAgYmx1ZXZpb2xldDogMHg4YTJiZTIsXG4gIGJyb3duOiAweGE1MmEyYSxcbiAgYnVybHl3b29kOiAweGRlYjg4NyxcbiAgY2FkZXRibHVlOiAweDVmOWVhMCxcbiAgY2hhcnRyZXVzZTogMHg3ZmZmMDAsXG4gIGNob2NvbGF0ZTogMHhkMjY5MWUsXG4gIGNvcmFsOiAweGZmN2Y1MCxcbiAgY29ybmZsb3dlcmJsdWU6IDB4NjQ5NWVkLFxuICBjb3Juc2lsazogMHhmZmY4ZGMsXG4gIGNyaW1zb246IDB4ZGMxNDNjLFxuICBjeWFuOiAweDAwZmZmZixcbiAgZGFya2JsdWU6IDB4MDAwMDhiLFxuICBkYXJrY3lhbjogMHgwMDhiOGIsXG4gIGRhcmtnb2xkZW5yb2Q6IDB4Yjg4NjBiLFxuICBkYXJrZ3JheTogMHhhOWE5YTksXG4gIGRhcmtncmVlbjogMHgwMDY0MDAsXG4gIGRhcmtncmV5OiAweGE5YTlhOSxcbiAgZGFya2toYWtpOiAweGJkYjc2YixcbiAgZGFya21hZ2VudGE6IDB4OGIwMDhiLFxuICBkYXJrb2xpdmVncmVlbjogMHg1NTZiMmYsXG4gIGRhcmtvcmFuZ2U6IDB4ZmY4YzAwLFxuICBkYXJrb3JjaGlkOiAweDk5MzJjYyxcbiAgZGFya3JlZDogMHg4YjAwMDAsXG4gIGRhcmtzYWxtb246IDB4ZTk5NjdhLFxuICBkYXJrc2VhZ3JlZW46IDB4OGZiYzhmLFxuICBkYXJrc2xhdGVibHVlOiAweDQ4M2Q4YixcbiAgZGFya3NsYXRlZ3JheTogMHgyZjRmNGYsXG4gIGRhcmtzbGF0ZWdyZXk6IDB4MmY0ZjRmLFxuICBkYXJrdHVycXVvaXNlOiAweDAwY2VkMSxcbiAgZGFya3Zpb2xldDogMHg5NDAwZDMsXG4gIGRlZXBwaW5rOiAweGZmMTQ5MyxcbiAgZGVlcHNreWJsdWU6IDB4MDBiZmZmLFxuICBkaW1ncmF5OiAweDY5Njk2OSxcbiAgZGltZ3JleTogMHg2OTY5NjksXG4gIGRvZGdlcmJsdWU6IDB4MWU5MGZmLFxuICBmaXJlYnJpY2s6IDB4YjIyMjIyLFxuICBmbG9yYWx3aGl0ZTogMHhmZmZhZjAsXG4gIGZvcmVzdGdyZWVuOiAweDIyOGIyMixcbiAgZnVjaHNpYTogMHhmZjAwZmYsXG4gIGdhaW5zYm9ybzogMHhkY2RjZGMsXG4gIGdob3N0d2hpdGU6IDB4ZjhmOGZmLFxuICBnb2xkOiAweGZmZDcwMCxcbiAgZ29sZGVucm9kOiAweGRhYTUyMCxcbiAgZ3JheTogMHg4MDgwODAsXG4gIGdyZWVuOiAweDAwODAwMCxcbiAgZ3JlZW55ZWxsb3c6IDB4YWRmZjJmLFxuICBncmV5OiAweDgwODA4MCxcbiAgaG9uZXlkZXc6IDB4ZjBmZmYwLFxuICBob3RwaW5rOiAweGZmNjliNCxcbiAgaW5kaWFucmVkOiAweGNkNWM1YyxcbiAgaW5kaWdvOiAweDRiMDA4MixcbiAgaXZvcnk6IDB4ZmZmZmYwLFxuICBraGFraTogMHhmMGU2OGMsXG4gIGxhdmVuZGVyOiAweGU2ZTZmYSxcbiAgbGF2ZW5kZXJibHVzaDogMHhmZmYwZjUsXG4gIGxhd25ncmVlbjogMHg3Y2ZjMDAsXG4gIGxlbW9uY2hpZmZvbjogMHhmZmZhY2QsXG4gIGxpZ2h0Ymx1ZTogMHhhZGQ4ZTYsXG4gIGxpZ2h0Y29yYWw6IDB4ZjA4MDgwLFxuICBsaWdodGN5YW46IDB4ZTBmZmZmLFxuICBsaWdodGdvbGRlbnJvZHllbGxvdzogMHhmYWZhZDIsXG4gIGxpZ2h0Z3JheTogMHhkM2QzZDMsXG4gIGxpZ2h0Z3JlZW46IDB4OTBlZTkwLFxuICBsaWdodGdyZXk6IDB4ZDNkM2QzLFxuICBsaWdodHBpbms6IDB4ZmZiNmMxLFxuICBsaWdodHNhbG1vbjogMHhmZmEwN2EsXG4gIGxpZ2h0c2VhZ3JlZW46IDB4MjBiMmFhLFxuICBsaWdodHNreWJsdWU6IDB4ODdjZWZhLFxuICBsaWdodHNsYXRlZ3JheTogMHg3Nzg4OTksXG4gIGxpZ2h0c2xhdGVncmV5OiAweDc3ODg5OSxcbiAgbGlnaHRzdGVlbGJsdWU6IDB4YjBjNGRlLFxuICBsaWdodHllbGxvdzogMHhmZmZmZTAsXG4gIGxpbWU6IDB4MDBmZjAwLFxuICBsaW1lZ3JlZW46IDB4MzJjZDMyLFxuICBsaW5lbjogMHhmYWYwZTYsXG4gIG1hZ2VudGE6IDB4ZmYwMGZmLFxuICBtYXJvb246IDB4ODAwMDAwLFxuICBtZWRpdW1hcXVhbWFyaW5lOiAweDY2Y2RhYSxcbiAgbWVkaXVtYmx1ZTogMHgwMDAwY2QsXG4gIG1lZGl1bW9yY2hpZDogMHhiYTU1ZDMsXG4gIG1lZGl1bXB1cnBsZTogMHg5MzcwZGIsXG4gIG1lZGl1bXNlYWdyZWVuOiAweDNjYjM3MSxcbiAgbWVkaXVtc2xhdGVibHVlOiAweDdiNjhlZSxcbiAgbWVkaXVtc3ByaW5nZ3JlZW46IDB4MDBmYTlhLFxuICBtZWRpdW10dXJxdW9pc2U6IDB4NDhkMWNjLFxuICBtZWRpdW12aW9sZXRyZWQ6IDB4YzcxNTg1LFxuICBtaWRuaWdodGJsdWU6IDB4MTkxOTcwLFxuICBtaW50Y3JlYW06IDB4ZjVmZmZhLFxuICBtaXN0eXJvc2U6IDB4ZmZlNGUxLFxuICBtb2NjYXNpbjogMHhmZmU0YjUsXG4gIG5hdmFqb3doaXRlOiAweGZmZGVhZCxcbiAgbmF2eTogMHgwMDAwODAsXG4gIG9sZGxhY2U6IDB4ZmRmNWU2LFxuICBvbGl2ZTogMHg4MDgwMDAsXG4gIG9saXZlZHJhYjogMHg2YjhlMjMsXG4gIG9yYW5nZTogMHhmZmE1MDAsXG4gIG9yYW5nZXJlZDogMHhmZjQ1MDAsXG4gIG9yY2hpZDogMHhkYTcwZDYsXG4gIHBhbGVnb2xkZW5yb2Q6IDB4ZWVlOGFhLFxuICBwYWxlZ3JlZW46IDB4OThmYjk4LFxuICBwYWxldHVycXVvaXNlOiAweGFmZWVlZSxcbiAgcGFsZXZpb2xldHJlZDogMHhkYjcwOTMsXG4gIHBhcGF5YXdoaXA6IDB4ZmZlZmQ1LFxuICBwZWFjaHB1ZmY6IDB4ZmZkYWI5LFxuICBwZXJ1OiAweGNkODUzZixcbiAgcGluazogMHhmZmMwY2IsXG4gIHBsdW06IDB4ZGRhMGRkLFxuICBwb3dkZXJibHVlOiAweGIwZTBlNixcbiAgcHVycGxlOiAweDgwMDA4MCxcbiAgcmViZWNjYXB1cnBsZTogMHg2NjMzOTksXG4gIHJlZDogMHhmZjAwMDAsXG4gIHJvc3licm93bjogMHhiYzhmOGYsXG4gIHJveWFsYmx1ZTogMHg0MTY5ZTEsXG4gIHNhZGRsZWJyb3duOiAweDhiNDUxMyxcbiAgc2FsbW9uOiAweGZhODA3MixcbiAgc2FuZHlicm93bjogMHhmNGE0NjAsXG4gIHNlYWdyZWVuOiAweDJlOGI1NyxcbiAgc2Vhc2hlbGw6IDB4ZmZmNWVlLFxuICBzaWVubmE6IDB4YTA1MjJkLFxuICBzaWx2ZXI6IDB4YzBjMGMwLFxuICBza3libHVlOiAweDg3Y2VlYixcbiAgc2xhdGVibHVlOiAweDZhNWFjZCxcbiAgc2xhdGVncmF5OiAweDcwODA5MCxcbiAgc2xhdGVncmV5OiAweDcwODA5MCxcbiAgc25vdzogMHhmZmZhZmEsXG4gIHNwcmluZ2dyZWVuOiAweDAwZmY3ZixcbiAgc3RlZWxibHVlOiAweDQ2ODJiNCxcbiAgdGFuOiAweGQyYjQ4YyxcbiAgdGVhbDogMHgwMDgwODAsXG4gIHRoaXN0bGU6IDB4ZDhiZmQ4LFxuICB0b21hdG86IDB4ZmY2MzQ3LFxuICB0dXJxdW9pc2U6IDB4NDBlMGQwLFxuICB2aW9sZXQ6IDB4ZWU4MmVlLFxuICB3aGVhdDogMHhmNWRlYjMsXG4gIHdoaXRlOiAweGZmZmZmZixcbiAgd2hpdGVzbW9rZTogMHhmNWY1ZjUsXG4gIHllbGxvdzogMHhmZmZmMDAsXG4gIHllbGxvd2dyZWVuOiAweDlhY2QzMlxufTtcblxuZGVmaW5lKENvbG9yLCBjb2xvciwge1xuICBkaXNwbGF5YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucmdiKCkuZGlzcGxheWFibGUoKTtcbiAgfSxcbiAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnJnYigpICsgXCJcIjtcbiAgfVxufSk7XG5cbmZ1bmN0aW9uIGNvbG9yKGZvcm1hdCkge1xuICB2YXIgbTtcbiAgZm9ybWF0ID0gKGZvcm1hdCArIFwiXCIpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKG0gPSByZUhleDMuZXhlYyhmb3JtYXQpKSA/IChtID0gcGFyc2VJbnQobVsxXSwgMTYpLCBuZXcgUmdiKChtID4+IDggJiAweGYpIHwgKG0gPj4gNCAmIDB4MGYwKSwgKG0gPj4gNCAmIDB4ZikgfCAobSAmIDB4ZjApLCAoKG0gJiAweGYpIDw8IDQpIHwgKG0gJiAweGYpLCAxKSkgLy8gI2YwMFxuICAgICAgOiAobSA9IHJlSGV4Ni5leGVjKGZvcm1hdCkpID8gcmdibihwYXJzZUludChtWzFdLCAxNikpIC8vICNmZjAwMDBcbiAgICAgIDogKG0gPSByZVJnYkludGVnZXIuZXhlYyhmb3JtYXQpKSA/IG5ldyBSZ2IobVsxXSwgbVsyXSwgbVszXSwgMSkgLy8gcmdiKDI1NSwgMCwgMClcbiAgICAgIDogKG0gPSByZVJnYlBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IG5ldyBSZ2IobVsxXSAqIDI1NSAvIDEwMCwgbVsyXSAqIDI1NSAvIDEwMCwgbVszXSAqIDI1NSAvIDEwMCwgMSkgLy8gcmdiKDEwMCUsIDAlLCAwJSlcbiAgICAgIDogKG0gPSByZVJnYmFJbnRlZ2VyLmV4ZWMoZm9ybWF0KSkgPyByZ2JhKG1bMV0sIG1bMl0sIG1bM10sIG1bNF0pIC8vIHJnYmEoMjU1LCAwLCAwLCAxKVxuICAgICAgOiAobSA9IHJlUmdiYVBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IHJnYmEobVsxXSAqIDI1NSAvIDEwMCwgbVsyXSAqIDI1NSAvIDEwMCwgbVszXSAqIDI1NSAvIDEwMCwgbVs0XSkgLy8gcmdiKDEwMCUsIDAlLCAwJSwgMSlcbiAgICAgIDogKG0gPSByZUhzbFBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IGhzbGEobVsxXSwgbVsyXSAvIDEwMCwgbVszXSAvIDEwMCwgMSkgLy8gaHNsKDEyMCwgNTAlLCA1MCUpXG4gICAgICA6IChtID0gcmVIc2xhUGVyY2VudC5leGVjKGZvcm1hdCkpID8gaHNsYShtWzFdLCBtWzJdIC8gMTAwLCBtWzNdIC8gMTAwLCBtWzRdKSAvLyBoc2xhKDEyMCwgNTAlLCA1MCUsIDEpXG4gICAgICA6IG5hbWVkLmhhc093blByb3BlcnR5KGZvcm1hdCkgPyByZ2JuKG5hbWVkW2Zvcm1hdF0pXG4gICAgICA6IGZvcm1hdCA9PT0gXCJ0cmFuc3BhcmVudFwiID8gbmV3IFJnYihOYU4sIE5hTiwgTmFOLCAwKVxuICAgICAgOiBudWxsO1xufVxuXG5mdW5jdGlvbiByZ2JuKG4pIHtcbiAgcmV0dXJuIG5ldyBSZ2IobiA+PiAxNiAmIDB4ZmYsIG4gPj4gOCAmIDB4ZmYsIG4gJiAweGZmLCAxKTtcbn1cblxuZnVuY3Rpb24gcmdiYShyLCBnLCBiLCBhKSB7XG4gIGlmIChhIDw9IDApIHIgPSBnID0gYiA9IE5hTjtcbiAgcmV0dXJuIG5ldyBSZ2IociwgZywgYiwgYSk7XG59XG5cbmZ1bmN0aW9uIHJnYkNvbnZlcnQobykge1xuICBpZiAoIShvIGluc3RhbmNlb2YgQ29sb3IpKSBvID0gY29sb3Iobyk7XG4gIGlmICghbykgcmV0dXJuIG5ldyBSZ2I7XG4gIG8gPSBvLnJnYigpO1xuICByZXR1cm4gbmV3IFJnYihvLnIsIG8uZywgby5iLCBvLm9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiByZ2IociwgZywgYiwgb3BhY2l0eSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IHJnYkNvbnZlcnQocikgOiBuZXcgUmdiKHIsIGcsIGIsIG9wYWNpdHkgPT0gbnVsbCA/IDEgOiBvcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gUmdiKHIsIGcsIGIsIG9wYWNpdHkpIHtcbiAgdGhpcy5yID0gK3I7XG4gIHRoaXMuZyA9ICtnO1xuICB0aGlzLmIgPSArYjtcbiAgdGhpcy5vcGFjaXR5ID0gK29wYWNpdHk7XG59XG5cbmRlZmluZShSZ2IsIHJnYiwgZXh0ZW5kKENvbG9yLCB7XG4gIGJyaWdodGVyOiBmdW5jdGlvbihrKSB7XG4gICAgayA9IGsgPT0gbnVsbCA/IGJyaWdodGVyIDogTWF0aC5wb3coYnJpZ2h0ZXIsIGspO1xuICAgIHJldHVybiBuZXcgUmdiKHRoaXMuciAqIGssIHRoaXMuZyAqIGssIHRoaXMuYiAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBkYXJrZXIgOiBNYXRoLnBvdyhkYXJrZXIsIGspO1xuICAgIHJldHVybiBuZXcgUmdiKHRoaXMuciAqIGssIHRoaXMuZyAqIGssIHRoaXMuYiAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIGRpc3BsYXlhYmxlOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKDAgPD0gdGhpcy5yICYmIHRoaXMuciA8PSAyNTUpXG4gICAgICAgICYmICgwIDw9IHRoaXMuZyAmJiB0aGlzLmcgPD0gMjU1KVxuICAgICAgICAmJiAoMCA8PSB0aGlzLmIgJiYgdGhpcy5iIDw9IDI1NSlcbiAgICAgICAgJiYgKDAgPD0gdGhpcy5vcGFjaXR5ICYmIHRoaXMub3BhY2l0eSA8PSAxKTtcbiAgfSxcbiAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhID0gdGhpcy5vcGFjaXR5OyBhID0gaXNOYU4oYSkgPyAxIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgYSkpO1xuICAgIHJldHVybiAoYSA9PT0gMSA/IFwicmdiKFwiIDogXCJyZ2JhKFwiKVxuICAgICAgICArIE1hdGgubWF4KDAsIE1hdGgubWluKDI1NSwgTWF0aC5yb3VuZCh0aGlzLnIpIHx8IDApKSArIFwiLCBcIlxuICAgICAgICArIE1hdGgubWF4KDAsIE1hdGgubWluKDI1NSwgTWF0aC5yb3VuZCh0aGlzLmcpIHx8IDApKSArIFwiLCBcIlxuICAgICAgICArIE1hdGgubWF4KDAsIE1hdGgubWluKDI1NSwgTWF0aC5yb3VuZCh0aGlzLmIpIHx8IDApKVxuICAgICAgICArIChhID09PSAxID8gXCIpXCIgOiBcIiwgXCIgKyBhICsgXCIpXCIpO1xuICB9XG59KSk7XG5cbmZ1bmN0aW9uIGhzbGEoaCwgcywgbCwgYSkge1xuICBpZiAoYSA8PSAwKSBoID0gcyA9IGwgPSBOYU47XG4gIGVsc2UgaWYgKGwgPD0gMCB8fCBsID49IDEpIGggPSBzID0gTmFOO1xuICBlbHNlIGlmIChzIDw9IDApIGggPSBOYU47XG4gIHJldHVybiBuZXcgSHNsKGgsIHMsIGwsIGEpO1xufVxuXG5mdW5jdGlvbiBoc2xDb252ZXJ0KG8pIHtcbiAgaWYgKG8gaW5zdGFuY2VvZiBIc2wpIHJldHVybiBuZXcgSHNsKG8uaCwgby5zLCBvLmwsIG8ub3BhY2l0eSk7XG4gIGlmICghKG8gaW5zdGFuY2VvZiBDb2xvcikpIG8gPSBjb2xvcihvKTtcbiAgaWYgKCFvKSByZXR1cm4gbmV3IEhzbDtcbiAgaWYgKG8gaW5zdGFuY2VvZiBIc2wpIHJldHVybiBvO1xuICBvID0gby5yZ2IoKTtcbiAgdmFyIHIgPSBvLnIgLyAyNTUsXG4gICAgICBnID0gby5nIC8gMjU1LFxuICAgICAgYiA9IG8uYiAvIDI1NSxcbiAgICAgIG1pbiA9IE1hdGgubWluKHIsIGcsIGIpLFxuICAgICAgbWF4ID0gTWF0aC5tYXgociwgZywgYiksXG4gICAgICBoID0gTmFOLFxuICAgICAgcyA9IG1heCAtIG1pbixcbiAgICAgIGwgPSAobWF4ICsgbWluKSAvIDI7XG4gIGlmIChzKSB7XG4gICAgaWYgKHIgPT09IG1heCkgaCA9IChnIC0gYikgLyBzICsgKGcgPCBiKSAqIDY7XG4gICAgZWxzZSBpZiAoZyA9PT0gbWF4KSBoID0gKGIgLSByKSAvIHMgKyAyO1xuICAgIGVsc2UgaCA9IChyIC0gZykgLyBzICsgNDtcbiAgICBzIC89IGwgPCAwLjUgPyBtYXggKyBtaW4gOiAyIC0gbWF4IC0gbWluO1xuICAgIGggKj0gNjA7XG4gIH0gZWxzZSB7XG4gICAgcyA9IGwgPiAwICYmIGwgPCAxID8gMCA6IGg7XG4gIH1cbiAgcmV0dXJuIG5ldyBIc2woaCwgcywgbCwgby5vcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gaHNsKGgsIHMsIGwsIG9wYWNpdHkpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyBoc2xDb252ZXJ0KGgpIDogbmV3IEhzbChoLCBzLCBsLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIEhzbChoLCBzLCBsLCBvcGFjaXR5KSB7XG4gIHRoaXMuaCA9ICtoO1xuICB0aGlzLnMgPSArcztcbiAgdGhpcy5sID0gK2w7XG4gIHRoaXMub3BhY2l0eSA9ICtvcGFjaXR5O1xufVxuXG5kZWZpbmUoSHNsLCBoc2wsIGV4dGVuZChDb2xvciwge1xuICBicmlnaHRlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBicmlnaHRlciA6IE1hdGgucG93KGJyaWdodGVyLCBrKTtcbiAgICByZXR1cm4gbmV3IEhzbCh0aGlzLmgsIHRoaXMucywgdGhpcy5sICogaywgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgZGFya2VyOiBmdW5jdGlvbihrKSB7XG4gICAgayA9IGsgPT0gbnVsbCA/IGRhcmtlciA6IE1hdGgucG93KGRhcmtlciwgayk7XG4gICAgcmV0dXJuIG5ldyBIc2wodGhpcy5oLCB0aGlzLnMsIHRoaXMubCAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGggPSB0aGlzLmggJSAzNjAgKyAodGhpcy5oIDwgMCkgKiAzNjAsXG4gICAgICAgIHMgPSBpc05hTihoKSB8fCBpc05hTih0aGlzLnMpID8gMCA6IHRoaXMucyxcbiAgICAgICAgbCA9IHRoaXMubCxcbiAgICAgICAgbTIgPSBsICsgKGwgPCAwLjUgPyBsIDogMSAtIGwpICogcyxcbiAgICAgICAgbTEgPSAyICogbCAtIG0yO1xuICAgIHJldHVybiBuZXcgUmdiKFxuICAgICAgaHNsMnJnYihoID49IDI0MCA/IGggLSAyNDAgOiBoICsgMTIwLCBtMSwgbTIpLFxuICAgICAgaHNsMnJnYihoLCBtMSwgbTIpLFxuICAgICAgaHNsMnJnYihoIDwgMTIwID8gaCArIDI0MCA6IGggLSAxMjAsIG0xLCBtMiksXG4gICAgICB0aGlzLm9wYWNpdHlcbiAgICApO1xuICB9LFxuICBkaXNwbGF5YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuICgwIDw9IHRoaXMucyAmJiB0aGlzLnMgPD0gMSB8fCBpc05hTih0aGlzLnMpKVxuICAgICAgICAmJiAoMCA8PSB0aGlzLmwgJiYgdGhpcy5sIDw9IDEpXG4gICAgICAgICYmICgwIDw9IHRoaXMub3BhY2l0eSAmJiB0aGlzLm9wYWNpdHkgPD0gMSk7XG4gIH1cbn0pKTtcblxuLyogRnJvbSBGdkQgMTMuMzcsIENTUyBDb2xvciBNb2R1bGUgTGV2ZWwgMyAqL1xuZnVuY3Rpb24gaHNsMnJnYihoLCBtMSwgbTIpIHtcbiAgcmV0dXJuIChoIDwgNjAgPyBtMSArIChtMiAtIG0xKSAqIGggLyA2MFxuICAgICAgOiBoIDwgMTgwID8gbTJcbiAgICAgIDogaCA8IDI0MCA/IG0xICsgKG0yIC0gbTEpICogKDI0MCAtIGgpIC8gNjBcbiAgICAgIDogbTEpICogMjU1O1xufVxuXG52YXIgZGVnMnJhZCA9IE1hdGguUEkgLyAxODA7XG52YXIgcmFkMmRlZyA9IDE4MCAvIE1hdGguUEk7XG5cbnZhciBLbiA9IDE4O1xudmFyIFhuID0gMC45NTA0NzA7XG52YXIgWW4gPSAxO1xudmFyIFpuID0gMS4wODg4MzA7XG52YXIgdDAgPSA0IC8gMjk7XG52YXIgdDEgPSA2IC8gMjk7XG52YXIgdDIgPSAzICogdDEgKiB0MTtcbnZhciB0MyA9IHQxICogdDEgKiB0MTtcblxuZnVuY3Rpb24gbGFiQ29udmVydChvKSB7XG4gIGlmIChvIGluc3RhbmNlb2YgTGFiKSByZXR1cm4gbmV3IExhYihvLmwsIG8uYSwgby5iLCBvLm9wYWNpdHkpO1xuICBpZiAobyBpbnN0YW5jZW9mIEhjbCkge1xuICAgIHZhciBoID0gby5oICogZGVnMnJhZDtcbiAgICByZXR1cm4gbmV3IExhYihvLmwsIE1hdGguY29zKGgpICogby5jLCBNYXRoLnNpbihoKSAqIG8uYywgby5vcGFjaXR5KTtcbiAgfVxuICBpZiAoIShvIGluc3RhbmNlb2YgUmdiKSkgbyA9IHJnYkNvbnZlcnQobyk7XG4gIHZhciBiID0gcmdiMnh5eihvLnIpLFxuICAgICAgYSA9IHJnYjJ4eXooby5nKSxcbiAgICAgIGwgPSByZ2IyeHl6KG8uYiksXG4gICAgICB4ID0geHl6MmxhYigoMC40MTI0NTY0ICogYiArIDAuMzU3NTc2MSAqIGEgKyAwLjE4MDQzNzUgKiBsKSAvIFhuKSxcbiAgICAgIHkgPSB4eXoybGFiKCgwLjIxMjY3MjkgKiBiICsgMC43MTUxNTIyICogYSArIDAuMDcyMTc1MCAqIGwpIC8gWW4pLFxuICAgICAgeiA9IHh5ejJsYWIoKDAuMDE5MzMzOSAqIGIgKyAwLjExOTE5MjAgKiBhICsgMC45NTAzMDQxICogbCkgLyBabik7XG4gIHJldHVybiBuZXcgTGFiKDExNiAqIHkgLSAxNiwgNTAwICogKHggLSB5KSwgMjAwICogKHkgLSB6KSwgby5vcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gbGFiKGwsIGEsIGIsIG9wYWNpdHkpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyBsYWJDb252ZXJ0KGwpIDogbmV3IExhYihsLCBhLCBiLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIExhYihsLCBhLCBiLCBvcGFjaXR5KSB7XG4gIHRoaXMubCA9ICtsO1xuICB0aGlzLmEgPSArYTtcbiAgdGhpcy5iID0gK2I7XG4gIHRoaXMub3BhY2l0eSA9ICtvcGFjaXR5O1xufVxuXG5kZWZpbmUoTGFiLCBsYWIsIGV4dGVuZChDb2xvciwge1xuICBicmlnaHRlcjogZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBuZXcgTGFiKHRoaXMubCArIEtuICogKGsgPT0gbnVsbCA/IDEgOiBrKSwgdGhpcy5hLCB0aGlzLmIsIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBuZXcgTGFiKHRoaXMubCAtIEtuICogKGsgPT0gbnVsbCA/IDEgOiBrKSwgdGhpcy5hLCB0aGlzLmIsIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHkgPSAodGhpcy5sICsgMTYpIC8gMTE2LFxuICAgICAgICB4ID0gaXNOYU4odGhpcy5hKSA/IHkgOiB5ICsgdGhpcy5hIC8gNTAwLFxuICAgICAgICB6ID0gaXNOYU4odGhpcy5iKSA/IHkgOiB5IC0gdGhpcy5iIC8gMjAwO1xuICAgIHkgPSBZbiAqIGxhYjJ4eXooeSk7XG4gICAgeCA9IFhuICogbGFiMnh5eih4KTtcbiAgICB6ID0gWm4gKiBsYWIyeHl6KHopO1xuICAgIHJldHVybiBuZXcgUmdiKFxuICAgICAgeHl6MnJnYiggMy4yNDA0NTQyICogeCAtIDEuNTM3MTM4NSAqIHkgLSAwLjQ5ODUzMTQgKiB6KSwgLy8gRDY1IC0+IHNSR0JcbiAgICAgIHh5ejJyZ2IoLTAuOTY5MjY2MCAqIHggKyAxLjg3NjAxMDggKiB5ICsgMC4wNDE1NTYwICogeiksXG4gICAgICB4eXoycmdiKCAwLjA1NTY0MzQgKiB4IC0gMC4yMDQwMjU5ICogeSArIDEuMDU3MjI1MiAqIHopLFxuICAgICAgdGhpcy5vcGFjaXR5XG4gICAgKTtcbiAgfVxufSkpO1xuXG5mdW5jdGlvbiB4eXoybGFiKHQpIHtcbiAgcmV0dXJuIHQgPiB0MyA/IE1hdGgucG93KHQsIDEgLyAzKSA6IHQgLyB0MiArIHQwO1xufVxuXG5mdW5jdGlvbiBsYWIyeHl6KHQpIHtcbiAgcmV0dXJuIHQgPiB0MSA/IHQgKiB0ICogdCA6IHQyICogKHQgLSB0MCk7XG59XG5cbmZ1bmN0aW9uIHh5ejJyZ2IoeCkge1xuICByZXR1cm4gMjU1ICogKHggPD0gMC4wMDMxMzA4ID8gMTIuOTIgKiB4IDogMS4wNTUgKiBNYXRoLnBvdyh4LCAxIC8gMi40KSAtIDAuMDU1KTtcbn1cblxuZnVuY3Rpb24gcmdiMnh5eih4KSB7XG4gIHJldHVybiAoeCAvPSAyNTUpIDw9IDAuMDQwNDUgPyB4IC8gMTIuOTIgOiBNYXRoLnBvdygoeCArIDAuMDU1KSAvIDEuMDU1LCAyLjQpO1xufVxuXG5mdW5jdGlvbiBoY2xDb252ZXJ0KG8pIHtcbiAgaWYgKG8gaW5zdGFuY2VvZiBIY2wpIHJldHVybiBuZXcgSGNsKG8uaCwgby5jLCBvLmwsIG8ub3BhY2l0eSk7XG4gIGlmICghKG8gaW5zdGFuY2VvZiBMYWIpKSBvID0gbGFiQ29udmVydChvKTtcbiAgdmFyIGggPSBNYXRoLmF0YW4yKG8uYiwgby5hKSAqIHJhZDJkZWc7XG4gIHJldHVybiBuZXcgSGNsKGggPCAwID8gaCArIDM2MCA6IGgsIE1hdGguc3FydChvLmEgKiBvLmEgKyBvLmIgKiBvLmIpLCBvLmwsIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGhjbChoLCBjLCBsLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gaGNsQ29udmVydChoKSA6IG5ldyBIY2woaCwgYywgbCwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBIY2woaCwgYywgbCwgb3BhY2l0eSkge1xuICB0aGlzLmggPSAraDtcbiAgdGhpcy5jID0gK2M7XG4gIHRoaXMubCA9ICtsO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKEhjbCwgaGNsLCBleHRlbmQoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHtcbiAgICByZXR1cm4gbmV3IEhjbCh0aGlzLmgsIHRoaXMuYywgdGhpcy5sICsgS24gKiAoayA9PSBudWxsID8gMSA6IGspLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICBkYXJrZXI6IGZ1bmN0aW9uKGspIHtcbiAgICByZXR1cm4gbmV3IEhjbCh0aGlzLmgsIHRoaXMuYywgdGhpcy5sIC0gS24gKiAoayA9PSBudWxsID8gMSA6IGspLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICByZ2I6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBsYWJDb252ZXJ0KHRoaXMpLnJnYigpO1xuICB9XG59KSk7XG5cbnZhciBBID0gLTAuMTQ4NjE7XG52YXIgQiA9ICsxLjc4Mjc3O1xudmFyIEMgPSAtMC4yOTIyNztcbnZhciBEID0gLTAuOTA2NDk7XG52YXIgRSA9ICsxLjk3Mjk0O1xudmFyIEVEID0gRSAqIEQ7XG52YXIgRUIgPSBFICogQjtcbnZhciBCQ19EQSA9IEIgKiBDIC0gRCAqIEE7XG5cbmZ1bmN0aW9uIGN1YmVoZWxpeENvbnZlcnQobykge1xuICBpZiAobyBpbnN0YW5jZW9mIEN1YmVoZWxpeCkgcmV0dXJuIG5ldyBDdWJlaGVsaXgoby5oLCBvLnMsIG8ubCwgby5vcGFjaXR5KTtcbiAgaWYgKCEobyBpbnN0YW5jZW9mIFJnYikpIG8gPSByZ2JDb252ZXJ0KG8pO1xuICB2YXIgciA9IG8uciAvIDI1NSxcbiAgICAgIGcgPSBvLmcgLyAyNTUsXG4gICAgICBiID0gby5iIC8gMjU1LFxuICAgICAgbCA9IChCQ19EQSAqIGIgKyBFRCAqIHIgLSBFQiAqIGcpIC8gKEJDX0RBICsgRUQgLSBFQiksXG4gICAgICBibCA9IGIgLSBsLFxuICAgICAgayA9IChFICogKGcgLSBsKSAtIEMgKiBibCkgLyBELFxuICAgICAgcyA9IE1hdGguc3FydChrICogayArIGJsICogYmwpIC8gKEUgKiBsICogKDEgLSBsKSksIC8vIE5hTiBpZiBsPTAgb3IgbD0xXG4gICAgICBoID0gcyA/IE1hdGguYXRhbjIoaywgYmwpICogcmFkMmRlZyAtIDEyMCA6IE5hTjtcbiAgcmV0dXJuIG5ldyBDdWJlaGVsaXgoaCA8IDAgPyBoICsgMzYwIDogaCwgcywgbCwgby5vcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gY3ViZWhlbGl4KGgsIHMsIGwsIG9wYWNpdHkpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyBjdWJlaGVsaXhDb252ZXJ0KGgpIDogbmV3IEN1YmVoZWxpeChoLCBzLCBsLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIEN1YmVoZWxpeChoLCBzLCBsLCBvcGFjaXR5KSB7XG4gIHRoaXMuaCA9ICtoO1xuICB0aGlzLnMgPSArcztcbiAgdGhpcy5sID0gK2w7XG4gIHRoaXMub3BhY2l0eSA9ICtvcGFjaXR5O1xufVxuXG5kZWZpbmUoQ3ViZWhlbGl4LCBjdWJlaGVsaXgsIGV4dGVuZChDb2xvciwge1xuICBicmlnaHRlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBicmlnaHRlciA6IE1hdGgucG93KGJyaWdodGVyLCBrKTtcbiAgICByZXR1cm4gbmV3IEN1YmVoZWxpeCh0aGlzLmgsIHRoaXMucywgdGhpcy5sICogaywgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgZGFya2VyOiBmdW5jdGlvbihrKSB7XG4gICAgayA9IGsgPT0gbnVsbCA/IGRhcmtlciA6IE1hdGgucG93KGRhcmtlciwgayk7XG4gICAgcmV0dXJuIG5ldyBDdWJlaGVsaXgodGhpcy5oLCB0aGlzLnMsIHRoaXMubCAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGggPSBpc05hTih0aGlzLmgpID8gMCA6ICh0aGlzLmggKyAxMjApICogZGVnMnJhZCxcbiAgICAgICAgbCA9ICt0aGlzLmwsXG4gICAgICAgIGEgPSBpc05hTih0aGlzLnMpID8gMCA6IHRoaXMucyAqIGwgKiAoMSAtIGwpLFxuICAgICAgICBjb3NoID0gTWF0aC5jb3MoaCksXG4gICAgICAgIHNpbmggPSBNYXRoLnNpbihoKTtcbiAgICByZXR1cm4gbmV3IFJnYihcbiAgICAgIDI1NSAqIChsICsgYSAqIChBICogY29zaCArIEIgKiBzaW5oKSksXG4gICAgICAyNTUgKiAobCArIGEgKiAoQyAqIGNvc2ggKyBEICogc2luaCkpLFxuICAgICAgMjU1ICogKGwgKyBhICogKEUgKiBjb3NoKSksXG4gICAgICB0aGlzLm9wYWNpdHlcbiAgICApO1xuICB9XG59KSk7XG5cbmZ1bmN0aW9uIGJhc2lzKHQxLCB2MCwgdjEsIHYyLCB2Mykge1xuICB2YXIgdDIgPSB0MSAqIHQxLCB0MyA9IHQyICogdDE7XG4gIHJldHVybiAoKDEgLSAzICogdDEgKyAzICogdDIgLSB0MykgKiB2MFxuICAgICAgKyAoNCAtIDYgKiB0MiArIDMgKiB0MykgKiB2MVxuICAgICAgKyAoMSArIDMgKiB0MSArIDMgKiB0MiAtIDMgKiB0MykgKiB2MlxuICAgICAgKyB0MyAqIHYzKSAvIDY7XG59XG5cbnZhciBiYXNpcyQxID0gZnVuY3Rpb24odmFsdWVzKSB7XG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGkgPSB0IDw9IDAgPyAodCA9IDApIDogdCA+PSAxID8gKHQgPSAxLCBuIC0gMSkgOiBNYXRoLmZsb29yKHQgKiBuKSxcbiAgICAgICAgdjEgPSB2YWx1ZXNbaV0sXG4gICAgICAgIHYyID0gdmFsdWVzW2kgKyAxXSxcbiAgICAgICAgdjAgPSBpID4gMCA/IHZhbHVlc1tpIC0gMV0gOiAyICogdjEgLSB2MixcbiAgICAgICAgdjMgPSBpIDwgbiAtIDEgPyB2YWx1ZXNbaSArIDJdIDogMiAqIHYyIC0gdjE7XG4gICAgcmV0dXJuIGJhc2lzKCh0IC0gaSAvIG4pICogbiwgdjAsIHYxLCB2MiwgdjMpO1xuICB9O1xufTtcblxudmFyIGJhc2lzQ2xvc2VkID0gZnVuY3Rpb24odmFsdWVzKSB7XG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aDtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgaSA9IE1hdGguZmxvb3IoKCh0ICU9IDEpIDwgMCA/ICsrdCA6IHQpICogbiksXG4gICAgICAgIHYwID0gdmFsdWVzWyhpICsgbiAtIDEpICUgbl0sXG4gICAgICAgIHYxID0gdmFsdWVzW2kgJSBuXSxcbiAgICAgICAgdjIgPSB2YWx1ZXNbKGkgKyAxKSAlIG5dLFxuICAgICAgICB2MyA9IHZhbHVlc1soaSArIDIpICUgbl07XG4gICAgcmV0dXJuIGJhc2lzKCh0IC0gaSAvIG4pICogbiwgdjAsIHYxLCB2MiwgdjMpO1xuICB9O1xufTtcblxudmFyIGNvbnN0YW50JDMgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIGxpbmVhcihhLCBkKSB7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIGEgKyB0ICogZDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZXhwb25lbnRpYWwoYSwgYiwgeSkge1xuICByZXR1cm4gYSA9IE1hdGgucG93KGEsIHkpLCBiID0gTWF0aC5wb3coYiwgeSkgLSBhLCB5ID0gMSAvIHksIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gTWF0aC5wb3coYSArIHQgKiBiLCB5KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaHVlKGEsIGIpIHtcbiAgdmFyIGQgPSBiIC0gYTtcbiAgcmV0dXJuIGQgPyBsaW5lYXIoYSwgZCA+IDE4MCB8fCBkIDwgLTE4MCA/IGQgLSAzNjAgKiBNYXRoLnJvdW5kKGQgLyAzNjApIDogZCkgOiBjb25zdGFudCQzKGlzTmFOKGEpID8gYiA6IGEpO1xufVxuXG5mdW5jdGlvbiBnYW1tYSh5KSB7XG4gIHJldHVybiAoeSA9ICt5KSA9PT0gMSA/IG5vZ2FtbWEgOiBmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGIgLSBhID8gZXhwb25lbnRpYWwoYSwgYiwgeSkgOiBjb25zdGFudCQzKGlzTmFOKGEpID8gYiA6IGEpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBub2dhbW1hKGEsIGIpIHtcbiAgdmFyIGQgPSBiIC0gYTtcbiAgcmV0dXJuIGQgPyBsaW5lYXIoYSwgZCkgOiBjb25zdGFudCQzKGlzTmFOKGEpID8gYiA6IGEpO1xufVxuXG52YXIgaW50ZXJwb2xhdGVSZ2IgPSAoKGZ1bmN0aW9uIHJnYkdhbW1hKHkpIHtcbiAgdmFyIGNvbG9yJCQxID0gZ2FtbWEoeSk7XG5cbiAgZnVuY3Rpb24gcmdiJCQxKHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgciA9IGNvbG9yJCQxKChzdGFydCA9IHJnYihzdGFydCkpLnIsIChlbmQgPSByZ2IoZW5kKSkuciksXG4gICAgICAgIGcgPSBjb2xvciQkMShzdGFydC5nLCBlbmQuZyksXG4gICAgICAgIGIgPSBjb2xvciQkMShzdGFydC5iLCBlbmQuYiksXG4gICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgc3RhcnQuciA9IHIodCk7XG4gICAgICBzdGFydC5nID0gZyh0KTtcbiAgICAgIHN0YXJ0LmIgPSBiKHQpO1xuICAgICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgIH07XG4gIH1cblxuICByZ2IkJDEuZ2FtbWEgPSByZ2JHYW1tYTtcblxuICByZXR1cm4gcmdiJCQxO1xufSkpKDEpO1xuXG5mdW5jdGlvbiByZ2JTcGxpbmUoc3BsaW5lKSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xvcnMpIHtcbiAgICB2YXIgbiA9IGNvbG9ycy5sZW5ndGgsXG4gICAgICAgIHIgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIGcgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIGIgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIGksIGNvbG9yJCQxO1xuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGNvbG9yJCQxID0gcmdiKGNvbG9yc1tpXSk7XG4gICAgICByW2ldID0gY29sb3IkJDEuciB8fCAwO1xuICAgICAgZ1tpXSA9IGNvbG9yJCQxLmcgfHwgMDtcbiAgICAgIGJbaV0gPSBjb2xvciQkMS5iIHx8IDA7XG4gICAgfVxuICAgIHIgPSBzcGxpbmUocik7XG4gICAgZyA9IHNwbGluZShnKTtcbiAgICBiID0gc3BsaW5lKGIpO1xuICAgIGNvbG9yJCQxLm9wYWNpdHkgPSAxO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICBjb2xvciQkMS5yID0gcih0KTtcbiAgICAgIGNvbG9yJCQxLmcgPSBnKHQpO1xuICAgICAgY29sb3IkJDEuYiA9IGIodCk7XG4gICAgICByZXR1cm4gY29sb3IkJDEgKyBcIlwiO1xuICAgIH07XG4gIH07XG59XG5cbnZhciByZ2JCYXNpcyA9IHJnYlNwbGluZShiYXNpcyQxKTtcbnZhciByZ2JCYXNpc0Nsb3NlZCA9IHJnYlNwbGluZShiYXNpc0Nsb3NlZCk7XG5cbnZhciBhcnJheSQxID0gZnVuY3Rpb24oYSwgYikge1xuICB2YXIgbmIgPSBiID8gYi5sZW5ndGggOiAwLFxuICAgICAgbmEgPSBhID8gTWF0aC5taW4obmIsIGEubGVuZ3RoKSA6IDAsXG4gICAgICB4ID0gbmV3IEFycmF5KG5iKSxcbiAgICAgIGMgPSBuZXcgQXJyYXkobmIpLFxuICAgICAgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgbmE7ICsraSkgeFtpXSA9IGludGVycG9sYXRlVmFsdWUoYVtpXSwgYltpXSk7XG4gIGZvciAoOyBpIDwgbmI7ICsraSkgY1tpXSA9IGJbaV07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbmE7ICsraSkgY1tpXSA9IHhbaV0odCk7XG4gICAgcmV0dXJuIGM7XG4gIH07XG59O1xuXG52YXIgZGF0ZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZTtcbiAgcmV0dXJuIGEgPSArYSwgYiAtPSBhLCBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIGQuc2V0VGltZShhICsgYiAqIHQpLCBkO1xuICB9O1xufTtcblxudmFyIHJlaW50ZXJwb2xhdGUgPSBmdW5jdGlvbihhLCBiKSB7XG4gIHJldHVybiBhID0gK2EsIGIgLT0gYSwgZnVuY3Rpb24odCkge1xuICAgIHJldHVybiBhICsgYiAqIHQ7XG4gIH07XG59O1xuXG52YXIgb2JqZWN0ID0gZnVuY3Rpb24oYSwgYikge1xuICB2YXIgaSA9IHt9LFxuICAgICAgYyA9IHt9LFxuICAgICAgaztcblxuICBpZiAoYSA9PT0gbnVsbCB8fCB0eXBlb2YgYSAhPT0gXCJvYmplY3RcIikgYSA9IHt9O1xuICBpZiAoYiA9PT0gbnVsbCB8fCB0eXBlb2YgYiAhPT0gXCJvYmplY3RcIikgYiA9IHt9O1xuXG4gIGZvciAoayBpbiBiKSB7XG4gICAgaWYgKGsgaW4gYSkge1xuICAgICAgaVtrXSA9IGludGVycG9sYXRlVmFsdWUoYVtrXSwgYltrXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNba10gPSBiW2tdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgZm9yIChrIGluIGkpIGNba10gPSBpW2tdKHQpO1xuICAgIHJldHVybiBjO1xuICB9O1xufTtcblxudmFyIHJlQSA9IC9bLStdPyg/OlxcZCtcXC4/XFxkKnxcXC4/XFxkKykoPzpbZUVdWy0rXT9cXGQrKT8vZztcbnZhciByZUIgPSBuZXcgUmVnRXhwKHJlQS5zb3VyY2UsIFwiZ1wiKTtcblxuZnVuY3Rpb24gemVybyhiKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYjtcbiAgfTtcbn1cblxuZnVuY3Rpb24gb25lKGIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gYih0KSArIFwiXCI7XG4gIH07XG59XG5cbnZhciBpbnRlcnBvbGF0ZVN0cmluZyA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIGJpID0gcmVBLmxhc3RJbmRleCA9IHJlQi5sYXN0SW5kZXggPSAwLCAvLyBzY2FuIGluZGV4IGZvciBuZXh0IG51bWJlciBpbiBiXG4gICAgICBhbSwgLy8gY3VycmVudCBtYXRjaCBpbiBhXG4gICAgICBibSwgLy8gY3VycmVudCBtYXRjaCBpbiBiXG4gICAgICBicywgLy8gc3RyaW5nIHByZWNlZGluZyBjdXJyZW50IG51bWJlciBpbiBiLCBpZiBhbnlcbiAgICAgIGkgPSAtMSwgLy8gaW5kZXggaW4gc1xuICAgICAgcyA9IFtdLCAvLyBzdHJpbmcgY29uc3RhbnRzIGFuZCBwbGFjZWhvbGRlcnNcbiAgICAgIHEgPSBbXTsgLy8gbnVtYmVyIGludGVycG9sYXRvcnNcblxuICAvLyBDb2VyY2UgaW5wdXRzIHRvIHN0cmluZ3MuXG4gIGEgPSBhICsgXCJcIiwgYiA9IGIgKyBcIlwiO1xuXG4gIC8vIEludGVycG9sYXRlIHBhaXJzIG9mIG51bWJlcnMgaW4gYSAmIGIuXG4gIHdoaWxlICgoYW0gPSByZUEuZXhlYyhhKSlcbiAgICAgICYmIChibSA9IHJlQi5leGVjKGIpKSkge1xuICAgIGlmICgoYnMgPSBibS5pbmRleCkgPiBiaSkgeyAvLyBhIHN0cmluZyBwcmVjZWRlcyB0aGUgbmV4dCBudW1iZXIgaW4gYlxuICAgICAgYnMgPSBiLnNsaWNlKGJpLCBicyk7XG4gICAgICBpZiAoc1tpXSkgc1tpXSArPSBiczsgLy8gY29hbGVzY2Ugd2l0aCBwcmV2aW91cyBzdHJpbmdcbiAgICAgIGVsc2Ugc1srK2ldID0gYnM7XG4gICAgfVxuICAgIGlmICgoYW0gPSBhbVswXSkgPT09IChibSA9IGJtWzBdKSkgeyAvLyBudW1iZXJzIGluIGEgJiBiIG1hdGNoXG4gICAgICBpZiAoc1tpXSkgc1tpXSArPSBibTsgLy8gY29hbGVzY2Ugd2l0aCBwcmV2aW91cyBzdHJpbmdcbiAgICAgIGVsc2Ugc1srK2ldID0gYm07XG4gICAgfSBlbHNlIHsgLy8gaW50ZXJwb2xhdGUgbm9uLW1hdGNoaW5nIG51bWJlcnNcbiAgICAgIHNbKytpXSA9IG51bGw7XG4gICAgICBxLnB1c2goe2k6IGksIHg6IHJlaW50ZXJwb2xhdGUoYW0sIGJtKX0pO1xuICAgIH1cbiAgICBiaSA9IHJlQi5sYXN0SW5kZXg7XG4gIH1cblxuICAvLyBBZGQgcmVtYWlucyBvZiBiLlxuICBpZiAoYmkgPCBiLmxlbmd0aCkge1xuICAgIGJzID0gYi5zbGljZShiaSk7XG4gICAgaWYgKHNbaV0pIHNbaV0gKz0gYnM7IC8vIGNvYWxlc2NlIHdpdGggcHJldmlvdXMgc3RyaW5nXG4gICAgZWxzZSBzWysraV0gPSBicztcbiAgfVxuXG4gIC8vIFNwZWNpYWwgb3B0aW1pemF0aW9uIGZvciBvbmx5IGEgc2luZ2xlIG1hdGNoLlxuICAvLyBPdGhlcndpc2UsIGludGVycG9sYXRlIGVhY2ggb2YgdGhlIG51bWJlcnMgYW5kIHJlam9pbiB0aGUgc3RyaW5nLlxuICByZXR1cm4gcy5sZW5ndGggPCAyID8gKHFbMF1cbiAgICAgID8gb25lKHFbMF0ueClcbiAgICAgIDogemVybyhiKSlcbiAgICAgIDogKGIgPSBxLmxlbmd0aCwgZnVuY3Rpb24odCkge1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgYjsgKytpKSBzWyhvID0gcVtpXSkuaV0gPSBvLngodCk7XG4gICAgICAgICAgcmV0dXJuIHMuam9pbihcIlwiKTtcbiAgICAgICAgfSk7XG59O1xuXG52YXIgaW50ZXJwb2xhdGVWYWx1ZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIHQgPSB0eXBlb2YgYiwgYztcbiAgcmV0dXJuIGIgPT0gbnVsbCB8fCB0ID09PSBcImJvb2xlYW5cIiA/IGNvbnN0YW50JDMoYilcbiAgICAgIDogKHQgPT09IFwibnVtYmVyXCIgPyByZWludGVycG9sYXRlXG4gICAgICA6IHQgPT09IFwic3RyaW5nXCIgPyAoKGMgPSBjb2xvcihiKSkgPyAoYiA9IGMsIGludGVycG9sYXRlUmdiKSA6IGludGVycG9sYXRlU3RyaW5nKVxuICAgICAgOiBiIGluc3RhbmNlb2YgY29sb3IgPyBpbnRlcnBvbGF0ZVJnYlxuICAgICAgOiBiIGluc3RhbmNlb2YgRGF0ZSA/IGRhdGVcbiAgICAgIDogQXJyYXkuaXNBcnJheShiKSA/IGFycmF5JDFcbiAgICAgIDogaXNOYU4oYikgPyBvYmplY3RcbiAgICAgIDogcmVpbnRlcnBvbGF0ZSkoYSwgYik7XG59O1xuXG52YXIgaW50ZXJwb2xhdGVSb3VuZCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGEgPSArYSwgYiAtPSBhLCBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoYSArIGIgKiB0KTtcbiAgfTtcbn07XG5cbnZhciBkZWdyZWVzID0gMTgwIC8gTWF0aC5QSTtcblxudmFyIGlkZW50aXR5JDIgPSB7XG4gIHRyYW5zbGF0ZVg6IDAsXG4gIHRyYW5zbGF0ZVk6IDAsXG4gIHJvdGF0ZTogMCxcbiAgc2tld1g6IDAsXG4gIHNjYWxlWDogMSxcbiAgc2NhbGVZOiAxXG59O1xuXG52YXIgZGVjb21wb3NlID0gZnVuY3Rpb24oYSwgYiwgYywgZCwgZSwgZikge1xuICB2YXIgc2NhbGVYLCBzY2FsZVksIHNrZXdYO1xuICBpZiAoc2NhbGVYID0gTWF0aC5zcXJ0KGEgKiBhICsgYiAqIGIpKSBhIC89IHNjYWxlWCwgYiAvPSBzY2FsZVg7XG4gIGlmIChza2V3WCA9IGEgKiBjICsgYiAqIGQpIGMgLT0gYSAqIHNrZXdYLCBkIC09IGIgKiBza2V3WDtcbiAgaWYgKHNjYWxlWSA9IE1hdGguc3FydChjICogYyArIGQgKiBkKSkgYyAvPSBzY2FsZVksIGQgLz0gc2NhbGVZLCBza2V3WCAvPSBzY2FsZVk7XG4gIGlmIChhICogZCA8IGIgKiBjKSBhID0gLWEsIGIgPSAtYiwgc2tld1ggPSAtc2tld1gsIHNjYWxlWCA9IC1zY2FsZVg7XG4gIHJldHVybiB7XG4gICAgdHJhbnNsYXRlWDogZSxcbiAgICB0cmFuc2xhdGVZOiBmLFxuICAgIHJvdGF0ZTogTWF0aC5hdGFuMihiLCBhKSAqIGRlZ3JlZXMsXG4gICAgc2tld1g6IE1hdGguYXRhbihza2V3WCkgKiBkZWdyZWVzLFxuICAgIHNjYWxlWDogc2NhbGVYLFxuICAgIHNjYWxlWTogc2NhbGVZXG4gIH07XG59O1xuXG52YXIgY3NzTm9kZTtcbnZhciBjc3NSb290O1xudmFyIGNzc1ZpZXc7XG52YXIgc3ZnTm9kZTtcblxuZnVuY3Rpb24gcGFyc2VDc3ModmFsdWUpIHtcbiAgaWYgKHZhbHVlID09PSBcIm5vbmVcIikgcmV0dXJuIGlkZW50aXR5JDI7XG4gIGlmICghY3NzTm9kZSkgY3NzTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJESVZcIiksIGNzc1Jvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIGNzc1ZpZXcgPSBkb2N1bWVudC5kZWZhdWx0VmlldztcbiAgY3NzTm9kZS5zdHlsZS50cmFuc2Zvcm0gPSB2YWx1ZTtcbiAgdmFsdWUgPSBjc3NWaWV3LmdldENvbXB1dGVkU3R5bGUoY3NzUm9vdC5hcHBlbmRDaGlsZChjc3NOb2RlKSwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShcInRyYW5zZm9ybVwiKTtcbiAgY3NzUm9vdC5yZW1vdmVDaGlsZChjc3NOb2RlKTtcbiAgdmFsdWUgPSB2YWx1ZS5zbGljZSg3LCAtMSkuc3BsaXQoXCIsXCIpO1xuICByZXR1cm4gZGVjb21wb3NlKCt2YWx1ZVswXSwgK3ZhbHVlWzFdLCArdmFsdWVbMl0sICt2YWx1ZVszXSwgK3ZhbHVlWzRdLCArdmFsdWVbNV0pO1xufVxuXG5mdW5jdGlvbiBwYXJzZVN2Zyh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIGlkZW50aXR5JDI7XG4gIGlmICghc3ZnTm9kZSkgc3ZnTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwiZ1wiKTtcbiAgc3ZnTm9kZS5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgdmFsdWUpO1xuICBpZiAoISh2YWx1ZSA9IHN2Z05vZGUudHJhbnNmb3JtLmJhc2VWYWwuY29uc29saWRhdGUoKSkpIHJldHVybiBpZGVudGl0eSQyO1xuICB2YWx1ZSA9IHZhbHVlLm1hdHJpeDtcbiAgcmV0dXJuIGRlY29tcG9zZSh2YWx1ZS5hLCB2YWx1ZS5iLCB2YWx1ZS5jLCB2YWx1ZS5kLCB2YWx1ZS5lLCB2YWx1ZS5mKTtcbn1cblxuZnVuY3Rpb24gaW50ZXJwb2xhdGVUcmFuc2Zvcm0ocGFyc2UsIHB4Q29tbWEsIHB4UGFyZW4sIGRlZ1BhcmVuKSB7XG5cbiAgZnVuY3Rpb24gcG9wKHMpIHtcbiAgICByZXR1cm4gcy5sZW5ndGggPyBzLnBvcCgpICsgXCIgXCIgOiBcIlwiO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhbnNsYXRlKHhhLCB5YSwgeGIsIHliLCBzLCBxKSB7XG4gICAgaWYgKHhhICE9PSB4YiB8fCB5YSAhPT0geWIpIHtcbiAgICAgIHZhciBpID0gcy5wdXNoKFwidHJhbnNsYXRlKFwiLCBudWxsLCBweENvbW1hLCBudWxsLCBweFBhcmVuKTtcbiAgICAgIHEucHVzaCh7aTogaSAtIDQsIHg6IHJlaW50ZXJwb2xhdGUoeGEsIHhiKX0sIHtpOiBpIC0gMiwgeDogcmVpbnRlcnBvbGF0ZSh5YSwgeWIpfSk7XG4gICAgfSBlbHNlIGlmICh4YiB8fCB5Yikge1xuICAgICAgcy5wdXNoKFwidHJhbnNsYXRlKFwiICsgeGIgKyBweENvbW1hICsgeWIgKyBweFBhcmVuKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByb3RhdGUoYSwgYiwgcywgcSkge1xuICAgIGlmIChhICE9PSBiKSB7XG4gICAgICBpZiAoYSAtIGIgPiAxODApIGIgKz0gMzYwOyBlbHNlIGlmIChiIC0gYSA+IDE4MCkgYSArPSAzNjA7IC8vIHNob3J0ZXN0IHBhdGhcbiAgICAgIHEucHVzaCh7aTogcy5wdXNoKHBvcChzKSArIFwicm90YXRlKFwiLCBudWxsLCBkZWdQYXJlbikgLSAyLCB4OiByZWludGVycG9sYXRlKGEsIGIpfSk7XG4gICAgfSBlbHNlIGlmIChiKSB7XG4gICAgICBzLnB1c2gocG9wKHMpICsgXCJyb3RhdGUoXCIgKyBiICsgZGVnUGFyZW4pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNrZXdYKGEsIGIsIHMsIHEpIHtcbiAgICBpZiAoYSAhPT0gYikge1xuICAgICAgcS5wdXNoKHtpOiBzLnB1c2gocG9wKHMpICsgXCJza2V3WChcIiwgbnVsbCwgZGVnUGFyZW4pIC0gMiwgeDogcmVpbnRlcnBvbGF0ZShhLCBiKX0pO1xuICAgIH0gZWxzZSBpZiAoYikge1xuICAgICAgcy5wdXNoKHBvcChzKSArIFwic2tld1goXCIgKyBiICsgZGVnUGFyZW4pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNjYWxlKHhhLCB5YSwgeGIsIHliLCBzLCBxKSB7XG4gICAgaWYgKHhhICE9PSB4YiB8fCB5YSAhPT0geWIpIHtcbiAgICAgIHZhciBpID0gcy5wdXNoKHBvcChzKSArIFwic2NhbGUoXCIsIG51bGwsIFwiLFwiLCBudWxsLCBcIilcIik7XG4gICAgICBxLnB1c2goe2k6IGkgLSA0LCB4OiByZWludGVycG9sYXRlKHhhLCB4Yil9LCB7aTogaSAtIDIsIHg6IHJlaW50ZXJwb2xhdGUoeWEsIHliKX0pO1xuICAgIH0gZWxzZSBpZiAoeGIgIT09IDEgfHwgeWIgIT09IDEpIHtcbiAgICAgIHMucHVzaChwb3AocykgKyBcInNjYWxlKFwiICsgeGIgKyBcIixcIiArIHliICsgXCIpXCIpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbihhLCBiKSB7XG4gICAgdmFyIHMgPSBbXSwgLy8gc3RyaW5nIGNvbnN0YW50cyBhbmQgcGxhY2Vob2xkZXJzXG4gICAgICAgIHEgPSBbXTsgLy8gbnVtYmVyIGludGVycG9sYXRvcnNcbiAgICBhID0gcGFyc2UoYSksIGIgPSBwYXJzZShiKTtcbiAgICB0cmFuc2xhdGUoYS50cmFuc2xhdGVYLCBhLnRyYW5zbGF0ZVksIGIudHJhbnNsYXRlWCwgYi50cmFuc2xhdGVZLCBzLCBxKTtcbiAgICByb3RhdGUoYS5yb3RhdGUsIGIucm90YXRlLCBzLCBxKTtcbiAgICBza2V3WChhLnNrZXdYLCBiLnNrZXdYLCBzLCBxKTtcbiAgICBzY2FsZShhLnNjYWxlWCwgYS5zY2FsZVksIGIuc2NhbGVYLCBiLnNjYWxlWSwgcywgcSk7XG4gICAgYSA9IGIgPSBudWxsOyAvLyBnY1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgaSA9IC0xLCBuID0gcS5sZW5ndGgsIG87XG4gICAgICB3aGlsZSAoKytpIDwgbikgc1sobyA9IHFbaV0pLmldID0gby54KHQpO1xuICAgICAgcmV0dXJuIHMuam9pbihcIlwiKTtcbiAgICB9O1xuICB9O1xufVxuXG52YXIgaW50ZXJwb2xhdGVUcmFuc2Zvcm1Dc3MgPSBpbnRlcnBvbGF0ZVRyYW5zZm9ybShwYXJzZUNzcywgXCJweCwgXCIsIFwicHgpXCIsIFwiZGVnKVwiKTtcbnZhciBpbnRlcnBvbGF0ZVRyYW5zZm9ybVN2ZyA9IGludGVycG9sYXRlVHJhbnNmb3JtKHBhcnNlU3ZnLCBcIiwgXCIsIFwiKVwiLCBcIilcIik7XG5cbnZhciByaG8gPSBNYXRoLlNRUlQyO1xudmFyIHJobzIgPSAyO1xudmFyIHJobzQgPSA0O1xudmFyIGVwc2lsb24yID0gMWUtMTI7XG5cbmZ1bmN0aW9uIGNvc2goeCkge1xuICByZXR1cm4gKCh4ID0gTWF0aC5leHAoeCkpICsgMSAvIHgpIC8gMjtcbn1cblxuZnVuY3Rpb24gc2luaCh4KSB7XG4gIHJldHVybiAoKHggPSBNYXRoLmV4cCh4KSkgLSAxIC8geCkgLyAyO1xufVxuXG5mdW5jdGlvbiB0YW5oKHgpIHtcbiAgcmV0dXJuICgoeCA9IE1hdGguZXhwKDIgKiB4KSkgLSAxKSAvICh4ICsgMSk7XG59XG5cbi8vIHAwID0gW3V4MCwgdXkwLCB3MF1cbi8vIHAxID0gW3V4MSwgdXkxLCB3MV1cbnZhciBpbnRlcnBvbGF0ZVpvb20gPSBmdW5jdGlvbihwMCwgcDEpIHtcbiAgdmFyIHV4MCA9IHAwWzBdLCB1eTAgPSBwMFsxXSwgdzAgPSBwMFsyXSxcbiAgICAgIHV4MSA9IHAxWzBdLCB1eTEgPSBwMVsxXSwgdzEgPSBwMVsyXSxcbiAgICAgIGR4ID0gdXgxIC0gdXgwLFxuICAgICAgZHkgPSB1eTEgLSB1eTAsXG4gICAgICBkMiA9IGR4ICogZHggKyBkeSAqIGR5LFxuICAgICAgaSxcbiAgICAgIFM7XG5cbiAgLy8gU3BlY2lhbCBjYXNlIGZvciB1MCDiiYUgdTEuXG4gIGlmIChkMiA8IGVwc2lsb24yKSB7XG4gICAgUyA9IE1hdGgubG9nKHcxIC8gdzApIC8gcmhvO1xuICAgIGkgPSBmdW5jdGlvbih0KSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB1eDAgKyB0ICogZHgsXG4gICAgICAgIHV5MCArIHQgKiBkeSxcbiAgICAgICAgdzAgKiBNYXRoLmV4cChyaG8gKiB0ICogUylcbiAgICAgIF07XG4gICAgfTtcbiAgfVxuXG4gIC8vIEdlbmVyYWwgY2FzZS5cbiAgZWxzZSB7XG4gICAgdmFyIGQxID0gTWF0aC5zcXJ0KGQyKSxcbiAgICAgICAgYjAgPSAodzEgKiB3MSAtIHcwICogdzAgKyByaG80ICogZDIpIC8gKDIgKiB3MCAqIHJobzIgKiBkMSksXG4gICAgICAgIGIxID0gKHcxICogdzEgLSB3MCAqIHcwIC0gcmhvNCAqIGQyKSAvICgyICogdzEgKiByaG8yICogZDEpLFxuICAgICAgICByMCA9IE1hdGgubG9nKE1hdGguc3FydChiMCAqIGIwICsgMSkgLSBiMCksXG4gICAgICAgIHIxID0gTWF0aC5sb2coTWF0aC5zcXJ0KGIxICogYjEgKyAxKSAtIGIxKTtcbiAgICBTID0gKHIxIC0gcjApIC8gcmhvO1xuICAgIGkgPSBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgcyA9IHQgKiBTLFxuICAgICAgICAgIGNvc2hyMCA9IGNvc2gocjApLFxuICAgICAgICAgIHUgPSB3MCAvIChyaG8yICogZDEpICogKGNvc2hyMCAqIHRhbmgocmhvICogcyArIHIwKSAtIHNpbmgocjApKTtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHV4MCArIHUgKiBkeCxcbiAgICAgICAgdXkwICsgdSAqIGR5LFxuICAgICAgICB3MCAqIGNvc2hyMCAvIGNvc2gocmhvICogcyArIHIwKVxuICAgICAgXTtcbiAgICB9O1xuICB9XG5cbiAgaS5kdXJhdGlvbiA9IFMgKiAxMDAwO1xuXG4gIHJldHVybiBpO1xufTtcblxuZnVuY3Rpb24gaHNsJDEoaHVlJCQxKSB7XG4gIHJldHVybiBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgdmFyIGggPSBodWUkJDEoKHN0YXJ0ID0gaHNsKHN0YXJ0KSkuaCwgKGVuZCA9IGhzbChlbmQpKS5oKSxcbiAgICAgICAgcyA9IG5vZ2FtbWEoc3RhcnQucywgZW5kLnMpLFxuICAgICAgICBsID0gbm9nYW1tYShzdGFydC5sLCBlbmQubCksXG4gICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgc3RhcnQuaCA9IGgodCk7XG4gICAgICBzdGFydC5zID0gcyh0KTtcbiAgICAgIHN0YXJ0LmwgPSBsKHQpO1xuICAgICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgIH07XG4gIH1cbn1cblxudmFyIGhzbCQyID0gaHNsJDEoaHVlKTtcbnZhciBoc2xMb25nID0gaHNsJDEobm9nYW1tYSk7XG5cbmZ1bmN0aW9uIGxhYiQxKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGwgPSBub2dhbW1hKChzdGFydCA9IGxhYihzdGFydCkpLmwsIChlbmQgPSBsYWIoZW5kKSkubCksXG4gICAgICBhID0gbm9nYW1tYShzdGFydC5hLCBlbmQuYSksXG4gICAgICBiID0gbm9nYW1tYShzdGFydC5iLCBlbmQuYiksXG4gICAgICBvcGFjaXR5ID0gbm9nYW1tYShzdGFydC5vcGFjaXR5LCBlbmQub3BhY2l0eSk7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgc3RhcnQubCA9IGwodCk7XG4gICAgc3RhcnQuYSA9IGEodCk7XG4gICAgc3RhcnQuYiA9IGIodCk7XG4gICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgcmV0dXJuIHN0YXJ0ICsgXCJcIjtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaGNsJDEoaHVlJCQxKSB7XG4gIHJldHVybiBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgdmFyIGggPSBodWUkJDEoKHN0YXJ0ID0gaGNsKHN0YXJ0KSkuaCwgKGVuZCA9IGhjbChlbmQpKS5oKSxcbiAgICAgICAgYyA9IG5vZ2FtbWEoc3RhcnQuYywgZW5kLmMpLFxuICAgICAgICBsID0gbm9nYW1tYShzdGFydC5sLCBlbmQubCksXG4gICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgc3RhcnQuaCA9IGgodCk7XG4gICAgICBzdGFydC5jID0gYyh0KTtcbiAgICAgIHN0YXJ0LmwgPSBsKHQpO1xuICAgICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgIH07XG4gIH1cbn1cblxudmFyIGhjbCQyID0gaGNsJDEoaHVlKTtcbnZhciBoY2xMb25nID0gaGNsJDEobm9nYW1tYSk7XG5cbmZ1bmN0aW9uIGN1YmVoZWxpeCQxKGh1ZSQkMSkge1xuICByZXR1cm4gKGZ1bmN0aW9uIGN1YmVoZWxpeEdhbW1hKHkpIHtcbiAgICB5ID0gK3k7XG5cbiAgICBmdW5jdGlvbiBjdWJlaGVsaXgkJDEoc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGggPSBodWUkJDEoKHN0YXJ0ID0gY3ViZWhlbGl4KHN0YXJ0KSkuaCwgKGVuZCA9IGN1YmVoZWxpeChlbmQpKS5oKSxcbiAgICAgICAgICBzID0gbm9nYW1tYShzdGFydC5zLCBlbmQucyksXG4gICAgICAgICAgbCA9IG5vZ2FtbWEoc3RhcnQubCwgZW5kLmwpLFxuICAgICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICAgIHN0YXJ0LmggPSBoKHQpO1xuICAgICAgICBzdGFydC5zID0gcyh0KTtcbiAgICAgICAgc3RhcnQubCA9IGwoTWF0aC5wb3codCwgeSkpO1xuICAgICAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTtcbiAgICAgICAgcmV0dXJuIHN0YXJ0ICsgXCJcIjtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY3ViZWhlbGl4JCQxLmdhbW1hID0gY3ViZWhlbGl4R2FtbWE7XG5cbiAgICByZXR1cm4gY3ViZWhlbGl4JCQxO1xuICB9KSgxKTtcbn1cblxudmFyIGN1YmVoZWxpeCQyID0gY3ViZWhlbGl4JDEoaHVlKTtcbnZhciBjdWJlaGVsaXhMb25nID0gY3ViZWhlbGl4JDEobm9nYW1tYSk7XG5cbnZhciBxdWFudGl6ZSA9IGZ1bmN0aW9uKGludGVycG9sYXRvciwgbikge1xuICB2YXIgc2FtcGxlcyA9IG5ldyBBcnJheShuKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpIHNhbXBsZXNbaV0gPSBpbnRlcnBvbGF0b3IoaSAvIChuIC0gMSkpO1xuICByZXR1cm4gc2FtcGxlcztcbn07XG5cbnZhciBmcmFtZSA9IDA7XG52YXIgdGltZW91dCA9IDA7XG52YXIgaW50ZXJ2YWwgPSAwO1xudmFyIHBva2VEZWxheSA9IDEwMDA7XG52YXIgdGFza0hlYWQ7XG52YXIgdGFza1RhaWw7XG52YXIgY2xvY2tMYXN0ID0gMDtcbnZhciBjbG9ja05vdyA9IDA7XG52YXIgY2xvY2tTa2V3ID0gMDtcbnZhciBjbG9jayA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gXCJvYmplY3RcIiAmJiBwZXJmb3JtYW5jZS5ub3cgPyBwZXJmb3JtYW5jZSA6IERhdGU7XG52YXIgc2V0RnJhbWUgPSB0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSBcImZ1bmN0aW9uXCIgPyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgOiBmdW5jdGlvbihmKSB7IHNldFRpbWVvdXQoZiwgMTcpOyB9O1xuXG5mdW5jdGlvbiBub3coKSB7XG4gIHJldHVybiBjbG9ja05vdyB8fCAoc2V0RnJhbWUoY2xlYXJOb3cpLCBjbG9ja05vdyA9IGNsb2NrLm5vdygpICsgY2xvY2tTa2V3KTtcbn1cblxuZnVuY3Rpb24gY2xlYXJOb3coKSB7XG4gIGNsb2NrTm93ID0gMDtcbn1cblxuZnVuY3Rpb24gVGltZXIoKSB7XG4gIHRoaXMuX2NhbGwgPVxuICB0aGlzLl90aW1lID1cbiAgdGhpcy5fbmV4dCA9IG51bGw7XG59XG5cblRpbWVyLnByb3RvdHlwZSA9IHRpbWVyLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFRpbWVyLFxuICByZXN0YXJ0OiBmdW5jdGlvbihjYWxsYmFjaywgZGVsYXksIHRpbWUpIHtcbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYWxsYmFjayBpcyBub3QgYSBmdW5jdGlvblwiKTtcbiAgICB0aW1lID0gKHRpbWUgPT0gbnVsbCA/IG5vdygpIDogK3RpbWUpICsgKGRlbGF5ID09IG51bGwgPyAwIDogK2RlbGF5KTtcbiAgICBpZiAoIXRoaXMuX25leHQgJiYgdGFza1RhaWwgIT09IHRoaXMpIHtcbiAgICAgIGlmICh0YXNrVGFpbCkgdGFza1RhaWwuX25leHQgPSB0aGlzO1xuICAgICAgZWxzZSB0YXNrSGVhZCA9IHRoaXM7XG4gICAgICB0YXNrVGFpbCA9IHRoaXM7XG4gICAgfVxuICAgIHRoaXMuX2NhbGwgPSBjYWxsYmFjaztcbiAgICB0aGlzLl90aW1lID0gdGltZTtcbiAgICBzbGVlcCgpO1xuICB9LFxuICBzdG9wOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fY2FsbCkge1xuICAgICAgdGhpcy5fY2FsbCA9IG51bGw7XG4gICAgICB0aGlzLl90aW1lID0gSW5maW5pdHk7XG4gICAgICBzbGVlcCgpO1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gdGltZXIoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSB7XG4gIHZhciB0ID0gbmV3IFRpbWVyO1xuICB0LnJlc3RhcnQoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKTtcbiAgcmV0dXJuIHQ7XG59XG5cbmZ1bmN0aW9uIHRpbWVyRmx1c2goKSB7XG4gIG5vdygpOyAvLyBHZXQgdGhlIGN1cnJlbnQgdGltZSwgaWYgbm90IGFscmVhZHkgc2V0LlxuICArK2ZyYW1lOyAvLyBQcmV0ZW5kIHdl4oCZdmUgc2V0IGFuIGFsYXJtLCBpZiB3ZSBoYXZlbuKAmXQgYWxyZWFkeS5cbiAgdmFyIHQgPSB0YXNrSGVhZCwgZTtcbiAgd2hpbGUgKHQpIHtcbiAgICBpZiAoKGUgPSBjbG9ja05vdyAtIHQuX3RpbWUpID49IDApIHQuX2NhbGwuY2FsbChudWxsLCBlKTtcbiAgICB0ID0gdC5fbmV4dDtcbiAgfVxuICAtLWZyYW1lO1xufVxuXG5mdW5jdGlvbiB3YWtlKCkge1xuICBjbG9ja05vdyA9IChjbG9ja0xhc3QgPSBjbG9jay5ub3coKSkgKyBjbG9ja1NrZXc7XG4gIGZyYW1lID0gdGltZW91dCA9IDA7XG4gIHRyeSB7XG4gICAgdGltZXJGbHVzaCgpO1xuICB9IGZpbmFsbHkge1xuICAgIGZyYW1lID0gMDtcbiAgICBuYXAoKTtcbiAgICBjbG9ja05vdyA9IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gcG9rZSgpIHtcbiAgdmFyIG5vdyA9IGNsb2NrLm5vdygpLCBkZWxheSA9IG5vdyAtIGNsb2NrTGFzdDtcbiAgaWYgKGRlbGF5ID4gcG9rZURlbGF5KSBjbG9ja1NrZXcgLT0gZGVsYXksIGNsb2NrTGFzdCA9IG5vdztcbn1cblxuZnVuY3Rpb24gbmFwKCkge1xuICB2YXIgdDAsIHQxID0gdGFza0hlYWQsIHQyLCB0aW1lID0gSW5maW5pdHk7XG4gIHdoaWxlICh0MSkge1xuICAgIGlmICh0MS5fY2FsbCkge1xuICAgICAgaWYgKHRpbWUgPiB0MS5fdGltZSkgdGltZSA9IHQxLl90aW1lO1xuICAgICAgdDAgPSB0MSwgdDEgPSB0MS5fbmV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgdDIgPSB0MS5fbmV4dCwgdDEuX25leHQgPSBudWxsO1xuICAgICAgdDEgPSB0MCA/IHQwLl9uZXh0ID0gdDIgOiB0YXNrSGVhZCA9IHQyO1xuICAgIH1cbiAgfVxuICB0YXNrVGFpbCA9IHQwO1xuICBzbGVlcCh0aW1lKTtcbn1cblxuZnVuY3Rpb24gc2xlZXAodGltZSkge1xuICBpZiAoZnJhbWUpIHJldHVybjsgLy8gU29vbmVzdCBhbGFybSBhbHJlYWR5IHNldCwgb3Igd2lsbCBiZS5cbiAgaWYgKHRpbWVvdXQpIHRpbWVvdXQgPSBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gIHZhciBkZWxheSA9IHRpbWUgLSBjbG9ja05vdztcbiAgaWYgKGRlbGF5ID4gMjQpIHtcbiAgICBpZiAodGltZSA8IEluZmluaXR5KSB0aW1lb3V0ID0gc2V0VGltZW91dCh3YWtlLCBkZWxheSk7XG4gICAgaWYgKGludGVydmFsKSBpbnRlcnZhbCA9IGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICB9IGVsc2Uge1xuICAgIGlmICghaW50ZXJ2YWwpIGNsb2NrTGFzdCA9IGNsb2NrTm93LCBpbnRlcnZhbCA9IHNldEludGVydmFsKHBva2UsIHBva2VEZWxheSk7XG4gICAgZnJhbWUgPSAxLCBzZXRGcmFtZSh3YWtlKTtcbiAgfVxufVxuXG52YXIgdGltZW91dCQxID0gZnVuY3Rpb24oY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSB7XG4gIHZhciB0ID0gbmV3IFRpbWVyO1xuICBkZWxheSA9IGRlbGF5ID09IG51bGwgPyAwIDogK2RlbGF5O1xuICB0LnJlc3RhcnQoZnVuY3Rpb24oZWxhcHNlZCkge1xuICAgIHQuc3RvcCgpO1xuICAgIGNhbGxiYWNrKGVsYXBzZWQgKyBkZWxheSk7XG4gIH0sIGRlbGF5LCB0aW1lKTtcbiAgcmV0dXJuIHQ7XG59O1xuXG52YXIgaW50ZXJ2YWwkMSA9IGZ1bmN0aW9uKGNhbGxiYWNrLCBkZWxheSwgdGltZSkge1xuICB2YXIgdCA9IG5ldyBUaW1lciwgdG90YWwgPSBkZWxheTtcbiAgaWYgKGRlbGF5ID09IG51bGwpIHJldHVybiB0LnJlc3RhcnQoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSwgdDtcbiAgZGVsYXkgPSArZGVsYXksIHRpbWUgPSB0aW1lID09IG51bGwgPyBub3coKSA6ICt0aW1lO1xuICB0LnJlc3RhcnQoZnVuY3Rpb24gdGljayhlbGFwc2VkKSB7XG4gICAgZWxhcHNlZCArPSB0b3RhbDtcbiAgICB0LnJlc3RhcnQodGljaywgdG90YWwgKz0gZGVsYXksIHRpbWUpO1xuICAgIGNhbGxiYWNrKGVsYXBzZWQpO1xuICB9LCBkZWxheSwgdGltZSk7XG4gIHJldHVybiB0O1xufTtcblxudmFyIGVtcHR5T24gPSBkaXNwYXRjaChcInN0YXJ0XCIsIFwiZW5kXCIsIFwiaW50ZXJydXB0XCIpO1xudmFyIGVtcHR5VHdlZW4gPSBbXTtcblxudmFyIENSRUFURUQgPSAwO1xudmFyIFNDSEVEVUxFRCA9IDE7XG52YXIgU1RBUlRJTkcgPSAyO1xudmFyIFNUQVJURUQgPSAzO1xudmFyIFJVTk5JTkcgPSA0O1xudmFyIEVORElORyA9IDU7XG52YXIgRU5ERUQgPSA2O1xuXG52YXIgc2NoZWR1bGUgPSBmdW5jdGlvbihub2RlLCBuYW1lLCBpZCwgaW5kZXgsIGdyb3VwLCB0aW1pbmcpIHtcbiAgdmFyIHNjaGVkdWxlcyA9IG5vZGUuX190cmFuc2l0aW9uO1xuICBpZiAoIXNjaGVkdWxlcykgbm9kZS5fX3RyYW5zaXRpb24gPSB7fTtcbiAgZWxzZSBpZiAoaWQgaW4gc2NoZWR1bGVzKSByZXR1cm47XG4gIGNyZWF0ZShub2RlLCBpZCwge1xuICAgIG5hbWU6IG5hbWUsXG4gICAgaW5kZXg6IGluZGV4LCAvLyBGb3IgY29udGV4dCBkdXJpbmcgY2FsbGJhY2suXG4gICAgZ3JvdXA6IGdyb3VwLCAvLyBGb3IgY29udGV4dCBkdXJpbmcgY2FsbGJhY2suXG4gICAgb246IGVtcHR5T24sXG4gICAgdHdlZW46IGVtcHR5VHdlZW4sXG4gICAgdGltZTogdGltaW5nLnRpbWUsXG4gICAgZGVsYXk6IHRpbWluZy5kZWxheSxcbiAgICBkdXJhdGlvbjogdGltaW5nLmR1cmF0aW9uLFxuICAgIGVhc2U6IHRpbWluZy5lYXNlLFxuICAgIHRpbWVyOiBudWxsLFxuICAgIHN0YXRlOiBDUkVBVEVEXG4gIH0pO1xufTtcblxuZnVuY3Rpb24gaW5pdChub2RlLCBpZCkge1xuICB2YXIgc2NoZWR1bGUgPSBub2RlLl9fdHJhbnNpdGlvbjtcbiAgaWYgKCFzY2hlZHVsZSB8fCAhKHNjaGVkdWxlID0gc2NoZWR1bGVbaWRdKSB8fCBzY2hlZHVsZS5zdGF0ZSA+IENSRUFURUQpIHRocm93IG5ldyBFcnJvcihcInRvbyBsYXRlXCIpO1xuICByZXR1cm4gc2NoZWR1bGU7XG59XG5cbmZ1bmN0aW9uIHNldCQxKG5vZGUsIGlkKSB7XG4gIHZhciBzY2hlZHVsZSA9IG5vZGUuX190cmFuc2l0aW9uO1xuICBpZiAoIXNjaGVkdWxlIHx8ICEoc2NoZWR1bGUgPSBzY2hlZHVsZVtpZF0pIHx8IHNjaGVkdWxlLnN0YXRlID4gU1RBUlRJTkcpIHRocm93IG5ldyBFcnJvcihcInRvbyBsYXRlXCIpO1xuICByZXR1cm4gc2NoZWR1bGU7XG59XG5cbmZ1bmN0aW9uIGdldCQxKG5vZGUsIGlkKSB7XG4gIHZhciBzY2hlZHVsZSA9IG5vZGUuX190cmFuc2l0aW9uO1xuICBpZiAoIXNjaGVkdWxlIHx8ICEoc2NoZWR1bGUgPSBzY2hlZHVsZVtpZF0pKSB0aHJvdyBuZXcgRXJyb3IoXCJ0b28gbGF0ZVwiKTtcbiAgcmV0dXJuIHNjaGVkdWxlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGUobm9kZSwgaWQsIHNlbGYpIHtcbiAgdmFyIHNjaGVkdWxlcyA9IG5vZGUuX190cmFuc2l0aW9uLFxuICAgICAgdHdlZW47XG5cbiAgLy8gSW5pdGlhbGl6ZSB0aGUgc2VsZiB0aW1lciB3aGVuIHRoZSB0cmFuc2l0aW9uIGlzIGNyZWF0ZWQuXG4gIC8vIE5vdGUgdGhlIGFjdHVhbCBkZWxheSBpcyBub3Qga25vd24gdW50aWwgdGhlIGZpcnN0IGNhbGxiYWNrIVxuICBzY2hlZHVsZXNbaWRdID0gc2VsZjtcbiAgc2VsZi50aW1lciA9IHRpbWVyKHNjaGVkdWxlLCAwLCBzZWxmLnRpbWUpO1xuXG4gIGZ1bmN0aW9uIHNjaGVkdWxlKGVsYXBzZWQpIHtcbiAgICBzZWxmLnN0YXRlID0gU0NIRURVTEVEO1xuICAgIHNlbGYudGltZXIucmVzdGFydChzdGFydCwgc2VsZi5kZWxheSwgc2VsZi50aW1lKTtcblxuICAgIC8vIElmIHRoZSBlbGFwc2VkIGRlbGF5IGlzIGxlc3MgdGhhbiBvdXIgZmlyc3Qgc2xlZXAsIHN0YXJ0IGltbWVkaWF0ZWx5LlxuICAgIGlmIChzZWxmLmRlbGF5IDw9IGVsYXBzZWQpIHN0YXJ0KGVsYXBzZWQgLSBzZWxmLmRlbGF5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0YXJ0KGVsYXBzZWQpIHtcbiAgICB2YXIgaSwgaiwgbiwgbztcblxuICAgIC8vIElmIHRoZSBzdGF0ZSBpcyBub3QgU0NIRURVTEVELCB0aGVuIHdlIHByZXZpb3VzbHkgZXJyb3JlZCBvbiBzdGFydC5cbiAgICBpZiAoc2VsZi5zdGF0ZSAhPT0gU0NIRURVTEVEKSByZXR1cm4gc3RvcCgpO1xuXG4gICAgZm9yIChpIGluIHNjaGVkdWxlcykge1xuICAgICAgbyA9IHNjaGVkdWxlc1tpXTtcbiAgICAgIGlmIChvLm5hbWUgIT09IHNlbGYubmFtZSkgY29udGludWU7XG5cbiAgICAgIC8vIFdoaWxlIHRoaXMgZWxlbWVudCBhbHJlYWR5IGhhcyBhIHN0YXJ0aW5nIHRyYW5zaXRpb24gZHVyaW5nIHRoaXMgZnJhbWUsXG4gICAgICAvLyBkZWZlciBzdGFydGluZyBhbiBpbnRlcnJ1cHRpbmcgdHJhbnNpdGlvbiB1bnRpbCB0aGF0IHRyYW5zaXRpb24gaGFzIGFcbiAgICAgIC8vIGNoYW5jZSB0byB0aWNrIChhbmQgcG9zc2libHkgZW5kKTsgc2VlIGQzL2QzLXRyYW5zaXRpb24jNTQhXG4gICAgICBpZiAoby5zdGF0ZSA9PT0gU1RBUlRFRCkgcmV0dXJuIHRpbWVvdXQkMShzdGFydCk7XG5cbiAgICAgIC8vIEludGVycnVwdCB0aGUgYWN0aXZlIHRyYW5zaXRpb24sIGlmIGFueS5cbiAgICAgIC8vIERpc3BhdGNoIHRoZSBpbnRlcnJ1cHQgZXZlbnQuXG4gICAgICBpZiAoby5zdGF0ZSA9PT0gUlVOTklORykge1xuICAgICAgICBvLnN0YXRlID0gRU5ERUQ7XG4gICAgICAgIG8udGltZXIuc3RvcCgpO1xuICAgICAgICBvLm9uLmNhbGwoXCJpbnRlcnJ1cHRcIiwgbm9kZSwgbm9kZS5fX2RhdGFfXywgby5pbmRleCwgby5ncm91cCk7XG4gICAgICAgIGRlbGV0ZSBzY2hlZHVsZXNbaV07XG4gICAgICB9XG5cbiAgICAgIC8vIENhbmNlbCBhbnkgcHJlLWVtcHRlZCB0cmFuc2l0aW9ucy4gTm8gaW50ZXJydXB0IGV2ZW50IGlzIGRpc3BhdGNoZWRcbiAgICAgIC8vIGJlY2F1c2UgdGhlIGNhbmNlbGxlZCB0cmFuc2l0aW9ucyBuZXZlciBzdGFydGVkLiBOb3RlIHRoYXQgdGhpcyBhbHNvXG4gICAgICAvLyByZW1vdmVzIHRoaXMgdHJhbnNpdGlvbiBmcm9tIHRoZSBwZW5kaW5nIGxpc3QhXG4gICAgICBlbHNlIGlmICgraSA8IGlkKSB7XG4gICAgICAgIG8uc3RhdGUgPSBFTkRFRDtcbiAgICAgICAgby50aW1lci5zdG9wKCk7XG4gICAgICAgIGRlbGV0ZSBzY2hlZHVsZXNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRGVmZXIgdGhlIGZpcnN0IHRpY2sgdG8gZW5kIG9mIHRoZSBjdXJyZW50IGZyYW1lOyBzZWUgZDMvZDMjMTU3Ni5cbiAgICAvLyBOb3RlIHRoZSB0cmFuc2l0aW9uIG1heSBiZSBjYW5jZWxlZCBhZnRlciBzdGFydCBhbmQgYmVmb3JlIHRoZSBmaXJzdCB0aWNrIVxuICAgIC8vIE5vdGUgdGhpcyBtdXN0IGJlIHNjaGVkdWxlZCBiZWZvcmUgdGhlIHN0YXJ0IGV2ZW50OyBzZWUgZDMvZDMtdHJhbnNpdGlvbiMxNiFcbiAgICAvLyBBc3N1bWluZyB0aGlzIGlzIHN1Y2Nlc3NmdWwsIHN1YnNlcXVlbnQgY2FsbGJhY2tzIGdvIHN0cmFpZ2h0IHRvIHRpY2suXG4gICAgdGltZW91dCQxKGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHNlbGYuc3RhdGUgPT09IFNUQVJURUQpIHtcbiAgICAgICAgc2VsZi5zdGF0ZSA9IFJVTk5JTkc7XG4gICAgICAgIHNlbGYudGltZXIucmVzdGFydCh0aWNrLCBzZWxmLmRlbGF5LCBzZWxmLnRpbWUpO1xuICAgICAgICB0aWNrKGVsYXBzZWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gRGlzcGF0Y2ggdGhlIHN0YXJ0IGV2ZW50LlxuICAgIC8vIE5vdGUgdGhpcyBtdXN0IGJlIGRvbmUgYmVmb3JlIHRoZSB0d2VlbiBhcmUgaW5pdGlhbGl6ZWQuXG4gICAgc2VsZi5zdGF0ZSA9IFNUQVJUSU5HO1xuICAgIHNlbGYub24uY2FsbChcInN0YXJ0XCIsIG5vZGUsIG5vZGUuX19kYXRhX18sIHNlbGYuaW5kZXgsIHNlbGYuZ3JvdXApO1xuICAgIGlmIChzZWxmLnN0YXRlICE9PSBTVEFSVElORykgcmV0dXJuOyAvLyBpbnRlcnJ1cHRlZFxuICAgIHNlbGYuc3RhdGUgPSBTVEFSVEVEO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgdHdlZW4sIGRlbGV0aW5nIG51bGwgdHdlZW4uXG4gICAgdHdlZW4gPSBuZXcgQXJyYXkobiA9IHNlbGYudHdlZW4ubGVuZ3RoKTtcbiAgICBmb3IgKGkgPSAwLCBqID0gLTE7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmIChvID0gc2VsZi50d2VlbltpXS52YWx1ZS5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIHNlbGYuaW5kZXgsIHNlbGYuZ3JvdXApKSB7XG4gICAgICAgIHR3ZWVuWysral0gPSBvO1xuICAgICAgfVxuICAgIH1cbiAgICB0d2Vlbi5sZW5ndGggPSBqICsgMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRpY2soZWxhcHNlZCkge1xuICAgIHZhciB0ID0gZWxhcHNlZCA8IHNlbGYuZHVyYXRpb24gPyBzZWxmLmVhc2UuY2FsbChudWxsLCBlbGFwc2VkIC8gc2VsZi5kdXJhdGlvbikgOiAoc2VsZi50aW1lci5yZXN0YXJ0KHN0b3ApLCBzZWxmLnN0YXRlID0gRU5ESU5HLCAxKSxcbiAgICAgICAgaSA9IC0xLFxuICAgICAgICBuID0gdHdlZW4ubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIHR3ZWVuW2ldLmNhbGwobnVsbCwgdCk7XG4gICAgfVxuXG4gICAgLy8gRGlzcGF0Y2ggdGhlIGVuZCBldmVudC5cbiAgICBpZiAoc2VsZi5zdGF0ZSA9PT0gRU5ESU5HKSB7XG4gICAgICBzZWxmLm9uLmNhbGwoXCJlbmRcIiwgbm9kZSwgbm9kZS5fX2RhdGFfXywgc2VsZi5pbmRleCwgc2VsZi5ncm91cCk7XG4gICAgICBzdG9wKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc3RvcCgpIHtcbiAgICBzZWxmLnN0YXRlID0gRU5ERUQ7XG4gICAgc2VsZi50aW1lci5zdG9wKCk7XG4gICAgZGVsZXRlIHNjaGVkdWxlc1tpZF07XG4gICAgZm9yICh2YXIgaSBpbiBzY2hlZHVsZXMpIHJldHVybjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIGRlbGV0ZSBub2RlLl9fdHJhbnNpdGlvbjtcbiAgfVxufVxuXG52YXIgaW50ZXJydXB0ID0gZnVuY3Rpb24obm9kZSwgbmFtZSkge1xuICB2YXIgc2NoZWR1bGVzID0gbm9kZS5fX3RyYW5zaXRpb24sXG4gICAgICBzY2hlZHVsZSxcbiAgICAgIGFjdGl2ZSxcbiAgICAgIGVtcHR5ID0gdHJ1ZSxcbiAgICAgIGk7XG5cbiAgaWYgKCFzY2hlZHVsZXMpIHJldHVybjtcblxuICBuYW1lID0gbmFtZSA9PSBudWxsID8gbnVsbCA6IG5hbWUgKyBcIlwiO1xuXG4gIGZvciAoaSBpbiBzY2hlZHVsZXMpIHtcbiAgICBpZiAoKHNjaGVkdWxlID0gc2NoZWR1bGVzW2ldKS5uYW1lICE9PSBuYW1lKSB7IGVtcHR5ID0gZmFsc2U7IGNvbnRpbnVlOyB9XG4gICAgYWN0aXZlID0gc2NoZWR1bGUuc3RhdGUgPiBTVEFSVElORyAmJiBzY2hlZHVsZS5zdGF0ZSA8IEVORElORztcbiAgICBzY2hlZHVsZS5zdGF0ZSA9IEVOREVEO1xuICAgIHNjaGVkdWxlLnRpbWVyLnN0b3AoKTtcbiAgICBpZiAoYWN0aXZlKSBzY2hlZHVsZS5vbi5jYWxsKFwiaW50ZXJydXB0XCIsIG5vZGUsIG5vZGUuX19kYXRhX18sIHNjaGVkdWxlLmluZGV4LCBzY2hlZHVsZS5ncm91cCk7XG4gICAgZGVsZXRlIHNjaGVkdWxlc1tpXTtcbiAgfVxuXG4gIGlmIChlbXB0eSkgZGVsZXRlIG5vZGUuX190cmFuc2l0aW9uO1xufTtcblxudmFyIHNlbGVjdGlvbl9pbnRlcnJ1cHQgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgaW50ZXJydXB0KHRoaXMsIG5hbWUpO1xuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHR3ZWVuUmVtb3ZlKGlkLCBuYW1lKSB7XG4gIHZhciB0d2VlbjAsIHR3ZWVuMTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBzY2hlZHVsZSA9IHNldCQxKHRoaXMsIGlkKSxcbiAgICAgICAgdHdlZW4gPSBzY2hlZHVsZS50d2VlbjtcblxuICAgIC8vIElmIHRoaXMgbm9kZSBzaGFyZWQgdHdlZW4gd2l0aCB0aGUgcHJldmlvdXMgbm9kZSxcbiAgICAvLyBqdXN0IGFzc2lnbiB0aGUgdXBkYXRlZCBzaGFyZWQgdHdlZW4gYW5kIHdl4oCZcmUgZG9uZSFcbiAgICAvLyBPdGhlcndpc2UsIGNvcHktb24td3JpdGUuXG4gICAgaWYgKHR3ZWVuICE9PSB0d2VlbjApIHtcbiAgICAgIHR3ZWVuMSA9IHR3ZWVuMCA9IHR3ZWVuO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSB0d2VlbjEubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmICh0d2VlbjFbaV0ubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgIHR3ZWVuMSA9IHR3ZWVuMS5zbGljZSgpO1xuICAgICAgICAgIHR3ZWVuMS5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBzY2hlZHVsZS50d2VlbiA9IHR3ZWVuMTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gdHdlZW5GdW5jdGlvbihpZCwgbmFtZSwgdmFsdWUpIHtcbiAgdmFyIHR3ZWVuMCwgdHdlZW4xO1xuICBpZiAodHlwZW9mIHZhbHVlICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBFcnJvcjtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBzY2hlZHVsZSA9IHNldCQxKHRoaXMsIGlkKSxcbiAgICAgICAgdHdlZW4gPSBzY2hlZHVsZS50d2VlbjtcblxuICAgIC8vIElmIHRoaXMgbm9kZSBzaGFyZWQgdHdlZW4gd2l0aCB0aGUgcHJldmlvdXMgbm9kZSxcbiAgICAvLyBqdXN0IGFzc2lnbiB0aGUgdXBkYXRlZCBzaGFyZWQgdHdlZW4gYW5kIHdl4oCZcmUgZG9uZSFcbiAgICAvLyBPdGhlcndpc2UsIGNvcHktb24td3JpdGUuXG4gICAgaWYgKHR3ZWVuICE9PSB0d2VlbjApIHtcbiAgICAgIHR3ZWVuMSA9ICh0d2VlbjAgPSB0d2Vlbikuc2xpY2UoKTtcbiAgICAgIGZvciAodmFyIHQgPSB7bmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlfSwgaSA9IDAsIG4gPSB0d2VlbjEubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmICh0d2VlbjFbaV0ubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgIHR3ZWVuMVtpXSA9IHQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpID09PSBuKSB0d2VlbjEucHVzaCh0KTtcbiAgICB9XG5cbiAgICBzY2hlZHVsZS50d2VlbiA9IHR3ZWVuMTtcbiAgfTtcbn1cblxudmFyIHRyYW5zaXRpb25fdHdlZW4gPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICB2YXIgaWQgPSB0aGlzLl9pZDtcblxuICBuYW1lICs9IFwiXCI7XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgdmFyIHR3ZWVuID0gZ2V0JDEodGhpcy5ub2RlKCksIGlkKS50d2VlbjtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IHR3ZWVuLmxlbmd0aCwgdDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKCh0ID0gdHdlZW5baV0pLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHQudmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuZWFjaCgodmFsdWUgPT0gbnVsbCA/IHR3ZWVuUmVtb3ZlIDogdHdlZW5GdW5jdGlvbikoaWQsIG5hbWUsIHZhbHVlKSk7XG59O1xuXG5mdW5jdGlvbiB0d2VlblZhbHVlKHRyYW5zaXRpb24sIG5hbWUsIHZhbHVlKSB7XG4gIHZhciBpZCA9IHRyYW5zaXRpb24uX2lkO1xuXG4gIHRyYW5zaXRpb24uZWFjaChmdW5jdGlvbigpIHtcbiAgICB2YXIgc2NoZWR1bGUgPSBzZXQkMSh0aGlzLCBpZCk7XG4gICAgKHNjaGVkdWxlLnZhbHVlIHx8IChzY2hlZHVsZS52YWx1ZSA9IHt9KSlbbmFtZV0gPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9KTtcblxuICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgIHJldHVybiBnZXQkMShub2RlLCBpZCkudmFsdWVbbmFtZV07XG4gIH07XG59XG5cbnZhciBpbnRlcnBvbGF0ZSQkMSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIGM7XG4gIHJldHVybiAodHlwZW9mIGIgPT09IFwibnVtYmVyXCIgPyByZWludGVycG9sYXRlXG4gICAgICA6IGIgaW5zdGFuY2VvZiBjb2xvciA/IGludGVycG9sYXRlUmdiXG4gICAgICA6IChjID0gY29sb3IoYikpID8gKGIgPSBjLCBpbnRlcnBvbGF0ZVJnYilcbiAgICAgIDogaW50ZXJwb2xhdGVTdHJpbmcpKGEsIGIpO1xufTtcblxuZnVuY3Rpb24gYXR0clJlbW92ZSQxKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyUmVtb3ZlTlMkMShmdWxsbmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyQ29uc3RhbnQkMShuYW1lLCBpbnRlcnBvbGF0ZSQkMSwgdmFsdWUxKSB7XG4gIHZhciB2YWx1ZTAwLFxuICAgICAgaW50ZXJwb2xhdGUwO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZhbHVlMCA9IHRoaXMuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgIHJldHVybiB2YWx1ZTAgPT09IHZhbHVlMSA/IG51bGxcbiAgICAgICAgOiB2YWx1ZTAgPT09IHZhbHVlMDAgPyBpbnRlcnBvbGF0ZTBcbiAgICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZSQkMSh2YWx1ZTAwID0gdmFsdWUwLCB2YWx1ZTEpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyQ29uc3RhbnROUyQxKGZ1bGxuYW1lLCBpbnRlcnBvbGF0ZSQkMSwgdmFsdWUxKSB7XG4gIHZhciB2YWx1ZTAwLFxuICAgICAgaW50ZXJwb2xhdGUwO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZhbHVlMCA9IHRoaXMuZ2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgICByZXR1cm4gdmFsdWUwID09PSB2YWx1ZTEgPyBudWxsXG4gICAgICAgIDogdmFsdWUwID09PSB2YWx1ZTAwID8gaW50ZXJwb2xhdGUwXG4gICAgICAgIDogaW50ZXJwb2xhdGUwID0gaW50ZXJwb2xhdGUkJDEodmFsdWUwMCA9IHZhbHVlMCwgdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckZ1bmN0aW9uJDEobmFtZSwgaW50ZXJwb2xhdGUkJDEsIHZhbHVlKSB7XG4gIHZhciB2YWx1ZTAwLFxuICAgICAgdmFsdWUxMCxcbiAgICAgIGludGVycG9sYXRlMDtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2YWx1ZTAsIHZhbHVlMSA9IHZhbHVlKHRoaXMpO1xuICAgIGlmICh2YWx1ZTEgPT0gbnVsbCkgcmV0dXJuIHZvaWQgdGhpcy5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgdmFsdWUwID0gdGhpcy5nZXRBdHRyaWJ1dGUobmFtZSk7XG4gICAgcmV0dXJuIHZhbHVlMCA9PT0gdmFsdWUxID8gbnVsbFxuICAgICAgICA6IHZhbHVlMCA9PT0gdmFsdWUwMCAmJiB2YWx1ZTEgPT09IHZhbHVlMTAgPyBpbnRlcnBvbGF0ZTBcbiAgICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZSQkMSh2YWx1ZTAwID0gdmFsdWUwLCB2YWx1ZTEwID0gdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckZ1bmN0aW9uTlMkMShmdWxsbmFtZSwgaW50ZXJwb2xhdGUkJDEsIHZhbHVlKSB7XG4gIHZhciB2YWx1ZTAwLFxuICAgICAgdmFsdWUxMCxcbiAgICAgIGludGVycG9sYXRlMDtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2YWx1ZTAsIHZhbHVlMSA9IHZhbHVlKHRoaXMpO1xuICAgIGlmICh2YWx1ZTEgPT0gbnVsbCkgcmV0dXJuIHZvaWQgdGhpcy5yZW1vdmVBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwpO1xuICAgIHZhbHVlMCA9IHRoaXMuZ2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgICByZXR1cm4gdmFsdWUwID09PSB2YWx1ZTEgPyBudWxsXG4gICAgICAgIDogdmFsdWUwID09PSB2YWx1ZTAwICYmIHZhbHVlMSA9PT0gdmFsdWUxMCA/IGludGVycG9sYXRlMFxuICAgICAgICA6IGludGVycG9sYXRlMCA9IGludGVycG9sYXRlJCQxKHZhbHVlMDAgPSB2YWx1ZTAsIHZhbHVlMTAgPSB2YWx1ZTEpO1xuICB9O1xufVxuXG52YXIgdHJhbnNpdGlvbl9hdHRyID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgdmFyIGZ1bGxuYW1lID0gbmFtZXNwYWNlKG5hbWUpLCBpID0gZnVsbG5hbWUgPT09IFwidHJhbnNmb3JtXCIgPyBpbnRlcnBvbGF0ZVRyYW5zZm9ybVN2ZyA6IGludGVycG9sYXRlJCQxO1xuICByZXR1cm4gdGhpcy5hdHRyVHdlZW4obmFtZSwgdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gKGZ1bGxuYW1lLmxvY2FsID8gYXR0ckZ1bmN0aW9uTlMkMSA6IGF0dHJGdW5jdGlvbiQxKShmdWxsbmFtZSwgaSwgdHdlZW5WYWx1ZSh0aGlzLCBcImF0dHIuXCIgKyBuYW1lLCB2YWx1ZSkpXG4gICAgICA6IHZhbHVlID09IG51bGwgPyAoZnVsbG5hbWUubG9jYWwgPyBhdHRyUmVtb3ZlTlMkMSA6IGF0dHJSZW1vdmUkMSkoZnVsbG5hbWUpXG4gICAgICA6IChmdWxsbmFtZS5sb2NhbCA/IGF0dHJDb25zdGFudE5TJDEgOiBhdHRyQ29uc3RhbnQkMSkoZnVsbG5hbWUsIGksIHZhbHVlICsgXCJcIikpO1xufTtcblxuZnVuY3Rpb24gYXR0clR3ZWVuTlMoZnVsbG5hbWUsIHZhbHVlKSB7XG4gIGZ1bmN0aW9uIHR3ZWVuKCkge1xuICAgIHZhciBub2RlID0gdGhpcywgaSA9IHZhbHVlLmFwcGx5KG5vZGUsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGkgJiYgZnVuY3Rpb24odCkge1xuICAgICAgbm9kZS5zZXRBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwsIGkodCkpO1xuICAgIH07XG4gIH1cbiAgdHdlZW4uX3ZhbHVlID0gdmFsdWU7XG4gIHJldHVybiB0d2Vlbjtcbn1cblxuZnVuY3Rpb24gYXR0clR3ZWVuKG5hbWUsIHZhbHVlKSB7XG4gIGZ1bmN0aW9uIHR3ZWVuKCkge1xuICAgIHZhciBub2RlID0gdGhpcywgaSA9IHZhbHVlLmFwcGx5KG5vZGUsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGkgJiYgZnVuY3Rpb24odCkge1xuICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUobmFtZSwgaSh0KSk7XG4gICAgfTtcbiAgfVxuICB0d2Vlbi5fdmFsdWUgPSB2YWx1ZTtcbiAgcmV0dXJuIHR3ZWVuO1xufVxuXG52YXIgdHJhbnNpdGlvbl9hdHRyVHdlZW4gPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICB2YXIga2V5ID0gXCJhdHRyLlwiICsgbmFtZTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSByZXR1cm4gKGtleSA9IHRoaXMudHdlZW4oa2V5KSkgJiYga2V5Ll92YWx1ZTtcbiAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiB0aGlzLnR3ZWVuKGtleSwgbnVsbCk7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yO1xuICB2YXIgZnVsbG5hbWUgPSBuYW1lc3BhY2UobmFtZSk7XG4gIHJldHVybiB0aGlzLnR3ZWVuKGtleSwgKGZ1bGxuYW1lLmxvY2FsID8gYXR0clR3ZWVuTlMgOiBhdHRyVHdlZW4pKGZ1bGxuYW1lLCB2YWx1ZSkpO1xufTtcblxuZnVuY3Rpb24gZGVsYXlGdW5jdGlvbihpZCwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIGluaXQodGhpcywgaWQpLmRlbGF5ID0gK3ZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGRlbGF5Q29uc3RhbnQoaWQsIHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9ICt2YWx1ZSwgZnVuY3Rpb24oKSB7XG4gICAgaW5pdCh0aGlzLCBpZCkuZGVsYXkgPSB2YWx1ZTtcbiAgfTtcbn1cblxudmFyIHRyYW5zaXRpb25fZGVsYXkgPSBmdW5jdGlvbih2YWx1ZSkge1xuICB2YXIgaWQgPSB0aGlzLl9pZDtcblxuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgPyB0aGlzLmVhY2goKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgPyBkZWxheUZ1bmN0aW9uXG4gICAgICAgICAgOiBkZWxheUNvbnN0YW50KShpZCwgdmFsdWUpKVxuICAgICAgOiBnZXQkMSh0aGlzLm5vZGUoKSwgaWQpLmRlbGF5O1xufTtcblxuZnVuY3Rpb24gZHVyYXRpb25GdW5jdGlvbihpZCwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHNldCQxKHRoaXMsIGlkKS5kdXJhdGlvbiA9ICt2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBkdXJhdGlvbkNvbnN0YW50KGlkLCB2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPSArdmFsdWUsIGZ1bmN0aW9uKCkge1xuICAgIHNldCQxKHRoaXMsIGlkKS5kdXJhdGlvbiA9IHZhbHVlO1xuICB9O1xufVxuXG52YXIgdHJhbnNpdGlvbl9kdXJhdGlvbiA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHZhciBpZCA9IHRoaXMuX2lkO1xuXG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoXG4gICAgICA/IHRoaXMuZWFjaCgodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IGR1cmF0aW9uRnVuY3Rpb25cbiAgICAgICAgICA6IGR1cmF0aW9uQ29uc3RhbnQpKGlkLCB2YWx1ZSkpXG4gICAgICA6IGdldCQxKHRoaXMubm9kZSgpLCBpZCkuZHVyYXRpb247XG59O1xuXG5mdW5jdGlvbiBlYXNlQ29uc3RhbnQoaWQsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgc2V0JDEodGhpcywgaWQpLmVhc2UgPSB2YWx1ZTtcbiAgfTtcbn1cblxudmFyIHRyYW5zaXRpb25fZWFzZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHZhciBpZCA9IHRoaXMuX2lkO1xuXG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoXG4gICAgICA/IHRoaXMuZWFjaChlYXNlQ29uc3RhbnQoaWQsIHZhbHVlKSlcbiAgICAgIDogZ2V0JDEodGhpcy5ub2RlKCksIGlkKS5lYXNlO1xufTtcblxudmFyIHRyYW5zaXRpb25fZmlsdGVyID0gZnVuY3Rpb24obWF0Y2gpIHtcbiAgaWYgKHR5cGVvZiBtYXRjaCAhPT0gXCJmdW5jdGlvblwiKSBtYXRjaCA9IG1hdGNoZXIkMShtYXRjaCk7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzdWJncm91cCA9IHN1Ymdyb3Vwc1tqXSA9IFtdLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKChub2RlID0gZ3JvdXBbaV0pICYmIG1hdGNoLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgZ3JvdXApKSB7XG4gICAgICAgIHN1Ymdyb3VwLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKHN1Ymdyb3VwcywgdGhpcy5fcGFyZW50cywgdGhpcy5fbmFtZSwgdGhpcy5faWQpO1xufTtcblxudmFyIHRyYW5zaXRpb25fbWVyZ2UgPSBmdW5jdGlvbih0cmFuc2l0aW9uKSB7XG4gIGlmICh0cmFuc2l0aW9uLl9pZCAhPT0gdGhpcy5faWQpIHRocm93IG5ldyBFcnJvcjtcblxuICBmb3IgKHZhciBncm91cHMwID0gdGhpcy5fZ3JvdXBzLCBncm91cHMxID0gdHJhbnNpdGlvbi5fZ3JvdXBzLCBtMCA9IGdyb3VwczAubGVuZ3RoLCBtMSA9IGdyb3VwczEubGVuZ3RoLCBtID0gTWF0aC5taW4obTAsIG0xKSwgbWVyZ2VzID0gbmV3IEFycmF5KG0wKSwgaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHZhciBncm91cDAgPSBncm91cHMwW2pdLCBncm91cDEgPSBncm91cHMxW2pdLCBuID0gZ3JvdXAwLmxlbmd0aCwgbWVyZ2UgPSBtZXJnZXNbal0gPSBuZXcgQXJyYXkobiksIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwMFtpXSB8fCBncm91cDFbaV0pIHtcbiAgICAgICAgbWVyZ2VbaV0gPSBub2RlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBqIDwgbTA7ICsraikge1xuICAgIG1lcmdlc1tqXSA9IGdyb3VwczBbal07XG4gIH1cblxuICByZXR1cm4gbmV3IFRyYW5zaXRpb24obWVyZ2VzLCB0aGlzLl9wYXJlbnRzLCB0aGlzLl9uYW1lLCB0aGlzLl9pZCk7XG59O1xuXG5mdW5jdGlvbiBzdGFydChuYW1lKSB7XG4gIHJldHVybiAobmFtZSArIFwiXCIpLnRyaW0oKS5zcGxpdCgvXnxcXHMrLykuZXZlcnkoZnVuY3Rpb24odCkge1xuICAgIHZhciBpID0gdC5pbmRleE9mKFwiLlwiKTtcbiAgICBpZiAoaSA+PSAwKSB0ID0gdC5zbGljZSgwLCBpKTtcbiAgICByZXR1cm4gIXQgfHwgdCA9PT0gXCJzdGFydFwiO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gb25GdW5jdGlvbihpZCwgbmFtZSwgbGlzdGVuZXIpIHtcbiAgdmFyIG9uMCwgb24xLCBzaXQgPSBzdGFydChuYW1lKSA/IGluaXQgOiBzZXQkMTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBzY2hlZHVsZSA9IHNpdCh0aGlzLCBpZCksXG4gICAgICAgIG9uID0gc2NoZWR1bGUub247XG5cbiAgICAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIGEgZGlzcGF0Y2ggd2l0aCB0aGUgcHJldmlvdXMgbm9kZSxcbiAgICAvLyBqdXN0IGFzc2lnbiB0aGUgdXBkYXRlZCBzaGFyZWQgZGlzcGF0Y2ggYW5kIHdl4oCZcmUgZG9uZSFcbiAgICAvLyBPdGhlcndpc2UsIGNvcHktb24td3JpdGUuXG4gICAgaWYgKG9uICE9PSBvbjApIChvbjEgPSAob24wID0gb24pLmNvcHkoKSkub24obmFtZSwgbGlzdGVuZXIpO1xuXG4gICAgc2NoZWR1bGUub24gPSBvbjE7XG4gIH07XG59XG5cbnZhciB0cmFuc2l0aW9uX29uID0gZnVuY3Rpb24obmFtZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGlkID0gdGhpcy5faWQ7XG5cbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPCAyXG4gICAgICA/IGdldCQxKHRoaXMubm9kZSgpLCBpZCkub24ub24obmFtZSlcbiAgICAgIDogdGhpcy5lYWNoKG9uRnVuY3Rpb24oaWQsIG5hbWUsIGxpc3RlbmVyKSk7XG59O1xuXG5mdW5jdGlvbiByZW1vdmVGdW5jdGlvbihpZCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50Tm9kZTtcbiAgICBmb3IgKHZhciBpIGluIHRoaXMuX190cmFuc2l0aW9uKSBpZiAoK2kgIT09IGlkKSByZXR1cm47XG4gICAgaWYgKHBhcmVudCkgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMpO1xuICB9O1xufVxuXG52YXIgdHJhbnNpdGlvbl9yZW1vdmUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMub24oXCJlbmQucmVtb3ZlXCIsIHJlbW92ZUZ1bmN0aW9uKHRoaXMuX2lkKSk7XG59O1xuXG52YXIgdHJhbnNpdGlvbl9zZWxlY3QgPSBmdW5jdGlvbihzZWxlY3QkJDEpIHtcbiAgdmFyIG5hbWUgPSB0aGlzLl9uYW1lLFxuICAgICAgaWQgPSB0aGlzLl9pZDtcblxuICBpZiAodHlwZW9mIHNlbGVjdCQkMSAhPT0gXCJmdW5jdGlvblwiKSBzZWxlY3QkJDEgPSBzZWxlY3RvcihzZWxlY3QkJDEpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHN1Ymdyb3VwcyA9IG5ldyBBcnJheShtKSwgaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgc3ViZ3JvdXAgPSBzdWJncm91cHNbal0gPSBuZXcgQXJyYXkobiksIG5vZGUsIHN1Ym5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKG5vZGUgPSBncm91cFtpXSkgJiYgKHN1Ym5vZGUgPSBzZWxlY3QkJDEuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpKSB7XG4gICAgICAgIGlmIChcIl9fZGF0YV9fXCIgaW4gbm9kZSkgc3Vibm9kZS5fX2RhdGFfXyA9IG5vZGUuX19kYXRhX187XG4gICAgICAgIHN1Ymdyb3VwW2ldID0gc3Vibm9kZTtcbiAgICAgICAgc2NoZWR1bGUoc3ViZ3JvdXBbaV0sIG5hbWUsIGlkLCBpLCBzdWJncm91cCwgZ2V0JDEobm9kZSwgaWQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFRyYW5zaXRpb24oc3ViZ3JvdXBzLCB0aGlzLl9wYXJlbnRzLCBuYW1lLCBpZCk7XG59O1xuXG52YXIgdHJhbnNpdGlvbl9zZWxlY3RBbGwgPSBmdW5jdGlvbihzZWxlY3QkJDEpIHtcbiAgdmFyIG5hbWUgPSB0aGlzLl9uYW1lLFxuICAgICAgaWQgPSB0aGlzLl9pZDtcblxuICBpZiAodHlwZW9mIHNlbGVjdCQkMSAhPT0gXCJmdW5jdGlvblwiKSBzZWxlY3QkJDEgPSBzZWxlY3RvckFsbChzZWxlY3QkJDEpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHN1Ymdyb3VwcyA9IFtdLCBwYXJlbnRzID0gW10sIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgIGZvciAodmFyIGNoaWxkcmVuID0gc2VsZWN0JCQxLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgZ3JvdXApLCBjaGlsZCwgaW5oZXJpdCA9IGdldCQxKG5vZGUsIGlkKSwgayA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spIHtcbiAgICAgICAgICBpZiAoY2hpbGQgPSBjaGlsZHJlbltrXSkge1xuICAgICAgICAgICAgc2NoZWR1bGUoY2hpbGQsIG5hbWUsIGlkLCBrLCBjaGlsZHJlbiwgaW5oZXJpdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN1Ymdyb3Vwcy5wdXNoKGNoaWxkcmVuKTtcbiAgICAgICAgcGFyZW50cy5wdXNoKG5vZGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXcgVHJhbnNpdGlvbihzdWJncm91cHMsIHBhcmVudHMsIG5hbWUsIGlkKTtcbn07XG5cbnZhciBTZWxlY3Rpb24kMSA9IHNlbGVjdGlvbi5wcm90b3R5cGUuY29uc3RydWN0b3I7XG5cbnZhciB0cmFuc2l0aW9uX3NlbGVjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFNlbGVjdGlvbiQxKHRoaXMuX2dyb3VwcywgdGhpcy5fcGFyZW50cyk7XG59O1xuXG5mdW5jdGlvbiBzdHlsZVJlbW92ZSQxKG5hbWUsIGludGVycG9sYXRlJCQyKSB7XG4gIHZhciB2YWx1ZTAwLFxuICAgICAgdmFsdWUxMCxcbiAgICAgIGludGVycG9sYXRlMDtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBzdHlsZSA9IHdpbmRvdyh0aGlzKS5nZXRDb21wdXRlZFN0eWxlKHRoaXMsIG51bGwpLFxuICAgICAgICB2YWx1ZTAgPSBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKG5hbWUpLFxuICAgICAgICB2YWx1ZTEgPSAodGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKSwgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSk7XG4gICAgcmV0dXJuIHZhbHVlMCA9PT0gdmFsdWUxID8gbnVsbFxuICAgICAgICA6IHZhbHVlMCA9PT0gdmFsdWUwMCAmJiB2YWx1ZTEgPT09IHZhbHVlMTAgPyBpbnRlcnBvbGF0ZTBcbiAgICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZSQkMih2YWx1ZTAwID0gdmFsdWUwLCB2YWx1ZTEwID0gdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVSZW1vdmVFbmQobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVDb25zdGFudCQxKG5hbWUsIGludGVycG9sYXRlJCQyLCB2YWx1ZTEpIHtcbiAgdmFyIHZhbHVlMDAsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWUwID0gd2luZG93KHRoaXMpLmdldENvbXB1dGVkU3R5bGUodGhpcywgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKTtcbiAgICByZXR1cm4gdmFsdWUwID09PSB2YWx1ZTEgPyBudWxsXG4gICAgICAgIDogdmFsdWUwID09PSB2YWx1ZTAwID8gaW50ZXJwb2xhdGUwXG4gICAgICAgIDogaW50ZXJwb2xhdGUwID0gaW50ZXJwb2xhdGUkJDIodmFsdWUwMCA9IHZhbHVlMCwgdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVGdW5jdGlvbiQxKG5hbWUsIGludGVycG9sYXRlJCQyLCB2YWx1ZSkge1xuICB2YXIgdmFsdWUwMCxcbiAgICAgIHZhbHVlMTAsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc3R5bGUgPSB3aW5kb3codGhpcykuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLCBudWxsKSxcbiAgICAgICAgdmFsdWUwID0gc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSxcbiAgICAgICAgdmFsdWUxID0gdmFsdWUodGhpcyk7XG4gICAgaWYgKHZhbHVlMSA9PSBudWxsKSB2YWx1ZTEgPSAodGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKSwgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSk7XG4gICAgcmV0dXJuIHZhbHVlMCA9PT0gdmFsdWUxID8gbnVsbFxuICAgICAgICA6IHZhbHVlMCA9PT0gdmFsdWUwMCAmJiB2YWx1ZTEgPT09IHZhbHVlMTAgPyBpbnRlcnBvbGF0ZTBcbiAgICAgICAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZSQkMih2YWx1ZTAwID0gdmFsdWUwLCB2YWx1ZTEwID0gdmFsdWUxKTtcbiAgfTtcbn1cblxudmFyIHRyYW5zaXRpb25fc3R5bGUgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpIHtcbiAgdmFyIGkgPSAobmFtZSArPSBcIlwiKSA9PT0gXCJ0cmFuc2Zvcm1cIiA/IGludGVycG9sYXRlVHJhbnNmb3JtQ3NzIDogaW50ZXJwb2xhdGUkJDE7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gdGhpc1xuICAgICAgICAgIC5zdHlsZVR3ZWVuKG5hbWUsIHN0eWxlUmVtb3ZlJDEobmFtZSwgaSkpXG4gICAgICAgICAgLm9uKFwiZW5kLnN0eWxlLlwiICsgbmFtZSwgc3R5bGVSZW1vdmVFbmQobmFtZSkpXG4gICAgICA6IHRoaXMuc3R5bGVUd2VlbihuYW1lLCB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgID8gc3R5bGVGdW5jdGlvbiQxKG5hbWUsIGksIHR3ZWVuVmFsdWUodGhpcywgXCJzdHlsZS5cIiArIG5hbWUsIHZhbHVlKSlcbiAgICAgICAgICA6IHN0eWxlQ29uc3RhbnQkMShuYW1lLCBpLCB2YWx1ZSArIFwiXCIpLCBwcmlvcml0eSk7XG59O1xuXG5mdW5jdGlvbiBzdHlsZVR3ZWVuKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICBmdW5jdGlvbiB0d2VlbigpIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMsIGkgPSB2YWx1ZS5hcHBseShub2RlLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiBpICYmIGZ1bmN0aW9uKHQpIHtcbiAgICAgIG5vZGUuc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgaSh0KSwgcHJpb3JpdHkpO1xuICAgIH07XG4gIH1cbiAgdHdlZW4uX3ZhbHVlID0gdmFsdWU7XG4gIHJldHVybiB0d2Vlbjtcbn1cblxudmFyIHRyYW5zaXRpb25fc3R5bGVUd2VlbiA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICB2YXIga2V5ID0gXCJzdHlsZS5cIiArIChuYW1lICs9IFwiXCIpO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHJldHVybiAoa2V5ID0gdGhpcy50d2VlbihrZXkpKSAmJiBrZXkuX3ZhbHVlO1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIHRoaXMudHdlZW4oa2V5LCBudWxsKTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3I7XG4gIHJldHVybiB0aGlzLnR3ZWVuKGtleSwgc3R5bGVUd2VlbihuYW1lLCB2YWx1ZSwgcHJpb3JpdHkgPT0gbnVsbCA/IFwiXCIgOiBwcmlvcml0eSkpO1xufTtcblxuZnVuY3Rpb24gdGV4dENvbnN0YW50JDEodmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMudGV4dENvbnRlbnQgPSB2YWx1ZTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gdGV4dEZ1bmN0aW9uJDEodmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2YWx1ZTEgPSB2YWx1ZSh0aGlzKTtcbiAgICB0aGlzLnRleHRDb250ZW50ID0gdmFsdWUxID09IG51bGwgPyBcIlwiIDogdmFsdWUxO1xuICB9O1xufVxuXG52YXIgdHJhbnNpdGlvbl90ZXh0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMudHdlZW4oXCJ0ZXh0XCIsIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICA/IHRleHRGdW5jdGlvbiQxKHR3ZWVuVmFsdWUodGhpcywgXCJ0ZXh0XCIsIHZhbHVlKSlcbiAgICAgIDogdGV4dENvbnN0YW50JDEodmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSArIFwiXCIpKTtcbn07XG5cbnZhciB0cmFuc2l0aW9uX3RyYW5zaXRpb24gPSBmdW5jdGlvbigpIHtcbiAgdmFyIG5hbWUgPSB0aGlzLl9uYW1lLFxuICAgICAgaWQwID0gdGhpcy5faWQsXG4gICAgICBpZDEgPSBuZXdJZCgpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgIHZhciBpbmhlcml0ID0gZ2V0JDEobm9kZSwgaWQwKTtcbiAgICAgICAgc2NoZWR1bGUobm9kZSwgbmFtZSwgaWQxLCBpLCBncm91cCwge1xuICAgICAgICAgIHRpbWU6IGluaGVyaXQudGltZSArIGluaGVyaXQuZGVsYXkgKyBpbmhlcml0LmR1cmF0aW9uLFxuICAgICAgICAgIGRlbGF5OiAwLFxuICAgICAgICAgIGR1cmF0aW9uOiBpbmhlcml0LmR1cmF0aW9uLFxuICAgICAgICAgIGVhc2U6IGluaGVyaXQuZWFzZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFRyYW5zaXRpb24oZ3JvdXBzLCB0aGlzLl9wYXJlbnRzLCBuYW1lLCBpZDEpO1xufTtcblxudmFyIGlkID0gMDtcblxuZnVuY3Rpb24gVHJhbnNpdGlvbihncm91cHMsIHBhcmVudHMsIG5hbWUsIGlkKSB7XG4gIHRoaXMuX2dyb3VwcyA9IGdyb3VwcztcbiAgdGhpcy5fcGFyZW50cyA9IHBhcmVudHM7XG4gIHRoaXMuX25hbWUgPSBuYW1lO1xuICB0aGlzLl9pZCA9IGlkO1xufVxuXG5mdW5jdGlvbiB0cmFuc2l0aW9uKG5hbWUpIHtcbiAgcmV0dXJuIHNlbGVjdGlvbigpLnRyYW5zaXRpb24obmFtZSk7XG59XG5cbmZ1bmN0aW9uIG5ld0lkKCkge1xuICByZXR1cm4gKytpZDtcbn1cblxudmFyIHNlbGVjdGlvbl9wcm90b3R5cGUgPSBzZWxlY3Rpb24ucHJvdG90eXBlO1xuXG5UcmFuc2l0aW9uLnByb3RvdHlwZSA9IHRyYW5zaXRpb24ucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogVHJhbnNpdGlvbixcbiAgc2VsZWN0OiB0cmFuc2l0aW9uX3NlbGVjdCxcbiAgc2VsZWN0QWxsOiB0cmFuc2l0aW9uX3NlbGVjdEFsbCxcbiAgZmlsdGVyOiB0cmFuc2l0aW9uX2ZpbHRlcixcbiAgbWVyZ2U6IHRyYW5zaXRpb25fbWVyZ2UsXG4gIHNlbGVjdGlvbjogdHJhbnNpdGlvbl9zZWxlY3Rpb24sXG4gIHRyYW5zaXRpb246IHRyYW5zaXRpb25fdHJhbnNpdGlvbixcbiAgY2FsbDogc2VsZWN0aW9uX3Byb3RvdHlwZS5jYWxsLFxuICBub2Rlczogc2VsZWN0aW9uX3Byb3RvdHlwZS5ub2RlcyxcbiAgbm9kZTogc2VsZWN0aW9uX3Byb3RvdHlwZS5ub2RlLFxuICBzaXplOiBzZWxlY3Rpb25fcHJvdG90eXBlLnNpemUsXG4gIGVtcHR5OiBzZWxlY3Rpb25fcHJvdG90eXBlLmVtcHR5LFxuICBlYWNoOiBzZWxlY3Rpb25fcHJvdG90eXBlLmVhY2gsXG4gIG9uOiB0cmFuc2l0aW9uX29uLFxuICBhdHRyOiB0cmFuc2l0aW9uX2F0dHIsXG4gIGF0dHJUd2VlbjogdHJhbnNpdGlvbl9hdHRyVHdlZW4sXG4gIHN0eWxlOiB0cmFuc2l0aW9uX3N0eWxlLFxuICBzdHlsZVR3ZWVuOiB0cmFuc2l0aW9uX3N0eWxlVHdlZW4sXG4gIHRleHQ6IHRyYW5zaXRpb25fdGV4dCxcbiAgcmVtb3ZlOiB0cmFuc2l0aW9uX3JlbW92ZSxcbiAgdHdlZW46IHRyYW5zaXRpb25fdHdlZW4sXG4gIGRlbGF5OiB0cmFuc2l0aW9uX2RlbGF5LFxuICBkdXJhdGlvbjogdHJhbnNpdGlvbl9kdXJhdGlvbixcbiAgZWFzZTogdHJhbnNpdGlvbl9lYXNlXG59O1xuXG5mdW5jdGlvbiBsaW5lYXIkMSh0KSB7XG4gIHJldHVybiArdDtcbn1cblxuZnVuY3Rpb24gcXVhZEluKHQpIHtcbiAgcmV0dXJuIHQgKiB0O1xufVxuXG5mdW5jdGlvbiBxdWFkT3V0KHQpIHtcbiAgcmV0dXJuIHQgKiAoMiAtIHQpO1xufVxuXG5mdW5jdGlvbiBxdWFkSW5PdXQodCkge1xuICByZXR1cm4gKCh0ICo9IDIpIDw9IDEgPyB0ICogdCA6IC0tdCAqICgyIC0gdCkgKyAxKSAvIDI7XG59XG5cbmZ1bmN0aW9uIGN1YmljSW4odCkge1xuICByZXR1cm4gdCAqIHQgKiB0O1xufVxuXG5mdW5jdGlvbiBjdWJpY091dCh0KSB7XG4gIHJldHVybiAtLXQgKiB0ICogdCArIDE7XG59XG5cbmZ1bmN0aW9uIGN1YmljSW5PdXQodCkge1xuICByZXR1cm4gKCh0ICo9IDIpIDw9IDEgPyB0ICogdCAqIHQgOiAodCAtPSAyKSAqIHQgKiB0ICsgMikgLyAyO1xufVxuXG52YXIgZXhwb25lbnQgPSAzO1xuXG52YXIgcG9seUluID0gKGZ1bmN0aW9uIGN1c3RvbShlKSB7XG4gIGUgPSArZTtcblxuICBmdW5jdGlvbiBwb2x5SW4odCkge1xuICAgIHJldHVybiBNYXRoLnBvdyh0LCBlKTtcbiAgfVxuXG4gIHBvbHlJbi5leHBvbmVudCA9IGN1c3RvbTtcblxuICByZXR1cm4gcG9seUluO1xufSkoZXhwb25lbnQpO1xuXG52YXIgcG9seU91dCA9IChmdW5jdGlvbiBjdXN0b20oZSkge1xuICBlID0gK2U7XG5cbiAgZnVuY3Rpb24gcG9seU91dCh0KSB7XG4gICAgcmV0dXJuIDEgLSBNYXRoLnBvdygxIC0gdCwgZSk7XG4gIH1cblxuICBwb2x5T3V0LmV4cG9uZW50ID0gY3VzdG9tO1xuXG4gIHJldHVybiBwb2x5T3V0O1xufSkoZXhwb25lbnQpO1xuXG52YXIgcG9seUluT3V0ID0gKGZ1bmN0aW9uIGN1c3RvbShlKSB7XG4gIGUgPSArZTtcblxuICBmdW5jdGlvbiBwb2x5SW5PdXQodCkge1xuICAgIHJldHVybiAoKHQgKj0gMikgPD0gMSA/IE1hdGgucG93KHQsIGUpIDogMiAtIE1hdGgucG93KDIgLSB0LCBlKSkgLyAyO1xuICB9XG5cbiAgcG9seUluT3V0LmV4cG9uZW50ID0gY3VzdG9tO1xuXG4gIHJldHVybiBwb2x5SW5PdXQ7XG59KShleHBvbmVudCk7XG5cbnZhciBwaSA9IE1hdGguUEk7XG52YXIgaGFsZlBpID0gcGkgLyAyO1xuXG5mdW5jdGlvbiBzaW5Jbih0KSB7XG4gIHJldHVybiAxIC0gTWF0aC5jb3ModCAqIGhhbGZQaSk7XG59XG5cbmZ1bmN0aW9uIHNpbk91dCh0KSB7XG4gIHJldHVybiBNYXRoLnNpbih0ICogaGFsZlBpKTtcbn1cblxuZnVuY3Rpb24gc2luSW5PdXQodCkge1xuICByZXR1cm4gKDEgLSBNYXRoLmNvcyhwaSAqIHQpKSAvIDI7XG59XG5cbmZ1bmN0aW9uIGV4cEluKHQpIHtcbiAgcmV0dXJuIE1hdGgucG93KDIsIDEwICogdCAtIDEwKTtcbn1cblxuZnVuY3Rpb24gZXhwT3V0KHQpIHtcbiAgcmV0dXJuIDEgLSBNYXRoLnBvdygyLCAtMTAgKiB0KTtcbn1cblxuZnVuY3Rpb24gZXhwSW5PdXQodCkge1xuICByZXR1cm4gKCh0ICo9IDIpIDw9IDEgPyBNYXRoLnBvdygyLCAxMCAqIHQgLSAxMCkgOiAyIC0gTWF0aC5wb3coMiwgMTAgLSAxMCAqIHQpKSAvIDI7XG59XG5cbmZ1bmN0aW9uIGNpcmNsZUluKHQpIHtcbiAgcmV0dXJuIDEgLSBNYXRoLnNxcnQoMSAtIHQgKiB0KTtcbn1cblxuZnVuY3Rpb24gY2lyY2xlT3V0KHQpIHtcbiAgcmV0dXJuIE1hdGguc3FydCgxIC0gLS10ICogdCk7XG59XG5cbmZ1bmN0aW9uIGNpcmNsZUluT3V0KHQpIHtcbiAgcmV0dXJuICgodCAqPSAyKSA8PSAxID8gMSAtIE1hdGguc3FydCgxIC0gdCAqIHQpIDogTWF0aC5zcXJ0KDEgLSAodCAtPSAyKSAqIHQpICsgMSkgLyAyO1xufVxuXG52YXIgYjEgPSA0IC8gMTE7XG52YXIgYjIgPSA2IC8gMTE7XG52YXIgYjMgPSA4IC8gMTE7XG52YXIgYjQgPSAzIC8gNDtcbnZhciBiNSA9IDkgLyAxMTtcbnZhciBiNiA9IDEwIC8gMTE7XG52YXIgYjcgPSAxNSAvIDE2O1xudmFyIGI4ID0gMjEgLyAyMjtcbnZhciBiOSA9IDYzIC8gNjQ7XG52YXIgYjAgPSAxIC8gYjEgLyBiMTtcblxuZnVuY3Rpb24gYm91bmNlSW4odCkge1xuICByZXR1cm4gMSAtIGJvdW5jZU91dCgxIC0gdCk7XG59XG5cbmZ1bmN0aW9uIGJvdW5jZU91dCh0KSB7XG4gIHJldHVybiAodCA9ICt0KSA8IGIxID8gYjAgKiB0ICogdCA6IHQgPCBiMyA/IGIwICogKHQgLT0gYjIpICogdCArIGI0IDogdCA8IGI2ID8gYjAgKiAodCAtPSBiNSkgKiB0ICsgYjcgOiBiMCAqICh0IC09IGI4KSAqIHQgKyBiOTtcbn1cblxuZnVuY3Rpb24gYm91bmNlSW5PdXQodCkge1xuICByZXR1cm4gKCh0ICo9IDIpIDw9IDEgPyAxIC0gYm91bmNlT3V0KDEgLSB0KSA6IGJvdW5jZU91dCh0IC0gMSkgKyAxKSAvIDI7XG59XG5cbnZhciBvdmVyc2hvb3QgPSAxLjcwMTU4O1xuXG52YXIgYmFja0luID0gKGZ1bmN0aW9uIGN1c3RvbShzKSB7XG4gIHMgPSArcztcblxuICBmdW5jdGlvbiBiYWNrSW4odCkge1xuICAgIHJldHVybiB0ICogdCAqICgocyArIDEpICogdCAtIHMpO1xuICB9XG5cbiAgYmFja0luLm92ZXJzaG9vdCA9IGN1c3RvbTtcblxuICByZXR1cm4gYmFja0luO1xufSkob3ZlcnNob290KTtcblxudmFyIGJhY2tPdXQgPSAoZnVuY3Rpb24gY3VzdG9tKHMpIHtcbiAgcyA9ICtzO1xuXG4gIGZ1bmN0aW9uIGJhY2tPdXQodCkge1xuICAgIHJldHVybiAtLXQgKiB0ICogKChzICsgMSkgKiB0ICsgcykgKyAxO1xuICB9XG5cbiAgYmFja091dC5vdmVyc2hvb3QgPSBjdXN0b207XG5cbiAgcmV0dXJuIGJhY2tPdXQ7XG59KShvdmVyc2hvb3QpO1xuXG52YXIgYmFja0luT3V0ID0gKGZ1bmN0aW9uIGN1c3RvbShzKSB7XG4gIHMgPSArcztcblxuICBmdW5jdGlvbiBiYWNrSW5PdXQodCkge1xuICAgIHJldHVybiAoKHQgKj0gMikgPCAxID8gdCAqIHQgKiAoKHMgKyAxKSAqIHQgLSBzKSA6ICh0IC09IDIpICogdCAqICgocyArIDEpICogdCArIHMpICsgMikgLyAyO1xuICB9XG5cbiAgYmFja0luT3V0Lm92ZXJzaG9vdCA9IGN1c3RvbTtcblxuICByZXR1cm4gYmFja0luT3V0O1xufSkob3ZlcnNob290KTtcblxudmFyIHRhdSA9IDIgKiBNYXRoLlBJO1xudmFyIGFtcGxpdHVkZSA9IDE7XG52YXIgcGVyaW9kID0gMC4zO1xuXG52YXIgZWxhc3RpY0luID0gKGZ1bmN0aW9uIGN1c3RvbShhLCBwKSB7XG4gIHZhciBzID0gTWF0aC5hc2luKDEgLyAoYSA9IE1hdGgubWF4KDEsIGEpKSkgKiAocCAvPSB0YXUpO1xuXG4gIGZ1bmN0aW9uIGVsYXN0aWNJbih0KSB7XG4gICAgcmV0dXJuIGEgKiBNYXRoLnBvdygyLCAxMCAqIC0tdCkgKiBNYXRoLnNpbigocyAtIHQpIC8gcCk7XG4gIH1cblxuICBlbGFzdGljSW4uYW1wbGl0dWRlID0gZnVuY3Rpb24oYSkgeyByZXR1cm4gY3VzdG9tKGEsIHAgKiB0YXUpOyB9O1xuICBlbGFzdGljSW4ucGVyaW9kID0gZnVuY3Rpb24ocCkgeyByZXR1cm4gY3VzdG9tKGEsIHApOyB9O1xuXG4gIHJldHVybiBlbGFzdGljSW47XG59KShhbXBsaXR1ZGUsIHBlcmlvZCk7XG5cbnZhciBlbGFzdGljT3V0ID0gKGZ1bmN0aW9uIGN1c3RvbShhLCBwKSB7XG4gIHZhciBzID0gTWF0aC5hc2luKDEgLyAoYSA9IE1hdGgubWF4KDEsIGEpKSkgKiAocCAvPSB0YXUpO1xuXG4gIGZ1bmN0aW9uIGVsYXN0aWNPdXQodCkge1xuICAgIHJldHVybiAxIC0gYSAqIE1hdGgucG93KDIsIC0xMCAqICh0ID0gK3QpKSAqIE1hdGguc2luKCh0ICsgcykgLyBwKTtcbiAgfVxuXG4gIGVsYXN0aWNPdXQuYW1wbGl0dWRlID0gZnVuY3Rpb24oYSkgeyByZXR1cm4gY3VzdG9tKGEsIHAgKiB0YXUpOyB9O1xuICBlbGFzdGljT3V0LnBlcmlvZCA9IGZ1bmN0aW9uKHApIHsgcmV0dXJuIGN1c3RvbShhLCBwKTsgfTtcblxuICByZXR1cm4gZWxhc3RpY091dDtcbn0pKGFtcGxpdHVkZSwgcGVyaW9kKTtcblxudmFyIGVsYXN0aWNJbk91dCA9IChmdW5jdGlvbiBjdXN0b20oYSwgcCkge1xuICB2YXIgcyA9IE1hdGguYXNpbigxIC8gKGEgPSBNYXRoLm1heCgxLCBhKSkpICogKHAgLz0gdGF1KTtcblxuICBmdW5jdGlvbiBlbGFzdGljSW5PdXQodCkge1xuICAgIHJldHVybiAoKHQgPSB0ICogMiAtIDEpIDwgMFxuICAgICAgICA/IGEgKiBNYXRoLnBvdygyLCAxMCAqIHQpICogTWF0aC5zaW4oKHMgLSB0KSAvIHApXG4gICAgICAgIDogMiAtIGEgKiBNYXRoLnBvdygyLCAtMTAgKiB0KSAqIE1hdGguc2luKChzICsgdCkgLyBwKSkgLyAyO1xuICB9XG5cbiAgZWxhc3RpY0luT3V0LmFtcGxpdHVkZSA9IGZ1bmN0aW9uKGEpIHsgcmV0dXJuIGN1c3RvbShhLCBwICogdGF1KTsgfTtcbiAgZWxhc3RpY0luT3V0LnBlcmlvZCA9IGZ1bmN0aW9uKHApIHsgcmV0dXJuIGN1c3RvbShhLCBwKTsgfTtcblxuICByZXR1cm4gZWxhc3RpY0luT3V0O1xufSkoYW1wbGl0dWRlLCBwZXJpb2QpO1xuXG52YXIgZGVmYXVsdFRpbWluZyA9IHtcbiAgdGltZTogbnVsbCwgLy8gU2V0IG9uIHVzZS5cbiAgZGVsYXk6IDAsXG4gIGR1cmF0aW9uOiAyNTAsXG4gIGVhc2U6IGN1YmljSW5PdXRcbn07XG5cbmZ1bmN0aW9uIGluaGVyaXQobm9kZSwgaWQpIHtcbiAgdmFyIHRpbWluZztcbiAgd2hpbGUgKCEodGltaW5nID0gbm9kZS5fX3RyYW5zaXRpb24pIHx8ICEodGltaW5nID0gdGltaW5nW2lkXSkpIHtcbiAgICBpZiAoIShub2RlID0gbm9kZS5wYXJlbnROb2RlKSkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRUaW1pbmcudGltZSA9IG5vdygpLCBkZWZhdWx0VGltaW5nO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGltaW5nO1xufVxuXG52YXIgc2VsZWN0aW9uX3RyYW5zaXRpb24gPSBmdW5jdGlvbihuYW1lKSB7XG4gIHZhciBpZCxcbiAgICAgIHRpbWluZztcblxuICBpZiAobmFtZSBpbnN0YW5jZW9mIFRyYW5zaXRpb24pIHtcbiAgICBpZCA9IG5hbWUuX2lkLCBuYW1lID0gbmFtZS5fbmFtZTtcbiAgfSBlbHNlIHtcbiAgICBpZCA9IG5ld0lkKCksICh0aW1pbmcgPSBkZWZhdWx0VGltaW5nKS50aW1lID0gbm93KCksIG5hbWUgPSBuYW1lID09IG51bGwgPyBudWxsIDogbmFtZSArIFwiXCI7XG4gIH1cblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBzY2hlZHVsZShub2RlLCBuYW1lLCBpZCwgaSwgZ3JvdXAsIHRpbWluZyB8fCBpbmhlcml0KG5vZGUsIGlkKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKGdyb3VwcywgdGhpcy5fcGFyZW50cywgbmFtZSwgaWQpO1xufTtcblxuc2VsZWN0aW9uLnByb3RvdHlwZS5pbnRlcnJ1cHQgPSBzZWxlY3Rpb25faW50ZXJydXB0O1xuc2VsZWN0aW9uLnByb3RvdHlwZS50cmFuc2l0aW9uID0gc2VsZWN0aW9uX3RyYW5zaXRpb247XG5cbnZhciByb290JDEgPSBbbnVsbF07XG5cbnZhciBhY3RpdmUgPSBmdW5jdGlvbihub2RlLCBuYW1lKSB7XG4gIHZhciBzY2hlZHVsZXMgPSBub2RlLl9fdHJhbnNpdGlvbixcbiAgICAgIHNjaGVkdWxlLFxuICAgICAgaTtcblxuICBpZiAoc2NoZWR1bGVzKSB7XG4gICAgbmFtZSA9IG5hbWUgPT0gbnVsbCA/IG51bGwgOiBuYW1lICsgXCJcIjtcbiAgICBmb3IgKGkgaW4gc2NoZWR1bGVzKSB7XG4gICAgICBpZiAoKHNjaGVkdWxlID0gc2NoZWR1bGVzW2ldKS5zdGF0ZSA+IFNDSEVEVUxFRCAmJiBzY2hlZHVsZS5uYW1lID09PSBuYW1lKSB7XG4gICAgICAgIHJldHVybiBuZXcgVHJhbnNpdGlvbihbW25vZGVdXSwgcm9vdCQxLCBuYW1lLCAraSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG52YXIgY29uc3RhbnQkNCA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxudmFyIEJydXNoRXZlbnQgPSBmdW5jdGlvbih0YXJnZXQsIHR5cGUsIHNlbGVjdGlvbikge1xuICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5zZWxlY3Rpb24gPSBzZWxlY3Rpb247XG59O1xuXG5mdW5jdGlvbiBub3Byb3BhZ2F0aW9uJDEoKSB7XG4gIGV4cG9ydHMuZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG59XG5cbnZhciBub2V2ZW50JDEgPSBmdW5jdGlvbigpIHtcbiAgZXhwb3J0cy5ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICBleHBvcnRzLmV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xufTtcblxudmFyIE1PREVfRFJBRyA9IHtuYW1lOiBcImRyYWdcIn07XG52YXIgTU9ERV9TUEFDRSA9IHtuYW1lOiBcInNwYWNlXCJ9O1xudmFyIE1PREVfSEFORExFID0ge25hbWU6IFwiaGFuZGxlXCJ9O1xudmFyIE1PREVfQ0VOVEVSID0ge25hbWU6IFwiY2VudGVyXCJ9O1xuXG52YXIgWCA9IHtcbiAgbmFtZTogXCJ4XCIsXG4gIGhhbmRsZXM6IFtcImVcIiwgXCJ3XCJdLm1hcCh0eXBlKSxcbiAgaW5wdXQ6IGZ1bmN0aW9uKHgsIGUpIHsgcmV0dXJuIHggJiYgW1t4WzBdLCBlWzBdWzFdXSwgW3hbMV0sIGVbMV1bMV1dXTsgfSxcbiAgb3V0cHV0OiBmdW5jdGlvbih4eSkgeyByZXR1cm4geHkgJiYgW3h5WzBdWzBdLCB4eVsxXVswXV07IH1cbn07XG5cbnZhciBZID0ge1xuICBuYW1lOiBcInlcIixcbiAgaGFuZGxlczogW1wiblwiLCBcInNcIl0ubWFwKHR5cGUpLFxuICBpbnB1dDogZnVuY3Rpb24oeSwgZSkgeyByZXR1cm4geSAmJiBbW2VbMF1bMF0sIHlbMF1dLCBbZVsxXVswXSwgeVsxXV1dOyB9LFxuICBvdXRwdXQ6IGZ1bmN0aW9uKHh5KSB7IHJldHVybiB4eSAmJiBbeHlbMF1bMV0sIHh5WzFdWzFdXTsgfVxufTtcblxudmFyIFhZID0ge1xuICBuYW1lOiBcInh5XCIsXG4gIGhhbmRsZXM6IFtcIm5cIiwgXCJlXCIsIFwic1wiLCBcIndcIiwgXCJud1wiLCBcIm5lXCIsIFwic2VcIiwgXCJzd1wiXS5tYXAodHlwZSksXG4gIGlucHV0OiBmdW5jdGlvbih4eSkgeyByZXR1cm4geHk7IH0sXG4gIG91dHB1dDogZnVuY3Rpb24oeHkpIHsgcmV0dXJuIHh5OyB9XG59O1xuXG52YXIgY3Vyc29ycyA9IHtcbiAgb3ZlcmxheTogXCJjcm9zc2hhaXJcIixcbiAgc2VsZWN0aW9uOiBcIm1vdmVcIixcbiAgbjogXCJucy1yZXNpemVcIixcbiAgZTogXCJldy1yZXNpemVcIixcbiAgczogXCJucy1yZXNpemVcIixcbiAgdzogXCJldy1yZXNpemVcIixcbiAgbnc6IFwibndzZS1yZXNpemVcIixcbiAgbmU6IFwibmVzdy1yZXNpemVcIixcbiAgc2U6IFwibndzZS1yZXNpemVcIixcbiAgc3c6IFwibmVzdy1yZXNpemVcIlxufTtcblxudmFyIGZsaXBYID0ge1xuICBlOiBcIndcIixcbiAgdzogXCJlXCIsXG4gIG53OiBcIm5lXCIsXG4gIG5lOiBcIm53XCIsXG4gIHNlOiBcInN3XCIsXG4gIHN3OiBcInNlXCJcbn07XG5cbnZhciBmbGlwWSA9IHtcbiAgbjogXCJzXCIsXG4gIHM6IFwiblwiLFxuICBudzogXCJzd1wiLFxuICBuZTogXCJzZVwiLFxuICBzZTogXCJuZVwiLFxuICBzdzogXCJud1wiXG59O1xuXG52YXIgc2lnbnNYID0ge1xuICBvdmVybGF5OiArMSxcbiAgc2VsZWN0aW9uOiArMSxcbiAgbjogbnVsbCxcbiAgZTogKzEsXG4gIHM6IG51bGwsXG4gIHc6IC0xLFxuICBudzogLTEsXG4gIG5lOiArMSxcbiAgc2U6ICsxLFxuICBzdzogLTFcbn07XG5cbnZhciBzaWduc1kgPSB7XG4gIG92ZXJsYXk6ICsxLFxuICBzZWxlY3Rpb246ICsxLFxuICBuOiAtMSxcbiAgZTogbnVsbCxcbiAgczogKzEsXG4gIHc6IG51bGwsXG4gIG53OiAtMSxcbiAgbmU6IC0xLFxuICBzZTogKzEsXG4gIHN3OiArMVxufTtcblxuZnVuY3Rpb24gdHlwZSh0KSB7XG4gIHJldHVybiB7dHlwZTogdH07XG59XG5cbi8vIElnbm9yZSByaWdodC1jbGljaywgc2luY2UgdGhhdCBzaG91bGQgb3BlbiB0aGUgY29udGV4dCBtZW51LlxuZnVuY3Rpb24gZGVmYXVsdEZpbHRlcigpIHtcbiAgcmV0dXJuICFleHBvcnRzLmV2ZW50LmJ1dHRvbjtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdEV4dGVudCgpIHtcbiAgdmFyIHN2ZyA9IHRoaXMub3duZXJTVkdFbGVtZW50IHx8IHRoaXM7XG4gIHJldHVybiBbWzAsIDBdLCBbc3ZnLndpZHRoLmJhc2VWYWwudmFsdWUsIHN2Zy5oZWlnaHQuYmFzZVZhbC52YWx1ZV1dO1xufVxuXG4vLyBMaWtlIGQzLmxvY2FsLCBidXQgd2l0aCB0aGUgbmFtZSDigJxfX2JydXNo4oCdIHJhdGhlciB0aGFuIGF1dG8tZ2VuZXJhdGVkLlxuZnVuY3Rpb24gbG9jYWwkJDEobm9kZSkge1xuICB3aGlsZSAoIW5vZGUuX19icnVzaCkgaWYgKCEobm9kZSA9IG5vZGUucGFyZW50Tm9kZSkpIHJldHVybjtcbiAgcmV0dXJuIG5vZGUuX19icnVzaDtcbn1cblxuZnVuY3Rpb24gZW1wdHkoZXh0ZW50KSB7XG4gIHJldHVybiBleHRlbnRbMF1bMF0gPT09IGV4dGVudFsxXVswXVxuICAgICAgfHwgZXh0ZW50WzBdWzFdID09PSBleHRlbnRbMV1bMV07XG59XG5cbmZ1bmN0aW9uIGJydXNoU2VsZWN0aW9uKG5vZGUpIHtcbiAgdmFyIHN0YXRlID0gbm9kZS5fX2JydXNoO1xuICByZXR1cm4gc3RhdGUgPyBzdGF0ZS5kaW0ub3V0cHV0KHN0YXRlLnNlbGVjdGlvbikgOiBudWxsO1xufVxuXG5mdW5jdGlvbiBicnVzaFgoKSB7XG4gIHJldHVybiBicnVzaCQxKFgpO1xufVxuXG5mdW5jdGlvbiBicnVzaFkoKSB7XG4gIHJldHVybiBicnVzaCQxKFkpO1xufVxuXG52YXIgYnJ1c2ggPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGJydXNoJDEoWFkpO1xufTtcblxuZnVuY3Rpb24gYnJ1c2gkMShkaW0pIHtcbiAgdmFyIGV4dGVudCA9IGRlZmF1bHRFeHRlbnQsXG4gICAgICBmaWx0ZXIgPSBkZWZhdWx0RmlsdGVyLFxuICAgICAgbGlzdGVuZXJzID0gZGlzcGF0Y2goYnJ1c2gsIFwic3RhcnRcIiwgXCJicnVzaFwiLCBcImVuZFwiKSxcbiAgICAgIGhhbmRsZVNpemUgPSA2LFxuICAgICAgdG91Y2hlbmRpbmc7XG5cbiAgZnVuY3Rpb24gYnJ1c2goZ3JvdXApIHtcbiAgICB2YXIgb3ZlcmxheSA9IGdyb3VwXG4gICAgICAgIC5wcm9wZXJ0eShcIl9fYnJ1c2hcIiwgaW5pdGlhbGl6ZSlcbiAgICAgIC5zZWxlY3RBbGwoXCIub3ZlcmxheVwiKVxuICAgICAgLmRhdGEoW3R5cGUoXCJvdmVybGF5XCIpXSk7XG5cbiAgICBvdmVybGF5LmVudGVyKCkuYXBwZW5kKFwicmVjdFwiKVxuICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwib3ZlcmxheVwiKVxuICAgICAgICAuYXR0cihcInBvaW50ZXItZXZlbnRzXCIsIFwiYWxsXCIpXG4gICAgICAgIC5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnMub3ZlcmxheSlcbiAgICAgIC5tZXJnZShvdmVybGF5KVxuICAgICAgICAuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgZXh0ZW50ID0gbG9jYWwkJDEodGhpcykuZXh0ZW50O1xuICAgICAgICAgIHNlbGVjdCh0aGlzKVxuICAgICAgICAgICAgICAuYXR0cihcInhcIiwgZXh0ZW50WzBdWzBdKVxuICAgICAgICAgICAgICAuYXR0cihcInlcIiwgZXh0ZW50WzBdWzFdKVxuICAgICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGV4dGVudFsxXVswXSAtIGV4dGVudFswXVswXSlcbiAgICAgICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgZXh0ZW50WzFdWzFdIC0gZXh0ZW50WzBdWzFdKTtcbiAgICAgICAgfSk7XG5cbiAgICBncm91cC5zZWxlY3RBbGwoXCIuc2VsZWN0aW9uXCIpXG4gICAgICAuZGF0YShbdHlwZShcInNlbGVjdGlvblwiKV0pXG4gICAgICAuZW50ZXIoKS5hcHBlbmQoXCJyZWN0XCIpXG4gICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJzZWxlY3Rpb25cIilcbiAgICAgICAgLmF0dHIoXCJjdXJzb3JcIiwgY3Vyc29ycy5zZWxlY3Rpb24pXG4gICAgICAgIC5hdHRyKFwiZmlsbFwiLCBcIiM3NzdcIilcbiAgICAgICAgLmF0dHIoXCJmaWxsLW9wYWNpdHlcIiwgMC4zKVxuICAgICAgICAuYXR0cihcInN0cm9rZVwiLCBcIiNmZmZcIilcbiAgICAgICAgLmF0dHIoXCJzaGFwZS1yZW5kZXJpbmdcIiwgXCJjcmlzcEVkZ2VzXCIpO1xuXG4gICAgdmFyIGhhbmRsZSA9IGdyb3VwLnNlbGVjdEFsbChcIi5oYW5kbGVcIilcbiAgICAgIC5kYXRhKGRpbS5oYW5kbGVzLCBmdW5jdGlvbihkKSB7IHJldHVybiBkLnR5cGU7IH0pO1xuXG4gICAgaGFuZGxlLmV4aXQoKS5yZW1vdmUoKTtcblxuICAgIGhhbmRsZS5lbnRlcigpLmFwcGVuZChcInJlY3RcIilcbiAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBmdW5jdGlvbihkKSB7IHJldHVybiBcImhhbmRsZSBoYW5kbGUtLVwiICsgZC50eXBlOyB9KVxuICAgICAgICAuYXR0cihcImN1cnNvclwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBjdXJzb3JzW2QudHlwZV07IH0pO1xuXG4gICAgZ3JvdXBcbiAgICAgICAgLmVhY2gocmVkcmF3KVxuICAgICAgICAuYXR0cihcImZpbGxcIiwgXCJub25lXCIpXG4gICAgICAgIC5hdHRyKFwicG9pbnRlci1ldmVudHNcIiwgXCJhbGxcIilcbiAgICAgICAgLnN0eWxlKFwiLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yXCIsIFwicmdiYSgwLDAsMCwwKVwiKVxuICAgICAgICAub24oXCJtb3VzZWRvd24uYnJ1c2ggdG91Y2hzdGFydC5icnVzaFwiLCBzdGFydGVkKTtcbiAgfVxuXG4gIGJydXNoLm1vdmUgPSBmdW5jdGlvbihncm91cCwgc2VsZWN0aW9uJCQxKSB7XG4gICAgaWYgKGdyb3VwLnNlbGVjdGlvbikge1xuICAgICAgZ3JvdXBcbiAgICAgICAgICAub24oXCJzdGFydC5icnVzaFwiLCBmdW5jdGlvbigpIHsgZW1pdHRlcih0aGlzLCBhcmd1bWVudHMpLmJlZm9yZXN0YXJ0KCkuc3RhcnQoKTsgfSlcbiAgICAgICAgICAub24oXCJpbnRlcnJ1cHQuYnJ1c2ggZW5kLmJydXNoXCIsIGZ1bmN0aW9uKCkgeyBlbWl0dGVyKHRoaXMsIGFyZ3VtZW50cykuZW5kKCk7IH0pXG4gICAgICAgICAgLnR3ZWVuKFwiYnJ1c2hcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXG4gICAgICAgICAgICAgICAgc3RhdGUgPSB0aGF0Ll9fYnJ1c2gsXG4gICAgICAgICAgICAgICAgZW1pdCA9IGVtaXR0ZXIodGhhdCwgYXJndW1lbnRzKSxcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb24wID0gc3RhdGUuc2VsZWN0aW9uLFxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbjEgPSBkaW0uaW5wdXQodHlwZW9mIHNlbGVjdGlvbiQkMSA9PT0gXCJmdW5jdGlvblwiID8gc2VsZWN0aW9uJCQxLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBzZWxlY3Rpb24kJDEsIHN0YXRlLmV4dGVudCksXG4gICAgICAgICAgICAgICAgaSA9IGludGVycG9sYXRlVmFsdWUoc2VsZWN0aW9uMCwgc2VsZWN0aW9uMSk7XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHR3ZWVuKHQpIHtcbiAgICAgICAgICAgICAgc3RhdGUuc2VsZWN0aW9uID0gdCA9PT0gMSAmJiBlbXB0eShzZWxlY3Rpb24xKSA/IG51bGwgOiBpKHQpO1xuICAgICAgICAgICAgICByZWRyYXcuY2FsbCh0aGF0KTtcbiAgICAgICAgICAgICAgZW1pdC5icnVzaCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gc2VsZWN0aW9uMCAmJiBzZWxlY3Rpb24xID8gdHdlZW4gOiB0d2VlbigxKTtcbiAgICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ3JvdXBcbiAgICAgICAgICAuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAgICAgIHN0YXRlID0gdGhhdC5fX2JydXNoLFxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbjEgPSBkaW0uaW5wdXQodHlwZW9mIHNlbGVjdGlvbiQkMSA9PT0gXCJmdW5jdGlvblwiID8gc2VsZWN0aW9uJCQxLmFwcGx5KHRoYXQsIGFyZ3MpIDogc2VsZWN0aW9uJCQxLCBzdGF0ZS5leHRlbnQpLFxuICAgICAgICAgICAgICAgIGVtaXQgPSBlbWl0dGVyKHRoYXQsIGFyZ3MpLmJlZm9yZXN0YXJ0KCk7XG5cbiAgICAgICAgICAgIGludGVycnVwdCh0aGF0KTtcbiAgICAgICAgICAgIHN0YXRlLnNlbGVjdGlvbiA9IHNlbGVjdGlvbjEgPT0gbnVsbCB8fCBlbXB0eShzZWxlY3Rpb24xKSA/IG51bGwgOiBzZWxlY3Rpb24xO1xuICAgICAgICAgICAgcmVkcmF3LmNhbGwodGhhdCk7XG4gICAgICAgICAgICBlbWl0LnN0YXJ0KCkuYnJ1c2goKS5lbmQoKTtcbiAgICAgICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVkcmF3KCkge1xuICAgIHZhciBncm91cCA9IHNlbGVjdCh0aGlzKSxcbiAgICAgICAgc2VsZWN0aW9uJCQxID0gbG9jYWwkJDEodGhpcykuc2VsZWN0aW9uO1xuXG4gICAgaWYgKHNlbGVjdGlvbiQkMSkge1xuICAgICAgZ3JvdXAuc2VsZWN0QWxsKFwiLnNlbGVjdGlvblwiKVxuICAgICAgICAgIC5zdHlsZShcImRpc3BsYXlcIiwgbnVsbClcbiAgICAgICAgICAuYXR0cihcInhcIiwgc2VsZWN0aW9uJCQxWzBdWzBdKVxuICAgICAgICAgIC5hdHRyKFwieVwiLCBzZWxlY3Rpb24kJDFbMF1bMV0pXG4gICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBzZWxlY3Rpb24kJDFbMV1bMF0gLSBzZWxlY3Rpb24kJDFbMF1bMF0pXG4gICAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgc2VsZWN0aW9uJCQxWzFdWzFdIC0gc2VsZWN0aW9uJCQxWzBdWzFdKTtcblxuICAgICAgZ3JvdXAuc2VsZWN0QWxsKFwiLmhhbmRsZVwiKVxuICAgICAgICAgIC5zdHlsZShcImRpc3BsYXlcIiwgbnVsbClcbiAgICAgICAgICAuYXR0cihcInhcIiwgZnVuY3Rpb24oZCkgeyByZXR1cm4gZC50eXBlW2QudHlwZS5sZW5ndGggLSAxXSA9PT0gXCJlXCIgPyBzZWxlY3Rpb24kJDFbMV1bMF0gLSBoYW5kbGVTaXplIC8gMiA6IHNlbGVjdGlvbiQkMVswXVswXSAtIGhhbmRsZVNpemUgLyAyOyB9KVxuICAgICAgICAgIC5hdHRyKFwieVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBkLnR5cGVbMF0gPT09IFwic1wiID8gc2VsZWN0aW9uJCQxWzFdWzFdIC0gaGFuZGxlU2l6ZSAvIDIgOiBzZWxlY3Rpb24kJDFbMF1bMV0gLSBoYW5kbGVTaXplIC8gMjsgfSlcbiAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQudHlwZSA9PT0gXCJuXCIgfHwgZC50eXBlID09PSBcInNcIiA/IHNlbGVjdGlvbiQkMVsxXVswXSAtIHNlbGVjdGlvbiQkMVswXVswXSArIGhhbmRsZVNpemUgOiBoYW5kbGVTaXplOyB9KVxuICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQudHlwZSA9PT0gXCJlXCIgfHwgZC50eXBlID09PSBcIndcIiA/IHNlbGVjdGlvbiQkMVsxXVsxXSAtIHNlbGVjdGlvbiQkMVswXVsxXSArIGhhbmRsZVNpemUgOiBoYW5kbGVTaXplOyB9KTtcbiAgICB9XG5cbiAgICBlbHNlIHtcbiAgICAgIGdyb3VwLnNlbGVjdEFsbChcIi5zZWxlY3Rpb24sLmhhbmRsZVwiKVxuICAgICAgICAgIC5zdHlsZShcImRpc3BsYXlcIiwgXCJub25lXCIpXG4gICAgICAgICAgLmF0dHIoXCJ4XCIsIG51bGwpXG4gICAgICAgICAgLmF0dHIoXCJ5XCIsIG51bGwpXG4gICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBudWxsKVxuICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGVtaXR0ZXIodGhhdCwgYXJncykge1xuICAgIHJldHVybiB0aGF0Ll9fYnJ1c2guZW1pdHRlciB8fCBuZXcgRW1pdHRlcih0aGF0LCBhcmdzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIEVtaXR0ZXIodGhhdCwgYXJncykge1xuICAgIHRoaXMudGhhdCA9IHRoYXQ7XG4gICAgdGhpcy5hcmdzID0gYXJncztcbiAgICB0aGlzLnN0YXRlID0gdGhhdC5fX2JydXNoO1xuICAgIHRoaXMuYWN0aXZlID0gMDtcbiAgfVxuXG4gIEVtaXR0ZXIucHJvdG90eXBlID0ge1xuICAgIGJlZm9yZXN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICgrK3RoaXMuYWN0aXZlID09PSAxKSB0aGlzLnN0YXRlLmVtaXR0ZXIgPSB0aGlzLCB0aGlzLnN0YXJ0aW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgc3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc3RhcnRpbmcpIHRoaXMuc3RhcnRpbmcgPSBmYWxzZSwgdGhpcy5lbWl0KFwic3RhcnRcIik7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGJydXNoOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZW1pdChcImJydXNoXCIpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBlbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKC0tdGhpcy5hY3RpdmUgPT09IDApIGRlbGV0ZSB0aGlzLnN0YXRlLmVtaXR0ZXIsIHRoaXMuZW1pdChcImVuZFwiKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgZW1pdDogZnVuY3Rpb24odHlwZSkge1xuICAgICAgY3VzdG9tRXZlbnQobmV3IEJydXNoRXZlbnQoYnJ1c2gsIHR5cGUsIGRpbS5vdXRwdXQodGhpcy5zdGF0ZS5zZWxlY3Rpb24pKSwgbGlzdGVuZXJzLmFwcGx5LCBsaXN0ZW5lcnMsIFt0eXBlLCB0aGlzLnRoYXQsIHRoaXMuYXJnc10pO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBzdGFydGVkKCkge1xuICAgIGlmIChleHBvcnRzLmV2ZW50LnRvdWNoZXMpIHsgaWYgKGV4cG9ydHMuZXZlbnQuY2hhbmdlZFRvdWNoZXMubGVuZ3RoIDwgZXhwb3J0cy5ldmVudC50b3VjaGVzLmxlbmd0aCkgcmV0dXJuIG5vZXZlbnQkMSgpOyB9XG4gICAgZWxzZSBpZiAodG91Y2hlbmRpbmcpIHJldHVybjtcbiAgICBpZiAoIWZpbHRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm47XG5cbiAgICB2YXIgdGhhdCA9IHRoaXMsXG4gICAgICAgIHR5cGUgPSBleHBvcnRzLmV2ZW50LnRhcmdldC5fX2RhdGFfXy50eXBlLFxuICAgICAgICBtb2RlID0gKGV4cG9ydHMuZXZlbnQubWV0YUtleSA/IHR5cGUgPSBcIm92ZXJsYXlcIiA6IHR5cGUpID09PSBcInNlbGVjdGlvblwiID8gTU9ERV9EUkFHIDogKGV4cG9ydHMuZXZlbnQuYWx0S2V5ID8gTU9ERV9DRU5URVIgOiBNT0RFX0hBTkRMRSksXG4gICAgICAgIHNpZ25YID0gZGltID09PSBZID8gbnVsbCA6IHNpZ25zWFt0eXBlXSxcbiAgICAgICAgc2lnblkgPSBkaW0gPT09IFggPyBudWxsIDogc2lnbnNZW3R5cGVdLFxuICAgICAgICBzdGF0ZSA9IGxvY2FsJCQxKHRoYXQpLFxuICAgICAgICBleHRlbnQgPSBzdGF0ZS5leHRlbnQsXG4gICAgICAgIHNlbGVjdGlvbiQkMSA9IHN0YXRlLnNlbGVjdGlvbixcbiAgICAgICAgVyA9IGV4dGVudFswXVswXSwgdzAsIHcxLFxuICAgICAgICBOID0gZXh0ZW50WzBdWzFdLCBuMCwgbjEsXG4gICAgICAgIEUgPSBleHRlbnRbMV1bMF0sIGUwLCBlMSxcbiAgICAgICAgUyA9IGV4dGVudFsxXVsxXSwgczAsIHMxLFxuICAgICAgICBkeCxcbiAgICAgICAgZHksXG4gICAgICAgIG1vdmluZyxcbiAgICAgICAgc2hpZnRpbmcgPSBzaWduWCAmJiBzaWduWSAmJiBleHBvcnRzLmV2ZW50LnNoaWZ0S2V5LFxuICAgICAgICBsb2NrWCxcbiAgICAgICAgbG9ja1ksXG4gICAgICAgIHBvaW50MCA9IG1vdXNlKHRoYXQpLFxuICAgICAgICBwb2ludCA9IHBvaW50MCxcbiAgICAgICAgZW1pdCA9IGVtaXR0ZXIodGhhdCwgYXJndW1lbnRzKS5iZWZvcmVzdGFydCgpO1xuXG4gICAgaWYgKHR5cGUgPT09IFwib3ZlcmxheVwiKSB7XG4gICAgICBzdGF0ZS5zZWxlY3Rpb24gPSBzZWxlY3Rpb24kJDEgPSBbXG4gICAgICAgIFt3MCA9IGRpbSA9PT0gWSA/IFcgOiBwb2ludDBbMF0sIG4wID0gZGltID09PSBYID8gTiA6IHBvaW50MFsxXV0sXG4gICAgICAgIFtlMCA9IGRpbSA9PT0gWSA/IEUgOiB3MCwgczAgPSBkaW0gPT09IFggPyBTIDogbjBdXG4gICAgICBdO1xuICAgIH0gZWxzZSB7XG4gICAgICB3MCA9IHNlbGVjdGlvbiQkMVswXVswXTtcbiAgICAgIG4wID0gc2VsZWN0aW9uJCQxWzBdWzFdO1xuICAgICAgZTAgPSBzZWxlY3Rpb24kJDFbMV1bMF07XG4gICAgICBzMCA9IHNlbGVjdGlvbiQkMVsxXVsxXTtcbiAgICB9XG5cbiAgICB3MSA9IHcwO1xuICAgIG4xID0gbjA7XG4gICAgZTEgPSBlMDtcbiAgICBzMSA9IHMwO1xuXG4gICAgdmFyIGdyb3VwID0gc2VsZWN0KHRoYXQpXG4gICAgICAgIC5hdHRyKFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuXG4gICAgdmFyIG92ZXJsYXkgPSBncm91cC5zZWxlY3RBbGwoXCIub3ZlcmxheVwiKVxuICAgICAgICAuYXR0cihcImN1cnNvclwiLCBjdXJzb3JzW3R5cGVdKTtcblxuICAgIGlmIChleHBvcnRzLmV2ZW50LnRvdWNoZXMpIHtcbiAgICAgIGdyb3VwXG4gICAgICAgICAgLm9uKFwidG91Y2htb3ZlLmJydXNoXCIsIG1vdmVkLCB0cnVlKVxuICAgICAgICAgIC5vbihcInRvdWNoZW5kLmJydXNoIHRvdWNoY2FuY2VsLmJydXNoXCIsIGVuZGVkLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHZpZXcgPSBzZWxlY3QoZXhwb3J0cy5ldmVudC52aWV3KVxuICAgICAgICAgIC5vbihcImtleWRvd24uYnJ1c2hcIiwga2V5ZG93bmVkLCB0cnVlKVxuICAgICAgICAgIC5vbihcImtleXVwLmJydXNoXCIsIGtleXVwcGVkLCB0cnVlKVxuICAgICAgICAgIC5vbihcIm1vdXNlbW92ZS5icnVzaFwiLCBtb3ZlZCwgdHJ1ZSlcbiAgICAgICAgICAub24oXCJtb3VzZXVwLmJydXNoXCIsIGVuZGVkLCB0cnVlKTtcblxuICAgICAgZHJhZ0Rpc2FibGUoZXhwb3J0cy5ldmVudC52aWV3KTtcbiAgICB9XG5cbiAgICBub3Byb3BhZ2F0aW9uJDEoKTtcbiAgICBpbnRlcnJ1cHQodGhhdCk7XG4gICAgcmVkcmF3LmNhbGwodGhhdCk7XG4gICAgZW1pdC5zdGFydCgpO1xuXG4gICAgZnVuY3Rpb24gbW92ZWQoKSB7XG4gICAgICB2YXIgcG9pbnQxID0gbW91c2UodGhhdCk7XG4gICAgICBpZiAoc2hpZnRpbmcgJiYgIWxvY2tYICYmICFsb2NrWSkge1xuICAgICAgICBpZiAoTWF0aC5hYnMocG9pbnQxWzBdIC0gcG9pbnRbMF0pID4gTWF0aC5hYnMocG9pbnQxWzFdIC0gcG9pbnRbMV0pKSBsb2NrWSA9IHRydWU7XG4gICAgICAgIGVsc2UgbG9ja1ggPSB0cnVlO1xuICAgICAgfVxuICAgICAgcG9pbnQgPSBwb2ludDE7XG4gICAgICBtb3ZpbmcgPSB0cnVlO1xuICAgICAgbm9ldmVudCQxKCk7XG4gICAgICBtb3ZlKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW92ZSgpIHtcbiAgICAgIHZhciB0O1xuXG4gICAgICBkeCA9IHBvaW50WzBdIC0gcG9pbnQwWzBdO1xuICAgICAgZHkgPSBwb2ludFsxXSAtIHBvaW50MFsxXTtcblxuICAgICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICAgIGNhc2UgTU9ERV9TUEFDRTpcbiAgICAgICAgY2FzZSBNT0RFX0RSQUc6IHtcbiAgICAgICAgICBpZiAoc2lnblgpIGR4ID0gTWF0aC5tYXgoVyAtIHcwLCBNYXRoLm1pbihFIC0gZTAsIGR4KSksIHcxID0gdzAgKyBkeCwgZTEgPSBlMCArIGR4O1xuICAgICAgICAgIGlmIChzaWduWSkgZHkgPSBNYXRoLm1heChOIC0gbjAsIE1hdGgubWluKFMgLSBzMCwgZHkpKSwgbjEgPSBuMCArIGR5LCBzMSA9IHMwICsgZHk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBNT0RFX0hBTkRMRToge1xuICAgICAgICAgIGlmIChzaWduWCA8IDApIGR4ID0gTWF0aC5tYXgoVyAtIHcwLCBNYXRoLm1pbihFIC0gdzAsIGR4KSksIHcxID0gdzAgKyBkeCwgZTEgPSBlMDtcbiAgICAgICAgICBlbHNlIGlmIChzaWduWCA+IDApIGR4ID0gTWF0aC5tYXgoVyAtIGUwLCBNYXRoLm1pbihFIC0gZTAsIGR4KSksIHcxID0gdzAsIGUxID0gZTAgKyBkeDtcbiAgICAgICAgICBpZiAoc2lnblkgPCAwKSBkeSA9IE1hdGgubWF4KE4gLSBuMCwgTWF0aC5taW4oUyAtIG4wLCBkeSkpLCBuMSA9IG4wICsgZHksIHMxID0gczA7XG4gICAgICAgICAgZWxzZSBpZiAoc2lnblkgPiAwKSBkeSA9IE1hdGgubWF4KE4gLSBzMCwgTWF0aC5taW4oUyAtIHMwLCBkeSkpLCBuMSA9IG4wLCBzMSA9IHMwICsgZHk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBNT0RFX0NFTlRFUjoge1xuICAgICAgICAgIGlmIChzaWduWCkgdzEgPSBNYXRoLm1heChXLCBNYXRoLm1pbihFLCB3MCAtIGR4ICogc2lnblgpKSwgZTEgPSBNYXRoLm1heChXLCBNYXRoLm1pbihFLCBlMCArIGR4ICogc2lnblgpKTtcbiAgICAgICAgICBpZiAoc2lnblkpIG4xID0gTWF0aC5tYXgoTiwgTWF0aC5taW4oUywgbjAgLSBkeSAqIHNpZ25ZKSksIHMxID0gTWF0aC5tYXgoTiwgTWF0aC5taW4oUywgczAgKyBkeSAqIHNpZ25ZKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGUxIDwgdzEpIHtcbiAgICAgICAgc2lnblggKj0gLTE7XG4gICAgICAgIHQgPSB3MCwgdzAgPSBlMCwgZTAgPSB0O1xuICAgICAgICB0ID0gdzEsIHcxID0gZTEsIGUxID0gdDtcbiAgICAgICAgaWYgKHR5cGUgaW4gZmxpcFgpIG92ZXJsYXkuYXR0cihcImN1cnNvclwiLCBjdXJzb3JzW3R5cGUgPSBmbGlwWFt0eXBlXV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoczEgPCBuMSkge1xuICAgICAgICBzaWduWSAqPSAtMTtcbiAgICAgICAgdCA9IG4wLCBuMCA9IHMwLCBzMCA9IHQ7XG4gICAgICAgIHQgPSBuMSwgbjEgPSBzMSwgczEgPSB0O1xuICAgICAgICBpZiAodHlwZSBpbiBmbGlwWSkgb3ZlcmxheS5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnNbdHlwZSA9IGZsaXBZW3R5cGVdXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0ZS5zZWxlY3Rpb24pIHNlbGVjdGlvbiQkMSA9IHN0YXRlLnNlbGVjdGlvbjsgLy8gTWF5IGJlIHNldCBieSBicnVzaC5tb3ZlIVxuICAgICAgaWYgKGxvY2tYKSB3MSA9IHNlbGVjdGlvbiQkMVswXVswXSwgZTEgPSBzZWxlY3Rpb24kJDFbMV1bMF07XG4gICAgICBpZiAobG9ja1kpIG4xID0gc2VsZWN0aW9uJCQxWzBdWzFdLCBzMSA9IHNlbGVjdGlvbiQkMVsxXVsxXTtcblxuICAgICAgaWYgKHNlbGVjdGlvbiQkMVswXVswXSAhPT0gdzFcbiAgICAgICAgICB8fCBzZWxlY3Rpb24kJDFbMF1bMV0gIT09IG4xXG4gICAgICAgICAgfHwgc2VsZWN0aW9uJCQxWzFdWzBdICE9PSBlMVxuICAgICAgICAgIHx8IHNlbGVjdGlvbiQkMVsxXVsxXSAhPT0gczEpIHtcbiAgICAgICAgc3RhdGUuc2VsZWN0aW9uID0gW1t3MSwgbjFdLCBbZTEsIHMxXV07XG4gICAgICAgIHJlZHJhdy5jYWxsKHRoYXQpO1xuICAgICAgICBlbWl0LmJydXNoKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZW5kZWQoKSB7XG4gICAgICBub3Byb3BhZ2F0aW9uJDEoKTtcbiAgICAgIGlmIChleHBvcnRzLmV2ZW50LnRvdWNoZXMpIHtcbiAgICAgICAgaWYgKGV4cG9ydHMuZXZlbnQudG91Y2hlcy5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgaWYgKHRvdWNoZW5kaW5nKSBjbGVhclRpbWVvdXQodG91Y2hlbmRpbmcpO1xuICAgICAgICB0b3VjaGVuZGluZyA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHRvdWNoZW5kaW5nID0gbnVsbDsgfSwgNTAwKTsgLy8gR2hvc3QgY2xpY2tzIGFyZSBkZWxheWVkIVxuICAgICAgICBncm91cC5vbihcInRvdWNobW92ZS5icnVzaCB0b3VjaGVuZC5icnVzaCB0b3VjaGNhbmNlbC5icnVzaFwiLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHllc2RyYWcoZXhwb3J0cy5ldmVudC52aWV3LCBtb3ZpbmcpO1xuICAgICAgICB2aWV3Lm9uKFwia2V5ZG93bi5icnVzaCBrZXl1cC5icnVzaCBtb3VzZW1vdmUuYnJ1c2ggbW91c2V1cC5icnVzaFwiLCBudWxsKTtcbiAgICAgIH1cbiAgICAgIGdyb3VwLmF0dHIoXCJwb2ludGVyLWV2ZW50c1wiLCBcImFsbFwiKTtcbiAgICAgIG92ZXJsYXkuYXR0cihcImN1cnNvclwiLCBjdXJzb3JzLm92ZXJsYXkpO1xuICAgICAgaWYgKHN0YXRlLnNlbGVjdGlvbikgc2VsZWN0aW9uJCQxID0gc3RhdGUuc2VsZWN0aW9uOyAvLyBNYXkgYmUgc2V0IGJ5IGJydXNoLm1vdmUgKG9uIHN0YXJ0KSFcbiAgICAgIGlmIChlbXB0eShzZWxlY3Rpb24kJDEpKSBzdGF0ZS5zZWxlY3Rpb24gPSBudWxsLCByZWRyYXcuY2FsbCh0aGF0KTtcbiAgICAgIGVtaXQuZW5kKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24ga2V5ZG93bmVkKCkge1xuICAgICAgc3dpdGNoIChleHBvcnRzLmV2ZW50LmtleUNvZGUpIHtcbiAgICAgICAgY2FzZSAxNjogeyAvLyBTSElGVFxuICAgICAgICAgIHNoaWZ0aW5nID0gc2lnblggJiYgc2lnblk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAxODogeyAvLyBBTFRcbiAgICAgICAgICBpZiAobW9kZSA9PT0gTU9ERV9IQU5ETEUpIHtcbiAgICAgICAgICAgIGlmIChzaWduWCkgZTAgPSBlMSAtIGR4ICogc2lnblgsIHcwID0gdzEgKyBkeCAqIHNpZ25YO1xuICAgICAgICAgICAgaWYgKHNpZ25ZKSBzMCA9IHMxIC0gZHkgKiBzaWduWSwgbjAgPSBuMSArIGR5ICogc2lnblk7XG4gICAgICAgICAgICBtb2RlID0gTU9ERV9DRU5URVI7XG4gICAgICAgICAgICBtb3ZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMzI6IHsgLy8gU1BBQ0U7IHRha2VzIHByaW9yaXR5IG92ZXIgQUxUXG4gICAgICAgICAgaWYgKG1vZGUgPT09IE1PREVfSEFORExFIHx8IG1vZGUgPT09IE1PREVfQ0VOVEVSKSB7XG4gICAgICAgICAgICBpZiAoc2lnblggPCAwKSBlMCA9IGUxIC0gZHg7IGVsc2UgaWYgKHNpZ25YID4gMCkgdzAgPSB3MSAtIGR4O1xuICAgICAgICAgICAgaWYgKHNpZ25ZIDwgMCkgczAgPSBzMSAtIGR5OyBlbHNlIGlmIChzaWduWSA+IDApIG4wID0gbjEgLSBkeTtcbiAgICAgICAgICAgIG1vZGUgPSBNT0RFX1NQQUNFO1xuICAgICAgICAgICAgb3ZlcmxheS5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnMuc2VsZWN0aW9uKTtcbiAgICAgICAgICAgIG1vdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogcmV0dXJuO1xuICAgICAgfVxuICAgICAgbm9ldmVudCQxKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24ga2V5dXBwZWQoKSB7XG4gICAgICBzd2l0Y2ggKGV4cG9ydHMuZXZlbnQua2V5Q29kZSkge1xuICAgICAgICBjYXNlIDE2OiB7IC8vIFNISUZUXG4gICAgICAgICAgaWYgKHNoaWZ0aW5nKSB7XG4gICAgICAgICAgICBsb2NrWCA9IGxvY2tZID0gc2hpZnRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIG1vdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAxODogeyAvLyBBTFRcbiAgICAgICAgICBpZiAobW9kZSA9PT0gTU9ERV9DRU5URVIpIHtcbiAgICAgICAgICAgIGlmIChzaWduWCA8IDApIGUwID0gZTE7IGVsc2UgaWYgKHNpZ25YID4gMCkgdzAgPSB3MTtcbiAgICAgICAgICAgIGlmIChzaWduWSA8IDApIHMwID0gczE7IGVsc2UgaWYgKHNpZ25ZID4gMCkgbjAgPSBuMTtcbiAgICAgICAgICAgIG1vZGUgPSBNT0RFX0hBTkRMRTtcbiAgICAgICAgICAgIG1vdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAzMjogeyAvLyBTUEFDRVxuICAgICAgICAgIGlmIChtb2RlID09PSBNT0RFX1NQQUNFKSB7XG4gICAgICAgICAgICBpZiAoZXhwb3J0cy5ldmVudC5hbHRLZXkpIHtcbiAgICAgICAgICAgICAgaWYgKHNpZ25YKSBlMCA9IGUxIC0gZHggKiBzaWduWCwgdzAgPSB3MSArIGR4ICogc2lnblg7XG4gICAgICAgICAgICAgIGlmIChzaWduWSkgczAgPSBzMSAtIGR5ICogc2lnblksIG4wID0gbjEgKyBkeSAqIHNpZ25ZO1xuICAgICAgICAgICAgICBtb2RlID0gTU9ERV9DRU5URVI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAoc2lnblggPCAwKSBlMCA9IGUxOyBlbHNlIGlmIChzaWduWCA+IDApIHcwID0gdzE7XG4gICAgICAgICAgICAgIGlmIChzaWduWSA8IDApIHMwID0gczE7IGVsc2UgaWYgKHNpZ25ZID4gMCkgbjAgPSBuMTtcbiAgICAgICAgICAgICAgbW9kZSA9IE1PREVfSEFORExFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb3ZlcmxheS5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnNbdHlwZV0pO1xuICAgICAgICAgICAgbW92ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OiByZXR1cm47XG4gICAgICB9XG4gICAgICBub2V2ZW50JDEoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplKCkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX19icnVzaCB8fCB7c2VsZWN0aW9uOiBudWxsfTtcbiAgICBzdGF0ZS5leHRlbnQgPSBleHRlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBzdGF0ZS5kaW0gPSBkaW07XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgYnJ1c2guZXh0ZW50ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGV4dGVudCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNChbWytfWzBdWzBdLCArX1swXVsxXV0sIFsrX1sxXVswXSwgK19bMV1bMV1dXSksIGJydXNoKSA6IGV4dGVudDtcbiAgfTtcblxuICBicnVzaC5maWx0ZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZmlsdGVyID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ0KCEhXyksIGJydXNoKSA6IGZpbHRlcjtcbiAgfTtcblxuICBicnVzaC5oYW5kbGVTaXplID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGhhbmRsZVNpemUgPSArXywgYnJ1c2gpIDogaGFuZGxlU2l6ZTtcbiAgfTtcblxuICBicnVzaC5vbiA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB2YWx1ZSA9IGxpc3RlbmVycy5vbi5hcHBseShsaXN0ZW5lcnMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHZhbHVlID09PSBsaXN0ZW5lcnMgPyBicnVzaCA6IHZhbHVlO1xuICB9O1xuXG4gIHJldHVybiBicnVzaDtcbn1cblxudmFyIGNvcyA9IE1hdGguY29zO1xudmFyIHNpbiA9IE1hdGguc2luO1xudmFyIHBpJDEgPSBNYXRoLlBJO1xudmFyIGhhbGZQaSQxID0gcGkkMSAvIDI7XG52YXIgdGF1JDEgPSBwaSQxICogMjtcbnZhciBtYXgkMSA9IE1hdGgubWF4O1xuXG5mdW5jdGlvbiBjb21wYXJlVmFsdWUoY29tcGFyZSkge1xuICByZXR1cm4gZnVuY3Rpb24oYSwgYikge1xuICAgIHJldHVybiBjb21wYXJlKFxuICAgICAgYS5zb3VyY2UudmFsdWUgKyBhLnRhcmdldC52YWx1ZSxcbiAgICAgIGIuc291cmNlLnZhbHVlICsgYi50YXJnZXQudmFsdWVcbiAgICApO1xuICB9O1xufVxuXG52YXIgY2hvcmQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhZEFuZ2xlID0gMCxcbiAgICAgIHNvcnRHcm91cHMgPSBudWxsLFxuICAgICAgc29ydFN1Ymdyb3VwcyA9IG51bGwsXG4gICAgICBzb3J0Q2hvcmRzID0gbnVsbDtcblxuICBmdW5jdGlvbiBjaG9yZChtYXRyaXgpIHtcbiAgICB2YXIgbiA9IG1hdHJpeC5sZW5ndGgsXG4gICAgICAgIGdyb3VwU3VtcyA9IFtdLFxuICAgICAgICBncm91cEluZGV4ID0gc2VxdWVuY2UobiksXG4gICAgICAgIHN1Ymdyb3VwSW5kZXggPSBbXSxcbiAgICAgICAgY2hvcmRzID0gW10sXG4gICAgICAgIGdyb3VwcyA9IGNob3Jkcy5ncm91cHMgPSBuZXcgQXJyYXkobiksXG4gICAgICAgIHN1Ymdyb3VwcyA9IG5ldyBBcnJheShuICogbiksXG4gICAgICAgIGssXG4gICAgICAgIHgsXG4gICAgICAgIHgwLFxuICAgICAgICBkeCxcbiAgICAgICAgaSxcbiAgICAgICAgajtcblxuICAgIC8vIENvbXB1dGUgdGhlIHN1bS5cbiAgICBrID0gMCwgaSA9IC0xOyB3aGlsZSAoKytpIDwgbikge1xuICAgICAgeCA9IDAsIGogPSAtMTsgd2hpbGUgKCsraiA8IG4pIHtcbiAgICAgICAgeCArPSBtYXRyaXhbaV1bal07XG4gICAgICB9XG4gICAgICBncm91cFN1bXMucHVzaCh4KTtcbiAgICAgIHN1Ymdyb3VwSW5kZXgucHVzaChzZXF1ZW5jZShuKSk7XG4gICAgICBrICs9IHg7XG4gICAgfVxuXG4gICAgLy8gU29ydCBncm91cHPigKZcbiAgICBpZiAoc29ydEdyb3VwcykgZ3JvdXBJbmRleC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgIHJldHVybiBzb3J0R3JvdXBzKGdyb3VwU3Vtc1thXSwgZ3JvdXBTdW1zW2JdKTtcbiAgICB9KTtcblxuICAgIC8vIFNvcnQgc3ViZ3JvdXBz4oCmXG4gICAgaWYgKHNvcnRTdWJncm91cHMpIHN1Ymdyb3VwSW5kZXguZm9yRWFjaChmdW5jdGlvbihkLCBpKSB7XG4gICAgICBkLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICByZXR1cm4gc29ydFN1Ymdyb3VwcyhtYXRyaXhbaV1bYV0sIG1hdHJpeFtpXVtiXSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIENvbnZlcnQgdGhlIHN1bSB0byBzY2FsaW5nIGZhY3RvciBmb3IgWzAsIDJwaV0uXG4gICAgLy8gVE9ETyBBbGxvdyBzdGFydCBhbmQgZW5kIGFuZ2xlIHRvIGJlIHNwZWNpZmllZD9cbiAgICAvLyBUT0RPIEFsbG93IHBhZGRpbmcgdG8gYmUgc3BlY2lmaWVkIGFzIHBlcmNlbnRhZ2U/XG4gICAgayA9IG1heCQxKDAsIHRhdSQxIC0gcGFkQW5nbGUgKiBuKSAvIGs7XG4gICAgZHggPSBrID8gcGFkQW5nbGUgOiB0YXUkMSAvIG47XG5cbiAgICAvLyBDb21wdXRlIHRoZSBzdGFydCBhbmQgZW5kIGFuZ2xlIGZvciBlYWNoIGdyb3VwIGFuZCBzdWJncm91cC5cbiAgICAvLyBOb3RlOiBPcGVyYSBoYXMgYSBidWcgcmVvcmRlcmluZyBvYmplY3QgbGl0ZXJhbCBwcm9wZXJ0aWVzIVxuICAgIHggPSAwLCBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICB4MCA9IHgsIGogPSAtMTsgd2hpbGUgKCsraiA8IG4pIHtcbiAgICAgICAgdmFyIGRpID0gZ3JvdXBJbmRleFtpXSxcbiAgICAgICAgICAgIGRqID0gc3ViZ3JvdXBJbmRleFtkaV1bal0sXG4gICAgICAgICAgICB2ID0gbWF0cml4W2RpXVtkal0sXG4gICAgICAgICAgICBhMCA9IHgsXG4gICAgICAgICAgICBhMSA9IHggKz0gdiAqIGs7XG4gICAgICAgIHN1Ymdyb3Vwc1tkaiAqIG4gKyBkaV0gPSB7XG4gICAgICAgICAgaW5kZXg6IGRpLFxuICAgICAgICAgIHN1YmluZGV4OiBkaixcbiAgICAgICAgICBzdGFydEFuZ2xlOiBhMCxcbiAgICAgICAgICBlbmRBbmdsZTogYTEsXG4gICAgICAgICAgdmFsdWU6IHZcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGdyb3Vwc1tkaV0gPSB7XG4gICAgICAgIGluZGV4OiBkaSxcbiAgICAgICAgc3RhcnRBbmdsZTogeDAsXG4gICAgICAgIGVuZEFuZ2xlOiB4LFxuICAgICAgICB2YWx1ZTogZ3JvdXBTdW1zW2RpXVxuICAgICAgfTtcbiAgICAgIHggKz0gZHg7XG4gICAgfVxuXG4gICAgLy8gR2VuZXJhdGUgY2hvcmRzIGZvciBlYWNoIChub24tZW1wdHkpIHN1Ymdyb3VwLXN1Ymdyb3VwIGxpbmsuXG4gICAgaSA9IC0xOyB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaiA9IGkgLSAxOyB3aGlsZSAoKytqIDwgbikge1xuICAgICAgICB2YXIgc291cmNlID0gc3ViZ3JvdXBzW2ogKiBuICsgaV0sXG4gICAgICAgICAgICB0YXJnZXQgPSBzdWJncm91cHNbaSAqIG4gKyBqXTtcbiAgICAgICAgaWYgKHNvdXJjZS52YWx1ZSB8fCB0YXJnZXQudmFsdWUpIHtcbiAgICAgICAgICBjaG9yZHMucHVzaChzb3VyY2UudmFsdWUgPCB0YXJnZXQudmFsdWVcbiAgICAgICAgICAgICAgPyB7c291cmNlOiB0YXJnZXQsIHRhcmdldDogc291cmNlfVxuICAgICAgICAgICAgICA6IHtzb3VyY2U6IHNvdXJjZSwgdGFyZ2V0OiB0YXJnZXR9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzb3J0Q2hvcmRzID8gY2hvcmRzLnNvcnQoc29ydENob3JkcykgOiBjaG9yZHM7XG4gIH1cblxuICBjaG9yZC5wYWRBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRBbmdsZSA9IG1heCQxKDAsIF8pLCBjaG9yZCkgOiBwYWRBbmdsZTtcbiAgfTtcblxuICBjaG9yZC5zb3J0R3JvdXBzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNvcnRHcm91cHMgPSBfLCBjaG9yZCkgOiBzb3J0R3JvdXBzO1xuICB9O1xuXG4gIGNob3JkLnNvcnRTdWJncm91cHMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc29ydFN1Ymdyb3VwcyA9IF8sIGNob3JkKSA6IHNvcnRTdWJncm91cHM7XG4gIH07XG5cbiAgY2hvcmQuc29ydENob3JkcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChfID09IG51bGwgPyBzb3J0Q2hvcmRzID0gbnVsbCA6IChzb3J0Q2hvcmRzID0gY29tcGFyZVZhbHVlKF8pKS5fID0gXywgY2hvcmQpIDogc29ydENob3JkcyAmJiBzb3J0Q2hvcmRzLl87XG4gIH07XG5cbiAgcmV0dXJuIGNob3JkO1xufTtcblxudmFyIHNsaWNlJDIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbnZhciBjb25zdGFudCQ1ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG52YXIgcGkkMiA9IE1hdGguUEk7XG52YXIgdGF1JDIgPSAyICogcGkkMjtcbnZhciBlcHNpbG9uJDEgPSAxZS02O1xudmFyIHRhdUVwc2lsb24gPSB0YXUkMiAtIGVwc2lsb24kMTtcblxuZnVuY3Rpb24gUGF0aCgpIHtcbiAgdGhpcy5feDAgPSB0aGlzLl95MCA9IC8vIHN0YXJ0IG9mIGN1cnJlbnQgc3VicGF0aFxuICB0aGlzLl94MSA9IHRoaXMuX3kxID0gbnVsbDsgLy8gZW5kIG9mIGN1cnJlbnQgc3VicGF0aFxuICB0aGlzLl8gPSBcIlwiO1xufVxuXG5mdW5jdGlvbiBwYXRoKCkge1xuICByZXR1cm4gbmV3IFBhdGg7XG59XG5cblBhdGgucHJvdG90eXBlID0gcGF0aC5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBQYXRoLFxuICBtb3ZlVG86IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB0aGlzLl8gKz0gXCJNXCIgKyAodGhpcy5feDAgPSB0aGlzLl94MSA9ICt4KSArIFwiLFwiICsgKHRoaXMuX3kwID0gdGhpcy5feTEgPSAreSk7XG4gIH0sXG4gIGNsb3NlUGF0aDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX3gxICE9PSBudWxsKSB7XG4gICAgICB0aGlzLl94MSA9IHRoaXMuX3gwLCB0aGlzLl95MSA9IHRoaXMuX3kwO1xuICAgICAgdGhpcy5fICs9IFwiWlwiO1xuICAgIH1cbiAgfSxcbiAgbGluZVRvOiBmdW5jdGlvbih4LCB5KSB7XG4gICAgdGhpcy5fICs9IFwiTFwiICsgKHRoaXMuX3gxID0gK3gpICsgXCIsXCIgKyAodGhpcy5feTEgPSAreSk7XG4gIH0sXG4gIHF1YWRyYXRpY0N1cnZlVG86IGZ1bmN0aW9uKHgxLCB5MSwgeCwgeSkge1xuICAgIHRoaXMuXyArPSBcIlFcIiArICgreDEpICsgXCIsXCIgKyAoK3kxKSArIFwiLFwiICsgKHRoaXMuX3gxID0gK3gpICsgXCIsXCIgKyAodGhpcy5feTEgPSAreSk7XG4gIH0sXG4gIGJlemllckN1cnZlVG86IGZ1bmN0aW9uKHgxLCB5MSwgeDIsIHkyLCB4LCB5KSB7XG4gICAgdGhpcy5fICs9IFwiQ1wiICsgKCt4MSkgKyBcIixcIiArICgreTEpICsgXCIsXCIgKyAoK3gyKSArIFwiLFwiICsgKCt5MikgKyBcIixcIiArICh0aGlzLl94MSA9ICt4KSArIFwiLFwiICsgKHRoaXMuX3kxID0gK3kpO1xuICB9LFxuICBhcmNUbzogZnVuY3Rpb24oeDEsIHkxLCB4MiwgeTIsIHIpIHtcbiAgICB4MSA9ICt4MSwgeTEgPSAreTEsIHgyID0gK3gyLCB5MiA9ICt5MiwgciA9ICtyO1xuICAgIHZhciB4MCA9IHRoaXMuX3gxLFxuICAgICAgICB5MCA9IHRoaXMuX3kxLFxuICAgICAgICB4MjEgPSB4MiAtIHgxLFxuICAgICAgICB5MjEgPSB5MiAtIHkxLFxuICAgICAgICB4MDEgPSB4MCAtIHgxLFxuICAgICAgICB5MDEgPSB5MCAtIHkxLFxuICAgICAgICBsMDFfMiA9IHgwMSAqIHgwMSArIHkwMSAqIHkwMTtcblxuICAgIC8vIElzIHRoZSByYWRpdXMgbmVnYXRpdmU/IEVycm9yLlxuICAgIGlmIChyIDwgMCkgdGhyb3cgbmV3IEVycm9yKFwibmVnYXRpdmUgcmFkaXVzOiBcIiArIHIpO1xuXG4gICAgLy8gSXMgdGhpcyBwYXRoIGVtcHR5PyBNb3ZlIHRvICh4MSx5MSkuXG4gICAgaWYgKHRoaXMuX3gxID09PSBudWxsKSB7XG4gICAgICB0aGlzLl8gKz0gXCJNXCIgKyAodGhpcy5feDEgPSB4MSkgKyBcIixcIiArICh0aGlzLl95MSA9IHkxKTtcbiAgICB9XG5cbiAgICAvLyBPciwgaXMgKHgxLHkxKSBjb2luY2lkZW50IHdpdGggKHgwLHkwKT8gRG8gbm90aGluZy5cbiAgICBlbHNlIGlmICghKGwwMV8yID4gZXBzaWxvbiQxKSkge31cblxuICAgIC8vIE9yLCBhcmUgKHgwLHkwKSwgKHgxLHkxKSBhbmQgKHgyLHkyKSBjb2xsaW5lYXI/XG4gICAgLy8gRXF1aXZhbGVudGx5LCBpcyAoeDEseTEpIGNvaW5jaWRlbnQgd2l0aCAoeDIseTIpP1xuICAgIC8vIE9yLCBpcyB0aGUgcmFkaXVzIHplcm8/IExpbmUgdG8gKHgxLHkxKS5cbiAgICBlbHNlIGlmICghKE1hdGguYWJzKHkwMSAqIHgyMSAtIHkyMSAqIHgwMSkgPiBlcHNpbG9uJDEpIHx8ICFyKSB7XG4gICAgICB0aGlzLl8gKz0gXCJMXCIgKyAodGhpcy5feDEgPSB4MSkgKyBcIixcIiArICh0aGlzLl95MSA9IHkxKTtcbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UsIGRyYXcgYW4gYXJjIVxuICAgIGVsc2Uge1xuICAgICAgdmFyIHgyMCA9IHgyIC0geDAsXG4gICAgICAgICAgeTIwID0geTIgLSB5MCxcbiAgICAgICAgICBsMjFfMiA9IHgyMSAqIHgyMSArIHkyMSAqIHkyMSxcbiAgICAgICAgICBsMjBfMiA9IHgyMCAqIHgyMCArIHkyMCAqIHkyMCxcbiAgICAgICAgICBsMjEgPSBNYXRoLnNxcnQobDIxXzIpLFxuICAgICAgICAgIGwwMSA9IE1hdGguc3FydChsMDFfMiksXG4gICAgICAgICAgbCA9IHIgKiBNYXRoLnRhbigocGkkMiAtIE1hdGguYWNvcygobDIxXzIgKyBsMDFfMiAtIGwyMF8yKSAvICgyICogbDIxICogbDAxKSkpIC8gMiksXG4gICAgICAgICAgdDAxID0gbCAvIGwwMSxcbiAgICAgICAgICB0MjEgPSBsIC8gbDIxO1xuXG4gICAgICAvLyBJZiB0aGUgc3RhcnQgdGFuZ2VudCBpcyBub3QgY29pbmNpZGVudCB3aXRoICh4MCx5MCksIGxpbmUgdG8uXG4gICAgICBpZiAoTWF0aC5hYnModDAxIC0gMSkgPiBlcHNpbG9uJDEpIHtcbiAgICAgICAgdGhpcy5fICs9IFwiTFwiICsgKHgxICsgdDAxICogeDAxKSArIFwiLFwiICsgKHkxICsgdDAxICogeTAxKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fICs9IFwiQVwiICsgciArIFwiLFwiICsgciArIFwiLDAsMCxcIiArICgrKHkwMSAqIHgyMCA+IHgwMSAqIHkyMCkpICsgXCIsXCIgKyAodGhpcy5feDEgPSB4MSArIHQyMSAqIHgyMSkgKyBcIixcIiArICh0aGlzLl95MSA9IHkxICsgdDIxICogeTIxKTtcbiAgICB9XG4gIH0sXG4gIGFyYzogZnVuY3Rpb24oeCwgeSwgciwgYTAsIGExLCBjY3cpIHtcbiAgICB4ID0gK3gsIHkgPSAreSwgciA9ICtyO1xuICAgIHZhciBkeCA9IHIgKiBNYXRoLmNvcyhhMCksXG4gICAgICAgIGR5ID0gciAqIE1hdGguc2luKGEwKSxcbiAgICAgICAgeDAgPSB4ICsgZHgsXG4gICAgICAgIHkwID0geSArIGR5LFxuICAgICAgICBjdyA9IDEgXiBjY3csXG4gICAgICAgIGRhID0gY2N3ID8gYTAgLSBhMSA6IGExIC0gYTA7XG5cbiAgICAvLyBJcyB0aGUgcmFkaXVzIG5lZ2F0aXZlPyBFcnJvci5cbiAgICBpZiAociA8IDApIHRocm93IG5ldyBFcnJvcihcIm5lZ2F0aXZlIHJhZGl1czogXCIgKyByKTtcblxuICAgIC8vIElzIHRoaXMgcGF0aCBlbXB0eT8gTW92ZSB0byAoeDAseTApLlxuICAgIGlmICh0aGlzLl94MSA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5fICs9IFwiTVwiICsgeDAgKyBcIixcIiArIHkwO1xuICAgIH1cblxuICAgIC8vIE9yLCBpcyAoeDAseTApIG5vdCBjb2luY2lkZW50IHdpdGggdGhlIHByZXZpb3VzIHBvaW50PyBMaW5lIHRvICh4MCx5MCkuXG4gICAgZWxzZSBpZiAoTWF0aC5hYnModGhpcy5feDEgLSB4MCkgPiBlcHNpbG9uJDEgfHwgTWF0aC5hYnModGhpcy5feTEgLSB5MCkgPiBlcHNpbG9uJDEpIHtcbiAgICAgIHRoaXMuXyArPSBcIkxcIiArIHgwICsgXCIsXCIgKyB5MDtcbiAgICB9XG5cbiAgICAvLyBJcyB0aGlzIGFyYyBlbXB0eT8gV2XigJlyZSBkb25lLlxuICAgIGlmICghcikgcmV0dXJuO1xuXG4gICAgLy8gRG9lcyB0aGUgYW5nbGUgZ28gdGhlIHdyb25nIHdheT8gRmxpcCB0aGUgZGlyZWN0aW9uLlxuICAgIGlmIChkYSA8IDApIGRhID0gZGEgJSB0YXUkMiArIHRhdSQyO1xuXG4gICAgLy8gSXMgdGhpcyBhIGNvbXBsZXRlIGNpcmNsZT8gRHJhdyB0d28gYXJjcyB0byBjb21wbGV0ZSB0aGUgY2lyY2xlLlxuICAgIGlmIChkYSA+IHRhdUVwc2lsb24pIHtcbiAgICAgIHRoaXMuXyArPSBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiwwLDEsXCIgKyBjdyArIFwiLFwiICsgKHggLSBkeCkgKyBcIixcIiArICh5IC0gZHkpICsgXCJBXCIgKyByICsgXCIsXCIgKyByICsgXCIsMCwxLFwiICsgY3cgKyBcIixcIiArICh0aGlzLl94MSA9IHgwKSArIFwiLFwiICsgKHRoaXMuX3kxID0geTApO1xuICAgIH1cblxuICAgIC8vIElzIHRoaXMgYXJjIG5vbi1lbXB0eT8gRHJhdyBhbiBhcmMhXG4gICAgZWxzZSBpZiAoZGEgPiBlcHNpbG9uJDEpIHtcbiAgICAgIHRoaXMuXyArPSBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiwwLFwiICsgKCsoZGEgPj0gcGkkMikpICsgXCIsXCIgKyBjdyArIFwiLFwiICsgKHRoaXMuX3gxID0geCArIHIgKiBNYXRoLmNvcyhhMSkpICsgXCIsXCIgKyAodGhpcy5feTEgPSB5ICsgciAqIE1hdGguc2luKGExKSk7XG4gICAgfVxuICB9LFxuICByZWN0OiBmdW5jdGlvbih4LCB5LCB3LCBoKSB7XG4gICAgdGhpcy5fICs9IFwiTVwiICsgKHRoaXMuX3gwID0gdGhpcy5feDEgPSAreCkgKyBcIixcIiArICh0aGlzLl95MCA9IHRoaXMuX3kxID0gK3kpICsgXCJoXCIgKyAoK3cpICsgXCJ2XCIgKyAoK2gpICsgXCJoXCIgKyAoLXcpICsgXCJaXCI7XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fO1xuICB9XG59O1xuXG5mdW5jdGlvbiBkZWZhdWx0U291cmNlKGQpIHtcbiAgcmV0dXJuIGQuc291cmNlO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0VGFyZ2V0KGQpIHtcbiAgcmV0dXJuIGQudGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0UmFkaXVzKGQpIHtcbiAgcmV0dXJuIGQucmFkaXVzO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0U3RhcnRBbmdsZShkKSB7XG4gIHJldHVybiBkLnN0YXJ0QW5nbGU7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRFbmRBbmdsZShkKSB7XG4gIHJldHVybiBkLmVuZEFuZ2xlO1xufVxuXG52YXIgcmliYm9uID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzb3VyY2UgPSBkZWZhdWx0U291cmNlLFxuICAgICAgdGFyZ2V0ID0gZGVmYXVsdFRhcmdldCxcbiAgICAgIHJhZGl1cyA9IGRlZmF1bHRSYWRpdXMsXG4gICAgICBzdGFydEFuZ2xlID0gZGVmYXVsdFN0YXJ0QW5nbGUsXG4gICAgICBlbmRBbmdsZSA9IGRlZmF1bHRFbmRBbmdsZSxcbiAgICAgIGNvbnRleHQgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIHJpYmJvbigpIHtcbiAgICB2YXIgYnVmZmVyLFxuICAgICAgICBhcmd2ID0gc2xpY2UkMi5jYWxsKGFyZ3VtZW50cyksXG4gICAgICAgIHMgPSBzb3VyY2UuYXBwbHkodGhpcywgYXJndiksXG4gICAgICAgIHQgPSB0YXJnZXQuYXBwbHkodGhpcywgYXJndiksXG4gICAgICAgIHNyID0gK3JhZGl1cy5hcHBseSh0aGlzLCAoYXJndlswXSA9IHMsIGFyZ3YpKSxcbiAgICAgICAgc2EwID0gc3RhcnRBbmdsZS5hcHBseSh0aGlzLCBhcmd2KSAtIGhhbGZQaSQxLFxuICAgICAgICBzYTEgPSBlbmRBbmdsZS5hcHBseSh0aGlzLCBhcmd2KSAtIGhhbGZQaSQxLFxuICAgICAgICBzeDAgPSBzciAqIGNvcyhzYTApLFxuICAgICAgICBzeTAgPSBzciAqIHNpbihzYTApLFxuICAgICAgICB0ciA9ICtyYWRpdXMuYXBwbHkodGhpcywgKGFyZ3ZbMF0gPSB0LCBhcmd2KSksXG4gICAgICAgIHRhMCA9IHN0YXJ0QW5nbGUuYXBwbHkodGhpcywgYXJndikgLSBoYWxmUGkkMSxcbiAgICAgICAgdGExID0gZW5kQW5nbGUuYXBwbHkodGhpcywgYXJndikgLSBoYWxmUGkkMTtcblxuICAgIGlmICghY29udGV4dCkgY29udGV4dCA9IGJ1ZmZlciA9IHBhdGgoKTtcblxuICAgIGNvbnRleHQubW92ZVRvKHN4MCwgc3kwKTtcbiAgICBjb250ZXh0LmFyYygwLCAwLCBzciwgc2EwLCBzYTEpO1xuICAgIGlmIChzYTAgIT09IHRhMCB8fCBzYTEgIT09IHRhMSkgeyAvLyBUT0RPIHNyICE9PSB0cj9cbiAgICAgIGNvbnRleHQucXVhZHJhdGljQ3VydmVUbygwLCAwLCB0ciAqIGNvcyh0YTApLCB0ciAqIHNpbih0YTApKTtcbiAgICAgIGNvbnRleHQuYXJjKDAsIDAsIHRyLCB0YTAsIHRhMSk7XG4gICAgfVxuICAgIGNvbnRleHQucXVhZHJhdGljQ3VydmVUbygwLCAwLCBzeDAsIHN5MCk7XG4gICAgY29udGV4dC5jbG9zZVBhdGgoKTtcblxuICAgIGlmIChidWZmZXIpIHJldHVybiBjb250ZXh0ID0gbnVsbCwgYnVmZmVyICsgXCJcIiB8fCBudWxsO1xuICB9XG5cbiAgcmliYm9uLnJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYWRpdXMgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDUoK18pLCByaWJib24pIDogcmFkaXVzO1xuICB9O1xuXG4gIHJpYmJvbi5zdGFydEFuZ2xlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0YXJ0QW5nbGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDUoK18pLCByaWJib24pIDogc3RhcnRBbmdsZTtcbiAgfTtcblxuICByaWJib24uZW5kQW5nbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZW5kQW5nbGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDUoK18pLCByaWJib24pIDogZW5kQW5nbGU7XG4gIH07XG5cbiAgcmliYm9uLnNvdXJjZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzb3VyY2UgPSBfLCByaWJib24pIDogc291cmNlO1xuICB9O1xuXG4gIHJpYmJvbi50YXJnZXQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGFyZ2V0ID0gXywgcmliYm9uKSA6IHRhcmdldDtcbiAgfTtcblxuICByaWJib24uY29udGV4dCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICgoY29udGV4dCA9IF8gPT0gbnVsbCA/IG51bGwgOiBfKSwgcmliYm9uKSA6IGNvbnRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIHJpYmJvbjtcbn07XG5cbnZhciBwcmVmaXggPSBcIiRcIjtcblxuZnVuY3Rpb24gTWFwKCkge31cblxuTWFwLnByb3RvdHlwZSA9IG1hcCQxLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IE1hcCxcbiAgaGFzOiBmdW5jdGlvbihrZXkpIHtcbiAgICByZXR1cm4gKHByZWZpeCArIGtleSkgaW4gdGhpcztcbiAgfSxcbiAgZ2V0OiBmdW5jdGlvbihrZXkpIHtcbiAgICByZXR1cm4gdGhpc1twcmVmaXggKyBrZXldO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICB0aGlzW3ByZWZpeCArIGtleV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgcmVtb3ZlOiBmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgcHJvcGVydHkgPSBwcmVmaXggKyBrZXk7XG4gICAgcmV0dXJuIHByb3BlcnR5IGluIHRoaXMgJiYgZGVsZXRlIHRoaXNbcHJvcGVydHldO1xuICB9LFxuICBjbGVhcjogZnVuY3Rpb24oKSB7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpIGRlbGV0ZSB0aGlzW3Byb3BlcnR5XTtcbiAgfSxcbiAga2V5czogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiB0aGlzKSBpZiAocHJvcGVydHlbMF0gPT09IHByZWZpeCkga2V5cy5wdXNoKHByb3BlcnR5LnNsaWNlKDEpKTtcbiAgICByZXR1cm4ga2V5cztcbiAgfSxcbiAgdmFsdWVzOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpIHZhbHVlcy5wdXNoKHRoaXNbcHJvcGVydHldKTtcbiAgICByZXR1cm4gdmFsdWVzO1xuICB9LFxuICBlbnRyaWVzOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgZW50cmllcyA9IFtdO1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9wZXJ0eVswXSA9PT0gcHJlZml4KSBlbnRyaWVzLnB1c2goe2tleTogcHJvcGVydHkuc2xpY2UoMSksIHZhbHVlOiB0aGlzW3Byb3BlcnR5XX0pO1xuICAgIHJldHVybiBlbnRyaWVzO1xuICB9LFxuICBzaXplOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc2l6ZSA9IDA7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpICsrc2l6ZTtcbiAgICByZXR1cm4gc2l6ZTtcbiAgfSxcbiAgZW1wdHk6IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9wZXJ0eVswXSA9PT0gcHJlZml4KSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG4gIGVhY2g6IGZ1bmN0aW9uKGYpIHtcbiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiB0aGlzKSBpZiAocHJvcGVydHlbMF0gPT09IHByZWZpeCkgZih0aGlzW3Byb3BlcnR5XSwgcHJvcGVydHkuc2xpY2UoMSksIHRoaXMpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBtYXAkMShvYmplY3QsIGYpIHtcbiAgdmFyIG1hcCA9IG5ldyBNYXA7XG5cbiAgLy8gQ29weSBjb25zdHJ1Y3Rvci5cbiAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE1hcCkgb2JqZWN0LmVhY2goZnVuY3Rpb24odmFsdWUsIGtleSkgeyBtYXAuc2V0KGtleSwgdmFsdWUpOyB9KTtcblxuICAvLyBJbmRleCBhcnJheSBieSBudW1lcmljIGluZGV4IG9yIHNwZWNpZmllZCBrZXkgZnVuY3Rpb24uXG4gIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgIHZhciBpID0gLTEsXG4gICAgICAgIG4gPSBvYmplY3QubGVuZ3RoLFxuICAgICAgICBvO1xuXG4gICAgaWYgKGYgPT0gbnVsbCkgd2hpbGUgKCsraSA8IG4pIG1hcC5zZXQoaSwgb2JqZWN0W2ldKTtcbiAgICBlbHNlIHdoaWxlICgrK2kgPCBuKSBtYXAuc2V0KGYobyA9IG9iamVjdFtpXSwgaSwgb2JqZWN0KSwgbyk7XG4gIH1cblxuICAvLyBDb252ZXJ0IG9iamVjdCB0byBtYXAuXG4gIGVsc2UgaWYgKG9iamVjdCkgZm9yICh2YXIga2V5IGluIG9iamVjdCkgbWFwLnNldChrZXksIG9iamVjdFtrZXldKTtcblxuICByZXR1cm4gbWFwO1xufVxuXG52YXIgbmVzdCA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5cyA9IFtdLFxuICAgICAgc29ydEtleXMgPSBbXSxcbiAgICAgIHNvcnRWYWx1ZXMsXG4gICAgICByb2xsdXAsXG4gICAgICBuZXN0O1xuXG4gIGZ1bmN0aW9uIGFwcGx5KGFycmF5LCBkZXB0aCwgY3JlYXRlUmVzdWx0LCBzZXRSZXN1bHQpIHtcbiAgICBpZiAoZGVwdGggPj0ga2V5cy5sZW5ndGgpIHJldHVybiByb2xsdXAgIT0gbnVsbFxuICAgICAgICA/IHJvbGx1cChhcnJheSkgOiAoc29ydFZhbHVlcyAhPSBudWxsXG4gICAgICAgID8gYXJyYXkuc29ydChzb3J0VmFsdWVzKVxuICAgICAgICA6IGFycmF5KTtcblxuICAgIHZhciBpID0gLTEsXG4gICAgICAgIG4gPSBhcnJheS5sZW5ndGgsXG4gICAgICAgIGtleSA9IGtleXNbZGVwdGgrK10sXG4gICAgICAgIGtleVZhbHVlLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgdmFsdWVzQnlLZXkgPSBtYXAkMSgpLFxuICAgICAgICB2YWx1ZXMsXG4gICAgICAgIHJlc3VsdCA9IGNyZWF0ZVJlc3VsdCgpO1xuXG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIGlmICh2YWx1ZXMgPSB2YWx1ZXNCeUtleS5nZXQoa2V5VmFsdWUgPSBrZXkodmFsdWUgPSBhcnJheVtpXSkgKyBcIlwiKSkge1xuICAgICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZXNCeUtleS5zZXQoa2V5VmFsdWUsIFt2YWx1ZV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhbHVlc0J5S2V5LmVhY2goZnVuY3Rpb24odmFsdWVzLCBrZXkpIHtcbiAgICAgIHNldFJlc3VsdChyZXN1bHQsIGtleSwgYXBwbHkodmFsdWVzLCBkZXB0aCwgY3JlYXRlUmVzdWx0LCBzZXRSZXN1bHQpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBlbnRyaWVzKG1hcCwgZGVwdGgpIHtcbiAgICBpZiAoKytkZXB0aCA+IGtleXMubGVuZ3RoKSByZXR1cm4gbWFwO1xuICAgIHZhciBhcnJheSwgc29ydEtleSA9IHNvcnRLZXlzW2RlcHRoIC0gMV07XG4gICAgaWYgKHJvbGx1cCAhPSBudWxsICYmIGRlcHRoID49IGtleXMubGVuZ3RoKSBhcnJheSA9IG1hcC5lbnRyaWVzKCk7XG4gICAgZWxzZSBhcnJheSA9IFtdLCBtYXAuZWFjaChmdW5jdGlvbih2LCBrKSB7IGFycmF5LnB1c2goe2tleTogaywgdmFsdWVzOiBlbnRyaWVzKHYsIGRlcHRoKX0pOyB9KTtcbiAgICByZXR1cm4gc29ydEtleSAhPSBudWxsID8gYXJyYXkuc29ydChmdW5jdGlvbihhLCBiKSB7IHJldHVybiBzb3J0S2V5KGEua2V5LCBiLmtleSk7IH0pIDogYXJyYXk7XG4gIH1cblxuICByZXR1cm4gbmVzdCA9IHtcbiAgICBvYmplY3Q6IGZ1bmN0aW9uKGFycmF5KSB7IHJldHVybiBhcHBseShhcnJheSwgMCwgY3JlYXRlT2JqZWN0LCBzZXRPYmplY3QpOyB9LFxuICAgIG1hcDogZnVuY3Rpb24oYXJyYXkpIHsgcmV0dXJuIGFwcGx5KGFycmF5LCAwLCBjcmVhdGVNYXAsIHNldE1hcCk7IH0sXG4gICAgZW50cmllczogZnVuY3Rpb24oYXJyYXkpIHsgcmV0dXJuIGVudHJpZXMoYXBwbHkoYXJyYXksIDAsIGNyZWF0ZU1hcCwgc2V0TWFwKSwgMCk7IH0sXG4gICAga2V5OiBmdW5jdGlvbihkKSB7IGtleXMucHVzaChkKTsgcmV0dXJuIG5lc3Q7IH0sXG4gICAgc29ydEtleXM6IGZ1bmN0aW9uKG9yZGVyKSB7IHNvcnRLZXlzW2tleXMubGVuZ3RoIC0gMV0gPSBvcmRlcjsgcmV0dXJuIG5lc3Q7IH0sXG4gICAgc29ydFZhbHVlczogZnVuY3Rpb24ob3JkZXIpIHsgc29ydFZhbHVlcyA9IG9yZGVyOyByZXR1cm4gbmVzdDsgfSxcbiAgICByb2xsdXA6IGZ1bmN0aW9uKGYpIHsgcm9sbHVwID0gZjsgcmV0dXJuIG5lc3Q7IH1cbiAgfTtcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZU9iamVjdCgpIHtcbiAgcmV0dXJuIHt9O1xufVxuXG5mdW5jdGlvbiBzZXRPYmplY3Qob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU1hcCgpIHtcbiAgcmV0dXJuIG1hcCQxKCk7XG59XG5cbmZ1bmN0aW9uIHNldE1hcChtYXAsIGtleSwgdmFsdWUpIHtcbiAgbWFwLnNldChrZXksIHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gU2V0KCkge31cblxudmFyIHByb3RvID0gbWFwJDEucHJvdG90eXBlO1xuXG5TZXQucHJvdG90eXBlID0gc2V0JDIucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogU2V0LFxuICBoYXM6IHByb3RvLmhhcyxcbiAgYWRkOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhbHVlICs9IFwiXCI7XG4gICAgdGhpc1twcmVmaXggKyB2YWx1ZV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgcmVtb3ZlOiBwcm90by5yZW1vdmUsXG4gIGNsZWFyOiBwcm90by5jbGVhcixcbiAgdmFsdWVzOiBwcm90by5rZXlzLFxuICBzaXplOiBwcm90by5zaXplLFxuICBlbXB0eTogcHJvdG8uZW1wdHksXG4gIGVhY2g6IHByb3RvLmVhY2hcbn07XG5cbmZ1bmN0aW9uIHNldCQyKG9iamVjdCwgZikge1xuICB2YXIgc2V0ID0gbmV3IFNldDtcblxuICAvLyBDb3B5IGNvbnN0cnVjdG9yLlxuICBpZiAob2JqZWN0IGluc3RhbmNlb2YgU2V0KSBvYmplY3QuZWFjaChmdW5jdGlvbih2YWx1ZSkgeyBzZXQuYWRkKHZhbHVlKTsgfSk7XG5cbiAgLy8gT3RoZXJ3aXNlLCBhc3N1bWUgaXTigJlzIGFuIGFycmF5LlxuICBlbHNlIGlmIChvYmplY3QpIHtcbiAgICB2YXIgaSA9IC0xLCBuID0gb2JqZWN0Lmxlbmd0aDtcbiAgICBpZiAoZiA9PSBudWxsKSB3aGlsZSAoKytpIDwgbikgc2V0LmFkZChvYmplY3RbaV0pO1xuICAgIGVsc2Ugd2hpbGUgKCsraSA8IG4pIHNldC5hZGQoZihvYmplY3RbaV0sIGksIG9iamVjdCkpO1xuICB9XG5cbiAgcmV0dXJuIHNldDtcbn1cblxudmFyIGtleXMgPSBmdW5jdGlvbihtYXApIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG1hcCkga2V5cy5wdXNoKGtleSk7XG4gIHJldHVybiBrZXlzO1xufTtcblxudmFyIHZhbHVlcyA9IGZ1bmN0aW9uKG1hcCkge1xuICB2YXIgdmFsdWVzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBtYXApIHZhbHVlcy5wdXNoKG1hcFtrZXldKTtcbiAgcmV0dXJuIHZhbHVlcztcbn07XG5cbnZhciBlbnRyaWVzID0gZnVuY3Rpb24obWFwKSB7XG4gIHZhciBlbnRyaWVzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBtYXApIGVudHJpZXMucHVzaCh7a2V5OiBrZXksIHZhbHVlOiBtYXBba2V5XX0pO1xuICByZXR1cm4gZW50cmllcztcbn07XG5cbmZ1bmN0aW9uIG9iamVjdENvbnZlcnRlcihjb2x1bW5zKSB7XG4gIHJldHVybiBuZXcgRnVuY3Rpb24oXCJkXCIsIFwicmV0dXJuIHtcIiArIGNvbHVtbnMubWFwKGZ1bmN0aW9uKG5hbWUsIGkpIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobmFtZSkgKyBcIjogZFtcIiArIGkgKyBcIl1cIjtcbiAgfSkuam9pbihcIixcIikgKyBcIn1cIik7XG59XG5cbmZ1bmN0aW9uIGN1c3RvbUNvbnZlcnRlcihjb2x1bW5zLCBmKSB7XG4gIHZhciBvYmplY3QgPSBvYmplY3RDb252ZXJ0ZXIoY29sdW1ucyk7XG4gIHJldHVybiBmdW5jdGlvbihyb3csIGkpIHtcbiAgICByZXR1cm4gZihvYmplY3Qocm93KSwgaSwgY29sdW1ucyk7XG4gIH07XG59XG5cbi8vIENvbXB1dGUgdW5pcXVlIGNvbHVtbnMgaW4gb3JkZXIgb2YgZGlzY292ZXJ5LlxuZnVuY3Rpb24gaW5mZXJDb2x1bW5zKHJvd3MpIHtcbiAgdmFyIGNvbHVtblNldCA9IE9iamVjdC5jcmVhdGUobnVsbCksXG4gICAgICBjb2x1bW5zID0gW107XG5cbiAgcm93cy5mb3JFYWNoKGZ1bmN0aW9uKHJvdykge1xuICAgIGZvciAodmFyIGNvbHVtbiBpbiByb3cpIHtcbiAgICAgIGlmICghKGNvbHVtbiBpbiBjb2x1bW5TZXQpKSB7XG4gICAgICAgIGNvbHVtbnMucHVzaChjb2x1bW5TZXRbY29sdW1uXSA9IGNvbHVtbik7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gY29sdW1ucztcbn1cblxudmFyIGRzdiA9IGZ1bmN0aW9uKGRlbGltaXRlcikge1xuICB2YXIgcmVGb3JtYXQgPSBuZXcgUmVnRXhwKFwiW1xcXCJcIiArIGRlbGltaXRlciArIFwiXFxuXFxyXVwiKSxcbiAgICAgIGRlbGltaXRlckNvZGUgPSBkZWxpbWl0ZXIuY2hhckNvZGVBdCgwKTtcblxuICBmdW5jdGlvbiBwYXJzZSh0ZXh0LCBmKSB7XG4gICAgdmFyIGNvbnZlcnQsIGNvbHVtbnMsIHJvd3MgPSBwYXJzZVJvd3ModGV4dCwgZnVuY3Rpb24ocm93LCBpKSB7XG4gICAgICBpZiAoY29udmVydCkgcmV0dXJuIGNvbnZlcnQocm93LCBpIC0gMSk7XG4gICAgICBjb2x1bW5zID0gcm93LCBjb252ZXJ0ID0gZiA/IGN1c3RvbUNvbnZlcnRlcihyb3csIGYpIDogb2JqZWN0Q29udmVydGVyKHJvdyk7XG4gICAgfSk7XG4gICAgcm93cy5jb2x1bW5zID0gY29sdW1ucztcbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlUm93cyh0ZXh0LCBmKSB7XG4gICAgdmFyIEVPTCA9IHt9LCAvLyBzZW50aW5lbCB2YWx1ZSBmb3IgZW5kLW9mLWxpbmVcbiAgICAgICAgRU9GID0ge30sIC8vIHNlbnRpbmVsIHZhbHVlIGZvciBlbmQtb2YtZmlsZVxuICAgICAgICByb3dzID0gW10sIC8vIG91dHB1dCByb3dzXG4gICAgICAgIE4gPSB0ZXh0Lmxlbmd0aCxcbiAgICAgICAgSSA9IDAsIC8vIGN1cnJlbnQgY2hhcmFjdGVyIGluZGV4XG4gICAgICAgIG4gPSAwLCAvLyB0aGUgY3VycmVudCBsaW5lIG51bWJlclxuICAgICAgICB0LCAvLyB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICBlb2w7IC8vIGlzIHRoZSBjdXJyZW50IHRva2VuIGZvbGxvd2VkIGJ5IEVPTD9cblxuICAgIGZ1bmN0aW9uIHRva2VuKCkge1xuICAgICAgaWYgKEkgPj0gTikgcmV0dXJuIEVPRjsgLy8gc3BlY2lhbCBjYXNlOiBlbmQgb2YgZmlsZVxuICAgICAgaWYgKGVvbCkgcmV0dXJuIGVvbCA9IGZhbHNlLCBFT0w7IC8vIHNwZWNpYWwgY2FzZTogZW5kIG9mIGxpbmVcblxuICAgICAgLy8gc3BlY2lhbCBjYXNlOiBxdW90ZXNcbiAgICAgIHZhciBqID0gSSwgYztcbiAgICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoaikgPT09IDM0KSB7XG4gICAgICAgIHZhciBpID0gajtcbiAgICAgICAgd2hpbGUgKGkrKyA8IE4pIHtcbiAgICAgICAgICBpZiAodGV4dC5jaGFyQ29kZUF0KGkpID09PSAzNCkge1xuICAgICAgICAgICAgaWYgKHRleHQuY2hhckNvZGVBdChpICsgMSkgIT09IDM0KSBicmVhaztcbiAgICAgICAgICAgICsraTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgSSA9IGkgKyAyO1xuICAgICAgICBjID0gdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgICAgaWYgKGMgPT09IDEzKSB7XG4gICAgICAgICAgZW9sID0gdHJ1ZTtcbiAgICAgICAgICBpZiAodGV4dC5jaGFyQ29kZUF0KGkgKyAyKSA9PT0gMTApICsrSTtcbiAgICAgICAgfSBlbHNlIGlmIChjID09PSAxMCkge1xuICAgICAgICAgIGVvbCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRleHQuc2xpY2UoaiArIDEsIGkpLnJlcGxhY2UoL1wiXCIvZywgXCJcXFwiXCIpO1xuICAgICAgfVxuXG4gICAgICAvLyBjb21tb24gY2FzZTogZmluZCBuZXh0IGRlbGltaXRlciBvciBuZXdsaW5lXG4gICAgICB3aGlsZSAoSSA8IE4pIHtcbiAgICAgICAgdmFyIGsgPSAxO1xuICAgICAgICBjID0gdGV4dC5jaGFyQ29kZUF0KEkrKyk7XG4gICAgICAgIGlmIChjID09PSAxMCkgZW9sID0gdHJ1ZTsgLy8gXFxuXG4gICAgICAgIGVsc2UgaWYgKGMgPT09IDEzKSB7IGVvbCA9IHRydWU7IGlmICh0ZXh0LmNoYXJDb2RlQXQoSSkgPT09IDEwKSArK0ksICsrazsgfSAvLyBcXHJ8XFxyXFxuXG4gICAgICAgIGVsc2UgaWYgKGMgIT09IGRlbGltaXRlckNvZGUpIGNvbnRpbnVlO1xuICAgICAgICByZXR1cm4gdGV4dC5zbGljZShqLCBJIC0gayk7XG4gICAgICB9XG5cbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogbGFzdCB0b2tlbiBiZWZvcmUgRU9GXG4gICAgICByZXR1cm4gdGV4dC5zbGljZShqKTtcbiAgICB9XG5cbiAgICB3aGlsZSAoKHQgPSB0b2tlbigpKSAhPT0gRU9GKSB7XG4gICAgICB2YXIgYSA9IFtdO1xuICAgICAgd2hpbGUgKHQgIT09IEVPTCAmJiB0ICE9PSBFT0YpIHtcbiAgICAgICAgYS5wdXNoKHQpO1xuICAgICAgICB0ID0gdG9rZW4oKTtcbiAgICAgIH1cbiAgICAgIGlmIChmICYmIChhID0gZihhLCBuKyspKSA9PSBudWxsKSBjb250aW51ZTtcbiAgICAgIHJvd3MucHVzaChhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdChyb3dzLCBjb2x1bW5zKSB7XG4gICAgaWYgKGNvbHVtbnMgPT0gbnVsbCkgY29sdW1ucyA9IGluZmVyQ29sdW1ucyhyb3dzKTtcbiAgICByZXR1cm4gW2NvbHVtbnMubWFwKGZvcm1hdFZhbHVlKS5qb2luKGRlbGltaXRlcildLmNvbmNhdChyb3dzLm1hcChmdW5jdGlvbihyb3cpIHtcbiAgICAgIHJldHVybiBjb2x1bW5zLm1hcChmdW5jdGlvbihjb2x1bW4pIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdFZhbHVlKHJvd1tjb2x1bW5dKTtcbiAgICAgIH0pLmpvaW4oZGVsaW1pdGVyKTtcbiAgICB9KSkuam9pbihcIlxcblwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFJvd3Mocm93cykge1xuICAgIHJldHVybiByb3dzLm1hcChmb3JtYXRSb3cpLmpvaW4oXCJcXG5cIik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRSb3cocm93KSB7XG4gICAgcmV0dXJuIHJvdy5tYXAoZm9ybWF0VmFsdWUpLmpvaW4oZGVsaW1pdGVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFZhbHVlKHRleHQpIHtcbiAgICByZXR1cm4gdGV4dCA9PSBudWxsID8gXCJcIlxuICAgICAgICA6IHJlRm9ybWF0LnRlc3QodGV4dCArPSBcIlwiKSA/IFwiXFxcIlwiICsgdGV4dC5yZXBsYWNlKC9cXFwiL2csIFwiXFxcIlxcXCJcIikgKyBcIlxcXCJcIlxuICAgICAgICA6IHRleHQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHBhcnNlOiBwYXJzZSxcbiAgICBwYXJzZVJvd3M6IHBhcnNlUm93cyxcbiAgICBmb3JtYXQ6IGZvcm1hdCxcbiAgICBmb3JtYXRSb3dzOiBmb3JtYXRSb3dzXG4gIH07XG59O1xuXG52YXIgY3N2ID0gZHN2KFwiLFwiKTtcblxudmFyIGNzdlBhcnNlID0gY3N2LnBhcnNlO1xudmFyIGNzdlBhcnNlUm93cyA9IGNzdi5wYXJzZVJvd3M7XG52YXIgY3N2Rm9ybWF0ID0gY3N2LmZvcm1hdDtcbnZhciBjc3ZGb3JtYXRSb3dzID0gY3N2LmZvcm1hdFJvd3M7XG5cbnZhciB0c3YgPSBkc3YoXCJcXHRcIik7XG5cbnZhciB0c3ZQYXJzZSA9IHRzdi5wYXJzZTtcbnZhciB0c3ZQYXJzZVJvd3MgPSB0c3YucGFyc2VSb3dzO1xudmFyIHRzdkZvcm1hdCA9IHRzdi5mb3JtYXQ7XG52YXIgdHN2Rm9ybWF0Um93cyA9IHRzdi5mb3JtYXRSb3dzO1xuXG52YXIgY2VudGVyJDEgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHZhciBub2RlcztcblxuICBpZiAoeCA9PSBudWxsKSB4ID0gMDtcbiAgaWYgKHkgPT0gbnVsbCkgeSA9IDA7XG5cbiAgZnVuY3Rpb24gZm9yY2UoKSB7XG4gICAgdmFyIGksXG4gICAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIHN4ID0gMCxcbiAgICAgICAgc3kgPSAwO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZSA9IG5vZGVzW2ldLCBzeCArPSBub2RlLngsIHN5ICs9IG5vZGUueTtcbiAgICB9XG5cbiAgICBmb3IgKHN4ID0gc3ggLyBuIC0geCwgc3kgPSBzeSAvIG4gLSB5LCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZSA9IG5vZGVzW2ldLCBub2RlLnggLT0gc3gsIG5vZGUueSAtPSBzeTtcbiAgICB9XG4gIH1cblxuICBmb3JjZS5pbml0aWFsaXplID0gZnVuY3Rpb24oXykge1xuICAgIG5vZGVzID0gXztcbiAgfTtcblxuICBmb3JjZS54ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSArXywgZm9yY2UpIDogeDtcbiAgfTtcblxuICBmb3JjZS55ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkgPSArXywgZm9yY2UpIDogeTtcbiAgfTtcblxuICByZXR1cm4gZm9yY2U7XG59O1xuXG52YXIgY29uc3RhbnQkNiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxudmFyIGppZ2dsZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gKE1hdGgucmFuZG9tKCkgLSAwLjUpICogMWUtNjtcbn07XG5cbnZhciB0cmVlX2FkZCA9IGZ1bmN0aW9uKGQpIHtcbiAgdmFyIHggPSArdGhpcy5feC5jYWxsKG51bGwsIGQpLFxuICAgICAgeSA9ICt0aGlzLl95LmNhbGwobnVsbCwgZCk7XG4gIHJldHVybiBhZGQodGhpcy5jb3Zlcih4LCB5KSwgeCwgeSwgZCk7XG59O1xuXG5mdW5jdGlvbiBhZGQodHJlZSwgeCwgeSwgZCkge1xuICBpZiAoaXNOYU4oeCkgfHwgaXNOYU4oeSkpIHJldHVybiB0cmVlOyAvLyBpZ25vcmUgaW52YWxpZCBwb2ludHNcblxuICB2YXIgcGFyZW50LFxuICAgICAgbm9kZSA9IHRyZWUuX3Jvb3QsXG4gICAgICBsZWFmID0ge2RhdGE6IGR9LFxuICAgICAgeDAgPSB0cmVlLl94MCxcbiAgICAgIHkwID0gdHJlZS5feTAsXG4gICAgICB4MSA9IHRyZWUuX3gxLFxuICAgICAgeTEgPSB0cmVlLl95MSxcbiAgICAgIHhtLFxuICAgICAgeW0sXG4gICAgICB4cCxcbiAgICAgIHlwLFxuICAgICAgcmlnaHQsXG4gICAgICBib3R0b20sXG4gICAgICBpLFxuICAgICAgajtcblxuICAvLyBJZiB0aGUgdHJlZSBpcyBlbXB0eSwgaW5pdGlhbGl6ZSB0aGUgcm9vdCBhcyBhIGxlYWYuXG4gIGlmICghbm9kZSkgcmV0dXJuIHRyZWUuX3Jvb3QgPSBsZWFmLCB0cmVlO1xuXG4gIC8vIEZpbmQgdGhlIGV4aXN0aW5nIGxlYWYgZm9yIHRoZSBuZXcgcG9pbnQsIG9yIGFkZCBpdC5cbiAgd2hpbGUgKG5vZGUubGVuZ3RoKSB7XG4gICAgaWYgKHJpZ2h0ID0geCA+PSAoeG0gPSAoeDAgKyB4MSkgLyAyKSkgeDAgPSB4bTsgZWxzZSB4MSA9IHhtO1xuICAgIGlmIChib3R0b20gPSB5ID49ICh5bSA9ICh5MCArIHkxKSAvIDIpKSB5MCA9IHltOyBlbHNlIHkxID0geW07XG4gICAgaWYgKHBhcmVudCA9IG5vZGUsICEobm9kZSA9IG5vZGVbaSA9IGJvdHRvbSA8PCAxIHwgcmlnaHRdKSkgcmV0dXJuIHBhcmVudFtpXSA9IGxlYWYsIHRyZWU7XG4gIH1cblxuICAvLyBJcyB0aGUgbmV3IHBvaW50IGlzIGV4YWN0bHkgY29pbmNpZGVudCB3aXRoIHRoZSBleGlzdGluZyBwb2ludD9cbiAgeHAgPSArdHJlZS5feC5jYWxsKG51bGwsIG5vZGUuZGF0YSk7XG4gIHlwID0gK3RyZWUuX3kuY2FsbChudWxsLCBub2RlLmRhdGEpO1xuICBpZiAoeCA9PT0geHAgJiYgeSA9PT0geXApIHJldHVybiBsZWFmLm5leHQgPSBub2RlLCBwYXJlbnQgPyBwYXJlbnRbaV0gPSBsZWFmIDogdHJlZS5fcm9vdCA9IGxlYWYsIHRyZWU7XG5cbiAgLy8gT3RoZXJ3aXNlLCBzcGxpdCB0aGUgbGVhZiBub2RlIHVudGlsIHRoZSBvbGQgYW5kIG5ldyBwb2ludCBhcmUgc2VwYXJhdGVkLlxuICBkbyB7XG4gICAgcGFyZW50ID0gcGFyZW50ID8gcGFyZW50W2ldID0gbmV3IEFycmF5KDQpIDogdHJlZS5fcm9vdCA9IG5ldyBBcnJheSg0KTtcbiAgICBpZiAocmlnaHQgPSB4ID49ICh4bSA9ICh4MCArIHgxKSAvIDIpKSB4MCA9IHhtOyBlbHNlIHgxID0geG07XG4gICAgaWYgKGJvdHRvbSA9IHkgPj0gKHltID0gKHkwICsgeTEpIC8gMikpIHkwID0geW07IGVsc2UgeTEgPSB5bTtcbiAgfSB3aGlsZSAoKGkgPSBib3R0b20gPDwgMSB8IHJpZ2h0KSA9PT0gKGogPSAoeXAgPj0geW0pIDw8IDEgfCAoeHAgPj0geG0pKSk7XG4gIHJldHVybiBwYXJlbnRbal0gPSBub2RlLCBwYXJlbnRbaV0gPSBsZWFmLCB0cmVlO1xufVxuXG5mdW5jdGlvbiBhZGRBbGwoZGF0YSkge1xuICB2YXIgZCwgaSwgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgeCxcbiAgICAgIHksXG4gICAgICB4eiA9IG5ldyBBcnJheShuKSxcbiAgICAgIHl6ID0gbmV3IEFycmF5KG4pLFxuICAgICAgeDAgPSBJbmZpbml0eSxcbiAgICAgIHkwID0gSW5maW5pdHksXG4gICAgICB4MSA9IC1JbmZpbml0eSxcbiAgICAgIHkxID0gLUluZmluaXR5O1xuXG4gIC8vIENvbXB1dGUgdGhlIHBvaW50cyBhbmQgdGhlaXIgZXh0ZW50LlxuICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgaWYgKGlzTmFOKHggPSArdGhpcy5feC5jYWxsKG51bGwsIGQgPSBkYXRhW2ldKSkgfHwgaXNOYU4oeSA9ICt0aGlzLl95LmNhbGwobnVsbCwgZCkpKSBjb250aW51ZTtcbiAgICB4eltpXSA9IHg7XG4gICAgeXpbaV0gPSB5O1xuICAgIGlmICh4IDwgeDApIHgwID0geDtcbiAgICBpZiAoeCA+IHgxKSB4MSA9IHg7XG4gICAgaWYgKHkgPCB5MCkgeTAgPSB5O1xuICAgIGlmICh5ID4geTEpIHkxID0geTtcbiAgfVxuXG4gIC8vIElmIHRoZXJlIHdlcmUgbm8gKHZhbGlkKSBwb2ludHMsIGluaGVyaXQgdGhlIGV4aXN0aW5nIGV4dGVudC5cbiAgaWYgKHgxIDwgeDApIHgwID0gdGhpcy5feDAsIHgxID0gdGhpcy5feDE7XG4gIGlmICh5MSA8IHkwKSB5MCA9IHRoaXMuX3kwLCB5MSA9IHRoaXMuX3kxO1xuXG4gIC8vIEV4cGFuZCB0aGUgdHJlZSB0byBjb3ZlciB0aGUgbmV3IHBvaW50cy5cbiAgdGhpcy5jb3Zlcih4MCwgeTApLmNvdmVyKHgxLCB5MSk7XG5cbiAgLy8gQWRkIHRoZSBuZXcgcG9pbnRzLlxuICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgYWRkKHRoaXMsIHh6W2ldLCB5eltpXSwgZGF0YVtpXSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxudmFyIHRyZWVfY292ZXIgPSBmdW5jdGlvbih4LCB5KSB7XG4gIGlmIChpc05hTih4ID0gK3gpIHx8IGlzTmFOKHkgPSAreSkpIHJldHVybiB0aGlzOyAvLyBpZ25vcmUgaW52YWxpZCBwb2ludHNcblxuICB2YXIgeDAgPSB0aGlzLl94MCxcbiAgICAgIHkwID0gdGhpcy5feTAsXG4gICAgICB4MSA9IHRoaXMuX3gxLFxuICAgICAgeTEgPSB0aGlzLl95MTtcblxuICAvLyBJZiB0aGUgcXVhZHRyZWUgaGFzIG5vIGV4dGVudCwgaW5pdGlhbGl6ZSB0aGVtLlxuICAvLyBJbnRlZ2VyIGV4dGVudCBhcmUgbmVjZXNzYXJ5IHNvIHRoYXQgaWYgd2UgbGF0ZXIgZG91YmxlIHRoZSBleHRlbnQsXG4gIC8vIHRoZSBleGlzdGluZyBxdWFkcmFudCBib3VuZGFyaWVzIGRvbuKAmXQgY2hhbmdlIGR1ZSB0byBmbG9hdGluZyBwb2ludCBlcnJvciFcbiAgaWYgKGlzTmFOKHgwKSkge1xuICAgIHgxID0gKHgwID0gTWF0aC5mbG9vcih4KSkgKyAxO1xuICAgIHkxID0gKHkwID0gTWF0aC5mbG9vcih5KSkgKyAxO1xuICB9XG5cbiAgLy8gT3RoZXJ3aXNlLCBkb3VibGUgcmVwZWF0ZWRseSB0byBjb3Zlci5cbiAgZWxzZSBpZiAoeDAgPiB4IHx8IHggPiB4MSB8fCB5MCA+IHkgfHwgeSA+IHkxKSB7XG4gICAgdmFyIHogPSB4MSAtIHgwLFxuICAgICAgICBub2RlID0gdGhpcy5fcm9vdCxcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBpO1xuXG4gICAgc3dpdGNoIChpID0gKHkgPCAoeTAgKyB5MSkgLyAyKSA8PCAxIHwgKHggPCAoeDAgKyB4MSkgLyAyKSkge1xuICAgICAgY2FzZSAwOiB7XG4gICAgICAgIGRvIHBhcmVudCA9IG5ldyBBcnJheSg0KSwgcGFyZW50W2ldID0gbm9kZSwgbm9kZSA9IHBhcmVudDtcbiAgICAgICAgd2hpbGUgKHogKj0gMiwgeDEgPSB4MCArIHosIHkxID0geTAgKyB6LCB4ID4geDEgfHwgeSA+IHkxKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIDE6IHtcbiAgICAgICAgZG8gcGFyZW50ID0gbmV3IEFycmF5KDQpLCBwYXJlbnRbaV0gPSBub2RlLCBub2RlID0gcGFyZW50O1xuICAgICAgICB3aGlsZSAoeiAqPSAyLCB4MCA9IHgxIC0geiwgeTEgPSB5MCArIHosIHgwID4geCB8fCB5ID4geTEpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICBkbyBwYXJlbnQgPSBuZXcgQXJyYXkoNCksIHBhcmVudFtpXSA9IG5vZGUsIG5vZGUgPSBwYXJlbnQ7XG4gICAgICAgIHdoaWxlICh6ICo9IDIsIHgxID0geDAgKyB6LCB5MCA9IHkxIC0geiwgeCA+IHgxIHx8IHkwID4geSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAzOiB7XG4gICAgICAgIGRvIHBhcmVudCA9IG5ldyBBcnJheSg0KSwgcGFyZW50W2ldID0gbm9kZSwgbm9kZSA9IHBhcmVudDtcbiAgICAgICAgd2hpbGUgKHogKj0gMiwgeDAgPSB4MSAtIHosIHkwID0geTEgLSB6LCB4MCA+IHggfHwgeTAgPiB5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3Jvb3QgJiYgdGhpcy5fcm9vdC5sZW5ndGgpIHRoaXMuX3Jvb3QgPSBub2RlO1xuICB9XG5cbiAgLy8gSWYgdGhlIHF1YWR0cmVlIGNvdmVycyB0aGUgcG9pbnQgYWxyZWFkeSwganVzdCByZXR1cm4uXG4gIGVsc2UgcmV0dXJuIHRoaXM7XG5cbiAgdGhpcy5feDAgPSB4MDtcbiAgdGhpcy5feTAgPSB5MDtcbiAgdGhpcy5feDEgPSB4MTtcbiAgdGhpcy5feTEgPSB5MTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG52YXIgdHJlZV9kYXRhID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkYXRhID0gW107XG4gIHRoaXMudmlzaXQoZnVuY3Rpb24obm9kZSkge1xuICAgIGlmICghbm9kZS5sZW5ndGgpIGRvIGRhdGEucHVzaChub2RlLmRhdGEpOyB3aGlsZSAobm9kZSA9IG5vZGUubmV4dClcbiAgfSk7XG4gIHJldHVybiBkYXRhO1xufTtcblxudmFyIHRyZWVfZXh0ZW50ID0gZnVuY3Rpb24oXykge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgPyB0aGlzLmNvdmVyKCtfWzBdWzBdLCArX1swXVsxXSkuY292ZXIoK19bMV1bMF0sICtfWzFdWzFdKVxuICAgICAgOiBpc05hTih0aGlzLl94MCkgPyB1bmRlZmluZWQgOiBbW3RoaXMuX3gwLCB0aGlzLl95MF0sIFt0aGlzLl94MSwgdGhpcy5feTFdXTtcbn07XG5cbnZhciBRdWFkID0gZnVuY3Rpb24obm9kZSwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgdGhpcy5ub2RlID0gbm9kZTtcbiAgdGhpcy54MCA9IHgwO1xuICB0aGlzLnkwID0geTA7XG4gIHRoaXMueDEgPSB4MTtcbiAgdGhpcy55MSA9IHkxO1xufTtcblxudmFyIHRyZWVfZmluZCA9IGZ1bmN0aW9uKHgsIHksIHJhZGl1cykge1xuICB2YXIgZGF0YSxcbiAgICAgIHgwID0gdGhpcy5feDAsXG4gICAgICB5MCA9IHRoaXMuX3kwLFxuICAgICAgeDEsXG4gICAgICB5MSxcbiAgICAgIHgyLFxuICAgICAgeTIsXG4gICAgICB4MyA9IHRoaXMuX3gxLFxuICAgICAgeTMgPSB0aGlzLl95MSxcbiAgICAgIHF1YWRzID0gW10sXG4gICAgICBub2RlID0gdGhpcy5fcm9vdCxcbiAgICAgIHEsXG4gICAgICBpO1xuXG4gIGlmIChub2RlKSBxdWFkcy5wdXNoKG5ldyBRdWFkKG5vZGUsIHgwLCB5MCwgeDMsIHkzKSk7XG4gIGlmIChyYWRpdXMgPT0gbnVsbCkgcmFkaXVzID0gSW5maW5pdHk7XG4gIGVsc2Uge1xuICAgIHgwID0geCAtIHJhZGl1cywgeTAgPSB5IC0gcmFkaXVzO1xuICAgIHgzID0geCArIHJhZGl1cywgeTMgPSB5ICsgcmFkaXVzO1xuICAgIHJhZGl1cyAqPSByYWRpdXM7XG4gIH1cblxuICB3aGlsZSAocSA9IHF1YWRzLnBvcCgpKSB7XG5cbiAgICAvLyBTdG9wIHNlYXJjaGluZyBpZiB0aGlzIHF1YWRyYW50IGNhbuKAmXQgY29udGFpbiBhIGNsb3NlciBub2RlLlxuICAgIGlmICghKG5vZGUgPSBxLm5vZGUpXG4gICAgICAgIHx8ICh4MSA9IHEueDApID4geDNcbiAgICAgICAgfHwgKHkxID0gcS55MCkgPiB5M1xuICAgICAgICB8fCAoeDIgPSBxLngxKSA8IHgwXG4gICAgICAgIHx8ICh5MiA9IHEueTEpIDwgeTApIGNvbnRpbnVlO1xuXG4gICAgLy8gQmlzZWN0IHRoZSBjdXJyZW50IHF1YWRyYW50LlxuICAgIGlmIChub2RlLmxlbmd0aCkge1xuICAgICAgdmFyIHhtID0gKHgxICsgeDIpIC8gMixcbiAgICAgICAgICB5bSA9ICh5MSArIHkyKSAvIDI7XG5cbiAgICAgIHF1YWRzLnB1c2goXG4gICAgICAgIG5ldyBRdWFkKG5vZGVbM10sIHhtLCB5bSwgeDIsIHkyKSxcbiAgICAgICAgbmV3IFF1YWQobm9kZVsyXSwgeDEsIHltLCB4bSwgeTIpLFxuICAgICAgICBuZXcgUXVhZChub2RlWzFdLCB4bSwgeTEsIHgyLCB5bSksXG4gICAgICAgIG5ldyBRdWFkKG5vZGVbMF0sIHgxLCB5MSwgeG0sIHltKVxuICAgICAgKTtcblxuICAgICAgLy8gVmlzaXQgdGhlIGNsb3Nlc3QgcXVhZHJhbnQgZmlyc3QuXG4gICAgICBpZiAoaSA9ICh5ID49IHltKSA8PCAxIHwgKHggPj0geG0pKSB7XG4gICAgICAgIHEgPSBxdWFkc1txdWFkcy5sZW5ndGggLSAxXTtcbiAgICAgICAgcXVhZHNbcXVhZHMubGVuZ3RoIC0gMV0gPSBxdWFkc1txdWFkcy5sZW5ndGggLSAxIC0gaV07XG4gICAgICAgIHF1YWRzW3F1YWRzLmxlbmd0aCAtIDEgLSBpXSA9IHE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmlzaXQgdGhpcyBwb2ludC4gKFZpc2l0aW5nIGNvaW5jaWRlbnQgcG9pbnRzIGlzbuKAmXQgbmVjZXNzYXJ5ISlcbiAgICBlbHNlIHtcbiAgICAgIHZhciBkeCA9IHggLSArdGhpcy5feC5jYWxsKG51bGwsIG5vZGUuZGF0YSksXG4gICAgICAgICAgZHkgPSB5IC0gK3RoaXMuX3kuY2FsbChudWxsLCBub2RlLmRhdGEpLFxuICAgICAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHk7XG4gICAgICBpZiAoZDIgPCByYWRpdXMpIHtcbiAgICAgICAgdmFyIGQgPSBNYXRoLnNxcnQocmFkaXVzID0gZDIpO1xuICAgICAgICB4MCA9IHggLSBkLCB5MCA9IHkgLSBkO1xuICAgICAgICB4MyA9IHggKyBkLCB5MyA9IHkgKyBkO1xuICAgICAgICBkYXRhID0gbm9kZS5kYXRhO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkYXRhO1xufTtcblxudmFyIHRyZWVfcmVtb3ZlID0gZnVuY3Rpb24oZCkge1xuICBpZiAoaXNOYU4oeCA9ICt0aGlzLl94LmNhbGwobnVsbCwgZCkpIHx8IGlzTmFOKHkgPSArdGhpcy5feS5jYWxsKG51bGwsIGQpKSkgcmV0dXJuIHRoaXM7IC8vIGlnbm9yZSBpbnZhbGlkIHBvaW50c1xuXG4gIHZhciBwYXJlbnQsXG4gICAgICBub2RlID0gdGhpcy5fcm9vdCxcbiAgICAgIHJldGFpbmVyLFxuICAgICAgcHJldmlvdXMsXG4gICAgICBuZXh0LFxuICAgICAgeDAgPSB0aGlzLl94MCxcbiAgICAgIHkwID0gdGhpcy5feTAsXG4gICAgICB4MSA9IHRoaXMuX3gxLFxuICAgICAgeTEgPSB0aGlzLl95MSxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgeG0sXG4gICAgICB5bSxcbiAgICAgIHJpZ2h0LFxuICAgICAgYm90dG9tLFxuICAgICAgaSxcbiAgICAgIGo7XG5cbiAgLy8gSWYgdGhlIHRyZWUgaXMgZW1wdHksIGluaXRpYWxpemUgdGhlIHJvb3QgYXMgYSBsZWFmLlxuICBpZiAoIW5vZGUpIHJldHVybiB0aGlzO1xuXG4gIC8vIEZpbmQgdGhlIGxlYWYgbm9kZSBmb3IgdGhlIHBvaW50LlxuICAvLyBXaGlsZSBkZXNjZW5kaW5nLCBhbHNvIHJldGFpbiB0aGUgZGVlcGVzdCBwYXJlbnQgd2l0aCBhIG5vbi1yZW1vdmVkIHNpYmxpbmcuXG4gIGlmIChub2RlLmxlbmd0aCkgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAocmlnaHQgPSB4ID49ICh4bSA9ICh4MCArIHgxKSAvIDIpKSB4MCA9IHhtOyBlbHNlIHgxID0geG07XG4gICAgaWYgKGJvdHRvbSA9IHkgPj0gKHltID0gKHkwICsgeTEpIC8gMikpIHkwID0geW07IGVsc2UgeTEgPSB5bTtcbiAgICBpZiAoIShwYXJlbnQgPSBub2RlLCBub2RlID0gbm9kZVtpID0gYm90dG9tIDw8IDEgfCByaWdodF0pKSByZXR1cm4gdGhpcztcbiAgICBpZiAoIW5vZGUubGVuZ3RoKSBicmVhaztcbiAgICBpZiAocGFyZW50WyhpICsgMSkgJiAzXSB8fCBwYXJlbnRbKGkgKyAyKSAmIDNdIHx8IHBhcmVudFsoaSArIDMpICYgM10pIHJldGFpbmVyID0gcGFyZW50LCBqID0gaTtcbiAgfVxuXG4gIC8vIEZpbmQgdGhlIHBvaW50IHRvIHJlbW92ZS5cbiAgd2hpbGUgKG5vZGUuZGF0YSAhPT0gZCkgaWYgKCEocHJldmlvdXMgPSBub2RlLCBub2RlID0gbm9kZS5uZXh0KSkgcmV0dXJuIHRoaXM7XG4gIGlmIChuZXh0ID0gbm9kZS5uZXh0KSBkZWxldGUgbm9kZS5uZXh0O1xuXG4gIC8vIElmIHRoZXJlIGFyZSBtdWx0aXBsZSBjb2luY2lkZW50IHBvaW50cywgcmVtb3ZlIGp1c3QgdGhlIHBvaW50LlxuICBpZiAocHJldmlvdXMpIHJldHVybiAobmV4dCA/IHByZXZpb3VzLm5leHQgPSBuZXh0IDogZGVsZXRlIHByZXZpb3VzLm5leHQpLCB0aGlzO1xuXG4gIC8vIElmIHRoaXMgaXMgdGhlIHJvb3QgcG9pbnQsIHJlbW92ZSBpdC5cbiAgaWYgKCFwYXJlbnQpIHJldHVybiB0aGlzLl9yb290ID0gbmV4dCwgdGhpcztcblxuICAvLyBSZW1vdmUgdGhpcyBsZWFmLlxuICBuZXh0ID8gcGFyZW50W2ldID0gbmV4dCA6IGRlbGV0ZSBwYXJlbnRbaV07XG5cbiAgLy8gSWYgdGhlIHBhcmVudCBub3cgY29udGFpbnMgZXhhY3RseSBvbmUgbGVhZiwgY29sbGFwc2Ugc3VwZXJmbHVvdXMgcGFyZW50cy5cbiAgaWYgKChub2RlID0gcGFyZW50WzBdIHx8IHBhcmVudFsxXSB8fCBwYXJlbnRbMl0gfHwgcGFyZW50WzNdKVxuICAgICAgJiYgbm9kZSA9PT0gKHBhcmVudFszXSB8fCBwYXJlbnRbMl0gfHwgcGFyZW50WzFdIHx8IHBhcmVudFswXSlcbiAgICAgICYmICFub2RlLmxlbmd0aCkge1xuICAgIGlmIChyZXRhaW5lcikgcmV0YWluZXJbal0gPSBub2RlO1xuICAgIGVsc2UgdGhpcy5fcm9vdCA9IG5vZGU7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHJlbW92ZUFsbChkYXRhKSB7XG4gIGZvciAodmFyIGkgPSAwLCBuID0gZGF0YS5sZW5ndGg7IGkgPCBuOyArK2kpIHRoaXMucmVtb3ZlKGRhdGFbaV0pO1xuICByZXR1cm4gdGhpcztcbn1cblxudmFyIHRyZWVfcm9vdCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fcm9vdDtcbn07XG5cbnZhciB0cmVlX3NpemUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNpemUgPSAwO1xuICB0aGlzLnZpc2l0KGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUubGVuZ3RoKSBkbyArK3NpemU7IHdoaWxlIChub2RlID0gbm9kZS5uZXh0KVxuICB9KTtcbiAgcmV0dXJuIHNpemU7XG59O1xuXG52YXIgdHJlZV92aXNpdCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHZhciBxdWFkcyA9IFtdLCBxLCBub2RlID0gdGhpcy5fcm9vdCwgY2hpbGQsIHgwLCB5MCwgeDEsIHkxO1xuICBpZiAobm9kZSkgcXVhZHMucHVzaChuZXcgUXVhZChub2RlLCB0aGlzLl94MCwgdGhpcy5feTAsIHRoaXMuX3gxLCB0aGlzLl95MSkpO1xuICB3aGlsZSAocSA9IHF1YWRzLnBvcCgpKSB7XG4gICAgaWYgKCFjYWxsYmFjayhub2RlID0gcS5ub2RlLCB4MCA9IHEueDAsIHkwID0gcS55MCwgeDEgPSBxLngxLCB5MSA9IHEueTEpICYmIG5vZGUubGVuZ3RoKSB7XG4gICAgICB2YXIgeG0gPSAoeDAgKyB4MSkgLyAyLCB5bSA9ICh5MCArIHkxKSAvIDI7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzNdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4bSwgeW0sIHgxLCB5MSkpO1xuICAgICAgaWYgKGNoaWxkID0gbm9kZVsyXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeDAsIHltLCB4bSwgeTEpKTtcbiAgICAgIGlmIChjaGlsZCA9IG5vZGVbMV0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hpbGQsIHhtLCB5MCwgeDEsIHltKSk7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzBdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4MCwgeTAsIHhtLCB5bSkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbnZhciB0cmVlX3Zpc2l0QWZ0ZXIgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgcXVhZHMgPSBbXSwgbmV4dCA9IFtdLCBxO1xuICBpZiAodGhpcy5fcm9vdCkgcXVhZHMucHVzaChuZXcgUXVhZCh0aGlzLl9yb290LCB0aGlzLl94MCwgdGhpcy5feTAsIHRoaXMuX3gxLCB0aGlzLl95MSkpO1xuICB3aGlsZSAocSA9IHF1YWRzLnBvcCgpKSB7XG4gICAgdmFyIG5vZGUgPSBxLm5vZGU7XG4gICAgaWYgKG5vZGUubGVuZ3RoKSB7XG4gICAgICB2YXIgY2hpbGQsIHgwID0gcS54MCwgeTAgPSBxLnkwLCB4MSA9IHEueDEsIHkxID0gcS55MSwgeG0gPSAoeDAgKyB4MSkgLyAyLCB5bSA9ICh5MCArIHkxKSAvIDI7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzBdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4MCwgeTAsIHhtLCB5bSkpO1xuICAgICAgaWYgKGNoaWxkID0gbm9kZVsxXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeG0sIHkwLCB4MSwgeW0pKTtcbiAgICAgIGlmIChjaGlsZCA9IG5vZGVbMl0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hpbGQsIHgwLCB5bSwgeG0sIHkxKSk7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzNdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4bSwgeW0sIHgxLCB5MSkpO1xuICAgIH1cbiAgICBuZXh0LnB1c2gocSk7XG4gIH1cbiAgd2hpbGUgKHEgPSBuZXh0LnBvcCgpKSB7XG4gICAgY2FsbGJhY2socS5ub2RlLCBxLngwLCBxLnkwLCBxLngxLCBxLnkxKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGRlZmF1bHRYKGQpIHtcbiAgcmV0dXJuIGRbMF07XG59XG5cbnZhciB0cmVlX3ggPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRoaXMuX3ggPSBfLCB0aGlzKSA6IHRoaXMuX3g7XG59O1xuXG5mdW5jdGlvbiBkZWZhdWx0WShkKSB7XG4gIHJldHVybiBkWzFdO1xufVxuXG52YXIgdHJlZV95ID0gZnVuY3Rpb24oXykge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aGlzLl95ID0gXywgdGhpcykgOiB0aGlzLl95O1xufTtcblxuZnVuY3Rpb24gcXVhZHRyZWUobm9kZXMsIHgsIHkpIHtcbiAgdmFyIHRyZWUgPSBuZXcgUXVhZHRyZWUoeCA9PSBudWxsID8gZGVmYXVsdFggOiB4LCB5ID09IG51bGwgPyBkZWZhdWx0WSA6IHksIE5hTiwgTmFOLCBOYU4sIE5hTik7XG4gIHJldHVybiBub2RlcyA9PSBudWxsID8gdHJlZSA6IHRyZWUuYWRkQWxsKG5vZGVzKTtcbn1cblxuZnVuY3Rpb24gUXVhZHRyZWUoeCwgeSwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgdGhpcy5feCA9IHg7XG4gIHRoaXMuX3kgPSB5O1xuICB0aGlzLl94MCA9IHgwO1xuICB0aGlzLl95MCA9IHkwO1xuICB0aGlzLl94MSA9IHgxO1xuICB0aGlzLl95MSA9IHkxO1xuICB0aGlzLl9yb290ID0gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBsZWFmX2NvcHkobGVhZikge1xuICB2YXIgY29weSA9IHtkYXRhOiBsZWFmLmRhdGF9LCBuZXh0ID0gY29weTtcbiAgd2hpbGUgKGxlYWYgPSBsZWFmLm5leHQpIG5leHQgPSBuZXh0Lm5leHQgPSB7ZGF0YTogbGVhZi5kYXRhfTtcbiAgcmV0dXJuIGNvcHk7XG59XG5cbnZhciB0cmVlUHJvdG8gPSBxdWFkdHJlZS5wcm90b3R5cGUgPSBRdWFkdHJlZS5wcm90b3R5cGU7XG5cbnRyZWVQcm90by5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjb3B5ID0gbmV3IFF1YWR0cmVlKHRoaXMuX3gsIHRoaXMuX3ksIHRoaXMuX3gwLCB0aGlzLl95MCwgdGhpcy5feDEsIHRoaXMuX3kxKSxcbiAgICAgIG5vZGUgPSB0aGlzLl9yb290LFxuICAgICAgbm9kZXMsXG4gICAgICBjaGlsZDtcblxuICBpZiAoIW5vZGUpIHJldHVybiBjb3B5O1xuXG4gIGlmICghbm9kZS5sZW5ndGgpIHJldHVybiBjb3B5Ll9yb290ID0gbGVhZl9jb3B5KG5vZGUpLCBjb3B5O1xuXG4gIG5vZGVzID0gW3tzb3VyY2U6IG5vZGUsIHRhcmdldDogY29weS5fcm9vdCA9IG5ldyBBcnJheSg0KX1dO1xuICB3aGlsZSAobm9kZSA9IG5vZGVzLnBvcCgpKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyArK2kpIHtcbiAgICAgIGlmIChjaGlsZCA9IG5vZGUuc291cmNlW2ldKSB7XG4gICAgICAgIGlmIChjaGlsZC5sZW5ndGgpIG5vZGVzLnB1c2goe3NvdXJjZTogY2hpbGQsIHRhcmdldDogbm9kZS50YXJnZXRbaV0gPSBuZXcgQXJyYXkoNCl9KTtcbiAgICAgICAgZWxzZSBub2RlLnRhcmdldFtpXSA9IGxlYWZfY29weShjaGlsZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvcHk7XG59O1xuXG50cmVlUHJvdG8uYWRkID0gdHJlZV9hZGQ7XG50cmVlUHJvdG8uYWRkQWxsID0gYWRkQWxsO1xudHJlZVByb3RvLmNvdmVyID0gdHJlZV9jb3ZlcjtcbnRyZWVQcm90by5kYXRhID0gdHJlZV9kYXRhO1xudHJlZVByb3RvLmV4dGVudCA9IHRyZWVfZXh0ZW50O1xudHJlZVByb3RvLmZpbmQgPSB0cmVlX2ZpbmQ7XG50cmVlUHJvdG8ucmVtb3ZlID0gdHJlZV9yZW1vdmU7XG50cmVlUHJvdG8ucmVtb3ZlQWxsID0gcmVtb3ZlQWxsO1xudHJlZVByb3RvLnJvb3QgPSB0cmVlX3Jvb3Q7XG50cmVlUHJvdG8uc2l6ZSA9IHRyZWVfc2l6ZTtcbnRyZWVQcm90by52aXNpdCA9IHRyZWVfdmlzaXQ7XG50cmVlUHJvdG8udmlzaXRBZnRlciA9IHRyZWVfdmlzaXRBZnRlcjtcbnRyZWVQcm90by54ID0gdHJlZV94O1xudHJlZVByb3RvLnkgPSB0cmVlX3k7XG5cbmZ1bmN0aW9uIHgoZCkge1xuICByZXR1cm4gZC54ICsgZC52eDtcbn1cblxuZnVuY3Rpb24geShkKSB7XG4gIHJldHVybiBkLnkgKyBkLnZ5O1xufVxuXG52YXIgY29sbGlkZSA9IGZ1bmN0aW9uKHJhZGl1cykge1xuICB2YXIgbm9kZXMsXG4gICAgICByYWRpaSxcbiAgICAgIHN0cmVuZ3RoID0gMSxcbiAgICAgIGl0ZXJhdGlvbnMgPSAxO1xuXG4gIGlmICh0eXBlb2YgcmFkaXVzICE9PSBcImZ1bmN0aW9uXCIpIHJhZGl1cyA9IGNvbnN0YW50JDYocmFkaXVzID09IG51bGwgPyAxIDogK3JhZGl1cyk7XG5cbiAgZnVuY3Rpb24gZm9yY2UoKSB7XG4gICAgdmFyIGksIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICAgIHRyZWUsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIHhpLFxuICAgICAgICB5aSxcbiAgICAgICAgcmksXG4gICAgICAgIHJpMjtcblxuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgaXRlcmF0aW9uczsgKytrKSB7XG4gICAgICB0cmVlID0gcXVhZHRyZWUobm9kZXMsIHgsIHkpLnZpc2l0QWZ0ZXIocHJlcGFyZSk7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgcmkgPSByYWRpaVtub2RlLmluZGV4XSwgcmkyID0gcmkgKiByaTtcbiAgICAgICAgeGkgPSBub2RlLnggKyBub2RlLnZ4O1xuICAgICAgICB5aSA9IG5vZGUueSArIG5vZGUudnk7XG4gICAgICAgIHRyZWUudmlzaXQoYXBwbHkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFwcGx5KHF1YWQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgICB2YXIgZGF0YSA9IHF1YWQuZGF0YSwgcmogPSBxdWFkLnIsIHIgPSByaSArIHJqO1xuICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgaWYgKGRhdGEuaW5kZXggPiBub2RlLmluZGV4KSB7XG4gICAgICAgICAgdmFyIHggPSB4aSAtIGRhdGEueCAtIGRhdGEudngsXG4gICAgICAgICAgICAgIHkgPSB5aSAtIGRhdGEueSAtIGRhdGEudnksXG4gICAgICAgICAgICAgIGwgPSB4ICogeCArIHkgKiB5O1xuICAgICAgICAgIGlmIChsIDwgciAqIHIpIHtcbiAgICAgICAgICAgIGlmICh4ID09PSAwKSB4ID0gamlnZ2xlKCksIGwgKz0geCAqIHg7XG4gICAgICAgICAgICBpZiAoeSA9PT0gMCkgeSA9IGppZ2dsZSgpLCBsICs9IHkgKiB5O1xuICAgICAgICAgICAgbCA9IChyIC0gKGwgPSBNYXRoLnNxcnQobCkpKSAvIGwgKiBzdHJlbmd0aDtcbiAgICAgICAgICAgIG5vZGUudnggKz0gKHggKj0gbCkgKiAociA9IChyaiAqPSByaikgLyAocmkyICsgcmopKTtcbiAgICAgICAgICAgIG5vZGUudnkgKz0gKHkgKj0gbCkgKiByO1xuICAgICAgICAgICAgZGF0YS52eCAtPSB4ICogKHIgPSAxIC0gcik7XG4gICAgICAgICAgICBkYXRhLnZ5IC09IHkgKiByO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICByZXR1cm4geDAgPiB4aSArIHIgfHwgeDEgPCB4aSAtIHIgfHwgeTAgPiB5aSArIHIgfHwgeTEgPCB5aSAtIHI7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcHJlcGFyZShxdWFkKSB7XG4gICAgaWYgKHF1YWQuZGF0YSkgcmV0dXJuIHF1YWQuciA9IHJhZGlpW3F1YWQuZGF0YS5pbmRleF07XG4gICAgZm9yICh2YXIgaSA9IHF1YWQuciA9IDA7IGkgPCA0OyArK2kpIHtcbiAgICAgIGlmIChxdWFkW2ldICYmIHF1YWRbaV0uciA+IHF1YWQucikge1xuICAgICAgICBxdWFkLnIgPSBxdWFkW2ldLnI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpIHtcbiAgICBpZiAoIW5vZGVzKSByZXR1cm47XG4gICAgdmFyIGksIG4gPSBub2Rlcy5sZW5ndGgsIG5vZGU7XG4gICAgcmFkaWkgPSBuZXcgQXJyYXkobik7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgbm9kZSA9IG5vZGVzW2ldLCByYWRpaVtub2RlLmluZGV4XSA9ICtyYWRpdXMobm9kZSwgaSwgbm9kZXMpO1xuICB9XG5cbiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBub2RlcyA9IF87XG4gICAgaW5pdGlhbGl6ZSgpO1xuICB9O1xuXG4gIGZvcmNlLml0ZXJhdGlvbnMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaXRlcmF0aW9ucyA9ICtfLCBmb3JjZSkgOiBpdGVyYXRpb25zO1xuICB9O1xuXG4gIGZvcmNlLnN0cmVuZ3RoID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3RoID0gK18sIGZvcmNlKSA6IHN0cmVuZ3RoO1xuICB9O1xuXG4gIGZvcmNlLnJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYWRpdXMgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDYoK18pLCBpbml0aWFsaXplKCksIGZvcmNlKSA6IHJhZGl1cztcbiAgfTtcblxuICByZXR1cm4gZm9yY2U7XG59O1xuXG5mdW5jdGlvbiBpbmRleChkKSB7XG4gIHJldHVybiBkLmluZGV4O1xufVxuXG5mdW5jdGlvbiBmaW5kKG5vZGVCeUlkLCBub2RlSWQpIHtcbiAgdmFyIG5vZGUgPSBub2RlQnlJZC5nZXQobm9kZUlkKTtcbiAgaWYgKCFub2RlKSB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nOiBcIiArIG5vZGVJZCk7XG4gIHJldHVybiBub2RlO1xufVxuXG52YXIgbGluayA9IGZ1bmN0aW9uKGxpbmtzKSB7XG4gIHZhciBpZCA9IGluZGV4LFxuICAgICAgc3RyZW5ndGggPSBkZWZhdWx0U3RyZW5ndGgsXG4gICAgICBzdHJlbmd0aHMsXG4gICAgICBkaXN0YW5jZSA9IGNvbnN0YW50JDYoMzApLFxuICAgICAgZGlzdGFuY2VzLFxuICAgICAgbm9kZXMsXG4gICAgICBjb3VudCxcbiAgICAgIGJpYXMsXG4gICAgICBpdGVyYXRpb25zID0gMTtcblxuICBpZiAobGlua3MgPT0gbnVsbCkgbGlua3MgPSBbXTtcblxuICBmdW5jdGlvbiBkZWZhdWx0U3RyZW5ndGgobGluaykge1xuICAgIHJldHVybiAxIC8gTWF0aC5taW4oY291bnRbbGluay5zb3VyY2UuaW5kZXhdLCBjb3VudFtsaW5rLnRhcmdldC5pbmRleF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9yY2UoYWxwaGEpIHtcbiAgICBmb3IgKHZhciBrID0gMCwgbiA9IGxpbmtzLmxlbmd0aDsgayA8IGl0ZXJhdGlvbnM7ICsraykge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxpbmssIHNvdXJjZSwgdGFyZ2V0LCB4LCB5LCBsLCBiOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGxpbmsgPSBsaW5rc1tpXSwgc291cmNlID0gbGluay5zb3VyY2UsIHRhcmdldCA9IGxpbmsudGFyZ2V0O1xuICAgICAgICB4ID0gdGFyZ2V0LnggKyB0YXJnZXQudnggLSBzb3VyY2UueCAtIHNvdXJjZS52eCB8fCBqaWdnbGUoKTtcbiAgICAgICAgeSA9IHRhcmdldC55ICsgdGFyZ2V0LnZ5IC0gc291cmNlLnkgLSBzb3VyY2UudnkgfHwgamlnZ2xlKCk7XG4gICAgICAgIGwgPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7XG4gICAgICAgIGwgPSAobCAtIGRpc3RhbmNlc1tpXSkgLyBsICogYWxwaGEgKiBzdHJlbmd0aHNbaV07XG4gICAgICAgIHggKj0gbCwgeSAqPSBsO1xuICAgICAgICB0YXJnZXQudnggLT0geCAqIChiID0gYmlhc1tpXSk7XG4gICAgICAgIHRhcmdldC52eSAtPSB5ICogYjtcbiAgICAgICAgc291cmNlLnZ4ICs9IHggKiAoYiA9IDEgLSBiKTtcbiAgICAgICAgc291cmNlLnZ5ICs9IHkgKiBiO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuXG4gICAgdmFyIGksXG4gICAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICAgIG0gPSBsaW5rcy5sZW5ndGgsXG4gICAgICAgIG5vZGVCeUlkID0gbWFwJDEobm9kZXMsIGlkKSxcbiAgICAgICAgbGluaztcblxuICAgIGZvciAoaSA9IDAsIGNvdW50ID0gbmV3IEFycmF5KG4pOyBpIDwgbTsgKytpKSB7XG4gICAgICBsaW5rID0gbGlua3NbaV0sIGxpbmsuaW5kZXggPSBpO1xuICAgICAgaWYgKHR5cGVvZiBsaW5rLnNvdXJjZSAhPT0gXCJvYmplY3RcIikgbGluay5zb3VyY2UgPSBmaW5kKG5vZGVCeUlkLCBsaW5rLnNvdXJjZSk7XG4gICAgICBpZiAodHlwZW9mIGxpbmsudGFyZ2V0ICE9PSBcIm9iamVjdFwiKSBsaW5rLnRhcmdldCA9IGZpbmQobm9kZUJ5SWQsIGxpbmsudGFyZ2V0KTtcbiAgICAgIGNvdW50W2xpbmsuc291cmNlLmluZGV4XSA9IChjb3VudFtsaW5rLnNvdXJjZS5pbmRleF0gfHwgMCkgKyAxO1xuICAgICAgY291bnRbbGluay50YXJnZXQuaW5kZXhdID0gKGNvdW50W2xpbmsudGFyZ2V0LmluZGV4XSB8fCAwKSArIDE7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMCwgYmlhcyA9IG5ldyBBcnJheShtKTsgaSA8IG07ICsraSkge1xuICAgICAgbGluayA9IGxpbmtzW2ldLCBiaWFzW2ldID0gY291bnRbbGluay5zb3VyY2UuaW5kZXhdIC8gKGNvdW50W2xpbmsuc291cmNlLmluZGV4XSArIGNvdW50W2xpbmsudGFyZ2V0LmluZGV4XSk7XG4gICAgfVxuXG4gICAgc3RyZW5ndGhzID0gbmV3IEFycmF5KG0pLCBpbml0aWFsaXplU3RyZW5ndGgoKTtcbiAgICBkaXN0YW5jZXMgPSBuZXcgQXJyYXkobSksIGluaXRpYWxpemVEaXN0YW5jZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5pdGlhbGl6ZVN0cmVuZ3RoKCkge1xuICAgIGlmICghbm9kZXMpIHJldHVybjtcblxuICAgIGZvciAodmFyIGkgPSAwLCBuID0gbGlua3MubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICBzdHJlbmd0aHNbaV0gPSArc3RyZW5ndGgobGlua3NbaV0sIGksIGxpbmtzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplRGlzdGFuY2UoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBsaW5rcy5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICAgIGRpc3RhbmNlc1tpXSA9ICtkaXN0YW5jZShsaW5rc1tpXSwgaSwgbGlua3MpO1xuICAgIH1cbiAgfVxuXG4gIGZvcmNlLmluaXRpYWxpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgbm9kZXMgPSBfO1xuICAgIGluaXRpYWxpemUoKTtcbiAgfTtcblxuICBmb3JjZS5saW5rcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChsaW5rcyA9IF8sIGluaXRpYWxpemUoKSwgZm9yY2UpIDogbGlua3M7XG4gIH07XG5cbiAgZm9yY2UuaWQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaWQgPSBfLCBmb3JjZSkgOiBpZDtcbiAgfTtcblxuICBmb3JjZS5pdGVyYXRpb25zID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGl0ZXJhdGlvbnMgPSArXywgZm9yY2UpIDogaXRlcmF0aW9ucztcbiAgfTtcblxuICBmb3JjZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdHJlbmd0aCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNigrXyksIGluaXRpYWxpemVTdHJlbmd0aCgpLCBmb3JjZSkgOiBzdHJlbmd0aDtcbiAgfTtcblxuICBmb3JjZS5kaXN0YW5jZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkaXN0YW5jZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNigrXyksIGluaXRpYWxpemVEaXN0YW5jZSgpLCBmb3JjZSkgOiBkaXN0YW5jZTtcbiAgfTtcblxuICByZXR1cm4gZm9yY2U7XG59O1xuXG5mdW5jdGlvbiB4JDEoZCkge1xuICByZXR1cm4gZC54O1xufVxuXG5mdW5jdGlvbiB5JDEoZCkge1xuICByZXR1cm4gZC55O1xufVxuXG52YXIgaW5pdGlhbFJhZGl1cyA9IDEwO1xudmFyIGluaXRpYWxBbmdsZSA9IE1hdGguUEkgKiAoMyAtIE1hdGguc3FydCg1KSk7XG5cbnZhciBzaW11bGF0aW9uID0gZnVuY3Rpb24obm9kZXMpIHtcbiAgdmFyIHNpbXVsYXRpb24sXG4gICAgICBhbHBoYSA9IDEsXG4gICAgICBhbHBoYU1pbiA9IDAuMDAxLFxuICAgICAgYWxwaGFEZWNheSA9IDEgLSBNYXRoLnBvdyhhbHBoYU1pbiwgMSAvIDMwMCksXG4gICAgICBhbHBoYVRhcmdldCA9IDAsXG4gICAgICB2ZWxvY2l0eURlY2F5ID0gMC42LFxuICAgICAgZm9yY2VzID0gbWFwJDEoKSxcbiAgICAgIHN0ZXBwZXIgPSB0aW1lcihzdGVwKSxcbiAgICAgIGV2ZW50ID0gZGlzcGF0Y2goXCJ0aWNrXCIsIFwiZW5kXCIpO1xuXG4gIGlmIChub2RlcyA9PSBudWxsKSBub2RlcyA9IFtdO1xuXG4gIGZ1bmN0aW9uIHN0ZXAoKSB7XG4gICAgdGljaygpO1xuICAgIGV2ZW50LmNhbGwoXCJ0aWNrXCIsIHNpbXVsYXRpb24pO1xuICAgIGlmIChhbHBoYSA8IGFscGhhTWluKSB7XG4gICAgICBzdGVwcGVyLnN0b3AoKTtcbiAgICAgIGV2ZW50LmNhbGwoXCJlbmRcIiwgc2ltdWxhdGlvbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdGljaygpIHtcbiAgICB2YXIgaSwgbiA9IG5vZGVzLmxlbmd0aCwgbm9kZTtcblxuICAgIGFscGhhICs9IChhbHBoYVRhcmdldCAtIGFscGhhKSAqIGFscGhhRGVjYXk7XG5cbiAgICBmb3JjZXMuZWFjaChmdW5jdGlvbihmb3JjZSkge1xuICAgICAgZm9yY2UoYWxwaGEpO1xuICAgIH0pO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgaWYgKG5vZGUuZnggPT0gbnVsbCkgbm9kZS54ICs9IG5vZGUudnggKj0gdmVsb2NpdHlEZWNheTtcbiAgICAgIGVsc2Ugbm9kZS54ID0gbm9kZS5meCwgbm9kZS52eCA9IDA7XG4gICAgICBpZiAobm9kZS5meSA9PSBudWxsKSBub2RlLnkgKz0gbm9kZS52eSAqPSB2ZWxvY2l0eURlY2F5O1xuICAgICAgZWxzZSBub2RlLnkgPSBub2RlLmZ5LCBub2RlLnZ5ID0gMDtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplTm9kZXMoKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBub2Rlcy5sZW5ndGgsIG5vZGU7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZS5pbmRleCA9IGk7XG4gICAgICBpZiAoaXNOYU4obm9kZS54KSB8fCBpc05hTihub2RlLnkpKSB7XG4gICAgICAgIHZhciByYWRpdXMgPSBpbml0aWFsUmFkaXVzICogTWF0aC5zcXJ0KGkpLCBhbmdsZSA9IGkgKiBpbml0aWFsQW5nbGU7XG4gICAgICAgIG5vZGUueCA9IHJhZGl1cyAqIE1hdGguY29zKGFuZ2xlKTtcbiAgICAgICAgbm9kZS55ID0gcmFkaXVzICogTWF0aC5zaW4oYW5nbGUpO1xuICAgICAgfVxuICAgICAgaWYgKGlzTmFOKG5vZGUudngpIHx8IGlzTmFOKG5vZGUudnkpKSB7XG4gICAgICAgIG5vZGUudnggPSBub2RlLnZ5ID0gMDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplRm9yY2UoZm9yY2UpIHtcbiAgICBpZiAoZm9yY2UuaW5pdGlhbGl6ZSkgZm9yY2UuaW5pdGlhbGl6ZShub2Rlcyk7XG4gICAgcmV0dXJuIGZvcmNlO1xuICB9XG5cbiAgaW5pdGlhbGl6ZU5vZGVzKCk7XG5cbiAgcmV0dXJuIHNpbXVsYXRpb24gPSB7XG4gICAgdGljazogdGljayxcblxuICAgIHJlc3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHN0ZXBwZXIucmVzdGFydChzdGVwKSwgc2ltdWxhdGlvbjtcbiAgICB9LFxuXG4gICAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gc3RlcHBlci5zdG9wKCksIHNpbXVsYXRpb247XG4gICAgfSxcblxuICAgIG5vZGVzOiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlcyA9IF8sIGluaXRpYWxpemVOb2RlcygpLCBmb3JjZXMuZWFjaChpbml0aWFsaXplRm9yY2UpLCBzaW11bGF0aW9uKSA6IG5vZGVzO1xuICAgIH0sXG5cbiAgICBhbHBoYTogZnVuY3Rpb24oXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoYWxwaGEgPSArXywgc2ltdWxhdGlvbikgOiBhbHBoYTtcbiAgICB9LFxuXG4gICAgYWxwaGFNaW46IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFscGhhTWluID0gK18sIHNpbXVsYXRpb24pIDogYWxwaGFNaW47XG4gICAgfSxcblxuICAgIGFscGhhRGVjYXk6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFscGhhRGVjYXkgPSArXywgc2ltdWxhdGlvbikgOiArYWxwaGFEZWNheTtcbiAgICB9LFxuXG4gICAgYWxwaGFUYXJnZXQ6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFscGhhVGFyZ2V0ID0gK18sIHNpbXVsYXRpb24pIDogYWxwaGFUYXJnZXQ7XG4gICAgfSxcblxuICAgIHZlbG9jaXR5RGVjYXk6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHZlbG9jaXR5RGVjYXkgPSAxIC0gXywgc2ltdWxhdGlvbikgOiAxIC0gdmVsb2NpdHlEZWNheTtcbiAgICB9LFxuXG4gICAgZm9yY2U6IGZ1bmN0aW9uKG5hbWUsIF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMSA/ICgoXyA9PSBudWxsID8gZm9yY2VzLnJlbW92ZShuYW1lKSA6IGZvcmNlcy5zZXQobmFtZSwgaW5pdGlhbGl6ZUZvcmNlKF8pKSksIHNpbXVsYXRpb24pIDogZm9yY2VzLmdldChuYW1lKTtcbiAgICB9LFxuXG4gICAgZmluZDogZnVuY3Rpb24oeCwgeSwgcmFkaXVzKSB7XG4gICAgICB2YXIgaSA9IDAsXG4gICAgICAgICAgbiA9IG5vZGVzLmxlbmd0aCxcbiAgICAgICAgICBkeCxcbiAgICAgICAgICBkeSxcbiAgICAgICAgICBkMixcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIGNsb3Nlc3Q7XG5cbiAgICAgIGlmIChyYWRpdXMgPT0gbnVsbCkgcmFkaXVzID0gSW5maW5pdHk7XG4gICAgICBlbHNlIHJhZGl1cyAqPSByYWRpdXM7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICBkeCA9IHggLSBub2RlLng7XG4gICAgICAgIGR5ID0geSAtIG5vZGUueTtcbiAgICAgICAgZDIgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgICAgaWYgKGQyIDwgcmFkaXVzKSBjbG9zZXN0ID0gbm9kZSwgcmFkaXVzID0gZDI7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjbG9zZXN0O1xuICAgIH0sXG5cbiAgICBvbjogZnVuY3Rpb24obmFtZSwgXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gKGV2ZW50Lm9uKG5hbWUsIF8pLCBzaW11bGF0aW9uKSA6IGV2ZW50Lm9uKG5hbWUpO1xuICAgIH1cbiAgfTtcbn07XG5cbnZhciBtYW55Qm9keSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZXMsXG4gICAgICBub2RlLFxuICAgICAgYWxwaGEsXG4gICAgICBzdHJlbmd0aCA9IGNvbnN0YW50JDYoLTMwKSxcbiAgICAgIHN0cmVuZ3RocyxcbiAgICAgIGRpc3RhbmNlTWluMiA9IDEsXG4gICAgICBkaXN0YW5jZU1heDIgPSBJbmZpbml0eSxcbiAgICAgIHRoZXRhMiA9IDAuODE7XG5cbiAgZnVuY3Rpb24gZm9yY2UoXykge1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLCB0cmVlID0gcXVhZHRyZWUobm9kZXMsIHgkMSwgeSQxKS52aXNpdEFmdGVyKGFjY3VtdWxhdGUpO1xuICAgIGZvciAoYWxwaGEgPSBfLCBpID0gMDsgaSA8IG47ICsraSkgbm9kZSA9IG5vZGVzW2ldLCB0cmVlLnZpc2l0KGFwcGx5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLCBub2RlO1xuICAgIHN0cmVuZ3RocyA9IG5ldyBBcnJheShuKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBub2RlID0gbm9kZXNbaV0sIHN0cmVuZ3Roc1tub2RlLmluZGV4XSA9ICtzdHJlbmd0aChub2RlLCBpLCBub2Rlcyk7XG4gIH1cblxuICBmdW5jdGlvbiBhY2N1bXVsYXRlKHF1YWQpIHtcbiAgICB2YXIgc3RyZW5ndGggPSAwLCBxLCBjLCB4JCQxLCB5JCQxLCBpO1xuXG4gICAgLy8gRm9yIGludGVybmFsIG5vZGVzLCBhY2N1bXVsYXRlIGZvcmNlcyBmcm9tIGNoaWxkIHF1YWRyYW50cy5cbiAgICBpZiAocXVhZC5sZW5ndGgpIHtcbiAgICAgIGZvciAoeCQkMSA9IHkkJDEgPSBpID0gMDsgaSA8IDQ7ICsraSkge1xuICAgICAgICBpZiAoKHEgPSBxdWFkW2ldKSAmJiAoYyA9IHEudmFsdWUpKSB7XG4gICAgICAgICAgc3RyZW5ndGggKz0gYywgeCQkMSArPSBjICogcS54LCB5JCQxICs9IGMgKiBxLnk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHF1YWQueCA9IHgkJDEgLyBzdHJlbmd0aDtcbiAgICAgIHF1YWQueSA9IHkkJDEgLyBzdHJlbmd0aDtcbiAgICB9XG5cbiAgICAvLyBGb3IgbGVhZiBub2RlcywgYWNjdW11bGF0ZSBmb3JjZXMgZnJvbSBjb2luY2lkZW50IHF1YWRyYW50cy5cbiAgICBlbHNlIHtcbiAgICAgIHEgPSBxdWFkO1xuICAgICAgcS54ID0gcS5kYXRhLng7XG4gICAgICBxLnkgPSBxLmRhdGEueTtcbiAgICAgIGRvIHN0cmVuZ3RoICs9IHN0cmVuZ3Roc1txLmRhdGEuaW5kZXhdO1xuICAgICAgd2hpbGUgKHEgPSBxLm5leHQpO1xuICAgIH1cblxuICAgIHF1YWQudmFsdWUgPSBzdHJlbmd0aDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGx5KHF1YWQsIHgxLCBfLCB4Mikge1xuICAgIGlmICghcXVhZC52YWx1ZSkgcmV0dXJuIHRydWU7XG5cbiAgICB2YXIgeCQkMSA9IHF1YWQueCAtIG5vZGUueCxcbiAgICAgICAgeSQkMSA9IHF1YWQueSAtIG5vZGUueSxcbiAgICAgICAgdyA9IHgyIC0geDEsXG4gICAgICAgIGwgPSB4JCQxICogeCQkMSArIHkkJDEgKiB5JCQxO1xuXG4gICAgLy8gQXBwbHkgdGhlIEJhcm5lcy1IdXQgYXBwcm94aW1hdGlvbiBpZiBwb3NzaWJsZS5cbiAgICAvLyBMaW1pdCBmb3JjZXMgZm9yIHZlcnkgY2xvc2Ugbm9kZXM7IHJhbmRvbWl6ZSBkaXJlY3Rpb24gaWYgY29pbmNpZGVudC5cbiAgICBpZiAodyAqIHcgLyB0aGV0YTIgPCBsKSB7XG4gICAgICBpZiAobCA8IGRpc3RhbmNlTWF4Mikge1xuICAgICAgICBpZiAoeCQkMSA9PT0gMCkgeCQkMSA9IGppZ2dsZSgpLCBsICs9IHgkJDEgKiB4JCQxO1xuICAgICAgICBpZiAoeSQkMSA9PT0gMCkgeSQkMSA9IGppZ2dsZSgpLCBsICs9IHkkJDEgKiB5JCQxO1xuICAgICAgICBpZiAobCA8IGRpc3RhbmNlTWluMikgbCA9IE1hdGguc3FydChkaXN0YW5jZU1pbjIgKiBsKTtcbiAgICAgICAgbm9kZS52eCArPSB4JCQxICogcXVhZC52YWx1ZSAqIGFscGhhIC8gbDtcbiAgICAgICAgbm9kZS52eSArPSB5JCQxICogcXVhZC52YWx1ZSAqIGFscGhhIC8gbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIE90aGVyd2lzZSwgcHJvY2VzcyBwb2ludHMgZGlyZWN0bHkuXG4gICAgZWxzZSBpZiAocXVhZC5sZW5ndGggfHwgbCA+PSBkaXN0YW5jZU1heDIpIHJldHVybjtcblxuICAgIC8vIExpbWl0IGZvcmNlcyBmb3IgdmVyeSBjbG9zZSBub2RlczsgcmFuZG9taXplIGRpcmVjdGlvbiBpZiBjb2luY2lkZW50LlxuICAgIGlmIChxdWFkLmRhdGEgIT09IG5vZGUgfHwgcXVhZC5uZXh0KSB7XG4gICAgICBpZiAoeCQkMSA9PT0gMCkgeCQkMSA9IGppZ2dsZSgpLCBsICs9IHgkJDEgKiB4JCQxO1xuICAgICAgaWYgKHkkJDEgPT09IDApIHkkJDEgPSBqaWdnbGUoKSwgbCArPSB5JCQxICogeSQkMTtcbiAgICAgIGlmIChsIDwgZGlzdGFuY2VNaW4yKSBsID0gTWF0aC5zcXJ0KGRpc3RhbmNlTWluMiAqIGwpO1xuICAgIH1cblxuICAgIGRvIGlmIChxdWFkLmRhdGEgIT09IG5vZGUpIHtcbiAgICAgIHcgPSBzdHJlbmd0aHNbcXVhZC5kYXRhLmluZGV4XSAqIGFscGhhIC8gbDtcbiAgICAgIG5vZGUudnggKz0geCQkMSAqIHc7XG4gICAgICBub2RlLnZ5ICs9IHkkJDEgKiB3O1xuICAgIH0gd2hpbGUgKHF1YWQgPSBxdWFkLm5leHQpO1xuICB9XG5cbiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBub2RlcyA9IF87XG4gICAgaW5pdGlhbGl6ZSgpO1xuICB9O1xuXG4gIGZvcmNlLnN0cmVuZ3RoID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3RoID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ2KCtfKSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiBzdHJlbmd0aDtcbiAgfTtcblxuICBmb3JjZS5kaXN0YW5jZU1pbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkaXN0YW5jZU1pbjIgPSBfICogXywgZm9yY2UpIDogTWF0aC5zcXJ0KGRpc3RhbmNlTWluMik7XG4gIH07XG5cbiAgZm9yY2UuZGlzdGFuY2VNYXggPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZGlzdGFuY2VNYXgyID0gXyAqIF8sIGZvcmNlKSA6IE1hdGguc3FydChkaXN0YW5jZU1heDIpO1xuICB9O1xuXG4gIGZvcmNlLnRoZXRhID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRoZXRhMiA9IF8gKiBfLCBmb3JjZSkgOiBNYXRoLnNxcnQodGhldGEyKTtcbiAgfTtcblxuICByZXR1cm4gZm9yY2U7XG59O1xuXG52YXIgeCQyID0gZnVuY3Rpb24oeCkge1xuICB2YXIgc3RyZW5ndGggPSBjb25zdGFudCQ2KDAuMSksXG4gICAgICBub2RlcyxcbiAgICAgIHN0cmVuZ3RocyxcbiAgICAgIHh6O1xuXG4gIGlmICh0eXBlb2YgeCAhPT0gXCJmdW5jdGlvblwiKSB4ID0gY29uc3RhbnQkNih4ID09IG51bGwgPyAwIDogK3gpO1xuXG4gIGZ1bmN0aW9uIGZvcmNlKGFscGhhKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBub2Rlcy5sZW5ndGgsIG5vZGU7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZS52eCArPSAoeHpbaV0gLSBub2RlLngpICogc3RyZW5ndGhzW2ldICogYWxwaGE7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdGlhbGl6ZSgpIHtcbiAgICBpZiAoIW5vZGVzKSByZXR1cm47XG4gICAgdmFyIGksIG4gPSBub2Rlcy5sZW5ndGg7XG4gICAgc3RyZW5ndGhzID0gbmV3IEFycmF5KG4pO1xuICAgIHh6ID0gbmV3IEFycmF5KG4pO1xuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIHN0cmVuZ3Roc1tpXSA9IGlzTmFOKHh6W2ldID0gK3gobm9kZXNbaV0sIGksIG5vZGVzKSkgPyAwIDogK3N0cmVuZ3RoKG5vZGVzW2ldLCBpLCBub2Rlcyk7XG4gICAgfVxuICB9XG5cbiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBub2RlcyA9IF87XG4gICAgaW5pdGlhbGl6ZSgpO1xuICB9O1xuXG4gIGZvcmNlLnN0cmVuZ3RoID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3RoID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ2KCtfKSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiBzdHJlbmd0aDtcbiAgfTtcblxuICBmb3JjZS54ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDYoK18pLCBpbml0aWFsaXplKCksIGZvcmNlKSA6IHg7XG4gIH07XG5cbiAgcmV0dXJuIGZvcmNlO1xufTtcblxudmFyIHkkMiA9IGZ1bmN0aW9uKHkpIHtcbiAgdmFyIHN0cmVuZ3RoID0gY29uc3RhbnQkNigwLjEpLFxuICAgICAgbm9kZXMsXG4gICAgICBzdHJlbmd0aHMsXG4gICAgICB5ejtcblxuICBpZiAodHlwZW9mIHkgIT09IFwiZnVuY3Rpb25cIikgeSA9IGNvbnN0YW50JDYoeSA9PSBudWxsID8gMCA6ICt5KTtcblxuICBmdW5jdGlvbiBmb3JjZShhbHBoYSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gbm9kZXMubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7XG4gICAgICBub2RlID0gbm9kZXNbaV0sIG5vZGUudnkgKz0gKHl6W2ldIC0gbm9kZS55KSAqIHN0cmVuZ3Roc1tpXSAqIGFscGhhO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoO1xuICAgIHN0cmVuZ3RocyA9IG5ldyBBcnJheShuKTtcbiAgICB5eiA9IG5ldyBBcnJheShuKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBzdHJlbmd0aHNbaV0gPSBpc05hTih5eltpXSA9ICt5KG5vZGVzW2ldLCBpLCBub2RlcykpID8gMCA6ICtzdHJlbmd0aChub2Rlc1tpXSwgaSwgbm9kZXMpO1xuICAgIH1cbiAgfVxuXG4gIGZvcmNlLmluaXRpYWxpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgbm9kZXMgPSBfO1xuICAgIGluaXRpYWxpemUoKTtcbiAgfTtcblxuICBmb3JjZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdHJlbmd0aCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNigrXyksIGluaXRpYWxpemUoKSwgZm9yY2UpIDogc3RyZW5ndGg7XG4gIH07XG5cbiAgZm9yY2UueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5ID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ2KCtfKSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiB5O1xuICB9O1xuXG4gIHJldHVybiBmb3JjZTtcbn07XG5cbi8vIENvbXB1dGVzIHRoZSBkZWNpbWFsIGNvZWZmaWNpZW50IGFuZCBleHBvbmVudCBvZiB0aGUgc3BlY2lmaWVkIG51bWJlciB4IHdpdGhcbi8vIHNpZ25pZmljYW50IGRpZ2l0cyBwLCB3aGVyZSB4IGlzIHBvc2l0aXZlIGFuZCBwIGlzIGluIFsxLCAyMV0gb3IgdW5kZWZpbmVkLlxuLy8gRm9yIGV4YW1wbGUsIGZvcm1hdERlY2ltYWwoMS4yMykgcmV0dXJucyBbXCIxMjNcIiwgMF0uXG52YXIgZm9ybWF0RGVjaW1hbCA9IGZ1bmN0aW9uKHgsIHApIHtcbiAgaWYgKChpID0gKHggPSBwID8geC50b0V4cG9uZW50aWFsKHAgLSAxKSA6IHgudG9FeHBvbmVudGlhbCgpKS5pbmRleE9mKFwiZVwiKSkgPCAwKSByZXR1cm4gbnVsbDsgLy8gTmFOLCDCsUluZmluaXR5XG4gIHZhciBpLCBjb2VmZmljaWVudCA9IHguc2xpY2UoMCwgaSk7XG5cbiAgLy8gVGhlIHN0cmluZyByZXR1cm5lZCBieSB0b0V4cG9uZW50aWFsIGVpdGhlciBoYXMgdGhlIGZvcm0gXFxkXFwuXFxkK2VbLStdXFxkK1xuICAvLyAoZS5nLiwgMS4yZSszKSBvciB0aGUgZm9ybSBcXGRlWy0rXVxcZCsgKGUuZy4sIDFlKzMpLlxuICByZXR1cm4gW1xuICAgIGNvZWZmaWNpZW50Lmxlbmd0aCA+IDEgPyBjb2VmZmljaWVudFswXSArIGNvZWZmaWNpZW50LnNsaWNlKDIpIDogY29lZmZpY2llbnQsXG4gICAgK3guc2xpY2UoaSArIDEpXG4gIF07XG59O1xuXG52YXIgZXhwb25lbnQkMSA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIHggPSBmb3JtYXREZWNpbWFsKE1hdGguYWJzKHgpKSwgeCA/IHhbMV0gOiBOYU47XG59O1xuXG52YXIgZm9ybWF0R3JvdXAgPSBmdW5jdGlvbihncm91cGluZywgdGhvdXNhbmRzKSB7XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSwgd2lkdGgpIHtcbiAgICB2YXIgaSA9IHZhbHVlLmxlbmd0aCxcbiAgICAgICAgdCA9IFtdLFxuICAgICAgICBqID0gMCxcbiAgICAgICAgZyA9IGdyb3VwaW5nWzBdLFxuICAgICAgICBsZW5ndGggPSAwO1xuXG4gICAgd2hpbGUgKGkgPiAwICYmIGcgPiAwKSB7XG4gICAgICBpZiAobGVuZ3RoICsgZyArIDEgPiB3aWR0aCkgZyA9IE1hdGgubWF4KDEsIHdpZHRoIC0gbGVuZ3RoKTtcbiAgICAgIHQucHVzaCh2YWx1ZS5zdWJzdHJpbmcoaSAtPSBnLCBpICsgZykpO1xuICAgICAgaWYgKChsZW5ndGggKz0gZyArIDEpID4gd2lkdGgpIGJyZWFrO1xuICAgICAgZyA9IGdyb3VwaW5nW2ogPSAoaiArIDEpICUgZ3JvdXBpbmcubGVuZ3RoXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdC5yZXZlcnNlKCkuam9pbih0aG91c2FuZHMpO1xuICB9O1xufTtcblxudmFyIGZvcm1hdE51bWVyYWxzID0gZnVuY3Rpb24obnVtZXJhbHMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1swLTldL2csIGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBudW1lcmFsc1sraV07XG4gICAgfSk7XG4gIH07XG59O1xuXG52YXIgZm9ybWF0RGVmYXVsdCA9IGZ1bmN0aW9uKHgsIHApIHtcbiAgeCA9IHgudG9QcmVjaXNpb24ocCk7XG5cbiAgb3V0OiBmb3IgKHZhciBuID0geC5sZW5ndGgsIGkgPSAxLCBpMCA9IC0xLCBpMTsgaSA8IG47ICsraSkge1xuICAgIHN3aXRjaCAoeFtpXSkge1xuICAgICAgY2FzZSBcIi5cIjogaTAgPSBpMSA9IGk7IGJyZWFrO1xuICAgICAgY2FzZSBcIjBcIjogaWYgKGkwID09PSAwKSBpMCA9IGk7IGkxID0gaTsgYnJlYWs7XG4gICAgICBjYXNlIFwiZVwiOiBicmVhayBvdXQ7XG4gICAgICBkZWZhdWx0OiBpZiAoaTAgPiAwKSBpMCA9IDA7IGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBpMCA+IDAgPyB4LnNsaWNlKDAsIGkwKSArIHguc2xpY2UoaTEgKyAxKSA6IHg7XG59O1xuXG52YXIgcHJlZml4RXhwb25lbnQ7XG5cbnZhciBmb3JtYXRQcmVmaXhBdXRvID0gZnVuY3Rpb24oeCwgcCkge1xuICB2YXIgZCA9IGZvcm1hdERlY2ltYWwoeCwgcCk7XG4gIGlmICghZCkgcmV0dXJuIHggKyBcIlwiO1xuICB2YXIgY29lZmZpY2llbnQgPSBkWzBdLFxuICAgICAgZXhwb25lbnQgPSBkWzFdLFxuICAgICAgaSA9IGV4cG9uZW50IC0gKHByZWZpeEV4cG9uZW50ID0gTWF0aC5tYXgoLTgsIE1hdGgubWluKDgsIE1hdGguZmxvb3IoZXhwb25lbnQgLyAzKSkpICogMykgKyAxLFxuICAgICAgbiA9IGNvZWZmaWNpZW50Lmxlbmd0aDtcbiAgcmV0dXJuIGkgPT09IG4gPyBjb2VmZmljaWVudFxuICAgICAgOiBpID4gbiA/IGNvZWZmaWNpZW50ICsgbmV3IEFycmF5KGkgLSBuICsgMSkuam9pbihcIjBcIilcbiAgICAgIDogaSA+IDAgPyBjb2VmZmljaWVudC5zbGljZSgwLCBpKSArIFwiLlwiICsgY29lZmZpY2llbnQuc2xpY2UoaSlcbiAgICAgIDogXCIwLlwiICsgbmV3IEFycmF5KDEgLSBpKS5qb2luKFwiMFwiKSArIGZvcm1hdERlY2ltYWwoeCwgTWF0aC5tYXgoMCwgcCArIGkgLSAxKSlbMF07IC8vIGxlc3MgdGhhbiAxeSFcbn07XG5cbnZhciBmb3JtYXRSb3VuZGVkID0gZnVuY3Rpb24oeCwgcCkge1xuICB2YXIgZCA9IGZvcm1hdERlY2ltYWwoeCwgcCk7XG4gIGlmICghZCkgcmV0dXJuIHggKyBcIlwiO1xuICB2YXIgY29lZmZpY2llbnQgPSBkWzBdLFxuICAgICAgZXhwb25lbnQgPSBkWzFdO1xuICByZXR1cm4gZXhwb25lbnQgPCAwID8gXCIwLlwiICsgbmV3IEFycmF5KC1leHBvbmVudCkuam9pbihcIjBcIikgKyBjb2VmZmljaWVudFxuICAgICAgOiBjb2VmZmljaWVudC5sZW5ndGggPiBleHBvbmVudCArIDEgPyBjb2VmZmljaWVudC5zbGljZSgwLCBleHBvbmVudCArIDEpICsgXCIuXCIgKyBjb2VmZmljaWVudC5zbGljZShleHBvbmVudCArIDEpXG4gICAgICA6IGNvZWZmaWNpZW50ICsgbmV3IEFycmF5KGV4cG9uZW50IC0gY29lZmZpY2llbnQubGVuZ3RoICsgMikuam9pbihcIjBcIik7XG59O1xuXG52YXIgZm9ybWF0VHlwZXMgPSB7XG4gIFwiXCI6IGZvcm1hdERlZmF1bHQsXG4gIFwiJVwiOiBmdW5jdGlvbih4LCBwKSB7IHJldHVybiAoeCAqIDEwMCkudG9GaXhlZChwKTsgfSxcbiAgXCJiXCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoMik7IH0sXG4gIFwiY1wiOiBmdW5jdGlvbih4KSB7IHJldHVybiB4ICsgXCJcIjsgfSxcbiAgXCJkXCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoMTApOyB9LFxuICBcImVcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b0V4cG9uZW50aWFsKHApOyB9LFxuICBcImZcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b0ZpeGVkKHApOyB9LFxuICBcImdcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b1ByZWNpc2lvbihwKTsgfSxcbiAgXCJvXCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoOCk7IH0sXG4gIFwicFwiOiBmdW5jdGlvbih4LCBwKSB7IHJldHVybiBmb3JtYXRSb3VuZGVkKHggKiAxMDAsIHApOyB9LFxuICBcInJcIjogZm9ybWF0Um91bmRlZCxcbiAgXCJzXCI6IGZvcm1hdFByZWZpeEF1dG8sXG4gIFwiWFwiOiBmdW5jdGlvbih4KSB7IHJldHVybiBNYXRoLnJvdW5kKHgpLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpOyB9LFxuICBcInhcIjogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZygxNik7IH1cbn07XG5cbi8vIFtbZmlsbF1hbGlnbl1bc2lnbl1bc3ltYm9sXVswXVt3aWR0aF1bLF1bLnByZWNpc2lvbl1bdHlwZV1cbnZhciByZSA9IC9eKD86KC4pPyhbPD49Xl0pKT8oWytcXC1cXCggXSk/KFskI10pPygwKT8oXFxkKyk/KCwpPyhcXC5cXGQrKT8oW2EteiVdKT8kL2k7XG5cbmZ1bmN0aW9uIGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpIHtcbiAgcmV0dXJuIG5ldyBGb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyKTtcbn1cblxuZm9ybWF0U3BlY2lmaWVyLnByb3RvdHlwZSA9IEZvcm1hdFNwZWNpZmllci5wcm90b3R5cGU7IC8vIGluc3RhbmNlb2ZcblxuZnVuY3Rpb24gRm9ybWF0U3BlY2lmaWVyKHNwZWNpZmllcikge1xuICBpZiAoIShtYXRjaCA9IHJlLmV4ZWMoc3BlY2lmaWVyKSkpIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZm9ybWF0OiBcIiArIHNwZWNpZmllcik7XG5cbiAgdmFyIG1hdGNoLFxuICAgICAgZmlsbCA9IG1hdGNoWzFdIHx8IFwiIFwiLFxuICAgICAgYWxpZ24gPSBtYXRjaFsyXSB8fCBcIj5cIixcbiAgICAgIHNpZ24gPSBtYXRjaFszXSB8fCBcIi1cIixcbiAgICAgIHN5bWJvbCA9IG1hdGNoWzRdIHx8IFwiXCIsXG4gICAgICB6ZXJvID0gISFtYXRjaFs1XSxcbiAgICAgIHdpZHRoID0gbWF0Y2hbNl0gJiYgK21hdGNoWzZdLFxuICAgICAgY29tbWEgPSAhIW1hdGNoWzddLFxuICAgICAgcHJlY2lzaW9uID0gbWF0Y2hbOF0gJiYgK21hdGNoWzhdLnNsaWNlKDEpLFxuICAgICAgdHlwZSA9IG1hdGNoWzldIHx8IFwiXCI7XG5cbiAgLy8gVGhlIFwiblwiIHR5cGUgaXMgYW4gYWxpYXMgZm9yIFwiLGdcIi5cbiAgaWYgKHR5cGUgPT09IFwiblwiKSBjb21tYSA9IHRydWUsIHR5cGUgPSBcImdcIjtcblxuICAvLyBNYXAgaW52YWxpZCB0eXBlcyB0byB0aGUgZGVmYXVsdCBmb3JtYXQuXG4gIGVsc2UgaWYgKCFmb3JtYXRUeXBlc1t0eXBlXSkgdHlwZSA9IFwiXCI7XG5cbiAgLy8gSWYgemVybyBmaWxsIGlzIHNwZWNpZmllZCwgcGFkZGluZyBnb2VzIGFmdGVyIHNpZ24gYW5kIGJlZm9yZSBkaWdpdHMuXG4gIGlmICh6ZXJvIHx8IChmaWxsID09PSBcIjBcIiAmJiBhbGlnbiA9PT0gXCI9XCIpKSB6ZXJvID0gdHJ1ZSwgZmlsbCA9IFwiMFwiLCBhbGlnbiA9IFwiPVwiO1xuXG4gIHRoaXMuZmlsbCA9IGZpbGw7XG4gIHRoaXMuYWxpZ24gPSBhbGlnbjtcbiAgdGhpcy5zaWduID0gc2lnbjtcbiAgdGhpcy5zeW1ib2wgPSBzeW1ib2w7XG4gIHRoaXMuemVybyA9IHplcm87XG4gIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgdGhpcy5jb21tYSA9IGNvbW1hO1xuICB0aGlzLnByZWNpc2lvbiA9IHByZWNpc2lvbjtcbiAgdGhpcy50eXBlID0gdHlwZTtcbn1cblxuRm9ybWF0U3BlY2lmaWVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5maWxsXG4gICAgICArIHRoaXMuYWxpZ25cbiAgICAgICsgdGhpcy5zaWduXG4gICAgICArIHRoaXMuc3ltYm9sXG4gICAgICArICh0aGlzLnplcm8gPyBcIjBcIiA6IFwiXCIpXG4gICAgICArICh0aGlzLndpZHRoID09IG51bGwgPyBcIlwiIDogTWF0aC5tYXgoMSwgdGhpcy53aWR0aCB8IDApKVxuICAgICAgKyAodGhpcy5jb21tYSA/IFwiLFwiIDogXCJcIilcbiAgICAgICsgKHRoaXMucHJlY2lzaW9uID09IG51bGwgPyBcIlwiIDogXCIuXCIgKyBNYXRoLm1heCgwLCB0aGlzLnByZWNpc2lvbiB8IDApKVxuICAgICAgKyB0aGlzLnR5cGU7XG59O1xuXG52YXIgaWRlbnRpdHkkMyA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIHg7XG59O1xuXG52YXIgcHJlZml4ZXMgPSBbXCJ5XCIsXCJ6XCIsXCJhXCIsXCJmXCIsXCJwXCIsXCJuXCIsXCJcXHhCNVwiLFwibVwiLFwiXCIsXCJrXCIsXCJNXCIsXCJHXCIsXCJUXCIsXCJQXCIsXCJFXCIsXCJaXCIsXCJZXCJdO1xuXG52YXIgZm9ybWF0TG9jYWxlID0gZnVuY3Rpb24obG9jYWxlKSB7XG4gIHZhciBncm91cCA9IGxvY2FsZS5ncm91cGluZyAmJiBsb2NhbGUudGhvdXNhbmRzID8gZm9ybWF0R3JvdXAobG9jYWxlLmdyb3VwaW5nLCBsb2NhbGUudGhvdXNhbmRzKSA6IGlkZW50aXR5JDMsXG4gICAgICBjdXJyZW5jeSA9IGxvY2FsZS5jdXJyZW5jeSxcbiAgICAgIGRlY2ltYWwgPSBsb2NhbGUuZGVjaW1hbCxcbiAgICAgIG51bWVyYWxzID0gbG9jYWxlLm51bWVyYWxzID8gZm9ybWF0TnVtZXJhbHMobG9jYWxlLm51bWVyYWxzKSA6IGlkZW50aXR5JDM7XG5cbiAgZnVuY3Rpb24gbmV3Rm9ybWF0KHNwZWNpZmllcikge1xuICAgIHNwZWNpZmllciA9IGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpO1xuXG4gICAgdmFyIGZpbGwgPSBzcGVjaWZpZXIuZmlsbCxcbiAgICAgICAgYWxpZ24gPSBzcGVjaWZpZXIuYWxpZ24sXG4gICAgICAgIHNpZ24gPSBzcGVjaWZpZXIuc2lnbixcbiAgICAgICAgc3ltYm9sID0gc3BlY2lmaWVyLnN5bWJvbCxcbiAgICAgICAgemVybyA9IHNwZWNpZmllci56ZXJvLFxuICAgICAgICB3aWR0aCA9IHNwZWNpZmllci53aWR0aCxcbiAgICAgICAgY29tbWEgPSBzcGVjaWZpZXIuY29tbWEsXG4gICAgICAgIHByZWNpc2lvbiA9IHNwZWNpZmllci5wcmVjaXNpb24sXG4gICAgICAgIHR5cGUgPSBzcGVjaWZpZXIudHlwZTtcblxuICAgIC8vIENvbXB1dGUgdGhlIHByZWZpeCBhbmQgc3VmZml4LlxuICAgIC8vIEZvciBTSS1wcmVmaXgsIHRoZSBzdWZmaXggaXMgbGF6aWx5IGNvbXB1dGVkLlxuICAgIHZhciBwcmVmaXggPSBzeW1ib2wgPT09IFwiJFwiID8gY3VycmVuY3lbMF0gOiBzeW1ib2wgPT09IFwiI1wiICYmIC9bYm94WF0vLnRlc3QodHlwZSkgPyBcIjBcIiArIHR5cGUudG9Mb3dlckNhc2UoKSA6IFwiXCIsXG4gICAgICAgIHN1ZmZpeCA9IHN5bWJvbCA9PT0gXCIkXCIgPyBjdXJyZW5jeVsxXSA6IC9bJXBdLy50ZXN0KHR5cGUpID8gXCIlXCIgOiBcIlwiO1xuXG4gICAgLy8gV2hhdCBmb3JtYXQgZnVuY3Rpb24gc2hvdWxkIHdlIHVzZT9cbiAgICAvLyBJcyB0aGlzIGFuIGludGVnZXIgdHlwZT9cbiAgICAvLyBDYW4gdGhpcyB0eXBlIGdlbmVyYXRlIGV4cG9uZW50aWFsIG5vdGF0aW9uP1xuICAgIHZhciBmb3JtYXRUeXBlID0gZm9ybWF0VHlwZXNbdHlwZV0sXG4gICAgICAgIG1heWJlU3VmZml4ID0gIXR5cGUgfHwgL1tkZWZncHJzJV0vLnRlc3QodHlwZSk7XG5cbiAgICAvLyBTZXQgdGhlIGRlZmF1bHQgcHJlY2lzaW9uIGlmIG5vdCBzcGVjaWZpZWQsXG4gICAgLy8gb3IgY2xhbXAgdGhlIHNwZWNpZmllZCBwcmVjaXNpb24gdG8gdGhlIHN1cHBvcnRlZCByYW5nZS5cbiAgICAvLyBGb3Igc2lnbmlmaWNhbnQgcHJlY2lzaW9uLCBpdCBtdXN0IGJlIGluIFsxLCAyMV0uXG4gICAgLy8gRm9yIGZpeGVkIHByZWNpc2lvbiwgaXQgbXVzdCBiZSBpbiBbMCwgMjBdLlxuICAgIHByZWNpc2lvbiA9IHByZWNpc2lvbiA9PSBudWxsID8gKHR5cGUgPyA2IDogMTIpXG4gICAgICAgIDogL1tncHJzXS8udGVzdCh0eXBlKSA/IE1hdGgubWF4KDEsIE1hdGgubWluKDIxLCBwcmVjaXNpb24pKVxuICAgICAgICA6IE1hdGgubWF4KDAsIE1hdGgubWluKDIwLCBwcmVjaXNpb24pKTtcblxuICAgIGZ1bmN0aW9uIGZvcm1hdCh2YWx1ZSkge1xuICAgICAgdmFyIHZhbHVlUHJlZml4ID0gcHJlZml4LFxuICAgICAgICAgIHZhbHVlU3VmZml4ID0gc3VmZml4LFxuICAgICAgICAgIGksIG4sIGM7XG5cbiAgICAgIGlmICh0eXBlID09PSBcImNcIikge1xuICAgICAgICB2YWx1ZVN1ZmZpeCA9IGZvcm1hdFR5cGUodmFsdWUpICsgdmFsdWVTdWZmaXg7XG4gICAgICAgIHZhbHVlID0gXCJcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gK3ZhbHVlO1xuXG4gICAgICAgIC8vIFBlcmZvcm0gdGhlIGluaXRpYWwgZm9ybWF0dGluZy5cbiAgICAgICAgdmFyIHZhbHVlTmVnYXRpdmUgPSB2YWx1ZSA8IDA7XG4gICAgICAgIHZhbHVlID0gZm9ybWF0VHlwZShNYXRoLmFicyh2YWx1ZSksIHByZWNpc2lvbik7XG5cbiAgICAgICAgLy8gSWYgYSBuZWdhdGl2ZSB2YWx1ZSByb3VuZHMgdG8gemVybyBkdXJpbmcgZm9ybWF0dGluZywgdHJlYXQgYXMgcG9zaXRpdmUuXG4gICAgICAgIGlmICh2YWx1ZU5lZ2F0aXZlICYmICt2YWx1ZSA9PT0gMCkgdmFsdWVOZWdhdGl2ZSA9IGZhbHNlO1xuXG4gICAgICAgIC8vIENvbXB1dGUgdGhlIHByZWZpeCBhbmQgc3VmZml4LlxuICAgICAgICB2YWx1ZVByZWZpeCA9ICh2YWx1ZU5lZ2F0aXZlID8gKHNpZ24gPT09IFwiKFwiID8gc2lnbiA6IFwiLVwiKSA6IHNpZ24gPT09IFwiLVwiIHx8IHNpZ24gPT09IFwiKFwiID8gXCJcIiA6IHNpZ24pICsgdmFsdWVQcmVmaXg7XG4gICAgICAgIHZhbHVlU3VmZml4ID0gdmFsdWVTdWZmaXggKyAodHlwZSA9PT0gXCJzXCIgPyBwcmVmaXhlc1s4ICsgcHJlZml4RXhwb25lbnQgLyAzXSA6IFwiXCIpICsgKHZhbHVlTmVnYXRpdmUgJiYgc2lnbiA9PT0gXCIoXCIgPyBcIilcIiA6IFwiXCIpO1xuXG4gICAgICAgIC8vIEJyZWFrIHRoZSBmb3JtYXR0ZWQgdmFsdWUgaW50byB0aGUgaW50ZWdlciDigJx2YWx1ZeKAnSBwYXJ0IHRoYXQgY2FuIGJlXG4gICAgICAgIC8vIGdyb3VwZWQsIGFuZCBmcmFjdGlvbmFsIG9yIGV4cG9uZW50aWFsIOKAnHN1ZmZpeOKAnSBwYXJ0IHRoYXQgaXMgbm90LlxuICAgICAgICBpZiAobWF5YmVTdWZmaXgpIHtcbiAgICAgICAgICBpID0gLTEsIG4gPSB2YWx1ZS5sZW5ndGg7XG4gICAgICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgICAgIGlmIChjID0gdmFsdWUuY2hhckNvZGVBdChpKSwgNDggPiBjIHx8IGMgPiA1Nykge1xuICAgICAgICAgICAgICB2YWx1ZVN1ZmZpeCA9IChjID09PSA0NiA/IGRlY2ltYWwgKyB2YWx1ZS5zbGljZShpICsgMSkgOiB2YWx1ZS5zbGljZShpKSkgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElmIHRoZSBmaWxsIGNoYXJhY3RlciBpcyBub3QgXCIwXCIsIGdyb3VwaW5nIGlzIGFwcGxpZWQgYmVmb3JlIHBhZGRpbmcuXG4gICAgICBpZiAoY29tbWEgJiYgIXplcm8pIHZhbHVlID0gZ3JvdXAodmFsdWUsIEluZmluaXR5KTtcblxuICAgICAgLy8gQ29tcHV0ZSB0aGUgcGFkZGluZy5cbiAgICAgIHZhciBsZW5ndGggPSB2YWx1ZVByZWZpeC5sZW5ndGggKyB2YWx1ZS5sZW5ndGggKyB2YWx1ZVN1ZmZpeC5sZW5ndGgsXG4gICAgICAgICAgcGFkZGluZyA9IGxlbmd0aCA8IHdpZHRoID8gbmV3IEFycmF5KHdpZHRoIC0gbGVuZ3RoICsgMSkuam9pbihmaWxsKSA6IFwiXCI7XG5cbiAgICAgIC8vIElmIHRoZSBmaWxsIGNoYXJhY3RlciBpcyBcIjBcIiwgZ3JvdXBpbmcgaXMgYXBwbGllZCBhZnRlciBwYWRkaW5nLlxuICAgICAgaWYgKGNvbW1hICYmIHplcm8pIHZhbHVlID0gZ3JvdXAocGFkZGluZyArIHZhbHVlLCBwYWRkaW5nLmxlbmd0aCA/IHdpZHRoIC0gdmFsdWVTdWZmaXgubGVuZ3RoIDogSW5maW5pdHkpLCBwYWRkaW5nID0gXCJcIjtcblxuICAgICAgLy8gUmVjb25zdHJ1Y3QgdGhlIGZpbmFsIG91dHB1dCBiYXNlZCBvbiB0aGUgZGVzaXJlZCBhbGlnbm1lbnQuXG4gICAgICBzd2l0Y2ggKGFsaWduKSB7XG4gICAgICAgIGNhc2UgXCI8XCI6IHZhbHVlID0gdmFsdWVQcmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4ICsgcGFkZGluZzsgYnJlYWs7XG4gICAgICAgIGNhc2UgXCI9XCI6IHZhbHVlID0gdmFsdWVQcmVmaXggKyBwYWRkaW5nICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeDsgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJeXCI6IHZhbHVlID0gcGFkZGluZy5zbGljZSgwLCBsZW5ndGggPSBwYWRkaW5nLmxlbmd0aCA+PiAxKSArIHZhbHVlUHJlZml4ICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeCArIHBhZGRpbmcuc2xpY2UobGVuZ3RoKTsgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6IHZhbHVlID0gcGFkZGluZyArIHZhbHVlUHJlZml4ICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeDsgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudW1lcmFscyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgZm9ybWF0LnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gc3BlY2lmaWVyICsgXCJcIjtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGZvcm1hdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFByZWZpeChzcGVjaWZpZXIsIHZhbHVlKSB7XG4gICAgdmFyIGYgPSBuZXdGb3JtYXQoKHNwZWNpZmllciA9IGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpLCBzcGVjaWZpZXIudHlwZSA9IFwiZlwiLCBzcGVjaWZpZXIpKSxcbiAgICAgICAgZSA9IE1hdGgubWF4KC04LCBNYXRoLm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50JDEodmFsdWUpIC8gMykpKSAqIDMsXG4gICAgICAgIGsgPSBNYXRoLnBvdygxMCwgLWUpLFxuICAgICAgICBwcmVmaXggPSBwcmVmaXhlc1s4ICsgZSAvIDNdO1xuICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGYoayAqIHZhbHVlKSArIHByZWZpeDtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBmb3JtYXQ6IG5ld0Zvcm1hdCxcbiAgICBmb3JtYXRQcmVmaXg6IGZvcm1hdFByZWZpeFxuICB9O1xufTtcblxudmFyIGxvY2FsZSQxO1xuXG5cblxuZGVmYXVsdExvY2FsZSh7XG4gIGRlY2ltYWw6IFwiLlwiLFxuICB0aG91c2FuZHM6IFwiLFwiLFxuICBncm91cGluZzogWzNdLFxuICBjdXJyZW5jeTogW1wiJFwiLCBcIlwiXVxufSk7XG5cbmZ1bmN0aW9uIGRlZmF1bHRMb2NhbGUoZGVmaW5pdGlvbikge1xuICBsb2NhbGUkMSA9IGZvcm1hdExvY2FsZShkZWZpbml0aW9uKTtcbiAgZXhwb3J0cy5mb3JtYXQgPSBsb2NhbGUkMS5mb3JtYXQ7XG4gIGV4cG9ydHMuZm9ybWF0UHJlZml4ID0gbG9jYWxlJDEuZm9ybWF0UHJlZml4O1xuICByZXR1cm4gbG9jYWxlJDE7XG59XG5cbnZhciBwcmVjaXNpb25GaXhlZCA9IGZ1bmN0aW9uKHN0ZXApIHtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIC1leHBvbmVudCQxKE1hdGguYWJzKHN0ZXApKSk7XG59O1xuXG52YXIgcHJlY2lzaW9uUHJlZml4ID0gZnVuY3Rpb24oc3RlcCwgdmFsdWUpIHtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWF4KC04LCBNYXRoLm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50JDEodmFsdWUpIC8gMykpKSAqIDMgLSBleHBvbmVudCQxKE1hdGguYWJzKHN0ZXApKSk7XG59O1xuXG52YXIgcHJlY2lzaW9uUm91bmQgPSBmdW5jdGlvbihzdGVwLCBtYXgpIHtcbiAgc3RlcCA9IE1hdGguYWJzKHN0ZXApLCBtYXggPSBNYXRoLmFicyhtYXgpIC0gc3RlcDtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIGV4cG9uZW50JDEobWF4KSAtIGV4cG9uZW50JDEoc3RlcCkpICsgMTtcbn07XG5cbi8vIEFkZHMgZmxvYXRpbmcgcG9pbnQgbnVtYmVycyB3aXRoIHR3aWNlIHRoZSBub3JtYWwgcHJlY2lzaW9uLlxuLy8gUmVmZXJlbmNlOiBKLiBSLiBTaGV3Y2h1aywgQWRhcHRpdmUgUHJlY2lzaW9uIEZsb2F0aW5nLVBvaW50IEFyaXRobWV0aWMgYW5kXG4vLyBGYXN0IFJvYnVzdCBHZW9tZXRyaWMgUHJlZGljYXRlcywgRGlzY3JldGUgJiBDb21wdXRhdGlvbmFsIEdlb21ldHJ5IDE4KDMpXG4vLyAzMDXigJMzNjMgKDE5OTcpLlxuLy8gQ29kZSBhZGFwdGVkIGZyb20gR2VvZ3JhcGhpY0xpYiBieSBDaGFybGVzIEYuIEYuIEthcm5leSxcbi8vIGh0dHA6Ly9nZW9ncmFwaGljbGliLnNvdXJjZWZvcmdlLm5ldC9cblxudmFyIGFkZGVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgQWRkZXI7XG59O1xuXG5mdW5jdGlvbiBBZGRlcigpIHtcbiAgdGhpcy5yZXNldCgpO1xufVxuXG5BZGRlci5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBBZGRlcixcbiAgcmVzZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMucyA9IC8vIHJvdW5kZWQgdmFsdWVcbiAgICB0aGlzLnQgPSAwOyAvLyBleGFjdCBlcnJvclxuICB9LFxuICBhZGQ6IGZ1bmN0aW9uKHkpIHtcbiAgICBhZGQkMSh0ZW1wLCB5LCB0aGlzLnQpO1xuICAgIGFkZCQxKHRoaXMsIHRlbXAucywgdGhpcy5zKTtcbiAgICBpZiAodGhpcy5zKSB0aGlzLnQgKz0gdGVtcC50O1xuICAgIGVsc2UgdGhpcy5zID0gdGVtcC50O1xuICB9LFxuICB2YWx1ZU9mOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5zO1xuICB9XG59O1xuXG52YXIgdGVtcCA9IG5ldyBBZGRlcjtcblxuZnVuY3Rpb24gYWRkJDEoYWRkZXIsIGEsIGIpIHtcbiAgdmFyIHggPSBhZGRlci5zID0gYSArIGIsXG4gICAgICBidiA9IHggLSBhLFxuICAgICAgYXYgPSB4IC0gYnY7XG4gIGFkZGVyLnQgPSAoYSAtIGF2KSArIChiIC0gYnYpO1xufVxuXG52YXIgZXBzaWxvbiQyID0gMWUtNjtcbnZhciBlcHNpbG9uMiQxID0gMWUtMTI7XG52YXIgcGkkMyA9IE1hdGguUEk7XG52YXIgaGFsZlBpJDIgPSBwaSQzIC8gMjtcbnZhciBxdWFydGVyUGkgPSBwaSQzIC8gNDtcbnZhciB0YXUkMyA9IHBpJDMgKiAyO1xuXG52YXIgZGVncmVlcyQxID0gMTgwIC8gcGkkMztcbnZhciByYWRpYW5zID0gcGkkMyAvIDE4MDtcblxudmFyIGFicyA9IE1hdGguYWJzO1xudmFyIGF0YW4gPSBNYXRoLmF0YW47XG52YXIgYXRhbjIgPSBNYXRoLmF0YW4yO1xudmFyIGNvcyQxID0gTWF0aC5jb3M7XG52YXIgY2VpbCA9IE1hdGguY2VpbDtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxudmFyIGxvZyA9IE1hdGgubG9nO1xudmFyIHBvdyA9IE1hdGgucG93O1xudmFyIHNpbiQxID0gTWF0aC5zaW47XG52YXIgc2lnbiA9IE1hdGguc2lnbiB8fCBmdW5jdGlvbih4KSB7IHJldHVybiB4ID4gMCA/IDEgOiB4IDwgMCA/IC0xIDogMDsgfTtcbnZhciBzcXJ0ID0gTWF0aC5zcXJ0O1xudmFyIHRhbiA9IE1hdGgudGFuO1xuXG5mdW5jdGlvbiBhY29zKHgpIHtcbiAgcmV0dXJuIHggPiAxID8gMCA6IHggPCAtMSA/IHBpJDMgOiBNYXRoLmFjb3MoeCk7XG59XG5cbmZ1bmN0aW9uIGFzaW4oeCkge1xuICByZXR1cm4geCA+IDEgPyBoYWxmUGkkMiA6IHggPCAtMSA/IC1oYWxmUGkkMiA6IE1hdGguYXNpbih4KTtcbn1cblxuZnVuY3Rpb24gaGF2ZXJzaW4oeCkge1xuICByZXR1cm4gKHggPSBzaW4kMSh4IC8gMikpICogeDtcbn1cblxuZnVuY3Rpb24gbm9vcCQxKCkge31cblxuZnVuY3Rpb24gc3RyZWFtR2VvbWV0cnkoZ2VvbWV0cnksIHN0cmVhbSkge1xuICBpZiAoZ2VvbWV0cnkgJiYgc3RyZWFtR2VvbWV0cnlUeXBlLmhhc093blByb3BlcnR5KGdlb21ldHJ5LnR5cGUpKSB7XG4gICAgc3RyZWFtR2VvbWV0cnlUeXBlW2dlb21ldHJ5LnR5cGVdKGdlb21ldHJ5LCBzdHJlYW0pO1xuICB9XG59XG5cbnZhciBzdHJlYW1PYmplY3RUeXBlID0ge1xuICBGZWF0dXJlOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHN0cmVhbUdlb21ldHJ5KG9iamVjdC5nZW9tZXRyeSwgc3RyZWFtKTtcbiAgfSxcbiAgRmVhdHVyZUNvbGxlY3Rpb246IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgdmFyIGZlYXR1cmVzID0gb2JqZWN0LmZlYXR1cmVzLCBpID0gLTEsIG4gPSBmZWF0dXJlcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIHN0cmVhbUdlb21ldHJ5KGZlYXR1cmVzW2ldLmdlb21ldHJ5LCBzdHJlYW0pO1xuICB9XG59O1xuXG52YXIgc3RyZWFtR2VvbWV0cnlUeXBlID0ge1xuICBTcGhlcmU6IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgc3RyZWFtLnNwaGVyZSgpO1xuICB9LFxuICBQb2ludDogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICBvYmplY3QgPSBvYmplY3QuY29vcmRpbmF0ZXM7XG4gICAgc3RyZWFtLnBvaW50KG9iamVjdFswXSwgb2JqZWN0WzFdLCBvYmplY3RbMl0pO1xuICB9LFxuICBNdWx0aVBvaW50OiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHZhciBjb29yZGluYXRlcyA9IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBvYmplY3QgPSBjb29yZGluYXRlc1tpXSwgc3RyZWFtLnBvaW50KG9iamVjdFswXSwgb2JqZWN0WzFdLCBvYmplY3RbMl0pO1xuICB9LFxuICBMaW5lU3RyaW5nOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHN0cmVhbUxpbmUob2JqZWN0LmNvb3JkaW5hdGVzLCBzdHJlYW0sIDApO1xuICB9LFxuICBNdWx0aUxpbmVTdHJpbmc6IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgdmFyIGNvb3JkaW5hdGVzID0gb2JqZWN0LmNvb3JkaW5hdGVzLCBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIHN0cmVhbUxpbmUoY29vcmRpbmF0ZXNbaV0sIHN0cmVhbSwgMCk7XG4gIH0sXG4gIFBvbHlnb246IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgc3RyZWFtUG9seWdvbihvYmplY3QuY29vcmRpbmF0ZXMsIHN0cmVhbSk7XG4gIH0sXG4gIE11bHRpUG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICB2YXIgY29vcmRpbmF0ZXMgPSBvYmplY3QuY29vcmRpbmF0ZXMsIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgc3RyZWFtUG9seWdvbihjb29yZGluYXRlc1tpXSwgc3RyZWFtKTtcbiAgfSxcbiAgR2VvbWV0cnlDb2xsZWN0aW9uOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHZhciBnZW9tZXRyaWVzID0gb2JqZWN0Lmdlb21ldHJpZXMsIGkgPSAtMSwgbiA9IGdlb21ldHJpZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBzdHJlYW1HZW9tZXRyeShnZW9tZXRyaWVzW2ldLCBzdHJlYW0pO1xuICB9XG59O1xuXG5mdW5jdGlvbiBzdHJlYW1MaW5lKGNvb3JkaW5hdGVzLCBzdHJlYW0sIGNsb3NlZCkge1xuICB2YXIgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoIC0gY2xvc2VkLCBjb29yZGluYXRlO1xuICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gIHdoaWxlICgrK2kgPCBuKSBjb29yZGluYXRlID0gY29vcmRpbmF0ZXNbaV0sIHN0cmVhbS5wb2ludChjb29yZGluYXRlWzBdLCBjb29yZGluYXRlWzFdLCBjb29yZGluYXRlWzJdKTtcbiAgc3RyZWFtLmxpbmVFbmQoKTtcbn1cblxuZnVuY3Rpb24gc3RyZWFtUG9seWdvbihjb29yZGluYXRlcywgc3RyZWFtKSB7XG4gIHZhciBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gIHN0cmVhbS5wb2x5Z29uU3RhcnQoKTtcbiAgd2hpbGUgKCsraSA8IG4pIHN0cmVhbUxpbmUoY29vcmRpbmF0ZXNbaV0sIHN0cmVhbSwgMSk7XG4gIHN0cmVhbS5wb2x5Z29uRW5kKCk7XG59XG5cbnZhciBnZW9TdHJlYW0gPSBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICBpZiAob2JqZWN0ICYmIHN0cmVhbU9iamVjdFR5cGUuaGFzT3duUHJvcGVydHkob2JqZWN0LnR5cGUpKSB7XG4gICAgc3RyZWFtT2JqZWN0VHlwZVtvYmplY3QudHlwZV0ob2JqZWN0LCBzdHJlYW0pO1xuICB9IGVsc2Uge1xuICAgIHN0cmVhbUdlb21ldHJ5KG9iamVjdCwgc3RyZWFtKTtcbiAgfVxufTtcblxudmFyIGFyZWFSaW5nU3VtID0gYWRkZXIoKTtcblxudmFyIGFyZWFTdW0gPSBhZGRlcigpO1xudmFyIGxhbWJkYTAwO1xudmFyIHBoaTAwO1xudmFyIGxhbWJkYTA7XG52YXIgY29zUGhpMDtcbnZhciBzaW5QaGkwO1xuXG52YXIgYXJlYVN0cmVhbSA9IHtcbiAgcG9pbnQ6IG5vb3AkMSxcbiAgbGluZVN0YXJ0OiBub29wJDEsXG4gIGxpbmVFbmQ6IG5vb3AkMSxcbiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICBhcmVhUmluZ1N1bS5yZXNldCgpO1xuICAgIGFyZWFTdHJlYW0ubGluZVN0YXJ0ID0gYXJlYVJpbmdTdGFydDtcbiAgICBhcmVhU3RyZWFtLmxpbmVFbmQgPSBhcmVhUmluZ0VuZDtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZWFSaW5nID0gK2FyZWFSaW5nU3VtO1xuICAgIGFyZWFTdW0uYWRkKGFyZWFSaW5nIDwgMCA/IHRhdSQzICsgYXJlYVJpbmcgOiBhcmVhUmluZyk7XG4gICAgdGhpcy5saW5lU3RhcnQgPSB0aGlzLmxpbmVFbmQgPSB0aGlzLnBvaW50ID0gbm9vcCQxO1xuICB9LFxuICBzcGhlcmU6IGZ1bmN0aW9uKCkge1xuICAgIGFyZWFTdW0uYWRkKHRhdSQzKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYXJlYVJpbmdTdGFydCgpIHtcbiAgYXJlYVN0cmVhbS5wb2ludCA9IGFyZWFQb2ludEZpcnN0O1xufVxuXG5mdW5jdGlvbiBhcmVhUmluZ0VuZCgpIHtcbiAgYXJlYVBvaW50KGxhbWJkYTAwLCBwaGkwMCk7XG59XG5cbmZ1bmN0aW9uIGFyZWFQb2ludEZpcnN0KGxhbWJkYSwgcGhpKSB7XG4gIGFyZWFTdHJlYW0ucG9pbnQgPSBhcmVhUG9pbnQ7XG4gIGxhbWJkYTAwID0gbGFtYmRhLCBwaGkwMCA9IHBoaTtcbiAgbGFtYmRhICo9IHJhZGlhbnMsIHBoaSAqPSByYWRpYW5zO1xuICBsYW1iZGEwID0gbGFtYmRhLCBjb3NQaGkwID0gY29zJDEocGhpID0gcGhpIC8gMiArIHF1YXJ0ZXJQaSksIHNpblBoaTAgPSBzaW4kMShwaGkpO1xufVxuXG5mdW5jdGlvbiBhcmVhUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgbGFtYmRhICo9IHJhZGlhbnMsIHBoaSAqPSByYWRpYW5zO1xuICBwaGkgPSBwaGkgLyAyICsgcXVhcnRlclBpOyAvLyBoYWxmIHRoZSBhbmd1bGFyIGRpc3RhbmNlIGZyb20gc291dGggcG9sZVxuXG4gIC8vIFNwaGVyaWNhbCBleGNlc3MgRSBmb3IgYSBzcGhlcmljYWwgdHJpYW5nbGUgd2l0aCB2ZXJ0aWNlczogc291dGggcG9sZSxcbiAgLy8gcHJldmlvdXMgcG9pbnQsIGN1cnJlbnQgcG9pbnQuICBVc2VzIGEgZm9ybXVsYSBkZXJpdmVkIGZyb20gQ2Fnbm9saeKAmXNcbiAgLy8gdGhlb3JlbS4gIFNlZSBUb2RodW50ZXIsIFNwaGVyaWNhbCBUcmlnLiAoMTg3MSksIFNlYy4gMTAzLCBFcS4gKDIpLlxuICB2YXIgZExhbWJkYSA9IGxhbWJkYSAtIGxhbWJkYTAsXG4gICAgICBzZExhbWJkYSA9IGRMYW1iZGEgPj0gMCA/IDEgOiAtMSxcbiAgICAgIGFkTGFtYmRhID0gc2RMYW1iZGEgKiBkTGFtYmRhLFxuICAgICAgY29zUGhpID0gY29zJDEocGhpKSxcbiAgICAgIHNpblBoaSA9IHNpbiQxKHBoaSksXG4gICAgICBrID0gc2luUGhpMCAqIHNpblBoaSxcbiAgICAgIHUgPSBjb3NQaGkwICogY29zUGhpICsgayAqIGNvcyQxKGFkTGFtYmRhKSxcbiAgICAgIHYgPSBrICogc2RMYW1iZGEgKiBzaW4kMShhZExhbWJkYSk7XG4gIGFyZWFSaW5nU3VtLmFkZChhdGFuMih2LCB1KSk7XG5cbiAgLy8gQWR2YW5jZSB0aGUgcHJldmlvdXMgcG9pbnRzLlxuICBsYW1iZGEwID0gbGFtYmRhLCBjb3NQaGkwID0gY29zUGhpLCBzaW5QaGkwID0gc2luUGhpO1xufVxuXG52YXIgYXJlYSA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICBhcmVhU3VtLnJlc2V0KCk7XG4gIGdlb1N0cmVhbShvYmplY3QsIGFyZWFTdHJlYW0pO1xuICByZXR1cm4gYXJlYVN1bSAqIDI7XG59O1xuXG5mdW5jdGlvbiBzcGhlcmljYWwoY2FydGVzaWFuKSB7XG4gIHJldHVybiBbYXRhbjIoY2FydGVzaWFuWzFdLCBjYXJ0ZXNpYW5bMF0pLCBhc2luKGNhcnRlc2lhblsyXSldO1xufVxuXG5mdW5jdGlvbiBjYXJ0ZXNpYW4oc3BoZXJpY2FsKSB7XG4gIHZhciBsYW1iZGEgPSBzcGhlcmljYWxbMF0sIHBoaSA9IHNwaGVyaWNhbFsxXSwgY29zUGhpID0gY29zJDEocGhpKTtcbiAgcmV0dXJuIFtjb3NQaGkgKiBjb3MkMShsYW1iZGEpLCBjb3NQaGkgKiBzaW4kMShsYW1iZGEpLCBzaW4kMShwaGkpXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuRG90KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuQ3Jvc3MoYSwgYikge1xuICByZXR1cm4gW2FbMV0gKiBiWzJdIC0gYVsyXSAqIGJbMV0sIGFbMl0gKiBiWzBdIC0gYVswXSAqIGJbMl0sIGFbMF0gKiBiWzFdIC0gYVsxXSAqIGJbMF1dO1xufVxuXG4vLyBUT0RPIHJldHVybiBhXG5mdW5jdGlvbiBjYXJ0ZXNpYW5BZGRJblBsYWNlKGEsIGIpIHtcbiAgYVswXSArPSBiWzBdLCBhWzFdICs9IGJbMV0sIGFbMl0gKz0gYlsyXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuU2NhbGUodmVjdG9yLCBrKSB7XG4gIHJldHVybiBbdmVjdG9yWzBdICogaywgdmVjdG9yWzFdICogaywgdmVjdG9yWzJdICoga107XG59XG5cbi8vIFRPRE8gcmV0dXJuIGRcbmZ1bmN0aW9uIGNhcnRlc2lhbk5vcm1hbGl6ZUluUGxhY2UoZCkge1xuICB2YXIgbCA9IHNxcnQoZFswXSAqIGRbMF0gKyBkWzFdICogZFsxXSArIGRbMl0gKiBkWzJdKTtcbiAgZFswXSAvPSBsLCBkWzFdIC89IGwsIGRbMl0gLz0gbDtcbn1cblxudmFyIGxhbWJkYTAkMTtcbnZhciBwaGkwO1xudmFyIGxhbWJkYTE7XG52YXIgcGhpMTtcbnZhciBsYW1iZGEyO1xudmFyIGxhbWJkYTAwJDE7XG52YXIgcGhpMDAkMTtcbnZhciBwMDtcbnZhciBkZWx0YVN1bSA9IGFkZGVyKCk7XG52YXIgcmFuZ2VzO1xudmFyIHJhbmdlO1xuXG52YXIgYm91bmRzU3RyZWFtID0ge1xuICBwb2ludDogYm91bmRzUG9pbnQsXG4gIGxpbmVTdGFydDogYm91bmRzTGluZVN0YXJ0LFxuICBsaW5lRW5kOiBib3VuZHNMaW5lRW5kLFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIGJvdW5kc1N0cmVhbS5wb2ludCA9IGJvdW5kc1JpbmdQb2ludDtcbiAgICBib3VuZHNTdHJlYW0ubGluZVN0YXJ0ID0gYm91bmRzUmluZ1N0YXJ0O1xuICAgIGJvdW5kc1N0cmVhbS5saW5lRW5kID0gYm91bmRzUmluZ0VuZDtcbiAgICBkZWx0YVN1bS5yZXNldCgpO1xuICAgIGFyZWFTdHJlYW0ucG9seWdvblN0YXJ0KCk7XG4gIH0sXG4gIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGFyZWFTdHJlYW0ucG9seWdvbkVuZCgpO1xuICAgIGJvdW5kc1N0cmVhbS5wb2ludCA9IGJvdW5kc1BvaW50O1xuICAgIGJvdW5kc1N0cmVhbS5saW5lU3RhcnQgPSBib3VuZHNMaW5lU3RhcnQ7XG4gICAgYm91bmRzU3RyZWFtLmxpbmVFbmQgPSBib3VuZHNMaW5lRW5kO1xuICAgIGlmIChhcmVhUmluZ1N1bSA8IDApIGxhbWJkYTAkMSA9IC0obGFtYmRhMSA9IDE4MCksIHBoaTAgPSAtKHBoaTEgPSA5MCk7XG4gICAgZWxzZSBpZiAoZGVsdGFTdW0gPiBlcHNpbG9uJDIpIHBoaTEgPSA5MDtcbiAgICBlbHNlIGlmIChkZWx0YVN1bSA8IC1lcHNpbG9uJDIpIHBoaTAgPSAtOTA7XG4gICAgcmFuZ2VbMF0gPSBsYW1iZGEwJDEsIHJhbmdlWzFdID0gbGFtYmRhMTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYm91bmRzUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgcmFuZ2VzLnB1c2gocmFuZ2UgPSBbbGFtYmRhMCQxID0gbGFtYmRhLCBsYW1iZGExID0gbGFtYmRhXSk7XG4gIGlmIChwaGkgPCBwaGkwKSBwaGkwID0gcGhpO1xuICBpZiAocGhpID4gcGhpMSkgcGhpMSA9IHBoaTtcbn1cblxuZnVuY3Rpb24gbGluZVBvaW50KGxhbWJkYSwgcGhpKSB7XG4gIHZhciBwID0gY2FydGVzaWFuKFtsYW1iZGEgKiByYWRpYW5zLCBwaGkgKiByYWRpYW5zXSk7XG4gIGlmIChwMCkge1xuICAgIHZhciBub3JtYWwgPSBjYXJ0ZXNpYW5Dcm9zcyhwMCwgcCksXG4gICAgICAgIGVxdWF0b3JpYWwgPSBbbm9ybWFsWzFdLCAtbm9ybWFsWzBdLCAwXSxcbiAgICAgICAgaW5mbGVjdGlvbiA9IGNhcnRlc2lhbkNyb3NzKGVxdWF0b3JpYWwsIG5vcm1hbCk7XG4gICAgY2FydGVzaWFuTm9ybWFsaXplSW5QbGFjZShpbmZsZWN0aW9uKTtcbiAgICBpbmZsZWN0aW9uID0gc3BoZXJpY2FsKGluZmxlY3Rpb24pO1xuICAgIHZhciBkZWx0YSA9IGxhbWJkYSAtIGxhbWJkYTIsXG4gICAgICAgIHNpZ24kJDEgPSBkZWx0YSA+IDAgPyAxIDogLTEsXG4gICAgICAgIGxhbWJkYWkgPSBpbmZsZWN0aW9uWzBdICogZGVncmVlcyQxICogc2lnbiQkMSxcbiAgICAgICAgcGhpaSxcbiAgICAgICAgYW50aW1lcmlkaWFuID0gYWJzKGRlbHRhKSA+IDE4MDtcbiAgICBpZiAoYW50aW1lcmlkaWFuIF4gKHNpZ24kJDEgKiBsYW1iZGEyIDwgbGFtYmRhaSAmJiBsYW1iZGFpIDwgc2lnbiQkMSAqIGxhbWJkYSkpIHtcbiAgICAgIHBoaWkgPSBpbmZsZWN0aW9uWzFdICogZGVncmVlcyQxO1xuICAgICAgaWYgKHBoaWkgPiBwaGkxKSBwaGkxID0gcGhpaTtcbiAgICB9IGVsc2UgaWYgKGxhbWJkYWkgPSAobGFtYmRhaSArIDM2MCkgJSAzNjAgLSAxODAsIGFudGltZXJpZGlhbiBeIChzaWduJCQxICogbGFtYmRhMiA8IGxhbWJkYWkgJiYgbGFtYmRhaSA8IHNpZ24kJDEgKiBsYW1iZGEpKSB7XG4gICAgICBwaGlpID0gLWluZmxlY3Rpb25bMV0gKiBkZWdyZWVzJDE7XG4gICAgICBpZiAocGhpaSA8IHBoaTApIHBoaTAgPSBwaGlpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocGhpIDwgcGhpMCkgcGhpMCA9IHBoaTtcbiAgICAgIGlmIChwaGkgPiBwaGkxKSBwaGkxID0gcGhpO1xuICAgIH1cbiAgICBpZiAoYW50aW1lcmlkaWFuKSB7XG4gICAgICBpZiAobGFtYmRhIDwgbGFtYmRhMikge1xuICAgICAgICBpZiAoYW5nbGUobGFtYmRhMCQxLCBsYW1iZGEpID4gYW5nbGUobGFtYmRhMCQxLCBsYW1iZGExKSkgbGFtYmRhMSA9IGxhbWJkYTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChhbmdsZShsYW1iZGEsIGxhbWJkYTEpID4gYW5nbGUobGFtYmRhMCQxLCBsYW1iZGExKSkgbGFtYmRhMCQxID0gbGFtYmRhO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobGFtYmRhMSA+PSBsYW1iZGEwJDEpIHtcbiAgICAgICAgaWYgKGxhbWJkYSA8IGxhbWJkYTAkMSkgbGFtYmRhMCQxID0gbGFtYmRhO1xuICAgICAgICBpZiAobGFtYmRhID4gbGFtYmRhMSkgbGFtYmRhMSA9IGxhbWJkYTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChsYW1iZGEgPiBsYW1iZGEyKSB7XG4gICAgICAgICAgaWYgKGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhKSA+IGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhMSkpIGxhbWJkYTEgPSBsYW1iZGE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGFuZ2xlKGxhbWJkYSwgbGFtYmRhMSkgPiBhbmdsZShsYW1iZGEwJDEsIGxhbWJkYTEpKSBsYW1iZGEwJDEgPSBsYW1iZGE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmFuZ2VzLnB1c2gocmFuZ2UgPSBbbGFtYmRhMCQxID0gbGFtYmRhLCBsYW1iZGExID0gbGFtYmRhXSk7XG4gIH1cbiAgaWYgKHBoaSA8IHBoaTApIHBoaTAgPSBwaGk7XG4gIGlmIChwaGkgPiBwaGkxKSBwaGkxID0gcGhpO1xuICBwMCA9IHAsIGxhbWJkYTIgPSBsYW1iZGE7XG59XG5cbmZ1bmN0aW9uIGJvdW5kc0xpbmVTdGFydCgpIHtcbiAgYm91bmRzU3RyZWFtLnBvaW50ID0gbGluZVBvaW50O1xufVxuXG5mdW5jdGlvbiBib3VuZHNMaW5lRW5kKCkge1xuICByYW5nZVswXSA9IGxhbWJkYTAkMSwgcmFuZ2VbMV0gPSBsYW1iZGExO1xuICBib3VuZHNTdHJlYW0ucG9pbnQgPSBib3VuZHNQb2ludDtcbiAgcDAgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBib3VuZHNSaW5nUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgaWYgKHAwKSB7XG4gICAgdmFyIGRlbHRhID0gbGFtYmRhIC0gbGFtYmRhMjtcbiAgICBkZWx0YVN1bS5hZGQoYWJzKGRlbHRhKSA+IDE4MCA/IGRlbHRhICsgKGRlbHRhID4gMCA/IDM2MCA6IC0zNjApIDogZGVsdGEpO1xuICB9IGVsc2Uge1xuICAgIGxhbWJkYTAwJDEgPSBsYW1iZGEsIHBoaTAwJDEgPSBwaGk7XG4gIH1cbiAgYXJlYVN0cmVhbS5wb2ludChsYW1iZGEsIHBoaSk7XG4gIGxpbmVQb2ludChsYW1iZGEsIHBoaSk7XG59XG5cbmZ1bmN0aW9uIGJvdW5kc1JpbmdTdGFydCgpIHtcbiAgYXJlYVN0cmVhbS5saW5lU3RhcnQoKTtcbn1cblxuZnVuY3Rpb24gYm91bmRzUmluZ0VuZCgpIHtcbiAgYm91bmRzUmluZ1BvaW50KGxhbWJkYTAwJDEsIHBoaTAwJDEpO1xuICBhcmVhU3RyZWFtLmxpbmVFbmQoKTtcbiAgaWYgKGFicyhkZWx0YVN1bSkgPiBlcHNpbG9uJDIpIGxhbWJkYTAkMSA9IC0obGFtYmRhMSA9IDE4MCk7XG4gIHJhbmdlWzBdID0gbGFtYmRhMCQxLCByYW5nZVsxXSA9IGxhbWJkYTE7XG4gIHAwID0gbnVsbDtcbn1cblxuLy8gRmluZHMgdGhlIGxlZnQtcmlnaHQgZGlzdGFuY2UgYmV0d2VlbiB0d28gbG9uZ2l0dWRlcy5cbi8vIFRoaXMgaXMgYWxtb3N0IHRoZSBzYW1lIGFzIChsYW1iZGExIC0gbGFtYmRhMCArIDM2MMKwKSAlIDM2MMKwLCBleGNlcHQgdGhhdCB3ZSB3YW50XG4vLyB0aGUgZGlzdGFuY2UgYmV0d2VlbiDCsTE4MMKwIHRvIGJlIDM2MMKwLlxuZnVuY3Rpb24gYW5nbGUobGFtYmRhMCwgbGFtYmRhMSkge1xuICByZXR1cm4gKGxhbWJkYTEgLT0gbGFtYmRhMCkgPCAwID8gbGFtYmRhMSArIDM2MCA6IGxhbWJkYTE7XG59XG5cbmZ1bmN0aW9uIHJhbmdlQ29tcGFyZShhLCBiKSB7XG4gIHJldHVybiBhWzBdIC0gYlswXTtcbn1cblxuZnVuY3Rpb24gcmFuZ2VDb250YWlucyhyYW5nZSwgeCkge1xuICByZXR1cm4gcmFuZ2VbMF0gPD0gcmFuZ2VbMV0gPyByYW5nZVswXSA8PSB4ICYmIHggPD0gcmFuZ2VbMV0gOiB4IDwgcmFuZ2VbMF0gfHwgcmFuZ2VbMV0gPCB4O1xufVxuXG52YXIgYm91bmRzID0gZnVuY3Rpb24oZmVhdHVyZSkge1xuICB2YXIgaSwgbiwgYSwgYiwgbWVyZ2VkLCBkZWx0YU1heCwgZGVsdGE7XG5cbiAgcGhpMSA9IGxhbWJkYTEgPSAtKGxhbWJkYTAkMSA9IHBoaTAgPSBJbmZpbml0eSk7XG4gIHJhbmdlcyA9IFtdO1xuICBnZW9TdHJlYW0oZmVhdHVyZSwgYm91bmRzU3RyZWFtKTtcblxuICAvLyBGaXJzdCwgc29ydCByYW5nZXMgYnkgdGhlaXIgbWluaW11bSBsb25naXR1ZGVzLlxuICBpZiAobiA9IHJhbmdlcy5sZW5ndGgpIHtcbiAgICByYW5nZXMuc29ydChyYW5nZUNvbXBhcmUpO1xuXG4gICAgLy8gVGhlbiwgbWVyZ2UgYW55IHJhbmdlcyB0aGF0IG92ZXJsYXAuXG4gICAgZm9yIChpID0gMSwgYSA9IHJhbmdlc1swXSwgbWVyZ2VkID0gW2FdOyBpIDwgbjsgKytpKSB7XG4gICAgICBiID0gcmFuZ2VzW2ldO1xuICAgICAgaWYgKHJhbmdlQ29udGFpbnMoYSwgYlswXSkgfHwgcmFuZ2VDb250YWlucyhhLCBiWzFdKSkge1xuICAgICAgICBpZiAoYW5nbGUoYVswXSwgYlsxXSkgPiBhbmdsZShhWzBdLCBhWzFdKSkgYVsxXSA9IGJbMV07XG4gICAgICAgIGlmIChhbmdsZShiWzBdLCBhWzFdKSA+IGFuZ2xlKGFbMF0sIGFbMV0pKSBhWzBdID0gYlswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1lcmdlZC5wdXNoKGEgPSBiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGaW5hbGx5LCBmaW5kIHRoZSBsYXJnZXN0IGdhcCBiZXR3ZWVuIHRoZSBtZXJnZWQgcmFuZ2VzLlxuICAgIC8vIFRoZSBmaW5hbCBib3VuZGluZyBib3ggd2lsbCBiZSB0aGUgaW52ZXJzZSBvZiB0aGlzIGdhcC5cbiAgICBmb3IgKGRlbHRhTWF4ID0gLUluZmluaXR5LCBuID0gbWVyZ2VkLmxlbmd0aCAtIDEsIGkgPSAwLCBhID0gbWVyZ2VkW25dOyBpIDw9IG47IGEgPSBiLCArK2kpIHtcbiAgICAgIGIgPSBtZXJnZWRbaV07XG4gICAgICBpZiAoKGRlbHRhID0gYW5nbGUoYVsxXSwgYlswXSkpID4gZGVsdGFNYXgpIGRlbHRhTWF4ID0gZGVsdGEsIGxhbWJkYTAkMSA9IGJbMF0sIGxhbWJkYTEgPSBhWzFdO1xuICAgIH1cbiAgfVxuXG4gIHJhbmdlcyA9IHJhbmdlID0gbnVsbDtcblxuICByZXR1cm4gbGFtYmRhMCQxID09PSBJbmZpbml0eSB8fCBwaGkwID09PSBJbmZpbml0eVxuICAgICAgPyBbW05hTiwgTmFOXSwgW05hTiwgTmFOXV1cbiAgICAgIDogW1tsYW1iZGEwJDEsIHBoaTBdLCBbbGFtYmRhMSwgcGhpMV1dO1xufTtcblxudmFyIFcwO1xudmFyIFcxO1xudmFyIFgwO1xudmFyIFkwO1xudmFyIFowO1xudmFyIFgxO1xudmFyIFkxO1xudmFyIFoxO1xudmFyIFgyO1xudmFyIFkyO1xudmFyIFoyO1xudmFyIGxhbWJkYTAwJDI7XG52YXIgcGhpMDAkMjtcbnZhciB4MDtcbnZhciB5MDtcbnZhciB6MDsgLy8gcHJldmlvdXMgcG9pbnRcblxudmFyIGNlbnRyb2lkU3RyZWFtID0ge1xuICBzcGhlcmU6IG5vb3AkMSxcbiAgcG9pbnQ6IGNlbnRyb2lkUG9pbnQsXG4gIGxpbmVTdGFydDogY2VudHJvaWRMaW5lU3RhcnQsXG4gIGxpbmVFbmQ6IGNlbnRyb2lkTGluZUVuZCxcbiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICBjZW50cm9pZFN0cmVhbS5saW5lU3RhcnQgPSBjZW50cm9pZFJpbmdTdGFydDtcbiAgICBjZW50cm9pZFN0cmVhbS5saW5lRW5kID0gY2VudHJvaWRSaW5nRW5kO1xuICB9LFxuICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICBjZW50cm9pZFN0cmVhbS5saW5lU3RhcnQgPSBjZW50cm9pZExpbmVTdGFydDtcbiAgICBjZW50cm9pZFN0cmVhbS5saW5lRW5kID0gY2VudHJvaWRMaW5lRW5kO1xuICB9XG59O1xuXG4vLyBBcml0aG1ldGljIG1lYW4gb2YgQ2FydGVzaWFuIHZlY3RvcnMuXG5mdW5jdGlvbiBjZW50cm9pZFBvaW50KGxhbWJkYSwgcGhpKSB7XG4gIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFucztcbiAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSk7XG4gIGNlbnRyb2lkUG9pbnRDYXJ0ZXNpYW4oY29zUGhpICogY29zJDEobGFtYmRhKSwgY29zUGhpICogc2luJDEobGFtYmRhKSwgc2luJDEocGhpKSk7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUG9pbnRDYXJ0ZXNpYW4oeCwgeSwgeikge1xuICArK1cwO1xuICBYMCArPSAoeCAtIFgwKSAvIFcwO1xuICBZMCArPSAoeSAtIFkwKSAvIFcwO1xuICBaMCArPSAoeiAtIFowKSAvIFcwO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZExpbmVTdGFydCgpIHtcbiAgY2VudHJvaWRTdHJlYW0ucG9pbnQgPSBjZW50cm9pZExpbmVQb2ludEZpcnN0O1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZExpbmVQb2ludEZpcnN0KGxhbWJkYSwgcGhpKSB7XG4gIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFucztcbiAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSk7XG4gIHgwID0gY29zUGhpICogY29zJDEobGFtYmRhKTtcbiAgeTAgPSBjb3NQaGkgKiBzaW4kMShsYW1iZGEpO1xuICB6MCA9IHNpbiQxKHBoaSk7XG4gIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJvaWRMaW5lUG9pbnQ7XG4gIGNlbnRyb2lkUG9pbnRDYXJ0ZXNpYW4oeDAsIHkwLCB6MCk7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkTGluZVBvaW50KGxhbWJkYSwgcGhpKSB7XG4gIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFucztcbiAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSksXG4gICAgICB4ID0gY29zUGhpICogY29zJDEobGFtYmRhKSxcbiAgICAgIHkgPSBjb3NQaGkgKiBzaW4kMShsYW1iZGEpLFxuICAgICAgeiA9IHNpbiQxKHBoaSksXG4gICAgICB3ID0gYXRhbjIoc3FydCgodyA9IHkwICogeiAtIHowICogeSkgKiB3ICsgKHcgPSB6MCAqIHggLSB4MCAqIHopICogdyArICh3ID0geDAgKiB5IC0geTAgKiB4KSAqIHcpLCB4MCAqIHggKyB5MCAqIHkgKyB6MCAqIHopO1xuICBXMSArPSB3O1xuICBYMSArPSB3ICogKHgwICsgKHgwID0geCkpO1xuICBZMSArPSB3ICogKHkwICsgKHkwID0geSkpO1xuICBaMSArPSB3ICogKHowICsgKHowID0geikpO1xuICBjZW50cm9pZFBvaW50Q2FydGVzaWFuKHgwLCB5MCwgejApO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZExpbmVFbmQoKSB7XG4gIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJvaWRQb2ludDtcbn1cblxuLy8gU2VlIEouIEUuIEJyb2NrLCBUaGUgSW5lcnRpYSBUZW5zb3IgZm9yIGEgU3BoZXJpY2FsIFRyaWFuZ2xlLFxuLy8gSi4gQXBwbGllZCBNZWNoYW5pY3MgNDIsIDIzOSAoMTk3NSkuXG5mdW5jdGlvbiBjZW50cm9pZFJpbmdTdGFydCgpIHtcbiAgY2VudHJvaWRTdHJlYW0ucG9pbnQgPSBjZW50cm9pZFJpbmdQb2ludEZpcnN0O1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFJpbmdFbmQoKSB7XG4gIGNlbnRyb2lkUmluZ1BvaW50KGxhbWJkYTAwJDIsIHBoaTAwJDIpO1xuICBjZW50cm9pZFN0cmVhbS5wb2ludCA9IGNlbnRyb2lkUG9pbnQ7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUmluZ1BvaW50Rmlyc3QobGFtYmRhLCBwaGkpIHtcbiAgbGFtYmRhMDAkMiA9IGxhbWJkYSwgcGhpMDAkMiA9IHBoaTtcbiAgbGFtYmRhICo9IHJhZGlhbnMsIHBoaSAqPSByYWRpYW5zO1xuICBjZW50cm9pZFN0cmVhbS5wb2ludCA9IGNlbnRyb2lkUmluZ1BvaW50O1xuICB2YXIgY29zUGhpID0gY29zJDEocGhpKTtcbiAgeDAgPSBjb3NQaGkgKiBjb3MkMShsYW1iZGEpO1xuICB5MCA9IGNvc1BoaSAqIHNpbiQxKGxhbWJkYSk7XG4gIHowID0gc2luJDEocGhpKTtcbiAgY2VudHJvaWRQb2ludENhcnRlc2lhbih4MCwgeTAsIHowKTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRSaW5nUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgbGFtYmRhICo9IHJhZGlhbnMsIHBoaSAqPSByYWRpYW5zO1xuICB2YXIgY29zUGhpID0gY29zJDEocGhpKSxcbiAgICAgIHggPSBjb3NQaGkgKiBjb3MkMShsYW1iZGEpLFxuICAgICAgeSA9IGNvc1BoaSAqIHNpbiQxKGxhbWJkYSksXG4gICAgICB6ID0gc2luJDEocGhpKSxcbiAgICAgIGN4ID0geTAgKiB6IC0gejAgKiB5LFxuICAgICAgY3kgPSB6MCAqIHggLSB4MCAqIHosXG4gICAgICBjeiA9IHgwICogeSAtIHkwICogeCxcbiAgICAgIG0gPSBzcXJ0KGN4ICogY3ggKyBjeSAqIGN5ICsgY3ogKiBjeiksXG4gICAgICB3ID0gYXNpbihtKSwgLy8gbGluZSB3ZWlnaHQgPSBhbmdsZVxuICAgICAgdiA9IG0gJiYgLXcgLyBtOyAvLyBhcmVhIHdlaWdodCBtdWx0aXBsaWVyXG4gIFgyICs9IHYgKiBjeDtcbiAgWTIgKz0gdiAqIGN5O1xuICBaMiArPSB2ICogY3o7XG4gIFcxICs9IHc7XG4gIFgxICs9IHcgKiAoeDAgKyAoeDAgPSB4KSk7XG4gIFkxICs9IHcgKiAoeTAgKyAoeTAgPSB5KSk7XG4gIFoxICs9IHcgKiAoejAgKyAoejAgPSB6KSk7XG4gIGNlbnRyb2lkUG9pbnRDYXJ0ZXNpYW4oeDAsIHkwLCB6MCk7XG59XG5cbnZhciBjZW50cm9pZCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICBXMCA9IFcxID1cbiAgWDAgPSBZMCA9IFowID1cbiAgWDEgPSBZMSA9IFoxID1cbiAgWDIgPSBZMiA9IFoyID0gMDtcbiAgZ2VvU3RyZWFtKG9iamVjdCwgY2VudHJvaWRTdHJlYW0pO1xuXG4gIHZhciB4ID0gWDIsXG4gICAgICB5ID0gWTIsXG4gICAgICB6ID0gWjIsXG4gICAgICBtID0geCAqIHggKyB5ICogeSArIHogKiB6O1xuXG4gIC8vIElmIHRoZSBhcmVhLXdlaWdodGVkIGNjZW50cm9pZCBpcyB1bmRlZmluZWQsIGZhbGwgYmFjayB0byBsZW5ndGgtd2VpZ2h0ZWQgY2NlbnRyb2lkLlxuICBpZiAobSA8IGVwc2lsb24yJDEpIHtcbiAgICB4ID0gWDEsIHkgPSBZMSwgeiA9IFoxO1xuICAgIC8vIElmIHRoZSBmZWF0dXJlIGhhcyB6ZXJvIGxlbmd0aCwgZmFsbCBiYWNrIHRvIGFyaXRobWV0aWMgbWVhbiBvZiBwb2ludCB2ZWN0b3JzLlxuICAgIGlmIChXMSA8IGVwc2lsb24kMikgeCA9IFgwLCB5ID0gWTAsIHogPSBaMDtcbiAgICBtID0geCAqIHggKyB5ICogeSArIHogKiB6O1xuICAgIC8vIElmIHRoZSBmZWF0dXJlIHN0aWxsIGhhcyBhbiB1bmRlZmluZWQgY2NlbnRyb2lkLCB0aGVuIHJldHVybi5cbiAgICBpZiAobSA8IGVwc2lsb24yJDEpIHJldHVybiBbTmFOLCBOYU5dO1xuICB9XG5cbiAgcmV0dXJuIFthdGFuMih5LCB4KSAqIGRlZ3JlZXMkMSwgYXNpbih6IC8gc3FydChtKSkgKiBkZWdyZWVzJDFdO1xufTtcblxudmFyIGNvbnN0YW50JDcgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn07XG5cbnZhciBjb21wb3NlID0gZnVuY3Rpb24oYSwgYikge1xuXG4gIGZ1bmN0aW9uIGNvbXBvc2UoeCwgeSkge1xuICAgIHJldHVybiB4ID0gYSh4LCB5KSwgYih4WzBdLCB4WzFdKTtcbiAgfVxuXG4gIGlmIChhLmludmVydCAmJiBiLmludmVydCkgY29tcG9zZS5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgcmV0dXJuIHggPSBiLmludmVydCh4LCB5KSwgeCAmJiBhLmludmVydCh4WzBdLCB4WzFdKTtcbiAgfTtcblxuICByZXR1cm4gY29tcG9zZTtcbn07XG5cbmZ1bmN0aW9uIHJvdGF0aW9uSWRlbnRpdHkobGFtYmRhLCBwaGkpIHtcbiAgcmV0dXJuIFtsYW1iZGEgPiBwaSQzID8gbGFtYmRhIC0gdGF1JDMgOiBsYW1iZGEgPCAtcGkkMyA/IGxhbWJkYSArIHRhdSQzIDogbGFtYmRhLCBwaGldO1xufVxuXG5yb3RhdGlvbklkZW50aXR5LmludmVydCA9IHJvdGF0aW9uSWRlbnRpdHk7XG5cbmZ1bmN0aW9uIHJvdGF0ZVJhZGlhbnMoZGVsdGFMYW1iZGEsIGRlbHRhUGhpLCBkZWx0YUdhbW1hKSB7XG4gIHJldHVybiAoZGVsdGFMYW1iZGEgJT0gdGF1JDMpID8gKGRlbHRhUGhpIHx8IGRlbHRhR2FtbWEgPyBjb21wb3NlKHJvdGF0aW9uTGFtYmRhKGRlbHRhTGFtYmRhKSwgcm90YXRpb25QaGlHYW1tYShkZWx0YVBoaSwgZGVsdGFHYW1tYSkpXG4gICAgOiByb3RhdGlvbkxhbWJkYShkZWx0YUxhbWJkYSkpXG4gICAgOiAoZGVsdGFQaGkgfHwgZGVsdGFHYW1tYSA/IHJvdGF0aW9uUGhpR2FtbWEoZGVsdGFQaGksIGRlbHRhR2FtbWEpXG4gICAgOiByb3RhdGlvbklkZW50aXR5KTtcbn1cblxuZnVuY3Rpb24gZm9yd2FyZFJvdGF0aW9uTGFtYmRhKGRlbHRhTGFtYmRhKSB7XG4gIHJldHVybiBmdW5jdGlvbihsYW1iZGEsIHBoaSkge1xuICAgIHJldHVybiBsYW1iZGEgKz0gZGVsdGFMYW1iZGEsIFtsYW1iZGEgPiBwaSQzID8gbGFtYmRhIC0gdGF1JDMgOiBsYW1iZGEgPCAtcGkkMyA/IGxhbWJkYSArIHRhdSQzIDogbGFtYmRhLCBwaGldO1xuICB9O1xufVxuXG5mdW5jdGlvbiByb3RhdGlvbkxhbWJkYShkZWx0YUxhbWJkYSkge1xuICB2YXIgcm90YXRpb24gPSBmb3J3YXJkUm90YXRpb25MYW1iZGEoZGVsdGFMYW1iZGEpO1xuICByb3RhdGlvbi5pbnZlcnQgPSBmb3J3YXJkUm90YXRpb25MYW1iZGEoLWRlbHRhTGFtYmRhKTtcbiAgcmV0dXJuIHJvdGF0aW9uO1xufVxuXG5mdW5jdGlvbiByb3RhdGlvblBoaUdhbW1hKGRlbHRhUGhpLCBkZWx0YUdhbW1hKSB7XG4gIHZhciBjb3NEZWx0YVBoaSA9IGNvcyQxKGRlbHRhUGhpKSxcbiAgICAgIHNpbkRlbHRhUGhpID0gc2luJDEoZGVsdGFQaGkpLFxuICAgICAgY29zRGVsdGFHYW1tYSA9IGNvcyQxKGRlbHRhR2FtbWEpLFxuICAgICAgc2luRGVsdGFHYW1tYSA9IHNpbiQxKGRlbHRhR2FtbWEpO1xuXG4gIGZ1bmN0aW9uIHJvdGF0aW9uKGxhbWJkYSwgcGhpKSB7XG4gICAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSksXG4gICAgICAgIHggPSBjb3MkMShsYW1iZGEpICogY29zUGhpLFxuICAgICAgICB5ID0gc2luJDEobGFtYmRhKSAqIGNvc1BoaSxcbiAgICAgICAgeiA9IHNpbiQxKHBoaSksXG4gICAgICAgIGsgPSB6ICogY29zRGVsdGFQaGkgKyB4ICogc2luRGVsdGFQaGk7XG4gICAgcmV0dXJuIFtcbiAgICAgIGF0YW4yKHkgKiBjb3NEZWx0YUdhbW1hIC0gayAqIHNpbkRlbHRhR2FtbWEsIHggKiBjb3NEZWx0YVBoaSAtIHogKiBzaW5EZWx0YVBoaSksXG4gICAgICBhc2luKGsgKiBjb3NEZWx0YUdhbW1hICsgeSAqIHNpbkRlbHRhR2FtbWEpXG4gICAgXTtcbiAgfVxuXG4gIHJvdGF0aW9uLmludmVydCA9IGZ1bmN0aW9uKGxhbWJkYSwgcGhpKSB7XG4gICAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSksXG4gICAgICAgIHggPSBjb3MkMShsYW1iZGEpICogY29zUGhpLFxuICAgICAgICB5ID0gc2luJDEobGFtYmRhKSAqIGNvc1BoaSxcbiAgICAgICAgeiA9IHNpbiQxKHBoaSksXG4gICAgICAgIGsgPSB6ICogY29zRGVsdGFHYW1tYSAtIHkgKiBzaW5EZWx0YUdhbW1hO1xuICAgIHJldHVybiBbXG4gICAgICBhdGFuMih5ICogY29zRGVsdGFHYW1tYSArIHogKiBzaW5EZWx0YUdhbW1hLCB4ICogY29zRGVsdGFQaGkgKyBrICogc2luRGVsdGFQaGkpLFxuICAgICAgYXNpbihrICogY29zRGVsdGFQaGkgLSB4ICogc2luRGVsdGFQaGkpXG4gICAgXTtcbiAgfTtcblxuICByZXR1cm4gcm90YXRpb247XG59XG5cbnZhciByb3RhdGlvbiA9IGZ1bmN0aW9uKHJvdGF0ZSkge1xuICByb3RhdGUgPSByb3RhdGVSYWRpYW5zKHJvdGF0ZVswXSAqIHJhZGlhbnMsIHJvdGF0ZVsxXSAqIHJhZGlhbnMsIHJvdGF0ZS5sZW5ndGggPiAyID8gcm90YXRlWzJdICogcmFkaWFucyA6IDApO1xuXG4gIGZ1bmN0aW9uIGZvcndhcmQoY29vcmRpbmF0ZXMpIHtcbiAgICBjb29yZGluYXRlcyA9IHJvdGF0ZShjb29yZGluYXRlc1swXSAqIHJhZGlhbnMsIGNvb3JkaW5hdGVzWzFdICogcmFkaWFucyk7XG4gICAgcmV0dXJuIGNvb3JkaW5hdGVzWzBdICo9IGRlZ3JlZXMkMSwgY29vcmRpbmF0ZXNbMV0gKj0gZGVncmVlcyQxLCBjb29yZGluYXRlcztcbiAgfVxuXG4gIGZvcndhcmQuaW52ZXJ0ID0gZnVuY3Rpb24oY29vcmRpbmF0ZXMpIHtcbiAgICBjb29yZGluYXRlcyA9IHJvdGF0ZS5pbnZlcnQoY29vcmRpbmF0ZXNbMF0gKiByYWRpYW5zLCBjb29yZGluYXRlc1sxXSAqIHJhZGlhbnMpO1xuICAgIHJldHVybiBjb29yZGluYXRlc1swXSAqPSBkZWdyZWVzJDEsIGNvb3JkaW5hdGVzWzFdICo9IGRlZ3JlZXMkMSwgY29vcmRpbmF0ZXM7XG4gIH07XG5cbiAgcmV0dXJuIGZvcndhcmQ7XG59O1xuXG4vLyBHZW5lcmF0ZXMgYSBjaXJjbGUgY2VudGVyZWQgYXQgWzDCsCwgMMKwXSwgd2l0aCBhIGdpdmVuIHJhZGl1cyBhbmQgcHJlY2lzaW9uLlxuZnVuY3Rpb24gY2lyY2xlU3RyZWFtKHN0cmVhbSwgcmFkaXVzLCBkZWx0YSwgZGlyZWN0aW9uLCB0MCwgdDEpIHtcbiAgaWYgKCFkZWx0YSkgcmV0dXJuO1xuICB2YXIgY29zUmFkaXVzID0gY29zJDEocmFkaXVzKSxcbiAgICAgIHNpblJhZGl1cyA9IHNpbiQxKHJhZGl1cyksXG4gICAgICBzdGVwID0gZGlyZWN0aW9uICogZGVsdGE7XG4gIGlmICh0MCA9PSBudWxsKSB7XG4gICAgdDAgPSByYWRpdXMgKyBkaXJlY3Rpb24gKiB0YXUkMztcbiAgICB0MSA9IHJhZGl1cyAtIHN0ZXAgLyAyO1xuICB9IGVsc2Uge1xuICAgIHQwID0gY2lyY2xlUmFkaXVzKGNvc1JhZGl1cywgdDApO1xuICAgIHQxID0gY2lyY2xlUmFkaXVzKGNvc1JhZGl1cywgdDEpO1xuICAgIGlmIChkaXJlY3Rpb24gPiAwID8gdDAgPCB0MSA6IHQwID4gdDEpIHQwICs9IGRpcmVjdGlvbiAqIHRhdSQzO1xuICB9XG4gIGZvciAodmFyIHBvaW50LCB0ID0gdDA7IGRpcmVjdGlvbiA+IDAgPyB0ID4gdDEgOiB0IDwgdDE7IHQgLT0gc3RlcCkge1xuICAgIHBvaW50ID0gc3BoZXJpY2FsKFtjb3NSYWRpdXMsIC1zaW5SYWRpdXMgKiBjb3MkMSh0KSwgLXNpblJhZGl1cyAqIHNpbiQxKHQpXSk7XG4gICAgc3RyZWFtLnBvaW50KHBvaW50WzBdLCBwb2ludFsxXSk7XG4gIH1cbn1cblxuLy8gUmV0dXJucyB0aGUgc2lnbmVkIGFuZ2xlIG9mIGEgY2FydGVzaWFuIHBvaW50IHJlbGF0aXZlIHRvIFtjb3NSYWRpdXMsIDAsIDBdLlxuZnVuY3Rpb24gY2lyY2xlUmFkaXVzKGNvc1JhZGl1cywgcG9pbnQpIHtcbiAgcG9pbnQgPSBjYXJ0ZXNpYW4ocG9pbnQpLCBwb2ludFswXSAtPSBjb3NSYWRpdXM7XG4gIGNhcnRlc2lhbk5vcm1hbGl6ZUluUGxhY2UocG9pbnQpO1xuICB2YXIgcmFkaXVzID0gYWNvcygtcG9pbnRbMV0pO1xuICByZXR1cm4gKCgtcG9pbnRbMl0gPCAwID8gLXJhZGl1cyA6IHJhZGl1cykgKyB0YXUkMyAtIGVwc2lsb24kMikgJSB0YXUkMztcbn1cblxudmFyIGNpcmNsZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY2VudGVyID0gY29uc3RhbnQkNyhbMCwgMF0pLFxuICAgICAgcmFkaXVzID0gY29uc3RhbnQkNyg5MCksXG4gICAgICBwcmVjaXNpb24gPSBjb25zdGFudCQ3KDYpLFxuICAgICAgcmluZyxcbiAgICAgIHJvdGF0ZSxcbiAgICAgIHN0cmVhbSA9IHtwb2ludDogcG9pbnR9O1xuXG4gIGZ1bmN0aW9uIHBvaW50KHgsIHkpIHtcbiAgICByaW5nLnB1c2goeCA9IHJvdGF0ZSh4LCB5KSk7XG4gICAgeFswXSAqPSBkZWdyZWVzJDEsIHhbMV0gKj0gZGVncmVlcyQxO1xuICB9XG5cbiAgZnVuY3Rpb24gY2lyY2xlKCkge1xuICAgIHZhciBjID0gY2VudGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksXG4gICAgICAgIHIgPSByYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSAqIHJhZGlhbnMsXG4gICAgICAgIHAgPSBwcmVjaXNpb24uYXBwbHkodGhpcywgYXJndW1lbnRzKSAqIHJhZGlhbnM7XG4gICAgcmluZyA9IFtdO1xuICAgIHJvdGF0ZSA9IHJvdGF0ZVJhZGlhbnMoLWNbMF0gKiByYWRpYW5zLCAtY1sxXSAqIHJhZGlhbnMsIDApLmludmVydDtcbiAgICBjaXJjbGVTdHJlYW0oc3RyZWFtLCByLCBwLCAxKTtcbiAgICBjID0ge3R5cGU6IFwiUG9seWdvblwiLCBjb29yZGluYXRlczogW3JpbmddfTtcbiAgICByaW5nID0gcm90YXRlID0gbnVsbDtcbiAgICByZXR1cm4gYztcbiAgfVxuXG4gIGNpcmNsZS5jZW50ZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoY2VudGVyID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ3KFsrX1swXSwgK19bMV1dKSwgY2lyY2xlKSA6IGNlbnRlcjtcbiAgfTtcblxuICBjaXJjbGUucmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkNygrXyksIGNpcmNsZSkgOiByYWRpdXM7XG4gIH07XG5cbiAgY2lyY2xlLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcmVjaXNpb24gPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDcoK18pLCBjaXJjbGUpIDogcHJlY2lzaW9uO1xuICB9O1xuXG4gIHJldHVybiBjaXJjbGU7XG59O1xuXG52YXIgY2xpcEJ1ZmZlciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbGluZXMgPSBbXSxcbiAgICAgIGxpbmU7XG4gIHJldHVybiB7XG4gICAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgIGxpbmUucHVzaChbeCwgeV0pO1xuICAgIH0sXG4gICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgIGxpbmVzLnB1c2gobGluZSA9IFtdKTtcbiAgICB9LFxuICAgIGxpbmVFbmQ6IG5vb3AkMSxcbiAgICByZWpvaW46IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGxpbmVzLmxlbmd0aCA+IDEpIGxpbmVzLnB1c2gobGluZXMucG9wKCkuY29uY2F0KGxpbmVzLnNoaWZ0KCkpKTtcbiAgICB9LFxuICAgIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbGluZXM7XG4gICAgICBsaW5lcyA9IFtdO1xuICAgICAgbGluZSA9IG51bGw7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfTtcbn07XG5cbnZhciBjbGlwTGluZSA9IGZ1bmN0aW9uKGEsIGIsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBieCA9IGJbMF0sXG4gICAgICBieSA9IGJbMV0sXG4gICAgICB0MCA9IDAsXG4gICAgICB0MSA9IDEsXG4gICAgICBkeCA9IGJ4IC0gYXgsXG4gICAgICBkeSA9IGJ5IC0gYXksXG4gICAgICByO1xuXG4gIHIgPSB4MCAtIGF4O1xuICBpZiAoIWR4ICYmIHIgPiAwKSByZXR1cm47XG4gIHIgLz0gZHg7XG4gIGlmIChkeCA8IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9IGVsc2UgaWYgKGR4ID4gMCkge1xuICAgIGlmIChyID4gdDEpIHJldHVybjtcbiAgICBpZiAociA+IHQwKSB0MCA9IHI7XG4gIH1cblxuICByID0geDEgLSBheDtcbiAgaWYgKCFkeCAmJiByIDwgMCkgcmV0dXJuO1xuICByIC89IGR4O1xuICBpZiAoZHggPCAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfSBlbHNlIGlmIChkeCA+IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9XG5cbiAgciA9IHkwIC0gYXk7XG4gIGlmICghZHkgJiYgciA+IDApIHJldHVybjtcbiAgciAvPSBkeTtcbiAgaWYgKGR5IDwgMCkge1xuICAgIGlmIChyIDwgdDApIHJldHVybjtcbiAgICBpZiAociA8IHQxKSB0MSA9IHI7XG4gIH0gZWxzZSBpZiAoZHkgPiAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfVxuXG4gIHIgPSB5MSAtIGF5O1xuICBpZiAoIWR5ICYmIHIgPCAwKSByZXR1cm47XG4gIHIgLz0gZHk7XG4gIGlmIChkeSA8IDApIHtcbiAgICBpZiAociA+IHQxKSByZXR1cm47XG4gICAgaWYgKHIgPiB0MCkgdDAgPSByO1xuICB9IGVsc2UgaWYgKGR5ID4gMCkge1xuICAgIGlmIChyIDwgdDApIHJldHVybjtcbiAgICBpZiAociA8IHQxKSB0MSA9IHI7XG4gIH1cblxuICBpZiAodDAgPiAwKSBhWzBdID0gYXggKyB0MCAqIGR4LCBhWzFdID0gYXkgKyB0MCAqIGR5O1xuICBpZiAodDEgPCAxKSBiWzBdID0gYXggKyB0MSAqIGR4LCBiWzFdID0gYXkgKyB0MSAqIGR5O1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbnZhciBwb2ludEVxdWFsID0gZnVuY3Rpb24oYSwgYikge1xuICByZXR1cm4gYWJzKGFbMF0gLSBiWzBdKSA8IGVwc2lsb24kMiAmJiBhYnMoYVsxXSAtIGJbMV0pIDwgZXBzaWxvbiQyO1xufTtcblxuZnVuY3Rpb24gSW50ZXJzZWN0aW9uKHBvaW50LCBwb2ludHMsIG90aGVyLCBlbnRyeSkge1xuICB0aGlzLnggPSBwb2ludDtcbiAgdGhpcy56ID0gcG9pbnRzO1xuICB0aGlzLm8gPSBvdGhlcjsgLy8gYW5vdGhlciBpbnRlcnNlY3Rpb25cbiAgdGhpcy5lID0gZW50cnk7IC8vIGlzIGFuIGVudHJ5P1xuICB0aGlzLnYgPSBmYWxzZTsgLy8gdmlzaXRlZFxuICB0aGlzLm4gPSB0aGlzLnAgPSBudWxsOyAvLyBuZXh0ICYgcHJldmlvdXNcbn1cblxuLy8gQSBnZW5lcmFsaXplZCBwb2x5Z29uIGNsaXBwaW5nIGFsZ29yaXRobTogZ2l2ZW4gYSBwb2x5Z29uIHRoYXQgaGFzIGJlZW4gY3V0XG4vLyBpbnRvIGl0cyB2aXNpYmxlIGxpbmUgc2VnbWVudHMsIGFuZCByZWpvaW5zIHRoZSBzZWdtZW50cyBieSBpbnRlcnBvbGF0aW5nXG4vLyBhbG9uZyB0aGUgY2xpcCBlZGdlLlxudmFyIGNsaXBQb2x5Z29uID0gZnVuY3Rpb24oc2VnbWVudHMsIGNvbXBhcmVJbnRlcnNlY3Rpb24sIHN0YXJ0SW5zaWRlLCBpbnRlcnBvbGF0ZSwgc3RyZWFtKSB7XG4gIHZhciBzdWJqZWN0ID0gW10sXG4gICAgICBjbGlwID0gW10sXG4gICAgICBpLFxuICAgICAgbjtcblxuICBzZWdtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKHNlZ21lbnQpIHtcbiAgICBpZiAoKG4gPSBzZWdtZW50Lmxlbmd0aCAtIDEpIDw9IDApIHJldHVybjtcbiAgICB2YXIgbiwgcDAgPSBzZWdtZW50WzBdLCBwMSA9IHNlZ21lbnRbbl0sIHg7XG5cbiAgICAvLyBJZiB0aGUgZmlyc3QgYW5kIGxhc3QgcG9pbnRzIG9mIGEgc2VnbWVudCBhcmUgY29pbmNpZGVudCwgdGhlbiB0cmVhdCBhcyBhXG4gICAgLy8gY2xvc2VkIHJpbmcuIFRPRE8gaWYgYWxsIHJpbmdzIGFyZSBjbG9zZWQsIHRoZW4gdGhlIHdpbmRpbmcgb3JkZXIgb2YgdGhlXG4gICAgLy8gZXh0ZXJpb3IgcmluZyBzaG91bGQgYmUgY2hlY2tlZC5cbiAgICBpZiAocG9pbnRFcXVhbChwMCwgcDEpKSB7XG4gICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBzdHJlYW0ucG9pbnQoKHAwID0gc2VnbWVudFtpXSlbMF0sIHAwWzFdKTtcbiAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3ViamVjdC5wdXNoKHggPSBuZXcgSW50ZXJzZWN0aW9uKHAwLCBzZWdtZW50LCBudWxsLCB0cnVlKSk7XG4gICAgY2xpcC5wdXNoKHgubyA9IG5ldyBJbnRlcnNlY3Rpb24ocDAsIG51bGwsIHgsIGZhbHNlKSk7XG4gICAgc3ViamVjdC5wdXNoKHggPSBuZXcgSW50ZXJzZWN0aW9uKHAxLCBzZWdtZW50LCBudWxsLCBmYWxzZSkpO1xuICAgIGNsaXAucHVzaCh4Lm8gPSBuZXcgSW50ZXJzZWN0aW9uKHAxLCBudWxsLCB4LCB0cnVlKSk7XG4gIH0pO1xuXG4gIGlmICghc3ViamVjdC5sZW5ndGgpIHJldHVybjtcblxuICBjbGlwLnNvcnQoY29tcGFyZUludGVyc2VjdGlvbik7XG4gIGxpbmskMShzdWJqZWN0KTtcbiAgbGluayQxKGNsaXApO1xuXG4gIGZvciAoaSA9IDAsIG4gPSBjbGlwLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgIGNsaXBbaV0uZSA9IHN0YXJ0SW5zaWRlID0gIXN0YXJ0SW5zaWRlO1xuICB9XG5cbiAgdmFyIHN0YXJ0ID0gc3ViamVjdFswXSxcbiAgICAgIHBvaW50cyxcbiAgICAgIHBvaW50O1xuXG4gIHdoaWxlICgxKSB7XG4gICAgLy8gRmluZCBmaXJzdCB1bnZpc2l0ZWQgaW50ZXJzZWN0aW9uLlxuICAgIHZhciBjdXJyZW50ID0gc3RhcnQsXG4gICAgICAgIGlzU3ViamVjdCA9IHRydWU7XG4gICAgd2hpbGUgKGN1cnJlbnQudikgaWYgKChjdXJyZW50ID0gY3VycmVudC5uKSA9PT0gc3RhcnQpIHJldHVybjtcbiAgICBwb2ludHMgPSBjdXJyZW50Lno7XG4gICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgIGRvIHtcbiAgICAgIGN1cnJlbnQudiA9IGN1cnJlbnQuby52ID0gdHJ1ZTtcbiAgICAgIGlmIChjdXJyZW50LmUpIHtcbiAgICAgICAgaWYgKGlzU3ViamVjdCkge1xuICAgICAgICAgIGZvciAoaSA9IDAsIG4gPSBwb2ludHMubGVuZ3RoOyBpIDwgbjsgKytpKSBzdHJlYW0ucG9pbnQoKHBvaW50ID0gcG9pbnRzW2ldKVswXSwgcG9pbnRbMV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGludGVycG9sYXRlKGN1cnJlbnQueCwgY3VycmVudC5uLngsIDEsIHN0cmVhbSk7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudCA9IGN1cnJlbnQubjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc1N1YmplY3QpIHtcbiAgICAgICAgICBwb2ludHMgPSBjdXJyZW50LnAuejtcbiAgICAgICAgICBmb3IgKGkgPSBwb2ludHMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHN0cmVhbS5wb2ludCgocG9pbnQgPSBwb2ludHNbaV0pWzBdLCBwb2ludFsxXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaW50ZXJwb2xhdGUoY3VycmVudC54LCBjdXJyZW50LnAueCwgLTEsIHN0cmVhbSk7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudCA9IGN1cnJlbnQucDtcbiAgICAgIH1cbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm87XG4gICAgICBwb2ludHMgPSBjdXJyZW50Lno7XG4gICAgICBpc1N1YmplY3QgPSAhaXNTdWJqZWN0O1xuICAgIH0gd2hpbGUgKCFjdXJyZW50LnYpO1xuICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGxpbmskMShhcnJheSkge1xuICBpZiAoIShuID0gYXJyYXkubGVuZ3RoKSkgcmV0dXJuO1xuICB2YXIgbixcbiAgICAgIGkgPSAwLFxuICAgICAgYSA9IGFycmF5WzBdLFxuICAgICAgYjtcbiAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICBhLm4gPSBiID0gYXJyYXlbaV07XG4gICAgYi5wID0gYTtcbiAgICBhID0gYjtcbiAgfVxuICBhLm4gPSBiID0gYXJyYXlbMF07XG4gIGIucCA9IGE7XG59XG5cbnZhciBjbGlwTWF4ID0gMWU5O1xudmFyIGNsaXBNaW4gPSAtY2xpcE1heDtcblxuLy8gVE9ETyBVc2UgZDMtcG9seWdvbuKAmXMgcG9seWdvbkNvbnRhaW5zIGhlcmUgZm9yIHRoZSByaW5nIGNoZWNrP1xuLy8gVE9ETyBFbGltaW5hdGUgZHVwbGljYXRlIGJ1ZmZlcmluZyBpbiBjbGlwQnVmZmVyIGFuZCBwb2x5Z29uLnB1c2g/XG5cbmZ1bmN0aW9uIGNsaXBFeHRlbnQoeDAsIHkwLCB4MSwgeTEpIHtcblxuICBmdW5jdGlvbiB2aXNpYmxlKHgsIHkpIHtcbiAgICByZXR1cm4geDAgPD0geCAmJiB4IDw9IHgxICYmIHkwIDw9IHkgJiYgeSA8PSB5MTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGludGVycG9sYXRlKGZyb20sIHRvLCBkaXJlY3Rpb24sIHN0cmVhbSkge1xuICAgIHZhciBhID0gMCwgYTEgPSAwO1xuICAgIGlmIChmcm9tID09IG51bGxcbiAgICAgICAgfHwgKGEgPSBjb3JuZXIoZnJvbSwgZGlyZWN0aW9uKSkgIT09IChhMSA9IGNvcm5lcih0bywgZGlyZWN0aW9uKSlcbiAgICAgICAgfHwgY29tcGFyZVBvaW50KGZyb20sIHRvKSA8IDAgXiBkaXJlY3Rpb24gPiAwKSB7XG4gICAgICBkbyBzdHJlYW0ucG9pbnQoYSA9PT0gMCB8fCBhID09PSAzID8geDAgOiB4MSwgYSA+IDEgPyB5MSA6IHkwKTtcbiAgICAgIHdoaWxlICgoYSA9IChhICsgZGlyZWN0aW9uICsgNCkgJSA0KSAhPT0gYTEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHJlYW0ucG9pbnQodG9bMF0sIHRvWzFdKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjb3JuZXIocCwgZGlyZWN0aW9uKSB7XG4gICAgcmV0dXJuIGFicyhwWzBdIC0geDApIDwgZXBzaWxvbiQyID8gZGlyZWN0aW9uID4gMCA/IDAgOiAzXG4gICAgICAgIDogYWJzKHBbMF0gLSB4MSkgPCBlcHNpbG9uJDIgPyBkaXJlY3Rpb24gPiAwID8gMiA6IDFcbiAgICAgICAgOiBhYnMocFsxXSAtIHkwKSA8IGVwc2lsb24kMiA/IGRpcmVjdGlvbiA+IDAgPyAxIDogMFxuICAgICAgICA6IGRpcmVjdGlvbiA+IDAgPyAzIDogMjsgLy8gYWJzKHBbMV0gLSB5MSkgPCBlcHNpbG9uXG4gIH1cblxuICBmdW5jdGlvbiBjb21wYXJlSW50ZXJzZWN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gY29tcGFyZVBvaW50KGEueCwgYi54KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbXBhcmVQb2ludChhLCBiKSB7XG4gICAgdmFyIGNhID0gY29ybmVyKGEsIDEpLFxuICAgICAgICBjYiA9IGNvcm5lcihiLCAxKTtcbiAgICByZXR1cm4gY2EgIT09IGNiID8gY2EgLSBjYlxuICAgICAgICA6IGNhID09PSAwID8gYlsxXSAtIGFbMV1cbiAgICAgICAgOiBjYSA9PT0gMSA/IGFbMF0gLSBiWzBdXG4gICAgICAgIDogY2EgPT09IDIgPyBhWzFdIC0gYlsxXVxuICAgICAgICA6IGJbMF0gLSBhWzBdO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIHZhciBhY3RpdmVTdHJlYW0gPSBzdHJlYW0sXG4gICAgICAgIGJ1ZmZlclN0cmVhbSA9IGNsaXBCdWZmZXIoKSxcbiAgICAgICAgc2VnbWVudHMsXG4gICAgICAgIHBvbHlnb24sXG4gICAgICAgIHJpbmcsXG4gICAgICAgIHhfXywgeV9fLCB2X18sIC8vIGZpcnN0IHBvaW50XG4gICAgICAgIHhfLCB5Xywgdl8sIC8vIHByZXZpb3VzIHBvaW50XG4gICAgICAgIGZpcnN0LFxuICAgICAgICBjbGVhbjtcblxuICAgIHZhciBjbGlwU3RyZWFtID0ge1xuICAgICAgcG9pbnQ6IHBvaW50LFxuICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICBsaW5lRW5kOiBsaW5lRW5kLFxuICAgICAgcG9seWdvblN0YXJ0OiBwb2x5Z29uU3RhcnQsXG4gICAgICBwb2x5Z29uRW5kOiBwb2x5Z29uRW5kXG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHBvaW50KHgsIHkpIHtcbiAgICAgIGlmICh2aXNpYmxlKHgsIHkpKSBhY3RpdmVTdHJlYW0ucG9pbnQoeCwgeSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9seWdvbkluc2lkZSgpIHtcbiAgICAgIHZhciB3aW5kaW5nID0gMDtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBwb2x5Z29uLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgICBmb3IgKHZhciByaW5nID0gcG9seWdvbltpXSwgaiA9IDEsIG0gPSByaW5nLmxlbmd0aCwgcG9pbnQgPSByaW5nWzBdLCBhMCwgYTEsIGIwID0gcG9pbnRbMF0sIGIxID0gcG9pbnRbMV07IGogPCBtOyArK2opIHtcbiAgICAgICAgICBhMCA9IGIwLCBhMSA9IGIxLCBwb2ludCA9IHJpbmdbal0sIGIwID0gcG9pbnRbMF0sIGIxID0gcG9pbnRbMV07XG4gICAgICAgICAgaWYgKGExIDw9IHkxKSB7IGlmIChiMSA+IHkxICYmIChiMCAtIGEwKSAqICh5MSAtIGExKSA+IChiMSAtIGExKSAqICh4MCAtIGEwKSkgKyt3aW5kaW5nOyB9XG4gICAgICAgICAgZWxzZSB7IGlmIChiMSA8PSB5MSAmJiAoYjAgLSBhMCkgKiAoeTEgLSBhMSkgPCAoYjEgLSBhMSkgKiAoeDAgLSBhMCkpIC0td2luZGluZzsgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB3aW5kaW5nO1xuICAgIH1cblxuICAgIC8vIEJ1ZmZlciBnZW9tZXRyeSB3aXRoaW4gYSBwb2x5Z29uIGFuZCB0aGVuIGNsaXAgaXQgZW4gbWFzc2UuXG4gICAgZnVuY3Rpb24gcG9seWdvblN0YXJ0KCkge1xuICAgICAgYWN0aXZlU3RyZWFtID0gYnVmZmVyU3RyZWFtLCBzZWdtZW50cyA9IFtdLCBwb2x5Z29uID0gW10sIGNsZWFuID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwb2x5Z29uRW5kKCkge1xuICAgICAgdmFyIHN0YXJ0SW5zaWRlID0gcG9seWdvbkluc2lkZSgpLFxuICAgICAgICAgIGNsZWFuSW5zaWRlID0gY2xlYW4gJiYgc3RhcnRJbnNpZGUsXG4gICAgICAgICAgdmlzaWJsZSA9IChzZWdtZW50cyA9IG1lcmdlKHNlZ21lbnRzKSkubGVuZ3RoO1xuICAgICAgaWYgKGNsZWFuSW5zaWRlIHx8IHZpc2libGUpIHtcbiAgICAgICAgc3RyZWFtLnBvbHlnb25TdGFydCgpO1xuICAgICAgICBpZiAoY2xlYW5JbnNpZGUpIHtcbiAgICAgICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgICAgICAgaW50ZXJwb2xhdGUobnVsbCwgbnVsbCwgMSwgc3RyZWFtKTtcbiAgICAgICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2aXNpYmxlKSB7XG4gICAgICAgICAgY2xpcFBvbHlnb24oc2VnbWVudHMsIGNvbXBhcmVJbnRlcnNlY3Rpb24sIHN0YXJ0SW5zaWRlLCBpbnRlcnBvbGF0ZSwgc3RyZWFtKTtcbiAgICAgICAgfVxuICAgICAgICBzdHJlYW0ucG9seWdvbkVuZCgpO1xuICAgICAgfVxuICAgICAgYWN0aXZlU3RyZWFtID0gc3RyZWFtLCBzZWdtZW50cyA9IHBvbHlnb24gPSByaW5nID0gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lU3RhcnQoKSB7XG4gICAgICBjbGlwU3RyZWFtLnBvaW50ID0gbGluZVBvaW50O1xuICAgICAgaWYgKHBvbHlnb24pIHBvbHlnb24ucHVzaChyaW5nID0gW10pO1xuICAgICAgZmlyc3QgPSB0cnVlO1xuICAgICAgdl8gPSBmYWxzZTtcbiAgICAgIHhfID0geV8gPSBOYU47XG4gICAgfVxuXG4gICAgLy8gVE9ETyByYXRoZXIgdGhhbiBzcGVjaWFsLWNhc2UgcG9seWdvbnMsIHNpbXBseSBoYW5kbGUgdGhlbSBzZXBhcmF0ZWx5LlxuICAgIC8vIElkZWFsbHksIGNvaW5jaWRlbnQgaW50ZXJzZWN0aW9uIHBvaW50cyBzaG91bGQgYmUgaml0dGVyZWQgdG8gYXZvaWRcbiAgICAvLyBjbGlwcGluZyBpc3N1ZXMuXG4gICAgZnVuY3Rpb24gbGluZUVuZCgpIHtcbiAgICAgIGlmIChzZWdtZW50cykge1xuICAgICAgICBsaW5lUG9pbnQoeF9fLCB5X18pO1xuICAgICAgICBpZiAodl9fICYmIHZfKSBidWZmZXJTdHJlYW0ucmVqb2luKCk7XG4gICAgICAgIHNlZ21lbnRzLnB1c2goYnVmZmVyU3RyZWFtLnJlc3VsdCgpKTtcbiAgICAgIH1cbiAgICAgIGNsaXBTdHJlYW0ucG9pbnQgPSBwb2ludDtcbiAgICAgIGlmICh2XykgYWN0aXZlU3RyZWFtLmxpbmVFbmQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lUG9pbnQoeCwgeSkge1xuICAgICAgdmFyIHYgPSB2aXNpYmxlKHgsIHkpO1xuICAgICAgaWYgKHBvbHlnb24pIHJpbmcucHVzaChbeCwgeV0pO1xuICAgICAgaWYgKGZpcnN0KSB7XG4gICAgICAgIHhfXyA9IHgsIHlfXyA9IHksIHZfXyA9IHY7XG4gICAgICAgIGZpcnN0ID0gZmFsc2U7XG4gICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgYWN0aXZlU3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgIGFjdGl2ZVN0cmVhbS5wb2ludCh4LCB5KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHYgJiYgdl8pIGFjdGl2ZVN0cmVhbS5wb2ludCh4LCB5KTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIGEgPSBbeF8gPSBNYXRoLm1heChjbGlwTWluLCBNYXRoLm1pbihjbGlwTWF4LCB4XykpLCB5XyA9IE1hdGgubWF4KGNsaXBNaW4sIE1hdGgubWluKGNsaXBNYXgsIHlfKSldLFxuICAgICAgICAgICAgICBiID0gW3ggPSBNYXRoLm1heChjbGlwTWluLCBNYXRoLm1pbihjbGlwTWF4LCB4KSksIHkgPSBNYXRoLm1heChjbGlwTWluLCBNYXRoLm1pbihjbGlwTWF4LCB5KSldO1xuICAgICAgICAgIGlmIChjbGlwTGluZShhLCBiLCB4MCwgeTAsIHgxLCB5MSkpIHtcbiAgICAgICAgICAgIGlmICghdl8pIHtcbiAgICAgICAgICAgICAgYWN0aXZlU3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgICBhY3RpdmVTdHJlYW0ucG9pbnQoYVswXSwgYVsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhY3RpdmVTdHJlYW0ucG9pbnQoYlswXSwgYlsxXSk7XG4gICAgICAgICAgICBpZiAoIXYpIGFjdGl2ZVN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgICAgICBjbGVhbiA9IGZhbHNlO1xuICAgICAgICAgIH0gZWxzZSBpZiAodikge1xuICAgICAgICAgICAgYWN0aXZlU3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgYWN0aXZlU3RyZWFtLnBvaW50KHgsIHkpO1xuICAgICAgICAgICAgY2xlYW4gPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHhfID0geCwgeV8gPSB5LCB2XyA9IHY7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsaXBTdHJlYW07XG4gIH07XG59XG5cbnZhciBleHRlbnQkMSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgeDAgPSAwLFxuICAgICAgeTAgPSAwLFxuICAgICAgeDEgPSA5NjAsXG4gICAgICB5MSA9IDUwMCxcbiAgICAgIGNhY2hlLFxuICAgICAgY2FjaGVTdHJlYW0sXG4gICAgICBjbGlwO1xuXG4gIHJldHVybiBjbGlwID0ge1xuICAgIHN0cmVhbTogZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICByZXR1cm4gY2FjaGUgJiYgY2FjaGVTdHJlYW0gPT09IHN0cmVhbSA/IGNhY2hlIDogY2FjaGUgPSBjbGlwRXh0ZW50KHgwLCB5MCwgeDEsIHkxKShjYWNoZVN0cmVhbSA9IHN0cmVhbSk7XG4gICAgfSxcbiAgICBleHRlbnQ6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgwID0gK19bMF1bMF0sIHkwID0gK19bMF1bMV0sIHgxID0gK19bMV1bMF0sIHkxID0gK19bMV1bMV0sIGNhY2hlID0gY2FjaGVTdHJlYW0gPSBudWxsLCBjbGlwKSA6IFtbeDAsIHkwXSwgW3gxLCB5MV1dO1xuICAgIH1cbiAgfTtcbn07XG5cbnZhciBzdW0kMSA9IGFkZGVyKCk7XG5cbnZhciBwb2x5Z29uQ29udGFpbnMgPSBmdW5jdGlvbihwb2x5Z29uLCBwb2ludCkge1xuICB2YXIgbGFtYmRhID0gcG9pbnRbMF0sXG4gICAgICBwaGkgPSBwb2ludFsxXSxcbiAgICAgIG5vcm1hbCA9IFtzaW4kMShsYW1iZGEpLCAtY29zJDEobGFtYmRhKSwgMF0sXG4gICAgICBhbmdsZSA9IDAsXG4gICAgICB3aW5kaW5nID0gMDtcblxuICBzdW0kMS5yZXNldCgpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBuID0gcG9seWdvbi5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoIShtID0gKHJpbmcgPSBwb2x5Z29uW2ldKS5sZW5ndGgpKSBjb250aW51ZTtcbiAgICB2YXIgcmluZyxcbiAgICAgICAgbSxcbiAgICAgICAgcG9pbnQwID0gcmluZ1ttIC0gMV0sXG4gICAgICAgIGxhbWJkYTAgPSBwb2ludDBbMF0sXG4gICAgICAgIHBoaTAgPSBwb2ludDBbMV0gLyAyICsgcXVhcnRlclBpLFxuICAgICAgICBzaW5QaGkwID0gc2luJDEocGhpMCksXG4gICAgICAgIGNvc1BoaTAgPSBjb3MkMShwaGkwKTtcblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbTsgKytqLCBsYW1iZGEwID0gbGFtYmRhMSwgc2luUGhpMCA9IHNpblBoaTEsIGNvc1BoaTAgPSBjb3NQaGkxLCBwb2ludDAgPSBwb2ludDEpIHtcbiAgICAgIHZhciBwb2ludDEgPSByaW5nW2pdLFxuICAgICAgICAgIGxhbWJkYTEgPSBwb2ludDFbMF0sXG4gICAgICAgICAgcGhpMSA9IHBvaW50MVsxXSAvIDIgKyBxdWFydGVyUGksXG4gICAgICAgICAgc2luUGhpMSA9IHNpbiQxKHBoaTEpLFxuICAgICAgICAgIGNvc1BoaTEgPSBjb3MkMShwaGkxKSxcbiAgICAgICAgICBkZWx0YSA9IGxhbWJkYTEgLSBsYW1iZGEwLFxuICAgICAgICAgIHNpZ24kJDEgPSBkZWx0YSA+PSAwID8gMSA6IC0xLFxuICAgICAgICAgIGFic0RlbHRhID0gc2lnbiQkMSAqIGRlbHRhLFxuICAgICAgICAgIGFudGltZXJpZGlhbiA9IGFic0RlbHRhID4gcGkkMyxcbiAgICAgICAgICBrID0gc2luUGhpMCAqIHNpblBoaTE7XG5cbiAgICAgIHN1bSQxLmFkZChhdGFuMihrICogc2lnbiQkMSAqIHNpbiQxKGFic0RlbHRhKSwgY29zUGhpMCAqIGNvc1BoaTEgKyBrICogY29zJDEoYWJzRGVsdGEpKSk7XG4gICAgICBhbmdsZSArPSBhbnRpbWVyaWRpYW4gPyBkZWx0YSArIHNpZ24kJDEgKiB0YXUkMyA6IGRlbHRhO1xuXG4gICAgICAvLyBBcmUgdGhlIGxvbmdpdHVkZXMgZWl0aGVyIHNpZGUgb2YgdGhlIHBvaW504oCZcyBtZXJpZGlhbiAobGFtYmRhKSxcbiAgICAgIC8vIGFuZCBhcmUgdGhlIGxhdGl0dWRlcyBzbWFsbGVyIHRoYW4gdGhlIHBhcmFsbGVsIChwaGkpP1xuICAgICAgaWYgKGFudGltZXJpZGlhbiBeIGxhbWJkYTAgPj0gbGFtYmRhIF4gbGFtYmRhMSA+PSBsYW1iZGEpIHtcbiAgICAgICAgdmFyIGFyYyA9IGNhcnRlc2lhbkNyb3NzKGNhcnRlc2lhbihwb2ludDApLCBjYXJ0ZXNpYW4ocG9pbnQxKSk7XG4gICAgICAgIGNhcnRlc2lhbk5vcm1hbGl6ZUluUGxhY2UoYXJjKTtcbiAgICAgICAgdmFyIGludGVyc2VjdGlvbiA9IGNhcnRlc2lhbkNyb3NzKG5vcm1hbCwgYXJjKTtcbiAgICAgICAgY2FydGVzaWFuTm9ybWFsaXplSW5QbGFjZShpbnRlcnNlY3Rpb24pO1xuICAgICAgICB2YXIgcGhpQXJjID0gKGFudGltZXJpZGlhbiBeIGRlbHRhID49IDAgPyAtMSA6IDEpICogYXNpbihpbnRlcnNlY3Rpb25bMl0pO1xuICAgICAgICBpZiAocGhpID4gcGhpQXJjIHx8IHBoaSA9PT0gcGhpQXJjICYmIChhcmNbMF0gfHwgYXJjWzFdKSkge1xuICAgICAgICAgIHdpbmRpbmcgKz0gYW50aW1lcmlkaWFuIF4gZGVsdGEgPj0gMCA/IDEgOiAtMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEZpcnN0LCBkZXRlcm1pbmUgd2hldGhlciB0aGUgU291dGggcG9sZSBpcyBpbnNpZGUgb3Igb3V0c2lkZTpcbiAgLy9cbiAgLy8gSXQgaXMgaW5zaWRlIGlmOlxuICAvLyAqIHRoZSBwb2x5Z29uIHdpbmRzIGFyb3VuZCBpdCBpbiBhIGNsb2Nrd2lzZSBkaXJlY3Rpb24uXG4gIC8vICogdGhlIHBvbHlnb24gZG9lcyBub3QgKGN1bXVsYXRpdmVseSkgd2luZCBhcm91bmQgaXQsIGJ1dCBoYXMgYSBuZWdhdGl2ZVxuICAvLyAgIChjb3VudGVyLWNsb2Nrd2lzZSkgYXJlYS5cbiAgLy9cbiAgLy8gU2Vjb25kLCBjb3VudCB0aGUgKHNpZ25lZCkgbnVtYmVyIG9mIHRpbWVzIGEgc2VnbWVudCBjcm9zc2VzIGEgbGFtYmRhXG4gIC8vIGZyb20gdGhlIHBvaW50IHRvIHRoZSBTb3V0aCBwb2xlLiAgSWYgaXQgaXMgemVybywgdGhlbiB0aGUgcG9pbnQgaXMgdGhlXG4gIC8vIHNhbWUgc2lkZSBhcyB0aGUgU291dGggcG9sZS5cblxuICByZXR1cm4gKGFuZ2xlIDwgLWVwc2lsb24kMiB8fCBhbmdsZSA8IGVwc2lsb24kMiAmJiBzdW0kMSA8IC1lcHNpbG9uJDIpIF4gKHdpbmRpbmcgJiAxKTtcbn07XG5cbnZhciBsZW5ndGhTdW0gPSBhZGRlcigpO1xudmFyIGxhbWJkYTAkMjtcbnZhciBzaW5QaGkwJDE7XG52YXIgY29zUGhpMCQxO1xuXG52YXIgbGVuZ3RoU3RyZWFtID0ge1xuICBzcGhlcmU6IG5vb3AkMSxcbiAgcG9pbnQ6IG5vb3AkMSxcbiAgbGluZVN0YXJ0OiBsZW5ndGhMaW5lU3RhcnQsXG4gIGxpbmVFbmQ6IG5vb3AkMSxcbiAgcG9seWdvblN0YXJ0OiBub29wJDEsXG4gIHBvbHlnb25FbmQ6IG5vb3AkMVxufTtcblxuZnVuY3Rpb24gbGVuZ3RoTGluZVN0YXJ0KCkge1xuICBsZW5ndGhTdHJlYW0ucG9pbnQgPSBsZW5ndGhQb2ludEZpcnN0O1xuICBsZW5ndGhTdHJlYW0ubGluZUVuZCA9IGxlbmd0aExpbmVFbmQ7XG59XG5cbmZ1bmN0aW9uIGxlbmd0aExpbmVFbmQoKSB7XG4gIGxlbmd0aFN0cmVhbS5wb2ludCA9IGxlbmd0aFN0cmVhbS5saW5lRW5kID0gbm9vcCQxO1xufVxuXG5mdW5jdGlvbiBsZW5ndGhQb2ludEZpcnN0KGxhbWJkYSwgcGhpKSB7XG4gIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFucztcbiAgbGFtYmRhMCQyID0gbGFtYmRhLCBzaW5QaGkwJDEgPSBzaW4kMShwaGkpLCBjb3NQaGkwJDEgPSBjb3MkMShwaGkpO1xuICBsZW5ndGhTdHJlYW0ucG9pbnQgPSBsZW5ndGhQb2ludDtcbn1cblxuZnVuY3Rpb24gbGVuZ3RoUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgbGFtYmRhICo9IHJhZGlhbnMsIHBoaSAqPSByYWRpYW5zO1xuICB2YXIgc2luUGhpID0gc2luJDEocGhpKSxcbiAgICAgIGNvc1BoaSA9IGNvcyQxKHBoaSksXG4gICAgICBkZWx0YSA9IGFicyhsYW1iZGEgLSBsYW1iZGEwJDIpLFxuICAgICAgY29zRGVsdGEgPSBjb3MkMShkZWx0YSksXG4gICAgICBzaW5EZWx0YSA9IHNpbiQxKGRlbHRhKSxcbiAgICAgIHggPSBjb3NQaGkgKiBzaW5EZWx0YSxcbiAgICAgIHkgPSBjb3NQaGkwJDEgKiBzaW5QaGkgLSBzaW5QaGkwJDEgKiBjb3NQaGkgKiBjb3NEZWx0YSxcbiAgICAgIHogPSBzaW5QaGkwJDEgKiBzaW5QaGkgKyBjb3NQaGkwJDEgKiBjb3NQaGkgKiBjb3NEZWx0YTtcbiAgbGVuZ3RoU3VtLmFkZChhdGFuMihzcXJ0KHggKiB4ICsgeSAqIHkpLCB6KSk7XG4gIGxhbWJkYTAkMiA9IGxhbWJkYSwgc2luUGhpMCQxID0gc2luUGhpLCBjb3NQaGkwJDEgPSBjb3NQaGk7XG59XG5cbnZhciBsZW5ndGgkMSA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICBsZW5ndGhTdW0ucmVzZXQoKTtcbiAgZ2VvU3RyZWFtKG9iamVjdCwgbGVuZ3RoU3RyZWFtKTtcbiAgcmV0dXJuICtsZW5ndGhTdW07XG59O1xuXG52YXIgY29vcmRpbmF0ZXMgPSBbbnVsbCwgbnVsbF07XG52YXIgb2JqZWN0JDEgPSB7dHlwZTogXCJMaW5lU3RyaW5nXCIsIGNvb3JkaW5hdGVzOiBjb29yZGluYXRlc307XG5cbnZhciBkaXN0YW5jZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgY29vcmRpbmF0ZXNbMF0gPSBhO1xuICBjb29yZGluYXRlc1sxXSA9IGI7XG4gIHJldHVybiBsZW5ndGgkMShvYmplY3QkMSk7XG59O1xuXG52YXIgY29udGFpbnNPYmplY3RUeXBlID0ge1xuICBGZWF0dXJlOiBmdW5jdGlvbihvYmplY3QsIHBvaW50KSB7XG4gICAgcmV0dXJuIGNvbnRhaW5zR2VvbWV0cnkob2JqZWN0Lmdlb21ldHJ5LCBwb2ludCk7XG4gIH0sXG4gIEZlYXR1cmVDb2xsZWN0aW9uOiBmdW5jdGlvbihvYmplY3QsIHBvaW50KSB7XG4gICAgdmFyIGZlYXR1cmVzID0gb2JqZWN0LmZlYXR1cmVzLCBpID0gLTEsIG4gPSBmZWF0dXJlcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmIChjb250YWluc0dlb21ldHJ5KGZlYXR1cmVzW2ldLmdlb21ldHJ5LCBwb2ludCkpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxudmFyIGNvbnRhaW5zR2VvbWV0cnlUeXBlID0ge1xuICBTcGhlcmU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9LFxuICBQb2ludDogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHJldHVybiBjb250YWluc1BvaW50KG9iamVjdC5jb29yZGluYXRlcywgcG9pbnQpO1xuICB9LFxuICBNdWx0aVBvaW50OiBmdW5jdGlvbihvYmplY3QsIHBvaW50KSB7XG4gICAgdmFyIGNvb3JkaW5hdGVzID0gb2JqZWN0LmNvb3JkaW5hdGVzLCBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmIChjb250YWluc1BvaW50KGNvb3JkaW5hdGVzW2ldLCBwb2ludCkpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgTGluZVN0cmluZzogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHJldHVybiBjb250YWluc0xpbmUob2JqZWN0LmNvb3JkaW5hdGVzLCBwb2ludCk7XG4gIH0sXG4gIE11bHRpTGluZVN0cmluZzogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHZhciBjb29yZGluYXRlcyA9IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoY29udGFpbnNMaW5lKGNvb3JkaW5hdGVzW2ldLCBwb2ludCkpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgUG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHJldHVybiBjb250YWluc1BvbHlnb24ob2JqZWN0LmNvb3JkaW5hdGVzLCBwb2ludCk7XG4gIH0sXG4gIE11bHRpUG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHZhciBjb29yZGluYXRlcyA9IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoY29udGFpbnNQb2x5Z29uKGNvb3JkaW5hdGVzW2ldLCBwb2ludCkpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgR2VvbWV0cnlDb2xsZWN0aW9uOiBmdW5jdGlvbihvYmplY3QsIHBvaW50KSB7XG4gICAgdmFyIGdlb21ldHJpZXMgPSBvYmplY3QuZ2VvbWV0cmllcywgaSA9IC0xLCBuID0gZ2VvbWV0cmllcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmIChjb250YWluc0dlb21ldHJ5KGdlb21ldHJpZXNbaV0sIHBvaW50KSkgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjb250YWluc0dlb21ldHJ5KGdlb21ldHJ5LCBwb2ludCkge1xuICByZXR1cm4gZ2VvbWV0cnkgJiYgY29udGFpbnNHZW9tZXRyeVR5cGUuaGFzT3duUHJvcGVydHkoZ2VvbWV0cnkudHlwZSlcbiAgICAgID8gY29udGFpbnNHZW9tZXRyeVR5cGVbZ2VvbWV0cnkudHlwZV0oZ2VvbWV0cnksIHBvaW50KVxuICAgICAgOiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY29udGFpbnNQb2ludChjb29yZGluYXRlcywgcG9pbnQpIHtcbiAgcmV0dXJuIGRpc3RhbmNlKGNvb3JkaW5hdGVzLCBwb2ludCkgPT09IDA7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zTGluZShjb29yZGluYXRlcywgcG9pbnQpIHtcbiAgdmFyIGFiID0gZGlzdGFuY2UoY29vcmRpbmF0ZXNbMF0sIGNvb3JkaW5hdGVzWzFdKSxcbiAgICAgIGFvID0gZGlzdGFuY2UoY29vcmRpbmF0ZXNbMF0sIHBvaW50KSxcbiAgICAgIG9iID0gZGlzdGFuY2UocG9pbnQsIGNvb3JkaW5hdGVzWzFdKTtcbiAgcmV0dXJuIGFvICsgb2IgPD0gYWIgKyBlcHNpbG9uJDI7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zUG9seWdvbihjb29yZGluYXRlcywgcG9pbnQpIHtcbiAgcmV0dXJuICEhcG9seWdvbkNvbnRhaW5zKGNvb3JkaW5hdGVzLm1hcChyaW5nUmFkaWFucyksIHBvaW50UmFkaWFucyhwb2ludCkpO1xufVxuXG5mdW5jdGlvbiByaW5nUmFkaWFucyhyaW5nKSB7XG4gIHJldHVybiByaW5nID0gcmluZy5tYXAocG9pbnRSYWRpYW5zKSwgcmluZy5wb3AoKSwgcmluZztcbn1cblxuZnVuY3Rpb24gcG9pbnRSYWRpYW5zKHBvaW50KSB7XG4gIHJldHVybiBbcG9pbnRbMF0gKiByYWRpYW5zLCBwb2ludFsxXSAqIHJhZGlhbnNdO1xufVxuXG52YXIgY29udGFpbnMgPSBmdW5jdGlvbihvYmplY3QsIHBvaW50KSB7XG4gIHJldHVybiAob2JqZWN0ICYmIGNvbnRhaW5zT2JqZWN0VHlwZS5oYXNPd25Qcm9wZXJ0eShvYmplY3QudHlwZSlcbiAgICAgID8gY29udGFpbnNPYmplY3RUeXBlW29iamVjdC50eXBlXVxuICAgICAgOiBjb250YWluc0dlb21ldHJ5KShvYmplY3QsIHBvaW50KTtcbn07XG5cbmZ1bmN0aW9uIGdyYXRpY3VsZVgoeTAsIHkxLCBkeSkge1xuICB2YXIgeSA9IHNlcXVlbmNlKHkwLCB5MSAtIGVwc2lsb24kMiwgZHkpLmNvbmNhdCh5MSk7XG4gIHJldHVybiBmdW5jdGlvbih4KSB7IHJldHVybiB5Lm1hcChmdW5jdGlvbih5KSB7IHJldHVybiBbeCwgeV07IH0pOyB9O1xufVxuXG5mdW5jdGlvbiBncmF0aWN1bGVZKHgwLCB4MSwgZHgpIHtcbiAgdmFyIHggPSBzZXF1ZW5jZSh4MCwgeDEgLSBlcHNpbG9uJDIsIGR4KS5jb25jYXQoeDEpO1xuICByZXR1cm4gZnVuY3Rpb24oeSkgeyByZXR1cm4geC5tYXAoZnVuY3Rpb24oeCkgeyByZXR1cm4gW3gsIHldOyB9KTsgfTtcbn1cblxuZnVuY3Rpb24gZ3JhdGljdWxlKCkge1xuICB2YXIgeDEsIHgwLCBYMSwgWDAsXG4gICAgICB5MSwgeTAsIFkxLCBZMCxcbiAgICAgIGR4ID0gMTAsIGR5ID0gZHgsIERYID0gOTAsIERZID0gMzYwLFxuICAgICAgeCwgeSwgWCwgWSxcbiAgICAgIHByZWNpc2lvbiA9IDIuNTtcblxuICBmdW5jdGlvbiBncmF0aWN1bGUoKSB7XG4gICAgcmV0dXJuIHt0eXBlOiBcIk11bHRpTGluZVN0cmluZ1wiLCBjb29yZGluYXRlczogbGluZXMoKX07XG4gIH1cblxuICBmdW5jdGlvbiBsaW5lcygpIHtcbiAgICByZXR1cm4gc2VxdWVuY2UoY2VpbChYMCAvIERYKSAqIERYLCBYMSwgRFgpLm1hcChYKVxuICAgICAgICAuY29uY2F0KHNlcXVlbmNlKGNlaWwoWTAgLyBEWSkgKiBEWSwgWTEsIERZKS5tYXAoWSkpXG4gICAgICAgIC5jb25jYXQoc2VxdWVuY2UoY2VpbCh4MCAvIGR4KSAqIGR4LCB4MSwgZHgpLmZpbHRlcihmdW5jdGlvbih4KSB7IHJldHVybiBhYnMoeCAlIERYKSA+IGVwc2lsb24kMjsgfSkubWFwKHgpKVxuICAgICAgICAuY29uY2F0KHNlcXVlbmNlKGNlaWwoeTAgLyBkeSkgKiBkeSwgeTEsIGR5KS5maWx0ZXIoZnVuY3Rpb24oeSkgeyByZXR1cm4gYWJzKHkgJSBEWSkgPiBlcHNpbG9uJDI7IH0pLm1hcCh5KSk7XG4gIH1cblxuICBncmF0aWN1bGUubGluZXMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbGluZXMoKS5tYXAoZnVuY3Rpb24oY29vcmRpbmF0ZXMpIHsgcmV0dXJuIHt0eXBlOiBcIkxpbmVTdHJpbmdcIiwgY29vcmRpbmF0ZXM6IGNvb3JkaW5hdGVzfTsgfSk7XG4gIH07XG5cbiAgZ3JhdGljdWxlLm91dGxpbmUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogXCJQb2x5Z29uXCIsXG4gICAgICBjb29yZGluYXRlczogW1xuICAgICAgICBYKFgwKS5jb25jYXQoXG4gICAgICAgIFkoWTEpLnNsaWNlKDEpLFxuICAgICAgICBYKFgxKS5yZXZlcnNlKCkuc2xpY2UoMSksXG4gICAgICAgIFkoWTApLnJldmVyc2UoKS5zbGljZSgxKSlcbiAgICAgIF1cbiAgICB9O1xuICB9O1xuXG4gIGdyYXRpY3VsZS5leHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZ3JhdGljdWxlLmV4dGVudE1pbm9yKCk7XG4gICAgcmV0dXJuIGdyYXRpY3VsZS5leHRlbnRNYWpvcihfKS5leHRlbnRNaW5vcihfKTtcbiAgfTtcblxuICBncmF0aWN1bGUuZXh0ZW50TWFqb3IgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gW1tYMCwgWTBdLCBbWDEsIFkxXV07XG4gICAgWDAgPSArX1swXVswXSwgWDEgPSArX1sxXVswXTtcbiAgICBZMCA9ICtfWzBdWzFdLCBZMSA9ICtfWzFdWzFdO1xuICAgIGlmIChYMCA+IFgxKSBfID0gWDAsIFgwID0gWDEsIFgxID0gXztcbiAgICBpZiAoWTAgPiBZMSkgXyA9IFkwLCBZMCA9IFkxLCBZMSA9IF87XG4gICAgcmV0dXJuIGdyYXRpY3VsZS5wcmVjaXNpb24ocHJlY2lzaW9uKTtcbiAgfTtcblxuICBncmF0aWN1bGUuZXh0ZW50TWlub3IgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gW1t4MCwgeTBdLCBbeDEsIHkxXV07XG4gICAgeDAgPSArX1swXVswXSwgeDEgPSArX1sxXVswXTtcbiAgICB5MCA9ICtfWzBdWzFdLCB5MSA9ICtfWzFdWzFdO1xuICAgIGlmICh4MCA+IHgxKSBfID0geDAsIHgwID0geDEsIHgxID0gXztcbiAgICBpZiAoeTAgPiB5MSkgXyA9IHkwLCB5MCA9IHkxLCB5MSA9IF87XG4gICAgcmV0dXJuIGdyYXRpY3VsZS5wcmVjaXNpb24ocHJlY2lzaW9uKTtcbiAgfTtcblxuICBncmF0aWN1bGUuc3RlcCA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBncmF0aWN1bGUuc3RlcE1pbm9yKCk7XG4gICAgcmV0dXJuIGdyYXRpY3VsZS5zdGVwTWFqb3IoXykuc3RlcE1pbm9yKF8pO1xuICB9O1xuXG4gIGdyYXRpY3VsZS5zdGVwTWFqb3IgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gW0RYLCBEWV07XG4gICAgRFggPSArX1swXSwgRFkgPSArX1sxXTtcbiAgICByZXR1cm4gZ3JhdGljdWxlO1xuICB9O1xuXG4gIGdyYXRpY3VsZS5zdGVwTWlub3IgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gW2R4LCBkeV07XG4gICAgZHggPSArX1swXSwgZHkgPSArX1sxXTtcbiAgICByZXR1cm4gZ3JhdGljdWxlO1xuICB9O1xuXG4gIGdyYXRpY3VsZS5wcmVjaXNpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcHJlY2lzaW9uO1xuICAgIHByZWNpc2lvbiA9ICtfO1xuICAgIHggPSBncmF0aWN1bGVYKHkwLCB5MSwgOTApO1xuICAgIHkgPSBncmF0aWN1bGVZKHgwLCB4MSwgcHJlY2lzaW9uKTtcbiAgICBYID0gZ3JhdGljdWxlWChZMCwgWTEsIDkwKTtcbiAgICBZID0gZ3JhdGljdWxlWShYMCwgWDEsIHByZWNpc2lvbik7XG4gICAgcmV0dXJuIGdyYXRpY3VsZTtcbiAgfTtcblxuICByZXR1cm4gZ3JhdGljdWxlXG4gICAgICAuZXh0ZW50TWFqb3IoW1stMTgwLCAtOTAgKyBlcHNpbG9uJDJdLCBbMTgwLCA5MCAtIGVwc2lsb24kMl1dKVxuICAgICAgLmV4dGVudE1pbm9yKFtbLTE4MCwgLTgwIC0gZXBzaWxvbiQyXSwgWzE4MCwgODAgKyBlcHNpbG9uJDJdXSk7XG59XG5cbmZ1bmN0aW9uIGdyYXRpY3VsZTEwKCkge1xuICByZXR1cm4gZ3JhdGljdWxlKCkoKTtcbn1cblxudmFyIGludGVycG9sYXRlJDEgPSBmdW5jdGlvbihhLCBiKSB7XG4gIHZhciB4MCA9IGFbMF0gKiByYWRpYW5zLFxuICAgICAgeTAgPSBhWzFdICogcmFkaWFucyxcbiAgICAgIHgxID0gYlswXSAqIHJhZGlhbnMsXG4gICAgICB5MSA9IGJbMV0gKiByYWRpYW5zLFxuICAgICAgY3kwID0gY29zJDEoeTApLFxuICAgICAgc3kwID0gc2luJDEoeTApLFxuICAgICAgY3kxID0gY29zJDEoeTEpLFxuICAgICAgc3kxID0gc2luJDEoeTEpLFxuICAgICAga3gwID0gY3kwICogY29zJDEoeDApLFxuICAgICAga3kwID0gY3kwICogc2luJDEoeDApLFxuICAgICAga3gxID0gY3kxICogY29zJDEoeDEpLFxuICAgICAga3kxID0gY3kxICogc2luJDEoeDEpLFxuICAgICAgZCA9IDIgKiBhc2luKHNxcnQoaGF2ZXJzaW4oeTEgLSB5MCkgKyBjeTAgKiBjeTEgKiBoYXZlcnNpbih4MSAtIHgwKSkpLFxuICAgICAgayA9IHNpbiQxKGQpO1xuXG4gIHZhciBpbnRlcnBvbGF0ZSA9IGQgPyBmdW5jdGlvbih0KSB7XG4gICAgdmFyIEIgPSBzaW4kMSh0ICo9IGQpIC8gayxcbiAgICAgICAgQSA9IHNpbiQxKGQgLSB0KSAvIGssXG4gICAgICAgIHggPSBBICoga3gwICsgQiAqIGt4MSxcbiAgICAgICAgeSA9IEEgKiBreTAgKyBCICoga3kxLFxuICAgICAgICB6ID0gQSAqIHN5MCArIEIgKiBzeTE7XG4gICAgcmV0dXJuIFtcbiAgICAgIGF0YW4yKHksIHgpICogZGVncmVlcyQxLFxuICAgICAgYXRhbjIoeiwgc3FydCh4ICogeCArIHkgKiB5KSkgKiBkZWdyZWVzJDFcbiAgICBdO1xuICB9IDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIFt4MCAqIGRlZ3JlZXMkMSwgeTAgKiBkZWdyZWVzJDFdO1xuICB9O1xuXG4gIGludGVycG9sYXRlLmRpc3RhbmNlID0gZDtcblxuICByZXR1cm4gaW50ZXJwb2xhdGU7XG59O1xuXG52YXIgaWRlbnRpdHkkNCA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIHg7XG59O1xuXG52YXIgYXJlYVN1bSQxID0gYWRkZXIoKTtcbnZhciBhcmVhUmluZ1N1bSQxID0gYWRkZXIoKTtcbnZhciB4MDA7XG52YXIgeTAwO1xudmFyIHgwJDE7XG52YXIgeTAkMTtcblxudmFyIGFyZWFTdHJlYW0kMSA9IHtcbiAgcG9pbnQ6IG5vb3AkMSxcbiAgbGluZVN0YXJ0OiBub29wJDEsXG4gIGxpbmVFbmQ6IG5vb3AkMSxcbiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICBhcmVhU3RyZWFtJDEubGluZVN0YXJ0ID0gYXJlYVJpbmdTdGFydCQxO1xuICAgIGFyZWFTdHJlYW0kMS5saW5lRW5kID0gYXJlYVJpbmdFbmQkMTtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgYXJlYVN0cmVhbSQxLmxpbmVTdGFydCA9IGFyZWFTdHJlYW0kMS5saW5lRW5kID0gYXJlYVN0cmVhbSQxLnBvaW50ID0gbm9vcCQxO1xuICAgIGFyZWFTdW0kMS5hZGQoYWJzKGFyZWFSaW5nU3VtJDEpKTtcbiAgICBhcmVhUmluZ1N1bSQxLnJlc2V0KCk7XG4gIH0sXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZWEgPSBhcmVhU3VtJDEgLyAyO1xuICAgIGFyZWFTdW0kMS5yZXNldCgpO1xuICAgIHJldHVybiBhcmVhO1xuICB9XG59O1xuXG5mdW5jdGlvbiBhcmVhUmluZ1N0YXJ0JDEoKSB7XG4gIGFyZWFTdHJlYW0kMS5wb2ludCA9IGFyZWFQb2ludEZpcnN0JDE7XG59XG5cbmZ1bmN0aW9uIGFyZWFQb2ludEZpcnN0JDEoeCwgeSkge1xuICBhcmVhU3RyZWFtJDEucG9pbnQgPSBhcmVhUG9pbnQkMTtcbiAgeDAwID0geDAkMSA9IHgsIHkwMCA9IHkwJDEgPSB5O1xufVxuXG5mdW5jdGlvbiBhcmVhUG9pbnQkMSh4LCB5KSB7XG4gIGFyZWFSaW5nU3VtJDEuYWRkKHkwJDEgKiB4IC0geDAkMSAqIHkpO1xuICB4MCQxID0geCwgeTAkMSA9IHk7XG59XG5cbmZ1bmN0aW9uIGFyZWFSaW5nRW5kJDEoKSB7XG4gIGFyZWFQb2ludCQxKHgwMCwgeTAwKTtcbn1cblxudmFyIHgwJDIgPSBJbmZpbml0eTtcbnZhciB5MCQyID0geDAkMjtcbnZhciB4MSA9IC14MCQyO1xudmFyIHkxID0geDE7XG5cbnZhciBib3VuZHNTdHJlYW0kMSA9IHtcbiAgcG9pbnQ6IGJvdW5kc1BvaW50JDEsXG4gIGxpbmVTdGFydDogbm9vcCQxLFxuICBsaW5lRW5kOiBub29wJDEsXG4gIHBvbHlnb25TdGFydDogbm9vcCQxLFxuICBwb2x5Z29uRW5kOiBub29wJDEsXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJvdW5kcyA9IFtbeDAkMiwgeTAkMl0sIFt4MSwgeTFdXTtcbiAgICB4MSA9IHkxID0gLSh5MCQyID0geDAkMiA9IEluZmluaXR5KTtcbiAgICByZXR1cm4gYm91bmRzO1xuICB9XG59O1xuXG5mdW5jdGlvbiBib3VuZHNQb2ludCQxKHgsIHkpIHtcbiAgaWYgKHggPCB4MCQyKSB4MCQyID0geDtcbiAgaWYgKHggPiB4MSkgeDEgPSB4O1xuICBpZiAoeSA8IHkwJDIpIHkwJDIgPSB5O1xuICBpZiAoeSA+IHkxKSB5MSA9IHk7XG59XG5cbi8vIFRPRE8gRW5mb3JjZSBwb3NpdGl2ZSBhcmVhIGZvciBleHRlcmlvciwgbmVnYXRpdmUgYXJlYSBmb3IgaW50ZXJpb3I/XG5cbnZhciBYMCQxID0gMDtcbnZhciBZMCQxID0gMDtcbnZhciBaMCQxID0gMDtcbnZhciBYMSQxID0gMDtcbnZhciBZMSQxID0gMDtcbnZhciBaMSQxID0gMDtcbnZhciBYMiQxID0gMDtcbnZhciBZMiQxID0gMDtcbnZhciBaMiQxID0gMDtcbnZhciB4MDAkMTtcbnZhciB5MDAkMTtcbnZhciB4MCQzO1xudmFyIHkwJDM7XG5cbnZhciBjZW50cm9pZFN0cmVhbSQxID0ge1xuICBwb2ludDogY2VudHJvaWRQb2ludCQxLFxuICBsaW5lU3RhcnQ6IGNlbnRyb2lkTGluZVN0YXJ0JDEsXG4gIGxpbmVFbmQ6IGNlbnRyb2lkTGluZUVuZCQxLFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIGNlbnRyb2lkU3RyZWFtJDEubGluZVN0YXJ0ID0gY2VudHJvaWRSaW5nU3RhcnQkMTtcbiAgICBjZW50cm9pZFN0cmVhbSQxLmxpbmVFbmQgPSBjZW50cm9pZFJpbmdFbmQkMTtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgY2VudHJvaWRTdHJlYW0kMS5wb2ludCA9IGNlbnRyb2lkUG9pbnQkMTtcbiAgICBjZW50cm9pZFN0cmVhbSQxLmxpbmVTdGFydCA9IGNlbnRyb2lkTGluZVN0YXJ0JDE7XG4gICAgY2VudHJvaWRTdHJlYW0kMS5saW5lRW5kID0gY2VudHJvaWRMaW5lRW5kJDE7XG4gIH0sXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNlbnRyb2lkID0gWjIkMSA/IFtYMiQxIC8gWjIkMSwgWTIkMSAvIFoyJDFdXG4gICAgICAgIDogWjEkMSA/IFtYMSQxIC8gWjEkMSwgWTEkMSAvIFoxJDFdXG4gICAgICAgIDogWjAkMSA/IFtYMCQxIC8gWjAkMSwgWTAkMSAvIFowJDFdXG4gICAgICAgIDogW05hTiwgTmFOXTtcbiAgICBYMCQxID0gWTAkMSA9IFowJDEgPVxuICAgIFgxJDEgPSBZMSQxID0gWjEkMSA9XG4gICAgWDIkMSA9IFkyJDEgPSBaMiQxID0gMDtcbiAgICByZXR1cm4gY2VudHJvaWQ7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUG9pbnQkMSh4LCB5KSB7XG4gIFgwJDEgKz0geDtcbiAgWTAkMSArPSB5O1xuICArK1owJDE7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkTGluZVN0YXJ0JDEoKSB7XG4gIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50Rmlyc3RMaW5lO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFBvaW50Rmlyc3RMaW5lKHgsIHkpIHtcbiAgY2VudHJvaWRTdHJlYW0kMS5wb2ludCA9IGNlbnRyb2lkUG9pbnRMaW5lO1xuICBjZW50cm9pZFBvaW50JDEoeDAkMyA9IHgsIHkwJDMgPSB5KTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRQb2ludExpbmUoeCwgeSkge1xuICB2YXIgZHggPSB4IC0geDAkMywgZHkgPSB5IC0geTAkMywgeiA9IHNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xuICBYMSQxICs9IHogKiAoeDAkMyArIHgpIC8gMjtcbiAgWTEkMSArPSB6ICogKHkwJDMgKyB5KSAvIDI7XG4gIFoxJDEgKz0gejtcbiAgY2VudHJvaWRQb2ludCQxKHgwJDMgPSB4LCB5MCQzID0geSk7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkTGluZUVuZCQxKCkge1xuICBjZW50cm9pZFN0cmVhbSQxLnBvaW50ID0gY2VudHJvaWRQb2ludCQxO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFJpbmdTdGFydCQxKCkge1xuICBjZW50cm9pZFN0cmVhbSQxLnBvaW50ID0gY2VudHJvaWRQb2ludEZpcnN0UmluZztcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRSaW5nRW5kJDEoKSB7XG4gIGNlbnRyb2lkUG9pbnRSaW5nKHgwMCQxLCB5MDAkMSk7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUG9pbnRGaXJzdFJpbmcoeCwgeSkge1xuICBjZW50cm9pZFN0cmVhbSQxLnBvaW50ID0gY2VudHJvaWRQb2ludFJpbmc7XG4gIGNlbnRyb2lkUG9pbnQkMSh4MDAkMSA9IHgwJDMgPSB4LCB5MDAkMSA9IHkwJDMgPSB5KTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRQb2ludFJpbmcoeCwgeSkge1xuICB2YXIgZHggPSB4IC0geDAkMyxcbiAgICAgIGR5ID0geSAtIHkwJDMsXG4gICAgICB6ID0gc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG5cbiAgWDEkMSArPSB6ICogKHgwJDMgKyB4KSAvIDI7XG4gIFkxJDEgKz0geiAqICh5MCQzICsgeSkgLyAyO1xuICBaMSQxICs9IHo7XG5cbiAgeiA9IHkwJDMgKiB4IC0geDAkMyAqIHk7XG4gIFgyJDEgKz0geiAqICh4MCQzICsgeCk7XG4gIFkyJDEgKz0geiAqICh5MCQzICsgeSk7XG4gIFoyJDEgKz0geiAqIDM7XG4gIGNlbnRyb2lkUG9pbnQkMSh4MCQzID0geCwgeTAkMyA9IHkpO1xufVxuXG5mdW5jdGlvbiBQYXRoQ29udGV4dChjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5QYXRoQ29udGV4dC5wcm90b3R5cGUgPSB7XG4gIF9yYWRpdXM6IDQuNSxcbiAgcG9pbnRSYWRpdXM6IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gdGhpcy5fcmFkaXVzID0gXywgdGhpcztcbiAgfSxcbiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9saW5lID09PSAwKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX3BvaW50ID0gTmFOO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDoge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4LCB5KTtcbiAgICAgICAgdGhpcy5fcG9pbnQgPSAxO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubW92ZVRvKHggKyB0aGlzLl9yYWRpdXMsIHkpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmFyYyh4LCB5LCB0aGlzLl9yYWRpdXMsIDAsIHRhdSQzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICByZXN1bHQ6IG5vb3AkMVxufTtcblxudmFyIGxlbmd0aFN1bSQxID0gYWRkZXIoKTtcbnZhciBsZW5ndGhSaW5nO1xudmFyIHgwMCQyO1xudmFyIHkwMCQyO1xudmFyIHgwJDQ7XG52YXIgeTAkNDtcblxudmFyIGxlbmd0aFN0cmVhbSQxID0ge1xuICBwb2ludDogbm9vcCQxLFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIGxlbmd0aFN0cmVhbSQxLnBvaW50ID0gbGVuZ3RoUG9pbnRGaXJzdCQxO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAobGVuZ3RoUmluZykgbGVuZ3RoUG9pbnQkMSh4MDAkMiwgeTAwJDIpO1xuICAgIGxlbmd0aFN0cmVhbSQxLnBvaW50ID0gbm9vcCQxO1xuICB9LFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIGxlbmd0aFJpbmcgPSB0cnVlO1xuICB9LFxuICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICBsZW5ndGhSaW5nID0gbnVsbDtcbiAgfSxcbiAgcmVzdWx0OiBmdW5jdGlvbigpIHtcbiAgICB2YXIgbGVuZ3RoID0gK2xlbmd0aFN1bSQxO1xuICAgIGxlbmd0aFN1bSQxLnJlc2V0KCk7XG4gICAgcmV0dXJuIGxlbmd0aDtcbiAgfVxufTtcblxuZnVuY3Rpb24gbGVuZ3RoUG9pbnRGaXJzdCQxKHgsIHkpIHtcbiAgbGVuZ3RoU3RyZWFtJDEucG9pbnQgPSBsZW5ndGhQb2ludCQxO1xuICB4MDAkMiA9IHgwJDQgPSB4LCB5MDAkMiA9IHkwJDQgPSB5O1xufVxuXG5mdW5jdGlvbiBsZW5ndGhQb2ludCQxKHgsIHkpIHtcbiAgeDAkNCAtPSB4LCB5MCQ0IC09IHk7XG4gIGxlbmd0aFN1bSQxLmFkZChzcXJ0KHgwJDQgKiB4MCQ0ICsgeTAkNCAqIHkwJDQpKTtcbiAgeDAkNCA9IHgsIHkwJDQgPSB5O1xufVxuXG5mdW5jdGlvbiBQYXRoU3RyaW5nKCkge1xuICB0aGlzLl9zdHJpbmcgPSBbXTtcbn1cblxuUGF0aFN0cmluZy5wcm90b3R5cGUgPSB7XG4gIF9jaXJjbGU6IGNpcmNsZSQxKDQuNSksXG4gIHBvaW50UmFkaXVzOiBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NpcmNsZSA9IGNpcmNsZSQxKF8pLCB0aGlzO1xuICB9LFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2xpbmUgPT09IDApIHRoaXMuX3N0cmluZy5wdXNoKFwiWlwiKTtcbiAgICB0aGlzLl9wb2ludCA9IE5hTjtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHtcbiAgICAgICAgdGhpcy5fc3RyaW5nLnB1c2goXCJNXCIsIHgsIFwiLFwiLCB5KTtcbiAgICAgICAgdGhpcy5fcG9pbnQgPSAxO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9zdHJpbmcucHVzaChcIkxcIiwgeCwgXCIsXCIsIHkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgdGhpcy5fc3RyaW5nLnB1c2goXCJNXCIsIHgsIFwiLFwiLCB5LCB0aGlzLl9jaXJjbGUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX3N0cmluZy5sZW5ndGgpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9zdHJpbmcuam9pbihcIlwiKTtcbiAgICAgIHRoaXMuX3N0cmluZyA9IFtdO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNpcmNsZSQxKHJhZGl1cykge1xuICByZXR1cm4gXCJtMCxcIiArIHJhZGl1c1xuICAgICAgKyBcImFcIiArIHJhZGl1cyArIFwiLFwiICsgcmFkaXVzICsgXCIgMCAxLDEgMCxcIiArIC0yICogcmFkaXVzXG4gICAgICArIFwiYVwiICsgcmFkaXVzICsgXCIsXCIgKyByYWRpdXMgKyBcIiAwIDEsMSAwLFwiICsgMiAqIHJhZGl1c1xuICAgICAgKyBcInpcIjtcbn1cblxudmFyIGluZGV4JDEgPSBmdW5jdGlvbihwcm9qZWN0aW9uLCBjb250ZXh0KSB7XG4gIHZhciBwb2ludFJhZGl1cyA9IDQuNSxcbiAgICAgIHByb2plY3Rpb25TdHJlYW0sXG4gICAgICBjb250ZXh0U3RyZWFtO1xuXG4gIGZ1bmN0aW9uIHBhdGgob2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdCkge1xuICAgICAgaWYgKHR5cGVvZiBwb2ludFJhZGl1cyA9PT0gXCJmdW5jdGlvblwiKSBjb250ZXh0U3RyZWFtLnBvaW50UmFkaXVzKCtwb2ludFJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oY29udGV4dFN0cmVhbSkpO1xuICAgIH1cbiAgICByZXR1cm4gY29udGV4dFN0cmVhbS5yZXN1bHQoKTtcbiAgfVxuXG4gIHBhdGguYXJlYSA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oYXJlYVN0cmVhbSQxKSk7XG4gICAgcmV0dXJuIGFyZWFTdHJlYW0kMS5yZXN1bHQoKTtcbiAgfTtcblxuICBwYXRoLm1lYXN1cmUgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBnZW9TdHJlYW0ob2JqZWN0LCBwcm9qZWN0aW9uU3RyZWFtKGxlbmd0aFN0cmVhbSQxKSk7XG4gICAgcmV0dXJuIGxlbmd0aFN0cmVhbSQxLnJlc3VsdCgpO1xuICB9O1xuXG4gIHBhdGguYm91bmRzID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgZ2VvU3RyZWFtKG9iamVjdCwgcHJvamVjdGlvblN0cmVhbShib3VuZHNTdHJlYW0kMSkpO1xuICAgIHJldHVybiBib3VuZHNTdHJlYW0kMS5yZXN1bHQoKTtcbiAgfTtcblxuICBwYXRoLmNlbnRyb2lkID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgZ2VvU3RyZWFtKG9iamVjdCwgcHJvamVjdGlvblN0cmVhbShjZW50cm9pZFN0cmVhbSQxKSk7XG4gICAgcmV0dXJuIGNlbnRyb2lkU3RyZWFtJDEucmVzdWx0KCk7XG4gIH07XG5cbiAgcGF0aC5wcm9qZWN0aW9uID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHByb2plY3Rpb25TdHJlYW0gPSBfID09IG51bGwgPyAocHJvamVjdGlvbiA9IG51bGwsIGlkZW50aXR5JDQpIDogKHByb2plY3Rpb24gPSBfKS5zdHJlYW0sIHBhdGgpIDogcHJvamVjdGlvbjtcbiAgfTtcblxuICBwYXRoLmNvbnRleHQgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY29udGV4dDtcbiAgICBjb250ZXh0U3RyZWFtID0gXyA9PSBudWxsID8gKGNvbnRleHQgPSBudWxsLCBuZXcgUGF0aFN0cmluZykgOiBuZXcgUGF0aENvbnRleHQoY29udGV4dCA9IF8pO1xuICAgIGlmICh0eXBlb2YgcG9pbnRSYWRpdXMgIT09IFwiZnVuY3Rpb25cIikgY29udGV4dFN0cmVhbS5wb2ludFJhZGl1cyhwb2ludFJhZGl1cyk7XG4gICAgcmV0dXJuIHBhdGg7XG4gIH07XG5cbiAgcGF0aC5wb2ludFJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBwb2ludFJhZGl1cztcbiAgICBwb2ludFJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogKGNvbnRleHRTdHJlYW0ucG9pbnRSYWRpdXMoK18pLCArXyk7XG4gICAgcmV0dXJuIHBhdGg7XG4gIH07XG5cbiAgcmV0dXJuIHBhdGgucHJvamVjdGlvbihwcm9qZWN0aW9uKS5jb250ZXh0KGNvbnRleHQpO1xufTtcblxudmFyIGNsaXAgPSBmdW5jdGlvbihwb2ludFZpc2libGUsIGNsaXBMaW5lLCBpbnRlcnBvbGF0ZSwgc3RhcnQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHJvdGF0ZSwgc2luaykge1xuICAgIHZhciBsaW5lID0gY2xpcExpbmUoc2luayksXG4gICAgICAgIHJvdGF0ZWRTdGFydCA9IHJvdGF0ZS5pbnZlcnQoc3RhcnRbMF0sIHN0YXJ0WzFdKSxcbiAgICAgICAgcmluZ0J1ZmZlciA9IGNsaXBCdWZmZXIoKSxcbiAgICAgICAgcmluZ1NpbmsgPSBjbGlwTGluZShyaW5nQnVmZmVyKSxcbiAgICAgICAgcG9seWdvblN0YXJ0ZWQgPSBmYWxzZSxcbiAgICAgICAgcG9seWdvbixcbiAgICAgICAgc2VnbWVudHMsXG4gICAgICAgIHJpbmc7XG5cbiAgICB2YXIgY2xpcCA9IHtcbiAgICAgIHBvaW50OiBwb2ludCxcbiAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgbGluZUVuZDogbGluZUVuZCxcbiAgICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGNsaXAucG9pbnQgPSBwb2ludFJpbmc7XG4gICAgICAgIGNsaXAubGluZVN0YXJ0ID0gcmluZ1N0YXJ0O1xuICAgICAgICBjbGlwLmxpbmVFbmQgPSByaW5nRW5kO1xuICAgICAgICBzZWdtZW50cyA9IFtdO1xuICAgICAgICBwb2x5Z29uID0gW107XG4gICAgICB9LFxuICAgICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGNsaXAucG9pbnQgPSBwb2ludDtcbiAgICAgICAgY2xpcC5saW5lU3RhcnQgPSBsaW5lU3RhcnQ7XG4gICAgICAgIGNsaXAubGluZUVuZCA9IGxpbmVFbmQ7XG4gICAgICAgIHNlZ21lbnRzID0gbWVyZ2Uoc2VnbWVudHMpO1xuICAgICAgICB2YXIgc3RhcnRJbnNpZGUgPSBwb2x5Z29uQ29udGFpbnMocG9seWdvbiwgcm90YXRlZFN0YXJ0KTtcbiAgICAgICAgaWYgKHNlZ21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgIGlmICghcG9seWdvblN0YXJ0ZWQpIHNpbmsucG9seWdvblN0YXJ0KCksIHBvbHlnb25TdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgICBjbGlwUG9seWdvbihzZWdtZW50cywgY29tcGFyZUludGVyc2VjdGlvbiwgc3RhcnRJbnNpZGUsIGludGVycG9sYXRlLCBzaW5rKTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGFydEluc2lkZSkge1xuICAgICAgICAgIGlmICghcG9seWdvblN0YXJ0ZWQpIHNpbmsucG9seWdvblN0YXJ0KCksIHBvbHlnb25TdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgICBzaW5rLmxpbmVTdGFydCgpO1xuICAgICAgICAgIGludGVycG9sYXRlKG51bGwsIG51bGwsIDEsIHNpbmspO1xuICAgICAgICAgIHNpbmsubGluZUVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb2x5Z29uU3RhcnRlZCkgc2luay5wb2x5Z29uRW5kKCksIHBvbHlnb25TdGFydGVkID0gZmFsc2U7XG4gICAgICAgIHNlZ21lbnRzID0gcG9seWdvbiA9IG51bGw7XG4gICAgICB9LFxuICAgICAgc3BoZXJlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgc2luay5wb2x5Z29uU3RhcnQoKTtcbiAgICAgICAgc2luay5saW5lU3RhcnQoKTtcbiAgICAgICAgaW50ZXJwb2xhdGUobnVsbCwgbnVsbCwgMSwgc2luayk7XG4gICAgICAgIHNpbmsubGluZUVuZCgpO1xuICAgICAgICBzaW5rLnBvbHlnb25FbmQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgICAgIHZhciBwb2ludCA9IHJvdGF0ZShsYW1iZGEsIHBoaSk7XG4gICAgICBpZiAocG9pbnRWaXNpYmxlKGxhbWJkYSA9IHBvaW50WzBdLCBwaGkgPSBwb2ludFsxXSkpIHNpbmsucG9pbnQobGFtYmRhLCBwaGkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBvaW50TGluZShsYW1iZGEsIHBoaSkge1xuICAgICAgdmFyIHBvaW50ID0gcm90YXRlKGxhbWJkYSwgcGhpKTtcbiAgICAgIGxpbmUucG9pbnQocG9pbnRbMF0sIHBvaW50WzFdKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lU3RhcnQoKSB7XG4gICAgICBjbGlwLnBvaW50ID0gcG9pbnRMaW5lO1xuICAgICAgbGluZS5saW5lU3RhcnQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lRW5kKCkge1xuICAgICAgY2xpcC5wb2ludCA9IHBvaW50O1xuICAgICAgbGluZS5saW5lRW5kKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9pbnRSaW5nKGxhbWJkYSwgcGhpKSB7XG4gICAgICByaW5nLnB1c2goW2xhbWJkYSwgcGhpXSk7XG4gICAgICB2YXIgcG9pbnQgPSByb3RhdGUobGFtYmRhLCBwaGkpO1xuICAgICAgcmluZ1NpbmsucG9pbnQocG9pbnRbMF0sIHBvaW50WzFdKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByaW5nU3RhcnQoKSB7XG4gICAgICByaW5nU2luay5saW5lU3RhcnQoKTtcbiAgICAgIHJpbmcgPSBbXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByaW5nRW5kKCkge1xuICAgICAgcG9pbnRSaW5nKHJpbmdbMF1bMF0sIHJpbmdbMF1bMV0pO1xuICAgICAgcmluZ1NpbmsubGluZUVuZCgpO1xuXG4gICAgICB2YXIgY2xlYW4gPSByaW5nU2luay5jbGVhbigpLFxuICAgICAgICAgIHJpbmdTZWdtZW50cyA9IHJpbmdCdWZmZXIucmVzdWx0KCksXG4gICAgICAgICAgaSwgbiA9IHJpbmdTZWdtZW50cy5sZW5ndGgsIG0sXG4gICAgICAgICAgc2VnbWVudCxcbiAgICAgICAgICBwb2ludDtcblxuICAgICAgcmluZy5wb3AoKTtcbiAgICAgIHBvbHlnb24ucHVzaChyaW5nKTtcbiAgICAgIHJpbmcgPSBudWxsO1xuXG4gICAgICBpZiAoIW4pIHJldHVybjtcblxuICAgICAgLy8gTm8gaW50ZXJzZWN0aW9ucy5cbiAgICAgIGlmIChjbGVhbiAmIDEpIHtcbiAgICAgICAgc2VnbWVudCA9IHJpbmdTZWdtZW50c1swXTtcbiAgICAgICAgaWYgKChtID0gc2VnbWVudC5sZW5ndGggLSAxKSA+IDApIHtcbiAgICAgICAgICBpZiAoIXBvbHlnb25TdGFydGVkKSBzaW5rLnBvbHlnb25TdGFydCgpLCBwb2x5Z29uU3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgc2luay5saW5lU3RhcnQoKTtcbiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbTsgKytpKSBzaW5rLnBvaW50KChwb2ludCA9IHNlZ21lbnRbaV0pWzBdLCBwb2ludFsxXSk7XG4gICAgICAgICAgc2luay5saW5lRW5kKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBSZWpvaW4gY29ubmVjdGVkIHNlZ21lbnRzLlxuICAgICAgLy8gVE9ETyByZXVzZSByaW5nQnVmZmVyLnJlam9pbigpP1xuICAgICAgaWYgKG4gPiAxICYmIGNsZWFuICYgMikgcmluZ1NlZ21lbnRzLnB1c2gocmluZ1NlZ21lbnRzLnBvcCgpLmNvbmNhdChyaW5nU2VnbWVudHMuc2hpZnQoKSkpO1xuXG4gICAgICBzZWdtZW50cy5wdXNoKHJpbmdTZWdtZW50cy5maWx0ZXIodmFsaWRTZWdtZW50KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsaXA7XG4gIH07XG59O1xuXG5mdW5jdGlvbiB2YWxpZFNlZ21lbnQoc2VnbWVudCkge1xuICByZXR1cm4gc2VnbWVudC5sZW5ndGggPiAxO1xufVxuXG4vLyBJbnRlcnNlY3Rpb25zIGFyZSBzb3J0ZWQgYWxvbmcgdGhlIGNsaXAgZWRnZS4gRm9yIGJvdGggYW50aW1lcmlkaWFuIGN1dHRpbmdcbi8vIGFuZCBjaXJjbGUgY2xpcHBpbmcsIHRoZSBzYW1lIGNvbXBhcmlzb24gaXMgdXNlZC5cbmZ1bmN0aW9uIGNvbXBhcmVJbnRlcnNlY3Rpb24oYSwgYikge1xuICByZXR1cm4gKChhID0gYS54KVswXSA8IDAgPyBhWzFdIC0gaGFsZlBpJDIgLSBlcHNpbG9uJDIgOiBoYWxmUGkkMiAtIGFbMV0pXG4gICAgICAgLSAoKGIgPSBiLngpWzBdIDwgMCA/IGJbMV0gLSBoYWxmUGkkMiAtIGVwc2lsb24kMiA6IGhhbGZQaSQyIC0gYlsxXSk7XG59XG5cbnZhciBjbGlwQW50aW1lcmlkaWFuID0gY2xpcChcbiAgZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9LFxuICBjbGlwQW50aW1lcmlkaWFuTGluZSxcbiAgY2xpcEFudGltZXJpZGlhbkludGVycG9sYXRlLFxuICBbLXBpJDMsIC1oYWxmUGkkMl1cbik7XG5cbi8vIFRha2VzIGEgbGluZSBhbmQgY3V0cyBpbnRvIHZpc2libGUgc2VnbWVudHMuIFJldHVybiB2YWx1ZXM6IDAgLSB0aGVyZSB3ZXJlXG4vLyBpbnRlcnNlY3Rpb25zIG9yIHRoZSBsaW5lIHdhcyBlbXB0eTsgMSAtIG5vIGludGVyc2VjdGlvbnM7IDIgLSB0aGVyZSB3ZXJlXG4vLyBpbnRlcnNlY3Rpb25zLCBhbmQgdGhlIGZpcnN0IGFuZCBsYXN0IHNlZ21lbnRzIHNob3VsZCBiZSByZWpvaW5lZC5cbmZ1bmN0aW9uIGNsaXBBbnRpbWVyaWRpYW5MaW5lKHN0cmVhbSkge1xuICB2YXIgbGFtYmRhMCA9IE5hTixcbiAgICAgIHBoaTAgPSBOYU4sXG4gICAgICBzaWduMCA9IE5hTixcbiAgICAgIGNsZWFuOyAvLyBubyBpbnRlcnNlY3Rpb25zXG5cbiAgcmV0dXJuIHtcbiAgICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgY2xlYW4gPSAxO1xuICAgIH0sXG4gICAgcG9pbnQ6IGZ1bmN0aW9uKGxhbWJkYTEsIHBoaTEpIHtcbiAgICAgIHZhciBzaWduMSA9IGxhbWJkYTEgPiAwID8gcGkkMyA6IC1waSQzLFxuICAgICAgICAgIGRlbHRhID0gYWJzKGxhbWJkYTEgLSBsYW1iZGEwKTtcbiAgICAgIGlmIChhYnMoZGVsdGEgLSBwaSQzKSA8IGVwc2lsb24kMikgeyAvLyBsaW5lIGNyb3NzZXMgYSBwb2xlXG4gICAgICAgIHN0cmVhbS5wb2ludChsYW1iZGEwLCBwaGkwID0gKHBoaTAgKyBwaGkxKSAvIDIgPiAwID8gaGFsZlBpJDIgOiAtaGFsZlBpJDIpO1xuICAgICAgICBzdHJlYW0ucG9pbnQoc2lnbjAsIHBoaTApO1xuICAgICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgICAgIHN0cmVhbS5wb2ludChzaWduMSwgcGhpMCk7XG4gICAgICAgIHN0cmVhbS5wb2ludChsYW1iZGExLCBwaGkwKTtcbiAgICAgICAgY2xlYW4gPSAwO1xuICAgICAgfSBlbHNlIGlmIChzaWduMCAhPT0gc2lnbjEgJiYgZGVsdGEgPj0gcGkkMykgeyAvLyBsaW5lIGNyb3NzZXMgYW50aW1lcmlkaWFuXG4gICAgICAgIGlmIChhYnMobGFtYmRhMCAtIHNpZ24wKSA8IGVwc2lsb24kMikgbGFtYmRhMCAtPSBzaWduMCAqIGVwc2lsb24kMjsgLy8gaGFuZGxlIGRlZ2VuZXJhY2llc1xuICAgICAgICBpZiAoYWJzKGxhbWJkYTEgLSBzaWduMSkgPCBlcHNpbG9uJDIpIGxhbWJkYTEgLT0gc2lnbjEgKiBlcHNpbG9uJDI7XG4gICAgICAgIHBoaTAgPSBjbGlwQW50aW1lcmlkaWFuSW50ZXJzZWN0KGxhbWJkYTAsIHBoaTAsIGxhbWJkYTEsIHBoaTEpO1xuICAgICAgICBzdHJlYW0ucG9pbnQoc2lnbjAsIHBoaTApO1xuICAgICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgICAgIHN0cmVhbS5wb2ludChzaWduMSwgcGhpMCk7XG4gICAgICAgIGNsZWFuID0gMDtcbiAgICAgIH1cbiAgICAgIHN0cmVhbS5wb2ludChsYW1iZGEwID0gbGFtYmRhMSwgcGhpMCA9IHBoaTEpO1xuICAgICAgc2lnbjAgPSBzaWduMTtcbiAgICB9LFxuICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgIGxhbWJkYTAgPSBwaGkwID0gTmFOO1xuICAgIH0sXG4gICAgY2xlYW46IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIDIgLSBjbGVhbjsgLy8gaWYgaW50ZXJzZWN0aW9ucywgcmVqb2luIGZpcnN0IGFuZCBsYXN0IHNlZ21lbnRzXG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBjbGlwQW50aW1lcmlkaWFuSW50ZXJzZWN0KGxhbWJkYTAsIHBoaTAsIGxhbWJkYTEsIHBoaTEpIHtcbiAgdmFyIGNvc1BoaTAsXG4gICAgICBjb3NQaGkxLFxuICAgICAgc2luTGFtYmRhMExhbWJkYTEgPSBzaW4kMShsYW1iZGEwIC0gbGFtYmRhMSk7XG4gIHJldHVybiBhYnMoc2luTGFtYmRhMExhbWJkYTEpID4gZXBzaWxvbiQyXG4gICAgICA/IGF0YW4oKHNpbiQxKHBoaTApICogKGNvc1BoaTEgPSBjb3MkMShwaGkxKSkgKiBzaW4kMShsYW1iZGExKVxuICAgICAgICAgIC0gc2luJDEocGhpMSkgKiAoY29zUGhpMCA9IGNvcyQxKHBoaTApKSAqIHNpbiQxKGxhbWJkYTApKVxuICAgICAgICAgIC8gKGNvc1BoaTAgKiBjb3NQaGkxICogc2luTGFtYmRhMExhbWJkYTEpKVxuICAgICAgOiAocGhpMCArIHBoaTEpIC8gMjtcbn1cblxuZnVuY3Rpb24gY2xpcEFudGltZXJpZGlhbkludGVycG9sYXRlKGZyb20sIHRvLCBkaXJlY3Rpb24sIHN0cmVhbSkge1xuICB2YXIgcGhpO1xuICBpZiAoZnJvbSA9PSBudWxsKSB7XG4gICAgcGhpID0gZGlyZWN0aW9uICogaGFsZlBpJDI7XG4gICAgc3RyZWFtLnBvaW50KC1waSQzLCBwaGkpO1xuICAgIHN0cmVhbS5wb2ludCgwLCBwaGkpO1xuICAgIHN0cmVhbS5wb2ludChwaSQzLCBwaGkpO1xuICAgIHN0cmVhbS5wb2ludChwaSQzLCAwKTtcbiAgICBzdHJlYW0ucG9pbnQocGkkMywgLXBoaSk7XG4gICAgc3RyZWFtLnBvaW50KDAsIC1waGkpO1xuICAgIHN0cmVhbS5wb2ludCgtcGkkMywgLXBoaSk7XG4gICAgc3RyZWFtLnBvaW50KC1waSQzLCAwKTtcbiAgICBzdHJlYW0ucG9pbnQoLXBpJDMsIHBoaSk7XG4gIH0gZWxzZSBpZiAoYWJzKGZyb21bMF0gLSB0b1swXSkgPiBlcHNpbG9uJDIpIHtcbiAgICB2YXIgbGFtYmRhID0gZnJvbVswXSA8IHRvWzBdID8gcGkkMyA6IC1waSQzO1xuICAgIHBoaSA9IGRpcmVjdGlvbiAqIGxhbWJkYSAvIDI7XG4gICAgc3RyZWFtLnBvaW50KC1sYW1iZGEsIHBoaSk7XG4gICAgc3RyZWFtLnBvaW50KDAsIHBoaSk7XG4gICAgc3RyZWFtLnBvaW50KGxhbWJkYSwgcGhpKTtcbiAgfSBlbHNlIHtcbiAgICBzdHJlYW0ucG9pbnQodG9bMF0sIHRvWzFdKTtcbiAgfVxufVxuXG52YXIgY2xpcENpcmNsZSA9IGZ1bmN0aW9uKHJhZGl1cywgZGVsdGEpIHtcbiAgdmFyIGNyID0gY29zJDEocmFkaXVzKSxcbiAgICAgIHNtYWxsUmFkaXVzID0gY3IgPiAwLFxuICAgICAgbm90SGVtaXNwaGVyZSA9IGFicyhjcikgPiBlcHNpbG9uJDI7IC8vIFRPRE8gb3B0aW1pc2UgZm9yIHRoaXMgY29tbW9uIGNhc2VcblxuICBmdW5jdGlvbiBpbnRlcnBvbGF0ZShmcm9tLCB0bywgZGlyZWN0aW9uLCBzdHJlYW0pIHtcbiAgICBjaXJjbGVTdHJlYW0oc3RyZWFtLCByYWRpdXMsIGRlbHRhLCBkaXJlY3Rpb24sIGZyb20sIHRvKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZpc2libGUobGFtYmRhLCBwaGkpIHtcbiAgICByZXR1cm4gY29zJDEobGFtYmRhKSAqIGNvcyQxKHBoaSkgPiBjcjtcbiAgfVxuXG4gIC8vIFRha2VzIGEgbGluZSBhbmQgY3V0cyBpbnRvIHZpc2libGUgc2VnbWVudHMuIFJldHVybiB2YWx1ZXMgdXNlZCBmb3IgcG9seWdvblxuICAvLyBjbGlwcGluZzogMCAtIHRoZXJlIHdlcmUgaW50ZXJzZWN0aW9ucyBvciB0aGUgbGluZSB3YXMgZW1wdHk7IDEgLSBub1xuICAvLyBpbnRlcnNlY3Rpb25zIDIgLSB0aGVyZSB3ZXJlIGludGVyc2VjdGlvbnMsIGFuZCB0aGUgZmlyc3QgYW5kIGxhc3Qgc2VnbWVudHNcbiAgLy8gc2hvdWxkIGJlIHJlam9pbmVkLlxuICBmdW5jdGlvbiBjbGlwTGluZShzdHJlYW0pIHtcbiAgICB2YXIgcG9pbnQwLCAvLyBwcmV2aW91cyBwb2ludFxuICAgICAgICBjMCwgLy8gY29kZSBmb3IgcHJldmlvdXMgcG9pbnRcbiAgICAgICAgdjAsIC8vIHZpc2liaWxpdHkgb2YgcHJldmlvdXMgcG9pbnRcbiAgICAgICAgdjAwLCAvLyB2aXNpYmlsaXR5IG9mIGZpcnN0IHBvaW50XG4gICAgICAgIGNsZWFuOyAvLyBubyBpbnRlcnNlY3Rpb25zXG4gICAgcmV0dXJuIHtcbiAgICAgIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHYwMCA9IHYwID0gZmFsc2U7XG4gICAgICAgIGNsZWFuID0gMTtcbiAgICAgIH0sXG4gICAgICBwb2ludDogZnVuY3Rpb24obGFtYmRhLCBwaGkpIHtcbiAgICAgICAgdmFyIHBvaW50MSA9IFtsYW1iZGEsIHBoaV0sXG4gICAgICAgICAgICBwb2ludDIsXG4gICAgICAgICAgICB2ID0gdmlzaWJsZShsYW1iZGEsIHBoaSksXG4gICAgICAgICAgICBjID0gc21hbGxSYWRpdXNcbiAgICAgICAgICAgICAgPyB2ID8gMCA6IGNvZGUobGFtYmRhLCBwaGkpXG4gICAgICAgICAgICAgIDogdiA/IGNvZGUobGFtYmRhICsgKGxhbWJkYSA8IDAgPyBwaSQzIDogLXBpJDMpLCBwaGkpIDogMDtcbiAgICAgICAgaWYgKCFwb2ludDAgJiYgKHYwMCA9IHYwID0gdikpIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgLy8gSGFuZGxlIGRlZ2VuZXJhY2llcy5cbiAgICAgICAgLy8gVE9ETyBpZ25vcmUgaWYgbm90IGNsaXBwaW5nIHBvbHlnb25zLlxuICAgICAgICBpZiAodiAhPT0gdjApIHtcbiAgICAgICAgICBwb2ludDIgPSBpbnRlcnNlY3QocG9pbnQwLCBwb2ludDEpO1xuICAgICAgICAgIGlmIChwb2ludEVxdWFsKHBvaW50MCwgcG9pbnQyKSB8fCBwb2ludEVxdWFsKHBvaW50MSwgcG9pbnQyKSkge1xuICAgICAgICAgICAgcG9pbnQxWzBdICs9IGVwc2lsb24kMjtcbiAgICAgICAgICAgIHBvaW50MVsxXSArPSBlcHNpbG9uJDI7XG4gICAgICAgICAgICB2ID0gdmlzaWJsZShwb2ludDFbMF0sIHBvaW50MVsxXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh2ICE9PSB2MCkge1xuICAgICAgICAgIGNsZWFuID0gMDtcbiAgICAgICAgICBpZiAodikge1xuICAgICAgICAgICAgLy8gb3V0c2lkZSBnb2luZyBpblxuICAgICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgcG9pbnQyID0gaW50ZXJzZWN0KHBvaW50MSwgcG9pbnQwKTtcbiAgICAgICAgICAgIHN0cmVhbS5wb2ludChwb2ludDJbMF0sIHBvaW50MlsxXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGluc2lkZSBnb2luZyBvdXRcbiAgICAgICAgICAgIHBvaW50MiA9IGludGVyc2VjdChwb2ludDAsIHBvaW50MSk7XG4gICAgICAgICAgICBzdHJlYW0ucG9pbnQocG9pbnQyWzBdLCBwb2ludDJbMV0pO1xuICAgICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcG9pbnQwID0gcG9pbnQyO1xuICAgICAgICB9IGVsc2UgaWYgKG5vdEhlbWlzcGhlcmUgJiYgcG9pbnQwICYmIHNtYWxsUmFkaXVzIF4gdikge1xuICAgICAgICAgIHZhciB0O1xuICAgICAgICAgIC8vIElmIHRoZSBjb2RlcyBmb3IgdHdvIHBvaW50cyBhcmUgZGlmZmVyZW50LCBvciBhcmUgYm90aCB6ZXJvLFxuICAgICAgICAgIC8vIGFuZCB0aGVyZSB0aGlzIHNlZ21lbnQgaW50ZXJzZWN0cyB3aXRoIHRoZSBzbWFsbCBjaXJjbGUuXG4gICAgICAgICAgaWYgKCEoYyAmIGMwKSAmJiAodCA9IGludGVyc2VjdChwb2ludDEsIHBvaW50MCwgdHJ1ZSkpKSB7XG4gICAgICAgICAgICBjbGVhbiA9IDA7XG4gICAgICAgICAgICBpZiAoc21hbGxSYWRpdXMpIHtcbiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgICBzdHJlYW0ucG9pbnQodFswXVswXSwgdFswXVsxXSk7XG4gICAgICAgICAgICAgIHN0cmVhbS5wb2ludCh0WzFdWzBdLCB0WzFdWzFdKTtcbiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHN0cmVhbS5wb2ludCh0WzFdWzBdLCB0WzFdWzFdKTtcbiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgICBzdHJlYW0ucG9pbnQodFswXVswXSwgdFswXVsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh2ICYmICghcG9pbnQwIHx8ICFwb2ludEVxdWFsKHBvaW50MCwgcG9pbnQxKSkpIHtcbiAgICAgICAgICBzdHJlYW0ucG9pbnQocG9pbnQxWzBdLCBwb2ludDFbMV0pO1xuICAgICAgICB9XG4gICAgICAgIHBvaW50MCA9IHBvaW50MSwgdjAgPSB2LCBjMCA9IGM7XG4gICAgICB9LFxuICAgICAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh2MCkgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgcG9pbnQwID0gbnVsbDtcbiAgICAgIH0sXG4gICAgICAvLyBSZWpvaW4gZmlyc3QgYW5kIGxhc3Qgc2VnbWVudHMgaWYgdGhlcmUgd2VyZSBpbnRlcnNlY3Rpb25zIGFuZCB0aGUgZmlyc3RcbiAgICAgIC8vIGFuZCBsYXN0IHBvaW50cyB3ZXJlIHZpc2libGUuXG4gICAgICBjbGVhbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBjbGVhbiB8ICgodjAwICYmIHYwKSA8PCAxKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gSW50ZXJzZWN0cyB0aGUgZ3JlYXQgY2lyY2xlIGJldHdlZW4gYSBhbmQgYiB3aXRoIHRoZSBjbGlwIGNpcmNsZS5cbiAgZnVuY3Rpb24gaW50ZXJzZWN0KGEsIGIsIHR3bykge1xuICAgIHZhciBwYSA9IGNhcnRlc2lhbihhKSxcbiAgICAgICAgcGIgPSBjYXJ0ZXNpYW4oYik7XG5cbiAgICAvLyBXZSBoYXZlIHR3byBwbGFuZXMsIG4xLnAgPSBkMSBhbmQgbjIucCA9IGQyLlxuICAgIC8vIEZpbmQgaW50ZXJzZWN0aW9uIGxpbmUgcCh0KSA9IGMxIG4xICsgYzIgbjIgKyB0IChuMSDiqK8gbjIpLlxuICAgIHZhciBuMSA9IFsxLCAwLCAwXSwgLy8gbm9ybWFsXG4gICAgICAgIG4yID0gY2FydGVzaWFuQ3Jvc3MocGEsIHBiKSxcbiAgICAgICAgbjJuMiA9IGNhcnRlc2lhbkRvdChuMiwgbjIpLFxuICAgICAgICBuMW4yID0gbjJbMF0sIC8vIGNhcnRlc2lhbkRvdChuMSwgbjIpLFxuICAgICAgICBkZXRlcm1pbmFudCA9IG4ybjIgLSBuMW4yICogbjFuMjtcblxuICAgIC8vIFR3byBwb2xhciBwb2ludHMuXG4gICAgaWYgKCFkZXRlcm1pbmFudCkgcmV0dXJuICF0d28gJiYgYTtcblxuICAgIHZhciBjMSA9ICBjciAqIG4ybjIgLyBkZXRlcm1pbmFudCxcbiAgICAgICAgYzIgPSAtY3IgKiBuMW4yIC8gZGV0ZXJtaW5hbnQsXG4gICAgICAgIG4xeG4yID0gY2FydGVzaWFuQ3Jvc3MobjEsIG4yKSxcbiAgICAgICAgQSA9IGNhcnRlc2lhblNjYWxlKG4xLCBjMSksXG4gICAgICAgIEIgPSBjYXJ0ZXNpYW5TY2FsZShuMiwgYzIpO1xuICAgIGNhcnRlc2lhbkFkZEluUGxhY2UoQSwgQik7XG5cbiAgICAvLyBTb2x2ZSB8cCh0KXxeMiA9IDEuXG4gICAgdmFyIHUgPSBuMXhuMixcbiAgICAgICAgdyA9IGNhcnRlc2lhbkRvdChBLCB1KSxcbiAgICAgICAgdXUgPSBjYXJ0ZXNpYW5Eb3QodSwgdSksXG4gICAgICAgIHQyID0gdyAqIHcgLSB1dSAqIChjYXJ0ZXNpYW5Eb3QoQSwgQSkgLSAxKTtcblxuICAgIGlmICh0MiA8IDApIHJldHVybjtcblxuICAgIHZhciB0ID0gc3FydCh0MiksXG4gICAgICAgIHEgPSBjYXJ0ZXNpYW5TY2FsZSh1LCAoLXcgLSB0KSAvIHV1KTtcbiAgICBjYXJ0ZXNpYW5BZGRJblBsYWNlKHEsIEEpO1xuICAgIHEgPSBzcGhlcmljYWwocSk7XG5cbiAgICBpZiAoIXR3bykgcmV0dXJuIHE7XG5cbiAgICAvLyBUd28gaW50ZXJzZWN0aW9uIHBvaW50cy5cbiAgICB2YXIgbGFtYmRhMCA9IGFbMF0sXG4gICAgICAgIGxhbWJkYTEgPSBiWzBdLFxuICAgICAgICBwaGkwID0gYVsxXSxcbiAgICAgICAgcGhpMSA9IGJbMV0sXG4gICAgICAgIHo7XG5cbiAgICBpZiAobGFtYmRhMSA8IGxhbWJkYTApIHogPSBsYW1iZGEwLCBsYW1iZGEwID0gbGFtYmRhMSwgbGFtYmRhMSA9IHo7XG5cbiAgICB2YXIgZGVsdGEgPSBsYW1iZGExIC0gbGFtYmRhMCxcbiAgICAgICAgcG9sYXIgPSBhYnMoZGVsdGEgLSBwaSQzKSA8IGVwc2lsb24kMixcbiAgICAgICAgbWVyaWRpYW4gPSBwb2xhciB8fCBkZWx0YSA8IGVwc2lsb24kMjtcblxuICAgIGlmICghcG9sYXIgJiYgcGhpMSA8IHBoaTApIHogPSBwaGkwLCBwaGkwID0gcGhpMSwgcGhpMSA9IHo7XG5cbiAgICAvLyBDaGVjayB0aGF0IHRoZSBmaXJzdCBwb2ludCBpcyBiZXR3ZWVuIGEgYW5kIGIuXG4gICAgaWYgKG1lcmlkaWFuXG4gICAgICAgID8gcG9sYXJcbiAgICAgICAgICA/IHBoaTAgKyBwaGkxID4gMCBeIHFbMV0gPCAoYWJzKHFbMF0gLSBsYW1iZGEwKSA8IGVwc2lsb24kMiA/IHBoaTAgOiBwaGkxKVxuICAgICAgICAgIDogcGhpMCA8PSBxWzFdICYmIHFbMV0gPD0gcGhpMVxuICAgICAgICA6IGRlbHRhID4gcGkkMyBeIChsYW1iZGEwIDw9IHFbMF0gJiYgcVswXSA8PSBsYW1iZGExKSkge1xuICAgICAgdmFyIHExID0gY2FydGVzaWFuU2NhbGUodSwgKC13ICsgdCkgLyB1dSk7XG4gICAgICBjYXJ0ZXNpYW5BZGRJblBsYWNlKHExLCBBKTtcbiAgICAgIHJldHVybiBbcSwgc3BoZXJpY2FsKHExKV07XG4gICAgfVxuICB9XG5cbiAgLy8gR2VuZXJhdGVzIGEgNC1iaXQgdmVjdG9yIHJlcHJlc2VudGluZyB0aGUgbG9jYXRpb24gb2YgYSBwb2ludCByZWxhdGl2ZSB0b1xuICAvLyB0aGUgc21hbGwgY2lyY2xlJ3MgYm91bmRpbmcgYm94LlxuICBmdW5jdGlvbiBjb2RlKGxhbWJkYSwgcGhpKSB7XG4gICAgdmFyIHIgPSBzbWFsbFJhZGl1cyA/IHJhZGl1cyA6IHBpJDMgLSByYWRpdXMsXG4gICAgICAgIGNvZGUgPSAwO1xuICAgIGlmIChsYW1iZGEgPCAtcikgY29kZSB8PSAxOyAvLyBsZWZ0XG4gICAgZWxzZSBpZiAobGFtYmRhID4gcikgY29kZSB8PSAyOyAvLyByaWdodFxuICAgIGlmIChwaGkgPCAtcikgY29kZSB8PSA0OyAvLyBiZWxvd1xuICAgIGVsc2UgaWYgKHBoaSA+IHIpIGNvZGUgfD0gODsgLy8gYWJvdmVcbiAgICByZXR1cm4gY29kZTtcbiAgfVxuXG4gIHJldHVybiBjbGlwKHZpc2libGUsIGNsaXBMaW5lLCBpbnRlcnBvbGF0ZSwgc21hbGxSYWRpdXMgPyBbMCwgLXJhZGl1c10gOiBbLXBpJDMsIHJhZGl1cyAtIHBpJDNdKTtcbn07XG5cbnZhciB0cmFuc2Zvcm0gPSBmdW5jdGlvbihtZXRob2RzKSB7XG4gIHJldHVybiB7XG4gICAgc3RyZWFtOiB0cmFuc2Zvcm1lcihtZXRob2RzKVxuICB9O1xufTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtZXIobWV0aG9kcykge1xuICByZXR1cm4gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgdmFyIHMgPSBuZXcgVHJhbnNmb3JtU3RyZWFtO1xuICAgIGZvciAodmFyIGtleSBpbiBtZXRob2RzKSBzW2tleV0gPSBtZXRob2RzW2tleV07XG4gICAgcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgcmV0dXJuIHM7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbSgpIHt9XG5cblRyYW5zZm9ybVN0cmVhbS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBUcmFuc2Zvcm1TdHJlYW0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7IHRoaXMuc3RyZWFtLnBvaW50KHgsIHkpOyB9LFxuICBzcGhlcmU6IGZ1bmN0aW9uKCkgeyB0aGlzLnN0cmVhbS5zcGhlcmUoKTsgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHsgdGhpcy5zdHJlYW0ubGluZVN0YXJ0KCk7IH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkgeyB0aGlzLnN0cmVhbS5saW5lRW5kKCk7IH0sXG4gIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7IHRoaXMuc3RyZWFtLnBvbHlnb25TdGFydCgpOyB9LFxuICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHsgdGhpcy5zdHJlYW0ucG9seWdvbkVuZCgpOyB9XG59O1xuXG5mdW5jdGlvbiBmaXRFeHRlbnQocHJvamVjdGlvbiwgZXh0ZW50LCBvYmplY3QpIHtcbiAgdmFyIHcgPSBleHRlbnRbMV1bMF0gLSBleHRlbnRbMF1bMF0sXG4gICAgICBoID0gZXh0ZW50WzFdWzFdIC0gZXh0ZW50WzBdWzFdLFxuICAgICAgY2xpcCA9IHByb2plY3Rpb24uY2xpcEV4dGVudCAmJiBwcm9qZWN0aW9uLmNsaXBFeHRlbnQoKTtcblxuICBwcm9qZWN0aW9uXG4gICAgICAuc2NhbGUoMTUwKVxuICAgICAgLnRyYW5zbGF0ZShbMCwgMF0pO1xuXG4gIGlmIChjbGlwICE9IG51bGwpIHByb2plY3Rpb24uY2xpcEV4dGVudChudWxsKTtcblxuICBnZW9TdHJlYW0ob2JqZWN0LCBwcm9qZWN0aW9uLnN0cmVhbShib3VuZHNTdHJlYW0kMSkpO1xuXG4gIHZhciBiID0gYm91bmRzU3RyZWFtJDEucmVzdWx0KCksXG4gICAgICBrID0gTWF0aC5taW4odyAvIChiWzFdWzBdIC0gYlswXVswXSksIGggLyAoYlsxXVsxXSAtIGJbMF1bMV0pKSxcbiAgICAgIHggPSArZXh0ZW50WzBdWzBdICsgKHcgLSBrICogKGJbMV1bMF0gKyBiWzBdWzBdKSkgLyAyLFxuICAgICAgeSA9ICtleHRlbnRbMF1bMV0gKyAoaCAtIGsgKiAoYlsxXVsxXSArIGJbMF1bMV0pKSAvIDI7XG5cbiAgaWYgKGNsaXAgIT0gbnVsbCkgcHJvamVjdGlvbi5jbGlwRXh0ZW50KGNsaXApO1xuXG4gIHJldHVybiBwcm9qZWN0aW9uXG4gICAgICAuc2NhbGUoayAqIDE1MClcbiAgICAgIC50cmFuc2xhdGUoW3gsIHldKTtcbn1cblxuZnVuY3Rpb24gZml0U2l6ZShwcm9qZWN0aW9uLCBzaXplLCBvYmplY3QpIHtcbiAgcmV0dXJuIGZpdEV4dGVudChwcm9qZWN0aW9uLCBbWzAsIDBdLCBzaXplXSwgb2JqZWN0KTtcbn1cblxudmFyIG1heERlcHRoID0gMTY7XG52YXIgY29zTWluRGlzdGFuY2UgPSBjb3MkMSgzMCAqIHJhZGlhbnMpOyAvLyBjb3MobWluaW11bSBhbmd1bGFyIGRpc3RhbmNlKVxuXG52YXIgcmVzYW1wbGUgPSBmdW5jdGlvbihwcm9qZWN0LCBkZWx0YTIpIHtcbiAgcmV0dXJuICtkZWx0YTIgPyByZXNhbXBsZSQxKHByb2plY3QsIGRlbHRhMikgOiByZXNhbXBsZU5vbmUocHJvamVjdCk7XG59O1xuXG5mdW5jdGlvbiByZXNhbXBsZU5vbmUocHJvamVjdCkge1xuICByZXR1cm4gdHJhbnNmb3JtZXIoe1xuICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgICB4ID0gcHJvamVjdCh4LCB5KTtcbiAgICAgIHRoaXMuc3RyZWFtLnBvaW50KHhbMF0sIHhbMV0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlc2FtcGxlJDEocHJvamVjdCwgZGVsdGEyKSB7XG5cbiAgZnVuY3Rpb24gcmVzYW1wbGVMaW5lVG8oeDAsIHkwLCBsYW1iZGEwLCBhMCwgYjAsIGMwLCB4MSwgeTEsIGxhbWJkYTEsIGExLCBiMSwgYzEsIGRlcHRoLCBzdHJlYW0pIHtcbiAgICB2YXIgZHggPSB4MSAtIHgwLFxuICAgICAgICBkeSA9IHkxIC0geTAsXG4gICAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHk7XG4gICAgaWYgKGQyID4gNCAqIGRlbHRhMiAmJiBkZXB0aC0tKSB7XG4gICAgICB2YXIgYSA9IGEwICsgYTEsXG4gICAgICAgICAgYiA9IGIwICsgYjEsXG4gICAgICAgICAgYyA9IGMwICsgYzEsXG4gICAgICAgICAgbSA9IHNxcnQoYSAqIGEgKyBiICogYiArIGMgKiBjKSxcbiAgICAgICAgICBwaGkyID0gYXNpbihjIC89IG0pLFxuICAgICAgICAgIGxhbWJkYTIgPSBhYnMoYWJzKGMpIC0gMSkgPCBlcHNpbG9uJDIgfHwgYWJzKGxhbWJkYTAgLSBsYW1iZGExKSA8IGVwc2lsb24kMiA/IChsYW1iZGEwICsgbGFtYmRhMSkgLyAyIDogYXRhbjIoYiwgYSksXG4gICAgICAgICAgcCA9IHByb2plY3QobGFtYmRhMiwgcGhpMiksXG4gICAgICAgICAgeDIgPSBwWzBdLFxuICAgICAgICAgIHkyID0gcFsxXSxcbiAgICAgICAgICBkeDIgPSB4MiAtIHgwLFxuICAgICAgICAgIGR5MiA9IHkyIC0geTAsXG4gICAgICAgICAgZHogPSBkeSAqIGR4MiAtIGR4ICogZHkyO1xuICAgICAgaWYgKGR6ICogZHogLyBkMiA+IGRlbHRhMiAvLyBwZXJwZW5kaWN1bGFyIHByb2plY3RlZCBkaXN0YW5jZVxuICAgICAgICAgIHx8IGFicygoZHggKiBkeDIgKyBkeSAqIGR5MikgLyBkMiAtIDAuNSkgPiAwLjMgLy8gbWlkcG9pbnQgY2xvc2UgdG8gYW4gZW5kXG4gICAgICAgICAgfHwgYTAgKiBhMSArIGIwICogYjEgKyBjMCAqIGMxIDwgY29zTWluRGlzdGFuY2UpIHsgLy8gYW5ndWxhciBkaXN0YW5jZVxuICAgICAgICByZXNhbXBsZUxpbmVUbyh4MCwgeTAsIGxhbWJkYTAsIGEwLCBiMCwgYzAsIHgyLCB5MiwgbGFtYmRhMiwgYSAvPSBtLCBiIC89IG0sIGMsIGRlcHRoLCBzdHJlYW0pO1xuICAgICAgICBzdHJlYW0ucG9pbnQoeDIsIHkyKTtcbiAgICAgICAgcmVzYW1wbGVMaW5lVG8oeDIsIHkyLCBsYW1iZGEyLCBhLCBiLCBjLCB4MSwgeTEsIGxhbWJkYTEsIGExLCBiMSwgYzEsIGRlcHRoLCBzdHJlYW0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgdmFyIGxhbWJkYTAwLCB4MDAsIHkwMCwgYTAwLCBiMDAsIGMwMCwgLy8gZmlyc3QgcG9pbnRcbiAgICAgICAgbGFtYmRhMCwgeDAsIHkwLCBhMCwgYjAsIGMwOyAvLyBwcmV2aW91cyBwb2ludFxuXG4gICAgdmFyIHJlc2FtcGxlU3RyZWFtID0ge1xuICAgICAgcG9pbnQ6IHBvaW50LFxuICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICBsaW5lRW5kOiBsaW5lRW5kLFxuICAgICAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHsgc3RyZWFtLnBvbHlnb25TdGFydCgpOyByZXNhbXBsZVN0cmVhbS5saW5lU3RhcnQgPSByaW5nU3RhcnQ7IH0sXG4gICAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHsgc3RyZWFtLnBvbHlnb25FbmQoKTsgcmVzYW1wbGVTdHJlYW0ubGluZVN0YXJ0ID0gbGluZVN0YXJ0OyB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHBvaW50KHgsIHkpIHtcbiAgICAgIHggPSBwcm9qZWN0KHgsIHkpO1xuICAgICAgc3RyZWFtLnBvaW50KHhbMF0sIHhbMV0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpbmVTdGFydCgpIHtcbiAgICAgIHgwID0gTmFOO1xuICAgICAgcmVzYW1wbGVTdHJlYW0ucG9pbnQgPSBsaW5lUG9pbnQ7XG4gICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGluZVBvaW50KGxhbWJkYSwgcGhpKSB7XG4gICAgICB2YXIgYyA9IGNhcnRlc2lhbihbbGFtYmRhLCBwaGldKSwgcCA9IHByb2plY3QobGFtYmRhLCBwaGkpO1xuICAgICAgcmVzYW1wbGVMaW5lVG8oeDAsIHkwLCBsYW1iZGEwLCBhMCwgYjAsIGMwLCB4MCA9IHBbMF0sIHkwID0gcFsxXSwgbGFtYmRhMCA9IGxhbWJkYSwgYTAgPSBjWzBdLCBiMCA9IGNbMV0sIGMwID0gY1syXSwgbWF4RGVwdGgsIHN0cmVhbSk7XG4gICAgICBzdHJlYW0ucG9pbnQoeDAsIHkwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lRW5kKCkge1xuICAgICAgcmVzYW1wbGVTdHJlYW0ucG9pbnQgPSBwb2ludDtcbiAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmluZ1N0YXJ0KCkge1xuICAgICAgbGluZVN0YXJ0KCk7XG4gICAgICByZXNhbXBsZVN0cmVhbS5wb2ludCA9IHJpbmdQb2ludDtcbiAgICAgIHJlc2FtcGxlU3RyZWFtLmxpbmVFbmQgPSByaW5nRW5kO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJpbmdQb2ludChsYW1iZGEsIHBoaSkge1xuICAgICAgbGluZVBvaW50KGxhbWJkYTAwID0gbGFtYmRhLCBwaGkpLCB4MDAgPSB4MCwgeTAwID0geTAsIGEwMCA9IGEwLCBiMDAgPSBiMCwgYzAwID0gYzA7XG4gICAgICByZXNhbXBsZVN0cmVhbS5wb2ludCA9IGxpbmVQb2ludDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByaW5nRW5kKCkge1xuICAgICAgcmVzYW1wbGVMaW5lVG8oeDAsIHkwLCBsYW1iZGEwLCBhMCwgYjAsIGMwLCB4MDAsIHkwMCwgbGFtYmRhMDAsIGEwMCwgYjAwLCBjMDAsIG1heERlcHRoLCBzdHJlYW0pO1xuICAgICAgcmVzYW1wbGVTdHJlYW0ubGluZUVuZCA9IGxpbmVFbmQ7XG4gICAgICBsaW5lRW5kKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc2FtcGxlU3RyZWFtO1xuICB9O1xufVxuXG52YXIgdHJhbnNmb3JtUmFkaWFucyA9IHRyYW5zZm9ybWVyKHtcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB0aGlzLnN0cmVhbS5wb2ludCh4ICogcmFkaWFucywgeSAqIHJhZGlhbnMpO1xuICB9XG59KTtcblxuZnVuY3Rpb24gcHJvamVjdGlvbihwcm9qZWN0KSB7XG4gIHJldHVybiBwcm9qZWN0aW9uTXV0YXRvcihmdW5jdGlvbigpIHsgcmV0dXJuIHByb2plY3Q7IH0pKCk7XG59XG5cbmZ1bmN0aW9uIHByb2plY3Rpb25NdXRhdG9yKHByb2plY3RBdCkge1xuICB2YXIgcHJvamVjdCxcbiAgICAgIGsgPSAxNTAsIC8vIHNjYWxlXG4gICAgICB4ID0gNDgwLCB5ID0gMjUwLCAvLyB0cmFuc2xhdGVcbiAgICAgIGR4LCBkeSwgbGFtYmRhID0gMCwgcGhpID0gMCwgLy8gY2VudGVyXG4gICAgICBkZWx0YUxhbWJkYSA9IDAsIGRlbHRhUGhpID0gMCwgZGVsdGFHYW1tYSA9IDAsIHJvdGF0ZSwgcHJvamVjdFJvdGF0ZSwgLy8gcm90YXRlXG4gICAgICB0aGV0YSA9IG51bGwsIHByZWNsaXAgPSBjbGlwQW50aW1lcmlkaWFuLCAvLyBjbGlwIGFuZ2xlXG4gICAgICB4MCA9IG51bGwsIHkwLCB4MSwgeTEsIHBvc3RjbGlwID0gaWRlbnRpdHkkNCwgLy8gY2xpcCBleHRlbnRcbiAgICAgIGRlbHRhMiA9IDAuNSwgcHJvamVjdFJlc2FtcGxlID0gcmVzYW1wbGUocHJvamVjdFRyYW5zZm9ybSwgZGVsdGEyKSwgLy8gcHJlY2lzaW9uXG4gICAgICBjYWNoZSxcbiAgICAgIGNhY2hlU3RyZWFtO1xuXG4gIGZ1bmN0aW9uIHByb2plY3Rpb24ocG9pbnQpIHtcbiAgICBwb2ludCA9IHByb2plY3RSb3RhdGUocG9pbnRbMF0gKiByYWRpYW5zLCBwb2ludFsxXSAqIHJhZGlhbnMpO1xuICAgIHJldHVybiBbcG9pbnRbMF0gKiBrICsgZHgsIGR5IC0gcG9pbnRbMV0gKiBrXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGludmVydChwb2ludCkge1xuICAgIHBvaW50ID0gcHJvamVjdFJvdGF0ZS5pbnZlcnQoKHBvaW50WzBdIC0gZHgpIC8gaywgKGR5IC0gcG9pbnRbMV0pIC8gayk7XG4gICAgcmV0dXJuIHBvaW50ICYmIFtwb2ludFswXSAqIGRlZ3JlZXMkMSwgcG9pbnRbMV0gKiBkZWdyZWVzJDFdO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJvamVjdFRyYW5zZm9ybSh4LCB5KSB7XG4gICAgcmV0dXJuIHggPSBwcm9qZWN0KHgsIHkpLCBbeFswXSAqIGsgKyBkeCwgZHkgLSB4WzFdICoga107XG4gIH1cblxuICBwcm9qZWN0aW9uLnN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIHJldHVybiBjYWNoZSAmJiBjYWNoZVN0cmVhbSA9PT0gc3RyZWFtID8gY2FjaGUgOiBjYWNoZSA9IHRyYW5zZm9ybVJhZGlhbnMocHJlY2xpcChyb3RhdGUsIHByb2plY3RSZXNhbXBsZShwb3N0Y2xpcChjYWNoZVN0cmVhbSA9IHN0cmVhbSkpKSk7XG4gIH07XG5cbiAgcHJvamVjdGlvbi5jbGlwQW5nbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocHJlY2xpcCA9ICtfID8gY2xpcENpcmNsZSh0aGV0YSA9IF8gKiByYWRpYW5zLCA2ICogcmFkaWFucykgOiAodGhldGEgPSBudWxsLCBjbGlwQW50aW1lcmlkaWFuKSwgcmVzZXQoKSkgOiB0aGV0YSAqIGRlZ3JlZXMkMTtcbiAgfTtcblxuICBwcm9qZWN0aW9uLmNsaXBFeHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocG9zdGNsaXAgPSBfID09IG51bGwgPyAoeDAgPSB5MCA9IHgxID0geTEgPSBudWxsLCBpZGVudGl0eSQ0KSA6IGNsaXBFeHRlbnQoeDAgPSArX1swXVswXSwgeTAgPSArX1swXVsxXSwgeDEgPSArX1sxXVswXSwgeTEgPSArX1sxXVsxXSksIHJlc2V0KCkpIDogeDAgPT0gbnVsbCA/IG51bGwgOiBbW3gwLCB5MF0sIFt4MSwgeTFdXTtcbiAgfTtcblxuICBwcm9qZWN0aW9uLnNjYWxlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGsgPSArXywgcmVjZW50ZXIoKSkgOiBrO1xuICB9O1xuXG4gIHByb2plY3Rpb24udHJhbnNsYXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSArX1swXSwgeSA9ICtfWzFdLCByZWNlbnRlcigpKSA6IFt4LCB5XTtcbiAgfTtcblxuICBwcm9qZWN0aW9uLmNlbnRlciA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChsYW1iZGEgPSBfWzBdICUgMzYwICogcmFkaWFucywgcGhpID0gX1sxXSAlIDM2MCAqIHJhZGlhbnMsIHJlY2VudGVyKCkpIDogW2xhbWJkYSAqIGRlZ3JlZXMkMSwgcGhpICogZGVncmVlcyQxXTtcbiAgfTtcblxuICBwcm9qZWN0aW9uLnJvdGF0ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkZWx0YUxhbWJkYSA9IF9bMF0gJSAzNjAgKiByYWRpYW5zLCBkZWx0YVBoaSA9IF9bMV0gJSAzNjAgKiByYWRpYW5zLCBkZWx0YUdhbW1hID0gXy5sZW5ndGggPiAyID8gX1syXSAlIDM2MCAqIHJhZGlhbnMgOiAwLCByZWNlbnRlcigpKSA6IFtkZWx0YUxhbWJkYSAqIGRlZ3JlZXMkMSwgZGVsdGFQaGkgKiBkZWdyZWVzJDEsIGRlbHRhR2FtbWEgKiBkZWdyZWVzJDFdO1xuICB9O1xuXG4gIHByb2plY3Rpb24ucHJlY2lzaW9uID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHByb2plY3RSZXNhbXBsZSA9IHJlc2FtcGxlKHByb2plY3RUcmFuc2Zvcm0sIGRlbHRhMiA9IF8gKiBfKSwgcmVzZXQoKSkgOiBzcXJ0KGRlbHRhMik7XG4gIH07XG5cbiAgcHJvamVjdGlvbi5maXRFeHRlbnQgPSBmdW5jdGlvbihleHRlbnQsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRFeHRlbnQocHJvamVjdGlvbiwgZXh0ZW50LCBvYmplY3QpO1xuICB9O1xuXG4gIHByb2plY3Rpb24uZml0U2l6ZSA9IGZ1bmN0aW9uKHNpemUsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRTaXplKHByb2plY3Rpb24sIHNpemUsIG9iamVjdCk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVjZW50ZXIoKSB7XG4gICAgcHJvamVjdFJvdGF0ZSA9IGNvbXBvc2Uocm90YXRlID0gcm90YXRlUmFkaWFucyhkZWx0YUxhbWJkYSwgZGVsdGFQaGksIGRlbHRhR2FtbWEpLCBwcm9qZWN0KTtcbiAgICB2YXIgY2VudGVyID0gcHJvamVjdChsYW1iZGEsIHBoaSk7XG4gICAgZHggPSB4IC0gY2VudGVyWzBdICogaztcbiAgICBkeSA9IHkgKyBjZW50ZXJbMV0gKiBrO1xuICAgIHJldHVybiByZXNldCgpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgY2FjaGUgPSBjYWNoZVN0cmVhbSA9IG51bGw7XG4gICAgcmV0dXJuIHByb2plY3Rpb247XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcHJvamVjdCA9IHByb2plY3RBdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHByb2plY3Rpb24uaW52ZXJ0ID0gcHJvamVjdC5pbnZlcnQgJiYgaW52ZXJ0O1xuICAgIHJldHVybiByZWNlbnRlcigpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjb25pY1Byb2plY3Rpb24ocHJvamVjdEF0KSB7XG4gIHZhciBwaGkwID0gMCxcbiAgICAgIHBoaTEgPSBwaSQzIC8gMyxcbiAgICAgIG0gPSBwcm9qZWN0aW9uTXV0YXRvcihwcm9qZWN0QXQpLFxuICAgICAgcCA9IG0ocGhpMCwgcGhpMSk7XG5cbiAgcC5wYXJhbGxlbHMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyBtKHBoaTAgPSBfWzBdICogcmFkaWFucywgcGhpMSA9IF9bMV0gKiByYWRpYW5zKSA6IFtwaGkwICogZGVncmVlcyQxLCBwaGkxICogZGVncmVlcyQxXTtcbiAgfTtcblxuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gY3lsaW5kcmljYWxFcXVhbEFyZWFSYXcocGhpMCkge1xuICB2YXIgY29zUGhpMCA9IGNvcyQxKHBoaTApO1xuXG4gIGZ1bmN0aW9uIGZvcndhcmQobGFtYmRhLCBwaGkpIHtcbiAgICByZXR1cm4gW2xhbWJkYSAqIGNvc1BoaTAsIHNpbiQxKHBoaSkgLyBjb3NQaGkwXTtcbiAgfVxuXG4gIGZvcndhcmQuaW52ZXJ0ID0gZnVuY3Rpb24oeCwgeSkge1xuICAgIHJldHVybiBbeCAvIGNvc1BoaTAsIGFzaW4oeSAqIGNvc1BoaTApXTtcbiAgfTtcblxuICByZXR1cm4gZm9yd2FyZDtcbn1cblxuZnVuY3Rpb24gY29uaWNFcXVhbEFyZWFSYXcoeTAsIHkxKSB7XG4gIHZhciBzeTAgPSBzaW4kMSh5MCksIG4gPSAoc3kwICsgc2luJDEoeTEpKSAvIDI7XG5cbiAgLy8gQXJlIHRoZSBwYXJhbGxlbHMgc3ltbWV0cmljYWwgYXJvdW5kIHRoZSBFcXVhdG9yP1xuICBpZiAoYWJzKG4pIDwgZXBzaWxvbiQyKSByZXR1cm4gY3lsaW5kcmljYWxFcXVhbEFyZWFSYXcoeTApO1xuXG4gIHZhciBjID0gMSArIHN5MCAqICgyICogbiAtIHN5MCksIHIwID0gc3FydChjKSAvIG47XG5cbiAgZnVuY3Rpb24gcHJvamVjdCh4LCB5KSB7XG4gICAgdmFyIHIgPSBzcXJ0KGMgLSAyICogbiAqIHNpbiQxKHkpKSAvIG47XG4gICAgcmV0dXJuIFtyICogc2luJDEoeCAqPSBuKSwgcjAgLSByICogY29zJDEoeCldO1xuICB9XG5cbiAgcHJvamVjdC5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIHIweSA9IHIwIC0geTtcbiAgICByZXR1cm4gW2F0YW4yKHgsIGFicyhyMHkpKSAvIG4gKiBzaWduKHIweSksIGFzaW4oKGMgLSAoeCAqIHggKyByMHkgKiByMHkpICogbiAqIG4pIC8gKDIgKiBuKSldO1xuICB9O1xuXG4gIHJldHVybiBwcm9qZWN0O1xufVxuXG52YXIgY29uaWNFcXVhbEFyZWEgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGNvbmljUHJvamVjdGlvbihjb25pY0VxdWFsQXJlYVJhdylcbiAgICAgIC5zY2FsZSgxNTUuNDI0KVxuICAgICAgLmNlbnRlcihbMCwgMzMuNjQ0Ml0pO1xufTtcblxudmFyIGFsYmVycyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY29uaWNFcXVhbEFyZWEoKVxuICAgICAgLnBhcmFsbGVscyhbMjkuNSwgNDUuNV0pXG4gICAgICAuc2NhbGUoMTA3MClcbiAgICAgIC50cmFuc2xhdGUoWzQ4MCwgMjUwXSlcbiAgICAgIC5yb3RhdGUoWzk2LCAwXSlcbiAgICAgIC5jZW50ZXIoWy0wLjYsIDM4LjddKTtcbn07XG5cbi8vIFRoZSBwcm9qZWN0aW9ucyBtdXN0IGhhdmUgbXV0dWFsbHkgZXhjbHVzaXZlIGNsaXAgcmVnaW9ucyBvbiB0aGUgc3BoZXJlLFxuLy8gYXMgdGhpcyB3aWxsIGF2b2lkIGVtaXR0aW5nIGludGVybGVhdmluZyBsaW5lcyBhbmQgcG9seWdvbnMuXG5mdW5jdGlvbiBtdWx0aXBsZXgoc3RyZWFtcykge1xuICB2YXIgbiA9IHN0cmVhbXMubGVuZ3RoO1xuICByZXR1cm4ge1xuICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7IHZhciBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLnBvaW50KHgsIHkpOyB9LFxuICAgIHNwaGVyZTogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLnNwaGVyZSgpOyB9LFxuICAgIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLmxpbmVTdGFydCgpOyB9LFxuICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkgeyB2YXIgaSA9IC0xOyB3aGlsZSAoKytpIDwgbikgc3RyZWFtc1tpXS5saW5lRW5kKCk7IH0sXG4gICAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0ucG9seWdvblN0YXJ0KCk7IH0sXG4gICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLnBvbHlnb25FbmQoKTsgfVxuICB9O1xufVxuXG4vLyBBIGNvbXBvc2l0ZSBwcm9qZWN0aW9uIGZvciB0aGUgVW5pdGVkIFN0YXRlcywgY29uZmlndXJlZCBieSBkZWZhdWx0IGZvclxuLy8gOTYww5c1MDAuIFRoZSBwcm9qZWN0aW9uIGFsc28gd29ya3MgcXVpdGUgd2VsbCBhdCA5NjDDlzYwMCBpZiB5b3UgY2hhbmdlIHRoZVxuLy8gc2NhbGUgdG8gMTI4NSBhbmQgYWRqdXN0IHRoZSB0cmFuc2xhdGUgYWNjb3JkaW5nbHkuIFRoZSBzZXQgb2Ygc3RhbmRhcmRcbi8vIHBhcmFsbGVscyBmb3IgZWFjaCByZWdpb24gY29tZXMgZnJvbSBVU0dTLCB3aGljaCBpcyBwdWJsaXNoZWQgaGVyZTpcbi8vIGh0dHA6Ly9lZ3NjLnVzZ3MuZ292L2lzYi9wdWJzL01hcFByb2plY3Rpb25zL3Byb2plY3Rpb25zLmh0bWwjYWxiZXJzXG52YXIgYWxiZXJzVXNhID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjYWNoZSxcbiAgICAgIGNhY2hlU3RyZWFtLFxuICAgICAgbG93ZXI0OCA9IGFsYmVycygpLCBsb3dlcjQ4UG9pbnQsXG4gICAgICBhbGFza2EgPSBjb25pY0VxdWFsQXJlYSgpLnJvdGF0ZShbMTU0LCAwXSkuY2VudGVyKFstMiwgNTguNV0pLnBhcmFsbGVscyhbNTUsIDY1XSksIGFsYXNrYVBvaW50LCAvLyBFUFNHOjMzMzhcbiAgICAgIGhhd2FpaSA9IGNvbmljRXF1YWxBcmVhKCkucm90YXRlKFsxNTcsIDBdKS5jZW50ZXIoWy0zLCAxOS45XSkucGFyYWxsZWxzKFs4LCAxOF0pLCBoYXdhaWlQb2ludCwgLy8gRVNSSToxMDIwMDdcbiAgICAgIHBvaW50LCBwb2ludFN0cmVhbSA9IHtwb2ludDogZnVuY3Rpb24oeCwgeSkgeyBwb2ludCA9IFt4LCB5XTsgfX07XG5cbiAgZnVuY3Rpb24gYWxiZXJzVXNhKGNvb3JkaW5hdGVzKSB7XG4gICAgdmFyIHggPSBjb29yZGluYXRlc1swXSwgeSA9IGNvb3JkaW5hdGVzWzFdO1xuICAgIHJldHVybiBwb2ludCA9IG51bGwsXG4gICAgICAgIChsb3dlcjQ4UG9pbnQucG9pbnQoeCwgeSksIHBvaW50KVxuICAgICAgICB8fCAoYWxhc2thUG9pbnQucG9pbnQoeCwgeSksIHBvaW50KVxuICAgICAgICB8fCAoaGF3YWlpUG9pbnQucG9pbnQoeCwgeSksIHBvaW50KTtcbiAgfVxuXG4gIGFsYmVyc1VzYS5pbnZlcnQgPSBmdW5jdGlvbihjb29yZGluYXRlcykge1xuICAgIHZhciBrID0gbG93ZXI0OC5zY2FsZSgpLFxuICAgICAgICB0ID0gbG93ZXI0OC50cmFuc2xhdGUoKSxcbiAgICAgICAgeCA9IChjb29yZGluYXRlc1swXSAtIHRbMF0pIC8gayxcbiAgICAgICAgeSA9IChjb29yZGluYXRlc1sxXSAtIHRbMV0pIC8gaztcbiAgICByZXR1cm4gKHkgPj0gMC4xMjAgJiYgeSA8IDAuMjM0ICYmIHggPj0gLTAuNDI1ICYmIHggPCAtMC4yMTQgPyBhbGFza2FcbiAgICAgICAgOiB5ID49IDAuMTY2ICYmIHkgPCAwLjIzNCAmJiB4ID49IC0wLjIxNCAmJiB4IDwgLTAuMTE1ID8gaGF3YWlpXG4gICAgICAgIDogbG93ZXI0OCkuaW52ZXJ0KGNvb3JkaW5hdGVzKTtcbiAgfTtcblxuICBhbGJlcnNVc2Euc3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgcmV0dXJuIGNhY2hlICYmIGNhY2hlU3RyZWFtID09PSBzdHJlYW0gPyBjYWNoZSA6IGNhY2hlID0gbXVsdGlwbGV4KFtsb3dlcjQ4LnN0cmVhbShjYWNoZVN0cmVhbSA9IHN0cmVhbSksIGFsYXNrYS5zdHJlYW0oc3RyZWFtKSwgaGF3YWlpLnN0cmVhbShzdHJlYW0pXSk7XG4gIH07XG5cbiAgYWxiZXJzVXNhLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsb3dlcjQ4LnByZWNpc2lvbigpO1xuICAgIGxvd2VyNDgucHJlY2lzaW9uKF8pLCBhbGFza2EucHJlY2lzaW9uKF8pLCBoYXdhaWkucHJlY2lzaW9uKF8pO1xuICAgIHJldHVybiByZXNldCgpO1xuICB9O1xuXG4gIGFsYmVyc1VzYS5zY2FsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsb3dlcjQ4LnNjYWxlKCk7XG4gICAgbG93ZXI0OC5zY2FsZShfKSwgYWxhc2thLnNjYWxlKF8gKiAwLjM1KSwgaGF3YWlpLnNjYWxlKF8pO1xuICAgIHJldHVybiBhbGJlcnNVc2EudHJhbnNsYXRlKGxvd2VyNDgudHJhbnNsYXRlKCkpO1xuICB9O1xuXG4gIGFsYmVyc1VzYS50cmFuc2xhdGUgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbG93ZXI0OC50cmFuc2xhdGUoKTtcbiAgICB2YXIgayA9IGxvd2VyNDguc2NhbGUoKSwgeCA9ICtfWzBdLCB5ID0gK19bMV07XG5cbiAgICBsb3dlcjQ4UG9pbnQgPSBsb3dlcjQ4XG4gICAgICAgIC50cmFuc2xhdGUoXylcbiAgICAgICAgLmNsaXBFeHRlbnQoW1t4IC0gMC40NTUgKiBrLCB5IC0gMC4yMzggKiBrXSwgW3ggKyAwLjQ1NSAqIGssIHkgKyAwLjIzOCAqIGtdXSlcbiAgICAgICAgLnN0cmVhbShwb2ludFN0cmVhbSk7XG5cbiAgICBhbGFza2FQb2ludCA9IGFsYXNrYVxuICAgICAgICAudHJhbnNsYXRlKFt4IC0gMC4zMDcgKiBrLCB5ICsgMC4yMDEgKiBrXSlcbiAgICAgICAgLmNsaXBFeHRlbnQoW1t4IC0gMC40MjUgKiBrICsgZXBzaWxvbiQyLCB5ICsgMC4xMjAgKiBrICsgZXBzaWxvbiQyXSwgW3ggLSAwLjIxNCAqIGsgLSBlcHNpbG9uJDIsIHkgKyAwLjIzNCAqIGsgLSBlcHNpbG9uJDJdXSlcbiAgICAgICAgLnN0cmVhbShwb2ludFN0cmVhbSk7XG5cbiAgICBoYXdhaWlQb2ludCA9IGhhd2FpaVxuICAgICAgICAudHJhbnNsYXRlKFt4IC0gMC4yMDUgKiBrLCB5ICsgMC4yMTIgKiBrXSlcbiAgICAgICAgLmNsaXBFeHRlbnQoW1t4IC0gMC4yMTQgKiBrICsgZXBzaWxvbiQyLCB5ICsgMC4xNjYgKiBrICsgZXBzaWxvbiQyXSwgW3ggLSAwLjExNSAqIGsgLSBlcHNpbG9uJDIsIHkgKyAwLjIzNCAqIGsgLSBlcHNpbG9uJDJdXSlcbiAgICAgICAgLnN0cmVhbShwb2ludFN0cmVhbSk7XG5cbiAgICByZXR1cm4gcmVzZXQoKTtcbiAgfTtcblxuICBhbGJlcnNVc2EuZml0RXh0ZW50ID0gZnVuY3Rpb24oZXh0ZW50LCBvYmplY3QpIHtcbiAgICByZXR1cm4gZml0RXh0ZW50KGFsYmVyc1VzYSwgZXh0ZW50LCBvYmplY3QpO1xuICB9O1xuXG4gIGFsYmVyc1VzYS5maXRTaXplID0gZnVuY3Rpb24oc2l6ZSwgb2JqZWN0KSB7XG4gICAgcmV0dXJuIGZpdFNpemUoYWxiZXJzVXNhLCBzaXplLCBvYmplY3QpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgIGNhY2hlID0gY2FjaGVTdHJlYW0gPSBudWxsO1xuICAgIHJldHVybiBhbGJlcnNVc2E7XG4gIH1cblxuICByZXR1cm4gYWxiZXJzVXNhLnNjYWxlKDEwNzApO1xufTtcblxuZnVuY3Rpb24gYXppbXV0aGFsUmF3KHNjYWxlKSB7XG4gIHJldHVybiBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIGN4ID0gY29zJDEoeCksXG4gICAgICAgIGN5ID0gY29zJDEoeSksXG4gICAgICAgIGsgPSBzY2FsZShjeCAqIGN5KTtcbiAgICByZXR1cm4gW1xuICAgICAgayAqIGN5ICogc2luJDEoeCksXG4gICAgICBrICogc2luJDEoeSlcbiAgICBdO1xuICB9XG59XG5cbmZ1bmN0aW9uIGF6aW11dGhhbEludmVydChhbmdsZSkge1xuICByZXR1cm4gZnVuY3Rpb24oeCwgeSkge1xuICAgIHZhciB6ID0gc3FydCh4ICogeCArIHkgKiB5KSxcbiAgICAgICAgYyA9IGFuZ2xlKHopLFxuICAgICAgICBzYyA9IHNpbiQxKGMpLFxuICAgICAgICBjYyA9IGNvcyQxKGMpO1xuICAgIHJldHVybiBbXG4gICAgICBhdGFuMih4ICogc2MsIHogKiBjYyksXG4gICAgICBhc2luKHogJiYgeSAqIHNjIC8geilcbiAgICBdO1xuICB9XG59XG5cbnZhciBhemltdXRoYWxFcXVhbEFyZWFSYXcgPSBhemltdXRoYWxSYXcoZnVuY3Rpb24oY3hjeSkge1xuICByZXR1cm4gc3FydCgyIC8gKDEgKyBjeGN5KSk7XG59KTtcblxuYXppbXV0aGFsRXF1YWxBcmVhUmF3LmludmVydCA9IGF6aW11dGhhbEludmVydChmdW5jdGlvbih6KSB7XG4gIHJldHVybiAyICogYXNpbih6IC8gMik7XG59KTtcblxudmFyIGF6aW11dGhhbEVxdWFsQXJlYSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gcHJvamVjdGlvbihhemltdXRoYWxFcXVhbEFyZWFSYXcpXG4gICAgICAuc2NhbGUoMTI0Ljc1KVxuICAgICAgLmNsaXBBbmdsZSgxODAgLSAxZS0zKTtcbn07XG5cbnZhciBhemltdXRoYWxFcXVpZGlzdGFudFJhdyA9IGF6aW11dGhhbFJhdyhmdW5jdGlvbihjKSB7XG4gIHJldHVybiAoYyA9IGFjb3MoYykpICYmIGMgLyBzaW4kMShjKTtcbn0pO1xuXG5hemltdXRoYWxFcXVpZGlzdGFudFJhdy5pbnZlcnQgPSBhemltdXRoYWxJbnZlcnQoZnVuY3Rpb24oeikge1xuICByZXR1cm4gejtcbn0pO1xuXG52YXIgYXppbXV0aGFsRXF1aWRpc3RhbnQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHByb2plY3Rpb24oYXppbXV0aGFsRXF1aWRpc3RhbnRSYXcpXG4gICAgICAuc2NhbGUoNzkuNDE4OClcbiAgICAgIC5jbGlwQW5nbGUoMTgwIC0gMWUtMyk7XG59O1xuXG5mdW5jdGlvbiBtZXJjYXRvclJhdyhsYW1iZGEsIHBoaSkge1xuICByZXR1cm4gW2xhbWJkYSwgbG9nKHRhbigoaGFsZlBpJDIgKyBwaGkpIC8gMikpXTtcbn1cblxubWVyY2F0b3JSYXcuaW52ZXJ0ID0gZnVuY3Rpb24oeCwgeSkge1xuICByZXR1cm4gW3gsIDIgKiBhdGFuKGV4cCh5KSkgLSBoYWxmUGkkMl07XG59O1xuXG52YXIgbWVyY2F0b3IgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG1lcmNhdG9yUHJvamVjdGlvbihtZXJjYXRvclJhdylcbiAgICAgIC5zY2FsZSg5NjEgLyB0YXUkMyk7XG59O1xuXG5mdW5jdGlvbiBtZXJjYXRvclByb2plY3Rpb24ocHJvamVjdCkge1xuICB2YXIgbSA9IHByb2plY3Rpb24ocHJvamVjdCksXG4gICAgICBjZW50ZXIgPSBtLmNlbnRlcixcbiAgICAgIHNjYWxlID0gbS5zY2FsZSxcbiAgICAgIHRyYW5zbGF0ZSA9IG0udHJhbnNsYXRlLFxuICAgICAgY2xpcEV4dGVudCA9IG0uY2xpcEV4dGVudCxcbiAgICAgIHgwID0gbnVsbCwgeTAsIHgxLCB5MTsgLy8gY2xpcCBleHRlbnRcblxuICBtLnNjYWxlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNjYWxlKF8pLCByZWNsaXAoKSkgOiBzY2FsZSgpO1xuICB9O1xuXG4gIG0udHJhbnNsYXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRyYW5zbGF0ZShfKSwgcmVjbGlwKCkpIDogdHJhbnNsYXRlKCk7XG4gIH07XG5cbiAgbS5jZW50ZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoY2VudGVyKF8pLCByZWNsaXAoKSkgOiBjZW50ZXIoKTtcbiAgfTtcblxuICBtLmNsaXBFeHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoKF8gPT0gbnVsbCA/IHgwID0geTAgPSB4MSA9IHkxID0gbnVsbCA6ICh4MCA9ICtfWzBdWzBdLCB5MCA9ICtfWzBdWzFdLCB4MSA9ICtfWzFdWzBdLCB5MSA9ICtfWzFdWzFdKSksIHJlY2xpcCgpKSA6IHgwID09IG51bGwgPyBudWxsIDogW1t4MCwgeTBdLCBbeDEsIHkxXV07XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVjbGlwKCkge1xuICAgIHZhciBrID0gcGkkMyAqIHNjYWxlKCksXG4gICAgICAgIHQgPSBtKHJvdGF0aW9uKG0ucm90YXRlKCkpLmludmVydChbMCwgMF0pKTtcbiAgICByZXR1cm4gY2xpcEV4dGVudCh4MCA9PSBudWxsXG4gICAgICAgID8gW1t0WzBdIC0gaywgdFsxXSAtIGtdLCBbdFswXSArIGssIHRbMV0gKyBrXV0gOiBwcm9qZWN0ID09PSBtZXJjYXRvclJhd1xuICAgICAgICA/IFtbTWF0aC5tYXgodFswXSAtIGssIHgwKSwgeTBdLCBbTWF0aC5taW4odFswXSArIGssIHgxKSwgeTFdXVxuICAgICAgICA6IFtbeDAsIE1hdGgubWF4KHRbMV0gLSBrLCB5MCldLCBbeDEsIE1hdGgubWluKHRbMV0gKyBrLCB5MSldXSk7XG4gIH1cblxuICByZXR1cm4gcmVjbGlwKCk7XG59XG5cbmZ1bmN0aW9uIHRhbnkoeSkge1xuICByZXR1cm4gdGFuKChoYWxmUGkkMiArIHkpIC8gMik7XG59XG5cbmZ1bmN0aW9uIGNvbmljQ29uZm9ybWFsUmF3KHkwLCB5MSkge1xuICB2YXIgY3kwID0gY29zJDEoeTApLFxuICAgICAgbiA9IHkwID09PSB5MSA/IHNpbiQxKHkwKSA6IGxvZyhjeTAgLyBjb3MkMSh5MSkpIC8gbG9nKHRhbnkoeTEpIC8gdGFueSh5MCkpLFxuICAgICAgZiA9IGN5MCAqIHBvdyh0YW55KHkwKSwgbikgLyBuO1xuXG4gIGlmICghbikgcmV0dXJuIG1lcmNhdG9yUmF3O1xuXG4gIGZ1bmN0aW9uIHByb2plY3QoeCwgeSkge1xuICAgIGlmIChmID4gMCkgeyBpZiAoeSA8IC1oYWxmUGkkMiArIGVwc2lsb24kMikgeSA9IC1oYWxmUGkkMiArIGVwc2lsb24kMjsgfVxuICAgIGVsc2UgeyBpZiAoeSA+IGhhbGZQaSQyIC0gZXBzaWxvbiQyKSB5ID0gaGFsZlBpJDIgLSBlcHNpbG9uJDI7IH1cbiAgICB2YXIgciA9IGYgLyBwb3codGFueSh5KSwgbik7XG4gICAgcmV0dXJuIFtyICogc2luJDEobiAqIHgpLCBmIC0gciAqIGNvcyQxKG4gKiB4KV07XG4gIH1cblxuICBwcm9qZWN0LmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB2YXIgZnkgPSBmIC0geSwgciA9IHNpZ24obikgKiBzcXJ0KHggKiB4ICsgZnkgKiBmeSk7XG4gICAgcmV0dXJuIFthdGFuMih4LCBhYnMoZnkpKSAvIG4gKiBzaWduKGZ5KSwgMiAqIGF0YW4ocG93KGYgLyByLCAxIC8gbikpIC0gaGFsZlBpJDJdO1xuICB9O1xuXG4gIHJldHVybiBwcm9qZWN0O1xufVxuXG52YXIgY29uaWNDb25mb3JtYWwgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGNvbmljUHJvamVjdGlvbihjb25pY0NvbmZvcm1hbFJhdylcbiAgICAgIC5zY2FsZSgxMDkuNSlcbiAgICAgIC5wYXJhbGxlbHMoWzMwLCAzMF0pO1xufTtcblxuZnVuY3Rpb24gZXF1aXJlY3Rhbmd1bGFyUmF3KGxhbWJkYSwgcGhpKSB7XG4gIHJldHVybiBbbGFtYmRhLCBwaGldO1xufVxuXG5lcXVpcmVjdGFuZ3VsYXJSYXcuaW52ZXJ0ID0gZXF1aXJlY3Rhbmd1bGFyUmF3O1xuXG52YXIgZXF1aXJlY3Rhbmd1bGFyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwcm9qZWN0aW9uKGVxdWlyZWN0YW5ndWxhclJhdylcbiAgICAgIC5zY2FsZSgxNTIuNjMpO1xufTtcblxuZnVuY3Rpb24gY29uaWNFcXVpZGlzdGFudFJhdyh5MCwgeTEpIHtcbiAgdmFyIGN5MCA9IGNvcyQxKHkwKSxcbiAgICAgIG4gPSB5MCA9PT0geTEgPyBzaW4kMSh5MCkgOiAoY3kwIC0gY29zJDEoeTEpKSAvICh5MSAtIHkwKSxcbiAgICAgIGcgPSBjeTAgLyBuICsgeTA7XG5cbiAgaWYgKGFicyhuKSA8IGVwc2lsb24kMikgcmV0dXJuIGVxdWlyZWN0YW5ndWxhclJhdztcblxuICBmdW5jdGlvbiBwcm9qZWN0KHgsIHkpIHtcbiAgICB2YXIgZ3kgPSBnIC0geSwgbnggPSBuICogeDtcbiAgICByZXR1cm4gW2d5ICogc2luJDEobngpLCBnIC0gZ3kgKiBjb3MkMShueCldO1xuICB9XG5cbiAgcHJvamVjdC5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIGd5ID0gZyAtIHk7XG4gICAgcmV0dXJuIFthdGFuMih4LCBhYnMoZ3kpKSAvIG4gKiBzaWduKGd5KSwgZyAtIHNpZ24obikgKiBzcXJ0KHggKiB4ICsgZ3kgKiBneSldO1xuICB9O1xuXG4gIHJldHVybiBwcm9qZWN0O1xufVxuXG52YXIgY29uaWNFcXVpZGlzdGFudCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY29uaWNQcm9qZWN0aW9uKGNvbmljRXF1aWRpc3RhbnRSYXcpXG4gICAgICAuc2NhbGUoMTMxLjE1NClcbiAgICAgIC5jZW50ZXIoWzAsIDEzLjkzODldKTtcbn07XG5cbmZ1bmN0aW9uIGdub21vbmljUmF3KHgsIHkpIHtcbiAgdmFyIGN5ID0gY29zJDEoeSksIGsgPSBjb3MkMSh4KSAqIGN5O1xuICByZXR1cm4gW2N5ICogc2luJDEoeCkgLyBrLCBzaW4kMSh5KSAvIGtdO1xufVxuXG5nbm9tb25pY1Jhdy5pbnZlcnQgPSBhemltdXRoYWxJbnZlcnQoYXRhbik7XG5cbnZhciBnbm9tb25pYyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gcHJvamVjdGlvbihnbm9tb25pY1JhdylcbiAgICAgIC5zY2FsZSgxNDQuMDQ5KVxuICAgICAgLmNsaXBBbmdsZSg2MCk7XG59O1xuXG5mdW5jdGlvbiBzY2FsZVRyYW5zbGF0ZShreCwga3ksIHR4LCB0eSkge1xuICByZXR1cm4ga3ggPT09IDEgJiYga3kgPT09IDEgJiYgdHggPT09IDAgJiYgdHkgPT09IDAgPyBpZGVudGl0eSQ0IDogdHJhbnNmb3JtZXIoe1xuICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgICB0aGlzLnN0cmVhbS5wb2ludCh4ICoga3ggKyB0eCwgeSAqIGt5ICsgdHkpO1xuICAgIH1cbiAgfSk7XG59XG5cbnZhciBpZGVudGl0eSQ1ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrID0gMSwgdHggPSAwLCB0eSA9IDAsIHN4ID0gMSwgc3kgPSAxLCB0cmFuc2Zvcm0gPSBpZGVudGl0eSQ0LCAvLyBzY2FsZSwgdHJhbnNsYXRlIGFuZCByZWZsZWN0XG4gICAgICB4MCA9IG51bGwsIHkwLCB4MSwgeTEsIGNsaXAgPSBpZGVudGl0eSQ0LCAvLyBjbGlwIGV4dGVudFxuICAgICAgY2FjaGUsXG4gICAgICBjYWNoZVN0cmVhbSxcbiAgICAgIHByb2plY3Rpb247XG5cbiAgZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgY2FjaGUgPSBjYWNoZVN0cmVhbSA9IG51bGw7XG4gICAgcmV0dXJuIHByb2plY3Rpb247XG4gIH1cblxuICByZXR1cm4gcHJvamVjdGlvbiA9IHtcbiAgICBzdHJlYW06IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgcmV0dXJuIGNhY2hlICYmIGNhY2hlU3RyZWFtID09PSBzdHJlYW0gPyBjYWNoZSA6IGNhY2hlID0gdHJhbnNmb3JtKGNsaXAoY2FjaGVTdHJlYW0gPSBzdHJlYW0pKTtcbiAgICB9LFxuICAgIGNsaXBFeHRlbnQ6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNsaXAgPSBfID09IG51bGwgPyAoeDAgPSB5MCA9IHgxID0geTEgPSBudWxsLCBpZGVudGl0eSQ0KSA6IGNsaXBFeHRlbnQoeDAgPSArX1swXVswXSwgeTAgPSArX1swXVsxXSwgeDEgPSArX1sxXVswXSwgeTEgPSArX1sxXVsxXSksIHJlc2V0KCkpIDogeDAgPT0gbnVsbCA/IG51bGwgOiBbW3gwLCB5MF0sIFt4MSwgeTFdXTtcbiAgICB9LFxuICAgIHNjYWxlOiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0cmFuc2Zvcm0gPSBzY2FsZVRyYW5zbGF0ZSgoayA9ICtfKSAqIHN4LCBrICogc3ksIHR4LCB0eSksIHJlc2V0KCkpIDogaztcbiAgICB9LFxuICAgIHRyYW5zbGF0ZTogZnVuY3Rpb24oXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodHJhbnNmb3JtID0gc2NhbGVUcmFuc2xhdGUoayAqIHN4LCBrICogc3ksIHR4ID0gK19bMF0sIHR5ID0gK19bMV0pLCByZXNldCgpKSA6IFt0eCwgdHldO1xuICAgIH0sXG4gICAgcmVmbGVjdFg6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRyYW5zZm9ybSA9IHNjYWxlVHJhbnNsYXRlKGsgKiAoc3ggPSBfID8gLTEgOiAxKSwgayAqIHN5LCB0eCwgdHkpLCByZXNldCgpKSA6IHN4IDwgMDtcbiAgICB9LFxuICAgIHJlZmxlY3RZOiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0cmFuc2Zvcm0gPSBzY2FsZVRyYW5zbGF0ZShrICogc3gsIGsgKiAoc3kgPSBfID8gLTEgOiAxKSwgdHgsIHR5KSwgcmVzZXQoKSkgOiBzeSA8IDA7XG4gICAgfSxcbiAgICBmaXRFeHRlbnQ6IGZ1bmN0aW9uKGV4dGVudCwgb2JqZWN0KSB7XG4gICAgICByZXR1cm4gZml0RXh0ZW50KHByb2plY3Rpb24sIGV4dGVudCwgb2JqZWN0KTtcbiAgICB9LFxuICAgIGZpdFNpemU6IGZ1bmN0aW9uKHNpemUsIG9iamVjdCkge1xuICAgICAgcmV0dXJuIGZpdFNpemUocHJvamVjdGlvbiwgc2l6ZSwgb2JqZWN0KTtcbiAgICB9XG4gIH07XG59O1xuXG5mdW5jdGlvbiBvcnRob2dyYXBoaWNSYXcoeCwgeSkge1xuICByZXR1cm4gW2NvcyQxKHkpICogc2luJDEoeCksIHNpbiQxKHkpXTtcbn1cblxub3J0aG9ncmFwaGljUmF3LmludmVydCA9IGF6aW11dGhhbEludmVydChhc2luKTtcblxudmFyIG9ydGhvZ3JhcGhpYyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gcHJvamVjdGlvbihvcnRob2dyYXBoaWNSYXcpXG4gICAgICAuc2NhbGUoMjQ5LjUpXG4gICAgICAuY2xpcEFuZ2xlKDkwICsgZXBzaWxvbiQyKTtcbn07XG5cbmZ1bmN0aW9uIHN0ZXJlb2dyYXBoaWNSYXcoeCwgeSkge1xuICB2YXIgY3kgPSBjb3MkMSh5KSwgayA9IDEgKyBjb3MkMSh4KSAqIGN5O1xuICByZXR1cm4gW2N5ICogc2luJDEoeCkgLyBrLCBzaW4kMSh5KSAvIGtdO1xufVxuXG5zdGVyZW9ncmFwaGljUmF3LmludmVydCA9IGF6aW11dGhhbEludmVydChmdW5jdGlvbih6KSB7XG4gIHJldHVybiAyICogYXRhbih6KTtcbn0pO1xuXG52YXIgc3RlcmVvZ3JhcGhpYyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gcHJvamVjdGlvbihzdGVyZW9ncmFwaGljUmF3KVxuICAgICAgLnNjYWxlKDI1MClcbiAgICAgIC5jbGlwQW5nbGUoMTQyKTtcbn07XG5cbmZ1bmN0aW9uIHRyYW5zdmVyc2VNZXJjYXRvclJhdyhsYW1iZGEsIHBoaSkge1xuICByZXR1cm4gW2xvZyh0YW4oKGhhbGZQaSQyICsgcGhpKSAvIDIpKSwgLWxhbWJkYV07XG59XG5cbnRyYW5zdmVyc2VNZXJjYXRvclJhdy5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHJldHVybiBbLXksIDIgKiBhdGFuKGV4cCh4KSkgLSBoYWxmUGkkMl07XG59O1xuXG52YXIgdHJhbnN2ZXJzZU1lcmNhdG9yID0gZnVuY3Rpb24oKSB7XG4gIHZhciBtID0gbWVyY2F0b3JQcm9qZWN0aW9uKHRyYW5zdmVyc2VNZXJjYXRvclJhdyksXG4gICAgICBjZW50ZXIgPSBtLmNlbnRlcixcbiAgICAgIHJvdGF0ZSA9IG0ucm90YXRlO1xuXG4gIG0uY2VudGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gY2VudGVyKFstX1sxXSwgX1swXV0pIDogKF8gPSBjZW50ZXIoKSwgW19bMV0sIC1fWzBdXSk7XG4gIH07XG5cbiAgbS5yb3RhdGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyByb3RhdGUoW19bMF0sIF9bMV0sIF8ubGVuZ3RoID4gMiA/IF9bMl0gKyA5MCA6IDkwXSkgOiAoXyA9IHJvdGF0ZSgpLCBbX1swXSwgX1sxXSwgX1syXSAtIDkwXSk7XG4gIH07XG5cbiAgcmV0dXJuIHJvdGF0ZShbMCwgMCwgOTBdKVxuICAgICAgLnNjYWxlKDE1OS4xNTUpO1xufTtcblxuZnVuY3Rpb24gZGVmYXVsdFNlcGFyYXRpb24oYSwgYikge1xuICByZXR1cm4gYS5wYXJlbnQgPT09IGIucGFyZW50ID8gMSA6IDI7XG59XG5cbmZ1bmN0aW9uIG1lYW5YKGNoaWxkcmVuKSB7XG4gIHJldHVybiBjaGlsZHJlbi5yZWR1Y2UobWVhblhSZWR1Y2UsIDApIC8gY2hpbGRyZW4ubGVuZ3RoO1xufVxuXG5mdW5jdGlvbiBtZWFuWFJlZHVjZSh4LCBjKSB7XG4gIHJldHVybiB4ICsgYy54O1xufVxuXG5mdW5jdGlvbiBtYXhZKGNoaWxkcmVuKSB7XG4gIHJldHVybiAxICsgY2hpbGRyZW4ucmVkdWNlKG1heFlSZWR1Y2UsIDApO1xufVxuXG5mdW5jdGlvbiBtYXhZUmVkdWNlKHksIGMpIHtcbiAgcmV0dXJuIE1hdGgubWF4KHksIGMueSk7XG59XG5cbmZ1bmN0aW9uIGxlYWZMZWZ0KG5vZGUpIHtcbiAgdmFyIGNoaWxkcmVuO1xuICB3aGlsZSAoY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuKSBub2RlID0gY2hpbGRyZW5bMF07XG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBsZWFmUmlnaHQobm9kZSkge1xuICB2YXIgY2hpbGRyZW47XG4gIHdoaWxlIChjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4pIG5vZGUgPSBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbnZhciBjbHVzdGVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzZXBhcmF0aW9uID0gZGVmYXVsdFNlcGFyYXRpb24sXG4gICAgICBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICBub2RlU2l6ZSA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGNsdXN0ZXIocm9vdCkge1xuICAgIHZhciBwcmV2aW91c05vZGUsXG4gICAgICAgIHggPSAwO1xuXG4gICAgLy8gRmlyc3Qgd2FsaywgY29tcHV0aW5nIHRoZSBpbml0aWFsIHggJiB5IHZhbHVlcy5cbiAgICByb290LmVhY2hBZnRlcihmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xuICAgICAgaWYgKGNoaWxkcmVuKSB7XG4gICAgICAgIG5vZGUueCA9IG1lYW5YKGNoaWxkcmVuKTtcbiAgICAgICAgbm9kZS55ID0gbWF4WShjaGlsZHJlbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlLnggPSBwcmV2aW91c05vZGUgPyB4ICs9IHNlcGFyYXRpb24obm9kZSwgcHJldmlvdXNOb2RlKSA6IDA7XG4gICAgICAgIG5vZGUueSA9IDA7XG4gICAgICAgIHByZXZpb3VzTm9kZSA9IG5vZGU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB2YXIgbGVmdCA9IGxlYWZMZWZ0KHJvb3QpLFxuICAgICAgICByaWdodCA9IGxlYWZSaWdodChyb290KSxcbiAgICAgICAgeDAgPSBsZWZ0LnggLSBzZXBhcmF0aW9uKGxlZnQsIHJpZ2h0KSAvIDIsXG4gICAgICAgIHgxID0gcmlnaHQueCArIHNlcGFyYXRpb24ocmlnaHQsIGxlZnQpIC8gMjtcblxuICAgIC8vIFNlY29uZCB3YWxrLCBub3JtYWxpemluZyB4ICYgeSB0byB0aGUgZGVzaXJlZCBzaXplLlxuICAgIHJldHVybiByb290LmVhY2hBZnRlcihub2RlU2l6ZSA/IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIG5vZGUueCA9IChub2RlLnggLSByb290LngpICogZHg7XG4gICAgICBub2RlLnkgPSAocm9vdC55IC0gbm9kZS55KSAqIGR5O1xuICAgIH0gOiBmdW5jdGlvbihub2RlKSB7XG4gICAgICBub2RlLnggPSAobm9kZS54IC0geDApIC8gKHgxIC0geDApICogZHg7XG4gICAgICBub2RlLnkgPSAoMSAtIChyb290LnkgPyBub2RlLnkgLyByb290LnkgOiAxKSkgKiBkeTtcbiAgICB9KTtcbiAgfVxuXG4gIGNsdXN0ZXIuc2VwYXJhdGlvbiA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzZXBhcmF0aW9uID0geCwgY2x1c3RlcikgOiBzZXBhcmF0aW9uO1xuICB9O1xuXG4gIGNsdXN0ZXIuc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IGZhbHNlLCBkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCBjbHVzdGVyKSA6IChub2RlU2l6ZSA/IG51bGwgOiBbZHgsIGR5XSk7XG4gIH07XG5cbiAgY2x1c3Rlci5ub2RlU2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IHRydWUsIGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIGNsdXN0ZXIpIDogKG5vZGVTaXplID8gW2R4LCBkeV0gOiBudWxsKTtcbiAgfTtcblxuICByZXR1cm4gY2x1c3Rlcjtcbn07XG5cbmZ1bmN0aW9uIGNvdW50KG5vZGUpIHtcbiAgdmFyIHN1bSA9IDAsXG4gICAgICBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4sXG4gICAgICBpID0gY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoO1xuICBpZiAoIWkpIHN1bSA9IDE7XG4gIGVsc2Ugd2hpbGUgKC0taSA+PSAwKSBzdW0gKz0gY2hpbGRyZW5baV0udmFsdWU7XG4gIG5vZGUudmFsdWUgPSBzdW07XG59XG5cbnZhciBub2RlX2NvdW50ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmVhY2hBZnRlcihjb3VudCk7XG59O1xuXG52YXIgbm9kZV9lYWNoID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIG5vZGUgPSB0aGlzLCBjdXJyZW50LCBuZXh0ID0gW25vZGVdLCBjaGlsZHJlbiwgaSwgbjtcbiAgZG8ge1xuICAgIGN1cnJlbnQgPSBuZXh0LnJldmVyc2UoKSwgbmV4dCA9IFtdO1xuICAgIHdoaWxlIChub2RlID0gY3VycmVudC5wb3AoKSkge1xuICAgICAgY2FsbGJhY2sobm9kZSksIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjtcbiAgICAgIGlmIChjaGlsZHJlbikgZm9yIChpID0gMCwgbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgICBuZXh0LnB1c2goY2hpbGRyZW5baV0pO1xuICAgICAgfVxuICAgIH1cbiAgfSB3aGlsZSAobmV4dC5sZW5ndGgpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnZhciBub2RlX2VhY2hCZWZvcmUgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgbm9kZSA9IHRoaXMsIG5vZGVzID0gW25vZGVdLCBjaGlsZHJlbiwgaTtcbiAgd2hpbGUgKG5vZGUgPSBub2Rlcy5wb3AoKSkge1xuICAgIGNhbGxiYWNrKG5vZGUpLCBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW47XG4gICAgaWYgKGNoaWxkcmVuKSBmb3IgKGkgPSBjaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgbm9kZXMucHVzaChjaGlsZHJlbltpXSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIG5vZGVfZWFjaEFmdGVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIG5vZGUgPSB0aGlzLCBub2RlcyA9IFtub2RlXSwgbmV4dCA9IFtdLCBjaGlsZHJlbiwgaSwgbjtcbiAgd2hpbGUgKG5vZGUgPSBub2Rlcy5wb3AoKSkge1xuICAgIG5leHQucHVzaChub2RlKSwgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xuICAgIGlmIChjaGlsZHJlbikgZm9yIChpID0gMCwgbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZXMucHVzaChjaGlsZHJlbltpXSk7XG4gICAgfVxuICB9XG4gIHdoaWxlIChub2RlID0gbmV4dC5wb3AoKSkge1xuICAgIGNhbGxiYWNrKG5vZGUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIG5vZGVfc3VtID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaEFmdGVyKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICB2YXIgc3VtID0gK3ZhbHVlKG5vZGUuZGF0YSkgfHwgMCxcbiAgICAgICAgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuLFxuICAgICAgICBpID0gY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoO1xuICAgIHdoaWxlICgtLWkgPj0gMCkgc3VtICs9IGNoaWxkcmVuW2ldLnZhbHVlO1xuICAgIG5vZGUudmFsdWUgPSBzdW07XG4gIH0pO1xufTtcblxudmFyIG5vZGVfc29ydCA9IGZ1bmN0aW9uKGNvbXBhcmUpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaEJlZm9yZShmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIG5vZGUuY2hpbGRyZW4uc29ydChjb21wYXJlKTtcbiAgICB9XG4gIH0pO1xufTtcblxudmFyIG5vZGVfcGF0aCA9IGZ1bmN0aW9uKGVuZCkge1xuICB2YXIgc3RhcnQgPSB0aGlzLFxuICAgICAgYW5jZXN0b3IgPSBsZWFzdENvbW1vbkFuY2VzdG9yKHN0YXJ0LCBlbmQpLFxuICAgICAgbm9kZXMgPSBbc3RhcnRdO1xuICB3aGlsZSAoc3RhcnQgIT09IGFuY2VzdG9yKSB7XG4gICAgc3RhcnQgPSBzdGFydC5wYXJlbnQ7XG4gICAgbm9kZXMucHVzaChzdGFydCk7XG4gIH1cbiAgdmFyIGsgPSBub2Rlcy5sZW5ndGg7XG4gIHdoaWxlIChlbmQgIT09IGFuY2VzdG9yKSB7XG4gICAgbm9kZXMuc3BsaWNlKGssIDAsIGVuZCk7XG4gICAgZW5kID0gZW5kLnBhcmVudDtcbiAgfVxuICByZXR1cm4gbm9kZXM7XG59O1xuXG5mdW5jdGlvbiBsZWFzdENvbW1vbkFuY2VzdG9yKGEsIGIpIHtcbiAgaWYgKGEgPT09IGIpIHJldHVybiBhO1xuICB2YXIgYU5vZGVzID0gYS5hbmNlc3RvcnMoKSxcbiAgICAgIGJOb2RlcyA9IGIuYW5jZXN0b3JzKCksXG4gICAgICBjID0gbnVsbDtcbiAgYSA9IGFOb2Rlcy5wb3AoKTtcbiAgYiA9IGJOb2Rlcy5wb3AoKTtcbiAgd2hpbGUgKGEgPT09IGIpIHtcbiAgICBjID0gYTtcbiAgICBhID0gYU5vZGVzLnBvcCgpO1xuICAgIGIgPSBiTm9kZXMucG9wKCk7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG5cbnZhciBub2RlX2FuY2VzdG9ycyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZSA9IHRoaXMsIG5vZGVzID0gW25vZGVdO1xuICB3aGlsZSAobm9kZSA9IG5vZGUucGFyZW50KSB7XG4gICAgbm9kZXMucHVzaChub2RlKTtcbiAgfVxuICByZXR1cm4gbm9kZXM7XG59O1xuXG52YXIgbm9kZV9kZXNjZW5kYW50cyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZXMgPSBbXTtcbiAgdGhpcy5lYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBub2Rlcy5wdXNoKG5vZGUpO1xuICB9KTtcbiAgcmV0dXJuIG5vZGVzO1xufTtcblxudmFyIG5vZGVfbGVhdmVzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBsZWF2ZXMgPSBbXTtcbiAgdGhpcy5lYWNoQmVmb3JlKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIGxlYXZlcy5wdXNoKG5vZGUpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBsZWF2ZXM7XG59O1xuXG52YXIgbm9kZV9saW5rcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcm9vdCA9IHRoaXMsIGxpbmtzID0gW107XG4gIHJvb3QuZWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKG5vZGUgIT09IHJvb3QpIHsgLy8gRG9u4oCZdCBpbmNsdWRlIHRoZSByb2904oCZcyBwYXJlbnQsIGlmIGFueS5cbiAgICAgIGxpbmtzLnB1c2goe3NvdXJjZTogbm9kZS5wYXJlbnQsIHRhcmdldDogbm9kZX0pO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBsaW5rcztcbn07XG5cbmZ1bmN0aW9uIGhpZXJhcmNoeShkYXRhLCBjaGlsZHJlbikge1xuICB2YXIgcm9vdCA9IG5ldyBOb2RlKGRhdGEpLFxuICAgICAgdmFsdWVkID0gK2RhdGEudmFsdWUgJiYgKHJvb3QudmFsdWUgPSBkYXRhLnZhbHVlKSxcbiAgICAgIG5vZGUsXG4gICAgICBub2RlcyA9IFtyb290XSxcbiAgICAgIGNoaWxkLFxuICAgICAgY2hpbGRzLFxuICAgICAgaSxcbiAgICAgIG47XG5cbiAgaWYgKGNoaWxkcmVuID09IG51bGwpIGNoaWxkcmVuID0gZGVmYXVsdENoaWxkcmVuO1xuXG4gIHdoaWxlIChub2RlID0gbm9kZXMucG9wKCkpIHtcbiAgICBpZiAodmFsdWVkKSBub2RlLnZhbHVlID0gK25vZGUuZGF0YS52YWx1ZTtcbiAgICBpZiAoKGNoaWxkcyA9IGNoaWxkcmVuKG5vZGUuZGF0YSkpICYmIChuID0gY2hpbGRzLmxlbmd0aCkpIHtcbiAgICAgIG5vZGUuY2hpbGRyZW4gPSBuZXcgQXJyYXkobik7XG4gICAgICBmb3IgKGkgPSBuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgbm9kZXMucHVzaChjaGlsZCA9IG5vZGUuY2hpbGRyZW5baV0gPSBuZXcgTm9kZShjaGlsZHNbaV0pKTtcbiAgICAgICAgY2hpbGQucGFyZW50ID0gbm9kZTtcbiAgICAgICAgY2hpbGQuZGVwdGggPSBub2RlLmRlcHRoICsgMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcm9vdC5lYWNoQmVmb3JlKGNvbXB1dGVIZWlnaHQpO1xufVxuXG5mdW5jdGlvbiBub2RlX2NvcHkoKSB7XG4gIHJldHVybiBoaWVyYXJjaHkodGhpcykuZWFjaEJlZm9yZShjb3B5RGF0YSk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRDaGlsZHJlbihkKSB7XG4gIHJldHVybiBkLmNoaWxkcmVuO1xufVxuXG5mdW5jdGlvbiBjb3B5RGF0YShub2RlKSB7XG4gIG5vZGUuZGF0YSA9IG5vZGUuZGF0YS5kYXRhO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlSGVpZ2h0KG5vZGUpIHtcbiAgdmFyIGhlaWdodCA9IDA7XG4gIGRvIG5vZGUuaGVpZ2h0ID0gaGVpZ2h0O1xuICB3aGlsZSAoKG5vZGUgPSBub2RlLnBhcmVudCkgJiYgKG5vZGUuaGVpZ2h0IDwgKytoZWlnaHQpKTtcbn1cblxuZnVuY3Rpb24gTm9kZShkYXRhKSB7XG4gIHRoaXMuZGF0YSA9IGRhdGE7XG4gIHRoaXMuZGVwdGggPVxuICB0aGlzLmhlaWdodCA9IDA7XG4gIHRoaXMucGFyZW50ID0gbnVsbDtcbn1cblxuTm9kZS5wcm90b3R5cGUgPSBoaWVyYXJjaHkucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogTm9kZSxcbiAgY291bnQ6IG5vZGVfY291bnQsXG4gIGVhY2g6IG5vZGVfZWFjaCxcbiAgZWFjaEFmdGVyOiBub2RlX2VhY2hBZnRlcixcbiAgZWFjaEJlZm9yZTogbm9kZV9lYWNoQmVmb3JlLFxuICBzdW06IG5vZGVfc3VtLFxuICBzb3J0OiBub2RlX3NvcnQsXG4gIHBhdGg6IG5vZGVfcGF0aCxcbiAgYW5jZXN0b3JzOiBub2RlX2FuY2VzdG9ycyxcbiAgZGVzY2VuZGFudHM6IG5vZGVfZGVzY2VuZGFudHMsXG4gIGxlYXZlczogbm9kZV9sZWF2ZXMsXG4gIGxpbmtzOiBub2RlX2xpbmtzLFxuICBjb3B5OiBub2RlX2NvcHlcbn07XG5cbmZ1bmN0aW9uIE5vZGUkMih2YWx1ZSkge1xuICB0aGlzLl8gPSB2YWx1ZTtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbn1cblxudmFyIHNodWZmbGUkMSA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gIHZhciBpLFxuICAgICAgbiA9IChhcnJheSA9IGFycmF5LnNsaWNlKCkpLmxlbmd0aCxcbiAgICAgIGhlYWQgPSBudWxsLFxuICAgICAgbm9kZSA9IGhlYWQ7XG5cbiAgd2hpbGUgKG4pIHtcbiAgICB2YXIgbmV4dCA9IG5ldyBOb2RlJDIoYXJyYXlbbiAtIDFdKTtcbiAgICBpZiAobm9kZSkgbm9kZSA9IG5vZGUubmV4dCA9IG5leHQ7XG4gICAgZWxzZSBub2RlID0gaGVhZCA9IG5leHQ7XG4gICAgYXJyYXlbaV0gPSBhcnJheVstLW5dO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBoZWFkOiBoZWFkLFxuICAgIHRhaWw6IG5vZGVcbiAgfTtcbn07XG5cbnZhciBlbmNsb3NlID0gZnVuY3Rpb24oY2lyY2xlcykge1xuICByZXR1cm4gZW5jbG9zZU4oc2h1ZmZsZSQxKGNpcmNsZXMpLCBbXSk7XG59O1xuXG5mdW5jdGlvbiBlbmNsb3NlcyhhLCBiKSB7XG4gIHZhciBkeCA9IGIueCAtIGEueCxcbiAgICAgIGR5ID0gYi55IC0gYS55LFxuICAgICAgZHIgPSBhLnIgLSBiLnI7XG4gIHJldHVybiBkciAqIGRyICsgMWUtNiA+IGR4ICogZHggKyBkeSAqIGR5O1xufVxuXG4vLyBSZXR1cm5zIHRoZSBzbWFsbGVzdCBjaXJjbGUgdGhhdCBjb250YWlucyBjaXJjbGVzIEwgYW5kIGludGVyc2VjdHMgY2lyY2xlcyBCLlxuZnVuY3Rpb24gZW5jbG9zZU4oTCwgQikge1xuICB2YXIgY2lyY2xlLFxuICAgICAgbDAgPSBudWxsLFxuICAgICAgbDEgPSBMLmhlYWQsXG4gICAgICBsMixcbiAgICAgIHAxO1xuXG4gIHN3aXRjaCAoQi5sZW5ndGgpIHtcbiAgICBjYXNlIDE6IGNpcmNsZSA9IGVuY2xvc2UxKEJbMF0pOyBicmVhaztcbiAgICBjYXNlIDI6IGNpcmNsZSA9IGVuY2xvc2UyKEJbMF0sIEJbMV0pOyBicmVhaztcbiAgICBjYXNlIDM6IGNpcmNsZSA9IGVuY2xvc2UzKEJbMF0sIEJbMV0sIEJbMl0pOyBicmVhaztcbiAgfVxuXG4gIHdoaWxlIChsMSkge1xuICAgIHAxID0gbDEuXywgbDIgPSBsMS5uZXh0O1xuICAgIGlmICghY2lyY2xlIHx8ICFlbmNsb3NlcyhjaXJjbGUsIHAxKSkge1xuXG4gICAgICAvLyBUZW1wb3JhcmlseSB0cnVuY2F0ZSBMIGJlZm9yZSBsMS5cbiAgICAgIGlmIChsMCkgTC50YWlsID0gbDAsIGwwLm5leHQgPSBudWxsO1xuICAgICAgZWxzZSBMLmhlYWQgPSBMLnRhaWwgPSBudWxsO1xuXG4gICAgICBCLnB1c2gocDEpO1xuICAgICAgY2lyY2xlID0gZW5jbG9zZU4oTCwgQik7IC8vIE5vdGU6IHJlb3JkZXJzIEwhXG4gICAgICBCLnBvcCgpO1xuXG4gICAgICAvLyBNb3ZlIGwxIHRvIHRoZSBmcm9udCBvZiBMIGFuZCByZWNvbm5lY3QgdGhlIHRydW5jYXRlZCBsaXN0IEwuXG4gICAgICBpZiAoTC5oZWFkKSBsMS5uZXh0ID0gTC5oZWFkLCBMLmhlYWQgPSBsMTtcbiAgICAgIGVsc2UgbDEubmV4dCA9IG51bGwsIEwuaGVhZCA9IEwudGFpbCA9IGwxO1xuICAgICAgbDAgPSBMLnRhaWwsIGwwLm5leHQgPSBsMjtcblxuICAgIH0gZWxzZSB7XG4gICAgICBsMCA9IGwxO1xuICAgIH1cbiAgICBsMSA9IGwyO1xuICB9XG5cbiAgTC50YWlsID0gbDA7XG4gIHJldHVybiBjaXJjbGU7XG59XG5cbmZ1bmN0aW9uIGVuY2xvc2UxKGEpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBhLngsXG4gICAgeTogYS55LFxuICAgIHI6IGEuclxuICB9O1xufVxuXG5mdW5jdGlvbiBlbmNsb3NlMihhLCBiKSB7XG4gIHZhciB4MSA9IGEueCwgeTEgPSBhLnksIHIxID0gYS5yLFxuICAgICAgeDIgPSBiLngsIHkyID0gYi55LCByMiA9IGIucixcbiAgICAgIHgyMSA9IHgyIC0geDEsIHkyMSA9IHkyIC0geTEsIHIyMSA9IHIyIC0gcjEsXG4gICAgICBsID0gTWF0aC5zcXJ0KHgyMSAqIHgyMSArIHkyMSAqIHkyMSk7XG4gIHJldHVybiB7XG4gICAgeDogKHgxICsgeDIgKyB4MjEgLyBsICogcjIxKSAvIDIsXG4gICAgeTogKHkxICsgeTIgKyB5MjEgLyBsICogcjIxKSAvIDIsXG4gICAgcjogKGwgKyByMSArIHIyKSAvIDJcbiAgfTtcbn1cblxuZnVuY3Rpb24gZW5jbG9zZTMoYSwgYiwgYykge1xuICB2YXIgeDEgPSBhLngsIHkxID0gYS55LCByMSA9IGEucixcbiAgICAgIHgyID0gYi54LCB5MiA9IGIueSwgcjIgPSBiLnIsXG4gICAgICB4MyA9IGMueCwgeTMgPSBjLnksIHIzID0gYy5yLFxuICAgICAgYTIgPSAyICogKHgxIC0geDIpLFxuICAgICAgYjIgPSAyICogKHkxIC0geTIpLFxuICAgICAgYzIgPSAyICogKHIyIC0gcjEpLFxuICAgICAgZDIgPSB4MSAqIHgxICsgeTEgKiB5MSAtIHIxICogcjEgLSB4MiAqIHgyIC0geTIgKiB5MiArIHIyICogcjIsXG4gICAgICBhMyA9IDIgKiAoeDEgLSB4MyksXG4gICAgICBiMyA9IDIgKiAoeTEgLSB5MyksXG4gICAgICBjMyA9IDIgKiAocjMgLSByMSksXG4gICAgICBkMyA9IHgxICogeDEgKyB5MSAqIHkxIC0gcjEgKiByMSAtIHgzICogeDMgLSB5MyAqIHkzICsgcjMgKiByMyxcbiAgICAgIGFiID0gYTMgKiBiMiAtIGEyICogYjMsXG4gICAgICB4YSA9IChiMiAqIGQzIC0gYjMgKiBkMikgLyBhYiAtIHgxLFxuICAgICAgeGIgPSAoYjMgKiBjMiAtIGIyICogYzMpIC8gYWIsXG4gICAgICB5YSA9IChhMyAqIGQyIC0gYTIgKiBkMykgLyBhYiAtIHkxLFxuICAgICAgeWIgPSAoYTIgKiBjMyAtIGEzICogYzIpIC8gYWIsXG4gICAgICBBID0geGIgKiB4YiArIHliICogeWIgLSAxLFxuICAgICAgQiA9IDIgKiAoeGEgKiB4YiArIHlhICogeWIgKyByMSksXG4gICAgICBDID0geGEgKiB4YSArIHlhICogeWEgLSByMSAqIHIxLFxuICAgICAgciA9ICgtQiAtIE1hdGguc3FydChCICogQiAtIDQgKiBBICogQykpIC8gKDIgKiBBKTtcbiAgcmV0dXJuIHtcbiAgICB4OiB4YSArIHhiICogciArIHgxLFxuICAgIHk6IHlhICsgeWIgKiByICsgeTEsXG4gICAgcjogclxuICB9O1xufVxuXG5mdW5jdGlvbiBwbGFjZShhLCBiLCBjKSB7XG4gIHZhciBheCA9IGEueCxcbiAgICAgIGF5ID0gYS55LFxuICAgICAgZGEgPSBiLnIgKyBjLnIsXG4gICAgICBkYiA9IGEuciArIGMucixcbiAgICAgIGR4ID0gYi54IC0gYXgsXG4gICAgICBkeSA9IGIueSAtIGF5LFxuICAgICAgZGMgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgaWYgKGRjKSB7XG4gICAgdmFyIHggPSAwLjUgKyAoKGRiICo9IGRiKSAtIChkYSAqPSBkYSkpIC8gKDIgKiBkYyksXG4gICAgICAgIHkgPSBNYXRoLnNxcnQoTWF0aC5tYXgoMCwgMiAqIGRhICogKGRiICsgZGMpIC0gKGRiIC09IGRjKSAqIGRiIC0gZGEgKiBkYSkpIC8gKDIgKiBkYyk7XG4gICAgYy54ID0gYXggKyB4ICogZHggKyB5ICogZHk7XG4gICAgYy55ID0gYXkgKyB4ICogZHkgLSB5ICogZHg7XG4gIH0gZWxzZSB7XG4gICAgYy54ID0gYXggKyBkYjtcbiAgICBjLnkgPSBheTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnRlcnNlY3RzKGEsIGIpIHtcbiAgdmFyIGR4ID0gYi54IC0gYS54LFxuICAgICAgZHkgPSBiLnkgLSBhLnksXG4gICAgICBkciA9IGEuciArIGIucjtcbiAgcmV0dXJuIGRyICogZHIgLSAxZS02ID4gZHggKiBkeCArIGR5ICogZHk7XG59XG5cbmZ1bmN0aW9uIGRpc3RhbmNlMihub2RlLCB4LCB5KSB7XG4gIHZhciBhID0gbm9kZS5fLFxuICAgICAgYiA9IG5vZGUubmV4dC5fLFxuICAgICAgYWIgPSBhLnIgKyBiLnIsXG4gICAgICBkeCA9IChhLnggKiBiLnIgKyBiLnggKiBhLnIpIC8gYWIgLSB4LFxuICAgICAgZHkgPSAoYS55ICogYi5yICsgYi55ICogYS5yKSAvIGFiIC0geTtcbiAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5O1xufVxuXG5mdW5jdGlvbiBOb2RlJDEoY2lyY2xlKSB7XG4gIHRoaXMuXyA9IGNpcmNsZTtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbiAgdGhpcy5wcmV2aW91cyA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIHBhY2tFbmNsb3NlKGNpcmNsZXMpIHtcbiAgaWYgKCEobiA9IGNpcmNsZXMubGVuZ3RoKSkgcmV0dXJuIDA7XG5cbiAgdmFyIGEsIGIsIGMsIG47XG5cbiAgLy8gUGxhY2UgdGhlIGZpcnN0IGNpcmNsZS5cbiAgYSA9IGNpcmNsZXNbMF0sIGEueCA9IDAsIGEueSA9IDA7XG4gIGlmICghKG4gPiAxKSkgcmV0dXJuIGEucjtcblxuICAvLyBQbGFjZSB0aGUgc2Vjb25kIGNpcmNsZS5cbiAgYiA9IGNpcmNsZXNbMV0sIGEueCA9IC1iLnIsIGIueCA9IGEuciwgYi55ID0gMDtcbiAgaWYgKCEobiA+IDIpKSByZXR1cm4gYS5yICsgYi5yO1xuXG4gIC8vIFBsYWNlIHRoZSB0aGlyZCBjaXJjbGUuXG4gIHBsYWNlKGIsIGEsIGMgPSBjaXJjbGVzWzJdKTtcblxuICAvLyBJbml0aWFsaXplIHRoZSB3ZWlnaHRlZCBjZW50cm9pZC5cbiAgdmFyIGFhID0gYS5yICogYS5yLFxuICAgICAgYmEgPSBiLnIgKiBiLnIsXG4gICAgICBjYSA9IGMuciAqIGMucixcbiAgICAgIG9hID0gYWEgKyBiYSArIGNhLFxuICAgICAgb3ggPSBhYSAqIGEueCArIGJhICogYi54ICsgY2EgKiBjLngsXG4gICAgICBveSA9IGFhICogYS55ICsgYmEgKiBiLnkgKyBjYSAqIGMueSxcbiAgICAgIGN4LCBjeSwgaSwgaiwgaywgc2osIHNrO1xuXG4gIC8vIEluaXRpYWxpemUgdGhlIGZyb250LWNoYWluIHVzaW5nIHRoZSBmaXJzdCB0aHJlZSBjaXJjbGVzIGEsIGIgYW5kIGMuXG4gIGEgPSBuZXcgTm9kZSQxKGEpLCBiID0gbmV3IE5vZGUkMShiKSwgYyA9IG5ldyBOb2RlJDEoYyk7XG4gIGEubmV4dCA9IGMucHJldmlvdXMgPSBiO1xuICBiLm5leHQgPSBhLnByZXZpb3VzID0gYztcbiAgYy5uZXh0ID0gYi5wcmV2aW91cyA9IGE7XG5cbiAgLy8gQXR0ZW1wdCB0byBwbGFjZSBlYWNoIHJlbWFpbmluZyBjaXJjbGXigKZcbiAgcGFjazogZm9yIChpID0gMzsgaSA8IG47ICsraSkge1xuICAgIHBsYWNlKGEuXywgYi5fLCBjID0gY2lyY2xlc1tpXSksIGMgPSBuZXcgTm9kZSQxKGMpO1xuXG4gICAgLy8gRmluZCB0aGUgY2xvc2VzdCBpbnRlcnNlY3RpbmcgY2lyY2xlIG9uIHRoZSBmcm9udC1jaGFpbiwgaWYgYW55LlxuICAgIC8vIOKAnENsb3NlbmVzc+KAnSBpcyBkZXRlcm1pbmVkIGJ5IGxpbmVhciBkaXN0YW5jZSBhbG9uZyB0aGUgZnJvbnQtY2hhaW4uXG4gICAgLy8g4oCcQWhlYWTigJ0gb3Ig4oCcYmVoaW5k4oCdIGlzIGxpa2V3aXNlIGRldGVybWluZWQgYnkgbGluZWFyIGRpc3RhbmNlLlxuICAgIGogPSBiLm5leHQsIGsgPSBhLnByZXZpb3VzLCBzaiA9IGIuXy5yLCBzayA9IGEuXy5yO1xuICAgIGRvIHtcbiAgICAgIGlmIChzaiA8PSBzaykge1xuICAgICAgICBpZiAoaW50ZXJzZWN0cyhqLl8sIGMuXykpIHtcbiAgICAgICAgICBiID0gaiwgYS5uZXh0ID0gYiwgYi5wcmV2aW91cyA9IGEsIC0taTtcbiAgICAgICAgICBjb250aW51ZSBwYWNrO1xuICAgICAgICB9XG4gICAgICAgIHNqICs9IGouXy5yLCBqID0gai5uZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGludGVyc2VjdHMoay5fLCBjLl8pKSB7XG4gICAgICAgICAgYSA9IGssIGEubmV4dCA9IGIsIGIucHJldmlvdXMgPSBhLCAtLWk7XG4gICAgICAgICAgY29udGludWUgcGFjaztcbiAgICAgICAgfVxuICAgICAgICBzayArPSBrLl8uciwgayA9IGsucHJldmlvdXM7XG4gICAgICB9XG4gICAgfSB3aGlsZSAoaiAhPT0gay5uZXh0KTtcblxuICAgIC8vIFN1Y2Nlc3MhIEluc2VydCB0aGUgbmV3IGNpcmNsZSBjIGJldHdlZW4gYSBhbmQgYi5cbiAgICBjLnByZXZpb3VzID0gYSwgYy5uZXh0ID0gYiwgYS5uZXh0ID0gYi5wcmV2aW91cyA9IGIgPSBjO1xuXG4gICAgLy8gVXBkYXRlIHRoZSB3ZWlnaHRlZCBjZW50cm9pZC5cbiAgICBvYSArPSBjYSA9IGMuXy5yICogYy5fLnI7XG4gICAgb3ggKz0gY2EgKiBjLl8ueDtcbiAgICBveSArPSBjYSAqIGMuXy55O1xuXG4gICAgLy8gQ29tcHV0ZSB0aGUgbmV3IGNsb3Nlc3QgY2lyY2xlIHBhaXIgdG8gdGhlIGNlbnRyb2lkLlxuICAgIGFhID0gZGlzdGFuY2UyKGEsIGN4ID0gb3ggLyBvYSwgY3kgPSBveSAvIG9hKTtcbiAgICB3aGlsZSAoKGMgPSBjLm5leHQpICE9PSBiKSB7XG4gICAgICBpZiAoKGNhID0gZGlzdGFuY2UyKGMsIGN4LCBjeSkpIDwgYWEpIHtcbiAgICAgICAgYSA9IGMsIGFhID0gY2E7XG4gICAgICB9XG4gICAgfVxuICAgIGIgPSBhLm5leHQ7XG4gIH1cblxuICAvLyBDb21wdXRlIHRoZSBlbmNsb3NpbmcgY2lyY2xlIG9mIHRoZSBmcm9udCBjaGFpbi5cbiAgYSA9IFtiLl9dLCBjID0gYjsgd2hpbGUgKChjID0gYy5uZXh0KSAhPT0gYikgYS5wdXNoKGMuXyk7IGMgPSBlbmNsb3NlKGEpO1xuXG4gIC8vIFRyYW5zbGF0ZSB0aGUgY2lyY2xlcyB0byBwdXQgdGhlIGVuY2xvc2luZyBjaXJjbGUgYXJvdW5kIHRoZSBvcmlnaW4uXG4gIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIGEgPSBjaXJjbGVzW2ldLCBhLnggLT0gYy54LCBhLnkgLT0gYy55O1xuXG4gIHJldHVybiBjLnI7XG59XG5cbnZhciBzaWJsaW5ncyA9IGZ1bmN0aW9uKGNpcmNsZXMpIHtcbiAgcGFja0VuY2xvc2UoY2lyY2xlcyk7XG4gIHJldHVybiBjaXJjbGVzO1xufTtcblxuZnVuY3Rpb24gb3B0aW9uYWwoZikge1xuICByZXR1cm4gZiA9PSBudWxsID8gbnVsbCA6IHJlcXVpcmVkKGYpO1xufVxuXG5mdW5jdGlvbiByZXF1aXJlZChmKSB7XG4gIGlmICh0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3I7XG4gIHJldHVybiBmO1xufVxuXG5mdW5jdGlvbiBjb25zdGFudFplcm8oKSB7XG4gIHJldHVybiAwO1xufVxuXG52YXIgY29uc3RhbnQkOCA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxuZnVuY3Rpb24gZGVmYXVsdFJhZGl1cyQxKGQpIHtcbiAgcmV0dXJuIE1hdGguc3FydChkLnZhbHVlKTtcbn1cblxudmFyIGluZGV4JDIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHJhZGl1cyA9IG51bGwsXG4gICAgICBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICBwYWRkaW5nID0gY29uc3RhbnRaZXJvO1xuXG4gIGZ1bmN0aW9uIHBhY2socm9vdCkge1xuICAgIHJvb3QueCA9IGR4IC8gMiwgcm9vdC55ID0gZHkgLyAyO1xuICAgIGlmIChyYWRpdXMpIHtcbiAgICAgIHJvb3QuZWFjaEJlZm9yZShyYWRpdXNMZWFmKHJhZGl1cykpXG4gICAgICAgICAgLmVhY2hBZnRlcihwYWNrQ2hpbGRyZW4ocGFkZGluZywgMC41KSlcbiAgICAgICAgICAuZWFjaEJlZm9yZSh0cmFuc2xhdGVDaGlsZCgxKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJvb3QuZWFjaEJlZm9yZShyYWRpdXNMZWFmKGRlZmF1bHRSYWRpdXMkMSkpXG4gICAgICAgICAgLmVhY2hBZnRlcihwYWNrQ2hpbGRyZW4oY29uc3RhbnRaZXJvLCAxKSlcbiAgICAgICAgICAuZWFjaEFmdGVyKHBhY2tDaGlsZHJlbihwYWRkaW5nLCByb290LnIgLyBNYXRoLm1pbihkeCwgZHkpKSlcbiAgICAgICAgICAuZWFjaEJlZm9yZSh0cmFuc2xhdGVDaGlsZChNYXRoLm1pbihkeCwgZHkpIC8gKDIgKiByb290LnIpKSk7XG4gICAgfVxuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgcGFjay5yYWRpdXMgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFkaXVzID0gb3B0aW9uYWwoeCksIHBhY2spIDogcmFkaXVzO1xuICB9O1xuXG4gIHBhY2suc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCBwYWNrKSA6IFtkeCwgZHldO1xuICB9O1xuXG4gIHBhY2sucGFkZGluZyA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiBjb25zdGFudCQ4KCt4KSwgcGFjaykgOiBwYWRkaW5nO1xuICB9O1xuXG4gIHJldHVybiBwYWNrO1xufTtcblxuZnVuY3Rpb24gcmFkaXVzTGVhZihyYWRpdXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIG5vZGUuciA9IE1hdGgubWF4KDAsICtyYWRpdXMobm9kZSkgfHwgMCk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBwYWNrQ2hpbGRyZW4ocGFkZGluZywgaykge1xuICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgIGlmIChjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIHZhciBjaGlsZHJlbixcbiAgICAgICAgICBpLFxuICAgICAgICAgIG4gPSBjaGlsZHJlbi5sZW5ndGgsXG4gICAgICAgICAgciA9IHBhZGRpbmcobm9kZSkgKiBrIHx8IDAsXG4gICAgICAgICAgZTtcblxuICAgICAgaWYgKHIpIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIGNoaWxkcmVuW2ldLnIgKz0gcjtcbiAgICAgIGUgPSBwYWNrRW5jbG9zZShjaGlsZHJlbik7XG4gICAgICBpZiAocikgZm9yIChpID0gMDsgaSA8IG47ICsraSkgY2hpbGRyZW5baV0uciAtPSByO1xuICAgICAgbm9kZS5yID0gZSArIHI7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiB0cmFuc2xhdGVDaGlsZChrKSB7XG4gIHJldHVybiBmdW5jdGlvbihub2RlKSB7XG4gICAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50O1xuICAgIG5vZGUuciAqPSBrO1xuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgIG5vZGUueCA9IHBhcmVudC54ICsgayAqIG5vZGUueDtcbiAgICAgIG5vZGUueSA9IHBhcmVudC55ICsgayAqIG5vZGUueTtcbiAgICB9XG4gIH07XG59XG5cbnZhciByb3VuZE5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gIG5vZGUueDAgPSBNYXRoLnJvdW5kKG5vZGUueDApO1xuICBub2RlLnkwID0gTWF0aC5yb3VuZChub2RlLnkwKTtcbiAgbm9kZS54MSA9IE1hdGgucm91bmQobm9kZS54MSk7XG4gIG5vZGUueTEgPSBNYXRoLnJvdW5kKG5vZGUueTEpO1xufTtcblxudmFyIHRyZWVtYXBEaWNlID0gZnVuY3Rpb24ocGFyZW50LCB4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgbm9kZXMgPSBwYXJlbnQuY2hpbGRyZW4sXG4gICAgICBub2RlLFxuICAgICAgaSA9IC0xLFxuICAgICAgbiA9IG5vZGVzLmxlbmd0aCxcbiAgICAgIGsgPSBwYXJlbnQudmFsdWUgJiYgKHgxIC0geDApIC8gcGFyZW50LnZhbHVlO1xuXG4gIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgbm9kZSA9IG5vZGVzW2ldLCBub2RlLnkwID0geTAsIG5vZGUueTEgPSB5MTtcbiAgICBub2RlLngwID0geDAsIG5vZGUueDEgPSB4MCArPSBub2RlLnZhbHVlICogaztcbiAgfVxufTtcblxudmFyIHBhcnRpdGlvbiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZHggPSAxLFxuICAgICAgZHkgPSAxLFxuICAgICAgcGFkZGluZyA9IDAsXG4gICAgICByb3VuZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIHBhcnRpdGlvbihyb290KSB7XG4gICAgdmFyIG4gPSByb290LmhlaWdodCArIDE7XG4gICAgcm9vdC54MCA9XG4gICAgcm9vdC55MCA9IHBhZGRpbmc7XG4gICAgcm9vdC54MSA9IGR4O1xuICAgIHJvb3QueTEgPSBkeSAvIG47XG4gICAgcm9vdC5lYWNoQmVmb3JlKHBvc2l0aW9uTm9kZShkeSwgbikpO1xuICAgIGlmIChyb3VuZCkgcm9vdC5lYWNoQmVmb3JlKHJvdW5kTm9kZSk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH1cblxuICBmdW5jdGlvbiBwb3NpdGlvbk5vZGUoZHksIG4pIHtcbiAgICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgdHJlZW1hcERpY2Uobm9kZSwgbm9kZS54MCwgZHkgKiAobm9kZS5kZXB0aCArIDEpIC8gbiwgbm9kZS54MSwgZHkgKiAobm9kZS5kZXB0aCArIDIpIC8gbik7XG4gICAgICB9XG4gICAgICB2YXIgeDAgPSBub2RlLngwLFxuICAgICAgICAgIHkwID0gbm9kZS55MCxcbiAgICAgICAgICB4MSA9IG5vZGUueDEgLSBwYWRkaW5nLFxuICAgICAgICAgIHkxID0gbm9kZS55MSAtIHBhZGRpbmc7XG4gICAgICBpZiAoeDEgPCB4MCkgeDAgPSB4MSA9ICh4MCArIHgxKSAvIDI7XG4gICAgICBpZiAoeTEgPCB5MCkgeTAgPSB5MSA9ICh5MCArIHkxKSAvIDI7XG4gICAgICBub2RlLngwID0geDA7XG4gICAgICBub2RlLnkwID0geTA7XG4gICAgICBub2RlLngxID0geDE7XG4gICAgICBub2RlLnkxID0geTE7XG4gICAgfTtcbiAgfVxuXG4gIHBhcnRpdGlvbi5yb3VuZCA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyb3VuZCA9ICEheCwgcGFydGl0aW9uKSA6IHJvdW5kO1xuICB9O1xuXG4gIHBhcnRpdGlvbi5zaXplID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIHBhcnRpdGlvbikgOiBbZHgsIGR5XTtcbiAgfTtcblxuICBwYXJ0aXRpb24ucGFkZGluZyA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nID0gK3gsIHBhcnRpdGlvbikgOiBwYWRkaW5nO1xuICB9O1xuXG4gIHJldHVybiBwYXJ0aXRpb247XG59O1xuXG52YXIga2V5UHJlZml4JDEgPSBcIiRcIjtcbnZhciBwcmVyb290ID0ge2RlcHRoOiAtMX07XG52YXIgYW1iaWd1b3VzID0ge307XG5cbmZ1bmN0aW9uIGRlZmF1bHRJZChkKSB7XG4gIHJldHVybiBkLmlkO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0UGFyZW50SWQoZCkge1xuICByZXR1cm4gZC5wYXJlbnRJZDtcbn1cblxudmFyIHN0cmF0aWZ5ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBpZCA9IGRlZmF1bHRJZCxcbiAgICAgIHBhcmVudElkID0gZGVmYXVsdFBhcmVudElkO1xuXG4gIGZ1bmN0aW9uIHN0cmF0aWZ5KGRhdGEpIHtcbiAgICB2YXIgZCxcbiAgICAgICAgaSxcbiAgICAgICAgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgICByb290LFxuICAgICAgICBwYXJlbnQsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIG5vZGVzID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBub2RlSWQsXG4gICAgICAgIG5vZGVLZXksXG4gICAgICAgIG5vZGVCeUtleSA9IHt9O1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgZCA9IGRhdGFbaV0sIG5vZGUgPSBub2Rlc1tpXSA9IG5ldyBOb2RlKGQpO1xuICAgICAgaWYgKChub2RlSWQgPSBpZChkLCBpLCBkYXRhKSkgIT0gbnVsbCAmJiAobm9kZUlkICs9IFwiXCIpKSB7XG4gICAgICAgIG5vZGVLZXkgPSBrZXlQcmVmaXgkMSArIChub2RlLmlkID0gbm9kZUlkKTtcbiAgICAgICAgbm9kZUJ5S2V5W25vZGVLZXldID0gbm9kZUtleSBpbiBub2RlQnlLZXkgPyBhbWJpZ3VvdXMgOiBub2RlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZUlkID0gcGFyZW50SWQoZGF0YVtpXSwgaSwgZGF0YSk7XG4gICAgICBpZiAobm9kZUlkID09IG51bGwgfHwgIShub2RlSWQgKz0gXCJcIikpIHtcbiAgICAgICAgaWYgKHJvb3QpIHRocm93IG5ldyBFcnJvcihcIm11bHRpcGxlIHJvb3RzXCIpO1xuICAgICAgICByb290ID0gbm9kZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmVudCA9IG5vZGVCeUtleVtrZXlQcmVmaXgkMSArIG5vZGVJZF07XG4gICAgICAgIGlmICghcGFyZW50KSB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nOiBcIiArIG5vZGVJZCk7XG4gICAgICAgIGlmIChwYXJlbnQgPT09IGFtYmlndW91cykgdGhyb3cgbmV3IEVycm9yKFwiYW1iaWd1b3VzOiBcIiArIG5vZGVJZCk7XG4gICAgICAgIGlmIChwYXJlbnQuY2hpbGRyZW4pIHBhcmVudC5jaGlsZHJlbi5wdXNoKG5vZGUpO1xuICAgICAgICBlbHNlIHBhcmVudC5jaGlsZHJlbiA9IFtub2RlXTtcbiAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFyb290KSB0aHJvdyBuZXcgRXJyb3IoXCJubyByb290XCIpO1xuICAgIHJvb3QucGFyZW50ID0gcHJlcm9vdDtcbiAgICByb290LmVhY2hCZWZvcmUoZnVuY3Rpb24obm9kZSkgeyBub2RlLmRlcHRoID0gbm9kZS5wYXJlbnQuZGVwdGggKyAxOyAtLW47IH0pLmVhY2hCZWZvcmUoY29tcHV0ZUhlaWdodCk7XG4gICAgcm9vdC5wYXJlbnQgPSBudWxsO1xuICAgIGlmIChuID4gMCkgdGhyb3cgbmV3IEVycm9yKFwiY3ljbGVcIik7XG5cbiAgICByZXR1cm4gcm9vdDtcbiAgfVxuXG4gIHN0cmF0aWZ5LmlkID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGlkID0gcmVxdWlyZWQoeCksIHN0cmF0aWZ5KSA6IGlkO1xuICB9O1xuXG4gIHN0cmF0aWZ5LnBhcmVudElkID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhcmVudElkID0gcmVxdWlyZWQoeCksIHN0cmF0aWZ5KSA6IHBhcmVudElkO1xuICB9O1xuXG4gIHJldHVybiBzdHJhdGlmeTtcbn07XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXBhcmF0aW9uJDEoYSwgYikge1xuICByZXR1cm4gYS5wYXJlbnQgPT09IGIucGFyZW50ID8gMSA6IDI7XG59XG5cbi8vIGZ1bmN0aW9uIHJhZGlhbFNlcGFyYXRpb24oYSwgYikge1xuLy8gICByZXR1cm4gKGEucGFyZW50ID09PSBiLnBhcmVudCA/IDEgOiAyKSAvIGEuZGVwdGg7XG4vLyB9XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byB0cmF2ZXJzZSB0aGUgbGVmdCBjb250b3VyIG9mIGEgc3VidHJlZSAob3Jcbi8vIHN1YmZvcmVzdCkuIEl0IHJldHVybnMgdGhlIHN1Y2Nlc3NvciBvZiB2IG9uIHRoaXMgY29udG91ci4gVGhpcyBzdWNjZXNzb3IgaXNcbi8vIGVpdGhlciBnaXZlbiBieSB0aGUgbGVmdG1vc3QgY2hpbGQgb2YgdiBvciBieSB0aGUgdGhyZWFkIG9mIHYuIFRoZSBmdW5jdGlvblxuLy8gcmV0dXJucyBudWxsIGlmIGFuZCBvbmx5IGlmIHYgaXMgb24gdGhlIGhpZ2hlc3QgbGV2ZWwgb2YgaXRzIHN1YnRyZWUuXG5mdW5jdGlvbiBuZXh0TGVmdCh2KSB7XG4gIHZhciBjaGlsZHJlbiA9IHYuY2hpbGRyZW47XG4gIHJldHVybiBjaGlsZHJlbiA/IGNoaWxkcmVuWzBdIDogdi50O1xufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIHdvcmtzIGFuYWxvZ291c2x5IHRvIG5leHRMZWZ0LlxuZnVuY3Rpb24gbmV4dFJpZ2h0KHYpIHtcbiAgdmFyIGNoaWxkcmVuID0gdi5jaGlsZHJlbjtcbiAgcmV0dXJuIGNoaWxkcmVuID8gY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoIC0gMV0gOiB2LnQ7XG59XG5cbi8vIFNoaWZ0cyB0aGUgY3VycmVudCBzdWJ0cmVlIHJvb3RlZCBhdCB3Ky4gVGhpcyBpcyBkb25lIGJ5IGluY3JlYXNpbmdcbi8vIHByZWxpbSh3KykgYW5kIG1vZCh3KykgYnkgc2hpZnQuXG5mdW5jdGlvbiBtb3ZlU3VidHJlZSh3bSwgd3AsIHNoaWZ0KSB7XG4gIHZhciBjaGFuZ2UgPSBzaGlmdCAvICh3cC5pIC0gd20uaSk7XG4gIHdwLmMgLT0gY2hhbmdlO1xuICB3cC5zICs9IHNoaWZ0O1xuICB3bS5jICs9IGNoYW5nZTtcbiAgd3AueiArPSBzaGlmdDtcbiAgd3AubSArPSBzaGlmdDtcbn1cblxuLy8gQWxsIG90aGVyIHNoaWZ0cywgYXBwbGllZCB0byB0aGUgc21hbGxlciBzdWJ0cmVlcyBiZXR3ZWVuIHctIGFuZCB3KywgYXJlXG4vLyBwZXJmb3JtZWQgYnkgdGhpcyBmdW5jdGlvbi4gVG8gcHJlcGFyZSB0aGUgc2hpZnRzLCB3ZSBoYXZlIHRvIGFkanVzdFxuLy8gY2hhbmdlKHcrKSwgc2hpZnQodyspLCBhbmQgY2hhbmdlKHctKS5cbmZ1bmN0aW9uIGV4ZWN1dGVTaGlmdHModikge1xuICB2YXIgc2hpZnQgPSAwLFxuICAgICAgY2hhbmdlID0gMCxcbiAgICAgIGNoaWxkcmVuID0gdi5jaGlsZHJlbixcbiAgICAgIGkgPSBjaGlsZHJlbi5sZW5ndGgsXG4gICAgICB3O1xuICB3aGlsZSAoLS1pID49IDApIHtcbiAgICB3ID0gY2hpbGRyZW5baV07XG4gICAgdy56ICs9IHNoaWZ0O1xuICAgIHcubSArPSBzaGlmdDtcbiAgICBzaGlmdCArPSB3LnMgKyAoY2hhbmdlICs9IHcuYyk7XG4gIH1cbn1cblxuLy8gSWYgdmkt4oCZcyBhbmNlc3RvciBpcyBhIHNpYmxpbmcgb2YgdiwgcmV0dXJucyB2aS3igJlzIGFuY2VzdG9yLiBPdGhlcndpc2UsXG4vLyByZXR1cm5zIHRoZSBzcGVjaWZpZWQgKGRlZmF1bHQpIGFuY2VzdG9yLlxuZnVuY3Rpb24gbmV4dEFuY2VzdG9yKHZpbSwgdiwgYW5jZXN0b3IpIHtcbiAgcmV0dXJuIHZpbS5hLnBhcmVudCA9PT0gdi5wYXJlbnQgPyB2aW0uYSA6IGFuY2VzdG9yO1xufVxuXG5mdW5jdGlvbiBUcmVlTm9kZShub2RlLCBpKSB7XG4gIHRoaXMuXyA9IG5vZGU7XG4gIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgdGhpcy5jaGlsZHJlbiA9IG51bGw7XG4gIHRoaXMuQSA9IG51bGw7IC8vIGRlZmF1bHQgYW5jZXN0b3JcbiAgdGhpcy5hID0gdGhpczsgLy8gYW5jZXN0b3JcbiAgdGhpcy56ID0gMDsgLy8gcHJlbGltXG4gIHRoaXMubSA9IDA7IC8vIG1vZFxuICB0aGlzLmMgPSAwOyAvLyBjaGFuZ2VcbiAgdGhpcy5zID0gMDsgLy8gc2hpZnRcbiAgdGhpcy50ID0gbnVsbDsgLy8gdGhyZWFkXG4gIHRoaXMuaSA9IGk7IC8vIG51bWJlclxufVxuXG5UcmVlTm9kZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKE5vZGUucHJvdG90eXBlKTtcblxuZnVuY3Rpb24gdHJlZVJvb3Qocm9vdCkge1xuICB2YXIgdHJlZSA9IG5ldyBUcmVlTm9kZShyb290LCAwKSxcbiAgICAgIG5vZGUsXG4gICAgICBub2RlcyA9IFt0cmVlXSxcbiAgICAgIGNoaWxkLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBpLFxuICAgICAgbjtcblxuICB3aGlsZSAobm9kZSA9IG5vZGVzLnBvcCgpKSB7XG4gICAgaWYgKGNoaWxkcmVuID0gbm9kZS5fLmNoaWxkcmVuKSB7XG4gICAgICBub2RlLmNoaWxkcmVuID0gbmV3IEFycmF5KG4gPSBjaGlsZHJlbi5sZW5ndGgpO1xuICAgICAgZm9yIChpID0gbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIG5vZGVzLnB1c2goY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldID0gbmV3IFRyZWVOb2RlKGNoaWxkcmVuW2ldLCBpKSk7XG4gICAgICAgIGNoaWxkLnBhcmVudCA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgKHRyZWUucGFyZW50ID0gbmV3IFRyZWVOb2RlKG51bGwsIDApKS5jaGlsZHJlbiA9IFt0cmVlXTtcbiAgcmV0dXJuIHRyZWU7XG59XG5cbi8vIE5vZGUtbGluayB0cmVlIGRpYWdyYW0gdXNpbmcgdGhlIFJlaW5nb2xkLVRpbGZvcmQgXCJ0aWR5XCIgYWxnb3JpdGhtXG52YXIgdHJlZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VwYXJhdGlvbiA9IGRlZmF1bHRTZXBhcmF0aW9uJDEsXG4gICAgICBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICBub2RlU2l6ZSA9IG51bGw7XG5cbiAgZnVuY3Rpb24gdHJlZShyb290KSB7XG4gICAgdmFyIHQgPSB0cmVlUm9vdChyb290KTtcblxuICAgIC8vIENvbXB1dGUgdGhlIGxheW91dCB1c2luZyBCdWNoaGVpbSBldCBhbC7igJlzIGFsZ29yaXRobS5cbiAgICB0LmVhY2hBZnRlcihmaXJzdFdhbGspLCB0LnBhcmVudC5tID0gLXQuejtcbiAgICB0LmVhY2hCZWZvcmUoc2Vjb25kV2Fsayk7XG5cbiAgICAvLyBJZiBhIGZpeGVkIG5vZGUgc2l6ZSBpcyBzcGVjaWZpZWQsIHNjYWxlIHggYW5kIHkuXG4gICAgaWYgKG5vZGVTaXplKSByb290LmVhY2hCZWZvcmUoc2l6ZU5vZGUpO1xuXG4gICAgLy8gSWYgYSBmaXhlZCB0cmVlIHNpemUgaXMgc3BlY2lmaWVkLCBzY2FsZSB4IGFuZCB5IGJhc2VkIG9uIHRoZSBleHRlbnQuXG4gICAgLy8gQ29tcHV0ZSB0aGUgbGVmdC1tb3N0LCByaWdodC1tb3N0LCBhbmQgZGVwdGgtbW9zdCBub2RlcyBmb3IgZXh0ZW50cy5cbiAgICBlbHNlIHtcbiAgICAgIHZhciBsZWZ0ID0gcm9vdCxcbiAgICAgICAgICByaWdodCA9IHJvb3QsXG4gICAgICAgICAgYm90dG9tID0gcm9vdDtcbiAgICAgIHJvb3QuZWFjaEJlZm9yZShmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIGlmIChub2RlLnggPCBsZWZ0LngpIGxlZnQgPSBub2RlO1xuICAgICAgICBpZiAobm9kZS54ID4gcmlnaHQueCkgcmlnaHQgPSBub2RlO1xuICAgICAgICBpZiAobm9kZS5kZXB0aCA+IGJvdHRvbS5kZXB0aCkgYm90dG9tID0gbm9kZTtcbiAgICAgIH0pO1xuICAgICAgdmFyIHMgPSBsZWZ0ID09PSByaWdodCA/IDEgOiBzZXBhcmF0aW9uKGxlZnQsIHJpZ2h0KSAvIDIsXG4gICAgICAgICAgdHggPSBzIC0gbGVmdC54LFxuICAgICAgICAgIGt4ID0gZHggLyAocmlnaHQueCArIHMgKyB0eCksXG4gICAgICAgICAga3kgPSBkeSAvIChib3R0b20uZGVwdGggfHwgMSk7XG4gICAgICByb290LmVhY2hCZWZvcmUoZnVuY3Rpb24obm9kZSkge1xuICAgICAgICBub2RlLnggPSAobm9kZS54ICsgdHgpICoga3g7XG4gICAgICAgIG5vZGUueSA9IG5vZGUuZGVwdGggKiBreTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgLy8gQ29tcHV0ZXMgYSBwcmVsaW1pbmFyeSB4LWNvb3JkaW5hdGUgZm9yIHYuIEJlZm9yZSB0aGF0LCBGSVJTVCBXQUxLIGlzXG4gIC8vIGFwcGxpZWQgcmVjdXJzaXZlbHkgdG8gdGhlIGNoaWxkcmVuIG9mIHYsIGFzIHdlbGwgYXMgdGhlIGZ1bmN0aW9uXG4gIC8vIEFQUE9SVElPTi4gQWZ0ZXIgc3BhY2luZyBvdXQgdGhlIGNoaWxkcmVuIGJ5IGNhbGxpbmcgRVhFQ1VURSBTSElGVFMsIHRoZVxuICAvLyBub2RlIHYgaXMgcGxhY2VkIHRvIHRoZSBtaWRwb2ludCBvZiBpdHMgb3V0ZXJtb3N0IGNoaWxkcmVuLlxuICBmdW5jdGlvbiBmaXJzdFdhbGsodikge1xuICAgIHZhciBjaGlsZHJlbiA9IHYuY2hpbGRyZW4sXG4gICAgICAgIHNpYmxpbmdzID0gdi5wYXJlbnQuY2hpbGRyZW4sXG4gICAgICAgIHcgPSB2LmkgPyBzaWJsaW5nc1t2LmkgLSAxXSA6IG51bGw7XG4gICAgaWYgKGNoaWxkcmVuKSB7XG4gICAgICBleGVjdXRlU2hpZnRzKHYpO1xuICAgICAgdmFyIG1pZHBvaW50ID0gKGNoaWxkcmVuWzBdLnogKyBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXS56KSAvIDI7XG4gICAgICBpZiAodykge1xuICAgICAgICB2LnogPSB3LnogKyBzZXBhcmF0aW9uKHYuXywgdy5fKTtcbiAgICAgICAgdi5tID0gdi56IC0gbWlkcG9pbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2LnogPSBtaWRwb2ludDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHcpIHtcbiAgICAgIHYueiA9IHcueiArIHNlcGFyYXRpb24odi5fLCB3Ll8pO1xuICAgIH1cbiAgICB2LnBhcmVudC5BID0gYXBwb3J0aW9uKHYsIHcsIHYucGFyZW50LkEgfHwgc2libGluZ3NbMF0pO1xuICB9XG5cbiAgLy8gQ29tcHV0ZXMgYWxsIHJlYWwgeC1jb29yZGluYXRlcyBieSBzdW1taW5nIHVwIHRoZSBtb2RpZmllcnMgcmVjdXJzaXZlbHkuXG4gIGZ1bmN0aW9uIHNlY29uZFdhbGsodikge1xuICAgIHYuXy54ID0gdi56ICsgdi5wYXJlbnQubTtcbiAgICB2Lm0gKz0gdi5wYXJlbnQubTtcbiAgfVxuXG4gIC8vIFRoZSBjb3JlIG9mIHRoZSBhbGdvcml0aG0uIEhlcmUsIGEgbmV3IHN1YnRyZWUgaXMgY29tYmluZWQgd2l0aCB0aGVcbiAgLy8gcHJldmlvdXMgc3VidHJlZXMuIFRocmVhZHMgYXJlIHVzZWQgdG8gdHJhdmVyc2UgdGhlIGluc2lkZSBhbmQgb3V0c2lkZVxuICAvLyBjb250b3VycyBvZiB0aGUgbGVmdCBhbmQgcmlnaHQgc3VidHJlZSB1cCB0byB0aGUgaGlnaGVzdCBjb21tb24gbGV2ZWwuIFRoZVxuICAvLyB2ZXJ0aWNlcyB1c2VkIGZvciB0aGUgdHJhdmVyc2FscyBhcmUgdmkrLCB2aS0sIHZvLSwgYW5kIHZvKywgd2hlcmUgdGhlXG4gIC8vIHN1cGVyc2NyaXB0IG8gbWVhbnMgb3V0c2lkZSBhbmQgaSBtZWFucyBpbnNpZGUsIHRoZSBzdWJzY3JpcHQgLSBtZWFucyBsZWZ0XG4gIC8vIHN1YnRyZWUgYW5kICsgbWVhbnMgcmlnaHQgc3VidHJlZS4gRm9yIHN1bW1pbmcgdXAgdGhlIG1vZGlmaWVycyBhbG9uZyB0aGVcbiAgLy8gY29udG91ciwgd2UgdXNlIHJlc3BlY3RpdmUgdmFyaWFibGVzIHNpKywgc2ktLCBzby0sIGFuZCBzbysuIFdoZW5ldmVyIHR3b1xuICAvLyBub2RlcyBvZiB0aGUgaW5zaWRlIGNvbnRvdXJzIGNvbmZsaWN0LCB3ZSBjb21wdXRlIHRoZSBsZWZ0IG9uZSBvZiB0aGVcbiAgLy8gZ3JlYXRlc3QgdW5jb21tb24gYW5jZXN0b3JzIHVzaW5nIHRoZSBmdW5jdGlvbiBBTkNFU1RPUiBhbmQgY2FsbCBNT1ZFXG4gIC8vIFNVQlRSRUUgdG8gc2hpZnQgdGhlIHN1YnRyZWUgYW5kIHByZXBhcmUgdGhlIHNoaWZ0cyBvZiBzbWFsbGVyIHN1YnRyZWVzLlxuICAvLyBGaW5hbGx5LCB3ZSBhZGQgYSBuZXcgdGhyZWFkIChpZiBuZWNlc3NhcnkpLlxuICBmdW5jdGlvbiBhcHBvcnRpb24odiwgdywgYW5jZXN0b3IpIHtcbiAgICBpZiAodykge1xuICAgICAgdmFyIHZpcCA9IHYsXG4gICAgICAgICAgdm9wID0gdixcbiAgICAgICAgICB2aW0gPSB3LFxuICAgICAgICAgIHZvbSA9IHZpcC5wYXJlbnQuY2hpbGRyZW5bMF0sXG4gICAgICAgICAgc2lwID0gdmlwLm0sXG4gICAgICAgICAgc29wID0gdm9wLm0sXG4gICAgICAgICAgc2ltID0gdmltLm0sXG4gICAgICAgICAgc29tID0gdm9tLm0sXG4gICAgICAgICAgc2hpZnQ7XG4gICAgICB3aGlsZSAodmltID0gbmV4dFJpZ2h0KHZpbSksIHZpcCA9IG5leHRMZWZ0KHZpcCksIHZpbSAmJiB2aXApIHtcbiAgICAgICAgdm9tID0gbmV4dExlZnQodm9tKTtcbiAgICAgICAgdm9wID0gbmV4dFJpZ2h0KHZvcCk7XG4gICAgICAgIHZvcC5hID0gdjtcbiAgICAgICAgc2hpZnQgPSB2aW0ueiArIHNpbSAtIHZpcC56IC0gc2lwICsgc2VwYXJhdGlvbih2aW0uXywgdmlwLl8pO1xuICAgICAgICBpZiAoc2hpZnQgPiAwKSB7XG4gICAgICAgICAgbW92ZVN1YnRyZWUobmV4dEFuY2VzdG9yKHZpbSwgdiwgYW5jZXN0b3IpLCB2LCBzaGlmdCk7XG4gICAgICAgICAgc2lwICs9IHNoaWZ0O1xuICAgICAgICAgIHNvcCArPSBzaGlmdDtcbiAgICAgICAgfVxuICAgICAgICBzaW0gKz0gdmltLm07XG4gICAgICAgIHNpcCArPSB2aXAubTtcbiAgICAgICAgc29tICs9IHZvbS5tO1xuICAgICAgICBzb3AgKz0gdm9wLm07XG4gICAgICB9XG4gICAgICBpZiAodmltICYmICFuZXh0UmlnaHQodm9wKSkge1xuICAgICAgICB2b3AudCA9IHZpbTtcbiAgICAgICAgdm9wLm0gKz0gc2ltIC0gc29wO1xuICAgICAgfVxuICAgICAgaWYgKHZpcCAmJiAhbmV4dExlZnQodm9tKSkge1xuICAgICAgICB2b20udCA9IHZpcDtcbiAgICAgICAgdm9tLm0gKz0gc2lwIC0gc29tO1xuICAgICAgICBhbmNlc3RvciA9IHY7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhbmNlc3RvcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNpemVOb2RlKG5vZGUpIHtcbiAgICBub2RlLnggKj0gZHg7XG4gICAgbm9kZS55ID0gbm9kZS5kZXB0aCAqIGR5O1xuICB9XG5cbiAgdHJlZS5zZXBhcmF0aW9uID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNlcGFyYXRpb24gPSB4LCB0cmVlKSA6IHNlcGFyYXRpb247XG4gIH07XG5cbiAgdHJlZS5zaXplID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG5vZGVTaXplID0gZmFsc2UsIGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIHRyZWUpIDogKG5vZGVTaXplID8gbnVsbCA6IFtkeCwgZHldKTtcbiAgfTtcblxuICB0cmVlLm5vZGVTaXplID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG5vZGVTaXplID0gdHJ1ZSwgZHggPSAreFswXSwgZHkgPSAreFsxXSwgdHJlZSkgOiAobm9kZVNpemUgPyBbZHgsIGR5XSA6IG51bGwpO1xuICB9O1xuXG4gIHJldHVybiB0cmVlO1xufTtcblxudmFyIHRyZWVtYXBTbGljZSA9IGZ1bmN0aW9uKHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgdmFyIG5vZGVzID0gcGFyZW50LmNoaWxkcmVuLFxuICAgICAgbm9kZSxcbiAgICAgIGkgPSAtMSxcbiAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICBrID0gcGFyZW50LnZhbHVlICYmICh5MSAtIHkwKSAvIHBhcmVudC52YWx1ZTtcblxuICB3aGlsZSAoKytpIDwgbikge1xuICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZS54MCA9IHgwLCBub2RlLngxID0geDE7XG4gICAgbm9kZS55MCA9IHkwLCBub2RlLnkxID0geTAgKz0gbm9kZS52YWx1ZSAqIGs7XG4gIH1cbn07XG5cbnZhciBwaGkgPSAoMSArIE1hdGguc3FydCg1KSkgLyAyO1xuXG5mdW5jdGlvbiBzcXVhcmlmeVJhdGlvKHJhdGlvLCBwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciByb3dzID0gW10sXG4gICAgICBub2RlcyA9IHBhcmVudC5jaGlsZHJlbixcbiAgICAgIHJvdyxcbiAgICAgIG5vZGVWYWx1ZSxcbiAgICAgIGkwID0gMCxcbiAgICAgIGkxID0gMCxcbiAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICBkeCwgZHksXG4gICAgICB2YWx1ZSA9IHBhcmVudC52YWx1ZSxcbiAgICAgIHN1bVZhbHVlLFxuICAgICAgbWluVmFsdWUsXG4gICAgICBtYXhWYWx1ZSxcbiAgICAgIG5ld1JhdGlvLFxuICAgICAgbWluUmF0aW8sXG4gICAgICBhbHBoYSxcbiAgICAgIGJldGE7XG5cbiAgd2hpbGUgKGkwIDwgbikge1xuICAgIGR4ID0geDEgLSB4MCwgZHkgPSB5MSAtIHkwO1xuXG4gICAgLy8gRmluZCB0aGUgbmV4dCBub24tZW1wdHkgbm9kZS5cbiAgICBkbyBzdW1WYWx1ZSA9IG5vZGVzW2kxKytdLnZhbHVlOyB3aGlsZSAoIXN1bVZhbHVlICYmIGkxIDwgbik7XG4gICAgbWluVmFsdWUgPSBtYXhWYWx1ZSA9IHN1bVZhbHVlO1xuICAgIGFscGhhID0gTWF0aC5tYXgoZHkgLyBkeCwgZHggLyBkeSkgLyAodmFsdWUgKiByYXRpbyk7XG4gICAgYmV0YSA9IHN1bVZhbHVlICogc3VtVmFsdWUgKiBhbHBoYTtcbiAgICBtaW5SYXRpbyA9IE1hdGgubWF4KG1heFZhbHVlIC8gYmV0YSwgYmV0YSAvIG1pblZhbHVlKTtcblxuICAgIC8vIEtlZXAgYWRkaW5nIG5vZGVzIHdoaWxlIHRoZSBhc3BlY3QgcmF0aW8gbWFpbnRhaW5zIG9yIGltcHJvdmVzLlxuICAgIGZvciAoOyBpMSA8IG47ICsraTEpIHtcbiAgICAgIHN1bVZhbHVlICs9IG5vZGVWYWx1ZSA9IG5vZGVzW2kxXS52YWx1ZTtcbiAgICAgIGlmIChub2RlVmFsdWUgPCBtaW5WYWx1ZSkgbWluVmFsdWUgPSBub2RlVmFsdWU7XG4gICAgICBpZiAobm9kZVZhbHVlID4gbWF4VmFsdWUpIG1heFZhbHVlID0gbm9kZVZhbHVlO1xuICAgICAgYmV0YSA9IHN1bVZhbHVlICogc3VtVmFsdWUgKiBhbHBoYTtcbiAgICAgIG5ld1JhdGlvID0gTWF0aC5tYXgobWF4VmFsdWUgLyBiZXRhLCBiZXRhIC8gbWluVmFsdWUpO1xuICAgICAgaWYgKG5ld1JhdGlvID4gbWluUmF0aW8pIHsgc3VtVmFsdWUgLT0gbm9kZVZhbHVlOyBicmVhazsgfVxuICAgICAgbWluUmF0aW8gPSBuZXdSYXRpbztcbiAgICB9XG5cbiAgICAvLyBQb3NpdGlvbiBhbmQgcmVjb3JkIHRoZSByb3cgb3JpZW50YXRpb24uXG4gICAgcm93cy5wdXNoKHJvdyA9IHt2YWx1ZTogc3VtVmFsdWUsIGRpY2U6IGR4IDwgZHksIGNoaWxkcmVuOiBub2Rlcy5zbGljZShpMCwgaTEpfSk7XG4gICAgaWYgKHJvdy5kaWNlKSB0cmVlbWFwRGljZShyb3csIHgwLCB5MCwgeDEsIHZhbHVlID8geTAgKz0gZHkgKiBzdW1WYWx1ZSAvIHZhbHVlIDogeTEpO1xuICAgIGVsc2UgdHJlZW1hcFNsaWNlKHJvdywgeDAsIHkwLCB2YWx1ZSA/IHgwICs9IGR4ICogc3VtVmFsdWUgLyB2YWx1ZSA6IHgxLCB5MSk7XG4gICAgdmFsdWUgLT0gc3VtVmFsdWUsIGkwID0gaTE7XG4gIH1cblxuICByZXR1cm4gcm93cztcbn1cblxudmFyIHNxdWFyaWZ5ID0gKChmdW5jdGlvbiBjdXN0b20ocmF0aW8pIHtcblxuICBmdW5jdGlvbiBzcXVhcmlmeShwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgc3F1YXJpZnlSYXRpbyhyYXRpbywgcGFyZW50LCB4MCwgeTAsIHgxLCB5MSk7XG4gIH1cblxuICBzcXVhcmlmeS5yYXRpbyA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gY3VzdG9tKCh4ID0gK3gpID4gMSA/IHggOiAxKTtcbiAgfTtcblxuICByZXR1cm4gc3F1YXJpZnk7XG59KSkocGhpKTtcblxudmFyIGluZGV4JDMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHRpbGUgPSBzcXVhcmlmeSxcbiAgICAgIHJvdW5kID0gZmFsc2UsXG4gICAgICBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICBwYWRkaW5nU3RhY2sgPSBbMF0sXG4gICAgICBwYWRkaW5nSW5uZXIgPSBjb25zdGFudFplcm8sXG4gICAgICBwYWRkaW5nVG9wID0gY29uc3RhbnRaZXJvLFxuICAgICAgcGFkZGluZ1JpZ2h0ID0gY29uc3RhbnRaZXJvLFxuICAgICAgcGFkZGluZ0JvdHRvbSA9IGNvbnN0YW50WmVybyxcbiAgICAgIHBhZGRpbmdMZWZ0ID0gY29uc3RhbnRaZXJvO1xuXG4gIGZ1bmN0aW9uIHRyZWVtYXAocm9vdCkge1xuICAgIHJvb3QueDAgPVxuICAgIHJvb3QueTAgPSAwO1xuICAgIHJvb3QueDEgPSBkeDtcbiAgICByb290LnkxID0gZHk7XG4gICAgcm9vdC5lYWNoQmVmb3JlKHBvc2l0aW9uTm9kZSk7XG4gICAgcGFkZGluZ1N0YWNrID0gWzBdO1xuICAgIGlmIChyb3VuZCkgcm9vdC5lYWNoQmVmb3JlKHJvdW5kTm9kZSk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH1cblxuICBmdW5jdGlvbiBwb3NpdGlvbk5vZGUobm9kZSkge1xuICAgIHZhciBwID0gcGFkZGluZ1N0YWNrW25vZGUuZGVwdGhdLFxuICAgICAgICB4MCA9IG5vZGUueDAgKyBwLFxuICAgICAgICB5MCA9IG5vZGUueTAgKyBwLFxuICAgICAgICB4MSA9IG5vZGUueDEgLSBwLFxuICAgICAgICB5MSA9IG5vZGUueTEgLSBwO1xuICAgIGlmICh4MSA8IHgwKSB4MCA9IHgxID0gKHgwICsgeDEpIC8gMjtcbiAgICBpZiAoeTEgPCB5MCkgeTAgPSB5MSA9ICh5MCArIHkxKSAvIDI7XG4gICAgbm9kZS54MCA9IHgwO1xuICAgIG5vZGUueTAgPSB5MDtcbiAgICBub2RlLngxID0geDE7XG4gICAgbm9kZS55MSA9IHkxO1xuICAgIGlmIChub2RlLmNoaWxkcmVuKSB7XG4gICAgICBwID0gcGFkZGluZ1N0YWNrW25vZGUuZGVwdGggKyAxXSA9IHBhZGRpbmdJbm5lcihub2RlKSAvIDI7XG4gICAgICB4MCArPSBwYWRkaW5nTGVmdChub2RlKSAtIHA7XG4gICAgICB5MCArPSBwYWRkaW5nVG9wKG5vZGUpIC0gcDtcbiAgICAgIHgxIC09IHBhZGRpbmdSaWdodChub2RlKSAtIHA7XG4gICAgICB5MSAtPSBwYWRkaW5nQm90dG9tKG5vZGUpIC0gcDtcbiAgICAgIGlmICh4MSA8IHgwKSB4MCA9IHgxID0gKHgwICsgeDEpIC8gMjtcbiAgICAgIGlmICh5MSA8IHkwKSB5MCA9IHkxID0gKHkwICsgeTEpIC8gMjtcbiAgICAgIHRpbGUobm9kZSwgeDAsIHkwLCB4MSwgeTEpO1xuICAgIH1cbiAgfVxuXG4gIHRyZWVtYXAucm91bmQgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocm91bmQgPSAhIXgsIHRyZWVtYXApIDogcm91bmQ7XG4gIH07XG5cbiAgdHJlZW1hcC5zaXplID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIHRyZWVtYXApIDogW2R4LCBkeV07XG4gIH07XG5cbiAgdHJlZW1hcC50aWxlID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRpbGUgPSByZXF1aXJlZCh4KSwgdHJlZW1hcCkgOiB0aWxlO1xuICB9O1xuXG4gIHRyZWVtYXAucGFkZGluZyA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHRyZWVtYXAucGFkZGluZ0lubmVyKHgpLnBhZGRpbmdPdXRlcih4KSA6IHRyZWVtYXAucGFkZGluZ0lubmVyKCk7XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nSW5uZXIgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ0lubmVyID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiBjb25zdGFudCQ4KCt4KSwgdHJlZW1hcCkgOiBwYWRkaW5nSW5uZXI7XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nT3V0ZXIgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0cmVlbWFwLnBhZGRpbmdUb3AoeCkucGFkZGluZ1JpZ2h0KHgpLnBhZGRpbmdCb3R0b20oeCkucGFkZGluZ0xlZnQoeCkgOiB0cmVlbWFwLnBhZGRpbmdUb3AoKTtcbiAgfTtcblxuICB0cmVlbWFwLnBhZGRpbmdUb3AgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ1RvcCA9IHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIgPyB4IDogY29uc3RhbnQkOCgreCksIHRyZWVtYXApIDogcGFkZGluZ1RvcDtcbiAgfTtcblxuICB0cmVlbWFwLnBhZGRpbmdSaWdodCA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nUmlnaHQgPSB0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiID8geCA6IGNvbnN0YW50JDgoK3gpLCB0cmVlbWFwKSA6IHBhZGRpbmdSaWdodDtcbiAgfTtcblxuICB0cmVlbWFwLnBhZGRpbmdCb3R0b20gPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ0JvdHRvbSA9IHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIgPyB4IDogY29uc3RhbnQkOCgreCksIHRyZWVtYXApIDogcGFkZGluZ0JvdHRvbTtcbiAgfTtcblxuICB0cmVlbWFwLnBhZGRpbmdMZWZ0ID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdMZWZ0ID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiBjb25zdGFudCQ4KCt4KSwgdHJlZW1hcCkgOiBwYWRkaW5nTGVmdDtcbiAgfTtcblxuICByZXR1cm4gdHJlZW1hcDtcbn07XG5cbnZhciBiaW5hcnkgPSBmdW5jdGlvbihwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciBub2RlcyA9IHBhcmVudC5jaGlsZHJlbixcbiAgICAgIGksIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICBzdW0sIHN1bXMgPSBuZXcgQXJyYXkobiArIDEpO1xuXG4gIGZvciAoc3Vtc1swXSA9IHN1bSA9IGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgc3Vtc1tpICsgMV0gPSBzdW0gKz0gbm9kZXNbaV0udmFsdWU7XG4gIH1cblxuICBwYXJ0aXRpb24oMCwgbiwgcGFyZW50LnZhbHVlLCB4MCwgeTAsIHgxLCB5MSk7XG5cbiAgZnVuY3Rpb24gcGFydGl0aW9uKGksIGosIHZhbHVlLCB4MCwgeTAsIHgxLCB5MSkge1xuICAgIGlmIChpID49IGogLSAxKSB7XG4gICAgICB2YXIgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgbm9kZS54MCA9IHgwLCBub2RlLnkwID0geTA7XG4gICAgICBub2RlLngxID0geDEsIG5vZGUueTEgPSB5MTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWVPZmZzZXQgPSBzdW1zW2ldLFxuICAgICAgICB2YWx1ZVRhcmdldCA9ICh2YWx1ZSAvIDIpICsgdmFsdWVPZmZzZXQsXG4gICAgICAgIGsgPSBpICsgMSxcbiAgICAgICAgaGkgPSBqIC0gMTtcblxuICAgIHdoaWxlIChrIDwgaGkpIHtcbiAgICAgIHZhciBtaWQgPSBrICsgaGkgPj4+IDE7XG4gICAgICBpZiAoc3Vtc1ttaWRdIDwgdmFsdWVUYXJnZXQpIGsgPSBtaWQgKyAxO1xuICAgICAgZWxzZSBoaSA9IG1pZDtcbiAgICB9XG5cbiAgICBpZiAoKHZhbHVlVGFyZ2V0IC0gc3Vtc1trIC0gMV0pIDwgKHN1bXNba10gLSB2YWx1ZVRhcmdldCkgJiYgaSArIDEgPCBrKSAtLWs7XG5cbiAgICB2YXIgdmFsdWVMZWZ0ID0gc3Vtc1trXSAtIHZhbHVlT2Zmc2V0LFxuICAgICAgICB2YWx1ZVJpZ2h0ID0gdmFsdWUgLSB2YWx1ZUxlZnQ7XG5cbiAgICBpZiAoKHgxIC0geDApID4gKHkxIC0geTApKSB7XG4gICAgICB2YXIgeGsgPSAoeDAgKiB2YWx1ZVJpZ2h0ICsgeDEgKiB2YWx1ZUxlZnQpIC8gdmFsdWU7XG4gICAgICBwYXJ0aXRpb24oaSwgaywgdmFsdWVMZWZ0LCB4MCwgeTAsIHhrLCB5MSk7XG4gICAgICBwYXJ0aXRpb24oaywgaiwgdmFsdWVSaWdodCwgeGssIHkwLCB4MSwgeTEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgeWsgPSAoeTAgKiB2YWx1ZVJpZ2h0ICsgeTEgKiB2YWx1ZUxlZnQpIC8gdmFsdWU7XG4gICAgICBwYXJ0aXRpb24oaSwgaywgdmFsdWVMZWZ0LCB4MCwgeTAsIHgxLCB5ayk7XG4gICAgICBwYXJ0aXRpb24oaywgaiwgdmFsdWVSaWdodCwgeDAsIHlrLCB4MSwgeTEpO1xuICAgIH1cbiAgfVxufTtcblxudmFyIHNsaWNlRGljZSA9IGZ1bmN0aW9uKHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgKHBhcmVudC5kZXB0aCAmIDEgPyB0cmVlbWFwU2xpY2UgOiB0cmVlbWFwRGljZSkocGFyZW50LCB4MCwgeTAsIHgxLCB5MSk7XG59O1xuXG52YXIgcmVzcXVhcmlmeSA9ICgoZnVuY3Rpb24gY3VzdG9tKHJhdGlvKSB7XG5cbiAgZnVuY3Rpb24gcmVzcXVhcmlmeShwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgaWYgKChyb3dzID0gcGFyZW50Ll9zcXVhcmlmeSkgJiYgKHJvd3MucmF0aW8gPT09IHJhdGlvKSkge1xuICAgICAgdmFyIHJvd3MsXG4gICAgICAgICAgcm93LFxuICAgICAgICAgIG5vZGVzLFxuICAgICAgICAgIGksXG4gICAgICAgICAgaiA9IC0xLFxuICAgICAgICAgIG4sXG4gICAgICAgICAgbSA9IHJvd3MubGVuZ3RoLFxuICAgICAgICAgIHZhbHVlID0gcGFyZW50LnZhbHVlO1xuXG4gICAgICB3aGlsZSAoKytqIDwgbSkge1xuICAgICAgICByb3cgPSByb3dzW2pdLCBub2RlcyA9IHJvdy5jaGlsZHJlbjtcbiAgICAgICAgZm9yIChpID0gcm93LnZhbHVlID0gMCwgbiA9IG5vZGVzLmxlbmd0aDsgaSA8IG47ICsraSkgcm93LnZhbHVlICs9IG5vZGVzW2ldLnZhbHVlO1xuICAgICAgICBpZiAocm93LmRpY2UpIHRyZWVtYXBEaWNlKHJvdywgeDAsIHkwLCB4MSwgeTAgKz0gKHkxIC0geTApICogcm93LnZhbHVlIC8gdmFsdWUpO1xuICAgICAgICBlbHNlIHRyZWVtYXBTbGljZShyb3csIHgwLCB5MCwgeDAgKz0gKHgxIC0geDApICogcm93LnZhbHVlIC8gdmFsdWUsIHkxKTtcbiAgICAgICAgdmFsdWUgLT0gcm93LnZhbHVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYXJlbnQuX3NxdWFyaWZ5ID0gcm93cyA9IHNxdWFyaWZ5UmF0aW8ocmF0aW8sIHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpO1xuICAgICAgcm93cy5yYXRpbyA9IHJhdGlvO1xuICAgIH1cbiAgfVxuXG4gIHJlc3F1YXJpZnkucmF0aW8gPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGN1c3RvbSgoeCA9ICt4KSA+IDEgPyB4IDogMSk7XG4gIH07XG5cbiAgcmV0dXJuIHJlc3F1YXJpZnk7XG59KSkocGhpKTtcblxudmFyIGFyZWEkMSA9IGZ1bmN0aW9uKHBvbHlnb24pIHtcbiAgdmFyIGkgPSAtMSxcbiAgICAgIG4gPSBwb2x5Z29uLmxlbmd0aCxcbiAgICAgIGEsXG4gICAgICBiID0gcG9seWdvbltuIC0gMV0sXG4gICAgICBhcmVhID0gMDtcblxuICB3aGlsZSAoKytpIDwgbikge1xuICAgIGEgPSBiO1xuICAgIGIgPSBwb2x5Z29uW2ldO1xuICAgIGFyZWEgKz0gYVsxXSAqIGJbMF0gLSBhWzBdICogYlsxXTtcbiAgfVxuXG4gIHJldHVybiBhcmVhIC8gMjtcbn07XG5cbnZhciBjZW50cm9pZCQxID0gZnVuY3Rpb24ocG9seWdvbikge1xuICB2YXIgaSA9IC0xLFxuICAgICAgbiA9IHBvbHlnb24ubGVuZ3RoLFxuICAgICAgeCA9IDAsXG4gICAgICB5ID0gMCxcbiAgICAgIGEsXG4gICAgICBiID0gcG9seWdvbltuIC0gMV0sXG4gICAgICBjLFxuICAgICAgayA9IDA7XG5cbiAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICBhID0gYjtcbiAgICBiID0gcG9seWdvbltpXTtcbiAgICBrICs9IGMgPSBhWzBdICogYlsxXSAtIGJbMF0gKiBhWzFdO1xuICAgIHggKz0gKGFbMF0gKyBiWzBdKSAqIGM7XG4gICAgeSArPSAoYVsxXSArIGJbMV0pICogYztcbiAgfVxuXG4gIHJldHVybiBrICo9IDMsIFt4IC8gaywgeSAvIGtdO1xufTtcblxuLy8gUmV0dXJucyB0aGUgMkQgY3Jvc3MgcHJvZHVjdCBvZiBBQiBhbmQgQUMgdmVjdG9ycywgaS5lLiwgdGhlIHotY29tcG9uZW50IG9mXG4vLyB0aGUgM0QgY3Jvc3MgcHJvZHVjdCBpbiBhIHF1YWRyYW50IEkgQ2FydGVzaWFuIGNvb3JkaW5hdGUgc3lzdGVtICgreCBpc1xuLy8gcmlnaHQsICt5IGlzIHVwKS4gUmV0dXJucyBhIHBvc2l0aXZlIHZhbHVlIGlmIEFCQyBpcyBjb3VudGVyLWNsb2Nrd2lzZSxcbi8vIG5lZ2F0aXZlIGlmIGNsb2Nrd2lzZSwgYW5kIHplcm8gaWYgdGhlIHBvaW50cyBhcmUgY29sbGluZWFyLlxudmFyIGNyb3NzJDEgPSBmdW5jdGlvbihhLCBiLCBjKSB7XG4gIHJldHVybiAoYlswXSAtIGFbMF0pICogKGNbMV0gLSBhWzFdKSAtIChiWzFdIC0gYVsxXSkgKiAoY1swXSAtIGFbMF0pO1xufTtcblxuZnVuY3Rpb24gbGV4aWNvZ3JhcGhpY09yZGVyKGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gLSBiWzBdIHx8IGFbMV0gLSBiWzFdO1xufVxuXG4vLyBDb21wdXRlcyB0aGUgdXBwZXIgY29udmV4IGh1bGwgcGVyIHRoZSBtb25vdG9uZSBjaGFpbiBhbGdvcml0aG0uXG4vLyBBc3N1bWVzIHBvaW50cy5sZW5ndGggPj0gMywgaXMgc29ydGVkIGJ5IHgsIHVuaXF1ZSBpbiB5LlxuLy8gUmV0dXJucyBhbiBhcnJheSBvZiBpbmRpY2VzIGludG8gcG9pbnRzIGluIGxlZnQtdG8tcmlnaHQgb3JkZXIuXG5mdW5jdGlvbiBjb21wdXRlVXBwZXJIdWxsSW5kZXhlcyhwb2ludHMpIHtcbiAgdmFyIG4gPSBwb2ludHMubGVuZ3RoLFxuICAgICAgaW5kZXhlcyA9IFswLCAxXSxcbiAgICAgIHNpemUgPSAyO1xuXG4gIGZvciAodmFyIGkgPSAyOyBpIDwgbjsgKytpKSB7XG4gICAgd2hpbGUgKHNpemUgPiAxICYmIGNyb3NzJDEocG9pbnRzW2luZGV4ZXNbc2l6ZSAtIDJdXSwgcG9pbnRzW2luZGV4ZXNbc2l6ZSAtIDFdXSwgcG9pbnRzW2ldKSA8PSAwKSAtLXNpemU7XG4gICAgaW5kZXhlc1tzaXplKytdID0gaTtcbiAgfVxuXG4gIHJldHVybiBpbmRleGVzLnNsaWNlKDAsIHNpemUpOyAvLyByZW1vdmUgcG9wcGVkIHBvaW50c1xufVxuXG52YXIgaHVsbCA9IGZ1bmN0aW9uKHBvaW50cykge1xuICBpZiAoKG4gPSBwb2ludHMubGVuZ3RoKSA8IDMpIHJldHVybiBudWxsO1xuXG4gIHZhciBpLFxuICAgICAgbixcbiAgICAgIHNvcnRlZFBvaW50cyA9IG5ldyBBcnJheShuKSxcbiAgICAgIGZsaXBwZWRQb2ludHMgPSBuZXcgQXJyYXkobik7XG5cbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgc29ydGVkUG9pbnRzW2ldID0gWytwb2ludHNbaV1bMF0sICtwb2ludHNbaV1bMV0sIGldO1xuICBzb3J0ZWRQb2ludHMuc29ydChsZXhpY29ncmFwaGljT3JkZXIpO1xuICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBmbGlwcGVkUG9pbnRzW2ldID0gW3NvcnRlZFBvaW50c1tpXVswXSwgLXNvcnRlZFBvaW50c1tpXVsxXV07XG5cbiAgdmFyIHVwcGVySW5kZXhlcyA9IGNvbXB1dGVVcHBlckh1bGxJbmRleGVzKHNvcnRlZFBvaW50cyksXG4gICAgICBsb3dlckluZGV4ZXMgPSBjb21wdXRlVXBwZXJIdWxsSW5kZXhlcyhmbGlwcGVkUG9pbnRzKTtcblxuICAvLyBDb25zdHJ1Y3QgdGhlIGh1bGwgcG9seWdvbiwgcmVtb3ZpbmcgcG9zc2libGUgZHVwbGljYXRlIGVuZHBvaW50cy5cbiAgdmFyIHNraXBMZWZ0ID0gbG93ZXJJbmRleGVzWzBdID09PSB1cHBlckluZGV4ZXNbMF0sXG4gICAgICBza2lwUmlnaHQgPSBsb3dlckluZGV4ZXNbbG93ZXJJbmRleGVzLmxlbmd0aCAtIDFdID09PSB1cHBlckluZGV4ZXNbdXBwZXJJbmRleGVzLmxlbmd0aCAtIDFdLFxuICAgICAgaHVsbCA9IFtdO1xuXG4gIC8vIEFkZCB1cHBlciBodWxsIGluIHJpZ2h0LXRvLWwgb3JkZXIuXG4gIC8vIFRoZW4gYWRkIGxvd2VyIGh1bGwgaW4gbGVmdC10by1yaWdodCBvcmRlci5cbiAgZm9yIChpID0gdXBwZXJJbmRleGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSBodWxsLnB1c2gocG9pbnRzW3NvcnRlZFBvaW50c1t1cHBlckluZGV4ZXNbaV1dWzJdXSk7XG4gIGZvciAoaSA9ICtza2lwTGVmdDsgaSA8IGxvd2VySW5kZXhlcy5sZW5ndGggLSBza2lwUmlnaHQ7ICsraSkgaHVsbC5wdXNoKHBvaW50c1tzb3J0ZWRQb2ludHNbbG93ZXJJbmRleGVzW2ldXVsyXV0pO1xuXG4gIHJldHVybiBodWxsO1xufTtcblxudmFyIGNvbnRhaW5zJDEgPSBmdW5jdGlvbihwb2x5Z29uLCBwb2ludCkge1xuICB2YXIgbiA9IHBvbHlnb24ubGVuZ3RoLFxuICAgICAgcCA9IHBvbHlnb25bbiAtIDFdLFxuICAgICAgeCA9IHBvaW50WzBdLCB5ID0gcG9pbnRbMV0sXG4gICAgICB4MCA9IHBbMF0sIHkwID0gcFsxXSxcbiAgICAgIHgxLCB5MSxcbiAgICAgIGluc2lkZSA9IGZhbHNlO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgcCA9IHBvbHlnb25baV0sIHgxID0gcFswXSwgeTEgPSBwWzFdO1xuICAgIGlmICgoKHkxID4geSkgIT09ICh5MCA+IHkpKSAmJiAoeCA8ICh4MCAtIHgxKSAqICh5IC0geTEpIC8gKHkwIC0geTEpICsgeDEpKSBpbnNpZGUgPSAhaW5zaWRlO1xuICAgIHgwID0geDEsIHkwID0geTE7XG4gIH1cblxuICByZXR1cm4gaW5zaWRlO1xufTtcblxudmFyIGxlbmd0aCQyID0gZnVuY3Rpb24ocG9seWdvbikge1xuICB2YXIgaSA9IC0xLFxuICAgICAgbiA9IHBvbHlnb24ubGVuZ3RoLFxuICAgICAgYiA9IHBvbHlnb25bbiAtIDFdLFxuICAgICAgeGEsXG4gICAgICB5YSxcbiAgICAgIHhiID0gYlswXSxcbiAgICAgIHliID0gYlsxXSxcbiAgICAgIHBlcmltZXRlciA9IDA7XG5cbiAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICB4YSA9IHhiO1xuICAgIHlhID0geWI7XG4gICAgYiA9IHBvbHlnb25baV07XG4gICAgeGIgPSBiWzBdO1xuICAgIHliID0gYlsxXTtcbiAgICB4YSAtPSB4YjtcbiAgICB5YSAtPSB5YjtcbiAgICBwZXJpbWV0ZXIgKz0gTWF0aC5zcXJ0KHhhICogeGEgKyB5YSAqIHlhKTtcbiAgfVxuXG4gIHJldHVybiBwZXJpbWV0ZXI7XG59O1xuXG52YXIgc2xpY2UkMyA9IFtdLnNsaWNlO1xuXG52YXIgbm9hYm9ydCA9IHt9O1xuXG5mdW5jdGlvbiBRdWV1ZShzaXplKSB7XG4gIGlmICghKHNpemUgPj0gMSkpIHRocm93IG5ldyBFcnJvcjtcbiAgdGhpcy5fc2l6ZSA9IHNpemU7XG4gIHRoaXMuX2NhbGwgPVxuICB0aGlzLl9lcnJvciA9IG51bGw7XG4gIHRoaXMuX3Rhc2tzID0gW107XG4gIHRoaXMuX2RhdGEgPSBbXTtcbiAgdGhpcy5fd2FpdGluZyA9XG4gIHRoaXMuX2FjdGl2ZSA9XG4gIHRoaXMuX2VuZGVkID1cbiAgdGhpcy5fc3RhcnQgPSAwOyAvLyBpbnNpZGUgYSBzeW5jaHJvbm91cyB0YXNrIGNhbGxiYWNrP1xufVxuXG5RdWV1ZS5wcm90b3R5cGUgPSBxdWV1ZS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBRdWV1ZSxcbiAgZGVmZXI6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiIHx8IHRoaXMuX2NhbGwpIHRocm93IG5ldyBFcnJvcjtcbiAgICBpZiAodGhpcy5fZXJyb3IgIT0gbnVsbCkgcmV0dXJuIHRoaXM7XG4gICAgdmFyIHQgPSBzbGljZSQzLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICB0LnB1c2goY2FsbGJhY2spO1xuICAgICsrdGhpcy5fd2FpdGluZywgdGhpcy5fdGFza3MucHVzaCh0KTtcbiAgICBwb2tlJDEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIGFib3J0OiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fZXJyb3IgPT0gbnVsbCkgYWJvcnQodGhpcywgbmV3IEVycm9yKFwiYWJvcnRcIikpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBhd2FpdDogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIgfHwgdGhpcy5fY2FsbCkgdGhyb3cgbmV3IEVycm9yO1xuICAgIHRoaXMuX2NhbGwgPSBmdW5jdGlvbihlcnJvciwgcmVzdWx0cykgeyBjYWxsYmFjay5hcHBseShudWxsLCBbZXJyb3JdLmNvbmNhdChyZXN1bHRzKSk7IH07XG4gICAgbWF5YmVOb3RpZnkodGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIGF3YWl0QWxsOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIiB8fCB0aGlzLl9jYWxsKSB0aHJvdyBuZXcgRXJyb3I7XG4gICAgdGhpcy5fY2FsbCA9IGNhbGxiYWNrO1xuICAgIG1heWJlTm90aWZ5KHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59O1xuXG5mdW5jdGlvbiBwb2tlJDEocSkge1xuICBpZiAoIXEuX3N0YXJ0KSB7XG4gICAgdHJ5IHsgc3RhcnQkMShxKTsgfSAvLyBsZXQgdGhlIGN1cnJlbnQgdGFzayBjb21wbGV0ZVxuICAgIGNhdGNoIChlKSB7XG4gICAgICBpZiAocS5fdGFza3NbcS5fZW5kZWQgKyBxLl9hY3RpdmUgLSAxXSkgYWJvcnQocSwgZSk7IC8vIHRhc2sgZXJyb3JlZCBzeW5jaHJvbm91c2x5XG4gICAgICBlbHNlIGlmICghcS5fZGF0YSkgdGhyb3cgZTsgLy8gYXdhaXQgY2FsbGJhY2sgZXJyb3JlZCBzeW5jaHJvbm91c2x5XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHN0YXJ0JDEocSkge1xuICB3aGlsZSAocS5fc3RhcnQgPSBxLl93YWl0aW5nICYmIHEuX2FjdGl2ZSA8IHEuX3NpemUpIHtcbiAgICB2YXIgaSA9IHEuX2VuZGVkICsgcS5fYWN0aXZlLFxuICAgICAgICB0ID0gcS5fdGFza3NbaV0sXG4gICAgICAgIGogPSB0Lmxlbmd0aCAtIDEsXG4gICAgICAgIGMgPSB0W2pdO1xuICAgIHRbal0gPSBlbmQocSwgaSk7XG4gICAgLS1xLl93YWl0aW5nLCArK3EuX2FjdGl2ZTtcbiAgICB0ID0gYy5hcHBseShudWxsLCB0KTtcbiAgICBpZiAoIXEuX3Rhc2tzW2ldKSBjb250aW51ZTsgLy8gdGFzayBmaW5pc2hlZCBzeW5jaHJvbm91c2x5XG4gICAgcS5fdGFza3NbaV0gPSB0IHx8IG5vYWJvcnQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kKHEsIGkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGUsIHIpIHtcbiAgICBpZiAoIXEuX3Rhc2tzW2ldKSByZXR1cm47IC8vIGlnbm9yZSBtdWx0aXBsZSBjYWxsYmFja3NcbiAgICAtLXEuX2FjdGl2ZSwgKytxLl9lbmRlZDtcbiAgICBxLl90YXNrc1tpXSA9IG51bGw7XG4gICAgaWYgKHEuX2Vycm9yICE9IG51bGwpIHJldHVybjsgLy8gaWdub3JlIHNlY29uZGFyeSBlcnJvcnNcbiAgICBpZiAoZSAhPSBudWxsKSB7XG4gICAgICBhYm9ydChxLCBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcS5fZGF0YVtpXSA9IHI7XG4gICAgICBpZiAocS5fd2FpdGluZykgcG9rZSQxKHEpO1xuICAgICAgZWxzZSBtYXliZU5vdGlmeShxKTtcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIGFib3J0KHEsIGUpIHtcbiAgdmFyIGkgPSBxLl90YXNrcy5sZW5ndGgsIHQ7XG4gIHEuX2Vycm9yID0gZTsgLy8gaWdub3JlIGFjdGl2ZSBjYWxsYmFja3NcbiAgcS5fZGF0YSA9IHVuZGVmaW5lZDsgLy8gYWxsb3cgZ2NcbiAgcS5fd2FpdGluZyA9IE5hTjsgLy8gcHJldmVudCBzdGFydGluZ1xuXG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIGlmICh0ID0gcS5fdGFza3NbaV0pIHtcbiAgICAgIHEuX3Rhc2tzW2ldID0gbnVsbDtcbiAgICAgIGlmICh0LmFib3J0KSB7XG4gICAgICAgIHRyeSB7IHQuYWJvcnQoKTsgfVxuICAgICAgICBjYXRjaCAoZSkgeyAvKiBpZ25vcmUgKi8gfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHEuX2FjdGl2ZSA9IE5hTjsgLy8gYWxsb3cgbm90aWZpY2F0aW9uXG4gIG1heWJlTm90aWZ5KHEpO1xufVxuXG5mdW5jdGlvbiBtYXliZU5vdGlmeShxKSB7XG4gIGlmICghcS5fYWN0aXZlICYmIHEuX2NhbGwpIHtcbiAgICB2YXIgZCA9IHEuX2RhdGE7XG4gICAgcS5fZGF0YSA9IHVuZGVmaW5lZDsgLy8gYWxsb3cgZ2NcbiAgICBxLl9jYWxsKHEuX2Vycm9yLCBkKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBxdWV1ZShjb25jdXJyZW5jeSkge1xuICByZXR1cm4gbmV3IFF1ZXVlKGFyZ3VtZW50cy5sZW5ndGggPyArY29uY3VycmVuY3kgOiBJbmZpbml0eSk7XG59XG5cbnZhciB1bmlmb3JtID0gZnVuY3Rpb24obWluLCBtYXgpIHtcbiAgbWluID0gbWluID09IG51bGwgPyAwIDogK21pbjtcbiAgbWF4ID0gbWF4ID09IG51bGwgPyAxIDogK21heDtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIG1heCA9IG1pbiwgbWluID0gMDtcbiAgZWxzZSBtYXggLT0gbWluO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIE1hdGgucmFuZG9tKCkgKiBtYXggKyBtaW47XG4gIH07XG59O1xuXG52YXIgbm9ybWFsID0gZnVuY3Rpb24obXUsIHNpZ21hKSB7XG4gIHZhciB4LCByO1xuICBtdSA9IG11ID09IG51bGwgPyAwIDogK211O1xuICBzaWdtYSA9IHNpZ21hID09IG51bGwgPyAxIDogK3NpZ21hO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHk7XG5cbiAgICAvLyBJZiBhdmFpbGFibGUsIHVzZSB0aGUgc2Vjb25kIHByZXZpb3VzbHktZ2VuZXJhdGVkIHVuaWZvcm0gcmFuZG9tLlxuICAgIGlmICh4ICE9IG51bGwpIHkgPSB4LCB4ID0gbnVsbDtcblxuICAgIC8vIE90aGVyd2lzZSwgZ2VuZXJhdGUgYSBuZXcgeCBhbmQgeS5cbiAgICBlbHNlIGRvIHtcbiAgICAgIHggPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7XG4gICAgICB5ID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgciA9IHggKiB4ICsgeSAqIHk7XG4gICAgfSB3aGlsZSAoIXIgfHwgciA+IDEpO1xuXG4gICAgcmV0dXJuIG11ICsgc2lnbWEgKiB5ICogTWF0aC5zcXJ0KC0yICogTWF0aC5sb2cocikgLyByKTtcbiAgfTtcbn07XG5cbnZhciBsb2dOb3JtYWwgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHJhbmRvbU5vcm1hbCA9IG5vcm1hbC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIE1hdGguZXhwKHJhbmRvbU5vcm1hbCgpKTtcbiAgfTtcbn07XG5cbnZhciBpcndpbkhhbGwgPSBmdW5jdGlvbihuKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBmb3IgKHZhciBzdW0gPSAwLCBpID0gMDsgaSA8IG47ICsraSkgc3VtICs9IE1hdGgucmFuZG9tKCk7XG4gICAgcmV0dXJuIHN1bTtcbiAgfTtcbn07XG5cbnZhciBiYXRlcyA9IGZ1bmN0aW9uKG4pIHtcbiAgdmFyIHJhbmRvbUlyd2luSGFsbCA9IGlyd2luSGFsbChuKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiByYW5kb21JcndpbkhhbGwoKSAvIG47XG4gIH07XG59O1xuXG52YXIgZXhwb25lbnRpYWwkMSA9IGZ1bmN0aW9uKGxhbWJkYSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIC1NYXRoLmxvZygxIC0gTWF0aC5yYW5kb20oKSkgLyBsYW1iZGE7XG4gIH07XG59O1xuXG52YXIgcmVxdWVzdCA9IGZ1bmN0aW9uKHVybCwgY2FsbGJhY2spIHtcbiAgdmFyIHJlcXVlc3QsXG4gICAgICBldmVudCA9IGRpc3BhdGNoKFwiYmVmb3Jlc2VuZFwiLCBcInByb2dyZXNzXCIsIFwibG9hZFwiLCBcImVycm9yXCIpLFxuICAgICAgbWltZVR5cGUsXG4gICAgICBoZWFkZXJzID0gbWFwJDEoKSxcbiAgICAgIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCxcbiAgICAgIHVzZXIgPSBudWxsLFxuICAgICAgcGFzc3dvcmQgPSBudWxsLFxuICAgICAgcmVzcG9uc2UsXG4gICAgICByZXNwb25zZVR5cGUsXG4gICAgICB0aW1lb3V0ID0gMDtcblxuICAvLyBJZiBJRSBkb2VzIG5vdCBzdXBwb3J0IENPUlMsIHVzZSBYRG9tYWluUmVxdWVzdC5cbiAgaWYgKHR5cGVvZiBYRG9tYWluUmVxdWVzdCAhPT0gXCJ1bmRlZmluZWRcIlxuICAgICAgJiYgIShcIndpdGhDcmVkZW50aWFsc1wiIGluIHhocilcbiAgICAgICYmIC9eKGh0dHAocyk/Oik/XFwvXFwvLy50ZXN0KHVybCkpIHhociA9IG5ldyBYRG9tYWluUmVxdWVzdDtcblxuICBcIm9ubG9hZFwiIGluIHhoclxuICAgICAgPyB4aHIub25sb2FkID0geGhyLm9uZXJyb3IgPSB4aHIub250aW1lb3V0ID0gcmVzcG9uZFxuICAgICAgOiB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24obykgeyB4aHIucmVhZHlTdGF0ZSA+IDMgJiYgcmVzcG9uZChvKTsgfTtcblxuICBmdW5jdGlvbiByZXNwb25kKG8pIHtcbiAgICB2YXIgc3RhdHVzID0geGhyLnN0YXR1cywgcmVzdWx0O1xuICAgIGlmICghc3RhdHVzICYmIGhhc1Jlc3BvbnNlKHhocilcbiAgICAgICAgfHwgc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDBcbiAgICAgICAgfHwgc3RhdHVzID09PSAzMDQpIHtcbiAgICAgIGlmIChyZXNwb25zZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlc3VsdCA9IHJlc3BvbnNlLmNhbGwocmVxdWVzdCwgeGhyKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGV2ZW50LmNhbGwoXCJlcnJvclwiLCByZXF1ZXN0LCBlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IHhocjtcbiAgICAgIH1cbiAgICAgIGV2ZW50LmNhbGwoXCJsb2FkXCIsIHJlcXVlc3QsIHJlc3VsdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2ZW50LmNhbGwoXCJlcnJvclwiLCByZXF1ZXN0LCBvKTtcbiAgICB9XG4gIH1cblxuICB4aHIub25wcm9ncmVzcyA9IGZ1bmN0aW9uKGUpIHtcbiAgICBldmVudC5jYWxsKFwicHJvZ3Jlc3NcIiwgcmVxdWVzdCwgZSk7XG4gIH07XG5cbiAgcmVxdWVzdCA9IHtcbiAgICBoZWFkZXI6IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICBuYW1lID0gKG5hbWUgKyBcIlwiKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSByZXR1cm4gaGVhZGVycy5nZXQobmFtZSk7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkgaGVhZGVycy5yZW1vdmUobmFtZSk7XG4gICAgICBlbHNlIGhlYWRlcnMuc2V0KG5hbWUsIHZhbHVlICsgXCJcIik7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgLy8gSWYgbWltZVR5cGUgaXMgbm9uLW51bGwgYW5kIG5vIEFjY2VwdCBoZWFkZXIgaXMgc2V0LCBhIGRlZmF1bHQgaXMgdXNlZC5cbiAgICBtaW1lVHlwZTogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIG1pbWVUeXBlO1xuICAgICAgbWltZVR5cGUgPSB2YWx1ZSA9PSBudWxsID8gbnVsbCA6IHZhbHVlICsgXCJcIjtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0sXG5cbiAgICAvLyBTcGVjaWZpZXMgd2hhdCB0eXBlIHRoZSByZXNwb25zZSB2YWx1ZSBzaG91bGQgdGFrZTtcbiAgICAvLyBmb3IgaW5zdGFuY2UsIGFycmF5YnVmZmVyLCBibG9iLCBkb2N1bWVudCwgb3IgdGV4dC5cbiAgICByZXNwb25zZVR5cGU6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiByZXNwb25zZVR5cGU7XG4gICAgICByZXNwb25zZVR5cGUgPSB2YWx1ZTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0sXG5cbiAgICB0aW1lb3V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGltZW91dDtcbiAgICAgIHRpbWVvdXQgPSArdmFsdWU7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgdXNlcjogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoIDwgMSA/IHVzZXIgOiAodXNlciA9IHZhbHVlID09IG51bGwgPyBudWxsIDogdmFsdWUgKyBcIlwiLCByZXF1ZXN0KTtcbiAgICB9LFxuXG4gICAgcGFzc3dvcmQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA8IDEgPyBwYXNzd29yZCA6IChwYXNzd29yZCA9IHZhbHVlID09IG51bGwgPyBudWxsIDogdmFsdWUgKyBcIlwiLCByZXF1ZXN0KTtcbiAgICB9LFxuXG4gICAgLy8gU3BlY2lmeSBob3cgdG8gY29udmVydCB0aGUgcmVzcG9uc2UgY29udGVudCB0byBhIHNwZWNpZmljIHR5cGU7XG4gICAgLy8gY2hhbmdlcyB0aGUgY2FsbGJhY2sgdmFsdWUgb24gXCJsb2FkXCIgZXZlbnRzLlxuICAgIHJlc3BvbnNlOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmVzcG9uc2UgPSB2YWx1ZTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0sXG5cbiAgICAvLyBBbGlhcyBmb3Igc2VuZChcIkdFVFwiLCDigKYpLlxuICAgIGdldDogZnVuY3Rpb24oZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgIHJldHVybiByZXF1ZXN0LnNlbmQoXCJHRVRcIiwgZGF0YSwgY2FsbGJhY2spO1xuICAgIH0sXG5cbiAgICAvLyBBbGlhcyBmb3Igc2VuZChcIlBPU1RcIiwg4oCmKS5cbiAgICBwb3N0OiBmdW5jdGlvbihkYXRhLCBjYWxsYmFjaykge1xuICAgICAgcmV0dXJuIHJlcXVlc3Quc2VuZChcIlBPU1RcIiwgZGF0YSwgY2FsbGJhY2spO1xuICAgIH0sXG5cbiAgICAvLyBJZiBjYWxsYmFjayBpcyBub24tbnVsbCwgaXQgd2lsbCBiZSB1c2VkIGZvciBlcnJvciBhbmQgbG9hZCBldmVudHMuXG4gICAgc2VuZDogZnVuY3Rpb24obWV0aG9kLCBkYXRhLCBjYWxsYmFjaykge1xuICAgICAgeGhyLm9wZW4obWV0aG9kLCB1cmwsIHRydWUsIHVzZXIsIHBhc3N3b3JkKTtcbiAgICAgIGlmIChtaW1lVHlwZSAhPSBudWxsICYmICFoZWFkZXJzLmhhcyhcImFjY2VwdFwiKSkgaGVhZGVycy5zZXQoXCJhY2NlcHRcIiwgbWltZVR5cGUgKyBcIiwqLypcIik7XG4gICAgICBpZiAoeGhyLnNldFJlcXVlc3RIZWFkZXIpIGhlYWRlcnMuZWFjaChmdW5jdGlvbih2YWx1ZSwgbmFtZSkgeyB4aHIuc2V0UmVxdWVzdEhlYWRlcihuYW1lLCB2YWx1ZSk7IH0pO1xuICAgICAgaWYgKG1pbWVUeXBlICE9IG51bGwgJiYgeGhyLm92ZXJyaWRlTWltZVR5cGUpIHhoci5vdmVycmlkZU1pbWVUeXBlKG1pbWVUeXBlKTtcbiAgICAgIGlmIChyZXNwb25zZVR5cGUgIT0gbnVsbCkgeGhyLnJlc3BvbnNlVHlwZSA9IHJlc3BvbnNlVHlwZTtcbiAgICAgIGlmICh0aW1lb3V0ID4gMCkgeGhyLnRpbWVvdXQgPSB0aW1lb3V0O1xuICAgICAgaWYgKGNhbGxiYWNrID09IG51bGwgJiYgdHlwZW9mIGRhdGEgPT09IFwiZnVuY3Rpb25cIikgY2FsbGJhY2sgPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgICAgIGlmIChjYWxsYmFjayAhPSBudWxsICYmIGNhbGxiYWNrLmxlbmd0aCA9PT0gMSkgY2FsbGJhY2sgPSBmaXhDYWxsYmFjayhjYWxsYmFjayk7XG4gICAgICBpZiAoY2FsbGJhY2sgIT0gbnVsbCkgcmVxdWVzdC5vbihcImVycm9yXCIsIGNhbGxiYWNrKS5vbihcImxvYWRcIiwgZnVuY3Rpb24oeGhyKSB7IGNhbGxiYWNrKG51bGwsIHhocik7IH0pO1xuICAgICAgZXZlbnQuY2FsbChcImJlZm9yZXNlbmRcIiwgcmVxdWVzdCwgeGhyKTtcbiAgICAgIHhoci5zZW5kKGRhdGEgPT0gbnVsbCA/IG51bGwgOiBkYXRhKTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0sXG5cbiAgICBhYm9ydDogZnVuY3Rpb24oKSB7XG4gICAgICB4aHIuYWJvcnQoKTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0sXG5cbiAgICBvbjogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdmFsdWUgPSBldmVudC5vbi5hcHBseShldmVudCwgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gZXZlbnQgPyByZXF1ZXN0IDogdmFsdWU7XG4gICAgfVxuICB9O1xuXG4gIGlmIChjYWxsYmFjayAhPSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGNhbGxiYWNrOiBcIiArIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcmVxdWVzdC5nZXQoY2FsbGJhY2spO1xuICB9XG5cbiAgcmV0dXJuIHJlcXVlc3Q7XG59O1xuXG5mdW5jdGlvbiBmaXhDYWxsYmFjayhjYWxsYmFjaykge1xuICByZXR1cm4gZnVuY3Rpb24oZXJyb3IsIHhocikge1xuICAgIGNhbGxiYWNrKGVycm9yID09IG51bGwgPyB4aHIgOiBudWxsKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaGFzUmVzcG9uc2UoeGhyKSB7XG4gIHZhciB0eXBlID0geGhyLnJlc3BvbnNlVHlwZTtcbiAgcmV0dXJuIHR5cGUgJiYgdHlwZSAhPT0gXCJ0ZXh0XCJcbiAgICAgID8geGhyLnJlc3BvbnNlIC8vIG51bGwgb24gZXJyb3JcbiAgICAgIDogeGhyLnJlc3BvbnNlVGV4dDsgLy8gXCJcIiBvbiBlcnJvclxufVxuXG52YXIgdHlwZSQxID0gZnVuY3Rpb24oZGVmYXVsdE1pbWVUeXBlLCByZXNwb25zZSkge1xuICByZXR1cm4gZnVuY3Rpb24odXJsLCBjYWxsYmFjaykge1xuICAgIHZhciByID0gcmVxdWVzdCh1cmwpLm1pbWVUeXBlKGRlZmF1bHRNaW1lVHlwZSkucmVzcG9uc2UocmVzcG9uc2UpO1xuICAgIGlmIChjYWxsYmFjayAhPSBudWxsKSB7XG4gICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgY2FsbGJhY2s6IFwiICsgY2FsbGJhY2spO1xuICAgICAgcmV0dXJuIHIuZ2V0KGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH07XG59O1xuXG52YXIgaHRtbCA9IHR5cGUkMShcInRleHQvaHRtbFwiLCBmdW5jdGlvbih4aHIpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVJhbmdlKCkuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KHhoci5yZXNwb25zZVRleHQpO1xufSk7XG5cbnZhciBqc29uID0gdHlwZSQxKFwiYXBwbGljYXRpb24vanNvblwiLCBmdW5jdGlvbih4aHIpIHtcbiAgcmV0dXJuIEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlVGV4dCk7XG59KTtcblxudmFyIHRleHQgPSB0eXBlJDEoXCJ0ZXh0L3BsYWluXCIsIGZ1bmN0aW9uKHhocikge1xuICByZXR1cm4geGhyLnJlc3BvbnNlVGV4dDtcbn0pO1xuXG52YXIgeG1sID0gdHlwZSQxKFwiYXBwbGljYXRpb24veG1sXCIsIGZ1bmN0aW9uKHhocikge1xuICB2YXIgeG1sID0geGhyLnJlc3BvbnNlWE1MO1xuICBpZiAoIXhtbCkgdGhyb3cgbmV3IEVycm9yKFwicGFyc2UgZXJyb3JcIik7XG4gIHJldHVybiB4bWw7XG59KTtcblxudmFyIGRzdiQxID0gZnVuY3Rpb24oZGVmYXVsdE1pbWVUeXBlLCBwYXJzZSkge1xuICByZXR1cm4gZnVuY3Rpb24odXJsLCByb3csIGNhbGxiYWNrKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSBjYWxsYmFjayA9IHJvdywgcm93ID0gbnVsbDtcbiAgICB2YXIgciA9IHJlcXVlc3QodXJsKS5taW1lVHlwZShkZWZhdWx0TWltZVR5cGUpO1xuICAgIHIucm93ID0gZnVuY3Rpb24oXykgeyByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHIucmVzcG9uc2UocmVzcG9uc2VPZihwYXJzZSwgcm93ID0gXykpIDogcm93OyB9O1xuICAgIHIucm93KHJvdyk7XG4gICAgcmV0dXJuIGNhbGxiYWNrID8gci5nZXQoY2FsbGJhY2spIDogcjtcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIHJlc3BvbnNlT2YocGFyc2UsIHJvdykge1xuICByZXR1cm4gZnVuY3Rpb24ocmVxdWVzdCQkMSkge1xuICAgIHJldHVybiBwYXJzZShyZXF1ZXN0JCQxLnJlc3BvbnNlVGV4dCwgcm93KTtcbiAgfTtcbn1cblxudmFyIGNzdiQxID0gZHN2JDEoXCJ0ZXh0L2NzdlwiLCBjc3ZQYXJzZSk7XG5cbnZhciB0c3YkMSA9IGRzdiQxKFwidGV4dC90YWItc2VwYXJhdGVkLXZhbHVlc1wiLCB0c3ZQYXJzZSk7XG5cbnZhciBhcnJheSQyID0gQXJyYXkucHJvdG90eXBlO1xuXG52YXIgbWFwJDMgPSBhcnJheSQyLm1hcDtcbnZhciBzbGljZSQ0ID0gYXJyYXkkMi5zbGljZTtcblxudmFyIGltcGxpY2l0ID0ge25hbWU6IFwiaW1wbGljaXRcIn07XG5cbmZ1bmN0aW9uIG9yZGluYWwocmFuZ2UpIHtcbiAgdmFyIGluZGV4ID0gbWFwJDEoKSxcbiAgICAgIGRvbWFpbiA9IFtdLFxuICAgICAgdW5rbm93biA9IGltcGxpY2l0O1xuXG4gIHJhbmdlID0gcmFuZ2UgPT0gbnVsbCA/IFtdIDogc2xpY2UkNC5jYWxsKHJhbmdlKTtcblxuICBmdW5jdGlvbiBzY2FsZShkKSB7XG4gICAgdmFyIGtleSA9IGQgKyBcIlwiLCBpID0gaW5kZXguZ2V0KGtleSk7XG4gICAgaWYgKCFpKSB7XG4gICAgICBpZiAodW5rbm93biAhPT0gaW1wbGljaXQpIHJldHVybiB1bmtub3duO1xuICAgICAgaW5kZXguc2V0KGtleSwgaSA9IGRvbWFpbi5wdXNoKGQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJhbmdlWyhpIC0gMSkgJSByYW5nZS5sZW5ndGhdO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGRvbWFpbi5zbGljZSgpO1xuICAgIGRvbWFpbiA9IFtdLCBpbmRleCA9IG1hcCQxKCk7XG4gICAgdmFyIGkgPSAtMSwgbiA9IF8ubGVuZ3RoLCBkLCBrZXk7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICghaW5kZXguaGFzKGtleSA9IChkID0gX1tpXSkgKyBcIlwiKSkgaW5kZXguc2V0KGtleSwgZG9tYWluLnB1c2goZCkpO1xuICAgIHJldHVybiBzY2FsZTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSA9IHNsaWNlJDQuY2FsbChfKSwgc2NhbGUpIDogcmFuZ2Uuc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS51bmtub3duID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHVua25vd24gPSBfLCBzY2FsZSkgOiB1bmtub3duO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gb3JkaW5hbCgpXG4gICAgICAgIC5kb21haW4oZG9tYWluKVxuICAgICAgICAucmFuZ2UocmFuZ2UpXG4gICAgICAgIC51bmtub3duKHVua25vd24pO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxuZnVuY3Rpb24gYmFuZCgpIHtcbiAgdmFyIHNjYWxlID0gb3JkaW5hbCgpLnVua25vd24odW5kZWZpbmVkKSxcbiAgICAgIGRvbWFpbiA9IHNjYWxlLmRvbWFpbixcbiAgICAgIG9yZGluYWxSYW5nZSA9IHNjYWxlLnJhbmdlLFxuICAgICAgcmFuZ2UkJDEgPSBbMCwgMV0sXG4gICAgICBzdGVwLFxuICAgICAgYmFuZHdpZHRoLFxuICAgICAgcm91bmQgPSBmYWxzZSxcbiAgICAgIHBhZGRpbmdJbm5lciA9IDAsXG4gICAgICBwYWRkaW5nT3V0ZXIgPSAwLFxuICAgICAgYWxpZ24gPSAwLjU7XG5cbiAgZGVsZXRlIHNjYWxlLnVua25vd247XG5cbiAgZnVuY3Rpb24gcmVzY2FsZSgpIHtcbiAgICB2YXIgbiA9IGRvbWFpbigpLmxlbmd0aCxcbiAgICAgICAgcmV2ZXJzZSA9IHJhbmdlJCQxWzFdIDwgcmFuZ2UkJDFbMF0sXG4gICAgICAgIHN0YXJ0ID0gcmFuZ2UkJDFbcmV2ZXJzZSAtIDBdLFxuICAgICAgICBzdG9wID0gcmFuZ2UkJDFbMSAtIHJldmVyc2VdO1xuICAgIHN0ZXAgPSAoc3RvcCAtIHN0YXJ0KSAvIE1hdGgubWF4KDEsIG4gLSBwYWRkaW5nSW5uZXIgKyBwYWRkaW5nT3V0ZXIgKiAyKTtcbiAgICBpZiAocm91bmQpIHN0ZXAgPSBNYXRoLmZsb29yKHN0ZXApO1xuICAgIHN0YXJ0ICs9IChzdG9wIC0gc3RhcnQgLSBzdGVwICogKG4gLSBwYWRkaW5nSW5uZXIpKSAqIGFsaWduO1xuICAgIGJhbmR3aWR0aCA9IHN0ZXAgKiAoMSAtIHBhZGRpbmdJbm5lcik7XG4gICAgaWYgKHJvdW5kKSBzdGFydCA9IE1hdGgucm91bmQoc3RhcnQpLCBiYW5kd2lkdGggPSBNYXRoLnJvdW5kKGJhbmR3aWR0aCk7XG4gICAgdmFyIHZhbHVlcyA9IHNlcXVlbmNlKG4pLm1hcChmdW5jdGlvbihpKSB7IHJldHVybiBzdGFydCArIHN0ZXAgKiBpOyB9KTtcbiAgICByZXR1cm4gb3JkaW5hbFJhbmdlKHJldmVyc2UgPyB2YWx1ZXMucmV2ZXJzZSgpIDogdmFsdWVzKTtcbiAgfVxuXG4gIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4oXyksIHJlc2NhbGUoKSkgOiBkb21haW4oKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSQkMSA9IFsrX1swXSwgK19bMV1dLCByZXNjYWxlKCkpIDogcmFuZ2UkJDEuc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZVJvdW5kID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiByYW5nZSQkMSA9IFsrX1swXSwgK19bMV1dLCByb3VuZCA9IHRydWUsIHJlc2NhbGUoKTtcbiAgfTtcblxuICBzY2FsZS5iYW5kd2lkdGggPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYmFuZHdpZHRoO1xuICB9O1xuXG4gIHNjYWxlLnN0ZXAgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gc3RlcDtcbiAgfTtcblxuICBzY2FsZS5yb3VuZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyb3VuZCA9ICEhXywgcmVzY2FsZSgpKSA6IHJvdW5kO1xuICB9O1xuXG4gIHNjYWxlLnBhZGRpbmcgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ0lubmVyID0gcGFkZGluZ091dGVyID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgXykpLCByZXNjYWxlKCkpIDogcGFkZGluZ0lubmVyO1xuICB9O1xuXG4gIHNjYWxlLnBhZGRpbmdJbm5lciA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nSW5uZXIgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBfKSksIHJlc2NhbGUoKSkgOiBwYWRkaW5nSW5uZXI7XG4gIH07XG5cbiAgc2NhbGUucGFkZGluZ091dGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdPdXRlciA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIF8pKSwgcmVzY2FsZSgpKSA6IHBhZGRpbmdPdXRlcjtcbiAgfTtcblxuICBzY2FsZS5hbGlnbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChhbGlnbiA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIF8pKSwgcmVzY2FsZSgpKSA6IGFsaWduO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYmFuZCgpXG4gICAgICAgIC5kb21haW4oZG9tYWluKCkpXG4gICAgICAgIC5yYW5nZShyYW5nZSQkMSlcbiAgICAgICAgLnJvdW5kKHJvdW5kKVxuICAgICAgICAucGFkZGluZ0lubmVyKHBhZGRpbmdJbm5lcilcbiAgICAgICAgLnBhZGRpbmdPdXRlcihwYWRkaW5nT3V0ZXIpXG4gICAgICAgIC5hbGlnbihhbGlnbik7XG4gIH07XG5cbiAgcmV0dXJuIHJlc2NhbGUoKTtcbn1cblxuZnVuY3Rpb24gcG9pbnRpc2goc2NhbGUpIHtcbiAgdmFyIGNvcHkgPSBzY2FsZS5jb3B5O1xuXG4gIHNjYWxlLnBhZGRpbmcgPSBzY2FsZS5wYWRkaW5nT3V0ZXI7XG4gIGRlbGV0ZSBzY2FsZS5wYWRkaW5nSW5uZXI7XG4gIGRlbGV0ZSBzY2FsZS5wYWRkaW5nT3V0ZXI7XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBwb2ludGlzaChjb3B5KCkpO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxuZnVuY3Rpb24gcG9pbnQkMSgpIHtcbiAgcmV0dXJuIHBvaW50aXNoKGJhbmQoKS5wYWRkaW5nSW5uZXIoMSkpO1xufVxuXG52YXIgY29uc3RhbnQkOSA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxudmFyIG51bWJlciQxID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gK3g7XG59O1xuXG52YXIgdW5pdCA9IFswLCAxXTtcblxuZnVuY3Rpb24gZGVpbnRlcnBvbGF0ZUxpbmVhcihhLCBiKSB7XG4gIHJldHVybiAoYiAtPSAoYSA9ICthKSlcbiAgICAgID8gZnVuY3Rpb24oeCkgeyByZXR1cm4gKHggLSBhKSAvIGI7IH1cbiAgICAgIDogY29uc3RhbnQkOShiKTtcbn1cblxuZnVuY3Rpb24gZGVpbnRlcnBvbGF0ZUNsYW1wKGRlaW50ZXJwb2xhdGUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgZCA9IGRlaW50ZXJwb2xhdGUoYSA9ICthLCBiID0gK2IpO1xuICAgIHJldHVybiBmdW5jdGlvbih4KSB7IHJldHVybiB4IDw9IGEgPyAwIDogeCA+PSBiID8gMSA6IGQoeCk7IH07XG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlaW50ZXJwb2xhdGVDbGFtcChyZWludGVycG9sYXRlKSB7XG4gIHJldHVybiBmdW5jdGlvbihhLCBiKSB7XG4gICAgdmFyIHIgPSByZWludGVycG9sYXRlKGEgPSArYSwgYiA9ICtiKTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkgeyByZXR1cm4gdCA8PSAwID8gYSA6IHQgPj0gMSA/IGIgOiByKHQpOyB9O1xuICB9O1xufVxuXG5mdW5jdGlvbiBiaW1hcChkb21haW4sIHJhbmdlJCQxLCBkZWludGVycG9sYXRlLCByZWludGVycG9sYXRlKSB7XG4gIHZhciBkMCA9IGRvbWFpblswXSwgZDEgPSBkb21haW5bMV0sIHIwID0gcmFuZ2UkJDFbMF0sIHIxID0gcmFuZ2UkJDFbMV07XG4gIGlmIChkMSA8IGQwKSBkMCA9IGRlaW50ZXJwb2xhdGUoZDEsIGQwKSwgcjAgPSByZWludGVycG9sYXRlKHIxLCByMCk7XG4gIGVsc2UgZDAgPSBkZWludGVycG9sYXRlKGQwLCBkMSksIHIwID0gcmVpbnRlcnBvbGF0ZShyMCwgcjEpO1xuICByZXR1cm4gZnVuY3Rpb24oeCkgeyByZXR1cm4gcjAoZDAoeCkpOyB9O1xufVxuXG5mdW5jdGlvbiBwb2x5bWFwKGRvbWFpbiwgcmFuZ2UkJDEsIGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUpIHtcbiAgdmFyIGogPSBNYXRoLm1pbihkb21haW4ubGVuZ3RoLCByYW5nZSQkMS5sZW5ndGgpIC0gMSxcbiAgICAgIGQgPSBuZXcgQXJyYXkoaiksXG4gICAgICByID0gbmV3IEFycmF5KGopLFxuICAgICAgaSA9IC0xO1xuXG4gIC8vIFJldmVyc2UgZGVzY2VuZGluZyBkb21haW5zLlxuICBpZiAoZG9tYWluW2pdIDwgZG9tYWluWzBdKSB7XG4gICAgZG9tYWluID0gZG9tYWluLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIHJhbmdlJCQxID0gcmFuZ2UkJDEuc2xpY2UoKS5yZXZlcnNlKCk7XG4gIH1cblxuICB3aGlsZSAoKytpIDwgaikge1xuICAgIGRbaV0gPSBkZWludGVycG9sYXRlKGRvbWFpbltpXSwgZG9tYWluW2kgKyAxXSk7XG4gICAgcltpXSA9IHJlaW50ZXJwb2xhdGUocmFuZ2UkJDFbaV0sIHJhbmdlJCQxW2kgKyAxXSk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24oeCkge1xuICAgIHZhciBpID0gYmlzZWN0UmlnaHQoZG9tYWluLCB4LCAxLCBqKSAtIDE7XG4gICAgcmV0dXJuIHJbaV0oZFtpXSh4KSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvcHkoc291cmNlLCB0YXJnZXQpIHtcbiAgcmV0dXJuIHRhcmdldFxuICAgICAgLmRvbWFpbihzb3VyY2UuZG9tYWluKCkpXG4gICAgICAucmFuZ2Uoc291cmNlLnJhbmdlKCkpXG4gICAgICAuaW50ZXJwb2xhdGUoc291cmNlLmludGVycG9sYXRlKCkpXG4gICAgICAuY2xhbXAoc291cmNlLmNsYW1wKCkpO1xufVxuXG4vLyBkZWludGVycG9sYXRlKGEsIGIpKHgpIHRha2VzIGEgZG9tYWluIHZhbHVlIHggaW4gW2EsYl0gYW5kIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcGFyYW1ldGVyIHQgaW4gWzAsMV0uXG4vLyByZWludGVycG9sYXRlKGEsIGIpKHQpIHRha2VzIGEgcGFyYW1ldGVyIHQgaW4gWzAsMV0gYW5kIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgZG9tYWluIHZhbHVlIHggaW4gW2EsYl0uXG5mdW5jdGlvbiBjb250aW51b3VzKGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUpIHtcbiAgdmFyIGRvbWFpbiA9IHVuaXQsXG4gICAgICByYW5nZSQkMSA9IHVuaXQsXG4gICAgICBpbnRlcnBvbGF0ZSQkMSA9IGludGVycG9sYXRlVmFsdWUsXG4gICAgICBjbGFtcCA9IGZhbHNlLFxuICAgICAgcGllY2V3aXNlLFxuICAgICAgb3V0cHV0LFxuICAgICAgaW5wdXQ7XG5cbiAgZnVuY3Rpb24gcmVzY2FsZSgpIHtcbiAgICBwaWVjZXdpc2UgPSBNYXRoLm1pbihkb21haW4ubGVuZ3RoLCByYW5nZSQkMS5sZW5ndGgpID4gMiA/IHBvbHltYXAgOiBiaW1hcDtcbiAgICBvdXRwdXQgPSBpbnB1dCA9IG51bGw7XG4gICAgcmV0dXJuIHNjYWxlO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIHJldHVybiAob3V0cHV0IHx8IChvdXRwdXQgPSBwaWVjZXdpc2UoZG9tYWluLCByYW5nZSQkMSwgY2xhbXAgPyBkZWludGVycG9sYXRlQ2xhbXAoZGVpbnRlcnBvbGF0ZSkgOiBkZWludGVycG9sYXRlLCBpbnRlcnBvbGF0ZSQkMSkpKSgreCk7XG4gIH1cblxuICBzY2FsZS5pbnZlcnQgPSBmdW5jdGlvbih5KSB7XG4gICAgcmV0dXJuIChpbnB1dCB8fCAoaW5wdXQgPSBwaWVjZXdpc2UocmFuZ2UkJDEsIGRvbWFpbiwgZGVpbnRlcnBvbGF0ZUxpbmVhciwgY2xhbXAgPyByZWludGVycG9sYXRlQ2xhbXAocmVpbnRlcnBvbGF0ZSkgOiByZWludGVycG9sYXRlKSkpKCt5KTtcbiAgfTtcblxuICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZG9tYWluID0gbWFwJDMuY2FsbChfLCBudW1iZXIkMSksIHJlc2NhbGUoKSkgOiBkb21haW4uc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSQkMSA9IHNsaWNlJDQuY2FsbChfKSwgcmVzY2FsZSgpKSA6IHJhbmdlJCQxLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUucmFuZ2VSb3VuZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gcmFuZ2UkJDEgPSBzbGljZSQ0LmNhbGwoXyksIGludGVycG9sYXRlJCQxID0gaW50ZXJwb2xhdGVSb3VuZCwgcmVzY2FsZSgpO1xuICB9O1xuXG4gIHNjYWxlLmNsYW1wID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNsYW1wID0gISFfLCByZXNjYWxlKCkpIDogY2xhbXA7XG4gIH07XG5cbiAgc2NhbGUuaW50ZXJwb2xhdGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaW50ZXJwb2xhdGUkJDEgPSBfLCByZXNjYWxlKCkpIDogaW50ZXJwb2xhdGUkJDE7XG4gIH07XG5cbiAgcmV0dXJuIHJlc2NhbGUoKTtcbn1cblxudmFyIHRpY2tGb3JtYXQgPSBmdW5jdGlvbihkb21haW4sIGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgdmFyIHN0YXJ0ID0gZG9tYWluWzBdLFxuICAgICAgc3RvcCA9IGRvbWFpbltkb21haW4ubGVuZ3RoIC0gMV0sXG4gICAgICBzdGVwID0gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIGNvdW50ID09IG51bGwgPyAxMCA6IGNvdW50KSxcbiAgICAgIHByZWNpc2lvbjtcbiAgc3BlY2lmaWVyID0gZm9ybWF0U3BlY2lmaWVyKHNwZWNpZmllciA9PSBudWxsID8gXCIsZlwiIDogc3BlY2lmaWVyKTtcbiAgc3dpdGNoIChzcGVjaWZpZXIudHlwZSkge1xuICAgIGNhc2UgXCJzXCI6IHtcbiAgICAgIHZhciB2YWx1ZSA9IE1hdGgubWF4KE1hdGguYWJzKHN0YXJ0KSwgTWF0aC5hYnMoc3RvcCkpO1xuICAgICAgaWYgKHNwZWNpZmllci5wcmVjaXNpb24gPT0gbnVsbCAmJiAhaXNOYU4ocHJlY2lzaW9uID0gcHJlY2lzaW9uUHJlZml4KHN0ZXAsIHZhbHVlKSkpIHNwZWNpZmllci5wcmVjaXNpb24gPSBwcmVjaXNpb247XG4gICAgICByZXR1cm4gZXhwb3J0cy5mb3JtYXRQcmVmaXgoc3BlY2lmaWVyLCB2YWx1ZSk7XG4gICAgfVxuICAgIGNhc2UgXCJcIjpcbiAgICBjYXNlIFwiZVwiOlxuICAgIGNhc2UgXCJnXCI6XG4gICAgY2FzZSBcInBcIjpcbiAgICBjYXNlIFwiclwiOiB7XG4gICAgICBpZiAoc3BlY2lmaWVyLnByZWNpc2lvbiA9PSBudWxsICYmICFpc05hTihwcmVjaXNpb24gPSBwcmVjaXNpb25Sb3VuZChzdGVwLCBNYXRoLm1heChNYXRoLmFicyhzdGFydCksIE1hdGguYWJzKHN0b3ApKSkpKSBzcGVjaWZpZXIucHJlY2lzaW9uID0gcHJlY2lzaW9uIC0gKHNwZWNpZmllci50eXBlID09PSBcImVcIik7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSBcImZcIjpcbiAgICBjYXNlIFwiJVwiOiB7XG4gICAgICBpZiAoc3BlY2lmaWVyLnByZWNpc2lvbiA9PSBudWxsICYmICFpc05hTihwcmVjaXNpb24gPSBwcmVjaXNpb25GaXhlZChzdGVwKSkpIHNwZWNpZmllci5wcmVjaXNpb24gPSBwcmVjaXNpb24gLSAoc3BlY2lmaWVyLnR5cGUgPT09IFwiJVwiKSAqIDI7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4cG9ydHMuZm9ybWF0KHNwZWNpZmllcik7XG59O1xuXG5mdW5jdGlvbiBsaW5lYXJpc2goc2NhbGUpIHtcbiAgdmFyIGRvbWFpbiA9IHNjYWxlLmRvbWFpbjtcblxuICBzY2FsZS50aWNrcyA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgdmFyIGQgPSBkb21haW4oKTtcbiAgICByZXR1cm4gdGlja3MoZFswXSwgZFtkLmxlbmd0aCAtIDFdLCBjb3VudCA9PSBudWxsID8gMTAgOiBjb3VudCk7XG4gIH07XG5cbiAgc2NhbGUudGlja0Zvcm1hdCA9IGZ1bmN0aW9uKGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgICByZXR1cm4gdGlja0Zvcm1hdChkb21haW4oKSwgY291bnQsIHNwZWNpZmllcik7XG4gIH07XG5cbiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgdmFyIGQgPSBkb21haW4oKSxcbiAgICAgICAgaSA9IGQubGVuZ3RoIC0gMSxcbiAgICAgICAgbiA9IGNvdW50ID09IG51bGwgPyAxMCA6IGNvdW50LFxuICAgICAgICBzdGFydCA9IGRbMF0sXG4gICAgICAgIHN0b3AgPSBkW2ldLFxuICAgICAgICBzdGVwID0gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIG4pO1xuXG4gICAgaWYgKHN0ZXApIHtcbiAgICAgIHN0ZXAgPSB0aWNrU3RlcChNYXRoLmZsb29yKHN0YXJ0IC8gc3RlcCkgKiBzdGVwLCBNYXRoLmNlaWwoc3RvcCAvIHN0ZXApICogc3RlcCwgbik7XG4gICAgICBkWzBdID0gTWF0aC5mbG9vcihzdGFydCAvIHN0ZXApICogc3RlcDtcbiAgICAgIGRbaV0gPSBNYXRoLmNlaWwoc3RvcCAvIHN0ZXApICogc3RlcDtcbiAgICAgIGRvbWFpbihkKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2NhbGU7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG5mdW5jdGlvbiBsaW5lYXIkMigpIHtcbiAgdmFyIHNjYWxlID0gY29udGludW91cyhkZWludGVycG9sYXRlTGluZWFyLCByZWludGVycG9sYXRlKTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGNvcHkoc2NhbGUsIGxpbmVhciQyKCkpO1xuICB9O1xuXG4gIHJldHVybiBsaW5lYXJpc2goc2NhbGUpO1xufVxuXG5mdW5jdGlvbiBpZGVudGl0eSQ2KCkge1xuICB2YXIgZG9tYWluID0gWzAsIDFdO1xuXG4gIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICByZXR1cm4gK3g7XG4gIH1cblxuICBzY2FsZS5pbnZlcnQgPSBzY2FsZTtcblxuICBzY2FsZS5kb21haW4gPSBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4gPSBtYXAkMy5jYWxsKF8sIG51bWJlciQxKSwgc2NhbGUpIDogZG9tYWluLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBpZGVudGl0eSQ2KCkuZG9tYWluKGRvbWFpbik7XG4gIH07XG5cbiAgcmV0dXJuIGxpbmVhcmlzaChzY2FsZSk7XG59XG5cbnZhciBuaWNlID0gZnVuY3Rpb24oZG9tYWluLCBpbnRlcnZhbCkge1xuICBkb21haW4gPSBkb21haW4uc2xpY2UoKTtcblxuICB2YXIgaTAgPSAwLFxuICAgICAgaTEgPSBkb21haW4ubGVuZ3RoIC0gMSxcbiAgICAgIHgwID0gZG9tYWluW2kwXSxcbiAgICAgIHgxID0gZG9tYWluW2kxXSxcbiAgICAgIHQ7XG5cbiAgaWYgKHgxIDwgeDApIHtcbiAgICB0ID0gaTAsIGkwID0gaTEsIGkxID0gdDtcbiAgICB0ID0geDAsIHgwID0geDEsIHgxID0gdDtcbiAgfVxuXG4gIGRvbWFpbltpMF0gPSBpbnRlcnZhbC5mbG9vcih4MCk7XG4gIGRvbWFpbltpMV0gPSBpbnRlcnZhbC5jZWlsKHgxKTtcbiAgcmV0dXJuIGRvbWFpbjtcbn07XG5cbmZ1bmN0aW9uIGRlaW50ZXJwb2xhdGUoYSwgYikge1xuICByZXR1cm4gKGIgPSBNYXRoLmxvZyhiIC8gYSkpXG4gICAgICA/IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgubG9nKHggLyBhKSAvIGI7IH1cbiAgICAgIDogY29uc3RhbnQkOShiKTtcbn1cblxuZnVuY3Rpb24gcmVpbnRlcnBvbGF0ZSQxKGEsIGIpIHtcbiAgcmV0dXJuIGEgPCAwXG4gICAgICA/IGZ1bmN0aW9uKHQpIHsgcmV0dXJuIC1NYXRoLnBvdygtYiwgdCkgKiBNYXRoLnBvdygtYSwgMSAtIHQpOyB9XG4gICAgICA6IGZ1bmN0aW9uKHQpIHsgcmV0dXJuIE1hdGgucG93KGIsIHQpICogTWF0aC5wb3coYSwgMSAtIHQpOyB9O1xufVxuXG5mdW5jdGlvbiBwb3cxMCh4KSB7XG4gIHJldHVybiBpc0Zpbml0ZSh4KSA/ICsoXCIxZVwiICsgeCkgOiB4IDwgMCA/IDAgOiB4O1xufVxuXG5mdW5jdGlvbiBwb3dwKGJhc2UpIHtcbiAgcmV0dXJuIGJhc2UgPT09IDEwID8gcG93MTBcbiAgICAgIDogYmFzZSA9PT0gTWF0aC5FID8gTWF0aC5leHBcbiAgICAgIDogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5wb3coYmFzZSwgeCk7IH07XG59XG5cbmZ1bmN0aW9uIGxvZ3AoYmFzZSkge1xuICByZXR1cm4gYmFzZSA9PT0gTWF0aC5FID8gTWF0aC5sb2dcbiAgICAgIDogYmFzZSA9PT0gMTAgJiYgTWF0aC5sb2cxMFxuICAgICAgfHwgYmFzZSA9PT0gMiAmJiBNYXRoLmxvZzJcbiAgICAgIHx8IChiYXNlID0gTWF0aC5sb2coYmFzZSksIGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgubG9nKHgpIC8gYmFzZTsgfSk7XG59XG5cbmZ1bmN0aW9uIHJlZmxlY3QoZikge1xuICByZXR1cm4gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiAtZigteCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGxvZyQxKCkge1xuICB2YXIgc2NhbGUgPSBjb250aW51b3VzKGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUkMSkuZG9tYWluKFsxLCAxMF0pLFxuICAgICAgZG9tYWluID0gc2NhbGUuZG9tYWluLFxuICAgICAgYmFzZSA9IDEwLFxuICAgICAgbG9ncyA9IGxvZ3AoMTApLFxuICAgICAgcG93cyA9IHBvd3AoMTApO1xuXG4gIGZ1bmN0aW9uIHJlc2NhbGUoKSB7XG4gICAgbG9ncyA9IGxvZ3AoYmFzZSksIHBvd3MgPSBwb3dwKGJhc2UpO1xuICAgIGlmIChkb21haW4oKVswXSA8IDApIGxvZ3MgPSByZWZsZWN0KGxvZ3MpLCBwb3dzID0gcmVmbGVjdChwb3dzKTtcbiAgICByZXR1cm4gc2NhbGU7XG4gIH1cblxuICBzY2FsZS5iYXNlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGJhc2UgPSArXywgcmVzY2FsZSgpKSA6IGJhc2U7XG4gIH07XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbihfKSwgcmVzY2FsZSgpKSA6IGRvbWFpbigpO1xuICB9O1xuXG4gIHNjYWxlLnRpY2tzID0gZnVuY3Rpb24oY291bnQpIHtcbiAgICB2YXIgZCA9IGRvbWFpbigpLFxuICAgICAgICB1ID0gZFswXSxcbiAgICAgICAgdiA9IGRbZC5sZW5ndGggLSAxXSxcbiAgICAgICAgcjtcblxuICAgIGlmIChyID0gdiA8IHUpIGkgPSB1LCB1ID0gdiwgdiA9IGk7XG5cbiAgICB2YXIgaSA9IGxvZ3ModSksXG4gICAgICAgIGogPSBsb2dzKHYpLFxuICAgICAgICBwLFxuICAgICAgICBrLFxuICAgICAgICB0LFxuICAgICAgICBuID0gY291bnQgPT0gbnVsbCA/IDEwIDogK2NvdW50LFxuICAgICAgICB6ID0gW107XG5cbiAgICBpZiAoIShiYXNlICUgMSkgJiYgaiAtIGkgPCBuKSB7XG4gICAgICBpID0gTWF0aC5yb3VuZChpKSAtIDEsIGogPSBNYXRoLnJvdW5kKGopICsgMTtcbiAgICAgIGlmICh1ID4gMCkgZm9yICg7IGkgPCBqOyArK2kpIHtcbiAgICAgICAgZm9yIChrID0gMSwgcCA9IHBvd3MoaSk7IGsgPCBiYXNlOyArK2spIHtcbiAgICAgICAgICB0ID0gcCAqIGs7XG4gICAgICAgICAgaWYgKHQgPCB1KSBjb250aW51ZTtcbiAgICAgICAgICBpZiAodCA+IHYpIGJyZWFrO1xuICAgICAgICAgIHoucHVzaCh0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGZvciAoOyBpIDwgajsgKytpKSB7XG4gICAgICAgIGZvciAoayA9IGJhc2UgLSAxLCBwID0gcG93cyhpKTsgayA+PSAxOyAtLWspIHtcbiAgICAgICAgICB0ID0gcCAqIGs7XG4gICAgICAgICAgaWYgKHQgPCB1KSBjb250aW51ZTtcbiAgICAgICAgICBpZiAodCA+IHYpIGJyZWFrO1xuICAgICAgICAgIHoucHVzaCh0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB6ID0gdGlja3MoaSwgaiwgTWF0aC5taW4oaiAtIGksIG4pKS5tYXAocG93cyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHIgPyB6LnJldmVyc2UoKSA6IHo7XG4gIH07XG5cbiAgc2NhbGUudGlja0Zvcm1hdCA9IGZ1bmN0aW9uKGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgICBpZiAoc3BlY2lmaWVyID09IG51bGwpIHNwZWNpZmllciA9IGJhc2UgPT09IDEwID8gXCIuMGVcIiA6IFwiLFwiO1xuICAgIGlmICh0eXBlb2Ygc3BlY2lmaWVyICE9PSBcImZ1bmN0aW9uXCIpIHNwZWNpZmllciA9IGV4cG9ydHMuZm9ybWF0KHNwZWNpZmllcik7XG4gICAgaWYgKGNvdW50ID09PSBJbmZpbml0eSkgcmV0dXJuIHNwZWNpZmllcjtcbiAgICBpZiAoY291bnQgPT0gbnVsbCkgY291bnQgPSAxMDtcbiAgICB2YXIgayA9IE1hdGgubWF4KDEsIGJhc2UgKiBjb3VudCAvIHNjYWxlLnRpY2tzKCkubGVuZ3RoKTsgLy8gVE9ETyBmYXN0IGVzdGltYXRlP1xuICAgIHJldHVybiBmdW5jdGlvbihkKSB7XG4gICAgICB2YXIgaSA9IGQgLyBwb3dzKE1hdGgucm91bmQobG9ncyhkKSkpO1xuICAgICAgaWYgKGkgKiBiYXNlIDwgYmFzZSAtIDAuNSkgaSAqPSBiYXNlO1xuICAgICAgcmV0dXJuIGkgPD0gayA/IHNwZWNpZmllcihkKSA6IFwiXCI7XG4gICAgfTtcbiAgfTtcblxuICBzY2FsZS5uaWNlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGRvbWFpbihuaWNlKGRvbWFpbigpLCB7XG4gICAgICBmbG9vcjogZnVuY3Rpb24oeCkgeyByZXR1cm4gcG93cyhNYXRoLmZsb29yKGxvZ3MoeCkpKTsgfSxcbiAgICAgIGNlaWw6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHBvd3MoTWF0aC5jZWlsKGxvZ3MoeCkpKTsgfVxuICAgIH0pKTtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGNvcHkoc2NhbGUsIGxvZyQxKCkuYmFzZShiYXNlKSk7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG5mdW5jdGlvbiByYWlzZSQxKHgsIGV4cG9uZW50KSB7XG4gIHJldHVybiB4IDwgMCA/IC1NYXRoLnBvdygteCwgZXhwb25lbnQpIDogTWF0aC5wb3coeCwgZXhwb25lbnQpO1xufVxuXG5mdW5jdGlvbiBwb3ckMSgpIHtcbiAgdmFyIGV4cG9uZW50ID0gMSxcbiAgICAgIHNjYWxlID0gY29udGludW91cyhkZWludGVycG9sYXRlLCByZWludGVycG9sYXRlKSxcbiAgICAgIGRvbWFpbiA9IHNjYWxlLmRvbWFpbjtcblxuICBmdW5jdGlvbiBkZWludGVycG9sYXRlKGEsIGIpIHtcbiAgICByZXR1cm4gKGIgPSByYWlzZSQxKGIsIGV4cG9uZW50KSAtIChhID0gcmFpc2UkMShhLCBleHBvbmVudCkpKVxuICAgICAgICA/IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIChyYWlzZSQxKHgsIGV4cG9uZW50KSAtIGEpIC8gYjsgfVxuICAgICAgICA6IGNvbnN0YW50JDkoYik7XG4gIH1cblxuICBmdW5jdGlvbiByZWludGVycG9sYXRlKGEsIGIpIHtcbiAgICBiID0gcmFpc2UkMShiLCBleHBvbmVudCkgLSAoYSA9IHJhaXNlJDEoYSwgZXhwb25lbnQpKTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkgeyByZXR1cm4gcmFpc2UkMShhICsgYiAqIHQsIDEgLyBleHBvbmVudCk7IH07XG4gIH1cblxuICBzY2FsZS5leHBvbmVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChleHBvbmVudCA9ICtfLCBkb21haW4oZG9tYWluKCkpKSA6IGV4cG9uZW50O1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gY29weShzY2FsZSwgcG93JDEoKS5leHBvbmVudChleHBvbmVudCkpO1xuICB9O1xuXG4gIHJldHVybiBsaW5lYXJpc2goc2NhbGUpO1xufVxuXG5mdW5jdGlvbiBzcXJ0JDEoKSB7XG4gIHJldHVybiBwb3ckMSgpLmV4cG9uZW50KDAuNSk7XG59XG5cbmZ1bmN0aW9uIHF1YW50aWxlJCQxKCkge1xuICB2YXIgZG9tYWluID0gW10sXG4gICAgICByYW5nZSQkMSA9IFtdLFxuICAgICAgdGhyZXNob2xkcyA9IFtdO1xuXG4gIGZ1bmN0aW9uIHJlc2NhbGUoKSB7XG4gICAgdmFyIGkgPSAwLCBuID0gTWF0aC5tYXgoMSwgcmFuZ2UkJDEubGVuZ3RoKTtcbiAgICB0aHJlc2hvbGRzID0gbmV3IEFycmF5KG4gLSAxKTtcbiAgICB3aGlsZSAoKytpIDwgbikgdGhyZXNob2xkc1tpIC0gMV0gPSB0aHJlc2hvbGQoZG9tYWluLCBpIC8gbik7XG4gICAgcmV0dXJuIHNjYWxlO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIGlmICghaXNOYU4oeCA9ICt4KSkgcmV0dXJuIHJhbmdlJCQxW2Jpc2VjdFJpZ2h0KHRocmVzaG9sZHMsIHgpXTtcbiAgfVxuXG4gIHNjYWxlLmludmVydEV4dGVudCA9IGZ1bmN0aW9uKHkpIHtcbiAgICB2YXIgaSA9IHJhbmdlJCQxLmluZGV4T2YoeSk7XG4gICAgcmV0dXJuIGkgPCAwID8gW05hTiwgTmFOXSA6IFtcbiAgICAgIGkgPiAwID8gdGhyZXNob2xkc1tpIC0gMV0gOiBkb21haW5bMF0sXG4gICAgICBpIDwgdGhyZXNob2xkcy5sZW5ndGggPyB0aHJlc2hvbGRzW2ldIDogZG9tYWluW2RvbWFpbi5sZW5ndGggLSAxXVxuICAgIF07XG4gIH07XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGRvbWFpbi5zbGljZSgpO1xuICAgIGRvbWFpbiA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gXy5sZW5ndGgsIGQ7IGkgPCBuOyArK2kpIGlmIChkID0gX1tpXSwgZCAhPSBudWxsICYmICFpc05hTihkID0gK2QpKSBkb21haW4ucHVzaChkKTtcbiAgICBkb21haW4uc29ydChhc2NlbmRpbmcpO1xuICAgIHJldHVybiByZXNjYWxlKCk7XG4gIH07XG5cbiAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFuZ2UkJDEgPSBzbGljZSQ0LmNhbGwoXyksIHJlc2NhbGUoKSkgOiByYW5nZSQkMS5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLnF1YW50aWxlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aHJlc2hvbGRzLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBxdWFudGlsZSQkMSgpXG4gICAgICAgIC5kb21haW4oZG9tYWluKVxuICAgICAgICAucmFuZ2UocmFuZ2UkJDEpO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxuZnVuY3Rpb24gcXVhbnRpemUkMSgpIHtcbiAgdmFyIHgwID0gMCxcbiAgICAgIHgxID0gMSxcbiAgICAgIG4gPSAxLFxuICAgICAgZG9tYWluID0gWzAuNV0sXG4gICAgICByYW5nZSQkMSA9IFswLCAxXTtcblxuICBmdW5jdGlvbiBzY2FsZSh4KSB7XG4gICAgaWYgKHggPD0geCkgcmV0dXJuIHJhbmdlJCQxW2Jpc2VjdFJpZ2h0KGRvbWFpbiwgeCwgMCwgbildO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzY2FsZSgpIHtcbiAgICB2YXIgaSA9IC0xO1xuICAgIGRvbWFpbiA9IG5ldyBBcnJheShuKTtcbiAgICB3aGlsZSAoKytpIDwgbikgZG9tYWluW2ldID0gKChpICsgMSkgKiB4MSAtIChpIC0gbikgKiB4MCkgLyAobiArIDEpO1xuICAgIHJldHVybiBzY2FsZTtcbiAgfVxuXG4gIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MCA9ICtfWzBdLCB4MSA9ICtfWzFdLCByZXNjYWxlKCkpIDogW3gwLCB4MV07XG4gIH07XG5cbiAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAobiA9IChyYW5nZSQkMSA9IHNsaWNlJDQuY2FsbChfKSkubGVuZ3RoIC0gMSwgcmVzY2FsZSgpKSA6IHJhbmdlJCQxLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUuaW52ZXJ0RXh0ZW50ID0gZnVuY3Rpb24oeSkge1xuICAgIHZhciBpID0gcmFuZ2UkJDEuaW5kZXhPZih5KTtcbiAgICByZXR1cm4gaSA8IDAgPyBbTmFOLCBOYU5dXG4gICAgICAgIDogaSA8IDEgPyBbeDAsIGRvbWFpblswXV1cbiAgICAgICAgOiBpID49IG4gPyBbZG9tYWluW24gLSAxXSwgeDFdXG4gICAgICAgIDogW2RvbWFpbltpIC0gMV0sIGRvbWFpbltpXV07XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBxdWFudGl6ZSQxKClcbiAgICAgICAgLmRvbWFpbihbeDAsIHgxXSlcbiAgICAgICAgLnJhbmdlKHJhbmdlJCQxKTtcbiAgfTtcblxuICByZXR1cm4gbGluZWFyaXNoKHNjYWxlKTtcbn1cblxuZnVuY3Rpb24gdGhyZXNob2xkJDEoKSB7XG4gIHZhciBkb21haW4gPSBbMC41XSxcbiAgICAgIHJhbmdlJCQxID0gWzAsIDFdLFxuICAgICAgbiA9IDE7XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIGlmICh4IDw9IHgpIHJldHVybiByYW5nZSQkMVtiaXNlY3RSaWdodChkb21haW4sIHgsIDAsIG4pXTtcbiAgfVxuXG4gIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4gPSBzbGljZSQ0LmNhbGwoXyksIG4gPSBNYXRoLm1pbihkb21haW4ubGVuZ3RoLCByYW5nZSQkMS5sZW5ndGggLSAxKSwgc2NhbGUpIDogZG9tYWluLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFuZ2UkJDEgPSBzbGljZSQ0LmNhbGwoXyksIG4gPSBNYXRoLm1pbihkb21haW4ubGVuZ3RoLCByYW5nZSQkMS5sZW5ndGggLSAxKSwgc2NhbGUpIDogcmFuZ2UkJDEuc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5pbnZlcnRFeHRlbnQgPSBmdW5jdGlvbih5KSB7XG4gICAgdmFyIGkgPSByYW5nZSQkMS5pbmRleE9mKHkpO1xuICAgIHJldHVybiBbZG9tYWluW2kgLSAxXSwgZG9tYWluW2ldXTtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRocmVzaG9sZCQxKClcbiAgICAgICAgLmRvbWFpbihkb21haW4pXG4gICAgICAgIC5yYW5nZShyYW5nZSQkMSk7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG52YXIgdDAkMSA9IG5ldyBEYXRlO1xudmFyIHQxJDEgPSBuZXcgRGF0ZTtcblxuZnVuY3Rpb24gbmV3SW50ZXJ2YWwoZmxvb3JpLCBvZmZzZXRpLCBjb3VudCwgZmllbGQpIHtcblxuICBmdW5jdGlvbiBpbnRlcnZhbChkYXRlKSB7XG4gICAgcmV0dXJuIGZsb29yaShkYXRlID0gbmV3IERhdGUoK2RhdGUpKSwgZGF0ZTtcbiAgfVxuXG4gIGludGVydmFsLmZsb29yID0gaW50ZXJ2YWw7XG5cbiAgaW50ZXJ2YWwuY2VpbCA9IGZ1bmN0aW9uKGRhdGUpIHtcbiAgICByZXR1cm4gZmxvb3JpKGRhdGUgPSBuZXcgRGF0ZShkYXRlIC0gMSkpLCBvZmZzZXRpKGRhdGUsIDEpLCBmbG9vcmkoZGF0ZSksIGRhdGU7XG4gIH07XG5cbiAgaW50ZXJ2YWwucm91bmQgPSBmdW5jdGlvbihkYXRlKSB7XG4gICAgdmFyIGQwID0gaW50ZXJ2YWwoZGF0ZSksXG4gICAgICAgIGQxID0gaW50ZXJ2YWwuY2VpbChkYXRlKTtcbiAgICByZXR1cm4gZGF0ZSAtIGQwIDwgZDEgLSBkYXRlID8gZDAgOiBkMTtcbiAgfTtcblxuICBpbnRlcnZhbC5vZmZzZXQgPSBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgcmV0dXJuIG9mZnNldGkoZGF0ZSA9IG5ldyBEYXRlKCtkYXRlKSwgc3RlcCA9PSBudWxsID8gMSA6IE1hdGguZmxvb3Ioc3RlcCkpLCBkYXRlO1xuICB9O1xuXG4gIGludGVydmFsLnJhbmdlID0gZnVuY3Rpb24oc3RhcnQsIHN0b3AsIHN0ZXApIHtcbiAgICB2YXIgcmFuZ2UgPSBbXTtcbiAgICBzdGFydCA9IGludGVydmFsLmNlaWwoc3RhcnQpO1xuICAgIHN0ZXAgPSBzdGVwID09IG51bGwgPyAxIDogTWF0aC5mbG9vcihzdGVwKTtcbiAgICBpZiAoIShzdGFydCA8IHN0b3ApIHx8ICEoc3RlcCA+IDApKSByZXR1cm4gcmFuZ2U7IC8vIGFsc28gaGFuZGxlcyBJbnZhbGlkIERhdGVcbiAgICBkbyByYW5nZS5wdXNoKG5ldyBEYXRlKCtzdGFydCkpOyB3aGlsZSAob2Zmc2V0aShzdGFydCwgc3RlcCksIGZsb29yaShzdGFydCksIHN0YXJ0IDwgc3RvcClcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH07XG5cbiAgaW50ZXJ2YWwuZmlsdGVyID0gZnVuY3Rpb24odGVzdCkge1xuICAgIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgICBpZiAoZGF0ZSA+PSBkYXRlKSB3aGlsZSAoZmxvb3JpKGRhdGUpLCAhdGVzdChkYXRlKSkgZGF0ZS5zZXRUaW1lKGRhdGUgLSAxKTtcbiAgICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgICBpZiAoZGF0ZSA+PSBkYXRlKSB3aGlsZSAoLS1zdGVwID49IDApIHdoaWxlIChvZmZzZXRpKGRhdGUsIDEpLCAhdGVzdChkYXRlKSkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1lbXB0eVxuICAgIH0pO1xuICB9O1xuXG4gIGlmIChjb3VudCkge1xuICAgIGludGVydmFsLmNvdW50ID0gZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgICAgdDAkMS5zZXRUaW1lKCtzdGFydCksIHQxJDEuc2V0VGltZSgrZW5kKTtcbiAgICAgIGZsb29yaSh0MCQxKSwgZmxvb3JpKHQxJDEpO1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoY291bnQodDAkMSwgdDEkMSkpO1xuICAgIH07XG5cbiAgICBpbnRlcnZhbC5ldmVyeSA9IGZ1bmN0aW9uKHN0ZXApIHtcbiAgICAgIHN0ZXAgPSBNYXRoLmZsb29yKHN0ZXApO1xuICAgICAgcmV0dXJuICFpc0Zpbml0ZShzdGVwKSB8fCAhKHN0ZXAgPiAwKSA/IG51bGxcbiAgICAgICAgICA6ICEoc3RlcCA+IDEpID8gaW50ZXJ2YWxcbiAgICAgICAgICA6IGludGVydmFsLmZpbHRlcihmaWVsZFxuICAgICAgICAgICAgICA/IGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGZpZWxkKGQpICUgc3RlcCA9PT0gMDsgfVxuICAgICAgICAgICAgICA6IGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGludGVydmFsLmNvdW50KDAsIGQpICUgc3RlcCA9PT0gMDsgfSk7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBpbnRlcnZhbDtcbn1cblxudmFyIG1pbGxpc2Vjb25kID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oKSB7XG4gIC8vIG5vb3Bcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgc3RlcCk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiBlbmQgLSBzdGFydDtcbn0pO1xuXG4vLyBBbiBvcHRpbWl6ZWQgaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgc2ltcGxlIGNhc2UuXG5taWxsaXNlY29uZC5ldmVyeSA9IGZ1bmN0aW9uKGspIHtcbiAgayA9IE1hdGguZmxvb3Ioayk7XG4gIGlmICghaXNGaW5pdGUoaykgfHwgIShrID4gMCkpIHJldHVybiBudWxsO1xuICBpZiAoIShrID4gMSkpIHJldHVybiBtaWxsaXNlY29uZDtcbiAgcmV0dXJuIG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldFRpbWUoTWF0aC5mbG9vcihkYXRlIC8gaykgKiBrKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXAgKiBrKTtcbiAgfSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gaztcbiAgfSk7XG59O1xuXG52YXIgbWlsbGlzZWNvbmRzID0gbWlsbGlzZWNvbmQucmFuZ2U7XG5cbnZhciBkdXJhdGlvblNlY29uZCQxID0gMWUzO1xudmFyIGR1cmF0aW9uTWludXRlJDEgPSA2ZTQ7XG52YXIgZHVyYXRpb25Ib3VyJDEgPSAzNmU1O1xudmFyIGR1cmF0aW9uRGF5JDEgPSA4NjRlNTtcbnZhciBkdXJhdGlvbldlZWskMSA9IDYwNDhlNTtcblxudmFyIHNlY29uZCA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRUaW1lKE1hdGguZmxvb3IoZGF0ZSAvIGR1cmF0aW9uU2Vjb25kJDEpICogZHVyYXRpb25TZWNvbmQkMSk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXAgKiBkdXJhdGlvblNlY29uZCQxKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBkdXJhdGlvblNlY29uZCQxO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXRVVENTZWNvbmRzKCk7XG59KTtcblxudmFyIHNlY29uZHMgPSBzZWNvbmQucmFuZ2U7XG5cbnZhciBtaW51dGUgPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gIGRhdGUuc2V0VGltZShNYXRoLmZsb29yKGRhdGUgLyBkdXJhdGlvbk1pbnV0ZSQxKSAqIGR1cmF0aW9uTWludXRlJDEpO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogZHVyYXRpb25NaW51dGUkMSk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gZHVyYXRpb25NaW51dGUkMTtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0TWludXRlcygpO1xufSk7XG5cbnZhciBtaW51dGVzID0gbWludXRlLnJhbmdlO1xuXG52YXIgaG91ciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgdmFyIG9mZnNldCA9IGRhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIGR1cmF0aW9uTWludXRlJDEgJSBkdXJhdGlvbkhvdXIkMTtcbiAgaWYgKG9mZnNldCA8IDApIG9mZnNldCArPSBkdXJhdGlvbkhvdXIkMTtcbiAgZGF0ZS5zZXRUaW1lKE1hdGguZmxvb3IoKCtkYXRlIC0gb2Zmc2V0KSAvIGR1cmF0aW9uSG91ciQxKSAqIGR1cmF0aW9uSG91ciQxICsgb2Zmc2V0KTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgc3RlcCAqIGR1cmF0aW9uSG91ciQxKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBkdXJhdGlvbkhvdXIkMTtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0SG91cnMoKTtcbn0pO1xuXG52YXIgaG91cnMgPSBob3VyLnJhbmdlO1xuXG52YXIgZGF5ID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCAtIChlbmQuZ2V0VGltZXpvbmVPZmZzZXQoKSAtIHN0YXJ0LmdldFRpbWV6b25lT2Zmc2V0KCkpICogZHVyYXRpb25NaW51dGUkMSkgLyBkdXJhdGlvbkRheSQxO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXREYXRlKCkgLSAxO1xufSk7XG5cbnZhciBkYXlzID0gZGF5LnJhbmdlO1xuXG5mdW5jdGlvbiB3ZWVrZGF5KGkpIHtcbiAgcmV0dXJuIG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgLSAoZGF0ZS5nZXREYXkoKSArIDcgLSBpKSAlIDcpO1xuICAgIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBzdGVwICogNyk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKGVuZCAtIHN0YXJ0IC0gKGVuZC5nZXRUaW1lem9uZU9mZnNldCgpIC0gc3RhcnQuZ2V0VGltZXpvbmVPZmZzZXQoKSkgKiBkdXJhdGlvbk1pbnV0ZSQxKSAvIGR1cmF0aW9uV2VlayQxO1xuICB9KTtcbn1cblxudmFyIHN1bmRheSA9IHdlZWtkYXkoMCk7XG52YXIgbW9uZGF5ID0gd2Vla2RheSgxKTtcbnZhciB0dWVzZGF5ID0gd2Vla2RheSgyKTtcbnZhciB3ZWRuZXNkYXkgPSB3ZWVrZGF5KDMpO1xudmFyIHRodXJzZGF5ID0gd2Vla2RheSg0KTtcbnZhciBmcmlkYXkgPSB3ZWVrZGF5KDUpO1xudmFyIHNhdHVyZGF5ID0gd2Vla2RheSg2KTtcblxudmFyIHN1bmRheXMgPSBzdW5kYXkucmFuZ2U7XG52YXIgbW9uZGF5cyA9IG1vbmRheS5yYW5nZTtcbnZhciB0dWVzZGF5cyA9IHR1ZXNkYXkucmFuZ2U7XG52YXIgd2VkbmVzZGF5cyA9IHdlZG5lc2RheS5yYW5nZTtcbnZhciB0aHVyc2RheXMgPSB0aHVyc2RheS5yYW5nZTtcbnZhciBmcmlkYXlzID0gZnJpZGF5LnJhbmdlO1xudmFyIHNhdHVyZGF5cyA9IHNhdHVyZGF5LnJhbmdlO1xuXG52YXIgbW9udGggPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gIGRhdGUuc2V0RGF0ZSgxKTtcbiAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRNb250aChkYXRlLmdldE1vbnRoKCkgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIGVuZC5nZXRNb250aCgpIC0gc3RhcnQuZ2V0TW9udGgoKSArIChlbmQuZ2V0RnVsbFllYXIoKSAtIHN0YXJ0LmdldEZ1bGxZZWFyKCkpICogMTI7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldE1vbnRoKCk7XG59KTtcblxudmFyIG1vbnRocyA9IG1vbnRoLnJhbmdlO1xuXG52YXIgeWVhciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRNb250aCgwLCAxKTtcbiAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRGdWxsWWVhcihkYXRlLmdldEZ1bGxZZWFyKCkgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIGVuZC5nZXRGdWxsWWVhcigpIC0gc3RhcnQuZ2V0RnVsbFllYXIoKTtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKTtcbn0pO1xuXG4vLyBBbiBvcHRpbWl6ZWQgaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgc2ltcGxlIGNhc2UuXG55ZWFyLmV2ZXJ5ID0gZnVuY3Rpb24oaykge1xuICByZXR1cm4gIWlzRmluaXRlKGsgPSBNYXRoLmZsb29yKGspKSB8fCAhKGsgPiAwKSA/IG51bGwgOiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgZGF0ZS5zZXRGdWxsWWVhcihNYXRoLmZsb29yKGRhdGUuZ2V0RnVsbFllYXIoKSAvIGspICogayk7XG4gICAgZGF0ZS5zZXRNb250aCgwLCAxKTtcbiAgICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRGdWxsWWVhcihkYXRlLmdldEZ1bGxZZWFyKCkgKyBzdGVwICogayk7XG4gIH0pO1xufTtcblxudmFyIHllYXJzID0geWVhci5yYW5nZTtcblxudmFyIHV0Y01pbnV0ZSA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRVVENTZWNvbmRzKDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogZHVyYXRpb25NaW51dGUkMSk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gZHVyYXRpb25NaW51dGUkMTtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0VVRDTWludXRlcygpO1xufSk7XG5cbnZhciB1dGNNaW51dGVzID0gdXRjTWludXRlLnJhbmdlO1xuXG52YXIgdXRjSG91ciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRVVENNaW51dGVzKDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogZHVyYXRpb25Ib3VyJDEpO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIGR1cmF0aW9uSG91ciQxO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXRVVENIb3VycygpO1xufSk7XG5cbnZhciB1dGNIb3VycyA9IHV0Y0hvdXIucmFuZ2U7XG5cbnZhciB1dGNEYXkgPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gIGRhdGUuc2V0VVRDSG91cnMoMCwgMCwgMCwgMCk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0VVRDRGF0ZShkYXRlLmdldFVUQ0RhdGUoKSArIHN0ZXApO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIGR1cmF0aW9uRGF5JDE7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ0RhdGUoKSAtIDE7XG59KTtcblxudmFyIHV0Y0RheXMgPSB1dGNEYXkucmFuZ2U7XG5cbmZ1bmN0aW9uIHV0Y1dlZWtkYXkoaSkge1xuICByZXR1cm4gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0VVRDRGF0ZShkYXRlLmdldFVUQ0RhdGUoKSAtIChkYXRlLmdldFVUQ0RheSgpICsgNyAtIGkpICUgNyk7XG4gICAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VVRDRGF0ZShkYXRlLmdldFVUQ0RhdGUoKSArIHN0ZXAgKiA3KTtcbiAgfSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gZHVyYXRpb25XZWVrJDE7XG4gIH0pO1xufVxuXG52YXIgdXRjU3VuZGF5ID0gdXRjV2Vla2RheSgwKTtcbnZhciB1dGNNb25kYXkgPSB1dGNXZWVrZGF5KDEpO1xudmFyIHV0Y1R1ZXNkYXkgPSB1dGNXZWVrZGF5KDIpO1xudmFyIHV0Y1dlZG5lc2RheSA9IHV0Y1dlZWtkYXkoMyk7XG52YXIgdXRjVGh1cnNkYXkgPSB1dGNXZWVrZGF5KDQpO1xudmFyIHV0Y0ZyaWRheSA9IHV0Y1dlZWtkYXkoNSk7XG52YXIgdXRjU2F0dXJkYXkgPSB1dGNXZWVrZGF5KDYpO1xuXG52YXIgdXRjU3VuZGF5cyA9IHV0Y1N1bmRheS5yYW5nZTtcbnZhciB1dGNNb25kYXlzID0gdXRjTW9uZGF5LnJhbmdlO1xudmFyIHV0Y1R1ZXNkYXlzID0gdXRjVHVlc2RheS5yYW5nZTtcbnZhciB1dGNXZWRuZXNkYXlzID0gdXRjV2VkbmVzZGF5LnJhbmdlO1xudmFyIHV0Y1RodXJzZGF5cyA9IHV0Y1RodXJzZGF5LnJhbmdlO1xudmFyIHV0Y0ZyaWRheXMgPSB1dGNGcmlkYXkucmFuZ2U7XG52YXIgdXRjU2F0dXJkYXlzID0gdXRjU2F0dXJkYXkucmFuZ2U7XG5cbnZhciB1dGNNb250aCA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRVVENEYXRlKDEpO1xuICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFVUQ01vbnRoKGRhdGUuZ2V0VVRDTW9udGgoKSArIHN0ZXApO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gZW5kLmdldFVUQ01vbnRoKCkgLSBzdGFydC5nZXRVVENNb250aCgpICsgKGVuZC5nZXRVVENGdWxsWWVhcigpIC0gc3RhcnQuZ2V0VVRDRnVsbFllYXIoKSkgKiAxMjtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0VVRDTW9udGgoKTtcbn0pO1xuXG52YXIgdXRjTW9udGhzID0gdXRjTW9udGgucmFuZ2U7XG5cbnZhciB1dGNZZWFyID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldFVUQ01vbnRoKDAsIDEpO1xuICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFVUQ0Z1bGxZZWFyKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSArIHN0ZXApO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gZW5kLmdldFVUQ0Z1bGxZZWFyKCkgLSBzdGFydC5nZXRVVENGdWxsWWVhcigpO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXRVVENGdWxsWWVhcigpO1xufSk7XG5cbi8vIEFuIG9wdGltaXplZCBpbXBsZW1lbnRhdGlvbiBmb3IgdGhpcyBzaW1wbGUgY2FzZS5cbnV0Y1llYXIuZXZlcnkgPSBmdW5jdGlvbihrKSB7XG4gIHJldHVybiAhaXNGaW5pdGUoayA9IE1hdGguZmxvb3IoaykpIHx8ICEoayA+IDApID8gbnVsbCA6IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKE1hdGguZmxvb3IoZGF0ZS5nZXRVVENGdWxsWWVhcigpIC8gaykgKiBrKTtcbiAgICBkYXRlLnNldFVUQ01vbnRoKDAsIDEpO1xuICAgIGRhdGUuc2V0VVRDSG91cnMoMCwgMCwgMCwgMCk7XG4gIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSArIHN0ZXAgKiBrKTtcbiAgfSk7XG59O1xuXG52YXIgdXRjWWVhcnMgPSB1dGNZZWFyLnJhbmdlO1xuXG5mdW5jdGlvbiBsb2NhbERhdGUoZCkge1xuICBpZiAoMCA8PSBkLnkgJiYgZC55IDwgMTAwKSB7XG4gICAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgtMSwgZC5tLCBkLmQsIGQuSCwgZC5NLCBkLlMsIGQuTCk7XG4gICAgZGF0ZS5zZXRGdWxsWWVhcihkLnkpO1xuICAgIHJldHVybiBkYXRlO1xuICB9XG4gIHJldHVybiBuZXcgRGF0ZShkLnksIGQubSwgZC5kLCBkLkgsIGQuTSwgZC5TLCBkLkwpO1xufVxuXG5mdW5jdGlvbiB1dGNEYXRlKGQpIHtcbiAgaWYgKDAgPD0gZC55ICYmIGQueSA8IDEwMCkge1xuICAgIHZhciBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMoLTEsIGQubSwgZC5kLCBkLkgsIGQuTSwgZC5TLCBkLkwpKTtcbiAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKGQueSk7XG4gICAgcmV0dXJuIGRhdGU7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKGQueSwgZC5tLCBkLmQsIGQuSCwgZC5NLCBkLlMsIGQuTCkpO1xufVxuXG5mdW5jdGlvbiBuZXdZZWFyKHkpIHtcbiAgcmV0dXJuIHt5OiB5LCBtOiAwLCBkOiAxLCBIOiAwLCBNOiAwLCBTOiAwLCBMOiAwfTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0TG9jYWxlJDEobG9jYWxlKSB7XG4gIHZhciBsb2NhbGVfZGF0ZVRpbWUgPSBsb2NhbGUuZGF0ZVRpbWUsXG4gICAgICBsb2NhbGVfZGF0ZSA9IGxvY2FsZS5kYXRlLFxuICAgICAgbG9jYWxlX3RpbWUgPSBsb2NhbGUudGltZSxcbiAgICAgIGxvY2FsZV9wZXJpb2RzID0gbG9jYWxlLnBlcmlvZHMsXG4gICAgICBsb2NhbGVfd2Vla2RheXMgPSBsb2NhbGUuZGF5cyxcbiAgICAgIGxvY2FsZV9zaG9ydFdlZWtkYXlzID0gbG9jYWxlLnNob3J0RGF5cyxcbiAgICAgIGxvY2FsZV9tb250aHMgPSBsb2NhbGUubW9udGhzLFxuICAgICAgbG9jYWxlX3Nob3J0TW9udGhzID0gbG9jYWxlLnNob3J0TW9udGhzO1xuXG4gIHZhciBwZXJpb2RSZSA9IGZvcm1hdFJlKGxvY2FsZV9wZXJpb2RzKSxcbiAgICAgIHBlcmlvZExvb2t1cCA9IGZvcm1hdExvb2t1cChsb2NhbGVfcGVyaW9kcyksXG4gICAgICB3ZWVrZGF5UmUgPSBmb3JtYXRSZShsb2NhbGVfd2Vla2RheXMpLFxuICAgICAgd2Vla2RheUxvb2t1cCA9IGZvcm1hdExvb2t1cChsb2NhbGVfd2Vla2RheXMpLFxuICAgICAgc2hvcnRXZWVrZGF5UmUgPSBmb3JtYXRSZShsb2NhbGVfc2hvcnRXZWVrZGF5cyksXG4gICAgICBzaG9ydFdlZWtkYXlMb29rdXAgPSBmb3JtYXRMb29rdXAobG9jYWxlX3Nob3J0V2Vla2RheXMpLFxuICAgICAgbW9udGhSZSA9IGZvcm1hdFJlKGxvY2FsZV9tb250aHMpLFxuICAgICAgbW9udGhMb29rdXAgPSBmb3JtYXRMb29rdXAobG9jYWxlX21vbnRocyksXG4gICAgICBzaG9ydE1vbnRoUmUgPSBmb3JtYXRSZShsb2NhbGVfc2hvcnRNb250aHMpLFxuICAgICAgc2hvcnRNb250aExvb2t1cCA9IGZvcm1hdExvb2t1cChsb2NhbGVfc2hvcnRNb250aHMpO1xuXG4gIHZhciBmb3JtYXRzID0ge1xuICAgIFwiYVwiOiBmb3JtYXRTaG9ydFdlZWtkYXksXG4gICAgXCJBXCI6IGZvcm1hdFdlZWtkYXksXG4gICAgXCJiXCI6IGZvcm1hdFNob3J0TW9udGgsXG4gICAgXCJCXCI6IGZvcm1hdE1vbnRoLFxuICAgIFwiY1wiOiBudWxsLFxuICAgIFwiZFwiOiBmb3JtYXREYXlPZk1vbnRoLFxuICAgIFwiZVwiOiBmb3JtYXREYXlPZk1vbnRoLFxuICAgIFwiSFwiOiBmb3JtYXRIb3VyMjQsXG4gICAgXCJJXCI6IGZvcm1hdEhvdXIxMixcbiAgICBcImpcIjogZm9ybWF0RGF5T2ZZZWFyLFxuICAgIFwiTFwiOiBmb3JtYXRNaWxsaXNlY29uZHMsXG4gICAgXCJtXCI6IGZvcm1hdE1vbnRoTnVtYmVyLFxuICAgIFwiTVwiOiBmb3JtYXRNaW51dGVzLFxuICAgIFwicFwiOiBmb3JtYXRQZXJpb2QsXG4gICAgXCJTXCI6IGZvcm1hdFNlY29uZHMsXG4gICAgXCJVXCI6IGZvcm1hdFdlZWtOdW1iZXJTdW5kYXksXG4gICAgXCJ3XCI6IGZvcm1hdFdlZWtkYXlOdW1iZXIsXG4gICAgXCJXXCI6IGZvcm1hdFdlZWtOdW1iZXJNb25kYXksXG4gICAgXCJ4XCI6IG51bGwsXG4gICAgXCJYXCI6IG51bGwsXG4gICAgXCJ5XCI6IGZvcm1hdFllYXIsXG4gICAgXCJZXCI6IGZvcm1hdEZ1bGxZZWFyLFxuICAgIFwiWlwiOiBmb3JtYXRab25lLFxuICAgIFwiJVwiOiBmb3JtYXRMaXRlcmFsUGVyY2VudFxuICB9O1xuXG4gIHZhciB1dGNGb3JtYXRzID0ge1xuICAgIFwiYVwiOiBmb3JtYXRVVENTaG9ydFdlZWtkYXksXG4gICAgXCJBXCI6IGZvcm1hdFVUQ1dlZWtkYXksXG4gICAgXCJiXCI6IGZvcm1hdFVUQ1Nob3J0TW9udGgsXG4gICAgXCJCXCI6IGZvcm1hdFVUQ01vbnRoLFxuICAgIFwiY1wiOiBudWxsLFxuICAgIFwiZFwiOiBmb3JtYXRVVENEYXlPZk1vbnRoLFxuICAgIFwiZVwiOiBmb3JtYXRVVENEYXlPZk1vbnRoLFxuICAgIFwiSFwiOiBmb3JtYXRVVENIb3VyMjQsXG4gICAgXCJJXCI6IGZvcm1hdFVUQ0hvdXIxMixcbiAgICBcImpcIjogZm9ybWF0VVRDRGF5T2ZZZWFyLFxuICAgIFwiTFwiOiBmb3JtYXRVVENNaWxsaXNlY29uZHMsXG4gICAgXCJtXCI6IGZvcm1hdFVUQ01vbnRoTnVtYmVyLFxuICAgIFwiTVwiOiBmb3JtYXRVVENNaW51dGVzLFxuICAgIFwicFwiOiBmb3JtYXRVVENQZXJpb2QsXG4gICAgXCJTXCI6IGZvcm1hdFVUQ1NlY29uZHMsXG4gICAgXCJVXCI6IGZvcm1hdFVUQ1dlZWtOdW1iZXJTdW5kYXksXG4gICAgXCJ3XCI6IGZvcm1hdFVUQ1dlZWtkYXlOdW1iZXIsXG4gICAgXCJXXCI6IGZvcm1hdFVUQ1dlZWtOdW1iZXJNb25kYXksXG4gICAgXCJ4XCI6IG51bGwsXG4gICAgXCJYXCI6IG51bGwsXG4gICAgXCJ5XCI6IGZvcm1hdFVUQ1llYXIsXG4gICAgXCJZXCI6IGZvcm1hdFVUQ0Z1bGxZZWFyLFxuICAgIFwiWlwiOiBmb3JtYXRVVENab25lLFxuICAgIFwiJVwiOiBmb3JtYXRMaXRlcmFsUGVyY2VudFxuICB9O1xuXG4gIHZhciBwYXJzZXMgPSB7XG4gICAgXCJhXCI6IHBhcnNlU2hvcnRXZWVrZGF5LFxuICAgIFwiQVwiOiBwYXJzZVdlZWtkYXksXG4gICAgXCJiXCI6IHBhcnNlU2hvcnRNb250aCxcbiAgICBcIkJcIjogcGFyc2VNb250aCxcbiAgICBcImNcIjogcGFyc2VMb2NhbGVEYXRlVGltZSxcbiAgICBcImRcIjogcGFyc2VEYXlPZk1vbnRoLFxuICAgIFwiZVwiOiBwYXJzZURheU9mTW9udGgsXG4gICAgXCJIXCI6IHBhcnNlSG91cjI0LFxuICAgIFwiSVwiOiBwYXJzZUhvdXIyNCxcbiAgICBcImpcIjogcGFyc2VEYXlPZlllYXIsXG4gICAgXCJMXCI6IHBhcnNlTWlsbGlzZWNvbmRzLFxuICAgIFwibVwiOiBwYXJzZU1vbnRoTnVtYmVyLFxuICAgIFwiTVwiOiBwYXJzZU1pbnV0ZXMsXG4gICAgXCJwXCI6IHBhcnNlUGVyaW9kLFxuICAgIFwiU1wiOiBwYXJzZVNlY29uZHMsXG4gICAgXCJVXCI6IHBhcnNlV2Vla051bWJlclN1bmRheSxcbiAgICBcIndcIjogcGFyc2VXZWVrZGF5TnVtYmVyLFxuICAgIFwiV1wiOiBwYXJzZVdlZWtOdW1iZXJNb25kYXksXG4gICAgXCJ4XCI6IHBhcnNlTG9jYWxlRGF0ZSxcbiAgICBcIlhcIjogcGFyc2VMb2NhbGVUaW1lLFxuICAgIFwieVwiOiBwYXJzZVllYXIsXG4gICAgXCJZXCI6IHBhcnNlRnVsbFllYXIsXG4gICAgXCJaXCI6IHBhcnNlWm9uZSxcbiAgICBcIiVcIjogcGFyc2VMaXRlcmFsUGVyY2VudFxuICB9O1xuXG4gIC8vIFRoZXNlIHJlY3Vyc2l2ZSBkaXJlY3RpdmUgZGVmaW5pdGlvbnMgbXVzdCBiZSBkZWZlcnJlZC5cbiAgZm9ybWF0cy54ID0gbmV3Rm9ybWF0KGxvY2FsZV9kYXRlLCBmb3JtYXRzKTtcbiAgZm9ybWF0cy5YID0gbmV3Rm9ybWF0KGxvY2FsZV90aW1lLCBmb3JtYXRzKTtcbiAgZm9ybWF0cy5jID0gbmV3Rm9ybWF0KGxvY2FsZV9kYXRlVGltZSwgZm9ybWF0cyk7XG4gIHV0Y0Zvcm1hdHMueCA9IG5ld0Zvcm1hdChsb2NhbGVfZGF0ZSwgdXRjRm9ybWF0cyk7XG4gIHV0Y0Zvcm1hdHMuWCA9IG5ld0Zvcm1hdChsb2NhbGVfdGltZSwgdXRjRm9ybWF0cyk7XG4gIHV0Y0Zvcm1hdHMuYyA9IG5ld0Zvcm1hdChsb2NhbGVfZGF0ZVRpbWUsIHV0Y0Zvcm1hdHMpO1xuXG4gIGZ1bmN0aW9uIG5ld0Zvcm1hdChzcGVjaWZpZXIsIGZvcm1hdHMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oZGF0ZSkge1xuICAgICAgdmFyIHN0cmluZyA9IFtdLFxuICAgICAgICAgIGkgPSAtMSxcbiAgICAgICAgICBqID0gMCxcbiAgICAgICAgICBuID0gc3BlY2lmaWVyLmxlbmd0aCxcbiAgICAgICAgICBjLFxuICAgICAgICAgIHBhZCxcbiAgICAgICAgICBmb3JtYXQ7XG5cbiAgICAgIGlmICghKGRhdGUgaW5zdGFuY2VvZiBEYXRlKSkgZGF0ZSA9IG5ldyBEYXRlKCtkYXRlKTtcblxuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgaWYgKHNwZWNpZmllci5jaGFyQ29kZUF0KGkpID09PSAzNykge1xuICAgICAgICAgIHN0cmluZy5wdXNoKHNwZWNpZmllci5zbGljZShqLCBpKSk7XG4gICAgICAgICAgaWYgKChwYWQgPSBwYWRzW2MgPSBzcGVjaWZpZXIuY2hhckF0KCsraSldKSAhPSBudWxsKSBjID0gc3BlY2lmaWVyLmNoYXJBdCgrK2kpO1xuICAgICAgICAgIGVsc2UgcGFkID0gYyA9PT0gXCJlXCIgPyBcIiBcIiA6IFwiMFwiO1xuICAgICAgICAgIGlmIChmb3JtYXQgPSBmb3JtYXRzW2NdKSBjID0gZm9ybWF0KGRhdGUsIHBhZCk7XG4gICAgICAgICAgc3RyaW5nLnB1c2goYyk7XG4gICAgICAgICAgaiA9IGkgKyAxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHN0cmluZy5wdXNoKHNwZWNpZmllci5zbGljZShqLCBpKSk7XG4gICAgICByZXR1cm4gc3RyaW5nLmpvaW4oXCJcIik7XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5ld1BhcnNlKHNwZWNpZmllciwgbmV3RGF0ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgIHZhciBkID0gbmV3WWVhcigxOTAwKSxcbiAgICAgICAgICBpID0gcGFyc2VTcGVjaWZpZXIoZCwgc3BlY2lmaWVyLCBzdHJpbmcgKz0gXCJcIiwgMCk7XG4gICAgICBpZiAoaSAhPSBzdHJpbmcubGVuZ3RoKSByZXR1cm4gbnVsbDtcblxuICAgICAgLy8gVGhlIGFtLXBtIGZsYWcgaXMgMCBmb3IgQU0sIGFuZCAxIGZvciBQTS5cbiAgICAgIGlmIChcInBcIiBpbiBkKSBkLkggPSBkLkggJSAxMiArIGQucCAqIDEyO1xuXG4gICAgICAvLyBDb252ZXJ0IGRheS1vZi13ZWVrIGFuZCB3ZWVrLW9mLXllYXIgdG8gZGF5LW9mLXllYXIuXG4gICAgICBpZiAoXCJXXCIgaW4gZCB8fCBcIlVcIiBpbiBkKSB7XG4gICAgICAgIGlmICghKFwid1wiIGluIGQpKSBkLncgPSBcIldcIiBpbiBkID8gMSA6IDA7XG4gICAgICAgIHZhciBkYXkkJDEgPSBcIlpcIiBpbiBkID8gdXRjRGF0ZShuZXdZZWFyKGQueSkpLmdldFVUQ0RheSgpIDogbmV3RGF0ZShuZXdZZWFyKGQueSkpLmdldERheSgpO1xuICAgICAgICBkLm0gPSAwO1xuICAgICAgICBkLmQgPSBcIldcIiBpbiBkID8gKGQudyArIDYpICUgNyArIGQuVyAqIDcgLSAoZGF5JCQxICsgNSkgJSA3IDogZC53ICsgZC5VICogNyAtIChkYXkkJDEgKyA2KSAlIDc7XG4gICAgICB9XG5cbiAgICAgIC8vIElmIGEgdGltZSB6b25lIGlzIHNwZWNpZmllZCwgYWxsIGZpZWxkcyBhcmUgaW50ZXJwcmV0ZWQgYXMgVVRDIGFuZCB0aGVuXG4gICAgICAvLyBvZmZzZXQgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgdGltZSB6b25lLlxuICAgICAgaWYgKFwiWlwiIGluIGQpIHtcbiAgICAgICAgZC5IICs9IGQuWiAvIDEwMCB8IDA7XG4gICAgICAgIGQuTSArPSBkLlogJSAxMDA7XG4gICAgICAgIHJldHVybiB1dGNEYXRlKGQpO1xuICAgICAgfVxuXG4gICAgICAvLyBPdGhlcndpc2UsIGFsbCBmaWVsZHMgYXJlIGluIGxvY2FsIHRpbWUuXG4gICAgICByZXR1cm4gbmV3RGF0ZShkKTtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VTcGVjaWZpZXIoZCwgc3BlY2lmaWVyLCBzdHJpbmcsIGopIHtcbiAgICB2YXIgaSA9IDAsXG4gICAgICAgIG4gPSBzcGVjaWZpZXIubGVuZ3RoLFxuICAgICAgICBtID0gc3RyaW5nLmxlbmd0aCxcbiAgICAgICAgYyxcbiAgICAgICAgcGFyc2U7XG5cbiAgICB3aGlsZSAoaSA8IG4pIHtcbiAgICAgIGlmIChqID49IG0pIHJldHVybiAtMTtcbiAgICAgIGMgPSBzcGVjaWZpZXIuY2hhckNvZGVBdChpKyspO1xuICAgICAgaWYgKGMgPT09IDM3KSB7XG4gICAgICAgIGMgPSBzcGVjaWZpZXIuY2hhckF0KGkrKyk7XG4gICAgICAgIHBhcnNlID0gcGFyc2VzW2MgaW4gcGFkcyA/IHNwZWNpZmllci5jaGFyQXQoaSsrKSA6IGNdO1xuICAgICAgICBpZiAoIXBhcnNlIHx8ICgoaiA9IHBhcnNlKGQsIHN0cmluZywgaikpIDwgMCkpIHJldHVybiAtMTtcbiAgICAgIH0gZWxzZSBpZiAoYyAhPSBzdHJpbmcuY2hhckNvZGVBdChqKyspKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gajtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlUGVyaW9kKGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gcGVyaW9kUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICAgIHJldHVybiBuID8gKGQucCA9IHBlcmlvZExvb2t1cFtuWzBdLnRvTG93ZXJDYXNlKCldLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVNob3J0V2Vla2RheShkLCBzdHJpbmcsIGkpIHtcbiAgICB2YXIgbiA9IHNob3J0V2Vla2RheVJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgICByZXR1cm4gbiA/IChkLncgPSBzaG9ydFdlZWtkYXlMb29rdXBbblswXS50b0xvd2VyQ2FzZSgpXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VXZWVrZGF5KGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gd2Vla2RheVJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgICByZXR1cm4gbiA/IChkLncgPSB3ZWVrZGF5TG9va3VwW25bMF0udG9Mb3dlckNhc2UoKV0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlU2hvcnRNb250aChkLCBzdHJpbmcsIGkpIHtcbiAgICB2YXIgbiA9IHNob3J0TW9udGhSZS5leGVjKHN0cmluZy5zbGljZShpKSk7XG4gICAgcmV0dXJuIG4gPyAoZC5tID0gc2hvcnRNb250aExvb2t1cFtuWzBdLnRvTG93ZXJDYXNlKCldLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZU1vbnRoKGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gbW9udGhSZS5leGVjKHN0cmluZy5zbGljZShpKSk7XG4gICAgcmV0dXJuIG4gPyAoZC5tID0gbW9udGhMb29rdXBbblswXS50b0xvd2VyQ2FzZSgpXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VMb2NhbGVEYXRlVGltZShkLCBzdHJpbmcsIGkpIHtcbiAgICByZXR1cm4gcGFyc2VTcGVjaWZpZXIoZCwgbG9jYWxlX2RhdGVUaW1lLCBzdHJpbmcsIGkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VMb2NhbGVEYXRlKGQsIHN0cmluZywgaSkge1xuICAgIHJldHVybiBwYXJzZVNwZWNpZmllcihkLCBsb2NhbGVfZGF0ZSwgc3RyaW5nLCBpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTG9jYWxlVGltZShkLCBzdHJpbmcsIGkpIHtcbiAgICByZXR1cm4gcGFyc2VTcGVjaWZpZXIoZCwgbG9jYWxlX3RpbWUsIHN0cmluZywgaSk7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRTaG9ydFdlZWtkYXkoZCkge1xuICAgIHJldHVybiBsb2NhbGVfc2hvcnRXZWVrZGF5c1tkLmdldERheSgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFdlZWtkYXkoZCkge1xuICAgIHJldHVybiBsb2NhbGVfd2Vla2RheXNbZC5nZXREYXkoKV07XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRTaG9ydE1vbnRoKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX3Nob3J0TW9udGhzW2QuZ2V0TW9udGgoKV07XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRNb250aChkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV9tb250aHNbZC5nZXRNb250aCgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFBlcmlvZChkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV9wZXJpb2RzWysoZC5nZXRIb3VycygpID49IDEyKV07XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENTaG9ydFdlZWtkYXkoZCkge1xuICAgIHJldHVybiBsb2NhbGVfc2hvcnRXZWVrZGF5c1tkLmdldFVUQ0RheSgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1dlZWtkYXkoZCkge1xuICAgIHJldHVybiBsb2NhbGVfd2Vla2RheXNbZC5nZXRVVENEYXkoKV07XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENTaG9ydE1vbnRoKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX3Nob3J0TW9udGhzW2QuZ2V0VVRDTW9udGgoKV07XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENNb250aChkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV9tb250aHNbZC5nZXRVVENNb250aCgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1BlcmlvZChkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV9wZXJpb2RzWysoZC5nZXRVVENIb3VycygpID49IDEyKV07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGZvcm1hdDogZnVuY3Rpb24oc3BlY2lmaWVyKSB7XG4gICAgICB2YXIgZiA9IG5ld0Zvcm1hdChzcGVjaWZpZXIgKz0gXCJcIiwgZm9ybWF0cyk7XG4gICAgICBmLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7IHJldHVybiBzcGVjaWZpZXI7IH07XG4gICAgICByZXR1cm4gZjtcbiAgICB9LFxuICAgIHBhcnNlOiBmdW5jdGlvbihzcGVjaWZpZXIpIHtcbiAgICAgIHZhciBwID0gbmV3UGFyc2Uoc3BlY2lmaWVyICs9IFwiXCIsIGxvY2FsRGF0ZSk7XG4gICAgICBwLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7IHJldHVybiBzcGVjaWZpZXI7IH07XG4gICAgICByZXR1cm4gcDtcbiAgICB9LFxuICAgIHV0Y0Zvcm1hdDogZnVuY3Rpb24oc3BlY2lmaWVyKSB7XG4gICAgICB2YXIgZiA9IG5ld0Zvcm1hdChzcGVjaWZpZXIgKz0gXCJcIiwgdXRjRm9ybWF0cyk7XG4gICAgICBmLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7IHJldHVybiBzcGVjaWZpZXI7IH07XG4gICAgICByZXR1cm4gZjtcbiAgICB9LFxuICAgIHV0Y1BhcnNlOiBmdW5jdGlvbihzcGVjaWZpZXIpIHtcbiAgICAgIHZhciBwID0gbmV3UGFyc2Uoc3BlY2lmaWVyLCB1dGNEYXRlKTtcbiAgICAgIHAudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHNwZWNpZmllcjsgfTtcbiAgICAgIHJldHVybiBwO1xuICAgIH1cbiAgfTtcbn1cblxudmFyIHBhZHMgPSB7XCItXCI6IFwiXCIsIFwiX1wiOiBcIiBcIiwgXCIwXCI6IFwiMFwifTtcbnZhciBudW1iZXJSZSA9IC9eXFxzKlxcZCsvO1xudmFyIHBlcmNlbnRSZSA9IC9eJS87XG52YXIgcmVxdW90ZVJlID0gL1tcXFxcXFxeXFwkXFwqXFwrXFw/XFx8XFxbXFxdXFwoXFwpXFwuXFx7XFx9XS9nO1xuXG5mdW5jdGlvbiBwYWQodmFsdWUsIGZpbGwsIHdpZHRoKSB7XG4gIHZhciBzaWduID0gdmFsdWUgPCAwID8gXCItXCIgOiBcIlwiLFxuICAgICAgc3RyaW5nID0gKHNpZ24gPyAtdmFsdWUgOiB2YWx1ZSkgKyBcIlwiLFxuICAgICAgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcbiAgcmV0dXJuIHNpZ24gKyAobGVuZ3RoIDwgd2lkdGggPyBuZXcgQXJyYXkod2lkdGggLSBsZW5ndGggKyAxKS5qb2luKGZpbGwpICsgc3RyaW5nIDogc3RyaW5nKTtcbn1cblxuZnVuY3Rpb24gcmVxdW90ZShzKSB7XG4gIHJldHVybiBzLnJlcGxhY2UocmVxdW90ZVJlLCBcIlxcXFwkJlwiKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0UmUobmFtZXMpIHtcbiAgcmV0dXJuIG5ldyBSZWdFeHAoXCJeKD86XCIgKyBuYW1lcy5tYXAocmVxdW90ZSkuam9pbihcInxcIikgKyBcIilcIiwgXCJpXCIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRMb29rdXAobmFtZXMpIHtcbiAgdmFyIG1hcCA9IHt9LCBpID0gLTEsIG4gPSBuYW1lcy5sZW5ndGg7XG4gIHdoaWxlICgrK2kgPCBuKSBtYXBbbmFtZXNbaV0udG9Mb3dlckNhc2UoKV0gPSBpO1xuICByZXR1cm4gbWFwO1xufVxuXG5mdW5jdGlvbiBwYXJzZVdlZWtkYXlOdW1iZXIoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDEpKTtcbiAgcmV0dXJuIG4gPyAoZC53ID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VXZWVrTnVtYmVyU3VuZGF5KGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgcmV0dXJuIG4gPyAoZC5VID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VXZWVrTnVtYmVyTW9uZGF5KGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgcmV0dXJuIG4gPyAoZC5XID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VGdWxsWWVhcihkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgNCkpO1xuICByZXR1cm4gbiA/IChkLnkgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZVllYXIoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgcmV0dXJuIG4gPyAoZC55ID0gK25bMF0gKyAoK25bMF0gPiA2OCA/IDE5MDAgOiAyMDAwKSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZVpvbmUoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gL14oWil8KFsrLV1cXGRcXGQpKD86XFw6PyhcXGRcXGQpKT8vLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyA2KSk7XG4gIHJldHVybiBuID8gKGQuWiA9IG5bMV0gPyAwIDogLShuWzJdICsgKG5bM10gfHwgXCIwMFwiKSksIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VNb250aE51bWJlcihkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLm0gPSBuWzBdIC0gMSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZURheU9mTW9udGgoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgcmV0dXJuIG4gPyAoZC5kID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VEYXlPZlllYXIoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDMpKTtcbiAgcmV0dXJuIG4gPyAoZC5tID0gMCwgZC5kID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VIb3VyMjQoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgcmV0dXJuIG4gPyAoZC5IID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VNaW51dGVzKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAyKSk7XG4gIHJldHVybiBuID8gKGQuTSA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU2Vjb25kcyhkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLlMgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZU1pbGxpc2Vjb25kcyhkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMykpO1xuICByZXR1cm4gbiA/IChkLkwgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZUxpdGVyYWxQZXJjZW50KGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IHBlcmNlbnRSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMSkpO1xuICByZXR1cm4gbiA/IGkgKyBuWzBdLmxlbmd0aCA6IC0xO1xufVxuXG5mdW5jdGlvbiBmb3JtYXREYXlPZk1vbnRoKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldERhdGUoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdEhvdXIyNChkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRIb3VycygpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0SG91cjEyKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldEhvdXJzKCkgJSAxMiB8fCAxMiwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdERheU9mWWVhcihkLCBwKSB7XG4gIHJldHVybiBwYWQoMSArIGRheS5jb3VudCh5ZWFyKGQpLCBkKSwgcCwgMyk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdE1pbGxpc2Vjb25kcyhkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRNaWxsaXNlY29uZHMoKSwgcCwgMyk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdE1vbnRoTnVtYmVyKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldE1vbnRoKCkgKyAxLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0TWludXRlcyhkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRNaW51dGVzKCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRTZWNvbmRzKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldFNlY29uZHMoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFdlZWtOdW1iZXJTdW5kYXkoZCwgcCkge1xuICByZXR1cm4gcGFkKHN1bmRheS5jb3VudCh5ZWFyKGQpLCBkKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFdlZWtkYXlOdW1iZXIoZCkge1xuICByZXR1cm4gZC5nZXREYXkoKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0V2Vla051bWJlck1vbmRheShkLCBwKSB7XG4gIHJldHVybiBwYWQobW9uZGF5LmNvdW50KHllYXIoZCksIGQpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0WWVhcihkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRGdWxsWWVhcigpICUgMTAwLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RnVsbFllYXIoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0RnVsbFllYXIoKSAlIDEwMDAwLCBwLCA0KTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0Wm9uZShkKSB7XG4gIHZhciB6ID0gZC5nZXRUaW1lem9uZU9mZnNldCgpO1xuICByZXR1cm4gKHogPiAwID8gXCItXCIgOiAoeiAqPSAtMSwgXCIrXCIpKVxuICAgICAgKyBwYWQoeiAvIDYwIHwgMCwgXCIwXCIsIDIpXG4gICAgICArIHBhZCh6ICUgNjAsIFwiMFwiLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDRGF5T2ZNb250aChkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRVVENEYXRlKCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENIb3VyMjQoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0VVRDSG91cnMoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ0hvdXIxMihkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRVVENIb3VycygpICUgMTIgfHwgMTIsIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENEYXlPZlllYXIoZCwgcCkge1xuICByZXR1cm4gcGFkKDEgKyB1dGNEYXkuY291bnQodXRjWWVhcihkKSwgZCksIHAsIDMpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENNaWxsaXNlY29uZHMoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0VVRDTWlsbGlzZWNvbmRzKCksIHAsIDMpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENNb250aE51bWJlcihkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRVVENNb250aCgpICsgMSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ01pbnV0ZXMoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0VVRDTWludXRlcygpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDU2Vjb25kcyhkLCBwKSB7XG4gIHJldHVybiBwYWQoZC5nZXRVVENTZWNvbmRzKCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENXZWVrTnVtYmVyU3VuZGF5KGQsIHApIHtcbiAgcmV0dXJuIHBhZCh1dGNTdW5kYXkuY291bnQodXRjWWVhcihkKSwgZCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENXZWVrZGF5TnVtYmVyKGQpIHtcbiAgcmV0dXJuIGQuZ2V0VVRDRGF5KCk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1dlZWtOdW1iZXJNb25kYXkoZCwgcCkge1xuICByZXR1cm4gcGFkKHV0Y01vbmRheS5jb3VudCh1dGNZZWFyKGQpLCBkKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1llYXIoZCwgcCkge1xuICByZXR1cm4gcGFkKGQuZ2V0VVRDRnVsbFllYXIoKSAlIDEwMCwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ0Z1bGxZZWFyKGQsIHApIHtcbiAgcmV0dXJuIHBhZChkLmdldFVUQ0Z1bGxZZWFyKCkgJSAxMDAwMCwgcCwgNCk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1pvbmUoKSB7XG4gIHJldHVybiBcIiswMDAwXCI7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdExpdGVyYWxQZXJjZW50KCkge1xuICByZXR1cm4gXCIlXCI7XG59XG5cbnZhciBsb2NhbGUkMjtcblxuXG5cblxuXG5kZWZhdWx0TG9jYWxlJDEoe1xuICBkYXRlVGltZTogXCIleCwgJVhcIixcbiAgZGF0ZTogXCIlLW0vJS1kLyVZXCIsXG4gIHRpbWU6IFwiJS1JOiVNOiVTICVwXCIsXG4gIHBlcmlvZHM6IFtcIkFNXCIsIFwiUE1cIl0sXG4gIGRheXM6IFtcIlN1bmRheVwiLCBcIk1vbmRheVwiLCBcIlR1ZXNkYXlcIiwgXCJXZWRuZXNkYXlcIiwgXCJUaHVyc2RheVwiLCBcIkZyaWRheVwiLCBcIlNhdHVyZGF5XCJdLFxuICBzaG9ydERheXM6IFtcIlN1blwiLCBcIk1vblwiLCBcIlR1ZVwiLCBcIldlZFwiLCBcIlRodVwiLCBcIkZyaVwiLCBcIlNhdFwiXSxcbiAgbW9udGhzOiBbXCJKYW51YXJ5XCIsIFwiRmVicnVhcnlcIiwgXCJNYXJjaFwiLCBcIkFwcmlsXCIsIFwiTWF5XCIsIFwiSnVuZVwiLCBcIkp1bHlcIiwgXCJBdWd1c3RcIiwgXCJTZXB0ZW1iZXJcIiwgXCJPY3RvYmVyXCIsIFwiTm92ZW1iZXJcIiwgXCJEZWNlbWJlclwiXSxcbiAgc2hvcnRNb250aHM6IFtcIkphblwiLCBcIkZlYlwiLCBcIk1hclwiLCBcIkFwclwiLCBcIk1heVwiLCBcIkp1blwiLCBcIkp1bFwiLCBcIkF1Z1wiLCBcIlNlcFwiLCBcIk9jdFwiLCBcIk5vdlwiLCBcIkRlY1wiXVxufSk7XG5cbmZ1bmN0aW9uIGRlZmF1bHRMb2NhbGUkMShkZWZpbml0aW9uKSB7XG4gIGxvY2FsZSQyID0gZm9ybWF0TG9jYWxlJDEoZGVmaW5pdGlvbik7XG4gIGV4cG9ydHMudGltZUZvcm1hdCA9IGxvY2FsZSQyLmZvcm1hdDtcbiAgZXhwb3J0cy50aW1lUGFyc2UgPSBsb2NhbGUkMi5wYXJzZTtcbiAgZXhwb3J0cy51dGNGb3JtYXQgPSBsb2NhbGUkMi51dGNGb3JtYXQ7XG4gIGV4cG9ydHMudXRjUGFyc2UgPSBsb2NhbGUkMi51dGNQYXJzZTtcbiAgcmV0dXJuIGxvY2FsZSQyO1xufVxuXG52YXIgaXNvU3BlY2lmaWVyID0gXCIlWS0lbS0lZFQlSDolTTolUy4lTFpcIjtcblxuZnVuY3Rpb24gZm9ybWF0SXNvTmF0aXZlKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUudG9JU09TdHJpbmcoKTtcbn1cblxudmFyIGZvcm1hdElzbyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nXG4gICAgPyBmb3JtYXRJc29OYXRpdmVcbiAgICA6IGV4cG9ydHMudXRjRm9ybWF0KGlzb1NwZWNpZmllcik7XG5cbmZ1bmN0aW9uIHBhcnNlSXNvTmF0aXZlKHN0cmluZykge1xuICB2YXIgZGF0ZSA9IG5ldyBEYXRlKHN0cmluZyk7XG4gIHJldHVybiBpc05hTihkYXRlKSA/IG51bGwgOiBkYXRlO1xufVxuXG52YXIgcGFyc2VJc28gPSArbmV3IERhdGUoXCIyMDAwLTAxLTAxVDAwOjAwOjAwLjAwMFpcIilcbiAgICA/IHBhcnNlSXNvTmF0aXZlXG4gICAgOiBleHBvcnRzLnV0Y1BhcnNlKGlzb1NwZWNpZmllcik7XG5cbnZhciBkdXJhdGlvblNlY29uZCA9IDEwMDA7XG52YXIgZHVyYXRpb25NaW51dGUgPSBkdXJhdGlvblNlY29uZCAqIDYwO1xudmFyIGR1cmF0aW9uSG91ciA9IGR1cmF0aW9uTWludXRlICogNjA7XG52YXIgZHVyYXRpb25EYXkgPSBkdXJhdGlvbkhvdXIgKiAyNDtcbnZhciBkdXJhdGlvbldlZWsgPSBkdXJhdGlvbkRheSAqIDc7XG52YXIgZHVyYXRpb25Nb250aCA9IGR1cmF0aW9uRGF5ICogMzA7XG52YXIgZHVyYXRpb25ZZWFyID0gZHVyYXRpb25EYXkgKiAzNjU7XG5cbmZ1bmN0aW9uIGRhdGUkMSh0KSB7XG4gIHJldHVybiBuZXcgRGF0ZSh0KTtcbn1cblxuZnVuY3Rpb24gbnVtYmVyJDIodCkge1xuICByZXR1cm4gdCBpbnN0YW5jZW9mIERhdGUgPyArdCA6ICtuZXcgRGF0ZSgrdCk7XG59XG5cbmZ1bmN0aW9uIGNhbGVuZGFyKHllYXIkJDEsIG1vbnRoJCQxLCB3ZWVrLCBkYXkkJDEsIGhvdXIkJDEsIG1pbnV0ZSQkMSwgc2Vjb25kJCQxLCBtaWxsaXNlY29uZCQkMSwgZm9ybWF0KSB7XG4gIHZhciBzY2FsZSA9IGNvbnRpbnVvdXMoZGVpbnRlcnBvbGF0ZUxpbmVhciwgcmVpbnRlcnBvbGF0ZSksXG4gICAgICBpbnZlcnQgPSBzY2FsZS5pbnZlcnQsXG4gICAgICBkb21haW4gPSBzY2FsZS5kb21haW47XG5cbiAgdmFyIGZvcm1hdE1pbGxpc2Vjb25kID0gZm9ybWF0KFwiLiVMXCIpLFxuICAgICAgZm9ybWF0U2Vjb25kID0gZm9ybWF0KFwiOiVTXCIpLFxuICAgICAgZm9ybWF0TWludXRlID0gZm9ybWF0KFwiJUk6JU1cIiksXG4gICAgICBmb3JtYXRIb3VyID0gZm9ybWF0KFwiJUkgJXBcIiksXG4gICAgICBmb3JtYXREYXkgPSBmb3JtYXQoXCIlYSAlZFwiKSxcbiAgICAgIGZvcm1hdFdlZWsgPSBmb3JtYXQoXCIlYiAlZFwiKSxcbiAgICAgIGZvcm1hdE1vbnRoID0gZm9ybWF0KFwiJUJcIiksXG4gICAgICBmb3JtYXRZZWFyID0gZm9ybWF0KFwiJVlcIik7XG5cbiAgdmFyIHRpY2tJbnRlcnZhbHMgPSBbXG4gICAgW3NlY29uZCQkMSwgIDEsICAgICAgZHVyYXRpb25TZWNvbmRdLFxuICAgIFtzZWNvbmQkJDEsICA1LCAgNSAqIGR1cmF0aW9uU2Vjb25kXSxcbiAgICBbc2Vjb25kJCQxLCAxNSwgMTUgKiBkdXJhdGlvblNlY29uZF0sXG4gICAgW3NlY29uZCQkMSwgMzAsIDMwICogZHVyYXRpb25TZWNvbmRdLFxuICAgIFttaW51dGUkJDEsICAxLCAgICAgIGR1cmF0aW9uTWludXRlXSxcbiAgICBbbWludXRlJCQxLCAgNSwgIDUgKiBkdXJhdGlvbk1pbnV0ZV0sXG4gICAgW21pbnV0ZSQkMSwgMTUsIDE1ICogZHVyYXRpb25NaW51dGVdLFxuICAgIFttaW51dGUkJDEsIDMwLCAzMCAqIGR1cmF0aW9uTWludXRlXSxcbiAgICBbICBob3VyJCQxLCAgMSwgICAgICBkdXJhdGlvbkhvdXIgIF0sXG4gICAgWyAgaG91ciQkMSwgIDMsICAzICogZHVyYXRpb25Ib3VyICBdLFxuICAgIFsgIGhvdXIkJDEsICA2LCAgNiAqIGR1cmF0aW9uSG91ciAgXSxcbiAgICBbICBob3VyJCQxLCAxMiwgMTIgKiBkdXJhdGlvbkhvdXIgIF0sXG4gICAgWyAgIGRheSQkMSwgIDEsICAgICAgZHVyYXRpb25EYXkgICBdLFxuICAgIFsgICBkYXkkJDEsICAyLCAgMiAqIGR1cmF0aW9uRGF5ICAgXSxcbiAgICBbICB3ZWVrLCAgMSwgICAgICBkdXJhdGlvbldlZWsgIF0sXG4gICAgWyBtb250aCQkMSwgIDEsICAgICAgZHVyYXRpb25Nb250aCBdLFxuICAgIFsgbW9udGgkJDEsICAzLCAgMyAqIGR1cmF0aW9uTW9udGggXSxcbiAgICBbICB5ZWFyJCQxLCAgMSwgICAgICBkdXJhdGlvblllYXIgIF1cbiAgXTtcblxuICBmdW5jdGlvbiB0aWNrRm9ybWF0KGRhdGUpIHtcbiAgICByZXR1cm4gKHNlY29uZCQkMShkYXRlKSA8IGRhdGUgPyBmb3JtYXRNaWxsaXNlY29uZFxuICAgICAgICA6IG1pbnV0ZSQkMShkYXRlKSA8IGRhdGUgPyBmb3JtYXRTZWNvbmRcbiAgICAgICAgOiBob3VyJCQxKGRhdGUpIDwgZGF0ZSA/IGZvcm1hdE1pbnV0ZVxuICAgICAgICA6IGRheSQkMShkYXRlKSA8IGRhdGUgPyBmb3JtYXRIb3VyXG4gICAgICAgIDogbW9udGgkJDEoZGF0ZSkgPCBkYXRlID8gKHdlZWsoZGF0ZSkgPCBkYXRlID8gZm9ybWF0RGF5IDogZm9ybWF0V2VlaylcbiAgICAgICAgOiB5ZWFyJCQxKGRhdGUpIDwgZGF0ZSA/IGZvcm1hdE1vbnRoXG4gICAgICAgIDogZm9ybWF0WWVhcikoZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiB0aWNrSW50ZXJ2YWwoaW50ZXJ2YWwsIHN0YXJ0LCBzdG9wLCBzdGVwKSB7XG4gICAgaWYgKGludGVydmFsID09IG51bGwpIGludGVydmFsID0gMTA7XG5cbiAgICAvLyBJZiBhIGRlc2lyZWQgdGljayBjb3VudCBpcyBzcGVjaWZpZWQsIHBpY2sgYSByZWFzb25hYmxlIHRpY2sgaW50ZXJ2YWxcbiAgICAvLyBiYXNlZCBvbiB0aGUgZXh0ZW50IG9mIHRoZSBkb21haW4gYW5kIGEgcm91Z2ggZXN0aW1hdGUgb2YgdGljayBzaXplLlxuICAgIC8vIE90aGVyd2lzZSwgYXNzdW1lIGludGVydmFsIGlzIGFscmVhZHkgYSB0aW1lIGludGVydmFsIGFuZCB1c2UgaXQuXG4gICAgaWYgKHR5cGVvZiBpbnRlcnZhbCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgdmFyIHRhcmdldCA9IE1hdGguYWJzKHN0b3AgLSBzdGFydCkgLyBpbnRlcnZhbCxcbiAgICAgICAgICBpID0gYmlzZWN0b3IoZnVuY3Rpb24oaSkgeyByZXR1cm4gaVsyXTsgfSkucmlnaHQodGlja0ludGVydmFscywgdGFyZ2V0KTtcbiAgICAgIGlmIChpID09PSB0aWNrSW50ZXJ2YWxzLmxlbmd0aCkge1xuICAgICAgICBzdGVwID0gdGlja1N0ZXAoc3RhcnQgLyBkdXJhdGlvblllYXIsIHN0b3AgLyBkdXJhdGlvblllYXIsIGludGVydmFsKTtcbiAgICAgICAgaW50ZXJ2YWwgPSB5ZWFyJCQxO1xuICAgICAgfSBlbHNlIGlmIChpKSB7XG4gICAgICAgIGkgPSB0aWNrSW50ZXJ2YWxzW3RhcmdldCAvIHRpY2tJbnRlcnZhbHNbaSAtIDFdWzJdIDwgdGlja0ludGVydmFsc1tpXVsyXSAvIHRhcmdldCA/IGkgLSAxIDogaV07XG4gICAgICAgIHN0ZXAgPSBpWzFdO1xuICAgICAgICBpbnRlcnZhbCA9IGlbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGVwID0gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIGludGVydmFsKTtcbiAgICAgICAgaW50ZXJ2YWwgPSBtaWxsaXNlY29uZCQkMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc3RlcCA9PSBudWxsID8gaW50ZXJ2YWwgOiBpbnRlcnZhbC5ldmVyeShzdGVwKTtcbiAgfVxuXG4gIHNjYWxlLmludmVydCA9IGZ1bmN0aW9uKHkpIHtcbiAgICByZXR1cm4gbmV3IERhdGUoaW52ZXJ0KHkpKTtcbiAgfTtcblxuICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyBkb21haW4obWFwJDMuY2FsbChfLCBudW1iZXIkMikpIDogZG9tYWluKCkubWFwKGRhdGUkMSk7XG4gIH07XG5cbiAgc2NhbGUudGlja3MgPSBmdW5jdGlvbihpbnRlcnZhbCwgc3RlcCkge1xuICAgIHZhciBkID0gZG9tYWluKCksXG4gICAgICAgIHQwID0gZFswXSxcbiAgICAgICAgdDEgPSBkW2QubGVuZ3RoIC0gMV0sXG4gICAgICAgIHIgPSB0MSA8IHQwLFxuICAgICAgICB0O1xuICAgIGlmIChyKSB0ID0gdDAsIHQwID0gdDEsIHQxID0gdDtcbiAgICB0ID0gdGlja0ludGVydmFsKGludGVydmFsLCB0MCwgdDEsIHN0ZXApO1xuICAgIHQgPSB0ID8gdC5yYW5nZSh0MCwgdDEgKyAxKSA6IFtdOyAvLyBpbmNsdXNpdmUgc3RvcFxuICAgIHJldHVybiByID8gdC5yZXZlcnNlKCkgOiB0O1xuICB9O1xuXG4gIHNjYWxlLnRpY2tGb3JtYXQgPSBmdW5jdGlvbihjb3VudCwgc3BlY2lmaWVyKSB7XG4gICAgcmV0dXJuIHNwZWNpZmllciA9PSBudWxsID8gdGlja0Zvcm1hdCA6IGZvcm1hdChzcGVjaWZpZXIpO1xuICB9O1xuXG4gIHNjYWxlLm5pY2UgPSBmdW5jdGlvbihpbnRlcnZhbCwgc3RlcCkge1xuICAgIHZhciBkID0gZG9tYWluKCk7XG4gICAgcmV0dXJuIChpbnRlcnZhbCA9IHRpY2tJbnRlcnZhbChpbnRlcnZhbCwgZFswXSwgZFtkLmxlbmd0aCAtIDFdLCBzdGVwKSlcbiAgICAgICAgPyBkb21haW4obmljZShkLCBpbnRlcnZhbCkpXG4gICAgICAgIDogc2NhbGU7XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBjb3B5KHNjYWxlLCBjYWxlbmRhcih5ZWFyJCQxLCBtb250aCQkMSwgd2VlaywgZGF5JCQxLCBob3VyJCQxLCBtaW51dGUkJDEsIHNlY29uZCQkMSwgbWlsbGlzZWNvbmQkJDEsIGZvcm1hdCkpO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxudmFyIHRpbWUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGNhbGVuZGFyKHllYXIsIG1vbnRoLCBzdW5kYXksIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIG1pbGxpc2Vjb25kLCBleHBvcnRzLnRpbWVGb3JtYXQpLmRvbWFpbihbbmV3IERhdGUoMjAwMCwgMCwgMSksIG5ldyBEYXRlKDIwMDAsIDAsIDIpXSk7XG59O1xuXG52YXIgdXRjVGltZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY2FsZW5kYXIodXRjWWVhciwgdXRjTW9udGgsIHV0Y1N1bmRheSwgdXRjRGF5LCB1dGNIb3VyLCB1dGNNaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmQsIGV4cG9ydHMudXRjRm9ybWF0KS5kb21haW4oW0RhdGUuVVRDKDIwMDAsIDAsIDEpLCBEYXRlLlVUQygyMDAwLCAwLCAyKV0pO1xufTtcblxudmFyIGNvbG9ycyA9IGZ1bmN0aW9uKHMpIHtcbiAgcmV0dXJuIHMubWF0Y2goLy57Nn0vZykubWFwKGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gXCIjXCIgKyB4O1xuICB9KTtcbn07XG5cbnZhciBjYXRlZ29yeTEwID0gY29sb3JzKFwiMWY3N2I0ZmY3ZjBlMmNhMDJjZDYyNzI4OTQ2N2JkOGM1NjRiZTM3N2MyN2Y3ZjdmYmNiZDIyMTdiZWNmXCIpO1xuXG52YXIgY2F0ZWdvcnkyMGIgPSBjb2xvcnMoXCIzOTNiNzk1MjU0YTM2YjZlY2Y5YzllZGU2Mzc5Mzk4Y2EyNTJiNWNmNmJjZWRiOWM4YzZkMzFiZDllMzllN2JhNTJlN2NiOTQ4NDNjMzlhZDQ5NGFkNjYxNmJlNzk2OWM3YjQxNzNhNTUxOTRjZTZkYmRkZTllZDZcIik7XG5cbnZhciBjYXRlZ29yeTIwYyA9IGNvbG9ycyhcIjMxODJiZDZiYWVkNjllY2FlMWM2ZGJlZmU2NTUwZGZkOGQzY2ZkYWU2YmZkZDBhMjMxYTM1NDc0YzQ3NmExZDk5YmM3ZTljMDc1NmJiMTllOWFjOGJjYmRkY2RhZGFlYjYzNjM2Mzk2OTY5NmJkYmRiZGQ5ZDlkOVwiKTtcblxudmFyIGNhdGVnb3J5MjAgPSBjb2xvcnMoXCIxZjc3YjRhZWM3ZThmZjdmMGVmZmJiNzgyY2EwMmM5OGRmOGFkNjI3MjhmZjk4OTY5NDY3YmRjNWIwZDU4YzU2NGJjNDljOTRlMzc3YzJmN2I2ZDI3ZjdmN2ZjN2M3YzdiY2JkMjJkYmRiOGQxN2JlY2Y5ZWRhZTVcIik7XG5cbnZhciBjdWJlaGVsaXgkMyA9IGN1YmVoZWxpeExvbmcoY3ViZWhlbGl4KDMwMCwgMC41LCAwLjApLCBjdWJlaGVsaXgoLTI0MCwgMC41LCAxLjApKTtcblxudmFyIHdhcm0gPSBjdWJlaGVsaXhMb25nKGN1YmVoZWxpeCgtMTAwLCAwLjc1LCAwLjM1KSwgY3ViZWhlbGl4KDgwLCAxLjUwLCAwLjgpKTtcblxudmFyIGNvb2wgPSBjdWJlaGVsaXhMb25nKGN1YmVoZWxpeCgyNjAsIDAuNzUsIDAuMzUpLCBjdWJlaGVsaXgoODAsIDEuNTAsIDAuOCkpO1xuXG52YXIgcmFpbmJvdyA9IGN1YmVoZWxpeCgpO1xuXG52YXIgcmFpbmJvdyQxID0gZnVuY3Rpb24odCkge1xuICBpZiAodCA8IDAgfHwgdCA+IDEpIHQgLT0gTWF0aC5mbG9vcih0KTtcbiAgdmFyIHRzID0gTWF0aC5hYnModCAtIDAuNSk7XG4gIHJhaW5ib3cuaCA9IDM2MCAqIHQgLSAxMDA7XG4gIHJhaW5ib3cucyA9IDEuNSAtIDEuNSAqIHRzO1xuICByYWluYm93LmwgPSAwLjggLSAwLjkgKiB0cztcbiAgcmV0dXJuIHJhaW5ib3cgKyBcIlwiO1xufTtcblxuZnVuY3Rpb24gcmFtcChyYW5nZSkge1xuICB2YXIgbiA9IHJhbmdlLmxlbmd0aDtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gcmFuZ2VbTWF0aC5tYXgoMCwgTWF0aC5taW4obiAtIDEsIE1hdGguZmxvb3IodCAqIG4pKSldO1xuICB9O1xufVxuXG52YXIgdmlyaWRpcyA9IHJhbXAoY29sb3JzKFwiNDQwMTU0NDQwMjU2NDUwNDU3NDUwNTU5NDYwNzVhNDYwODVjNDYwYTVkNDYwYjVlNDcwZDYwNDcwZTYxNDcxMDYzNDcxMTY0NDcxMzY1NDgxNDY3NDgxNjY4NDgxNzY5NDgxODZhNDgxYTZjNDgxYjZkNDgxYzZlNDgxZDZmNDgxZjcwNDgyMDcxNDgyMTczNDgyMzc0NDgyNDc1NDgyNTc2NDgyNjc3NDgyODc4NDgyOTc5NDcyYTdhNDcyYzdhNDcyZDdiNDcyZTdjNDcyZjdkNDYzMDdlNDYzMjdlNDYzMzdmNDYzNDgwNDUzNTgxNDUzNzgxNDUzODgyNDQzOTgzNDQzYTgzNDQzYjg0NDMzZDg0NDMzZTg1NDIzZjg1NDI0MDg2NDI0MTg2NDE0Mjg3NDE0NDg3NDA0NTg4NDA0Njg4M2Y0Nzg4M2Y0ODg5M2U0OTg5M2U0YTg5M2U0YzhhM2Q0ZDhhM2Q0ZThhM2M0ZjhhM2M1MDhiM2I1MThiM2I1MjhiM2E1MzhiM2E1NDhjMzk1NThjMzk1NjhjMzg1ODhjMzg1OThjMzc1YThjMzc1YjhkMzY1YzhkMzY1ZDhkMzU1ZThkMzU1ZjhkMzQ2MDhkMzQ2MThkMzM2MjhkMzM2MzhkMzI2NDhlMzI2NThlMzE2NjhlMzE2NzhlMzE2ODhlMzA2OThlMzA2YThlMmY2YjhlMmY2YzhlMmU2ZDhlMmU2ZThlMmU2ZjhlMmQ3MDhlMmQ3MThlMmM3MThlMmM3MjhlMmM3MzhlMmI3NDhlMmI3NThlMmE3NjhlMmE3NzhlMmE3ODhlMjk3OThlMjk3YThlMjk3YjhlMjg3YzhlMjg3ZDhlMjc3ZThlMjc3ZjhlMjc4MDhlMjY4MThlMjY4MjhlMjY4MjhlMjU4MzhlMjU4NDhlMjU4NThlMjQ4NjhlMjQ4NzhlMjM4ODhlMjM4OThlMjM4YThkMjI4YjhkMjI4YzhkMjI4ZDhkMjE4ZThkMjE4ZjhkMjE5MDhkMjE5MThjMjA5MjhjMjA5MjhjMjA5MzhjMWY5NDhjMWY5NThiMWY5NjhiMWY5NzhiMWY5ODhiMWY5OThhMWY5YThhMWU5YjhhMWU5Yzg5MWU5ZDg5MWY5ZTg5MWY5Zjg4MWZhMDg4MWZhMTg4MWZhMTg3MWZhMjg3MjBhMzg2MjBhNDg2MjFhNTg1MjFhNjg1MjJhNzg1MjJhODg0MjNhOTgzMjRhYTgzMjVhYjgyMjVhYzgyMjZhZDgxMjdhZDgxMjhhZTgwMjlhZjdmMmFiMDdmMmNiMTdlMmRiMjdkMmViMzdjMmZiNDdjMzFiNTdiMzJiNjdhMzRiNjc5MzViNzc5MzdiODc4MzhiOTc3M2FiYTc2M2JiYjc1M2RiYzc0M2ZiYzczNDBiZDcyNDJiZTcxNDRiZjcwNDZjMDZmNDhjMTZlNGFjMTZkNGNjMjZjNGVjMzZiNTBjNDZhNTJjNTY5NTRjNTY4NTZjNjY3NThjNzY1NWFjODY0NWNjODYzNWVjOTYyNjBjYTYwNjNjYjVmNjVjYjVlNjdjYzVjNjljZDViNmNjZDVhNmVjZTU4NzBjZjU3NzNkMDU2NzVkMDU0NzdkMTUzN2FkMTUxN2NkMjUwN2ZkMzRlODFkMzRkODRkNDRiODZkNTQ5ODlkNTQ4OGJkNjQ2OGVkNjQ1OTBkNzQzOTNkNzQxOTVkODQwOThkODNlOWJkOTNjOWRkOTNiYTBkYTM5YTJkYTM3YTVkYjM2YThkYjM0YWFkYzMyYWRkYzMwYjBkZDJmYjJkZDJkYjVkZTJiYjhkZTI5YmFkZTI4YmRkZjI2YzBkZjI1YzJkZjIzYzVlMDIxYzhlMDIwY2FlMTFmY2RlMTFkZDBlMTFjZDJlMjFiZDVlMjFhZDhlMjE5ZGFlMzE5ZGRlMzE4ZGZlMzE4ZTJlNDE4ZTVlNDE5ZTdlNDE5ZWFlNTFhZWNlNTFiZWZlNTFjZjFlNTFkZjRlNjFlZjZlNjIwZjhlNjIxZmJlNzIzZmRlNzI1XCIpKTtcblxudmFyIG1hZ21hID0gcmFtcChjb2xvcnMoXCIwMDAwMDQwMTAwMDUwMTAxMDYwMTAxMDgwMjAxMDkwMjAyMGIwMjAyMGQwMzAzMGYwMzAzMTIwNDA0MTQwNTA0MTYwNjA1MTgwNjA1MWEwNzA2MWMwODA3MWUwOTA3MjAwYTA4MjIwYjA5MjQwYzA5MjYwZDBhMjkwZTBiMmIxMDBiMmQxMTBjMmYxMjBkMzExMzBkMzQxNDBlMzYxNTBlMzgxNjBmM2IxODBmM2QxOTEwM2YxYTEwNDIxYzEwNDQxZDExNDcxZTExNDkyMDExNGIyMTExNGUyMjExNTAyNDEyNTMyNTEyNTUyNzEyNTgyOTExNWEyYTExNWMyYzExNWYyZDExNjEyZjExNjMzMTExNjUzMzEwNjczNDEwNjkzNjEwNmIzODEwNmMzOTBmNmUzYjBmNzAzZDBmNzEzZjBmNzI0MDBmNzQ0MjBmNzU0NDBmNzY0NTEwNzc0NzEwNzg0OTEwNzg0YTEwNzk0YzExN2E0ZTExN2I0ZjEyN2I1MTEyN2M1MjEzN2M1NDEzN2Q1NjE0N2Q1NzE1N2U1OTE1N2U1YTE2N2U1YzE2N2Y1ZDE3N2Y1ZjE4N2Y2MDE4ODA2MjE5ODA2NDFhODA2NTFhODA2NzFiODA2ODFjODE2YTFjODE2YjFkODE2ZDFkODE2ZTFlODE3MDFmODE3MjFmODE3MzIwODE3NTIxODE3NjIxODE3ODIyODE3OTIyODI3YjIzODI3YzIzODI3ZTI0ODI4MDI1ODI4MTI1ODE4MzI2ODE4NDI2ODE4NjI3ODE4ODI3ODE4OTI4ODE4YjI5ODE4YzI5ODE4ZTJhODE5MDJhODE5MTJiODE5MzJiODA5NDJjODA5NjJjODA5ODJkODA5OTJkODA5YjJlN2Y5YzJlN2Y5ZTJmN2ZhMDJmN2ZhMTMwN2VhMzMwN2VhNTMxN2VhNjMxN2RhODMyN2RhYTMzN2RhYjMzN2NhZDM0N2NhZTM0N2JiMDM1N2JiMjM1N2JiMzM2N2FiNTM2N2FiNzM3NzliODM3NzliYTM4NzhiYzM5NzhiZDM5NzdiZjNhNzdjMDNhNzZjMjNiNzVjNDNjNzVjNTNjNzRjNzNkNzNjODNlNzNjYTNlNzJjYzNmNzFjZDQwNzFjZjQwNzBkMDQxNmZkMjQyNmZkMzQzNmVkNTQ0NmRkNjQ1NmNkODQ1NmNkOTQ2NmJkYjQ3NmFkYzQ4NjlkZTQ5NjhkZjRhNjhlMDRjNjdlMjRkNjZlMzRlNjVlNDRmNjRlNTUwNjRlNzUyNjNlODUzNjJlOTU0NjJlYTU2NjFlYjU3NjBlYzU4NjBlZDVhNWZlZTViNWVlZjVkNWVmMDVmNWVmMTYwNWRmMjYyNWRmMjY0NWNmMzY1NWNmNDY3NWNmNDY5NWNmNTZiNWNmNjZjNWNmNjZlNWNmNzcwNWNmNzcyNWNmODc0NWNmODc2NWNmOTc4NWRmOTc5NWRmOTdiNWRmYTdkNWVmYTdmNWVmYTgxNWZmYjgzNWZmYjg1NjBmYjg3NjFmYzg5NjFmYzhhNjJmYzhjNjNmYzhlNjRmYzkwNjVmZDkyNjZmZDk0NjdmZDk2NjhmZDk4NjlmZDlhNmFmZDliNmJmZTlkNmNmZTlmNmRmZWExNmVmZWEzNmZmZWE1NzFmZWE3NzJmZWE5NzNmZWFhNzRmZWFjNzZmZWFlNzdmZWIwNzhmZWIyN2FmZWI0N2JmZWI2N2NmZWI3N2VmZWI5N2ZmZWJiODFmZWJkODJmZWJmODRmZWMxODVmZWMyODdmZWM0ODhmZWM2OGFmZWM4OGNmZWNhOGRmZWNjOGZmZWNkOTBmZWNmOTJmZWQxOTRmZWQzOTVmZWQ1OTdmZWQ3OTlmZWQ4OWFmZGRhOWNmZGRjOWVmZGRlYTBmZGUwYTFmZGUyYTNmZGUzYTVmZGU1YTdmZGU3YTlmZGU5YWFmZGViYWNmY2VjYWVmY2VlYjBmY2YwYjJmY2YyYjRmY2Y0YjZmY2Y2YjhmY2Y3YjlmY2Y5YmJmY2ZiYmRmY2ZkYmZcIikpO1xuXG52YXIgaW5mZXJubyA9IHJhbXAoY29sb3JzKFwiMDAwMDA0MDEwMDA1MDEwMTA2MDEwMTA4MDIwMTBhMDIwMjBjMDIwMjBlMDMwMjEwMDQwMzEyMDQwMzE0MDUwNDE3MDYwNDE5MDcwNTFiMDgwNTFkMDkwNjFmMGEwNzIyMGIwNzI0MGMwODI2MGQwODI5MGUwOTJiMTAwOTJkMTEwYTMwMTIwYTMyMTQwYjM0MTUwYjM3MTYwYjM5MTgwYzNjMTkwYzNlMWIwYzQxMWMwYzQzMWUwYzQ1MWYwYzQ4MjEwYzRhMjMwYzRjMjQwYzRmMjYwYzUxMjgwYjUzMjkwYjU1MmIwYjU3MmQwYjU5MmYwYTViMzEwYTVjMzIwYTVlMzQwYTVmMzYwOTYxMzgwOTYyMzkwOTYzM2IwOTY0M2QwOTY1M2UwOTY2NDAwYTY3NDIwYTY4NDQwYTY4NDUwYTY5NDcwYjZhNDkwYjZhNGEwYzZiNGMwYzZiNGQwZDZjNGYwZDZjNTEwZTZjNTIwZTZkNTQwZjZkNTUwZjZkNTcxMDZlNTkxMDZlNWExMTZlNWMxMjZlNWQxMjZlNWYxMzZlNjExMzZlNjIxNDZlNjQxNTZlNjUxNTZlNjcxNjZlNjkxNjZlNmExNzZlNmMxODZlNmQxODZlNmYxOTZlNzExOTZlNzIxYTZlNzQxYTZlNzUxYjZlNzcxYzZkNzgxYzZkN2ExZDZkN2MxZDZkN2QxZTZkN2YxZTZjODAxZjZjODIyMDZjODQyMDZiODUyMTZiODcyMTZiODgyMjZhOGEyMjZhOGMyMzY5OGQyMzY5OGYyNDY5OTAyNTY4OTIyNTY4OTMyNjY3OTUyNjY3OTcyNzY2OTgyNzY2OWEyODY1OWIyOTY0OWQyOTY0OWYyYTYzYTAyYTYzYTIyYjYyYTMyYzYxYTUyYzYwYTYyZDYwYTgyZTVmYTkyZTVlYWIyZjVlYWQzMDVkYWUzMDVjYjAzMTViYjEzMjVhYjMzMjVhYjQzMzU5YjYzNDU4YjczNTU3YjkzNTU2YmEzNjU1YmMzNzU0YmQzODUzYmYzOTUyYzAzYTUxYzEzYTUwYzMzYjRmYzQzYzRlYzYzZDRkYzczZTRjYzgzZjRiY2E0MDRhY2I0MTQ5Y2M0MjQ4Y2U0MzQ3Y2Y0NDQ2ZDA0NTQ1ZDI0NjQ0ZDM0NzQzZDQ0ODQyZDU0YTQxZDc0YjNmZDg0YzNlZDk0ZDNkZGE0ZTNjZGI1MDNiZGQ1MTNhZGU1MjM4ZGY1MzM3ZTA1NTM2ZTE1NjM1ZTI1NzM0ZTM1OTMzZTQ1YTMxZTU1YzMwZTY1ZDJmZTc1ZTJlZTg2MDJkZTk2MTJiZWE2MzJhZWI2NDI5ZWI2NjI4ZWM2NzI2ZWQ2OTI1ZWU2YTI0ZWY2YzIzZWY2ZTIxZjA2ZjIwZjE3MTFmZjE3MzFkZjI3NDFjZjM3NjFiZjM3ODE5ZjQ3OTE4ZjU3YjE3ZjU3ZDE1ZjY3ZTE0ZjY4MDEzZjc4MjEyZjc4NDEwZjg4NTBmZjg4NzBlZjg4OTBjZjk4YjBiZjk4YzBhZjk4ZTA5ZmE5MDA4ZmE5MjA3ZmE5NDA3ZmI5NjA2ZmI5NzA2ZmI5OTA2ZmI5YjA2ZmI5ZDA3ZmM5ZjA3ZmNhMTA4ZmNhMzA5ZmNhNTBhZmNhNjBjZmNhODBkZmNhYTBmZmNhYzExZmNhZTEyZmNiMDE0ZmNiMjE2ZmNiNDE4ZmJiNjFhZmJiODFkZmJiYTFmZmJiYzIxZmJiZTIzZmFjMDI2ZmFjMjI4ZmFjNDJhZmFjNjJkZjljNzJmZjljOTMyZjljYjM1ZjhjZDM3ZjhjZjNhZjdkMTNkZjdkMzQwZjZkNTQzZjZkNzQ2ZjVkOTQ5ZjVkYjRjZjRkZDRmZjRkZjUzZjRlMTU2ZjNlMzVhZjNlNTVkZjJlNjYxZjJlODY1ZjJlYTY5ZjFlYzZkZjFlZDcxZjFlZjc1ZjFmMTc5ZjJmMjdkZjJmNDgyZjNmNTg2ZjNmNjhhZjRmODhlZjVmOTkyZjZmYTk2ZjhmYjlhZjlmYzlkZmFmZGExZmNmZmE0XCIpKTtcblxudmFyIHBsYXNtYSA9IHJhbXAoY29sb3JzKFwiMGQwODg3MTAwNzg4MTMwNzg5MTYwNzhhMTkwNjhjMWIwNjhkMWQwNjhlMjAwNjhmMjIwNjkwMjQwNjkxMjYwNTkxMjgwNTkyMmEwNTkzMmMwNTk0MmUwNTk1MmYwNTk2MzEwNTk3MzMwNTk3MzUwNDk4MzcwNDk5MzgwNDlhM2EwNDlhM2MwNDliM2UwNDljM2YwNDljNDEwNDlkNDMwMzllNDQwMzllNDYwMzlmNDgwMzlmNDkwM2EwNGIwM2ExNGMwMmExNGUwMmEyNTAwMmEyNTEwMmEzNTMwMmEzNTUwMmE0NTYwMWE0NTgwMWE0NTkwMWE1NWIwMWE1NWMwMWE2NWUwMWE2NjAwMWE2NjEwMGE3NjMwMGE3NjQwMGE3NjYwMGE3NjcwMGE4NjkwMGE4NmEwMGE4NmMwMGE4NmUwMGE4NmYwMGE4NzEwMGE4NzIwMWE4NzQwMWE4NzUwMWE4NzcwMWE4NzgwMWE4N2EwMmE4N2IwMmE4N2QwM2E4N2UwM2E4ODAwNGE4ODEwNGE3ODMwNWE3ODQwNWE3ODYwNmE2ODcwN2E2ODgwOGE2OGEwOWE1OGIwYWE1OGQwYmE1OGUwY2E0OGYwZGE0OTEwZWEzOTIwZmEzOTQxMGEyOTUxMWExOTYxM2ExOTgxNGEwOTkxNTlmOWExNjlmOWMxNzllOWQxODlkOWUxOTlkYTAxYTljYTExYjliYTIxZDlhYTMxZTlhYTUxZjk5YTYyMDk4YTcyMTk3YTgyMjk2YWEyMzk1YWIyNDk0YWMyNjk0YWQyNzkzYWUyODkyYjAyOTkxYjEyYTkwYjIyYjhmYjMyYzhlYjQyZThkYjUyZjhjYjYzMDhiYjczMThhYjgzMjg5YmEzMzg4YmIzNDg4YmMzNTg3YmQzNzg2YmUzODg1YmYzOTg0YzAzYTgzYzEzYjgyYzIzYzgxYzMzZDgwYzQzZTdmYzU0MDdlYzY0MTdkYzc0MjdjYzg0MzdiYzk0NDdhY2E0NTdhY2I0Njc5Y2M0Nzc4Y2M0OTc3Y2Q0YTc2Y2U0Yjc1Y2Y0Yzc0ZDA0ZDczZDE0ZTcyZDI0ZjcxZDM1MTcxZDQ1MjcwZDU1MzZmZDU1NDZlZDY1NTZkZDc1NjZjZDg1NzZiZDk1ODZhZGE1YTZhZGE1YjY5ZGI1YzY4ZGM1ZDY3ZGQ1ZTY2ZGU1ZjY1ZGU2MTY0ZGY2MjYzZTA2MzYzZTE2NDYyZTI2NTYxZTI2NjYwZTM2ODVmZTQ2OTVlZTU2YTVkZTU2YjVkZTY2YzVjZTc2ZTViZTc2ZjVhZTg3MDU5ZTk3MTU4ZTk3MjU3ZWE3NDU3ZWI3NTU2ZWI3NjU1ZWM3NzU0ZWQ3OTUzZWQ3YTUyZWU3YjUxZWY3YzUxZWY3ZTUwZjA3ZjRmZjA4MDRlZjE4MTRkZjE4MzRjZjI4NDRiZjM4NTRiZjM4NzRhZjQ4ODQ5ZjQ4OTQ4ZjU4YjQ3ZjU4YzQ2ZjY4ZDQ1ZjY4ZjQ0Zjc5MDQ0Zjc5MTQzZjc5MzQyZjg5NDQxZjg5NTQwZjk5NzNmZjk5ODNlZjk5YTNlZmE5YjNkZmE5YzNjZmE5ZTNiZmI5ZjNhZmJhMTM5ZmJhMjM4ZmNhMzM4ZmNhNTM3ZmNhNjM2ZmNhODM1ZmNhOTM0ZmRhYjMzZmRhYzMzZmRhZTMyZmRhZjMxZmRiMTMwZmRiMjJmZmRiNDJmZmRiNTJlZmViNzJkZmViODJjZmViYTJjZmViYjJiZmViZDJhZmViZTJhZmVjMDI5ZmRjMjI5ZmRjMzI4ZmRjNTI3ZmRjNjI3ZmRjODI3ZmRjYTI2ZmRjYjI2ZmNjZDI1ZmNjZTI1ZmNkMDI1ZmNkMjI1ZmJkMzI0ZmJkNTI0ZmJkNzI0ZmFkODI0ZmFkYTI0ZjlkYzI0ZjlkZDI1ZjhkZjI1ZjhlMTI1ZjdlMjI1ZjdlNDI1ZjZlNjI2ZjZlODI2ZjVlOTI2ZjVlYjI3ZjRlZDI3ZjNlZTI3ZjNmMDI3ZjJmMjI3ZjFmNDI2ZjFmNTI1ZjBmNzI0ZjBmOTIxXCIpKTtcblxuZnVuY3Rpb24gc2VxdWVudGlhbChpbnRlcnBvbGF0b3IpIHtcbiAgdmFyIHgwID0gMCxcbiAgICAgIHgxID0gMSxcbiAgICAgIGNsYW1wID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIHZhciB0ID0gKHggLSB4MCkgLyAoeDEgLSB4MCk7XG4gICAgcmV0dXJuIGludGVycG9sYXRvcihjbGFtcCA/IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHQpKSA6IHQpO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgwID0gK19bMF0sIHgxID0gK19bMV0sIHNjYWxlKSA6IFt4MCwgeDFdO1xuICB9O1xuXG4gIHNjYWxlLmNsYW1wID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNsYW1wID0gISFfLCBzY2FsZSkgOiBjbGFtcDtcbiAgfTtcblxuICBzY2FsZS5pbnRlcnBvbGF0b3IgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaW50ZXJwb2xhdG9yID0gXywgc2NhbGUpIDogaW50ZXJwb2xhdG9yO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gc2VxdWVudGlhbChpbnRlcnBvbGF0b3IpLmRvbWFpbihbeDAsIHgxXSkuY2xhbXAoY2xhbXApO1xuICB9O1xuXG4gIHJldHVybiBsaW5lYXJpc2goc2NhbGUpO1xufVxuXG52YXIgY29uc3RhbnQkMTAgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiBmdW5jdGlvbiBjb25zdGFudCgpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn07XG5cbnZhciBhYnMkMSA9IE1hdGguYWJzO1xudmFyIGF0YW4yJDEgPSBNYXRoLmF0YW4yO1xudmFyIGNvcyQyID0gTWF0aC5jb3M7XG52YXIgbWF4JDIgPSBNYXRoLm1heDtcbnZhciBtaW4kMSA9IE1hdGgubWluO1xudmFyIHNpbiQyID0gTWF0aC5zaW47XG52YXIgc3FydCQyID0gTWF0aC5zcXJ0O1xuXG52YXIgZXBzaWxvbiQzID0gMWUtMTI7XG52YXIgcGkkNCA9IE1hdGguUEk7XG52YXIgaGFsZlBpJDMgPSBwaSQ0IC8gMjtcbnZhciB0YXUkNCA9IDIgKiBwaSQ0O1xuXG5mdW5jdGlvbiBhY29zJDEoeCkge1xuICByZXR1cm4geCA+IDEgPyAwIDogeCA8IC0xID8gcGkkNCA6IE1hdGguYWNvcyh4KTtcbn1cblxuZnVuY3Rpb24gYXNpbiQxKHgpIHtcbiAgcmV0dXJuIHggPj0gMSA/IGhhbGZQaSQzIDogeCA8PSAtMSA/IC1oYWxmUGkkMyA6IE1hdGguYXNpbih4KTtcbn1cblxuZnVuY3Rpb24gYXJjSW5uZXJSYWRpdXMoZCkge1xuICByZXR1cm4gZC5pbm5lclJhZGl1cztcbn1cblxuZnVuY3Rpb24gYXJjT3V0ZXJSYWRpdXMoZCkge1xuICByZXR1cm4gZC5vdXRlclJhZGl1cztcbn1cblxuZnVuY3Rpb24gYXJjU3RhcnRBbmdsZShkKSB7XG4gIHJldHVybiBkLnN0YXJ0QW5nbGU7XG59XG5cbmZ1bmN0aW9uIGFyY0VuZEFuZ2xlKGQpIHtcbiAgcmV0dXJuIGQuZW5kQW5nbGU7XG59XG5cbmZ1bmN0aW9uIGFyY1BhZEFuZ2xlKGQpIHtcbiAgcmV0dXJuIGQgJiYgZC5wYWRBbmdsZTsgLy8gTm90ZTogb3B0aW9uYWwhXG59XG5cbmZ1bmN0aW9uIGludGVyc2VjdCh4MCwgeTAsIHgxLCB5MSwgeDIsIHkyLCB4MywgeTMpIHtcbiAgdmFyIHgxMCA9IHgxIC0geDAsIHkxMCA9IHkxIC0geTAsXG4gICAgICB4MzIgPSB4MyAtIHgyLCB5MzIgPSB5MyAtIHkyLFxuICAgICAgdCA9ICh4MzIgKiAoeTAgLSB5MikgLSB5MzIgKiAoeDAgLSB4MikpIC8gKHkzMiAqIHgxMCAtIHgzMiAqIHkxMCk7XG4gIHJldHVybiBbeDAgKyB0ICogeDEwLCB5MCArIHQgKiB5MTBdO1xufVxuXG4vLyBDb21wdXRlIHBlcnBlbmRpY3VsYXIgb2Zmc2V0IGxpbmUgb2YgbGVuZ3RoIHJjLlxuLy8gaHR0cDovL21hdGh3b3JsZC53b2xmcmFtLmNvbS9DaXJjbGUtTGluZUludGVyc2VjdGlvbi5odG1sXG5mdW5jdGlvbiBjb3JuZXJUYW5nZW50cyh4MCwgeTAsIHgxLCB5MSwgcjEsIHJjLCBjdykge1xuICB2YXIgeDAxID0geDAgLSB4MSxcbiAgICAgIHkwMSA9IHkwIC0geTEsXG4gICAgICBsbyA9IChjdyA/IHJjIDogLXJjKSAvIHNxcnQkMih4MDEgKiB4MDEgKyB5MDEgKiB5MDEpLFxuICAgICAgb3ggPSBsbyAqIHkwMSxcbiAgICAgIG95ID0gLWxvICogeDAxLFxuICAgICAgeDExID0geDAgKyBveCxcbiAgICAgIHkxMSA9IHkwICsgb3ksXG4gICAgICB4MTAgPSB4MSArIG94LFxuICAgICAgeTEwID0geTEgKyBveSxcbiAgICAgIHgwMCA9ICh4MTEgKyB4MTApIC8gMixcbiAgICAgIHkwMCA9ICh5MTEgKyB5MTApIC8gMixcbiAgICAgIGR4ID0geDEwIC0geDExLFxuICAgICAgZHkgPSB5MTAgLSB5MTEsXG4gICAgICBkMiA9IGR4ICogZHggKyBkeSAqIGR5LFxuICAgICAgciA9IHIxIC0gcmMsXG4gICAgICBEID0geDExICogeTEwIC0geDEwICogeTExLFxuICAgICAgZCA9IChkeSA8IDAgPyAtMSA6IDEpICogc3FydCQyKG1heCQyKDAsIHIgKiByICogZDIgLSBEICogRCkpLFxuICAgICAgY3gwID0gKEQgKiBkeSAtIGR4ICogZCkgLyBkMixcbiAgICAgIGN5MCA9ICgtRCAqIGR4IC0gZHkgKiBkKSAvIGQyLFxuICAgICAgY3gxID0gKEQgKiBkeSArIGR4ICogZCkgLyBkMixcbiAgICAgIGN5MSA9ICgtRCAqIGR4ICsgZHkgKiBkKSAvIGQyLFxuICAgICAgZHgwID0gY3gwIC0geDAwLFxuICAgICAgZHkwID0gY3kwIC0geTAwLFxuICAgICAgZHgxID0gY3gxIC0geDAwLFxuICAgICAgZHkxID0gY3kxIC0geTAwO1xuXG4gIC8vIFBpY2sgdGhlIGNsb3NlciBvZiB0aGUgdHdvIGludGVyc2VjdGlvbiBwb2ludHMuXG4gIC8vIFRPRE8gSXMgdGhlcmUgYSBmYXN0ZXIgd2F5IHRvIGRldGVybWluZSB3aGljaCBpbnRlcnNlY3Rpb24gdG8gdXNlP1xuICBpZiAoZHgwICogZHgwICsgZHkwICogZHkwID4gZHgxICogZHgxICsgZHkxICogZHkxKSBjeDAgPSBjeDEsIGN5MCA9IGN5MTtcblxuICByZXR1cm4ge1xuICAgIGN4OiBjeDAsXG4gICAgY3k6IGN5MCxcbiAgICB4MDE6IC1veCxcbiAgICB5MDE6IC1veSxcbiAgICB4MTE6IGN4MCAqIChyMSAvIHIgLSAxKSxcbiAgICB5MTE6IGN5MCAqIChyMSAvIHIgLSAxKVxuICB9O1xufVxuXG52YXIgYXJjID0gZnVuY3Rpb24oKSB7XG4gIHZhciBpbm5lclJhZGl1cyA9IGFyY0lubmVyUmFkaXVzLFxuICAgICAgb3V0ZXJSYWRpdXMgPSBhcmNPdXRlclJhZGl1cyxcbiAgICAgIGNvcm5lclJhZGl1cyA9IGNvbnN0YW50JDEwKDApLFxuICAgICAgcGFkUmFkaXVzID0gbnVsbCxcbiAgICAgIHN0YXJ0QW5nbGUgPSBhcmNTdGFydEFuZ2xlLFxuICAgICAgZW5kQW5nbGUgPSBhcmNFbmRBbmdsZSxcbiAgICAgIHBhZEFuZ2xlID0gYXJjUGFkQW5nbGUsXG4gICAgICBjb250ZXh0ID0gbnVsbDtcblxuICBmdW5jdGlvbiBhcmMoKSB7XG4gICAgdmFyIGJ1ZmZlcixcbiAgICAgICAgcixcbiAgICAgICAgcjAgPSAraW5uZXJSYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgcjEgPSArb3V0ZXJSYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgYTAgPSBzdGFydEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgLSBoYWxmUGkkMyxcbiAgICAgICAgYTEgPSBlbmRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIC0gaGFsZlBpJDMsXG4gICAgICAgIGRhID0gYWJzJDEoYTEgLSBhMCksXG4gICAgICAgIGN3ID0gYTEgPiBhMDtcblxuICAgIGlmICghY29udGV4dCkgY29udGV4dCA9IGJ1ZmZlciA9IHBhdGgoKTtcblxuICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBvdXRlciByYWRpdXMgaXMgYWx3YXlzIGxhcmdlciB0aGFuIHRoZSBpbm5lciByYWRpdXMuXG4gICAgaWYgKHIxIDwgcjApIHIgPSByMSwgcjEgPSByMCwgcjAgPSByO1xuXG4gICAgLy8gSXMgaXQgYSBwb2ludD9cbiAgICBpZiAoIShyMSA+IGVwc2lsb24kMykpIGNvbnRleHQubW92ZVRvKDAsIDApO1xuXG4gICAgLy8gT3IgaXMgaXQgYSBjaXJjbGUgb3IgYW5udWx1cz9cbiAgICBlbHNlIGlmIChkYSA+IHRhdSQ0IC0gZXBzaWxvbiQzKSB7XG4gICAgICBjb250ZXh0Lm1vdmVUbyhyMSAqIGNvcyQyKGEwKSwgcjEgKiBzaW4kMihhMCkpO1xuICAgICAgY29udGV4dC5hcmMoMCwgMCwgcjEsIGEwLCBhMSwgIWN3KTtcbiAgICAgIGlmIChyMCA+IGVwc2lsb24kMykge1xuICAgICAgICBjb250ZXh0Lm1vdmVUbyhyMCAqIGNvcyQyKGExKSwgcjAgKiBzaW4kMihhMSkpO1xuICAgICAgICBjb250ZXh0LmFyYygwLCAwLCByMCwgYTEsIGEwLCBjdyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gT3IgaXMgaXQgYSBjaXJjdWxhciBvciBhbm51bGFyIHNlY3Rvcj9cbiAgICBlbHNlIHtcbiAgICAgIHZhciBhMDEgPSBhMCxcbiAgICAgICAgICBhMTEgPSBhMSxcbiAgICAgICAgICBhMDAgPSBhMCxcbiAgICAgICAgICBhMTAgPSBhMSxcbiAgICAgICAgICBkYTAgPSBkYSxcbiAgICAgICAgICBkYTEgPSBkYSxcbiAgICAgICAgICBhcCA9IHBhZEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgLyAyLFxuICAgICAgICAgIHJwID0gKGFwID4gZXBzaWxvbiQzKSAmJiAocGFkUmFkaXVzID8gK3BhZFJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogc3FydCQyKHIwICogcjAgKyByMSAqIHIxKSksXG4gICAgICAgICAgcmMgPSBtaW4kMShhYnMkMShyMSAtIHIwKSAvIDIsICtjb3JuZXJSYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSksXG4gICAgICAgICAgcmMwID0gcmMsXG4gICAgICAgICAgcmMxID0gcmMsXG4gICAgICAgICAgdDAsXG4gICAgICAgICAgdDE7XG5cbiAgICAgIC8vIEFwcGx5IHBhZGRpbmc/IE5vdGUgdGhhdCBzaW5jZSByMSDiiaUgcjAsIGRhMSDiiaUgZGEwLlxuICAgICAgaWYgKHJwID4gZXBzaWxvbiQzKSB7XG4gICAgICAgIHZhciBwMCA9IGFzaW4kMShycCAvIHIwICogc2luJDIoYXApKSxcbiAgICAgICAgICAgIHAxID0gYXNpbiQxKHJwIC8gcjEgKiBzaW4kMihhcCkpO1xuICAgICAgICBpZiAoKGRhMCAtPSBwMCAqIDIpID4gZXBzaWxvbiQzKSBwMCAqPSAoY3cgPyAxIDogLTEpLCBhMDAgKz0gcDAsIGExMCAtPSBwMDtcbiAgICAgICAgZWxzZSBkYTAgPSAwLCBhMDAgPSBhMTAgPSAoYTAgKyBhMSkgLyAyO1xuICAgICAgICBpZiAoKGRhMSAtPSBwMSAqIDIpID4gZXBzaWxvbiQzKSBwMSAqPSAoY3cgPyAxIDogLTEpLCBhMDEgKz0gcDEsIGExMSAtPSBwMTtcbiAgICAgICAgZWxzZSBkYTEgPSAwLCBhMDEgPSBhMTEgPSAoYTAgKyBhMSkgLyAyO1xuICAgICAgfVxuXG4gICAgICB2YXIgeDAxID0gcjEgKiBjb3MkMihhMDEpLFxuICAgICAgICAgIHkwMSA9IHIxICogc2luJDIoYTAxKSxcbiAgICAgICAgICB4MTAgPSByMCAqIGNvcyQyKGExMCksXG4gICAgICAgICAgeTEwID0gcjAgKiBzaW4kMihhMTApO1xuXG4gICAgICAvLyBBcHBseSByb3VuZGVkIGNvcm5lcnM/XG4gICAgICBpZiAocmMgPiBlcHNpbG9uJDMpIHtcbiAgICAgICAgdmFyIHgxMSA9IHIxICogY29zJDIoYTExKSxcbiAgICAgICAgICAgIHkxMSA9IHIxICogc2luJDIoYTExKSxcbiAgICAgICAgICAgIHgwMCA9IHIwICogY29zJDIoYTAwKSxcbiAgICAgICAgICAgIHkwMCA9IHIwICogc2luJDIoYTAwKTtcblxuICAgICAgICAvLyBSZXN0cmljdCB0aGUgY29ybmVyIHJhZGl1cyBhY2NvcmRpbmcgdG8gdGhlIHNlY3RvciBhbmdsZS5cbiAgICAgICAgaWYgKGRhIDwgcGkkNCkge1xuICAgICAgICAgIHZhciBvYyA9IGRhMCA+IGVwc2lsb24kMyA/IGludGVyc2VjdCh4MDEsIHkwMSwgeDAwLCB5MDAsIHgxMSwgeTExLCB4MTAsIHkxMCkgOiBbeDEwLCB5MTBdLFxuICAgICAgICAgICAgICBheCA9IHgwMSAtIG9jWzBdLFxuICAgICAgICAgICAgICBheSA9IHkwMSAtIG9jWzFdLFxuICAgICAgICAgICAgICBieCA9IHgxMSAtIG9jWzBdLFxuICAgICAgICAgICAgICBieSA9IHkxMSAtIG9jWzFdLFxuICAgICAgICAgICAgICBrYyA9IDEgLyBzaW4kMihhY29zJDEoKGF4ICogYnggKyBheSAqIGJ5KSAvIChzcXJ0JDIoYXggKiBheCArIGF5ICogYXkpICogc3FydCQyKGJ4ICogYnggKyBieSAqIGJ5KSkpIC8gMiksXG4gICAgICAgICAgICAgIGxjID0gc3FydCQyKG9jWzBdICogb2NbMF0gKyBvY1sxXSAqIG9jWzFdKTtcbiAgICAgICAgICByYzAgPSBtaW4kMShyYywgKHIwIC0gbGMpIC8gKGtjIC0gMSkpO1xuICAgICAgICAgIHJjMSA9IG1pbiQxKHJjLCAocjEgLSBsYykgLyAoa2MgKyAxKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSXMgdGhlIHNlY3RvciBjb2xsYXBzZWQgdG8gYSBsaW5lP1xuICAgICAgaWYgKCEoZGExID4gZXBzaWxvbiQzKSkgY29udGV4dC5tb3ZlVG8oeDAxLCB5MDEpO1xuXG4gICAgICAvLyBEb2VzIHRoZSBzZWN0b3LigJlzIG91dGVyIHJpbmcgaGF2ZSByb3VuZGVkIGNvcm5lcnM/XG4gICAgICBlbHNlIGlmIChyYzEgPiBlcHNpbG9uJDMpIHtcbiAgICAgICAgdDAgPSBjb3JuZXJUYW5nZW50cyh4MDAsIHkwMCwgeDAxLCB5MDEsIHIxLCByYzEsIGN3KTtcbiAgICAgICAgdDEgPSBjb3JuZXJUYW5nZW50cyh4MTEsIHkxMSwgeDEwLCB5MTAsIHIxLCByYzEsIGN3KTtcblxuICAgICAgICBjb250ZXh0Lm1vdmVUbyh0MC5jeCArIHQwLngwMSwgdDAuY3kgKyB0MC55MDEpO1xuXG4gICAgICAgIC8vIEhhdmUgdGhlIGNvcm5lcnMgbWVyZ2VkP1xuICAgICAgICBpZiAocmMxIDwgcmMpIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMxLCBhdGFuMiQxKHQwLnkwMSwgdDAueDAxKSwgYXRhbjIkMSh0MS55MDEsIHQxLngwMSksICFjdyk7XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBkcmF3IHRoZSB0d28gY29ybmVycyBhbmQgdGhlIHJpbmcuXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMxLCBhdGFuMiQxKHQwLnkwMSwgdDAueDAxKSwgYXRhbjIkMSh0MC55MTEsIHQwLngxMSksICFjdyk7XG4gICAgICAgICAgY29udGV4dC5hcmMoMCwgMCwgcjEsIGF0YW4yJDEodDAuY3kgKyB0MC55MTEsIHQwLmN4ICsgdDAueDExKSwgYXRhbjIkMSh0MS5jeSArIHQxLnkxMSwgdDEuY3ggKyB0MS54MTEpLCAhY3cpO1xuICAgICAgICAgIGNvbnRleHQuYXJjKHQxLmN4LCB0MS5jeSwgcmMxLCBhdGFuMiQxKHQxLnkxMSwgdDEueDExKSwgYXRhbjIkMSh0MS55MDEsIHQxLngwMSksICFjdyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT3IgaXMgdGhlIG91dGVyIHJpbmcganVzdCBhIGNpcmN1bGFyIGFyYz9cbiAgICAgIGVsc2UgY29udGV4dC5tb3ZlVG8oeDAxLCB5MDEpLCBjb250ZXh0LmFyYygwLCAwLCByMSwgYTAxLCBhMTEsICFjdyk7XG5cbiAgICAgIC8vIElzIHRoZXJlIG5vIGlubmVyIHJpbmcsIGFuZCBpdOKAmXMgYSBjaXJjdWxhciBzZWN0b3I/XG4gICAgICAvLyBPciBwZXJoYXBzIGl04oCZcyBhbiBhbm51bGFyIHNlY3RvciBjb2xsYXBzZWQgZHVlIHRvIHBhZGRpbmc/XG4gICAgICBpZiAoIShyMCA+IGVwc2lsb24kMykgfHwgIShkYTAgPiBlcHNpbG9uJDMpKSBjb250ZXh0LmxpbmVUbyh4MTAsIHkxMCk7XG5cbiAgICAgIC8vIERvZXMgdGhlIHNlY3RvcuKAmXMgaW5uZXIgcmluZyAob3IgcG9pbnQpIGhhdmUgcm91bmRlZCBjb3JuZXJzP1xuICAgICAgZWxzZSBpZiAocmMwID4gZXBzaWxvbiQzKSB7XG4gICAgICAgIHQwID0gY29ybmVyVGFuZ2VudHMoeDEwLCB5MTAsIHgxMSwgeTExLCByMCwgLXJjMCwgY3cpO1xuICAgICAgICB0MSA9IGNvcm5lclRhbmdlbnRzKHgwMSwgeTAxLCB4MDAsIHkwMCwgcjAsIC1yYzAsIGN3KTtcblxuICAgICAgICBjb250ZXh0LmxpbmVUbyh0MC5jeCArIHQwLngwMSwgdDAuY3kgKyB0MC55MDEpO1xuXG4gICAgICAgIC8vIEhhdmUgdGhlIGNvcm5lcnMgbWVyZ2VkP1xuICAgICAgICBpZiAocmMwIDwgcmMpIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMwLCBhdGFuMiQxKHQwLnkwMSwgdDAueDAxKSwgYXRhbjIkMSh0MS55MDEsIHQxLngwMSksICFjdyk7XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBkcmF3IHRoZSB0d28gY29ybmVycyBhbmQgdGhlIHJpbmcuXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMwLCBhdGFuMiQxKHQwLnkwMSwgdDAueDAxKSwgYXRhbjIkMSh0MC55MTEsIHQwLngxMSksICFjdyk7XG4gICAgICAgICAgY29udGV4dC5hcmMoMCwgMCwgcjAsIGF0YW4yJDEodDAuY3kgKyB0MC55MTEsIHQwLmN4ICsgdDAueDExKSwgYXRhbjIkMSh0MS5jeSArIHQxLnkxMSwgdDEuY3ggKyB0MS54MTEpLCBjdyk7XG4gICAgICAgICAgY29udGV4dC5hcmModDEuY3gsIHQxLmN5LCByYzAsIGF0YW4yJDEodDEueTExLCB0MS54MTEpLCBhdGFuMiQxKHQxLnkwMSwgdDEueDAxKSwgIWN3KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBPciBpcyB0aGUgaW5uZXIgcmluZyBqdXN0IGEgY2lyY3VsYXIgYXJjP1xuICAgICAgZWxzZSBjb250ZXh0LmFyYygwLCAwLCByMCwgYTEwLCBhMDAsIGN3KTtcbiAgICB9XG5cbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuXG4gICAgaWYgKGJ1ZmZlcikgcmV0dXJuIGNvbnRleHQgPSBudWxsLCBidWZmZXIgKyBcIlwiIHx8IG51bGw7XG4gIH1cblxuICBhcmMuY2VudHJvaWQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgciA9ICgraW5uZXJSYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSArICtvdXRlclJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSAvIDIsXG4gICAgICAgIGEgPSAoK3N0YXJ0QW5nbGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSArICtlbmRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSAvIDIgLSBwaSQ0IC8gMjtcbiAgICByZXR1cm4gW2NvcyQyKGEpICogciwgc2luJDIoYSkgKiByXTtcbiAgfTtcblxuICBhcmMuaW5uZXJSYWRpdXMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaW5uZXJSYWRpdXMgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCtfKSwgYXJjKSA6IGlubmVyUmFkaXVzO1xuICB9O1xuXG4gIGFyYy5vdXRlclJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChvdXRlclJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoK18pLCBhcmMpIDogb3V0ZXJSYWRpdXM7XG4gIH07XG5cbiAgYXJjLmNvcm5lclJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjb3JuZXJSYWRpdXMgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCtfKSwgYXJjKSA6IGNvcm5lclJhZGl1cztcbiAgfTtcblxuICBhcmMucGFkUmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZFJhZGl1cyA9IF8gPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCtfKSwgYXJjKSA6IHBhZFJhZGl1cztcbiAgfTtcblxuICBhcmMuc3RhcnRBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdGFydEFuZ2xlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMCgrXyksIGFyYykgOiBzdGFydEFuZ2xlO1xuICB9O1xuXG4gIGFyYy5lbmRBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChlbmRBbmdsZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoK18pLCBhcmMpIDogZW5kQW5nbGU7XG4gIH07XG5cbiAgYXJjLnBhZEFuZ2xlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZEFuZ2xlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMCgrXyksIGFyYykgOiBwYWRBbmdsZTtcbiAgfTtcblxuICBhcmMuY29udGV4dCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICgoY29udGV4dCA9IF8gPT0gbnVsbCA/IG51bGwgOiBfKSwgYXJjKSA6IGNvbnRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIGFyYztcbn07XG5cbmZ1bmN0aW9uIExpbmVhcihjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5MaW5lYXIucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpIDogdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IC8vIHByb2NlZWRcbiAgICAgIGRlZmF1bHQ6IHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpOyBicmVhaztcbiAgICB9XG4gIH1cbn07XG5cbnZhciBjdXJ2ZUxpbmVhciA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBMaW5lYXIoY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiB4JDMocCkge1xuICByZXR1cm4gcFswXTtcbn1cblxuZnVuY3Rpb24geSQzKHApIHtcbiAgcmV0dXJuIHBbMV07XG59XG5cbnZhciBsaW5lID0gZnVuY3Rpb24oKSB7XG4gIHZhciB4JCQxID0geCQzLFxuICAgICAgeSQkMSA9IHkkMyxcbiAgICAgIGRlZmluZWQgPSBjb25zdGFudCQxMCh0cnVlKSxcbiAgICAgIGNvbnRleHQgPSBudWxsLFxuICAgICAgY3VydmUgPSBjdXJ2ZUxpbmVhcixcbiAgICAgIG91dHB1dCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gbGluZShkYXRhKSB7XG4gICAgdmFyIGksXG4gICAgICAgIG4gPSBkYXRhLmxlbmd0aCxcbiAgICAgICAgZCxcbiAgICAgICAgZGVmaW5lZDAgPSBmYWxzZSxcbiAgICAgICAgYnVmZmVyO1xuXG4gICAgaWYgKGNvbnRleHQgPT0gbnVsbCkgb3V0cHV0ID0gY3VydmUoYnVmZmVyID0gcGF0aCgpKTtcblxuICAgIGZvciAoaSA9IDA7IGkgPD0gbjsgKytpKSB7XG4gICAgICBpZiAoIShpIDwgbiAmJiBkZWZpbmVkKGQgPSBkYXRhW2ldLCBpLCBkYXRhKSkgPT09IGRlZmluZWQwKSB7XG4gICAgICAgIGlmIChkZWZpbmVkMCA9ICFkZWZpbmVkMCkgb3V0cHV0LmxpbmVTdGFydCgpO1xuICAgICAgICBlbHNlIG91dHB1dC5saW5lRW5kKCk7XG4gICAgICB9XG4gICAgICBpZiAoZGVmaW5lZDApIG91dHB1dC5wb2ludCgreCQkMShkLCBpLCBkYXRhKSwgK3kkJDEoZCwgaSwgZGF0YSkpO1xuICAgIH1cblxuICAgIGlmIChidWZmZXIpIHJldHVybiBvdXRwdXQgPSBudWxsLCBidWZmZXIgKyBcIlwiIHx8IG51bGw7XG4gIH1cblxuICBsaW5lLnggPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeCQkMSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoK18pLCBsaW5lKSA6IHgkJDE7XG4gIH07XG5cbiAgbGluZS55ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkkJDEgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCtfKSwgbGluZSkgOiB5JCQxO1xuICB9O1xuXG4gIGxpbmUuZGVmaW5lZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkZWZpbmVkID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMCghIV8pLCBsaW5lKSA6IGRlZmluZWQ7XG4gIH07XG5cbiAgbGluZS5jdXJ2ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjdXJ2ZSA9IF8sIGNvbnRleHQgIT0gbnVsbCAmJiAob3V0cHV0ID0gY3VydmUoY29udGV4dCkpLCBsaW5lKSA6IGN1cnZlO1xuICB9O1xuXG4gIGxpbmUuY29udGV4dCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChfID09IG51bGwgPyBjb250ZXh0ID0gb3V0cHV0ID0gbnVsbCA6IG91dHB1dCA9IGN1cnZlKGNvbnRleHQgPSBfKSwgbGluZSkgOiBjb250ZXh0O1xuICB9O1xuXG4gIHJldHVybiBsaW5lO1xufTtcblxudmFyIGFyZWEkMiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgeDAgPSB4JDMsXG4gICAgICB4MSA9IG51bGwsXG4gICAgICB5MCA9IGNvbnN0YW50JDEwKDApLFxuICAgICAgeTEgPSB5JDMsXG4gICAgICBkZWZpbmVkID0gY29uc3RhbnQkMTAodHJ1ZSksXG4gICAgICBjb250ZXh0ID0gbnVsbCxcbiAgICAgIGN1cnZlID0gY3VydmVMaW5lYXIsXG4gICAgICBvdXRwdXQgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIGFyZWEoZGF0YSkge1xuICAgIHZhciBpLFxuICAgICAgICBqLFxuICAgICAgICBrLFxuICAgICAgICBuID0gZGF0YS5sZW5ndGgsXG4gICAgICAgIGQsXG4gICAgICAgIGRlZmluZWQwID0gZmFsc2UsXG4gICAgICAgIGJ1ZmZlcixcbiAgICAgICAgeDB6ID0gbmV3IEFycmF5KG4pLFxuICAgICAgICB5MHogPSBuZXcgQXJyYXkobik7XG5cbiAgICBpZiAoY29udGV4dCA9PSBudWxsKSBvdXRwdXQgPSBjdXJ2ZShidWZmZXIgPSBwYXRoKCkpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8PSBuOyArK2kpIHtcbiAgICAgIGlmICghKGkgPCBuICYmIGRlZmluZWQoZCA9IGRhdGFbaV0sIGksIGRhdGEpKSA9PT0gZGVmaW5lZDApIHtcbiAgICAgICAgaWYgKGRlZmluZWQwID0gIWRlZmluZWQwKSB7XG4gICAgICAgICAgaiA9IGk7XG4gICAgICAgICAgb3V0cHV0LmFyZWFTdGFydCgpO1xuICAgICAgICAgIG91dHB1dC5saW5lU3RhcnQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXRwdXQubGluZUVuZCgpO1xuICAgICAgICAgIG91dHB1dC5saW5lU3RhcnQoKTtcbiAgICAgICAgICBmb3IgKGsgPSBpIC0gMTsgayA+PSBqOyAtLWspIHtcbiAgICAgICAgICAgIG91dHB1dC5wb2ludCh4MHpba10sIHkweltrXSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG91dHB1dC5saW5lRW5kKCk7XG4gICAgICAgICAgb3V0cHV0LmFyZWFFbmQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRlZmluZWQwKSB7XG4gICAgICAgIHgweltpXSA9ICt4MChkLCBpLCBkYXRhKSwgeTB6W2ldID0gK3kwKGQsIGksIGRhdGEpO1xuICAgICAgICBvdXRwdXQucG9pbnQoeDEgPyAreDEoZCwgaSwgZGF0YSkgOiB4MHpbaV0sIHkxID8gK3kxKGQsIGksIGRhdGEpIDogeTB6W2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYnVmZmVyKSByZXR1cm4gb3V0cHV0ID0gbnVsbCwgYnVmZmVyICsgXCJcIiB8fCBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gYXJlYWxpbmUoKSB7XG4gICAgcmV0dXJuIGxpbmUoKS5kZWZpbmVkKGRlZmluZWQpLmN1cnZlKGN1cnZlKS5jb250ZXh0KGNvbnRleHQpO1xuICB9XG5cbiAgYXJlYS54ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgwID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMCgrXyksIHgxID0gbnVsbCwgYXJlYSkgOiB4MDtcbiAgfTtcblxuICBhcmVhLngwID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgwID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMCgrXyksIGFyZWEpIDogeDA7XG4gIH07XG5cbiAgYXJlYS54MSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MSA9IF8gPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCtfKSwgYXJlYSkgOiB4MTtcbiAgfTtcblxuICBhcmVhLnkgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeTAgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCtfKSwgeTEgPSBudWxsLCBhcmVhKSA6IHkwO1xuICB9O1xuXG4gIGFyZWEueTAgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeTAgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCtfKSwgYXJlYSkgOiB5MDtcbiAgfTtcblxuICBhcmVhLnkxID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkxID0gXyA9PSBudWxsID8gbnVsbCA6IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoK18pLCBhcmVhKSA6IHkxO1xuICB9O1xuXG4gIGFyZWEubGluZVgwID1cbiAgYXJlYS5saW5lWTAgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXJlYWxpbmUoKS54KHgwKS55KHkwKTtcbiAgfTtcblxuICBhcmVhLmxpbmVZMSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhcmVhbGluZSgpLngoeDApLnkoeTEpO1xuICB9O1xuXG4gIGFyZWEubGluZVgxID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGFyZWFsaW5lKCkueCh4MSkueSh5MCk7XG4gIH07XG5cbiAgYXJlYS5kZWZpbmVkID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRlZmluZWQgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCEhXyksIGFyZWEpIDogZGVmaW5lZDtcbiAgfTtcblxuICBhcmVhLmN1cnZlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGN1cnZlID0gXywgY29udGV4dCAhPSBudWxsICYmIChvdXRwdXQgPSBjdXJ2ZShjb250ZXh0KSksIGFyZWEpIDogY3VydmU7XG4gIH07XG5cbiAgYXJlYS5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKF8gPT0gbnVsbCA/IGNvbnRleHQgPSBvdXRwdXQgPSBudWxsIDogb3V0cHV0ID0gY3VydmUoY29udGV4dCA9IF8pLCBhcmVhKSA6IGNvbnRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIGFyZWE7XG59O1xuXG52YXIgZGVzY2VuZGluZyQxID0gZnVuY3Rpb24oYSwgYikge1xuICByZXR1cm4gYiA8IGEgPyAtMSA6IGIgPiBhID8gMSA6IGIgPj0gYSA/IDAgOiBOYU47XG59O1xuXG52YXIgaWRlbnRpdHkkNyA9IGZ1bmN0aW9uKGQpIHtcbiAgcmV0dXJuIGQ7XG59O1xuXG52YXIgcGllID0gZnVuY3Rpb24oKSB7XG4gIHZhciB2YWx1ZSA9IGlkZW50aXR5JDcsXG4gICAgICBzb3J0VmFsdWVzID0gZGVzY2VuZGluZyQxLFxuICAgICAgc29ydCA9IG51bGwsXG4gICAgICBzdGFydEFuZ2xlID0gY29uc3RhbnQkMTAoMCksXG4gICAgICBlbmRBbmdsZSA9IGNvbnN0YW50JDEwKHRhdSQ0KSxcbiAgICAgIHBhZEFuZ2xlID0gY29uc3RhbnQkMTAoMCk7XG5cbiAgZnVuY3Rpb24gcGllKGRhdGEpIHtcbiAgICB2YXIgaSxcbiAgICAgICAgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgICBqLFxuICAgICAgICBrLFxuICAgICAgICBzdW0gPSAwLFxuICAgICAgICBpbmRleCA9IG5ldyBBcnJheShuKSxcbiAgICAgICAgYXJjcyA9IG5ldyBBcnJheShuKSxcbiAgICAgICAgYTAgPSArc3RhcnRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICBkYSA9IE1hdGgubWluKHRhdSQ0LCBNYXRoLm1heCgtdGF1JDQsIGVuZEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgLSBhMCkpLFxuICAgICAgICBhMSxcbiAgICAgICAgcCA9IE1hdGgubWluKE1hdGguYWJzKGRhKSAvIG4sIHBhZEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpLFxuICAgICAgICBwYSA9IHAgKiAoZGEgPCAwID8gLTEgOiAxKSxcbiAgICAgICAgdjtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmICgodiA9IGFyY3NbaW5kZXhbaV0gPSBpXSA9ICt2YWx1ZShkYXRhW2ldLCBpLCBkYXRhKSkgPiAwKSB7XG4gICAgICAgIHN1bSArPSB2O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE9wdGlvbmFsbHkgc29ydCB0aGUgYXJjcyBieSBwcmV2aW91c2x5LWNvbXB1dGVkIHZhbHVlcyBvciBieSBkYXRhLlxuICAgIGlmIChzb3J0VmFsdWVzICE9IG51bGwpIGluZGV4LnNvcnQoZnVuY3Rpb24oaSwgaikgeyByZXR1cm4gc29ydFZhbHVlcyhhcmNzW2ldLCBhcmNzW2pdKTsgfSk7XG4gICAgZWxzZSBpZiAoc29ydCAhPSBudWxsKSBpbmRleC5zb3J0KGZ1bmN0aW9uKGksIGopIHsgcmV0dXJuIHNvcnQoZGF0YVtpXSwgZGF0YVtqXSk7IH0pO1xuXG4gICAgLy8gQ29tcHV0ZSB0aGUgYXJjcyEgVGhleSBhcmUgc3RvcmVkIGluIHRoZSBvcmlnaW5hbCBkYXRhJ3Mgb3JkZXIuXG4gICAgZm9yIChpID0gMCwgayA9IHN1bSA/IChkYSAtIG4gKiBwYSkgLyBzdW0gOiAwOyBpIDwgbjsgKytpLCBhMCA9IGExKSB7XG4gICAgICBqID0gaW5kZXhbaV0sIHYgPSBhcmNzW2pdLCBhMSA9IGEwICsgKHYgPiAwID8gdiAqIGsgOiAwKSArIHBhLCBhcmNzW2pdID0ge1xuICAgICAgICBkYXRhOiBkYXRhW2pdLFxuICAgICAgICBpbmRleDogaSxcbiAgICAgICAgdmFsdWU6IHYsXG4gICAgICAgIHN0YXJ0QW5nbGU6IGEwLFxuICAgICAgICBlbmRBbmdsZTogYTEsXG4gICAgICAgIHBhZEFuZ2xlOiBwXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBhcmNzO1xuICB9XG5cbiAgcGllLnZhbHVlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHZhbHVlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMCgrXyksIHBpZSkgOiB2YWx1ZTtcbiAgfTtcblxuICBwaWUuc29ydFZhbHVlcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzb3J0VmFsdWVzID0gXywgc29ydCA9IG51bGwsIHBpZSkgOiBzb3J0VmFsdWVzO1xuICB9O1xuXG4gIHBpZS5zb3J0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNvcnQgPSBfLCBzb3J0VmFsdWVzID0gbnVsbCwgcGllKSA6IHNvcnQ7XG4gIH07XG5cbiAgcGllLnN0YXJ0QW5nbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc3RhcnRBbmdsZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoK18pLCBwaWUpIDogc3RhcnRBbmdsZTtcbiAgfTtcblxuICBwaWUuZW5kQW5nbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZW5kQW5nbGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDEwKCtfKSwgcGllKSA6IGVuZEFuZ2xlO1xuICB9O1xuXG4gIHBpZS5wYWRBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRBbmdsZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoK18pLCBwaWUpIDogcGFkQW5nbGU7XG4gIH07XG5cbiAgcmV0dXJuIHBpZTtcbn07XG5cbnZhciBjdXJ2ZVJhZGlhbExpbmVhciA9IGN1cnZlUmFkaWFsKGN1cnZlTGluZWFyKTtcblxuZnVuY3Rpb24gUmFkaWFsKGN1cnZlKSB7XG4gIHRoaXMuX2N1cnZlID0gY3VydmU7XG59XG5cblJhZGlhbC5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fY3VydmUuYXJlYVN0YXJ0KCk7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2N1cnZlLmFyZWFFbmQoKTtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9jdXJ2ZS5saW5lU3RhcnQoKTtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fY3VydmUubGluZUVuZCgpO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oYSwgcikge1xuICAgIHRoaXMuX2N1cnZlLnBvaW50KHIgKiBNYXRoLnNpbihhKSwgciAqIC1NYXRoLmNvcyhhKSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGN1cnZlUmFkaWFsKGN1cnZlKSB7XG5cbiAgZnVuY3Rpb24gcmFkaWFsKGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFJhZGlhbChjdXJ2ZShjb250ZXh0KSk7XG4gIH1cblxuICByYWRpYWwuX2N1cnZlID0gY3VydmU7XG5cbiAgcmV0dXJuIHJhZGlhbDtcbn1cblxuZnVuY3Rpb24gcmFkaWFsTGluZShsKSB7XG4gIHZhciBjID0gbC5jdXJ2ZTtcblxuICBsLmFuZ2xlID0gbC54LCBkZWxldGUgbC54O1xuICBsLnJhZGl1cyA9IGwueSwgZGVsZXRlIGwueTtcblxuICBsLmN1cnZlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gYyhjdXJ2ZVJhZGlhbChfKSkgOiBjKCkuX2N1cnZlO1xuICB9O1xuXG4gIHJldHVybiBsO1xufVxuXG52YXIgcmFkaWFsTGluZSQxID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiByYWRpYWxMaW5lKGxpbmUoKS5jdXJ2ZShjdXJ2ZVJhZGlhbExpbmVhcikpO1xufTtcblxudmFyIHJhZGlhbEFyZWEgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGEgPSBhcmVhJDIoKS5jdXJ2ZShjdXJ2ZVJhZGlhbExpbmVhciksXG4gICAgICBjID0gYS5jdXJ2ZSxcbiAgICAgIHgwID0gYS5saW5lWDAsXG4gICAgICB4MSA9IGEubGluZVgxLFxuICAgICAgeTAgPSBhLmxpbmVZMCxcbiAgICAgIHkxID0gYS5saW5lWTE7XG5cbiAgYS5hbmdsZSA9IGEueCwgZGVsZXRlIGEueDtcbiAgYS5zdGFydEFuZ2xlID0gYS54MCwgZGVsZXRlIGEueDA7XG4gIGEuZW5kQW5nbGUgPSBhLngxLCBkZWxldGUgYS54MTtcbiAgYS5yYWRpdXMgPSBhLnksIGRlbGV0ZSBhLnk7XG4gIGEuaW5uZXJSYWRpdXMgPSBhLnkwLCBkZWxldGUgYS55MDtcbiAgYS5vdXRlclJhZGl1cyA9IGEueTEsIGRlbGV0ZSBhLnkxO1xuICBhLmxpbmVTdGFydEFuZ2xlID0gZnVuY3Rpb24oKSB7IHJldHVybiByYWRpYWxMaW5lKHgwKCkpOyB9LCBkZWxldGUgYS5saW5lWDA7XG4gIGEubGluZUVuZEFuZ2xlID0gZnVuY3Rpb24oKSB7IHJldHVybiByYWRpYWxMaW5lKHgxKCkpOyB9LCBkZWxldGUgYS5saW5lWDE7XG4gIGEubGluZUlubmVyUmFkaXVzID0gZnVuY3Rpb24oKSB7IHJldHVybiByYWRpYWxMaW5lKHkwKCkpOyB9LCBkZWxldGUgYS5saW5lWTA7XG4gIGEubGluZU91dGVyUmFkaXVzID0gZnVuY3Rpb24oKSB7IHJldHVybiByYWRpYWxMaW5lKHkxKCkpOyB9LCBkZWxldGUgYS5saW5lWTE7XG5cbiAgYS5jdXJ2ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IGMoY3VydmVSYWRpYWwoXykpIDogYygpLl9jdXJ2ZTtcbiAgfTtcblxuICByZXR1cm4gYTtcbn07XG5cbnZhciBjaXJjbGUkMiA9IHtcbiAgZHJhdzogZnVuY3Rpb24oY29udGV4dCwgc2l6ZSkge1xuICAgIHZhciByID0gTWF0aC5zcXJ0KHNpemUgLyBwaSQ0KTtcbiAgICBjb250ZXh0Lm1vdmVUbyhyLCAwKTtcbiAgICBjb250ZXh0LmFyYygwLCAwLCByLCAwLCB0YXUkNCk7XG4gIH1cbn07XG5cbnZhciBjcm9zcyQyID0ge1xuICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgdmFyIHIgPSBNYXRoLnNxcnQoc2l6ZSAvIDUpIC8gMjtcbiAgICBjb250ZXh0Lm1vdmVUbygtMyAqIHIsIC1yKTtcbiAgICBjb250ZXh0LmxpbmVUbygtciwgLXIpO1xuICAgIGNvbnRleHQubGluZVRvKC1yLCAtMyAqIHIpO1xuICAgIGNvbnRleHQubGluZVRvKHIsIC0zICogcik7XG4gICAgY29udGV4dC5saW5lVG8ociwgLXIpO1xuICAgIGNvbnRleHQubGluZVRvKDMgKiByLCAtcik7XG4gICAgY29udGV4dC5saW5lVG8oMyAqIHIsIHIpO1xuICAgIGNvbnRleHQubGluZVRvKHIsIHIpO1xuICAgIGNvbnRleHQubGluZVRvKHIsIDMgKiByKTtcbiAgICBjb250ZXh0LmxpbmVUbygtciwgMyAqIHIpO1xuICAgIGNvbnRleHQubGluZVRvKC1yLCByKTtcbiAgICBjb250ZXh0LmxpbmVUbygtMyAqIHIsIHIpO1xuICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gIH1cbn07XG5cbnZhciB0YW4zMCA9IE1hdGguc3FydCgxIC8gMyk7XG52YXIgdGFuMzBfMiA9IHRhbjMwICogMjtcblxudmFyIGRpYW1vbmQgPSB7XG4gIGRyYXc6IGZ1bmN0aW9uKGNvbnRleHQsIHNpemUpIHtcbiAgICB2YXIgeSA9IE1hdGguc3FydChzaXplIC8gdGFuMzBfMiksXG4gICAgICAgIHggPSB5ICogdGFuMzA7XG4gICAgY29udGV4dC5tb3ZlVG8oMCwgLXkpO1xuICAgIGNvbnRleHQubGluZVRvKHgsIDApO1xuICAgIGNvbnRleHQubGluZVRvKDAsIHkpO1xuICAgIGNvbnRleHQubGluZVRvKC14LCAwKTtcbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICB9XG59O1xuXG52YXIga2EgPSAwLjg5MDgxMzA5MTUyOTI4NTIyODEwO1xudmFyIGtyID0gTWF0aC5zaW4ocGkkNCAvIDEwKSAvIE1hdGguc2luKDcgKiBwaSQ0IC8gMTApO1xudmFyIGt4ID0gTWF0aC5zaW4odGF1JDQgLyAxMCkgKiBrcjtcbnZhciBreSA9IC1NYXRoLmNvcyh0YXUkNCAvIDEwKSAqIGtyO1xuXG52YXIgc3RhciA9IHtcbiAgZHJhdzogZnVuY3Rpb24oY29udGV4dCwgc2l6ZSkge1xuICAgIHZhciByID0gTWF0aC5zcXJ0KHNpemUgKiBrYSksXG4gICAgICAgIHggPSBreCAqIHIsXG4gICAgICAgIHkgPSBreSAqIHI7XG4gICAgY29udGV4dC5tb3ZlVG8oMCwgLXIpO1xuICAgIGNvbnRleHQubGluZVRvKHgsIHkpO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgNTsgKytpKSB7XG4gICAgICB2YXIgYSA9IHRhdSQ0ICogaSAvIDUsXG4gICAgICAgICAgYyA9IE1hdGguY29zKGEpLFxuICAgICAgICAgIHMgPSBNYXRoLnNpbihhKTtcbiAgICAgIGNvbnRleHQubGluZVRvKHMgKiByLCAtYyAqIHIpO1xuICAgICAgY29udGV4dC5saW5lVG8oYyAqIHggLSBzICogeSwgcyAqIHggKyBjICogeSk7XG4gICAgfVxuICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gIH1cbn07XG5cbnZhciBzcXVhcmUgPSB7XG4gIGRyYXc6IGZ1bmN0aW9uKGNvbnRleHQsIHNpemUpIHtcbiAgICB2YXIgdyA9IE1hdGguc3FydChzaXplKSxcbiAgICAgICAgeCA9IC13IC8gMjtcbiAgICBjb250ZXh0LnJlY3QoeCwgeCwgdywgdyk7XG4gIH1cbn07XG5cbnZhciBzcXJ0MyA9IE1hdGguc3FydCgzKTtcblxudmFyIHRyaWFuZ2xlID0ge1xuICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgdmFyIHkgPSAtTWF0aC5zcXJ0KHNpemUgLyAoc3FydDMgKiAzKSk7XG4gICAgY29udGV4dC5tb3ZlVG8oMCwgeSAqIDIpO1xuICAgIGNvbnRleHQubGluZVRvKC1zcXJ0MyAqIHksIC15KTtcbiAgICBjb250ZXh0LmxpbmVUbyhzcXJ0MyAqIHksIC15KTtcbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICB9XG59O1xuXG52YXIgYyA9IC0wLjU7XG52YXIgcyA9IE1hdGguc3FydCgzKSAvIDI7XG52YXIgayA9IDEgLyBNYXRoLnNxcnQoMTIpO1xudmFyIGEgPSAoayAvIDIgKyAxKSAqIDM7XG5cbnZhciB3eWUgPSB7XG4gIGRyYXc6IGZ1bmN0aW9uKGNvbnRleHQsIHNpemUpIHtcbiAgICB2YXIgciA9IE1hdGguc3FydChzaXplIC8gYSksXG4gICAgICAgIHgwID0gciAvIDIsXG4gICAgICAgIHkwID0gciAqIGssXG4gICAgICAgIHgxID0geDAsXG4gICAgICAgIHkxID0gciAqIGsgKyByLFxuICAgICAgICB4MiA9IC14MSxcbiAgICAgICAgeTIgPSB5MTtcbiAgICBjb250ZXh0Lm1vdmVUbyh4MCwgeTApO1xuICAgIGNvbnRleHQubGluZVRvKHgxLCB5MSk7XG4gICAgY29udGV4dC5saW5lVG8oeDIsIHkyKTtcbiAgICBjb250ZXh0LmxpbmVUbyhjICogeDAgLSBzICogeTAsIHMgKiB4MCArIGMgKiB5MCk7XG4gICAgY29udGV4dC5saW5lVG8oYyAqIHgxIC0gcyAqIHkxLCBzICogeDEgKyBjICogeTEpO1xuICAgIGNvbnRleHQubGluZVRvKGMgKiB4MiAtIHMgKiB5MiwgcyAqIHgyICsgYyAqIHkyKTtcbiAgICBjb250ZXh0LmxpbmVUbyhjICogeDAgKyBzICogeTAsIGMgKiB5MCAtIHMgKiB4MCk7XG4gICAgY29udGV4dC5saW5lVG8oYyAqIHgxICsgcyAqIHkxLCBjICogeTEgLSBzICogeDEpO1xuICAgIGNvbnRleHQubGluZVRvKGMgKiB4MiArIHMgKiB5MiwgYyAqIHkyIC0gcyAqIHgyKTtcbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICB9XG59O1xuXG52YXIgc3ltYm9scyA9IFtcbiAgY2lyY2xlJDIsXG4gIGNyb3NzJDIsXG4gIGRpYW1vbmQsXG4gIHNxdWFyZSxcbiAgc3RhcixcbiAgdHJpYW5nbGUsXG4gIHd5ZVxuXTtcblxudmFyIHN5bWJvbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdHlwZSA9IGNvbnN0YW50JDEwKGNpcmNsZSQyKSxcbiAgICAgIHNpemUgPSBjb25zdGFudCQxMCg2NCksXG4gICAgICBjb250ZXh0ID0gbnVsbDtcblxuICBmdW5jdGlvbiBzeW1ib2woKSB7XG4gICAgdmFyIGJ1ZmZlcjtcbiAgICBpZiAoIWNvbnRleHQpIGNvbnRleHQgPSBidWZmZXIgPSBwYXRoKCk7XG4gICAgdHlwZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpLmRyYXcoY29udGV4dCwgK3NpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gICAgaWYgKGJ1ZmZlcikgcmV0dXJuIGNvbnRleHQgPSBudWxsLCBidWZmZXIgKyBcIlwiIHx8IG51bGw7XG4gIH1cblxuICBzeW1ib2wudHlwZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0eXBlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMChfKSwgc3ltYm9sKSA6IHR5cGU7XG4gIH07XG5cbiAgc3ltYm9sLnNpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc2l6ZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoK18pLCBzeW1ib2wpIDogc2l6ZTtcbiAgfTtcblxuICBzeW1ib2wuY29udGV4dCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjb250ZXh0ID0gXyA9PSBudWxsID8gbnVsbCA6IF8sIHN5bWJvbCkgOiBjb250ZXh0O1xuICB9O1xuXG4gIHJldHVybiBzeW1ib2w7XG59O1xuXG52YXIgbm9vcCQyID0gZnVuY3Rpb24oKSB7fTtcblxuZnVuY3Rpb24gcG9pbnQkMih0aGF0LCB4LCB5KSB7XG4gIHRoYXQuX2NvbnRleHQuYmV6aWVyQ3VydmVUbyhcbiAgICAoMiAqIHRoYXQuX3gwICsgdGhhdC5feDEpIC8gMyxcbiAgICAoMiAqIHRoYXQuX3kwICsgdGhhdC5feTEpIC8gMyxcbiAgICAodGhhdC5feDAgKyAyICogdGhhdC5feDEpIC8gMyxcbiAgICAodGhhdC5feTAgKyAyICogdGhhdC5feTEpIC8gMyxcbiAgICAodGhhdC5feDAgKyA0ICogdGhhdC5feDEgKyB4KSAvIDYsXG4gICAgKHRoYXQuX3kwICsgNCAqIHRoYXQuX3kxICsgeSkgLyA2XG4gICk7XG59XG5cbmZ1bmN0aW9uIEJhc2lzKGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG59XG5cbkJhc2lzLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID1cbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxID0gTmFOO1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAzOiBwb2ludCQyKHRoaXMsIHRoaXMuX3gxLCB0aGlzLl95MSk7IC8vIHByb2NlZWRcbiAgICAgIGNhc2UgMjogdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feDEsIHRoaXMuX3kxKTsgYnJlYWs7XG4gICAgfVxuICAgIGlmICh0aGlzLl9saW5lIHx8ICh0aGlzLl9saW5lICE9PSAwICYmIHRoaXMuX3BvaW50ID09PSAxKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyB0aGlzLl9jb250ZXh0LmxpbmVUbygoNSAqIHRoaXMuX3gwICsgdGhpcy5feDEpIC8gNiwgKDUgKiB0aGlzLl95MCArIHRoaXMuX3kxKSAvIDYpOyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiBwb2ludCQyKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0geTtcbiAgfVxufTtcblxudmFyIGJhc2lzJDIgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgQmFzaXMoY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiBCYXNpc0Nsb3NlZChjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5CYXNpc0Nsb3NlZC5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogbm9vcCQyLFxuICBhcmVhRW5kOiBub29wJDIsXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9IHRoaXMuX3gyID0gdGhpcy5feDMgPSB0aGlzLl94NCA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gdGhpcy5feTMgPSB0aGlzLl95NCA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MiwgdGhpcy5feTIpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbygodGhpcy5feDIgKyAyICogdGhpcy5feDMpIC8gMywgKHRoaXMuX3kyICsgMiAqIHRoaXMuX3kzKSAvIDMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbygodGhpcy5feDMgKyAyICogdGhpcy5feDIpIC8gMywgKHRoaXMuX3kzICsgMiAqIHRoaXMuX3kyKSAvIDMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMzoge1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3gyLCB0aGlzLl95Mik7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDMsIHRoaXMuX3kzKTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NCwgdGhpcy5feTQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX3gyID0geCwgdGhpcy5feTIgPSB5OyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl94MyA9IHgsIHRoaXMuX3kzID0geTsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgdGhpcy5feDQgPSB4LCB0aGlzLl95NCA9IHk7IHRoaXMuX2NvbnRleHQubW92ZVRvKCh0aGlzLl94MCArIDQgKiB0aGlzLl94MSArIHgpIC8gNiwgKHRoaXMuX3kwICsgNCAqIHRoaXMuX3kxICsgeSkgLyA2KTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBwb2ludCQyKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0geTtcbiAgfVxufTtcblxudmFyIGJhc2lzQ2xvc2VkJDEgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgQmFzaXNDbG9zZWQoY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiBCYXNpc09wZW4oY29udGV4dCkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbn1cblxuQmFzaXNPcGVuLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID1cbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxID0gTmFOO1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDMpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgdmFyIHgwID0gKHRoaXMuX3gwICsgNCAqIHRoaXMuX3gxICsgeCkgLyA2LCB5MCA9ICh0aGlzLl95MCArIDQgKiB0aGlzLl95MSArIHkpIC8gNjsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHgwLCB5MCkgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4MCwgeTApOyBicmVhaztcbiAgICAgIGNhc2UgMzogdGhpcy5fcG9pbnQgPSA0OyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiBwb2ludCQyKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0geTtcbiAgfVxufTtcblxudmFyIGJhc2lzT3BlbiA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBCYXNpc09wZW4oY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiBCdW5kbGUoY29udGV4dCwgYmV0YSkge1xuICB0aGlzLl9iYXNpcyA9IG5ldyBCYXNpcyhjb250ZXh0KTtcbiAgdGhpcy5fYmV0YSA9IGJldGE7XG59XG5cbkJ1bmRsZS5wcm90b3R5cGUgPSB7XG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feCA9IFtdO1xuICAgIHRoaXMuX3kgPSBbXTtcbiAgICB0aGlzLl9iYXNpcy5saW5lU3RhcnQoKTtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHggPSB0aGlzLl94LFxuICAgICAgICB5ID0gdGhpcy5feSxcbiAgICAgICAgaiA9IHgubGVuZ3RoIC0gMTtcblxuICAgIGlmIChqID4gMCkge1xuICAgICAgdmFyIHgwID0geFswXSxcbiAgICAgICAgICB5MCA9IHlbMF0sXG4gICAgICAgICAgZHggPSB4W2pdIC0geDAsXG4gICAgICAgICAgZHkgPSB5W2pdIC0geTAsXG4gICAgICAgICAgaSA9IC0xLFxuICAgICAgICAgIHQ7XG5cbiAgICAgIHdoaWxlICgrK2kgPD0gaikge1xuICAgICAgICB0ID0gaSAvIGo7XG4gICAgICAgIHRoaXMuX2Jhc2lzLnBvaW50KFxuICAgICAgICAgIHRoaXMuX2JldGEgKiB4W2ldICsgKDEgLSB0aGlzLl9iZXRhKSAqICh4MCArIHQgKiBkeCksXG4gICAgICAgICAgdGhpcy5fYmV0YSAqIHlbaV0gKyAoMSAtIHRoaXMuX2JldGEpICogKHkwICsgdCAqIGR5KVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3ggPSB0aGlzLl95ID0gbnVsbDtcbiAgICB0aGlzLl9iYXNpcy5saW5lRW5kKCk7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgdGhpcy5feC5wdXNoKCt4KTtcbiAgICB0aGlzLl95LnB1c2goK3kpO1xuICB9XG59O1xuXG52YXIgYnVuZGxlID0gKChmdW5jdGlvbiBjdXN0b20oYmV0YSkge1xuXG4gIGZ1bmN0aW9uIGJ1bmRsZShjb250ZXh0KSB7XG4gICAgcmV0dXJuIGJldGEgPT09IDEgPyBuZXcgQmFzaXMoY29udGV4dCkgOiBuZXcgQnVuZGxlKGNvbnRleHQsIGJldGEpO1xuICB9XG5cbiAgYnVuZGxlLmJldGEgPSBmdW5jdGlvbihiZXRhKSB7XG4gICAgcmV0dXJuIGN1c3RvbSgrYmV0YSk7XG4gIH07XG5cbiAgcmV0dXJuIGJ1bmRsZTtcbn0pKSgwLjg1KTtcblxuZnVuY3Rpb24gcG9pbnQkMyh0aGF0LCB4LCB5KSB7XG4gIHRoYXQuX2NvbnRleHQuYmV6aWVyQ3VydmVUbyhcbiAgICB0aGF0Ll94MSArIHRoYXQuX2sgKiAodGhhdC5feDIgLSB0aGF0Ll94MCksXG4gICAgdGhhdC5feTEgKyB0aGF0Ll9rICogKHRoYXQuX3kyIC0gdGhhdC5feTApLFxuICAgIHRoYXQuX3gyICsgdGhhdC5fayAqICh0aGF0Ll94MSAtIHgpLFxuICAgIHRoYXQuX3kyICsgdGhhdC5fayAqICh0aGF0Ll95MSAtIHkpLFxuICAgIHRoYXQuX3gyLFxuICAgIHRoYXQuX3kyXG4gICk7XG59XG5cbmZ1bmN0aW9uIENhcmRpbmFsKGNvbnRleHQsIHRlbnNpb24pIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX2sgPSAoMSAtIHRlbnNpb24pIC8gNjtcbn1cblxuQ2FyZGluYWwucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPSB0aGlzLl94MiA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gTmFOO1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAyOiB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MiwgdGhpcy5feTIpOyBicmVhaztcbiAgICAgIGNhc2UgMzogcG9pbnQkMyh0aGlzLCB0aGlzLl94MSwgdGhpcy5feTEpOyBicmVhaztcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpIDogdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IHRoaXMuX3gxID0geCwgdGhpcy5feTEgPSB5OyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiBwb2ludCQzKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB0aGlzLl94MiwgdGhpcy5feDIgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0gdGhpcy5feTIsIHRoaXMuX3kyID0geTtcbiAgfVxufTtcblxudmFyIGNhcmRpbmFsID0gKChmdW5jdGlvbiBjdXN0b20odGVuc2lvbikge1xuXG4gIGZ1bmN0aW9uIGNhcmRpbmFsKGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IENhcmRpbmFsKGNvbnRleHQsIHRlbnNpb24pO1xuICB9XG5cbiAgY2FyZGluYWwudGVuc2lvbiA9IGZ1bmN0aW9uKHRlbnNpb24pIHtcbiAgICByZXR1cm4gY3VzdG9tKCt0ZW5zaW9uKTtcbiAgfTtcblxuICByZXR1cm4gY2FyZGluYWw7XG59KSkoMCk7XG5cbmZ1bmN0aW9uIENhcmRpbmFsQ2xvc2VkKGNvbnRleHQsIHRlbnNpb24pIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX2sgPSAoMSAtIHRlbnNpb24pIC8gNjtcbn1cblxuQ2FyZGluYWxDbG9zZWQucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IG5vb3AkMixcbiAgYXJlYUVuZDogbm9vcCQyLFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPSB0aGlzLl94MiA9IHRoaXMuX3gzID0gdGhpcy5feDQgPSB0aGlzLl94NSA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gdGhpcy5feTMgPSB0aGlzLl95NCA9IHRoaXMuX3k1ID0gTmFOO1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAxOiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubW92ZVRvKHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAyOiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAzOiB7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDMsIHRoaXMuX3kzKTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NCwgdGhpcy5feTQpO1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3g1LCB0aGlzLl95NSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgdGhpcy5feDMgPSB4LCB0aGlzLl95MyA9IHk7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IHRoaXMuX2NvbnRleHQubW92ZVRvKHRoaXMuX3g0ID0geCwgdGhpcy5feTQgPSB5KTsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgdGhpcy5feDUgPSB4LCB0aGlzLl95NSA9IHk7IGJyZWFrO1xuICAgICAgZGVmYXVsdDogcG9pbnQkMyh0aGlzLCB4LCB5KTsgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjYXJkaW5hbENsb3NlZCA9ICgoZnVuY3Rpb24gY3VzdG9tKHRlbnNpb24pIHtcblxuICBmdW5jdGlvbiBjYXJkaW5hbChjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBDYXJkaW5hbENsb3NlZChjb250ZXh0LCB0ZW5zaW9uKTtcbiAgfVxuXG4gIGNhcmRpbmFsLnRlbnNpb24gPSBmdW5jdGlvbih0ZW5zaW9uKSB7XG4gICAgcmV0dXJuIGN1c3RvbSgrdGVuc2lvbik7XG4gIH07XG5cbiAgcmV0dXJuIGNhcmRpbmFsO1xufSkpKDApO1xuXG5mdW5jdGlvbiBDYXJkaW5hbE9wZW4oY29udGV4dCwgdGVuc2lvbikge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgdGhpcy5fayA9ICgxIC0gdGVuc2lvbikgLyA2O1xufVxuXG5DYXJkaW5hbE9wZW4ucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPSB0aGlzLl94MiA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gTmFOO1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDMpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHRoaXMuX3gyLCB0aGlzLl95MikgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MiwgdGhpcy5feTIpOyBicmVhaztcbiAgICAgIGNhc2UgMzogdGhpcy5fcG9pbnQgPSA0OyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiBwb2ludCQzKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB0aGlzLl94MiwgdGhpcy5feDIgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0gdGhpcy5feTIsIHRoaXMuX3kyID0geTtcbiAgfVxufTtcblxudmFyIGNhcmRpbmFsT3BlbiA9ICgoZnVuY3Rpb24gY3VzdG9tKHRlbnNpb24pIHtcblxuICBmdW5jdGlvbiBjYXJkaW5hbChjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBDYXJkaW5hbE9wZW4oY29udGV4dCwgdGVuc2lvbik7XG4gIH1cblxuICBjYXJkaW5hbC50ZW5zaW9uID0gZnVuY3Rpb24odGVuc2lvbikge1xuICAgIHJldHVybiBjdXN0b20oK3RlbnNpb24pO1xuICB9O1xuXG4gIHJldHVybiBjYXJkaW5hbDtcbn0pKSgwKTtcblxuZnVuY3Rpb24gcG9pbnQkNCh0aGF0LCB4LCB5KSB7XG4gIHZhciB4MSA9IHRoYXQuX3gxLFxuICAgICAgeTEgPSB0aGF0Ll95MSxcbiAgICAgIHgyID0gdGhhdC5feDIsXG4gICAgICB5MiA9IHRoYXQuX3kyO1xuXG4gIGlmICh0aGF0Ll9sMDFfYSA+IGVwc2lsb24kMykge1xuICAgIHZhciBhID0gMiAqIHRoYXQuX2wwMV8yYSArIDMgKiB0aGF0Ll9sMDFfYSAqIHRoYXQuX2wxMl9hICsgdGhhdC5fbDEyXzJhLFxuICAgICAgICBuID0gMyAqIHRoYXQuX2wwMV9hICogKHRoYXQuX2wwMV9hICsgdGhhdC5fbDEyX2EpO1xuICAgIHgxID0gKHgxICogYSAtIHRoYXQuX3gwICogdGhhdC5fbDEyXzJhICsgdGhhdC5feDIgKiB0aGF0Ll9sMDFfMmEpIC8gbjtcbiAgICB5MSA9ICh5MSAqIGEgLSB0aGF0Ll95MCAqIHRoYXQuX2wxMl8yYSArIHRoYXQuX3kyICogdGhhdC5fbDAxXzJhKSAvIG47XG4gIH1cblxuICBpZiAodGhhdC5fbDIzX2EgPiBlcHNpbG9uJDMpIHtcbiAgICB2YXIgYiA9IDIgKiB0aGF0Ll9sMjNfMmEgKyAzICogdGhhdC5fbDIzX2EgKiB0aGF0Ll9sMTJfYSArIHRoYXQuX2wxMl8yYSxcbiAgICAgICAgbSA9IDMgKiB0aGF0Ll9sMjNfYSAqICh0aGF0Ll9sMjNfYSArIHRoYXQuX2wxMl9hKTtcbiAgICB4MiA9ICh4MiAqIGIgKyB0aGF0Ll94MSAqIHRoYXQuX2wyM18yYSAtIHggKiB0aGF0Ll9sMTJfMmEpIC8gbTtcbiAgICB5MiA9ICh5MiAqIGIgKyB0aGF0Ll95MSAqIHRoYXQuX2wyM18yYSAtIHkgKiB0aGF0Ll9sMTJfMmEpIC8gbTtcbiAgfVxuXG4gIHRoYXQuX2NvbnRleHQuYmV6aWVyQ3VydmVUbyh4MSwgeTEsIHgyLCB5MiwgdGhhdC5feDIsIHRoYXQuX3kyKTtcbn1cblxuZnVuY3Rpb24gQ2F0bXVsbFJvbShjb250ZXh0LCBhbHBoYSkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgdGhpcy5fYWxwaGEgPSBhbHBoYTtcbn1cblxuQ2F0bXVsbFJvbS5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9IHRoaXMuX3gyID1cbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxID0gdGhpcy5feTIgPSBOYU47XG4gICAgdGhpcy5fbDAxX2EgPSB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hID1cbiAgICB0aGlzLl9sMDFfMmEgPSB0aGlzLl9sMTJfMmEgPSB0aGlzLl9sMjNfMmEgPVxuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAyOiB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MiwgdGhpcy5feTIpOyBicmVhaztcbiAgICAgIGNhc2UgMzogdGhpcy5wb2ludCh0aGlzLl94MiwgdGhpcy5feTIpOyBicmVhaztcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcblxuICAgIGlmICh0aGlzLl9wb2ludCkge1xuICAgICAgdmFyIHgyMyA9IHRoaXMuX3gyIC0geCxcbiAgICAgICAgICB5MjMgPSB0aGlzLl95MiAtIHk7XG4gICAgICB0aGlzLl9sMjNfYSA9IE1hdGguc3FydCh0aGlzLl9sMjNfMmEgPSBNYXRoLnBvdyh4MjMgKiB4MjMgKyB5MjMgKiB5MjMsIHRoaXMuX2FscGhhKSk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiBwb2ludCQ0KHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLl9sMDFfYSA9IHRoaXMuX2wxMl9hLCB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hO1xuICAgIHRoaXMuX2wwMV8yYSA9IHRoaXMuX2wxMl8yYSwgdGhpcy5fbDEyXzJhID0gdGhpcy5fbDIzXzJhO1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjYXRtdWxsUm9tID0gKChmdW5jdGlvbiBjdXN0b20oYWxwaGEpIHtcblxuICBmdW5jdGlvbiBjYXRtdWxsUm9tKGNvbnRleHQpIHtcbiAgICByZXR1cm4gYWxwaGEgPyBuZXcgQ2F0bXVsbFJvbShjb250ZXh0LCBhbHBoYSkgOiBuZXcgQ2FyZGluYWwoY29udGV4dCwgMCk7XG4gIH1cblxuICBjYXRtdWxsUm9tLmFscGhhID0gZnVuY3Rpb24oYWxwaGEpIHtcbiAgICByZXR1cm4gY3VzdG9tKCthbHBoYSk7XG4gIH07XG5cbiAgcmV0dXJuIGNhdG11bGxSb207XG59KSkoMC41KTtcblxuZnVuY3Rpb24gQ2F0bXVsbFJvbUNsb3NlZChjb250ZXh0LCBhbHBoYSkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgdGhpcy5fYWxwaGEgPSBhbHBoYTtcbn1cblxuQ2F0bXVsbFJvbUNsb3NlZC5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogbm9vcCQyLFxuICBhcmVhRW5kOiBub29wJDIsXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9IHRoaXMuX3gyID0gdGhpcy5feDMgPSB0aGlzLl94NCA9IHRoaXMuX3g1ID1cbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxID0gdGhpcy5feTIgPSB0aGlzLl95MyA9IHRoaXMuX3k0ID0gdGhpcy5feTUgPSBOYU47XG4gICAgdGhpcy5fbDAxX2EgPSB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hID1cbiAgICB0aGlzLl9sMDFfMmEgPSB0aGlzLl9sMTJfMmEgPSB0aGlzLl9sMjNfMmEgPVxuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAxOiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubW92ZVRvKHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAyOiB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAzOiB7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDMsIHRoaXMuX3kzKTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NCwgdGhpcy5feTQpO1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3g1LCB0aGlzLl95NSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcblxuICAgIGlmICh0aGlzLl9wb2ludCkge1xuICAgICAgdmFyIHgyMyA9IHRoaXMuX3gyIC0geCxcbiAgICAgICAgICB5MjMgPSB0aGlzLl95MiAtIHk7XG4gICAgICB0aGlzLl9sMjNfYSA9IE1hdGguc3FydCh0aGlzLl9sMjNfMmEgPSBNYXRoLnBvdyh4MjMgKiB4MjMgKyB5MjMgKiB5MjMsIHRoaXMuX2FscGhhKSk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX3gzID0geCwgdGhpcy5feTMgPSB5OyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94NCA9IHgsIHRoaXMuX3k0ID0geSk7IGJyZWFrO1xuICAgICAgY2FzZSAyOiB0aGlzLl9wb2ludCA9IDM7IHRoaXMuX3g1ID0geCwgdGhpcy5feTUgPSB5OyBicmVhaztcbiAgICAgIGRlZmF1bHQ6IHBvaW50JDQodGhpcywgeCwgeSk7IGJyZWFrO1xuICAgIH1cblxuICAgIHRoaXMuX2wwMV9hID0gdGhpcy5fbDEyX2EsIHRoaXMuX2wxMl9hID0gdGhpcy5fbDIzX2E7XG4gICAgdGhpcy5fbDAxXzJhID0gdGhpcy5fbDEyXzJhLCB0aGlzLl9sMTJfMmEgPSB0aGlzLl9sMjNfMmE7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB0aGlzLl94MiwgdGhpcy5feDIgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0gdGhpcy5feTIsIHRoaXMuX3kyID0geTtcbiAgfVxufTtcblxudmFyIGNhdG11bGxSb21DbG9zZWQgPSAoKGZ1bmN0aW9uIGN1c3RvbShhbHBoYSkge1xuXG4gIGZ1bmN0aW9uIGNhdG11bGxSb20oY29udGV4dCkge1xuICAgIHJldHVybiBhbHBoYSA/IG5ldyBDYXRtdWxsUm9tQ2xvc2VkKGNvbnRleHQsIGFscGhhKSA6IG5ldyBDYXJkaW5hbENsb3NlZChjb250ZXh0LCAwKTtcbiAgfVxuXG4gIGNhdG11bGxSb20uYWxwaGEgPSBmdW5jdGlvbihhbHBoYSkge1xuICAgIHJldHVybiBjdXN0b20oK2FscGhhKTtcbiAgfTtcblxuICByZXR1cm4gY2F0bXVsbFJvbTtcbn0pKSgwLjUpO1xuXG5mdW5jdGlvbiBDYXRtdWxsUm9tT3Blbihjb250ZXh0LCBhbHBoYSkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgdGhpcy5fYWxwaGEgPSBhbHBoYTtcbn1cblxuQ2F0bXVsbFJvbU9wZW4ucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPSB0aGlzLl94MiA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gTmFOO1xuICAgIHRoaXMuX2wwMV9hID0gdGhpcy5fbDEyX2EgPSB0aGlzLl9sMjNfYSA9XG4gICAgdGhpcy5fbDAxXzJhID0gdGhpcy5fbDEyXzJhID0gdGhpcy5fbDIzXzJhID1cbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9saW5lIHx8ICh0aGlzLl9saW5lICE9PSAwICYmIHRoaXMuX3BvaW50ID09PSAzKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG5cbiAgICBpZiAodGhpcy5fcG9pbnQpIHtcbiAgICAgIHZhciB4MjMgPSB0aGlzLl94MiAtIHgsXG4gICAgICAgICAgeTIzID0gdGhpcy5feTIgLSB5O1xuICAgICAgdGhpcy5fbDIzX2EgPSBNYXRoLnNxcnQodGhpcy5fbDIzXzJhID0gTWF0aC5wb3coeDIzICogeDIzICsgeTIzICogeTIzLCB0aGlzLl9hbHBoYSkpO1xuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDogdGhpcy5fcG9pbnQgPSAxOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feDIsIHRoaXMuX3kyKSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHRoaXMuX3gyLCB0aGlzLl95Mik7IGJyZWFrO1xuICAgICAgY2FzZSAzOiB0aGlzLl9wb2ludCA9IDQ7IC8vIHByb2NlZWRcbiAgICAgIGRlZmF1bHQ6IHBvaW50JDQodGhpcywgeCwgeSk7IGJyZWFrO1xuICAgIH1cblxuICAgIHRoaXMuX2wwMV9hID0gdGhpcy5fbDEyX2EsIHRoaXMuX2wxMl9hID0gdGhpcy5fbDIzX2E7XG4gICAgdGhpcy5fbDAxXzJhID0gdGhpcy5fbDEyXzJhLCB0aGlzLl9sMTJfMmEgPSB0aGlzLl9sMjNfMmE7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB0aGlzLl94MiwgdGhpcy5feDIgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0gdGhpcy5feTIsIHRoaXMuX3kyID0geTtcbiAgfVxufTtcblxudmFyIGNhdG11bGxSb21PcGVuID0gKChmdW5jdGlvbiBjdXN0b20oYWxwaGEpIHtcblxuICBmdW5jdGlvbiBjYXRtdWxsUm9tKGNvbnRleHQpIHtcbiAgICByZXR1cm4gYWxwaGEgPyBuZXcgQ2F0bXVsbFJvbU9wZW4oY29udGV4dCwgYWxwaGEpIDogbmV3IENhcmRpbmFsT3Blbihjb250ZXh0LCAwKTtcbiAgfVxuXG4gIGNhdG11bGxSb20uYWxwaGEgPSBmdW5jdGlvbihhbHBoYSkge1xuICAgIHJldHVybiBjdXN0b20oK2FscGhhKTtcbiAgfTtcblxuICByZXR1cm4gY2F0bXVsbFJvbTtcbn0pKSgwLjUpO1xuXG5mdW5jdGlvbiBMaW5lYXJDbG9zZWQoY29udGV4dCkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbn1cblxuTGluZWFyQ2xvc2VkLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBub29wJDIsXG4gIGFyZWFFbmQ6IG5vb3AkMixcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9wb2ludCkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBpZiAodGhpcy5fcG9pbnQpIHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpO1xuICAgIGVsc2UgdGhpcy5fcG9pbnQgPSAxLCB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4LCB5KTtcbiAgfVxufTtcblxudmFyIGxpbmVhckNsb3NlZCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBMaW5lYXJDbG9zZWQoY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiBzaWduJDEoeCkge1xuICByZXR1cm4geCA8IDAgPyAtMSA6IDE7XG59XG5cbi8vIENhbGN1bGF0ZSB0aGUgc2xvcGVzIG9mIHRoZSB0YW5nZW50cyAoSGVybWl0ZS10eXBlIGludGVycG9sYXRpb24pIGJhc2VkIG9uXG4vLyB0aGUgZm9sbG93aW5nIHBhcGVyOiBTdGVmZmVuLCBNLiAxOTkwLiBBIFNpbXBsZSBNZXRob2QgZm9yIE1vbm90b25pY1xuLy8gSW50ZXJwb2xhdGlvbiBpbiBPbmUgRGltZW5zaW9uLiBBc3Ryb25vbXkgYW5kIEFzdHJvcGh5c2ljcywgVm9sLiAyMzksIE5PLlxuLy8gTk9WKElJKSwgUC4gNDQzLCAxOTkwLlxuZnVuY3Rpb24gc2xvcGUzKHRoYXQsIHgyLCB5Mikge1xuICB2YXIgaDAgPSB0aGF0Ll94MSAtIHRoYXQuX3gwLFxuICAgICAgaDEgPSB4MiAtIHRoYXQuX3gxLFxuICAgICAgczAgPSAodGhhdC5feTEgLSB0aGF0Ll95MCkgLyAoaDAgfHwgaDEgPCAwICYmIC0wKSxcbiAgICAgIHMxID0gKHkyIC0gdGhhdC5feTEpIC8gKGgxIHx8IGgwIDwgMCAmJiAtMCksXG4gICAgICBwID0gKHMwICogaDEgKyBzMSAqIGgwKSAvIChoMCArIGgxKTtcbiAgcmV0dXJuIChzaWduJDEoczApICsgc2lnbiQxKHMxKSkgKiBNYXRoLm1pbihNYXRoLmFicyhzMCksIE1hdGguYWJzKHMxKSwgMC41ICogTWF0aC5hYnMocCkpIHx8IDA7XG59XG5cbi8vIENhbGN1bGF0ZSBhIG9uZS1zaWRlZCBzbG9wZS5cbmZ1bmN0aW9uIHNsb3BlMih0aGF0LCB0KSB7XG4gIHZhciBoID0gdGhhdC5feDEgLSB0aGF0Ll94MDtcbiAgcmV0dXJuIGggPyAoMyAqICh0aGF0Ll95MSAtIHRoYXQuX3kwKSAvIGggLSB0KSAvIDIgOiB0O1xufVxuXG4vLyBBY2NvcmRpbmcgdG8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ3ViaWNfSGVybWl0ZV9zcGxpbmUjUmVwcmVzZW50YXRpb25zXG4vLyBcInlvdSBjYW4gZXhwcmVzcyBjdWJpYyBIZXJtaXRlIGludGVycG9sYXRpb24gaW4gdGVybXMgb2YgY3ViaWMgQsOpemllciBjdXJ2ZXNcbi8vIHdpdGggcmVzcGVjdCB0byB0aGUgZm91ciB2YWx1ZXMgcDAsIHAwICsgbTAgLyAzLCBwMSAtIG0xIC8gMywgcDFcIi5cbmZ1bmN0aW9uIHBvaW50JDUodGhhdCwgdDAsIHQxKSB7XG4gIHZhciB4MCA9IHRoYXQuX3gwLFxuICAgICAgeTAgPSB0aGF0Ll95MCxcbiAgICAgIHgxID0gdGhhdC5feDEsXG4gICAgICB5MSA9IHRoYXQuX3kxLFxuICAgICAgZHggPSAoeDEgLSB4MCkgLyAzO1xuICB0aGF0Ll9jb250ZXh0LmJlemllckN1cnZlVG8oeDAgKyBkeCwgeTAgKyBkeCAqIHQwLCB4MSAtIGR4LCB5MSAtIGR4ICogdDEsIHgxLCB5MSk7XG59XG5cbmZ1bmN0aW9uIE1vbm90b25lWChjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5Nb25vdG9uZVgucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPVxuICAgIHRoaXMuX3QwID0gTmFOO1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAyOiB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MSwgdGhpcy5feTEpOyBicmVhaztcbiAgICAgIGNhc2UgMzogcG9pbnQkNSh0aGlzLCB0aGlzLl90MCwgc2xvcGUyKHRoaXMsIHRoaXMuX3QwKSk7IGJyZWFrO1xuICAgIH1cbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiB0aGlzLl9wb2ludCA9PT0gMSkpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHZhciB0MSA9IE5hTjtcblxuICAgIHggPSAreCwgeSA9ICt5O1xuICAgIGlmICh4ID09PSB0aGlzLl94MSAmJiB5ID09PSB0aGlzLl95MSkgcmV0dXJuOyAvLyBJZ25vcmUgY29pbmNpZGVudCBwb2ludHMuXG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyBwb2ludCQ1KHRoaXMsIHNsb3BlMih0aGlzLCB0MSA9IHNsb3BlMyh0aGlzLCB4LCB5KSksIHQxKTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBwb2ludCQ1KHRoaXMsIHRoaXMuX3QwLCB0MSA9IHNsb3BlMyh0aGlzLCB4LCB5KSk7IGJyZWFrO1xuICAgIH1cblxuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHk7XG4gICAgdGhpcy5fdDAgPSB0MTtcbiAgfVxufTtcblxuZnVuY3Rpb24gTW9ub3RvbmVZKGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IG5ldyBSZWZsZWN0Q29udGV4dChjb250ZXh0KTtcbn1cblxuKE1vbm90b25lWS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKE1vbm90b25lWC5wcm90b3R5cGUpKS5wb2ludCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgTW9ub3RvbmVYLnByb3RvdHlwZS5wb2ludC5jYWxsKHRoaXMsIHksIHgpO1xufTtcblxuZnVuY3Rpb24gUmVmbGVjdENvbnRleHQoY29udGV4dCkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbn1cblxuUmVmbGVjdENvbnRleHQucHJvdG90eXBlID0ge1xuICBtb3ZlVG86IGZ1bmN0aW9uKHgsIHkpIHsgdGhpcy5fY29udGV4dC5tb3ZlVG8oeSwgeCk7IH0sXG4gIGNsb3NlUGF0aDogZnVuY3Rpb24oKSB7IHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7IH0sXG4gIGxpbmVUbzogZnVuY3Rpb24oeCwgeSkgeyB0aGlzLl9jb250ZXh0LmxpbmVUbyh5LCB4KTsgfSxcbiAgYmV6aWVyQ3VydmVUbzogZnVuY3Rpb24oeDEsIHkxLCB4MiwgeTIsIHgsIHkpIHsgdGhpcy5fY29udGV4dC5iZXppZXJDdXJ2ZVRvKHkxLCB4MSwgeTIsIHgyLCB5LCB4KTsgfVxufTtcblxuZnVuY3Rpb24gbW9ub3RvbmVYKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBNb25vdG9uZVgoY29udGV4dCk7XG59XG5cbmZ1bmN0aW9uIG1vbm90b25lWShjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgTW9ub3RvbmVZKGNvbnRleHQpO1xufVxuXG5mdW5jdGlvbiBOYXR1cmFsKGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG59XG5cbk5hdHVyYWwucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3ggPSBbXTtcbiAgICB0aGlzLl95ID0gW107XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB4ID0gdGhpcy5feCxcbiAgICAgICAgeSA9IHRoaXMuX3ksXG4gICAgICAgIG4gPSB4Lmxlbmd0aDtcblxuICAgIGlmIChuKSB7XG4gICAgICB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8oeFswXSwgeVswXSkgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4WzBdLCB5WzBdKTtcbiAgICAgIGlmIChuID09PSAyKSB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHhbMV0sIHlbMV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHB4ID0gY29udHJvbFBvaW50cyh4KSxcbiAgICAgICAgICAgIHB5ID0gY29udHJvbFBvaW50cyh5KTtcbiAgICAgICAgZm9yICh2YXIgaTAgPSAwLCBpMSA9IDE7IGkxIDwgbjsgKytpMCwgKytpMSkge1xuICAgICAgICAgIHRoaXMuX2NvbnRleHQuYmV6aWVyQ3VydmVUbyhweFswXVtpMF0sIHB5WzBdW2kwXSwgcHhbMV1baTBdLCBweVsxXVtpMF0sIHhbaTFdLCB5W2kxXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiBuID09PSAxKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gICAgdGhpcy5feCA9IHRoaXMuX3kgPSBudWxsO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHRoaXMuX3gucHVzaCgreCk7XG4gICAgdGhpcy5feS5wdXNoKCt5KTtcbiAgfVxufTtcblxuLy8gU2VlIGh0dHBzOi8vd3d3LnBhcnRpY2xlaW5jZWxsLmNvbS8yMDEyL2Jlemllci1zcGxpbmVzLyBmb3IgZGVyaXZhdGlvbi5cbmZ1bmN0aW9uIGNvbnRyb2xQb2ludHMoeCkge1xuICB2YXIgaSxcbiAgICAgIG4gPSB4Lmxlbmd0aCAtIDEsXG4gICAgICBtLFxuICAgICAgYSA9IG5ldyBBcnJheShuKSxcbiAgICAgIGIgPSBuZXcgQXJyYXkobiksXG4gICAgICByID0gbmV3IEFycmF5KG4pO1xuICBhWzBdID0gMCwgYlswXSA9IDIsIHJbMF0gPSB4WzBdICsgMiAqIHhbMV07XG4gIGZvciAoaSA9IDE7IGkgPCBuIC0gMTsgKytpKSBhW2ldID0gMSwgYltpXSA9IDQsIHJbaV0gPSA0ICogeFtpXSArIDIgKiB4W2kgKyAxXTtcbiAgYVtuIC0gMV0gPSAyLCBiW24gLSAxXSA9IDcsIHJbbiAtIDFdID0gOCAqIHhbbiAtIDFdICsgeFtuXTtcbiAgZm9yIChpID0gMTsgaSA8IG47ICsraSkgbSA9IGFbaV0gLyBiW2kgLSAxXSwgYltpXSAtPSBtLCByW2ldIC09IG0gKiByW2kgLSAxXTtcbiAgYVtuIC0gMV0gPSByW24gLSAxXSAvIGJbbiAtIDFdO1xuICBmb3IgKGkgPSBuIC0gMjsgaSA+PSAwOyAtLWkpIGFbaV0gPSAocltpXSAtIGFbaSArIDFdKSAvIGJbaV07XG4gIGJbbiAtIDFdID0gKHhbbl0gKyBhW24gLSAxXSkgLyAyO1xuICBmb3IgKGkgPSAwOyBpIDwgbiAtIDE7ICsraSkgYltpXSA9IDIgKiB4W2kgKyAxXSAtIGFbaSArIDFdO1xuICByZXR1cm4gW2EsIGJdO1xufVxuXG52YXIgbmF0dXJhbCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBOYXR1cmFsKGNvbnRleHQpO1xufTtcblxuZnVuY3Rpb24gU3RlcChjb250ZXh0LCB0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xuICB0aGlzLl90ID0gdDtcbn1cblxuU3RlcC5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feCA9IHRoaXMuX3kgPSBOYU47XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAoMCA8IHRoaXMuX3QgJiYgdGhpcy5fdCA8IDEgJiYgdGhpcy5fcG9pbnQgPT09IDIpIHRoaXMuX2NvbnRleHQubGluZVRvKHRoaXMuX3gsIHRoaXMuX3kpO1xuICAgIGlmICh0aGlzLl9saW5lIHx8ICh0aGlzLl9saW5lICE9PSAwICYmIHRoaXMuX3BvaW50ID09PSAxKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICBpZiAodGhpcy5fbGluZSA+PSAwKSB0aGlzLl90ID0gMSAtIHRoaXMuX3QsIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpIDogdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IC8vIHByb2NlZWRcbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgaWYgKHRoaXMuX3QgPD0gMCkge1xuICAgICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHRoaXMuX3gsIHkpO1xuICAgICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB4MSA9IHRoaXMuX3ggKiAoMSAtIHRoaXMuX3QpICsgeCAqIHRoaXMuX3Q7XG4gICAgICAgICAgdGhpcy5fY29udGV4dC5saW5lVG8oeDEsIHRoaXMuX3kpO1xuICAgICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHgxLCB5KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5feCA9IHgsIHRoaXMuX3kgPSB5O1xuICB9XG59O1xuXG52YXIgc3RlcCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBTdGVwKGNvbnRleHQsIDAuNSk7XG59O1xuXG5mdW5jdGlvbiBzdGVwQmVmb3JlKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBTdGVwKGNvbnRleHQsIDApO1xufVxuXG5mdW5jdGlvbiBzdGVwQWZ0ZXIoY29udGV4dCkge1xuICByZXR1cm4gbmV3IFN0ZXAoY29udGV4dCwgMSk7XG59XG5cbnZhciBzbGljZSQ1ID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG52YXIgbm9uZSQxID0gZnVuY3Rpb24oc2VyaWVzLCBvcmRlcikge1xuICBpZiAoISgobiA9IHNlcmllcy5sZW5ndGgpID4gMSkpIHJldHVybjtcbiAgZm9yICh2YXIgaSA9IDEsIHMwLCBzMSA9IHNlcmllc1tvcmRlclswXV0sIG4sIG0gPSBzMS5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICBzMCA9IHMxLCBzMSA9IHNlcmllc1tvcmRlcltpXV07XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICAgIHMxW2pdWzFdICs9IHMxW2pdWzBdID0gaXNOYU4oczBbal1bMV0pID8gczBbal1bMF0gOiBzMFtqXVsxXTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBub25lJDIgPSBmdW5jdGlvbihzZXJpZXMpIHtcbiAgdmFyIG4gPSBzZXJpZXMubGVuZ3RoLCBvID0gbmV3IEFycmF5KG4pO1xuICB3aGlsZSAoLS1uID49IDApIG9bbl0gPSBuO1xuICByZXR1cm4gbztcbn07XG5cbmZ1bmN0aW9uIHN0YWNrVmFsdWUoZCwga2V5KSB7XG4gIHJldHVybiBkW2tleV07XG59XG5cbnZhciBzdGFjayA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5cyA9IGNvbnN0YW50JDEwKFtdKSxcbiAgICAgIG9yZGVyID0gbm9uZSQyLFxuICAgICAgb2Zmc2V0ID0gbm9uZSQxLFxuICAgICAgdmFsdWUgPSBzdGFja1ZhbHVlO1xuXG4gIGZ1bmN0aW9uIHN0YWNrKGRhdGEpIHtcbiAgICB2YXIga3ogPSBrZXlzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksXG4gICAgICAgIGksXG4gICAgICAgIG0gPSBkYXRhLmxlbmd0aCxcbiAgICAgICAgbiA9IGt6Lmxlbmd0aCxcbiAgICAgICAgc3ogPSBuZXcgQXJyYXkobiksXG4gICAgICAgIG96O1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgZm9yICh2YXIga2kgPSBreltpXSwgc2kgPSBzeltpXSA9IG5ldyBBcnJheShtKSwgaiA9IDAsIHNpajsgaiA8IG07ICsraikge1xuICAgICAgICBzaVtqXSA9IHNpaiA9IFswLCArdmFsdWUoZGF0YVtqXSwga2ksIGosIGRhdGEpXTtcbiAgICAgICAgc2lqLmRhdGEgPSBkYXRhW2pdO1xuICAgICAgfVxuICAgICAgc2kua2V5ID0ga2k7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMCwgb3ogPSBvcmRlcihzeik7IGkgPCBuOyArK2kpIHtcbiAgICAgIHN6W296W2ldXS5pbmRleCA9IGk7XG4gICAgfVxuXG4gICAgb2Zmc2V0KHN6LCBveik7XG4gICAgcmV0dXJuIHN6O1xuICB9XG5cbiAgc3RhY2sua2V5cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChrZXlzID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMChzbGljZSQ1LmNhbGwoXykpLCBzdGFjaykgOiBrZXlzO1xuICB9O1xuXG4gIHN0YWNrLnZhbHVlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHZhbHVlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMCgrXyksIHN0YWNrKSA6IHZhbHVlO1xuICB9O1xuXG4gIHN0YWNrLm9yZGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG9yZGVyID0gXyA9PSBudWxsID8gbm9uZSQyIDogdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMChzbGljZSQ1LmNhbGwoXykpLCBzdGFjaykgOiBvcmRlcjtcbiAgfTtcblxuICBzdGFjay5vZmZzZXQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAob2Zmc2V0ID0gXyA9PSBudWxsID8gbm9uZSQxIDogXywgc3RhY2spIDogb2Zmc2V0O1xuICB9O1xuXG4gIHJldHVybiBzdGFjaztcbn07XG5cbnZhciBleHBhbmQgPSBmdW5jdGlvbihzZXJpZXMsIG9yZGVyKSB7XG4gIGlmICghKChuID0gc2VyaWVzLmxlbmd0aCkgPiAwKSkgcmV0dXJuO1xuICBmb3IgKHZhciBpLCBuLCBqID0gMCwgbSA9IHNlcmllc1swXS5sZW5ndGgsIHk7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHkgPSBpID0gMDsgaSA8IG47ICsraSkgeSArPSBzZXJpZXNbaV1bal1bMV0gfHwgMDtcbiAgICBpZiAoeSkgZm9yIChpID0gMDsgaSA8IG47ICsraSkgc2VyaWVzW2ldW2pdWzFdIC89IHk7XG4gIH1cbiAgbm9uZSQxKHNlcmllcywgb3JkZXIpO1xufTtcblxudmFyIHNpbGhvdWV0dGUgPSBmdW5jdGlvbihzZXJpZXMsIG9yZGVyKSB7XG4gIGlmICghKChuID0gc2VyaWVzLmxlbmd0aCkgPiAwKSkgcmV0dXJuO1xuICBmb3IgKHZhciBqID0gMCwgczAgPSBzZXJpZXNbb3JkZXJbMF1dLCBuLCBtID0gczAubGVuZ3RoOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIHkgPSAwOyBpIDwgbjsgKytpKSB5ICs9IHNlcmllc1tpXVtqXVsxXSB8fCAwO1xuICAgIHMwW2pdWzFdICs9IHMwW2pdWzBdID0gLXkgLyAyO1xuICB9XG4gIG5vbmUkMShzZXJpZXMsIG9yZGVyKTtcbn07XG5cbnZhciB3aWdnbGUgPSBmdW5jdGlvbihzZXJpZXMsIG9yZGVyKSB7XG4gIGlmICghKChuID0gc2VyaWVzLmxlbmd0aCkgPiAwKSB8fCAhKChtID0gKHMwID0gc2VyaWVzW29yZGVyWzBdXSkubGVuZ3RoKSA+IDApKSByZXR1cm47XG4gIGZvciAodmFyIHkgPSAwLCBqID0gMSwgczAsIG0sIG47IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHZhciBpID0gMCwgczEgPSAwLCBzMiA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIHZhciBzaSA9IHNlcmllc1tvcmRlcltpXV0sXG4gICAgICAgICAgc2lqMCA9IHNpW2pdWzFdIHx8IDAsXG4gICAgICAgICAgc2lqMSA9IHNpW2ogLSAxXVsxXSB8fCAwLFxuICAgICAgICAgIHMzID0gKHNpajAgLSBzaWoxKSAvIDI7XG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IGk7ICsraykge1xuICAgICAgICB2YXIgc2sgPSBzZXJpZXNbb3JkZXJba11dLFxuICAgICAgICAgICAgc2tqMCA9IHNrW2pdWzFdIHx8IDAsXG4gICAgICAgICAgICBza2oxID0gc2tbaiAtIDFdWzFdIHx8IDA7XG4gICAgICAgIHMzICs9IHNrajAgLSBza2oxO1xuICAgICAgfVxuICAgICAgczEgKz0gc2lqMCwgczIgKz0gczMgKiBzaWowO1xuICAgIH1cbiAgICBzMFtqIC0gMV1bMV0gKz0gczBbaiAtIDFdWzBdID0geTtcbiAgICBpZiAoczEpIHkgLT0gczIgLyBzMTtcbiAgfVxuICBzMFtqIC0gMV1bMV0gKz0gczBbaiAtIDFdWzBdID0geTtcbiAgbm9uZSQxKHNlcmllcywgb3JkZXIpO1xufTtcblxudmFyIGFzY2VuZGluZyQyID0gZnVuY3Rpb24oc2VyaWVzKSB7XG4gIHZhciBzdW1zID0gc2VyaWVzLm1hcChzdW0kMik7XG4gIHJldHVybiBub25lJDIoc2VyaWVzKS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIHN1bXNbYV0gLSBzdW1zW2JdOyB9KTtcbn07XG5cbmZ1bmN0aW9uIHN1bSQyKHNlcmllcykge1xuICB2YXIgcyA9IDAsIGkgPSAtMSwgbiA9IHNlcmllcy5sZW5ndGgsIHY7XG4gIHdoaWxlICgrK2kgPCBuKSBpZiAodiA9ICtzZXJpZXNbaV1bMV0pIHMgKz0gdjtcbiAgcmV0dXJuIHM7XG59XG5cbnZhciBkZXNjZW5kaW5nJDIgPSBmdW5jdGlvbihzZXJpZXMpIHtcbiAgcmV0dXJuIGFzY2VuZGluZyQyKHNlcmllcykucmV2ZXJzZSgpO1xufTtcblxudmFyIGluc2lkZU91dCA9IGZ1bmN0aW9uKHNlcmllcykge1xuICB2YXIgbiA9IHNlcmllcy5sZW5ndGgsXG4gICAgICBpLFxuICAgICAgaixcbiAgICAgIHN1bXMgPSBzZXJpZXMubWFwKHN1bSQyKSxcbiAgICAgIG9yZGVyID0gbm9uZSQyKHNlcmllcykuc29ydChmdW5jdGlvbihhLCBiKSB7IHJldHVybiBzdW1zW2JdIC0gc3Vtc1thXTsgfSksXG4gICAgICB0b3AgPSAwLFxuICAgICAgYm90dG9tID0gMCxcbiAgICAgIHRvcHMgPSBbXSxcbiAgICAgIGJvdHRvbXMgPSBbXTtcblxuICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgaiA9IG9yZGVyW2ldO1xuICAgIGlmICh0b3AgPCBib3R0b20pIHtcbiAgICAgIHRvcCArPSBzdW1zW2pdO1xuICAgICAgdG9wcy5wdXNoKGopO1xuICAgIH0gZWxzZSB7XG4gICAgICBib3R0b20gKz0gc3Vtc1tqXTtcbiAgICAgIGJvdHRvbXMucHVzaChqKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYm90dG9tcy5yZXZlcnNlKCkuY29uY2F0KHRvcHMpO1xufTtcblxudmFyIHJldmVyc2UgPSBmdW5jdGlvbihzZXJpZXMpIHtcbiAgcmV0dXJuIG5vbmUkMihzZXJpZXMpLnJldmVyc2UoKTtcbn07XG5cbnZhciBjb25zdGFudCQxMSA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxuZnVuY3Rpb24geCQ0KGQpIHtcbiAgcmV0dXJuIGRbMF07XG59XG5cbmZ1bmN0aW9uIHkkNChkKSB7XG4gIHJldHVybiBkWzFdO1xufVxuXG5mdW5jdGlvbiBSZWRCbGFja1RyZWUoKSB7XG4gIHRoaXMuXyA9IG51bGw7IC8vIHJvb3Qgbm9kZVxufVxuXG5mdW5jdGlvbiBSZWRCbGFja05vZGUobm9kZSkge1xuICBub2RlLlUgPSAvLyBwYXJlbnQgbm9kZVxuICBub2RlLkMgPSAvLyBjb2xvciAtIHRydWUgZm9yIHJlZCwgZmFsc2UgZm9yIGJsYWNrXG4gIG5vZGUuTCA9IC8vIGxlZnQgbm9kZVxuICBub2RlLlIgPSAvLyByaWdodCBub2RlXG4gIG5vZGUuUCA9IC8vIHByZXZpb3VzIG5vZGVcbiAgbm9kZS5OID0gbnVsbDsgLy8gbmV4dCBub2RlXG59XG5cblJlZEJsYWNrVHJlZS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBSZWRCbGFja1RyZWUsXG5cbiAgaW5zZXJ0OiBmdW5jdGlvbihhZnRlciwgbm9kZSkge1xuICAgIHZhciBwYXJlbnQsIGdyYW5kcGEsIHVuY2xlO1xuXG4gICAgaWYgKGFmdGVyKSB7XG4gICAgICBub2RlLlAgPSBhZnRlcjtcbiAgICAgIG5vZGUuTiA9IGFmdGVyLk47XG4gICAgICBpZiAoYWZ0ZXIuTikgYWZ0ZXIuTi5QID0gbm9kZTtcbiAgICAgIGFmdGVyLk4gPSBub2RlO1xuICAgICAgaWYgKGFmdGVyLlIpIHtcbiAgICAgICAgYWZ0ZXIgPSBhZnRlci5SO1xuICAgICAgICB3aGlsZSAoYWZ0ZXIuTCkgYWZ0ZXIgPSBhZnRlci5MO1xuICAgICAgICBhZnRlci5MID0gbm9kZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFmdGVyLlIgPSBub2RlO1xuICAgICAgfVxuICAgICAgcGFyZW50ID0gYWZ0ZXI7XG4gICAgfSBlbHNlIGlmICh0aGlzLl8pIHtcbiAgICAgIGFmdGVyID0gUmVkQmxhY2tGaXJzdCh0aGlzLl8pO1xuICAgICAgbm9kZS5QID0gbnVsbDtcbiAgICAgIG5vZGUuTiA9IGFmdGVyO1xuICAgICAgYWZ0ZXIuUCA9IGFmdGVyLkwgPSBub2RlO1xuICAgICAgcGFyZW50ID0gYWZ0ZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGUuUCA9IG5vZGUuTiA9IG51bGw7XG4gICAgICB0aGlzLl8gPSBub2RlO1xuICAgICAgcGFyZW50ID0gbnVsbDtcbiAgICB9XG4gICAgbm9kZS5MID0gbm9kZS5SID0gbnVsbDtcbiAgICBub2RlLlUgPSBwYXJlbnQ7XG4gICAgbm9kZS5DID0gdHJ1ZTtcblxuICAgIGFmdGVyID0gbm9kZTtcbiAgICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5DKSB7XG4gICAgICBncmFuZHBhID0gcGFyZW50LlU7XG4gICAgICBpZiAocGFyZW50ID09PSBncmFuZHBhLkwpIHtcbiAgICAgICAgdW5jbGUgPSBncmFuZHBhLlI7XG4gICAgICAgIGlmICh1bmNsZSAmJiB1bmNsZS5DKSB7XG4gICAgICAgICAgcGFyZW50LkMgPSB1bmNsZS5DID0gZmFsc2U7XG4gICAgICAgICAgZ3JhbmRwYS5DID0gdHJ1ZTtcbiAgICAgICAgICBhZnRlciA9IGdyYW5kcGE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGFmdGVyID09PSBwYXJlbnQuUikge1xuICAgICAgICAgICAgUmVkQmxhY2tSb3RhdGVMZWZ0KHRoaXMsIHBhcmVudCk7XG4gICAgICAgICAgICBhZnRlciA9IHBhcmVudDtcbiAgICAgICAgICAgIHBhcmVudCA9IGFmdGVyLlU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhcmVudC5DID0gZmFsc2U7XG4gICAgICAgICAgZ3JhbmRwYS5DID0gdHJ1ZTtcbiAgICAgICAgICBSZWRCbGFja1JvdGF0ZVJpZ2h0KHRoaXMsIGdyYW5kcGEpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1bmNsZSA9IGdyYW5kcGEuTDtcbiAgICAgICAgaWYgKHVuY2xlICYmIHVuY2xlLkMpIHtcbiAgICAgICAgICBwYXJlbnQuQyA9IHVuY2xlLkMgPSBmYWxzZTtcbiAgICAgICAgICBncmFuZHBhLkMgPSB0cnVlO1xuICAgICAgICAgIGFmdGVyID0gZ3JhbmRwYTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoYWZ0ZXIgPT09IHBhcmVudC5MKSB7XG4gICAgICAgICAgICBSZWRCbGFja1JvdGF0ZVJpZ2h0KHRoaXMsIHBhcmVudCk7XG4gICAgICAgICAgICBhZnRlciA9IHBhcmVudDtcbiAgICAgICAgICAgIHBhcmVudCA9IGFmdGVyLlU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhcmVudC5DID0gZmFsc2U7XG4gICAgICAgICAgZ3JhbmRwYS5DID0gdHJ1ZTtcbiAgICAgICAgICBSZWRCbGFja1JvdGF0ZUxlZnQodGhpcywgZ3JhbmRwYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHBhcmVudCA9IGFmdGVyLlU7XG4gICAgfVxuICAgIHRoaXMuXy5DID0gZmFsc2U7XG4gIH0sXG5cbiAgcmVtb3ZlOiBmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKG5vZGUuTikgbm9kZS5OLlAgPSBub2RlLlA7XG4gICAgaWYgKG5vZGUuUCkgbm9kZS5QLk4gPSBub2RlLk47XG4gICAgbm9kZS5OID0gbm9kZS5QID0gbnVsbDtcblxuICAgIHZhciBwYXJlbnQgPSBub2RlLlUsXG4gICAgICAgIHNpYmxpbmcsXG4gICAgICAgIGxlZnQgPSBub2RlLkwsXG4gICAgICAgIHJpZ2h0ID0gbm9kZS5SLFxuICAgICAgICBuZXh0LFxuICAgICAgICByZWQ7XG5cbiAgICBpZiAoIWxlZnQpIG5leHQgPSByaWdodDtcbiAgICBlbHNlIGlmICghcmlnaHQpIG5leHQgPSBsZWZ0O1xuICAgIGVsc2UgbmV4dCA9IFJlZEJsYWNrRmlyc3QocmlnaHQpO1xuXG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgaWYgKHBhcmVudC5MID09PSBub2RlKSBwYXJlbnQuTCA9IG5leHQ7XG4gICAgICBlbHNlIHBhcmVudC5SID0gbmV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fID0gbmV4dDtcbiAgICB9XG5cbiAgICBpZiAobGVmdCAmJiByaWdodCkge1xuICAgICAgcmVkID0gbmV4dC5DO1xuICAgICAgbmV4dC5DID0gbm9kZS5DO1xuICAgICAgbmV4dC5MID0gbGVmdDtcbiAgICAgIGxlZnQuVSA9IG5leHQ7XG4gICAgICBpZiAobmV4dCAhPT0gcmlnaHQpIHtcbiAgICAgICAgcGFyZW50ID0gbmV4dC5VO1xuICAgICAgICBuZXh0LlUgPSBub2RlLlU7XG4gICAgICAgIG5vZGUgPSBuZXh0LlI7XG4gICAgICAgIHBhcmVudC5MID0gbm9kZTtcbiAgICAgICAgbmV4dC5SID0gcmlnaHQ7XG4gICAgICAgIHJpZ2h0LlUgPSBuZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dC5VID0gcGFyZW50O1xuICAgICAgICBwYXJlbnQgPSBuZXh0O1xuICAgICAgICBub2RlID0gbmV4dC5SO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZWQgPSBub2RlLkM7XG4gICAgICBub2RlID0gbmV4dDtcbiAgICB9XG5cbiAgICBpZiAobm9kZSkgbm9kZS5VID0gcGFyZW50O1xuICAgIGlmIChyZWQpIHJldHVybjtcbiAgICBpZiAobm9kZSAmJiBub2RlLkMpIHsgbm9kZS5DID0gZmFsc2U7IHJldHVybjsgfVxuXG4gICAgZG8ge1xuICAgICAgaWYgKG5vZGUgPT09IHRoaXMuXykgYnJlYWs7XG4gICAgICBpZiAobm9kZSA9PT0gcGFyZW50LkwpIHtcbiAgICAgICAgc2libGluZyA9IHBhcmVudC5SO1xuICAgICAgICBpZiAoc2libGluZy5DKSB7XG4gICAgICAgICAgc2libGluZy5DID0gZmFsc2U7XG4gICAgICAgICAgcGFyZW50LkMgPSB0cnVlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlTGVmdCh0aGlzLCBwYXJlbnQpO1xuICAgICAgICAgIHNpYmxpbmcgPSBwYXJlbnQuUjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKHNpYmxpbmcuTCAmJiBzaWJsaW5nLkwuQylcbiAgICAgICAgICAgIHx8IChzaWJsaW5nLlIgJiYgc2libGluZy5SLkMpKSB7XG4gICAgICAgICAgaWYgKCFzaWJsaW5nLlIgfHwgIXNpYmxpbmcuUi5DKSB7XG4gICAgICAgICAgICBzaWJsaW5nLkwuQyA9IGZhbHNlO1xuICAgICAgICAgICAgc2libGluZy5DID0gdHJ1ZTtcbiAgICAgICAgICAgIFJlZEJsYWNrUm90YXRlUmlnaHQodGhpcywgc2libGluZyk7XG4gICAgICAgICAgICBzaWJsaW5nID0gcGFyZW50LlI7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNpYmxpbmcuQyA9IHBhcmVudC5DO1xuICAgICAgICAgIHBhcmVudC5DID0gc2libGluZy5SLkMgPSBmYWxzZTtcbiAgICAgICAgICBSZWRCbGFja1JvdGF0ZUxlZnQodGhpcywgcGFyZW50KTtcbiAgICAgICAgICBub2RlID0gdGhpcy5fO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaWJsaW5nID0gcGFyZW50Lkw7XG4gICAgICAgIGlmIChzaWJsaW5nLkMpIHtcbiAgICAgICAgICBzaWJsaW5nLkMgPSBmYWxzZTtcbiAgICAgICAgICBwYXJlbnQuQyA9IHRydWU7XG4gICAgICAgICAgUmVkQmxhY2tSb3RhdGVSaWdodCh0aGlzLCBwYXJlbnQpO1xuICAgICAgICAgIHNpYmxpbmcgPSBwYXJlbnQuTDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKHNpYmxpbmcuTCAmJiBzaWJsaW5nLkwuQylcbiAgICAgICAgICB8fCAoc2libGluZy5SICYmIHNpYmxpbmcuUi5DKSkge1xuICAgICAgICAgIGlmICghc2libGluZy5MIHx8ICFzaWJsaW5nLkwuQykge1xuICAgICAgICAgICAgc2libGluZy5SLkMgPSBmYWxzZTtcbiAgICAgICAgICAgIHNpYmxpbmcuQyA9IHRydWU7XG4gICAgICAgICAgICBSZWRCbGFja1JvdGF0ZUxlZnQodGhpcywgc2libGluZyk7XG4gICAgICAgICAgICBzaWJsaW5nID0gcGFyZW50Lkw7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNpYmxpbmcuQyA9IHBhcmVudC5DO1xuICAgICAgICAgIHBhcmVudC5DID0gc2libGluZy5MLkMgPSBmYWxzZTtcbiAgICAgICAgICBSZWRCbGFja1JvdGF0ZVJpZ2h0KHRoaXMsIHBhcmVudCk7XG4gICAgICAgICAgbm9kZSA9IHRoaXMuXztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2libGluZy5DID0gdHJ1ZTtcbiAgICAgIG5vZGUgPSBwYXJlbnQ7XG4gICAgICBwYXJlbnQgPSBwYXJlbnQuVTtcbiAgICB9IHdoaWxlICghbm9kZS5DKTtcblxuICAgIGlmIChub2RlKSBub2RlLkMgPSBmYWxzZTtcbiAgfVxufTtcblxuZnVuY3Rpb24gUmVkQmxhY2tSb3RhdGVMZWZ0KHRyZWUsIG5vZGUpIHtcbiAgdmFyIHAgPSBub2RlLFxuICAgICAgcSA9IG5vZGUuUixcbiAgICAgIHBhcmVudCA9IHAuVTtcblxuICBpZiAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudC5MID09PSBwKSBwYXJlbnQuTCA9IHE7XG4gICAgZWxzZSBwYXJlbnQuUiA9IHE7XG4gIH0gZWxzZSB7XG4gICAgdHJlZS5fID0gcTtcbiAgfVxuXG4gIHEuVSA9IHBhcmVudDtcbiAgcC5VID0gcTtcbiAgcC5SID0gcS5MO1xuICBpZiAocC5SKSBwLlIuVSA9IHA7XG4gIHEuTCA9IHA7XG59XG5cbmZ1bmN0aW9uIFJlZEJsYWNrUm90YXRlUmlnaHQodHJlZSwgbm9kZSkge1xuICB2YXIgcCA9IG5vZGUsXG4gICAgICBxID0gbm9kZS5MLFxuICAgICAgcGFyZW50ID0gcC5VO1xuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBpZiAocGFyZW50LkwgPT09IHApIHBhcmVudC5MID0gcTtcbiAgICBlbHNlIHBhcmVudC5SID0gcTtcbiAgfSBlbHNlIHtcbiAgICB0cmVlLl8gPSBxO1xuICB9XG5cbiAgcS5VID0gcGFyZW50O1xuICBwLlUgPSBxO1xuICBwLkwgPSBxLlI7XG4gIGlmIChwLkwpIHAuTC5VID0gcDtcbiAgcS5SID0gcDtcbn1cblxuZnVuY3Rpb24gUmVkQmxhY2tGaXJzdChub2RlKSB7XG4gIHdoaWxlIChub2RlLkwpIG5vZGUgPSBub2RlLkw7XG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVFZGdlKGxlZnQsIHJpZ2h0LCB2MCwgdjEpIHtcbiAgdmFyIGVkZ2UgPSBbbnVsbCwgbnVsbF0sXG4gICAgICBpbmRleCA9IGVkZ2VzLnB1c2goZWRnZSkgLSAxO1xuICBlZGdlLmxlZnQgPSBsZWZ0O1xuICBlZGdlLnJpZ2h0ID0gcmlnaHQ7XG4gIGlmICh2MCkgc2V0RWRnZUVuZChlZGdlLCBsZWZ0LCByaWdodCwgdjApO1xuICBpZiAodjEpIHNldEVkZ2VFbmQoZWRnZSwgcmlnaHQsIGxlZnQsIHYxKTtcbiAgY2VsbHNbbGVmdC5pbmRleF0uaGFsZmVkZ2VzLnB1c2goaW5kZXgpO1xuICBjZWxsc1tyaWdodC5pbmRleF0uaGFsZmVkZ2VzLnB1c2goaW5kZXgpO1xuICByZXR1cm4gZWRnZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQm9yZGVyRWRnZShsZWZ0LCB2MCwgdjEpIHtcbiAgdmFyIGVkZ2UgPSBbdjAsIHYxXTtcbiAgZWRnZS5sZWZ0ID0gbGVmdDtcbiAgcmV0dXJuIGVkZ2U7XG59XG5cbmZ1bmN0aW9uIHNldEVkZ2VFbmQoZWRnZSwgbGVmdCwgcmlnaHQsIHZlcnRleCkge1xuICBpZiAoIWVkZ2VbMF0gJiYgIWVkZ2VbMV0pIHtcbiAgICBlZGdlWzBdID0gdmVydGV4O1xuICAgIGVkZ2UubGVmdCA9IGxlZnQ7XG4gICAgZWRnZS5yaWdodCA9IHJpZ2h0O1xuICB9IGVsc2UgaWYgKGVkZ2UubGVmdCA9PT0gcmlnaHQpIHtcbiAgICBlZGdlWzFdID0gdmVydGV4O1xuICB9IGVsc2Uge1xuICAgIGVkZ2VbMF0gPSB2ZXJ0ZXg7XG4gIH1cbn1cblxuLy8gTGlhbmfigJNCYXJza3kgbGluZSBjbGlwcGluZy5cbmZ1bmN0aW9uIGNsaXBFZGdlKGVkZ2UsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciBhID0gZWRnZVswXSxcbiAgICAgIGIgPSBlZGdlWzFdLFxuICAgICAgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYnggPSBiWzBdLFxuICAgICAgYnkgPSBiWzFdLFxuICAgICAgdDAgPSAwLFxuICAgICAgdDEgPSAxLFxuICAgICAgZHggPSBieCAtIGF4LFxuICAgICAgZHkgPSBieSAtIGF5LFxuICAgICAgcjtcblxuICByID0geDAgLSBheDtcbiAgaWYgKCFkeCAmJiByID4gMCkgcmV0dXJuO1xuICByIC89IGR4O1xuICBpZiAoZHggPCAwKSB7XG4gICAgaWYgKHIgPCB0MCkgcmV0dXJuO1xuICAgIGlmIChyIDwgdDEpIHQxID0gcjtcbiAgfSBlbHNlIGlmIChkeCA+IDApIHtcbiAgICBpZiAociA+IHQxKSByZXR1cm47XG4gICAgaWYgKHIgPiB0MCkgdDAgPSByO1xuICB9XG5cbiAgciA9IHgxIC0gYXg7XG4gIGlmICghZHggJiYgciA8IDApIHJldHVybjtcbiAgciAvPSBkeDtcbiAgaWYgKGR4IDwgMCkge1xuICAgIGlmIChyID4gdDEpIHJldHVybjtcbiAgICBpZiAociA+IHQwKSB0MCA9IHI7XG4gIH0gZWxzZSBpZiAoZHggPiAwKSB7XG4gICAgaWYgKHIgPCB0MCkgcmV0dXJuO1xuICAgIGlmIChyIDwgdDEpIHQxID0gcjtcbiAgfVxuXG4gIHIgPSB5MCAtIGF5O1xuICBpZiAoIWR5ICYmIHIgPiAwKSByZXR1cm47XG4gIHIgLz0gZHk7XG4gIGlmIChkeSA8IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9IGVsc2UgaWYgKGR5ID4gMCkge1xuICAgIGlmIChyID4gdDEpIHJldHVybjtcbiAgICBpZiAociA+IHQwKSB0MCA9IHI7XG4gIH1cblxuICByID0geTEgLSBheTtcbiAgaWYgKCFkeSAmJiByIDwgMCkgcmV0dXJuO1xuICByIC89IGR5O1xuICBpZiAoZHkgPCAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfSBlbHNlIGlmIChkeSA+IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9XG5cbiAgaWYgKCEodDAgPiAwKSAmJiAhKHQxIDwgMSkpIHJldHVybiB0cnVlOyAvLyBUT0RPIEJldHRlciBjaGVjaz9cblxuICBpZiAodDAgPiAwKSBlZGdlWzBdID0gW2F4ICsgdDAgKiBkeCwgYXkgKyB0MCAqIGR5XTtcbiAgaWYgKHQxIDwgMSkgZWRnZVsxXSA9IFtheCArIHQxICogZHgsIGF5ICsgdDEgKiBkeV07XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25uZWN0RWRnZShlZGdlLCB4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgdjEgPSBlZGdlWzFdO1xuICBpZiAodjEpIHJldHVybiB0cnVlO1xuXG4gIHZhciB2MCA9IGVkZ2VbMF0sXG4gICAgICBsZWZ0ID0gZWRnZS5sZWZ0LFxuICAgICAgcmlnaHQgPSBlZGdlLnJpZ2h0LFxuICAgICAgbHggPSBsZWZ0WzBdLFxuICAgICAgbHkgPSBsZWZ0WzFdLFxuICAgICAgcnggPSByaWdodFswXSxcbiAgICAgIHJ5ID0gcmlnaHRbMV0sXG4gICAgICBmeCA9IChseCArIHJ4KSAvIDIsXG4gICAgICBmeSA9IChseSArIHJ5KSAvIDIsXG4gICAgICBmbSxcbiAgICAgIGZiO1xuXG4gIGlmIChyeSA9PT0gbHkpIHtcbiAgICBpZiAoZnggPCB4MCB8fCBmeCA+PSB4MSkgcmV0dXJuO1xuICAgIGlmIChseCA+IHJ4KSB7XG4gICAgICBpZiAoIXYwKSB2MCA9IFtmeCwgeTBdO1xuICAgICAgZWxzZSBpZiAodjBbMV0gPj0geTEpIHJldHVybjtcbiAgICAgIHYxID0gW2Z4LCB5MV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdjApIHYwID0gW2Z4LCB5MV07XG4gICAgICBlbHNlIGlmICh2MFsxXSA8IHkwKSByZXR1cm47XG4gICAgICB2MSA9IFtmeCwgeTBdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmbSA9IChseCAtIHJ4KSAvIChyeSAtIGx5KTtcbiAgICBmYiA9IGZ5IC0gZm0gKiBmeDtcbiAgICBpZiAoZm0gPCAtMSB8fCBmbSA+IDEpIHtcbiAgICAgIGlmIChseCA+IHJ4KSB7XG4gICAgICAgIGlmICghdjApIHYwID0gWyh5MCAtIGZiKSAvIGZtLCB5MF07XG4gICAgICAgIGVsc2UgaWYgKHYwWzFdID49IHkxKSByZXR1cm47XG4gICAgICAgIHYxID0gWyh5MSAtIGZiKSAvIGZtLCB5MV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIXYwKSB2MCA9IFsoeTEgLSBmYikgLyBmbSwgeTFdO1xuICAgICAgICBlbHNlIGlmICh2MFsxXSA8IHkwKSByZXR1cm47XG4gICAgICAgIHYxID0gWyh5MCAtIGZiKSAvIGZtLCB5MF07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChseSA8IHJ5KSB7XG4gICAgICAgIGlmICghdjApIHYwID0gW3gwLCBmbSAqIHgwICsgZmJdO1xuICAgICAgICBlbHNlIGlmICh2MFswXSA+PSB4MSkgcmV0dXJuO1xuICAgICAgICB2MSA9IFt4MSwgZm0gKiB4MSArIGZiXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghdjApIHYwID0gW3gxLCBmbSAqIHgxICsgZmJdO1xuICAgICAgICBlbHNlIGlmICh2MFswXSA8IHgwKSByZXR1cm47XG4gICAgICAgIHYxID0gW3gwLCBmbSAqIHgwICsgZmJdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVkZ2VbMF0gPSB2MDtcbiAgZWRnZVsxXSA9IHYxO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY2xpcEVkZ2VzKHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciBpID0gZWRnZXMubGVuZ3RoLFxuICAgICAgZWRnZTtcblxuICB3aGlsZSAoaS0tKSB7XG4gICAgaWYgKCFjb25uZWN0RWRnZShlZGdlID0gZWRnZXNbaV0sIHgwLCB5MCwgeDEsIHkxKVxuICAgICAgICB8fCAhY2xpcEVkZ2UoZWRnZSwgeDAsIHkwLCB4MSwgeTEpXG4gICAgICAgIHx8ICEoTWF0aC5hYnMoZWRnZVswXVswXSAtIGVkZ2VbMV1bMF0pID4gZXBzaWxvbiQ0XG4gICAgICAgICAgICB8fCBNYXRoLmFicyhlZGdlWzBdWzFdIC0gZWRnZVsxXVsxXSkgPiBlcHNpbG9uJDQpKSB7XG4gICAgICBkZWxldGUgZWRnZXNbaV07XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNlbGwoc2l0ZSkge1xuICByZXR1cm4gY2VsbHNbc2l0ZS5pbmRleF0gPSB7XG4gICAgc2l0ZTogc2l0ZSxcbiAgICBoYWxmZWRnZXM6IFtdXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNlbGxIYWxmZWRnZUFuZ2xlKGNlbGwsIGVkZ2UpIHtcbiAgdmFyIHNpdGUgPSBjZWxsLnNpdGUsXG4gICAgICB2YSA9IGVkZ2UubGVmdCxcbiAgICAgIHZiID0gZWRnZS5yaWdodDtcbiAgaWYgKHNpdGUgPT09IHZiKSB2YiA9IHZhLCB2YSA9IHNpdGU7XG4gIGlmICh2YikgcmV0dXJuIE1hdGguYXRhbjIodmJbMV0gLSB2YVsxXSwgdmJbMF0gLSB2YVswXSk7XG4gIGlmIChzaXRlID09PSB2YSkgdmEgPSBlZGdlWzFdLCB2YiA9IGVkZ2VbMF07XG4gIGVsc2UgdmEgPSBlZGdlWzBdLCB2YiA9IGVkZ2VbMV07XG4gIHJldHVybiBNYXRoLmF0YW4yKHZhWzBdIC0gdmJbMF0sIHZiWzFdIC0gdmFbMV0pO1xufVxuXG5mdW5jdGlvbiBjZWxsSGFsZmVkZ2VTdGFydChjZWxsLCBlZGdlKSB7XG4gIHJldHVybiBlZGdlWysoZWRnZS5sZWZ0ICE9PSBjZWxsLnNpdGUpXTtcbn1cblxuZnVuY3Rpb24gY2VsbEhhbGZlZGdlRW5kKGNlbGwsIGVkZ2UpIHtcbiAgcmV0dXJuIGVkZ2VbKyhlZGdlLmxlZnQgPT09IGNlbGwuc2l0ZSldO1xufVxuXG5mdW5jdGlvbiBzb3J0Q2VsbEhhbGZlZGdlcygpIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSBjZWxscy5sZW5ndGgsIGNlbGwsIGhhbGZlZGdlcywgaiwgbTsgaSA8IG47ICsraSkge1xuICAgIGlmICgoY2VsbCA9IGNlbGxzW2ldKSAmJiAobSA9IChoYWxmZWRnZXMgPSBjZWxsLmhhbGZlZGdlcykubGVuZ3RoKSkge1xuICAgICAgdmFyIGluZGV4ID0gbmV3IEFycmF5KG0pLFxuICAgICAgICAgIGFycmF5ID0gbmV3IEFycmF5KG0pO1xuICAgICAgZm9yIChqID0gMDsgaiA8IG07ICsraikgaW5kZXhbal0gPSBqLCBhcnJheVtqXSA9IGNlbGxIYWxmZWRnZUFuZ2xlKGNlbGwsIGVkZ2VzW2hhbGZlZGdlc1tqXV0pO1xuICAgICAgaW5kZXguc29ydChmdW5jdGlvbihpLCBqKSB7IHJldHVybiBhcnJheVtqXSAtIGFycmF5W2ldOyB9KTtcbiAgICAgIGZvciAoaiA9IDA7IGogPCBtOyArK2opIGFycmF5W2pdID0gaGFsZmVkZ2VzW2luZGV4W2pdXTtcbiAgICAgIGZvciAoaiA9IDA7IGogPCBtOyArK2opIGhhbGZlZGdlc1tqXSA9IGFycmF5W2pdO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjbGlwQ2VsbHMoeDAsIHkwLCB4MSwgeTEpIHtcbiAgdmFyIG5DZWxscyA9IGNlbGxzLmxlbmd0aCxcbiAgICAgIGlDZWxsLFxuICAgICAgY2VsbCxcbiAgICAgIHNpdGUsXG4gICAgICBpSGFsZmVkZ2UsXG4gICAgICBoYWxmZWRnZXMsXG4gICAgICBuSGFsZmVkZ2VzLFxuICAgICAgc3RhcnQsXG4gICAgICBzdGFydFgsXG4gICAgICBzdGFydFksXG4gICAgICBlbmQsXG4gICAgICBlbmRYLFxuICAgICAgZW5kWSxcbiAgICAgIGNvdmVyID0gdHJ1ZTtcblxuICBmb3IgKGlDZWxsID0gMDsgaUNlbGwgPCBuQ2VsbHM7ICsraUNlbGwpIHtcbiAgICBpZiAoY2VsbCA9IGNlbGxzW2lDZWxsXSkge1xuICAgICAgc2l0ZSA9IGNlbGwuc2l0ZTtcbiAgICAgIGhhbGZlZGdlcyA9IGNlbGwuaGFsZmVkZ2VzO1xuICAgICAgaUhhbGZlZGdlID0gaGFsZmVkZ2VzLmxlbmd0aDtcblxuICAgICAgLy8gUmVtb3ZlIGFueSBkYW5nbGluZyBjbGlwcGVkIGVkZ2VzLlxuICAgICAgd2hpbGUgKGlIYWxmZWRnZS0tKSB7XG4gICAgICAgIGlmICghZWRnZXNbaGFsZmVkZ2VzW2lIYWxmZWRnZV1dKSB7XG4gICAgICAgICAgaGFsZmVkZ2VzLnNwbGljZShpSGFsZmVkZ2UsIDEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEluc2VydCBhbnkgYm9yZGVyIGVkZ2VzIGFzIG5lY2Vzc2FyeS5cbiAgICAgIGlIYWxmZWRnZSA9IDAsIG5IYWxmZWRnZXMgPSBoYWxmZWRnZXMubGVuZ3RoO1xuICAgICAgd2hpbGUgKGlIYWxmZWRnZSA8IG5IYWxmZWRnZXMpIHtcbiAgICAgICAgZW5kID0gY2VsbEhhbGZlZGdlRW5kKGNlbGwsIGVkZ2VzW2hhbGZlZGdlc1tpSGFsZmVkZ2VdXSksIGVuZFggPSBlbmRbMF0sIGVuZFkgPSBlbmRbMV07XG4gICAgICAgIHN0YXJ0ID0gY2VsbEhhbGZlZGdlU3RhcnQoY2VsbCwgZWRnZXNbaGFsZmVkZ2VzWysraUhhbGZlZGdlICUgbkhhbGZlZGdlc11dKSwgc3RhcnRYID0gc3RhcnRbMF0sIHN0YXJ0WSA9IHN0YXJ0WzFdO1xuICAgICAgICBpZiAoTWF0aC5hYnMoZW5kWCAtIHN0YXJ0WCkgPiBlcHNpbG9uJDQgfHwgTWF0aC5hYnMoZW5kWSAtIHN0YXJ0WSkgPiBlcHNpbG9uJDQpIHtcbiAgICAgICAgICBoYWxmZWRnZXMuc3BsaWNlKGlIYWxmZWRnZSwgMCwgZWRnZXMucHVzaChjcmVhdGVCb3JkZXJFZGdlKHNpdGUsIGVuZCxcbiAgICAgICAgICAgICAgTWF0aC5hYnMoZW5kWCAtIHgwKSA8IGVwc2lsb24kNCAmJiB5MSAtIGVuZFkgPiBlcHNpbG9uJDQgPyBbeDAsIE1hdGguYWJzKHN0YXJ0WCAtIHgwKSA8IGVwc2lsb24kNCA/IHN0YXJ0WSA6IHkxXVxuICAgICAgICAgICAgICA6IE1hdGguYWJzKGVuZFkgLSB5MSkgPCBlcHNpbG9uJDQgJiYgeDEgLSBlbmRYID4gZXBzaWxvbiQ0ID8gW01hdGguYWJzKHN0YXJ0WSAtIHkxKSA8IGVwc2lsb24kNCA/IHN0YXJ0WCA6IHgxLCB5MV1cbiAgICAgICAgICAgICAgOiBNYXRoLmFicyhlbmRYIC0geDEpIDwgZXBzaWxvbiQ0ICYmIGVuZFkgLSB5MCA+IGVwc2lsb24kNCA/IFt4MSwgTWF0aC5hYnMoc3RhcnRYIC0geDEpIDwgZXBzaWxvbiQ0ID8gc3RhcnRZIDogeTBdXG4gICAgICAgICAgICAgIDogTWF0aC5hYnMoZW5kWSAtIHkwKSA8IGVwc2lsb24kNCAmJiBlbmRYIC0geDAgPiBlcHNpbG9uJDQgPyBbTWF0aC5hYnMoc3RhcnRZIC0geTApIDwgZXBzaWxvbiQ0ID8gc3RhcnRYIDogeDAsIHkwXVxuICAgICAgICAgICAgICA6IG51bGwpKSAtIDEpO1xuICAgICAgICAgICsrbkhhbGZlZGdlcztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobkhhbGZlZGdlcykgY292ZXIgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvLyBJZiB0aGVyZSB3ZXJlbuKAmXQgYW55IGVkZ2VzLCBoYXZlIHRoZSBjbG9zZXN0IHNpdGUgY292ZXIgdGhlIGV4dGVudC5cbiAgLy8gSXQgZG9lc27igJl0IG1hdHRlciB3aGljaCBjb3JuZXIgb2YgdGhlIGV4dGVudCB3ZSBtZWFzdXJlIVxuICBpZiAoY292ZXIpIHtcbiAgICB2YXIgZHgsIGR5LCBkMiwgZGMgPSBJbmZpbml0eTtcblxuICAgIGZvciAoaUNlbGwgPSAwLCBjb3ZlciA9IG51bGw7IGlDZWxsIDwgbkNlbGxzOyArK2lDZWxsKSB7XG4gICAgICBpZiAoY2VsbCA9IGNlbGxzW2lDZWxsXSkge1xuICAgICAgICBzaXRlID0gY2VsbC5zaXRlO1xuICAgICAgICBkeCA9IHNpdGVbMF0gLSB4MDtcbiAgICAgICAgZHkgPSBzaXRlWzFdIC0geTA7XG4gICAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHk7XG4gICAgICAgIGlmIChkMiA8IGRjKSBkYyA9IGQyLCBjb3ZlciA9IGNlbGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvdmVyKSB7XG4gICAgICB2YXIgdjAwID0gW3gwLCB5MF0sIHYwMSA9IFt4MCwgeTFdLCB2MTEgPSBbeDEsIHkxXSwgdjEwID0gW3gxLCB5MF07XG4gICAgICBjb3Zlci5oYWxmZWRnZXMucHVzaChcbiAgICAgICAgZWRnZXMucHVzaChjcmVhdGVCb3JkZXJFZGdlKHNpdGUgPSBjb3Zlci5zaXRlLCB2MDAsIHYwMSkpIC0gMSxcbiAgICAgICAgZWRnZXMucHVzaChjcmVhdGVCb3JkZXJFZGdlKHNpdGUsIHYwMSwgdjExKSkgLSAxLFxuICAgICAgICBlZGdlcy5wdXNoKGNyZWF0ZUJvcmRlckVkZ2Uoc2l0ZSwgdjExLCB2MTApKSAtIDEsXG4gICAgICAgIGVkZ2VzLnB1c2goY3JlYXRlQm9yZGVyRWRnZShzaXRlLCB2MTAsIHYwMCkpIC0gMVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBMYXN0bHkgZGVsZXRlIGFueSBjZWxscyB3aXRoIG5vIGVkZ2VzOyB0aGVzZSB3ZXJlIGVudGlyZWx5IGNsaXBwZWQuXG4gIGZvciAoaUNlbGwgPSAwOyBpQ2VsbCA8IG5DZWxsczsgKytpQ2VsbCkge1xuICAgIGlmIChjZWxsID0gY2VsbHNbaUNlbGxdKSB7XG4gICAgICBpZiAoIWNlbGwuaGFsZmVkZ2VzLmxlbmd0aCkge1xuICAgICAgICBkZWxldGUgY2VsbHNbaUNlbGxdO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgY2lyY2xlUG9vbCA9IFtdO1xuXG52YXIgZmlyc3RDaXJjbGU7XG5cbmZ1bmN0aW9uIENpcmNsZSgpIHtcbiAgUmVkQmxhY2tOb2RlKHRoaXMpO1xuICB0aGlzLnggPVxuICB0aGlzLnkgPVxuICB0aGlzLmFyYyA9XG4gIHRoaXMuc2l0ZSA9XG4gIHRoaXMuY3kgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBhdHRhY2hDaXJjbGUoYXJjKSB7XG4gIHZhciBsQXJjID0gYXJjLlAsXG4gICAgICByQXJjID0gYXJjLk47XG5cbiAgaWYgKCFsQXJjIHx8ICFyQXJjKSByZXR1cm47XG5cbiAgdmFyIGxTaXRlID0gbEFyYy5zaXRlLFxuICAgICAgY1NpdGUgPSBhcmMuc2l0ZSxcbiAgICAgIHJTaXRlID0gckFyYy5zaXRlO1xuXG4gIGlmIChsU2l0ZSA9PT0gclNpdGUpIHJldHVybjtcblxuICB2YXIgYnggPSBjU2l0ZVswXSxcbiAgICAgIGJ5ID0gY1NpdGVbMV0sXG4gICAgICBheCA9IGxTaXRlWzBdIC0gYngsXG4gICAgICBheSA9IGxTaXRlWzFdIC0gYnksXG4gICAgICBjeCA9IHJTaXRlWzBdIC0gYngsXG4gICAgICBjeSA9IHJTaXRlWzFdIC0gYnk7XG5cbiAgdmFyIGQgPSAyICogKGF4ICogY3kgLSBheSAqIGN4KTtcbiAgaWYgKGQgPj0gLWVwc2lsb24yJDIpIHJldHVybjtcblxuICB2YXIgaGEgPSBheCAqIGF4ICsgYXkgKiBheSxcbiAgICAgIGhjID0gY3ggKiBjeCArIGN5ICogY3ksXG4gICAgICB4ID0gKGN5ICogaGEgLSBheSAqIGhjKSAvIGQsXG4gICAgICB5ID0gKGF4ICogaGMgLSBjeCAqIGhhKSAvIGQ7XG5cbiAgdmFyIGNpcmNsZSA9IGNpcmNsZVBvb2wucG9wKCkgfHwgbmV3IENpcmNsZTtcbiAgY2lyY2xlLmFyYyA9IGFyYztcbiAgY2lyY2xlLnNpdGUgPSBjU2l0ZTtcbiAgY2lyY2xlLnggPSB4ICsgYng7XG4gIGNpcmNsZS55ID0gKGNpcmNsZS5jeSA9IHkgKyBieSkgKyBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7IC8vIHkgYm90dG9tXG5cbiAgYXJjLmNpcmNsZSA9IGNpcmNsZTtcblxuICB2YXIgYmVmb3JlID0gbnVsbCxcbiAgICAgIG5vZGUgPSBjaXJjbGVzLl87XG5cbiAgd2hpbGUgKG5vZGUpIHtcbiAgICBpZiAoY2lyY2xlLnkgPCBub2RlLnkgfHwgKGNpcmNsZS55ID09PSBub2RlLnkgJiYgY2lyY2xlLnggPD0gbm9kZS54KSkge1xuICAgICAgaWYgKG5vZGUuTCkgbm9kZSA9IG5vZGUuTDtcbiAgICAgIGVsc2UgeyBiZWZvcmUgPSBub2RlLlA7IGJyZWFrOyB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChub2RlLlIpIG5vZGUgPSBub2RlLlI7XG4gICAgICBlbHNlIHsgYmVmb3JlID0gbm9kZTsgYnJlYWs7IH1cbiAgICB9XG4gIH1cblxuICBjaXJjbGVzLmluc2VydChiZWZvcmUsIGNpcmNsZSk7XG4gIGlmICghYmVmb3JlKSBmaXJzdENpcmNsZSA9IGNpcmNsZTtcbn1cblxuZnVuY3Rpb24gZGV0YWNoQ2lyY2xlKGFyYykge1xuICB2YXIgY2lyY2xlID0gYXJjLmNpcmNsZTtcbiAgaWYgKGNpcmNsZSkge1xuICAgIGlmICghY2lyY2xlLlApIGZpcnN0Q2lyY2xlID0gY2lyY2xlLk47XG4gICAgY2lyY2xlcy5yZW1vdmUoY2lyY2xlKTtcbiAgICBjaXJjbGVQb29sLnB1c2goY2lyY2xlKTtcbiAgICBSZWRCbGFja05vZGUoY2lyY2xlKTtcbiAgICBhcmMuY2lyY2xlID0gbnVsbDtcbiAgfVxufVxuXG52YXIgYmVhY2hQb29sID0gW107XG5cbmZ1bmN0aW9uIEJlYWNoKCkge1xuICBSZWRCbGFja05vZGUodGhpcyk7XG4gIHRoaXMuZWRnZSA9XG4gIHRoaXMuc2l0ZSA9XG4gIHRoaXMuY2lyY2xlID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQmVhY2goc2l0ZSkge1xuICB2YXIgYmVhY2ggPSBiZWFjaFBvb2wucG9wKCkgfHwgbmV3IEJlYWNoO1xuICBiZWFjaC5zaXRlID0gc2l0ZTtcbiAgcmV0dXJuIGJlYWNoO1xufVxuXG5mdW5jdGlvbiBkZXRhY2hCZWFjaChiZWFjaCkge1xuICBkZXRhY2hDaXJjbGUoYmVhY2gpO1xuICBiZWFjaGVzLnJlbW92ZShiZWFjaCk7XG4gIGJlYWNoUG9vbC5wdXNoKGJlYWNoKTtcbiAgUmVkQmxhY2tOb2RlKGJlYWNoKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlQmVhY2goYmVhY2gpIHtcbiAgdmFyIGNpcmNsZSA9IGJlYWNoLmNpcmNsZSxcbiAgICAgIHggPSBjaXJjbGUueCxcbiAgICAgIHkgPSBjaXJjbGUuY3ksXG4gICAgICB2ZXJ0ZXggPSBbeCwgeV0sXG4gICAgICBwcmV2aW91cyA9IGJlYWNoLlAsXG4gICAgICBuZXh0ID0gYmVhY2guTixcbiAgICAgIGRpc2FwcGVhcmluZyA9IFtiZWFjaF07XG5cbiAgZGV0YWNoQmVhY2goYmVhY2gpO1xuXG4gIHZhciBsQXJjID0gcHJldmlvdXM7XG4gIHdoaWxlIChsQXJjLmNpcmNsZVxuICAgICAgJiYgTWF0aC5hYnMoeCAtIGxBcmMuY2lyY2xlLngpIDwgZXBzaWxvbiQ0XG4gICAgICAmJiBNYXRoLmFicyh5IC0gbEFyYy5jaXJjbGUuY3kpIDwgZXBzaWxvbiQ0KSB7XG4gICAgcHJldmlvdXMgPSBsQXJjLlA7XG4gICAgZGlzYXBwZWFyaW5nLnVuc2hpZnQobEFyYyk7XG4gICAgZGV0YWNoQmVhY2gobEFyYyk7XG4gICAgbEFyYyA9IHByZXZpb3VzO1xuICB9XG5cbiAgZGlzYXBwZWFyaW5nLnVuc2hpZnQobEFyYyk7XG4gIGRldGFjaENpcmNsZShsQXJjKTtcblxuICB2YXIgckFyYyA9IG5leHQ7XG4gIHdoaWxlIChyQXJjLmNpcmNsZVxuICAgICAgJiYgTWF0aC5hYnMoeCAtIHJBcmMuY2lyY2xlLngpIDwgZXBzaWxvbiQ0XG4gICAgICAmJiBNYXRoLmFicyh5IC0gckFyYy5jaXJjbGUuY3kpIDwgZXBzaWxvbiQ0KSB7XG4gICAgbmV4dCA9IHJBcmMuTjtcbiAgICBkaXNhcHBlYXJpbmcucHVzaChyQXJjKTtcbiAgICBkZXRhY2hCZWFjaChyQXJjKTtcbiAgICByQXJjID0gbmV4dDtcbiAgfVxuXG4gIGRpc2FwcGVhcmluZy5wdXNoKHJBcmMpO1xuICBkZXRhY2hDaXJjbGUockFyYyk7XG5cbiAgdmFyIG5BcmNzID0gZGlzYXBwZWFyaW5nLmxlbmd0aCxcbiAgICAgIGlBcmM7XG4gIGZvciAoaUFyYyA9IDE7IGlBcmMgPCBuQXJjczsgKytpQXJjKSB7XG4gICAgckFyYyA9IGRpc2FwcGVhcmluZ1tpQXJjXTtcbiAgICBsQXJjID0gZGlzYXBwZWFyaW5nW2lBcmMgLSAxXTtcbiAgICBzZXRFZGdlRW5kKHJBcmMuZWRnZSwgbEFyYy5zaXRlLCByQXJjLnNpdGUsIHZlcnRleCk7XG4gIH1cblxuICBsQXJjID0gZGlzYXBwZWFyaW5nWzBdO1xuICByQXJjID0gZGlzYXBwZWFyaW5nW25BcmNzIC0gMV07XG4gIHJBcmMuZWRnZSA9IGNyZWF0ZUVkZ2UobEFyYy5zaXRlLCByQXJjLnNpdGUsIG51bGwsIHZlcnRleCk7XG5cbiAgYXR0YWNoQ2lyY2xlKGxBcmMpO1xuICBhdHRhY2hDaXJjbGUockFyYyk7XG59XG5cbmZ1bmN0aW9uIGFkZEJlYWNoKHNpdGUpIHtcbiAgdmFyIHggPSBzaXRlWzBdLFxuICAgICAgZGlyZWN0cml4ID0gc2l0ZVsxXSxcbiAgICAgIGxBcmMsXG4gICAgICByQXJjLFxuICAgICAgZHhsLFxuICAgICAgZHhyLFxuICAgICAgbm9kZSA9IGJlYWNoZXMuXztcblxuICB3aGlsZSAobm9kZSkge1xuICAgIGR4bCA9IGxlZnRCcmVha1BvaW50KG5vZGUsIGRpcmVjdHJpeCkgLSB4O1xuICAgIGlmIChkeGwgPiBlcHNpbG9uJDQpIG5vZGUgPSBub2RlLkw7IGVsc2Uge1xuICAgICAgZHhyID0geCAtIHJpZ2h0QnJlYWtQb2ludChub2RlLCBkaXJlY3RyaXgpO1xuICAgICAgaWYgKGR4ciA+IGVwc2lsb24kNCkge1xuICAgICAgICBpZiAoIW5vZGUuUikge1xuICAgICAgICAgIGxBcmMgPSBub2RlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUgPSBub2RlLlI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZHhsID4gLWVwc2lsb24kNCkge1xuICAgICAgICAgIGxBcmMgPSBub2RlLlA7XG4gICAgICAgICAgckFyYyA9IG5vZGU7XG4gICAgICAgIH0gZWxzZSBpZiAoZHhyID4gLWVwc2lsb24kNCkge1xuICAgICAgICAgIGxBcmMgPSBub2RlO1xuICAgICAgICAgIHJBcmMgPSBub2RlLk47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbEFyYyA9IHJBcmMgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNyZWF0ZUNlbGwoc2l0ZSk7XG4gIHZhciBuZXdBcmMgPSBjcmVhdGVCZWFjaChzaXRlKTtcbiAgYmVhY2hlcy5pbnNlcnQobEFyYywgbmV3QXJjKTtcblxuICBpZiAoIWxBcmMgJiYgIXJBcmMpIHJldHVybjtcblxuICBpZiAobEFyYyA9PT0gckFyYykge1xuICAgIGRldGFjaENpcmNsZShsQXJjKTtcbiAgICByQXJjID0gY3JlYXRlQmVhY2gobEFyYy5zaXRlKTtcbiAgICBiZWFjaGVzLmluc2VydChuZXdBcmMsIHJBcmMpO1xuICAgIG5ld0FyYy5lZGdlID0gckFyYy5lZGdlID0gY3JlYXRlRWRnZShsQXJjLnNpdGUsIG5ld0FyYy5zaXRlKTtcbiAgICBhdHRhY2hDaXJjbGUobEFyYyk7XG4gICAgYXR0YWNoQ2lyY2xlKHJBcmMpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghckFyYykgeyAvLyAmJiBsQXJjXG4gICAgbmV3QXJjLmVkZ2UgPSBjcmVhdGVFZGdlKGxBcmMuc2l0ZSwgbmV3QXJjLnNpdGUpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGVsc2UgbEFyYyAhPT0gckFyY1xuICBkZXRhY2hDaXJjbGUobEFyYyk7XG4gIGRldGFjaENpcmNsZShyQXJjKTtcblxuICB2YXIgbFNpdGUgPSBsQXJjLnNpdGUsXG4gICAgICBheCA9IGxTaXRlWzBdLFxuICAgICAgYXkgPSBsU2l0ZVsxXSxcbiAgICAgIGJ4ID0gc2l0ZVswXSAtIGF4LFxuICAgICAgYnkgPSBzaXRlWzFdIC0gYXksXG4gICAgICByU2l0ZSA9IHJBcmMuc2l0ZSxcbiAgICAgIGN4ID0gclNpdGVbMF0gLSBheCxcbiAgICAgIGN5ID0gclNpdGVbMV0gLSBheSxcbiAgICAgIGQgPSAyICogKGJ4ICogY3kgLSBieSAqIGN4KSxcbiAgICAgIGhiID0gYnggKiBieCArIGJ5ICogYnksXG4gICAgICBoYyA9IGN4ICogY3ggKyBjeSAqIGN5LFxuICAgICAgdmVydGV4ID0gWyhjeSAqIGhiIC0gYnkgKiBoYykgLyBkICsgYXgsIChieCAqIGhjIC0gY3ggKiBoYikgLyBkICsgYXldO1xuXG4gIHNldEVkZ2VFbmQockFyYy5lZGdlLCBsU2l0ZSwgclNpdGUsIHZlcnRleCk7XG4gIG5ld0FyYy5lZGdlID0gY3JlYXRlRWRnZShsU2l0ZSwgc2l0ZSwgbnVsbCwgdmVydGV4KTtcbiAgckFyYy5lZGdlID0gY3JlYXRlRWRnZShzaXRlLCByU2l0ZSwgbnVsbCwgdmVydGV4KTtcbiAgYXR0YWNoQ2lyY2xlKGxBcmMpO1xuICBhdHRhY2hDaXJjbGUockFyYyk7XG59XG5cbmZ1bmN0aW9uIGxlZnRCcmVha1BvaW50KGFyYywgZGlyZWN0cml4KSB7XG4gIHZhciBzaXRlID0gYXJjLnNpdGUsXG4gICAgICByZm9jeCA9IHNpdGVbMF0sXG4gICAgICByZm9jeSA9IHNpdGVbMV0sXG4gICAgICBwYnkyID0gcmZvY3kgLSBkaXJlY3RyaXg7XG5cbiAgaWYgKCFwYnkyKSByZXR1cm4gcmZvY3g7XG5cbiAgdmFyIGxBcmMgPSBhcmMuUDtcbiAgaWYgKCFsQXJjKSByZXR1cm4gLUluZmluaXR5O1xuXG4gIHNpdGUgPSBsQXJjLnNpdGU7XG4gIHZhciBsZm9jeCA9IHNpdGVbMF0sXG4gICAgICBsZm9jeSA9IHNpdGVbMV0sXG4gICAgICBwbGJ5MiA9IGxmb2N5IC0gZGlyZWN0cml4O1xuXG4gIGlmICghcGxieTIpIHJldHVybiBsZm9jeDtcblxuICB2YXIgaGwgPSBsZm9jeCAtIHJmb2N4LFxuICAgICAgYWJ5MiA9IDEgLyBwYnkyIC0gMSAvIHBsYnkyLFxuICAgICAgYiA9IGhsIC8gcGxieTI7XG5cbiAgaWYgKGFieTIpIHJldHVybiAoLWIgKyBNYXRoLnNxcnQoYiAqIGIgLSAyICogYWJ5MiAqIChobCAqIGhsIC8gKC0yICogcGxieTIpIC0gbGZvY3kgKyBwbGJ5MiAvIDIgKyByZm9jeSAtIHBieTIgLyAyKSkpIC8gYWJ5MiArIHJmb2N4O1xuXG4gIHJldHVybiAocmZvY3ggKyBsZm9jeCkgLyAyO1xufVxuXG5mdW5jdGlvbiByaWdodEJyZWFrUG9pbnQoYXJjLCBkaXJlY3RyaXgpIHtcbiAgdmFyIHJBcmMgPSBhcmMuTjtcbiAgaWYgKHJBcmMpIHJldHVybiBsZWZ0QnJlYWtQb2ludChyQXJjLCBkaXJlY3RyaXgpO1xuICB2YXIgc2l0ZSA9IGFyYy5zaXRlO1xuICByZXR1cm4gc2l0ZVsxXSA9PT0gZGlyZWN0cml4ID8gc2l0ZVswXSA6IEluZmluaXR5O1xufVxuXG52YXIgZXBzaWxvbiQ0ID0gMWUtNjtcbnZhciBlcHNpbG9uMiQyID0gMWUtMTI7XG52YXIgYmVhY2hlcztcbnZhciBjZWxscztcbnZhciBjaXJjbGVzO1xudmFyIGVkZ2VzO1xuXG5mdW5jdGlvbiB0cmlhbmdsZUFyZWEoYSwgYiwgYykge1xuICByZXR1cm4gKGFbMF0gLSBjWzBdKSAqIChiWzFdIC0gYVsxXSkgLSAoYVswXSAtIGJbMF0pICogKGNbMV0gLSBhWzFdKTtcbn1cblxuZnVuY3Rpb24gbGV4aWNvZ3JhcGhpYyhhLCBiKSB7XG4gIHJldHVybiBiWzFdIC0gYVsxXVxuICAgICAgfHwgYlswXSAtIGFbMF07XG59XG5cbmZ1bmN0aW9uIERpYWdyYW0oc2l0ZXMsIGV4dGVudCkge1xuICB2YXIgc2l0ZSA9IHNpdGVzLnNvcnQobGV4aWNvZ3JhcGhpYykucG9wKCksXG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIGNpcmNsZTtcblxuICBlZGdlcyA9IFtdO1xuICBjZWxscyA9IG5ldyBBcnJheShzaXRlcy5sZW5ndGgpO1xuICBiZWFjaGVzID0gbmV3IFJlZEJsYWNrVHJlZTtcbiAgY2lyY2xlcyA9IG5ldyBSZWRCbGFja1RyZWU7XG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjaXJjbGUgPSBmaXJzdENpcmNsZTtcbiAgICBpZiAoc2l0ZSAmJiAoIWNpcmNsZSB8fCBzaXRlWzFdIDwgY2lyY2xlLnkgfHwgKHNpdGVbMV0gPT09IGNpcmNsZS55ICYmIHNpdGVbMF0gPCBjaXJjbGUueCkpKSB7XG4gICAgICBpZiAoc2l0ZVswXSAhPT0geCB8fCBzaXRlWzFdICE9PSB5KSB7XG4gICAgICAgIGFkZEJlYWNoKHNpdGUpO1xuICAgICAgICB4ID0gc2l0ZVswXSwgeSA9IHNpdGVbMV07XG4gICAgICB9XG4gICAgICBzaXRlID0gc2l0ZXMucG9wKCk7XG4gICAgfSBlbHNlIGlmIChjaXJjbGUpIHtcbiAgICAgIHJlbW92ZUJlYWNoKGNpcmNsZS5hcmMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBzb3J0Q2VsbEhhbGZlZGdlcygpO1xuXG4gIGlmIChleHRlbnQpIHtcbiAgICB2YXIgeDAgPSArZXh0ZW50WzBdWzBdLFxuICAgICAgICB5MCA9ICtleHRlbnRbMF1bMV0sXG4gICAgICAgIHgxID0gK2V4dGVudFsxXVswXSxcbiAgICAgICAgeTEgPSArZXh0ZW50WzFdWzFdO1xuICAgIGNsaXBFZGdlcyh4MCwgeTAsIHgxLCB5MSk7XG4gICAgY2xpcENlbGxzKHgwLCB5MCwgeDEsIHkxKTtcbiAgfVxuXG4gIHRoaXMuZWRnZXMgPSBlZGdlcztcbiAgdGhpcy5jZWxscyA9IGNlbGxzO1xuXG4gIGJlYWNoZXMgPVxuICBjaXJjbGVzID1cbiAgZWRnZXMgPVxuICBjZWxscyA9IG51bGw7XG59XG5cbkRpYWdyYW0ucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogRGlhZ3JhbSxcblxuICBwb2x5Z29uczogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGVkZ2VzID0gdGhpcy5lZGdlcztcblxuICAgIHJldHVybiB0aGlzLmNlbGxzLm1hcChmdW5jdGlvbihjZWxsKSB7XG4gICAgICB2YXIgcG9seWdvbiA9IGNlbGwuaGFsZmVkZ2VzLm1hcChmdW5jdGlvbihpKSB7IHJldHVybiBjZWxsSGFsZmVkZ2VTdGFydChjZWxsLCBlZGdlc1tpXSk7IH0pO1xuICAgICAgcG9seWdvbi5kYXRhID0gY2VsbC5zaXRlLmRhdGE7XG4gICAgICByZXR1cm4gcG9seWdvbjtcbiAgICB9KTtcbiAgfSxcblxuICB0cmlhbmdsZXM6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0cmlhbmdsZXMgPSBbXSxcbiAgICAgICAgZWRnZXMgPSB0aGlzLmVkZ2VzO1xuXG4gICAgdGhpcy5jZWxscy5mb3JFYWNoKGZ1bmN0aW9uKGNlbGwsIGkpIHtcbiAgICAgIGlmICghKG0gPSAoaGFsZmVkZ2VzID0gY2VsbC5oYWxmZWRnZXMpLmxlbmd0aCkpIHJldHVybjtcbiAgICAgIHZhciBzaXRlID0gY2VsbC5zaXRlLFxuICAgICAgICAgIGhhbGZlZGdlcyxcbiAgICAgICAgICBqID0gLTEsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBzMCxcbiAgICAgICAgICBlMSA9IGVkZ2VzW2hhbGZlZGdlc1ttIC0gMV1dLFxuICAgICAgICAgIHMxID0gZTEubGVmdCA9PT0gc2l0ZSA/IGUxLnJpZ2h0IDogZTEubGVmdDtcblxuICAgICAgd2hpbGUgKCsraiA8IG0pIHtcbiAgICAgICAgczAgPSBzMTtcbiAgICAgICAgZTEgPSBlZGdlc1toYWxmZWRnZXNbal1dO1xuICAgICAgICBzMSA9IGUxLmxlZnQgPT09IHNpdGUgPyBlMS5yaWdodCA6IGUxLmxlZnQ7XG4gICAgICAgIGlmIChzMCAmJiBzMSAmJiBpIDwgczAuaW5kZXggJiYgaSA8IHMxLmluZGV4ICYmIHRyaWFuZ2xlQXJlYShzaXRlLCBzMCwgczEpIDwgMCkge1xuICAgICAgICAgIHRyaWFuZ2xlcy5wdXNoKFtzaXRlLmRhdGEsIHMwLmRhdGEsIHMxLmRhdGFdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRyaWFuZ2xlcztcbiAgfSxcblxuICBsaW5rczogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZWRnZXMuZmlsdGVyKGZ1bmN0aW9uKGVkZ2UpIHtcbiAgICAgIHJldHVybiBlZGdlLnJpZ2h0O1xuICAgIH0pLm1hcChmdW5jdGlvbihlZGdlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzb3VyY2U6IGVkZ2UubGVmdC5kYXRhLFxuICAgICAgICB0YXJnZXQ6IGVkZ2UucmlnaHQuZGF0YVxuICAgICAgfTtcbiAgICB9KTtcbiAgfSxcblxuICBmaW5kOiBmdW5jdGlvbih4LCB5LCByYWRpdXMpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXMsIGkwLCBpMSA9IHRoYXQuX2ZvdW5kIHx8IDAsIG4gPSB0aGF0LmNlbGxzLmxlbmd0aCwgY2VsbDtcblxuICAgIC8vIFVzZSB0aGUgcHJldmlvdXNseS1mb3VuZCBjZWxsLCBvciBzdGFydCB3aXRoIGFuIGFyYml0cmFyeSBvbmUuXG4gICAgd2hpbGUgKCEoY2VsbCA9IHRoYXQuY2VsbHNbaTFdKSkgaWYgKCsraTEgPj0gbikgcmV0dXJuIG51bGw7XG4gICAgdmFyIGR4ID0geCAtIGNlbGwuc2l0ZVswXSwgZHkgPSB5IC0gY2VsbC5zaXRlWzFdLCBkMiA9IGR4ICogZHggKyBkeSAqIGR5O1xuXG4gICAgLy8gVHJhdmVyc2UgdGhlIGhhbGYtZWRnZXMgdG8gZmluZCBhIGNsb3NlciBjZWxsLCBpZiBhbnkuXG4gICAgZG8ge1xuICAgICAgY2VsbCA9IHRoYXQuY2VsbHNbaTAgPSBpMV0sIGkxID0gbnVsbDtcbiAgICAgIGNlbGwuaGFsZmVkZ2VzLmZvckVhY2goZnVuY3Rpb24oZSkge1xuICAgICAgICB2YXIgZWRnZSA9IHRoYXQuZWRnZXNbZV0sIHYgPSBlZGdlLmxlZnQ7XG4gICAgICAgIGlmICgodiA9PT0gY2VsbC5zaXRlIHx8ICF2KSAmJiAhKHYgPSBlZGdlLnJpZ2h0KSkgcmV0dXJuO1xuICAgICAgICB2YXIgdnggPSB4IC0gdlswXSwgdnkgPSB5IC0gdlsxXSwgdjIgPSB2eCAqIHZ4ICsgdnkgKiB2eTtcbiAgICAgICAgaWYgKHYyIDwgZDIpIGQyID0gdjIsIGkxID0gdi5pbmRleDtcbiAgICAgIH0pO1xuICAgIH0gd2hpbGUgKGkxICE9PSBudWxsKTtcblxuICAgIHRoYXQuX2ZvdW5kID0gaTA7XG5cbiAgICByZXR1cm4gcmFkaXVzID09IG51bGwgfHwgZDIgPD0gcmFkaXVzICogcmFkaXVzID8gY2VsbC5zaXRlIDogbnVsbDtcbiAgfVxufTtcblxudmFyIHZvcm9ub2kgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHgkJDEgPSB4JDQsXG4gICAgICB5JCQxID0geSQ0LFxuICAgICAgZXh0ZW50ID0gbnVsbDtcblxuICBmdW5jdGlvbiB2b3Jvbm9pKGRhdGEpIHtcbiAgICByZXR1cm4gbmV3IERpYWdyYW0oZGF0YS5tYXAoZnVuY3Rpb24oZCwgaSkge1xuICAgICAgdmFyIHMgPSBbTWF0aC5yb3VuZCh4JCQxKGQsIGksIGRhdGEpIC8gZXBzaWxvbiQ0KSAqIGVwc2lsb24kNCwgTWF0aC5yb3VuZCh5JCQxKGQsIGksIGRhdGEpIC8gZXBzaWxvbiQ0KSAqIGVwc2lsb24kNF07XG4gICAgICBzLmluZGV4ID0gaTtcbiAgICAgIHMuZGF0YSA9IGQ7XG4gICAgICByZXR1cm4gcztcbiAgICB9KSwgZXh0ZW50KTtcbiAgfVxuXG4gIHZvcm9ub2kucG9seWdvbnMgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgcmV0dXJuIHZvcm9ub2koZGF0YSkucG9seWdvbnMoKTtcbiAgfTtcblxuICB2b3Jvbm9pLmxpbmtzID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIHJldHVybiB2b3Jvbm9pKGRhdGEpLmxpbmtzKCk7XG4gIH07XG5cbiAgdm9yb25vaS50cmlhbmdsZXMgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgcmV0dXJuIHZvcm9ub2koZGF0YSkudHJpYW5nbGVzKCk7XG4gIH07XG5cbiAgdm9yb25vaS54ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgkJDEgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDExKCtfKSwgdm9yb25vaSkgOiB4JCQxO1xuICB9O1xuXG4gIHZvcm9ub2kueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5JCQxID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMSgrXyksIHZvcm9ub2kpIDogeSQkMTtcbiAgfTtcblxuICB2b3Jvbm9pLmV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChleHRlbnQgPSBfID09IG51bGwgPyBudWxsIDogW1srX1swXVswXSwgK19bMF1bMV1dLCBbK19bMV1bMF0sICtfWzFdWzFdXV0sIHZvcm9ub2kpIDogZXh0ZW50ICYmIFtbZXh0ZW50WzBdWzBdLCBleHRlbnRbMF1bMV1dLCBbZXh0ZW50WzFdWzBdLCBleHRlbnRbMV1bMV1dXTtcbiAgfTtcblxuICB2b3Jvbm9pLnNpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZXh0ZW50ID0gXyA9PSBudWxsID8gbnVsbCA6IFtbMCwgMF0sIFsrX1swXSwgK19bMV1dXSwgdm9yb25vaSkgOiBleHRlbnQgJiYgW2V4dGVudFsxXVswXSAtIGV4dGVudFswXVswXSwgZXh0ZW50WzFdWzFdIC0gZXh0ZW50WzBdWzFdXTtcbiAgfTtcblxuICByZXR1cm4gdm9yb25vaTtcbn07XG5cbnZhciBjb25zdGFudCQxMiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxuZnVuY3Rpb24gWm9vbUV2ZW50KHRhcmdldCwgdHlwZSwgdHJhbnNmb3JtKSB7XG4gIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICB0aGlzLnR5cGUgPSB0eXBlO1xuICB0aGlzLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbn1cblxuZnVuY3Rpb24gVHJhbnNmb3JtKGssIHgsIHkpIHtcbiAgdGhpcy5rID0gaztcbiAgdGhpcy54ID0geDtcbiAgdGhpcy55ID0geTtcbn1cblxuVHJhbnNmb3JtLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFRyYW5zZm9ybSxcbiAgc2NhbGU6IGZ1bmN0aW9uKGspIHtcbiAgICByZXR1cm4gayA9PT0gMSA/IHRoaXMgOiBuZXcgVHJhbnNmb3JtKHRoaXMuayAqIGssIHRoaXMueCwgdGhpcy55KTtcbiAgfSxcbiAgdHJhbnNsYXRlOiBmdW5jdGlvbih4LCB5KSB7XG4gICAgcmV0dXJuIHggPT09IDAgJiB5ID09PSAwID8gdGhpcyA6IG5ldyBUcmFuc2Zvcm0odGhpcy5rLCB0aGlzLnggKyB0aGlzLmsgKiB4LCB0aGlzLnkgKyB0aGlzLmsgKiB5KTtcbiAgfSxcbiAgYXBwbHk6IGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgcmV0dXJuIFtwb2ludFswXSAqIHRoaXMuayArIHRoaXMueCwgcG9pbnRbMV0gKiB0aGlzLmsgKyB0aGlzLnldO1xuICB9LFxuICBhcHBseVg6IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4geCAqIHRoaXMuayArIHRoaXMueDtcbiAgfSxcbiAgYXBwbHlZOiBmdW5jdGlvbih5KSB7XG4gICAgcmV0dXJuIHkgKiB0aGlzLmsgKyB0aGlzLnk7XG4gIH0sXG4gIGludmVydDogZnVuY3Rpb24obG9jYXRpb24pIHtcbiAgICByZXR1cm4gWyhsb2NhdGlvblswXSAtIHRoaXMueCkgLyB0aGlzLmssIChsb2NhdGlvblsxXSAtIHRoaXMueSkgLyB0aGlzLmtdO1xuICB9LFxuICBpbnZlcnRYOiBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuICh4IC0gdGhpcy54KSAvIHRoaXMuaztcbiAgfSxcbiAgaW52ZXJ0WTogZnVuY3Rpb24oeSkge1xuICAgIHJldHVybiAoeSAtIHRoaXMueSkgLyB0aGlzLms7XG4gIH0sXG4gIHJlc2NhbGVYOiBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIHguY29weSgpLmRvbWFpbih4LnJhbmdlKCkubWFwKHRoaXMuaW52ZXJ0WCwgdGhpcykubWFwKHguaW52ZXJ0LCB4KSk7XG4gIH0sXG4gIHJlc2NhbGVZOiBmdW5jdGlvbih5KSB7XG4gICAgcmV0dXJuIHkuY29weSgpLmRvbWFpbih5LnJhbmdlKCkubWFwKHRoaXMuaW52ZXJ0WSwgdGhpcykubWFwKHkuaW52ZXJ0LCB5KSk7XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyB0aGlzLnggKyBcIixcIiArIHRoaXMueSArIFwiKSBzY2FsZShcIiArIHRoaXMuayArIFwiKVwiO1xuICB9XG59O1xuXG52YXIgaWRlbnRpdHkkOCA9IG5ldyBUcmFuc2Zvcm0oMSwgMCwgMCk7XG5cbnRyYW5zZm9ybSQxLnByb3RvdHlwZSA9IFRyYW5zZm9ybS5wcm90b3R5cGU7XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybSQxKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUuX196b29tIHx8IGlkZW50aXR5JDg7XG59XG5cbmZ1bmN0aW9uIG5vcHJvcGFnYXRpb24kMigpIHtcbiAgZXhwb3J0cy5ldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbn1cblxudmFyIG5vZXZlbnQkMiA9IGZ1bmN0aW9uKCkge1xuICBleHBvcnRzLmV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIGV4cG9ydHMuZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG59O1xuXG4vLyBJZ25vcmUgcmlnaHQtY2xpY2ssIHNpbmNlIHRoYXQgc2hvdWxkIG9wZW4gdGhlIGNvbnRleHQgbWVudS5cbmZ1bmN0aW9uIGRlZmF1bHRGaWx0ZXIkMigpIHtcbiAgcmV0dXJuICFleHBvcnRzLmV2ZW50LmJ1dHRvbjtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdEV4dGVudCQxKCkge1xuICB2YXIgZSA9IHRoaXMsIHcsIGg7XG4gIGlmIChlIGluc3RhbmNlb2YgU1ZHRWxlbWVudCkge1xuICAgIGUgPSBlLm93bmVyU1ZHRWxlbWVudCB8fCBlO1xuICAgIHcgPSBlLndpZHRoLmJhc2VWYWwudmFsdWU7XG4gICAgaCA9IGUuaGVpZ2h0LmJhc2VWYWwudmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgdyA9IGUuY2xpZW50V2lkdGg7XG4gICAgaCA9IGUuY2xpZW50SGVpZ2h0O1xuICB9XG4gIHJldHVybiBbWzAsIDBdLCBbdywgaF1dO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0VHJhbnNmb3JtKCkge1xuICByZXR1cm4gdGhpcy5fX3pvb20gfHwgaWRlbnRpdHkkODtcbn1cblxudmFyIHpvb20gPSBmdW5jdGlvbigpIHtcbiAgdmFyIGZpbHRlciA9IGRlZmF1bHRGaWx0ZXIkMixcbiAgICAgIGV4dGVudCA9IGRlZmF1bHRFeHRlbnQkMSxcbiAgICAgIGswID0gMCxcbiAgICAgIGsxID0gSW5maW5pdHksXG4gICAgICB4MCA9IC1rMSxcbiAgICAgIHgxID0gazEsXG4gICAgICB5MCA9IHgwLFxuICAgICAgeTEgPSB4MSxcbiAgICAgIGR1cmF0aW9uID0gMjUwLFxuICAgICAgaW50ZXJwb2xhdGUkJDEgPSBpbnRlcnBvbGF0ZVpvb20sXG4gICAgICBnZXN0dXJlcyA9IFtdLFxuICAgICAgbGlzdGVuZXJzID0gZGlzcGF0Y2goXCJzdGFydFwiLCBcInpvb21cIiwgXCJlbmRcIiksXG4gICAgICB0b3VjaHN0YXJ0aW5nLFxuICAgICAgdG91Y2hlbmRpbmcsXG4gICAgICB0b3VjaERlbGF5ID0gNTAwLFxuICAgICAgd2hlZWxEZWxheSA9IDE1MDtcblxuICBmdW5jdGlvbiB6b29tKHNlbGVjdGlvbiQkMSkge1xuICAgIHNlbGVjdGlvbiQkMVxuICAgICAgICAub24oXCJ3aGVlbC56b29tXCIsIHdoZWVsZWQpXG4gICAgICAgIC5vbihcIm1vdXNlZG93bi56b29tXCIsIG1vdXNlZG93bmVkKVxuICAgICAgICAub24oXCJkYmxjbGljay56b29tXCIsIGRibGNsaWNrZWQpXG4gICAgICAgIC5vbihcInRvdWNoc3RhcnQuem9vbVwiLCB0b3VjaHN0YXJ0ZWQpXG4gICAgICAgIC5vbihcInRvdWNobW92ZS56b29tXCIsIHRvdWNobW92ZWQpXG4gICAgICAgIC5vbihcInRvdWNoZW5kLnpvb20gdG91Y2hjYW5jZWwuem9vbVwiLCB0b3VjaGVuZGVkKVxuICAgICAgICAuc3R5bGUoXCItd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3JcIiwgXCJyZ2JhKDAsMCwwLDApXCIpXG4gICAgICAgIC5wcm9wZXJ0eShcIl9fem9vbVwiLCBkZWZhdWx0VHJhbnNmb3JtKTtcbiAgfVxuXG4gIHpvb20udHJhbnNmb3JtID0gZnVuY3Rpb24oY29sbGVjdGlvbiwgdHJhbnNmb3JtKSB7XG4gICAgdmFyIHNlbGVjdGlvbiQkMSA9IGNvbGxlY3Rpb24uc2VsZWN0aW9uID8gY29sbGVjdGlvbi5zZWxlY3Rpb24oKSA6IGNvbGxlY3Rpb247XG4gICAgc2VsZWN0aW9uJCQxLnByb3BlcnR5KFwiX196b29tXCIsIGRlZmF1bHRUcmFuc2Zvcm0pO1xuICAgIGlmIChjb2xsZWN0aW9uICE9PSBzZWxlY3Rpb24kJDEpIHtcbiAgICAgIHNjaGVkdWxlKGNvbGxlY3Rpb24sIHRyYW5zZm9ybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGlvbiQkMS5pbnRlcnJ1cHQoKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICBnZXN0dXJlKHRoaXMsIGFyZ3VtZW50cylcbiAgICAgICAgICAgIC5zdGFydCgpXG4gICAgICAgICAgICAuem9vbShudWxsLCB0eXBlb2YgdHJhbnNmb3JtID09PSBcImZ1bmN0aW9uXCIgPyB0cmFuc2Zvcm0uYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IHRyYW5zZm9ybSlcbiAgICAgICAgICAgIC5lbmQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICB6b29tLnNjYWxlQnkgPSBmdW5jdGlvbihzZWxlY3Rpb24kJDEsIGspIHtcbiAgICB6b29tLnNjYWxlVG8oc2VsZWN0aW9uJCQxLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBrMCA9IHRoaXMuX196b29tLmssXG4gICAgICAgICAgazEgPSB0eXBlb2YgayA9PT0gXCJmdW5jdGlvblwiID8gay5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogaztcbiAgICAgIHJldHVybiBrMCAqIGsxO1xuICAgIH0pO1xuICB9O1xuXG4gIHpvb20uc2NhbGVUbyA9IGZ1bmN0aW9uKHNlbGVjdGlvbiQkMSwgaykge1xuICAgIHpvb20udHJhbnNmb3JtKHNlbGVjdGlvbiQkMSwgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZSA9IGV4dGVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICAgIHQwID0gdGhpcy5fX3pvb20sXG4gICAgICAgICAgcDAgPSBjZW50cm9pZChlKSxcbiAgICAgICAgICBwMSA9IHQwLmludmVydChwMCksXG4gICAgICAgICAgazEgPSB0eXBlb2YgayA9PT0gXCJmdW5jdGlvblwiID8gay5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogaztcbiAgICAgIHJldHVybiBjb25zdHJhaW4odHJhbnNsYXRlKHNjYWxlKHQwLCBrMSksIHAwLCBwMSksIGUpO1xuICAgIH0pO1xuICB9O1xuXG4gIHpvb20udHJhbnNsYXRlQnkgPSBmdW5jdGlvbihzZWxlY3Rpb24kJDEsIHgsIHkpIHtcbiAgICB6b29tLnRyYW5zZm9ybShzZWxlY3Rpb24kJDEsIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGNvbnN0cmFpbih0aGlzLl9fem9vbS50cmFuc2xhdGUoXG4gICAgICAgIHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIgPyB4LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiB4LFxuICAgICAgICB0eXBlb2YgeSA9PT0gXCJmdW5jdGlvblwiID8geS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogeVxuICAgICAgKSwgZXh0ZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuICAgIH0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHNjYWxlKHRyYW5zZm9ybSwgaykge1xuICAgIGsgPSBNYXRoLm1heChrMCwgTWF0aC5taW4oazEsIGspKTtcbiAgICByZXR1cm4gayA9PT0gdHJhbnNmb3JtLmsgPyB0cmFuc2Zvcm0gOiBuZXcgVHJhbnNmb3JtKGssIHRyYW5zZm9ybS54LCB0cmFuc2Zvcm0ueSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2xhdGUodHJhbnNmb3JtLCBwMCwgcDEpIHtcbiAgICB2YXIgeCA9IHAwWzBdIC0gcDFbMF0gKiB0cmFuc2Zvcm0uaywgeSA9IHAwWzFdIC0gcDFbMV0gKiB0cmFuc2Zvcm0uaztcbiAgICByZXR1cm4geCA9PT0gdHJhbnNmb3JtLnggJiYgeSA9PT0gdHJhbnNmb3JtLnkgPyB0cmFuc2Zvcm0gOiBuZXcgVHJhbnNmb3JtKHRyYW5zZm9ybS5rLCB4LCB5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnN0cmFpbih0cmFuc2Zvcm0sIGV4dGVudCkge1xuICAgIHZhciBkeDAgPSB0cmFuc2Zvcm0uaW52ZXJ0WChleHRlbnRbMF1bMF0pIC0geDAsXG4gICAgICAgIGR4MSA9IHRyYW5zZm9ybS5pbnZlcnRYKGV4dGVudFsxXVswXSkgLSB4MSxcbiAgICAgICAgZHkwID0gdHJhbnNmb3JtLmludmVydFkoZXh0ZW50WzBdWzFdKSAtIHkwLFxuICAgICAgICBkeTEgPSB0cmFuc2Zvcm0uaW52ZXJ0WShleHRlbnRbMV1bMV0pIC0geTE7XG4gICAgcmV0dXJuIHRyYW5zZm9ybS50cmFuc2xhdGUoXG4gICAgICBkeDEgPiBkeDAgPyAoZHgwICsgZHgxKSAvIDIgOiBNYXRoLm1pbigwLCBkeDApIHx8IE1hdGgubWF4KDAsIGR4MSksXG4gICAgICBkeTEgPiBkeTAgPyAoZHkwICsgZHkxKSAvIDIgOiBNYXRoLm1pbigwLCBkeTApIHx8IE1hdGgubWF4KDAsIGR5MSlcbiAgICApO1xuICB9XG5cbiAgZnVuY3Rpb24gY2VudHJvaWQoZXh0ZW50KSB7XG4gICAgcmV0dXJuIFsoK2V4dGVudFswXVswXSArICtleHRlbnRbMV1bMF0pIC8gMiwgKCtleHRlbnRbMF1bMV0gKyArZXh0ZW50WzFdWzFdKSAvIDJdO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NoZWR1bGUodHJhbnNpdGlvbiQkMSwgdHJhbnNmb3JtLCBjZW50ZXIpIHtcbiAgICB0cmFuc2l0aW9uJCQxXG4gICAgICAgIC5vbihcInN0YXJ0Lnpvb21cIiwgZnVuY3Rpb24oKSB7IGdlc3R1cmUodGhpcywgYXJndW1lbnRzKS5zdGFydCgpOyB9KVxuICAgICAgICAub24oXCJpbnRlcnJ1cHQuem9vbSBlbmQuem9vbVwiLCBmdW5jdGlvbigpIHsgZ2VzdHVyZSh0aGlzLCBhcmd1bWVudHMpLmVuZCgpOyB9KVxuICAgICAgICAudHdlZW4oXCJ6b29tXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICAgICAgZyA9IGdlc3R1cmUodGhhdCwgYXJncyksXG4gICAgICAgICAgICAgIGUgPSBleHRlbnQuYXBwbHkodGhhdCwgYXJncyksXG4gICAgICAgICAgICAgIHAgPSBjZW50ZXIgfHwgY2VudHJvaWQoZSksXG4gICAgICAgICAgICAgIHcgPSBNYXRoLm1heChlWzFdWzBdIC0gZVswXVswXSwgZVsxXVsxXSAtIGVbMF1bMV0pLFxuICAgICAgICAgICAgICBhID0gdGhhdC5fX3pvb20sXG4gICAgICAgICAgICAgIGIgPSB0eXBlb2YgdHJhbnNmb3JtID09PSBcImZ1bmN0aW9uXCIgPyB0cmFuc2Zvcm0uYXBwbHkodGhhdCwgYXJncykgOiB0cmFuc2Zvcm0sXG4gICAgICAgICAgICAgIGkgPSBpbnRlcnBvbGF0ZSQkMShhLmludmVydChwKS5jb25jYXQodyAvIGEuayksIGIuaW52ZXJ0KHApLmNvbmNhdCh3IC8gYi5rKSk7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgICAgIGlmICh0ID09PSAxKSB0ID0gYjsgLy8gQXZvaWQgcm91bmRpbmcgZXJyb3Igb24gZW5kLlxuICAgICAgICAgICAgZWxzZSB7IHZhciBsID0gaSh0KSwgayA9IHcgLyBsWzJdOyB0ID0gbmV3IFRyYW5zZm9ybShrLCBwWzBdIC0gbFswXSAqIGssIHBbMV0gLSBsWzFdICogayk7IH1cbiAgICAgICAgICAgIGcuem9vbShudWxsLCB0KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdlc3R1cmUodGhhdCwgYXJncykge1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gZ2VzdHVyZXMubGVuZ3RoLCBnOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKGcgPSBnZXN0dXJlc1tpXSkudGhhdCA9PT0gdGhhdCkge1xuICAgICAgICByZXR1cm4gZztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBHZXN0dXJlKHRoYXQsIGFyZ3MpO1xuICB9XG5cbiAgZnVuY3Rpb24gR2VzdHVyZSh0aGF0LCBhcmdzKSB7XG4gICAgdGhpcy50aGF0ID0gdGhhdDtcbiAgICB0aGlzLmFyZ3MgPSBhcmdzO1xuICAgIHRoaXMuaW5kZXggPSAtMTtcbiAgICB0aGlzLmFjdGl2ZSA9IDA7XG4gICAgdGhpcy5leHRlbnQgPSBleHRlbnQuYXBwbHkodGhhdCwgYXJncyk7XG4gIH1cblxuICBHZXN0dXJlLnByb3RvdHlwZSA9IHtcbiAgICBzdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoKyt0aGlzLmFjdGl2ZSA9PT0gMSkge1xuICAgICAgICB0aGlzLmluZGV4ID0gZ2VzdHVyZXMucHVzaCh0aGlzKSAtIDE7XG4gICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICB6b29tOiBmdW5jdGlvbihrZXksIHRyYW5zZm9ybSkge1xuICAgICAgaWYgKHRoaXMubW91c2UgJiYga2V5ICE9PSBcIm1vdXNlXCIpIHRoaXMubW91c2VbMV0gPSB0cmFuc2Zvcm0uaW52ZXJ0KHRoaXMubW91c2VbMF0pO1xuICAgICAgaWYgKHRoaXMudG91Y2gwICYmIGtleSAhPT0gXCJ0b3VjaFwiKSB0aGlzLnRvdWNoMFsxXSA9IHRyYW5zZm9ybS5pbnZlcnQodGhpcy50b3VjaDBbMF0pO1xuICAgICAgaWYgKHRoaXMudG91Y2gxICYmIGtleSAhPT0gXCJ0b3VjaFwiKSB0aGlzLnRvdWNoMVsxXSA9IHRyYW5zZm9ybS5pbnZlcnQodGhpcy50b3VjaDFbMF0pO1xuICAgICAgdGhpcy50aGF0Ll9fem9vbSA9IHRyYW5zZm9ybTtcbiAgICAgIHRoaXMuZW1pdChcInpvb21cIik7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGVuZDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoLS10aGlzLmFjdGl2ZSA9PT0gMCkge1xuICAgICAgICBnZXN0dXJlcy5zcGxpY2UodGhpcy5pbmRleCwgMSk7XG4gICAgICAgIHRoaXMuaW5kZXggPSAtMTtcbiAgICAgICAgdGhpcy5lbWl0KFwiZW5kXCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBlbWl0OiBmdW5jdGlvbih0eXBlKSB7XG4gICAgICBjdXN0b21FdmVudChuZXcgWm9vbUV2ZW50KHpvb20sIHR5cGUsIHRoaXMudGhhdC5fX3pvb20pLCBsaXN0ZW5lcnMuYXBwbHksIGxpc3RlbmVycywgW3R5cGUsIHRoaXMudGhhdCwgdGhpcy5hcmdzXSk7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIHdoZWVsZWQoKSB7XG4gICAgaWYgKCFmaWx0ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuO1xuICAgIHZhciBnID0gZ2VzdHVyZSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICB0ID0gdGhpcy5fX3pvb20sXG4gICAgICAgIGsgPSBNYXRoLm1heChrMCwgTWF0aC5taW4oazEsIHQuayAqIE1hdGgucG93KDIsIC1leHBvcnRzLmV2ZW50LmRlbHRhWSAqIChleHBvcnRzLmV2ZW50LmRlbHRhTW9kZSA/IDEyMCA6IDEpIC8gNTAwKSkpLFxuICAgICAgICBwID0gbW91c2UodGhpcyk7XG5cbiAgICAvLyBJZiB0aGUgbW91c2UgaXMgaW4gdGhlIHNhbWUgbG9jYXRpb24gYXMgYmVmb3JlLCByZXVzZSBpdC5cbiAgICAvLyBJZiB0aGVyZSB3ZXJlIHJlY2VudCB3aGVlbCBldmVudHMsIHJlc2V0IHRoZSB3aGVlbCBpZGxlIHRpbWVvdXQuXG4gICAgaWYgKGcud2hlZWwpIHtcbiAgICAgIGlmIChnLm1vdXNlWzBdWzBdICE9PSBwWzBdIHx8IGcubW91c2VbMF1bMV0gIT09IHBbMV0pIHtcbiAgICAgICAgZy5tb3VzZVsxXSA9IHQuaW52ZXJ0KGcubW91c2VbMF0gPSBwKTtcbiAgICAgIH1cbiAgICAgIGNsZWFyVGltZW91dChnLndoZWVsKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGlzIHdoZWVsIGV2ZW50IHdvbuKAmXQgdHJpZ2dlciBhIHRyYW5zZm9ybSBjaGFuZ2UsIGlnbm9yZSBpdC5cbiAgICBlbHNlIGlmICh0LmsgPT09IGspIHJldHVybjtcblxuICAgIC8vIE90aGVyd2lzZSwgY2FwdHVyZSB0aGUgbW91c2UgcG9pbnQgYW5kIGxvY2F0aW9uIGF0IHRoZSBzdGFydC5cbiAgICBlbHNlIHtcbiAgICAgIGcubW91c2UgPSBbcCwgdC5pbnZlcnQocCldO1xuICAgICAgaW50ZXJydXB0KHRoaXMpO1xuICAgICAgZy5zdGFydCgpO1xuICAgIH1cblxuICAgIG5vZXZlbnQkMigpO1xuICAgIGcud2hlZWwgPSBzZXRUaW1lb3V0KHdoZWVsaWRsZWQsIHdoZWVsRGVsYXkpO1xuICAgIGcuem9vbShcIm1vdXNlXCIsIGNvbnN0cmFpbih0cmFuc2xhdGUoc2NhbGUodCwgayksIGcubW91c2VbMF0sIGcubW91c2VbMV0pLCBnLmV4dGVudCkpO1xuXG4gICAgZnVuY3Rpb24gd2hlZWxpZGxlZCgpIHtcbiAgICAgIGcud2hlZWwgPSBudWxsO1xuICAgICAgZy5lbmQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBtb3VzZWRvd25lZCgpIHtcbiAgICBpZiAodG91Y2hlbmRpbmcgfHwgIWZpbHRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm47XG4gICAgdmFyIGcgPSBnZXN0dXJlKHRoaXMsIGFyZ3VtZW50cyksXG4gICAgICAgIHYgPSBzZWxlY3QoZXhwb3J0cy5ldmVudC52aWV3KS5vbihcIm1vdXNlbW92ZS56b29tXCIsIG1vdXNlbW92ZWQsIHRydWUpLm9uKFwibW91c2V1cC56b29tXCIsIG1vdXNldXBwZWQsIHRydWUpLFxuICAgICAgICBwID0gbW91c2UodGhpcyk7XG5cbiAgICBkcmFnRGlzYWJsZShleHBvcnRzLmV2ZW50LnZpZXcpO1xuICAgIG5vcHJvcGFnYXRpb24kMigpO1xuICAgIGcubW91c2UgPSBbcCwgdGhpcy5fX3pvb20uaW52ZXJ0KHApXTtcbiAgICBpbnRlcnJ1cHQodGhpcyk7XG4gICAgZy5zdGFydCgpO1xuXG4gICAgZnVuY3Rpb24gbW91c2Vtb3ZlZCgpIHtcbiAgICAgIG5vZXZlbnQkMigpO1xuICAgICAgZy5tb3ZlZCA9IHRydWU7XG4gICAgICBnLnpvb20oXCJtb3VzZVwiLCBjb25zdHJhaW4odHJhbnNsYXRlKGcudGhhdC5fX3pvb20sIGcubW91c2VbMF0gPSBtb3VzZShnLnRoYXQpLCBnLm1vdXNlWzFdKSwgZy5leHRlbnQpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3VzZXVwcGVkKCkge1xuICAgICAgdi5vbihcIm1vdXNlbW92ZS56b29tIG1vdXNldXAuem9vbVwiLCBudWxsKTtcbiAgICAgIHllc2RyYWcoZXhwb3J0cy5ldmVudC52aWV3LCBnLm1vdmVkKTtcbiAgICAgIG5vZXZlbnQkMigpO1xuICAgICAgZy5lbmQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkYmxjbGlja2VkKCkge1xuICAgIGlmICghZmlsdGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIHJldHVybjtcbiAgICB2YXIgdDAgPSB0aGlzLl9fem9vbSxcbiAgICAgICAgcDAgPSBtb3VzZSh0aGlzKSxcbiAgICAgICAgcDEgPSB0MC5pbnZlcnQocDApLFxuICAgICAgICBrMSA9IHQwLmsgKiAoZXhwb3J0cy5ldmVudC5zaGlmdEtleSA/IDAuNSA6IDIpLFxuICAgICAgICB0MSA9IGNvbnN0cmFpbih0cmFuc2xhdGUoc2NhbGUodDAsIGsxKSwgcDAsIHAxKSwgZXh0ZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuXG4gICAgbm9ldmVudCQyKCk7XG4gICAgaWYgKGR1cmF0aW9uID4gMCkgc2VsZWN0KHRoaXMpLnRyYW5zaXRpb24oKS5kdXJhdGlvbihkdXJhdGlvbikuY2FsbChzY2hlZHVsZSwgdDEsIHAwKTtcbiAgICBlbHNlIHNlbGVjdCh0aGlzKS5jYWxsKHpvb20udHJhbnNmb3JtLCB0MSk7XG4gIH1cblxuICBmdW5jdGlvbiB0b3VjaHN0YXJ0ZWQoKSB7XG4gICAgaWYgKCFmaWx0ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuO1xuICAgIHZhciBnID0gZ2VzdHVyZSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICB0b3VjaGVzJCQxID0gZXhwb3J0cy5ldmVudC5jaGFuZ2VkVG91Y2hlcyxcbiAgICAgICAgc3RhcnRlZCxcbiAgICAgICAgbiA9IHRvdWNoZXMkJDEubGVuZ3RoLCBpLCB0LCBwO1xuXG4gICAgbm9wcm9wYWdhdGlvbiQyKCk7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgdCA9IHRvdWNoZXMkJDFbaV0sIHAgPSB0b3VjaCh0aGlzLCB0b3VjaGVzJCQxLCB0LmlkZW50aWZpZXIpO1xuICAgICAgcCA9IFtwLCB0aGlzLl9fem9vbS5pbnZlcnQocCksIHQuaWRlbnRpZmllcl07XG4gICAgICBpZiAoIWcudG91Y2gwKSBnLnRvdWNoMCA9IHAsIHN0YXJ0ZWQgPSB0cnVlO1xuICAgICAgZWxzZSBpZiAoIWcudG91Y2gxKSBnLnRvdWNoMSA9IHA7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhpcyBpcyBhIGRibHRhcCwgcmVyb3V0ZSB0byB0aGUgKG9wdGlvbmFsKSBkYmxjbGljay56b29tIGhhbmRsZXIuXG4gICAgaWYgKHRvdWNoc3RhcnRpbmcpIHtcbiAgICAgIHRvdWNoc3RhcnRpbmcgPSBjbGVhclRpbWVvdXQodG91Y2hzdGFydGluZyk7XG4gICAgICBpZiAoIWcudG91Y2gxKSB7XG4gICAgICAgIGcuZW5kKCk7XG4gICAgICAgIHAgPSBzZWxlY3QodGhpcykub24oXCJkYmxjbGljay56b29tXCIpO1xuICAgICAgICBpZiAocCkgcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ZWQpIHtcbiAgICAgIHRvdWNoc3RhcnRpbmcgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyB0b3VjaHN0YXJ0aW5nID0gbnVsbDsgfSwgdG91Y2hEZWxheSk7XG4gICAgICBpbnRlcnJ1cHQodGhpcyk7XG4gICAgICBnLnN0YXJ0KCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG91Y2htb3ZlZCgpIHtcbiAgICB2YXIgZyA9IGdlc3R1cmUodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgdG91Y2hlcyQkMSA9IGV4cG9ydHMuZXZlbnQuY2hhbmdlZFRvdWNoZXMsXG4gICAgICAgIG4gPSB0b3VjaGVzJCQxLmxlbmd0aCwgaSwgdCwgcCwgbDtcblxuICAgIG5vZXZlbnQkMigpO1xuICAgIGlmICh0b3VjaHN0YXJ0aW5nKSB0b3VjaHN0YXJ0aW5nID0gY2xlYXJUaW1lb3V0KHRvdWNoc3RhcnRpbmcpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIHQgPSB0b3VjaGVzJCQxW2ldLCBwID0gdG91Y2godGhpcywgdG91Y2hlcyQkMSwgdC5pZGVudGlmaWVyKTtcbiAgICAgIGlmIChnLnRvdWNoMCAmJiBnLnRvdWNoMFsyXSA9PT0gdC5pZGVudGlmaWVyKSBnLnRvdWNoMFswXSA9IHA7XG4gICAgICBlbHNlIGlmIChnLnRvdWNoMSAmJiBnLnRvdWNoMVsyXSA9PT0gdC5pZGVudGlmaWVyKSBnLnRvdWNoMVswXSA9IHA7XG4gICAgfVxuICAgIHQgPSBnLnRoYXQuX196b29tO1xuICAgIGlmIChnLnRvdWNoMSkge1xuICAgICAgdmFyIHAwID0gZy50b3VjaDBbMF0sIGwwID0gZy50b3VjaDBbMV0sXG4gICAgICAgICAgcDEgPSBnLnRvdWNoMVswXSwgbDEgPSBnLnRvdWNoMVsxXSxcbiAgICAgICAgICBkcCA9IChkcCA9IHAxWzBdIC0gcDBbMF0pICogZHAgKyAoZHAgPSBwMVsxXSAtIHAwWzFdKSAqIGRwLFxuICAgICAgICAgIGRsID0gKGRsID0gbDFbMF0gLSBsMFswXSkgKiBkbCArIChkbCA9IGwxWzFdIC0gbDBbMV0pICogZGw7XG4gICAgICB0ID0gc2NhbGUodCwgTWF0aC5zcXJ0KGRwIC8gZGwpKTtcbiAgICAgIHAgPSBbKHAwWzBdICsgcDFbMF0pIC8gMiwgKHAwWzFdICsgcDFbMV0pIC8gMl07XG4gICAgICBsID0gWyhsMFswXSArIGwxWzBdKSAvIDIsIChsMFsxXSArIGwxWzFdKSAvIDJdO1xuICAgIH1cbiAgICBlbHNlIGlmIChnLnRvdWNoMCkgcCA9IGcudG91Y2gwWzBdLCBsID0gZy50b3VjaDBbMV07XG4gICAgZWxzZSByZXR1cm47XG4gICAgZy56b29tKFwidG91Y2hcIiwgY29uc3RyYWluKHRyYW5zbGF0ZSh0LCBwLCBsKSwgZy5leHRlbnQpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvdWNoZW5kZWQoKSB7XG4gICAgdmFyIGcgPSBnZXN0dXJlKHRoaXMsIGFyZ3VtZW50cyksXG4gICAgICAgIHRvdWNoZXMkJDEgPSBleHBvcnRzLmV2ZW50LmNoYW5nZWRUb3VjaGVzLFxuICAgICAgICBuID0gdG91Y2hlcyQkMS5sZW5ndGgsIGksIHQ7XG5cbiAgICBub3Byb3BhZ2F0aW9uJDIoKTtcbiAgICBpZiAodG91Y2hlbmRpbmcpIGNsZWFyVGltZW91dCh0b3VjaGVuZGluZyk7XG4gICAgdG91Y2hlbmRpbmcgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyB0b3VjaGVuZGluZyA9IG51bGw7IH0sIHRvdWNoRGVsYXkpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIHQgPSB0b3VjaGVzJCQxW2ldO1xuICAgICAgaWYgKGcudG91Y2gwICYmIGcudG91Y2gwWzJdID09PSB0LmlkZW50aWZpZXIpIGRlbGV0ZSBnLnRvdWNoMDtcbiAgICAgIGVsc2UgaWYgKGcudG91Y2gxICYmIGcudG91Y2gxWzJdID09PSB0LmlkZW50aWZpZXIpIGRlbGV0ZSBnLnRvdWNoMTtcbiAgICB9XG4gICAgaWYgKGcudG91Y2gxICYmICFnLnRvdWNoMCkgZy50b3VjaDAgPSBnLnRvdWNoMSwgZGVsZXRlIGcudG91Y2gxO1xuICAgIGlmIChnLnRvdWNoMCkgZy50b3VjaDBbMV0gPSB0aGlzLl9fem9vbS5pbnZlcnQoZy50b3VjaDBbMF0pO1xuICAgIGVsc2UgZy5lbmQoKTtcbiAgfVxuXG4gIHpvb20uZmlsdGVyID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGZpbHRlciA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTIoISFfKSwgem9vbSkgOiBmaWx0ZXI7XG4gIH07XG5cbiAgem9vbS5leHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZXh0ZW50ID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMihbWytfWzBdWzBdLCArX1swXVsxXV0sIFsrX1sxXVswXSwgK19bMV1bMV1dXSksIHpvb20pIDogZXh0ZW50O1xuICB9O1xuXG4gIHpvb20uc2NhbGVFeHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoazAgPSArX1swXSwgazEgPSArX1sxXSwgem9vbSkgOiBbazAsIGsxXTtcbiAgfTtcblxuICB6b29tLnRyYW5zbGF0ZUV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MCA9ICtfWzBdWzBdLCB4MSA9ICtfWzFdWzBdLCB5MCA9ICtfWzBdWzFdLCB5MSA9ICtfWzFdWzFdLCB6b29tKSA6IFtbeDAsIHkwXSwgW3gxLCB5MV1dO1xuICB9O1xuXG4gIHpvb20uZHVyYXRpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZHVyYXRpb24gPSArXywgem9vbSkgOiBkdXJhdGlvbjtcbiAgfTtcblxuICB6b29tLmludGVycG9sYXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGludGVycG9sYXRlJCQxID0gXywgem9vbSkgOiBpbnRlcnBvbGF0ZSQkMTtcbiAgfTtcblxuICB6b29tLm9uID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZhbHVlID0gbGlzdGVuZXJzLm9uLmFwcGx5KGxpc3RlbmVycywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gdmFsdWUgPT09IGxpc3RlbmVycyA/IHpvb20gOiB2YWx1ZTtcbiAgfTtcblxuICByZXR1cm4gem9vbTtcbn07XG5cbmV4cG9ydHMudmVyc2lvbiA9IHZlcnNpb247XG5leHBvcnRzLmJpc2VjdCA9IGJpc2VjdFJpZ2h0O1xuZXhwb3J0cy5iaXNlY3RSaWdodCA9IGJpc2VjdFJpZ2h0O1xuZXhwb3J0cy5iaXNlY3RMZWZ0ID0gYmlzZWN0TGVmdDtcbmV4cG9ydHMuYXNjZW5kaW5nID0gYXNjZW5kaW5nO1xuZXhwb3J0cy5iaXNlY3RvciA9IGJpc2VjdG9yO1xuZXhwb3J0cy5jcm9zcyA9IGNyb3NzO1xuZXhwb3J0cy5kZXNjZW5kaW5nID0gZGVzY2VuZGluZztcbmV4cG9ydHMuZGV2aWF0aW9uID0gZGV2aWF0aW9uO1xuZXhwb3J0cy5leHRlbnQgPSBleHRlbnQ7XG5leHBvcnRzLmhpc3RvZ3JhbSA9IGhpc3RvZ3JhbTtcbmV4cG9ydHMudGhyZXNob2xkRnJlZWRtYW5EaWFjb25pcyA9IGZyZWVkbWFuRGlhY29uaXM7XG5leHBvcnRzLnRocmVzaG9sZFNjb3R0ID0gc2NvdHQ7XG5leHBvcnRzLnRocmVzaG9sZFN0dXJnZXMgPSBzdHVyZ2VzO1xuZXhwb3J0cy5tYXggPSBtYXg7XG5leHBvcnRzLm1lYW4gPSBtZWFuO1xuZXhwb3J0cy5tZWRpYW4gPSBtZWRpYW47XG5leHBvcnRzLm1lcmdlID0gbWVyZ2U7XG5leHBvcnRzLm1pbiA9IG1pbjtcbmV4cG9ydHMucGFpcnMgPSBwYWlycztcbmV4cG9ydHMucGVybXV0ZSA9IHBlcm11dGU7XG5leHBvcnRzLnF1YW50aWxlID0gdGhyZXNob2xkO1xuZXhwb3J0cy5yYW5nZSA9IHNlcXVlbmNlO1xuZXhwb3J0cy5zY2FuID0gc2NhbjtcbmV4cG9ydHMuc2h1ZmZsZSA9IHNodWZmbGU7XG5leHBvcnRzLnN1bSA9IHN1bTtcbmV4cG9ydHMudGlja3MgPSB0aWNrcztcbmV4cG9ydHMudGlja1N0ZXAgPSB0aWNrU3RlcDtcbmV4cG9ydHMudHJhbnNwb3NlID0gdHJhbnNwb3NlO1xuZXhwb3J0cy52YXJpYW5jZSA9IHZhcmlhbmNlO1xuZXhwb3J0cy56aXAgPSB6aXA7XG5leHBvcnRzLmF4aXNUb3AgPSBheGlzVG9wO1xuZXhwb3J0cy5heGlzUmlnaHQgPSBheGlzUmlnaHQ7XG5leHBvcnRzLmF4aXNCb3R0b20gPSBheGlzQm90dG9tO1xuZXhwb3J0cy5heGlzTGVmdCA9IGF4aXNMZWZ0O1xuZXhwb3J0cy5icnVzaCA9IGJydXNoO1xuZXhwb3J0cy5icnVzaFggPSBicnVzaFg7XG5leHBvcnRzLmJydXNoWSA9IGJydXNoWTtcbmV4cG9ydHMuYnJ1c2hTZWxlY3Rpb24gPSBicnVzaFNlbGVjdGlvbjtcbmV4cG9ydHMuY2hvcmQgPSBjaG9yZDtcbmV4cG9ydHMucmliYm9uID0gcmliYm9uO1xuZXhwb3J0cy5uZXN0ID0gbmVzdDtcbmV4cG9ydHMuc2V0ID0gc2V0JDI7XG5leHBvcnRzLm1hcCA9IG1hcCQxO1xuZXhwb3J0cy5rZXlzID0ga2V5cztcbmV4cG9ydHMudmFsdWVzID0gdmFsdWVzO1xuZXhwb3J0cy5lbnRyaWVzID0gZW50cmllcztcbmV4cG9ydHMuY29sb3IgPSBjb2xvcjtcbmV4cG9ydHMucmdiID0gcmdiO1xuZXhwb3J0cy5oc2wgPSBoc2w7XG5leHBvcnRzLmxhYiA9IGxhYjtcbmV4cG9ydHMuaGNsID0gaGNsO1xuZXhwb3J0cy5jdWJlaGVsaXggPSBjdWJlaGVsaXg7XG5leHBvcnRzLmRpc3BhdGNoID0gZGlzcGF0Y2g7XG5leHBvcnRzLmRyYWcgPSBkcmFnO1xuZXhwb3J0cy5kcmFnRGlzYWJsZSA9IGRyYWdEaXNhYmxlO1xuZXhwb3J0cy5kcmFnRW5hYmxlID0geWVzZHJhZztcbmV4cG9ydHMuZHN2Rm9ybWF0ID0gZHN2O1xuZXhwb3J0cy5jc3ZQYXJzZSA9IGNzdlBhcnNlO1xuZXhwb3J0cy5jc3ZQYXJzZVJvd3MgPSBjc3ZQYXJzZVJvd3M7XG5leHBvcnRzLmNzdkZvcm1hdCA9IGNzdkZvcm1hdDtcbmV4cG9ydHMuY3N2Rm9ybWF0Um93cyA9IGNzdkZvcm1hdFJvd3M7XG5leHBvcnRzLnRzdlBhcnNlID0gdHN2UGFyc2U7XG5leHBvcnRzLnRzdlBhcnNlUm93cyA9IHRzdlBhcnNlUm93cztcbmV4cG9ydHMudHN2Rm9ybWF0ID0gdHN2Rm9ybWF0O1xuZXhwb3J0cy50c3ZGb3JtYXRSb3dzID0gdHN2Rm9ybWF0Um93cztcbmV4cG9ydHMuZWFzZUxpbmVhciA9IGxpbmVhciQxO1xuZXhwb3J0cy5lYXNlUXVhZCA9IHF1YWRJbk91dDtcbmV4cG9ydHMuZWFzZVF1YWRJbiA9IHF1YWRJbjtcbmV4cG9ydHMuZWFzZVF1YWRPdXQgPSBxdWFkT3V0O1xuZXhwb3J0cy5lYXNlUXVhZEluT3V0ID0gcXVhZEluT3V0O1xuZXhwb3J0cy5lYXNlQ3ViaWMgPSBjdWJpY0luT3V0O1xuZXhwb3J0cy5lYXNlQ3ViaWNJbiA9IGN1YmljSW47XG5leHBvcnRzLmVhc2VDdWJpY091dCA9IGN1YmljT3V0O1xuZXhwb3J0cy5lYXNlQ3ViaWNJbk91dCA9IGN1YmljSW5PdXQ7XG5leHBvcnRzLmVhc2VQb2x5ID0gcG9seUluT3V0O1xuZXhwb3J0cy5lYXNlUG9seUluID0gcG9seUluO1xuZXhwb3J0cy5lYXNlUG9seU91dCA9IHBvbHlPdXQ7XG5leHBvcnRzLmVhc2VQb2x5SW5PdXQgPSBwb2x5SW5PdXQ7XG5leHBvcnRzLmVhc2VTaW4gPSBzaW5Jbk91dDtcbmV4cG9ydHMuZWFzZVNpbkluID0gc2luSW47XG5leHBvcnRzLmVhc2VTaW5PdXQgPSBzaW5PdXQ7XG5leHBvcnRzLmVhc2VTaW5Jbk91dCA9IHNpbkluT3V0O1xuZXhwb3J0cy5lYXNlRXhwID0gZXhwSW5PdXQ7XG5leHBvcnRzLmVhc2VFeHBJbiA9IGV4cEluO1xuZXhwb3J0cy5lYXNlRXhwT3V0ID0gZXhwT3V0O1xuZXhwb3J0cy5lYXNlRXhwSW5PdXQgPSBleHBJbk91dDtcbmV4cG9ydHMuZWFzZUNpcmNsZSA9IGNpcmNsZUluT3V0O1xuZXhwb3J0cy5lYXNlQ2lyY2xlSW4gPSBjaXJjbGVJbjtcbmV4cG9ydHMuZWFzZUNpcmNsZU91dCA9IGNpcmNsZU91dDtcbmV4cG9ydHMuZWFzZUNpcmNsZUluT3V0ID0gY2lyY2xlSW5PdXQ7XG5leHBvcnRzLmVhc2VCb3VuY2UgPSBib3VuY2VPdXQ7XG5leHBvcnRzLmVhc2VCb3VuY2VJbiA9IGJvdW5jZUluO1xuZXhwb3J0cy5lYXNlQm91bmNlT3V0ID0gYm91bmNlT3V0O1xuZXhwb3J0cy5lYXNlQm91bmNlSW5PdXQgPSBib3VuY2VJbk91dDtcbmV4cG9ydHMuZWFzZUJhY2sgPSBiYWNrSW5PdXQ7XG5leHBvcnRzLmVhc2VCYWNrSW4gPSBiYWNrSW47XG5leHBvcnRzLmVhc2VCYWNrT3V0ID0gYmFja091dDtcbmV4cG9ydHMuZWFzZUJhY2tJbk91dCA9IGJhY2tJbk91dDtcbmV4cG9ydHMuZWFzZUVsYXN0aWMgPSBlbGFzdGljT3V0O1xuZXhwb3J0cy5lYXNlRWxhc3RpY0luID0gZWxhc3RpY0luO1xuZXhwb3J0cy5lYXNlRWxhc3RpY091dCA9IGVsYXN0aWNPdXQ7XG5leHBvcnRzLmVhc2VFbGFzdGljSW5PdXQgPSBlbGFzdGljSW5PdXQ7XG5leHBvcnRzLmZvcmNlQ2VudGVyID0gY2VudGVyJDE7XG5leHBvcnRzLmZvcmNlQ29sbGlkZSA9IGNvbGxpZGU7XG5leHBvcnRzLmZvcmNlTGluayA9IGxpbms7XG5leHBvcnRzLmZvcmNlTWFueUJvZHkgPSBtYW55Qm9keTtcbmV4cG9ydHMuZm9yY2VTaW11bGF0aW9uID0gc2ltdWxhdGlvbjtcbmV4cG9ydHMuZm9yY2VYID0geCQyO1xuZXhwb3J0cy5mb3JjZVkgPSB5JDI7XG5leHBvcnRzLmZvcm1hdERlZmF1bHRMb2NhbGUgPSBkZWZhdWx0TG9jYWxlO1xuZXhwb3J0cy5mb3JtYXRMb2NhbGUgPSBmb3JtYXRMb2NhbGU7XG5leHBvcnRzLmZvcm1hdFNwZWNpZmllciA9IGZvcm1hdFNwZWNpZmllcjtcbmV4cG9ydHMucHJlY2lzaW9uRml4ZWQgPSBwcmVjaXNpb25GaXhlZDtcbmV4cG9ydHMucHJlY2lzaW9uUHJlZml4ID0gcHJlY2lzaW9uUHJlZml4O1xuZXhwb3J0cy5wcmVjaXNpb25Sb3VuZCA9IHByZWNpc2lvblJvdW5kO1xuZXhwb3J0cy5nZW9BcmVhID0gYXJlYTtcbmV4cG9ydHMuZ2VvQm91bmRzID0gYm91bmRzO1xuZXhwb3J0cy5nZW9DZW50cm9pZCA9IGNlbnRyb2lkO1xuZXhwb3J0cy5nZW9DaXJjbGUgPSBjaXJjbGU7XG5leHBvcnRzLmdlb0NsaXBFeHRlbnQgPSBleHRlbnQkMTtcbmV4cG9ydHMuZ2VvQ29udGFpbnMgPSBjb250YWlucztcbmV4cG9ydHMuZ2VvRGlzdGFuY2UgPSBkaXN0YW5jZTtcbmV4cG9ydHMuZ2VvR3JhdGljdWxlID0gZ3JhdGljdWxlO1xuZXhwb3J0cy5nZW9HcmF0aWN1bGUxMCA9IGdyYXRpY3VsZTEwO1xuZXhwb3J0cy5nZW9JbnRlcnBvbGF0ZSA9IGludGVycG9sYXRlJDE7XG5leHBvcnRzLmdlb0xlbmd0aCA9IGxlbmd0aCQxO1xuZXhwb3J0cy5nZW9QYXRoID0gaW5kZXgkMTtcbmV4cG9ydHMuZ2VvQWxiZXJzID0gYWxiZXJzO1xuZXhwb3J0cy5nZW9BbGJlcnNVc2EgPSBhbGJlcnNVc2E7XG5leHBvcnRzLmdlb0F6aW11dGhhbEVxdWFsQXJlYSA9IGF6aW11dGhhbEVxdWFsQXJlYTtcbmV4cG9ydHMuZ2VvQXppbXV0aGFsRXF1YWxBcmVhUmF3ID0gYXppbXV0aGFsRXF1YWxBcmVhUmF3O1xuZXhwb3J0cy5nZW9BemltdXRoYWxFcXVpZGlzdGFudCA9IGF6aW11dGhhbEVxdWlkaXN0YW50O1xuZXhwb3J0cy5nZW9BemltdXRoYWxFcXVpZGlzdGFudFJhdyA9IGF6aW11dGhhbEVxdWlkaXN0YW50UmF3O1xuZXhwb3J0cy5nZW9Db25pY0NvbmZvcm1hbCA9IGNvbmljQ29uZm9ybWFsO1xuZXhwb3J0cy5nZW9Db25pY0NvbmZvcm1hbFJhdyA9IGNvbmljQ29uZm9ybWFsUmF3O1xuZXhwb3J0cy5nZW9Db25pY0VxdWFsQXJlYSA9IGNvbmljRXF1YWxBcmVhO1xuZXhwb3J0cy5nZW9Db25pY0VxdWFsQXJlYVJhdyA9IGNvbmljRXF1YWxBcmVhUmF3O1xuZXhwb3J0cy5nZW9Db25pY0VxdWlkaXN0YW50ID0gY29uaWNFcXVpZGlzdGFudDtcbmV4cG9ydHMuZ2VvQ29uaWNFcXVpZGlzdGFudFJhdyA9IGNvbmljRXF1aWRpc3RhbnRSYXc7XG5leHBvcnRzLmdlb0VxdWlyZWN0YW5ndWxhciA9IGVxdWlyZWN0YW5ndWxhcjtcbmV4cG9ydHMuZ2VvRXF1aXJlY3Rhbmd1bGFyUmF3ID0gZXF1aXJlY3Rhbmd1bGFyUmF3O1xuZXhwb3J0cy5nZW9Hbm9tb25pYyA9IGdub21vbmljO1xuZXhwb3J0cy5nZW9Hbm9tb25pY1JhdyA9IGdub21vbmljUmF3O1xuZXhwb3J0cy5nZW9JZGVudGl0eSA9IGlkZW50aXR5JDU7XG5leHBvcnRzLmdlb1Byb2plY3Rpb24gPSBwcm9qZWN0aW9uO1xuZXhwb3J0cy5nZW9Qcm9qZWN0aW9uTXV0YXRvciA9IHByb2plY3Rpb25NdXRhdG9yO1xuZXhwb3J0cy5nZW9NZXJjYXRvciA9IG1lcmNhdG9yO1xuZXhwb3J0cy5nZW9NZXJjYXRvclJhdyA9IG1lcmNhdG9yUmF3O1xuZXhwb3J0cy5nZW9PcnRob2dyYXBoaWMgPSBvcnRob2dyYXBoaWM7XG5leHBvcnRzLmdlb09ydGhvZ3JhcGhpY1JhdyA9IG9ydGhvZ3JhcGhpY1JhdztcbmV4cG9ydHMuZ2VvU3RlcmVvZ3JhcGhpYyA9IHN0ZXJlb2dyYXBoaWM7XG5leHBvcnRzLmdlb1N0ZXJlb2dyYXBoaWNSYXcgPSBzdGVyZW9ncmFwaGljUmF3O1xuZXhwb3J0cy5nZW9UcmFuc3ZlcnNlTWVyY2F0b3IgPSB0cmFuc3ZlcnNlTWVyY2F0b3I7XG5leHBvcnRzLmdlb1RyYW5zdmVyc2VNZXJjYXRvclJhdyA9IHRyYW5zdmVyc2VNZXJjYXRvclJhdztcbmV4cG9ydHMuZ2VvUm90YXRpb24gPSByb3RhdGlvbjtcbmV4cG9ydHMuZ2VvU3RyZWFtID0gZ2VvU3RyZWFtO1xuZXhwb3J0cy5nZW9UcmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG5leHBvcnRzLmNsdXN0ZXIgPSBjbHVzdGVyO1xuZXhwb3J0cy5oaWVyYXJjaHkgPSBoaWVyYXJjaHk7XG5leHBvcnRzLnBhY2sgPSBpbmRleCQyO1xuZXhwb3J0cy5wYWNrU2libGluZ3MgPSBzaWJsaW5ncztcbmV4cG9ydHMucGFja0VuY2xvc2UgPSBlbmNsb3NlO1xuZXhwb3J0cy5wYXJ0aXRpb24gPSBwYXJ0aXRpb247XG5leHBvcnRzLnN0cmF0aWZ5ID0gc3RyYXRpZnk7XG5leHBvcnRzLnRyZWUgPSB0cmVlO1xuZXhwb3J0cy50cmVlbWFwID0gaW5kZXgkMztcbmV4cG9ydHMudHJlZW1hcEJpbmFyeSA9IGJpbmFyeTtcbmV4cG9ydHMudHJlZW1hcERpY2UgPSB0cmVlbWFwRGljZTtcbmV4cG9ydHMudHJlZW1hcFNsaWNlID0gdHJlZW1hcFNsaWNlO1xuZXhwb3J0cy50cmVlbWFwU2xpY2VEaWNlID0gc2xpY2VEaWNlO1xuZXhwb3J0cy50cmVlbWFwU3F1YXJpZnkgPSBzcXVhcmlmeTtcbmV4cG9ydHMudHJlZW1hcFJlc3F1YXJpZnkgPSByZXNxdWFyaWZ5O1xuZXhwb3J0cy5pbnRlcnBvbGF0ZSA9IGludGVycG9sYXRlVmFsdWU7XG5leHBvcnRzLmludGVycG9sYXRlQXJyYXkgPSBhcnJheSQxO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZUJhc2lzID0gYmFzaXMkMTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVCYXNpc0Nsb3NlZCA9IGJhc2lzQ2xvc2VkO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZURhdGUgPSBkYXRlO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZU51bWJlciA9IHJlaW50ZXJwb2xhdGU7XG5leHBvcnRzLmludGVycG9sYXRlT2JqZWN0ID0gb2JqZWN0O1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJvdW5kID0gaW50ZXJwb2xhdGVSb3VuZDtcbmV4cG9ydHMuaW50ZXJwb2xhdGVTdHJpbmcgPSBpbnRlcnBvbGF0ZVN0cmluZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVUcmFuc2Zvcm1Dc3MgPSBpbnRlcnBvbGF0ZVRyYW5zZm9ybUNzcztcbmV4cG9ydHMuaW50ZXJwb2xhdGVUcmFuc2Zvcm1TdmcgPSBpbnRlcnBvbGF0ZVRyYW5zZm9ybVN2ZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVab29tID0gaW50ZXJwb2xhdGVab29tO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJnYiA9IGludGVycG9sYXRlUmdiO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJnYkJhc2lzID0gcmdiQmFzaXM7XG5leHBvcnRzLmludGVycG9sYXRlUmdiQmFzaXNDbG9zZWQgPSByZ2JCYXNpc0Nsb3NlZDtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIc2wgPSBoc2wkMjtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIc2xMb25nID0gaHNsTG9uZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVMYWIgPSBsYWIkMTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIY2wgPSBoY2wkMjtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIY2xMb25nID0gaGNsTG9uZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVDdWJlaGVsaXggPSBjdWJlaGVsaXgkMjtcbmV4cG9ydHMuaW50ZXJwb2xhdGVDdWJlaGVsaXhMb25nID0gY3ViZWhlbGl4TG9uZztcbmV4cG9ydHMucXVhbnRpemUgPSBxdWFudGl6ZTtcbmV4cG9ydHMucGF0aCA9IHBhdGg7XG5leHBvcnRzLnBvbHlnb25BcmVhID0gYXJlYSQxO1xuZXhwb3J0cy5wb2x5Z29uQ2VudHJvaWQgPSBjZW50cm9pZCQxO1xuZXhwb3J0cy5wb2x5Z29uSHVsbCA9IGh1bGw7XG5leHBvcnRzLnBvbHlnb25Db250YWlucyA9IGNvbnRhaW5zJDE7XG5leHBvcnRzLnBvbHlnb25MZW5ndGggPSBsZW5ndGgkMjtcbmV4cG9ydHMucXVhZHRyZWUgPSBxdWFkdHJlZTtcbmV4cG9ydHMucXVldWUgPSBxdWV1ZTtcbmV4cG9ydHMucmFuZG9tVW5pZm9ybSA9IHVuaWZvcm07XG5leHBvcnRzLnJhbmRvbU5vcm1hbCA9IG5vcm1hbDtcbmV4cG9ydHMucmFuZG9tTG9nTm9ybWFsID0gbG9nTm9ybWFsO1xuZXhwb3J0cy5yYW5kb21CYXRlcyA9IGJhdGVzO1xuZXhwb3J0cy5yYW5kb21JcndpbkhhbGwgPSBpcndpbkhhbGw7XG5leHBvcnRzLnJhbmRvbUV4cG9uZW50aWFsID0gZXhwb25lbnRpYWwkMTtcbmV4cG9ydHMucmVxdWVzdCA9IHJlcXVlc3Q7XG5leHBvcnRzLmh0bWwgPSBodG1sO1xuZXhwb3J0cy5qc29uID0ganNvbjtcbmV4cG9ydHMudGV4dCA9IHRleHQ7XG5leHBvcnRzLnhtbCA9IHhtbDtcbmV4cG9ydHMuY3N2ID0gY3N2JDE7XG5leHBvcnRzLnRzdiA9IHRzdiQxO1xuZXhwb3J0cy5zY2FsZUJhbmQgPSBiYW5kO1xuZXhwb3J0cy5zY2FsZVBvaW50ID0gcG9pbnQkMTtcbmV4cG9ydHMuc2NhbGVJZGVudGl0eSA9IGlkZW50aXR5JDY7XG5leHBvcnRzLnNjYWxlTGluZWFyID0gbGluZWFyJDI7XG5leHBvcnRzLnNjYWxlTG9nID0gbG9nJDE7XG5leHBvcnRzLnNjYWxlT3JkaW5hbCA9IG9yZGluYWw7XG5leHBvcnRzLnNjYWxlSW1wbGljaXQgPSBpbXBsaWNpdDtcbmV4cG9ydHMuc2NhbGVQb3cgPSBwb3ckMTtcbmV4cG9ydHMuc2NhbGVTcXJ0ID0gc3FydCQxO1xuZXhwb3J0cy5zY2FsZVF1YW50aWxlID0gcXVhbnRpbGUkJDE7XG5leHBvcnRzLnNjYWxlUXVhbnRpemUgPSBxdWFudGl6ZSQxO1xuZXhwb3J0cy5zY2FsZVRocmVzaG9sZCA9IHRocmVzaG9sZCQxO1xuZXhwb3J0cy5zY2FsZVRpbWUgPSB0aW1lO1xuZXhwb3J0cy5zY2FsZVV0YyA9IHV0Y1RpbWU7XG5leHBvcnRzLnNjaGVtZUNhdGVnb3J5MTAgPSBjYXRlZ29yeTEwO1xuZXhwb3J0cy5zY2hlbWVDYXRlZ29yeTIwYiA9IGNhdGVnb3J5MjBiO1xuZXhwb3J0cy5zY2hlbWVDYXRlZ29yeTIwYyA9IGNhdGVnb3J5MjBjO1xuZXhwb3J0cy5zY2hlbWVDYXRlZ29yeTIwID0gY2F0ZWdvcnkyMDtcbmV4cG9ydHMuaW50ZXJwb2xhdGVDdWJlaGVsaXhEZWZhdWx0ID0gY3ViZWhlbGl4JDM7XG5leHBvcnRzLmludGVycG9sYXRlUmFpbmJvdyA9IHJhaW5ib3ckMTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVXYXJtID0gd2FybTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVDb29sID0gY29vbDtcbmV4cG9ydHMuaW50ZXJwb2xhdGVWaXJpZGlzID0gdmlyaWRpcztcbmV4cG9ydHMuaW50ZXJwb2xhdGVNYWdtYSA9IG1hZ21hO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZUluZmVybm8gPSBpbmZlcm5vO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVBsYXNtYSA9IHBsYXNtYTtcbmV4cG9ydHMuc2NhbGVTZXF1ZW50aWFsID0gc2VxdWVudGlhbDtcbmV4cG9ydHMuY3JlYXRvciA9IGNyZWF0b3I7XG5leHBvcnRzLmxvY2FsID0gbG9jYWwkMTtcbmV4cG9ydHMubWF0Y2hlciA9IG1hdGNoZXIkMTtcbmV4cG9ydHMubW91c2UgPSBtb3VzZTtcbmV4cG9ydHMubmFtZXNwYWNlID0gbmFtZXNwYWNlO1xuZXhwb3J0cy5uYW1lc3BhY2VzID0gbmFtZXNwYWNlcztcbmV4cG9ydHMuc2VsZWN0ID0gc2VsZWN0O1xuZXhwb3J0cy5zZWxlY3RBbGwgPSBzZWxlY3RBbGw7XG5leHBvcnRzLnNlbGVjdGlvbiA9IHNlbGVjdGlvbjtcbmV4cG9ydHMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbmV4cG9ydHMuc2VsZWN0b3JBbGwgPSBzZWxlY3RvckFsbDtcbmV4cG9ydHMudG91Y2ggPSB0b3VjaDtcbmV4cG9ydHMudG91Y2hlcyA9IHRvdWNoZXM7XG5leHBvcnRzLndpbmRvdyA9IHdpbmRvdztcbmV4cG9ydHMuY3VzdG9tRXZlbnQgPSBjdXN0b21FdmVudDtcbmV4cG9ydHMuYXJjID0gYXJjO1xuZXhwb3J0cy5hcmVhID0gYXJlYSQyO1xuZXhwb3J0cy5saW5lID0gbGluZTtcbmV4cG9ydHMucGllID0gcGllO1xuZXhwb3J0cy5yYWRpYWxBcmVhID0gcmFkaWFsQXJlYTtcbmV4cG9ydHMucmFkaWFsTGluZSA9IHJhZGlhbExpbmUkMTtcbmV4cG9ydHMuc3ltYm9sID0gc3ltYm9sO1xuZXhwb3J0cy5zeW1ib2xzID0gc3ltYm9scztcbmV4cG9ydHMuc3ltYm9sQ2lyY2xlID0gY2lyY2xlJDI7XG5leHBvcnRzLnN5bWJvbENyb3NzID0gY3Jvc3MkMjtcbmV4cG9ydHMuc3ltYm9sRGlhbW9uZCA9IGRpYW1vbmQ7XG5leHBvcnRzLnN5bWJvbFNxdWFyZSA9IHNxdWFyZTtcbmV4cG9ydHMuc3ltYm9sU3RhciA9IHN0YXI7XG5leHBvcnRzLnN5bWJvbFRyaWFuZ2xlID0gdHJpYW5nbGU7XG5leHBvcnRzLnN5bWJvbFd5ZSA9IHd5ZTtcbmV4cG9ydHMuY3VydmVCYXNpc0Nsb3NlZCA9IGJhc2lzQ2xvc2VkJDE7XG5leHBvcnRzLmN1cnZlQmFzaXNPcGVuID0gYmFzaXNPcGVuO1xuZXhwb3J0cy5jdXJ2ZUJhc2lzID0gYmFzaXMkMjtcbmV4cG9ydHMuY3VydmVCdW5kbGUgPSBidW5kbGU7XG5leHBvcnRzLmN1cnZlQ2FyZGluYWxDbG9zZWQgPSBjYXJkaW5hbENsb3NlZDtcbmV4cG9ydHMuY3VydmVDYXJkaW5hbE9wZW4gPSBjYXJkaW5hbE9wZW47XG5leHBvcnRzLmN1cnZlQ2FyZGluYWwgPSBjYXJkaW5hbDtcbmV4cG9ydHMuY3VydmVDYXRtdWxsUm9tQ2xvc2VkID0gY2F0bXVsbFJvbUNsb3NlZDtcbmV4cG9ydHMuY3VydmVDYXRtdWxsUm9tT3BlbiA9IGNhdG11bGxSb21PcGVuO1xuZXhwb3J0cy5jdXJ2ZUNhdG11bGxSb20gPSBjYXRtdWxsUm9tO1xuZXhwb3J0cy5jdXJ2ZUxpbmVhckNsb3NlZCA9IGxpbmVhckNsb3NlZDtcbmV4cG9ydHMuY3VydmVMaW5lYXIgPSBjdXJ2ZUxpbmVhcjtcbmV4cG9ydHMuY3VydmVNb25vdG9uZVggPSBtb25vdG9uZVg7XG5leHBvcnRzLmN1cnZlTW9ub3RvbmVZID0gbW9ub3RvbmVZO1xuZXhwb3J0cy5jdXJ2ZU5hdHVyYWwgPSBuYXR1cmFsO1xuZXhwb3J0cy5jdXJ2ZVN0ZXAgPSBzdGVwO1xuZXhwb3J0cy5jdXJ2ZVN0ZXBBZnRlciA9IHN0ZXBBZnRlcjtcbmV4cG9ydHMuY3VydmVTdGVwQmVmb3JlID0gc3RlcEJlZm9yZTtcbmV4cG9ydHMuc3RhY2sgPSBzdGFjaztcbmV4cG9ydHMuc3RhY2tPZmZzZXRFeHBhbmQgPSBleHBhbmQ7XG5leHBvcnRzLnN0YWNrT2Zmc2V0Tm9uZSA9IG5vbmUkMTtcbmV4cG9ydHMuc3RhY2tPZmZzZXRTaWxob3VldHRlID0gc2lsaG91ZXR0ZTtcbmV4cG9ydHMuc3RhY2tPZmZzZXRXaWdnbGUgPSB3aWdnbGU7XG5leHBvcnRzLnN0YWNrT3JkZXJBc2NlbmRpbmcgPSBhc2NlbmRpbmckMjtcbmV4cG9ydHMuc3RhY2tPcmRlckRlc2NlbmRpbmcgPSBkZXNjZW5kaW5nJDI7XG5leHBvcnRzLnN0YWNrT3JkZXJJbnNpZGVPdXQgPSBpbnNpZGVPdXQ7XG5leHBvcnRzLnN0YWNrT3JkZXJOb25lID0gbm9uZSQyO1xuZXhwb3J0cy5zdGFja09yZGVyUmV2ZXJzZSA9IHJldmVyc2U7XG5leHBvcnRzLnRpbWVJbnRlcnZhbCA9IG5ld0ludGVydmFsO1xuZXhwb3J0cy50aW1lTWlsbGlzZWNvbmQgPSBtaWxsaXNlY29uZDtcbmV4cG9ydHMudGltZU1pbGxpc2Vjb25kcyA9IG1pbGxpc2Vjb25kcztcbmV4cG9ydHMudXRjTWlsbGlzZWNvbmQgPSBtaWxsaXNlY29uZDtcbmV4cG9ydHMudXRjTWlsbGlzZWNvbmRzID0gbWlsbGlzZWNvbmRzO1xuZXhwb3J0cy50aW1lU2Vjb25kID0gc2Vjb25kO1xuZXhwb3J0cy50aW1lU2Vjb25kcyA9IHNlY29uZHM7XG5leHBvcnRzLnV0Y1NlY29uZCA9IHNlY29uZDtcbmV4cG9ydHMudXRjU2Vjb25kcyA9IHNlY29uZHM7XG5leHBvcnRzLnRpbWVNaW51dGUgPSBtaW51dGU7XG5leHBvcnRzLnRpbWVNaW51dGVzID0gbWludXRlcztcbmV4cG9ydHMudGltZUhvdXIgPSBob3VyO1xuZXhwb3J0cy50aW1lSG91cnMgPSBob3VycztcbmV4cG9ydHMudGltZURheSA9IGRheTtcbmV4cG9ydHMudGltZURheXMgPSBkYXlzO1xuZXhwb3J0cy50aW1lV2VlayA9IHN1bmRheTtcbmV4cG9ydHMudGltZVdlZWtzID0gc3VuZGF5cztcbmV4cG9ydHMudGltZVN1bmRheSA9IHN1bmRheTtcbmV4cG9ydHMudGltZVN1bmRheXMgPSBzdW5kYXlzO1xuZXhwb3J0cy50aW1lTW9uZGF5ID0gbW9uZGF5O1xuZXhwb3J0cy50aW1lTW9uZGF5cyA9IG1vbmRheXM7XG5leHBvcnRzLnRpbWVUdWVzZGF5ID0gdHVlc2RheTtcbmV4cG9ydHMudGltZVR1ZXNkYXlzID0gdHVlc2RheXM7XG5leHBvcnRzLnRpbWVXZWRuZXNkYXkgPSB3ZWRuZXNkYXk7XG5leHBvcnRzLnRpbWVXZWRuZXNkYXlzID0gd2VkbmVzZGF5cztcbmV4cG9ydHMudGltZVRodXJzZGF5ID0gdGh1cnNkYXk7XG5leHBvcnRzLnRpbWVUaHVyc2RheXMgPSB0aHVyc2RheXM7XG5leHBvcnRzLnRpbWVGcmlkYXkgPSBmcmlkYXk7XG5leHBvcnRzLnRpbWVGcmlkYXlzID0gZnJpZGF5cztcbmV4cG9ydHMudGltZVNhdHVyZGF5ID0gc2F0dXJkYXk7XG5leHBvcnRzLnRpbWVTYXR1cmRheXMgPSBzYXR1cmRheXM7XG5leHBvcnRzLnRpbWVNb250aCA9IG1vbnRoO1xuZXhwb3J0cy50aW1lTW9udGhzID0gbW9udGhzO1xuZXhwb3J0cy50aW1lWWVhciA9IHllYXI7XG5leHBvcnRzLnRpbWVZZWFycyA9IHllYXJzO1xuZXhwb3J0cy51dGNNaW51dGUgPSB1dGNNaW51dGU7XG5leHBvcnRzLnV0Y01pbnV0ZXMgPSB1dGNNaW51dGVzO1xuZXhwb3J0cy51dGNIb3VyID0gdXRjSG91cjtcbmV4cG9ydHMudXRjSG91cnMgPSB1dGNIb3VycztcbmV4cG9ydHMudXRjRGF5ID0gdXRjRGF5O1xuZXhwb3J0cy51dGNEYXlzID0gdXRjRGF5cztcbmV4cG9ydHMudXRjV2VlayA9IHV0Y1N1bmRheTtcbmV4cG9ydHMudXRjV2Vla3MgPSB1dGNTdW5kYXlzO1xuZXhwb3J0cy51dGNTdW5kYXkgPSB1dGNTdW5kYXk7XG5leHBvcnRzLnV0Y1N1bmRheXMgPSB1dGNTdW5kYXlzO1xuZXhwb3J0cy51dGNNb25kYXkgPSB1dGNNb25kYXk7XG5leHBvcnRzLnV0Y01vbmRheXMgPSB1dGNNb25kYXlzO1xuZXhwb3J0cy51dGNUdWVzZGF5ID0gdXRjVHVlc2RheTtcbmV4cG9ydHMudXRjVHVlc2RheXMgPSB1dGNUdWVzZGF5cztcbmV4cG9ydHMudXRjV2VkbmVzZGF5ID0gdXRjV2VkbmVzZGF5O1xuZXhwb3J0cy51dGNXZWRuZXNkYXlzID0gdXRjV2VkbmVzZGF5cztcbmV4cG9ydHMudXRjVGh1cnNkYXkgPSB1dGNUaHVyc2RheTtcbmV4cG9ydHMudXRjVGh1cnNkYXlzID0gdXRjVGh1cnNkYXlzO1xuZXhwb3J0cy51dGNGcmlkYXkgPSB1dGNGcmlkYXk7XG5leHBvcnRzLnV0Y0ZyaWRheXMgPSB1dGNGcmlkYXlzO1xuZXhwb3J0cy51dGNTYXR1cmRheSA9IHV0Y1NhdHVyZGF5O1xuZXhwb3J0cy51dGNTYXR1cmRheXMgPSB1dGNTYXR1cmRheXM7XG5leHBvcnRzLnV0Y01vbnRoID0gdXRjTW9udGg7XG5leHBvcnRzLnV0Y01vbnRocyA9IHV0Y01vbnRocztcbmV4cG9ydHMudXRjWWVhciA9IHV0Y1llYXI7XG5leHBvcnRzLnV0Y1llYXJzID0gdXRjWWVhcnM7XG5leHBvcnRzLnRpbWVGb3JtYXREZWZhdWx0TG9jYWxlID0gZGVmYXVsdExvY2FsZSQxO1xuZXhwb3J0cy50aW1lRm9ybWF0TG9jYWxlID0gZm9ybWF0TG9jYWxlJDE7XG5leHBvcnRzLmlzb0Zvcm1hdCA9IGZvcm1hdElzbztcbmV4cG9ydHMuaXNvUGFyc2UgPSBwYXJzZUlzbztcbmV4cG9ydHMubm93ID0gbm93O1xuZXhwb3J0cy50aW1lciA9IHRpbWVyO1xuZXhwb3J0cy50aW1lckZsdXNoID0gdGltZXJGbHVzaDtcbmV4cG9ydHMudGltZW91dCA9IHRpbWVvdXQkMTtcbmV4cG9ydHMuaW50ZXJ2YWwgPSBpbnRlcnZhbCQxO1xuZXhwb3J0cy50cmFuc2l0aW9uID0gdHJhbnNpdGlvbjtcbmV4cG9ydHMuYWN0aXZlID0gYWN0aXZlO1xuZXhwb3J0cy5pbnRlcnJ1cHQgPSBpbnRlcnJ1cHQ7XG5leHBvcnRzLnZvcm9ub2kgPSB2b3Jvbm9pO1xuZXhwb3J0cy56b29tID0gem9vbTtcbmV4cG9ydHMuem9vbVRyYW5zZm9ybSA9IHRyYW5zZm9ybSQxO1xuZXhwb3J0cy56b29tSWRlbnRpdHkgPSBpZGVudGl0eSQ4O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG59KSkpO1xuIiwiLy8gQ29weXJpZ2h0IMKpIDIwMTYgUlRFIFLDqXNlYXUgZGUgdHJhbnNwb3J0IGTigJnDqWxlY3RyaWNpdMOpXHJcbihmdW5jdGlvbigpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIHZhciBkMyA9IHJlcXVpcmUoXCJkM1wiKTtcclxuICB2YXIgQ2hhcnQgPSByZXF1aXJlKFwiLi9jaGFydC5qc1wiKTtcclxuXHJcbiAgbW9kdWxlLmV4cG9ydHMgPSBCYXJjaGFydDtcclxuXHJcbiAgLy8gQmFyY2hhcnQgaW5oZXJpdHMgZnJvbSBDaGFydFxyXG4gIEJhcmNoYXJ0LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ2hhcnQucHJvdG90eXBlKTtcclxuICBCYXJjaGFydC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBCYXJjaGFydDtcclxuXHJcbiAgLyoqXHJcbiAgICAqIEBjbGFzcyBCYXJjaGFydFxyXG4gICAgKiBAc3VtbWFyeSBSZXByZXNlbnQgZGF0YSB3aXRoIGEgYmFyY2hhcnRcclxuICAgICogQGRlc2MgQmFyY2hhcnRzIGFyZSBwb2x5dmFsZW50IGNoYXJ0cyB0aGF0IHNob3VsZCBiZSB1c2VkIG1vc3Qgb2YgdGhlIHRpbWUuXHJcbiAgICAqIEluIGEgYmFyY2hhcnQgaW5kaXZpZHVhbCB2YWx1ZSBhcmUgdmlzdWFsbHkgZWFzeSB0byBjb21wYXJlIGJlY2F1c2UgdGhlXHJcbiAgICAqIGh1bWFuIGV5ZSBpcyBnb29kIGF0IGNvbXBhcmluZyBsZW5ndGhzLiBNb3Jlb3ZlciBiYXJjaGFydHMgY2FuIHJlcHJlc2VudFxyXG4gICAgKiBuZWdhdGl2ZSB2YWx1ZXMgd2hpbGUgcG9sYXIgY2hhcnRzIGNhbiBvbmx5IHJlcHJlc2VudCBwb3NpdGl2ZSB2YWx1ZXM7IFxyXG4gICAgKiBAcGFyYW0ge3N0cmluZ30gZWwgQ1NTIHNlbGVjdG9yIHJlcHJlc2VudGluZyB0aGUgZWxlbWVudCB0aGF0IHdpbGwgaG9sZCB0aGUgY2hhcnQuXHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyW119IGRhdGEgRGF0YSB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cclxuICAgICogQHBhcmFtIHtCYXJjaGFydE9wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyBjb250cm9saW5nIGdyYXBoaWNhbCBhc3BlY3RzIG9mIHRoZSBjaGFydC5cclxuICAgICovXHJcblxyXG4gIC8qKiBAdHlwZWRlZiB7b2JqZWN0fSBCYXJjaGFydE9wdGlvbnNcclxuICAgICogQG1lbWJlck9mIEJhcmNoYXJ0XHJcbiAgICAqIEBwcm9wIHtudW1iZXJ8XCJhdXRvXCJ9IFttaW5WYWx1ZT1cImF1dG9cIl0gTWluaW11bSB2YWx1ZSBkYXRhIGNvdWxkIHRha2UuIEl0XHJcbiAgICAqIGlzIGltcG9ydGFudCB0byBzZXQgdGhpcyBvcHRpb24gZXhwbGljaXRlbHkgaWYgb25lIHdhbnRzIHRvIGNvbXBhcmVcclxuICAgICogY2hhcnRzIGFuZCB1c2UgdGhlIHNhbWUgc2NhbGUgb24gZWFjaCBvbmUuIEJ5IGRlZmF1bHQgYG1pblZhbHVlYCBlcXVhbHMgdG8gMFxyXG4gICAgKiBpZiBhbGwgZGF0YSB2YWx1ZXMgYXJlIHBvc2l0aXZlIG9yIHRoZSBtaW5pbXVtIHZhbHVlIGlmIHNvbWUgdmFsdWVzIGFyZVxyXG4gICAgKiBuZWdhdGl2ZS5cclxuICAgICogQHByb3Age251bWJlcnxcImF1dG9cIn0gW21heFZhbHVlPVwiYXV0b1wiXSBNYXhpbXVtIHZhbHVlIGRhdGEgY291bGQgdGFrZS5JdFxyXG4gICAgKiBpcyBpbXBvcnRhbnQgdG8gc2V0IHRoaXMgb3B0aW9uIGV4cGxpY2l0ZWx5IGlmIG9uZSB3YW50cyB0byBjb21wYXJlXHJcbiAgICAqIGNoYXJ0cyBhbmQgdXNlIHRoZSBzYW1lIHNjYWxlIG9uIGVhY2ggb25lLiBCeSBkZWZhdWx0IGl0IGVxdWFscyB0byAwIGlmIGFsbFxyXG4gICAgKiB2YWx1ZXMgYXJlIG5lZ2F0aXZlIG9yIHRvIG1heGltbXVtIHZhbHVlIGlmIHNvbWUgdmFsdWUgaXMgcG9zaXRpdmUuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9IFt3aWR0aD02MF0gV2lkdGggb2YgdGhlIGNoYXJ0LlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbaGVpZ2h0PTYwXSBIZWlnaHQgb2YgdGhlIGNoYXJ0LlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbdHJhbnNpdGlvblRpbWU9NzUwXSBEdXJhdGlvbiBvZiB0aGUgdHJhbnNpdGlvbnMsIGluIG1pbGxpc2Vjb25kcy5cclxuICAgICogQHByb3Age3N0cmluZ1tdfGZ1bmN0aW9ufVtjb2xvcnM9ZDMuc2NoZW1lQ2F0ZWdvcnkxMF0gRWl0aGVyIGFuIGFycmF5IG9mXHJcbiAgICAqIGNvbG9ycyBvciBhIGZ1bmN0aW9uIGAoZCwgaSkgLT4gY29sb3JgIHdoZXJlIGBkYCBpcyBhIGRhdGEgdmFsdWUgYW5kIGBpYFxyXG4gICAgKiBpcyB0aGUgaW5kZXggb2YgdGhlIHZhbHVlLklmIGl0IGlzIGFuIGFycmF5IHdpdGggbGVuZ3RoIGxlc3MgdGhhbiB0aGUgbGVuZ3RoXHJcbiAgICAqIG9mIGRhdGEsIHRoZW4gdGhlIGNvbG9ycyBhcmUgcmVjeWNsZWQuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmdbXXxcIm5vbmVcInxcImF1dG9cInxmdW5jdGlvbn1bbGFiZWxzPVwibm9uZVwiXSBMYWJlbHMgdG8gZGlzcGxheSBpbiBiYXJzLlxyXG4gICAgKiBJdCBjYW4gYmUgYW4gYXJyYXkgd2l0aCBzYW1lIGxlbmd0aCBhcyB0aGUgZGF0YS4gSXQgY2FuIGFsc28gYmUgYSBmdW5jdGlvblxyXG4gICAgKiBgKGQsIGkpIC0+IGxhYmVsVGV4dGAgd2hlcmUgYGRgIGlzIGEgZGF0YSB2YWx1ZSBhbmQgYGlgXHJcbiAgICAqIGlzIHRoZSBpbmRleCBvZiB0aGUgdmFsdWUuIEZpbmFsbHkgaXQgY2FuIGJlIGVxdWFsIHRvIFwibm9uZVwiIHRvIGhpZGUgbGFiZWxzXHJcbiAgICAqIG9yIFwiYXV0b1wiIHRvIGRpc3BsYXkgaW4gYSBjb21wYWN0IHdheSB2YWx1ZXMuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmd8c3RyaW5nW118XCJhdXRvXCJ8ZnVuY3Rpb259W2xhYmVsQ29sb3JzPVwiYXV0b1wiXSBDb2xvciBvZiB0aGUgbGFiZWxzLlxyXG4gICAgKiBJdCBjYW4gYmUgYSBzaW5nbGUgdmFsdWUgb3IgYW4gYXJyYXkgd2l0aCBzYW1lIGxlbmd0aCBhcyB0aGUgZGF0YS4gSXQgY2FuXHJcbiAgICAqIGFsc28gYmUgYSBmdW5jdGlvbiBgKGQsIGkpIC0+IGNvbG9yYCB3aGVyZSBgZGAgaXMgYSBkYXRhIHZhbHVlIGFuZCBgaWBcclxuICAgICogaXMgdGhlIGluZGV4IG9mIHRoZSB2YWx1ZS4gRmluYWxseSBpdCBjYW4gYmUgZXF1YWwgdG8gXCJhdXRvXCIuIEluIHRoaXMgY2FzZSxcclxuICAgICogdGhlIG1vc3QgcmVhZGFibGUgY29sb3IgaXMgY2hvb3NlbiBkZXBkaW5nIG9uIHRoZSBjb2xvciBvZiB0aGUgYmFyLlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfVtsYWJlbE1pblNpemU9OF0gTGFiZWwgbWluaW11bSBzaXplIGluIHBpeGVscy4gSWYgdGhlcmUgaXNcclxuICAgICogbm90IGVub3VnaCBzcGFjZSBmb3IgYSBnaXZlbiBsYWJlbCwgdGhlbiBpdCBpcyBoaWRkZW4uXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9W2xhYmVsTWF4U2l6ZT0yNF0gTGFiZWwgbWF4aW11bSBzaXplIGluIHBpeGVscy5cclxuICAgICogQHByb3Age251bWJlcn1bbGFiZWxQYWRkaW5nPTJdIFBhZGRpbmcgdG8gYXBwbHkgdG8gYXBwbHkgdG8gbGFiZWxzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfVtsYWJlbENsYXNzPVwiXCJdIExhYmVscyBDU1MgY2xhc3MuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmd9W3NoYXBlQ2xhc3M9XCJcIl0gYmFycyBDU1MgY2xhc3MuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmd9W3plcm9MaW5lU3R5bGU9XCJzdHJva2U6IzMzMztzdHJva2Utd2lkdGg6MTtcIl0gQ1NTIHN0eWxlIG9mIHRoZVxyXG4gICAgKiBsaW5lIHJlcHJlc2VudGluZyB0aGUgemVybyB2YWx1ZS5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHNldERhdGFcclxuICAgICogQGRlc2MgVXBkYXRlIHRoZSBkYXRhIHJlcHJlc2VudGVkIGJ5IHRoZSBjaGFydFxyXG4gICAgKiBAaW5zdGFuY2VcclxuICAgICogQG1lbWJlck9mIEJhcmNoYXJ0XHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyW119IGRhdGEgRGF0YSB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHNldE9wdGlvbnNcclxuICAgICogQGRlc2MgVXBkYXRlIHRoZSBncmFwaGljYWwgb3B0aW9ucyBvZiBhIGNoYXJ0XHJcbiAgICAqIEBpbnN0YW5jZVxyXG4gICAgKiBAbWVtYmVyT2YgQmFyY2hhcnRcclxuICAgICogQHBhcmFtIHtCYXJjaGFydE9wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyBjb250cm9saW5nIGdyYXBoaWNhbCBhc3BlY3RzIG9mIHRoZSBjaGFydC5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHVwZGF0ZVxyXG4gICAgKiBAZGVzYyBVcGRhdGUgc2ltdWxhdGVub3VzbHkgZGF0YSBhbmQgb3B0aW9ucyBvZiBhIGJhcmNoYXJ0LlxyXG4gICAgKiBAaW5zdGFuY2VcclxuICAgICogQG1lbWJlck9mIEJhcmNoYXJ0XHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyW119IGRhdGEgRGF0YSB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cclxuICAgICogQHBhcmFtIHtCYXJjaGFydE9wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyBjb250cm9saW5nIGdyYXBoaWNhbCBhc3BlY3RzIG9mIHRoZSBjaGFydC5cclxuICAgICovXHJcbiAgZnVuY3Rpb24gQmFyY2hhcnQoZWwsIGRhdGEsIG9wdGlvbnMpIHtcclxuICAgIC8vIERlZmF1bHQgb3B0aW9uc1xyXG4gICAgdmFyIGRlZmF1bHRzID0ge1xyXG4gICAgICBtaW5WYWx1ZTogXCJhdXRvXCIsXHJcbiAgICAgIG1heFZhbHVlOiBcImF1dG9cIixcclxuICAgICAgemVyb0xpbmVTdHlsZTogXCJzdHJva2U6IzMzMztzdHJva2Utd2lkdGg6MTtcIlxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBDYWxsIHN1cGVyIGNvbnN0cnVjdG9yXHJcbiAgICBDaGFydC5jYWxsKHRoaXMsIGVsLCBkYXRhLCBvcHRpb25zLCBkZWZhdWx0cyk7XHJcblxyXG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgemVybyBsaW5lXHJcbiAgICB2YXIgc2NhbGVGdW4gPSBkMy5zY2FsZUxpbmVhcigpXHJcbiAgICAgIC5kb21haW4oW3RoaXMuX29wdGlvbnMubWluVmFsdWUsIHRoaXMuX29wdGlvbnMubWF4VmFsdWVdKVxyXG4gICAgICAucmFuZ2UoW3RoaXMuX29wdGlvbnMuaGVpZ2h0LCAwXSk7XHJcblxyXG4gICAgdGhpcy5femVyb0xpbmUgPSB0aGlzLl9jb250YWluZXIuYXBwZW5kKFwibGluZVwiKVxyXG4gICAgICAuYXR0cihcIngxXCIsIDApXHJcbiAgICAgIC5hdHRyKFwieTFcIiwgc2NhbGVGdW4oMCkpXHJcbiAgICAgIC5hdHRyKFwieDJcIiwgdGhpcy5fb3B0aW9ucy53aWR0aClcclxuICAgICAgLmF0dHIoXCJ5MlwiLCBzY2FsZUZ1bigwKSlcclxuICAgICAgLmF0dHIoXCJzdHlsZVwiLCB0aGlzLl9vcHRpb25zLnplcm9MaW5lU3R5bGUpO1xyXG5cclxuICAgIHRoaXMuX2RyYXcoKTtcclxuICB9XHJcblxyXG4gIC8vIFNlZSBjb21tZW50cyBpbiBjaGFydC5qc1xyXG4gIEJhcmNoYXJ0LnByb3RvdHlwZS5fcHJvY2Vzc09wdGlvbnMgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgICBvcHRpb25zID0gQ2hhcnQucHJvdG90eXBlLl9wcm9jZXNzT3B0aW9ucy5jYWxsKHRoaXMsIG9wdGlvbnMsIHRoaXMuX29wdGlvbnMpO1xyXG5cclxuICAgIC8vIFNldCBtaW4gdmFsdWUgYW5kIG1heCB2YWx1ZSBpZiBuZWNlc3NhcnkuXHJcbiAgICBpZiAob3B0aW9ucy5taW5WYWx1ZSA9PT0gXCJhdXRvXCIpIHtcclxuICAgICAgdmFyIG1pbiA9IGQzLm1pbih0aGlzLl9kYXRhKTtcclxuICAgICAgdmFyIG1heCA9IG9wdGlvbnMubWF4VmFsdWUgPT09IFwiYXV0b1wiPyBkMy5tYXgodGhpcy5fZGF0YSk6IG9wdGlvbnMubWF4VmFsdWU7XHJcblxyXG4gICAgICBpZiAobWF4ID4gMCAmJiBtaW4gPiAwKSBvcHRpb25zLm1pblZhbHVlID0gMDtcclxuICAgICAgZWxzZSBvcHRpb25zLm1pblZhbHVlID0gbWluO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChvcHRpb25zLm1heFZhbHVlID09PSBcImF1dG9cIikge1xyXG4gICAgICB2YXIgbWF4ID0gb3B0aW9ucy5taW5WYWx1ZSA9PT0gXCJhdXRvXCI/IGQzLm1pbih0aGlzLl9kYXRhKTogb3B0aW9ucy5taW5WYWx1ZTtcclxuICAgICAgdmFyIG1heCA9IGQzLm1heCh0aGlzLl9kYXRhKTtcclxuXHJcbiAgICAgIGlmIChtYXggPCAwICYmIG1pbiA8IDApIG9wdGlvbnMubWF4VmFsdWUgPSAwO1xyXG4gICAgICBlbHNlIG9wdGlvbnMubWF4VmFsdWUgPSBtYXg7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG9wdGlvbnM7XHJcbiAgfTtcclxuXHJcbiAgLy8gU2VlIGNvbW1lbnRzIGluIGNoYXJ0LmpzXHJcbiAgQmFyY2hhcnQucHJvdG90eXBlLl9kcmF3ID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICBDaGFydC5wcm90b3R5cGUuX2RyYXcuY2FsbCh0aGlzKTtcclxuXHJcbiAgICB2YXIgYmFyV2lkdGggPSAoc2VsZi5fb3B0aW9ucy53aWR0aCAtIDYpIC8gc2VsZi5fZGF0YS5sZW5ndGg7XHJcbiAgICB2YXIgc2NhbGVGdW4gPSBkMy5zY2FsZUxpbmVhcigpXHJcbiAgICAgIC5kb21haW4oW3NlbGYuX29wdGlvbnMubWluVmFsdWUsIHNlbGYuX29wdGlvbnMubWF4VmFsdWVdKVxyXG4gICAgICAucmFuZ2UoW3NlbGYuX29wdGlvbnMuaGVpZ2h0LCAwXSk7XHJcblxyXG4gICAgLy8gVXBkYXRlIHRoZSB6ZXJvIGxpbmVcclxuICAgIHNlbGYuX3plcm9MaW5lXHJcbiAgICAgIC50cmFuc2l0aW9uKClcclxuICAgICAgLmR1cmF0aW9uKHNlbGYuX29wdGlvbnMudHJhbnNpdGlvblRpbWUpXHJcbiAgICAgIC5hdHRyKFwieDFcIiwgMClcclxuICAgICAgLmF0dHIoXCJ5MVwiLCBzY2FsZUZ1bigwKSlcclxuICAgICAgLmF0dHIoXCJ4MlwiLCBzZWxmLl9vcHRpb25zLndpZHRoKVxyXG4gICAgICAuYXR0cihcInkyXCIsIHNjYWxlRnVuKDApKVxyXG4gICAgICAuYXR0cihcInN0eWxlXCIsIHNlbGYuX29wdGlvbnMuemVyb0xpbmVTdHlsZSk7XHJcblxyXG4gICAgLy8gVXBkYXRlIGJhcnNcclxuICAgIHZhciBiYXIgPSBzZWxmLl9jaGFydC5zZWxlY3RBbGwoXCJwYXRoXCIpLmRhdGEoc2VsZi5fZGF0YSk7XHJcbiAgICAvLyBBZGQgbmV3IGJhcnNcclxuICAgIGZ1bmN0aW9uIHJlY3RQYXRoKHgsIHksIHcsIGgpIHtcclxuICAgICAgcmV0dXJuIChcIk1cIiArIHggKyBcIiBcIiArIHkgKyBcImxcIiArIHcgKyBcIiAwbDAgXCIgKyBoICsgXCJsXCIgKyAoLXcpICsgXCIgMFpcIilcclxuICAgIH1cclxuXHJcbiAgICBiYXIuZW50ZXIoKVxyXG4gICAgICAuYXBwZW5kKFwicGF0aFwiKVxyXG4gICAgICAuYXR0cihcImRcIiwgZnVuY3Rpb24oZCwgaSkge3JldHVybiByZWN0UGF0aCgoaSArIDEpICogYmFyV2lkdGggKyAzLCBzY2FsZUZ1bigwKSwgMCwgMCl9KVxyXG4gICAgLy8gVXBkYXRlIGJhcnNcclxuICAgICAgLm1lcmdlKGJhcilcclxuICAgICAgLmF0dHIoXCJjbGFzc1wiLCBzZWxmLl9vcHRpb25zLnNoYXBlQ2xhc3MpXHJcbiAgICAgIC50cmFuc2l0aW9uKClcclxuICAgICAgLmR1cmF0aW9uKHNlbGYuX29wdGlvbnMudHJhbnNpdGlvblRpbWUpXHJcbiAgICAgIC5hdHRyKFwiZFwiLCBmdW5jdGlvbihkLCBpKSB7cmV0dXJuIHJlY3RQYXRoKGkgKiBiYXJXaWR0aCArIDMsIHNjYWxlRnVuKDApLCBiYXJXaWR0aCwgc2NhbGVGdW4oZCkgLSBzY2FsZUZ1bigwKSl9KVxyXG4gICAgICAuYXR0cihcImZpbGxcIiwgc2VsZi5fb3B0aW9ucy5jb2xvckZ1bik7XHJcbiAgICAvLyBSZW1vdmUgYmFyc1xyXG4gICAgYmFyLmV4aXQoKVxyXG4gICAgICAudHJhbnNpdGlvbigpXHJcbiAgICAgIC5kdXJhdGlvbihzZWxmLl9vcHRpb25zLnRyYW5zaXRpb25UaW1lKVxyXG4gICAgICAuYXR0cihcInhcIiwgZnVuY3Rpb24oZCwgaSkge3JldHVybiBpICogYmFyV2lkdGggKyAzO30pXHJcbiAgICAgIC5hdHRyKFwieVwiLCAwKVxyXG4gICAgICAuYXR0cihcIndpZHRoXCIsIDApXHJcbiAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIDApXHJcbiAgICAgIC5yZW1vdmUoKTtcclxuXHJcbiAgICAvLyBBZGQvIHVwZGF0ZSBsYWJlbHNcclxuICAgIGZ1bmN0aW9uIGluaXRMYWJlbChsYWJlbCwgZCwgaSkge1xyXG4gICAgICBsYWJlbC5maWxsUmVjdChcclxuICAgICAgICBpICogYmFyV2lkdGggKyAzLCBzY2FsZUZ1bigwKSxcclxuICAgICAgICBiYXJXaWR0aCwgMCxcclxuICAgICAgICBzZWxmLl9vcHRpb25zLmxhYmVsUGFkZGluZyxcclxuICAgICAgICBcImNlbnRlclwiLCBkID49IDA/IFwidG9wXCI6IFwiYm90dG9tXCIsXHJcbiAgICAgICAgMFxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHVwZGF0ZUxhYmVsKGxhYmVsLCBkLCBpKSB7XHJcbiAgICAgIGxhYmVsLmZpbGxSZWN0KFxyXG4gICAgICAgIGkgKiBiYXJXaWR0aCArIDMsIGQgPj0gMD8gc2NhbGVGdW4oZCkgOiBzY2FsZUZ1bigwKSxcclxuICAgICAgICBiYXJXaWR0aCwgTWF0aC5hYnMoc2NhbGVGdW4oZCkgLSBzY2FsZUZ1bigwKSksXHJcbiAgICAgICAgc2VsZi5fb3B0aW9ucy5sYWJlbFBhZGRpbmcsXHJcbiAgICAgICAgXCJjZW50ZXJcIiwgZCA+PSAwPyBcInRvcFwiOiBcImJvdHRvbVwiLFxyXG4gICAgICAgIHNlbGYuX29wdGlvbnMudHJhbnNpdGlvblRpbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2RyYXdMYWJlbHMoaW5pdExhYmVsLCB1cGRhdGVMYWJlbCk7XHJcbiAgfVxyXG5cclxufSgpKTtcclxuIiwiLy8gQ29weXJpZ2h0IMKpIDIwMTYgUlRFIFLDqXNlYXUgZGUgdHJhbnNwb3J0IGTigJnDqWxlY3RyaWNpdMOpXHJcbihmdW5jdGlvbigpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIHZhciBkMyA9IHJlcXVpcmUoXCJkM1wiKTtcclxuICB2YXIgdGlueWNvbG9yID0gcmVxdWlyZShcInRpbnljb2xvcjJcIik7XHJcbiAgdmFyIHV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHMuanNcIik7XHJcbiAgdmFyIExhYmVsID0gcmVxdWlyZShcIi4vbGFiZWwuanNcIilcclxuXHJcbiAgbW9kdWxlLmV4cG9ydHMgPSBDaGFydDtcclxuXHJcbiAgLyogIEBjbGFzcyBDaGFydFxyXG4gICAgKiBBYnN0cmFjdCBjbGFzcyBpbmhlcml0ZWQgYnkgb3RoZXIgY2xhc3Nlc1xyXG4gICAgKiBAcGFyYW17c3RyaW5nfSBlbFxyXG4gICAgKiBAcGFyYW17bnVtYmVyW119IGRhdGFcclxuICAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcclxuICAgICogQHBhcmFtIHtvYmplY3R9IGRlZmF1bHRzXHJcbiAgICAqXHJcbiAgICAqL1xyXG4gIGZ1bmN0aW9uIENoYXJ0KGVsLCBkYXRhLCBvcHRpb25zLCBkZWZhdWx0cykge1xyXG4gICAgdGhpcy5fZGF0YSA9IGRhdGE7XHJcblxyXG4gICAgLy8gTWVyZ2Ugb3B0aW9ucyB3aXRoIGRlZmF1bHQgb3B0aW9ucyBvZiB0aGlzIGNsYXNzIGFuZCBvZiB0aGUgY2hpbGQgY2xhc3NcclxuICAgIC8qKlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbaGVpZ2h0PTYwXSB3aWR0aFxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbd2lkdGg9NjBdIGhlaWdodFxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbdHJhbnNpdGlvblRpbWU9NzUwXSB0cmFuc2l0aW9uVGltZVxyXG4gICAgKiBAcHJvcCB7c3RyaW5nW118ZnVuY3Rpb259IFtjb2xvcnM9ZDMuc2NoZW1lQ2F0ZWdvcnkxMF0gY29sb3JzXHJcbiAgICAqIEBwcm9wIHtzdHJpbmdbXXxcIm5vbmVcInxcImF1dG9cInxmdW5jdGlvbn0gW2xhYmVscz1cIm5vbmVcIl0gbGFiZWxzXHJcbiAgICAqIEBwcm9wIHtzdHJpbmdbXXxcImF1dG9cInxmdW5jdGlvbn0gW2xhYmVsQ29sb3JzPVwiYXV0b1wiXSBsYWJlbENvbG9yc1xyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbbGFiZWxNaW5TaXplPThdIGxhYmVsTWluU2l6ZVxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbbGFiZWxNYXhTaXplPTI0XSBsYWJlbE1heFNpemVcclxuICAgICogQHByb3Age251bWJlcn0gW2xhYmVsUGFkZGluZz0yXSBsYWJlbFBhZGRpbmdcclxuICAgICogQHByb3Age2xhYmVsQ2xhc3N9IFtsYWJlbENsYXNzPVwiXCJdbGFiZWxDbGFzc1xyXG4gICAgKiBAcHJvcCB7c2hhcGVDbGFzc30gW3NoYXBlQ2xhc3M9XCJcIl0gc2hhcGVDbGFzc1xyXG4gICAgKi9cclxuICAgIHRoaXMuX29wdGlvbnMgPSB7XHJcbiAgICAgIHdpZHRoOjYwLFxyXG4gICAgICBoZWlnaHQ6IDYwLFxyXG4gICAgICB0cmFuc2l0aW9uVGltZTogNzUwLFxyXG4gICAgICBjb2xvcnM6IGQzLnNjaGVtZUNhdGVnb3J5MTAsXHJcbiAgICAgIGxhYmVsczogXCJub25lXCIsXHJcbiAgICAgIGxhYmVsQ29sb3JzOiBcImF1dG9cIixcclxuICAgICAgbGFiZWxNaW5TaXplOiA4LFxyXG4gICAgICBsYWJlbE1heFNpemU6IDI0LFxyXG4gICAgICBsYWJlbFBhZGRpbmc6IDIsXHJcbiAgICAgIGxhYmVsQ2xhc3M6IFwiXCIsXHJcbiAgICAgIHNoYXBlQ2xhc3M6IFwiXCJcclxuICAgIH07XHJcbiAgICB0aGlzLl9vcHRpb25zID0gdXRpbHMubWVyZ2VPcHRpb25zKHRoaXMuX29wdGlvbnMsIGRlZmF1bHRzIHx8IHt9KTtcclxuICAgIHRoaXMuX29wdGlvbnMgPSB0aGlzLl9wcm9jZXNzT3B0aW9ucyhvcHRpb25zKTtcclxuXHJcbiAgICAvLyBSZW1vdmUgZXZlcnl0aGluZyBpbiB0aGUgY29udGFpbmVyIGFuZCBjcmVhdGUgcmVxdWlyZWQgZWxlbWVudHNcclxuICAgIGQzLnNlbGVjdChlbCkuc2VsZWN0KFwiKlwiKS5yZW1vdmUoKTtcclxuICAgIHRoaXMuX2NvbnRhaW5lciA9IGQzLnNlbGVjdChlbCkuYXBwZW5kKFwic3ZnXCIpXHJcbiAgICAgIC5hdHRyKFwid2lkdGhcIiwgdGhpcy5fb3B0aW9ucy53aWR0aClcclxuICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgdGhpcy5fb3B0aW9ucy5oZWlnaHQpO1xyXG4gICAgdGhpcy5fY2hhcnQgPSB0aGlzLl9jb250YWluZXIuYXBwZW5kKFwiZ1wiKTtcclxuICB9XHJcblxyXG4gIC8qICBVcGRhdGUgZGF0YSBhbmQgb3B0aW9ucyBvZiBhIGNoYXJ0XHJcbiAgICAqXHJcbiAgICAqL1xyXG4gIENoYXJ0LnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihkYXRhLCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLl9kYXRhID0gZGF0YTtcclxuICAgIHRoaXMuX29wdGlvbnMgPSB0aGlzLl9wcm9jZXNzT3B0aW9ucyhvcHRpb25zKTtcclxuICAgIHRoaXMuX2RyYXcoKTtcclxuICB9O1xyXG5cclxuICBDaGFydC5wcm90b3R5cGUuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICAgIHRoaXMuX29wdGlvbnMgPSB0aGlzLl9wcm9jZXNzT3B0aW9ucyhvcHRpb25zKTtcclxuICAgIHRoaXMuX2RyYXcoKTtcclxuICB9O1xyXG5cclxuICBDaGFydC5wcm90b3R5cGUuc2V0RGF0YSA9IGZ1bmN0aW9uKGRhdGEpIHtcclxuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xyXG4gICAgdGhpcy5fZHJhdygpO1xyXG4gIH07XHJcblxyXG4gIENoYXJ0LnByb3RvdHlwZS5fZHJhdyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgLy8gVXBkYXRlIGNvbnRhaW5lciBzaXplXHJcbiAgICBzZWxmLl9jb250YWluZXJcclxuICAgICAgLnRyYW5zaXRpb24oKVxyXG4gICAgICAuZHVyYXRpb24oc2VsZi5fb3B0aW9ucy50cmFuc2l0aW9uVGltZSlcclxuICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBzZWxmLl9vcHRpb25zLndpZHRoKVxyXG4gICAgICAuYXR0cihcImhlaWdodFwiLCBzZWxmLl9vcHRpb25zLmhlaWdodCk7XHJcbiAgfTtcclxuXHJcbiAgQ2hhcnQucHJvdG90eXBlLl9wcm9jZXNzT3B0aW9ucyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICAgIG9wdGlvbnMgPSB1dGlscy5tZXJnZU9wdGlvbnMob3B0aW9ucywgdGhpcy5fb3B0aW9ucyk7XHJcblxyXG4gICAgLy8gQ29udmVydCBwYXJhbWV0ZXJzIGNvbG9ycywgbGFiZWxzIGFuZCBsYWJlbENvbG9ycyB0byBmdW5jdGlvbnNcclxuICAgIG9wdGlvbnMuY29sb3JGdW4gPSB1dGlscy50b0Z1bmN0aW9uKG9wdGlvbnMuY29sb3JzKTtcclxuICAgIG9wdGlvbnMubGFiZWxDbGFzcyA9IHV0aWxzLnRvRnVuY3Rpb24ob3B0aW9ucy5sYWJlbENsYXNzKTtcclxuICAgIG9wdGlvbnMuc2hhcGVDbGFzcyA9IHV0aWxzLnRvRnVuY3Rpb24ob3B0aW9ucy5zaGFwZUNsYXNzKTtcclxuXHJcbiAgICBpZiAob3B0aW9ucy5sYWJlbHMgPT09IFwibm9uZVwiKSB7XHJcbiAgICAgIG9wdGlvbnMubGFiZWxUZXh0ID0gbnVsbDtcclxuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5sYWJlbHMgPT09IFwiYXV0b1wiKSB7XHJcbiAgICAgIG9wdGlvbnMubGFiZWxUZXh0ID0gdXRpbHMucHJldHR5TnVtYmVyO1xyXG4gICAgfSAgZWxzZSB7XHJcbiAgICAgIG9wdGlvbnMubGFiZWxUZXh0ID0gdXRpbHMudG9GdW5jdGlvbihvcHRpb25zLmxhYmVscyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG9wdGlvbnMubGFiZWxDb2xvcnMgPT09IFwiYXV0b1wiKSB7XHJcbiAgICAgIG9wdGlvbnMubGFiZWxDb2xvckZ1biA9IGZ1bmN0aW9uKGQsIGkpIHtcclxuICAgICAgICByZXR1cm4gdGlueWNvbG9yLm1vc3RSZWFkYWJsZShvcHRpb25zLmNvbG9yRnVuKGQsIGkpLCBbXCJ3aGl0ZVwiLCBcImJsYWNrXCJdKS5fb3JpZ2luYWxJbnB1dFxyXG4gICAgICB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgb3B0aW9ucy5sYWJlbENvbG9yRnVuID0gdXRpbHMudG9GdW5jdGlvbihvcHRpb25zLmxhYmVsQ29sb3JGdW4pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBvcHRpb25zO1xyXG4gIH1cclxuXHJcbiAgQ2hhcnQucHJvdG90eXBlLl9kcmF3TGFiZWxzID0gZnVuY3Rpb24oaW5pdEZ1biwgdXBkYXRlRnVuKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgaWYgKHNlbGYuX29wdGlvbnMubGFiZWxzID09PSBcIm5vbmVcIikge1xyXG4gICAgICBzZWxmLl9jaGFydC5zZWxlY3RBbGwoXCIubGFiZWxzLWNvbnRhaW5lclwiKS5yZW1vdmUoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBzZWxmLl9sYWJlbHMgPSBzZWxmLl9jaGFydC5zZWxlY3RBbGwoXCIubGFiZWxzLWNvbnRhaW5lclwiKS5kYXRhKHNlbGYuX2RhdGEpO1xyXG4gICAgc2VsZi5fbGFiZWxzLmVudGVyKClcclxuICAgICAgLmFwcGVuZChcImdcIilcclxuICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcImxhYmVscy1jb250YWluZXJcIilcclxuICAgICAgLmVhY2goZnVuY3Rpb24oZCwgaSkge1xyXG4gICAgICAgIHRoaXMuX2xhYmVsID0gbmV3IExhYmVsKHRoaXMsIHNlbGYuX29wdGlvbnMubGFiZWxTdHlsZSwgc2VsZi5fb3B0aW9ucy5sYWJlbENvbG9yRnVuKGQsIGkpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX29wdGlvbnMubGFiZWxNaW5TaXplLCBzZWxmLl9vcHRpb25zLmxhYmVsTWF4U2l6ZSk7XHJcbiAgICAgICAgdGhpcy5fbGFiZWwudXBkYXRlVGV4dChzZWxmLl9vcHRpb25zLmxhYmVsVGV4dChkLCBpKSlcclxuICAgICAgICBpbml0RnVuKHRoaXMuX2xhYmVsLCBkLCBpKTtcclxuICAgICAgfSlcclxuXHJcbiAgICAgIC5tZXJnZShzZWxmLl9sYWJlbHMpXHJcbiAgICAgIC5lYWNoKGZ1bmN0aW9uKGQsIGkpIHtcclxuICAgICAgICB0aGlzLl9sYWJlbC51cGRhdGVUZXh0KHNlbGYuX29wdGlvbnMubGFiZWxUZXh0KGQsIGkpKTtcclxuICAgICAgICB0aGlzLl9sYWJlbC5fdGV4dFxyXG4gICAgICAgICAgLmF0dHIoXCJmaWxsXCIsIHNlbGYuX29wdGlvbnMubGFiZWxDb2xvckZ1bihkLCBpKSlcclxuICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgc2VsZi5fb3B0aW9ucy5sYWJlbENsYXNzKGQsIGkpKTtcclxuICAgICAgICB1cGRhdGVGdW4odGhpcy5fbGFiZWwsIGQsIGkpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICBzZWxmLl9sYWJlbHMuZXhpdCgpLnJlbW92ZSgpO1xyXG4gIH1cclxuXHJcbn0oKSk7XHJcbiIsIi8vIENvcHlyaWdodCDCqSAyMDE2IFJURSBSw6lzZWF1IGRlIHRyYW5zcG9ydCBk4oCZw6lsZWN0cmljaXTDqVxyXG4oZnVuY3Rpb24oKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICBtb2R1bGUuZXhwb3J0cy5Qb2ludCA9IFBvaW50O1xyXG4gIG1vZHVsZS5leHBvcnRzLkxpbmUgPSBMaW5lO1xyXG4gIG1vZHVsZS5leHBvcnRzLmludGVyc2VjdGlvbk9mVHdvTGluZXMgPSBpbnRlcnNlY3Rpb25PZlR3b0xpbmVzO1xyXG4gIG1vZHVsZS5leHBvcnRzLmludGVyc2VjdGlvbkxpbmVBbmRDaXJjbGUgPSBpbnRlcnNlY3Rpb25MaW5lQW5kQ2lyY2xlO1xyXG4gIG1vZHVsZS5leHBvcnRzLnBvaW50SW5TZWdtZW50ID0gcG9pbnRJblNlZ21lbnQ7XHJcbiAgbW9kdWxlLmV4cG9ydHMuaW50ZXJzZWN0aW9uTGluZVJhZGl1cyAgPSBpbnRlcnNlY3Rpb25MaW5lUmFkaXVzIDtcclxuICBtb2R1bGUuZXhwb3J0cy5kaXN0YW5jZSA9IGRpc3RhbmNlO1xyXG5cclxuICBmdW5jdGlvbiBQb2ludCh4LCB5KSB7XHJcbiAgICB0aGlzLnggPSB4O1xyXG4gICAgdGhpcy55ID0geTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIExpbmUoYSwgYikge1xyXG4gICAgdGhpcy5hID0gYTtcclxuICAgIHRoaXMuYiA9IGJcclxuICB9XHJcbiAgTGluZS5wcm90b3R5cGUuZ2V0WSA9IGZ1bmN0aW9uKHgpIHtcclxuICAgIHJldHVybiB0aGlzLmEgKyB0aGlzLmIgKiB4O1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gaW50ZXJzZWN0aW9uT2ZUd29MaW5lcyhsMSwgbDIpIHtcclxuICAgIGlmIChsMS5iID09IGwyLmIpIHJldHVybiBbXVxyXG4gICAgcmV0dXJuIFtuZXcgUG9pbnQoXHJcbiAgICAgIChsMi5hIC0gbDEuYSkgLyAobDEuYiAtIGwyLmIpLFxyXG4gICAgICAobDEuYiAqIGwyLmEgLSBsMS5hICogbDIuYikgLyAobDEuYiAtIGwyLmIpXHJcbiAgICApXVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gaW50ZXJzZWN0aW9uTGluZVJhZGl1cyhsLCBhbmdsZSwgcmFkaXVzKSB7XHJcbiAgICB2YXIgbDIgPSBuZXcgTGluZSgwLCBNYXRoLnRhbihhbmdsZSkpO1xyXG4gICAgdmFyIGludGVyc2VjdCA9IGludGVyc2VjdGlvbk9mVHdvTGluZXMobCwgbDIpO1xyXG4gICAgdmFyIHMxID0gbmV3IFBvaW50KDAsIDApO1xyXG4gICAgdmFyIHMyID0gbmV3IFBvaW50KHJhZGl1cyAqIE1hdGguY29zKGFuZ2xlKSwgcmFkaXVzICogTWF0aC5zaW4oYW5nbGUpKTtcclxuXHJcbiAgICBpZiAoaW50ZXJzZWN0Lmxlbmd0aCA9PSAwIHx8ICFwb2ludEluU2VnbWVudChpbnRlcnNlY3RbMF0sIHMxLCBzMikpIHtcclxuICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIGludGVyc2VjdDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGludGVyc2VjdGlvbkxpbmVBbmRDaXJjbGUobCwgcikge1xyXG4gICAgdmFyIHggPSBzb2x2ZUVxU2Vjb25kRGVncmVlKGwuYiAqIGwuYiArIDEsIDIgKiBsLmEgKiBsLmIsIGwuYSAqIGwuYSAtIHIgKiByKTtcclxuICAgIHJldHVybiB4Lm1hcChmdW5jdGlvbih4KSB7cmV0dXJuIG5ldyBQb2ludCh4LCBsLmdldFkoeCkpfSk7XHJcbiAgfVxyXG5cclxuICAvLyBJcyBwb2ludCBwIGluc2lkZSB0aGUgc2VnbWVudCBkZWZpbmVkIGJ5IHMxIGFuZCBzMi4gSXQgaXMgYXNzdW1lZCB0aGF0IHRoZVxyXG4gIC8vIHRocmVlIHBvaW50cyBhcmUgYWxpZ25lZC5cclxuICBmdW5jdGlvbiBwb2ludEluU2VnbWVudChwLCBzMSwgczIpIHtcclxuICAgIHZhciBrcCA9IGRvdFByb2QocG9pbnREaWZmKHMyLCBzMSksIHBvaW50RGlmZihwLCBzMSkpO1xyXG4gICAgdmFyIGtzID0gZG90UHJvZChwb2ludERpZmYoczIsIHMxKSwgcG9pbnREaWZmKHMyLCBzMSkpO1xyXG4gICAgcmV0dXJuIGtwID49IDAgJiYga3AgPD0ga3M7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBwb2ludERpZmYocDEsIHAyKSB7XHJcbiAgICByZXR1cm4gbmV3IFBvaW50KHAxLnggLSBwMi54LCBwMS55IC0gcDIueSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBkb3RQcm9kKHAxLCBwMikge1xyXG4gICAgcmV0dXJuIHAxLnggKiBwMi54ICsgcDEueSAqIHAyLnk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBzb2x2ZUVxU2Vjb25kRGVncmVlKGEsIGIsIGMpIHtcclxuICAgIHZhciBkZXQgPSBiICogYiAtIDQgKiBhICogY1xyXG4gICAgaWYgKGRldCA8IDApIHJldHVybiBbXTtcclxuICAgIGlmIChkZXQgPT0gMCkgcmV0dXJuIFsoLSBiKSAvICgyICogYSldO1xyXG4gICAgZWxzZSByZXR1cm4gW1xyXG4gICAgICAoLWIgLSBNYXRoLnNxcnQoZGV0KSkgLyAoMiAqIGEpLFxyXG4gICAgICAoLWIgKyBNYXRoLnNxcnQoZGV0KSkgLyAoMiAqIGEpXHJcbiAgICBdXHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBkaXN0YW5jZShwMSwgcDIpIHtcclxuICAgIHJldHVybiBNYXRoLnNxcnQoIE1hdGgucG93KHAxLnggLSBwMi54LCAyKSArIE1hdGgucG93KHAxLnkgLSBwMi55LCAyKSlcclxuICB9XHJcbn0oKSk7XHJcbiIsIi8vIENvcHlyaWdodCDCqSAyMDE2IFJURSBSw6lzZWF1IGRlIHRyYW5zcG9ydCBk4oCZw6lsZWN0cmljaXTDqVxyXG4oZnVuY3Rpb24oKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICB2YXIgZDMgPSByZXF1aXJlKFwiZDNcIik7XHJcbiAgdmFyIGcgPSByZXF1aXJlKFwiLi9nZW9tZXRyeS5qc1wiKVxyXG5cclxuICBtb2R1bGUuZXhwb3J0cyA9IExhYmVsO1xyXG5cclxuICBmdW5jdGlvbiBMYWJlbChlbCwgc3R5bGUsIGNvbG9yLCBtaW5TaXplLCBtYXhTaXplKSB7XHJcbiAgICB0aGlzLl9lbCA9IGVsO1xyXG4gICAgdGhpcy5fbWluU2l6ZSA9IG1pblNpemU7XHJcbiAgICB0aGlzLl9tYXhTaXplID0gbWF4U2l6ZTtcclxuICAgIHRoaXMuX2NvbnRhaW5lciA9IGQzLnNlbGVjdChlbCk7XHJcbiAgICB0aGlzLl9sYWJlbCA9IHRoaXMuX2NvbnRhaW5lci5hcHBlbmQoXCJnXCIpXHJcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJsYWJlbFwiKTtcclxuXHJcbiAgICB0aGlzLl90ZXh0ID0gdGhpcy5fbGFiZWwuYXBwZW5kKFwidGV4dFwiKVxyXG4gICAgICAuYXR0cihcImR5XCIsIFwiMC4zNWVtXCIpXHJcbiAgICAgIC5hdHRyKFwidGV4dC1hbmNob3JcIiwgXCJtaWRkbGVcIilcclxuICAgICAgLmF0dHIoXCJzdHlsZVwiLCBzdHlsZSB8fCBcIlwiKVxyXG4gICAgICAuYXR0cihcImZpbGxcIiwgY29sb3IgfHwgXCJibGFja1wiKTtcclxuICB9XHJcblxyXG4gIC8vIFNpemUgb2YgdGhlIGxhYmVsIGJlZm9yZSBzY2FsaW5nXHJcbiAgTGFiZWwucHJvdG90eXBlLmlubmVyU2l6ZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX3RleHQubm9kZSgpLmdldEJCb3goKTtcclxuICB9XHJcblxyXG4gIExhYmVsLnByb3RvdHlwZS5zaXplID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgYmJveCA9IHRoaXMuaW5uZXJTaXplKCk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICB3aWR0aDogYmJveC53aWR0aCAqIHRoaXMuX3NjYWxlLFxyXG4gICAgICBoZWlnaHQ6IGJib3guaGVpZ2h0ICogdGhpcy5fc2NhbGVcclxuICAgIH1cclxuICB9XHJcblxyXG4gIExhYmVsLnByb3RvdHlwZS51cGRhdGVUZXh0ID0gZnVuY3Rpb24obmV3VGV4dCkge1xyXG4gICAgLy8gTmV3IGxhYmVsIHNob3VsZCBmaXQgaW4gdGhlIG9sZCBib3VuZGluZyBiYm94XHJcbiAgICB2YXIgb2xkU2l6ZSA9IHRoaXMuc2l6ZSgpO1xyXG4gICAgdGhpcy5fdGV4dC50ZXh0KG5ld1RleHQpO1xyXG4gICAgdmFyIG5ld1NpemUgPSB0aGlzLnNpemUoKTtcclxuXHJcbiAgICB2YXIgc2NhbGUgPSBNYXRoLm1pbihcclxuICAgICAgb2xkU2l6ZS53aWR0aCAvIG5ld1NpemUud2lkdGgsXHJcbiAgICAgIG9sZFNpemUuaGVpZ2h0IC8gbmV3U2l6ZS5oZWlnaHRcclxuICAgICk7XHJcbiAgICB0aGlzLnVwZGF0ZVNjYWxlKHRoaXMuX3NjYWxlICogc2NhbGUsIDApO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBMYWJlbC5wcm90b3R5cGUudXBkYXRlUG9zaXRpb24gPSBmdW5jdGlvbih4LCB5LCB0cmFuc2l0aW9uVGltZSkge1xyXG4gICAgdGhpcy5fY29udGFpbmVyXHJcbiAgICAgIC50cmFuc2l0aW9uKClcclxuICAgICAgLmR1cmF0aW9uKHRyYW5zaXRpb25UaW1lIHx8IDApXHJcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgeCArIFwiLFwiICsgeSArIFwiKVwiKTtcclxuICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBMYWJlbC5wcm90b3R5cGUudXBkYXRlU2NhbGUgPSBmdW5jdGlvbihuZXdTY2FsZSwgdHJhbnNpdGlvblRpbWUpIHtcclxuICAgIGlmICghbmV3U2NhbGUgfHwgaXNOYU4obmV3U2NhbGUpIHx8ICFpc0Zpbml0ZShuZXdTY2FsZSkpIHtcclxuICAgICAgbmV3U2NhbGUgPSAwO1xyXG4gICAgfVxyXG4gICAgdmFyIG5ld0hlaWdodCA9IHRoaXMuaW5uZXJTaXplKCkuaGVpZ2h0ICogbmV3U2NhbGU7XHJcbiAgICBpZiAodGhpcy5fbWluU2l6ZSAmJiBuZXdIZWlnaHQgPCB0aGlzLl9taW5TaXplKSB7XHJcbiAgICAgIG5ld1NjYWxlID0gMDtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLl9tYXhTaXplICYmIG5ld0hlaWdodCA+IHRoaXMuX21heFNpemUpIHtcclxuICAgICAgbmV3U2NhbGUgPSB0aGlzLl9tYXhTaXplIC8gdGhpcy5pbm5lclNpemUoKS5oZWlnaHQ7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9sYWJlbFxyXG4gICAgICAudHJhbnNpdGlvbigpXHJcbiAgICAgIC5kdXJhdGlvbih0cmFuc2l0aW9uVGltZSB8fCAwKVxyXG4gICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInNjYWxlKFwiICsgbmV3U2NhbGUgKyBcIilcIik7XHJcbiAgICB0aGlzLl9zY2FsZSA9IG5ld1NjYWxlO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgTGFiZWwucHJvdG90eXBlLmZpbGxSZWN0ID0gZnVuY3Rpb24oeCwgeSwgd2lkdGgsIGhlaWdodCwgcGFkZGluZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWxpZ24sIHZBbGlnbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2l0aW9uVGltZSkge1xyXG4gICAgICB2YXIgYmJveCA9IHRoaXMuaW5uZXJTaXplKCk7XHJcbiAgICAgIHRoaXMudXBkYXRlU2NhbGUoTWF0aC5taW4oXHJcbiAgICAgICAgKHdpZHRoIC0gMiAqIHBhZGRpbmcpIC8gYmJveC53aWR0aCxcclxuICAgICAgICAoTWF0aC5hYnMoaGVpZ2h0KSkgLyBiYm94LmhlaWdodFxyXG4gICAgICApLCB0cmFuc2l0aW9uVGltZSk7XHJcblxyXG4gICAgICB2YXIgbHNpemUgPSB0aGlzLnNpemUoKTtcclxuICAgICAgdmFyIGx4LCBseTtcclxuICAgICAgc3dpdGNoKHZBbGlnbikge1xyXG4gICAgICAgIGNhc2UgXCJ0b3BcIjpcclxuICAgICAgICAgIGx5ID0geSArIGxzaXplLmhlaWdodCAvIDI7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFwiY2VudGVyXCI6XHJcbiAgICAgICAgICBseSA9IHkgKyAoaGVpZ2h0KSAvIDI7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFwiYm90dG9tXCI6XHJcbiAgICAgICAgICBseSA9IHkgKyBoZWlnaHQgLSBsc2l6ZS5oZWlnaHQgLyAyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzd2l0Y2goaEFsaWduKSB7XHJcbiAgICAgICAgY2FzZSBcImxlZnRcIjpcclxuICAgICAgICAgIGx4ID0geCArIHBhZGRpbmcgKyBsc2l6ZS53aWR0aCAvIDI7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFwiY2VudGVyXCI6XHJcbiAgICAgICAgICBseCA9IHggKyB3aWR0aCAvIDI7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFwicmlnaHRcIjpcclxuICAgICAgICAgIGx4ID0geCArIHdpZHRoIC0gcGFkZGluZyAtIGxzaXplLndpZHRoIC8gMjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbihseCwgbHksIHRyYW5zaXRpb25UaW1lKTtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIExhYmVsLnByb3RvdHlwZS5maWxsQ2lyY2xlID0gZnVuY3Rpb24ocmFkaXVzLCB0cmFuc2l0aW9uVGltZSkge1xyXG4gICAgdGhpcy51cGRhdGVQb3NpdGlvbigwLCAwLCB0cmFuc2l0aW9uVGltZSk7XHJcblxyXG4gICAgdmFyIGJib3ggPSB0aGlzLmlubmVyU2l6ZSgpO1xyXG4gICAgdmFyIHJhdGlvID0gYmJveC5oZWlnaHQgLyBiYm94LndpZHRoO1xyXG5cclxuICAgIHZhciBtYXhIZWlnaHQgPSByYWRpdXMgKiAyICogTWF0aC5jb3MoTWF0aC5QSS8yIC0gTWF0aC5hdGFuKHJhdGlvKSlcclxuICAgIHRoaXMudXBkYXRlU2NhbGUobWF4SGVpZ2h0IC8gYmJveC5oZWlnaHQsIHRyYW5zaXRpb25UaW1lKTtcclxuICB9XHJcblxyXG4gIExhYmVsLnByb3RvdHlwZS5maWxsU2xpY2UgPSBmdW5jdGlvbihhcmMsIHJhZGl1cywgZCwgdHJhbnNpdGlvblRpbWUpIHtcclxuICAgIHZhciBjID0gYXJjLmNlbnRyb2lkKGQpO1xyXG4gICAgdGhpcy51cGRhdGVQb3NpdGlvbihjWzBdLCBjWzFdLCB0cmFuc2l0aW9uVGltZSk7XHJcblxyXG4gICAgdmFyIGJib3ggPSB0aGlzLmlubmVyU2l6ZSgpO1xyXG4gICAgdmFyIHJhdGlvID0gYmJveC5oZWlnaHQgLyBiYm94LndpZHRoO1xyXG5cclxuICAgIC8vIEdldCBtYXhpbWFsIHNjYWxlIHNvIHRoYXQgbGFiZWwgZml0cyBpbiB0aGUgc2xpY2UuXHJcbiAgICB2YXIgZGlhZzEgPSBuZXcgZy5MaW5lKGNbMV0gLSByYXRpbyAqIGNbMF0sIHJhdGlvKTtcclxuICAgIHZhciBkaWFnMiA9IG5ldyBnLkxpbmUoY1sxXSArIHJhdGlvICogY1swXSwgLXJhdGlvKTtcclxuICAgIHZhciBsaW1pdDEgPSBuZXcgZy5MaW5lKDAsIE1hdGgudGFuKGQuc3RhcnRBbmdsZSArIE1hdGguUEkvMikpO1xyXG4gICAgdmFyIGxpbWl0MiA9IG5ldyBnLkxpbmUoMCwgTWF0aC50YW4oZC5lbmRBbmdsZSArIE1hdGguUEkvMikpO1xyXG5cclxuICAgIC8vIEdldCBhbGwgaW50ZXJzZWN0aW9uIHBvaW50c1xyXG4gICAgdmFyIGludGVyc2VjdHMgPSBbXTtcclxuICAgIGludGVyc2VjdHMgPSBpbnRlcnNlY3RzLmNvbmNhdChnLmludGVyc2VjdGlvbkxpbmVSYWRpdXMoZGlhZzEsIGQuc3RhcnRBbmdsZSAtIE1hdGguUEkvMiwgcmFkaXVzKSk7XHJcbiAgICBpbnRlcnNlY3RzID0gaW50ZXJzZWN0cy5jb25jYXQoZy5pbnRlcnNlY3Rpb25MaW5lUmFkaXVzKGRpYWcxLCBkLmVuZEFuZ2xlIC0gTWF0aC5QSS8yLCByYWRpdXMpKTtcclxuICAgIGludGVyc2VjdHMgPSBpbnRlcnNlY3RzLmNvbmNhdChnLmludGVyc2VjdGlvbkxpbmVBbmRDaXJjbGUoZGlhZzEsIHJhZGl1cykpO1xyXG4gICAgaW50ZXJzZWN0cyA9IGludGVyc2VjdHMuY29uY2F0KGcuaW50ZXJzZWN0aW9uTGluZVJhZGl1cyhkaWFnMiwgZC5zdGFydEFuZ2xlIC0gTWF0aC5QSS8yLCByYWRpdXMpKTtcclxuICAgIGludGVyc2VjdHMgPSBpbnRlcnNlY3RzLmNvbmNhdChnLmludGVyc2VjdGlvbkxpbmVSYWRpdXMoZGlhZzIsIGQuZW5kQW5nbGUgLSBNYXRoLlBJLzIsIHJhZGl1cykpO1xyXG4gICAgaW50ZXJzZWN0cyA9IGludGVyc2VjdHMuY29uY2F0KGcuaW50ZXJzZWN0aW9uTGluZUFuZENpcmNsZShkaWFnMiwgcmFkaXVzKSk7XHJcblxyXG4gICAgLy8gQ29tcHV0ZSBkaXN0YW5jZSBiZXR3ZWVuIGFsbCB0aGVzZSBwb2ludHMgYW5kIHRha2UgdGhlIG1pbmltdW1cclxuICAgIHZhciBjZW50ZXIgPSBuZXcgZy5Qb2ludChjWzBdLCBjWzFdKTtcclxuICAgIHZhciBkaXN0YW5jZXMgPSBpbnRlcnNlY3RzLm1hcChmdW5jdGlvbih4KSB7cmV0dXJuIGcuZGlzdGFuY2UoY2VudGVyLCB4KX0pO1xyXG4gICAgdmFyIG1pbkRpc3QgPSBkMy5taW4oZGlzdGFuY2VzKTtcclxuICAgIHZhciBhY3R1YWxEaXN0ID0gTWF0aC5zcXJ0KCBNYXRoLnBvdyhiYm94LmhlaWdodCAvIDIsIDIpICsgTWF0aC5wb3coYmJveC53aWR0aCAvIDIsIDIpKTtcclxuXHJcbiAgICB0aGlzLnVwZGF0ZVNjYWxlKG1pbkRpc3QgLyBhY3R1YWxEaXN0LCB0cmFuc2l0aW9uVGltZSk7XHJcbiAgfVxyXG59KCkpO1xyXG4iLCIvLyBDb3B5cmlnaHQgwqkgMjAxNiBSVEUgUsOpc2VhdSBkZSB0cmFuc3BvcnQgZOKAmcOpbGVjdHJpY2l0w6lcclxuKGZ1bmN0aW9uKCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgbW9kdWxlLmV4cG9ydHMuQmFyY2hhcnQgPSByZXF1aXJlKFwiLi9iYXJjaGFydC5qc1wiKTtcclxuICBtb2R1bGUuZXhwb3J0cy5Qb2xhcmNoYXJ0ID0gcmVxdWlyZShcIi4vcG9sYXJjaGFydC5qc1wiKTtcclxuICBtb2R1bGUuZXhwb3J0cy5QaWVjaGFydCA9IHJlcXVpcmUoXCIuL3BpZWNoYXJ0LmpzXCIpO1xyXG5cclxuICBpZiAod2luZG93KSB3aW5kb3cubWluaWNoYXJ0cyA9IG1vZHVsZS5leHBvcnRzO1xyXG59KCkpO1xyXG4iLCIvLyBDb3B5cmlnaHQgwqkgMjAxNiBSVEUgUsOpc2VhdSBkZSB0cmFuc3BvcnQgZOKAmcOpbGVjdHJpY2l0w6lcclxuKGZ1bmN0aW9uKCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuICB2YXIgUG9sYXJjaGFydCA9IHJlcXVpcmUoXCIuL3BvbGFyY2hhcnQuanNcIik7XHJcbiAgbW9kdWxlLmV4cG9ydHMgPSBQaWVjaGFydDtcclxuXHJcbiAgUGllY2hhcnQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShQb2xhcmNoYXJ0LnByb3RvdHlwZSk7XHJcbiAgUGllY2hhcnQucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUGllY2hhcnQ7XHJcblxyXG4gIC8qKlxyXG4gICAgKiBAY2xhc3MgUGllY2hhcnRcclxuICAgICogQHN1bW1hcnkgUmVwcmVzZW50IGRhdGEgd2l0aCBhIHBpZSBjaGFydFxyXG4gICAgKiBAZGVzYyBBIHBpZSBjaGFydCBpcyBhIHNwZWNpYWwgY2FzZSBvZiBwb2xhciBjaGFydCB3aGVyZSB0aGUgZGF0YSB2YWx1ZXNcclxuICAgICogYXJlIHJlcHJlc2VudGVkIGJ5IHRoZSBhbmdsZSBvZiB0aGUgc2xpY2VzLiBUaGV5IHNob3VsZCBvbmx5IGJlIHVzZWQgdG9cclxuICAgICogY29tcGFyZSBxdWFsaXRhdGl2ZWx5IHByb3BvcnRpb25zIGFuZCBjb21wb3NpdGlvbnMuIEluZGVlZCwgaHVtYW4gZXllIGlzXHJcbiAgICAqIG5vdCBnb29kIGF0IGNvbXBhcmluZyBhbmdsZXMgc28gb25seSBsYXJnZSBkaWZmZXJlbmNlcyBhcmUgdmlzaWJsZS5cclxuICAgICogQHBhcmFtIHtzdHJpbmd9IGVsIENTUyBzZWxlY3RvciByZXByZXNlbnRpbmcgdGhlIGVsZW1lbnQgdGhhdCB3aWxsIGhvbGQgdGhlIGNoYXJ0LlxyXG4gICAgKiBAcGFyYW0ge251bWJlcltdfSBkYXRhIERhdGEgdGhlIGNoYXJ0IGhhcyB0byByZXByZXNlbnQuXHJcbiAgICAqIEBwYXJhbSB7UGllY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQHR5cGVkZWYge29iamVjdH0gUGllY2hhcnRPcHRpb25zXHJcbiAgICAqIEBtZW1iZXJPZiBQaWVjaGFydFxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbd2lkdGg9NjBdIFdpZHRoIG9mIHRoZSBjaGFydC5cclxuICAgICogQHByb3Age251bWJlcn0gW2hlaWdodD02MF0gSGVpZ2h0IG9mIHRoZSBjaGFydC5cclxuICAgICogQHByb3Age251bWJlcn0gW3RyYW5zaXRpb25UaW1lPTc1MF0gRHVyYXRpb24gb2YgdGhlIHRyYW5zaXRpb25zLCBpbiBtaWxsaXNlY29uZHMuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmdbXXxmdW5jdGlvbn1bY29sb3JzPWQzLnNjaGVtZUNhdGVnb3J5MTBdIEVpdGhlciBhbiBhcnJheSBvZlxyXG4gICAgKiBjb2xvcnMgb3IgYSBmdW5jdGlvbiBgKGQsIGkpIC0+IGNvbG9yYCB3aGVyZSBgZGAgaXMgYSBkYXRhIHZhbHVlIGFuZCBgaWBcclxuICAgICogaXMgdGhlIGluZGV4IG9mIHRoZSB2YWx1ZS5JZiBpdCBpcyBhbiBhcnJheSB3aXRoIGxlbmd0aCBsZXNzIHRoYW4gdGhlIGxlbmd0aFxyXG4gICAgKiBvZiBkYXRhLCB0aGVuIHRoZSBjb2xvcnMgYXJlIHJlY3ljbGVkLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nW118XCJub25lXCJ8XCJhdXRvXCJ8ZnVuY3Rpb259W2xhYmVscz1cIm5vbmVcIl0gTGFiZWxzIHRvIGRpc3BsYXkgaW4gc2xpY2VzLlxyXG4gICAgKiBJdCBjYW4gYmUgYW4gYXJyYXkgd2l0aCBzYW1lIGxlbmd0aCBhcyB0aGUgZGF0YS4gSXQgY2FuIGFsc28gYmUgYSBmdW5jdGlvblxyXG4gICAgKiBgKGQsIGkpIC0+IGxhYmVsVGV4dGAgd2hlcmUgYGRgIGlzIGEgZGF0YSB2YWx1ZSBhbmQgYGlgXHJcbiAgICAqIGlzIHRoZSBpbmRleCBvZiB0aGUgdmFsdWUuIEZpbmFsbHkgaXQgY2FuIGJlIGVxdWFsIHRvIFwibm9uZVwiIHRvIGhpZGUgbGFiZWxzXHJcbiAgICAqIG9yIFwiYXV0b1wiIHRvIGRpc3BsYXkgaW4gYSBjb21wYWN0IHdheSB2YWx1ZXMuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmd8c3RyaW5nW118XCJhdXRvXCJ8ZnVuY3Rpb259W2xhYmVsQ29sb3JzPVwiYXV0b1wiXSBDb2xvciBvZiB0aGUgbGFiZWxzLlxyXG4gICAgKiBJdCBjYW4gYmUgYSBzaW5nbGUgdmFsdWUgb3IgYW4gYXJyYXkgd2l0aCBzYW1lIGxlbmd0aCBhcyB0aGUgZGF0YS4gSXQgY2FuXHJcbiAgICAqIGFsc28gYmUgYSBmdW5jdGlvbiBgKGQsIGkpIC0+IGNvbG9yYCB3aGVyZSBgZGAgaXMgYSBkYXRhIHZhbHVlIGFuZCBgaWBcclxuICAgICogaXMgdGhlIGluZGV4IG9mIHRoZSB2YWx1ZS4gRmluYWxseSBpdCBjYW4gYmUgZXF1YWwgdG8gXCJhdXRvXCIuIEluIHRoaXMgY2FzZSxcclxuICAgICogdGhlIG1vc3QgcmVhZGFibGUgY29sb3IgaXMgY2hvb3NlbiBkZXBkaW5nIG9uIHRoZSBjb2xvciBvZiB0aGUgc2xpY2UuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9W2xhYmVsTWluU2l6ZT04XSBMYWJlbCBtaW5pbXVtIHNpemUgaW4gcGl4ZWxzLiBJZiB0aGVyZSBpc1xyXG4gICAgKiBub3QgZW5vdWdoIHNwYWNlIGZvciBhIGdpdmVuIGxhYmVsLCB0aGVuIGl0IGlzIGhpZGRlbi5cclxuICAgICogQHByb3Age251bWJlcn1bbGFiZWxNYXhTaXplPTI0XSBMYWJlbCBtYXhpbXVtIHNpemUgaW4gcGl4ZWxzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfVtsYWJlbENsYXNzPVwiXCJdIExhYmVscyBDU1MgY2xhc3MuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmd9W3NoYXBlQ2xhc3M9XCJcIl0gc2xpY2VzIENTUyBjbGFzcy5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHNldERhdGFcclxuICAgICogQGRlc2MgVXBkYXRlIHRoZSBkYXRhIHJlcHJlc2VudGVkIGJ5IHRoZSBjaGFydFxyXG4gICAgKiBAaW5zdGFuY2VcclxuICAgICogQG1lbWJlck9mIFBpZWNoYXJ0XHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyW119IGRhdGEgRGF0YSB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHNldE9wdGlvbnNcclxuICAgICogQGRlc2MgVXBkYXRlIHRoZSBncmFwaGljYWwgb3B0aW9ucyBvZiBhIGNoYXJ0XHJcbiAgICAqIEBpbnN0YW5jZVxyXG4gICAgKiBAbWVtYmVyT2YgUGllY2hhcnRcclxuICAgICogQHBhcmFtIHtQaWVjaGFydE9wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyBjb250cm9saW5nIGdyYXBoaWNhbCBhc3BlY3RzIG9mIHRoZSBjaGFydC5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHVwZGF0ZVxyXG4gICAgKiBAZGVzYyBVcGRhdGUgc2ltdWxhdGVub3VzbHkgZGF0YSBhbmQgb3B0aW9ucyBvZiBhIHBpZSBjaGFydC5cclxuICAgICogQGluc3RhbmNlXHJcbiAgICAqIEBtZW1iZXJPZiBQaWVjaGFydFxyXG4gICAgKiBAcGFyYW0ge251bWJlcltdfSBkYXRhIERhdGEgdGhlIGNoYXJ0IGhhcyB0byByZXByZXNlbnQuXHJcbiAgICAqIEBwYXJhbSB7UGllY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG4gIGZ1bmN0aW9uIFBpZWNoYXJ0KGVsLCBkYXRhLCBvcHRpb25zKSB7XHJcbiAgICBQb2xhcmNoYXJ0LmNhbGwodGhpcywgZWwsIGRhdGEsIG9wdGlvbnMpO1xyXG4gIH1cclxuXHJcbiAgUGllY2hhcnQucHJvdG90eXBlLl9wcm9jZXNzT3B0aW9ucyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG4gICAgb3B0aW9ucy50eXBlID0gXCJhbmdsZVwiO1xyXG4gICAgcmV0dXJuIFBvbGFyY2hhcnQucHJvdG90eXBlLl9wcm9jZXNzT3B0aW9ucy5jYWxsKHRoaXMsIG9wdGlvbnMpO1xyXG4gIH1cclxuXHJcbn0oKSk7XHJcbiIsIi8vIENvcHlyaWdodCDCqSAyMDE2IFJURSBSw6lzZWF1IGRlIHRyYW5zcG9ydCBk4oCZw6lsZWN0cmljaXTDqVxyXG4oZnVuY3Rpb24oKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICB2YXIgZDMgPSByZXF1aXJlKFwiZDNcIik7XHJcbiAgdmFyIENoYXJ0ID0gcmVxdWlyZShcIi4vY2hhcnQuanNcIik7XHJcblxyXG4gIG1vZHVsZS5leHBvcnRzID0gUG9sYXJjaGFydDtcclxuXHJcbiAgUG9sYXJjaGFydC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKENoYXJ0LnByb3RvdHlwZSk7XHJcbiAgUG9sYXJjaGFydC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBQb2xhcmNoYXJ0O1xyXG5cclxuICAvKipcclxuICAgICogQGNsYXNzIFBvbGFyY2hhcnRcclxuICAgICogQHN1bW1hcnkgUmVwcmVzZW50IGRhdGEgd2l0aCBhIHBvbGFyIGNoYXJ0XHJcbiAgICAqIEBkZXNjIFBvbGFyIGNoYXJ0cyBhcmUgbmljZSBsb29raW5nIGNoYXJ0cyBlc3BlY2lhbGx5IG9uIGEgbWFwLFxyXG4gICAgKiBidXQgaW5kaXZpZHVhbCB2YWx1ZXMgYXJlIGhhcmQgdG8gY29tcGFyZVxyXG4gICAgKiBvbiB0aGVzZSBjaGFydHM6IHRoZSBodW1hbiBleWUgaXMgZ29vZCB0byBjb21wYXJlIGxlbmd0aHMsIGJ1dCBub3RcclxuICAgICogdG8gY29tcGFyZSBhZ25sZXMsIHJhZGl1cyBvciBhcmVhcy4gUG9sYXIgY2hhcnRzIHNob3VsZCBvbmx5IGJlIHVzZWQgd2hlblxyXG4gICAgKiBvbmUgd2FudHMgdG8gcG9pbnQgb3V0IHF1YWxpdGF0aXZlIHJlc3VsdHMgYW5kIGRvZXMgbm90IG5lZWQgYSBwcmVjaXNlXHJcbiAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGRhdGEuIEFub3RoZXIgbGltaXRhdGlvbiBjb21wYXJlZCB0byBiYXJjaGFydHMgaXMgdGhhdFxyXG4gICAgKiBwb2xhciBjaGFydHMgY2Fubm90IHJlcHJlc2VudCBuZWdhdGl2ZSB2YWx1ZXMuXHJcbiAgICAqIEBwYXJhbSB7c3RyaW5nfSBlbCBDU1Mgc2VsZWN0b3IgcmVwcmVzZW50aW5nIHRoZSBlbGVtZW50IHRoYXQgd2lsbCBob2xkIHRoZSBjaGFydC5cclxuICAgICogQHBhcmFtIHtudW1iZXJbXX0gZGF0YSBEYXRhIHRoZSBjaGFydCBoYXMgdG8gcmVwcmVzZW50LlxyXG4gICAgKiBAcGFyYW0ge1BvbGFyY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG5cclxuICAvKiogQHR5cGVkZWYge29iamVjdH0gUG9sYXJjaGFydE9wdGlvbnNcclxuICAgICogQG1lbWJlck9mIFBvbGFyY2hhcnRcclxuICAgICogQHByb3Age251bWJlcnxcImF1dG9cIn0gW21heFZhbHVlPVwiYXV0b1wiXSBNYXhpbXVtIHZhbHVlIGRhdGEgY291bGQgdGFrZS5JdFxyXG4gICAgKiBpcyBpbXBvcnRhbnQgdG8gc2V0IHRoaXMgb3B0aW9uIGV4cGxpY2l0ZWx5IGlmIG9uZSB3YW50cyB0byBjb21wYXJlXHJcbiAgICAqIGNoYXJ0cyBhbmQgdXNlIHRoZSBzYW1lIHNjYWxlIG9uIGVhY2ggb25lLiBCeSBkZWZhdWx0IGl0IGVxdWFscyB0byB0aGVcclxuICAgICogbWF4aW11bSB2YWx1ZSBvZiB0aGUgZGF0YS5cclxuICAgICogQHByb3Age1wiYXJlYVwifFwicmFkaXVzXCJ8XCJhbmdsZVwifSBbdHlwZT1cImFyZWFcIl0gV2hhdCBraW5kIG9mIHNjYWxlIHRvIHVzZSB0b1xyXG4gICAgKiByZXByZXNlbnQgdGhlIGRhdGE/IGBhbmdsZWAgcHJvZHVjZXMgYSBwaWUgY2hhcnQgYW5kIHNob3VsZCBiZSB1c2VkIG9ubHkgdG8gdmlzdWFsaXplXHJcbiAgICAqIHByb3BvcnRpb25zLiBJbiBvdGhlciBjYXNlcywgYGFyZWFgICh0aGUgZGVmYXVsdCkgc2hvdWxkIGdlbmVyYWxseSBiZVxyXG4gICAgKiBwcmVmZXJlZC4gYHJhZGl1c2Agc2hvdWxkIG9ubHkgYmUgdXNlZCB3aGVuIG9uZSB3YW50cyB0byBtYWduaWZ5IGRpZmZlcmVuY2VzLlxyXG4gICAgKiBAcHJvcCB7bnVtYmVyfSBbd2lkdGg9NjBdIFdpZHRoIG9mIHRoZSBjaGFydC5cclxuICAgICogQHByb3Age251bWJlcn0gW2hlaWdodD02MF0gSGVpZ2h0IG9mIHRoZSBjaGFydC5cclxuICAgICogQHByb3Age251bWJlcn0gW3RyYW5zaXRpb25UaW1lPTc1MF0gRHVyYXRpb24gb2YgdGhlIHRyYW5zaXRpb25zLCBpbiBtaWxsaXNlY29uZHMuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmdbXXxmdW5jdGlvbn1bY29sb3JzPWQzLnNjaGVtZUNhdGVnb3J5MTBdIEVpdGhlciBhbiBhcnJheSBvZlxyXG4gICAgKiBjb2xvcnMgb3IgYSBmdW5jdGlvbiBgKGQsIGkpIC0+IGNvbG9yYCB3aGVyZSBgZGAgaXMgYSBkYXRhIHZhbHVlIGFuZCBgaWBcclxuICAgICogaXMgdGhlIGluZGV4IG9mIHRoZSB2YWx1ZS5JZiBpdCBpcyBhbiBhcnJheSB3aXRoIGxlbmd0aCBsZXNzIHRoYW4gdGhlIGxlbmd0aFxyXG4gICAgKiBvZiBkYXRhLCB0aGVuIHRoZSBjb2xvcnMgYXJlIHJlY3ljbGVkLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nW118XCJub25lXCJ8XCJhdXRvXCJ8ZnVuY3Rpb259W2xhYmVscz1cIm5vbmVcIl0gTGFiZWxzIHRvIGRpc3BsYXkgaW4gc2xpY2VzLlxyXG4gICAgKiBJdCBjYW4gYmUgYW4gYXJyYXkgd2l0aCBzYW1lIGxlbmd0aCBhcyB0aGUgZGF0YS4gSXQgY2FuIGFsc28gYmUgYSBmdW5jdGlvblxyXG4gICAgKiBgKGQsIGkpIC0+IGxhYmVsVGV4dGAgd2hlcmUgYGRgIGlzIGEgZGF0YSB2YWx1ZSBhbmQgYGlgXHJcbiAgICAqIGlzIHRoZSBpbmRleCBvZiB0aGUgdmFsdWUuIEZpbmFsbHkgaXQgY2FuIGJlIGVxdWFsIHRvIFwibm9uZVwiIHRvIGhpZGUgbGFiZWxzXHJcbiAgICAqIG9yIFwiYXV0b1wiIHRvIGRpc3BsYXkgaW4gYSBjb21wYWN0IHdheSB2YWx1ZXMuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmd8c3RyaW5nW118XCJhdXRvXCJ8ZnVuY3Rpb259W2xhYmVsQ29sb3JzPVwiYXV0b1wiXSBDb2xvciBvZiB0aGUgbGFiZWxzLlxyXG4gICAgKiBJdCBjYW4gYmUgYSBzaW5nbGUgdmFsdWUgb3IgYW4gYXJyYXkgd2l0aCBzYW1lIGxlbmd0aCBhcyB0aGUgZGF0YS4gSXQgY2FuXHJcbiAgICAqIGFsc28gYmUgYSBmdW5jdGlvbiBgKGQsIGkpIC0+IGNvbG9yYCB3aGVyZSBgZGAgaXMgYSBkYXRhIHZhbHVlIGFuZCBgaWBcclxuICAgICogaXMgdGhlIGluZGV4IG9mIHRoZSB2YWx1ZS4gRmluYWxseSBpdCBjYW4gYmUgZXF1YWwgdG8gXCJhdXRvXCIuIEluIHRoaXMgY2FzZSxcclxuICAgICogdGhlIG1vc3QgcmVhZGFibGUgY29sb3IgaXMgY2hvb3NlbiBkZXBkaW5nIG9uIHRoZSBjb2xvciBvZiB0aGUgc2xpY2UuXHJcbiAgICAqIEBwcm9wIHtudW1iZXJ9W2xhYmVsTWluU2l6ZT04XSBMYWJlbCBtaW5pbXVtIHNpemUgaW4gcGl4ZWxzLiBJZiB0aGVyZSBpc1xyXG4gICAgKiBub3QgZW5vdWdoIHNwYWNlIGZvciBhIGdpdmVuIGxhYmVsLCB0aGVuIGl0IGlzIGhpZGRlbi5cclxuICAgICogQHByb3Age251bWJlcn1bbGFiZWxNYXhTaXplPTI0XSBMYWJlbCBtYXhpbXVtIHNpemUgaW4gcGl4ZWxzLlxyXG4gICAgKiBAcHJvcCB7c3RyaW5nfVtsYWJlbENsYXNzPVwiXCJdIExhYmVscyBDU1MgY2xhc3MuXHJcbiAgICAqIEBwcm9wIHtzdHJpbmd9W3NoYXBlQ2xhc3M9XCJcIl0gc2xpY2VzIENTUyBjbGFzcy5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHNldERhdGFcclxuICAgICogQGRlc2MgVXBkYXRlIHRoZSBkYXRhIHJlcHJlc2VudGVkIGJ5IHRoZSBjaGFydFxyXG4gICAgKiBAaW5zdGFuY2VcclxuICAgICogQG1lbWJlck9mIFBvbGFyY2hhcnRcclxuICAgICogQHBhcmFtIHtudW1iZXJbXX0gZGF0YSBEYXRhIHRoZSBjaGFydCBoYXMgdG8gcmVwcmVzZW50LlxyXG4gICAgKi9cclxuXHJcbiAgLyoqIEBtZXRob2Qgc2V0T3B0aW9uc1xyXG4gICAgKiBAZGVzYyBVcGRhdGUgdGhlIGdyYXBoaWNhbCBvcHRpb25zIG9mIGEgY2hhcnRcclxuICAgICogQGluc3RhbmNlXHJcbiAgICAqIEBtZW1iZXJPZiBQb2xhcmNoYXJ0XHJcbiAgICAqIEBwYXJhbSB7UG9sYXJjaGFydE9wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyBjb250cm9saW5nIGdyYXBoaWNhbCBhc3BlY3RzIG9mIHRoZSBjaGFydC5cclxuICAgICovXHJcblxyXG4gIC8qKiBAbWV0aG9kIHVwZGF0ZVxyXG4gICAgKiBAZGVzYyBVcGRhdGUgc2ltdWxhdGVub3VzbHkgZGF0YSBhbmQgb3B0aW9ucyBvZiBhIHBvbGFyIGNoYXJ0LlxyXG4gICAgKiBAaW5zdGFuY2VcclxuICAgICogQG1lbWJlck9mIFBvbGFyY2hhcnRcclxuICAgICogQHBhcmFtIHtudW1iZXJbXX0gZGF0YSBEYXRhIHRoZSBjaGFydCBoYXMgdG8gcmVwcmVzZW50LlxyXG4gICAgKiBAcGFyYW0ge1BvbGFyY2hhcnRPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgY29udHJvbGluZyBncmFwaGljYWwgYXNwZWN0cyBvZiB0aGUgY2hhcnQuXHJcbiAgICAqL1xyXG5cclxuICBmdW5jdGlvbiBQb2xhcmNoYXJ0KGVsLCBkYXRhLCBvcHRpb25zKSB7XHJcbiAgICB2YXIgZGVmYXVsdHMgPSB7XHJcbiAgICAgIHR5cGU6IFwiYXJlYVwiLFxyXG4gICAgICBtYXhWYWx1ZTogXCJhdXRvXCIsXHJcbiAgICB9XHJcblxyXG4gICAgQ2hhcnQuY2FsbCh0aGlzLCBlbCwgZGF0YSwgb3B0aW9ucywgZGVmYXVsdHMpO1xyXG5cclxuICAgIC8vIENlbnRlciB0aGUgY2hhcnQgZ3JvdXAgaW5zaWRlIHRoZSBjb250YWluZXJcclxuICAgIHRoaXMuX2NoYXJ0XHJcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgdGhpcy5fb3B0aW9ucy53aWR0aC8yICsgXCIsXCIgKyB0aGlzLl9vcHRpb25zLndpZHRoLzIgKyBcIilcIik7XHJcblxyXG4gICAgdGhpcy5fZHJhdygpO1xyXG4gIH1cclxuXHJcbiAgUG9sYXJjaGFydC5wcm90b3R5cGUuX3Byb2Nlc3NPcHRpb25zID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG4gICAgb3B0aW9ucyA9IENoYXJ0LnByb3RvdHlwZS5fcHJvY2Vzc09wdGlvbnMuY2FsbCh0aGlzLCBvcHRpb25zLCB0aGlzLl9vcHRpb25zKTtcclxuXHJcbiAgICBvcHRpb25zLmhlaWdodCA9IG9wdGlvbnMud2lkdGg7XHJcblxyXG4gICAgaWYgKG9wdGlvbnMubWF4VmFsdWUgPT09IFwiYXV0b1wiKSB7XHJcbiAgICAgIG9wdGlvbnMubWF4VmFsdWUgPSBkMy5tYXgodGhpcy5fZGF0YSk7XHJcbiAgICB9XHJcbiAgICAvL2RlYnVnZ2VyO1xyXG4gICAgdmFyIHJhZGl1cyA9IG9wdGlvbnMud2lkdGggLyAyO1xyXG4gICAgdmFyIHBpZSA9IGQzLnBpZSgpLnNvcnQobnVsbCk7XHJcbiAgICB2YXIgYXJjID0gZDMuYXJjKCkuaW5uZXJSYWRpdXMoMCk7XHJcbiAgICB2YXIgcmFkaXVzRnVuO1xyXG5cclxuICAgIGlmIChvcHRpb25zLnR5cGUgPT09IFwiYW5nbGVcIikge1xyXG4gICAgICByYWRpdXNGdW4gPSBmdW5jdGlvbihkKSB7cmV0dXJuIHJhZGl1c31cclxuICAgICAgcGllLnZhbHVlKGZ1bmN0aW9uKGQpIHtyZXR1cm4gZH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmFkaXVzRnVuID0gb3B0aW9ucy50eXBlID09IFwicmFkaXVzXCIgPyBkMy5zY2FsZUxpbmVhcigpIDogZDMuc2NhbGVQb3coKS5leHBvbmVudCgwLjUpO1xyXG4gICAgICByYWRpdXNGdW4ucmFuZ2UoWzAsIHJhZGl1c10pXHJcbiAgICAgICAgLmRvbWFpbihbMCwgb3B0aW9ucy5tYXhWYWx1ZV0pO1xyXG4gICAgICBwaWUudmFsdWUoZnVuY3Rpb24oZCkge3JldHVybiAxfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXJjLm91dGVyUmFkaXVzKGZ1bmN0aW9uKGQsIGkpIHtyZXR1cm4gcmFkaXVzRnVuKGQuZGF0YSl9KTtcclxuXHJcbiAgICBvcHRpb25zLnJhZGl1cyA9IHJhZGl1c0Z1bjtcclxuICAgIG9wdGlvbnMucGllID0gcGllO1xyXG4gICAgb3B0aW9ucy4gYXJjID0gYXJjO1xyXG4gICAgcmV0dXJuIG9wdGlvbnM7XHJcbiAgfVxyXG5cclxuICBQb2xhcmNoYXJ0LnByb3RvdHlwZS5fZHJhdyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgQ2hhcnQucHJvdG90eXBlLl9kcmF3LmNhbGwodGhpcyk7XHJcblxyXG4gICAgLy8gTW92ZSBjZW50ZXIgb2YgdGhlIGNoYXJ0XHJcbiAgICB0aGlzLl9jaGFydFxyXG4gICAgICAudHJhbnNpdGlvbigpXHJcbiAgICAgIC5kdXJhdGlvbihzZWxmLl9vcHRpb25zLnRyYW5zaXRpb25UaW1lKVxyXG4gICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIHNlbGYuX29wdGlvbnMud2lkdGgvMiArIFwiLFwiICsgc2VsZi5fb3B0aW9ucy53aWR0aC8yICsgXCIpXCIpO1xyXG5cclxuICAgIHZhciBzbGljZXMgPSB0aGlzLl9jaGFydC5zZWxlY3RBbGwoXCJwYXRoXCIpLmRhdGEodGhpcy5fb3B0aW9ucy5waWUodGhpcy5fZGF0YSkpO1xyXG5cclxuICAgIC8vIEluaXRpYWxpemUgbmV3IHNsaWNlc1xyXG4gICAgc2xpY2VzLmVudGVyKClcclxuICAgICAgLmFwcGVuZChcInBhdGhcIilcclxuICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcImxlYWZsZXQtY2xpY2thYmxlXCIpXHJcbiAgICAgIC5hdHRyKFwiZFwiLCB0aGlzLl9vcHRpb25zLmFyYylcclxuICAgICAgLmF0dHIoXCJmaWxsXCIsIGZ1bmN0aW9uKGQsIGkpIHtyZXR1cm4gc2VsZi5fb3B0aW9ucy5jb2xvckZ1bihkLCBpKX0pXHJcbiAgICAgIC5lYWNoKGZ1bmN0aW9uKGQsIGkpIHtcclxuICAgICAgICBpZiAoc2VsZi5fZGF0YS5sZW5ndGggPT0gMSkgdGhpcy5fY3VycmVudCA9IHtzdGFydEFuZ2xlOmQuc3RhcnRBbmdsZSwgZW5kQW5nbGU6ZC5lbmRBbmdsZSwgZGF0YTowfVxyXG4gICAgICAgIGVsc2UgdGhpcy5fY3VycmVudCA9IHtzdGFydEFuZ2xlOmQuZW5kQW5nbGUsIGVuZEFuZ2xlOmQuZW5kQW5nbGV9XHJcbiAgICAgIH0pXHJcbiAgICAvLyBVcGRhdGUgc2xpY2VzXHJcbiAgICAgIC5tZXJnZShzbGljZXMpXHJcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgZnVuY3Rpb24oZCwgaSkge3JldHVybiBzZWxmLl9vcHRpb25zLnNoYXBlQ2xhc3MoZC5kYXRhLCBpKX0pXHJcbiAgICAgIC50cmFuc2l0aW9uKClcclxuICAgICAgLmR1cmF0aW9uKHNlbGYuX29wdGlvbnMudHJhbnNpdGlvblRpbWUpXHJcbiAgICAgIC5hdHRyVHdlZW4oXCJkXCIsIGFyY1R3ZWVuKVxyXG4gICAgICAuYXR0cihcImZpbGxcIiwgZnVuY3Rpb24oZCwgaSkge3JldHVybiBzZWxmLl9vcHRpb25zLmNvbG9yRnVuKGQsIGkpfSk7XHJcbiAgICAvLyBSZW1vdmUgc2xpY2VzXHJcbiAgICBzbGljZXMuZXhpdCgpLnJlbW92ZSgpO1xyXG5cclxuICAgIGZ1bmN0aW9uIGFyY1R3ZWVuKGEpIHtcclxuICAgICAgdmFyIGkgPSBkMy5pbnRlcnBvbGF0ZSh0aGlzLl9jdXJyZW50LCBhKTtcclxuICAgICAgdGhpcy5fY3VycmVudCA9IGkoMCk7XHJcbiAgICAgIHJldHVybiBmdW5jdGlvbih0KSB7XHJcbiAgICAgICAgcmV0dXJuIHNlbGYuX29wdGlvbnMuYXJjKGkodCkpO1xyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEFkZC91cGRhdGUgbGFiZWxzXHJcbiAgICAvLyBmdW5jdGlvbihhcmMsIHJhZGl1c0Z1biwgZCwgdHJhbnNpdGlvblRpbWUpXHJcbiAgICB2YXIgaW5pdExhYmVsLCB1cGRhdGVMYWJlbDtcclxuICAgIGlmICh0aGlzLl9kYXRhLmxlbmd0aCA+IDEpIHtcclxuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9vcHRpb25zLnBpZSh0aGlzLl9kYXRhKTtcclxuICAgICAgaW5pdExhYmVsID0gZnVuY3Rpb24obGFiZWwsIGQsIGkpIHtcclxuICAgICAgICBsYWJlbC5maWxsU2xpY2Uoc2VsZi5fb3B0aW9ucy5hcmMsIHNlbGYuX29wdGlvbnMucmFkaXVzKGQpLCBkYXRhW2ldLCAwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdXBkYXRlTGFiZWwgPSBmdW5jdGlvbihsYWJlbCwgZCwgaSkge1xyXG4gICAgICAgIGxhYmVsLmZpbGxTbGljZShzZWxmLl9vcHRpb25zLmFyYywgc2VsZi5fb3B0aW9ucy5yYWRpdXMoZCksIGRhdGFbaV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX29wdGlvbnMudHJhbnNpdGlvblRpbWUpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpbml0TGFiZWwgPSBmdW5jdGlvbihsYWJlbCwgZCwgaSkge1xyXG4gICAgICAgIGxhYmVsLmZpbGxDaXJjbGUoc2VsZi5fb3B0aW9ucy5yYWRpdXMoZCksIDApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB1cGRhdGVMYWJlbCA9IGZ1bmN0aW9uKGxhYmVsLCBkLCBpKSB7XHJcbiAgICAgICAgbGFiZWwuZmlsbENpcmNsZShzZWxmLl9vcHRpb25zLnJhZGl1cyhkKSwgc2VsZi5fb3B0aW9ucy50cmFuc2l0aW9uVGltZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9kcmF3TGFiZWxzKGluaXRMYWJlbCwgdXBkYXRlTGFiZWwpO1xyXG4gIH1cclxuXHJcbn0oKSk7XHJcbiIsIi8vIENvcHlyaWdodCDCqSAyMDE2IFJURSBSw6lzZWF1IGRlIHRyYW5zcG9ydCBk4oCZw6lsZWN0cmljaXTDqVxyXG4oZnVuY3Rpb24oKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICBtb2R1bGUuZXhwb3J0cy5tZXJnZU9wdGlvbnMgPSBtZXJnZU9wdGlvbnM7XHJcbiAgbW9kdWxlLmV4cG9ydHMudG9BcnJheSA9IHRvQXJyYXk7XHJcbiAgbW9kdWxlLmV4cG9ydHMudG9GdW5jdGlvbiA9IHRvRnVuY3Rpb247XHJcbiAgbW9kdWxlLmV4cG9ydHMucHJldHR5TnVtYmVyID0gcHJldHR5TnVtYmVyO1xyXG5cclxuICAvKiogTWVyZ2UgdGhlIHByb3BlcnRpZXMgb2YgdHdvIG9iamVjdHMuIE1vcmUgcHJlY2lzZWx5LCBpZiBhIHByb3BlcnR5IGlzXHJcbiAgICAqIHByZXNlbnQgaW4gXCJkZWZhdWx0c1wiIGJ1dCBub3QgaW4gXCJvcHRpb25zXCIgaXQgaXMgY29waWVkIGluIG9wdGlvbnMuIHRoaXNcclxuICAgICogZnVuY3Rpb24gaXMgdXNlZCB0byBzcGVjaWZpZWQgZGVmYXVsdCBvcHRpb25zIGZvciBhIGZ1bmN0aW9uLlxyXG4gICAgKlxyXG4gICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyBPcHRpb24gb2JqZWN0XHJcbiAgICAqIEBwYXJhbSB7b2JqZWN0fSBkZWZhdWx0cyBPYmplY3QgY29udGFpbmluZyBkZWZhdWx0IHZhbHVlcyBvZiBvcHRpb25zXHJcbiAgICAqXHJcbiAgICAqIEByZXR1cm4ge29iamVjdH0gTWVyZ2VkIG9iamVjdC5cclxuICAgICovXHJcbiAgZnVuY3Rpb24gbWVyZ2VPcHRpb25zKG9wdGlvbnMsIGRlZmF1bHRzKSB7XHJcbiAgICBpZiAob3B0aW9ucykgb3B0aW9ucyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkob3B0aW9ucykpO1xyXG4gICAgZWxzZSBvcHRpb25zID0ge307XHJcbiAgICBkZWZhdWx0cyA9IGRlZmF1bHRzIHx8IHt9O1xyXG4gICAgZm9yICh2YXIgb3B0IGluIGRlZmF1bHRzKSB7XHJcbiAgICAgIGlmIChkZWZhdWx0cy5oYXNPd25Qcm9wZXJ0eShvcHQpICYmICFvcHRpb25zLmhhc093blByb3BlcnR5KG9wdCkpIHtcclxuICAgICAgICBvcHRpb25zW29wdF0gPSBkZWZhdWx0c1tvcHRdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gb3B0aW9ucztcclxuICB9XHJcblxyXG4gIC8qKiBDb252ZXJ0cyBwYXJhbWV0ZXIgdG8gQXJyYXkuIFVzZWQgd2hlbiB1c2VyIHdhbnRzIHRvIHBhc3MgYSBzaW5nbGUgdmFsdWUsXHJcbiAgICAqIGJ1dCBhIGZ1bmN0aW9uIGV4cGVjdHMgYW4gYXJyYXkuXHJcbiAgICAqIEBwYXJhbSB7YW55fSB4IEFuIGFycmF5IG9yIGEgc2NhbGFyIHZhbHVlXHJcbiAgICAqIEByZXR1cm4ge2FueVtdfVxyXG4gICAgKiAneCcgaWYgaXQgaXMgYW4gYXJyYXksIGVsc2UgYW4gYXJyYXkgd2l0aCAneCcgYXMgaXRzIHVuaXF1ZVxyXG4gICAgKiBlbGVtZW50LlxyXG4gICAgKi9cclxuICBmdW5jdGlvbiB0b0FycmF5KHgpIHtcclxuICAgIGlmICh4LmNvbnN0cnVjdG9yICE9PSBBcnJheSkgeCA9IFt4XTtcclxuICAgIHJldHVybiB4O1xyXG4gIH1cclxuXHJcbiAgLyoqIENvbnZlcnRzIGl0cyBhcmd1bWVudCBpbiBhIGZ1bmN0aW9uLlxyXG4gICAgKiBAcGFyYW0ge2FueX0geCBBIGZ1bmN0aW9uLCBhbiBhcnJheSwgb3IgYSBzY2FsYXIuXHJcbiAgICAqIEByZXR1cm4ge2Z1bmN0aW9ufVxyXG4gICAgKiAtICd4JyBpZiBpdCBpcyBhIGZ1bmN0aW9uLlxyXG4gICAgKiAtIElmICd4JyBpcyBhIHNjYWxhciwgaXQgcmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgYWx3YXlzIHJldHVybnMgJ3gnXHJcbiAgICAqIC0gSWYgJ3gnIGlzIGFuIGFycmF5IGl0IHJldHVybnMgdGhlIGZ1bmN0aW9uIChkLCBpKSAtPiB4W2ldXHJcbiAgICAqL1xyXG4gIGZ1bmN0aW9uIHRvRnVuY3Rpb24oeCkge1xyXG4gICAgaWYgKHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAoeCk7XHJcbiAgICB4ID0gdG9BcnJheSh4KTtcclxuICAgIHJldHVybiBmdW5jdGlvbihkLCBpKSB7cmV0dXJuIHhbaSAlIHgubGVuZ3RoXX07XHJcbiAgfVxyXG5cclxuICAvKiogVHJhbnNmb3JtcyBhIG51bWJlciBpbiBhIHByZXR0eSBhbmQgc21hbGwgc3RyaW5nXHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXJcclxuICAgICogQHJldHVybiB7c3RyaW5nfVxyXG4gICAgKiBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIG51bWJlci4gSXQgb25seSBrZWVwcyBhdCBtb3N0IDIgZGVjaW1hbFxyXG4gICAgKiBkaWdpdHMgYW5kIGl0IGFkZHMgc3VmZml4ZXMgXCJLXCIsIFwiTVwiLCBcIkJcIiwgXCJUXCIgZm9yIGxhcmdlIHZhbHVlcy5cclxuICAgICovXHJcbiAgZnVuY3Rpb24gcHJldHR5TnVtYmVyKG51bWJlcikge1xyXG4gICAgaWYgKGlzTmFOKG51bWJlcikgfHwgIWlzRmluaXRlKG51bWJlcikpIHJldHVybiBcIlwiO1xyXG5cclxuICAgIHZhciBhYnNWYWwgPSBNYXRoLmFicyhudW1iZXIpO1xyXG4gICAgdmFyIHNpZ249IG51bWJlciA8IDA/IFwiLVwiOiBcIlwiO1xyXG4gICAgdmFyIHNjYWxlO1xyXG5cclxuICAgIGlmKCBhYnNWYWwgPCAxMDAwICkge1xyXG4gICAgICAgIHNjYWxlID0gJyc7XHJcbiAgICB9IGVsc2UgaWYoIGFic1ZhbCA8IDEwMDAwMDAgKSB7XHJcbiAgICAgICAgc2NhbGUgPSAnSyc7XHJcbiAgICAgICAgYWJzVmFsID0gYWJzVmFsLzEwMDA7XHJcblxyXG4gICAgfSBlbHNlIGlmKCBhYnNWYWwgPCAxMDAwMDAwMDAwICkge1xyXG4gICAgICAgIHNjYWxlID0gJ00nO1xyXG4gICAgICAgIGFic1ZhbCA9IGFic1ZhbC8xMDAwMDAwO1xyXG5cclxuICAgIH0gZWxzZSBpZiggYWJzVmFsIDwgMTAwMDAwMDAwMDAwMCApIHtcclxuICAgICAgICBzY2FsZSA9ICdCJztcclxuICAgICAgICBhYnNWYWwgPSBhYnNWYWwvMTAwMDAwMDAwMDtcclxuXHJcbiAgICB9IGVsc2UgaWYoIGFic1ZhbCA8IDEwMDAwMDAwMDAwMDAwMDAgKSB7XHJcbiAgICAgICAgc2NhbGUgPSAnVCc7XHJcbiAgICAgICAgYWJzVmFsID0gYWJzVmFsLzEwMDAwMDAwMDAwMDA7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGFic1ZhbCA+IDEwKSBhYnNWYWwgPSByb3VuZFRvKGFic1ZhbCk7XHJcbiAgICBlbHNlIGlmIChhYnNWYWwgPiAxKSBhYnNWYWwgPSByb3VuZFRvKGFic1ZhbCwgMTAsIHRydWUpO1xyXG4gICAgZWxzZSBhYnNWYWwgPSByb3VuZFRvKGFic1ZhbCwgMTAwLCB0cnVlKTtcclxuXHJcbiAgICByZXR1cm4gc2lnbiArIGFic1ZhbCArIHNjYWxlO1xyXG4gIH1cclxuXHJcbiAgLyoqIFJvdW5kIGEgbnVtYmVyXHJcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXJcclxuICAgICogQHBhcmFtIHtudW1iZXJ9IHRvOiBkZXNpcmVkIHByZWNpc2lvblxyXG4gICAgKiBAcGFyYW0ge2Jvb2xlYW59IGludmVyc2UgSWYgdHJ1ZSwgbnVtYmVyIGlzIHJvdW5kZWQgYXQgdGhlIDEgLyAndG8nXHJcbiAgICAqL1xyXG4gIGZ1bmN0aW9uIHJvdW5kVG8obnVtYmVyLCB0bywgaW52ZXJzZSkge1xyXG4gICAgdG8gPSB0byB8fCAxO1xyXG4gICAgaWYgKGludmVyc2UpIHJldHVybiBNYXRoLnJvdW5kKG51bWJlciAqIHRvKSAvIHRvO1xyXG4gICAgZWxzZSByZXR1cm4gTWF0aC5yb3VuZChudW1iZXIgLyB0bykgKiB0bztcclxuICB9XHJcbn0oKSk7XHJcbiIsIi8vIFRpbnlDb2xvciB2MS40LjFcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9iZ3JpbnMvVGlueUNvbG9yXG4vLyBCcmlhbiBHcmluc3RlYWQsIE1JVCBMaWNlbnNlXG5cbihmdW5jdGlvbihNYXRoKSB7XG5cbnZhciB0cmltTGVmdCA9IC9eXFxzKy8sXG4gICAgdHJpbVJpZ2h0ID0gL1xccyskLyxcbiAgICB0aW55Q291bnRlciA9IDAsXG4gICAgbWF0aFJvdW5kID0gTWF0aC5yb3VuZCxcbiAgICBtYXRoTWluID0gTWF0aC5taW4sXG4gICAgbWF0aE1heCA9IE1hdGgubWF4LFxuICAgIG1hdGhSYW5kb20gPSBNYXRoLnJhbmRvbTtcblxuZnVuY3Rpb24gdGlueWNvbG9yIChjb2xvciwgb3B0cykge1xuXG4gICAgY29sb3IgPSAoY29sb3IpID8gY29sb3IgOiAnJztcbiAgICBvcHRzID0gb3B0cyB8fCB7IH07XG5cbiAgICAvLyBJZiBpbnB1dCBpcyBhbHJlYWR5IGEgdGlueWNvbG9yLCByZXR1cm4gaXRzZWxmXG4gICAgaWYgKGNvbG9yIGluc3RhbmNlb2YgdGlueWNvbG9yKSB7XG4gICAgICAgcmV0dXJuIGNvbG9yO1xuICAgIH1cbiAgICAvLyBJZiB3ZSBhcmUgY2FsbGVkIGFzIGEgZnVuY3Rpb24sIGNhbGwgdXNpbmcgbmV3IGluc3RlYWRcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgdGlueWNvbG9yKSkge1xuICAgICAgICByZXR1cm4gbmV3IHRpbnljb2xvcihjb2xvciwgb3B0cyk7XG4gICAgfVxuXG4gICAgdmFyIHJnYiA9IGlucHV0VG9SR0IoY29sb3IpO1xuICAgIHRoaXMuX29yaWdpbmFsSW5wdXQgPSBjb2xvcixcbiAgICB0aGlzLl9yID0gcmdiLnIsXG4gICAgdGhpcy5fZyA9IHJnYi5nLFxuICAgIHRoaXMuX2IgPSByZ2IuYixcbiAgICB0aGlzLl9hID0gcmdiLmEsXG4gICAgdGhpcy5fcm91bmRBID0gbWF0aFJvdW5kKDEwMCp0aGlzLl9hKSAvIDEwMCxcbiAgICB0aGlzLl9mb3JtYXQgPSBvcHRzLmZvcm1hdCB8fCByZ2IuZm9ybWF0O1xuICAgIHRoaXMuX2dyYWRpZW50VHlwZSA9IG9wdHMuZ3JhZGllbnRUeXBlO1xuXG4gICAgLy8gRG9uJ3QgbGV0IHRoZSByYW5nZSBvZiBbMCwyNTVdIGNvbWUgYmFjayBpbiBbMCwxXS5cbiAgICAvLyBQb3RlbnRpYWxseSBsb3NlIGEgbGl0dGxlIGJpdCBvZiBwcmVjaXNpb24gaGVyZSwgYnV0IHdpbGwgZml4IGlzc3VlcyB3aGVyZVxuICAgIC8vIC41IGdldHMgaW50ZXJwcmV0ZWQgYXMgaGFsZiBvZiB0aGUgdG90YWwsIGluc3RlYWQgb2YgaGFsZiBvZiAxXG4gICAgLy8gSWYgaXQgd2FzIHN1cHBvc2VkIHRvIGJlIDEyOCwgdGhpcyB3YXMgYWxyZWFkeSB0YWtlbiBjYXJlIG9mIGJ5IGBpbnB1dFRvUmdiYFxuICAgIGlmICh0aGlzLl9yIDwgMSkgeyB0aGlzLl9yID0gbWF0aFJvdW5kKHRoaXMuX3IpOyB9XG4gICAgaWYgKHRoaXMuX2cgPCAxKSB7IHRoaXMuX2cgPSBtYXRoUm91bmQodGhpcy5fZyk7IH1cbiAgICBpZiAodGhpcy5fYiA8IDEpIHsgdGhpcy5fYiA9IG1hdGhSb3VuZCh0aGlzLl9iKTsgfVxuXG4gICAgdGhpcy5fb2sgPSByZ2Iub2s7XG4gICAgdGhpcy5fdGNfaWQgPSB0aW55Q291bnRlcisrO1xufVxuXG50aW55Y29sb3IucHJvdG90eXBlID0ge1xuICAgIGlzRGFyazogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJyaWdodG5lc3MoKSA8IDEyODtcbiAgICB9LFxuICAgIGlzTGlnaHQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gIXRoaXMuaXNEYXJrKCk7XG4gICAgfSxcbiAgICBpc1ZhbGlkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29rO1xuICAgIH0sXG4gICAgZ2V0T3JpZ2luYWxJbnB1dDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fb3JpZ2luYWxJbnB1dDtcbiAgICB9LFxuICAgIGdldEZvcm1hdDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb3JtYXQ7XG4gICAgfSxcbiAgICBnZXRBbHBoYTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hO1xuICAgIH0sXG4gICAgZ2V0QnJpZ2h0bmVzczogZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vaHR0cDovL3d3dy53My5vcmcvVFIvQUVSVCNjb2xvci1jb250cmFzdFxuICAgICAgICB2YXIgcmdiID0gdGhpcy50b1JnYigpO1xuICAgICAgICByZXR1cm4gKHJnYi5yICogMjk5ICsgcmdiLmcgKiA1ODcgKyByZ2IuYiAqIDExNCkgLyAxMDAwO1xuICAgIH0sXG4gICAgZ2V0THVtaW5hbmNlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgLy9odHRwOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy1XQ0FHMjAtMjAwODEyMTEvI3JlbGF0aXZlbHVtaW5hbmNlZGVmXG4gICAgICAgIHZhciByZ2IgPSB0aGlzLnRvUmdiKCk7XG4gICAgICAgIHZhciBSc1JHQiwgR3NSR0IsIEJzUkdCLCBSLCBHLCBCO1xuICAgICAgICBSc1JHQiA9IHJnYi5yLzI1NTtcbiAgICAgICAgR3NSR0IgPSByZ2IuZy8yNTU7XG4gICAgICAgIEJzUkdCID0gcmdiLmIvMjU1O1xuXG4gICAgICAgIGlmIChSc1JHQiA8PSAwLjAzOTI4KSB7UiA9IFJzUkdCIC8gMTIuOTI7fSBlbHNlIHtSID0gTWF0aC5wb3coKChSc1JHQiArIDAuMDU1KSAvIDEuMDU1KSwgMi40KTt9XG4gICAgICAgIGlmIChHc1JHQiA8PSAwLjAzOTI4KSB7RyA9IEdzUkdCIC8gMTIuOTI7fSBlbHNlIHtHID0gTWF0aC5wb3coKChHc1JHQiArIDAuMDU1KSAvIDEuMDU1KSwgMi40KTt9XG4gICAgICAgIGlmIChCc1JHQiA8PSAwLjAzOTI4KSB7QiA9IEJzUkdCIC8gMTIuOTI7fSBlbHNlIHtCID0gTWF0aC5wb3coKChCc1JHQiArIDAuMDU1KSAvIDEuMDU1KSwgMi40KTt9XG4gICAgICAgIHJldHVybiAoMC4yMTI2ICogUikgKyAoMC43MTUyICogRykgKyAoMC4wNzIyICogQik7XG4gICAgfSxcbiAgICBzZXRBbHBoYTogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgdGhpcy5fYSA9IGJvdW5kQWxwaGEodmFsdWUpO1xuICAgICAgICB0aGlzLl9yb3VuZEEgPSBtYXRoUm91bmQoMTAwKnRoaXMuX2EpIC8gMTAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIHRvSHN2OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGhzdiA9IHJnYlRvSHN2KHRoaXMuX3IsIHRoaXMuX2csIHRoaXMuX2IpO1xuICAgICAgICByZXR1cm4geyBoOiBoc3YuaCAqIDM2MCwgczogaHN2LnMsIHY6IGhzdi52LCBhOiB0aGlzLl9hIH07XG4gICAgfSxcbiAgICB0b0hzdlN0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBoc3YgPSByZ2JUb0hzdih0aGlzLl9yLCB0aGlzLl9nLCB0aGlzLl9iKTtcbiAgICAgICAgdmFyIGggPSBtYXRoUm91bmQoaHN2LmggKiAzNjApLCBzID0gbWF0aFJvdW5kKGhzdi5zICogMTAwKSwgdiA9IG1hdGhSb3VuZChoc3YudiAqIDEwMCk7XG4gICAgICAgIHJldHVybiAodGhpcy5fYSA9PSAxKSA/XG4gICAgICAgICAgXCJoc3YoXCIgICsgaCArIFwiLCBcIiArIHMgKyBcIiUsIFwiICsgdiArIFwiJSlcIiA6XG4gICAgICAgICAgXCJoc3ZhKFwiICsgaCArIFwiLCBcIiArIHMgKyBcIiUsIFwiICsgdiArIFwiJSwgXCIrIHRoaXMuX3JvdW5kQSArIFwiKVwiO1xuICAgIH0sXG4gICAgdG9Ic2w6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgaHNsID0gcmdiVG9Ic2wodGhpcy5fciwgdGhpcy5fZywgdGhpcy5fYik7XG4gICAgICAgIHJldHVybiB7IGg6IGhzbC5oICogMzYwLCBzOiBoc2wucywgbDogaHNsLmwsIGE6IHRoaXMuX2EgfTtcbiAgICB9LFxuICAgIHRvSHNsU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGhzbCA9IHJnYlRvSHNsKHRoaXMuX3IsIHRoaXMuX2csIHRoaXMuX2IpO1xuICAgICAgICB2YXIgaCA9IG1hdGhSb3VuZChoc2wuaCAqIDM2MCksIHMgPSBtYXRoUm91bmQoaHNsLnMgKiAxMDApLCBsID0gbWF0aFJvdW5kKGhzbC5sICogMTAwKTtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9hID09IDEpID9cbiAgICAgICAgICBcImhzbChcIiAgKyBoICsgXCIsIFwiICsgcyArIFwiJSwgXCIgKyBsICsgXCIlKVwiIDpcbiAgICAgICAgICBcImhzbGEoXCIgKyBoICsgXCIsIFwiICsgcyArIFwiJSwgXCIgKyBsICsgXCIlLCBcIisgdGhpcy5fcm91bmRBICsgXCIpXCI7XG4gICAgfSxcbiAgICB0b0hleDogZnVuY3Rpb24oYWxsb3czQ2hhcikge1xuICAgICAgICByZXR1cm4gcmdiVG9IZXgodGhpcy5fciwgdGhpcy5fZywgdGhpcy5fYiwgYWxsb3czQ2hhcik7XG4gICAgfSxcbiAgICB0b0hleFN0cmluZzogZnVuY3Rpb24oYWxsb3czQ2hhcikge1xuICAgICAgICByZXR1cm4gJyMnICsgdGhpcy50b0hleChhbGxvdzNDaGFyKTtcbiAgICB9LFxuICAgIHRvSGV4ODogZnVuY3Rpb24oYWxsb3c0Q2hhcikge1xuICAgICAgICByZXR1cm4gcmdiYVRvSGV4KHRoaXMuX3IsIHRoaXMuX2csIHRoaXMuX2IsIHRoaXMuX2EsIGFsbG93NENoYXIpO1xuICAgIH0sXG4gICAgdG9IZXg4U3RyaW5nOiBmdW5jdGlvbihhbGxvdzRDaGFyKSB7XG4gICAgICAgIHJldHVybiAnIycgKyB0aGlzLnRvSGV4OChhbGxvdzRDaGFyKTtcbiAgICB9LFxuICAgIHRvUmdiOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHsgcjogbWF0aFJvdW5kKHRoaXMuX3IpLCBnOiBtYXRoUm91bmQodGhpcy5fZyksIGI6IG1hdGhSb3VuZCh0aGlzLl9iKSwgYTogdGhpcy5fYSB9O1xuICAgIH0sXG4gICAgdG9SZ2JTdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gKHRoaXMuX2EgPT0gMSkgP1xuICAgICAgICAgIFwicmdiKFwiICArIG1hdGhSb3VuZCh0aGlzLl9yKSArIFwiLCBcIiArIG1hdGhSb3VuZCh0aGlzLl9nKSArIFwiLCBcIiArIG1hdGhSb3VuZCh0aGlzLl9iKSArIFwiKVwiIDpcbiAgICAgICAgICBcInJnYmEoXCIgKyBtYXRoUm91bmQodGhpcy5fcikgKyBcIiwgXCIgKyBtYXRoUm91bmQodGhpcy5fZykgKyBcIiwgXCIgKyBtYXRoUm91bmQodGhpcy5fYikgKyBcIiwgXCIgKyB0aGlzLl9yb3VuZEEgKyBcIilcIjtcbiAgICB9LFxuICAgIHRvUGVyY2VudGFnZVJnYjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7IHI6IG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX3IsIDI1NSkgKiAxMDApICsgXCIlXCIsIGc6IG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX2csIDI1NSkgKiAxMDApICsgXCIlXCIsIGI6IG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX2IsIDI1NSkgKiAxMDApICsgXCIlXCIsIGE6IHRoaXMuX2EgfTtcbiAgICB9LFxuICAgIHRvUGVyY2VudGFnZVJnYlN0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiAodGhpcy5fYSA9PSAxKSA/XG4gICAgICAgICAgXCJyZ2IoXCIgICsgbWF0aFJvdW5kKGJvdW5kMDEodGhpcy5fciwgMjU1KSAqIDEwMCkgKyBcIiUsIFwiICsgbWF0aFJvdW5kKGJvdW5kMDEodGhpcy5fZywgMjU1KSAqIDEwMCkgKyBcIiUsIFwiICsgbWF0aFJvdW5kKGJvdW5kMDEodGhpcy5fYiwgMjU1KSAqIDEwMCkgKyBcIiUpXCIgOlxuICAgICAgICAgIFwicmdiYShcIiArIG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX3IsIDI1NSkgKiAxMDApICsgXCIlLCBcIiArIG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX2csIDI1NSkgKiAxMDApICsgXCIlLCBcIiArIG1hdGhSb3VuZChib3VuZDAxKHRoaXMuX2IsIDI1NSkgKiAxMDApICsgXCIlLCBcIiArIHRoaXMuX3JvdW5kQSArIFwiKVwiO1xuICAgIH0sXG4gICAgdG9OYW1lOiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2EgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBcInRyYW5zcGFyZW50XCI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fYSA8IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBoZXhOYW1lc1tyZ2JUb0hleCh0aGlzLl9yLCB0aGlzLl9nLCB0aGlzLl9iLCB0cnVlKV0gfHwgZmFsc2U7XG4gICAgfSxcbiAgICB0b0ZpbHRlcjogZnVuY3Rpb24oc2Vjb25kQ29sb3IpIHtcbiAgICAgICAgdmFyIGhleDhTdHJpbmcgPSAnIycgKyByZ2JhVG9BcmdiSGV4KHRoaXMuX3IsIHRoaXMuX2csIHRoaXMuX2IsIHRoaXMuX2EpO1xuICAgICAgICB2YXIgc2Vjb25kSGV4OFN0cmluZyA9IGhleDhTdHJpbmc7XG4gICAgICAgIHZhciBncmFkaWVudFR5cGUgPSB0aGlzLl9ncmFkaWVudFR5cGUgPyBcIkdyYWRpZW50VHlwZSA9IDEsIFwiIDogXCJcIjtcblxuICAgICAgICBpZiAoc2Vjb25kQ29sb3IpIHtcbiAgICAgICAgICAgIHZhciBzID0gdGlueWNvbG9yKHNlY29uZENvbG9yKTtcbiAgICAgICAgICAgIHNlY29uZEhleDhTdHJpbmcgPSAnIycgKyByZ2JhVG9BcmdiSGV4KHMuX3IsIHMuX2csIHMuX2IsIHMuX2EpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFwicHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LmdyYWRpZW50KFwiK2dyYWRpZW50VHlwZStcInN0YXJ0Q29sb3JzdHI9XCIraGV4OFN0cmluZytcIixlbmRDb2xvcnN0cj1cIitzZWNvbmRIZXg4U3RyaW5nK1wiKVwiO1xuICAgIH0sXG4gICAgdG9TdHJpbmc6IGZ1bmN0aW9uKGZvcm1hdCkge1xuICAgICAgICB2YXIgZm9ybWF0U2V0ID0gISFmb3JtYXQ7XG4gICAgICAgIGZvcm1hdCA9IGZvcm1hdCB8fCB0aGlzLl9mb3JtYXQ7XG5cbiAgICAgICAgdmFyIGZvcm1hdHRlZFN0cmluZyA9IGZhbHNlO1xuICAgICAgICB2YXIgaGFzQWxwaGEgPSB0aGlzLl9hIDwgMSAmJiB0aGlzLl9hID49IDA7XG4gICAgICAgIHZhciBuZWVkc0FscGhhRm9ybWF0ID0gIWZvcm1hdFNldCAmJiBoYXNBbHBoYSAmJiAoZm9ybWF0ID09PSBcImhleFwiIHx8IGZvcm1hdCA9PT0gXCJoZXg2XCIgfHwgZm9ybWF0ID09PSBcImhleDNcIiB8fCBmb3JtYXQgPT09IFwiaGV4NFwiIHx8IGZvcm1hdCA9PT0gXCJoZXg4XCIgfHwgZm9ybWF0ID09PSBcIm5hbWVcIik7XG5cbiAgICAgICAgaWYgKG5lZWRzQWxwaGFGb3JtYXQpIHtcbiAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgXCJ0cmFuc3BhcmVudFwiLCBhbGwgb3RoZXIgbm9uLWFscGhhIGZvcm1hdHNcbiAgICAgICAgICAgIC8vIHdpbGwgcmV0dXJuIHJnYmEgd2hlbiB0aGVyZSBpcyB0cmFuc3BhcmVuY3kuXG4gICAgICAgICAgICBpZiAoZm9ybWF0ID09PSBcIm5hbWVcIiAmJiB0aGlzLl9hID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9OYW1lKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50b1JnYlN0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmb3JtYXQgPT09IFwicmdiXCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9SZ2JTdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9ybWF0ID09PSBcInByZ2JcIikge1xuICAgICAgICAgICAgZm9ybWF0dGVkU3RyaW5nID0gdGhpcy50b1BlcmNlbnRhZ2VSZ2JTdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9ybWF0ID09PSBcImhleFwiIHx8IGZvcm1hdCA9PT0gXCJoZXg2XCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9IZXhTdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9ybWF0ID09PSBcImhleDNcIikge1xuICAgICAgICAgICAgZm9ybWF0dGVkU3RyaW5nID0gdGhpcy50b0hleFN0cmluZyh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9ybWF0ID09PSBcImhleDRcIikge1xuICAgICAgICAgICAgZm9ybWF0dGVkU3RyaW5nID0gdGhpcy50b0hleDhTdHJpbmcodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJoZXg4XCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9IZXg4U3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJuYW1lXCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9OYW1lKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJoc2xcIikge1xuICAgICAgICAgICAgZm9ybWF0dGVkU3RyaW5nID0gdGhpcy50b0hzbFN0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmb3JtYXQgPT09IFwiaHN2XCIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZFN0cmluZyA9IHRoaXMudG9Ic3ZTdHJpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXR0ZWRTdHJpbmcgfHwgdGhpcy50b0hleFN0cmluZygpO1xuICAgIH0sXG4gICAgY2xvbmU6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGlueWNvbG9yKHRoaXMudG9TdHJpbmcoKSk7XG4gICAgfSxcblxuICAgIF9hcHBseU1vZGlmaWNhdGlvbjogZnVuY3Rpb24oZm4sIGFyZ3MpIHtcbiAgICAgICAgdmFyIGNvbG9yID0gZm4uYXBwbHkobnVsbCwgW3RoaXNdLmNvbmNhdChbXS5zbGljZS5jYWxsKGFyZ3MpKSk7XG4gICAgICAgIHRoaXMuX3IgPSBjb2xvci5fcjtcbiAgICAgICAgdGhpcy5fZyA9IGNvbG9yLl9nO1xuICAgICAgICB0aGlzLl9iID0gY29sb3IuX2I7XG4gICAgICAgIHRoaXMuc2V0QWxwaGEoY29sb3IuX2EpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGxpZ2h0ZW46IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlNb2RpZmljYXRpb24obGlnaHRlbiwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGJyaWdodGVuOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5TW9kaWZpY2F0aW9uKGJyaWdodGVuLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgZGFya2VuOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5TW9kaWZpY2F0aW9uKGRhcmtlbiwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGRlc2F0dXJhdGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlNb2RpZmljYXRpb24oZGVzYXR1cmF0ZSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHNhdHVyYXRlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5TW9kaWZpY2F0aW9uKHNhdHVyYXRlLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgZ3JleXNjYWxlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5TW9kaWZpY2F0aW9uKGdyZXlzY2FsZSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHNwaW46IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlNb2RpZmljYXRpb24oc3BpbiwgYXJndW1lbnRzKTtcbiAgICB9LFxuXG4gICAgX2FwcGx5Q29tYmluYXRpb246IGZ1bmN0aW9uKGZuLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBmbi5hcHBseShudWxsLCBbdGhpc10uY29uY2F0KFtdLnNsaWNlLmNhbGwoYXJncykpKTtcbiAgICB9LFxuICAgIGFuYWxvZ291czogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUNvbWJpbmF0aW9uKGFuYWxvZ291cywgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGNvbXBsZW1lbnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlDb21iaW5hdGlvbihjb21wbGVtZW50LCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgbW9ub2Nocm9tYXRpYzogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUNvbWJpbmF0aW9uKG1vbm9jaHJvbWF0aWMsIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBzcGxpdGNvbXBsZW1lbnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlDb21iaW5hdGlvbihzcGxpdGNvbXBsZW1lbnQsIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICB0cmlhZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUNvbWJpbmF0aW9uKHRyaWFkLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgdGV0cmFkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5Q29tYmluYXRpb24odGV0cmFkLCBhcmd1bWVudHMpO1xuICAgIH1cbn07XG5cbi8vIElmIGlucHV0IGlzIGFuIG9iamVjdCwgZm9yY2UgMSBpbnRvIFwiMS4wXCIgdG8gaGFuZGxlIHJhdGlvcyBwcm9wZXJseVxuLy8gU3RyaW5nIGlucHV0IHJlcXVpcmVzIFwiMS4wXCIgYXMgaW5wdXQsIHNvIDEgd2lsbCBiZSB0cmVhdGVkIGFzIDFcbnRpbnljb2xvci5mcm9tUmF0aW8gPSBmdW5jdGlvbihjb2xvciwgb3B0cykge1xuICAgIGlmICh0eXBlb2YgY29sb3IgPT0gXCJvYmplY3RcIikge1xuICAgICAgICB2YXIgbmV3Q29sb3IgPSB7fTtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBjb2xvcikge1xuICAgICAgICAgICAgaWYgKGNvbG9yLmhhc093blByb3BlcnR5KGkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgPT09IFwiYVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld0NvbG9yW2ldID0gY29sb3JbaV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBuZXdDb2xvcltpXSA9IGNvbnZlcnRUb1BlcmNlbnRhZ2UoY29sb3JbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb2xvciA9IG5ld0NvbG9yO1xuICAgIH1cblxuICAgIHJldHVybiB0aW55Y29sb3IoY29sb3IsIG9wdHMpO1xufTtcblxuLy8gR2l2ZW4gYSBzdHJpbmcgb3Igb2JqZWN0LCBjb252ZXJ0IHRoYXQgaW5wdXQgdG8gUkdCXG4vLyBQb3NzaWJsZSBzdHJpbmcgaW5wdXRzOlxuLy9cbi8vICAgICBcInJlZFwiXG4vLyAgICAgXCIjZjAwXCIgb3IgXCJmMDBcIlxuLy8gICAgIFwiI2ZmMDAwMFwiIG9yIFwiZmYwMDAwXCJcbi8vICAgICBcIiNmZjAwMDAwMFwiIG9yIFwiZmYwMDAwMDBcIlxuLy8gICAgIFwicmdiIDI1NSAwIDBcIiBvciBcInJnYiAoMjU1LCAwLCAwKVwiXG4vLyAgICAgXCJyZ2IgMS4wIDAgMFwiIG9yIFwicmdiICgxLCAwLCAwKVwiXG4vLyAgICAgXCJyZ2JhICgyNTUsIDAsIDAsIDEpXCIgb3IgXCJyZ2JhIDI1NSwgMCwgMCwgMVwiXG4vLyAgICAgXCJyZ2JhICgxLjAsIDAsIDAsIDEpXCIgb3IgXCJyZ2JhIDEuMCwgMCwgMCwgMVwiXG4vLyAgICAgXCJoc2woMCwgMTAwJSwgNTAlKVwiIG9yIFwiaHNsIDAgMTAwJSA1MCVcIlxuLy8gICAgIFwiaHNsYSgwLCAxMDAlLCA1MCUsIDEpXCIgb3IgXCJoc2xhIDAgMTAwJSA1MCUsIDFcIlxuLy8gICAgIFwiaHN2KDAsIDEwMCUsIDEwMCUpXCIgb3IgXCJoc3YgMCAxMDAlIDEwMCVcIlxuLy9cbmZ1bmN0aW9uIGlucHV0VG9SR0IoY29sb3IpIHtcblxuICAgIHZhciByZ2IgPSB7IHI6IDAsIGc6IDAsIGI6IDAgfTtcbiAgICB2YXIgYSA9IDE7XG4gICAgdmFyIHMgPSBudWxsO1xuICAgIHZhciB2ID0gbnVsbDtcbiAgICB2YXIgbCA9IG51bGw7XG4gICAgdmFyIG9rID0gZmFsc2U7XG4gICAgdmFyIGZvcm1hdCA9IGZhbHNlO1xuXG4gICAgaWYgKHR5cGVvZiBjb2xvciA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGNvbG9yID0gc3RyaW5nSW5wdXRUb09iamVjdChjb2xvcik7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBjb2xvciA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIGlmIChpc1ZhbGlkQ1NTVW5pdChjb2xvci5yKSAmJiBpc1ZhbGlkQ1NTVW5pdChjb2xvci5nKSAmJiBpc1ZhbGlkQ1NTVW5pdChjb2xvci5iKSkge1xuICAgICAgICAgICAgcmdiID0gcmdiVG9SZ2IoY29sb3IuciwgY29sb3IuZywgY29sb3IuYik7XG4gICAgICAgICAgICBvayA9IHRydWU7XG4gICAgICAgICAgICBmb3JtYXQgPSBTdHJpbmcoY29sb3Iucikuc3Vic3RyKC0xKSA9PT0gXCIlXCIgPyBcInByZ2JcIiA6IFwicmdiXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNWYWxpZENTU1VuaXQoY29sb3IuaCkgJiYgaXNWYWxpZENTU1VuaXQoY29sb3IucykgJiYgaXNWYWxpZENTU1VuaXQoY29sb3IudikpIHtcbiAgICAgICAgICAgIHMgPSBjb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yLnMpO1xuICAgICAgICAgICAgdiA9IGNvbnZlcnRUb1BlcmNlbnRhZ2UoY29sb3Iudik7XG4gICAgICAgICAgICByZ2IgPSBoc3ZUb1JnYihjb2xvci5oLCBzLCB2KTtcbiAgICAgICAgICAgIG9rID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvcm1hdCA9IFwiaHN2XCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNWYWxpZENTU1VuaXQoY29sb3IuaCkgJiYgaXNWYWxpZENTU1VuaXQoY29sb3IucykgJiYgaXNWYWxpZENTU1VuaXQoY29sb3IubCkpIHtcbiAgICAgICAgICAgIHMgPSBjb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yLnMpO1xuICAgICAgICAgICAgbCA9IGNvbnZlcnRUb1BlcmNlbnRhZ2UoY29sb3IubCk7XG4gICAgICAgICAgICByZ2IgPSBoc2xUb1JnYihjb2xvci5oLCBzLCBsKTtcbiAgICAgICAgICAgIG9rID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvcm1hdCA9IFwiaHNsXCI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29sb3IuaGFzT3duUHJvcGVydHkoXCJhXCIpKSB7XG4gICAgICAgICAgICBhID0gY29sb3IuYTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGEgPSBib3VuZEFscGhhKGEpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgb2s6IG9rLFxuICAgICAgICBmb3JtYXQ6IGNvbG9yLmZvcm1hdCB8fCBmb3JtYXQsXG4gICAgICAgIHI6IG1hdGhNaW4oMjU1LCBtYXRoTWF4KHJnYi5yLCAwKSksXG4gICAgICAgIGc6IG1hdGhNaW4oMjU1LCBtYXRoTWF4KHJnYi5nLCAwKSksXG4gICAgICAgIGI6IG1hdGhNaW4oMjU1LCBtYXRoTWF4KHJnYi5iLCAwKSksXG4gICAgICAgIGE6IGFcbiAgICB9O1xufVxuXG5cbi8vIENvbnZlcnNpb24gRnVuY3Rpb25zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBgcmdiVG9Ic2xgLCBgcmdiVG9Ic3ZgLCBgaHNsVG9SZ2JgLCBgaHN2VG9SZ2JgIG1vZGlmaWVkIGZyb206XG4vLyA8aHR0cDovL21qaWphY2tzb24uY29tLzIwMDgvMDIvcmdiLXRvLWhzbC1hbmQtcmdiLXRvLWhzdi1jb2xvci1tb2RlbC1jb252ZXJzaW9uLWFsZ29yaXRobXMtaW4tamF2YXNjcmlwdD5cblxuLy8gYHJnYlRvUmdiYFxuLy8gSGFuZGxlIGJvdW5kcyAvIHBlcmNlbnRhZ2UgY2hlY2tpbmcgdG8gY29uZm9ybSB0byBDU1MgY29sb3Igc3BlY1xuLy8gPGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtY29sb3IvPlxuLy8gKkFzc3VtZXM6KiByLCBnLCBiIGluIFswLCAyNTVdIG9yIFswLCAxXVxuLy8gKlJldHVybnM6KiB7IHIsIGcsIGIgfSBpbiBbMCwgMjU1XVxuZnVuY3Rpb24gcmdiVG9SZ2IociwgZywgYil7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcjogYm91bmQwMShyLCAyNTUpICogMjU1LFxuICAgICAgICBnOiBib3VuZDAxKGcsIDI1NSkgKiAyNTUsXG4gICAgICAgIGI6IGJvdW5kMDEoYiwgMjU1KSAqIDI1NVxuICAgIH07XG59XG5cbi8vIGByZ2JUb0hzbGBcbi8vIENvbnZlcnRzIGFuIFJHQiBjb2xvciB2YWx1ZSB0byBIU0wuXG4vLyAqQXNzdW1lczoqIHIsIGcsIGFuZCBiIGFyZSBjb250YWluZWQgaW4gWzAsIDI1NV0gb3IgWzAsIDFdXG4vLyAqUmV0dXJuczoqIHsgaCwgcywgbCB9IGluIFswLDFdXG5mdW5jdGlvbiByZ2JUb0hzbChyLCBnLCBiKSB7XG5cbiAgICByID0gYm91bmQwMShyLCAyNTUpO1xuICAgIGcgPSBib3VuZDAxKGcsIDI1NSk7XG4gICAgYiA9IGJvdW5kMDEoYiwgMjU1KTtcblxuICAgIHZhciBtYXggPSBtYXRoTWF4KHIsIGcsIGIpLCBtaW4gPSBtYXRoTWluKHIsIGcsIGIpO1xuICAgIHZhciBoLCBzLCBsID0gKG1heCArIG1pbikgLyAyO1xuXG4gICAgaWYobWF4ID09IG1pbikge1xuICAgICAgICBoID0gcyA9IDA7IC8vIGFjaHJvbWF0aWNcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBkID0gbWF4IC0gbWluO1xuICAgICAgICBzID0gbCA+IDAuNSA/IGQgLyAoMiAtIG1heCAtIG1pbikgOiBkIC8gKG1heCArIG1pbik7XG4gICAgICAgIHN3aXRjaChtYXgpIHtcbiAgICAgICAgICAgIGNhc2UgcjogaCA9IChnIC0gYikgLyBkICsgKGcgPCBiID8gNiA6IDApOyBicmVhaztcbiAgICAgICAgICAgIGNhc2UgZzogaCA9IChiIC0gcikgLyBkICsgMjsgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGI6IGggPSAociAtIGcpIC8gZCArIDQ7IGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaCAvPSA2O1xuICAgIH1cblxuICAgIHJldHVybiB7IGg6IGgsIHM6IHMsIGw6IGwgfTtcbn1cblxuLy8gYGhzbFRvUmdiYFxuLy8gQ29udmVydHMgYW4gSFNMIGNvbG9yIHZhbHVlIHRvIFJHQi5cbi8vICpBc3N1bWVzOiogaCBpcyBjb250YWluZWQgaW4gWzAsIDFdIG9yIFswLCAzNjBdIGFuZCBzIGFuZCBsIGFyZSBjb250YWluZWQgWzAsIDFdIG9yIFswLCAxMDBdXG4vLyAqUmV0dXJuczoqIHsgciwgZywgYiB9IGluIHRoZSBzZXQgWzAsIDI1NV1cbmZ1bmN0aW9uIGhzbFRvUmdiKGgsIHMsIGwpIHtcbiAgICB2YXIgciwgZywgYjtcblxuICAgIGggPSBib3VuZDAxKGgsIDM2MCk7XG4gICAgcyA9IGJvdW5kMDEocywgMTAwKTtcbiAgICBsID0gYm91bmQwMShsLCAxMDApO1xuXG4gICAgZnVuY3Rpb24gaHVlMnJnYihwLCBxLCB0KSB7XG4gICAgICAgIGlmKHQgPCAwKSB0ICs9IDE7XG4gICAgICAgIGlmKHQgPiAxKSB0IC09IDE7XG4gICAgICAgIGlmKHQgPCAxLzYpIHJldHVybiBwICsgKHEgLSBwKSAqIDYgKiB0O1xuICAgICAgICBpZih0IDwgMS8yKSByZXR1cm4gcTtcbiAgICAgICAgaWYodCA8IDIvMykgcmV0dXJuIHAgKyAocSAtIHApICogKDIvMyAtIHQpICogNjtcbiAgICAgICAgcmV0dXJuIHA7XG4gICAgfVxuXG4gICAgaWYocyA9PT0gMCkge1xuICAgICAgICByID0gZyA9IGIgPSBsOyAvLyBhY2hyb21hdGljXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgcSA9IGwgPCAwLjUgPyBsICogKDEgKyBzKSA6IGwgKyBzIC0gbCAqIHM7XG4gICAgICAgIHZhciBwID0gMiAqIGwgLSBxO1xuICAgICAgICByID0gaHVlMnJnYihwLCBxLCBoICsgMS8zKTtcbiAgICAgICAgZyA9IGh1ZTJyZ2IocCwgcSwgaCk7XG4gICAgICAgIGIgPSBodWUycmdiKHAsIHEsIGggLSAxLzMpO1xuICAgIH1cblxuICAgIHJldHVybiB7IHI6IHIgKiAyNTUsIGc6IGcgKiAyNTUsIGI6IGIgKiAyNTUgfTtcbn1cblxuLy8gYHJnYlRvSHN2YFxuLy8gQ29udmVydHMgYW4gUkdCIGNvbG9yIHZhbHVlIHRvIEhTVlxuLy8gKkFzc3VtZXM6KiByLCBnLCBhbmQgYiBhcmUgY29udGFpbmVkIGluIHRoZSBzZXQgWzAsIDI1NV0gb3IgWzAsIDFdXG4vLyAqUmV0dXJuczoqIHsgaCwgcywgdiB9IGluIFswLDFdXG5mdW5jdGlvbiByZ2JUb0hzdihyLCBnLCBiKSB7XG5cbiAgICByID0gYm91bmQwMShyLCAyNTUpO1xuICAgIGcgPSBib3VuZDAxKGcsIDI1NSk7XG4gICAgYiA9IGJvdW5kMDEoYiwgMjU1KTtcblxuICAgIHZhciBtYXggPSBtYXRoTWF4KHIsIGcsIGIpLCBtaW4gPSBtYXRoTWluKHIsIGcsIGIpO1xuICAgIHZhciBoLCBzLCB2ID0gbWF4O1xuXG4gICAgdmFyIGQgPSBtYXggLSBtaW47XG4gICAgcyA9IG1heCA9PT0gMCA/IDAgOiBkIC8gbWF4O1xuXG4gICAgaWYobWF4ID09IG1pbikge1xuICAgICAgICBoID0gMDsgLy8gYWNocm9tYXRpY1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3dpdGNoKG1heCkge1xuICAgICAgICAgICAgY2FzZSByOiBoID0gKGcgLSBiKSAvIGQgKyAoZyA8IGIgPyA2IDogMCk7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBnOiBoID0gKGIgLSByKSAvIGQgKyAyOyBicmVhaztcbiAgICAgICAgICAgIGNhc2UgYjogaCA9IChyIC0gZykgLyBkICsgNDsgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaCAvPSA2O1xuICAgIH1cbiAgICByZXR1cm4geyBoOiBoLCBzOiBzLCB2OiB2IH07XG59XG5cbi8vIGBoc3ZUb1JnYmBcbi8vIENvbnZlcnRzIGFuIEhTViBjb2xvciB2YWx1ZSB0byBSR0IuXG4vLyAqQXNzdW1lczoqIGggaXMgY29udGFpbmVkIGluIFswLCAxXSBvciBbMCwgMzYwXSBhbmQgcyBhbmQgdiBhcmUgY29udGFpbmVkIGluIFswLCAxXSBvciBbMCwgMTAwXVxuLy8gKlJldHVybnM6KiB7IHIsIGcsIGIgfSBpbiB0aGUgc2V0IFswLCAyNTVdXG4gZnVuY3Rpb24gaHN2VG9SZ2IoaCwgcywgdikge1xuXG4gICAgaCA9IGJvdW5kMDEoaCwgMzYwKSAqIDY7XG4gICAgcyA9IGJvdW5kMDEocywgMTAwKTtcbiAgICB2ID0gYm91bmQwMSh2LCAxMDApO1xuXG4gICAgdmFyIGkgPSBNYXRoLmZsb29yKGgpLFxuICAgICAgICBmID0gaCAtIGksXG4gICAgICAgIHAgPSB2ICogKDEgLSBzKSxcbiAgICAgICAgcSA9IHYgKiAoMSAtIGYgKiBzKSxcbiAgICAgICAgdCA9IHYgKiAoMSAtICgxIC0gZikgKiBzKSxcbiAgICAgICAgbW9kID0gaSAlIDYsXG4gICAgICAgIHIgPSBbdiwgcSwgcCwgcCwgdCwgdl1bbW9kXSxcbiAgICAgICAgZyA9IFt0LCB2LCB2LCBxLCBwLCBwXVttb2RdLFxuICAgICAgICBiID0gW3AsIHAsIHQsIHYsIHYsIHFdW21vZF07XG5cbiAgICByZXR1cm4geyByOiByICogMjU1LCBnOiBnICogMjU1LCBiOiBiICogMjU1IH07XG59XG5cbi8vIGByZ2JUb0hleGBcbi8vIENvbnZlcnRzIGFuIFJHQiBjb2xvciB0byBoZXhcbi8vIEFzc3VtZXMgciwgZywgYW5kIGIgYXJlIGNvbnRhaW5lZCBpbiB0aGUgc2V0IFswLCAyNTVdXG4vLyBSZXR1cm5zIGEgMyBvciA2IGNoYXJhY3RlciBoZXhcbmZ1bmN0aW9uIHJnYlRvSGV4KHIsIGcsIGIsIGFsbG93M0NoYXIpIHtcblxuICAgIHZhciBoZXggPSBbXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKHIpLnRvU3RyaW5nKDE2KSksXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKGcpLnRvU3RyaW5nKDE2KSksXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKGIpLnRvU3RyaW5nKDE2KSlcbiAgICBdO1xuXG4gICAgLy8gUmV0dXJuIGEgMyBjaGFyYWN0ZXIgaGV4IGlmIHBvc3NpYmxlXG4gICAgaWYgKGFsbG93M0NoYXIgJiYgaGV4WzBdLmNoYXJBdCgwKSA9PSBoZXhbMF0uY2hhckF0KDEpICYmIGhleFsxXS5jaGFyQXQoMCkgPT0gaGV4WzFdLmNoYXJBdCgxKSAmJiBoZXhbMl0uY2hhckF0KDApID09IGhleFsyXS5jaGFyQXQoMSkpIHtcbiAgICAgICAgcmV0dXJuIGhleFswXS5jaGFyQXQoMCkgKyBoZXhbMV0uY2hhckF0KDApICsgaGV4WzJdLmNoYXJBdCgwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaGV4LmpvaW4oXCJcIik7XG59XG5cbi8vIGByZ2JhVG9IZXhgXG4vLyBDb252ZXJ0cyBhbiBSR0JBIGNvbG9yIHBsdXMgYWxwaGEgdHJhbnNwYXJlbmN5IHRvIGhleFxuLy8gQXNzdW1lcyByLCBnLCBiIGFyZSBjb250YWluZWQgaW4gdGhlIHNldCBbMCwgMjU1XSBhbmRcbi8vIGEgaW4gWzAsIDFdLiBSZXR1cm5zIGEgNCBvciA4IGNoYXJhY3RlciByZ2JhIGhleFxuZnVuY3Rpb24gcmdiYVRvSGV4KHIsIGcsIGIsIGEsIGFsbG93NENoYXIpIHtcblxuICAgIHZhciBoZXggPSBbXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKHIpLnRvU3RyaW5nKDE2KSksXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKGcpLnRvU3RyaW5nKDE2KSksXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKGIpLnRvU3RyaW5nKDE2KSksXG4gICAgICAgIHBhZDIoY29udmVydERlY2ltYWxUb0hleChhKSlcbiAgICBdO1xuXG4gICAgLy8gUmV0dXJuIGEgNCBjaGFyYWN0ZXIgaGV4IGlmIHBvc3NpYmxlXG4gICAgaWYgKGFsbG93NENoYXIgJiYgaGV4WzBdLmNoYXJBdCgwKSA9PSBoZXhbMF0uY2hhckF0KDEpICYmIGhleFsxXS5jaGFyQXQoMCkgPT0gaGV4WzFdLmNoYXJBdCgxKSAmJiBoZXhbMl0uY2hhckF0KDApID09IGhleFsyXS5jaGFyQXQoMSkgJiYgaGV4WzNdLmNoYXJBdCgwKSA9PSBoZXhbM10uY2hhckF0KDEpKSB7XG4gICAgICAgIHJldHVybiBoZXhbMF0uY2hhckF0KDApICsgaGV4WzFdLmNoYXJBdCgwKSArIGhleFsyXS5jaGFyQXQoMCkgKyBoZXhbM10uY2hhckF0KDApO1xuICAgIH1cblxuICAgIHJldHVybiBoZXguam9pbihcIlwiKTtcbn1cblxuLy8gYHJnYmFUb0FyZ2JIZXhgXG4vLyBDb252ZXJ0cyBhbiBSR0JBIGNvbG9yIHRvIGFuIEFSR0IgSGV4OCBzdHJpbmdcbi8vIFJhcmVseSB1c2VkLCBidXQgcmVxdWlyZWQgZm9yIFwidG9GaWx0ZXIoKVwiXG5mdW5jdGlvbiByZ2JhVG9BcmdiSGV4KHIsIGcsIGIsIGEpIHtcblxuICAgIHZhciBoZXggPSBbXG4gICAgICAgIHBhZDIoY29udmVydERlY2ltYWxUb0hleChhKSksXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKHIpLnRvU3RyaW5nKDE2KSksXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKGcpLnRvU3RyaW5nKDE2KSksXG4gICAgICAgIHBhZDIobWF0aFJvdW5kKGIpLnRvU3RyaW5nKDE2KSlcbiAgICBdO1xuXG4gICAgcmV0dXJuIGhleC5qb2luKFwiXCIpO1xufVxuXG4vLyBgZXF1YWxzYFxuLy8gQ2FuIGJlIGNhbGxlZCB3aXRoIGFueSB0aW55Y29sb3IgaW5wdXRcbnRpbnljb2xvci5lcXVhbHMgPSBmdW5jdGlvbiAoY29sb3IxLCBjb2xvcjIpIHtcbiAgICBpZiAoIWNvbG9yMSB8fCAhY29sb3IyKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIHJldHVybiB0aW55Y29sb3IoY29sb3IxKS50b1JnYlN0cmluZygpID09IHRpbnljb2xvcihjb2xvcjIpLnRvUmdiU3RyaW5nKCk7XG59O1xuXG50aW55Y29sb3IucmFuZG9tID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRpbnljb2xvci5mcm9tUmF0aW8oe1xuICAgICAgICByOiBtYXRoUmFuZG9tKCksXG4gICAgICAgIGc6IG1hdGhSYW5kb20oKSxcbiAgICAgICAgYjogbWF0aFJhbmRvbSgpXG4gICAgfSk7XG59O1xuXG5cbi8vIE1vZGlmaWNhdGlvbiBGdW5jdGlvbnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRoYW5rcyB0byBsZXNzLmpzIGZvciBzb21lIG9mIHRoZSBiYXNpY3MgaGVyZVxuLy8gPGh0dHBzOi8vZ2l0aHViLmNvbS9jbG91ZGhlYWQvbGVzcy5qcy9ibG9iL21hc3Rlci9saWIvbGVzcy9mdW5jdGlvbnMuanM+XG5cbmZ1bmN0aW9uIGRlc2F0dXJhdGUoY29sb3IsIGFtb3VudCkge1xuICAgIGFtb3VudCA9IChhbW91bnQgPT09IDApID8gMCA6IChhbW91bnQgfHwgMTApO1xuICAgIHZhciBoc2wgPSB0aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7XG4gICAgaHNsLnMgLT0gYW1vdW50IC8gMTAwO1xuICAgIGhzbC5zID0gY2xhbXAwMShoc2wucyk7XG4gICAgcmV0dXJuIHRpbnljb2xvcihoc2wpO1xufVxuXG5mdW5jdGlvbiBzYXR1cmF0ZShjb2xvciwgYW1vdW50KSB7XG4gICAgYW1vdW50ID0gKGFtb3VudCA9PT0gMCkgPyAwIDogKGFtb3VudCB8fCAxMCk7XG4gICAgdmFyIGhzbCA9IHRpbnljb2xvcihjb2xvcikudG9Ic2woKTtcbiAgICBoc2wucyArPSBhbW91bnQgLyAxMDA7XG4gICAgaHNsLnMgPSBjbGFtcDAxKGhzbC5zKTtcbiAgICByZXR1cm4gdGlueWNvbG9yKGhzbCk7XG59XG5cbmZ1bmN0aW9uIGdyZXlzY2FsZShjb2xvcikge1xuICAgIHJldHVybiB0aW55Y29sb3IoY29sb3IpLmRlc2F0dXJhdGUoMTAwKTtcbn1cblxuZnVuY3Rpb24gbGlnaHRlbiAoY29sb3IsIGFtb3VudCkge1xuICAgIGFtb3VudCA9IChhbW91bnQgPT09IDApID8gMCA6IChhbW91bnQgfHwgMTApO1xuICAgIHZhciBoc2wgPSB0aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7XG4gICAgaHNsLmwgKz0gYW1vdW50IC8gMTAwO1xuICAgIGhzbC5sID0gY2xhbXAwMShoc2wubCk7XG4gICAgcmV0dXJuIHRpbnljb2xvcihoc2wpO1xufVxuXG5mdW5jdGlvbiBicmlnaHRlbihjb2xvciwgYW1vdW50KSB7XG4gICAgYW1vdW50ID0gKGFtb3VudCA9PT0gMCkgPyAwIDogKGFtb3VudCB8fCAxMCk7XG4gICAgdmFyIHJnYiA9IHRpbnljb2xvcihjb2xvcikudG9SZ2IoKTtcbiAgICByZ2IuciA9IG1hdGhNYXgoMCwgbWF0aE1pbigyNTUsIHJnYi5yIC0gbWF0aFJvdW5kKDI1NSAqIC0gKGFtb3VudCAvIDEwMCkpKSk7XG4gICAgcmdiLmcgPSBtYXRoTWF4KDAsIG1hdGhNaW4oMjU1LCByZ2IuZyAtIG1hdGhSb3VuZCgyNTUgKiAtIChhbW91bnQgLyAxMDApKSkpO1xuICAgIHJnYi5iID0gbWF0aE1heCgwLCBtYXRoTWluKDI1NSwgcmdiLmIgLSBtYXRoUm91bmQoMjU1ICogLSAoYW1vdW50IC8gMTAwKSkpKTtcbiAgICByZXR1cm4gdGlueWNvbG9yKHJnYik7XG59XG5cbmZ1bmN0aW9uIGRhcmtlbiAoY29sb3IsIGFtb3VudCkge1xuICAgIGFtb3VudCA9IChhbW91bnQgPT09IDApID8gMCA6IChhbW91bnQgfHwgMTApO1xuICAgIHZhciBoc2wgPSB0aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7XG4gICAgaHNsLmwgLT0gYW1vdW50IC8gMTAwO1xuICAgIGhzbC5sID0gY2xhbXAwMShoc2wubCk7XG4gICAgcmV0dXJuIHRpbnljb2xvcihoc2wpO1xufVxuXG4vLyBTcGluIHRha2VzIGEgcG9zaXRpdmUgb3IgbmVnYXRpdmUgYW1vdW50IHdpdGhpbiBbLTM2MCwgMzYwXSBpbmRpY2F0aW5nIHRoZSBjaGFuZ2Ugb2YgaHVlLlxuLy8gVmFsdWVzIG91dHNpZGUgb2YgdGhpcyByYW5nZSB3aWxsIGJlIHdyYXBwZWQgaW50byB0aGlzIHJhbmdlLlxuZnVuY3Rpb24gc3Bpbihjb2xvciwgYW1vdW50KSB7XG4gICAgdmFyIGhzbCA9IHRpbnljb2xvcihjb2xvcikudG9Ic2woKTtcbiAgICB2YXIgaHVlID0gKGhzbC5oICsgYW1vdW50KSAlIDM2MDtcbiAgICBoc2wuaCA9IGh1ZSA8IDAgPyAzNjAgKyBodWUgOiBodWU7XG4gICAgcmV0dXJuIHRpbnljb2xvcihoc2wpO1xufVxuXG4vLyBDb21iaW5hdGlvbiBGdW5jdGlvbnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVGhhbmtzIHRvIGpRdWVyeSB4Q29sb3IgZm9yIHNvbWUgb2YgdGhlIGlkZWFzIGJlaGluZCB0aGVzZVxuLy8gPGh0dHBzOi8vZ2l0aHViLmNvbS9pbmZ1c2lvbi9qUXVlcnkteGNvbG9yL2Jsb2IvbWFzdGVyL2pxdWVyeS54Y29sb3IuanM+XG5cbmZ1bmN0aW9uIGNvbXBsZW1lbnQoY29sb3IpIHtcbiAgICB2YXIgaHNsID0gdGlueWNvbG9yKGNvbG9yKS50b0hzbCgpO1xuICAgIGhzbC5oID0gKGhzbC5oICsgMTgwKSAlIDM2MDtcbiAgICByZXR1cm4gdGlueWNvbG9yKGhzbCk7XG59XG5cbmZ1bmN0aW9uIHRyaWFkKGNvbG9yKSB7XG4gICAgdmFyIGhzbCA9IHRpbnljb2xvcihjb2xvcikudG9Ic2woKTtcbiAgICB2YXIgaCA9IGhzbC5oO1xuICAgIHJldHVybiBbXG4gICAgICAgIHRpbnljb2xvcihjb2xvciksXG4gICAgICAgIHRpbnljb2xvcih7IGg6IChoICsgMTIwKSAlIDM2MCwgczogaHNsLnMsIGw6IGhzbC5sIH0pLFxuICAgICAgICB0aW55Y29sb3IoeyBoOiAoaCArIDI0MCkgJSAzNjAsIHM6IGhzbC5zLCBsOiBoc2wubCB9KVxuICAgIF07XG59XG5cbmZ1bmN0aW9uIHRldHJhZChjb2xvcikge1xuICAgIHZhciBoc2wgPSB0aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7XG4gICAgdmFyIGggPSBoc2wuaDtcbiAgICByZXR1cm4gW1xuICAgICAgICB0aW55Y29sb3IoY29sb3IpLFxuICAgICAgICB0aW55Y29sb3IoeyBoOiAoaCArIDkwKSAlIDM2MCwgczogaHNsLnMsIGw6IGhzbC5sIH0pLFxuICAgICAgICB0aW55Y29sb3IoeyBoOiAoaCArIDE4MCkgJSAzNjAsIHM6IGhzbC5zLCBsOiBoc2wubCB9KSxcbiAgICAgICAgdGlueWNvbG9yKHsgaDogKGggKyAyNzApICUgMzYwLCBzOiBoc2wucywgbDogaHNsLmwgfSlcbiAgICBdO1xufVxuXG5mdW5jdGlvbiBzcGxpdGNvbXBsZW1lbnQoY29sb3IpIHtcbiAgICB2YXIgaHNsID0gdGlueWNvbG9yKGNvbG9yKS50b0hzbCgpO1xuICAgIHZhciBoID0gaHNsLmg7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgdGlueWNvbG9yKGNvbG9yKSxcbiAgICAgICAgdGlueWNvbG9yKHsgaDogKGggKyA3MikgJSAzNjAsIHM6IGhzbC5zLCBsOiBoc2wubH0pLFxuICAgICAgICB0aW55Y29sb3IoeyBoOiAoaCArIDIxNikgJSAzNjAsIHM6IGhzbC5zLCBsOiBoc2wubH0pXG4gICAgXTtcbn1cblxuZnVuY3Rpb24gYW5hbG9nb3VzKGNvbG9yLCByZXN1bHRzLCBzbGljZXMpIHtcbiAgICByZXN1bHRzID0gcmVzdWx0cyB8fCA2O1xuICAgIHNsaWNlcyA9IHNsaWNlcyB8fCAzMDtcblxuICAgIHZhciBoc2wgPSB0aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7XG4gICAgdmFyIHBhcnQgPSAzNjAgLyBzbGljZXM7XG4gICAgdmFyIHJldCA9IFt0aW55Y29sb3IoY29sb3IpXTtcblxuICAgIGZvciAoaHNsLmggPSAoKGhzbC5oIC0gKHBhcnQgKiByZXN1bHRzID4+IDEpKSArIDcyMCkgJSAzNjA7IC0tcmVzdWx0czsgKSB7XG4gICAgICAgIGhzbC5oID0gKGhzbC5oICsgcGFydCkgJSAzNjA7XG4gICAgICAgIHJldC5wdXNoKHRpbnljb2xvcihoc2wpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gbW9ub2Nocm9tYXRpYyhjb2xvciwgcmVzdWx0cykge1xuICAgIHJlc3VsdHMgPSByZXN1bHRzIHx8IDY7XG4gICAgdmFyIGhzdiA9IHRpbnljb2xvcihjb2xvcikudG9Ic3YoKTtcbiAgICB2YXIgaCA9IGhzdi5oLCBzID0gaHN2LnMsIHYgPSBoc3YudjtcbiAgICB2YXIgcmV0ID0gW107XG4gICAgdmFyIG1vZGlmaWNhdGlvbiA9IDEgLyByZXN1bHRzO1xuXG4gICAgd2hpbGUgKHJlc3VsdHMtLSkge1xuICAgICAgICByZXQucHVzaCh0aW55Y29sb3IoeyBoOiBoLCBzOiBzLCB2OiB2fSkpO1xuICAgICAgICB2ID0gKHYgKyBtb2RpZmljYXRpb24pICUgMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmV0O1xufVxuXG4vLyBVdGlsaXR5IEZ1bmN0aW9uc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbnRpbnljb2xvci5taXggPSBmdW5jdGlvbihjb2xvcjEsIGNvbG9yMiwgYW1vdW50KSB7XG4gICAgYW1vdW50ID0gKGFtb3VudCA9PT0gMCkgPyAwIDogKGFtb3VudCB8fCA1MCk7XG5cbiAgICB2YXIgcmdiMSA9IHRpbnljb2xvcihjb2xvcjEpLnRvUmdiKCk7XG4gICAgdmFyIHJnYjIgPSB0aW55Y29sb3IoY29sb3IyKS50b1JnYigpO1xuXG4gICAgdmFyIHAgPSBhbW91bnQgLyAxMDA7XG5cbiAgICB2YXIgcmdiYSA9IHtcbiAgICAgICAgcjogKChyZ2IyLnIgLSByZ2IxLnIpICogcCkgKyByZ2IxLnIsXG4gICAgICAgIGc6ICgocmdiMi5nIC0gcmdiMS5nKSAqIHApICsgcmdiMS5nLFxuICAgICAgICBiOiAoKHJnYjIuYiAtIHJnYjEuYikgKiBwKSArIHJnYjEuYixcbiAgICAgICAgYTogKChyZ2IyLmEgLSByZ2IxLmEpICogcCkgKyByZ2IxLmFcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRpbnljb2xvcihyZ2JhKTtcbn07XG5cblxuLy8gUmVhZGFiaWxpdHkgRnVuY3Rpb25zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIDxodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy1XQ0FHMjAtMjAwODEyMTEvI2NvbnRyYXN0LXJhdGlvZGVmIChXQ0FHIFZlcnNpb24gMilcblxuLy8gYGNvbnRyYXN0YFxuLy8gQW5hbHl6ZSB0aGUgMiBjb2xvcnMgYW5kIHJldHVybnMgdGhlIGNvbG9yIGNvbnRyYXN0IGRlZmluZWQgYnkgKFdDQUcgVmVyc2lvbiAyKVxudGlueWNvbG9yLnJlYWRhYmlsaXR5ID0gZnVuY3Rpb24oY29sb3IxLCBjb2xvcjIpIHtcbiAgICB2YXIgYzEgPSB0aW55Y29sb3IoY29sb3IxKTtcbiAgICB2YXIgYzIgPSB0aW55Y29sb3IoY29sb3IyKTtcbiAgICByZXR1cm4gKE1hdGgubWF4KGMxLmdldEx1bWluYW5jZSgpLGMyLmdldEx1bWluYW5jZSgpKSswLjA1KSAvIChNYXRoLm1pbihjMS5nZXRMdW1pbmFuY2UoKSxjMi5nZXRMdW1pbmFuY2UoKSkrMC4wNSk7XG59O1xuXG4vLyBgaXNSZWFkYWJsZWBcbi8vIEVuc3VyZSB0aGF0IGZvcmVncm91bmQgYW5kIGJhY2tncm91bmQgY29sb3IgY29tYmluYXRpb25zIG1lZXQgV0NBRzIgZ3VpZGVsaW5lcy5cbi8vIFRoZSB0aGlyZCBhcmd1bWVudCBpcyBhbiBvcHRpb25hbCBPYmplY3QuXG4vLyAgICAgIHRoZSAnbGV2ZWwnIHByb3BlcnR5IHN0YXRlcyAnQUEnIG9yICdBQUEnIC0gaWYgbWlzc2luZyBvciBpbnZhbGlkLCBpdCBkZWZhdWx0cyB0byAnQUEnO1xuLy8gICAgICB0aGUgJ3NpemUnIHByb3BlcnR5IHN0YXRlcyAnbGFyZ2UnIG9yICdzbWFsbCcgLSBpZiBtaXNzaW5nIG9yIGludmFsaWQsIGl0IGRlZmF1bHRzIHRvICdzbWFsbCcuXG4vLyBJZiB0aGUgZW50aXJlIG9iamVjdCBpcyBhYnNlbnQsIGlzUmVhZGFibGUgZGVmYXVsdHMgdG8ge2xldmVsOlwiQUFcIixzaXplOlwic21hbGxcIn0uXG5cbi8vICpFeGFtcGxlKlxuLy8gICAgdGlueWNvbG9yLmlzUmVhZGFibGUoXCIjMDAwXCIsIFwiIzExMVwiKSA9PiBmYWxzZVxuLy8gICAgdGlueWNvbG9yLmlzUmVhZGFibGUoXCIjMDAwXCIsIFwiIzExMVwiLHtsZXZlbDpcIkFBXCIsc2l6ZTpcImxhcmdlXCJ9KSA9PiBmYWxzZVxudGlueWNvbG9yLmlzUmVhZGFibGUgPSBmdW5jdGlvbihjb2xvcjEsIGNvbG9yMiwgd2NhZzIpIHtcbiAgICB2YXIgcmVhZGFiaWxpdHkgPSB0aW55Y29sb3IucmVhZGFiaWxpdHkoY29sb3IxLCBjb2xvcjIpO1xuICAgIHZhciB3Y2FnMlBhcm1zLCBvdXQ7XG5cbiAgICBvdXQgPSBmYWxzZTtcblxuICAgIHdjYWcyUGFybXMgPSB2YWxpZGF0ZVdDQUcyUGFybXMod2NhZzIpO1xuICAgIHN3aXRjaCAod2NhZzJQYXJtcy5sZXZlbCArIHdjYWcyUGFybXMuc2l6ZSkge1xuICAgICAgICBjYXNlIFwiQUFzbWFsbFwiOlxuICAgICAgICBjYXNlIFwiQUFBbGFyZ2VcIjpcbiAgICAgICAgICAgIG91dCA9IHJlYWRhYmlsaXR5ID49IDQuNTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiQUFsYXJnZVwiOlxuICAgICAgICAgICAgb3V0ID0gcmVhZGFiaWxpdHkgPj0gMztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiQUFBc21hbGxcIjpcbiAgICAgICAgICAgIG91dCA9IHJlYWRhYmlsaXR5ID49IDc7XG4gICAgICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIG91dDtcblxufTtcblxuLy8gYG1vc3RSZWFkYWJsZWBcbi8vIEdpdmVuIGEgYmFzZSBjb2xvciBhbmQgYSBsaXN0IG9mIHBvc3NpYmxlIGZvcmVncm91bmQgb3IgYmFja2dyb3VuZFxuLy8gY29sb3JzIGZvciB0aGF0IGJhc2UsIHJldHVybnMgdGhlIG1vc3QgcmVhZGFibGUgY29sb3IuXG4vLyBPcHRpb25hbGx5IHJldHVybnMgQmxhY2sgb3IgV2hpdGUgaWYgdGhlIG1vc3QgcmVhZGFibGUgY29sb3IgaXMgdW5yZWFkYWJsZS5cbi8vICpFeGFtcGxlKlxuLy8gICAgdGlueWNvbG9yLm1vc3RSZWFkYWJsZSh0aW55Y29sb3IubW9zdFJlYWRhYmxlKFwiIzEyM1wiLCBbXCIjMTI0XCIsIFwiIzEyNVwiXSx7aW5jbHVkZUZhbGxiYWNrQ29sb3JzOmZhbHNlfSkudG9IZXhTdHJpbmcoKTsgLy8gXCIjMTEyMjU1XCJcbi8vICAgIHRpbnljb2xvci5tb3N0UmVhZGFibGUodGlueWNvbG9yLm1vc3RSZWFkYWJsZShcIiMxMjNcIiwgW1wiIzEyNFwiLCBcIiMxMjVcIl0se2luY2x1ZGVGYWxsYmFja0NvbG9yczp0cnVlfSkudG9IZXhTdHJpbmcoKTsgIC8vIFwiI2ZmZmZmZlwiXG4vLyAgICB0aW55Y29sb3IubW9zdFJlYWRhYmxlKFwiI2E4MDE1YVwiLCBbXCIjZmFmM2YzXCJdLHtpbmNsdWRlRmFsbGJhY2tDb2xvcnM6dHJ1ZSxsZXZlbDpcIkFBQVwiLHNpemU6XCJsYXJnZVwifSkudG9IZXhTdHJpbmcoKTsgLy8gXCIjZmFmM2YzXCJcbi8vICAgIHRpbnljb2xvci5tb3N0UmVhZGFibGUoXCIjYTgwMTVhXCIsIFtcIiNmYWYzZjNcIl0se2luY2x1ZGVGYWxsYmFja0NvbG9yczp0cnVlLGxldmVsOlwiQUFBXCIsc2l6ZTpcInNtYWxsXCJ9KS50b0hleFN0cmluZygpOyAvLyBcIiNmZmZmZmZcIlxudGlueWNvbG9yLm1vc3RSZWFkYWJsZSA9IGZ1bmN0aW9uKGJhc2VDb2xvciwgY29sb3JMaXN0LCBhcmdzKSB7XG4gICAgdmFyIGJlc3RDb2xvciA9IG51bGw7XG4gICAgdmFyIGJlc3RTY29yZSA9IDA7XG4gICAgdmFyIHJlYWRhYmlsaXR5O1xuICAgIHZhciBpbmNsdWRlRmFsbGJhY2tDb2xvcnMsIGxldmVsLCBzaXplIDtcbiAgICBhcmdzID0gYXJncyB8fCB7fTtcbiAgICBpbmNsdWRlRmFsbGJhY2tDb2xvcnMgPSBhcmdzLmluY2x1ZGVGYWxsYmFja0NvbG9ycyA7XG4gICAgbGV2ZWwgPSBhcmdzLmxldmVsO1xuICAgIHNpemUgPSBhcmdzLnNpemU7XG5cbiAgICBmb3IgKHZhciBpPSAwOyBpIDwgY29sb3JMaXN0Lmxlbmd0aCA7IGkrKykge1xuICAgICAgICByZWFkYWJpbGl0eSA9IHRpbnljb2xvci5yZWFkYWJpbGl0eShiYXNlQ29sb3IsIGNvbG9yTGlzdFtpXSk7XG4gICAgICAgIGlmIChyZWFkYWJpbGl0eSA+IGJlc3RTY29yZSkge1xuICAgICAgICAgICAgYmVzdFNjb3JlID0gcmVhZGFiaWxpdHk7XG4gICAgICAgICAgICBiZXN0Q29sb3IgPSB0aW55Y29sb3IoY29sb3JMaXN0W2ldKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aW55Y29sb3IuaXNSZWFkYWJsZShiYXNlQ29sb3IsIGJlc3RDb2xvciwge1wibGV2ZWxcIjpsZXZlbCxcInNpemVcIjpzaXplfSkgfHwgIWluY2x1ZGVGYWxsYmFja0NvbG9ycykge1xuICAgICAgICByZXR1cm4gYmVzdENvbG9yO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgYXJncy5pbmNsdWRlRmFsbGJhY2tDb2xvcnM9ZmFsc2U7XG4gICAgICAgIHJldHVybiB0aW55Y29sb3IubW9zdFJlYWRhYmxlKGJhc2VDb2xvcixbXCIjZmZmXCIsIFwiIzAwMFwiXSxhcmdzKTtcbiAgICB9XG59O1xuXG5cbi8vIEJpZyBMaXN0IG9mIENvbG9yc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyA8aHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1jb2xvci8jc3ZnLWNvbG9yPlxudmFyIG5hbWVzID0gdGlueWNvbG9yLm5hbWVzID0ge1xuICAgIGFsaWNlYmx1ZTogXCJmMGY4ZmZcIixcbiAgICBhbnRpcXVld2hpdGU6IFwiZmFlYmQ3XCIsXG4gICAgYXF1YTogXCIwZmZcIixcbiAgICBhcXVhbWFyaW5lOiBcIjdmZmZkNFwiLFxuICAgIGF6dXJlOiBcImYwZmZmZlwiLFxuICAgIGJlaWdlOiBcImY1ZjVkY1wiLFxuICAgIGJpc3F1ZTogXCJmZmU0YzRcIixcbiAgICBibGFjazogXCIwMDBcIixcbiAgICBibGFuY2hlZGFsbW9uZDogXCJmZmViY2RcIixcbiAgICBibHVlOiBcIjAwZlwiLFxuICAgIGJsdWV2aW9sZXQ6IFwiOGEyYmUyXCIsXG4gICAgYnJvd246IFwiYTUyYTJhXCIsXG4gICAgYnVybHl3b29kOiBcImRlYjg4N1wiLFxuICAgIGJ1cm50c2llbm5hOiBcImVhN2U1ZFwiLFxuICAgIGNhZGV0Ymx1ZTogXCI1ZjllYTBcIixcbiAgICBjaGFydHJldXNlOiBcIjdmZmYwMFwiLFxuICAgIGNob2NvbGF0ZTogXCJkMjY5MWVcIixcbiAgICBjb3JhbDogXCJmZjdmNTBcIixcbiAgICBjb3JuZmxvd2VyYmx1ZTogXCI2NDk1ZWRcIixcbiAgICBjb3Juc2lsazogXCJmZmY4ZGNcIixcbiAgICBjcmltc29uOiBcImRjMTQzY1wiLFxuICAgIGN5YW46IFwiMGZmXCIsXG4gICAgZGFya2JsdWU6IFwiMDAwMDhiXCIsXG4gICAgZGFya2N5YW46IFwiMDA4YjhiXCIsXG4gICAgZGFya2dvbGRlbnJvZDogXCJiODg2MGJcIixcbiAgICBkYXJrZ3JheTogXCJhOWE5YTlcIixcbiAgICBkYXJrZ3JlZW46IFwiMDA2NDAwXCIsXG4gICAgZGFya2dyZXk6IFwiYTlhOWE5XCIsXG4gICAgZGFya2toYWtpOiBcImJkYjc2YlwiLFxuICAgIGRhcmttYWdlbnRhOiBcIjhiMDA4YlwiLFxuICAgIGRhcmtvbGl2ZWdyZWVuOiBcIjU1NmIyZlwiLFxuICAgIGRhcmtvcmFuZ2U6IFwiZmY4YzAwXCIsXG4gICAgZGFya29yY2hpZDogXCI5OTMyY2NcIixcbiAgICBkYXJrcmVkOiBcIjhiMDAwMFwiLFxuICAgIGRhcmtzYWxtb246IFwiZTk5NjdhXCIsXG4gICAgZGFya3NlYWdyZWVuOiBcIjhmYmM4ZlwiLFxuICAgIGRhcmtzbGF0ZWJsdWU6IFwiNDgzZDhiXCIsXG4gICAgZGFya3NsYXRlZ3JheTogXCIyZjRmNGZcIixcbiAgICBkYXJrc2xhdGVncmV5OiBcIjJmNGY0ZlwiLFxuICAgIGRhcmt0dXJxdW9pc2U6IFwiMDBjZWQxXCIsXG4gICAgZGFya3Zpb2xldDogXCI5NDAwZDNcIixcbiAgICBkZWVwcGluazogXCJmZjE0OTNcIixcbiAgICBkZWVwc2t5Ymx1ZTogXCIwMGJmZmZcIixcbiAgICBkaW1ncmF5OiBcIjY5Njk2OVwiLFxuICAgIGRpbWdyZXk6IFwiNjk2OTY5XCIsXG4gICAgZG9kZ2VyYmx1ZTogXCIxZTkwZmZcIixcbiAgICBmaXJlYnJpY2s6IFwiYjIyMjIyXCIsXG4gICAgZmxvcmFsd2hpdGU6IFwiZmZmYWYwXCIsXG4gICAgZm9yZXN0Z3JlZW46IFwiMjI4YjIyXCIsXG4gICAgZnVjaHNpYTogXCJmMGZcIixcbiAgICBnYWluc2Jvcm86IFwiZGNkY2RjXCIsXG4gICAgZ2hvc3R3aGl0ZTogXCJmOGY4ZmZcIixcbiAgICBnb2xkOiBcImZmZDcwMFwiLFxuICAgIGdvbGRlbnJvZDogXCJkYWE1MjBcIixcbiAgICBncmF5OiBcIjgwODA4MFwiLFxuICAgIGdyZWVuOiBcIjAwODAwMFwiLFxuICAgIGdyZWVueWVsbG93OiBcImFkZmYyZlwiLFxuICAgIGdyZXk6IFwiODA4MDgwXCIsXG4gICAgaG9uZXlkZXc6IFwiZjBmZmYwXCIsXG4gICAgaG90cGluazogXCJmZjY5YjRcIixcbiAgICBpbmRpYW5yZWQ6IFwiY2Q1YzVjXCIsXG4gICAgaW5kaWdvOiBcIjRiMDA4MlwiLFxuICAgIGl2b3J5OiBcImZmZmZmMFwiLFxuICAgIGtoYWtpOiBcImYwZTY4Y1wiLFxuICAgIGxhdmVuZGVyOiBcImU2ZTZmYVwiLFxuICAgIGxhdmVuZGVyYmx1c2g6IFwiZmZmMGY1XCIsXG4gICAgbGF3bmdyZWVuOiBcIjdjZmMwMFwiLFxuICAgIGxlbW9uY2hpZmZvbjogXCJmZmZhY2RcIixcbiAgICBsaWdodGJsdWU6IFwiYWRkOGU2XCIsXG4gICAgbGlnaHRjb3JhbDogXCJmMDgwODBcIixcbiAgICBsaWdodGN5YW46IFwiZTBmZmZmXCIsXG4gICAgbGlnaHRnb2xkZW5yb2R5ZWxsb3c6IFwiZmFmYWQyXCIsXG4gICAgbGlnaHRncmF5OiBcImQzZDNkM1wiLFxuICAgIGxpZ2h0Z3JlZW46IFwiOTBlZTkwXCIsXG4gICAgbGlnaHRncmV5OiBcImQzZDNkM1wiLFxuICAgIGxpZ2h0cGluazogXCJmZmI2YzFcIixcbiAgICBsaWdodHNhbG1vbjogXCJmZmEwN2FcIixcbiAgICBsaWdodHNlYWdyZWVuOiBcIjIwYjJhYVwiLFxuICAgIGxpZ2h0c2t5Ymx1ZTogXCI4N2NlZmFcIixcbiAgICBsaWdodHNsYXRlZ3JheTogXCI3ODlcIixcbiAgICBsaWdodHNsYXRlZ3JleTogXCI3ODlcIixcbiAgICBsaWdodHN0ZWVsYmx1ZTogXCJiMGM0ZGVcIixcbiAgICBsaWdodHllbGxvdzogXCJmZmZmZTBcIixcbiAgICBsaW1lOiBcIjBmMFwiLFxuICAgIGxpbWVncmVlbjogXCIzMmNkMzJcIixcbiAgICBsaW5lbjogXCJmYWYwZTZcIixcbiAgICBtYWdlbnRhOiBcImYwZlwiLFxuICAgIG1hcm9vbjogXCI4MDAwMDBcIixcbiAgICBtZWRpdW1hcXVhbWFyaW5lOiBcIjY2Y2RhYVwiLFxuICAgIG1lZGl1bWJsdWU6IFwiMDAwMGNkXCIsXG4gICAgbWVkaXVtb3JjaGlkOiBcImJhNTVkM1wiLFxuICAgIG1lZGl1bXB1cnBsZTogXCI5MzcwZGJcIixcbiAgICBtZWRpdW1zZWFncmVlbjogXCIzY2IzNzFcIixcbiAgICBtZWRpdW1zbGF0ZWJsdWU6IFwiN2I2OGVlXCIsXG4gICAgbWVkaXVtc3ByaW5nZ3JlZW46IFwiMDBmYTlhXCIsXG4gICAgbWVkaXVtdHVycXVvaXNlOiBcIjQ4ZDFjY1wiLFxuICAgIG1lZGl1bXZpb2xldHJlZDogXCJjNzE1ODVcIixcbiAgICBtaWRuaWdodGJsdWU6IFwiMTkxOTcwXCIsXG4gICAgbWludGNyZWFtOiBcImY1ZmZmYVwiLFxuICAgIG1pc3R5cm9zZTogXCJmZmU0ZTFcIixcbiAgICBtb2NjYXNpbjogXCJmZmU0YjVcIixcbiAgICBuYXZham93aGl0ZTogXCJmZmRlYWRcIixcbiAgICBuYXZ5OiBcIjAwMDA4MFwiLFxuICAgIG9sZGxhY2U6IFwiZmRmNWU2XCIsXG4gICAgb2xpdmU6IFwiODA4MDAwXCIsXG4gICAgb2xpdmVkcmFiOiBcIjZiOGUyM1wiLFxuICAgIG9yYW5nZTogXCJmZmE1MDBcIixcbiAgICBvcmFuZ2VyZWQ6IFwiZmY0NTAwXCIsXG4gICAgb3JjaGlkOiBcImRhNzBkNlwiLFxuICAgIHBhbGVnb2xkZW5yb2Q6IFwiZWVlOGFhXCIsXG4gICAgcGFsZWdyZWVuOiBcIjk4ZmI5OFwiLFxuICAgIHBhbGV0dXJxdW9pc2U6IFwiYWZlZWVlXCIsXG4gICAgcGFsZXZpb2xldHJlZDogXCJkYjcwOTNcIixcbiAgICBwYXBheWF3aGlwOiBcImZmZWZkNVwiLFxuICAgIHBlYWNocHVmZjogXCJmZmRhYjlcIixcbiAgICBwZXJ1OiBcImNkODUzZlwiLFxuICAgIHBpbms6IFwiZmZjMGNiXCIsXG4gICAgcGx1bTogXCJkZGEwZGRcIixcbiAgICBwb3dkZXJibHVlOiBcImIwZTBlNlwiLFxuICAgIHB1cnBsZTogXCI4MDAwODBcIixcbiAgICByZWJlY2NhcHVycGxlOiBcIjY2MzM5OVwiLFxuICAgIHJlZDogXCJmMDBcIixcbiAgICByb3N5YnJvd246IFwiYmM4ZjhmXCIsXG4gICAgcm95YWxibHVlOiBcIjQxNjllMVwiLFxuICAgIHNhZGRsZWJyb3duOiBcIjhiNDUxM1wiLFxuICAgIHNhbG1vbjogXCJmYTgwNzJcIixcbiAgICBzYW5keWJyb3duOiBcImY0YTQ2MFwiLFxuICAgIHNlYWdyZWVuOiBcIjJlOGI1N1wiLFxuICAgIHNlYXNoZWxsOiBcImZmZjVlZVwiLFxuICAgIHNpZW5uYTogXCJhMDUyMmRcIixcbiAgICBzaWx2ZXI6IFwiYzBjMGMwXCIsXG4gICAgc2t5Ymx1ZTogXCI4N2NlZWJcIixcbiAgICBzbGF0ZWJsdWU6IFwiNmE1YWNkXCIsXG4gICAgc2xhdGVncmF5OiBcIjcwODA5MFwiLFxuICAgIHNsYXRlZ3JleTogXCI3MDgwOTBcIixcbiAgICBzbm93OiBcImZmZmFmYVwiLFxuICAgIHNwcmluZ2dyZWVuOiBcIjAwZmY3ZlwiLFxuICAgIHN0ZWVsYmx1ZTogXCI0NjgyYjRcIixcbiAgICB0YW46IFwiZDJiNDhjXCIsXG4gICAgdGVhbDogXCIwMDgwODBcIixcbiAgICB0aGlzdGxlOiBcImQ4YmZkOFwiLFxuICAgIHRvbWF0bzogXCJmZjYzNDdcIixcbiAgICB0dXJxdW9pc2U6IFwiNDBlMGQwXCIsXG4gICAgdmlvbGV0OiBcImVlODJlZVwiLFxuICAgIHdoZWF0OiBcImY1ZGViM1wiLFxuICAgIHdoaXRlOiBcImZmZlwiLFxuICAgIHdoaXRlc21va2U6IFwiZjVmNWY1XCIsXG4gICAgeWVsbG93OiBcImZmMFwiLFxuICAgIHllbGxvd2dyZWVuOiBcIjlhY2QzMlwiXG59O1xuXG4vLyBNYWtlIGl0IGVhc3kgdG8gYWNjZXNzIGNvbG9ycyB2aWEgYGhleE5hbWVzW2hleF1gXG52YXIgaGV4TmFtZXMgPSB0aW55Y29sb3IuaGV4TmFtZXMgPSBmbGlwKG5hbWVzKTtcblxuXG4vLyBVdGlsaXRpZXNcbi8vIC0tLS0tLS0tLVxuXG4vLyBgeyAnbmFtZTEnOiAndmFsMScgfWAgYmVjb21lcyBgeyAndmFsMSc6ICduYW1lMScgfWBcbmZ1bmN0aW9uIGZsaXAobykge1xuICAgIHZhciBmbGlwcGVkID0geyB9O1xuICAgIGZvciAodmFyIGkgaW4gbykge1xuICAgICAgICBpZiAoby5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgICAgICAgZmxpcHBlZFtvW2ldXSA9IGk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZsaXBwZWQ7XG59XG5cbi8vIFJldHVybiBhIHZhbGlkIGFscGhhIHZhbHVlIFswLDFdIHdpdGggYWxsIGludmFsaWQgdmFsdWVzIGJlaW5nIHNldCB0byAxXG5mdW5jdGlvbiBib3VuZEFscGhhKGEpIHtcbiAgICBhID0gcGFyc2VGbG9hdChhKTtcblxuICAgIGlmIChpc05hTihhKSB8fCBhIDwgMCB8fCBhID4gMSkge1xuICAgICAgICBhID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gYTtcbn1cblxuLy8gVGFrZSBpbnB1dCBmcm9tIFswLCBuXSBhbmQgcmV0dXJuIGl0IGFzIFswLCAxXVxuZnVuY3Rpb24gYm91bmQwMShuLCBtYXgpIHtcbiAgICBpZiAoaXNPbmVQb2ludFplcm8obikpIHsgbiA9IFwiMTAwJVwiOyB9XG5cbiAgICB2YXIgcHJvY2Vzc1BlcmNlbnQgPSBpc1BlcmNlbnRhZ2Uobik7XG4gICAgbiA9IG1hdGhNaW4obWF4LCBtYXRoTWF4KDAsIHBhcnNlRmxvYXQobikpKTtcblxuICAgIC8vIEF1dG9tYXRpY2FsbHkgY29udmVydCBwZXJjZW50YWdlIGludG8gbnVtYmVyXG4gICAgaWYgKHByb2Nlc3NQZXJjZW50KSB7XG4gICAgICAgIG4gPSBwYXJzZUludChuICogbWF4LCAxMCkgLyAxMDA7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGZsb2F0aW5nIHBvaW50IHJvdW5kaW5nIGVycm9yc1xuICAgIGlmICgoTWF0aC5hYnMobiAtIG1heCkgPCAwLjAwMDAwMSkpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuXG4gICAgLy8gQ29udmVydCBpbnRvIFswLCAxXSByYW5nZSBpZiBpdCBpc24ndCBhbHJlYWR5XG4gICAgcmV0dXJuIChuICUgbWF4KSAvIHBhcnNlRmxvYXQobWF4KTtcbn1cblxuLy8gRm9yY2UgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCAxXG5mdW5jdGlvbiBjbGFtcDAxKHZhbCkge1xuICAgIHJldHVybiBtYXRoTWluKDEsIG1hdGhNYXgoMCwgdmFsKSk7XG59XG5cbi8vIFBhcnNlIGEgYmFzZS0xNiBoZXggdmFsdWUgaW50byBhIGJhc2UtMTAgaW50ZWdlclxuZnVuY3Rpb24gcGFyc2VJbnRGcm9tSGV4KHZhbCkge1xuICAgIHJldHVybiBwYXJzZUludCh2YWwsIDE2KTtcbn1cblxuLy8gTmVlZCB0byBoYW5kbGUgMS4wIGFzIDEwMCUsIHNpbmNlIG9uY2UgaXQgaXMgYSBudW1iZXIsIHRoZXJlIGlzIG5vIGRpZmZlcmVuY2UgYmV0d2VlbiBpdCBhbmQgMVxuLy8gPGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzQyMjA3Mi9qYXZhc2NyaXB0LWhvdy10by1kZXRlY3QtbnVtYmVyLWFzLWEtZGVjaW1hbC1pbmNsdWRpbmctMS0wPlxuZnVuY3Rpb24gaXNPbmVQb2ludFplcm8obikge1xuICAgIHJldHVybiB0eXBlb2YgbiA9PSBcInN0cmluZ1wiICYmIG4uaW5kZXhPZignLicpICE9IC0xICYmIHBhcnNlRmxvYXQobikgPT09IDE7XG59XG5cbi8vIENoZWNrIHRvIHNlZSBpZiBzdHJpbmcgcGFzc2VkIGluIGlzIGEgcGVyY2VudGFnZVxuZnVuY3Rpb24gaXNQZXJjZW50YWdlKG4pIHtcbiAgICByZXR1cm4gdHlwZW9mIG4gPT09IFwic3RyaW5nXCIgJiYgbi5pbmRleE9mKCclJykgIT0gLTE7XG59XG5cbi8vIEZvcmNlIGEgaGV4IHZhbHVlIHRvIGhhdmUgMiBjaGFyYWN0ZXJzXG5mdW5jdGlvbiBwYWQyKGMpIHtcbiAgICByZXR1cm4gYy5sZW5ndGggPT0gMSA/ICcwJyArIGMgOiAnJyArIGM7XG59XG5cbi8vIFJlcGxhY2UgYSBkZWNpbWFsIHdpdGggaXQncyBwZXJjZW50YWdlIHZhbHVlXG5mdW5jdGlvbiBjb252ZXJ0VG9QZXJjZW50YWdlKG4pIHtcbiAgICBpZiAobiA8PSAxKSB7XG4gICAgICAgIG4gPSAobiAqIDEwMCkgKyBcIiVcIjtcbiAgICB9XG5cbiAgICByZXR1cm4gbjtcbn1cblxuLy8gQ29udmVydHMgYSBkZWNpbWFsIHRvIGEgaGV4IHZhbHVlXG5mdW5jdGlvbiBjb252ZXJ0RGVjaW1hbFRvSGV4KGQpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChwYXJzZUZsb2F0KGQpICogMjU1KS50b1N0cmluZygxNik7XG59XG4vLyBDb252ZXJ0cyBhIGhleCB2YWx1ZSB0byBhIGRlY2ltYWxcbmZ1bmN0aW9uIGNvbnZlcnRIZXhUb0RlY2ltYWwoaCkge1xuICAgIHJldHVybiAocGFyc2VJbnRGcm9tSGV4KGgpIC8gMjU1KTtcbn1cblxudmFyIG1hdGNoZXJzID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgLy8gPGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtdmFsdWVzLyNpbnRlZ2Vycz5cbiAgICB2YXIgQ1NTX0lOVEVHRVIgPSBcIlstXFxcXCtdP1xcXFxkKyU/XCI7XG5cbiAgICAvLyA8aHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy12YWx1ZXMvI251bWJlci12YWx1ZT5cbiAgICB2YXIgQ1NTX05VTUJFUiA9IFwiWy1cXFxcK10/XFxcXGQqXFxcXC5cXFxcZCslP1wiO1xuXG4gICAgLy8gQWxsb3cgcG9zaXRpdmUvbmVnYXRpdmUgaW50ZWdlci9udW1iZXIuICBEb24ndCBjYXB0dXJlIHRoZSBlaXRoZXIvb3IsIGp1c3QgdGhlIGVudGlyZSBvdXRjb21lLlxuICAgIHZhciBDU1NfVU5JVCA9IFwiKD86XCIgKyBDU1NfTlVNQkVSICsgXCIpfCg/OlwiICsgQ1NTX0lOVEVHRVIgKyBcIilcIjtcblxuICAgIC8vIEFjdHVhbCBtYXRjaGluZy5cbiAgICAvLyBQYXJlbnRoZXNlcyBhbmQgY29tbWFzIGFyZSBvcHRpb25hbCwgYnV0IG5vdCByZXF1aXJlZC5cbiAgICAvLyBXaGl0ZXNwYWNlIGNhbiB0YWtlIHRoZSBwbGFjZSBvZiBjb21tYXMgb3Igb3BlbmluZyBwYXJlblxuICAgIHZhciBQRVJNSVNTSVZFX01BVENIMyA9IFwiW1xcXFxzfFxcXFwoXSsoXCIgKyBDU1NfVU5JVCArIFwiKVssfFxcXFxzXSsoXCIgKyBDU1NfVU5JVCArIFwiKVssfFxcXFxzXSsoXCIgKyBDU1NfVU5JVCArIFwiKVxcXFxzKlxcXFwpP1wiO1xuICAgIHZhciBQRVJNSVNTSVZFX01BVENINCA9IFwiW1xcXFxzfFxcXFwoXSsoXCIgKyBDU1NfVU5JVCArIFwiKVssfFxcXFxzXSsoXCIgKyBDU1NfVU5JVCArIFwiKVssfFxcXFxzXSsoXCIgKyBDU1NfVU5JVCArIFwiKVssfFxcXFxzXSsoXCIgKyBDU1NfVU5JVCArIFwiKVxcXFxzKlxcXFwpP1wiO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ1NTX1VOSVQ6IG5ldyBSZWdFeHAoQ1NTX1VOSVQpLFxuICAgICAgICByZ2I6IG5ldyBSZWdFeHAoXCJyZ2JcIiArIFBFUk1JU1NJVkVfTUFUQ0gzKSxcbiAgICAgICAgcmdiYTogbmV3IFJlZ0V4cChcInJnYmFcIiArIFBFUk1JU1NJVkVfTUFUQ0g0KSxcbiAgICAgICAgaHNsOiBuZXcgUmVnRXhwKFwiaHNsXCIgKyBQRVJNSVNTSVZFX01BVENIMyksXG4gICAgICAgIGhzbGE6IG5ldyBSZWdFeHAoXCJoc2xhXCIgKyBQRVJNSVNTSVZFX01BVENINCksXG4gICAgICAgIGhzdjogbmV3IFJlZ0V4cChcImhzdlwiICsgUEVSTUlTU0lWRV9NQVRDSDMpLFxuICAgICAgICBoc3ZhOiBuZXcgUmVnRXhwKFwiaHN2YVwiICsgUEVSTUlTU0lWRV9NQVRDSDQpLFxuICAgICAgICBoZXgzOiAvXiM/KFswLTlhLWZBLUZdezF9KShbMC05YS1mQS1GXXsxfSkoWzAtOWEtZkEtRl17MX0pJC8sXG4gICAgICAgIGhleDY6IC9eIz8oWzAtOWEtZkEtRl17Mn0pKFswLTlhLWZBLUZdezJ9KShbMC05YS1mQS1GXXsyfSkkLyxcbiAgICAgICAgaGV4NDogL14jPyhbMC05YS1mQS1GXXsxfSkoWzAtOWEtZkEtRl17MX0pKFswLTlhLWZBLUZdezF9KShbMC05YS1mQS1GXXsxfSkkLyxcbiAgICAgICAgaGV4ODogL14jPyhbMC05YS1mQS1GXXsyfSkoWzAtOWEtZkEtRl17Mn0pKFswLTlhLWZBLUZdezJ9KShbMC05YS1mQS1GXXsyfSkkL1xuICAgIH07XG59KSgpO1xuXG4vLyBgaXNWYWxpZENTU1VuaXRgXG4vLyBUYWtlIGluIGEgc2luZ2xlIHN0cmluZyAvIG51bWJlciBhbmQgY2hlY2sgdG8gc2VlIGlmIGl0IGxvb2tzIGxpa2UgYSBDU1MgdW5pdFxuLy8gKHNlZSBgbWF0Y2hlcnNgIGFib3ZlIGZvciBkZWZpbml0aW9uKS5cbmZ1bmN0aW9uIGlzVmFsaWRDU1NVbml0KGNvbG9yKSB7XG4gICAgcmV0dXJuICEhbWF0Y2hlcnMuQ1NTX1VOSVQuZXhlYyhjb2xvcik7XG59XG5cbi8vIGBzdHJpbmdJbnB1dFRvT2JqZWN0YFxuLy8gUGVybWlzc2l2ZSBzdHJpbmcgcGFyc2luZy4gIFRha2UgaW4gYSBudW1iZXIgb2YgZm9ybWF0cywgYW5kIG91dHB1dCBhbiBvYmplY3Rcbi8vIGJhc2VkIG9uIGRldGVjdGVkIGZvcm1hdC4gIFJldHVybnMgYHsgciwgZywgYiB9YCBvciBgeyBoLCBzLCBsIH1gIG9yIGB7IGgsIHMsIHZ9YFxuZnVuY3Rpb24gc3RyaW5nSW5wdXRUb09iamVjdChjb2xvcikge1xuXG4gICAgY29sb3IgPSBjb2xvci5yZXBsYWNlKHRyaW1MZWZ0LCcnKS5yZXBsYWNlKHRyaW1SaWdodCwgJycpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFyIG5hbWVkID0gZmFsc2U7XG4gICAgaWYgKG5hbWVzW2NvbG9yXSkge1xuICAgICAgICBjb2xvciA9IG5hbWVzW2NvbG9yXTtcbiAgICAgICAgbmFtZWQgPSB0cnVlO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb2xvciA9PSAndHJhbnNwYXJlbnQnKSB7XG4gICAgICAgIHJldHVybiB7IHI6IDAsIGc6IDAsIGI6IDAsIGE6IDAsIGZvcm1hdDogXCJuYW1lXCIgfTtcbiAgICB9XG5cbiAgICAvLyBUcnkgdG8gbWF0Y2ggc3RyaW5nIGlucHV0IHVzaW5nIHJlZ3VsYXIgZXhwcmVzc2lvbnMuXG4gICAgLy8gS2VlcCBtb3N0IG9mIHRoZSBudW1iZXIgYm91bmRpbmcgb3V0IG9mIHRoaXMgZnVuY3Rpb24gLSBkb24ndCB3b3JyeSBhYm91dCBbMCwxXSBvciBbMCwxMDBdIG9yIFswLDM2MF1cbiAgICAvLyBKdXN0IHJldHVybiBhbiBvYmplY3QgYW5kIGxldCB0aGUgY29udmVyc2lvbiBmdW5jdGlvbnMgaGFuZGxlIHRoYXQuXG4gICAgLy8gVGhpcyB3YXkgdGhlIHJlc3VsdCB3aWxsIGJlIHRoZSBzYW1lIHdoZXRoZXIgdGhlIHRpbnljb2xvciBpcyBpbml0aWFsaXplZCB3aXRoIHN0cmluZyBvciBvYmplY3QuXG4gICAgdmFyIG1hdGNoO1xuICAgIGlmICgobWF0Y2ggPSBtYXRjaGVycy5yZ2IuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7IHI6IG1hdGNoWzFdLCBnOiBtYXRjaFsyXSwgYjogbWF0Y2hbM10gfTtcbiAgICB9XG4gICAgaWYgKChtYXRjaCA9IG1hdGNoZXJzLnJnYmEuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7IHI6IG1hdGNoWzFdLCBnOiBtYXRjaFsyXSwgYjogbWF0Y2hbM10sIGE6IG1hdGNoWzRdIH07XG4gICAgfVxuICAgIGlmICgobWF0Y2ggPSBtYXRjaGVycy5oc2wuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7IGg6IG1hdGNoWzFdLCBzOiBtYXRjaFsyXSwgbDogbWF0Y2hbM10gfTtcbiAgICB9XG4gICAgaWYgKChtYXRjaCA9IG1hdGNoZXJzLmhzbGEuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7IGg6IG1hdGNoWzFdLCBzOiBtYXRjaFsyXSwgbDogbWF0Y2hbM10sIGE6IG1hdGNoWzRdIH07XG4gICAgfVxuICAgIGlmICgobWF0Y2ggPSBtYXRjaGVycy5oc3YuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7IGg6IG1hdGNoWzFdLCBzOiBtYXRjaFsyXSwgdjogbWF0Y2hbM10gfTtcbiAgICB9XG4gICAgaWYgKChtYXRjaCA9IG1hdGNoZXJzLmhzdmEuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7IGg6IG1hdGNoWzFdLCBzOiBtYXRjaFsyXSwgdjogbWF0Y2hbM10sIGE6IG1hdGNoWzRdIH07XG4gICAgfVxuICAgIGlmICgobWF0Y2ggPSBtYXRjaGVycy5oZXg4LmV4ZWMoY29sb3IpKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcjogcGFyc2VJbnRGcm9tSGV4KG1hdGNoWzFdKSxcbiAgICAgICAgICAgIGc6IHBhcnNlSW50RnJvbUhleChtYXRjaFsyXSksXG4gICAgICAgICAgICBiOiBwYXJzZUludEZyb21IZXgobWF0Y2hbM10pLFxuICAgICAgICAgICAgYTogY29udmVydEhleFRvRGVjaW1hbChtYXRjaFs0XSksXG4gICAgICAgICAgICBmb3JtYXQ6IG5hbWVkID8gXCJuYW1lXCIgOiBcImhleDhcIlxuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAoKG1hdGNoID0gbWF0Y2hlcnMuaGV4Ni5leGVjKGNvbG9yKSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHI6IHBhcnNlSW50RnJvbUhleChtYXRjaFsxXSksXG4gICAgICAgICAgICBnOiBwYXJzZUludEZyb21IZXgobWF0Y2hbMl0pLFxuICAgICAgICAgICAgYjogcGFyc2VJbnRGcm9tSGV4KG1hdGNoWzNdKSxcbiAgICAgICAgICAgIGZvcm1hdDogbmFtZWQgPyBcIm5hbWVcIiA6IFwiaGV4XCJcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKChtYXRjaCA9IG1hdGNoZXJzLmhleDQuZXhlYyhjb2xvcikpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByOiBwYXJzZUludEZyb21IZXgobWF0Y2hbMV0gKyAnJyArIG1hdGNoWzFdKSxcbiAgICAgICAgICAgIGc6IHBhcnNlSW50RnJvbUhleChtYXRjaFsyXSArICcnICsgbWF0Y2hbMl0pLFxuICAgICAgICAgICAgYjogcGFyc2VJbnRGcm9tSGV4KG1hdGNoWzNdICsgJycgKyBtYXRjaFszXSksXG4gICAgICAgICAgICBhOiBjb252ZXJ0SGV4VG9EZWNpbWFsKG1hdGNoWzRdICsgJycgKyBtYXRjaFs0XSksXG4gICAgICAgICAgICBmb3JtYXQ6IG5hbWVkID8gXCJuYW1lXCIgOiBcImhleDhcIlxuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAoKG1hdGNoID0gbWF0Y2hlcnMuaGV4My5leGVjKGNvbG9yKSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHI6IHBhcnNlSW50RnJvbUhleChtYXRjaFsxXSArICcnICsgbWF0Y2hbMV0pLFxuICAgICAgICAgICAgZzogcGFyc2VJbnRGcm9tSGV4KG1hdGNoWzJdICsgJycgKyBtYXRjaFsyXSksXG4gICAgICAgICAgICBiOiBwYXJzZUludEZyb21IZXgobWF0Y2hbM10gKyAnJyArIG1hdGNoWzNdKSxcbiAgICAgICAgICAgIGZvcm1hdDogbmFtZWQgPyBcIm5hbWVcIiA6IFwiaGV4XCJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlV0NBRzJQYXJtcyhwYXJtcykge1xuICAgIC8vIHJldHVybiB2YWxpZCBXQ0FHMiBwYXJtcyBmb3IgaXNSZWFkYWJsZS5cbiAgICAvLyBJZiBpbnB1dCBwYXJtcyBhcmUgaW52YWxpZCwgcmV0dXJuIHtcImxldmVsXCI6XCJBQVwiLCBcInNpemVcIjpcInNtYWxsXCJ9XG4gICAgdmFyIGxldmVsLCBzaXplO1xuICAgIHBhcm1zID0gcGFybXMgfHwge1wibGV2ZWxcIjpcIkFBXCIsIFwic2l6ZVwiOlwic21hbGxcIn07XG4gICAgbGV2ZWwgPSAocGFybXMubGV2ZWwgfHwgXCJBQVwiKS50b1VwcGVyQ2FzZSgpO1xuICAgIHNpemUgPSAocGFybXMuc2l6ZSB8fCBcInNtYWxsXCIpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKGxldmVsICE9PSBcIkFBXCIgJiYgbGV2ZWwgIT09IFwiQUFBXCIpIHtcbiAgICAgICAgbGV2ZWwgPSBcIkFBXCI7XG4gICAgfVxuICAgIGlmIChzaXplICE9PSBcInNtYWxsXCIgJiYgc2l6ZSAhPT0gXCJsYXJnZVwiKSB7XG4gICAgICAgIHNpemUgPSBcInNtYWxsXCI7XG4gICAgfVxuICAgIHJldHVybiB7XCJsZXZlbFwiOmxldmVsLCBcInNpemVcIjpzaXplfTtcbn1cblxuLy8gTm9kZTogRXhwb3J0IGZ1bmN0aW9uXG5pZiAodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gdGlueWNvbG9yO1xufVxuLy8gQU1EL3JlcXVpcmVqczogRGVmaW5lIHRoZSBtb2R1bGVcbmVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShmdW5jdGlvbiAoKSB7cmV0dXJuIHRpbnljb2xvcjt9KTtcbn1cbi8vIEJyb3dzZXI6IEV4cG9zZSB0byB3aW5kb3dcbmVsc2Uge1xuICAgIHdpbmRvdy50aW55Y29sb3IgPSB0aW55Y29sb3I7XG59XG5cbn0pKE1hdGgpO1xuIiwiLy8gQ29weXJpZ2h0IMKpIDIwMTYgUlRFIFLDqXNlYXUgZGUgdHJhbnNwb3J0IGTigJnDqWxlY3RyaWNpdMOpXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBkMyA9IHJlcXVpcmUoXCJkM1wiKTtcbiAgdmFyIG1pbmljaGFydHMgPSByZXF1aXJlKFwibWluaWNoYXJ0c1wiKTtcbiAgdmFyIHV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHMuanNcIik7XG5cbiAgTC5NaW5pY2hhcnQgPSBMLkNpcmNsZU1hcmtlci5leHRlbmQoe1xuICAgIC8qKiBPcHRpb25zIHVzZWQgdG8gaW5pdGlhbGl6ZS91cGRhdGUgYSBNaW5pY2hhcnQgb2JqZWN0LlxuICAgICAgKiBAdHlwZWRlZiB7b2JqZWN0fSBNaW5pY2hhcnRPcHRpb25zXG4gICAgICAqIEBtZW1iZXJPZiAnTC5NaW5pY2hhcnQnXG4gICAgICAqIEBwcm9wIHtzdHJpbmd9IFt0eXBlID0gXCJiYXJcIl1cbiAgICAgICogVHlwZSBvZiBjaGFydCB0byBjcmVhdGUuIFBvc3NpYmxlIHZhbHVlcyBhcmUgXCJiYXJcIiBmb3IgYmFyY2hhcnRzLCBcInBpZVwiXG4gICAgICAqIGZvciBwaWUgY2hhcnRzLCBcInBvbGFyLXJhZGl1c1wiIGFuZCBcInBvbGFyLWFyZWFcIiBmb3IgcG9sYXIgYXJlYSBjaGFydHNcbiAgICAgICogd2hlcmUgdmFsdWVzIGFyZSByZXByZXNlbnRlZCBlaXRoZXIgYnkgdGhlIHJhZGl1cyBvciB0aGUgYXJlYSBvZiB0aGVcbiAgICAgICogc2xpY2VzLlxuICAgICAgKiBAcHJvcCB7bnVtYmVyW119IFtkYXRhID0gWzFdXVxuICAgICAgKiBEYXRhIHZhbHVlcyB0aGUgY2hhcnQgaGFzIHRvIHJlcHJlc2VudC5cbiAgICAgICogQHByb3Age251bWJlcltdfFwiYXV0b1wifSBbbWF4VmFsdWVzID0gXCJhdXRvXCJdXG4gICAgICAqIG1heGltYWwgYWJzb2x1dGUgdmFsdWUgdGhlIGRhdGEgY291bGQgdGFrZS4gSXQgY2FuIGJlIGEgc2luZ2xlIG51bWVyaWNcbiAgICAgICogdmFsdWUgb3IgYW4gYXJyYXkgb2YgdmFsdWVzIHdpdGggc2FtZSBsZW5ndGggYXMgZGF0YS4gSW4gdGhlIGZpcnN0IGNhc2UsXG4gICAgICAqIGFsbCB2YWx1ZXMgd2lsbCBiZSByZXByZXNlbnRlZCB3aXRoIHRoZSBzYW1lIHNjYWxlIHdoaWxlIGluIHRoZSBzZWNvbmRcbiAgICAgICogY2FzZSwgZWFjaCB2YWx1ZSB3aWxsIGhhdmUgaXRzIG93biBzY2FsZS4gVGhpcyBpcyB1c2VmdWwgd2hlbiBvbmUgd2FudHNcbiAgICAgICogdG8gcmVwcmVzZW50IG11bHRpcGxlIHZhcmlhYmxlcyB0aGF0IGFyZSBub3QgY29tcGFyYWJsZS4gSWYgaXQgZXF1YWxzIHRvXG4gICAgICAqIFwiYXV0b1wiICh0aGUgZGVmYXVsdCkgdGhlbiB0aGUgbWF4aW11bSBhYnNvbHV0ZSB2YWx1ZSBpbiBkYXRhIGlzIHVzZWQuXG4gICAgICAqIEBwcm9wIHtzdHJpbmdbXX0gW2NvbG9ycz1kMy5zY2hlbWVDYXRlZ29yeTEwXSBBcnJheSBvZiBjb2xvcnMuIElmIGl0c1xuICAgICAgKiBsZW5ndGggaXMgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2YgZGF0YSwgY29sb3JzIGFyZSByZWN5Y2xlZC5cbiAgICAgICogQHByb3Age251bWJlcn0gW3dpZHRoPTYwXVxuICAgICAgKiBXaWR0aCBvZiB0aGUgY2hhcnQgd2hlbiBgdHlwZWAgZXF1YWxzICdiYXInIG9yIG1heGltYWwgZGlhbWV0ZXIgb2YgdGhlXG4gICAgICAqIGNoYXJ0IGZvciBhbGwgb3RoZXIgdHlwZXMuXG4gICAgICAqIEBwcm9wIHtudW1iZXJ9IFtoZWlnaHQ9NjBdXG4gICAgICAqIE1heGltYWwgaGVpZ2h0IG9mIGJhcmNoYXJ0cy5cbiAgICAgICogQHByb3Age3N0cmluZ1tdfFwibm9uZVwifFwiYXV0b1wifVtsYWJlbHM9XCJub25lXCJdXG4gICAgICAqIExhYmVscyB0byBkaXNwbGF5IG9uIHRoZSBjaGFydC4gSWYgaXQgZXF1YWxzIHRvIFwiYXV0b1wiIHRoZW4gZGF0YSB2YWx1ZXNcbiAgICAgICogYXJlIGRpc3BsYXllZCBpbiBhIGNvbXBhY3Qgd2F5LlxuICAgICAgKiBAcHJvcCB7bnVtYmVyfSBbbGFiZWxNaW5TaXplPThdXG4gICAgICAqIExhYmVscyBhcmUgYXV0b21hdGljYWxseSBoaWRkZW4gaWYgdGhlIGxhYmVsIGhlaWdodCBpcyBsZXNzIHRoYW4gdGhpcyBudW1iZXIuXG4gICAgICAqIEBwcm9wIHtudW1iZXJ9IFtsYWJlbE1heFNpemU9MjRdXG4gICAgICAqIE1heGltYWwgaGVpZ2h0IG9mIGxhYmVscyBpbiBwaXhlbHMuXG4gICAgICAqIEBwcm9wIHtudW1iZXJ9IFtsYWJlbFBhZGRpbmc9Ml1cbiAgICAgICogUGFkZGluZyB0byBhcHBseSB0byBsYWJlbHMuXG4gICAgICAqIEBwcm9wIHtzdHJpbmd9IFtsYWJlbFN0eWxlPVwiZm9udC1mYW1pbHk6c2Fucy1zZXJpZlwiXVxuICAgICAgKiBDU1Mgc3R5bGUgdG8gYXBwbHkgdG8gbGFiZWxzXG4gICAgICAqIEBwcm9wIHtzdHJpbmd9IFtsYWJlbENvbG9yPVwiYXV0b1wiXVxuICAgICAgKiBDb2xvciB0byBhcHBseSB0byBsYWJlbHMuIElmIFwiYXV0b1wiLCB0ZXh0IHdpbGwgYmUgYmxhY2sgb3Igd2hpdGVcbiAgICAgICogZGVwZW5kaW5nIG9uIHRoZSBiYWNrZ3JvdW5kIGNvbG9yLlxuICAgICAgKiBAcHJvcCB7bnVtYmVyfSBbdHJhbnNpdGlvblRpbWU9NzUwXVxuICAgICAgKiBEdXJhdGlvbiBpbiBtaWxsaXNlY29uZHEgb2YgdHJhbnNpdGlvbnMuXG4gICAgICAqXG4gICAgICAqL1xuICAgIG9wdGlvbnM6IHtcbiAgICAgIHR5cGU6IFwiYmFyXCIsXG4gICAgICBkYXRhOiBbMV0sXG4gICAgICBtYXhWYWx1ZXM6IFwiYXV0b1wiLFxuICAgICAgY29sb3JzOiBkMy5zY2hlbWVDYXRlZ29yeTEwLFxuICAgICAgd2lkdGg6IDYwLFxuICAgICAgaGVpZ2h0OiA2MCxcbiAgICAgIG9wYWNpdHk6IDEsXG4gICAgICBsYWJlbHM6XCJub25lXCIsXG4gICAgICBsYWJlbE1pblNpemU6IDgsXG4gICAgICBsYWJlbE1heFNpemU6IDI0LFxuICAgICAgbGFiZWxQYWRkaW5nOiAyLFxuICAgICAgbGFiZWxDb2xvcjogXCJhdXRvXCIsXG4gICAgICBsYWJlbFN0eWxlOiBcImZvbnQtZmFtaWx5OnNhbnMtc2VyaWZcIixcbiAgICAgIHRyYW5zaXRpb25UaW1lOiA3NTBcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICAqIEBjbGFzcyAnTC5NaW5pY2hhcnQnXG4gICAgICAqIEBzdW1tYXJ5IGFkZCBhZGQgYmFyLCBwaWUgYW5kIHBvbGFyIGNoYXJ0cyB0byBhIGxlYWZsZXQgbWFwXG4gICAgICAqIEBkZXNjIEwuTWluaWNoYXJ0IGlzIHVzZWQgdG8gYWRkIGR5bmFtaWMgY2hhcnRzIG9uIGEgbGVhZmxldCBtYXAuIEl0IGlzIHNwZWNpYWxseVxuICAgICAgKiB1c2VmdWwgdG8gcmVwcmVzZW50IG11bHRpcGxlIGRhdGEgdmFsdWVzIGFzc29jaWF0ZWQgdG8gc29tZSBnZW9ncmFwaGljYWxcbiAgICAgICogY29vcmRpbmF0ZXMuXG4gICAgICAqXG4gICAgICAqIEBleGFtcGxlXG4gICAgICAqXG4gICAgICAqIEwubWluaWNoYXJ0KFswLCAwXSwge2RhdGE6IFsxLCAyLCAzXSwgbWF4VmFsdWVzOiAzfSlcbiAgICAgICpcbiAgICAgICogQHBhcmFtIHtMLlBvaW50fSBjZW50ZXJcbiAgICAgICogQHBhcmFtIHtNaW5pY2hhcnRPcHRpb25zfSBvcHRpb25zIC0gT2JqZWN0IGNvbnRhaW5pbmdcbiAgICAgICogb3B0aW9ucyB0byBjb25zdHJ1Y3QgYSBjaGFydC5cbiAgICAgICovXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oY2VudGVyLCBvcHRpb25zKSB7XG4gICAgICB0aGlzLl9jZW50ZXIgPSBjZW50ZXI7XG4gICAgICB0aGlzLl96b29tID0gMDtcbiAgICAgIHRoaXMub3B0aW9ucyA9IHV0aWxzLm1lcmdlT3B0aW9ucyhvcHRpb25zLCB0aGlzLm9wdGlvbnMpO1xuICAgICAgTC5DaXJjbGVNYXJrZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbChcbiAgICAgICAgdGhpcyxcbiAgICAgICAgY2VudGVyLFxuICAgICAgICB7cmFkaXVzOiB0aGlzLm9wdGlvbnMud2lkdGgvMiwgc3Ryb2tlOiBmYWxzZSwgZmlsbDogZmFsc2V9XG4gICAgICApO1xuICAgIH0sXG5cbiAgICBvbkFkZDogZnVuY3Rpb24obWFwKSB7XG4gICAgICBMLkNpcmNsZU1hcmtlci5wcm90b3R5cGUub25BZGQuY2FsbCh0aGlzLCBtYXApO1xuICAgICAgLy8gQ2hhbmdlIGNsYXNzIG9mIGNvbnRhaW5lciBzbyB0aGF0IHRoZSBlbGVtZW50IGhpZGVzIHdoZW4gem9vbWluZ1xuICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lciB8fCB0aGlzLl9yZW5kZXJlci5fcm9vdEdyb3VwO1xuICAgICAgY29udGFpbmVyLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwibGVhZmxldC16b29tLWhpZGVcIik7XG5cbiAgICAgIC8vIGNyZWF0ZSB0aGUgc3ZnIGVsZW1lbnQgdGhhdCBob2xkcyB0aGUgY2hhcnRcbiAgICAgIHRoaXMuX2NoYXJ0ID0gZDMuc2VsZWN0KGNvbnRhaW5lcikuYXBwZW5kKFwiZ1wiKTtcblxuICAgICAgaWYgKEwudmVyc2lvbiA+PSBcIjEuMFwiKSB0aGlzLmFkZEludGVyYWN0aXZlVGFyZ2V0KHRoaXMuX2NoYXJ0Lm5vZGUoKSk7XG5cbiAgICAgIG1hcC5vbignbW92ZWVuZCcsIHRoaXMuX29uTW92ZWVuZCwgdGhpcyk7XG5cbiAgICAgIHRoaXMuX3JlZHJhdyh0cnVlKTtcbiAgICB9LFxuXG4gICAgb25SZW1vdmU6IGZ1bmN0aW9uKG1hcCkge1xuICAgICAgLy8gcmVtb3ZlIGxheWVyJ3MgRE9NIGVsZW1lbnRzIGFuZCBsaXN0ZW5lcnNcbiAgICAgIEwuQ2lyY2xlTWFya2VyLnByb3RvdHlwZS5vblJlbW92ZS5jYWxsKHRoaXMsIG1hcCk7XG4gICAgICBtYXAub2ZmKCdtb3ZlZW5kJywgdGhpcy5fb25Nb3ZlZW5kLCB0aGlzKTtcbiAgICB9LFxuXG4gICAgX29uTW92ZWVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAvLyBSZWRyYXcgY2hhcnQgb25seSBpZiB6b29tIGhhcyBjaGFuZ2VkXG4gICAgICB2YXIgb2xkWm9vbSA9IHRoaXMuX3pvb207XG4gICAgICB0aGlzLl96b29tID0gdGhpcy5fbWFwLmdldFpvb20oKTtcbiAgICAgIGlmIChvbGRab29tICE9IHRoaXMuX3pvb20pIHRoaXMuX3JlZHJhdygpIDtcbiAgICB9LFxuXG4gICAgLyoqIFVwZGF0ZSB0aGUgb3B0aW9ucyBvZiBhIG1pbmljaGFydCBvYmplY3QuXG4gICAgICAqIEBtZXRob2Qgc2V0T3B0aW9uc1xuICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICogQG1lbWJlck9mICdMLk1pbmljaGFydCdcbiAgICAgICpcbiAgICAgICogQHBhcmFtIHtNaW5pY2hhcnRPcHRpb25zfSBvcHRpb25zIC0gT2JqZWN0IGNvbnRhaW5pbmcgb3B0aW9ucyB0byB1cGRhdGUgdGhlIGNoYXJ0LlxuICAgICAgKi9cbiAgICBzZXRPcHRpb25zOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICB2YXIgbmV3Q2hhcnQgPSBvcHRpb25zLnR5cGUgJiYgb3B0aW9ucy50eXBlICE9IHRoaXMub3B0aW9ucy50eXBlO1xuICAgICAgdGhpcy5vcHRpb25zID0gdXRpbHMubWVyZ2VPcHRpb25zKG9wdGlvbnMsIHRoaXMub3B0aW9ucyk7XG4gICAgICB0aGlzLl9yZWRyYXcobmV3Q2hhcnQpO1xuICAgIH0sXG5cbiAgICBfcmVkcmF3OiBmdW5jdGlvbihuZXdDaGFydCkge1xuICAgICAgLy8gTW92ZSBjb250YWluZXIgb24gdGhlIG1hcFxuICAgICAgdmFyIGMgPSB0aGlzLl9tYXAubGF0TG5nVG9MYXllclBvaW50KHRoaXMuX2NlbnRlcik7XG4gICAgICB2YXIgaDtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMudHlwZSA9PSBcImJhclwiKSB7XG4gICAgICAgIGggPSB0aGlzLm9wdGlvbnMuaGVpZ2h0ICogMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGggPSB0aGlzLm9wdGlvbnMud2lkdGg7XG4gICAgICB9XG4gICAgICB0aGlzLl9jaGFydFxuICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIChjLnggLSB0aGlzLm9wdGlvbnMud2lkdGggLyAyKSArIFwiLFwiICsgKGMueSAtIGggLyAyKSArIFwiKVwiKVxuICAgICAgICAudHJhbnNpdGlvbigpXG4gICAgICAgIC5kdXJhdGlvbih0aGlzLm9wdGlvbnMudHJhbnNpdGlvblRpbWUpXG4gICAgICAgIC5hdHRyKFwib3BhY2l0eVwiLCB0aGlzLm9wdGlvbnMub3BhY2l0eSk7XG5cbiAgICAgIC8vIHByZXBhcmUgZGF0YVxuICAgICAgdmFyIGRhdGEgPSB0aGlzLm9wdGlvbnMuZGF0YTtcbiAgICAgIGRhdGEgPSB1dGlscy50b0FycmF5KGRhdGEpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpc05hTihkYXRhW2ldKSB8fCAhaXNGaW5pdGUoZGF0YVtpXSkpIGRhdGFbaV0gPSAwO1xuICAgICAgfVxuXG4gICAgICAvLyBNYXggYWJzb2x1dGUgdmFsdWUgZm9yIGVhY2ggdmFyaWFibGVcbiAgICAgIHZhciBtYXggPSB0aGlzLm9wdGlvbnMubWF4VmFsdWVzO1xuICAgICAgaWYgKG1heCA9PT0gXCJhdXRvXCIpIHtcbiAgICAgICAgbWF4ID0gTWF0aC5tYXgoXG4gICAgICAgICAgZDMubWF4KGRhdGEpLFxuICAgICAgICAgIE1hdGguYWJzKGQzLm1pbihkYXRhKSlcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgbWF4ID0gdXRpbHMudG9BcnJheShtYXgpO1xuXG4gICAgICBpZihtYXgubGVuZ3RoICE9PSAxICYmIG1heC5sZW5ndGggIT0gZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiJ21heFZhbHVlcycgc2hvdWxkIGJlIGEgc2luZ2xlIG51bWJlciBvciBoYXZlIHNhbWUgbGVuZ3RoIGFzICdkYXRhJ1wiKTtcbiAgICAgIH1cblxuICAgICAgLy8gU2NhbGUgZGF0YS4gVGhpcyBzdGVwIGlzIGVzc2VudGlhbCB0byBoYXZlIGRpZmZlcmVudCBzY2FsZXMgZm9yIGVhY2hcbiAgICAgIC8vIHZhcmlhYmxlLiBPbmx5IHJlbGV2YW50IGlmIGNoYXJ0IGlzIG5vdCBhIHBpZS9cbiAgICAgIHZhciBkYXRhU2NhbGVkID0gW107XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMudHlwZSA9PSBcInBpZVwiKSB7XG4gICAgICAgIGRhdGFTY2FsZWQgPSBkYXRhO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgZGF0YVNjYWxlZC5wdXNoKGRhdGFbaV0gLyBtYXhbaSAlIG1heC5sZW5ndGhdKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBQcmVwYXJlIGxhYmVsc1xuICAgICAgdmFyIGxhYmVscyA9IHRoaXMub3B0aW9ucy5sYWJlbHM7XG4gICAgICBpZiAobGFiZWxzID09PSBcImF1dG9cIikge1xuICAgICAgICBsYWJlbHMgPSB1dGlscy5wcmV0dHlOdW1iZXJzKGRhdGEpO1xuICAgICAgfVxuXG4gICAgICAvLyBHZW5lcmF0b3IgZnVuY3Rpb25cbiAgICAgIHZhciBnZW5lcmF0b3IsIHR5cGU7XG4gICAgICBzd2l0Y2godGhpcy5vcHRpb25zLnR5cGUpIHtcbiAgICAgICAgY2FzZSBcImJhclwiOlxuICAgICAgICAgIGdlbmVyYXRvciA9IG1pbmljaGFydHMuQmFyY2hhcnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJwaWVcIjpcbiAgICAgICAgICBnZW5lcmF0b3IgPSBtaW5pY2hhcnRzLlBpZWNoYXJ0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwicG9sYXItcmFkaXVzXCI6XG4gICAgICAgICAgZ2VuZXJhdG9yID0gbWluaWNoYXJ0cy5Qb2xhcmNoYXJ0O1xuICAgICAgICAgIHR5cGUgPSBcInJhZGl1c1wiO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwicG9sYXItYXJlYVwiOlxuICAgICAgICAgIGdlbmVyYXRvciA9IG1pbmljaGFydHMuUG9sYXJjaGFydDtcbiAgICAgICAgICB0eXBlID0gXCJhcmVhXCI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIC8vIEdyYXBoaWNhbCBvcHRpb25zIGZvciB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uXG4gICAgICB2YXIgY2hhcnRPcHRzID0ge1xuICAgICAgICB3aWR0aDogdGhpcy5vcHRpb25zLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IHRoaXMub3B0aW9ucy5oZWlnaHQgKiAyLCAvLyBVc2VkIG9ubHkgaWYgdHlwZSA9IFwiYmFyXCJcbiAgICAgICAgY29sb3JzOiB0aGlzLm9wdGlvbnMuY29sb3JzLFxuICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICB0cmFuc2l0aW9uVGltZTogdGhpcy5vcHRpb25zLnRyYW5zaXRpb25UaW1lLFxuICAgICAgICBtaW5WYWx1ZTogLTEsXG4gICAgICAgIG1heFZhbHVlOjEsXG4gICAgICAgIGxhYmVsczogbGFiZWxzLFxuICAgICAgICBsYWJlbENvbG9yczogdGhpcy5vcHRpb25zLmxhYmVsQ29sb3IsXG4gICAgICAgIGxhYmVsTWluU2l6ZTogdGhpcy5vcHRpb25zLmxhYmVsTWluU2l6ZSxcbiAgICAgICAgbGFiZWxNYXhTaXplOiB0aGlzLm9wdGlvbnMubGFiZWxNYXhTaXplLFxuICAgICAgICBsYWJlbFBhZGRpbmc6IHRoaXMub3B0aW9ucy5sYWJlbFBhZGRpbmcsXG4gICAgICAgIGxhYmVsQ2xhc3M6IFwibGVhZmxldC1jbGlja2FibGUgbGVhZmxldC1pbnRlcmFjdGl2ZVwiLFxuICAgICAgICBzaGFwZUNsYXNzOiBcImxlYWZsZXQtY2xpY2thYmxlIGxlYWZsZXQtaW50ZXJhY3RpdmVcIlxuICAgICAgfTtcblxuICAgICAgLy8gQ3JlYXRlIG9mIHVwZGF0ZSBjaGFydFxuICAgICAgaWYgKG5ld0NoYXJ0ID09PSB0cnVlKSB7XG4gICAgICAgIHRoaXMuX2NoYXJ0LnNlbGVjdEFsbChcIipcIikucmVtb3ZlKCk7XG4gICAgICAgIHRoaXMuX2NoYXJ0T2JqZWN0ID0gbmV3IGdlbmVyYXRvcih0aGlzLl9jaGFydC5ub2RlKCksIGRhdGFTY2FsZWQsIGNoYXJ0T3B0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9jaGFydE9iamVjdC51cGRhdGUoZGF0YVNjYWxlZCwgY2hhcnRPcHRzKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIEwubWluaWNoYXJ0ID0gZnVuY3Rpb24oY2VudGVyLCBvcHRpb25zKSB7XG4gIHJldHVybiBuZXcgTC5NaW5pY2hhcnQoY2VudGVyLCBvcHRpb25zKTtcbn07XG59KSgpO1xuIiwiKGZ1bmN0aW9uKCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgbW9kdWxlLmV4cG9ydHMubWVyZ2VPcHRpb25zID0gbWVyZ2VPcHRpb25zO1xuICBtb2R1bGUuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcbiAgbW9kdWxlLmV4cG9ydHMudG9GdW5jdGlvbiA9IHRvRnVuY3Rpb247XG4gIG1vZHVsZS5leHBvcnRzLnByZXR0eU51bWJlcnMgPSBmdW5jdGlvbihudW1iZXJzKSB7XG4gICAgcmV0dXJuIG51bWJlcnMubWFwKHByZXR0eU51bWJlcik7XG4gIH1cblxuICBmdW5jdGlvbiBtZXJnZU9wdGlvbnMob3B0aW9ucywgZGVmYXVsdHMpIHtcbiAgICBpZiAob3B0aW9ucykgb3B0aW9ucyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkob3B0aW9ucykpO1xuICAgIGVsc2Ugb3B0aW9ucyA9IHt9O1xuICAgIGRlZmF1bHRzID0gZGVmYXVsdHMgfHwge307XG4gICAgZm9yICh2YXIgb3B0IGluIGRlZmF1bHRzKSB7XG4gICAgICBpZiAoZGVmYXVsdHMuaGFzT3duUHJvcGVydHkob3B0KSAmJiAhb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShvcHQpKSB7XG4gICAgICAgIG9wdGlvbnNbb3B0XSA9IGRlZmF1bHRzW29wdF07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9BcnJheSh4KSB7XG4gICAgaWYgKHguY29uc3RydWN0b3IgIT09IEFycmF5KSB4ID0gW3hdO1xuICAgIHJldHVybiB4O1xuICB9XG5cbiAgZnVuY3Rpb24gdG9GdW5jdGlvbih4KSB7XG4gICAgaWYgKHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAoeCk7XG4gICAgeCA9IHRvQXJyYXkoeCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGQsIGkpIHtyZXR1cm4geFtpICUgeC5sZW5ndGhdfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByZXR0eU51bWJlcihudW1iZXIpIHtcbiAgICBpZiAoaXNOYU4obnVtYmVyKSB8fCAhaXNGaW5pdGUobnVtYmVyKSkgcmV0dXJuIFwiXCI7XG5cbiAgICB2YXIgYWJzVmFsID0gTWF0aC5hYnMobnVtYmVyKTtcbiAgICB2YXIgc2lnbj0gbnVtYmVyIDwgMD8gXCItXCI6IFwiXCI7XG4gICAgdmFyIHNjYWxlO1xuXG4gICAgaWYoIGFic1ZhbCA8IDEwMDAgKSB7XG4gICAgICAgIHNjYWxlID0gJyc7XG4gICAgfSBlbHNlIGlmKCBhYnNWYWwgPCAxMDAwMDAwICkge1xuICAgICAgICBzY2FsZSA9ICdLJztcbiAgICAgICAgYWJzVmFsID0gYWJzVmFsLzEwMDA7XG5cbiAgICB9IGVsc2UgaWYoIGFic1ZhbCA8IDEwMDAwMDAwMDAgKSB7XG4gICAgICAgIHNjYWxlID0gJ00nO1xuICAgICAgICBhYnNWYWwgPSBhYnNWYWwvMTAwMDAwMDtcblxuICAgIH0gZWxzZSBpZiggYWJzVmFsIDwgMTAwMDAwMDAwMDAwMCApIHtcbiAgICAgICAgc2NhbGUgPSAnQic7XG4gICAgICAgIGFic1ZhbCA9IGFic1ZhbC8xMDAwMDAwMDAwO1xuXG4gICAgfSBlbHNlIGlmKCBhYnNWYWwgPCAxMDAwMDAwMDAwMDAwMDAwICkge1xuICAgICAgICBzY2FsZSA9ICdUJztcbiAgICAgICAgYWJzVmFsID0gYWJzVmFsLzEwMDAwMDAwMDAwMDA7XG4gICAgfVxuXG4gICAgaWYgKGFic1ZhbCA+IDEwKSBhYnNWYWwgPSByb3VuZFRvKGFic1ZhbCk7XG4gICAgZWxzZSBpZiAoYWJzVmFsID4gMSkgYWJzVmFsID0gcm91bmRUbyhhYnNWYWwsIDEwLCB0cnVlKTtcbiAgICBlbHNlIGFic1ZhbCA9IHJvdW5kVG8oYWJzVmFsLCAxMDAsIHRydWUpO1xuXG4gICAgcmV0dXJuIHNpZ24gKyBhYnNWYWwgKyBzY2FsZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJvdW5kVG8obnVtYmVyLCB0bywgaW52ZXJzZSkge1xuICAgIHRvID0gdG8gfHwgMTtcbiAgICBpZiAoaW52ZXJzZSkgcmV0dXJuIE1hdGgucm91bmQobnVtYmVyICogdG8pIC8gdG87XG4gICAgZWxzZSByZXR1cm4gTWF0aC5yb3VuZChudW1iZXIgLyB0bykgKiB0bztcbiAgfVxufSgpKTtcbiJdfQ== diff --git a/dist/leaflet.minichart.min.js b/dist/leaflet.minichart.min.js index e1da355..1c4b9ee 100644 --- a/dist/leaflet.minichart.min.js +++ b/dist/leaflet.minichart.min.js @@ -1,10 +1,11 @@ /*! leaflet.minichart 0.2.3 2017-05-02 Copyright © 2016 RTE Réseau de transport d’électricité */ -!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g=Mj?e*=10:f>=Nj?e*=5:f>=Oj&&(e*=2),b1&&Tk(a[c[d-2]],a[c[d-1]],a[e])<=0;)--d;c[d++]=e}return c.slice(0,d)}function H(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function I(){return new H}function J(a,b,c,d){if(isNaN(b)||isNaN(c))return a;var e,f,g,h,i,j,k,l,m,n=a._root,o={data:d},p=a._x0,q=a._y0,r=a._x1,s=a._y1;if(!n)return a._root=o,a;for(;n.length;)if((j=b>=(f=(p+r)/2))?p=f:r=f,(k=c>=(g=(q+s)/2))?q=g:s=g,e=n,!(n=n[l=k<<1|j]))return e[l]=o,a;if(h=+a._x.call(null,n.data),i=+a._y.call(null,n.data),b===h&&c===i)return o.next=n,e?e[l]=o:a._root=o,a;do e=e?e[l]=new Array(4):a._root=new Array(4),(j=b>=(f=(p+r)/2))?p=f:r=f,(k=c>=(g=(q+s)/2))?q=g:s=g;while((l=k<<1|j)===(m=(i>=g)<<1|h>=f));return e[m]=n,e[l]=o,a}function K(a){var b,c,d,e,f=a.length,g=new Array(f),h=new Array(f),i=1/0,j=1/0,k=-(1/0),l=-(1/0);for(c=0;ck&&(k=d),el&&(l=e));for(k=1))throw new Error;this._size=a,this._call=this._error=null,this._tasks=[],this._data=[],this._waiting=this._active=this._ended=this._start=0}function S(a){if(!a._start)try{T(a)}catch(b){if(a._tasks[a._ended+a._active-1])V(a,b);else if(!a._data)throw b}}function T(a){for(;a._start=a._waiting&&a._active=0;)if((c=a._tasks[d])&&(a._tasks[d]=null,c.abort))try{c.abort()}catch(a){}a._active=NaN,W(a)}function W(a){if(!a._active&&a._call){var b=a._data;a._data=void 0,a._call(a._error,b)}}function X(a){return new R(arguments.length?+a:1/0)}function Y(a){return a.innerRadius}function Z(a){return a.outerRadius}function $(a){return a.startAngle}function _(a){return a.endAngle}function aa(a){return a&&a.padAngle}function ba(a){return a>=1?sl:a<=-1?-sl:Math.asin(a)}function ca(a,b,c,d,e,f,g,h){var i=c-a,j=d-b,k=g-e,l=h-f,m=(k*(b-f)-l*(a-e))/(l*i-k*j);return[a+m*i,b+m*j]}function da(a,b,c,d,e,f,g){var h=a-c,i=b-d,j=(g?f:-f)/Math.sqrt(h*h+i*i),k=j*i,l=-j*h,m=a+k,n=b+l,o=c+k,p=d+l,q=(m+o)/2,r=(n+p)/2,s=o-m,t=p-n,u=s*s+t*t,v=e-f,w=m*p-o*n,x=(t<0?-1:1)*Math.sqrt(Math.max(0,v*v*u-w*w)),y=(w*t-s*x)/u,z=(-w*s-t*x)/u,A=(w*t+s*x)/u,B=(-w*s+t*x)/u,C=y-q,D=z-r,E=A-q,F=B-r;return C*C+D*D>E*E+F*F&&(y=A,z=B),{cx:y,cy:z,x01:-k,y01:-l,x11:y*(e/v-1),y11:z*(e/v-1)}}function ea(a){this._context=a}function fa(a){return a[0]}function ga(a){return a[1]}function ha(a){this._curve=a}function ia(a){function b(b){return new ha(a(b))}return b._curve=a,b}function ja(a){var b=a.curve;return a.angle=a.x,delete a.x,a.radius=a.y,delete a.y,a.curve=function(a){return arguments.length?b(ia(a)):b()._curve},a}function ka(a,b,c){a._context.bezierCurveTo((2*a._x0+a._x1)/3,(2*a._y0+a._y1)/3,(a._x0+2*a._x1)/3,(a._y0+2*a._y1)/3,(a._x0+4*a._x1+b)/6,(a._y0+4*a._y1+c)/6)}function la(a){this._context=a}function ma(a){this._context=a}function na(a){this._context=a}function oa(a,b){this._basis=new la(a),this._beta=b}function pa(a,b,c){a._context.bezierCurveTo(a._x1+a._k*(a._x2-a._x0),a._y1+a._k*(a._y2-a._y0),a._x2+a._k*(a._x1-b),a._y2+a._k*(a._y1-c),a._x2,a._y2)}function qa(a,b){this._context=a,this._k=(1-b)/6}function ra(a,b){this._context=a,this._k=(1-b)/6}function sa(a,b){this._context=a,this._k=(1-b)/6}function ta(a,b,c){var d=a._x1,e=a._y1,f=a._x2,g=a._y2;if(a._l01_a>ql){var h=2*a._l01_2a+3*a._l01_a*a._l12_a+a._l12_2a,i=3*a._l01_a*(a._l01_a+a._l12_a);d=(d*h-a._x0*a._l12_2a+a._x2*a._l01_2a)/i,e=(e*h-a._y0*a._l12_2a+a._y2*a._l01_2a)/i}if(a._l23_a>ql){var j=2*a._l23_2a+3*a._l23_a*a._l12_a+a._l12_2a,k=3*a._l23_a*(a._l23_a+a._l12_a);f=(f*j+a._x1*a._l23_2a-b*a._l12_2a)/k,g=(g*j+a._y1*a._l23_2a-c*a._l12_2a)/k}a._context.bezierCurveTo(d,e,f,g,a._x2,a._y2)}function ua(a,b){this._context=a,this._alpha=b}function va(a,b){this._context=a,this._alpha=b}function wa(a,b){this._context=a,this._alpha=b}function xa(a){this._context=a}function ya(a){return a<0?-1:1}function za(a,b,c){var d=a._x1-a._x0,e=b-a._x1,f=(a._y1-a._y0)/(d||e<0&&-0),g=(c-a._y1)/(e||d<0&&-0),h=(f*e+g*d)/(d+e);return(ya(f)+ya(g))*Math.min(Math.abs(f),Math.abs(g),.5*Math.abs(h))||0}function Aa(a,b){var c=a._x1-a._x0;return c?(3*(a._y1-a._y0)/c-b)/2:b}function Ba(a,b,c){var d=a._x0,e=a._y0,f=a._x1,g=a._y1,h=(f-d)/3;a._context.bezierCurveTo(d+h,e+h*b,f-h,g-h*c,f,g)}function Ca(a){this._context=a}function Da(a){this._context=new Ea(a)}function Ea(a){this._context=a}function Fa(a){return new Ca(a)}function Ga(a){return new Da(a)}function Ha(a){this._context=a}function Ia(a){var b,c,d=a.length-1,e=new Array(d),f=new Array(d),g=new Array(d);for(e[0]=0,f[0]=2,g[0]=a[0]+2*a[1],b=1;b=0;--b)e[b]=(g[b]-e[b+1])/f[b];for(f[d-1]=(a[d]+e[d-1])/2,b=0;b>8&15|b>>4&240,b>>4&15|240&b,(15&b)<<4|15&b,1)):(b=Cm.exec(a))?Ra(parseInt(b[1],16)):(b=Dm.exec(a))?new Va(b[1],b[2],b[3],1):(b=Em.exec(a))?new Va(255*b[1]/100,255*b[2]/100,255*b[3]/100,1):(b=Fm.exec(a))?Sa(b[1],b[2],b[3],b[4]):(b=Gm.exec(a))?Sa(255*b[1]/100,255*b[2]/100,255*b[3]/100,b[4]):(b=Hm.exec(a))?Wa(b[1],b[2]/100,b[3]/100,1):(b=Im.exec(a))?Wa(b[1],b[2]/100,b[3]/100,b[4]):Jm.hasOwnProperty(a)?Ra(Jm[a]):"transparent"===a?new Va(NaN,NaN,NaN,0):null}function Ra(a){return new Va(a>>16&255,a>>8&255,255&a,1)}function Sa(a,b,c,d){return d<=0&&(a=b=c=NaN),new Va(a,b,c,d)}function Ta(a){return a instanceof Pa||(a=Qa(a)),a?(a=a.rgb(),new Va(a.r,a.g,a.b,a.opacity)):new Va}function Ua(a,b,c,d){return 1===arguments.length?Ta(a):new Va(a,b,c,null==d?1:d)}function Va(a,b,c,d){this.r=+a,this.g=+b,this.b=+c,this.opacity=+d}function Wa(a,b,c,d){return d<=0?a=b=c=NaN:c<=0||c>=1?a=b=NaN:b<=0&&(a=NaN),new Za(a,b,c,d)}function Xa(a){if(a instanceof Za)return new Za(a.h,a.s,a.l,a.opacity);if(a instanceof Pa||(a=Qa(a)),!a)return new Za;if(a instanceof Za)return a;a=a.rgb();var b=a.r/255,c=a.g/255,d=a.b/255,e=Math.min(b,c,d),f=Math.max(b,c,d),g=NaN,h=f-e,i=(f+e)/2;return h?(g=b===f?(c-d)/h+6*(c0&&i<1?0:g,new Za(g,h,i,a.opacity)}function Ya(a,b,c,d){return 1===arguments.length?Xa(a):new Za(a,b,c,null==d?1:d)}function Za(a,b,c,d){this.h=+a,this.s=+b,this.l=+c,this.opacity=+d}function $a(a,b,c){return 255*(a<60?b+(c-b)*a/60:a<180?c:a<240?b+(c-b)*(240-a)/60:b)}function _a(a){if(a instanceof bb)return new bb(a.l,a.a,a.b,a.opacity);if(a instanceof ib){var b=a.h*Km;return new bb(a.l,Math.cos(b)*a.c,Math.sin(b)*a.c,a.opacity)}a instanceof Va||(a=Ta(a));var c=fb(a.r),d=fb(a.g),e=fb(a.b),f=cb((.4124564*c+.3575761*d+.1804375*e)/Nm),g=cb((.2126729*c+.7151522*d+.072175*e)/Om),h=cb((.0193339*c+.119192*d+.9503041*e)/Pm);return new bb(116*g-16,500*(f-g),200*(g-h),a.opacity)}function ab(a,b,c,d){return 1===arguments.length?_a(a):new bb(a,b,c,null==d?1:d)}function bb(a,b,c,d){this.l=+a,this.a=+b,this.b=+c,this.opacity=+d}function cb(a){return a>Tm?Math.pow(a,1/3):a/Sm+Qm}function db(a){return a>Rm?a*a*a:Sm*(a-Qm)}function eb(a){return 255*(a<=.0031308?12.92*a:1.055*Math.pow(a,1/2.4)-.055)}function fb(a){return(a/=255)<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4)}function gb(a){if(a instanceof ib)return new ib(a.h,a.c,a.l,a.opacity);a instanceof bb||(a=_a(a));var b=Math.atan2(a.b,a.a)*Lm;return new ib(b<0?b+360:b,Math.sqrt(a.a*a.a+a.b*a.b),a.l,a.opacity)}function hb(a,b,c,d){return 1===arguments.length?gb(a):new ib(a,b,c,null==d?1:d)}function ib(a,b,c,d){this.h=+a,this.c=+b,this.l=+c,this.opacity=+d}function jb(a){if(a instanceof lb)return new lb(a.h,a.s,a.l,a.opacity);a instanceof Va||(a=Ta(a));var b=a.r/255,c=a.g/255,d=a.b/255,e=(_m*d+Zm*b-$m*c)/(_m+Zm-$m),f=d-e,g=(Ym*(c-e)-Wm*f)/Xm,h=Math.sqrt(g*g+f*f)/(Ym*e*(1-e)),i=h?Math.atan2(g,f)*Lm-120:NaN;return new lb(i<0?i+360:i,h,e,a.opacity)}function kb(a,b,c,d){return 1===arguments.length?jb(a):new lb(a,b,c,null==d?1:d)}function lb(a,b,c,d){this.h=+a,this.s=+b,this.l=+c,this.opacity=+d}function mb(a,b,c,d,e){var f=a*a,g=f*a;return((1-3*a+3*f-g)*b+(4-6*f+3*g)*c+(1+3*a+3*f-3*g)*d+g*e)/6}function nb(a,b){return function(c){return a+c*b}}function ob(a,b,c){return a=Math.pow(a,c),b=Math.pow(b,c)-a,c=1/c,function(d){return Math.pow(a+d*b,c)}}function pb(a,b){var c=b-a;return c?nb(a,c>180||c<-180?c-360*Math.round(c/360):c):gn(isNaN(a)?b:a)}function qb(a){return 1===(a=+a)?rb:function(b,c){return c-b?ob(b,c,a):gn(isNaN(b)?c:b)}}function rb(a,b){var c=b-a;return c?nb(a,c):gn(isNaN(a)?b:a)}function sb(a){return function(b){var c,d,e=b.length,f=new Array(e),g=new Array(e),h=new Array(e);for(c=0;c180?b+=360:b-a>180&&(a+=360),f.push({i:c.push(e(c)+"rotate(",null,d)-2,x:nn(a,b)})):b&&c.push(e(c)+"rotate("+b+d)}function h(a,b,c,f){a!==b?f.push({i:c.push(e(c)+"skewX(",null,d)-2,x:nn(a,b)}):b&&c.push(e(c)+"skewX("+b+d)}function i(a,b,c,d,f,g){if(a!==c||b!==d){var h=f.push(e(f)+"scale(",null,",",null,")");g.push({i:h-4,x:nn(a,c)},{i:h-2,x:nn(b,d)})}else 1===c&&1===d||f.push(e(f)+"scale("+c+","+d+")")}return function(b,c){var d=[],e=[];return b=a(b),c=a(c),f(b.translateX,b.translateY,c.translateX,c.translateY,d,e),g(b.rotate,c.rotate,d,e),h(b.skewX,c.skewX,d,e),i(b.scaleX,b.scaleY,c.scaleX,c.scaleY,d,e),b=c=null,function(a){for(var b,c=-1,f=e.length;++c=0&&(c=a.slice(d+1),a=a.slice(0,d)),a&&!b.hasOwnProperty(a))throw new Error("unknown type: "+a);return{type:a,name:c}})}function Ib(a,b){for(var c,d=0,e=a.length;d=0&&b._call.call(null,a),b=b._next;--ho}function Vb(){mo=(lo=oo.now())+no,ho=io=0;try{Ub()}finally{ho=0,Xb(),mo=0}}function Wb(){var a=oo.now(),b=a-lo;b>ko&&(no-=b,lo=a)}function Xb(){for(var a,b,c=Mn,d=1/0;c;)c._call?(d>c._time&&(d=c._time),a=c,c=c._next):(b=c._next,c._next=null,c=a?a._next=b:Mn=b);Nn=a,Yb(d)}function Yb(a){if(!ho){io&&(io=clearTimeout(io));var b=a-mo;b>24?(a<1/0&&(io=setTimeout(Vb,b)),jo&&(jo=clearInterval(jo))):(jo||(jo=setInterval(Wb,ko)),ho=1,po(Vb))}}function Zb(a,b,c,d){function e(b){return a(b=new Date(+b)),b}return e.floor=e,e.ceil=function(c){return a(c=new Date(c-1)),b(c,1),a(c),c},e.round=function(a){var b=e(a),c=e.ceil(a);return a-b0))return g;do g.push(new Date(+c));while(b(c,f),a(c),c=b)for(;a(b),!c(b);)b.setTime(b-1)},function(a,d){if(a>=a)for(;--d>=0;)for(;b(a,1),!c(a););})},c&&(e.count=function(b,d){return so.setTime(+b),to.setTime(+d),a(so),a(to),Math.floor(c(so,to))},e.every=function(a){return a=Math.floor(a),isFinite(a)&&a>0?a>1?e.filter(d?function(b){return d(b)%a===0}:function(b){return e.count(0,b)%a===0}):e:null}),e}function $b(a){return Zb(function(b){b.setDate(b.getDate()-(b.getDay()+7-a)%7),b.setHours(0,0,0,0)},function(a,b){a.setDate(a.getDate()+7*b)},function(a,b){return(b-a-(b.getTimezoneOffset()-a.getTimezoneOffset())*xo)/Ao})}function _b(a){return Zb(function(b){b.setUTCDate(b.getUTCDate()-(b.getUTCDay()+7-a)%7),b.setUTCHours(0,0,0,0)},function(a,b){a.setUTCDate(a.getUTCDate()+7*b)},function(a,b){return(b-a)/Ao})}function ac(a){if(!(b=Fp.exec(a)))throw new Error("invalid format: "+a);var b,c=b[1]||" ",d=b[2]||">",e=b[3]||"-",f=b[4]||"",g=!!b[5],h=b[6]&&+b[6],i=!!b[7],j=b[8]&&+b[8].slice(1),k=b[9]||"";"n"===k?(i=!0,k="g"):Ep[k]||(k=""),(g||"0"===c&&"="===d)&&(g=!0,c="0",d="="),this.fill=c,this.align=d,this.sign=e,this.symbol=f,this.zero=g,this.width=h,this.comma=i,this.precision=j,this.type=k}function bc(a){return a}function cc(b){return Hp=Jp(b),a.format=Hp.format,a.formatPrefix=Hp.formatPrefix,Hp}function dc(a){if(0<=a.y&&a.y<100){var b=new Date(-1,a.m,a.d,a.H,a.M,a.S,a.L);return b.setFullYear(a.y),b}return new Date(a.y,a.m,a.d,a.H,a.M,a.S,a.L)}function ec(a){if(0<=a.y&&a.y<100){var b=new Date(Date.UTC(-1,a.m,a.d,a.H,a.M,a.S,a.L));return b.setUTCFullYear(a.y),b}return new Date(Date.UTC(a.y,a.m,a.d,a.H,a.M,a.S,a.L))}function fc(a){return{y:a,m:0,d:1,H:0,M:0,S:0,L:0}}function gc(a){function b(a,b){return function(c){var d,e,f,g=[],h=-1,i=0,j=a.length;for(c instanceof Date||(c=new Date(+c));++h=i)return-1;if(e=b.charCodeAt(g++),37===e){if(e=b.charAt(g++),f=Q[e in Op?b.charAt(g++):e],!f||(d=f(a,c,d))<0)return-1}else if(e!=c.charCodeAt(d++))return-1}return d}function e(a,b,c){var d=E.exec(b.slice(c));return d?(a.p=F[d[0].toLowerCase()],c+d[0].length):-1}function f(a,b,c){var d=I.exec(b.slice(c));return d?(a.w=J[d[0].toLowerCase()],c+d[0].length):-1}function g(a,b,c){var d=G.exec(b.slice(c));return d?(a.w=H[d[0].toLowerCase()],c+d[0].length):-1}function h(a,b,c){var d=M.exec(b.slice(c));return d?(a.m=N[d[0].toLowerCase()],c+d[0].length):-1}function i(a,b,c){var d=K.exec(b.slice(c));return d?(a.m=L[d[0].toLowerCase()],c+d[0].length):-1}function j(a,b,c){return d(a,w,b,c)}function k(a,b,c){return d(a,x,b,c)}function l(a,b,c){return d(a,y,b,c)}function m(a){return B[a.getDay()]}function n(a){return A[a.getDay()]}function o(a){return D[a.getMonth()]}function p(a){return C[a.getMonth()]}function q(a){return z[+(a.getHours()>=12)]}function r(a){return B[a.getUTCDay()]}function s(a){return A[a.getUTCDay()]}function t(a){return D[a.getUTCMonth()]}function u(a){return C[a.getUTCMonth()]}function v(a){return z[+(a.getUTCHours()>=12)]}var w=a.dateTime,x=a.date,y=a.time,z=a.periods,A=a.days,B=a.shortDays,C=a.months,D=a.shortMonths,E=jc(z),F=kc(z),G=jc(A),H=kc(A),I=jc(B),J=kc(B),K=jc(C),L=kc(C),M=jc(D),N=kc(D),O={a:m,A:n,b:o,B:p,c:null,d:zc,e:zc,H:Ac,I:Bc,j:Cc,L:Dc,m:Ec,M:Fc,p:q,S:Gc,U:Hc,w:Ic,W:Jc,x:null,X:null,y:Kc,Y:Lc,Z:Mc,"%":_c},P={a:r,A:s,b:t,B:u,c:null,d:Nc,e:Nc,H:Oc,I:Pc,j:Qc,L:Rc,m:Sc,M:Tc,p:v,S:Uc,U:Vc,w:Wc,W:Xc,x:null,X:null,y:Yc,Y:Zc,Z:$c,"%":_c},Q={a:f,A:g,b:h,B:i,c:j,d:sc,e:sc,H:uc,I:uc,j:tc,L:xc,m:rc,M:vc,p:e,S:wc,U:mc,w:lc,W:nc,x:k,X:l,y:pc,Y:oc,Z:qc,"%":yc};return O.x=b(x,O),O.X=b(y,O),O.c=b(w,O),P.x=b(x,P),P.X=b(y,P),P.c=b(w,P),{format:function(a){var c=b(a+="",O);return c.toString=function(){return a},c},parse:function(a){var b=c(a+="",dc);return b.toString=function(){return a},b},utcFormat:function(a){var c=b(a+="",P);return c.toString=function(){return a},c},utcParse:function(a){var b=c(a,ec);return b.toString=function(){return a},b}}}function hc(a,b,c){var d=a<0?"-":"",e=(d?-a:a)+"",f=e.length;return d+(f68?1900:2e3),c+d[0].length):-1}function qc(a,b,c){var d=/^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(b.slice(c,c+6));return d?(a.Z=d[1]?0:-(d[2]+(d[3]||"00")),c+d[0].length):-1}function rc(a,b,c){var d=Pp.exec(b.slice(c,c+2));return d?(a.m=d[0]-1,c+d[0].length):-1}function sc(a,b,c){var d=Pp.exec(b.slice(c,c+2));return d?(a.d=+d[0],c+d[0].length):-1}function tc(a,b,c){var d=Pp.exec(b.slice(c,c+3));return d?(a.m=0,a.d=+d[0],c+d[0].length):-1}function uc(a,b,c){var d=Pp.exec(b.slice(c,c+2));return d?(a.H=+d[0],c+d[0].length):-1}function vc(a,b,c){var d=Pp.exec(b.slice(c,c+2));return d?(a.M=+d[0],c+d[0].length):-1}function wc(a,b,c){var d=Pp.exec(b.slice(c,c+2));return d?(a.S=+d[0],c+d[0].length):-1}function xc(a,b,c){var d=Pp.exec(b.slice(c,c+3));return d?(a.L=+d[0],c+d[0].length):-1}function yc(a,b,c){var d=Qp.exec(b.slice(c,c+1));return d?c+d[0].length:-1}function zc(a,b){return hc(a.getDate(),b,2)}function Ac(a,b){return hc(a.getHours(),b,2)}function Bc(a,b){return hc(a.getHours()%12||12,b,2)}function Cc(a,b){return hc(1+Ho.count(Zo(a),a),b,3)}function Dc(a,b){return hc(a.getMilliseconds(),b,3)}function Ec(a,b){return hc(a.getMonth()+1,b,2)}function Fc(a,b){return hc(a.getMinutes(),b,2)}function Gc(a,b){return hc(a.getSeconds(),b,2)}function Hc(a,b){return hc(Jo.count(Zo(a),a),b,2)}function Ic(a){return a.getDay()}function Jc(a,b){return hc(Ko.count(Zo(a),a),b,2)}function Kc(a,b){return hc(a.getFullYear()%100,b,2)}function Lc(a,b){return hc(a.getFullYear()%1e4,b,4)}function Mc(a){var b=a.getTimezoneOffset();return(b>0?"-":(b*=-1,"+"))+hc(b/60|0,"0",2)+hc(b%60,"0",2)}function Nc(a,b){return hc(a.getUTCDate(),b,2)}function Oc(a,b){return hc(a.getUTCHours(),b,2)}function Pc(a,b){return hc(a.getUTCHours()%12||12,b,2)}function Qc(a,b){return hc(1+dp.count(vp(a),a),b,3)}function Rc(a,b){return hc(a.getUTCMilliseconds(),b,3)}function Sc(a,b){return hc(a.getUTCMonth()+1,b,2)}function Tc(a,b){return hc(a.getUTCMinutes(),b,2)}function Uc(a,b){return hc(a.getUTCSeconds(),b,2)}function Vc(a,b){return hc(fp.count(vp(a),a),b,2)}function Wc(a){return a.getUTCDay()}function Xc(a,b){return hc(gp.count(vp(a),a),b,2)}function Yc(a,b){return hc(a.getUTCFullYear()%100,b,2)}function Zc(a,b){return hc(a.getUTCFullYear()%1e4,b,4)}function $c(){return"+0000"}function _c(){return"%"}function ad(b){return Kp=gc(b),a.timeFormat=Kp.format,a.timeParse=Kp.parse,a.utcFormat=Kp.utcFormat,a.utcParse=Kp.utcParse,Kp}function bd(a){return a.toISOString()}function cd(a){var b=new Date(a);return isNaN(b)?null:b}function dd(a){function b(b){var f=b+"",g=c.get(f);if(!g){if(e!==Yp)return e;c.set(f,g=d.push(b))}return a[(g-1)%a.length]}var c=f(),d=[],e=Yp;return a=null==a?[]:Xp.call(a),b.domain=function(a){if(!arguments.length)return d.slice();d=[],c=f();for(var e,g,h=-1,i=a.length;++h=c?1:d(a)}}}function jd(a){return function(b,c){var d=a(b=+b,c=+c);return function(a){return a<=0?b:a>=1?c:d(a)}}}function kd(a,b,c,d){var e=a[0],f=a[1],g=b[0],h=b[1];return f2?ld:kd,f=g=null,d}function d(b){return(f||(f=e(h,i,k?id(a):a,j)))(+b)}var e,f,g,h=_p,i=_p,j=sn,k=!1;return d.invert=function(a){return(g||(g=e(i,h,hd,k?jd(b):b)))(+a)},d.domain=function(a){return arguments.length?(h=Wp.call(a,$p),c()):h.slice()},d.range=function(a){return arguments.length?(i=Xp.call(a),c()):i.slice()},d.rangeRound=function(a){return i=Xp.call(a),j=tn,c()},d.clamp=function(a){return arguments.length?(k=!!a,c()):k},d.interpolate=function(a){return arguments.length?(j=a,c()):j},c()}function od(a){var b=a.domain;return a.ticks=function(a){var c=b();return Pj(c[0],c[c.length-1],null==a?10:a)},a.tickFormat=function(a,c){return aq(b(),a,c)},a.nice=function(d){var e=b(),f=e.length-1,g=null==d?10:d,h=e[0],i=e[f],j=c(h,i,g);return j&&(j=c(Math.floor(h/j)*j,Math.ceil(i/j)*j,g),e[0]=Math.floor(h/j)*j,e[f]=Math.ceil(i/j)*j,b(e)),a},a}function pd(){var a=nd(hd,nn);return a.copy=function(){return md(a,pd())},od(a)}function qd(){function a(a){return+a}var b=[0,1];return a.invert=a,a.domain=a.range=function(c){return arguments.length?(b=Wp.call(c,$p),a):b.slice()},a.copy=function(){return qd().domain(b)},od(a)}function rd(a,b){return(b=Math.log(b/a))?function(c){return Math.log(c/a)/b}:Zp(b)}function sd(a,b){return a<0?function(c){return-Math.pow(-b,c)*Math.pow(-a,1-c)}:function(c){return Math.pow(b,c)*Math.pow(a,1-c)}}function td(a){return isFinite(a)?+("1e"+a):a<0?0:a}function ud(a){return 10===a?td:a===Math.E?Math.exp:function(b){return Math.pow(a,b)}}function vd(a){return a===Math.E?Math.log:10===a&&Math.log10||2===a&&Math.log2||(a=Math.log(a),function(b){return Math.log(b)/a})}function wd(a){return function(b){return-a(-b)}}function xd(){function b(){return f=vd(e),g=ud(e),d()[0]<0&&(f=wd(f),g=wd(g)),c}var c=nd(rd,sd).domain([1,10]),d=c.domain,e=10,f=vd(10),g=ud(10);return c.base=function(a){return arguments.length?(e=+a,b()):e},c.domain=function(a){return arguments.length?(d(a),b()):d()},c.ticks=function(a){var b,c=d(),h=c[0],i=c[c.length-1];(b=i0){for(;mi)break;p.push(l)}}else for(;m=1;--k)if(l=j*k,!(li)break;p.push(l)}}else p=Pj(m,n,Math.min(n-m,o)).map(g);return b?p.reverse():p},c.tickFormat=function(b,d){if(null==d&&(d=10===e?".0e":","),"function"!=typeof d&&(d=a.format(d)),b===1/0)return d;null==b&&(b=10);var h=Math.max(1,e*b/c.ticks().length);return function(a){var b=a/g(Math.round(f(a)));return b*e0?e[b-1]:c[0],b=e?[f[e-1],d]:[f[b-1],f[b]]},a.copy=function(){return Cd().domain([c,d]).range(g)},od(a); -}function Dd(){function a(a){if(a<=a)return c[zj(b,a,0,d)]}var b=[.5],c=[0,1],d=1;return a.domain=function(e){return arguments.length?(b=Xp.call(e),d=Math.min(b.length,c.length-1),a):b.slice()},a.range=function(e){return arguments.length?(c=Xp.call(e),d=Math.min(b.length,c.length-1),a):c.slice()},a.invertExtent=function(a){var d=c.indexOf(a);return[b[d-1],b[d]]},a.copy=function(){return Dd().domain(b).range(c)},a}function Ed(a){return new Date(a)}function Fd(a){return a instanceof Date?+a:+new Date(+a)}function Gd(a,b,d,e,f,g,h,i,j){function k(c){return(h(c)=0&&(b=a.slice(c+1),a=a.slice(0,c)),{type:a,name:b}})}function Qd(a){return function(){var b=this.__on;if(b){for(var c,d=0,e=-1,f=b.length;db?1:a>=b?0:NaN}function Zd(a){return function(){this.removeAttribute(a)}}function $d(a){return function(){this.removeAttributeNS(a.space,a.local)}}function _d(a,b){return function(){this.setAttribute(a,b)}}function ae(a,b){return function(){this.setAttributeNS(a.space,a.local,b)}}function be(a,b){return function(){var c=b.apply(this,arguments);null==c?this.removeAttribute(a):this.setAttribute(a,c)}}function ce(a,b){return function(){var c=b.apply(this,arguments);null==c?this.removeAttributeNS(a.space,a.local):this.setAttributeNS(a.space,a.local,c)}}function de(a){return function(){this.style.removeProperty(a)}}function ee(a,b,c){return function(){this.style.setProperty(a,b,c)}}function fe(a,b,c){return function(){var d=b.apply(this,arguments);null==d?this.style.removeProperty(a):this.style.setProperty(a,d,c)}}function ge(a){return function(){delete this[a]}}function he(a,b){return function(){this[a]=b}}function ie(a,b){return function(){var c=b.apply(this,arguments);null==c?delete this[a]:this[a]=c}}function je(a){return a.trim().split(/^|\s+/)}function ke(a){return a.classList||new le(a)}function le(a){this._node=a,this._names=je(a.getAttribute("class")||"")}function me(a,b){for(var c=ke(a),d=-1,e=b.length;++dBr)throw new Error("too late");return c}function He(a,b){var c=a.__transition;if(!c||!(c=c[b])||c.state>Dr)throw new Error("too late");return c}function Ie(a,b){var c=a.__transition;if(!c||!(c=c[b]))throw new Error("too late");return c}function Je(a,b,c){function d(a){c.state=Cr,c.timer.restart(e,c.delay,c.time),c.delay<=a&&e(a-c.delay)}function e(d){var j,k,l,m;if(c.state!==Cr)return g();for(j in i)if(m=i[j],m.name===c.name){if(m.state===Er)return qo(e);m.state===Fr?(m.state=Hr,m.timer.stop(),m.on.call("interrupt",a,a.__data__,m.index,m.group),delete i[j]):+j=0&&(a=a.slice(0,b)),!a||"start"===a})}function _e(a,b,c){var d,e,f=$e(b)?Ge:He;return function(){var g=f(this,a),h=g.on;h!==d&&(e=(d=h).copy()).on(b,c),g.on=e}}function af(a){return function(){var b=this.parentNode;for(var c in this.__transition)if(+c!==a)return;b&&b.removeChild(this)}}function bf(a,b){var c,d,e;return function(){var f=hr(this).getComputedStyle(this,null),g=f.getPropertyValue(a),h=(this.style.removeProperty(a),f.getPropertyValue(a));return g===h?null:g===c&&h===d?e:e=b(c=g,d=h)}}function cf(a){return function(){this.style.removeProperty(a)}}function df(a,b,c){var d,e;return function(){var f=hr(this).getComputedStyle(this,null).getPropertyValue(a);return f===c?null:f===d?e:e=b(d=f,c)}}function ef(a,b,c){var d,e,f;return function(){var g=hr(this).getComputedStyle(this,null),h=g.getPropertyValue(a),i=c(this);return null==i&&(this.style.removeProperty(a),i=g.getPropertyValue(a)),h===i?null:h===d&&i===e?f:f=b(d=h,e=i)}}function ff(a,b,c){function d(){var d=this,e=b.apply(d,arguments);return e&&function(b){d.style.setProperty(a,e(b),c)}}return d._value=b,d}function gf(a){return function(){this.textContent=a}}function hf(a){return function(){var b=a(this);this.textContent=null==b?"":b}}function jf(a,b,c,d){this._groups=a,this._parents=b,this._name=c,this._id=d}function kf(a){return Fe().transition(a)}function lf(){return++cs}function mf(a,b){for(var c;!(c=a.__transition)||!(c=c[b]);)if(!(a=a.parentNode))return es.time=Qb(),es;return c}function nf(a,b,c){var d=a(c);return"translate("+(isFinite(d)?d:b(c))+",0)"}function of(a,b,c){var d=a(c);return"translate(0,"+(isFinite(d)?d:b(c))+")"}function pf(a){var b=a.bandwidth()/2;return a.round()&&(b=Math.round(b)),function(c){return a(c)+b}}function qf(){return!this.__axis}function rf(a,b){function c(c){var j,k=null==e?b.ticks?b.ticks.apply(b,d):b.domain():e,l=null==f?b.tickFormat?b.tickFormat.apply(b,d):js:f,m=Math.max(g,0)+i,n=a===ks||a===ms?nf:of,o=b.range(),p=o[0]+.5,q=o[o.length-1]+.5,r=(b.bandwidth?pf:js)(b.copy()),s=c.selection?c.selection():c,t=s.selectAll(".domain").data([null]),u=s.selectAll(".tick").data(k,b).order(),v=u.exit(),w=u.enter().append("g").attr("class","tick"),x=u.select("line"),y=u.select("text"),z=a===ks||a===ns?-1:1,A=a===ns||a===ls?(j="x","y"):(j="y","x");t=t.merge(t.enter().insert("path",".tick").attr("class","domain").attr("stroke","#000")),u=u.merge(w),x=x.merge(w.append("line").attr("stroke","#000").attr(j+"2",z*g).attr(A+"1",.5).attr(A+"2",.5)),y=y.merge(w.append("text").attr("fill","#000").attr(j,z*m).attr(A,.5).attr("dy",a===ks?"0em":a===ms?"0.71em":"0.32em")),c!==s&&(t=t.transition(c),u=u.transition(c),x=x.transition(c),y=y.transition(c),v=v.transition(c).attr("opacity",os).attr("transform",function(a){return n(r,this.parentNode.__axis||r,a)}),w.attr("opacity",os).attr("transform",function(a){return n(this.parentNode.__axis||r,r,a)})),v.remove(),t.attr("d",a===ns||a==ls?"M"+z*h+","+p+"H0.5V"+q+"H"+z*h:"M"+p+","+z*h+"V0.5H"+q+"V"+z*h),u.attr("opacity",1).attr("transform",function(a){return n(r,r,a)}),x.attr(j+"2",z*g),y.attr(j,z*m).text(l),s.filter(qf).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",a===ls?"start":a===ns?"end":"middle"),s.each(function(){this.__axis=r})}var d=[],e=null,f=null,g=6,h=6,i=3;return c.scale=function(a){return arguments.length?(b=a,c):b},c.ticks=function(){return d=is.call(arguments),c},c.tickArguments=function(a){return arguments.length?(d=null==a?[]:is.call(a),c):d.slice()},c.tickValues=function(a){return arguments.length?(e=null==a?null:is.call(a),c):e&&e.slice()},c.tickFormat=function(a){return arguments.length?(f=a,c):f},c.tickSize=function(a){return arguments.length?(g=h=+a,c):g},c.tickSizeInner=function(a){return arguments.length?(g=+a,c):g},c.tickSizeOuter=function(a){return arguments.length?(h=+a,c):h},c.tickPadding=function(a){return arguments.length?(i=+a,c):i},c}function sf(a){return rf(ks,a)}function tf(a){return rf(ls,a)}function uf(a){return rf(ms,a)}function vf(a){return rf(ns,a)}function wf(a,b){return a.parent===b.parent?1:2}function xf(a){return a.reduce(yf,0)/a.length}function yf(a,b){return a+b.x}function zf(a){return 1+a.reduce(Af,0)}function Af(a,b){return Math.max(a,b.y)}function Bf(a){for(var b;b=a.children;)a=b[0];return a}function Cf(a){for(var b;b=a.children;)a=b[b.length-1];return a}function Df(a,b){if(a===b)return a;var c=a.ancestors(),d=b.ancestors(),e=null;for(a=c.pop(),b=d.pop();a===b;)e=a,a=c.pop(),b=d.pop();return e}function Ef(a,b){var c,d,e,f,g,h=new Jf(a),i=+a.value&&(h.value=a.value),j=[h];for(null==b&&(b=Gf);c=j.pop();)if(i&&(c.value=+c.data.value),(e=b(c.data))&&(g=e.length))for(c.children=new Array(g),f=g-1;f>=0;--f)j.push(d=c.children[f]=new Jf(e[f])),d.parent=c,d.depth=c.depth+1;return h.eachBefore(If)}function Ff(){return Ef(this).eachBefore(Hf)}function Gf(a){return a.children}function Hf(a){a.data=a.data.data}function If(a){var b=0;do a.height=b;while((a=a.parent)&&a.height<++b)}function Jf(a){this.data=a,this.depth=this.height=0,this.parent=null}function Kf(a){this._=a,this.next=null}function Lf(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r-b.r;return e*e+1e-6>c*c+d*d}function Mf(a,b){var c,d,e,f=null,g=a.head;switch(b.length){case 1:c=Nf(b[0]);break;case 2:c=Of(b[0],b[1]);break;case 3:c=Pf(b[0],b[1],b[2])}for(;g;)e=g._,d=g.next,c&&Lf(c,e)?f=g:(f?(a.tail=f,f.next=null):a.head=a.tail=null,b.push(e),c=Mf(a,b),b.pop(),a.head?(g.next=a.head,a.head=g):(g.next=null,a.head=a.tail=g),f=a.tail,f.next=d),g=d;return a.tail=f,c}function Nf(a){return{x:a.x,y:a.y,r:a.r}}function Of(a,b){var c=a.x,d=a.y,e=a.r,f=b.x,g=b.y,h=b.r,i=f-c,j=g-d,k=h-e,l=Math.sqrt(i*i+j*j);return{x:(c+f+i/l*k)/2,y:(d+g+j/l*k)/2,r:(l+e+h)/2}}function Pf(a,b,c){var d=a.x,e=a.y,f=a.r,g=b.x,h=b.y,i=b.r,j=c.x,k=c.y,l=c.r,m=2*(d-g),n=2*(e-h),o=2*(i-f),p=d*d+e*e-f*f-g*g-h*h+i*i,q=2*(d-j),r=2*(e-k),s=2*(l-f),t=d*d+e*e-f*f-j*j-k*k+l*l,u=q*n-m*r,v=(n*t-r*p)/u-d,w=(r*o-n*s)/u,x=(q*p-m*t)/u-e,y=(m*s-q*o)/u,z=w*w+y*y-1,A=2*(v*w+x*y+f),B=v*v+x*x-f*f,C=(-A-Math.sqrt(A*A-4*z*B))/(2*z);return{x:v+w*C+d,y:x+y*C+e,r:C}}function Qf(a,b,c){var d=a.x,e=a.y,f=b.r+c.r,g=a.r+c.r,h=b.x-d,i=b.y-e,j=h*h+i*i;if(j){var k=.5+((g*=g)-(f*=f))/(2*j),l=Math.sqrt(Math.max(0,2*f*(g+j)-(g-=j)*g-f*f))/(2*j);c.x=d+k*h+l*i,c.y=e+k*i-l*h}else c.x=d+g,c.y=e}function Rf(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r+b.r;return e*e>c*c+d*d}function Sf(a,b,c){var d=a.x-b,e=a.y-c;return d*d+e*e}function Tf(a){this._=a,this.next=null,this.previous=null}function Uf(a){if(!(e=a.length))return 0;var b,c,d,e;if(b=a[0],b.x=0,b.y=0,!(e>1))return b.r;if(c=a[1],b.x=-c.r,c.x=b.r,c.y=0,!(e>2))return b.r+c.r;Qf(c,b,d=a[2]);var f,g,h,i,j,k,l,m=b.r*b.r,n=c.r*c.r,o=d.r*d.r,p=m+n+o,q=m*b.x+n*c.x+o*d.x,r=m*b.y+n*c.y+o*d.y;b=new Tf(b),c=new Tf(c),d=new Tf(d),b.next=d.previous=c,c.next=b.previous=d,d.next=c.previous=b;a:for(h=3;h=0;)b=e[f],b.z+=c,b.m+=c,c+=b.s+(d+=b.c)}function hg(a,b,c){return a.a.parent===b.parent?a.a:c}function ig(a,b){this._=a,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=b}function jg(a){for(var b,c,d,e,f,g=new ig(a,0),h=[g];b=h.pop();)if(d=b._.children)for(b.children=new Array(f=d.length),e=f-1;e>=0;--e)h.push(c=b.children[e]=new ig(d[e],e)),c.parent=b;return(g.parent=new ig(null,0)).children=[g],g}function kg(a,b,c,d,e,f){for(var g,h,i,j,k,l,m,n,o,p,q,r=[],s=b.children,t=0,u=0,v=s.length,w=b.value;tm&&(m=h),q=k*k*p,n=Math.max(m/q,q/l),n>o){k-=h;break}o=n}r.push(g={value:k,dice:i0)){if(f/=o,o<0){if(f0){if(f>n)return;f>m&&(m=f)}if(f=d-i,o||!(f<0)){if(f/=o,o<0){if(f>n)return;f>m&&(m=f)}else if(o>0){if(f0)){if(f/=p,p<0){if(f0){if(f>n)return;f>m&&(m=f)}if(f=e-j,p||!(f<0)){if(f/=p,p<0){if(f>n)return;f>m&&(m=f)}else if(p>0){if(f0||n<1)||(m>0&&(a[0]=[i+m*o,j+m*p]),n<1&&(a[1]=[i+n*o,j+n*p]),!0)}}}}}function Ig(a,b,c,d,e){var f=a[1];if(f)return!0;var g,h,i=a[0],j=a.left,k=a.right,l=j[0],m=j[1],n=k[0],o=k[1],p=(l+n)/2,q=(m+o)/2;if(o===m){if(p=d)return;if(l>n){if(i){if(i[1]>=e)return}else i=[p,c];f=[p,e]}else{if(i){if(i[1]1)if(l>n){if(i){if(i[1]>=e)return}else i=[(c-h)/g,c];f=[(e-h)/g,e]}else{if(i){if(i[1]=d)return}else i=[b,g*b+h];f=[d,g*d+h]}else{if(i){if(i[0]pt||Math.abs(e[0][1]-e[1][1])>pt)||delete mt[f]}function Kg(a){return kt[a.index]={site:a,halfedges:[]}}function Lg(a,b){var c=a.site,d=b.left,e=b.right;return c===e&&(e=d,d=c),e?Math.atan2(e[1]-d[1],e[0]-d[0]):(c===d?(d=b[1],e=b[0]):(d=b[0],e=b[1]),Math.atan2(d[0]-e[0],e[1]-d[1]))}function Mg(a,b){return b[+(b.left!==a.site)]}function Ng(a,b){return b[+(b.left===a.site)]}function Og(){for(var a,b,c,d,e=0,f=kt.length;ept||Math.abs(p-m)>pt)&&(i.splice(h,0,mt.push(Fg(g,n,Math.abs(o-a)pt?[a,Math.abs(l-a)pt?[Math.abs(m-d)pt?[c,Math.abs(l-c)pt?[Math.abs(m-b)=-qt)){var n=i*i+j*j,o=k*k+l*l,p=(l*n-j*o)/m,q=(i*o-k*n)/m,r=nt.pop()||new Qg;r.arc=a,r.site=e,r.x=p+g,r.y=(r.cy=q+h)+Math.sqrt(p*p+q*q),a.circle=r;for(var s=null,t=lt._;t;)if(r.ypt)h=h.L;else{if(e=f-Zg(h,g),!(e>pt)){d>-pt?(b=h.P,c=h):e>-pt?(b=h,c=h.N):b=c=h;break}if(!h.R){b=h;break}h=h.R}Kg(a);var i=Ug(a);if(jt.insert(b,i),b||c){if(b===c)return Sg(b),c=Ug(b.site),jt.insert(i,c),i.edge=c.edge=Eg(b.site,i.site),Rg(b),void Rg(c);if(!c)return void(i.edge=Eg(b.site,i.site));Sg(b),Sg(c);var j=b.site,k=j[0],l=j[1],m=a[0]-k,n=a[1]-l,o=c.site,p=o[0]-k,q=o[1]-l,r=2*(m*q-n*p),s=m*m+n*n,t=p*p+q*q,u=[(q*s-n*t)/r+k,(m*t-p*s)/r+l];Gg(c.edge,j,o,u),i.edge=Eg(j,a,null,u),c.edge=Eg(a,o,null,u),Rg(b),Rg(c)}}function Yg(a,b){var c=a.site,d=c[0],e=c[1],f=e-b;if(!f)return d;var g=a.P;if(!g)return-(1/0);c=g.site;var h=c[0],i=c[1],j=i-b;if(!j)return h;var k=h-d,l=1/f-1/j,m=k/j;return l?(-m+Math.sqrt(m*m-2*l*(k*k/(-2*j)-i+j/2+e-f/2)))/l+d:(d+h)/2}function Zg(a,b){var c=a.N;if(c)return Yg(c,b);var d=a.site;return d[1]===b?d[0]:1/0}function $g(a,b,c){return(a[0]-c[0])*(b[1]-a[1])-(a[0]-b[0])*(c[1]-a[1])}function _g(a,b){return b[1]-a[1]||b[0]-a[0]}function ah(a,b){var c,d,e,f=a.sort(_g).pop();for(mt=[],kt=new Array(a.length),jt=new zg,lt=new zg;;)if(e=it,f&&(!e||f[1]Math.abs(a[1]-M[1])?x=!0:w=!0),M=a,v=!0,yt(),f()}function f(){var a;switch(t=M[0]-L[0],u=M[1]-L[1],A){case At:case zt:B&&(t=Math.max(G-l,Math.min(I-p,t)),m=l+t,q=p+t),C&&(u=Math.max(H-n,Math.min(J-r,u)),o=n+u,s=r+u);break;case Bt:B<0?(t=Math.max(G-l,Math.min(I-l,t)),m=l+t,q=p):B>0&&(t=Math.max(G-p,Math.min(I-p,t)),m=l,q=p+t),C<0?(u=Math.max(H-n,Math.min(J-n,u)),o=n+u,s=r):C>0&&(u=Math.max(H-r,Math.min(J-r,u)),o=n,s=r+u);break;case Ct:B&&(m=Math.max(G,Math.min(I,l-t*B)),q=Math.max(G,Math.min(I,p+t*B))),C&&(o=Math.max(H,Math.min(J,n-u*C)),s=Math.max(H,Math.min(J,r+u*C)))}q0&&(l=m-t),C<0?r=s-u:C>0&&(n=o-u),A=At,P.attr("cursor",Gt.selection),f());break;default:return}yt()}function j(){switch(a.event.keyCode){case 16:K&&(w=x=K=!1,f());break;case 18:A===Ct&&(B<0?p=q:B>0&&(l=m),C<0?r=s:C>0&&(n=o),A=Bt,f());break;case 32:A===At&&(a.event.altKey?(B&&(p=q-t*B,l=m+t*B),C&&(r=s-u*C,n=o+u*C),A=Ct):(B<0?p=q:B>0&&(l=m),C<0?r=s:C>0&&(n=o),A=Bt),P.attr("cursor",Gt[z]),f());break;default:return}yt()}if(a.event.touches){if(a.event.changedTouches.length1?0:a<-1?Du:Math.acos(a)}function Bh(a){return a>1?Eu:a<-1?-Eu:Math.asin(a)}function Ch(a){return(a=Ru(a/2))*a}function Dh(){}function Eh(a,b){a&&Wu.hasOwnProperty(a.type)&&Wu[a.type](a,b)}function Fh(a,b,c){var d,e=-1,f=a.length-c;for(b.lineStart();++e=0?1:-1,e=d*c,f=Mu(b),g=Ru(b),h=_t*g,i=$t*f+h*Mu(e),j=h*d*Ru(e);Yu.add(Lu(j,i)),Zt=a,$t=f,_t=g}function Lh(a){return[Lu(a[1],a[0]),Bh(a[2])]}function Mh(a){var b=a[0],c=a[1],d=Mu(c);return[d*Mu(b),d*Ru(b),Ru(c)]}function Nh(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}function Oh(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]}function Ph(a,b){a[0]+=b[0],a[1]+=b[1],a[2]+=b[2]}function Qh(a,b){return[a[0]*b,a[1]*b,a[2]*b]}function Rh(a){var b=Tu(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);a[0]/=b,a[1]/=b,a[2]/=b}function Sh(a,b){iu.push(ju=[au=a,cu=a]),bdu&&(du=b)}function Th(a,b){var c=Mh([a*Iu,b*Iu]);if(hu){var d=Oh(hu,c),e=[d[1],-d[0],0],f=Oh(e,d);Rh(f),f=Lh(f);var g,h=a-eu,i=h>0?1:-1,j=f[0]*Hu*i,k=Ju(h)>180;k^(i*eudu&&(du=g)):(j=(j+360)%360-180,k^(i*eudu&&(du=b))),k?aZh(au,cu)&&(cu=a):Zh(a,cu)>Zh(au,cu)&&(au=a):cu>=au?(acu&&(cu=a)):a>eu?Zh(au,a)>Zh(au,cu)&&(cu=a):Zh(a,cu)>Zh(au,cu)&&(au=a)}else Sh(a,b);hu=c,eu=a}function Uh(){bv.point=Th}function Vh(){ju[0]=au,ju[1]=cu,bv.point=Sh,hu=null}function Wh(a,b){if(hu){var c=a-eu;av.add(Ju(c)>180?c+(c>0?360:-360):c)}else fu=a,gu=b;$u.point(a,b),Th(a,b)}function Xh(){$u.lineStart()}function Yh(){Wh(fu,gu),$u.lineEnd(),Ju(av)>Bu&&(au=-(cu=180)),ju[0]=au,ju[1]=cu,hu=null}function Zh(a,b){return(b-=a)<0?b+360:b}function $h(a,b){return a[0]-b[0]}function _h(a,b){return a[0]<=a[1]?a[0]<=b&&b<=a[1]:bDu?a-Gu:a<-Du?a+Gu:a,b]}function li(a,b,c){return(a%=Gu)?b||c?gv(ni(a),oi(b,c)):ni(a):b||c?oi(b,c):ki}function mi(a){return function(b,c){return b+=a,[b>Du?b-Gu:b<-Du?b+Gu:b,c]}}function ni(a){var b=mi(a);return b.invert=mi(-a),b}function oi(a,b){function c(a,b){var c=Mu(b),h=Mu(a)*c,i=Ru(a)*c,j=Ru(b),k=j*d+h*e;return[Lu(i*f-k*g,h*d-j*e),Bh(k*f+i*g)]}var d=Mu(a),e=Ru(a),f=Mu(b),g=Ru(b);return c.invert=function(a,b){var c=Mu(b),h=Mu(a)*c,i=Ru(a)*c,j=Ru(b),k=j*f-i*g;return[Lu(i*f+j*g,h*d+k*e),Bh(k*d-h*e)]},c}function pi(a,b,c,d,e,f){if(c){var g=Mu(b),h=Ru(b),i=d*c;null==e?(e=b+d*Gu,f=b-i/2):(e=qi(g,e),f=qi(g,f),(d>0?ef)&&(e+=d*Gu));for(var j,k=e;d>0?k>f:k0){do j.point(0===k||3===k?a:c,k>1?d:b);while((k=(k+h+4)%4)!==l)}else j.point(f[0],f[1])}function g(d,e){return Ju(d[0]-a)0?0:3:Ju(d[0]-c)0?2:1:Ju(d[1]-b)0?1:0:e>0?3:2}function h(a,b){return i(a.x,b.x)}function i(a,b){var c=g(a,1),d=g(b,1);return c!==d?c-d:0===c?b[1]-a[1]:1===c?a[0]-b[0]:2===c?a[1]-b[1]:b[0]-a[0]}return function(g){function i(a,b){e(a,b)&&A.point(a,b)}function j(){for(var b=0,c=0,e=q.length;cd&&(l-f)*(d-g)>(m-g)*(a-f)&&++b:m<=d&&(l-f)*(d-g)<(m-g)*(a-f)&&--b;return b}function k(){A=B,p=[],q=[],z=!0}function l(){var a=j(),b=z&&a,c=(p=Yj(p)).length;(b||c)&&(g.polygonStart(),b&&(g.lineStart(),f(null,null,1,g),g.lineEnd()),c&&xv(p,h,a,f,g),g.polygonEnd()),A=g,p=q=r=null}function m(){C.point=o,q&&q.push(r=[]),y=!0,x=!1,v=w=NaN}function n(){p&&(o(s,t),u&&x&&B.rejoin(),p.push(B.result())),C.point=i,x&&A.lineEnd()}function o(f,g){var h=e(f,g);if(q&&r.push([f,g]),y)s=f,t=g,u=h,y=!1,h&&(A.lineStart(),A.point(f,g));else if(h&&x)A.point(f,g);else{var i=[v=Math.max(zv,Math.min(yv,v)),w=Math.max(zv,Math.min(yv,w))],j=[f=Math.max(zv,Math.min(yv,f)),g=Math.max(zv,Math.min(yv,g))];vv(i,j,a,b,c,d)?(x||(A.lineStart(),A.point(i[0],i[1])),A.point(j[0],j[1]),h||A.lineEnd(),z=!1):h&&(A.lineStart(),A.point(f,g),z=!1)}v=f,w=g,x=h}var p,q,r,s,t,u,v,w,x,y,z,A=g,B=uv(),C={point:i,lineStart:m,lineEnd:n,polygonStart:k,polygonEnd:l};return C}}function ui(){Cv.point=wi,Cv.lineEnd=vi}function vi(){Cv.point=Cv.lineEnd=Dh}function wi(a,b){a*=Iu,b*=Iu,hv=a,iv=Ru(b),jv=Mu(b),Cv.point=xi}function xi(a,b){a*=Iu,b*=Iu;var c=Ru(b),d=Mu(b),e=Ju(a-hv),f=Mu(e),g=Ru(e),h=d*g,i=jv*c-iv*d*f,j=iv*c+jv*d*f;Bv.add(Lu(Tu(h*h+i*i),j)),hv=a,iv=c,jv=d}function yi(a,b,c){var d=Lj(a,b-Bu,c).concat(b);return function(a){return d.map(function(b){return[a,b]})}}function zi(a,b,c){var d=Lj(a,b-Bu,c).concat(b);return function(a){return d.map(function(b){return[b,a]})}}function Ai(){function a(){return{type:"MultiLineString",coordinates:b()}}function b(){return Lj(Nu(f/q)*q,e,q).map(m).concat(Lj(Nu(j/r)*r,i,r).map(n)).concat(Lj(Nu(d/o)*o,c,o).filter(function(a){return Ju(a%q)>Bu}).map(k)).concat(Lj(Nu(h/p)*p,g,p).filter(function(a){return Ju(a%r)>Bu}).map(l))}var c,d,e,f,g,h,i,j,k,l,m,n,o=10,p=o,q=90,r=360,s=2.5;return a.lines=function(){return b().map(function(a){return{type:"LineString",coordinates:a}})},a.outline=function(){return{type:"Polygon",coordinates:[m(f).concat(n(i).slice(1),m(e).reverse().slice(1),n(j).reverse().slice(1))]}},a.extent=function(b){return arguments.length?a.extentMajor(b).extentMinor(b):a.extentMinor()},a.extentMajor=function(b){return arguments.length?(f=+b[0][0],e=+b[1][0],j=+b[0][1],i=+b[1][1],f>e&&(b=f,f=e,e=b),j>i&&(b=j,j=i,i=b),a.precision(s)):[[f,j],[e,i]]},a.extentMinor=function(b){return arguments.length?(d=+b[0][0],c=+b[1][0],h=+b[0][1],g=+b[1][1],d>c&&(b=d,d=c,c=b),h>g&&(b=h,h=g,g=b),a.precision(s)):[[d,h],[c,g]]},a.step=function(b){return arguments.length?a.stepMajor(b).stepMinor(b):a.stepMinor()},a.stepMajor=function(b){return arguments.length?(q=+b[0],r=+b[1],a):[q,r]},a.stepMinor=function(b){return arguments.length?(o=+b[0],p=+b[1],a):[o,p]},a.precision=function(b){return arguments.length?(s=+b,k=yi(h,g,90),l=zi(d,c,s),m=yi(j,i,90),n=zi(f,e,s),a):s},a.extentMajor([[-180,-90+Bu],[180,90-Bu]]).extentMinor([[-180,-80-Bu],[180,80+Bu]])}function Bi(){return Ai()()}function Ci(){Lv.point=Di}function Di(a,b){Lv.point=Ei,kv=mv=a,lv=nv=b}function Ei(a,b){Kv.add(nv*a-mv*b),mv=a,nv=b}function Fi(){Ei(kv,lv)}function Gi(a,b){aOv&&(Ov=a),bPv&&(Pv=b)}function Hi(a,b){Rv+=a,Sv+=b,++Tv}function Ii(){$v.point=Ji}function Ji(a,b){$v.point=Ki,Hi(qv=a,rv=b)}function Ki(a,b){var c=a-qv,d=b-rv,e=Tu(c*c+d*d);Uv+=e*(qv+a)/2,Vv+=e*(rv+b)/2,Wv+=e,Hi(qv=a,rv=b)}function Li(){$v.point=Hi}function Mi(){$v.point=Oi}function Ni(){Pi(ov,pv)}function Oi(a,b){$v.point=Pi,Hi(ov=qv=a,pv=rv=b)}function Pi(a,b){var c=a-qv,d=b-rv,e=Tu(c*c+d*d);Uv+=e*(qv+a)/2,Vv+=e*(rv+b)/2,Wv+=e,e=rv*a-qv*b,Xv+=e*(qv+a),Yv+=e*(rv+b),Zv+=3*e,Hi(qv=a,rv=b)}function Qi(a){this._context=a}function Ri(){this._string=[]}function Si(a){return"m0,"+a+"a"+a+","+a+" 0 1,1 0,"+-2*a+"a"+a+","+a+" 0 1,1 0,"+2*a+"z"}function Ti(a){return a.length>1}function Ui(a,b){return((a=a.x)[0]<0?a[1]-Eu-Bu:Eu-a[1])-((b=b.x)[0]<0?b[1]-Eu-Bu:Eu-b[1])}function Vi(a){var b,c=NaN,d=NaN,e=NaN;return{lineStart:function(){a.lineStart(),b=1},point:function(f,g){var h=f>0?Du:-Du,i=Ju(f-c);Ju(i-Du)0?Eu:-Eu),a.point(e,d),a.lineEnd(),a.lineStart(),a.point(h,d),a.point(f,d),b=0):e!==h&&i>=Du&&(Ju(c-e)Bu?Ku((Ru(b)*(f=Mu(d))*Ru(c)-Ru(d)*(e=Mu(b))*Ru(a))/(e*f*g)):(b+d)/2}function Xi(a,b,c,d){var e;if(null==a)e=c*Eu,d.point(-Du,e),d.point(0,e),d.point(Du,e),d.point(Du,0),d.point(Du,-e),d.point(0,-e),d.point(-Du,-e),d.point(-Du,0),d.point(-Du,e);else if(Ju(a[0]-b[0])>Bu){var f=a[0]4*b&&p--){var u=g+m,v=h+n,w=i+o,x=Tu(u*u+v*v+w*w),y=Bh(w/=x),z=Ju(Ju(w)-1)b||Ju((r*D+s*E)/t-.5)>.3||g*m+h*n+i*o2?a[2]%360*Iu:0,e()):[v*Hu,w*Hu,x*Hu]},b.precision=function(a){return arguments.length?(D=iw(d,C=a*a),f()):Tu(C)},b.fitExtent=function(a,c){return $i(b,a,c)},b.fitSize=function(a,c){return _i(b,a,c)},function(){return g=a.apply(this,arguments),b.invert=g.invert&&c,e()}}function ej(a){var b=0,c=Du/3,d=dj(a),e=d(b,c);return e.parallels=function(a){return arguments.length?d(b=a[0]*Iu,c=a[1]*Iu):[b*Hu,c*Hu]},e}function fj(a){function b(a,b){return[a*c,Ru(b)/c]}var c=Mu(a);return b.invert=function(a,b){return[a/c,Bh(b*c)]},b}function gj(a,b){function c(a,b){var c=Tu(f-2*e*Ru(b))/e;return[c*Ru(a*=e),g-c*Mu(a)]}var d=Ru(a),e=(d+Ru(b))/2;if(Ju(e)0?b<-Eu+Bu&&(b=-Eu+Bu):b>Eu-Bu&&(b=Eu-Bu);var c=f/Qu(mj(b),e);return[c*Ru(e*a),f-c*Mu(e*a)]}var d=Mu(a),e=a===b?Ru(a):Pu(d/Mu(b))/Pu(mj(b)/mj(a)),f=d*Qu(mj(a),e)/e;return e?(c.invert=function(a,b){var c=f-b,d=Su(e)*Tu(a*a+c*c);return[Lu(a,Ju(c))/e*Su(c),2*Ku(Qu(f/d,1/e))-Eu]},c):kj}function oj(a,b){return[a,b]}function pj(a,b){function c(a,b){var c=f-b,d=e*a;return[c*Ru(d),f-c*Mu(d)]}var d=Mu(a),e=a===b?Ru(a):(d-Mu(b))/(b-a),f=d/e+a;return Ju(e)b?1:a>=b?0:NaN},xj=function(a){return 1===a.length&&(a=b(a)),{left:function(b,c,d,e){for(null==d&&(d=0),null==e&&(e=b.length);d>>1;a(b[f],c)<0?d=f+1:e=f}return d},right:function(b,c,d,e){for(null==d&&(d=0),null==e&&(e=b.length);d>>1;a(b[f],c)>0?e=f:d=f+1}return d}}},yj=xj(wj),zj=yj.right,Aj=yj.left,Bj=function(a,b){return ba?1:b>=a?0:NaN},Cj=function(a){return null===a?NaN:+a},Dj=function(a,b){var c,d,e=a.length,f=0,g=0,h=-1,i=0;if(null==b)for(;++h1)return g/(i-1)},Ej=function(a,b){var c=Dj(a,b);return c?Math.sqrt(c):c},Fj=function(a,b){var c,d,e,f=-1,g=a.length;if(null==b){for(;++f=d){c=e=d;break}for(;++fd&&(c=d),e=d){c=e=d;break}for(;++fd&&(c=d),e=k;)l.pop(),--m;var n,o=new Array(m+1);for(e=0;e<=m;++e)n=o[e]=[],n.x0=e>0?l[e-1]:j,n.x1=e=1)return+c(a[d-1],d-1,a);var d,e=(d-1)*b,f=Math.floor(e),g=+c(a[f],f,a),h=+c(a[f+1],f+1,a);return g+(h-g)*(e-f)}},Tj=function(a,b,c){return a=Ij.call(a,Cj).sort(wj),Math.ceil((c-b)/(2*(Sj(a,.75)-Sj(a,.25))*Math.pow(a.length,-1/3)))},Uj=function(a,b,c){return Math.ceil((c-b)/(3.5*Ej(a)*Math.pow(a.length,-1/3)))},Vj=function(a,b){var c,d,e=-1,f=a.length;if(null==b){for(;++e=d){c=d;break}for(;++ec&&(c=d)}else{for(;++e=d){c=d;break}for(;++ec&&(c=d)}return c},Wj=function(a,b){var c,d=0,e=a.length,f=-1,g=e;if(null==b)for(;++f=0;)for(d=a[e],b=d.length;--b>=0;)c[--g]=d[b];return c},Zj=function(a,b){var c,d,e=-1,f=a.length;if(null==b){for(;++e=d){c=d;break}for(;++ed&&(c=d)}else{for(;++e=d){c=d;break}for(;++ed&&(c=d)}return c},$j=function(a){for(var b=0,c=a.length-1,d=a[0],e=new Array(c<0?0:c);b=k.length)return null!=d?d(b):null!=c?b.sort(c):b;for(var i,j,l,m=-1,n=b.length,o=k[e++],p=f(),q=g();++mk.length)return a;var e,f=l[c-1];return null!=d&&c>=k.length?e=a.entries():(e=[],a.each(function(a,d){e.push({key:d,values:b(a,c)})})),null!=f?e.sort(function(a,b){return f(a.key,b.key)}):e}var c,d,e,k=[],l=[];return e={object:function(b){return a(b,0,g,h)},map:function(b){return a(b,0,i,j)},entries:function(c){return b(a(c,0,i,j),0)},key:function(a){return k.push(a),e},sortKeys:function(a){return l[k.length-1]=a,e},sortValues:function(a){return c=a,e},rollup:function(a){return d=a,e}}},hk=f.prototype;k.prototype=l.prototype={constructor:k,has:hk.has,add:function(a){return a+="",this[fk+a]=a,this},remove:hk.remove,clear:hk.clear,values:hk.keys,size:hk.size,empty:hk.empty,each:hk.each};var ik=function(a){var b=[];for(var c in a)b.push(c);return b},jk=function(a){var b=[];for(var c in a)b.push(a[c]);return b},kk=function(a){var b=[];for(var c in a)b.push({key:c,value:a[c]});return b},lk=function(a,b){return a=null==a?0:+a,b=null==b?1:+b,1===arguments.length?(b=a,a=0):b-=a,function(){return Math.random()*b+a}},mk=function(a,b){var c,d;return a=null==a?0:+a,b=null==b?1:+b,function(){var e;if(null!=c)e=c,c=null;else do c=2*Math.random()-1,e=2*Math.random()-1,d=c*c+e*e;while(!d||d>1);return a+b*e*Math.sqrt(-2*Math.log(d)/d)}},nk=function(){var a=mk.apply(this,arguments);return function(){return Math.exp(a())}},ok=function(a){return function(){for(var b=0,c=0;c=0;--b)j.push(a[d[f[b]][2]]);for(b=+h;bh!=j>h&&g<(i-c)*(h-d)/(j-d)+c&&(k=!k),i=c,j=d;return k},Wk=function(a){for(var b,c,d=-1,e=a.length,f=a[e-1],g=f[0],h=f[1],i=0;++dZk)if(Math.abs(k*h-i*j)>Zk&&e){var m=c-f,n=d-g,o=h*h+i*i,p=m*m+n*n,q=Math.sqrt(o),r=Math.sqrt(l),s=e*Math.tan((Xk-Math.acos((o+l-p)/(2*q*r)))/2),t=s/r,u=s/q;Math.abs(t-1)>Zk&&(this._+="L"+(a+t*j)+","+(b+t*k)),this._+="A"+e+","+e+",0,0,"+ +(k*m>j*n)+","+(this._x1=a+u*h)+","+(this._y1=b+u*i)}else this._+="L"+(this._x1=a)+","+(this._y1=b);else;},arc:function(a,b,c,d,e,f){a=+a,b=+b,c=+c;var g=c*Math.cos(d),h=c*Math.sin(d),i=a+g,j=b+h,k=1^f,l=f?d-e:e-d;if(c<0)throw new Error("negative radius: "+c);null===this._x1?this._+="M"+i+","+j:(Math.abs(this._x1-i)>Zk||Math.abs(this._y1-j)>Zk)&&(this._+="L"+i+","+j),c&&(l>$k?this._+="A"+c+","+c+",0,1,"+k+","+(a-g)+","+(b-h)+"A"+c+","+c+",0,1,"+k+","+(this._x1=i)+","+(this._y1=j):(l<0&&(l=l%Yk+Yk),this._+="A"+c+","+c+",0,"+ +(l>=Xk)+","+k+","+(this._x1=a+c*Math.cos(e))+","+(this._y1=b+c*Math.sin(e))))},rect:function(a,b,c,d){this._+="M"+(this._x0=this._x1=+a)+","+(this._y0=this._y1=+b)+"h"+ +c+"v"+ +d+"h"+-c+"Z"},toString:function(){return this._}};var _k=function(a){var b=+this._x.call(null,a),c=+this._y.call(null,a);return J(this.cover(b,c),b,c,a)},al=function(a,b){if(isNaN(a=+a)||isNaN(b=+b))return this;var c=this._x0,d=this._y0,e=this._x1,f=this._y1;if(isNaN(c))e=(c=Math.floor(a))+1,f=(d=Math.floor(b))+1;else{if(!(c>a||a>e||d>b||b>f))return this;var g,h,i=e-c,j=this._root;switch(h=(b<(d+f)/2)<<1|a<(c+e)/2){case 0:do g=new Array(4),g[h]=j,j=g;while(i*=2,e=c+i,f=d+i,a>e||b>f);break;case 1:do g=new Array(4),g[h]=j,j=g;while(i*=2,c=e-i,f=d+i,c>a||b>f);break;case 2:do g=new Array(4),g[h]=j,j=g;while(i*=2,e=c+i,d=f-i,a>e||d>b);break;case 3:do g=new Array(4),g[h]=j,j=g;while(i*=2,c=e-i,d=f-i,c>a||d>b)}this._root&&this._root.length&&(this._root=j)}return this._x0=c,this._y0=d,this._x1=e,this._y1=f,this},bl=function(){var a=[];return this.visit(function(b){if(!b.length)do a.push(b.data);while(b=b.next)}),a},cl=function(a){return arguments.length?this.cover(+a[0][0],+a[0][1]).cover(+a[1][0],+a[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},dl=function(a,b,c,d,e){this.node=a,this.x0=b,this.y0=c,this.x1=d,this.y1=e},el=function(a,b,c){var d,e,f,g,h,i,j,k=this._x0,l=this._y0,m=this._x1,n=this._y1,o=[],p=this._root;for(p&&o.push(new dl(p,k,l,m,n)),null==c?c=1/0:(k=a-c,l=b-c,m=a+c,n=b+c,c*=c);i=o.pop();)if(!(!(p=i.node)||(e=i.x0)>m||(f=i.y0)>n||(g=i.x1)=r)<<1|a>=q)&&(i=o[o.length-1],o[o.length-1]=o[o.length-1-j],o[o.length-1-j]=i)}else{var s=a-+this._x.call(null,p.data),t=b-+this._y.call(null,p.data),u=s*s+t*t;if(u=(h=(o+q)/2))?o=h:q=h,(k=g>=(i=(p+r)/2))?p=i:r=i,b=n,!(n=n[l=k<<1|j]))return this;if(!n.length)break;(b[l+1&3]||b[l+2&3]||b[l+3&3])&&(c=b,m=l)}for(;n.data!==a;)if(d=n,!(n=n.next))return this;return(e=n.next)&&delete n.next,d?(e?d.next=e:delete d.next,this):b?(e?b[l]=e:delete b[l],(n=b[0]||b[1]||b[2]||b[3])&&n===(b[3]||b[2]||b[1]||b[0])&&!n.length&&(c?c[m]=n:this._root=n),this):(this._root=e,this)},gl=function(){return this._root},hl=function(){var a=0;return this.visit(function(b){if(!b.length)do++a;while(b=b.next)}),a},il=function(a){var b,c,d,e,f,g,h=[],i=this._root;for(i&&h.push(new dl(i,this._x0,this._y0,this._x1,this._y1));b=h.pop();)if(!a(i=b.node,d=b.x0,e=b.y0,f=b.x1,g=b.y1)&&i.length){var j=(d+f)/2,k=(e+g)/2;(c=i[3])&&h.push(new dl(c,j,k,f,g)),(c=i[2])&&h.push(new dl(c,d,k,j,g)),(c=i[1])&&h.push(new dl(c,j,e,f,k)),(c=i[0])&&h.push(new dl(c,d,e,j,k))}return this},jl=function(a){var b,c=[],d=[];for(this._root&&c.push(new dl(this._root,this._x0,this._y0,this._x1,this._y1));b=c.pop();){var e=b.node;if(e.length){var f,g=b.x0,h=b.y0,i=b.x1,j=b.y1,k=(g+i)/2,l=(h+j)/2;(f=e[0])&&c.push(new dl(f,g,h,k,l)),(f=e[1])&&c.push(new dl(f,k,h,i,l)),(f=e[2])&&c.push(new dl(f,g,l,k,j)),(f=e[3])&&c.push(new dl(f,k,l,i,j))}d.push(b)}for(;b=d.pop();)a(b.node,b.x0,b.y0,b.x1,b.y1);return this},kl=function(a){return arguments.length?(this._x=a,this):this._x},ll=function(a){return arguments.length?(this._y=a,this):this._y},ml=O.prototype=P.prototype;ml.copy=function(){var a,b,c=new P(this._x,this._y,this._x0,this._y0,this._x1,this._y1),d=this._root;if(!d)return c;if(!d.length)return c._root=Q(d),c;for(a=[{source:d,target:c._root=new Array(4)}];d=a.pop();)for(var e=0;e<4;++e)(b=d.source[e])&&(b.length?a.push({source:b,target:d.target[e]=new Array(4)}):d.target[e]=Q(b));return c},ml.add=_k,ml.addAll=K,ml.cover=al,ml.data=bl,ml.extent=cl,ml.find=el,ml.remove=fl,ml.removeAll=L,ml.root=gl,ml.size=hl,ml.visit=il,ml.visitAfter=jl,ml.x=kl,ml.y=ll;var nl=[].slice,ol={};R.prototype=X.prototype={constructor:R,defer:function(a){ -if("function"!=typeof a||this._call)throw new Error;if(null!=this._error)return this;var b=nl.call(arguments,1);return b.push(a),++this._waiting,this._tasks.push(b),S(this),this},abort:function(){return null==this._error&&V(this,new Error("abort")),this},await:function(a){if("function"!=typeof a||this._call)throw new Error;return this._call=function(b,c){a.apply(null,[b].concat(c))},W(this),this},awaitAll:function(a){if("function"!=typeof a||this._call)throw new Error;return this._call=a,W(this),this}};var pl=function(a){return function(){return a}},ql=1e-12,rl=Math.PI,sl=rl/2,tl=2*rl,ul=function(){function a(){var a,j,k=+b.apply(this,arguments),l=+c.apply(this,arguments),m=f.apply(this,arguments)-sl,n=g.apply(this,arguments)-sl,o=Math.abs(n-m),p=n>m;if(i||(i=a=I()),lql)if(o>tl-ql)i.moveTo(l*Math.cos(m),l*Math.sin(m)),i.arc(0,0,l,m,n,!p),k>ql&&(i.moveTo(k*Math.cos(n),k*Math.sin(n)),i.arc(0,0,k,n,m,p));else{var q,r,s=m,t=n,u=m,v=n,w=o,x=o,y=h.apply(this,arguments)/2,z=y>ql&&(e?+e.apply(this,arguments):Math.sqrt(k*k+l*l)),A=Math.min(Math.abs(l-k)/2,+d.apply(this,arguments)),B=A,C=A;if(z>ql){var D=ba(z/k*Math.sin(y)),E=ba(z/l*Math.sin(y));(w-=2*D)>ql?(D*=p?1:-1,u+=D,v-=D):(w=0,u=v=(m+n)/2),(x-=2*E)>ql?(E*=p?1:-1,s+=E,t-=E):(x=0,s=t=(m+n)/2)}var F=l*Math.cos(s),G=l*Math.sin(s),H=k*Math.cos(v),J=k*Math.sin(v);if(A>ql){var K=l*Math.cos(t),L=l*Math.sin(t),M=k*Math.cos(u),N=k*Math.sin(u);if(oql?ca(F,G,M,N,K,L,H,J):[H,J],P=F-O[0],Q=G-O[1],R=K-O[0],S=L-O[1],T=1/Math.sin(Math.acos((P*R+Q*S)/(Math.sqrt(P*P+Q*Q)*Math.sqrt(R*R+S*S)))/2),U=Math.sqrt(O[0]*O[0]+O[1]*O[1]);B=Math.min(A,(k-U)/(T-1)),C=Math.min(A,(l-U)/(T+1))}}x>ql?C>ql?(q=da(M,N,F,G,l,C,p),r=da(K,L,H,J,l,C,p),i.moveTo(q.cx+q.x01,q.cy+q.y01),Cql&&w>ql?B>ql?(q=da(H,J,K,L,k,-B,p),r=da(F,G,M,N,k,-B,p),i.lineTo(q.cx+q.x01,q.cy+q.y01),B=k;--l)j.point(q[l],r[l]);j.lineEnd(),j.areaEnd()}p&&(q[b]=+c(m,b,a),r[b]=+e(m,b,a),j.point(d?+d(m,b,a):q[b],f?+f(m,b,a):r[b]))}if(n)return j=null,n+""||null}function b(){return wl().defined(g).curve(i).context(h)}var c=fa,d=null,e=pl(0),f=ga,g=pl(!0),h=null,i=vl,j=null;return a.x=function(b){return arguments.length?(c="function"==typeof b?b:pl(+b),d=null,a):c},a.x0=function(b){return arguments.length?(c="function"==typeof b?b:pl(+b),a):c},a.x1=function(b){return arguments.length?(d=null==b?null:"function"==typeof b?b:pl(+b),a):d},a.y=function(b){return arguments.length?(e="function"==typeof b?b:pl(+b),f=null,a):e},a.y0=function(b){return arguments.length?(e="function"==typeof b?b:pl(+b),a):e},a.y1=function(b){return arguments.length?(f=null==b?null:"function"==typeof b?b:pl(+b),a):f},a.lineX0=a.lineY0=function(){return b().x(c).y(e)},a.lineY1=function(){return b().x(c).y(f)},a.lineX1=function(){return b().x(d).y(e)},a.defined=function(b){return arguments.length?(g="function"==typeof b?b:pl(!!b),a):g},a.curve=function(b){return arguments.length?(i=b,null!=h&&(j=i(h)),a):i},a.context=function(b){return arguments.length?(null==b?h=j=null:j=i(h=b),a):h},a},yl=function(a,b){return ba?1:b>=a?0:NaN},zl=function(a){return a},Al=function(){function a(a){var h,i,j,k,l,m=a.length,n=0,o=new Array(m),p=new Array(m),q=+e.apply(this,arguments),r=Math.min(tl,Math.max(-tl,f.apply(this,arguments)-q)),s=Math.min(Math.abs(r)/m,g.apply(this,arguments)),t=s*(r<0?-1:1);for(h=0;h0&&(n+=l);for(null!=c?o.sort(function(a,b){return c(p[a],p[b])}):null!=d&&o.sort(function(b,c){return d(a[b],a[c])}),h=0,j=n?(r-m*t)/n:0;h0?l*j:0)+t,p[i]={data:a[i],index:h,value:l,startAngle:q,endAngle:k,padAngle:s};return p}var b=zl,c=yl,d=null,e=pl(0),f=pl(tl),g=pl(0);return a.value=function(c){return arguments.length?(b="function"==typeof c?c:pl(+c),a):b},a.sortValues=function(b){return arguments.length?(c=b,d=null,a):c},a.sort=function(b){return arguments.length?(d=b,c=null,a):d},a.startAngle=function(b){return arguments.length?(e="function"==typeof b?b:pl(+b),a):e},a.endAngle=function(b){return arguments.length?(f="function"==typeof b?b:pl(+b),a):f},a.padAngle=function(b){return arguments.length?(g="function"==typeof b?b:pl(+b),a):g},a},Bl=ia(vl);ha.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(a,b){this._curve.point(b*Math.sin(a),b*-Math.cos(a))}};var Cl=function(){return ja(wl().curve(Bl))},Dl=function(){var a=xl().curve(Bl),b=a.curve,c=a.lineX0,d=a.lineX1,e=a.lineY0,f=a.lineY1;return a.angle=a.x,delete a.x,a.startAngle=a.x0,delete a.x0,a.endAngle=a.x1,delete a.x1,a.radius=a.y,delete a.y,a.innerRadius=a.y0,delete a.y0,a.outerRadius=a.y1,delete a.y1,a.lineStartAngle=function(){return ja(c())},delete a.lineX0,a.lineEndAngle=function(){return ja(d())},delete a.lineX1,a.lineInnerRadius=function(){return ja(e())},delete a.lineY0,a.lineOuterRadius=function(){return ja(f())},delete a.lineY1,a.curve=function(a){return arguments.length?b(ia(a)):b()._curve},a},El={draw:function(a,b){var c=Math.sqrt(b/rl);a.moveTo(c,0),a.arc(0,0,c,0,tl)}},Fl={draw:function(a,b){var c=Math.sqrt(b/5)/2;a.moveTo(-3*c,-c),a.lineTo(-c,-c),a.lineTo(-c,-3*c),a.lineTo(c,-3*c),a.lineTo(c,-c),a.lineTo(3*c,-c),a.lineTo(3*c,c),a.lineTo(c,c),a.lineTo(c,3*c),a.lineTo(-c,3*c),a.lineTo(-c,c),a.lineTo(-3*c,c),a.closePath()}},Gl=Math.sqrt(1/3),Hl=2*Gl,Il={draw:function(a,b){var c=Math.sqrt(b/Hl),d=c*Gl;a.moveTo(0,-c),a.lineTo(d,0),a.lineTo(0,c),a.lineTo(-d,0),a.closePath()}},Jl=.8908130915292852,Kl=Math.sin(rl/10)/Math.sin(7*rl/10),Ll=Math.sin(tl/10)*Kl,Ml=-Math.cos(tl/10)*Kl,Nl={draw:function(a,b){var c=Math.sqrt(b*Jl),d=Ll*c,e=Ml*c;a.moveTo(0,-c),a.lineTo(d,e);for(var f=1;f<5;++f){var g=tl*f/5,h=Math.cos(g),i=Math.sin(g);a.lineTo(i*c,-h*c),a.lineTo(h*d-i*e,i*d+h*e)}a.closePath()}},Ol={draw:function(a,b){var c=Math.sqrt(b),d=-c/2;a.rect(d,d,c,c)}},Pl=Math.sqrt(3),Ql={draw:function(a,b){var c=-Math.sqrt(b/(3*Pl));a.moveTo(0,2*c),a.lineTo(-Pl*c,-c),a.lineTo(Pl*c,-c),a.closePath()}},Rl=-.5,Sl=Math.sqrt(3)/2,Tl=1/Math.sqrt(12),Ul=3*(Tl/2+1),Vl={draw:function(a,b){var c=Math.sqrt(b/Ul),d=c/2,e=c*Tl,f=d,g=c*Tl+c,h=-f,i=g;a.moveTo(d,e),a.lineTo(f,g),a.lineTo(h,i),a.lineTo(Rl*d-Sl*e,Sl*d+Rl*e),a.lineTo(Rl*f-Sl*g,Sl*f+Rl*g),a.lineTo(Rl*h-Sl*i,Sl*h+Rl*i),a.lineTo(Rl*d+Sl*e,Rl*e-Sl*d),a.lineTo(Rl*f+Sl*g,Rl*g-Sl*f),a.lineTo(Rl*h+Sl*i,Rl*i-Sl*h),a.closePath()}},Wl=[El,Fl,Il,Ol,Nl,Ql,Vl],Xl=function(){function a(){var a;if(d||(d=a=I()),b.apply(this,arguments).draw(d,+c.apply(this,arguments)),a)return d=null,a+""||null}var b=pl(El),c=pl(64),d=null;return a.type=function(c){return arguments.length?(b="function"==typeof c?c:pl(c),a):b},a.size=function(b){return arguments.length?(c="function"==typeof b?b:pl(+b),a):c},a.context=function(b){return arguments.length?(d=null==b?null:b,a):d},a},Yl=function(){};la.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:ka(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:ka(this,a,b)}this._x0=this._x1,this._x1=a,this._y0=this._y1,this._y1=b}};var Zl=function(a){return new la(a)};ma.prototype={areaStart:Yl,areaEnd:Yl,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._x2=a,this._y2=b;break;case 1:this._point=2,this._x3=a,this._y3=b;break;case 2:this._point=3,this._x4=a,this._y4=b,this._context.moveTo((this._x0+4*this._x1+a)/6,(this._y0+4*this._y1+b)/6);break;default:ka(this,a,b)}this._x0=this._x1,this._x1=a,this._y0=this._y1,this._y1=b}};var $l=function(a){return new ma(a)};na.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var c=(this._x0+4*this._x1+a)/6,d=(this._y0+4*this._y1+b)/6;this._line?this._context.lineTo(c,d):this._context.moveTo(c,d);break;case 3:this._point=4;default:ka(this,a,b)}this._x0=this._x1,this._x1=a,this._y0=this._y1,this._y1=b}};var _l=function(a){return new na(a)};oa.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var a=this._x,b=this._y,c=a.length-1;if(c>0)for(var d,e=a[0],f=b[0],g=a[c]-e,h=b[c]-f,i=-1;++i<=c;)d=i/c,this._basis.point(this._beta*a[i]+(1-this._beta)*(e+d*g),this._beta*b[i]+(1-this._beta)*(f+d*h));this._x=this._y=null,this._basis.lineEnd()},point:function(a,b){this._x.push(+a),this._y.push(+b)}};var am=function a(b){function c(a){return 1===b?new la(a):new oa(a,b)}return c.beta=function(b){return a(+b)},c}(.85);qa.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:pa(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2,this._x1=a,this._y1=b;break;case 2:this._point=3;default:pa(this,a,b)}this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var bm=function a(b){function c(a){return new qa(a,b)}return c.tension=function(b){return a(+b)},c}(0);ra.prototype={areaStart:Yl,areaEnd:Yl,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._x3=a,this._y3=b;break;case 1:this._point=2,this._context.moveTo(this._x4=a,this._y4=b);break;case 2:this._point=3,this._x5=a,this._y5=b;break;default:pa(this,a,b)}this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var cm=function a(b){function c(a){return new ra(a,b)}return c.tension=function(b){return a(+b)},c}(0);sa.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:pa(this,a,b)}this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var dm=function a(b){function c(a){return new sa(a,b)}return c.tension=function(b){return a(+b)},c}(0);ua.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){if(a=+a,b=+b,this._point){var c=this._x2-a,d=this._y2-b;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(c*c+d*d,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2;break;case 2:this._point=3;default:ta(this,a,b)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var em=function a(b){function c(a){return b?new ua(a,b):new qa(a,0)}return c.alpha=function(b){return a(+b)},c}(.5);va.prototype={areaStart:Yl,areaEnd:Yl,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(a,b){if(a=+a,b=+b,this._point){var c=this._x2-a,d=this._y2-b;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(c*c+d*d,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=a,this._y3=b;break;case 1:this._point=2,this._context.moveTo(this._x4=a,this._y4=b);break;case 2:this._point=3,this._x5=a,this._y5=b;break;default:ta(this,a,b)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var fm=function a(b){function c(a){return b?new va(a,b):new ra(a,0)}return c.alpha=function(b){return a(+b)},c}(.5);wa.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){if(a=+a,b=+b,this._point){var c=this._x2-a,d=this._y2-b;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(c*c+d*d,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:ta(this,a,b)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var gm=function a(b){function c(a){return b?new wa(a,b):new sa(a,0)}return c.alpha=function(b){return a(+b)},c}(.5);xa.prototype={areaStart:Yl,areaEnd:Yl,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(a,b){a=+a,b=+b,this._point?this._context.lineTo(a,b):(this._point=1,this._context.moveTo(a,b))}};var hm=function(a){return new xa(a)};Ca.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Ba(this,this._t0,Aa(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){var c=NaN;if(a=+a,b=+b,a!==this._x1||b!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2;break;case 2:this._point=3,Ba(this,Aa(this,c=za(this,a,b)),c);break;default:Ba(this,this._t0,c=za(this,a,b))}this._x0=this._x1,this._x1=a,this._y0=this._y1,this._y1=b,this._t0=c}}},(Da.prototype=Object.create(Ca.prototype)).point=function(a,b){Ca.prototype.point.call(this,b,a)},Ea.prototype={moveTo:function(a,b){this._context.moveTo(b,a)},closePath:function(){this._context.closePath()},lineTo:function(a,b){this._context.lineTo(b,a)},bezierCurveTo:function(a,b,c,d,e,f){this._context.bezierCurveTo(b,a,d,c,f,e)}},Ha.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var a=this._x,b=this._y,c=a.length;if(c)if(this._line?this._context.lineTo(a[0],b[0]):this._context.moveTo(a[0],b[0]),2===c)this._context.lineTo(a[1],b[1]);else for(var d=Ia(a),e=Ia(b),f=0,g=1;g=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,b),this._context.lineTo(a,b);else{var c=this._x*(1-this._t)+a*this._t;this._context.lineTo(c,this._y),this._context.lineTo(c,b)}}this._x=a,this._y=b}};var jm=function(a){return new Ja(a,.5)},km=Array.prototype.slice,lm=function(a,b){if((d=a.length)>1)for(var c,d,e=1,f=a[b[0]],g=f.length;e=0;)c[b]=b;return c},nm=function(){function a(a){var f,g,h=b.apply(this,arguments),i=a.length,j=h.length,k=new Array(j);for(f=0;f0){for(var c,d,e,f=0,g=a[0].length;f0){for(var c,d=0,e=a[b[0]],f=e.length;d0&&(d=(c=a[b[0]]).length)>0){for(var c,d,e,f=0,g=1;g=240?a-240:a+120,e,d),$a(a,e,d),$a(a<120?a+240:a-120,e,d),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var Km=Math.PI/180,Lm=180/Math.PI,Mm=18,Nm=.95047,Om=1,Pm=1.08883,Qm=4/29,Rm=6/29,Sm=3*Rm*Rm,Tm=Rm*Rm*Rm;vm(bb,ab,Oa(Pa,{brighter:function(a){return new bb(this.l+Mm*(null==a?1:a),this.a,this.b,this.opacity)},darker:function(a){return new bb(this.l-Mm*(null==a?1:a),this.a,this.b,this.opacity)},rgb:function(){var a=(this.l+16)/116,b=isNaN(this.a)?a:a+this.a/500,c=isNaN(this.b)?a:a-this.b/200;return a=Om*db(a),b=Nm*db(b),c=Pm*db(c),new Va(eb(3.2404542*b-1.5371385*a-.4985314*c),eb(-.969266*b+1.8760108*a+.041556*c),eb(.0556434*b-.2040259*a+1.0572252*c),this.opacity)}})),vm(ib,hb,Oa(Pa,{brighter:function(a){return new ib(this.h,this.c,this.l+Mm*(null==a?1:a),this.opacity)},darker:function(a){return new ib(this.h,this.c,this.l-Mm*(null==a?1:a),this.opacity)},rgb:function(){return _a(this).rgb()}}));var Um=-.14861,Vm=1.78277,Wm=-.29227,Xm=-.90649,Ym=1.97294,Zm=Ym*Xm,$m=Ym*Vm,_m=Vm*Wm-Xm*Um;vm(lb,kb,Oa(Pa,{brighter:function(a){return a=null==a?xm:Math.pow(xm,a),new lb(this.h,this.s,this.l*a,this.opacity)},darker:function(a){return a=null==a?wm:Math.pow(wm,a),new lb(this.h,this.s,this.l*a,this.opacity)},rgb:function(){var a=isNaN(this.h)?0:(this.h+120)*Km,b=+this.l,c=isNaN(this.s)?0:this.s*b*(1-b),d=Math.cos(a),e=Math.sin(a);return new Va(255*(b+c*(Um*d+Vm*e)),255*(b+c*(Wm*d+Xm*e)),255*(b+c*(Ym*d)),this.opacity)}}));var an,bn,cn,dn,en=function(a){var b=a.length-1;return function(c){var d=c<=0?c=0:c>=1?(c=1,b-1):Math.floor(c*b),e=a[d],f=a[d+1],g=d>0?a[d-1]:2*e-f,h=df&&(e=b.slice(f,e),h[g]?h[g]+=e:h[++g]=e),(c=c[0])===(d=d[0])?h[g]?h[g]+=d:h[++g]=d:(h[++g]=null,i.push({i:g,x:nn(c,d)})),f=qn.lastIndex;return f0)for(var c,d,e=new Array(c),f=0;f=j)return g;if(e)return e=!1,f;var b,c=k;if(34===a.charCodeAt(c)){for(var d=c;d++=200&&c<300||304===c){if(g)try{b=g.call(d,k)}catch(a){return void i.call("error",d,a)}else b=k;i.call("load",d,b)}else i.call("error",d,a)}var d,e,g,h,i=Fb("beforesend","progress","load","error"),j=f(),k=new XMLHttpRequest,l=null,m=null,n=0;if("undefined"==typeof XDomainRequest||"withCredentials"in k||!/^(http(s)?:)?\/\//.test(a)||(k=new XDomainRequest),"onload"in k?k.onload=k.onerror=k.ontimeout=c:k.onreadystatechange=function(a){k.readyState>3&&c(a)},k.onprogress=function(a){i.call("progress",d,a)},d={header:function(a,b){return a=(a+"").toLowerCase(),arguments.length<2?j.get(a):(null==b?j.remove(a):j.set(a,b+""),d)},mimeType:function(a){return arguments.length?(e=null==a?null:a+"",d):e},responseType:function(a){return arguments.length?(h=a,d):h},timeout:function(a){return arguments.length?(n=+a,d):n},user:function(a){return arguments.length<1?l:(l=null==a?null:a+"",d)},password:function(a){return arguments.length<1?m:(m=null==a?null:a+"",d)},response:function(a){return g=a,d},get:function(a,b){return d.send("GET",a,b)},post:function(a,b){return d.send("POST",a,b)},send:function(b,c,f){return k.open(b,a,!0,l,m),null==e||j.has("accept")||j.set("accept",e+",*/*"),k.setRequestHeader&&j.each(function(a,b){k.setRequestHeader(b,a)}),null!=e&&k.overrideMimeType&&k.overrideMimeType(e),null!=h&&(k.responseType=h),n>0&&(k.timeout=n),null==f&&"function"==typeof c&&(f=c,c=null),null!=f&&1===f.length&&(f=Nb(f)),null!=f&&d.on("error",f).on("load",function(a){f(null,a)}),i.call("beforesend",d,k),k.send(null==c?null:c),d},abort:function(){return k.abort(),d},on:function(){var a=i.on.apply(i,arguments);return a===i?d:a}},null!=b){if("function"!=typeof b)throw new Error("invalid callback: "+b);return d.get(b)}return d},$n=function(a,b){return function(c,d){var e=Zn(c).mimeType(a).response(b);if(null!=d){if("function"!=typeof d)throw new Error("invalid callback: "+d);return e.get(d)}return e}},_n=$n("text/html",function(a){return document.createRange().createContextualFragment(a.responseText)}),ao=$n("application/json",function(a){return JSON.parse(a.responseText)}),bo=$n("text/plain",function(a){return a.responseText}),co=$n("application/xml",function(a){var b=a.responseXML;if(!b)throw new Error("parse error");return b}),eo=function(a,b){return function(c,d,e){arguments.length<3&&(e=d,d=null);var f=Zn(c).mimeType(a);return f.row=function(a){return arguments.length?f.response(Pb(b,d=a)):d},f.row(d),e?f.get(e):f}},fo=eo("text/csv",Qn),go=eo("text/tab-separated-values",Vn),ho=0,io=0,jo=0,ko=1e3,lo=0,mo=0,no=0,oo="object"==typeof performance&&performance.now?performance:Date,po="function"==typeof requestAnimationFrame?requestAnimationFrame:function(a){setTimeout(a,17)};Sb.prototype=Tb.prototype={constructor:Sb,restart:function(a,b,c){if("function"!=typeof a)throw new TypeError("callback is not a function");c=(null==c?Qb():+c)+(null==b?0:+b),this._next||Nn===this||(Nn?Nn._next=this:Mn=this,Nn=this),this._call=a,this._time=c,Yb()},stop:function(){this._call&&(this._call=null,this._time=1/0,Yb())}};var qo=function(a,b,c){var d=new Sb;return b=null==b?0:+b,d.restart(function(c){d.stop(),a(c+b)},b,c),d},ro=function(a,b,c){var d=new Sb,e=b;return null==b?(d.restart(a,b,c),d):(b=+b,c=null==c?Qb():+c,d.restart(function f(g){g+=e,d.restart(f,e+=b,c),a(g)},b,c),d)},so=new Date,to=new Date,uo=Zb(function(){},function(a,b){a.setTime(+a+b)},function(a,b){return b-a});uo.every=function(a){return a=Math.floor(a),isFinite(a)&&a>0?a>1?Zb(function(b){b.setTime(Math.floor(b/a)*a)},function(b,c){b.setTime(+b+c*a)},function(b,c){return(c-b)/a}):uo:null};var vo=uo.range,wo=1e3,xo=6e4,yo=36e5,zo=864e5,Ao=6048e5,Bo=Zb(function(a){a.setTime(Math.floor(a/wo)*wo)},function(a,b){a.setTime(+a+b*wo)},function(a,b){return(b-a)/wo},function(a){return a.getUTCSeconds()}),Co=Bo.range,Do=Zb(function(a){a.setTime(Math.floor(a/xo)*xo)},function(a,b){a.setTime(+a+b*xo)},function(a,b){return(b-a)/xo},function(a){return a.getMinutes()}),Eo=Do.range,Fo=Zb(function(a){var b=a.getTimezoneOffset()*xo%yo;b<0&&(b+=yo),a.setTime(Math.floor((+a-b)/yo)*yo+b)},function(a,b){a.setTime(+a+b*yo)},function(a,b){return(b-a)/yo},function(a){return a.getHours()}),Go=Fo.range,Ho=Zb(function(a){a.setHours(0,0,0,0)},function(a,b){a.setDate(a.getDate()+b)},function(a,b){return(b-a-(b.getTimezoneOffset()-a.getTimezoneOffset())*xo)/zo},function(a){return a.getDate()-1}),Io=Ho.range,Jo=$b(0),Ko=$b(1),Lo=$b(2),Mo=$b(3),No=$b(4),Oo=$b(5),Po=$b(6),Qo=Jo.range,Ro=Ko.range,So=Lo.range,To=Mo.range,Uo=No.range,Vo=Oo.range,Wo=Po.range,Xo=Zb(function(a){a.setDate(1),a.setHours(0,0,0,0)},function(a,b){a.setMonth(a.getMonth()+b)},function(a,b){return b.getMonth()-a.getMonth()+12*(b.getFullYear()-a.getFullYear())},function(a){return a.getMonth()}),Yo=Xo.range,Zo=Zb(function(a){a.setMonth(0,1),a.setHours(0,0,0,0)},function(a,b){a.setFullYear(a.getFullYear()+b)},function(a,b){return b.getFullYear()-a.getFullYear()},function(a){return a.getFullYear()});Zo.every=function(a){return isFinite(a=Math.floor(a))&&a>0?Zb(function(b){b.setFullYear(Math.floor(b.getFullYear()/a)*a),b.setMonth(0,1),b.setHours(0,0,0,0)},function(b,c){b.setFullYear(b.getFullYear()+c*a)}):null};var $o=Zo.range,_o=Zb(function(a){a.setUTCSeconds(0,0)},function(a,b){a.setTime(+a+b*xo)},function(a,b){return(b-a)/xo},function(a){return a.getUTCMinutes()}),ap=_o.range,bp=Zb(function(a){a.setUTCMinutes(0,0,0)},function(a,b){a.setTime(+a+b*yo)},function(a,b){return(b-a)/yo},function(a){return a.getUTCHours()}),cp=bp.range,dp=Zb(function(a){a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCDate(a.getUTCDate()+b)},function(a,b){return(b-a)/zo},function(a){return a.getUTCDate()-1}),ep=dp.range,fp=_b(0),gp=_b(1),hp=_b(2),ip=_b(3),jp=_b(4),kp=_b(5),lp=_b(6),mp=fp.range,np=gp.range,op=hp.range,pp=ip.range,qp=jp.range,rp=kp.range,sp=lp.range,tp=Zb(function(a){a.setUTCDate(1),a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCMonth(a.getUTCMonth()+b)},function(a,b){return b.getUTCMonth()-a.getUTCMonth()+12*(b.getUTCFullYear()-a.getUTCFullYear())},function(a){return a.getUTCMonth()}),up=tp.range,vp=Zb(function(a){a.setUTCMonth(0,1),a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCFullYear(a.getUTCFullYear()+b)},function(a,b){return b.getUTCFullYear()-a.getUTCFullYear()},function(a){return a.getUTCFullYear()});vp.every=function(a){return isFinite(a=Math.floor(a))&&a>0?Zb(function(b){b.setUTCFullYear(Math.floor(b.getUTCFullYear()/a)*a),b.setUTCMonth(0,1),b.setUTCHours(0,0,0,0)},function(b,c){b.setUTCFullYear(b.getUTCFullYear()+c*a)}):null};var wp,xp=vp.range,yp=function(a,b){if((c=(a=b?a.toExponential(b-1):a.toExponential()).indexOf("e"))<0)return null;var c,d=a.slice(0,c);return[d.length>1?d[0]+d.slice(2):d,+a.slice(c+1)]},zp=function(a){return a=yp(Math.abs(a)),a?a[1]:NaN},Ap=function(a,b){return function(c,d){for(var e=c.length,f=[],g=0,h=a[0],i=0;e>0&&h>0&&(i+h+1>d&&(h=Math.max(1,d-i)),f.push(c.substring(e-=h,e+h)),!((i+=h+1)>d));)h=a[g=(g+1)%a.length];return f.reverse().join(b)}},Bp=function(a,b){a=a.toPrecision(b);a:for(var c,d=a.length,e=1,f=-1;e0&&(f=0)}return f>0?a.slice(0,f)+a.slice(c+1):a},Cp=function(a,b){var c=yp(a,b);if(!c)return a+"";var d=c[0],e=c[1],f=e-(wp=3*Math.max(-8,Math.min(8,Math.floor(e/3))))+1,g=d.length;return f===g?d:f>g?d+new Array(f-g+1).join("0"):f>0?d.slice(0,f)+"."+d.slice(f):"0."+new Array(1-f).join("0")+yp(a,Math.max(0,b+f-1))[0]},Dp=function(a,b){var c=yp(a,b);if(!c)return a+"";var d=c[0],e=c[1];return e<0?"0."+new Array(-e).join("0")+d:d.length>e+1?d.slice(0,e+1)+"."+d.slice(e+1):d+new Array(e-d.length+2).join("0")},Ep={"":Bp,"%":function(a,b){return(100*a).toFixed(b)},b:function(a){return Math.round(a).toString(2)},c:function(a){return a+""},d:function(a){return Math.round(a).toString(10)},e:function(a,b){return a.toExponential(b)},f:function(a,b){return a.toFixed(b)},g:function(a,b){return a.toPrecision(b)},o:function(a){return Math.round(a).toString(8)},p:function(a,b){return Dp(100*a,b)},r:Dp,s:Cp,X:function(a){return Math.round(a).toString(16).toUpperCase()},x:function(a){return Math.round(a).toString(16)}},Fp=/^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i,Gp=function(a){return new ac(a)};ac.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+this.type};var Hp,Ip=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"],Jp=function(a){function b(a){function b(a){var b,e,i,s=o,t=p;if("c"===n)t=q(a)+t,a="";else{a=+a;var u=(a<0||1/a<0)&&(a*=-1,!0);if(a=q(a,m),u)for(b=-1,e=a.length,u=!1;++bi||i>57){t=(46===i?f+a.slice(b+1):a.slice(b))+t,a=a.slice(0,b);break}}l&&!j&&(a=d(a,1/0));var v=s.length+a.length+t.length,w=v>1)+s+a+t+w.slice(v)}return w+s+a+t}a=Gp(a);var c=a.fill,g=a.align,h=a.sign,i=a.symbol,j=a.zero,k=a.width,l=a.comma,m=a.precision,n=a.type,o="$"===i?e[0]:"#"===i&&/[boxX]/.test(n)?"0"+n.toLowerCase():"",p="$"===i?e[1]:/[%p]/.test(n)?"%":"",q=Ep[n],r=!n||/[defgprs%]/.test(n);return m=null==m?n?6:12:/[gprs]/.test(n)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),b.toString=function(){return a+""},b}function c(a,c){var d=b((a=Gp(a),a.type="f",a)),e=3*Math.max(-8,Math.min(8,Math.floor(zp(c)/3))),f=Math.pow(10,-e),g=Ip[8+e/3];return function(a){return d(f*a)+g}}var d=a.grouping&&a.thousands?Ap(a.grouping,a.thousands):bc,e=a.currency,f=a.decimal;return{format:b,formatPrefix:c}};cc({decimal:".",thousands:",",grouping:[3],currency:["$",""]});var Kp,Lp=function(a){return Math.max(0,-zp(Math.abs(a)))},Mp=function(a,b){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(zp(b)/3)))-zp(Math.abs(a)))},Np=function(a,b){return a=Math.abs(a),b=Math.abs(b)-a,Math.max(0,zp(b)-zp(a))+1},Op={"-":"",_:" ",0:"0"},Pp=/^\s*\d+/,Qp=/^%/,Rp=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;ad({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});var Sp="%Y-%m-%dT%H:%M:%S.%LZ",Tp=Date.prototype.toISOString?bd:a.utcFormat(Sp),Up=+new Date("2000-01-01T00:00:00.000Z")?cd:a.utcParse(Sp),Vp=Array.prototype,Wp=Vp.map,Xp=Vp.slice,Yp={name:"implicit"},Zp=function(a){return function(){return a}},$p=function(a){return+a},_p=[0,1],aq=function(b,d,e){var f,g=b[0],h=b[b.length-1],i=c(g,h,null==d?10:d);switch(e=Gp(null==e?",f":e),e.type){case"s":var j=Math.max(Math.abs(g),Math.abs(h));return null!=e.precision||isNaN(f=Mp(i,j))||(e.precision=f),a.formatPrefix(e,j);case"":case"e":case"g":case"p":case"r":null!=e.precision||isNaN(f=Np(i,Math.max(Math.abs(g),Math.abs(h))))||(e.precision=f-("e"===e.type));break;case"f":case"%":null!=e.precision||isNaN(f=Lp(i))||(e.precision=f-2*("%"===e.type))}return a.format(e)},bq=function(a,b){a=a.slice();var c,d=0,e=a.length-1,f=a[d],g=a[e];return g1)&&(a-=Math.floor(a));var b=Math.abs(a-.5);return tq.h=360*a-100,tq.s=1.5-1.5*b,tq.l=.8-.9*b,tq+""},vq=Hd(lq("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")),wq=Hd(lq("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),xq=Hd(lq("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),yq=Hd(lq("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),zq="http://www.w3.org/1999/xhtml",Aq={svg:"http://www.w3.org/2000/svg",xhtml:zq,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},Bq=function(a){var b=a+="",c=b.indexOf(":");return c>=0&&"xmlns"!==(b=a.slice(0,c))&&(a=a.slice(c+1)),Aq.hasOwnProperty(b)?{space:Aq[b],local:a}:a},Cq=function(a){var b=Bq(a);return(b.local?Kd:Jd)(b)},Dq=0;Md.prototype=Ld.prototype={constructor:Md,get:function(a){for(var b=this._;!(b in a);)if(!(a=a.parentNode))return;return a[b]},set:function(a,b){return a[this._]=b},remove:function(a){return this._ in a&&delete a[this._]},toString:function(){return this._}};var Eq=function(a){return function(){return this.matches(a)}};if("undefined"!=typeof document){var Fq=document.documentElement;if(!Fq.matches){var Gq=Fq.webkitMatchesSelector||Fq.msMatchesSelector||Fq.mozMatchesSelector||Fq.oMatchesSelector;Eq=function(a){return function(){return Gq.call(this,a)}}}}var Hq=Eq,Iq={};if(a.event=null,"undefined"!=typeof document){var Jq=document.documentElement;"onmouseenter"in Jq||(Iq={mouseenter:"mouseover",mouseleave:"mouseout"})}var Kq=function(a,b,c){var d,e,f=Pd(a+""),g=f.length;{if(!(arguments.length<2)){for(h=b?Rd:Qd,null==c&&(c=!1),d=0;d=v&&(v=u+1);!(t=q[v])&&++v=0;)(d=e[f])&&(g&&g!==d.nextSibling&&g.parentNode.insertBefore(d,g),g=d);return this},_q=function(a){function b(b,c){return b&&c?a(b.__data__,c.__data__):!b-!c}a||(a=Yd);for(var c=this._groups,d=c.length,e=new Array(d),f=0;f1?this.each((null==b?de:"function"==typeof b?fe:ee)(a,b,null==c?"":c)):hr(d=this.node()).getComputedStyle(d,null).getPropertyValue(a)},jr=function(a,b){return arguments.length>1?this.each((null==b?ge:"function"==typeof b?ie:he)(a,b)):this.node()[a]};le.prototype={add:function(a){var b=this._names.indexOf(a);b<0&&(this._names.push(a),this._node.setAttribute("class",this._names.join(" ")))},remove:function(a){var b=this._names.indexOf(a);b>=0&&(this._names.splice(b,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(a){return this._names.indexOf(a)>=0}};var kr=function(a,b){var c=je(a+"");if(arguments.length<2){for(var d=ke(this.node()),e=-1,f=c.length;++eDr&&c.stateCr&&c.name===b)return new jf([[a]],gs,b,+d)}return null},is=Array.prototype.slice,js=function(a){return a},ks=1,ls=2,ms=3,ns=4,os=1e-6,ps=function(){function a(a){var f,g=0;a.eachAfter(function(a){var c=a.children;c?(a.x=xf(c),a.y=zf(c)):(a.x=f?g+=b(a,f):0,a.y=0,f=a)});var h=Bf(a),i=Cf(a),j=h.x-b(h,i)/2,k=i.x+b(i,h)/2;return a.eachAfter(e?function(b){b.x=(b.x-a.x)*c,b.y=(a.y-b.y)*d}:function(b){b.x=(b.x-j)/(k-j)*c,b.y=(1-(a.y?b.y/a.y:1))*d})}var b=wf,c=1,d=1,e=!1;return a.separation=function(c){return arguments.length?(b=c,a):b},a.size=function(b){return arguments.length?(e=!1,c=+b[0],d=+b[1],a):e?null:[c,d]},a.nodeSize=function(b){return arguments.length?(e=!0,c=+b[0],d=+b[1],a):e?[c,d]:null},a},qs=function(a){var b,c,d,e,f=this,g=[f];do for(b=g.reverse(),g=[];f=b.pop();)if(a(f),c=f.children)for(d=0,e=c.length;d=0;--c)e.push(b[c]);return this},ss=function(a){for(var b,c,d,e=this,f=[e],g=[];e=f.pop();)if(g.push(e),b=e.children)for(c=0,d=b.length;c=0;)c+=d[e].value;b.value=c})},us=function(a){return this.eachBefore(function(b){b.children&&b.children.sort(a)})},vs=function(a){for(var b=this,c=Df(b,a),d=[b];b!==c;)b=b.parent,d.push(b);for(var e=d.length;a!==c;)d.splice(e,0,a),a=a.parent;return d},ws=function(){for(var a=this,b=[a];a=a.parent;)b.push(a);return b},xs=function(){var a=[];return this.each(function(b){a.push(b)}),a},ys=function(){var a=[];return this.eachBefore(function(b){b.children||a.push(b)}),a},zs=function(){var a=this,b=[];return a.each(function(c){c!==a&&b.push({source:c.parent,target:c})}),b};Jf.prototype=Ef.prototype={constructor:Jf,each:qs,eachAfter:ss,eachBefore:rs,sum:ts,sort:us,path:vs,ancestors:ws,descendants:xs,leaves:ys,links:zs,copy:Ff};var As=function(a){for(var b,c=(a=a.slice()).length,d=null,e=d;c;){var f=new Kf(a[c-1]);e=e?e.next=f:d=f,a[b]=a[--c]}return{head:d,tail:e}},Bs=function(a){return Mf(As(a),[])},Cs=function(a){return Uf(a),a},Ds=function(a){return function(){return a}},Es=function(){function a(a){return a.x=c/2,a.y=d/2,b?a.eachBefore(Zf(b)).eachAfter($f(e,.5)).eachBefore(_f(1)):a.eachBefore(Zf(Yf)).eachAfter($f(Xf,1)).eachAfter($f(e,a.r/Math.min(c,d))).eachBefore(_f(Math.min(c,d)/(2*a.r))),a}var b=null,c=1,d=1,e=Xf;return a.radius=function(c){return arguments.length?(b=Vf(c),a):b},a.size=function(b){return arguments.length?(c=+b[0],d=+b[1],a):[c,d]},a.padding=function(b){return arguments.length?(e="function"==typeof b?b:Ds(+b),a):e},a},Fs=function(a){a.x0=Math.round(a.x0),a.y0=Math.round(a.y0),a.x1=Math.round(a.x1),a.y1=Math.round(a.y1)},Gs=function(a,b,c,d,e){for(var f,g=a.children,h=-1,i=g.length,j=a.value&&(d-b)/a.value;++h0)throw new Error("cycle");return f}var b=ag,c=bg;return a.id=function(c){return arguments.length?(b=Wf(c),a):b},a.parentId=function(b){return arguments.length?(c=Wf(b),a):c},a};ig.prototype=Object.create(Jf.prototype);var Ms=function(){function a(a){var d=jg(a);if(d.eachAfter(b),d.parent.m=-d.z,d.eachBefore(c),i)a.eachBefore(e);else{var j=a,k=a,l=a;a.eachBefore(function(a){a.xk.x&&(k=a),a.depth>l.depth&&(l=a)});var m=j===k?1:f(j,k)/2,n=m-j.x,o=g/(k.x+m+n),p=h/(l.depth||1);a.eachBefore(function(a){a.x=(a.x+n)*o,a.y=a.depth*p})}return a}function b(a){var b=a.children,c=a.parent.children,e=a.i?c[a.i-1]:null;if(b){gg(a);var g=(b[0].z+b[b.length-1].z)/2;e?(a.z=e.z+f(a._,e._),a.m=a.z-g):a.z=g}else e&&(a.z=e.z+f(a._,e._));a.parent.A=d(a,e,a.parent.A||c[0])}function c(a){a._.x=a.z+a.parent.m,a.m+=a.parent.m}function d(a,b,c){if(b){for(var d,e=a,g=a,h=b,i=e.parent.children[0],j=e.m,k=g.m,l=h.m,m=i.m;h=eg(h),e=dg(e),h&&e;)i=dg(i),g=eg(g),g.a=a,d=h.z+l-e.z-j+f(h._,e._),d>0&&(fg(hg(h,a,c),a,d),j+=d,k+=d),l+=h.m,j+=e.m,m+=i.m,k+=g.m;h&&!eg(g)&&(g.t=h,g.m+=l-k),e&&!dg(i)&&(i.t=e,i.m+=j-m,c=a)}return c}function e(a){a.x*=g,a.y=a.depth*h}var f=cg,g=1,h=1,i=null;return a.separation=function(b){return arguments.length?(f=b,a):f},a.size=function(b){return arguments.length?(i=!1,g=+b[0],h=+b[1],a):i?null:[g,h]},a.nodeSize=function(b){return arguments.length?(i=!0,g=+b[0],h=+b[1],a):i?[g,h]:null},a},Ns=function(a,b,c,d,e){for(var f,g=a.children,h=-1,i=g.length,j=a.value&&(e-c)/a.value;++h1?b:1)},c}(Os),Qs=function(){function a(a){return a.x0=a.y0=0,a.x1=e,a.y1=f,a.eachBefore(b),g=[0],d&&a.eachBefore(Fs),a}function b(a){var b=g[a.depth],d=a.x0+b,e=a.y0+b,f=a.x1-b,m=a.y1-b;f=b-1){var j=i[a];return j.x0=d,j.y0=e,j.x1=g,j.y1=h,void 0}for(var l=k[a],m=c/2+l,n=a+1,o=b-1;n>>1;k[p]g-d){var s=(e*r+h*q)/c;f(a,n,q,d,e,g,s),f(n,b,r,d,s,g,h)}else{var t=(d*r+g*q)/c;f(a,n,q,d,e,t,h),f(n,b,r,t,e,g,h)}}var g,h,i=a.children,j=i.length,k=new Array(j+1);for(k[0]=h=g=0;g1?b:1)},c}(Os),Us=function(a,b){function c(){var c,e,f=d.length,g=0,h=0;for(c=0;cj+n||dk+n||ei.index){var o=j-f.x-f.vx,p=k-f.y-f.vy,q=o*o+p*p;qa.r&&(a.r=a[b].r)}function d(){if(e){var b,c,d=e.length;for(f=new Array(d),b=0;b1?(null==b?m.remove(a):m.set(a,e(b)),g):m.get(a)},find:function(b,c,d){var e,f,g,h,i,j=0,k=a.length;for(null==d?d=1/0:d*=d,j=0;j1?(o.on(a,b),g):o.on(a)}}},at=function(){function a(a){var b,h=e.length,i=O(e,pg,qg).visitAfter(c);for(g=a,b=0;b=k)){(a.data!==f||a.next)&&(0===e&&(e=Ws(),n+=e*e),0===i&&(i=Ws(),n+=i*i),nc?(c+d)/2:Math.min(0,c)||Math.max(0,d),f>e?(e+f)/2:Math.min(0,e)||Math.max(0,f))}function f(a){return[(+a[0][0]+ +a[1][0])/2,(+a[0][1]+ +a[1][1])/2]}function g(a,b,c){a.on("start.zoom",function(){h(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){h(this,arguments).end()}).tween("zoom",function(){var a=this,d=arguments,e=h(a,d),g=s.apply(a,d),i=c||f(g),j=Math.max(g[1][0]-g[0][0],g[1][1]-g[0][1]),k=a.__zoom,l="function"==typeof b?b.apply(a,d):b,m=A(k.invert(i).concat(j/k.k),l.invert(i).concat(j/l.k));return function(a){if(1===a)a=l;else{var b=m(a),c=j/b[2];a=new ch(c,i[0]-b[0]*c,i[1]-b[1]*c)}e.zoom(null,a)}})}function h(a,b){for(var c,d=0,e=B.length;d0?vr(this).transition().duration(z).call(g,k,h):vr(this).call(b.transform,k)}}function m(){if(r.apply(this,arguments)){var b,c,d,e=h(this,arguments),f=a.event.changedTouches,g=f.length;for(eh(),b=0;b0?1:a<0?-1:0},Tu=Math.sqrt,Uu=Math.tan,Vu={Feature:function(a,b){Eh(a.geometry,b)},FeatureCollection:function(a,b){for(var c=a.features,d=-1,e=c.length;++dBu?du=90:av<-Bu&&(bu=-90),ju[0]=au,ju[1]=cu}},cv=function(a){var b,c,d,e,f,g,h;if(du=cu=-(au=bu=1/0),iu=[],Xu(a,bv),c=iu.length){for(iu.sort($h),b=1,d=iu[0],f=[d];bZh(d[0],d[1])&&(d[1]=e[1]),Zh(e[0],d[1])>Zh(d[0],d[1])&&(d[0]=e[0])):f.push(d=e);for(g=-(1/0),c=f.length-1,b=0,d=f[c];b<=c;d=e,++b)e=f[b],(h=Zh(d[1],e[0]))>g&&(g=h,au=e[0],cu=d[1])}return iu=ju=null,au===1/0||bu===1/0?[[NaN,NaN],[NaN,NaN]]:[[au,bu],[cu,du]]},dv={sphere:Dh,point:ai,lineStart:ci,lineEnd:fi,polygonStart:function(){dv.lineStart=gi,dv.lineEnd=hi},polygonEnd:function(){dv.lineStart=ci,dv.lineEnd=fi}},ev=function(a){ku=lu=mu=nu=ou=pu=qu=ru=su=tu=uu=0,Xu(a,dv);var b=su,c=tu,d=uu,e=b*b+c*c+d*d;return e2?a[2]*Iu:0),b.invert=function(b){return b=a.invert(b[0]*Iu,b[1]*Iu),b[0]*=Hu,b[1]*=Hu,b},b},tv=function(){function a(a,b){c.push(a=d(a,b)),a[0]*=Hu,a[1]*=Hu}function b(){var a=e.apply(this,arguments),b=f.apply(this,arguments)*Iu,i=g.apply(this,arguments)*Iu;return c=[],d=li(-a[0]*Iu,-a[1]*Iu,0).invert,pi(h,b,i,1),a={type:"Polygon",coordinates:[c]},c=d=null,a}var c,d,e=fv([0,0]),f=fv(90),g=fv(6),h={point:a};return b.center=function(a){return arguments.length?(e="function"==typeof a?a:fv([+a[0],+a[1]]),b):e},b.radius=function(a){return arguments.length?(f="function"==typeof a?a:fv(+a),b):f},b.precision=function(a){return arguments.length?(g="function"==typeof a?a:fv(+a),b):g},b},uv=function(){var a,b=[];return{point:function(b,c){a.push([b,c])},lineStart:function(){b.push(a=[])},lineEnd:Dh,rejoin:function(){b.length>1&&b.push(b.pop().concat(b.shift()))},result:function(){var c=b;return b=[],a=null,c}}},vv=function(a,b,c,d,e,f){var g,h=a[0],i=a[1],j=b[0],k=b[1],l=0,m=1,n=j-h,o=k-i;if(g=c-h,n||!(g>0)){if(g/=n,n<0){if(g0){if(g>m)return;g>l&&(l=g)}if(g=e-h,n||!(g<0)){if(g/=n,n<0){if(g>m)return;g>l&&(l=g)}else if(n>0){if(g0)){if(g/=o,o<0){if(g0){if(g>m)return;g>l&&(l=g)}if(g=f-i,o||!(g<0)){if(g/=o,o<0){if(g>m)return;g>l&&(l=g)}else if(o>0){if(g0&&(a[0]=h+l*n,a[1]=i+l*o),m<1&&(b[0]=h+m*n,b[1]=i+m*o),!0}}}}},wv=function(a,b){return Ju(a[0]-b[0])=0;--f)e.point((k=j[f])[0],k[1]);else d(m.x,m.p.x,-1,e);m=m.p}m=m.o,j=m.z,n=!n}while(!m.v);e.lineEnd()}}},yv=1e9,zv=-yv,Av=function(){var a,b,c,d=0,e=0,f=960,g=500;return c={stream:function(c){return a&&b===c?a:a=ti(d,e,f,g)(b=c)},extent:function(h){return arguments.length?(d=+h[0][0],e=+h[0][1],f=+h[1][0],g=+h[1][1],a=b=null,c):[[d,e],[f,g]]}}},Bv=Wt(),Cv={sphere:Dh,point:Dh,lineStart:ui,lineEnd:Dh,polygonStart:Dh,polygonEnd:Dh},Dv=function(a){return Bv.reset(),Xu(a,Cv),+Bv},Ev=[null,null],Fv={type:"LineString",coordinates:Ev},Gv=function(a,b){return Ev[0]=a,Ev[1]=b,Dv(Fv)},Hv=function(a,b){var c=a[0]*Iu,d=a[1]*Iu,e=b[0]*Iu,f=b[1]*Iu,g=Mu(d),h=Ru(d),i=Mu(f),j=Ru(f),k=g*Mu(c),l=g*Ru(c),m=i*Mu(e),n=i*Ru(e),o=2*Bh(Tu(Ch(f-d)+g*i*Ch(e-c))),p=Ru(o),q=o?function(a){var b=Ru(a*=o)/p,c=Ru(o-a)/p,d=c*k+b*m,e=c*l+b*n,f=c*h+b*j;return[Lu(e,d)*Hu,Lu(f,Tu(d*d+e*e))*Hu]}:function(){return[c*Hu,d*Hu]};return q.distance=o,q},Iv=function(a){return a},Jv=Wt(),Kv=Wt(),Lv={point:Dh,lineStart:Dh,lineEnd:Dh,polygonStart:function(){Lv.lineStart=Ci,Lv.lineEnd=Fi},polygonEnd:function(){Lv.lineStart=Lv.lineEnd=Lv.point=Dh,Jv.add(Ju(Kv)),Kv.reset()},result:function(){var a=Jv/2;return Jv.reset(),a}},Mv=1/0,Nv=Mv,Ov=-Mv,Pv=Ov,Qv={point:Gi,lineStart:Dh,lineEnd:Dh,polygonStart:Dh,polygonEnd:Dh,result:function(){var a=[[Mv,Nv],[Ov,Pv]];return Ov=Pv=-(Nv=Mv=1/0),a}},Rv=0,Sv=0,Tv=0,Uv=0,Vv=0,Wv=0,Xv=0,Yv=0,Zv=0,$v={point:Hi,lineStart:Ii,lineEnd:Li,polygonStart:function(){$v.lineStart=Mi,$v.lineEnd=Ni},polygonEnd:function(){$v.point=Hi,$v.lineStart=Ii,$v.lineEnd=Li},result:function(){var a=Zv?[Xv/Zv,Yv/Zv]:Wv?[Uv/Wv,Vv/Wv]:Tv?[Rv/Tv,Sv/Tv]:[NaN,NaN];return Rv=Sv=Tv=Uv=Vv=Wv=Xv=Yv=Zv=0,a}};Qi.prototype={_radius:4.5,pointRadius:function(a){return this._radius=a,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(a,b){switch(this._point){case 0:this._context.moveTo(a,b),this._point=1;break;case 1:this._context.lineTo(a,b);break;default:this._context.moveTo(a+this._radius,b),this._context.arc(a,b,this._radius,0,Gu)}},result:Dh},Ri.prototype={_circle:Si(4.5),pointRadius:function(a){return this._circle=Si(a),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(a,b){switch(this._point){case 0:this._string.push("M",a,",",b),this._point=1;break;case 1:this._string.push("L",a,",",b);break;default:this._string.push("M",a,",",b,this._circle)}},result:function(){if(this._string.length){var a=this._string.join("");return this._string=[],a}}};var _v=function(a,b){function c(a){return a&&("function"==typeof f&&e.pointRadius(+f.apply(this,arguments)),Xu(a,d(e))),e.result()}var d,e,f=4.5;return c.area=function(a){return Xu(a,d(Lv)),Lv.result()},c.bounds=function(a){return Xu(a,d(Qv)),Qv.result()},c.centroid=function(a){return Xu(a,d($v)),$v.result()},c.projection=function(b){return arguments.length?(d=null==b?(a=null,Iv):(a=b).stream,c):a},c.context=function(a){return arguments.length?(e=null==a?(b=null,new Ri):new Qi(b=a),"function"!=typeof f&&e.pointRadius(f),c):b},c.pointRadius=function(a){return arguments.length?(f="function"==typeof a?a:(e.pointRadius(+a),+a),c):f},c.projection(a).context(b)},aw=Wt(),bw=function(a,b){var c=b[0],d=b[1],e=[Ru(c),-Mu(c),0],f=0,g=0;aw.reset();for(var h=0,i=a.length;h=0?1:-1,y=x*w,z=y>Du,A=o*u;if(aw.add(Lu(A*x*Ru(y),p*v+A*Mu(y))),f+=z?w+x*Gu:w,z^m>=c^s>=c){var B=Oh(Mh(l),Mh(r));Rh(B);var C=Oh(e,B);Rh(C);var D=(z^w>=0?-1:1)*Bh(C[2]);(d>D||d===D&&(B[0]||B[1]))&&(g+=z^w>=0?1:-1)}}return(f<-Bu||f0){for(u||(f.polygonStart(),u=!0),f.lineStart(),a=0;a1&&2&e&&g.push(g.pop().concat(g.shift())),o.push(g.filter(Ti))}var n,o,p,q=b(f),r=e.invert(d[0],d[1]),s=uv(),t=b(s),u=!1,v={point:g,lineStart:i,lineEnd:j,polygonStart:function(){v.point=k,v.lineStart=l,v.lineEnd=m,o=[],n=[]},polygonEnd:function(){v.point=g,v.lineStart=i,v.lineEnd=j,o=Yj(o);var a=bw(n,r);o.length?(u||(f.polygonStart(),u=!0),xv(o,Ui,a,c,f)):a&&(u||(f.polygonStart(),u=!0),f.lineStart(),c(null,null,1,f),f.lineEnd()),u&&(f.polygonEnd(),u=!1),o=n=null},sphere:function(){f.polygonStart(),f.lineStart(),c(null,null,1,f),f.lineEnd(),f.polygonEnd()}};return v}},dw=cw(function(){return!0},Vi,Xi,[-Du,-Eu]),ew=function(a,b){function c(c,d,e,f){pi(f,a,b,e,c,d)}function d(a,b){return Mu(a)*Mu(b)>h}function e(a){var b,c,e,h,k;return{lineStart:function(){h=e=!1,k=1},point:function(l,m){var n,o=[l,m],p=d(l,m),q=i?p?0:g(l,m):p?g(l+(l<0?Du:-Du),m):0;if(!b&&(h=e=p)&&a.lineStart(),p!==e&&(n=f(b,o),(wv(b,n)||wv(o,n))&&(o[0]+=Bu,o[1]+=Bu,p=d(o[0],o[1]))),p!==e)k=0,p?(a.lineStart(),n=f(o,b),a.point(n[0],n[1])):(n=f(b,o),a.point(n[0],n[1]),a.lineEnd()),b=n;else if(j&&b&&i^p){var r;q&c||!(r=f(o,b,!0))||(k=0,i?(a.lineStart(),a.point(r[0][0],r[0][1]),a.point(r[1][0],r[1][1]),a.lineEnd()):(a.point(r[1][0],r[1][1]),a.lineEnd(),a.lineStart(),a.point(r[0][0],r[0][1])))}!p||b&&wv(b,o)||a.point(o[0],o[1]),b=o,e=p,c=q},lineEnd:function(){e&&a.lineEnd(),b=null},clean:function(){return k|(h&&e)<<1}}}function f(a,b,c){var d=Mh(a),e=Mh(b),f=[1,0,0],g=Oh(d,e),i=Nh(g,g),j=g[0],k=i-j*j;if(!k)return!c&&a;var l=h*i/k,m=-h*j/k,n=Oh(f,g),o=Qh(f,l),p=Qh(g,m);Ph(o,p);var q=n,r=Nh(o,q),s=Nh(q,q),t=r*r-s*(Nh(o,o)-1);if(!(t<0)){var u=Tu(t),v=Qh(q,(-r-u)/s);if(Ph(v,o),v=Lh(v),!c)return v;var w,x=a[0],y=b[0],z=a[1],A=b[1];y0^v[1]<(Ju(v[0]-x)Du^(x<=v[0]&&v[0]<=y)){var E=Qh(q,(-r+u)/s);return Ph(E,o),[v,Lh(E)]}}}function g(b,c){var d=i?a:Du-a,e=0;return b<-d?e|=1:b>d&&(e|=2),c<-d?e|=4:c>d&&(e|=8),e}var h=Mu(a),i=h>0,j=Ju(h)>Bu;return cw(d,e,c,i?[0,-a]:[-Du,a-Du])},fw=function(a){return{stream:Yi(a)}};Zi.prototype={constructor:Zi,point:function(a,b){this.stream.point(a,b)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var gw=16,hw=Mu(30*Iu),iw=function(a,b){return+b?bj(a,b):aj(a)},jw=Yi({point:function(a,b){this.stream.point(a*Iu,b*Iu)}}),kw=function(){return ej(gj).scale(155.424).center([0,33.6442])},lw=function(){return kw().parallels([29.5,45.5]).scale(1070).translate([480,250]).rotate([96,0]).center([-.6,38.7])},mw=function(){function a(a){var b=a[0],c=a[1];return h=null,e.point(b,c),h||(f.point(b,c),h)||(g.point(b,c),h)}function b(){return c=d=null,a}var c,d,e,f,g,h,i=lw(),j=kw().rotate([154,0]).center([-2,58.5]).parallels([55,65]),k=kw().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(a,b){h=[a,b]}};return a.invert=function(a){var b=i.scale(),c=i.translate(),d=(a[0]-c[0])/b,e=(a[1]-c[1])/b;return(e>=.12&&e<.234&&d>=-.425&&d<-.214?j:e>=.166&&e<.234&&d>=-.214&&d<-.115?k:i).invert(a)},a.stream=function(a){return c&&d===a?c:c=hj([i.stream(d=a),j.stream(a),k.stream(a)])},a.precision=function(a){return arguments.length?(i.precision(a),j.precision(a),k.precision(a),b()):i.precision()},a.scale=function(b){return arguments.length?(i.scale(b),j.scale(.35*b),k.scale(b),a.translate(i.translate())):i.scale()},a.translate=function(a){if(!arguments.length)return i.translate();var c=i.scale(),d=+a[0],h=+a[1];return e=i.translate(a).clipExtent([[d-.455*c,h-.238*c],[d+.455*c,h+.238*c]]).stream(l),f=j.translate([d-.307*c,h+.201*c]).clipExtent([[d-.425*c+Bu,h+.12*c+Bu],[d-.214*c-Bu,h+.234*c-Bu]]).stream(l),g=k.translate([d-.205*c,h+.212*c]).clipExtent([[d-.214*c+Bu,h+.166*c+Bu],[d-.115*c-Bu,h+.234*c-Bu]]).stream(l),b()},a.fitExtent=function(b,c){return $i(a,b,c)},a.fitSize=function(b,c){return _i(a,b,c)},a.scale(1070)},nw=ij(function(a){return Tu(2/(1+a))});nw.invert=jj(function(a){return 2*Bh(a/2)});var ow=function(){return cj(nw).scale(124.75).clipAngle(179.999)},pw=ij(function(a){return(a=Ah(a))&&a/Ru(a)});pw.invert=jj(function(a){return a});var qw=function(){return cj(pw).scale(79.4188).clipAngle(179.999)};kj.invert=function(a,b){return[a,2*Ku(Ou(b))-Eu]};var rw=function(){return lj(kj).scale(961/Gu)},sw=function(){return ej(nj).scale(109.5).parallels([30,30])};oj.invert=oj;var tw=function(){return cj(oj).scale(152.63)},uw=function(){return ej(pj).scale(131.154).center([0,13.9389])};qj.invert=jj(Ku);var vw=function(){return cj(qj).scale(144.049).clipAngle(60)},ww=function(){function a(){return e=f=null,g}var b,c,d,e,f,g,h=1,i=0,j=0,k=1,l=1,m=Iv,n=null,o=Iv;return g={stream:function(a){return e&&f===a?e:e=m(o(f=a))},clipExtent:function(e){return arguments.length?(o=null==e?(n=b=c=d=null,Iv):ti(n=+e[0][0],b=+e[0][1],c=+e[1][0],d=+e[1][1]),a()):null==n?null:[[n,b],[c,d]]},scale:function(b){return arguments.length?(m=rj((h=+b)*k,h*l,i,j),a()):h},translate:function(b){return arguments.length?(m=rj(h*k,h*l,i=+b[0],j=+b[1]),a()):[i,j]},reflectX:function(b){return arguments.length?(m=rj(h*(k=b?-1:1),h*l,i,j),a()):k<0},reflectY:function(b){return arguments.length?(m=rj(h*k,h*(l=b?-1:1),i,j),a()):l<0},fitExtent:function(a,b){return $i(g,a,b)},fitSize:function(a,b){return _i(g,a,b)}}};sj.invert=jj(Bh);var xw=function(){return cj(sj).scale(249.5).clipAngle(90+Bu)};tj.invert=jj(function(a){return 2*Ku(a)});var yw=function(){return cj(tj).scale(250).clipAngle(142)};uj.invert=function(a,b){return[-b,2*Ku(Ou(a))-Eu]};var zw=function(){var a=lj(uj),b=a.center,c=a.rotate;return a.center=function(a){return arguments.length?b([-a[1],a[0]]):(a=b(),[a[1],-a[0]])},a.rotate=function(a){return arguments.length?c([a[0],a[1],a.length>2?a[2]+90:90]):(a=c(),[a[0],a[1],a[2]-90])},c([0,0,90]).scale(159.155)};a.version=vj,a.bisect=zj,a.bisectRight=zj,a.bisectLeft=Aj,a.ascending=wj,a.bisector=xj,a.descending=Bj,a.deviation=Ej,a.extent=Fj,a.histogram=Rj,a.thresholdFreedmanDiaconis=Tj,a.thresholdScott=Uj,a.thresholdSturges=Qj,a.max=Vj,a.mean=Wj,a.median=Xj,a.merge=Yj,a.min=Zj,a.pairs=$j,a.permute=_j,a.quantile=Sj,a.range=Lj,a.scan=ak,a.shuffle=bk,a.sum=ck,a.ticks=Pj,a.tickStep=c,a.transpose=dk,a.variance=Dj,a.zip=ek,a.entries=kk,a.keys=ik,a.values=jk,a.map=f,a.set=l,a.nest=gk,a.randomUniform=lk,a.randomNormal=mk,a.randomLogNormal=nk,a.randomBates=pk,a.randomIrwinHall=ok,a.randomExponential=qk,a.easeLinear=m,a.easeQuad=p,a.easeQuadIn=n,a.easeQuadOut=o,a.easeQuadInOut=p,a.easeCubic=s,a.easeCubicIn=q,a.easeCubicOut=r,a.easeCubicInOut=s,a.easePoly=uk,a.easePolyIn=sk,a.easePolyOut=tk,a.easePolyInOut=uk,a.easeSin=v,a.easeSinIn=t,a.easeSinOut=u,a.easeSinInOut=v,a.easeExp=y,a.easeExpIn=w,a.easeExpOut=x,a.easeExpInOut=y,a.easeCircle=B,a.easeCircleIn=z,a.easeCircleOut=A,a.easeCircleInOut=B,a.easeBounce=D,a.easeBounceIn=C,a.easeBounceOut=D,a.easeBounceInOut=E,a.easeBack=Kk,a.easeBackIn=Ik,a.easeBackOut=Jk,a.easeBackInOut=Kk,a.easeElastic=Pk,a.easeElasticIn=Ok,a.easeElasticOut=Pk,a.easeElasticInOut=Qk,a.polygonArea=Rk,a.polygonCentroid=Sk,a.polygonHull=Uk,a.polygonContains=Vk,a.polygonLength=Wk,a.path=I,a.quadtree=O,a.queue=X,a.arc=ul,a.area=xl,a.line=wl,a.pie=Al,a.radialArea=Dl,a.radialLine=Cl,a.symbol=Xl,a.symbols=Wl,a.symbolCircle=El,a.symbolCross=Fl,a.symbolDiamond=Il,a.symbolSquare=Ol,a.symbolStar=Nl,a.symbolTriangle=Ql,a.symbolWye=Vl,a.curveBasisClosed=$l,a.curveBasisOpen=_l,a.curveBasis=Zl,a.curveBundle=am,a.curveCardinalClosed=cm,a.curveCardinalOpen=dm,a.curveCardinal=bm,a.curveCatmullRomClosed=fm,a.curveCatmullRomOpen=gm,a.curveCatmullRom=em,a.curveLinearClosed=hm,a.curveLinear=vl,a.curveMonotoneX=Fa,a.curveMonotoneY=Ga,a.curveNatural=im,a.curveStep=jm,a.curveStepAfter=La,a.curveStepBefore=Ka,a.stack=nm,a.stackOffsetExpand=om,a.stackOffsetNone=lm,a.stackOffsetSilhouette=pm,a.stackOffsetWiggle=qm,a.stackOrderAscending=rm,a.stackOrderDescending=sm,a.stackOrderInsideOut=tm,a.stackOrderNone=mm,a.stackOrderReverse=um,a.color=Qa,a.rgb=Ua,a.hsl=Ya,a.lab=ab,a.hcl=hb,a.cubehelix=kb,a.interpolate=sn,a.interpolateArray=ln,a.interpolateDate=mn,a.interpolateNumber=nn,a.interpolateObject=on,a.interpolateRound=tn,a.interpolateString=rn,a.interpolateTransformCss=xn,a.interpolateTransformSvg=yn,a.interpolateZoom=Dn,a.interpolateRgb=hn,a.interpolateRgbBasis=jn,a.interpolateRgbBasisClosed=kn,a.interpolateHsl=En,a.interpolateHslLong=Fn,a.interpolateLab=Cb,a.interpolateHcl=Gn,a.interpolateHclLong=Hn,a.interpolateCubehelix=In,a.interpolateCubehelixLong=Jn,a.interpolateBasis=en,a.interpolateBasisClosed=fn,a.quantize=Kn,a.dispatch=Fb,a.dsvFormat=On,a.csvParse=Qn,a.csvParseRows=Rn,a.csvFormat=Sn,a.csvFormatRows=Tn,a.tsvParse=Vn,a.tsvParseRows=Wn,a.tsvFormat=Xn,a.tsvFormatRows=Yn,a.request=Zn,a.html=_n,a.json=ao,a.text=bo,a.xml=co,a.csv=fo,a.tsv=go,a.now=Qb,a.timer=Tb,a.timerFlush=Ub,a.timeout=qo,a.interval=ro,a.timeInterval=Zb,a.timeMillisecond=uo,a.timeMilliseconds=vo,a.timeSecond=Bo,a.timeSeconds=Co,a.timeMinute=Do,a.timeMinutes=Eo,a.timeHour=Fo,a.timeHours=Go,a.timeDay=Ho,a.timeDays=Io,a.timeWeek=Jo,a.timeWeeks=Qo,a.timeSunday=Jo,a.timeSundays=Qo,a.timeMonday=Ko,a.timeMondays=Ro,a.timeTuesday=Lo,a.timeTuesdays=So;a.timeWednesday=Mo;a.timeWednesdays=To,a.timeThursday=No,a.timeThursdays=Uo,a.timeFriday=Oo,a.timeFridays=Vo,a.timeSaturday=Po,a.timeSaturdays=Wo,a.timeMonth=Xo,a.timeMonths=Yo,a.timeYear=Zo,a.timeYears=$o,a.utcMillisecond=uo,a.utcMilliseconds=vo,a.utcSecond=Bo,a.utcSeconds=Co,a.utcMinute=_o,a.utcMinutes=ap,a.utcHour=bp,a.utcHours=cp,a.utcDay=dp,a.utcDays=ep,a.utcWeek=fp,a.utcWeeks=mp,a.utcSunday=fp,a.utcSundays=mp,a.utcMonday=gp,a.utcMondays=np,a.utcTuesday=hp,a.utcTuesdays=op,a.utcWednesday=ip,a.utcWednesdays=pp,a.utcThursday=jp,a.utcThursdays=qp,a.utcFriday=kp,a.utcFridays=rp,a.utcSaturday=lp,a.utcSaturdays=sp,a.utcMonth=tp,a.utcMonths=up,a.utcYear=vp,a.utcYears=xp,a.formatLocale=Jp,a.formatDefaultLocale=cc,a.formatSpecifier=Gp,a.precisionFixed=Lp,a.precisionPrefix=Mp,a.precisionRound=Np,a.isoFormat=Tp,a.isoParse=Up,a.timeFormatLocale=gc,a.timeFormatDefaultLocale=ad,a.scaleBand=ed,a.scalePoint=gd,a.scaleIdentity=qd,a.scaleLinear=pd,a.scaleLog=xd,a.scaleOrdinal=dd,a.scaleImplicit=Yp,a.scalePow=zd,a.scaleSqrt=Ad,a.scaleQuantile=Bd,a.scaleQuantize=Cd,a.scaleThreshold=Dd,a.scaleTime=jq,a.scaleUtc=kq,a.schemeCategory10=mq,a.schemeCategory20b=nq,a.schemeCategory20c=oq,a.schemeCategory20=pq,a.scaleSequential=Id,a.interpolateCubehelixDefault=qq,a.interpolateRainbow=uq,a.interpolateWarm=rq,a.interpolateCool=sq,a.interpolateViridis=vq,a.interpolateMagma=wq,a.interpolateInferno=xq,a.interpolatePlasma=yq,a.creator=Cq,a.customEvent=Sd,a.local=Ld,a.matcher=Hq,a.mouse=Nq,a.namespace=Bq,a.namespaces=Aq,a.select=vr,a.selectAll=wr,a.selection=Fe,a.selector=Oq,a.selectorAll=Qq,a.touch=xr,a.touches=yr,a.window=hr,a.active=hs,a.interrupt=Jr,a.transition=kf,a.axisTop=sf,a.axisRight=tf,a.axisBottom=uf,a.axisLeft=vf,a.cluster=ps,a.hierarchy=Ef,a.pack=Es,a.packSiblings=Cs,a.packEnclose=Bs,a.partition=Hs,a.stratify=Ls,a.tree=Ms,a.treemap=Qs,a.treemapBinary=Rs,a.treemapDice=Gs,a.treemapSlice=Ns,a.treemapSliceDice=Ss,a.treemapSquarify=Ps,a.treemapResquarify=Ts,a.forceCenter=Us,a.forceCollide=Xs,a.forceLink=Ys,a.forceManyBody=at,a.forceSimulation=_s,a.forceX=bt,a.forceY=ct,a.drag=gt,a.dragDisable=et,a.dragEnable=sg,a.voronoi=rt,a.zoom=vt,a.zoomIdentity=tt,a.zoomTransform=dh,a.brush=Lt,a.brushX=ph,a.brushY=qh,a.brushSelection=oh,a.chord=St,a.ribbon=Vt,a.geoAlbers=lw,a.geoAlbersUsa=mw,a.geoArea=_u,a.geoAzimuthalEqualArea=ow,a.geoAzimuthalEqualAreaRaw=nw,a.geoAzimuthalEquidistant=qw,a.geoAzimuthalEquidistantRaw=pw,a.geoBounds=cv,a.geoCentroid=ev,a.geoCircle=tv,a.geoClipExtent=Av,a.geoConicConformal=sw,a.geoConicConformalRaw=nj,a.geoConicEqualArea=kw,a.geoConicEqualAreaRaw=gj,a.geoConicEquidistant=uw,a.geoConicEquidistantRaw=pj,a.geoDistance=Gv,a.geoEquirectangular=tw,a.geoEquirectangularRaw=oj,a.geoGnomonic=vw,a.geoGnomonicRaw=qj,a.geoGraticule=Ai,a.geoGraticule10=Bi,a.geoIdentity=ww,a.geoInterpolate=Hv,a.geoLength=Dv,a.geoMercator=rw,a.geoMercatorRaw=kj,a.geoOrthographic=xw,a.geoOrthographicRaw=sj,a.geoPath=_v,a.geoProjection=cj,a.geoProjectionMutator=dj,a.geoRotation=sv,a.geoStereographic=yw,a.geoStereographicRaw=tj,a.geoStream=Xu,a.geoTransform=fw,a.geoTransverseMercator=zw,a.geoTransverseMercatorRaw=uj,Object.defineProperty(a,"__esModule",{value:!0})})},{}],2:[function(a,b,c){!function(){"use strict";function c(a,b,c){var f={minValue:"auto",maxValue:"auto",zeroLineStyle:"stroke:#333;stroke-width:1;"};e.call(this,a,b,c,f);var g=d.scaleLinear().domain([this._options.minValue,this._options.maxValue]).range([this._options.height,0]);this._zeroLine=this._container.append("line").attr("x1",0).attr("y1",g(0)).attr("x2",this._options.width).attr("y2",g(0)).attr("style",this._options.zeroLineStyle),this._draw()}var d=a("d3"),e=a("./chart.js");b.exports=c,c.prototype=Object.create(e.prototype),c.prototype.constructor=c,c.prototype._processOptions=function(a){if(a=e.prototype._processOptions.call(this,a,this._options),"auto"===a.minValue){var b=d.min(this._data),c="auto"===a.maxValue?d.max(this._data):a.maxValue;c>0&&b>0?a.minValue=0:a.minValue=b}if("auto"===a.maxValue){var c="auto"===a.minValue?d.min(this._data):a.minValue,c=d.max(this._data);c<0&&b<0?a.maxValue=0:a.maxValue=c}return a},c.prototype._draw=function(){function a(a,b,c,d){return"M"+a+" "+b+"l"+c+" 0l0 "+d+"l"+-c+" 0Z"}function b(a,b,c){a.fillRect(c*g+3,h(0),g,0,f._options.labelPadding,"center",b>=0?"top":"bottom",0)}function c(a,b,c){a.fillRect(c*g+3,h(b>=0?b:0),g,Math.abs(h(b)-h(0)),f._options.labelPadding,"center",b>=0?"top":"bottom",f._options.transitionTime)}var f=this;e.prototype._draw.call(this);var g=(f._options.width-6)/f._data.length,h=d.scaleLinear().domain([f._options.minValue,f._options.maxValue]).range([f._options.height,0]);f._zeroLine.transition().duration(f._options.transitionTime).attr("x1",0).attr("y1",h(0)).attr("x2",f._options.width).attr("y2",h(0)).attr("style",f._options.zeroLineStyle);var i=f._chart.selectAll("path").data(f._data);i.enter().append("path").attr("d",function(b,c){return a((c+1)*g+3,h(0),0,0)}).merge(i).attr("class",f._options.shapeClass).transition().duration(f._options.transitionTime).attr("d",function(b,c){return a(c*g+3,h(0),g,h(b)-h(0))}).attr("fill",f._options.colorFun),i.exit().transition().duration(f._options.transitionTime).attr("x",function(a,b){return b*g+3}).attr("y",0).attr("width",0).attr("height",0).remove(),this._drawLabels(b,c)}}()},{"./chart.js":3,d3:1}],3:[function(a,b,c){!function(){"use strict";function c(a,b,c,e){this._data=b,this._options={width:60,height:60,transitionTime:750,colors:d.schemeCategory10,labels:"none",labelColors:"auto",labelMinSize:8,labelMaxSize:24,labelPadding:2,labelClass:"",shapeClass:""},this._options=f.mergeOptions(this._options,e||{}),this._options=this._processOptions(c),d.select(a).select("*").remove(),this._container=d.select(a).append("svg").attr("width",this._options.width).attr("height",this._options.height),this._chart=this._container.append("g")}var d=a("d3"),e=a("tinycolor2"),f=a("./utils.js"),g=a("./label.js");b.exports=c,c.prototype.update=function(a,b){this._data=a,this._options=this._processOptions(b),this._draw()},c.prototype.setOptions=function(a){this._options=this._processOptions(a),this._draw()},c.prototype.setData=function(a){this._data=a,this._draw()},c.prototype._draw=function(){var a=this;a._container.transition().duration(a._options.transitionTime).attr("width",a._options.width).attr("height",a._options.height)},c.prototype._processOptions=function(a){return a=f.mergeOptions(a,this._options),a.colorFun=f.toFunction(a.colors),a.labelClass=f.toFunction(a.labelClass),a.shapeClass=f.toFunction(a.shapeClass),"none"===a.labels?a.labelText=null:"auto"===a.labels?a.labelText=f.prettyNumber:a.labelText=f.toFunction(a.labels),"auto"===a.labelColors?a.labelColorFun=function(b,c){return e.mostReadable(a.colorFun(b,c),["white","black"])._originalInput}:a.labelColorFun=f.toFunction(a.labelColorFun),a},c.prototype._drawLabels=function(a,b){var c=this;return"none"===c._options.labels?void c._chart.selectAll(".labels-container").remove():(c._labels=c._chart.selectAll(".labels-container").data(c._data),c._labels.enter().append("g").attr("class","labels-container").each(function(b,d){this._label=new g(this,c._options.labelStyle,c._options.labelColorFun(b,d),c._options.labelMinSize,c._options.labelMaxSize),this._label.updateText(c._options.labelText(b,d)),a(this._label,b,d)}).merge(c._labels).each(function(a,d){this._label.updateText(c._options.labelText(a,d)),this._label._text.attr("fill",c._options.labelColorFun(a,d)).attr("class",c._options.labelClass(a,d)),b(this._label,a,d)}),void c._labels.exit().remove())}}()},{"./label.js":5,"./utils.js":9,d3:1,tinycolor2:10}],4:[function(a,b,c){!function(){"use strict";function a(a,b){this.x=a,this.y=b}function c(a,b){this.a=a,this.b=b}function d(b,c){return b.b==c.b?[]:[new a((c.a-b.a)/(b.b-c.b),(b.b*c.a-b.a*c.b)/(b.b-c.b))]}function e(b,e,f){var h=new c(0,Math.tan(e)),i=d(b,h),j=new a(0,0),k=new a(f*Math.cos(e),f*Math.sin(e));return 0!=i.length&&g(i[0],j,k)?i:[]}function f(b,c){var d=j(b.b*b.b+1,2*b.a*b.b,b.a*b.a-c*c);return d.map(function(c){return new a(c,b.getY(c))})}function g(a,b,c){var d=i(h(c,b),h(a,b)),e=i(h(c,b),h(c,b));return d>=0&&d<=e}function h(b,c){return new a(b.x-c.x,b.y-c.y)}function i(a,b){return a.x*b.x+a.y*b.y}function j(a,b,c){var d=b*b-4*a*c;return d<0?[]:0==d?[-b/(2*a)]:[(-b-Math.sqrt(d))/(2*a),(-b+Math.sqrt(d))/(2*a)]}function k(a,b){return Math.sqrt(Math.pow(a.x-b.x,2)+Math.pow(a.y-b.y,2))}b.exports.Point=a,b.exports.Line=c,b.exports.intersectionOfTwoLines=d,b.exports.intersectionLineAndCircle=f,b.exports.pointInSegment=g,b.exports.intersectionLineRadius=e,b.exports.distance=k,c.prototype.getY=function(a){return this.a+this.b*a}}()},{}],5:[function(a,b,c){!function(){"use strict";function c(a,b,c,e,f){this._el=a,this._minSize=e,this._maxSize=f,this._container=d.select(a),this._label=this._container.append("g").attr("class","label"),this._text=this._label.append("text").attr("dy","0.35em").attr("text-anchor","middle").attr("style",b||"").attr("fill",c||"black")}var d=a("d3"),e=a("./geometry.js");b.exports=c,c.prototype.innerSize=function(){return this._text.node().getBBox()},c.prototype.size=function(){var a=this.innerSize();return{width:a.width*this._scale,height:a.height*this._scale}},c.prototype.updateText=function(a){var b=this.size();this._text.text(a);var c=this.size(),d=Math.min(b.width/c.width,b.height/c.height);return this.updateScale(this._scale*d,0),this},c.prototype.updatePosition=function(a,b,c){return this._container.transition().duration(c||0).attr("transform","translate("+a+","+b+")"),this},c.prototype.updateScale=function(a,b){a&&!isNaN(a)&&isFinite(a)||(a=0);var c=this.innerSize().height*a;return this._minSize&&cthis._maxSize&&(a=this._maxSize/this.innerSize().height),this._label.transition().duration(b||0).attr("transform","scale("+a+")"),this._scale=a,this},c.prototype.fillRect=function(a,b,c,d,e,f,g,h){var i=this.innerSize();this.updateScale(Math.min((c-2*e)/i.width,Math.abs(d)/i.height),h);var j,k,l=this.size();switch(g){case"top":k=b+l.height/2;break;case"center":k=b+d/2;break;case"bottom":k=b+d-l.height/2}switch(f){case"left":j=a+e+l.width/2;break;case"center":j=a+c/2;break;case"right":j=a+c-e-l.width/2}return this.updatePosition(j,k,h),this},c.prototype.fillCircle=function(a,b){this.updatePosition(0,0,b);var c=this.innerSize(),d=c.height/c.width,e=2*a*Math.cos(Math.PI/2-Math.atan(d));this.updateScale(e/c.height,b)},c.prototype.fillSlice=function(a,b,c,f){var g=a.centroid(c);this.updatePosition(g[0],g[1],f);var h=this.innerSize(),i=h.height/h.width,j=new e.Line(g[1]-i*g[0],i),k=new e.Line(g[1]+i*g[0],-i),l=(new e.Line(0,Math.tan(c.startAngle+Math.PI/2)),new e.Line(0,Math.tan(c.endAngle+Math.PI/2)),[]);l=l.concat(e.intersectionLineRadius(j,c.startAngle-Math.PI/2,b)),l=l.concat(e.intersectionLineRadius(j,c.endAngle-Math.PI/2,b)),l=l.concat(e.intersectionLineAndCircle(j,b)),l=l.concat(e.intersectionLineRadius(k,c.startAngle-Math.PI/2,b)),l=l.concat(e.intersectionLineRadius(k,c.endAngle-Math.PI/2,b)),l=l.concat(e.intersectionLineAndCircle(k,b));var m=new e.Point(g[0],g[1]),n=l.map(function(a){return e.distance(m,a)}),o=d.min(n),p=Math.sqrt(Math.pow(h.height/2,2)+Math.pow(h.width/2,2));this.updateScale(o/p,f)}}()},{"./geometry.js":4,d3:1}],6:[function(a,b,c){!function(){"use strict";b.exports.Barchart=a("./barchart.js"),b.exports.Polarchart=a("./polarchart.js"),b.exports.Piechart=a("./piechart.js"),window&&(window.minicharts=b.exports)}()},{"./barchart.js":2,"./piechart.js":7,"./polarchart.js":8}],7:[function(a,b,c){!function(){"use strict";function c(a,b,c){d.call(this,a,b,c)}var d=a("./polarchart.js");b.exports=c,c.prototype=Object.create(d.prototype),c.prototype.constructor=c,c.prototype._processOptions=function(a){return a=a||{},a.type="angle",d.prototype._processOptions.call(this,a)}}()},{"./polarchart.js":8}],8:[function(a,b,c){!function(){"use strict";function c(a,b,c){var d={type:"area",maxValue:"auto"};e.call(this,a,b,c,d),this._chart.attr("transform","translate("+this._options.width/2+","+this._options.width/2+")"),this._draw()}var d=a("d3"),e=a("./chart.js");b.exports=c,c.prototype=Object.create(e.prototype),c.prototype.constructor=c,c.prototype._processOptions=function(a){a=e.prototype._processOptions.call(this,a,this._options),a.height=a.width,"auto"===a.maxValue&&(a.maxValue=d.max(this._data));var b,c=a.width/2,f=d.pie().sort(null),g=d.arc().innerRadius(0);return"angle"===a.type?(b=function(a){return c},f.value(function(a){return a})):(b="radius"==a.type?d.scaleLinear():d.scalePow().exponent(.5),b.range([0,c]).domain([0,a.maxValue]),f.value(function(a){return 1})),g.outerRadius(function(a,c){return b(a.data)}),a.radius=b,a.pie=f,a.arc=g,a},c.prototype._draw=function(){function a(a){var c=d.interpolate(this._current,a);return this._current=c(0),function(a){return b._options.arc(c(a))}}var b=this;e.prototype._draw.call(this),this._chart.transition().duration(b._options.transitionTime).attr("transform","translate("+b._options.width/2+","+b._options.width/2+")");var c=this._chart.selectAll("path").data(this._options.pie(this._data));c.enter().append("path").attr("class","leaflet-clickable").attr("d",this._options.arc).attr("fill",function(a,c){return b._options.colorFun(a,c)}).each(function(a,c){1==b._data.length?this._current={startAngle:a.startAngle,endAngle:a.endAngle,data:0}:this._current={startAngle:a.endAngle,endAngle:a.endAngle}}).merge(c).attr("class",function(a,c){ -return b._options.shapeClass(a.data,c)}).transition().duration(b._options.transitionTime).attrTween("d",a).attr("fill",function(a,c){return b._options.colorFun(a,c)}),c.exit().remove();var f,g;if(this._data.length>1){var h=this._options.pie(this._data);f=function(a,c,d){a.fillSlice(b._options.arc,b._options.radius(c),h[d],0)},g=function(a,c,d){a.fillSlice(b._options.arc,b._options.radius(c),h[d],b._options.transitionTime)}}else f=function(a,c,d){a.fillCircle(b._options.radius(c),0)},g=function(a,c,d){a.fillCircle(b._options.radius(c),b._options.transitionTime)};this._drawLabels(f,g)}}()},{"./chart.js":3,d3:1}],9:[function(a,b,c){!function(){"use strict";function a(a,b){a=a?JSON.parse(JSON.stringify(a)):{},b=b||{};for(var c in b)b.hasOwnProperty(c)&&!a.hasOwnProperty(c)&&(a[c]=b[c]);return a}function c(a){return a.constructor!==Array&&(a=[a]),a}function d(a){return"function"==typeof a?a:(a=c(a),function(b,c){return a[c%a.length]})}function e(a){if(isNaN(a)||!isFinite(a))return"";var b,c=Math.abs(a),d=a<0?"-":"";return c<1e3?b="":c<1e6?(b="K",c/=1e3):c<1e9?(b="M",c/=1e6):c<1e12?(b="B",c/=1e9):c<1e15&&(b="T",c/=1e12),c=c>10?f(c):c>1?f(c,10,!0):f(c,100,!0),d+c+b}function f(a,b,c){return b=b||1,c?Math.round(a*b)/b:Math.round(a/b)*b}b.exports.mergeOptions=a,b.exports.toArray=c,b.exports.toFunction=d,b.exports.prettyNumber=e}()},{}],10:[function(a,b,c){!function(a){function c(a,b){if(a=a?a:"",b=b||{},a instanceof c)return a;if(!(this instanceof c))return new c(a,b);var e=d(a);this._originalInput=a,this._r=e.r,this._g=e.g,this._b=e.b,this._a=e.a,this._roundA=Q(100*this._a)/100,this._format=b.format||e.format,this._gradientType=b.gradientType,this._r<1&&(this._r=Q(this._r)),this._g<1&&(this._g=Q(this._g)),this._b<1&&(this._b=Q(this._b)),this._ok=e.ok,this._tc_id=P++}function d(a){var b={r:0,g:0,b:0},c=1,d=null,f=null,h=null,j=!1,k=!1;return"string"==typeof a&&(a=L(a)),"object"==typeof a&&(K(a.r)&&K(a.g)&&K(a.b)?(b=e(a.r,a.g,a.b),j=!0,k="%"===String(a.r).substr(-1)?"prgb":"rgb"):K(a.h)&&K(a.s)&&K(a.v)?(d=H(a.s),f=H(a.v),b=i(a.h,d,f),j=!0,k="hsv"):K(a.h)&&K(a.s)&&K(a.l)&&(d=H(a.s),h=H(a.l),b=g(a.h,d,h),j=!0,k="hsl"),a.hasOwnProperty("a")&&(c=a.a)),c=A(c),{ok:j,format:a.format||k,r:R(255,S(b.r,0)),g:R(255,S(b.g,0)),b:R(255,S(b.b,0)),a:c}}function e(a,b,c){return{r:255*B(a,255),g:255*B(b,255),b:255*B(c,255)}}function f(a,b,c){a=B(a,255),b=B(b,255),c=B(c,255);var d,e,f=S(a,b,c),g=R(a,b,c),h=(f+g)/2;if(f==g)d=e=0;else{var i=f-g;switch(e=h>.5?i/(2-f-g):i/(f+g),f){case a:d=(b-c)/i+(b1&&(c-=1),c<1/6?a+6*(b-a)*c:c<.5?b:c<2/3?a+(b-a)*(2/3-c)*6:a}var e,f,g;if(a=B(a,360),b=B(b,100),c=B(c,100),0===b)e=f=g=c;else{var h=c<.5?c*(1+b):c+b-c*b,i=2*c-h;e=d(i,h,a+1/3),f=d(i,h,a),g=d(i,h,a-1/3)}return{r:255*e,g:255*f,b:255*g}}function h(a,b,c){a=B(a,255),b=B(b,255),c=B(c,255);var d,e,f=S(a,b,c),g=R(a,b,c),h=f,i=f-g;if(e=0===f?0:i/f,f==g)d=0;else{switch(f){case a:d=(b-c)/i+(b>1)+720)%360;--b;)e.h=(e.h+f)%360,g.push(c(e));return g}function y(a,b){b=b||6;for(var d=c(a).toHsv(),e=d.h,f=d.s,g=d.v,h=[],i=1/b;b--;)h.push(c({h:e,s:f,v:g})),g=(g+i)%1;return h}function z(a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[a[c]]=c);return b}function A(a){return a=parseFloat(a),(isNaN(a)||a<0||a>1)&&(a=1),a}function B(b,c){E(b)&&(b="100%");var d=F(b);return b=R(c,S(0,parseFloat(b))),d&&(b=parseInt(b*c,10)/100),a.abs(b-c)<1e-6?1:b%c/parseFloat(c)}function C(a){return R(1,S(0,a))}function D(a){return parseInt(a,16)}function E(a){return"string"==typeof a&&a.indexOf(".")!=-1&&1===parseFloat(a)}function F(a){return"string"==typeof a&&a.indexOf("%")!=-1}function G(a){return 1==a.length?"0"+a:""+a}function H(a){return a<=1&&(a=100*a+"%"),a}function I(b){return a.round(255*parseFloat(b)).toString(16)}function J(a){return D(a)/255}function K(a){return!!W.CSS_UNIT.exec(a)}function L(a){a=a.replace(N,"").replace(O,"").toLowerCase();var b=!1;if(U[a])a=U[a],b=!0;else if("transparent"==a)return{r:0,g:0,b:0,a:0,format:"name"};var c;return(c=W.rgb.exec(a))?{r:c[1],g:c[2],b:c[3]}:(c=W.rgba.exec(a))?{r:c[1],g:c[2],b:c[3],a:c[4]}:(c=W.hsl.exec(a))?{h:c[1],s:c[2],l:c[3]}:(c=W.hsla.exec(a))?{h:c[1],s:c[2],l:c[3],a:c[4]}:(c=W.hsv.exec(a))?{h:c[1],s:c[2],v:c[3]}:(c=W.hsva.exec(a))?{h:c[1],s:c[2],v:c[3],a:c[4]}:(c=W.hex8.exec(a))?{r:D(c[1]),g:D(c[2]),b:D(c[3]),a:J(c[4]),format:b?"name":"hex8"}:(c=W.hex6.exec(a))?{r:D(c[1]),g:D(c[2]),b:D(c[3]),format:b?"name":"hex"}:(c=W.hex4.exec(a))?{r:D(c[1]+""+c[1]),g:D(c[2]+""+c[2]),b:D(c[3]+""+c[3]),a:J(c[4]+""+c[4]),format:b?"name":"hex8"}:!!(c=W.hex3.exec(a))&&{r:D(c[1]+""+c[1]),g:D(c[2]+""+c[2]),b:D(c[3]+""+c[3]),format:b?"name":"hex"}}function M(a){var b,c;return a=a||{level:"AA",size:"small"},b=(a.level||"AA").toUpperCase(),c=(a.size||"small").toLowerCase(),"AA"!==b&&"AAA"!==b&&(b="AA"),"small"!==c&&"large"!==c&&(c="small"),{level:b,size:c}}var N=/^\s+/,O=/\s+$/,P=0,Q=a.round,R=a.min,S=a.max,T=a.random;c.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var a=this.toRgb();return(299*a.r+587*a.g+114*a.b)/1e3},getLuminance:function(){var b,c,d,e,f,g,h=this.toRgb();return b=h.r/255,c=h.g/255,d=h.b/255,e=b<=.03928?b/12.92:a.pow((b+.055)/1.055,2.4),f=c<=.03928?c/12.92:a.pow((c+.055)/1.055,2.4),g=d<=.03928?d/12.92:a.pow((d+.055)/1.055,2.4),.2126*e+.7152*f+.0722*g},setAlpha:function(a){return this._a=A(a),this._roundA=Q(100*this._a)/100,this},toHsv:function(){var a=h(this._r,this._g,this._b);return{h:360*a.h,s:a.s,v:a.v,a:this._a}},toHsvString:function(){var a=h(this._r,this._g,this._b),b=Q(360*a.h),c=Q(100*a.s),d=Q(100*a.v);return 1==this._a?"hsv("+b+", "+c+"%, "+d+"%)":"hsva("+b+", "+c+"%, "+d+"%, "+this._roundA+")"},toHsl:function(){var a=f(this._r,this._g,this._b);return{h:360*a.h,s:a.s,l:a.l,a:this._a}},toHslString:function(){var a=f(this._r,this._g,this._b),b=Q(360*a.h),c=Q(100*a.s),d=Q(100*a.l);return 1==this._a?"hsl("+b+", "+c+"%, "+d+"%)":"hsla("+b+", "+c+"%, "+d+"%, "+this._roundA+")"},toHex:function(a){return j(this._r,this._g,this._b,a)},toHexString:function(a){return"#"+this.toHex(a)},toHex8:function(a){return k(this._r,this._g,this._b,this._a,a)},toHex8String:function(a){return"#"+this.toHex8(a)},toRgb:function(){return{r:Q(this._r),g:Q(this._g),b:Q(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+Q(this._r)+", "+Q(this._g)+", "+Q(this._b)+")":"rgba("+Q(this._r)+", "+Q(this._g)+", "+Q(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:Q(100*B(this._r,255))+"%",g:Q(100*B(this._g,255))+"%",b:Q(100*B(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+Q(100*B(this._r,255))+"%, "+Q(100*B(this._g,255))+"%, "+Q(100*B(this._b,255))+"%)":"rgba("+Q(100*B(this._r,255))+"%, "+Q(100*B(this._g,255))+"%, "+Q(100*B(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(V[j(this._r,this._g,this._b,!0)]||!1)},toFilter:function(a){var b="#"+l(this._r,this._g,this._b,this._a),d=b,e=this._gradientType?"GradientType = 1, ":"";if(a){var f=c(a);d="#"+l(f._r,f._g,f._b,f._a)}return"progid:DXImageTransform.Microsoft.gradient("+e+"startColorstr="+b+",endColorstr="+d+")"},toString:function(a){var b=!!a;a=a||this._format;var c=!1,d=this._a<1&&this._a>=0,e=!b&&d&&("hex"===a||"hex6"===a||"hex3"===a||"hex4"===a||"hex8"===a||"name"===a);return e?"name"===a&&0===this._a?this.toName():this.toRgbString():("rgb"===a&&(c=this.toRgbString()),"prgb"===a&&(c=this.toPercentageRgbString()),"hex"!==a&&"hex6"!==a||(c=this.toHexString()),"hex3"===a&&(c=this.toHexString(!0)),"hex4"===a&&(c=this.toHex8String(!0)),"hex8"===a&&(c=this.toHex8String()),"name"===a&&(c=this.toName()),"hsl"===a&&(c=this.toHslString()),"hsv"===a&&(c=this.toHsvString()),c||this.toHexString())},clone:function(){return c(this.toString())},_applyModification:function(a,b){var c=a.apply(null,[this].concat([].slice.call(b)));return this._r=c._r,this._g=c._g,this._b=c._b,this.setAlpha(c._a),this},lighten:function(){return this._applyModification(p,arguments)},brighten:function(){return this._applyModification(q,arguments)},darken:function(){return this._applyModification(r,arguments)},desaturate:function(){return this._applyModification(m,arguments)},saturate:function(){return this._applyModification(n,arguments)},greyscale:function(){return this._applyModification(o,arguments)},spin:function(){return this._applyModification(s,arguments)},_applyCombination:function(a,b){return a.apply(null,[this].concat([].slice.call(b)))},analogous:function(){return this._applyCombination(x,arguments)},complement:function(){return this._applyCombination(t,arguments)},monochromatic:function(){return this._applyCombination(y,arguments)},splitcomplement:function(){return this._applyCombination(w,arguments)},triad:function(){return this._applyCombination(u,arguments)},tetrad:function(){return this._applyCombination(v,arguments)}},c.fromRatio=function(a,b){if("object"==typeof a){var d={};for(var e in a)a.hasOwnProperty(e)&&("a"===e?d[e]=a[e]:d[e]=H(a[e]));a=d}return c(a,b)},c.equals=function(a,b){return!(!a||!b)&&c(a).toRgbString()==c(b).toRgbString()},c.random=function(){return c.fromRatio({r:T(),g:T(),b:T()})},c.mix=function(a,b,d){d=0===d?0:d||50;var e=c(a).toRgb(),f=c(b).toRgb(),g=d/100,h={r:(f.r-e.r)*g+e.r,g:(f.g-e.g)*g+e.g,b:(f.b-e.b)*g+e.b,a:(f.a-e.a)*g+e.a};return c(h)},c.readability=function(b,d){var e=c(b),f=c(d);return(a.max(e.getLuminance(),f.getLuminance())+.05)/(a.min(e.getLuminance(),f.getLuminance())+.05)},c.isReadable=function(a,b,d){var e,f,g=c.readability(a,b);switch(f=!1,e=M(d),e.level+e.size){case"AAsmall":case"AAAlarge":f=g>=4.5;break;case"AAlarge":f=g>=3;break;case"AAAsmall":f=g>=7}return f},c.mostReadable=function(a,b,d){var e,f,g,h,i=null,j=0;d=d||{},f=d.includeFallbackColors,g=d.level,h=d.size;for(var k=0;kj&&(j=e,i=c(b[k]));return c.isReadable(a,i,{level:g,size:h})||!f?i:(d.includeFallbackColors=!1,c.mostReadable(a,["#fff","#000"],d))};var U=c.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},V=c.hexNames=z(U),W=function(){var a="[-\\+]?\\d+%?",b="[-\\+]?\\d*\\.\\d+%?",c="(?:"+b+")|(?:"+a+")",d="[\\s|\\(]+("+c+")[,|\\s]+("+c+")[,|\\s]+("+c+")\\s*\\)?",e="[\\s|\\(]+("+c+")[,|\\s]+("+c+")[,|\\s]+("+c+")[,|\\s]+("+c+")\\s*\\)?";return{CSS_UNIT:new RegExp(c),rgb:new RegExp("rgb"+d),rgba:new RegExp("rgba"+e),hsl:new RegExp("hsl"+d),hsla:new RegExp("hsla"+e),hsv:new RegExp("hsv"+d),hsva:new RegExp("hsva"+e),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/}}();"undefined"!=typeof b&&b.exports?b.exports=c:"function"==typeof define&&define.amd?define(function(){return c}):window.tinycolor=c}(Math)},{}],11:[function(a,b,c){!function(){var b=a("d3"),c=a("minicharts"),d=a("./utils.js");L.Minichart=L.CircleMarker.extend({options:{type:"bar",data:[1],maxValues:"auto",colors:b.schemeCategory10,width:60,height:60,opacity:1,labels:"none",labelMinSize:8,labelMaxSize:24,labelPadding:2,labelColor:"auto",labelStyle:"font-family:sans-serif",transitionTime:750},initialize:function(a,b){this._center=a,this._zoom=0,this.options=d.mergeOptions(b,this.options),L.CircleMarker.prototype.initialize.call(this,a,{radius:this.options.width/2,stroke:!1,fill:!1})},onAdd:function(a){L.CircleMarker.prototype.onAdd.call(this,a);var c=this._container||this._renderer._container;c.setAttribute("class","leaflet-zoom-hide"),this._chart=b.select(c).append("g"),a.on("moveend",this._onMoveend,this),this._redraw(!0)},onRemove:function(a){L.CircleMarker.prototype.onRemove.call(this,a),a.off("moveend",this._onMoveend,this)},_onMoveend:function(){var a=this._zoom;this._zoom=this._map.getZoom(),a!=this._zoom&&this._redraw()},setOptions:function(a){var b=a.type&&a.type!=this.options.type;this.options=d.mergeOptions(a,this.options),this._redraw(b)},_redraw:function(a){var e,f=this._map.latLngToLayerPoint(this._center);e="bar"==this.options.type?2*this.options.height:this.options.width,this._chart.attr("transform","translate("+(f.x-this.options.width/2)+","+(f.y-e/2)+")").transition().duration(this.options.transitionTime).attr("opacity",this.options.opacity);var g=this.options.data;g=d.toArray(g);for(var h=0;h10?f(c):c>1?f(c,10,!0):f(c,100,!0),d+c+b}function f(a,b,c){return b=b||1,c?Math.round(a*b)/b:Math.round(a/b)*b}b.exports.mergeOptions=a,b.exports.toArray=c,b.exports.toFunction=d,b.exports.prettyNumbers=function(a){return a.map(e)}}()},{}]},{},[11]); \ No newline at end of file + +!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c||a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g=Yj?e*=10:f>=Zj?e*=5:f>=$j&&(e*=2),b=0&&(c=a.slice(d+1),a=a.slice(0,d)),a&&!b.hasOwnProperty(a))throw new Error("unknown type: "+a);return{type:a,name:c}})}function r(a,b){for(var c,d=0,e=a.length;d=0&&(b=a.slice(c+1),a=a.slice(0,c)),{type:a,name:b}})}function A(a){return function(){var b=this.__on;if(b){for(var c,d=0,e=-1,f=b.length;db?1:a>=b?0:NaN}function J(a){return function(){this.removeAttribute(a)}}function K(a){return function(){this.removeAttributeNS(a.space,a.local)}}function L(a,b){return function(){this.setAttribute(a,b)}}function M(a,b){return function(){this.setAttributeNS(a.space,a.local,b)}}function N(a,b){return function(){var c=b.apply(this,arguments);null==c?this.removeAttribute(a):this.setAttribute(a,c)}}function O(a,b){return function(){var c=b.apply(this,arguments);null==c?this.removeAttributeNS(a.space,a.local):this.setAttributeNS(a.space,a.local,c)}}function P(a){return function(){this.style.removeProperty(a)}}function Q(a,b,c){return function(){this.style.setProperty(a,b,c)}}function R(a,b,c){return function(){var d=b.apply(this,arguments);null==d?this.style.removeProperty(a):this.style.setProperty(a,d,c)}}function S(a){return function(){delete this[a]}}function T(a,b){return function(){this[a]=b}}function U(a,b){return function(){var c=b.apply(this,arguments);null==c?delete this[a]:this[a]=c}}function V(a){return a.trim().split(/^|\s+/)}function W(a){return a.classList||new X(a)}function X(a){this._node=a,this._names=V(a.getAttribute("class")||"")}function Y(a,b){for(var c=W(a),d=-1,e=b.length;++d>8&15|b>>4&240,b>>4&15|240&b,(15&b)<<4|15&b,1)):(b=Gl.exec(a))?za(parseInt(b[1],16)):(b=Hl.exec(a))?new Da(b[1],b[2],b[3],1):(b=Il.exec(a))?new Da(255*b[1]/100,255*b[2]/100,255*b[3]/100,1):(b=Jl.exec(a))?Aa(b[1],b[2],b[3],b[4]):(b=Kl.exec(a))?Aa(255*b[1]/100,255*b[2]/100,255*b[3]/100,b[4]):(b=Ll.exec(a))?Ea(b[1],b[2]/100,b[3]/100,1):(b=Ml.exec(a))?Ea(b[1],b[2]/100,b[3]/100,b[4]):Nl.hasOwnProperty(a)?za(Nl[a]):"transparent"===a?new Da(NaN,NaN,NaN,0):null}function za(a){return new Da(a>>16&255,a>>8&255,255&a,1)}function Aa(a,b,c,d){return d<=0&&(a=b=c=NaN),new Da(a,b,c,d)}function Ba(a){return a instanceof xa||(a=ya(a)),a?(a=a.rgb(),new Da(a.r,a.g,a.b,a.opacity)):new Da}function Ca(a,b,c,d){return 1===arguments.length?Ba(a):new Da(a,b,c,null==d?1:d)}function Da(a,b,c,d){this.r=+a,this.g=+b,this.b=+c,this.opacity=+d}function Ea(a,b,c,d){return d<=0?a=b=c=NaN:c<=0||c>=1?a=b=NaN:b<=0&&(a=NaN),new Ha(a,b,c,d)}function Fa(a){if(a instanceof Ha)return new Ha(a.h,a.s,a.l,a.opacity);if(a instanceof xa||(a=ya(a)),!a)return new Ha;if(a instanceof Ha)return a;a=a.rgb();var b=a.r/255,c=a.g/255,d=a.b/255,e=Math.min(b,c,d),f=Math.max(b,c,d),g=NaN,h=f-e,i=(f+e)/2;return h?(g=b===f?(c-d)/h+6*(c0&&i<1?0:g,new Ha(g,h,i,a.opacity)}function Ga(a,b,c,d){return 1===arguments.length?Fa(a):new Ha(a,b,c,null==d?1:d)}function Ha(a,b,c,d){this.h=+a,this.s=+b,this.l=+c,this.opacity=+d}function Ia(a,b,c){return 255*(a<60?b+(c-b)*a/60:a<180?c:a<240?b+(c-b)*(240-a)/60:b)}function Ja(a){if(a instanceof La)return new La(a.l,a.a,a.b,a.opacity);if(a instanceof Sa){var b=a.h*Ol;return new La(a.l,Math.cos(b)*a.c,Math.sin(b)*a.c,a.opacity)}a instanceof Da||(a=Ba(a));var c=Pa(a.r),d=Pa(a.g),e=Pa(a.b),f=Ma((.4124564*c+.3575761*d+.1804375*e)/Ql),g=Ma((.2126729*c+.7151522*d+.072175*e)/Rl);return new La(116*g-16,500*(f-g),200*(g-Ma((.0193339*c+.119192*d+.9503041*e)/Sl)),a.opacity)}function Ka(a,b,c,d){return 1===arguments.length?Ja(a):new La(a,b,c,null==d?1:d)}function La(a,b,c,d){this.l=+a,this.a=+b,this.b=+c,this.opacity=+d}function Ma(a){return a>Wl?Math.pow(a,1/3):a/Vl+Tl}function Na(a){return a>Ul?a*a*a:Vl*(a-Tl)}function Oa(a){return 255*(a<=.0031308?12.92*a:1.055*Math.pow(a,1/2.4)-.055)}function Pa(a){return(a/=255)<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4)}function Qa(a){if(a instanceof Sa)return new Sa(a.h,a.c,a.l,a.opacity);a instanceof La||(a=Ja(a));var b=Math.atan2(a.b,a.a)*Pl;return new Sa(b<0?b+360:b,Math.sqrt(a.a*a.a+a.b*a.b),a.l,a.opacity)}function Ra(a,b,c,d){return 1===arguments.length?Qa(a):new Sa(a,b,c,null==d?1:d)}function Sa(a,b,c,d){this.h=+a,this.c=+b,this.l=+c,this.opacity=+d}function Ta(a){if(a instanceof Va)return new Va(a.h,a.s,a.l,a.opacity);a instanceof Da||(a=Ba(a));var b=a.r/255,c=a.g/255,d=a.b/255,e=(cm*d+am*b-bm*c)/(cm+am-bm),f=d-e,g=(_l*(c-e)-Zl*f)/$l,h=Math.sqrt(g*g+f*f)/(_l*e*(1-e)),i=h?Math.atan2(g,f)*Pl-120:NaN;return new Va(i<0?i+360:i,h,e,a.opacity)}function Ua(a,b,c,d){return 1===arguments.length?Ta(a):new Va(a,b,c,null==d?1:d)}function Va(a,b,c,d){this.h=+a,this.s=+b,this.l=+c,this.opacity=+d}function Wa(a,b,c,d,e){var f=a*a,g=f*a;return((1-3*a+3*f-g)*b+(4-6*f+3*g)*c+(1+3*a+3*f-3*g)*d+g*e)/6}function Xa(a,b){return function(c){return a+c*b}}function Ya(a,b,c){return a=Math.pow(a,c),b=Math.pow(b,c)-a,c=1/c,function(d){return Math.pow(a+d*b,c)}}function Za(a,b){var c=b-a;return c?Xa(a,c>180||c<-180?c-360*Math.round(c/360):c):lm(isNaN(a)?b:a)}function $a(a){return 1==(a=+a)?_a:function(b,c){return c-b?Ya(b,c,a):lm(isNaN(b)?c:b)}}function _a(a,b){var c=b-a;return c?Xa(a,c):lm(isNaN(a)?b:a)}function ab(a){return function(b){var c,d,e=b.length,f=new Array(e),g=new Array(e),h=new Array(e);for(c=0;c180?b+=360:b-a>180&&(a+=360),f.push({i:c.push(e(c)+"rotate(",null,d)-2,x:rm(a,b)})):b&&c.push(e(c)+"rotate("+b+d)}function h(a,b,c,f){a!==b?f.push({i:c.push(e(c)+"skewX(",null,d)-2,x:rm(a,b)}):b&&c.push(e(c)+"skewX("+b+d)}function i(a,b,c,d,f,g){if(a!==c||b!==d){var h=f.push(e(f)+"scale(",null,",",null,")");g.push({i:h-4,x:rm(a,c)},{i:h-2,x:rm(b,d)})}else 1===c&&1===d||f.push(e(f)+"scale("+c+","+d+")")}return function(b,c){var d=[],e=[];return b=a(b),c=a(c),f(b.translateX,b.translateY,c.translateX,c.translateY,d,e),g(b.rotate,c.rotate,d,e),h(b.skewX,c.skewX,d,e),i(b.scaleX,b.scaleY,c.scaleX,c.scaleY,d,e),b=c=null,function(a){for(var b,c=-1,f=e.length;++c=0&&b._call.call(null,a),b=b._next;--Mm}function sb(){Rm=(Qm=Tm.now())+Sm,Mm=Nm=0;try{rb()}finally{Mm=0,ub(),Rm=0}}function tb(){var a=Tm.now(),b=a-Qm;b>Pm&&(Sm-=b,Qm=a)}function ub(){for(var a,b,c=hm,d=1/0;c;)c._call?(d>c._time&&(d=c._time),a=c,c=c._next):(b=c._next,c._next=null,c=a?a._next=b:hm=b);im=a,vb(d)}function vb(a){if(!Mm){Nm&&(Nm=clearTimeout(Nm));var b=a-Rm;b>24?(a<1/0&&(Nm=setTimeout(sb,b)),Om&&(Om=clearInterval(Om))):(Om||(Qm=Rm,Om=setInterval(tb,Pm)),Mm=1,Um(sb))}}function wb(a,b){var c=a.__transition;if(!c||!(c=c[b])||c.state>Zm)throw new Error("too late");return c}function xb(a,b){var c=a.__transition;if(!c||!(c=c[b])||c.state>_m)throw new Error("too late");return c}function yb(a,b){var c=a.__transition;if(!c||!(c=c[b]))throw new Error("too late");return c}function zb(a,b,c){function d(a){c.state=$m,c.timer.restart(e,c.delay,c.time),c.delay<=a&&e(a-c.delay)}function e(d){var j,k,l,m;if(c.state!==$m)return g();for(j in i)if(m=i[j],m.name===c.name){if(m.state===an)return Vm(e);m.state===bn?(m.state=dn,m.timer.stop(),m.on.call("interrupt",a,a.__data__,m.index,m.group),delete i[j]):+j=0&&(a=a.slice(0,b)),!a||"start"===a})}function Rb(a,b,c){var d,e,f=Qb(b)?wb:xb;return function(){var g=f(this,a),h=g.on;h!==d&&(e=(d=h).copy()).on(b,c),g.on=e}}function Sb(a){return function(){var b=this.parentNode;for(var c in this.__transition)if(+c!==a)return;b&&b.removeChild(this)}}function Tb(a,b){var c,d,e;return function(){var f=fl(this).getComputedStyle(this,null),g=f.getPropertyValue(a),h=(this.style.removeProperty(a),f.getPropertyValue(a));return g===h?null:g===c&&h===d?e:e=b(c=g,d=h)}}function Ub(a){return function(){this.style.removeProperty(a)}}function Vb(a,b,c){var d,e;return function(){var f=fl(this).getComputedStyle(this,null).getPropertyValue(a);return f===c?null:f===d?e:e=b(d=f,c)}}function Wb(a,b,c){var d,e,f;return function(){var g=fl(this).getComputedStyle(this,null),h=g.getPropertyValue(a),i=c(this);return null==i&&(this.style.removeProperty(a),i=g.getPropertyValue(a)),h===i?null:h===d&&i===e?f:f=b(d=h,e=i)}}function Xb(a,b,c){function d(){var d=this,e=b.apply(d,arguments);return e&&function(b){d.style.setProperty(a,e(b),c)}}return d._value=b,d}function Yb(a){return function(){this.textContent=a}}function Zb(a){return function(){var b=a(this);this.textContent=null==b?"":b}}function $b(a,b,c,d){this._groups=a,this._parents=b,this._name=c,this._id=d}function _b(a){return pa().transition(a)}function ac(){return++Bn}function bc(a){return+a}function cc(a){return a*a}function dc(a){return a*(2-a)}function ec(a){return((a*=2)<=1?a*a:--a*(2-a)+1)/2}function fc(a){return a*a*a}function gc(a){return--a*a*a+1}function hc(a){return((a*=2)<=1?a*a*a:(a-=2)*a*a+2)/2}function ic(a){return 1-Math.cos(a*Hn)}function jc(a){return Math.sin(a*Hn)}function kc(a){return(1-Math.cos(Gn*a))/2}function lc(a){return Math.pow(2,10*a-10)}function mc(a){return 1-Math.pow(2,-10*a)}function nc(a){return((a*=2)<=1?Math.pow(2,10*a-10):2-Math.pow(2,10-10*a))/2}function oc(a){return 1-Math.sqrt(1-a*a)}function pc(a){return Math.sqrt(1- --a*a)}function qc(a){return((a*=2)<=1?1-Math.sqrt(1-a*a):Math.sqrt(1-(a-=2)*a)+1)/2}function rc(a){return 1-sc(1-a)}function sc(a){return(a=+a)Math.abs(a[1]-M[1])?x=!0:w=!0),M=a,v=!0,eo(),f()}function f(){var a;switch(t=M[0]-L[0],u=M[1]-L[1],A){case go:case fo:B&&(t=Math.max(G-l,Math.min(I-p,t)),m=l+t,q=p+t),C&&(u=Math.max(H-n,Math.min(J-r,u)),o=n+u,s=r+u);break;case ho:B<0?(t=Math.max(G-l,Math.min(I-l,t)),m=l+t,q=p):B>0&&(t=Math.max(G-p,Math.min(I-p,t)),m=l,q=p+t),C<0?(u=Math.max(H-n,Math.min(J-n,u)),o=n+u,s=r):C>0&&(u=Math.max(H-r,Math.min(J-r,u)),o=n,s=r+u);break;case io:B&&(m=Math.max(G,Math.min(I,l-t*B)),q=Math.max(G,Math.min(I,p+t*B))),C&&(o=Math.max(H,Math.min(J,n-u*C)),s=Math.max(H,Math.min(J,r+u*C)))}q0&&(l=m-t),C<0?r=s-u:C>0&&(n=o-u),A=go,P.attr("cursor",mo.selection),f());break;default:return}eo()}function j(){switch(a.event.keyCode){case 16:K&&(w=x=K=!1,f());break;case 18:A===io&&(B<0?p=q:B>0&&(l=m),C<0?r=s:C>0&&(n=o),A=ho,f());break;case 32:A===go&&(a.event.altKey?(B&&(p=q-t*B,l=m+t*B),C&&(r=s-u*C,n=o+u*C),A=io):(B<0?p=q:B>0&&(l=m),C<0?r=s:C>0&&(n=o),A=ho),P.attr("cursor",mo[z]),f());break;default:return}eo()}if(a.event.touches){if(a.event.changedTouches.length=(f=(p+r)/2))?p=f:r=f,(k=c>=(g=(q+s)/2))?q=g:s=g,e=n,!(n=n[l=k<<1|j]))return e[l]=o,a;if(h=+a._x.call(null,n.data),i=+a._y.call(null,n.data),b===h&&c===i)return o.next=n,e?e[l]=o:a._root=o,a;do{e=e?e[l]=new Array(4):a._root=new Array(4),(j=b>=(f=(p+r)/2))?p=f:r=f,(k=c>=(g=(q+s)/2))?q=g:s=g}while((l=k<<1|j)==(m=(i>=g)<<1|h>=f));return e[m]=n,e[l]=o,a}function Zc(a){var b,c,d,e,f=a.length,g=new Array(f),h=new Array(f),i=1/0,j=1/0,k=-1/0,l=-1/0;for(c=0;ck&&(k=d),el&&(l=e));for(k",e=b[3]||"-",f=b[4]||"",g=!!b[5],h=b[6]&&+b[6],i=!!b[7],j=b[8]&&+b[8].slice(1),k=b[9]||"";"n"===k?(i=!0,k="g"):Ap[k]||(k=""),(g||"0"===c&&"="===d)&&(g=!0,c="0",d="="),this.fill=c,this.align=d,this.sign=e,this.symbol=f,this.zero=g,this.width=h,this.comma=i,this.precision=j,this.type=k}function md(b){return Cp=Fp(b),a.format=Cp.format,a.formatPrefix=Cp.formatPrefix,Cp}function nd(){this.reset()}function od(a,b,c){var d=a.s=b+c,e=d-b,f=d-e;a.t=b-f+(c-e)}function pd(a){return a>1?0:a<-1?pq:Math.acos(a)}function qd(a){return a>1?qq:a<-1?-qq:Math.asin(a)}function rd(a){return(a=Dq(a/2))*a}function sd(){}function td(a,b){a&&Iq.hasOwnProperty(a.type)&&Iq[a.type](a,b)}function ud(a,b,c){var d,e=-1,f=a.length-c;for(b.lineStart();++e=0?1:-1,e=d*c,f=yq(b),g=Dq(b),h=Op*g,i=Np*f+h*yq(e),j=h*d*Dq(e);Kq.add(xq(j,i)),Mp=a,Np=f,Op=g}function Ad(a){return[xq(a[1],a[0]),qd(a[2])]}function Bd(a){var b=a[0],c=a[1],d=yq(c);return[d*yq(b),d*Dq(b),Dq(c)]}function Cd(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}function Dd(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]}function Ed(a,b){a[0]+=b[0],a[1]+=b[1],a[2]+=b[2]}function Fd(a,b){return[a[0]*b,a[1]*b,a[2]*b]}function Gd(a){var b=Fq(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);a[0]/=b,a[1]/=b,a[2]/=b}function Hd(a,b){Xp.push(Yp=[Pp=a,Rp=a]),bSp&&(Sp=b)}function Id(a,b){var c=Bd([a*uq,b*uq]);if(Wp){var d=Dd(Wp,c),e=[d[1],-d[0],0],f=Dd(e,d);Gd(f),f=Ad(f);var g,h=a-Tp,i=h>0?1:-1,j=f[0]*tq*i,k=vq(h)>180;k^(i*TpSp&&(Sp=g):(j=(j+360)%360-180,k^(i*TpSp&&(Sp=b))),k?aOd(Pp,Rp)&&(Rp=a):Od(a,Rp)>Od(Pp,Rp)&&(Pp=a):Rp>=Pp?(aRp&&(Rp=a)):a>Tp?Od(Pp,a)>Od(Pp,Rp)&&(Rp=a):Od(a,Rp)>Od(Pp,Rp)&&(Pp=a)}else Xp.push(Yp=[Pp=a,Rp=a]);bSp&&(Sp=b),Wp=c,Tp=a}function Jd(){Pq.point=Id}function Kd(){Yp[0]=Pp,Yp[1]=Rp,Pq.point=Hd,Wp=null}function Ld(a,b){if(Wp){var c=a-Tp;Oq.add(vq(c)>180?c+(c>0?360:-360):c)}else Up=a,Vp=b;Mq.point(a,b),Id(a,b)}function Md(){Mq.lineStart()}function Nd(){Ld(Up,Vp),Mq.lineEnd(),vq(Oq)>oq&&(Pp=-(Rp=180)),Yp[0]=Pp,Yp[1]=Rp,Wp=null}function Od(a,b){return(b-=a)<0?b+360:b}function Pd(a,b){return a[0]-b[0]}function Qd(a,b){return a[0]<=a[1]?a[0]<=b&&b<=a[1]:bpq?a-sq:a<-pq?a+sq:a,b]}function ae(a,b,c){return(a%=sq)?b||c?Uq(ce(a),de(b,c)):ce(a):b||c?de(b,c):_d}function be(a){return function(b,c){return b+=a,[b>pq?b-sq:b<-pq?b+sq:b,c]}}function ce(a){var b=be(a);return b.invert=be(-a),b}function de(a,b){function c(a,b){var c=yq(b),h=yq(a)*c,i=Dq(a)*c,j=Dq(b),k=j*d+h*e;return[xq(i*f-k*g,h*d-j*e),qd(k*f+i*g)]}var d=yq(a),e=Dq(a),f=yq(b),g=Dq(b);return c.invert=function(a,b){var c=yq(b),h=yq(a)*c,i=Dq(a)*c,j=Dq(b),k=j*f-i*g;return[xq(i*f+j*g,h*d+k*e),qd(k*d-h*e)]},c}function ee(a,b,c,d,e,f){if(c){var g=yq(b),h=Dq(b),i=d*c;null==e?(e=b+d*sq,f=b-i/2):(e=fe(g,e),f=fe(g,f),(d>0?ef)&&(e+=d*sq));for(var j,k=e;d>0?k>f:k0)do{j.point(0===k||3===k?a:c,k>1?d:b)}while((k=(k+h+4)%4)!==l);else j.point(f[0],f[1])}function g(d,e){return vq(d[0]-a)0?0:3:vq(d[0]-c)0?2:1:vq(d[1]-b)0?1:0:e>0?3:2}function h(a,b){return i(a.x,b.x)}function i(a,b){var c=g(a,1),d=g(b,1);return c!==d?c-d:0===c?b[1]-a[1]:1===c?a[0]-b[0]:2===c?a[1]-b[1]:b[0]-a[0]}return function(g){function i(a,b){e(a,b)&&A.point(a,b)}function j(){for(var b=0,c=0,e=q.length;cd&&(l-f)*(d-g)>(m-g)*(a-f)&&++b:m<=d&&(l-f)*(d-g)<(m-g)*(a-f)&&--b;return b}function k(){A=B,p=[],q=[],z=!0}function l(){var a=j(),b=z&&a,c=(p=ik(p)).length;(b||c)&&(g.polygonStart(),b&&(g.lineStart(),f(null,null,1,g),g.lineEnd()),c&&jr(p,h,a,f,g),g.polygonEnd()),A=g,p=q=r=null}function m(){C.point=o,q&&q.push(r=[]),y=!0,x=!1,v=w=NaN}function n(){p&&(o(s,t),u&&x&&B.rejoin(),p.push(B.result())),C.point=i,x&&A.lineEnd()}function o(f,g){var h=e(f,g);if(q&&r.push([f,g]),y)s=f,t=g,u=h,y=!1,h&&(A.lineStart(),A.point(f,g));else if(h&&x)A.point(f,g);else{var i=[v=Math.max(lr,Math.min(kr,v)),w=Math.max(lr,Math.min(kr,w))],j=[f=Math.max(lr,Math.min(kr,f)),g=Math.max(lr,Math.min(kr,g))];hr(i,j,a,b,c,d)?(x||(A.lineStart(),A.point(i[0],i[1])),A.point(j[0],j[1]),h||A.lineEnd(),z=!1):h&&(A.lineStart(),A.point(f,g),z=!1)}v=f,w=g,x=h}var p,q,r,s,t,u,v,w,x,y,z,A=g,B=gr(),C={point:i,lineStart:m,lineEnd:n,polygonStart:k,polygonEnd:l};return C}}function je(){qr.point=le,qr.lineEnd=ke}function ke(){qr.point=qr.lineEnd=sd}function le(a,b){a*=uq,b*=uq,Vq=a,Wq=Dq(b),Xq=yq(b),qr.point=me}function me(a,b){a*=uq,b*=uq;var c=Dq(b),d=yq(b),e=vq(a-Vq),f=yq(e),g=Dq(e),h=d*g,i=Xq*c-Wq*d*f,j=Wq*c+Xq*d*f;pr.add(xq(Fq(h*h+i*i),j)),Vq=a,Wq=c,Xq=d}function ne(a,b){return!(!a||!wr.hasOwnProperty(a.type))&&wr[a.type](a,b)}function oe(a,b){return 0===ur(a,b)}function pe(a,b){var c=ur(a[0],a[1]);return ur(a[0],b)+ur(b,a[1])<=c+oq}function qe(a,b){return!!or(a.map(re),se(b))}function re(a){return a=a.map(se),a.pop(),a}function se(a){return[a[0]*uq,a[1]*uq]}function te(a,b,c){var d=Xj(a,b-oq,c).concat(b);return function(a){return d.map(function(b){return[a,b]})}}function ue(a,b,c){var d=Xj(a,b-oq,c).concat(b);return function(a){return d.map(function(b){return[b,a]})}}function ve(){function a(){return{type:"MultiLineString",coordinates:b()}}function b(){return Xj(zq(f/q)*q,e,q).map(m).concat(Xj(zq(j/r)*r,i,r).map(n)).concat(Xj(zq(d/o)*o,c,o).filter(function(a){return vq(a%q)>oq}).map(k)).concat(Xj(zq(h/p)*p,g,p).filter(function(a){return vq(a%r)>oq}).map(l))}var c,d,e,f,g,h,i,j,k,l,m,n,o=10,p=o,q=90,r=360,s=2.5;return a.lines=function(){return b().map(function(a){return{type:"LineString",coordinates:a}})},a.outline=function(){return{type:"Polygon",coordinates:[m(f).concat(n(i).slice(1),m(e).reverse().slice(1),n(j).reverse().slice(1))]}},a.extent=function(b){return arguments.length?a.extentMajor(b).extentMinor(b):a.extentMinor()},a.extentMajor=function(b){return arguments.length?(f=+b[0][0],e=+b[1][0],j=+b[0][1],i=+b[1][1],f>e&&(b=f,f=e,e=b),j>i&&(b=j,j=i,i=b),a.precision(s)):[[f,j],[e,i]]},a.extentMinor=function(b){return arguments.length?(d=+b[0][0],c=+b[1][0],h=+b[0][1],g=+b[1][1],d>c&&(b=d,d=c,c=b),h>g&&(b=h,h=g,g=b),a.precision(s)):[[d,h],[c,g]]},a.step=function(b){return arguments.length?a.stepMajor(b).stepMinor(b):a.stepMinor()},a.stepMajor=function(b){return arguments.length?(q=+b[0],r=+b[1],a):[q,r]},a.stepMinor=function(b){return arguments.length?(o=+b[0],p=+b[1],a):[o,p]},a.precision=function(b){return arguments.length?(s=+b,k=te(h,g,90),l=ue(d,c,s),m=te(j,i,90),n=ue(f,e,s),a):s},a.extentMajor([[-180,-90+oq],[180,90-oq]]).extentMinor([[-180,-80-oq],[180,80+oq]])}function we(){return ve()()}function xe(){Cr.point=ye}function ye(a,b){Cr.point=ze,Yq=$q=a,Zq=_q=b}function ze(a,b){Br.add(_q*a-$q*b),$q=a,_q=b}function Ae(){ze(Yq,Zq)}function Be(a,b){aFr&&(Fr=a),bGr&&(Gr=b)}function Ce(a,b){Ir+=a,Jr+=b,++Kr}function De(){Rr.point=Ee}function Ee(a,b){Rr.point=Fe,Ce(cr=a,dr=b)}function Fe(a,b){var c=a-cr,d=b-dr,e=Fq(c*c+d*d);Lr+=e*(cr+a)/2,Mr+=e*(dr+b)/2,Nr+=e,Ce(cr=a,dr=b)}function Ge(){Rr.point=Ce}function He(){Rr.point=Je}function Ie(){Ke(ar,br)}function Je(a,b){Rr.point=Ke,Ce(ar=cr=a,br=dr=b)}function Ke(a,b){var c=a-cr,d=b-dr,e=Fq(c*c+d*d);Lr+=e*(cr+a)/2,Mr+=e*(dr+b)/2,Nr+=e,e=dr*a-cr*b,Or+=e*(cr+a),Pr+=e*(dr+b),Qr+=3*e,Ce(cr=a,dr=b)}function Le(a){this._context=a}function Me(a,b){Yr.point=Ne,Tr=Vr=a,Ur=Wr=b}function Ne(a,b){Vr-=a,Wr-=b,Xr.add(Fq(Vr*Vr+Wr*Wr)),Vr=a,Wr=b}function Oe(){this._string=[]}function Pe(a){return"m0,"+a+"a"+a+","+a+" 0 1,1 0,"+-2*a+"a"+a+","+a+" 0 1,1 0,"+2*a+"z"}function Qe(a){return a.length>1}function Re(a,b){return((a=a.x)[0]<0?a[1]-qq-oq:qq-a[1])-((b=b.x)[0]<0?b[1]-qq-oq:qq-b[1])}function Se(a){var b,c=NaN,d=NaN,e=NaN;return{lineStart:function(){a.lineStart(),b=1},point:function(f,g){var h=f>0?pq:-pq,i=vq(f-c);vq(i-pq)0?qq:-qq),a.point(e,d),a.lineEnd(),a.lineStart(),a.point(h,d),a.point(f,d),b=0):e!==h&&i>=pq&&(vq(c-e)oq?wq((Dq(b)*(f=yq(d))*Dq(c)-Dq(d)*(e=yq(b))*Dq(a))/(e*f*g)):(b+d)/2}function Ue(a,b,c,d){var e;if(null==a)e=c*qq,d.point(-pq,e),d.point(0,e),d.point(pq,e),d.point(pq,0),d.point(pq,-e),d.point(0,-e),d.point(-pq,-e),d.point(-pq,0),d.point(-pq,e);else if(vq(a[0]-b[0])>oq){var f=a[0]4*b&&p--){var u=g+m,v=h+n,w=i+o,x=Fq(u*u+v*v+w*w),y=qd(w/=x),z=vq(vq(w)-1)b||vq((r*D+s*E)/t-.5)>.3||g*m+h*n+i*o2?a[2]%360*uq:0,e()):[v*tq,w*tq,x*tq]},b.precision=function(a){return arguments.length?(D=es(d,C=a*a),f()):Fq(C)},b.fitExtent=function(a,c){return Xe(b,a,c)},b.fitSize=function(a,c){return Ye(b,a,c)},function(){return g=a.apply(this,arguments),b.invert=g.invert&&c,e()}}function bf(a){var b=0,c=pq/3,d=af(a),e=d(b,c);return e.parallels=function(a){return arguments.length?d(b=a[0]*uq,c=a[1]*uq):[b*tq,c*tq]},e}function cf(a){function b(a,b){return[a*c,Dq(b)/c]}var c=yq(a);return b.invert=function(a,b){return[a/c,qd(b*c)]},b}function df(a,b){function c(a,b){var c=Fq(f-2*e*Dq(b))/e;return[c*Dq(a*=e),g-c*yq(a)]}var d=Dq(a),e=(d+Dq(b))/2;if(vq(e)0?b<-qq+oq&&(b=-qq+oq):b>qq-oq&&(b=qq-oq);var c=f/Cq(kf(b),e);return[c*Dq(e*a),f-c*yq(e*a)]}var d=yq(a),e=a===b?Dq(a):Bq(d/yq(b))/Bq(kf(b)/kf(a)),f=d*Cq(kf(a),e)/e;return e?(c.invert=function(a,b){var c=f-b,d=Eq(e)*Fq(a*a+c*c);return[xq(a,vq(c))/e*Eq(c),2*wq(Cq(f/d,1/e))-qq]},c):hf}function mf(a,b){return[a,b]}function nf(a,b){function c(a,b){var c=f-b,d=e*a;return[c*Dq(d),f-c*yq(d)]}var d=yq(a),e=a===b?Dq(a):(d-yq(b))/(b-a),f=d/e+a;return vq(e)=0;)b+=c[d].value;else b=1;a.value=b}function Bf(a,b){if(a===b)return a;var c=a.ancestors(),d=b.ancestors(),e=null;for(a=c.pop(),b=d.pop();a===b;)e=a,a=c.pop(),b=d.pop();return e}function Cf(a,b){var c,d,e,f,g,h=new Hf(a),i=+a.value&&(h.value=a.value),j=[h];for(null==b&&(b=Ef);c=j.pop();)if(i&&(c.value=+c.data.value),(e=b(c.data))&&(g=e.length))for(c.children=new Array(g),f=g-1;f>=0;--f)j.push(d=c.children[f]=new Hf(e[f])),d.parent=c,d.depth=c.depth+1;return h.eachBefore(Gf)}function Df(){return Cf(this).eachBefore(Ff)}function Ef(a){return a.children}function Ff(a){a.data=a.data.data}function Gf(a){var b=0;do{a.height=b}while((a=a.parent)&&a.height<++b)}function Hf(a){this.data=a,this.depth=this.height=0,this.parent=null}function If(a){this._=a,this.next=null}function Jf(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r-b.r;return e*e+1e-6>c*c+d*d}function Kf(a,b){var c,d,e,f=null,g=a.head;switch(b.length){case 1:c=Lf(b[0]);break;case 2:c=Mf(b[0],b[1]);break;case 3:c=Nf(b[0],b[1],b[2])}for(;g;)e=g._,d=g.next,c&&Jf(c,e)?f=g:(f?(a.tail=f,f.next=null):a.head=a.tail=null,b.push(e),c=Kf(a,b),b.pop(),a.head?(g.next=a.head,a.head=g):(g.next=null,a.head=a.tail=g),f=a.tail,f.next=d),g=d;return a.tail=f,c}function Lf(a){return{x:a.x,y:a.y,r:a.r}}function Mf(a,b){var c=a.x,d=a.y,e=a.r,f=b.x,g=b.y,h=b.r,i=f-c,j=g-d,k=h-e,l=Math.sqrt(i*i+j*j);return{x:(c+f+i/l*k)/2,y:(d+g+j/l*k)/2,r:(l+e+h)/2}}function Nf(a,b,c){var d=a.x,e=a.y,f=a.r,g=b.x,h=b.y,i=b.r,j=c.x,k=c.y,l=c.r,m=2*(d-g),n=2*(e-h),o=2*(i-f),p=d*d+e*e-f*f-g*g-h*h+i*i,q=2*(d-j),r=2*(e-k),s=2*(l-f),t=d*d+e*e-f*f-j*j-k*k+l*l,u=q*n-m*r,v=(n*t-r*p)/u-d,w=(r*o-n*s)/u,x=(q*p-m*t)/u-e,y=(m*s-q*o)/u,z=w*w+y*y-1,A=2*(v*w+x*y+f),B=v*v+x*x-f*f,C=(-A-Math.sqrt(A*A-4*z*B))/(2*z);return{x:v+w*C+d,y:x+y*C+e,r:C}}function Of(a,b,c){var d=a.x,e=a.y,f=b.r+c.r,g=a.r+c.r,h=b.x-d,i=b.y-e,j=h*h+i*i;if(j){var k=.5+((g*=g)-(f*=f))/(2*j),l=Math.sqrt(Math.max(0,2*f*(g+j)-(g-=j)*g-f*f))/(2*j);c.x=d+k*h+l*i,c.y=e+k*i-l*h}else c.x=d+g,c.y=e}function Pf(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r+b.r;return e*e-1e-6>c*c+d*d}function Qf(a,b,c){var d=a._,e=a.next._,f=d.r+e.r,g=(d.x*e.r+e.x*d.r)/f-b,h=(d.y*e.r+e.y*d.r)/f-c;return g*g+h*h}function Rf(a){this._=a,this.next=null,this.previous=null}function Sf(a){if(!(e=a.length))return 0;var b,c,d,e;if(b=a[0],b.x=0,b.y=0,!(e>1))return b.r;if(c=a[1],b.x=-c.r,c.x=b.r,c.y=0,!(e>2))return b.r+c.r;Of(c,b,d=a[2]);var f,g,h,i,j,k,l,m=b.r*b.r,n=c.r*c.r,o=d.r*d.r,p=m+n+o,q=m*b.x+n*c.x+o*d.x,r=m*b.y+n*c.y+o*d.y;b=new Rf(b),c=new Rf(c),d=new Rf(d),b.next=d.previous=c,c.next=b.previous=d,d.next=c.previous=b;a:for(h=3;h=0;)b=e[f],b.z+=c,b.m+=c,c+=b.s+(d+=b.c)}function fg(a,b,c){return a.a.parent===b.parent?a.a:c}function gg(a,b){this._=a,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=b}function hg(a){for(var b,c,d,e,f,g=new gg(a,0),h=[g];b=h.pop();)if(d=b._.children)for(b.children=new Array(f=d.length),e=f-1;e>=0;--e)h.push(c=b.children[e]=new gg(d[e],e)),c.parent=b;return(g.parent=new gg(null,0)).children=[g],g}function ig(a,b,c,d,e,f){for(var g,h,i,j,k,l,m,n,o,p,q,r=[],s=b.children,t=0,u=0,v=s.length,w=b.value;tm&&(m=h),q=k*k*p,(n=Math.max(m/q,q/l))>o){k-=h;break}o=n}r.push(g={value:k,dice:i1&&ct(a[c[d-2]],a[c[d-1]],a[e])<=0;)--d;c[d++]=e}return c.slice(0,d)}function lg(a){if(!(a>=1))throw new Error;this._size=a,this._call=this._error=null,this._tasks=[],this._data=[],this._waiting=this._active=this._ended=this._start=0}function mg(a){if(!a._start)try{ng(a)}catch(b){if(a._tasks[a._ended+a._active-1])pg(a,b);else if(!a._data)throw b}}function ng(a){for(;a._start=a._waiting&&a._active=0;)if((c=a._tasks[d])&&(a._tasks[d]=null,c.abort))try{c.abort()}catch(b){}a._active=NaN,qg(a)}function qg(a){if(!a._active&&a._call){var b=a._data;a._data=void 0,a._call(a._error,b)}}function rg(a){return new lg(arguments.length?+a:1/0)}function sg(a){return function(b,c){a(null==b?c:null)}}function tg(a){var b=a.responseType;return b&&"text"!==b?a.response:a.responseText}function ug(a,b){return function(c){return a(c.responseText,b)}}function vg(a){function b(b){var f=b+"",g=c.get(f);if(!g){if(e!==At)return e;c.set(f,g=d.push(b))}return a[(g-1)%a.length]}var c=Oc(),d=[],e=At;return a=null==a?[]:zt.call(a),b.domain=function(a){if(!arguments.length)return d.slice();d=[],c=Oc();for(var e,f,g=-1,h=a.length;++g=c?1:d(a)}}}function Bg(a){return function(b,c){var d=a(b=+b,c=+c);return function(a){return a<=0?b:a>=1?c:d(a)}}}function Cg(a,b,c,d){var e=a[0],f=a[1],g=b[0],h=b[1];return f2?Dg:Cg,f=g=null,d}function d(b){return(f||(f=e(h,i,k?Ag(a):a,j)))(+b)}var e,f,g,h=Dt,i=Dt,j=wm,k=!1;return d.invert=function(a){return(g||(g=e(i,h,zg,k?Bg(b):b)))(+a)},d.domain=function(a){return arguments.length?(h=yt.call(a,Ct),c()):h.slice()},d.range=function(a){return arguments.length?(i=zt.call(a),c()):i.slice()},d.rangeRound=function(a){return i=zt.call(a),j=xm,c()},d.clamp=function(a){return arguments.length?(k=!!a,c()):k},d.interpolate=function(a){return arguments.length?(j=a,c()):j},c()}function Gg(a){var b=a.domain;return a.ticks=function(a){var c=b();return _j(c[0],c[c.length-1],null==a?10:a)},a.tickFormat=function(a,c){return Et(b(),a,c)},a.nice=function(c){var e=b(),f=e.length-1,g=null==c?10:c,h=e[0],i=e[f],j=d(h,i,g);return j&&(j=d(Math.floor(h/j)*j,Math.ceil(i/j)*j,g),e[0]=Math.floor(h/j)*j,e[f]=Math.ceil(i/j)*j,b(e)),a},a}function Hg(){var a=Fg(zg,rm);return a.copy=function(){return Eg(a,Hg())},Gg(a)}function Ig(){function a(a){return+a}var b=[0,1];return a.invert=a,a.domain=a.range=function(c){return arguments.length?(b=yt.call(c,Ct),a):b.slice()},a.copy=function(){return Ig().domain(b)},Gg(a)}function Jg(a,b){return(b=Math.log(b/a))?function(c){return Math.log(c/a)/b}:Bt(b)}function Kg(a,b){return a<0?function(c){return-Math.pow(-b,c)*Math.pow(-a,1-c)}:function(c){return Math.pow(b,c)*Math.pow(a,1-c)}}function Lg(a){return isFinite(a)?+("1e"+a):a<0?0:a}function Mg(a){return 10===a?Lg:a===Math.E?Math.exp:function(b){return Math.pow(a,b)}}function Ng(a){return a===Math.E?Math.log:10===a&&Math.log10||2===a&&Math.log2||(a=Math.log(a),function(b){return Math.log(b)/a})}function Og(a){return function(b){return-a(-b)}}function Pg(){function b(){return f=Ng(e),g=Mg(e),d()[0]<0&&(f=Og(f),g=Og(g)),c}var c=Fg(Jg,Kg).domain([1,10]),d=c.domain,e=10,f=Ng(10),g=Mg(10);return c.base=function(a){return arguments.length?(e=+a,b()):e},c.domain=function(a){return arguments.length?(d(a),b()):d()},c.ticks=function(a){var b,c=d(),h=c[0],i=c[c.length-1];(b=i0){for(;mi)break;p.push(l)}}else for(;m=1;--k)if(!((l=j*k)i)break;p.push(l)}}else p=_j(m,n,Math.min(n-m,o)).map(g);return b?p.reverse():p},c.tickFormat=function(b,d){if(null==d&&(d=10===e?".0e":","),"function"!=typeof d&&(d=a.format(d)),b===1/0)return d;null==b&&(b=10);var h=Math.max(1,e*b/c.ticks().length);return function(a){var b=a/g(Math.round(f(a)));return b*e0?e[b-1]:c[0],b=e?[f[e-1],d]:[f[b-1],f[b]]},a.copy=function(){return Ug().domain([c,d]).range(g)},Gg(a)}function Vg(){function a(a){if(a<=a)return c[Jj(b,a,0,d)]}var b=[.5],c=[0,1],d=1;return a.domain=function(e){return arguments.length?(b=zt.call(e),d=Math.min(b.length,c.length-1),a):b.slice()},a.range=function(e){return arguments.length?(c=zt.call(e),d=Math.min(b.length,c.length-1),a):c.slice()},a.invertExtent=function(a){var d=c.indexOf(a);return[b[d-1],b[d]]},a.copy=function(){return Vg().domain(b).range(c)},a}function Wg(a,b,c,d){function e(b){return a(b=new Date(+b)),b}return e.floor=e,e.ceil=function(c){return a(c=new Date(c-1)),b(c,1),a(c),c},e.round=function(a){var b=e(a),c=e.ceil(a);return a-b0))return g;do{g.push(new Date(+c))}while(b(c,f),a(c),c=b)for(;a(b),!c(b);)b.setTime(b-1)},function(a,d){if(a>=a)for(;--d>=0;)for(;b(a,1),!c(a););})},c&&(e.count=function(b,d){return Gt.setTime(+b),Ht.setTime(+d),a(Gt),a(Ht),Math.floor(c(Gt,Ht))},e.every=function(a){return a=Math.floor(a),isFinite(a)&&a>0?a>1?e.filter(d?function(b){return d(b)%a==0}:function(b){return e.count(0,b)%a==0}):e:null}),e}function Xg(a){return Wg(function(b){b.setDate(b.getDate()-(b.getDay()+7-a)%7),b.setHours(0,0,0,0)},function(a,b){a.setDate(a.getDate()+7*b)},function(a,b){return(b-a-(b.getTimezoneOffset()-a.getTimezoneOffset())*Kt)/Lt})}function Yg(a){return Wg(function(b){b.setUTCDate(b.getUTCDate()-(b.getUTCDay()+7-a)%7),b.setUTCHours(0,0,0,0)},function(a,b){a.setUTCDate(a.getUTCDate()+7*b)},function(a,b){return(b-a)/Lt})}function Zg(a){if(0<=a.y&&a.y<100){var b=new Date(-1,a.m,a.d,a.H,a.M,a.S,a.L);return b.setFullYear(a.y),b}return new Date(a.y,a.m,a.d,a.H,a.M,a.S,a.L)}function $g(a){if(0<=a.y&&a.y<100){var b=new Date(Date.UTC(-1,a.m,a.d,a.H,a.M,a.S,a.L));return b.setUTCFullYear(a.y),b}return new Date(Date.UTC(a.y,a.m,a.d,a.H,a.M,a.S,a.L))}function _g(a){return{y:a,m:0,d:1,H:0,M:0,S:0,L:0}}function ah(a){function b(a,b){return function(c){var d,e,f,g=[],h=-1,i=0,j=a.length +;for(c instanceof Date||(c=new Date(+c));++h=i)return-1;if(37===(e=b.charCodeAt(g++))){if(e=b.charAt(g++),!(f=Q[e in Ju?b.charAt(g++):e])||(d=f(a,c,d))<0)return-1}else if(e!=c.charCodeAt(d++))return-1}return d}function e(a,b,c){var d=E.exec(b.slice(c));return d?(a.p=F[d[0].toLowerCase()],c+d[0].length):-1}function f(a,b,c){var d=I.exec(b.slice(c));return d?(a.w=J[d[0].toLowerCase()],c+d[0].length):-1}function g(a,b,c){var d=G.exec(b.slice(c));return d?(a.w=H[d[0].toLowerCase()],c+d[0].length):-1}function h(a,b,c){var d=M.exec(b.slice(c));return d?(a.m=N[d[0].toLowerCase()],c+d[0].length):-1}function i(a,b,c){var d=K.exec(b.slice(c));return d?(a.m=L[d[0].toLowerCase()],c+d[0].length):-1}function j(a,b,c){return d(a,w,b,c)}function k(a,b,c){return d(a,x,b,c)}function l(a,b,c){return d(a,y,b,c)}function m(a){return B[a.getDay()]}function n(a){return A[a.getDay()]}function o(a){return D[a.getMonth()]}function p(a){return C[a.getMonth()]}function q(a){return z[+(a.getHours()>=12)]}function r(a){return B[a.getUTCDay()]}function s(a){return A[a.getUTCDay()]}function t(a){return D[a.getUTCMonth()]}function u(a){return C[a.getUTCMonth()]}function v(a){return z[+(a.getUTCHours()>=12)]}var w=a.dateTime,x=a.date,y=a.time,z=a.periods,A=a.days,B=a.shortDays,C=a.months,D=a.shortMonths,E=dh(z),F=eh(z),G=dh(A),H=eh(A),I=dh(B),J=eh(B),K=dh(C),L=eh(C),M=dh(D),N=eh(D),O={a:m,A:n,b:o,B:p,c:null,d:th,e:th,H:uh,I:vh,j:wh,L:xh,m:yh,M:zh,p:q,S:Ah,U:Bh,w:Ch,W:Dh,x:null,X:null,y:Eh,Y:Fh,Z:Gh,"%":Vh},P={a:r,A:s,b:t,B:u,c:null,d:Hh,e:Hh,H:Ih,I:Jh,j:Kh,L:Lh,m:Mh,M:Nh,p:v,S:Oh,U:Ph,w:Qh,W:Rh,x:null,X:null,y:Sh,Y:Th,Z:Uh,"%":Vh},Q={a:f,A:g,b:h,B:i,c:j,d:mh,e:mh,H:oh,I:oh,j:nh,L:rh,m:lh,M:ph,p:e,S:qh,U:gh,w:fh,W:hh,x:k,X:l,y:jh,Y:ih,Z:kh,"%":sh};return O.x=b(x,O),O.X=b(y,O),O.c=b(w,O),P.x=b(x,P),P.X=b(y,P),P.c=b(w,P),{format:function(a){var c=b(a+="",O);return c.toString=function(){return a},c},parse:function(a){var b=c(a+="",Zg);return b.toString=function(){return a},b},utcFormat:function(a){var c=b(a+="",P);return c.toString=function(){return a},c},utcParse:function(a){var b=c(a,$g);return b.toString=function(){return a},b}}}function bh(a,b,c){var d=a<0?"-":"",e=(d?-a:a)+"",f=e.length;return d+(f68?1900:2e3),c+d[0].length):-1}function kh(a,b,c){var d=/^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(b.slice(c,c+6));return d?(a.Z=d[1]?0:-(d[2]+(d[3]||"00")),c+d[0].length):-1}function lh(a,b,c){var d=Ku.exec(b.slice(c,c+2));return d?(a.m=d[0]-1,c+d[0].length):-1}function mh(a,b,c){var d=Ku.exec(b.slice(c,c+2));return d?(a.d=+d[0],c+d[0].length):-1}function nh(a,b,c){var d=Ku.exec(b.slice(c,c+3));return d?(a.m=0,a.d=+d[0],c+d[0].length):-1}function oh(a,b,c){var d=Ku.exec(b.slice(c,c+2));return d?(a.H=+d[0],c+d[0].length):-1}function ph(a,b,c){var d=Ku.exec(b.slice(c,c+2));return d?(a.M=+d[0],c+d[0].length):-1}function qh(a,b,c){var d=Ku.exec(b.slice(c,c+2));return d?(a.S=+d[0],c+d[0].length):-1}function rh(a,b,c){var d=Ku.exec(b.slice(c,c+3));return d?(a.L=+d[0],c+d[0].length):-1}function sh(a,b,c){var d=Lu.exec(b.slice(c,c+1));return d?c+d[0].length:-1}function th(a,b){return bh(a.getDate(),b,2)}function uh(a,b){return bh(a.getHours(),b,2)}function vh(a,b){return bh(a.getHours()%12||12,b,2)}function wh(a,b){return bh(1+St.count(iu(a),a),b,3)}function xh(a,b){return bh(a.getMilliseconds(),b,3)}function yh(a,b){return bh(a.getMonth()+1,b,2)}function zh(a,b){return bh(a.getMinutes(),b,2)}function Ah(a,b){return bh(a.getSeconds(),b,2)}function Bh(a,b){return bh(Ut.count(iu(a),a),b,2)}function Ch(a){return a.getDay()}function Dh(a,b){return bh(Vt.count(iu(a),a),b,2)}function Eh(a,b){return bh(a.getFullYear()%100,b,2)}function Fh(a,b){return bh(a.getFullYear()%1e4,b,4)}function Gh(a){var b=a.getTimezoneOffset();return(b>0?"-":(b*=-1,"+"))+bh(b/60|0,"0",2)+bh(b%60,"0",2)}function Hh(a,b){return bh(a.getUTCDate(),b,2)}function Ih(a,b){return bh(a.getUTCHours(),b,2)}function Jh(a,b){return bh(a.getUTCHours()%12||12,b,2)}function Kh(a,b){return bh(1+ou.count(Gu(a),a),b,3)}function Lh(a,b){return bh(a.getUTCMilliseconds(),b,3)}function Mh(a,b){return bh(a.getUTCMonth()+1,b,2)}function Nh(a,b){return bh(a.getUTCMinutes(),b,2)}function Oh(a,b){return bh(a.getUTCSeconds(),b,2)}function Ph(a,b){return bh(qu.count(Gu(a),a),b,2)}function Qh(a){return a.getUTCDay()}function Rh(a,b){return bh(ru.count(Gu(a),a),b,2)}function Sh(a,b){return bh(a.getUTCFullYear()%100,b,2)}function Th(a,b){return bh(a.getUTCFullYear()%1e4,b,4)}function Uh(){return"+0000"}function Vh(){return"%"}function Wh(b){return Hu=ah(b),a.timeFormat=Hu.format,a.timeParse=Hu.parse,a.utcFormat=Hu.utcFormat,a.utcParse=Hu.utcParse,Hu}function Xh(a){return a.toISOString()}function Yh(a){var b=new Date(a);return isNaN(b)?null:b}function Zh(a){return new Date(a)}function $h(a){return a instanceof Date?+a:+new Date(+a)}function _h(a,b,c,e,f,g,h,i,j){function k(d){return(h(d)1?0:a<-1?tv:Math.acos(a)}function di(a){return a>=1?uv:a<=-1?-uv:Math.asin(a)}function ei(a){return a.innerRadius}function fi(a){return a.outerRadius}function gi(a){return a.startAngle}function hi(a){return a.endAngle}function ii(a){return a&&a.padAngle}function ji(a,b,c,d,e,f,g,h){var i=c-a,j=d-b,k=g-e,l=h-f,m=(k*(b-f)-l*(a-e))/(l*i-k*j);return[a+m*i,b+m*j]}function ki(a,b,c,d,e,f,g){var h=a-c,i=b-d,j=(g?f:-f)/rv(h*h+i*i),k=j*i,l=-j*h,m=a+k,n=b+l,o=c+k,p=d+l,q=(m+o)/2,r=(n+p)/2,s=o-m,t=p-n,u=s*s+t*t,v=e-f,w=m*p-o*n,x=(t<0?-1:1)*rv(ov(0,v*v*u-w*w)),y=(w*t-s*x)/u,z=(-w*s-t*x)/u,A=(w*t+s*x)/u,B=(-w*s+t*x)/u,C=y-q,D=z-r,E=A-q,F=B-r;return C*C+D*D>E*E+F*F&&(y=A,z=B),{cx:y,cy:z,x01:-k,y01:-l,x11:y*(e/v-1),y11:z*(e/v-1)}}function li(a){this._context=a}function mi(a){return a[0]}function ni(a){return a[1]}function oi(a){this._curve=a}function pi(a){function b(b){return new oi(a(b))}return b._curve=a,b}function qi(a){var b=a.curve;return a.angle=a.x,delete a.x,a.radius=a.y,delete a.y,a.curve=function(a){return arguments.length?b(pi(a)):b()._curve},a}function ri(a,b,c){a._context.bezierCurveTo((2*a._x0+a._x1)/3,(2*a._y0+a._y1)/3,(a._x0+2*a._x1)/3,(a._y0+2*a._y1)/3,(a._x0+4*a._x1+b)/6,(a._y0+4*a._y1+c)/6)}function si(a){this._context=a}function ti(a){this._context=a}function ui(a){this._context=a}function vi(a,b){this._basis=new si(a),this._beta=b}function wi(a,b,c){a._context.bezierCurveTo(a._x1+a._k*(a._x2-a._x0),a._y1+a._k*(a._y2-a._y0),a._x2+a._k*(a._x1-b),a._y2+a._k*(a._y1-c),a._x2,a._y2)}function xi(a,b){this._context=a,this._k=(1-b)/6}function yi(a,b){this._context=a,this._k=(1-b)/6}function zi(a,b){this._context=a,this._k=(1-b)/6}function Ai(a,b,c){var d=a._x1,e=a._y1,f=a._x2,g=a._y2;if(a._l01_a>sv){var h=2*a._l01_2a+3*a._l01_a*a._l12_a+a._l12_2a,i=3*a._l01_a*(a._l01_a+a._l12_a);d=(d*h-a._x0*a._l12_2a+a._x2*a._l01_2a)/i,e=(e*h-a._y0*a._l12_2a+a._y2*a._l01_2a)/i}if(a._l23_a>sv){var j=2*a._l23_2a+3*a._l23_a*a._l12_a+a._l12_2a,k=3*a._l23_a*(a._l23_a+a._l12_a);f=(f*j+a._x1*a._l23_2a-b*a._l12_2a)/k,g=(g*j+a._y1*a._l23_2a-c*a._l12_2a)/k}a._context.bezierCurveTo(d,e,f,g,a._x2,a._y2)}function Bi(a,b){this._context=a,this._alpha=b}function Ci(a,b){this._context=a,this._alpha=b}function Di(a,b){this._context=a,this._alpha=b}function Ei(a){this._context=a}function Fi(a){return a<0?-1:1}function Gi(a,b,c){var d=a._x1-a._x0,e=b-a._x1,f=(a._y1-a._y0)/(d||e<0&&-0),g=(c-a._y1)/(e||d<0&&-0),h=(f*e+g*d)/(d+e);return(Fi(f)+Fi(g))*Math.min(Math.abs(f),Math.abs(g),.5*Math.abs(h))||0}function Hi(a,b){var c=a._x1-a._x0;return c?(3*(a._y1-a._y0)/c-b)/2:b}function Ii(a,b,c){var d=a._x0,e=a._y0,f=a._x1,g=a._y1,h=(f-d)/3;a._context.bezierCurveTo(d+h,e+h*b,f-h,g-h*c,f,g)}function Ji(a){this._context=a}function Ki(a){this._context=new Li(a)}function Li(a){this._context=a}function Mi(a){return new Ji(a)}function Ni(a){return new Ki(a)}function Oi(a){this._context=a}function Pi(a){var b,c,d=a.length-1,e=new Array(d),f=new Array(d),g=new Array(d);for(e[0]=0,f[0]=2,g[0]=a[0]+2*a[1],b=1;b=0;--b)e[b]=(g[b]-e[b+1])/f[b];for(f[d-1]=(a[d]+e[d-1])/2,b=0;b0)){if(f/=o,o<0){if(f0){if(f>n)return;f>m&&(m=f)}if(f=d-i,o||!(f<0)){if(f/=o,o<0){if(f>n)return;f>m&&(m=f)}else if(o>0){if(f0)){if(f/=p,p<0){if(f0){if(f>n)return;f>m&&(m=f)}if(f=e-j,p||!(f<0)){if(f/=p,p<0){if(f>n)return;f>m&&(m=f)}else if(p>0){if(f0||n<1)||(m>0&&(a[0]=[i+m*o,j+m*p]),n<1&&(a[1]=[i+n*o,j+n*p]),!0)}}}}}function ej(a,b,c,d,e){var f=a[1];if(f)return!0;var g,h,i=a[0],j=a.left,k=a.right,l=j[0],m=j[1],n=k[0],o=k[1],p=(l+n)/2,q=(m+o)/2;if(o===m){if(p=d)return;if(l>n){if(i){if(i[1]>=e)return}else i=[p,c];f=[p,e]}else{if(i){if(i[1]1)if(l>n){if(i){if(i[1]>=e)return}else i=[(c-h)/g,c];f=[(e-h)/g,e]}else{if(i){if(i[1]=d)return}else i=[b,g*b+h];f=[d,g*d+h]}else{if(i){if(i[0]Ew||Math.abs(e[0][1]-e[1][1])>Ew)||delete Bw[f]}function gj(a){return zw[a.index]={site:a,halfedges:[]}}function hj(a,b){var c=a.site,d=b.left,e=b.right;return c===e&&(e=d,d=c),e?Math.atan2(e[1]-d[1],e[0]-d[0]):(c===d?(d=b[1],e=b[0]):(d=b[0],e=b[1]),Math.atan2(d[0]-e[0],e[1]-d[1]))}function ij(a,b){return b[+(b.left!==a.site)]}function jj(a,b){return b[+(b.left===a.site)]}function kj(){for(var a,b,c,d,e=0,f=zw.length;eEw||Math.abs(p-m)>Ew)&&(i.splice(h,0,Bw.push(bj(g,n,Math.abs(o-a)Ew?[a,Math.abs(l-a)Ew?[Math.abs(m-d)Ew?[c,Math.abs(l-c)Ew?[Math.abs(m-b)=-Fw)){var n=i*i+j*j,o=k*k+l*l,p=(l*n-j*o)/m,q=(i*o-k*n)/m,r=Cw.pop()||new mj;r.arc=a,r.site=e,r.x=p+g,r.y=(r.cy=q+h)+Math.sqrt(p*p+q*q),a.circle=r;for(var s=null,t=Aw._;t;)if(r.yEw)h=h.L;else{if(!((e=f-vj(h,g))>Ew)){d>-Ew?(b=h.P,c=h):e>-Ew?(b=h,c=h.N):b=c=h;break}if(!h.R){b=h;break}h=h.R}gj(a);var i=qj(a);if(yw.insert(b,i),b||c){if(b===c)return oj(b),c=qj(b.site),yw.insert(i,c),i.edge=c.edge=aj(b.site,i.site),nj(b),void nj(c);if(!c)return void(i.edge=aj(b.site,i.site));oj(b),oj(c);var j=b.site,k=j[0],l=j[1],m=a[0]-k,n=a[1]-l,o=c.site,p=o[0]-k,q=o[1]-l,r=2*(m*q-n*p),s=m*m+n*n,t=p*p+q*q,u=[(q*s-n*t)/r+k,(m*t-p*s)/r+l];cj(c.edge,j,o,u),i.edge=aj(j,a,null,u),c.edge=aj(a,o,null,u),nj(b),nj(c)}}function uj(a,b){var c=a.site,d=c[0],e=c[1],f=e-b;if(!f)return d;var g=a.P;if(!g)return-1/0;c=g.site;var h=c[0],i=c[1],j=i-b;if(!j)return h;var k=h-d,l=1/f-1/j,m=k/j;return l?(-m+Math.sqrt(m*m-2*l*(k*k/(-2*j)-i+j/2+e-f/2)))/l+d:(d+h)/2}function vj(a,b){var c=a.N;if(c)return uj(c,b);var d=a.site;return d[1]===b?d[0]:1/0}function wj(a,b,c){return(a[0]-c[0])*(b[1]-a[1])-(a[0]-b[0])*(c[1]-a[1])}function xj(a,b){return b[1]-a[1]||b[0]-a[0]}function yj(a,b){var c,d,e,f=a.sort(xj).pop();for(Bw=[],zw=new Array(a.length),yw=new Xi,Aw=new Xi;;)if(e=xw,f&&(!e||f[1]b?1:a>=b?0:NaN},Hj=function(a){return 1===a.length&&(a=b(a)),{left:function(b,c,d,e){for(null==d&&(d=0),null==e&&(e=b.length);d>>1;a(b[f],c)<0?d=f+1:e=f}return d},right:function(b,c,d,e){for(null==d&&(d=0),null==e&&(e=b.length);d>>1;a(b[f],c)>0?e=f:d=f+1}return d}}},Ij=Hj(Gj),Jj=Ij.right,Kj=Ij.left,Lj=function(a,b){null==b&&(b=c);for(var d=0,e=a.length-1,f=a[0],g=new Array(e<0?0:e);da?1:b>=a?0:NaN},Oj=function(a){return null===a?NaN:+a},Pj=function(a,b){var c,d,e=a.length,f=0,g=0,h=-1,i=0;if(null==b)for(;++h1)return g/(i-1)},Qj=function(a,b){var c=Pj(a,b);return c?Math.sqrt(c):c},Rj=function(a,b){var c,d,e,f=-1,g=a.length;if(null==b){for(;++f=d){c=e=d;break}for(;++fd&&(c=d),e=d){c=e=d;break}for(;++fd&&(c=d),e=k;)l.pop(),--m;var n,o=new Array(m+1);for(e=0;e<=m;++e)n=o[e]=[],n.x0=e>0?l[e-1]:j,n.x1=e=1)return+c(a[d-1],d-1,a);var d,e=(d-1)*b,f=Math.floor(e),g=+c(a[f],f,a);return g+(+c(a[f+1],f+1,a)-g)*(e-f)}},dk=function(a,b,c){return a=Uj.call(a,Oj).sort(Gj),Math.ceil((c-b)/(2*(ck(a,.75)-ck(a,.25))*Math.pow(a.length,-1/3)))},ek=function(a,b,c){return Math.ceil((c-b)/(3.5*Qj(a)*Math.pow(a.length,-1/3)))},fk=function(a,b){var c,d,e=-1,f=a.length;if(null==b){for(;++e=d){c=d;break}for(;++ec&&(c=d)}else{for(;++e=d){c=d;break}for(;++ec&&(c=d)}return c},gk=function(a,b){var c,d=0,e=a.length,f=-1,g=e;if(null==b)for(;++f=0;)for(d=a[e],b=d.length;--b>=0;)c[--g]=d[b];return c},jk=function(a,b){var c,d,e=-1,f=a.length;if(null==b){for(;++e=d){c=d;break}for(;++ed&&(c=d)}else{for(;++e=d){c=d;break}for(;++ed&&(c=d)}return c},kk=function(a,b){for(var c=b.length,d=new Array(c);c--;)d[c]=a[b[c]];return d},lk=function(a,b){if(c=a.length){var c,d,e=0,f=0,g=a[f];for(b||(b=Gj);++e0)for(var c,d,e=new Array(c),f=0;f=0&&"xmlns"!==(b=a.slice(0,c))&&(a=a.slice(c+1)),zk.hasOwnProperty(b)?{space:zk[b],local:a}:a},Bk=function(a){var b=Ak(a);return(b.local?u:t)(b)},Ck=0;w.prototype=v.prototype={constructor:w,get:function(a){for(var b=this._;!(b in a);)if(!(a=a.parentNode))return;return a[b]},set:function(a,b){return a[this._]=b},remove:function(a){return this._ in a&&delete a[this._]},toString:function(){return this._}};var Dk=function(a){return function(){return this.matches(a)}};if("undefined"!=typeof document){var Ek=document.documentElement;if(!Ek.matches){var Fk=Ek.webkitMatchesSelector||Ek.msMatchesSelector||Ek.mozMatchesSelector||Ek.oMatchesSelector;Dk=function(a){return function(){return Fk.call(this,a)}}}}var Gk=Dk,Hk={};if(a.event=null,"undefined"!=typeof document){"onmouseenter"in document.documentElement||(Hk={mouseenter:"mouseover",mouseleave:"mouseout"})}var Ik=function(a,b,c){var d,e,f=z(a+""),g=f.length;{if(!(arguments.length<2)){for(h=b?B:A,null==c&&(c=!1),d=0;d=u&&(u=t+1);!(s=q[u])&&++u=0;)(d=e[f])&&(g&&g!==d.nextSibling&&g.parentNode.insertBefore(d,g),g=d);return this},Zk=function(a){function b(b,c){return b&&c?a(b.__data__,c.__data__):!b-!c}a||(a=I);for(var c=this._groups,d=c.length,e=new Array(d),f=0;f1?this.each((null==b?P:"function"==typeof b?R:Q)(a,b,null==c?"":c)):fl(d=this.node()).getComputedStyle(d,null).getPropertyValue(a)},hl=function(a,b){return arguments.length>1?this.each((null==b?S:"function"==typeof b?U:T)(a,b)):this.node()[a]};X.prototype={add:function(a){this._names.indexOf(a)<0&&(this._names.push(a),this._node.setAttribute("class",this._names.join(" ")))},remove:function(a){var b=this._names.indexOf(a);b>=0&&(this._names.splice(b,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(a){return this._names.indexOf(a)>=0}};var il=function(a,b){var c=V(a+"");if(arguments.length<2){for(var d=W(this.node()),e=-1,f=c.length;++e=240?a-240:a+120,e,d),Ia(a,e,d),Ia(a<120?a+240:a-120,e,d),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var Ol=Math.PI/180,Pl=180/Math.PI,Ql=.95047,Rl=1,Sl=1.08883,Tl=4/29,Ul=6/29,Vl=3*Ul*Ul,Wl=Ul*Ul*Ul;Bl(La,Ka,wa(xa,{brighter:function(a){return new La(this.l+18*(null==a?1:a),this.a,this.b,this.opacity)},darker:function(a){return new La(this.l-18*(null==a?1:a),this.a,this.b,this.opacity)},rgb:function(){var a=(this.l+16)/116,b=isNaN(this.a)?a:a+this.a/500,c=isNaN(this.b)?a:a-this.b/200;return a=Rl*Na(a),b=Ql*Na(b),c=Sl*Na(c),new Da(Oa(3.2404542*b-1.5371385*a-.4985314*c),Oa(-.969266*b+1.8760108*a+.041556*c),Oa(.0556434*b-.2040259*a+1.0572252*c),this.opacity)}})),Bl(Sa,Ra,wa(xa,{brighter:function(a){return new Sa(this.h,this.c,this.l+18*(null==a?1:a),this.opacity)},darker:function(a){return new Sa(this.h,this.c,this.l-18*(null==a?1:a),this.opacity)},rgb:function(){return Ja(this).rgb()}}));var Xl=-.14861,Yl=1.78277,Zl=-.29227,$l=-.90649,_l=1.97294,am=_l*$l,bm=_l*Yl,cm=Yl*Zl-$l*Xl;Bl(Va,Ua,wa(xa,{brighter:function(a){return a=null==a?1/.7:Math.pow(1/.7,a),new Va(this.h,this.s,this.l*a,this.opacity)},darker:function(a){return a=null==a?.7:Math.pow(.7,a),new Va(this.h,this.s,this.l*a,this.opacity)},rgb:function(){var a=isNaN(this.h)?0:(this.h+120)*Ol,b=+this.l,c=isNaN(this.s)?0:this.s*b*(1-b),d=Math.cos(a),e=Math.sin(a);return new Da(255*(b+c*(Xl*d+Yl*e)),255*(b+c*(Zl*d+$l*e)),255*(b+c*(_l*d)),this.opacity)}}));var dm,em,fm,gm,hm,im,jm=function(a){var b=a.length-1;return function(c){var d=c<=0?c=0:c>=1?(c=1,b-1):Math.floor(c*b),e=a[d],f=a[d+1],g=d>0?a[d-1]:2*e-f,h=df&&(e=b.slice(f,e),h[g]?h[g]+=e:h[++g]=e),(c=c[0])===(d=d[0])?h[g]?h[g]+=d:h[++g]=d:(h[++g]=null,i.push({i:g,x:rm(c,d)})),f=um.lastIndex;return f_m&&c.state$m&&c.name===b)return new $b([[a]],_n,b,+d)}return null},bo=function(a){return function(){return a}},co=function(a,b,c){this.target=a,this.type=b,this.selection=c},eo=function(){a.event.preventDefault(),a.event.stopImmediatePropagation()},fo={name:"drag"},go={name:"space"},ho={name:"handle"},io={name:"center"},jo={name:"x",handles:["e","w"].map(wc),input:function(a,b){return a&&[[a[0],b[0][1]],[a[1],b[1][1]]]},output:function(a){return a&&[a[0][0],a[1][0]]}},ko={name:"y",handles:["n","s"].map(wc),input:function(a,b){return a&&[[b[0][0],a[0]],[b[1][0],a[1]]]},output:function(a){return a&&[a[0][1],a[1][1]]}},lo={name:"xy",handles:["n","e","s","w","nw","ne","se","sw"].map(wc),input:function(a){return a},output:function(a){return a}},mo={overlay:"crosshair",selection:"move",n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},no={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},oo={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},po={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},qo={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1},ro=function(){return Ec(lo)},so=Math.cos,to=Math.sin,uo=Math.PI,vo=uo/2,wo=2*uo,xo=Math.max,yo=function(){function a(a){var f,g,h,i,j,k,l=a.length,m=[],n=Xj(l),o=[],p=[],q=p.groups=new Array(l),r=new Array(l*l);for(f=0,j=-1;++j1e-6)if(Math.abs(k*h-i*j)>1e-6&&e){var m=c-f,n=d-g,o=h*h+i*i,p=m*m+n*n,q=Math.sqrt(o),r=Math.sqrt(l),s=e*Math.tan((Bo-Math.acos((o+l-p)/(2*q*r)))/2),t=s/r,u=s/q;Math.abs(t-1)>1e-6&&(this._+="L"+(a+t*j)+","+(b+t*k)),this._+="A"+e+","+e+",0,0,"+ +(k*m>j*n)+","+(this._x1=a+u*h)+","+(this._y1=b+u*i)}else this._+="L"+(this._x1=a)+","+(this._y1=b);else;},arc:function(a,b,c,d,e,f){a=+a,b=+b,c=+c;var g=c*Math.cos(d),h=c*Math.sin(d),i=a+g,j=b+h,k=1^f,l=f?d-e:e-d;if(c<0)throw new Error("negative radius: "+c);null===this._x1?this._+="M"+i+","+j:(Math.abs(this._x1-i)>1e-6||Math.abs(this._y1-j)>1e-6)&&(this._+="L"+i+","+j),c&&(l<0&&(l=l%Co+Co),l>Do?this._+="A"+c+","+c+",0,1,"+k+","+(a-g)+","+(b-h)+"A"+c+","+c+",0,1,"+k+","+(this._x1=i)+","+(this._y1=j):l>1e-6&&(this._+="A"+c+","+c+",0,"+ +(l>=Bo)+","+k+","+(this._x1=a+c*Math.cos(e))+","+(this._y1=b+c*Math.sin(e))))},rect:function(a,b,c,d){this._+="M"+(this._x0=this._x1=+a)+","+(this._y0=this._y1=+b)+"h"+ +c+"v"+ +d+"h"+-c+"Z"},toString:function(){return this._}};var Eo=function(){function a(){var a,h=zo.call(arguments),i=b.apply(this,h),j=c.apply(this,h),k=+d.apply(this,(h[0]=i,h)),l=e.apply(this,h)-vo,m=f.apply(this,h)-vo,n=k*so(l),o=k*to(l),p=+d.apply(this,(h[0]=j,h)),q=e.apply(this,h)-vo,r=f.apply(this,h)-vo;if(g||(g=a=Hc()),g.moveTo(n,o),g.arc(0,0,k,l,m),l===q&&m===r||(g.quadraticCurveTo(0,0,p*so(q),p*to(q)),g.arc(0,0,p,q,r)),g.quadraticCurveTo(0,0,n,o),g.closePath(),a)return g=null,a+""||null}var b=Ic,c=Jc,d=Kc,e=Lc,f=Mc,g=null;return a.radius=function(b){return arguments.length?(d="function"==typeof b?b:Ao(+b),a):d},a.startAngle=function(b){return arguments.length?(e="function"==typeof b?b:Ao(+b),a):e},a.endAngle=function(b){return arguments.length?(f="function"==typeof b?b:Ao(+b),a):f},a.source=function(c){return arguments.length?(b=c,a):b},a.target=function(b){return arguments.length?(c=b,a):c},a.context=function(b){return arguments.length?(g=null==b?null:b,a):g},a};Nc.prototype=Oc.prototype={constructor:Nc,has:function(a){return"$"+a in this},get:function(a){return this["$"+a]},set:function(a,b){return this["$"+a]=b,this},remove:function(a){var b="$"+a;return b in this&&delete this[b]},clear:function(){for(var a in this)"$"===a[0]&&delete this[a]},keys:function(){var a=[];for(var b in this)"$"===b[0]&&a.push(b.slice(1));return a},values:function(){var a=[];for(var b in this)"$"===b[0]&&a.push(this[b]);return a},entries:function(){var a=[];for(var b in this)"$"===b[0]&&a.push({key:b.slice(1),value:this[b]});return a},size:function(){var a=0;for(var b in this)"$"===b[0]&&++a;return a},empty:function(){for(var a in this)if("$"===a[0])return!1;return!0},each:function(a){for(var b in this)"$"===b[0]&&a(this[b],b.slice(1),this)}};var Fo=function(){function a(b,e,g,h){if(e>=f.length)return null!=d?d(b):null!=c?b.sort(c):b;for(var i,j,k,l=-1,m=b.length,n=f[e++],o=Oc(),p=g();++lf.length)return a;var e,h=g[c-1];return null!=d&&c>=f.length?e=a.entries():(e=[],a.each(function(a,d){e.push({key:d,values:b(a,c)})})),null!=h?e.sort(function(a,b){return h(a.key,b.key)}):e}var c,d,e,f=[],g=[];return e={object:function(b){return a(b,0,Pc,Qc)},map:function(b){return a(b,0,Rc,Sc)},entries:function(c){return b(a(c,0,Rc,Sc),0)},key:function(a){return f.push(a),e},sortKeys:function(a){return g[f.length-1]=a,e},sortValues:function(a){return c=a,e},rollup:function(a){return d=a,e}}},Go=Oc.prototype;Tc.prototype=Uc.prototype={constructor:Tc,has:Go.has,add:function(a){return a+="",this["$"+a]=a,this},remove:Go.remove,clear:Go.clear,values:Go.keys,size:Go.size,empty:Go.empty,each:Go.each};var Ho=function(a){var b=[];for(var c in a)b.push(c);return b},Io=function(a){var b=[];for(var c in a)b.push(a[c]);return b},Jo=function(a){var b=[];for(var c in a)b.push({key:c,value:a[c]});return b},Ko=function(a){function b(a,b){var d,e,f=c(a,function(a,c){if(d)return d(a,c-1);e=a,d=b?Wc(a,b):Vc(a)});return f.columns=e,f}function c(a,b){function c(){if(k>=j)return g;if(e)return e=!1,f;var b,c=k;if(34===a.charCodeAt(c)){for(var d=c;d++a||a>e||d>b||b>f))return this;var g,h,i=e-c,j=this._root;switch(h=(b<(d+f)/2)<<1|a<(c+e)/2){case 0:do{g=new Array(4),g[h]=j,j=g}while(i*=2,e=c+i,f=d+i,a>e||b>f);break;case 1:do{g=new Array(4),g[h]=j,j=g}while(i*=2,c=e-i,f=d+i,c>a||b>f);break;case 2:do{g=new Array(4),g[h]=j,j=g}while(i*=2,e=c+i,d=f-i,a>e||d>b);break;case 3:do{g=new Array(4),g[h]=j,j=g}while(i*=2,c=e-i,d=f-i,c>a||d>b)}this._root&&this._root.length&&(this._root=j)}return this._x0=c,this._y0=d,this._x1=e,this._y1=f,this},$o=function(){var a=[];return this.visit(function(b){if(!b.length)do{a.push(b.data)}while(b=b.next)}),a},_o=function(a){return arguments.length?this.cover(+a[0][0],+a[0][1]).cover(+a[1][0],+a[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},ap=function(a,b,c,d,e){this.node=a,this.x0=b,this.y0=c,this.x1=d,this.y1=e},bp=function(a,b,c){var d,e,f,g,h,i,j,k=this._x0,l=this._y0,m=this._x1,n=this._y1,o=[],p=this._root;for(p&&o.push(new ap(p,k,l,m,n)),null==c?c=1/0:(k=a-c,l=b-c,m=a+c,n=b+c,c*=c);i=o.pop();)if(!(!(p=i.node)||(e=i.x0)>m||(f=i.y0)>n||(g=i.x1)=r)<<1|a>=q)&&(i=o[o.length-1],o[o.length-1]=o[o.length-1-j],o[o.length-1-j]=i)}else{var s=a-+this._x.call(null,p.data),t=b-+this._y.call(null,p.data),u=s*s+t*t;if(u=(h=(o+q)/2))?o=h:q=h,(k=g>=(i=(p+r)/2))?p=i:r=i,b=n,!(n=n[l=k<<1|j]))return this;if(!n.length)break;(b[l+1&3]||b[l+2&3]||b[l+3&3])&&(c=b,m=l)}for(;n.data!==a;)if(d=n,!(n=n.next))return this;return(e=n.next)&&delete n.next,d?(e?d.next=e:delete d.next,this):b?(e?b[l]=e:delete b[l],(n=b[0]||b[1]||b[2]||b[3])&&n===(b[3]||b[2]||b[1]||b[0])&&!n.length&&(c?c[m]=n:this._root=n),this):(this._root=e,this)},dp=function(){return this._root},ep=function(){var a=0;return this.visit(function(b){if(!b.length)do{++a}while(b=b.next)}),a},fp=function(a){var b,c,d,e,f,g,h=[],i=this._root;for(i&&h.push(new ap(i,this._x0,this._y0,this._x1,this._y1));b=h.pop();)if(!a(i=b.node,d=b.x0,e=b.y0,f=b.x1,g=b.y1)&&i.length){var j=(d+f)/2,k=(e+g)/2;(c=i[3])&&h.push(new ap(c,j,k,f,g)),(c=i[2])&&h.push(new ap(c,d,k,j,g)),(c=i[1])&&h.push(new ap(c,j,e,f,k)),(c=i[0])&&h.push(new ap(c,d,e,j,k))}return this},gp=function(a){var b,c=[],d=[];for(this._root&&c.push(new ap(this._root,this._x0,this._y0,this._x1,this._y1));b=c.pop();){var e=b.node;if(e.length){var f,g=b.x0,h=b.y0,i=b.x1,j=b.y1,k=(g+i)/2,l=(h+j)/2;(f=e[0])&&c.push(new ap(f,g,h,k,l)),(f=e[1])&&c.push(new ap(f,k,h,i,l)),(f=e[2])&&c.push(new ap(f,g,l,k,j)),(f=e[3])&&c.push(new ap(f,k,l,i,j))}d.push(b)}for(;b=d.pop();)a(b.node,b.x0,b.y0,b.x1,b.y1);return this},hp=function(a){return arguments.length?(this._x=a,this):this._x},ip=function(a){return arguments.length?(this._y=a,this):this._y},jp=bd.prototype=cd.prototype;jp.copy=function(){var a,b,c=new cd(this._x,this._y,this._x0,this._y0,this._x1,this._y1),d=this._root;if(!d)return c;if(!d.length)return c._root=dd(d),c;for(a=[{source:d,target:c._root=new Array(4)}];d=a.pop();)for(var e=0;e<4;++e)(b=d.source[e])&&(b.length?a.push({source:b,target:d.target[e]=new Array(4)}):d.target[e]=dd(b));return c},jp.add=Yo,jp.addAll=Zc,jp.cover=Zo,jp.data=$o,jp.extent=_o,jp.find=bp,jp.remove=cp,jp.removeAll=$c,jp.root=dp,jp.size=ep,jp.visit=fp,jp.visitAfter=gp,jp.x=hp,jp.y=ip;var kp,lp=function(a){function b(){function a(a,b,c,d,e){var f=a.data,h=a.r,n=l+h;{if(!f)return b>j+n||dk+n||ei.index){var o=j-f.x-f.vx,p=k-f.y-f.vy,q=o*o+p*p;qa.r&&(a.r=a[b].r)}function d(){if(e){var b,c,d=e.length;for(f=new Array(d),b=0;b1?(null==b?l.remove(a):l.set(a,e(b)),f):l.get(a)},find:function(b,c,d){var e,f,g,h,i,j=0,k=a.length;for(null==d?d=1/0:d*=d,j=0;j1?(n.on(a,b),f):n.on(a)}}},qp=function(){function a(a){var b,h=e.length,i=bd(e,id,jd).visitAfter(c);for(g=a,b=0;b=k)){(a.data!==f||a.next)&&(0===e&&(e=Xo(),n+=e*e),0===i&&(i=Xo(),n+=i*i),n1?d[0]+d.slice(2):d,+a.slice(c+1)]},up=function(a){return a=tp(Math.abs(a)),a?a[1]:NaN},vp=function(a,b){return function(c,d){for(var e=c.length,f=[],g=0,h=a[0],i=0;e>0&&h>0&&(i+h+1>d&&(h=Math.max(1,d-i)),f.push(c.substring(e-=h,e+h)),!((i+=h+1)>d));)h=a[g=(g+1)%a.length];return f.reverse().join(b)}},wp=function(a){return function(b){return b.replace(/[0-9]/g,function(b){return a[+b]})}},xp=function(a,b){a=a.toPrecision(b);a:for(var c,d=a.length,e=1,f=-1;e0&&(f=0)}return f>0?a.slice(0,f)+a.slice(c+1):a},yp=function(a,b){var c=tp(a,b);if(!c)return a+"";var d=c[0],e=c[1],f=e-(kp=3*Math.max(-8,Math.min(8,Math.floor(e/3))))+1,g=d.length;return f===g?d:f>g?d+new Array(f-g+1).join("0"):f>0?d.slice(0,f)+"."+d.slice(f):"0."+new Array(1-f).join("0")+tp(a,Math.max(0,b+f-1))[0]},zp=function(a,b){var c=tp(a,b);if(!c)return a+"";var d=c[0],e=c[1];return e<0?"0."+new Array(-e).join("0")+d:d.length>e+1?d.slice(0,e+1)+"."+d.slice(e+1):d+new Array(e-d.length+2).join("0")},Ap={"":xp,"%":function(a,b){return(100*a).toFixed(b)},b:function(a){return Math.round(a).toString(2)},c:function(a){return a+""},d:function(a){return Math.round(a).toString(10)},e:function(a,b){return a.toExponential(b)},f:function(a,b){return a.toFixed(b)},g:function(a,b){return a.toPrecision(b)},o:function(a){return Math.round(a).toString(8)},p:function(a,b){return zp(100*a,b)},r:zp,s:yp,X:function(a){return Math.round(a).toString(16).toUpperCase()},x:function(a){return Math.round(a).toString(16)}},Bp=/^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;kd.prototype=ld.prototype,ld.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+this.type};var Cp,Dp=function(a){return a},Ep=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"],Fp=function(a){function b(a){function b(a){var b,e,j,t=p,u=q;if("c"===o)u=r(a)+u,a="";else{a=+a;var v=a<0;if(a=r(Math.abs(a),n),v&&0==+a&&(v=!1),t=(v?"("===i?i:"-":"-"===i||"("===i?"":i)+t,u=u+("s"===o?Ep[8+kp/3]:"")+(v&&"("===i?")":""),s)for(b=-1,e=a.length;++b(j=a.charCodeAt(b))||j>57){u=(46===j?f+a.slice(b+1):a.slice(b))+u,a=a.slice(0,b);break}}m&&!k&&(a=d(a,1/0));var w=t.length+a.length+u.length,x=w>1)+t+a+u+x.slice(w);break;default:a=x+t+a+u}return g(a)}a=kd(a);var c=a.fill,h=a.align,i=a.sign,j=a.symbol,k=a.zero,l=a.width,m=a.comma,n=a.precision,o=a.type,p="$"===j?e[0]:"#"===j&&/[boxX]/.test(o)?"0"+o.toLowerCase():"",q="$"===j?e[1]:/[%p]/.test(o)?"%":"",r=Ap[o],s=!o||/[defgprs%]/.test(o);return n=null==n?o?6:12:/[gprs]/.test(o)?Math.max(1,Math.min(21,n)):Math.max(0,Math.min(20,n)),b.toString=function(){return a+""},b}function c(a,c){var d=b((a=kd(a),a.type="f",a)),e=3*Math.max(-8,Math.min(8,Math.floor(up(c)/3))),f=Math.pow(10,-e),g=Ep[8+e/3];return function(a){return d(f*a)+g}}var d=a.grouping&&a.thousands?vp(a.grouping,a.thousands):Dp,e=a.currency,f=a.decimal,g=a.numerals?wp(a.numerals):Dp;return{format:b,formatPrefix:c}};md({decimal:".",thousands:",",grouping:[3],currency:["$",""]});var Gp=function(a){return Math.max(0,-up(Math.abs(a)))},Hp=function(a,b){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(up(b)/3)))-up(Math.abs(a)))},Ip=function(a,b){return a=Math.abs(a),b=Math.abs(b)-a,Math.max(0,up(b)-up(a))+1},Jp=function(){return new nd};nd.prototype={constructor:nd,reset:function(){this.s=this.t=0},add:function(a){od(nq,a,this.t),od(this,nq.s,this.s),this.s?this.t+=nq.t:this.s=nq.t},valueOf:function(){return this.s}};var Kp,Lp,Mp,Np,Op,Pp,Qp,Rp,Sp,Tp,Up,Vp,Wp,Xp,Yp,Zp,$p,_p,aq,bq,cq,dq,eq,fq,gq,hq,iq,jq,kq,lq,mq,nq=new nd,oq=1e-6,pq=Math.PI,qq=pq/2,rq=pq/4,sq=2*pq,tq=180/pq,uq=pq/180,vq=Math.abs,wq=Math.atan,xq=Math.atan2,yq=Math.cos,zq=Math.ceil,Aq=Math.exp,Bq=Math.log,Cq=Math.pow,Dq=Math.sin,Eq=Math.sign||function(a){return a>0?1:a<0?-1:0},Fq=Math.sqrt,Gq=Math.tan,Hq={Feature:function(a,b){td(a.geometry,b)},FeatureCollection:function(a,b){for(var c=a.features,d=-1,e=c.length;++doq?Sp=90:Oq<-oq&&(Qp=-90),Yp[0]=Pp,Yp[1]=Rp}},Qq=function(a){var b,c,d,e,f,g,h;if(Sp=Rp=-(Pp=Qp=1/0),Xp=[],Jq(a,Pq),c=Xp.length){for(Xp.sort(Pd),b=1,d=Xp[0],f=[d];bOd(d[0],d[1])&&(d[1]=e[1]),Od(e[0],d[1])>Od(d[0],d[1])&&(d[0]=e[0])):f.push(d=e);for(g=-1/0,c=f.length-1,b=0,d=f[c];b<=c;d=e,++b)e=f[b],(h=Od(d[1],e[0]))>g&&(g=h,Pp=e[0],Rp=d[1])}return Xp=Yp=null,Pp===1/0||Qp===1/0?[[NaN,NaN],[NaN,NaN]]:[[Pp,Qp],[Rp,Sp]]},Rq={sphere:sd,point:Rd,lineStart:Td,lineEnd:Wd,polygonStart:function(){Rq.lineStart=Xd,Rq.lineEnd=Yd},polygonEnd:function(){Rq.lineStart=Td,Rq.lineEnd=Wd}},Sq=function(a){Zp=$p=_p=aq=bq=cq=dq=eq=fq=gq=hq=0,Jq(a,Rq);var b=fq,c=gq,d=hq,e=b*b+c*c+d*d;return e<1e-12&&(b=cq,c=dq,d=eq,$p2?a[2]*uq:0),b.invert=function(b){return b=a.invert(b[0]*uq,b[1]*uq),b[0]*=tq,b[1]*=tq,b},b},fr=function(){function a(a,b){c.push(a=d(a,b)),a[0]*=tq,a[1]*=tq}function b(){var a=e.apply(this,arguments),b=f.apply(this,arguments)*uq,i=g.apply(this,arguments)*uq;return c=[],d=ae(-a[0]*uq,-a[1]*uq,0).invert,ee(h,b,i,1),a={type:"Polygon",coordinates:[c]},c=d=null,a}var c,d,e=Tq([0,0]),f=Tq(90),g=Tq(6),h={point:a};return b.center=function(a){return arguments.length?(e="function"==typeof a?a:Tq([+a[0],+a[1]]),b):e},b.radius=function(a){return arguments.length?(f="function"==typeof a?a:Tq(+a),b):f},b.precision=function(a){return arguments.length?(g="function"==typeof a?a:Tq(+a),b):g},b},gr=function(){var a,b=[];return{point:function(b,c){a.push([b,c])},lineStart:function(){b.push(a=[])},lineEnd:sd,rejoin:function(){b.length>1&&b.push(b.pop().concat(b.shift()))},result:function(){var c=b;return b=[],a=null,c}}},hr=function(a,b,c,d,e,f){var g,h=a[0],i=a[1],j=b[0],k=b[1],l=0,m=1,n=j-h,o=k-i;if(g=c-h,n||!(g>0)){if(g/=n,n<0){if(g0){if(g>m)return;g>l&&(l=g)}if(g=e-h,n||!(g<0)){if(g/=n,n<0){if(g>m)return;g>l&&(l=g)}else if(n>0){if(g0)){if(g/=o,o<0){if(g0){if(g>m)return;g>l&&(l=g)}if(g=f-i,o||!(g<0)){if(g/=o,o<0){if(g>m)return;g>l&&(l=g)}else if(o>0){if(g0&&(a[0]=h+l*n,a[1]=i+l*o),m<1&&(b[0]=h+m*n,b[1]=i+m*o),!0}}}}},ir=function(a,b){return vq(a[0]-b[0])=0;--f)e.point((k=j[f])[0],k[1]);else d(m.x,m.p.x,-1,e);m=m.p}m=m.o,j=m.z,n=!n}while(!m.v);e.lineEnd()}}},kr=1e9,lr=-kr,mr=function(){var a,b,c,d=0,e=0,f=960,g=500;return c={stream:function(c){return a&&b===c?a:a=ie(d,e,f,g)(b=c)},extent:function(h){return arguments.length?(d=+h[0][0],e=+h[0][1],f=+h[1][0],g=+h[1][1],a=b=null,c):[[d,e],[f,g]]}}},nr=Jp(),or=function(a,b){var c=b[0],d=b[1],e=[Dq(c),-yq(c),0],f=0,g=0;nr.reset();for(var h=0,i=a.length;h=0?1:-1,y=x*w,z=y>pq,A=o*u;if(nr.add(xq(A*x*Dq(y),p*v+A*yq(y))),f+=z?w+x*sq:w,z^m>=c^s>=c){var B=Dd(Bd(l),Bd(r));Gd(B);var C=Dd(e,B);Gd(C);var D=(z^w>=0?-1:1)*qd(C[2]);(d>D||d===D&&(B[0]||B[1]))&&(g+=z^w>=0?1:-1)}}return(f<-oq||f0){for(u||(f.polygonStart(),u=!0),f.lineStart(),a=0;a1&&2&e&&g.push(g.pop().concat(g.shift())),o.push(g.filter(Qe))}var n,o,p,q=b(f),r=e.invert(d[0],d[1]),s=gr(),t=b(s),u=!1,v={point:g,lineStart:i,lineEnd:j,polygonStart:function(){v.point=k,v.lineStart=l,v.lineEnd=m,o=[],n=[]},polygonEnd:function(){v.point=g,v.lineStart=i,v.lineEnd=j,o=ik(o);var a=or(n,r);o.length?(u||(f.polygonStart(),u=!0),jr(o,Re,a,c,f)):a&&(u||(f.polygonStart(),u=!0),f.lineStart(),c(null,null,1,f),f.lineEnd()),u&&(f.polygonEnd(),u=!1),o=n=null},sphere:function(){f.polygonStart(),f.lineStart(),c(null,null,1,f),f.lineEnd(),f.polygonEnd()}};return v}},_r=$r(function(){return!0},Se,Ue,[-pq,-qq]),as=function(a,b){function c(c,d,e,f){ee(f,a,b,e,c,d)}function d(a,b){return yq(a)*yq(b)>h}function e(a){var b,c,e,h,k;return{lineStart:function(){h=e=!1,k=1},point:function(l,m){var n,o=[l,m],p=d(l,m),q=i?p?0:g(l,m):p?g(l+(l<0?pq:-pq),m):0;if(!b&&(h=e=p)&&a.lineStart(),p!==e&&(n=f(b,o),(ir(b,n)||ir(o,n))&&(o[0]+=oq,o[1]+=oq,p=d(o[0],o[1]))),p!==e)k=0,p?(a.lineStart(),n=f(o,b),a.point(n[0],n[1])):(n=f(b,o),a.point(n[0],n[1]),a.lineEnd()),b=n;else if(j&&b&&i^p){var r;q&c||!(r=f(o,b,!0))||(k=0,i?(a.lineStart(),a.point(r[0][0],r[0][1]),a.point(r[1][0],r[1][1]),a.lineEnd()):(a.point(r[1][0],r[1][1]),a.lineEnd(),a.lineStart(),a.point(r[0][0],r[0][1])))}!p||b&&ir(b,o)||a.point(o[0],o[1]),b=o,e=p,c=q},lineEnd:function(){e&&a.lineEnd(),b=null},clean:function(){return k|(h&&e)<<1}}}function f(a,b,c){var d=Bd(a),e=Bd(b),f=[1,0,0],g=Dd(d,e),i=Cd(g,g),j=g[0],k=i-j*j;if(!k)return!c&&a;var l=h*i/k,m=-h*j/k,n=Dd(f,g),o=Fd(f,l);Ed(o,Fd(g,m));var p=n,q=Cd(o,p),r=Cd(p,p),s=q*q-r*(Cd(o,o)-1);if(!(s<0)){var t=Fq(s),u=Fd(p,(-q-t)/r);if(Ed(u,o),u=Ad(u),!c)return u;var v,w=a[0],x=b[0],y=a[1],z=b[1];x0^u[1]<(vq(u[0]-w)pq^(w<=u[0]&&u[0]<=x)){var D=Fd(p,(-q+t)/r);return Ed(D,o),[u,Ad(D)]}}}function g(b,c){var d=i?a:pq-a,e=0;return b<-d?e|=1:b>d&&(e|=2),c<-d?e|=4:c>d&&(e|=8),e}var h=yq(a),i=h>0,j=vq(h)>oq;return $r(d,e,c,i?[0,-a]:[-pq,a-pq])},bs=function(a){return{stream:Ve(a)}};We.prototype={constructor:We,point:function(a,b){this.stream.point(a,b)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var cs=16,ds=yq(30*uq),es=function(a,b){return+b?$e(a,b):Ze(a)},fs=Ve({point:function(a,b){this.stream.point(a*uq,b*uq)}}),gs=function(){return bf(df).scale(155.424).center([0,33.6442])},hs=function(){return gs().parallels([29.5,45.5]).scale(1070).translate([480,250]).rotate([96,0]).center([-.6,38.7])},is=function(){function a(a){var b=a[0],c=a[1];return h=null,e.point(b,c),h||(f.point(b,c),h)||(g.point(b,c),h)}function b(){return c=d=null,a}var c,d,e,f,g,h,i=hs(),j=gs().rotate([154,0]).center([-2,58.5]).parallels([55,65]),k=gs().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(a,b){h=[a,b]}};return a.invert=function(a){var b=i.scale(),c=i.translate(),d=(a[0]-c[0])/b,e=(a[1]-c[1])/b;return(e>=.12&&e<.234&&d>=-.425&&d<-.214?j:e>=.166&&e<.234&&d>=-.214&&d<-.115?k:i).invert(a)},a.stream=function(a){return c&&d===a?c:c=ef([i.stream(d=a),j.stream(a),k.stream(a)])},a.precision=function(a){return arguments.length?(i.precision(a),j.precision(a),k.precision(a),b()):i.precision()},a.scale=function(b){return arguments.length?(i.scale(b),j.scale(.35*b),k.scale(b),a.translate(i.translate())):i.scale()},a.translate=function(a){if(!arguments.length)return i.translate();var c=i.scale(),d=+a[0],h=+a[1];return e=i.translate(a).clipExtent([[d-.455*c,h-.238*c],[d+.455*c,h+.238*c]]).stream(l),f=j.translate([d-.307*c,h+.201*c]).clipExtent([[d-.425*c+oq,h+.12*c+oq],[d-.214*c-oq,h+.234*c-oq]]).stream(l),g=k.translate([d-.205*c,h+.212*c]).clipExtent([[d-.214*c+oq,h+.166*c+oq],[d-.115*c-oq,h+.234*c-oq]]).stream(l),b()},a.fitExtent=function(b,c){return Xe(a,b,c)},a.fitSize=function(b,c){return Ye(a,b,c)},a.scale(1070)},js=ff(function(a){return Fq(2/(1+a))});js.invert=gf(function(a){return 2*qd(a/2)});var ks=function(){return _e(js).scale(124.75).clipAngle(179.999)},ls=ff(function(a){return(a=pd(a))&&a/Dq(a)});ls.invert=gf(function(a){return a});var ms=function(){return _e(ls).scale(79.4188).clipAngle(179.999)};hf.invert=function(a,b){return[a,2*wq(Aq(b))-qq]};var ns=function(){return jf(hf).scale(961/sq)},os=function(){return bf(lf).scale(109.5).parallels([30,30])};mf.invert=mf;var ps=function(){return _e(mf).scale(152.63)},qs=function(){return bf(nf).scale(131.154).center([0,13.9389])};of.invert=gf(wq);var rs=function(){return _e(of).scale(144.049).clipAngle(60)},ss=function(){function a(){return e=f=null,g}var b,c,d,e,f,g,h=1,i=0,j=0,k=1,l=1,m=zr,n=null,o=zr;return g={stream:function(a){return e&&f===a?e:e=m(o(f=a))},clipExtent:function(e){return arguments.length?(o=null==e?(n=b=c=d=null,zr):ie(n=+e[0][0],b=+e[0][1],c=+e[1][0],d=+e[1][1]),a()):null==n?null:[[n,b],[c,d]]},scale:function(b){return arguments.length?(m=pf((h=+b)*k,h*l,i,j),a()):h},translate:function(b){return arguments.length?(m=pf(h*k,h*l,i=+b[0],j=+b[1]),a()):[i,j]},reflectX:function(b){return arguments.length?(m=pf(h*(k=b?-1:1),h*l,i,j),a()):k<0},reflectY:function(b){return arguments.length?(m=pf(h*k,h*(l=b?-1:1),i,j),a()):l<0},fitExtent:function(a,b){return Xe(g,a,b)},fitSize:function(a,b){return Ye(g,a,b)}}};qf.invert=gf(qd);var ts=function(){return _e(qf).scale(249.5).clipAngle(90+oq)};rf.invert=gf(function(a){return 2*wq(a)});var us=function(){return _e(rf).scale(250).clipAngle(142)};sf.invert=function(a,b){return[-b,2*wq(Aq(a))-qq]};var vs=function(){var a=jf(sf),b=a.center,c=a.rotate;return a.center=function(a){return arguments.length?b([-a[1],a[0]]):(a=b(),[a[1],-a[0]])},a.rotate=function(a){return arguments.length?c([a[0],a[1],a.length>2?a[2]+90:90]):(a=c(),[a[0],a[1],a[2]-90])},c([0,0,90]).scale(159.155)},ws=function(){function a(a){var f,g=0;a.eachAfter(function(a){var c=a.children;c?(a.x=uf(c),a.y=wf(c)):(a.x=f?g+=b(a,f):0,a.y=0,f=a)});var h=yf(a),i=zf(a),j=h.x-b(h,i)/2,k=i.x+b(i,h)/2;return a.eachAfter(e?function(b){b.x=(b.x-a.x)*c,b.y=(a.y-b.y)*d}:function(b){b.x=(b.x-j)/(k-j)*c,b.y=(1-(a.y?b.y/a.y:1))*d})}var b=tf,c=1,d=1,e=!1;return a.separation=function(c){return arguments.length?(b=c,a):b},a.size=function(b){return arguments.length?(e=!1,c=+b[0],d=+b[1],a):e?null:[c,d]},a.nodeSize=function(b){return arguments.length?(e=!0,c=+b[0],d=+b[1],a):e?[c,d]:null},a},xs=function(){return this.eachAfter(Af)},ys=function(a){var b,c,d,e,f=this,g=[f];do{for(b=g.reverse(),g=[];f=b.pop();)if(a(f),c=f.children)for(d=0,e=c.length;d=0;--c)e.push(b[c]);return this},As=function(a){for(var b,c,d,e=this,f=[e],g=[];e=f.pop();)if(g.push(e),b=e.children)for(c=0,d=b.length;c=0;)c+=d[e].value;b.value=c})},Cs=function(a){return this.eachBefore(function(b){b.children&&b.children.sort(a)})},Ds=function(a){for(var b=this,c=Bf(b,a),d=[b];b!==c;)b=b.parent,d.push(b);for(var e=d.length;a!==c;)d.splice(e,0,a),a=a.parent;return d},Es=function(){for(var a=this,b=[a];a=a.parent;)b.push(a);return b},Fs=function(){var a=[];return this.each(function(b){a.push(b)}),a},Gs=function(){var a=[];return this.eachBefore(function(b){b.children||a.push(b)}),a},Hs=function(){var a=this,b=[];return a.each(function(c){c!==a&&b.push({source:c.parent,target:c})}),b};Hf.prototype=Cf.prototype={constructor:Hf,count:xs,each:ys,eachAfter:As,eachBefore:zs,sum:Bs,sort:Cs,path:Ds,ancestors:Es,descendants:Fs,leaves:Gs,links:Hs,copy:Df};var Is=function(a){for(var b=(a=a.slice()).length,c=null,d=c;b;){var e=new If(a[b-1]);d=d?d.next=e:c=e,a[void 0]=a[--b]}return{head:c,tail:d}},Js=function(a){return Kf(Is(a),[])},Ks=function(a){return Sf(a),a},Ls=function(a){return function(){return a}},Ms=function(){function a(a){return a.x=c/2,a.y=d/2,b?a.eachBefore(Xf(b)).eachAfter(Yf(e,.5)).eachBefore(Zf(1)):a.eachBefore(Xf(Wf)).eachAfter(Yf(Vf,1)).eachAfter(Yf(e,a.r/Math.min(c,d))).eachBefore(Zf(Math.min(c,d)/(2*a.r))),a}var b=null,c=1,d=1,e=Vf;return a.radius=function(c){return arguments.length?(b=Tf(c),a):b},a.size=function(b){return arguments.length?(c=+b[0],d=+b[1],a):[c,d]},a.padding=function(b){return arguments.length?(e="function"==typeof b?b:Ls(+b),a):e},a},Ns=function(a){a.x0=Math.round(a.x0),a.y0=Math.round(a.y0),a.x1=Math.round(a.x1),a.y1=Math.round(a.y1)},Os=function(a,b,c,d,e){for(var f,g=a.children,h=-1,i=g.length,j=a.value&&(d-b)/a.value;++h0)throw new Error("cycle");return f}var b=$f,c=_f;return a.id=function(c){return arguments.length?(b=Uf(c),a):b},a.parentId=function(b){return arguments.length?(c=Uf(b),a):c},a};gg.prototype=Object.create(Hf.prototype);var Us=function(){function a(a){var d=hg(a);if(d.eachAfter(b),d.parent.m=-d.z,d.eachBefore(c),i)a.eachBefore(e);else{var j=a,k=a,l=a;a.eachBefore(function(a){a.xk.x&&(k=a),a.depth>l.depth&&(l=a)});var m=j===k?1:f(j,k)/2,n=m-j.x,o=g/(k.x+m+n),p=h/(l.depth||1);a.eachBefore(function(a){a.x=(a.x+n)*o,a.y=a.depth*p})}return a}function b(a){var b=a.children,c=a.parent.children,e=a.i?c[a.i-1]:null;if(b){eg(a);var g=(b[0].z+b[b.length-1].z)/2;e?(a.z=e.z+f(a._,e._),a.m=a.z-g):a.z=g}else e&&(a.z=e.z+f(a._,e._));a.parent.A=d(a,e,a.parent.A||c[0])}function c(a){a._.x=a.z+a.parent.m,a.m+=a.parent.m}function d(a,b,c){if(b){for(var d,e=a,g=a,h=b,i=e.parent.children[0],j=e.m,k=g.m,l=h.m,m=i.m;h=cg(h),e=bg(e),h&&e;)i=bg(i),g=cg(g),g.a=a,d=h.z+l-e.z-j+f(h._,e._),d>0&&(dg(fg(h,a,c),a,d),j+=d,k+=d),l+=h.m,j+=e.m,m+=i.m,k+=g.m;h&&!cg(g)&&(g.t=h,g.m+=l-k),e&&!bg(i)&&(i.t=e,i.m+=j-m,c=a)}return c}function e(a){a.x*=g,a.y=a.depth*h}var f=ag,g=1,h=1,i=null;return a.separation=function(b){return arguments.length?(f=b,a):f},a.size=function(b){return arguments.length?(i=!1,g=+b[0],h=+b[1],a):i?null:[g,h]},a.nodeSize=function(b){return arguments.length?(i=!0,g=+b[0],h=+b[1],a):i?[g,h]:null},a},Vs=function(a,b,c,d,e){for(var f,g=a.children,h=-1,i=g.length,j=a.value&&(e-c)/a.value;++h1?b:1)},c}(Ws),Ys=function(){function a(a){return a.x0=a.y0=0,a.x1=e,a.y1=f,a.eachBefore(b),g=[0],d&&a.eachBefore(Ns),a}function b(a){var b=g[a.depth],d=a.x0+b,e=a.y0+b,f=a.x1-b,m=a.y1-b;f=b-1){var j=i[a];return j.x0=d,j.y0=e,j.x1=g,j.y1=h,void 0}for(var l=k[a],m=c/2+l,n=a+1,o=b-1;n>>1;k[p]h-e){var s=(d*r+g*q)/c;f(a,n,q,d,e,s,h),f(n,b,r,s,e,g,h)}else{var t=(e*r+h*q)/c;f(a,n,q,d,e,g,t),f(n,b,r,d,t,g,h)}}var g,h,i=a.children,j=i.length,k=new Array(j+1);for(k[0]=h=g=0;g1?b:1)},c}(Ws),at=function(a){for(var b,c=-1,d=a.length,e=a[d-1],f=0;++c=0;--b)j.push(a[d[f[b]][2]]);for(b=+h;bh!=j>h&&g<(i-c)*(h-d)/(j-d)+c&&(k=!k),i=c,j=d;return k},ft=function(a){for(var b,c,d=-1,e=a.length,f=a[e-1],g=f[0],h=f[1],i=0;++d1);return a+b*e*Math.sqrt(-2*Math.log(d)/d)}},kt=function(){var a=jt.apply(this,arguments);return function(){return Math.exp(a())}},lt=function(a){return function(){for(var b=0,c=0;c=200&&c<300||304===c){if(f)try{b=f.call(d,j)}catch(a){return void h.call("error",d,a)}else b=j;h.call("load",d,b)}else h.call("error",d,a)}var d,e,f,g,h=o("beforesend","progress","load","error"),i=Oc(),j=new XMLHttpRequest,k=null,l=null,m=0;if("undefined"==typeof XDomainRequest||"withCredentials"in j||!/^(http(s)?:)?\/\//.test(a)||(j=new XDomainRequest),"onload"in j?j.onload=j.onerror=j.ontimeout=c:j.onreadystatechange=function(a){j.readyState>3&&c(a)},j.onprogress=function(a){h.call("progress",d,a)},d={header:function(a,b){return a=(a+"").toLowerCase(),arguments.length<2?i.get(a):(null==b?i.remove(a):i.set(a,b+""),d)},mimeType:function(a){return arguments.length?(e=null==a?null:a+"",d):e},responseType:function(a){return arguments.length?(g=a,d):g},timeout:function(a){return arguments.length?(m=+a,d):m},user:function(a){return arguments.length<1?k:(k=null==a?null:a+"",d)},password:function(a){return arguments.length<1?l:(l=null==a?null:a+"",d)},response:function(a){return f=a,d},get:function(a,b){return d.send("GET",a,b)},post:function(a,b){return d.send("POST",a,b)},send:function(b,c,f){return j.open(b,a,!0,k,l),null==e||i.has("accept")||i.set("accept",e+",*/*"),j.setRequestHeader&&i.each(function(a,b){j.setRequestHeader(b,a)}),null!=e&&j.overrideMimeType&&j.overrideMimeType(e),null!=g&&(j.responseType=g),m>0&&(j.timeout=m),null==f&&"function"==typeof c&&(f=c,c=null),null!=f&&1===f.length&&(f=sg(f)),null!=f&&d.on("error",f).on("load",function(a){f(null,a)}),h.call("beforesend",d,j),j.send(null==c?null:c),d},abort:function(){return j.abort(),d},on:function(){var a=h.on.apply(h,arguments);return a===h?d:a}},null!=b){if("function"!=typeof b)throw new Error("invalid callback: "+b);return d.get(b)}return d},pt=function(a,b){return function(c,d){var e=ot(c).mimeType(a).response(b);if(null!=d){if("function"!=typeof d)throw new Error("invalid callback: "+d);return e.get(d)}return e}},qt=pt("text/html",function(a){return document.createRange().createContextualFragment(a.responseText)}),rt=pt("application/json",function(a){return JSON.parse(a.responseText)}),st=pt("text/plain",function(a){return a.responseText}),tt=pt("application/xml",function(a){var b=a.responseXML;if(!b)throw new Error("parse error");return b}),ut=function(a,b){return function(c,d,e){arguments.length<3&&(e=d,d=null);var f=ot(c).mimeType(a);return f.row=function(a){return arguments.length?f.response(ug(b,d=a)):d},f.row(d),e?f.get(e):f}},vt=ut("text/csv",Mo),wt=ut("text/tab-separated-values",Ro),xt=Array.prototype,yt=xt.map,zt=xt.slice,At={name:"implicit"},Bt=function(a){return function(){return a}},Ct=function(a){return+a},Dt=[0,1],Et=function(b,c,e){var f,g=b[0],h=b[b.length-1],i=d(g,h,null==c?10:c);switch(e=kd(null==e?",f":e),e.type){case"s":var j=Math.max(Math.abs(g),Math.abs(h));return null!=e.precision||isNaN(f=Hp(i,j))||(e.precision=f),a.formatPrefix(e,j);case"":case"e":case"g":case"p":case"r":null!=e.precision||isNaN(f=Ip(i,Math.max(Math.abs(g),Math.abs(h))))||(e.precision=f-("e"===e.type));break;case"f":case"%":null!=e.precision||isNaN(f=Gp(i))||(e.precision=f-2*("%"===e.type))}return a.format(e)},Ft=function(a,b){a=a.slice();var c,d=0,e=a.length-1,f=a[d],g=a[e];return g0?a>1?Wg(function(b){b.setTime(Math.floor(b/a)*a)},function(b,c){b.setTime(+b+c*a)},function(b,c){return(c-b)/a}):It:null};var Jt=It.range,Kt=6e4,Lt=6048e5,Mt=Wg(function(a){a.setTime(1e3*Math.floor(a/1e3))},function(a,b){a.setTime(+a+1e3*b)},function(a,b){return(b-a)/1e3},function(a){return a.getUTCSeconds()}),Nt=Mt.range,Ot=Wg(function(a){a.setTime(Math.floor(a/Kt)*Kt)},function(a,b){a.setTime(+a+b*Kt)},function(a,b){return(b-a)/Kt},function(a){return a.getMinutes()}),Pt=Ot.range,Qt=Wg(function(a){var b=a.getTimezoneOffset()*Kt%36e5;b<0&&(b+=36e5),a.setTime(36e5*Math.floor((+a-b)/36e5)+b)},function(a,b){a.setTime(+a+36e5*b)},function(a,b){return(b-a)/36e5},function(a){return a.getHours()}),Rt=Qt.range,St=Wg(function(a){a.setHours(0,0,0,0)},function(a,b){a.setDate(a.getDate()+b)},function(a,b){return(b-a-(b.getTimezoneOffset()-a.getTimezoneOffset())*Kt)/864e5},function(a){return a.getDate()-1}),Tt=St.range,Ut=Xg(0),Vt=Xg(1),Wt=Xg(2),Xt=Xg(3),Yt=Xg(4),Zt=Xg(5),$t=Xg(6),_t=Ut.range,au=Vt.range,bu=Wt.range,cu=Xt.range,du=Yt.range,eu=Zt.range,fu=$t.range,gu=Wg(function(a){a.setDate(1),a.setHours(0,0,0,0)},function(a,b){a.setMonth(a.getMonth()+b)},function(a,b){return b.getMonth()-a.getMonth()+12*(b.getFullYear()-a.getFullYear())},function(a){return a.getMonth()}),hu=gu.range,iu=Wg(function(a){a.setMonth(0,1),a.setHours(0,0,0,0)},function(a,b){a.setFullYear(a.getFullYear()+b)},function(a,b){return b.getFullYear()-a.getFullYear()},function(a){return a.getFullYear()});iu.every=function(a){return isFinite(a=Math.floor(a))&&a>0?Wg(function(b){b.setFullYear(Math.floor(b.getFullYear()/a)*a),b.setMonth(0,1),b.setHours(0,0,0,0)},function(b,c){b.setFullYear(b.getFullYear()+c*a)}):null};var ju=iu.range,ku=Wg(function(a){a.setUTCSeconds(0,0)},function(a,b){a.setTime(+a+b*Kt)},function(a,b){return(b-a)/Kt},function(a){return a.getUTCMinutes()}),lu=ku.range,mu=Wg(function(a){a.setUTCMinutes(0,0,0)},function(a,b){a.setTime(+a+36e5*b)},function(a,b){return(b-a)/36e5},function(a){return a.getUTCHours()}),nu=mu.range,ou=Wg(function(a){a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCDate(a.getUTCDate()+b)},function(a,b){return(b-a)/864e5},function(a){return a.getUTCDate()-1}),pu=ou.range,qu=Yg(0),ru=Yg(1),su=Yg(2),tu=Yg(3),uu=Yg(4),vu=Yg(5),wu=Yg(6),xu=qu.range,yu=ru.range,zu=su.range,Au=tu.range,Bu=uu.range,Cu=vu.range,Du=wu.range,Eu=Wg(function(a){a.setUTCDate(1),a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCMonth(a.getUTCMonth()+b)},function(a,b){return b.getUTCMonth()-a.getUTCMonth()+12*(b.getUTCFullYear()-a.getUTCFullYear())},function(a){return a.getUTCMonth()}),Fu=Eu.range,Gu=Wg(function(a){a.setUTCMonth(0,1),a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCFullYear(a.getUTCFullYear()+b)},function(a,b){return b.getUTCFullYear()-a.getUTCFullYear()},function(a){return a.getUTCFullYear()});Gu.every=function(a){return isFinite(a=Math.floor(a))&&a>0?Wg(function(b){b.setUTCFullYear(Math.floor(b.getUTCFullYear()/a)*a),b.setUTCMonth(0,1),b.setUTCHours(0,0,0,0)},function(b,c){b.setUTCFullYear(b.getUTCFullYear()+c*a)}):null};var Hu,Iu=Gu.range,Ju={"-":"",_:" ",0:"0"},Ku=/^\s*\d+/,Lu=/^%/,Mu=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;Wh({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});var Nu=Date.prototype.toISOString?Xh:a.utcFormat("%Y-%m-%dT%H:%M:%S.%LZ"),Ou=+new Date("2000-01-01T00:00:00.000Z")?Yh:a.utcParse("%Y-%m-%dT%H:%M:%S.%LZ"),Pu=1e3,Qu=60*Pu,Ru=60*Qu,Su=24*Ru,Tu=7*Su,Uu=30*Su,Vu=365*Su,Wu=function(){return _h(iu,gu,Ut,St,Qt,Ot,Mt,It,a.timeFormat).domain([new Date(2e3,0,1),new Date(2e3,0,2)])},Xu=function(){return _h(Gu,Eu,qu,ou,mu,ku,Mt,It,a.utcFormat).domain([Date.UTC(2e3,0,1),Date.UTC(2e3,0,2)])},Yu=function(a){return a.match(/.{6}/g).map(function(a){return"#"+a})},Zu=Yu("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"),$u=Yu("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6"),_u=Yu("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9"),av=Yu("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5"),bv=Km(Ua(300,.5,0),Ua(-240,.5,1)),cv=Km(Ua(-100,.75,.35),Ua(80,1.5,.8)),dv=Km(Ua(260,.75,.35),Ua(80,1.5,.8)),ev=Ua(),fv=function(a){(a<0||a>1)&&(a-=Math.floor(a));var b=Math.abs(a-.5);return ev.h=360*a-100,ev.s=1.5-1.5*b,ev.l=.8-.9*b,ev+""},gv=ai(Yu("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")),hv=ai(Yu("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),iv=ai(Yu("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),jv=ai(Yu("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),kv=function(a){return function(){return a}},lv=Math.abs,mv=Math.atan2,nv=Math.cos,ov=Math.max,pv=Math.min,qv=Math.sin,rv=Math.sqrt,sv=1e-12,tv=Math.PI,uv=tv/2,vv=2*tv,wv=function(){function a(){var a,j,k=+b.apply(this,arguments),l=+c.apply(this,arguments),m=f.apply(this,arguments)-uv,n=g.apply(this,arguments)-uv,o=lv(n-m),p=n>m;if(i||(i=a=Hc()),lsv)if(o>vv-sv)i.moveTo(l*nv(m),l*qv(m)),i.arc(0,0,l,m,n,!p),k>sv&&(i.moveTo(k*nv(n),k*qv(n)),i.arc(0,0,k,n,m,p));else{var q,r,s=m,t=n,u=m,v=n,w=o,x=o,y=h.apply(this,arguments)/2,z=y>sv&&(e?+e.apply(this,arguments):rv(k*k+l*l)),A=pv(lv(l-k)/2,+d.apply(this,arguments)),B=A,C=A;if(z>sv){var D=di(z/k*qv(y)),E=di(z/l*qv(y));(w-=2*D)>sv?(D*=p?1:-1,u+=D,v-=D):(w=0,u=v=(m+n)/2),(x-=2*E)>sv?(E*=p?1:-1,s+=E,t-=E):(x=0,s=t=(m+n)/2)}var F=l*nv(s),G=l*qv(s),H=k*nv(v),I=k*qv(v);if(A>sv){var J=l*nv(t),K=l*qv(t),L=k*nv(u),M=k*qv(u);if(osv?ji(F,G,L,M,J,K,H,I):[H,I],O=F-N[0],P=G-N[1],Q=J-N[0],R=K-N[1],S=1/qv(ci((O*Q+P*R)/(rv(O*O+P*P)*rv(Q*Q+R*R)))/2),T=rv(N[0]*N[0]+N[1]*N[1]);B=pv(A,(k-T)/(S-1)),C=pv(A,(l-T)/(S+1))}}x>sv?C>sv?(q=ki(L,M,F,G,l,C,p),r=ki(J,K,H,I,l,C,p),i.moveTo(q.cx+q.x01,q.cy+q.y01),Csv&&w>sv?B>sv?(q=ki(H,I,J,K,k,-B,p),r=ki(F,G,L,M,k,-B,p),i.lineTo(q.cx+q.x01,q.cy+q.y01),B=k;--l)j.point(q[l],r[l]);j.lineEnd(),j.areaEnd()}p&&(q[b]=+c(m,b,a),r[b]=+e(m,b,a),j.point(d?+d(m,b,a):q[b],f?+f(m,b,a):r[b]))}if(n)return j=null,n+""||null}function b(){return yv().defined(g).curve(i).context(h)}var c=mi,d=null,e=kv(0),f=ni,g=kv(!0),h=null,i=xv,j=null;return a.x=function(b){return arguments.length?(c="function"==typeof b?b:kv(+b),d=null,a):c},a.x0=function(b){return arguments.length?(c="function"==typeof b?b:kv(+b),a):c},a.x1=function(b){return arguments.length?(d=null==b?null:"function"==typeof b?b:kv(+b),a):d},a.y=function(b){return arguments.length?(e="function"==typeof b?b:kv(+b),f=null,a):e},a.y0=function(b){return arguments.length?(e="function"==typeof b?b:kv(+b),a):e},a.y1=function(b){return arguments.length?(f=null==b?null:"function"==typeof b?b:kv(+b),a):f},a.lineX0=a.lineY0=function(){return b().x(c).y(e)},a.lineY1=function(){return b().x(c).y(f)},a.lineX1=function(){return b().x(d).y(e)},a.defined=function(b){return arguments.length?(g="function"==typeof b?b:kv(!!b),a):g},a.curve=function(b){return arguments.length?(i=b,null!=h&&(j=i(h)),a):i},a.context=function(b){return arguments.length?(null==b?h=j=null:j=i(h=b),a):h},a},Av=function(a,b){return ba?1:b>=a?0:NaN},Bv=function(a){return a},Cv=function(){function a(a){var h,i,j,k,l,m=a.length,n=0,o=new Array(m),p=new Array(m),q=+e.apply(this,arguments),r=Math.min(vv,Math.max(-vv,f.apply(this,arguments)-q)),s=Math.min(Math.abs(r)/m,g.apply(this,arguments)),t=s*(r<0?-1:1);for(h=0;h0&&(n+=l);for(null!=c?o.sort(function(a,b){return c(p[a],p[b])}):null!=d&&o.sort(function(b,c){return d(a[b],a[c])}),h=0,j=n?(r-m*t)/n:0;h0?l*j:0)+t,p[i]={data:a[i],index:h,value:l,startAngle:q,endAngle:k,padAngle:s};return p}var b=Bv,c=Av,d=null,e=kv(0),f=kv(vv),g=kv(0);return a.value=function(c){return arguments.length?(b="function"==typeof c?c:kv(+c),a):b},a.sortValues=function(b){return arguments.length?(c=b,d=null,a):c},a.sort=function(b){return arguments.length?(d=b,c=null,a):d},a.startAngle=function(b){return arguments.length?(e="function"==typeof b?b:kv(+b),a):e},a.endAngle=function(b){return arguments.length?(f="function"==typeof b?b:kv(+b),a):f},a.padAngle=function(b){return arguments.length?(g="function"==typeof b?b:kv(+b),a):g},a},Dv=pi(xv);oi.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(a,b){this._curve.point(b*Math.sin(a),b*-Math.cos(a))}};var Ev=function(){return qi(yv().curve(Dv))},Fv=function(){var a=zv().curve(Dv),b=a.curve,c=a.lineX0,d=a.lineX1,e=a.lineY0,f=a.lineY1;return a.angle=a.x,delete a.x,a.startAngle=a.x0,delete a.x0,a.endAngle=a.x1,delete a.x1,a.radius=a.y,delete a.y,a.innerRadius=a.y0,delete a.y0,a.outerRadius=a.y1,delete a.y1,a.lineStartAngle=function(){return qi(c())},delete a.lineX0,a.lineEndAngle=function(){return qi(d())},delete a.lineX1,a.lineInnerRadius=function(){return qi(e())},delete a.lineY0,a.lineOuterRadius=function(){return qi(f())},delete a.lineY1,a.curve=function(a){return arguments.length?b(pi(a)):b()._curve},a},Gv={draw:function(a,b){var c=Math.sqrt(b/tv);a.moveTo(c,0),a.arc(0,0,c,0,vv)}},Hv={draw:function(a,b){var c=Math.sqrt(b/5)/2;a.moveTo(-3*c,-c),a.lineTo(-c,-c),a.lineTo(-c,-3*c),a.lineTo(c,-3*c),a.lineTo(c,-c),a.lineTo(3*c,-c),a.lineTo(3*c,c),a.lineTo(c,c),a.lineTo(c,3*c),a.lineTo(-c,3*c),a.lineTo(-c,c),a.lineTo(-3*c,c),a.closePath()}},Iv=Math.sqrt(1/3),Jv=2*Iv,Kv={draw:function(a,b){var c=Math.sqrt(b/Jv),d=c*Iv;a.moveTo(0,-c),a.lineTo(d,0),a.lineTo(0,c),a.lineTo(-d,0),a.closePath()}},Lv=Math.sin(tv/10)/Math.sin(7*tv/10),Mv=Math.sin(vv/10)*Lv,Nv=-Math.cos(vv/10)*Lv,Ov={draw:function(a,b){var c=Math.sqrt(.8908130915292852*b),d=Mv*c,e=Nv*c;a.moveTo(0,-c),a.lineTo(d,e);for(var f=1;f<5;++f){var g=vv*f/5,h=Math.cos(g),i=Math.sin(g);a.lineTo(i*c,-h*c),a.lineTo(h*d-i*e,i*d+h*e)}a.closePath()}},Pv={draw:function(a,b){var c=Math.sqrt(b),d=-c/2;a.rect(d,d,c,c)}},Qv=Math.sqrt(3),Rv={draw:function(a,b){var c=-Math.sqrt(b/(3*Qv));a.moveTo(0,2*c),a.lineTo(-Qv*c,-c),a.lineTo(Qv*c,-c),a.closePath()}},Sv=-.5,Tv=Math.sqrt(3)/2,Uv=1/Math.sqrt(12),Vv=3*(Uv/2+1),Wv={draw:function(a,b){var c=Math.sqrt(b/Vv),d=c/2,e=c*Uv,f=d,g=c*Uv+c,h=-f,i=g;a.moveTo(d,e),a.lineTo(f,g),a.lineTo(h,i),a.lineTo(Sv*d-Tv*e,Tv*d+Sv*e),a.lineTo(Sv*f-Tv*g,Tv*f+Sv*g),a.lineTo(Sv*h-Tv*i,Tv*h+Sv*i),a.lineTo(Sv*d+Tv*e,Sv*e-Tv*d),a.lineTo(Sv*f+Tv*g,Sv*g-Tv*f),a.lineTo(Sv*h+Tv*i,Sv*i-Tv*h),a.closePath()}},Xv=[Gv,Hv,Kv,Pv,Ov,Rv,Wv],Yv=function(){function a(){var a;if(d||(d=a=Hc()),b.apply(this,arguments).draw(d,+c.apply(this,arguments)),a)return d=null,a+""||null}var b=kv(Gv),c=kv(64),d=null;return a.type=function(c){return arguments.length?(b="function"==typeof c?c:kv(c),a):b},a.size=function(b){return arguments.length?(c="function"==typeof b?b:kv(+b),a):c},a.context=function(b){return arguments.length?(d=null==b?null:b,a):d},a},Zv=function(){};si.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:ri(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:ri(this,a,b)}this._x0=this._x1,this._x1=a,this._y0=this._y1,this._y1=b}};var $v=function(a){return new si(a)};ti.prototype={areaStart:Zv,areaEnd:Zv,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._x2=a,this._y2=b;break;case 1:this._point=2,this._x3=a,this._y3=b;break;case 2:this._point=3,this._x4=a,this._y4=b,this._context.moveTo((this._x0+4*this._x1+a)/6,(this._y0+4*this._y1+b)/6);break;default:ri(this,a,b)}this._x0=this._x1,this._x1=a,this._y0=this._y1,this._y1=b}};var _v=function(a){return new ti(a)};ui.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var c=(this._x0+4*this._x1+a)/6,d=(this._y0+4*this._y1+b)/6;this._line?this._context.lineTo(c,d):this._context.moveTo(c,d);break;case 3:this._point=4;default:ri(this,a,b)}this._x0=this._x1,this._x1=a,this._y0=this._y1,this._y1=b}};var aw=function(a){return new ui(a)};vi.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var a=this._x,b=this._y,c=a.length-1;if(c>0)for(var d,e=a[0],f=b[0],g=a[c]-e,h=b[c]-f,i=-1;++i<=c;)d=i/c,this._basis.point(this._beta*a[i]+(1-this._beta)*(e+d*g),this._beta*b[i]+(1-this._beta)*(f+d*h));this._x=this._y=null,this._basis.lineEnd()},point:function(a,b){this._x.push(+a),this._y.push(+b)}};var bw=function a(b){function c(a){return 1===b?new si(a):new vi(a,b)}return c.beta=function(b){return a(+b)},c}(.85);xi.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:wi(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2,this._x1=a,this._y1=b;break;case 2:this._point=3;default:wi(this,a,b)}this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var cw=function a(b){function c(a){return new xi(a,b)}return c.tension=function(b){return a(+b)},c}(0);yi.prototype={areaStart:Zv,areaEnd:Zv,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._x3=a,this._y3=b;break;case 1:this._point=2,this._context.moveTo(this._x4=a,this._y4=b);break;case 2:this._point=3,this._x5=a,this._y5=b;break;default:wi(this,a,b)}this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var dw=function a(b){function c(a){return new yi(a,b)}return c.tension=function(b){return a(+b)},c}(0);zi.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:wi(this,a,b)}this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var ew=function a(b){function c(a){return new zi(a,b)}return c.tension=function(b){return a(+b)},c}(0);Bi.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN, +this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){if(a=+a,b=+b,this._point){var c=this._x2-a,d=this._y2-b;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(c*c+d*d,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2;break;case 2:this._point=3;default:Ai(this,a,b)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var fw=function a(b){function c(a){return b?new Bi(a,b):new xi(a,0)}return c.alpha=function(b){return a(+b)},c}(.5);Ci.prototype={areaStart:Zv,areaEnd:Zv,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(a,b){if(a=+a,b=+b,this._point){var c=this._x2-a,d=this._y2-b;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(c*c+d*d,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=a,this._y3=b;break;case 1:this._point=2,this._context.moveTo(this._x4=a,this._y4=b);break;case 2:this._point=3,this._x5=a,this._y5=b;break;default:Ai(this,a,b)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var gw=function a(b){function c(a){return b?new Ci(a,b):new yi(a,0)}return c.alpha=function(b){return a(+b)},c}(.5);Di.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){if(a=+a,b=+b,this._point){var c=this._x2-a,d=this._y2-b;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(c*c+d*d,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ai(this,a,b)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=a,this._y0=this._y1,this._y1=this._y2,this._y2=b}};var hw=function a(b){function c(a){return b?new Di(a,b):new zi(a,0)}return c.alpha=function(b){return a(+b)},c}(.5);Ei.prototype={areaStart:Zv,areaEnd:Zv,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(a,b){a=+a,b=+b,this._point?this._context.lineTo(a,b):(this._point=1,this._context.moveTo(a,b))}};var iw=function(a){return new Ei(a)};Ji.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Ii(this,this._t0,Hi(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(a,b){var c=NaN;if(a=+a,b=+b,a!==this._x1||b!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2;break;case 2:this._point=3,Ii(this,Hi(this,c=Gi(this,a,b)),c);break;default:Ii(this,this._t0,c=Gi(this,a,b))}this._x0=this._x1,this._x1=a,this._y0=this._y1,this._y1=b,this._t0=c}}},(Ki.prototype=Object.create(Ji.prototype)).point=function(a,b){Ji.prototype.point.call(this,b,a)},Li.prototype={moveTo:function(a,b){this._context.moveTo(b,a)},closePath:function(){this._context.closePath()},lineTo:function(a,b){this._context.lineTo(b,a)},bezierCurveTo:function(a,b,c,d,e,f){this._context.bezierCurveTo(b,a,d,c,f,e)}},Oi.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var a=this._x,b=this._y,c=a.length;if(c)if(this._line?this._context.lineTo(a[0],b[0]):this._context.moveTo(a[0],b[0]),2===c)this._context.lineTo(a[1],b[1]);else for(var d=Pi(a),e=Pi(b),f=0,g=1;g=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(a,b){switch(a=+a,b=+b,this._point){case 0:this._point=1,this._line?this._context.lineTo(a,b):this._context.moveTo(a,b);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,b),this._context.lineTo(a,b);else{var c=this._x*(1-this._t)+a*this._t;this._context.lineTo(c,this._y),this._context.lineTo(c,b)}}this._x=a,this._y=b}};var kw=function(a){return new Qi(a,.5)},lw=Array.prototype.slice,mw=function(a,b){if((d=a.length)>1)for(var c,d,e=1,f=a[b[0]],g=f.length;e=0;)c[b]=b;return c},ow=function(){function a(a){var f,g,h=b.apply(this,arguments),i=a.length,j=h.length,k=new Array(j);for(f=0;f0){for(var c,d,e,f=0,g=a[0].length;f0){for(var c,d=0,e=a[b[0]],f=e.length;d0&&(d=(c=a[b[0]]).length)>0){for(var c,d,e,f=0,g=1;g=h)return null;var i=a-e.site[0],j=b-e.site[1],k=i*i+j*j;do{e=f.cells[d=g],g=null,e.halfedges.forEach(function(c){var d=f.edges[c],h=d.left;if(h!==e.site&&h||(h=d.right)){var i=a-h[0],j=b-h[1],l=i*i+j*j;lc?(c+d)/2:Math.min(0,c)||Math.max(0,d),f>e?(e+f)/2:Math.min(0,e)||Math.max(0,f))}function f(a){return[(+a[0][0]+ +a[1][0])/2,(+a[0][1]+ +a[1][1])/2]}function g(a,b,c){a.on("start.zoom",function(){h(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){h(this,arguments).end()}).tween("zoom",function(){var a=this,d=arguments,e=h(a,d),g=t.apply(a,d),i=c||f(g),j=Math.max(g[1][0]-g[0][0],g[1][1]-g[0][1]),k=a.__zoom,l="function"==typeof b?b.apply(a,d):b,m=B(k.invert(i).concat(j/k.k),l.invert(i).concat(j/l.k));return function(a){if(1===a)a=l;else{var b=m(a),c=j/b[2];a=new Aj(c,i[0]-b[0]*c,i[1]-b[1]*c)}e.zoom(null,a)}})}function h(a,b){for(var c,d=0,e=D.length;d0?tl(this).transition().duration(A).call(g,k,h):tl(this).call(b.transform,k)}}function m(){if(s.apply(this,arguments)){var b,c,d,e,f=h(this,arguments),g=a.event.changedTouches,i=g.length;for(Cj(),c=0;c0&&b>0?0:b}if("auto"===a.maxValue){var c="auto"===a.minValue?d.min(this._data):a.minValue,c=d.max(this._data);a.maxValue=c<0&&b<0?0:c}return a},c.prototype._draw=function(){function a(a,b,c,d){return"M"+a+" "+b+"l"+c+" 0l0 "+d+"l"+-c+" 0Z"}function b(a,b,c){a.fillRect(c*g+3,h(0),g,0,f._options.labelPadding,"center",b>=0?"top":"bottom",0)}function c(a,b,c){a.fillRect(c*g+3,h(b>=0?b:0),g,Math.abs(h(b)-h(0)),f._options.labelPadding,"center",b>=0?"top":"bottom",f._options.transitionTime)}var f=this;e.prototype._draw.call(this);var g=(f._options.width-6)/f._data.length,h=d.scaleLinear().domain([f._options.minValue,f._options.maxValue]).range([f._options.height,0]);f._zeroLine.transition().duration(f._options.transitionTime).attr("x1",0).attr("y1",h(0)).attr("x2",f._options.width).attr("y2",h(0)).attr("style",f._options.zeroLineStyle);var i=f._chart.selectAll("path").data(f._data);i.enter().append("path").attr("d",function(b,c){return a((c+1)*g+3,h(0),0,0)}).merge(i).attr("class",f._options.shapeClass).transition().duration(f._options.transitionTime).attr("d",function(b,c){return a(c*g+3,h(0),g,h(b)-h(0))}).attr("fill",f._options.colorFun),i.exit().transition().duration(f._options.transitionTime).attr("x",function(a,b){return b*g+3}).attr("y",0).attr("width",0).attr("height",0).remove(),this._drawLabels(b,c)}}()},{"./chart.js":3,d3:1}],3:[function(a,b,c){!function(){"use strict";function c(a,b,c,e){this._data=b,this._options={width:60,height:60,transitionTime:750,colors:d.schemeCategory10,labels:"none",labelColors:"auto",labelMinSize:8,labelMaxSize:24,labelPadding:2,labelClass:"",shapeClass:""},this._options=f.mergeOptions(this._options,e||{}),this._options=this._processOptions(c),d.select(a).select("*").remove(),this._container=d.select(a).append("svg").attr("width",this._options.width).attr("height",this._options.height),this._chart=this._container.append("g")}var d=a("d3"),e=a("tinycolor2"),f=a("./utils.js"),g=a("./label.js");b.exports=c,c.prototype.update=function(a,b){this._data=a,this._options=this._processOptions(b),this._draw()},c.prototype.setOptions=function(a){this._options=this._processOptions(a),this._draw()},c.prototype.setData=function(a){this._data=a,this._draw()},c.prototype._draw=function(){var a=this;a._container.transition().duration(a._options.transitionTime).attr("width",a._options.width).attr("height",a._options.height)},c.prototype._processOptions=function(a){return a=f.mergeOptions(a,this._options),a.colorFun=f.toFunction(a.colors),a.labelClass=f.toFunction(a.labelClass),a.shapeClass=f.toFunction(a.shapeClass),"none"===a.labels?a.labelText=null:"auto"===a.labels?a.labelText=f.prettyNumber:a.labelText=f.toFunction(a.labels),"auto"===a.labelColors?a.labelColorFun=function(b,c){return e.mostReadable(a.colorFun(b,c),["white","black"])._originalInput}:a.labelColorFun=f.toFunction(a.labelColorFun),a},c.prototype._drawLabels=function(a,b){var c=this;if("none"===c._options.labels)return void c._chart.selectAll(".labels-container").remove();c._labels=c._chart.selectAll(".labels-container").data(c._data),c._labels.enter().append("g").attr("class","labels-container").each(function(b,d){this._label=new g(this,c._options.labelStyle,c._options.labelColorFun(b,d),c._options.labelMinSize,c._options.labelMaxSize),this._label.updateText(c._options.labelText(b,d)),a(this._label,b,d)}).merge(c._labels).each(function(a,d){this._label.updateText(c._options.labelText(a,d)),this._label._text.attr("fill",c._options.labelColorFun(a,d)).attr("class",c._options.labelClass(a,d)),b(this._label,a,d)}),c._labels.exit().remove()}}()},{"./label.js":5,"./utils.js":9,d3:1,tinycolor2:10}],4:[function(a,b,c){!function(){"use strict";function a(a,b){this.x=a,this.y=b}function c(a,b){this.a=a,this.b=b}function d(b,c){return b.b==c.b?[]:[new a((c.a-b.a)/(b.b-c.b),(b.b*c.a-b.a*c.b)/(b.b-c.b))]}function e(b,e,f){var h=new c(0,Math.tan(e)),i=d(b,h),j=new a(0,0),k=new a(f*Math.cos(e),f*Math.sin(e));return 0!=i.length&&g(i[0],j,k)?i:[]}function f(b,c){return j(b.b*b.b+1,2*b.a*b.b,b.a*b.a-c*c).map(function(c){return new a(c,b.getY(c))})}function g(a,b,c){var d=i(h(c,b),h(a,b)),e=i(h(c,b),h(c,b));return d>=0&&d<=e}function h(b,c){return new a(b.x-c.x,b.y-c.y)}function i(a,b){return a.x*b.x+a.y*b.y}function j(a,b,c){var d=b*b-4*a*c;return d<0?[]:0==d?[-b/(2*a)]:[(-b-Math.sqrt(d))/(2*a),(-b+Math.sqrt(d))/(2*a)]}function k(a,b){return Math.sqrt(Math.pow(a.x-b.x,2)+Math.pow(a.y-b.y,2))}b.exports.Point=a,b.exports.Line=c,b.exports.intersectionOfTwoLines=d,b.exports.intersectionLineAndCircle=f,b.exports.pointInSegment=g,b.exports.intersectionLineRadius=e,b.exports.distance=k,c.prototype.getY=function(a){return this.a+this.b*a}}()},{}],5:[function(a,b,c){!function(){"use strict";function c(a,b,c,e,f){this._el=a,this._minSize=e,this._maxSize=f,this._container=d.select(a),this._label=this._container.append("g").attr("class","label"),this._text=this._label.append("text").attr("dy","0.35em").attr("text-anchor","middle").attr("style",b||"").attr("fill",c||"black")}var d=a("d3"),e=a("./geometry.js");b.exports=c,c.prototype.innerSize=function(){return this._text.node().getBBox()},c.prototype.size=function(){var a=this.innerSize();return{width:a.width*this._scale,height:a.height*this._scale}},c.prototype.updateText=function(a){var b=this.size();this._text.text(a);var c=this.size(),d=Math.min(b.width/c.width,b.height/c.height);return this.updateScale(this._scale*d,0),this},c.prototype.updatePosition=function(a,b,c){return this._container.transition().duration(c||0).attr("transform","translate("+a+","+b+")"),this},c.prototype.updateScale=function(a,b){a&&!isNaN(a)&&isFinite(a)||(a=0);var c=this.innerSize().height*a;return this._minSize&&cthis._maxSize&&(a=this._maxSize/this.innerSize().height),this._label.transition().duration(b||0).attr("transform","scale("+a+")"),this._scale=a,this},c.prototype.fillRect=function(a,b,c,d,e,f,g,h){var i=this.innerSize();this.updateScale(Math.min((c-2*e)/i.width,Math.abs(d)/i.height),h);var j,k,l=this.size();switch(g){case"top":k=b+l.height/2;break;case"center":k=b+d/2;break;case"bottom":k=b+d-l.height/2}switch(f){case"left":j=a+e+l.width/2;break;case"center":j=a+c/2;break;case"right":j=a+c-e-l.width/2}return this.updatePosition(j,k,h),this},c.prototype.fillCircle=function(a,b){this.updatePosition(0,0,b);var c=this.innerSize(),d=c.height/c.width,e=2*a*Math.cos(Math.PI/2-Math.atan(d));this.updateScale(e/c.height,b)},c.prototype.fillSlice=function(a,b,c,f){var g=a.centroid(c);this.updatePosition(g[0],g[1],f);var h=this.innerSize(),i=h.height/h.width,j=new e.Line(g[1]-i*g[0],i),k=new e.Line(g[1]+i*g[0],-i),l=(new e.Line(0,Math.tan(c.startAngle+Math.PI/2)), +new e.Line(0,Math.tan(c.endAngle+Math.PI/2)),[]);l=l.concat(e.intersectionLineRadius(j,c.startAngle-Math.PI/2,b)),l=l.concat(e.intersectionLineRadius(j,c.endAngle-Math.PI/2,b)),l=l.concat(e.intersectionLineAndCircle(j,b)),l=l.concat(e.intersectionLineRadius(k,c.startAngle-Math.PI/2,b)),l=l.concat(e.intersectionLineRadius(k,c.endAngle-Math.PI/2,b)),l=l.concat(e.intersectionLineAndCircle(k,b));var m=new e.Point(g[0],g[1]),n=l.map(function(a){return e.distance(m,a)}),o=d.min(n),p=Math.sqrt(Math.pow(h.height/2,2)+Math.pow(h.width/2,2));this.updateScale(o/p,f)}}()},{"./geometry.js":4,d3:1}],6:[function(a,b,c){!function(){"use strict";b.exports.Barchart=a("./barchart.js"),b.exports.Polarchart=a("./polarchart.js"),b.exports.Piechart=a("./piechart.js"),window&&(window.minicharts=b.exports)}()},{"./barchart.js":2,"./piechart.js":7,"./polarchart.js":8}],7:[function(a,b,c){!function(){"use strict";function c(a,b,c){d.call(this,a,b,c)}var d=a("./polarchart.js");b.exports=c,c.prototype=Object.create(d.prototype),c.prototype.constructor=c,c.prototype._processOptions=function(a){return a=a||{},a.type="angle",d.prototype._processOptions.call(this,a)}}()},{"./polarchart.js":8}],8:[function(a,b,c){!function(){"use strict";function c(a,b,c){var d={type:"area",maxValue:"auto"};e.call(this,a,b,c,d),this._chart.attr("transform","translate("+this._options.width/2+","+this._options.width/2+")"),this._draw()}var d=a("d3"),e=a("./chart.js");b.exports=c,c.prototype=Object.create(e.prototype),c.prototype.constructor=c,c.prototype._processOptions=function(a){a=e.prototype._processOptions.call(this,a,this._options),a.height=a.width,"auto"===a.maxValue&&(a.maxValue=d.max(this._data));var b,c=a.width/2,f=d.pie().sort(null),g=d.arc().innerRadius(0);return"angle"===a.type?(b=function(a){return c},f.value(function(a){return a})):(b="radius"==a.type?d.scaleLinear():d.scalePow().exponent(.5),b.range([0,c]).domain([0,a.maxValue]),f.value(function(a){return 1})),g.outerRadius(function(a,c){return b(a.data)}),a.radius=b,a.pie=f,a.arc=g,a},c.prototype._draw=function(){function a(a){var c=d.interpolate(this._current,a);return this._current=c(0),function(a){return b._options.arc(c(a))}}var b=this;e.prototype._draw.call(this),this._chart.transition().duration(b._options.transitionTime).attr("transform","translate("+b._options.width/2+","+b._options.width/2+")");var c=this._chart.selectAll("path").data(this._options.pie(this._data));c.enter().append("path").attr("class","leaflet-clickable").attr("d",this._options.arc).attr("fill",function(a,c){return b._options.colorFun(a,c)}).each(function(a,c){1==b._data.length?this._current={startAngle:a.startAngle,endAngle:a.endAngle,data:0}:this._current={startAngle:a.endAngle,endAngle:a.endAngle}}).merge(c).attr("class",function(a,c){return b._options.shapeClass(a.data,c)}).transition().duration(b._options.transitionTime).attrTween("d",a).attr("fill",function(a,c){return b._options.colorFun(a,c)}),c.exit().remove();var f,g;if(this._data.length>1){var h=this._options.pie(this._data);f=function(a,c,d){a.fillSlice(b._options.arc,b._options.radius(c),h[d],0)},g=function(a,c,d){a.fillSlice(b._options.arc,b._options.radius(c),h[d],b._options.transitionTime)}}else f=function(a,c,d){a.fillCircle(b._options.radius(c),0)},g=function(a,c,d){a.fillCircle(b._options.radius(c),b._options.transitionTime)};this._drawLabels(f,g)}}()},{"./chart.js":3,d3:1}],9:[function(a,b,c){!function(){"use strict";function a(a,b){a=a?JSON.parse(JSON.stringify(a)):{},b=b||{};for(var c in b)b.hasOwnProperty(c)&&!a.hasOwnProperty(c)&&(a[c]=b[c]);return a}function c(a){return a.constructor!==Array&&(a=[a]),a}function d(a){return"function"==typeof a?a:(a=c(a),function(b,c){return a[c%a.length]})}function e(a){if(isNaN(a)||!isFinite(a))return"";var b,c=Math.abs(a),d=a<0?"-":"";return c<1e3?b="":c<1e6?(b="K",c/=1e3):c<1e9?(b="M",c/=1e6):c<1e12?(b="B",c/=1e9):c<1e15&&(b="T",c/=1e12),c=c>10?f(c):c>1?f(c,10,!0):f(c,100,!0),d+c+b}function f(a,b,c){return b=b||1,c?Math.round(a*b)/b:Math.round(a/b)*b}b.exports.mergeOptions=a,b.exports.toArray=c,b.exports.toFunction=d,b.exports.prettyNumber=e}()},{}],10:[function(a,b,c){!function(a){function c(a,b){if(a=a||"",b=b||{},a instanceof c)return a;if(!(this instanceof c))return new c(a,b);var e=d(a);this._originalInput=a,this._r=e.r,this._g=e.g,this._b=e.b,this._a=e.a,this._roundA=P(100*this._a)/100,this._format=b.format||e.format,this._gradientType=b.gradientType,this._r<1&&(this._r=P(this._r)),this._g<1&&(this._g=P(this._g)),this._b<1&&(this._b=P(this._b)),this._ok=e.ok,this._tc_id=O++}function d(a){var b={r:0,g:0,b:0},c=1,d=null,f=null,h=null,j=!1,k=!1;return"string"==typeof a&&(a=K(a)),"object"==typeof a&&(J(a.r)&&J(a.g)&&J(a.b)?(b=e(a.r,a.g,a.b),j=!0,k="%"===String(a.r).substr(-1)?"prgb":"rgb"):J(a.h)&&J(a.s)&&J(a.v)?(d=G(a.s),f=G(a.v),b=i(a.h,d,f),j=!0,k="hsv"):J(a.h)&&J(a.s)&&J(a.l)&&(d=G(a.s),h=G(a.l),b=g(a.h,d,h),j=!0,k="hsl"),a.hasOwnProperty("a")&&(c=a.a)),c=z(c),{ok:j,format:a.format||k,r:Q(255,R(b.r,0)),g:Q(255,R(b.g,0)),b:Q(255,R(b.b,0)),a:c}}function e(a,b,c){return{r:255*A(a,255),g:255*A(b,255),b:255*A(c,255)}}function f(a,b,c){a=A(a,255),b=A(b,255),c=A(c,255);var d,e,f=R(a,b,c),g=Q(a,b,c),h=(f+g)/2;if(f==g)d=e=0;else{var i=f-g;switch(e=h>.5?i/(2-f-g):i/(f+g),f){case a:d=(b-c)/i+(b1&&(c-=1),c<1/6?a+6*(b-a)*c:c<.5?b:c<2/3?a+(b-a)*(2/3-c)*6:a}var e,f,g;if(a=A(a,360),b=A(b,100),c=A(c,100),0===b)e=f=g=c;else{var h=c<.5?c*(1+b):c+b-c*b,i=2*c-h;e=d(i,h,a+1/3),f=d(i,h,a),g=d(i,h,a-1/3)}return{r:255*e,g:255*f,b:255*g}}function h(a,b,c){a=A(a,255),b=A(b,255),c=A(c,255);var d,e,f=R(a,b,c),g=Q(a,b,c),h=f,i=f-g;if(e=0===f?0:i/f,f==g)d=0;else{switch(f){case a:d=(b-c)/i+(b>1)+720)%360;--b;)e.h=(e.h+f)%360,g.push(c(e));return g}function y(a,b){b=b||6;for(var d=c(a).toHsv(),e=d.h,f=d.s,g=d.v,h=[],i=1/b;b--;)h.push(c({h:e,s:f,v:g})),g=(g+i)%1;return h}function z(a){return a=parseFloat(a),(isNaN(a)||a<0||a>1)&&(a=1),a}function A(b,c){D(b)&&(b="100%");var d=E(b);return b=Q(c,R(0,parseFloat(b))),d&&(b=parseInt(b*c,10)/100),a.abs(b-c)<1e-6?1:b%c/parseFloat(c)}function B(a){return Q(1,R(0,a))}function C(a){return parseInt(a,16)}function D(a){return"string"==typeof a&&-1!=a.indexOf(".")&&1===parseFloat(a)}function E(a){return"string"==typeof a&&-1!=a.indexOf("%")}function F(a){return 1==a.length?"0"+a:""+a}function G(a){return a<=1&&(a=100*a+"%"),a}function H(b){return a.round(255*parseFloat(b)).toString(16)}function I(a){return C(a)/255}function J(a){return!!V.CSS_UNIT.exec(a)}function K(a){a=a.replace(M,"").replace(N,"").toLowerCase();var b=!1;if(T[a])a=T[a],b=!0;else if("transparent"==a)return{r:0,g:0,b:0,a:0,format:"name"};var c;return(c=V.rgb.exec(a))?{r:c[1],g:c[2],b:c[3]}:(c=V.rgba.exec(a))?{r:c[1],g:c[2],b:c[3],a:c[4]}:(c=V.hsl.exec(a))?{h:c[1],s:c[2],l:c[3]}:(c=V.hsla.exec(a))?{h:c[1],s:c[2],l:c[3],a:c[4]}:(c=V.hsv.exec(a))?{h:c[1],s:c[2],v:c[3]}:(c=V.hsva.exec(a))?{h:c[1],s:c[2],v:c[3],a:c[4]}:(c=V.hex8.exec(a))?{r:C(c[1]),g:C(c[2]),b:C(c[3]),a:I(c[4]),format:b?"name":"hex8"}:(c=V.hex6.exec(a))?{r:C(c[1]),g:C(c[2]),b:C(c[3]),format:b?"name":"hex"}:(c=V.hex4.exec(a))?{r:C(c[1]+""+c[1]),g:C(c[2]+""+c[2]),b:C(c[3]+""+c[3]),a:I(c[4]+""+c[4]),format:b?"name":"hex8"}:!!(c=V.hex3.exec(a))&&{r:C(c[1]+""+c[1]),g:C(c[2]+""+c[2]),b:C(c[3]+""+c[3]),format:b?"name":"hex"}}function L(a){var b,c;return a=a||{level:"AA",size:"small"},b=(a.level||"AA").toUpperCase(),c=(a.size||"small").toLowerCase(),"AA"!==b&&"AAA"!==b&&(b="AA"),"small"!==c&&"large"!==c&&(c="small"),{level:b,size:c}}var M=/^\s+/,N=/\s+$/,O=0,P=a.round,Q=a.min,R=a.max,S=a.random;c.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var a=this.toRgb();return(299*a.r+587*a.g+114*a.b)/1e3},getLuminance:function(){var b,c,d,e,f,g,h=this.toRgb();return b=h.r/255,c=h.g/255,d=h.b/255,e=b<=.03928?b/12.92:a.pow((b+.055)/1.055,2.4),f=c<=.03928?c/12.92:a.pow((c+.055)/1.055,2.4),g=d<=.03928?d/12.92:a.pow((d+.055)/1.055,2.4),.2126*e+.7152*f+.0722*g},setAlpha:function(a){return this._a=z(a),this._roundA=P(100*this._a)/100,this},toHsv:function(){var a=h(this._r,this._g,this._b);return{h:360*a.h,s:a.s,v:a.v,a:this._a}},toHsvString:function(){var a=h(this._r,this._g,this._b),b=P(360*a.h),c=P(100*a.s),d=P(100*a.v);return 1==this._a?"hsv("+b+", "+c+"%, "+d+"%)":"hsva("+b+", "+c+"%, "+d+"%, "+this._roundA+")"},toHsl:function(){var a=f(this._r,this._g,this._b);return{h:360*a.h,s:a.s,l:a.l,a:this._a}},toHslString:function(){var a=f(this._r,this._g,this._b),b=P(360*a.h),c=P(100*a.s),d=P(100*a.l);return 1==this._a?"hsl("+b+", "+c+"%, "+d+"%)":"hsla("+b+", "+c+"%, "+d+"%, "+this._roundA+")"},toHex:function(a){return j(this._r,this._g,this._b,a)},toHexString:function(a){return"#"+this.toHex(a)},toHex8:function(a){return k(this._r,this._g,this._b,this._a,a)},toHex8String:function(a){return"#"+this.toHex8(a)},toRgb:function(){return{r:P(this._r),g:P(this._g),b:P(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+P(this._r)+", "+P(this._g)+", "+P(this._b)+")":"rgba("+P(this._r)+", "+P(this._g)+", "+P(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:P(100*A(this._r,255))+"%",g:P(100*A(this._g,255))+"%",b:P(100*A(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+P(100*A(this._r,255))+"%, "+P(100*A(this._g,255))+"%, "+P(100*A(this._b,255))+"%)":"rgba("+P(100*A(this._r,255))+"%, "+P(100*A(this._g,255))+"%, "+P(100*A(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(U[j(this._r,this._g,this._b,!0)]||!1)},toFilter:function(a){var b="#"+l(this._r,this._g,this._b,this._a),d=b,e=this._gradientType?"GradientType = 1, ":"";if(a){var f=c(a);d="#"+l(f._r,f._g,f._b,f._a)}return"progid:DXImageTransform.Microsoft.gradient("+e+"startColorstr="+b+",endColorstr="+d+")"},toString:function(a){var b=!!a;a=a||this._format;var c=!1,d=this._a<1&&this._a>=0;return b||!d||"hex"!==a&&"hex6"!==a&&"hex3"!==a&&"hex4"!==a&&"hex8"!==a&&"name"!==a?("rgb"===a&&(c=this.toRgbString()),"prgb"===a&&(c=this.toPercentageRgbString()),"hex"!==a&&"hex6"!==a||(c=this.toHexString()),"hex3"===a&&(c=this.toHexString(!0)),"hex4"===a&&(c=this.toHex8String(!0)),"hex8"===a&&(c=this.toHex8String()),"name"===a&&(c=this.toName()),"hsl"===a&&(c=this.toHslString()),"hsv"===a&&(c=this.toHsvString()),c||this.toHexString()):"name"===a&&0===this._a?this.toName():this.toRgbString()},clone:function(){return c(this.toString())},_applyModification:function(a,b){var c=a.apply(null,[this].concat([].slice.call(b)));return this._r=c._r,this._g=c._g,this._b=c._b,this.setAlpha(c._a),this},lighten:function(){return this._applyModification(p,arguments)},brighten:function(){return this._applyModification(q,arguments)},darken:function(){return this._applyModification(r,arguments)},desaturate:function(){return this._applyModification(m,arguments)},saturate:function(){return this._applyModification(n,arguments)},greyscale:function(){return this._applyModification(o,arguments)},spin:function(){return this._applyModification(s,arguments)},_applyCombination:function(a,b){return a.apply(null,[this].concat([].slice.call(b)))},analogous:function(){return this._applyCombination(x,arguments)},complement:function(){return this._applyCombination(t,arguments)},monochromatic:function(){return this._applyCombination(y,arguments)},splitcomplement:function(){return this._applyCombination(w,arguments)},triad:function(){return this._applyCombination(u,arguments)},tetrad:function(){return this._applyCombination(v,arguments)}},c.fromRatio=function(a,b){if("object"==typeof a){var d={};for(var e in a)a.hasOwnProperty(e)&&(d[e]="a"===e?a[e]:G(a[e]));a=d}return c(a,b)},c.equals=function(a,b){return!(!a||!b)&&c(a).toRgbString()==c(b).toRgbString()},c.random=function(){return c.fromRatio({r:S(),g:S(),b:S()})},c.mix=function(a,b,d){d=0===d?0:d||50;var e=c(a).toRgb(),f=c(b).toRgb(),g=d/100;return c({r:(f.r-e.r)*g+e.r,g:(f.g-e.g)*g+e.g,b:(f.b-e.b)*g+e.b,a:(f.a-e.a)*g+e.a})},c.readability=function(b,d){var e=c(b),f=c(d);return(a.max(e.getLuminance(),f.getLuminance())+.05)/(a.min(e.getLuminance(),f.getLuminance())+.05)},c.isReadable=function(a,b,d){var e,f,g=c.readability(a,b);switch(f=!1,e=L(d),e.level+e.size){case"AAsmall":case"AAAlarge":f=g>=4.5;break;case"AAlarge":f=g>=3;break;case"AAAsmall":f=g>=7}return f},c.mostReadable=function(a,b,d){var e,f,g,h,i=null,j=0;d=d||{},f=d.includeFallbackColors,g=d.level,h=d.size;for(var k=0;kj&&(j=e,i=c(b[k]));return c.isReadable(a,i,{level:g,size:h})||!f?i:(d.includeFallbackColors=!1,c.mostReadable(a,["#fff","#000"],d))};var T=c.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},U=c.hexNames=function(a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[a[c]]=c);return b}(T),V=function(){var a="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)",b="[\\s|\\(]+("+a+")[,|\\s]+("+a+")[,|\\s]+("+a+")\\s*\\)?",c="[\\s|\\(]+("+a+")[,|\\s]+("+a+")[,|\\s]+("+a+")[,|\\s]+("+a+")\\s*\\)?";return{CSS_UNIT:new RegExp(a),rgb:new RegExp("rgb"+b),rgba:new RegExp("rgba"+c),hsl:new RegExp("hsl"+b),hsla:new RegExp("hsla"+c),hsv:new RegExp("hsv"+b),hsva:new RegExp("hsva"+c),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/}}();void 0!==b&&b.exports?b.exports=c:"function"==typeof define&&define.amd?define(function(){return c}):window.tinycolor=c}(Math)},{}],11:[function(a,b,c){!function(){var b=a("d3"),c=a("minicharts"),d=a("./utils.js");L.Minichart=L.CircleMarker.extend({options:{type:"bar",data:[1],maxValues:"auto",colors:b.schemeCategory10,width:60,height:60,opacity:1,labels:"none",labelMinSize:8,labelMaxSize:24,labelPadding:2,labelColor:"auto",labelStyle:"font-family:sans-serif",transitionTime:750},initialize:function(a,b){this._center=a,this._zoom=0,this.options=d.mergeOptions(b,this.options),L.CircleMarker.prototype.initialize.call(this,a,{radius:this.options.width/2,stroke:!1,fill:!1})},onAdd:function(a){L.CircleMarker.prototype.onAdd.call(this,a);var c=this._container||this._renderer._rootGroup;c.setAttribute("class","leaflet-zoom-hide"),this._chart=b.select(c).append("g"),L.version>="1.0"&&this.addInteractiveTarget(this._chart.node()),a.on("moveend",this._onMoveend,this),this._redraw(!0)},onRemove:function(a){L.CircleMarker.prototype.onRemove.call(this,a),a.off("moveend",this._onMoveend,this)},_onMoveend:function(){var a=this._zoom;this._zoom=this._map.getZoom(),a!=this._zoom&&this._redraw()},setOptions:function(a){var b=a.type&&a.type!=this.options.type;this.options=d.mergeOptions(a,this.options),this._redraw(b)},_redraw:function(a){var e,f=this._map.latLngToLayerPoint(this._center);e="bar"==this.options.type?2*this.options.height:this.options.width,this._chart.attr("transform","translate("+(f.x-this.options.width/2)+","+(f.y-e/2)+")").transition().duration(this.options.transitionTime).attr("opacity",this.options.opacity);var g=this.options.data;g=d.toArray(g);for(var h=0;h10?f(c):c>1?f(c,10,!0):f(c,100,!0),d+c+b}function f(a,b,c){return b=b||1,c?Math.round(a*b)/b:Math.round(a/b)*b}b.exports.mergeOptions=a,b.exports.toArray=c,b.exports.toFunction=d,b.exports.prettyNumbers=function(a){return a.map(e)}}()},{}]},{},[11]); \ No newline at end of file diff --git a/src/minichart.js b/src/minichart.js index 7c4952c..4e4af7e 100644 --- a/src/minichart.js +++ b/src/minichart.js @@ -93,13 +93,16 @@ onAdd: function(map) { L.CircleMarker.prototype.onAdd.call(this, map); // Change class of container so that the element hides when zooming - var container = this._container || this._renderer._container; + var container = this._container || this._renderer._rootGroup; container.setAttribute("class", "leaflet-zoom-hide"); // create the svg element that holds the chart this._chart = d3.select(container).append("g"); + if (L.version >= "1.0") this.addInteractiveTarget(this._chart.node()); + map.on('moveend', this._onMoveend, this); + this._redraw(true); }, @@ -216,8 +219,8 @@ labelMinSize: this.options.labelMinSize, labelMaxSize: this.options.labelMaxSize, labelPadding: this.options.labelPadding, - labelClass: "leaflet-clickable", - shapeClass: "leaflet-clickable" + labelClass: "leaflet-clickable leaflet-interactive", + shapeClass: "leaflet-clickable leaflet-interactive" }; // Create of update chart