Last active
February 7, 2017 15:15
-
-
Save hughsk/5941408 to your computer and use it in GitHub Desktop.
made with http://requirebin.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style type='text/css'> html, body { margin: 0; padding: 0; border: 0; } </style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var hypotrochoid = require('hypotrochoid') | |
, d3 = require('d3') | |
var ranged = range(0, 500, 1) | |
var points = ranged.map(function(t) { | |
return hypotrochoid(70, [50, 70, 82.5], t) | |
}) | |
function range(start, end, inc) { | |
var a = [] | |
for (var i = start; i < end; i += inc) a[a.length] = i | |
return a | |
} | |
var line = d3.svg.line() | |
.interpolate('basis') | |
.x(function(d) { return d[0] }) | |
.y(function(d) { return d[1] }) | |
var svg = d3.select('body').append('svg') | |
.attr('width', 512) | |
.attr('height', 512) | |
var stamp = svg.append('g') | |
.attr('transform', 'translate(256,256)') | |
var path = stamp.append('path') | |
.attr('d', line(points)) | |
.attr('stroke', '#000') | |
.attr('fill', 'none') | |
setInterval(function() { | |
var a = Math.random() * 190 + 10 | |
var b = Math.random() * 190 + 10 | |
var c = Math.random() * 190 + 10 | |
var h = 30 + Math.random() * 60 | |
ranged.forEach(function(t, i) { | |
points[i] = hypotrochoid(h, [a, b, c], t) | |
}) | |
path.transition() | |
.duration(2500) | |
.attr('d', line(points)) | |
}, 2500) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require=(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({"d3":[function(require,module,exports){ | |
module.exports=require('6j6BXj'); | |
},{}],"6j6BXj":[function(require,module,exports){ | |
(function(){require("./d3"); | |
module.exports = d3; | |
(function () { delete this.d3; })(); // unset global | |
})() | |
},{"./d3":1}],1:[function(require,module,exports){ | |
d3 = function() { | |
var d3 = { | |
version: "3.2.4" | |
}; | |
if (!Date.now) Date.now = function() { | |
return +new Date(); | |
}; | |
var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window; | |
try { | |
d3_document.createElement("div").style.setProperty("opacity", 0, ""); | |
} catch (error) { | |
var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; | |
d3_element_prototype.setAttribute = function(name, value) { | |
d3_element_setAttribute.call(this, name, value + ""); | |
}; | |
d3_element_prototype.setAttributeNS = function(space, local, value) { | |
d3_element_setAttributeNS.call(this, space, local, value + ""); | |
}; | |
d3_style_prototype.setProperty = function(name, value, priority) { | |
d3_style_setProperty.call(this, name, value + "", priority); | |
}; | |
} | |
d3.ascending = function(a, b) { | |
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; | |
}; | |
d3.descending = function(a, b) { | |
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; | |
}; | |
d3.min = function(array, f) { | |
var i = -1, n = array.length, a, b; | |
if (arguments.length === 1) { | |
while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; | |
while (++i < n) if ((b = array[i]) != null && a > b) a = b; | |
} else { | |
while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; | |
} | |
return a; | |
}; | |
d3.max = function(array, f) { | |
var i = -1, n = array.length, a, b; | |
if (arguments.length === 1) { | |
while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; | |
while (++i < n) if ((b = array[i]) != null && b > a) a = b; | |
} else { | |
while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; | |
} | |
return a; | |
}; | |
d3.extent = function(array, f) { | |
var i = -1, n = array.length, a, b, c; | |
if (arguments.length === 1) { | |
while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined; | |
while (++i < n) if ((b = array[i]) != null) { | |
if (a > b) a = b; | |
if (c < b) c = b; | |
} | |
} else { | |
while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined; | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null) { | |
if (a > b) a = b; | |
if (c < b) c = b; | |
} | |
} | |
return [ a, c ]; | |
}; | |
d3.sum = function(array, f) { | |
var s = 0, n = array.length, a, i = -1; | |
if (arguments.length === 1) { | |
while (++i < n) if (!isNaN(a = +array[i])) s += a; | |
} else { | |
while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; | |
} | |
return s; | |
}; | |
function d3_number(x) { | |
return x != null && !isNaN(x); | |
} | |
d3.mean = function(array, f) { | |
var n = array.length, a, m = 0, i = -1, j = 0; | |
if (arguments.length === 1) { | |
while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; | |
} else { | |
while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; | |
} | |
return j ? m : undefined; | |
}; | |
d3.quantile = function(values, p) { | |
var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; | |
return e ? v + e * (values[h] - v) : v; | |
}; | |
d3.median = function(array, f) { | |
if (arguments.length > 1) array = array.map(f); | |
array = array.filter(d3_number); | |
return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined; | |
}; | |
d3.bisector = function(f) { | |
return { | |
left: function(a, x, lo, hi) { | |
if (arguments.length < 3) lo = 0; | |
if (arguments.length < 4) hi = a.length; | |
while (lo < hi) { | |
var mid = lo + hi >>> 1; | |
if (f.call(a, a[mid], mid) < x) lo = mid + 1; else hi = mid; | |
} | |
return lo; | |
}, | |
right: function(a, x, lo, hi) { | |
if (arguments.length < 3) lo = 0; | |
if (arguments.length < 4) hi = a.length; | |
while (lo < hi) { | |
var mid = lo + hi >>> 1; | |
if (x < f.call(a, a[mid], mid)) hi = mid; else lo = mid + 1; | |
} | |
return lo; | |
} | |
}; | |
}; | |
var d3_bisector = d3.bisector(function(d) { | |
return d; | |
}); | |
d3.bisectLeft = d3_bisector.left; | |
d3.bisect = d3.bisectRight = d3_bisector.right; | |
d3.shuffle = function(array) { | |
var m = array.length, t, i; | |
while (m) { | |
i = Math.random() * m-- | 0; | |
t = array[m], array[m] = array[i], array[i] = t; | |
} | |
return array; | |
}; | |
d3.permute = function(array, indexes) { | |
var permutes = [], i = -1, n = indexes.length; | |
while (++i < n) permutes[i] = array[indexes[i]]; | |
return permutes; | |
}; | |
d3.zip = function() { | |
if (!(n = arguments.length)) return []; | |
for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { | |
for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { | |
zip[j] = arguments[j][i]; | |
} | |
} | |
return zips; | |
}; | |
function d3_zipLength(d) { | |
return d.length; | |
} | |
d3.transpose = function(matrix) { | |
return d3.zip.apply(d3, matrix); | |
}; | |
d3.keys = function(map) { | |
var keys = []; | |
for (var key in map) keys.push(key); | |
return keys; | |
}; | |
d3.values = function(map) { | |
var values = []; | |
for (var key in map) values.push(map[key]); | |
return values; | |
}; | |
d3.entries = function(map) { | |
var entries = []; | |
for (var key in map) entries.push({ | |
key: key, | |
value: map[key] | |
}); | |
return entries; | |
}; | |
d3.merge = function(arrays) { | |
return Array.prototype.concat.apply([], arrays); | |
}; | |
d3.range = function(start, stop, step) { | |
if (arguments.length < 3) { | |
step = 1; | |
if (arguments.length < 2) { | |
stop = start; | |
start = 0; | |
} | |
} | |
if ((stop - start) / step === Infinity) throw new Error("infinite range"); | |
var range = [], k = d3_range_integerScale(Math.abs(step)), i = -1, j; | |
start *= k, stop *= k, step *= k; | |
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); | |
return range; | |
}; | |
function d3_range_integerScale(x) { | |
var k = 1; | |
while (x * k % 1) k *= 10; | |
return k; | |
} | |
function d3_class(ctor, properties) { | |
try { | |
for (var key in properties) { | |
Object.defineProperty(ctor.prototype, key, { | |
value: properties[key], | |
enumerable: false | |
}); | |
} | |
} catch (e) { | |
ctor.prototype = properties; | |
} | |
} | |
d3.map = function(object) { | |
var map = new d3_Map(); | |
for (var key in object) map.set(key, object[key]); | |
return map; | |
}; | |
function d3_Map() {} | |
d3_class(d3_Map, { | |
has: function(key) { | |
return d3_map_prefix + key in this; | |
}, | |
get: function(key) { | |
return this[d3_map_prefix + key]; | |
}, | |
set: function(key, value) { | |
return this[d3_map_prefix + key] = value; | |
}, | |
remove: function(key) { | |
key = d3_map_prefix + key; | |
return key in this && delete this[key]; | |
}, | |
keys: function() { | |
var keys = []; | |
this.forEach(function(key) { | |
keys.push(key); | |
}); | |
return keys; | |
}, | |
values: function() { | |
var values = []; | |
this.forEach(function(key, value) { | |
values.push(value); | |
}); | |
return values; | |
}, | |
entries: function() { | |
var entries = []; | |
this.forEach(function(key, value) { | |
entries.push({ | |
key: key, | |
value: value | |
}); | |
}); | |
return entries; | |
}, | |
forEach: function(f) { | |
for (var key in this) { | |
if (key.charCodeAt(0) === d3_map_prefixCode) { | |
f.call(this, key.substring(1), this[key]); | |
} | |
} | |
} | |
}); | |
var d3_map_prefix = "\0", d3_map_prefixCode = d3_map_prefix.charCodeAt(0); | |
d3.nest = function() { | |
var nest = {}, keys = [], sortKeys = [], sortValues, rollup; | |
function map(mapType, array, depth) { | |
if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; | |
var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; | |
while (++i < n) { | |
if (values = valuesByKey.get(keyValue = key(object = array[i]))) { | |
values.push(object); | |
} else { | |
valuesByKey.set(keyValue, [ object ]); | |
} | |
} | |
if (mapType) { | |
object = mapType(); | |
setter = function(keyValue, values) { | |
object.set(keyValue, map(mapType, values, depth)); | |
}; | |
} else { | |
object = {}; | |
setter = function(keyValue, values) { | |
object[keyValue] = map(mapType, values, depth); | |
}; | |
} | |
valuesByKey.forEach(setter); | |
return object; | |
} | |
function entries(map, depth) { | |
if (depth >= keys.length) return map; | |
var array = [], sortKey = sortKeys[depth++]; | |
map.forEach(function(key, keyMap) { | |
array.push({ | |
key: key, | |
values: entries(keyMap, depth) | |
}); | |
}); | |
return sortKey ? array.sort(function(a, b) { | |
return sortKey(a.key, b.key); | |
}) : array; | |
} | |
nest.map = function(array, mapType) { | |
return map(mapType, array, 0); | |
}; | |
nest.entries = function(array) { | |
return entries(map(d3.map, array, 0), 0); | |
}; | |
nest.key = function(d) { | |
keys.push(d); | |
return nest; | |
}; | |
nest.sortKeys = function(order) { | |
sortKeys[keys.length - 1] = order; | |
return nest; | |
}; | |
nest.sortValues = function(order) { | |
sortValues = order; | |
return nest; | |
}; | |
nest.rollup = function(f) { | |
rollup = f; | |
return nest; | |
}; | |
return nest; | |
}; | |
d3.set = function(array) { | |
var set = new d3_Set(); | |
if (array) for (var i = 0; i < array.length; i++) set.add(array[i]); | |
return set; | |
}; | |
function d3_Set() {} | |
d3_class(d3_Set, { | |
has: function(value) { | |
return d3_map_prefix + value in this; | |
}, | |
add: function(value) { | |
this[d3_map_prefix + value] = true; | |
return value; | |
}, | |
remove: function(value) { | |
value = d3_map_prefix + value; | |
return value in this && delete this[value]; | |
}, | |
values: function() { | |
var values = []; | |
this.forEach(function(value) { | |
values.push(value); | |
}); | |
return values; | |
}, | |
forEach: function(f) { | |
for (var value in this) { | |
if (value.charCodeAt(0) === d3_map_prefixCode) { | |
f.call(this, value.substring(1)); | |
} | |
} | |
} | |
}); | |
d3.behavior = {}; | |
d3.rebind = function(target, source) { | |
var i = 1, n = arguments.length, method; | |
while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); | |
return target; | |
}; | |
function d3_rebind(target, source, method) { | |
return function() { | |
var value = method.apply(source, arguments); | |
return value === source ? target : value; | |
}; | |
} | |
function d3_vendorSymbol(object, name) { | |
if (name in object) return name; | |
name = name.charAt(0).toUpperCase() + name.substring(1); | |
for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { | |
var prefixName = d3_vendorPrefixes[i] + name; | |
if (prefixName in object) return prefixName; | |
} | |
} | |
var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; | |
var d3_array = d3_arraySlice; | |
function d3_arrayCopy(pseudoarray) { | |
var i = -1, n = pseudoarray.length, array = []; | |
while (++i < n) array.push(pseudoarray[i]); | |
return array; | |
} | |
function d3_arraySlice(pseudoarray) { | |
return Array.prototype.slice.call(pseudoarray); | |
} | |
try { | |
d3_array(d3_documentElement.childNodes)[0].nodeType; | |
} catch (e) { | |
d3_array = d3_arrayCopy; | |
} | |
function d3_noop() {} | |
d3.dispatch = function() { | |
var dispatch = new d3_dispatch(), i = -1, n = arguments.length; | |
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); | |
return dispatch; | |
}; | |
function d3_dispatch() {} | |
d3_dispatch.prototype.on = function(type, listener) { | |
var i = type.indexOf("."), name = ""; | |
if (i >= 0) { | |
name = type.substring(i + 1); | |
type = type.substring(0, i); | |
} | |
if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); | |
if (arguments.length === 2) { | |
if (listener == null) for (type in this) { | |
if (this.hasOwnProperty(type)) this[type].on(name, null); | |
} | |
return this; | |
} | |
}; | |
function d3_dispatch_event(dispatch) { | |
var listeners = [], listenerByName = new d3_Map(); | |
function event() { | |
var z = listeners, i = -1, n = z.length, l; | |
while (++i < n) if (l = z[i].on) l.apply(this, arguments); | |
return dispatch; | |
} | |
event.on = function(name, listener) { | |
var l = listenerByName.get(name), i; | |
if (arguments.length < 2) return l && l.on; | |
if (l) { | |
l.on = null; | |
listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); | |
listenerByName.remove(name); | |
} | |
if (listener) listeners.push(listenerByName.set(name, { | |
on: listener | |
})); | |
return dispatch; | |
}; | |
return event; | |
} | |
d3.event = null; | |
function d3_eventPreventDefault() { | |
d3.event.preventDefault(); | |
} | |
function d3_eventSource() { | |
var e = d3.event, s; | |
while (s = e.sourceEvent) e = s; | |
return e; | |
} | |
function d3_eventDispatch(target) { | |
var dispatch = new d3_dispatch(), i = 0, n = arguments.length; | |
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); | |
dispatch.of = function(thiz, argumentz) { | |
return function(e1) { | |
try { | |
var e0 = e1.sourceEvent = d3.event; | |
e1.target = target; | |
d3.event = e1; | |
dispatch[e1.type].apply(thiz, argumentz); | |
} finally { | |
d3.event = e0; | |
} | |
}; | |
}; | |
return dispatch; | |
} | |
d3.requote = function(s) { | |
return s.replace(d3_requote_re, "\\$&"); | |
}; | |
var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; | |
var d3_subclass = {}.__proto__ ? function(object, prototype) { | |
object.__proto__ = prototype; | |
} : function(object, prototype) { | |
for (var property in prototype) object[property] = prototype[property]; | |
}; | |
function d3_selection(groups) { | |
d3_subclass(groups, d3_selectionPrototype); | |
return groups; | |
} | |
var d3_select = function(s, n) { | |
return n.querySelector(s); | |
}, d3_selectAll = function(s, n) { | |
return n.querySelectorAll(s); | |
}, d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) { | |
return d3_selectMatcher.call(n, s); | |
}; | |
if (typeof Sizzle === "function") { | |
d3_select = function(s, n) { | |
return Sizzle(s, n)[0] || null; | |
}; | |
d3_selectAll = function(s, n) { | |
return Sizzle.uniqueSort(Sizzle(s, n)); | |
}; | |
d3_selectMatches = Sizzle.matchesSelector; | |
} | |
d3.selection = function() { | |
return d3_selectionRoot; | |
}; | |
var d3_selectionPrototype = d3.selection.prototype = []; | |
d3_selectionPrototype.select = function(selector) { | |
var subgroups = [], subgroup, subnode, group, node; | |
selector = d3_selection_selector(selector); | |
for (var j = -1, m = this.length; ++j < m; ) { | |
subgroups.push(subgroup = []); | |
subgroup.parentNode = (group = this[j]).parentNode; | |
for (var i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) { | |
subgroup.push(subnode = selector.call(node, node.__data__, i, j)); | |
if (subnode && "__data__" in node) subnode.__data__ = node.__data__; | |
} else { | |
subgroup.push(null); | |
} | |
} | |
} | |
return d3_selection(subgroups); | |
}; | |
function d3_selection_selector(selector) { | |
return typeof selector === "function" ? selector : function() { | |
return d3_select(selector, this); | |
}; | |
} | |
d3_selectionPrototype.selectAll = function(selector) { | |
var subgroups = [], subgroup, node; | |
selector = d3_selection_selectorAll(selector); | |
for (var j = -1, m = this.length; ++j < m; ) { | |
for (var group = this[j], i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) { | |
subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); | |
subgroup.parentNode = node; | |
} | |
} | |
} | |
return d3_selection(subgroups); | |
}; | |
function d3_selection_selectorAll(selector) { | |
return typeof selector === "function" ? selector : function() { | |
return d3_selectAll(selector, this); | |
}; | |
} | |
var d3_nsPrefix = { | |
svg: "http://www.w3.org/2000/svg", | |
xhtml: "http://www.w3.org/1999/xhtml", | |
xlink: "http://www.w3.org/1999/xlink", | |
xml: "http://www.w3.org/XML/1998/namespace", | |
xmlns: "http://www.w3.org/2000/xmlns/" | |
}; | |
d3.ns = { | |
prefix: d3_nsPrefix, | |
qualify: function(name) { | |
var i = name.indexOf(":"), prefix = name; | |
if (i >= 0) { | |
prefix = name.substring(0, i); | |
name = name.substring(i + 1); | |
} | |
return d3_nsPrefix.hasOwnProperty(prefix) ? { | |
space: d3_nsPrefix[prefix], | |
local: name | |
} : name; | |
} | |
}; | |
d3_selectionPrototype.attr = function(name, value) { | |
if (arguments.length < 2) { | |
if (typeof name === "string") { | |
var node = this.node(); | |
name = d3.ns.qualify(name); | |
return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); | |
} | |
for (value in name) this.each(d3_selection_attr(value, name[value])); | |
return this; | |
} | |
return this.each(d3_selection_attr(name, value)); | |
}; | |
function d3_selection_attr(name, value) { | |
name = d3.ns.qualify(name); | |
function attrNull() { | |
this.removeAttribute(name); | |
} | |
function attrNullNS() { | |
this.removeAttributeNS(name.space, name.local); | |
} | |
function attrConstant() { | |
this.setAttribute(name, value); | |
} | |
function attrConstantNS() { | |
this.setAttributeNS(name.space, name.local, value); | |
} | |
function attrFunction() { | |
var x = value.apply(this, arguments); | |
if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); | |
} | |
function attrFunctionNS() { | |
var x = value.apply(this, arguments); | |
if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); | |
} | |
return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; | |
} | |
function d3_collapse(s) { | |
return s.trim().replace(/\s+/g, " "); | |
} | |
d3_selectionPrototype.classed = function(name, value) { | |
if (arguments.length < 2) { | |
if (typeof name === "string") { | |
var node = this.node(), n = (name = name.trim().split(/^|\s+/g)).length, i = -1; | |
if (value = node.classList) { | |
while (++i < n) if (!value.contains(name[i])) return false; | |
} else { | |
value = node.getAttribute("class"); | |
while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; | |
} | |
return true; | |
} | |
for (value in name) this.each(d3_selection_classed(value, name[value])); | |
return this; | |
} | |
return this.each(d3_selection_classed(name, value)); | |
}; | |
function d3_selection_classedRe(name) { | |
return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); | |
} | |
function d3_selection_classed(name, value) { | |
name = name.trim().split(/\s+/).map(d3_selection_classedName); | |
var n = name.length; | |
function classedConstant() { | |
var i = -1; | |
while (++i < n) name[i](this, value); | |
} | |
function classedFunction() { | |
var i = -1, x = value.apply(this, arguments); | |
while (++i < n) name[i](this, x); | |
} | |
return typeof value === "function" ? classedFunction : classedConstant; | |
} | |
function d3_selection_classedName(name) { | |
var re = d3_selection_classedRe(name); | |
return function(node, value) { | |
if (c = node.classList) return value ? c.add(name) : c.remove(name); | |
var c = node.getAttribute("class") || ""; | |
if (value) { | |
re.lastIndex = 0; | |
if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); | |
} else { | |
node.setAttribute("class", d3_collapse(c.replace(re, " "))); | |
} | |
}; | |
} | |
d3_selectionPrototype.style = function(name, value, priority) { | |
var n = arguments.length; | |
if (n < 3) { | |
if (typeof name !== "string") { | |
if (n < 2) value = ""; | |
for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); | |
return this; | |
} | |
if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); | |
priority = ""; | |
} | |
return this.each(d3_selection_style(name, value, priority)); | |
}; | |
function d3_selection_style(name, value, priority) { | |
function styleNull() { | |
this.style.removeProperty(name); | |
} | |
function styleConstant() { | |
this.style.setProperty(name, value, priority); | |
} | |
function styleFunction() { | |
var x = value.apply(this, arguments); | |
if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); | |
} | |
return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; | |
} | |
d3_selectionPrototype.property = function(name, value) { | |
if (arguments.length < 2) { | |
if (typeof name === "string") return this.node()[name]; | |
for (value in name) this.each(d3_selection_property(value, name[value])); | |
return this; | |
} | |
return this.each(d3_selection_property(name, value)); | |
}; | |
function d3_selection_property(name, value) { | |
function propertyNull() { | |
delete this[name]; | |
} | |
function propertyConstant() { | |
this[name] = value; | |
} | |
function propertyFunction() { | |
var x = value.apply(this, arguments); | |
if (x == null) delete this[name]; else this[name] = x; | |
} | |
return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; | |
} | |
d3_selectionPrototype.text = function(value) { | |
return arguments.length ? this.each(typeof value === "function" ? function() { | |
var v = value.apply(this, arguments); | |
this.textContent = v == null ? "" : v; | |
} : value == null ? function() { | |
this.textContent = ""; | |
} : function() { | |
this.textContent = value; | |
}) : this.node().textContent; | |
}; | |
d3_selectionPrototype.html = function(value) { | |
return arguments.length ? this.each(typeof value === "function" ? function() { | |
var v = value.apply(this, arguments); | |
this.innerHTML = v == null ? "" : v; | |
} : value == null ? function() { | |
this.innerHTML = ""; | |
} : function() { | |
this.innerHTML = value; | |
}) : this.node().innerHTML; | |
}; | |
d3_selectionPrototype.append = function(name) { | |
name = d3_selection_creator(name); | |
return this.select(function() { | |
return this.appendChild(name.apply(this, arguments)); | |
}); | |
}; | |
function d3_selection_creator(name) { | |
return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() { | |
return d3_document.createElementNS(name.space, name.local); | |
} : function() { | |
return d3_document.createElementNS(this.namespaceURI, name); | |
}; | |
} | |
d3_selectionPrototype.insert = function(name, before) { | |
name = d3_selection_creator(name); | |
before = d3_selection_selector(before); | |
return this.select(function() { | |
return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments)); | |
}); | |
}; | |
d3_selectionPrototype.remove = function() { | |
return this.each(function() { | |
var parent = this.parentNode; | |
if (parent) parent.removeChild(this); | |
}); | |
}; | |
d3_selectionPrototype.data = function(value, key) { | |
var i = -1, n = this.length, group, node; | |
if (!arguments.length) { | |
value = new Array(n = (group = this[0]).length); | |
while (++i < n) { | |
if (node = group[i]) { | |
value[i] = node.__data__; | |
} | |
} | |
return value; | |
} | |
function bind(group, groupData) { | |
var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; | |
if (key) { | |
var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue; | |
for (i = -1; ++i < n; ) { | |
keyValue = key.call(node = group[i], node.__data__, i); | |
if (nodeByKeyValue.has(keyValue)) { | |
exitNodes[i] = node; | |
} else { | |
nodeByKeyValue.set(keyValue, node); | |
} | |
keyValues.push(keyValue); | |
} | |
for (i = -1; ++i < m; ) { | |
keyValue = key.call(groupData, nodeData = groupData[i], i); | |
if (node = nodeByKeyValue.get(keyValue)) { | |
updateNodes[i] = node; | |
node.__data__ = nodeData; | |
} else if (!dataByKeyValue.has(keyValue)) { | |
enterNodes[i] = d3_selection_dataNode(nodeData); | |
} | |
dataByKeyValue.set(keyValue, nodeData); | |
nodeByKeyValue.remove(keyValue); | |
} | |
for (i = -1; ++i < n; ) { | |
if (nodeByKeyValue.has(keyValues[i])) { | |
exitNodes[i] = group[i]; | |
} | |
} | |
} else { | |
for (i = -1; ++i < n0; ) { | |
node = group[i]; | |
nodeData = groupData[i]; | |
if (node) { | |
node.__data__ = nodeData; | |
updateNodes[i] = node; | |
} else { | |
enterNodes[i] = d3_selection_dataNode(nodeData); | |
} | |
} | |
for (;i < m; ++i) { | |
enterNodes[i] = d3_selection_dataNode(groupData[i]); | |
} | |
for (;i < n; ++i) { | |
exitNodes[i] = group[i]; | |
} | |
} | |
enterNodes.update = updateNodes; | |
enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; | |
enter.push(enterNodes); | |
update.push(updateNodes); | |
exit.push(exitNodes); | |
} | |
var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); | |
if (typeof value === "function") { | |
while (++i < n) { | |
bind(group = this[i], value.call(group, group.parentNode.__data__, i)); | |
} | |
} else { | |
while (++i < n) { | |
bind(group = this[i], value); | |
} | |
} | |
update.enter = function() { | |
return enter; | |
}; | |
update.exit = function() { | |
return exit; | |
}; | |
return update; | |
}; | |
function d3_selection_dataNode(data) { | |
return { | |
__data__: data | |
}; | |
} | |
d3_selectionPrototype.datum = function(value) { | |
return arguments.length ? this.property("__data__", value) : this.property("__data__"); | |
}; | |
d3_selectionPrototype.filter = function(filter) { | |
var subgroups = [], subgroup, group, node; | |
if (typeof filter !== "function") filter = d3_selection_filter(filter); | |
for (var j = 0, m = this.length; j < m; j++) { | |
subgroups.push(subgroup = []); | |
subgroup.parentNode = (group = this[j]).parentNode; | |
for (var i = 0, n = group.length; i < n; i++) { | |
if ((node = group[i]) && filter.call(node, node.__data__, i)) { | |
subgroup.push(node); | |
} | |
} | |
} | |
return d3_selection(subgroups); | |
}; | |
function d3_selection_filter(selector) { | |
return function() { | |
return d3_selectMatches(this, selector); | |
}; | |
} | |
d3_selectionPrototype.order = function() { | |
for (var j = -1, m = this.length; ++j < m; ) { | |
for (var group = this[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 this; | |
}; | |
d3_selectionPrototype.sort = function(comparator) { | |
comparator = d3_selection_sortComparator.apply(this, arguments); | |
for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); | |
return this.order(); | |
}; | |
function d3_selection_sortComparator(comparator) { | |
if (!arguments.length) comparator = d3.ascending; | |
return function(a, b) { | |
return !a - !b || comparator(a.__data__, b.__data__); | |
}; | |
} | |
d3_selectionPrototype.each = function(callback) { | |
return d3_selection_each(this, function(node, i, j) { | |
callback.call(node, node.__data__, i, j); | |
}); | |
}; | |
function d3_selection_each(groups, callback) { | |
for (var 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(node, i, j); | |
} | |
} | |
return groups; | |
} | |
d3_selectionPrototype.call = function(callback) { | |
var args = d3_array(arguments); | |
callback.apply(args[0] = this, args); | |
return this; | |
}; | |
d3_selectionPrototype.empty = function() { | |
return !this.node(); | |
}; | |
d3_selectionPrototype.node = function() { | |
for (var j = 0, m = this.length; j < m; j++) { | |
for (var group = this[j], i = 0, n = group.length; i < n; i++) { | |
var node = group[i]; | |
if (node) return node; | |
} | |
} | |
return null; | |
}; | |
d3_selectionPrototype.size = function() { | |
var n = 0; | |
this.each(function() { | |
++n; | |
}); | |
return n; | |
}; | |
function d3_selection_enter(selection) { | |
d3_subclass(selection, d3_selection_enterPrototype); | |
return selection; | |
} | |
var d3_selection_enterPrototype = []; | |
d3.selection.enter = d3_selection_enter; | |
d3.selection.enter.prototype = d3_selection_enterPrototype; | |
d3_selection_enterPrototype.append = d3_selectionPrototype.append; | |
d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; | |
d3_selection_enterPrototype.node = d3_selectionPrototype.node; | |
d3_selection_enterPrototype.call = d3_selectionPrototype.call; | |
d3_selection_enterPrototype.size = d3_selectionPrototype.size; | |
d3_selection_enterPrototype.select = function(selector) { | |
var subgroups = [], subgroup, subnode, upgroup, group, node; | |
for (var j = -1, m = this.length; ++j < m; ) { | |
upgroup = (group = this[j]).update; | |
subgroups.push(subgroup = []); | |
subgroup.parentNode = group.parentNode; | |
for (var i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) { | |
subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); | |
subnode.__data__ = node.__data__; | |
} else { | |
subgroup.push(null); | |
} | |
} | |
} | |
return d3_selection(subgroups); | |
}; | |
d3_selection_enterPrototype.insert = function(name, before) { | |
if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); | |
return d3_selectionPrototype.insert.call(this, name, before); | |
}; | |
function d3_selection_enterInsertBefore(enter) { | |
var i0, j0; | |
return function(d, i, j) { | |
var group = enter[j].update, n = group.length, node; | |
if (j != j0) j0 = j, i0 = 0; | |
if (i >= i0) i0 = i + 1; | |
while (!(node = group[i0]) && ++i0 < n) ; | |
return node; | |
}; | |
} | |
d3_selectionPrototype.transition = function() { | |
var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || { | |
time: Date.now(), | |
ease: d3_ease_cubicInOut, | |
delay: 0, | |
duration: 250 | |
}; | |
for (var j = -1, m = this.length; ++j < m; ) { | |
subgroups.push(subgroup = []); | |
for (var group = this[j], i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) d3_transitionNode(node, i, id, transition); | |
subgroup.push(node); | |
} | |
} | |
return d3_transition(subgroups, id); | |
}; | |
d3.select = function(node) { | |
var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ]; | |
group.parentNode = d3_documentElement; | |
return d3_selection([ group ]); | |
}; | |
d3.selectAll = function(nodes) { | |
var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); | |
group.parentNode = d3_documentElement; | |
return d3_selection([ group ]); | |
}; | |
var d3_selectionRoot = d3.select(d3_documentElement); | |
d3_selectionPrototype.on = function(type, listener, capture) { | |
var n = arguments.length; | |
if (n < 3) { | |
if (typeof type !== "string") { | |
if (n < 2) listener = false; | |
for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); | |
return this; | |
} | |
if (n < 2) return (n = this.node()["__on" + type]) && n._; | |
capture = false; | |
} | |
return this.each(d3_selection_on(type, listener, capture)); | |
}; | |
function d3_selection_on(type, listener, capture) { | |
var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; | |
if (i > 0) type = type.substring(0, i); | |
var filter = d3_selection_onFilters.get(type); | |
if (filter) type = filter, wrap = d3_selection_onFilter; | |
function onRemove() { | |
var l = this[name]; | |
if (l) { | |
this.removeEventListener(type, l, l.$); | |
delete this[name]; | |
} | |
} | |
function onAdd() { | |
var l = wrap(listener, d3_array(arguments)); | |
onRemove.call(this); | |
this.addEventListener(type, this[name] = l, l.$ = capture); | |
l._ = listener; | |
} | |
function removeAll() { | |
var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; | |
for (var name in this) { | |
if (match = name.match(re)) { | |
var l = this[name]; | |
this.removeEventListener(match[1], l, l.$); | |
delete this[name]; | |
} | |
} | |
} | |
return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; | |
} | |
var d3_selection_onFilters = d3.map({ | |
mouseenter: "mouseover", | |
mouseleave: "mouseout" | |
}); | |
d3_selection_onFilters.forEach(function(k) { | |
if ("on" + k in d3_document) d3_selection_onFilters.remove(k); | |
}); | |
function d3_selection_onListener(listener, argumentz) { | |
return function(e) { | |
var o = d3.event; | |
d3.event = e; | |
argumentz[0] = this.__data__; | |
try { | |
listener.apply(this, argumentz); | |
} finally { | |
d3.event = o; | |
} | |
}; | |
} | |
function d3_selection_onFilter(listener, argumentz) { | |
var l = d3_selection_onListener(listener, argumentz); | |
return function(e) { | |
var target = this, related = e.relatedTarget; | |
if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { | |
l.call(target, e); | |
} | |
}; | |
} | |
var d3_event_dragSelect = d3_vendorSymbol(d3_documentElement.style, "userSelect"); | |
function d3_event_dragSuppress(type) { | |
var selectstart = "selectstart." + type, dragstart = "dragstart." + type, click = "click." + type, w = d3.select(d3_window).on(selectstart, d3_eventPreventDefault).on(dragstart, d3_eventPreventDefault), style = d3_documentElement.style, select = style[d3_event_dragSelect]; | |
style[d3_event_dragSelect] = "none"; | |
return function(suppressClick) { | |
w.on(selectstart, null).on(dragstart, null); | |
style[d3_event_dragSelect] = select; | |
if (suppressClick) { | |
function off() { | |
w.on(click, null); | |
} | |
w.on(click, function() { | |
d3_eventPreventDefault(); | |
off(); | |
}, true); | |
setTimeout(off, 0); | |
} | |
}; | |
} | |
d3.mouse = function(container) { | |
return d3_mousePoint(container, d3_eventSource()); | |
}; | |
var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0; | |
function d3_mousePoint(container, e) { | |
var svg = container.ownerSVGElement || container; | |
if (svg.createSVGPoint) { | |
var point = svg.createSVGPoint(); | |
if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) { | |
svg = d3.select("body").append("svg").style({ | |
position: "absolute", | |
top: 0, | |
left: 0, | |
margin: 0, | |
padding: 0, | |
border: "none" | |
}, "important"); | |
var ctm = svg[0][0].getScreenCTM(); | |
d3_mouse_bug44083 = !(ctm.f || ctm.e); | |
svg.remove(); | |
} | |
if (d3_mouse_bug44083) { | |
point.x = e.pageX; | |
point.y = e.pageY; | |
} else { | |
point.x = e.clientX; | |
point.y = e.clientY; | |
} | |
point = point.matrixTransform(container.getScreenCTM().inverse()); | |
return [ point.x, point.y ]; | |
} | |
var rect = container.getBoundingClientRect(); | |
return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; | |
} | |
d3.touches = function(container, touches) { | |
if (arguments.length < 2) touches = d3_eventSource().touches; | |
return touches ? d3_array(touches).map(function(touch) { | |
var point = d3_mousePoint(container, touch); | |
point.identifier = touch.identifier; | |
return point; | |
}) : []; | |
}; | |
d3.behavior.drag = function() { | |
var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null; | |
function drag() { | |
this.on("mousedown.drag", mousedown).on("touchstart.drag", mousedown); | |
} | |
function mousedown() { | |
var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null, offset, origin_ = point(), moved = 0, dragRestore = d3_event_dragSuppress(touchId != null ? "drag-" + touchId : "drag"); | |
var w = d3.select(d3_window).on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true); | |
if (origin) { | |
offset = origin.apply(target, arguments); | |
offset = [ offset.x - origin_[0], offset.y - origin_[1] ]; | |
} else { | |
offset = [ 0, 0 ]; | |
} | |
event_({ | |
type: "dragstart" | |
}); | |
function point() { | |
var p = target.parentNode; | |
return touchId != null ? d3.touches(p).filter(function(p) { | |
return p.identifier === touchId; | |
})[0] : d3.mouse(p); | |
} | |
function dragmove() { | |
if (!target.parentNode) return dragend(); | |
var p = point(), dx = p[0] - origin_[0], dy = p[1] - origin_[1]; | |
moved |= dx | dy; | |
origin_ = p; | |
event_({ | |
type: "drag", | |
x: p[0] + offset[0], | |
y: p[1] + offset[1], | |
dx: dx, | |
dy: dy | |
}); | |
} | |
function dragend() { | |
w.on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", null).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", null); | |
dragRestore(moved && d3.event.target === eventTarget); | |
event_({ | |
type: "dragend" | |
}); | |
} | |
} | |
drag.origin = function(x) { | |
if (!arguments.length) return origin; | |
origin = x; | |
return drag; | |
}; | |
return d3.rebind(drag, event, "on"); | |
}; | |
d3.behavior.zoom = function() { | |
var translate = [ 0, 0 ], translate0, scale = 1, distance0, scale0, scaleExtent = d3_behavior_zoomInfinity, event = d3_eventDispatch(zoom, "zoom"), x0, x1, y0, y1, touchtime; | |
function zoom() { | |
this.on("mousedown.zoom", mousedown).on("mousemove.zoom", mousemove).on(d3_behavior_zoomWheel + ".zoom", mousewheel).on("dblclick.zoom", dblclick).on("touchstart.zoom", touchstart).on("touchmove.zoom", touchmove).on("touchend.zoom", touchstart); | |
} | |
zoom.translate = function(x) { | |
if (!arguments.length) return translate; | |
translate = x.map(Number); | |
rescale(); | |
return zoom; | |
}; | |
zoom.scale = function(x) { | |
if (!arguments.length) return scale; | |
scale = +x; | |
rescale(); | |
return zoom; | |
}; | |
zoom.scaleExtent = function(x) { | |
if (!arguments.length) return scaleExtent; | |
scaleExtent = x == null ? d3_behavior_zoomInfinity : x.map(Number); | |
return zoom; | |
}; | |
zoom.x = function(z) { | |
if (!arguments.length) return x1; | |
x1 = z; | |
x0 = z.copy(); | |
translate = [ 0, 0 ]; | |
scale = 1; | |
return zoom; | |
}; | |
zoom.y = function(z) { | |
if (!arguments.length) return y1; | |
y1 = z; | |
y0 = z.copy(); | |
translate = [ 0, 0 ]; | |
scale = 1; | |
return zoom; | |
}; | |
function location(p) { | |
return [ (p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale ]; | |
} | |
function point(l) { | |
return [ l[0] * scale + translate[0], l[1] * scale + translate[1] ]; | |
} | |
function scaleTo(s) { | |
scale = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); | |
} | |
function translateTo(p, l) { | |
l = point(l); | |
translate[0] += p[0] - l[0]; | |
translate[1] += p[1] - l[1]; | |
} | |
function rescale() { | |
if (x1) x1.domain(x0.range().map(function(x) { | |
return (x - translate[0]) / scale; | |
}).map(x0.invert)); | |
if (y1) y1.domain(y0.range().map(function(y) { | |
return (y - translate[1]) / scale; | |
}).map(y0.invert)); | |
} | |
function dispatch(event) { | |
rescale(); | |
d3.event.preventDefault(); | |
event({ | |
type: "zoom", | |
scale: scale, | |
translate: translate | |
}); | |
} | |
function mousedown() { | |
var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, moved = 0, w = d3.select(d3_window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup), l = location(d3.mouse(target)), dragRestore = d3_event_dragSuppress("zoom"); | |
function mousemove() { | |
moved = 1; | |
translateTo(d3.mouse(target), l); | |
dispatch(event_); | |
} | |
function mouseup() { | |
w.on("mousemove.zoom", null).on("mouseup.zoom", null); | |
dragRestore(moved && d3.event.target === eventTarget); | |
} | |
} | |
function mousewheel() { | |
if (!translate0) translate0 = location(d3.mouse(this)); | |
scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * scale); | |
translateTo(d3.mouse(this), translate0); | |
dispatch(event.of(this, arguments)); | |
} | |
function mousemove() { | |
translate0 = null; | |
} | |
function dblclick() { | |
var p = d3.mouse(this), l = location(p), k = Math.log(scale) / Math.LN2; | |
scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); | |
translateTo(p, l); | |
dispatch(event.of(this, arguments)); | |
} | |
function touchstart() { | |
var touches = d3.touches(this), now = Date.now(); | |
scale0 = scale; | |
translate0 = {}; | |
distance0 = 0; | |
touches.forEach(function(t) { | |
translate0[t.identifier] = location(t); | |
}); | |
if (touches.length === 1) { | |
if (now - touchtime < 500) { | |
var p = touches[0], l = location(touches[0]); | |
scaleTo(scale * 2); | |
translateTo(p, l); | |
dispatch(event.of(this, arguments)); | |
} | |
touchtime = now; | |
} else if (touches.length > 1) { | |
var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; | |
distance0 = dx * dx + dy * dy; | |
} | |
} | |
function touchmove() { | |
var touches = d3.touches(this), p0 = touches[0], l0 = translate0[p0.identifier]; | |
if (p1 = touches[1]) { | |
var p1, l1 = translate0[p1.identifier], scale1 = d3.event.scale; | |
if (scale1 == null) { | |
var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1; | |
scale1 = distance0 && Math.sqrt(distance1 / distance0); | |
} | |
p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; | |
l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; | |
scaleTo(scale1 * scale0); | |
} | |
translateTo(p0, l0); | |
touchtime = null; | |
dispatch(event.of(this, arguments)); | |
} | |
return d3.rebind(zoom, event, "on"); | |
}; | |
var d3_behavior_zoomInfinity = [ 0, Infinity ]; | |
var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { | |
return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); | |
}, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { | |
return d3.event.wheelDelta; | |
}, "mousewheel") : (d3_behavior_zoomDelta = function() { | |
return -d3.event.detail; | |
}, "MozMousePixelScroll"); | |
function d3_Color() {} | |
d3_Color.prototype.toString = function() { | |
return this.rgb() + ""; | |
}; | |
d3.hsl = function(h, s, l) { | |
return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l); | |
}; | |
function d3_hsl(h, s, l) { | |
return new d3_Hsl(h, s, l); | |
} | |
function d3_Hsl(h, s, l) { | |
this.h = h; | |
this.s = s; | |
this.l = l; | |
} | |
var d3_hslPrototype = d3_Hsl.prototype = new d3_Color(); | |
d3_hslPrototype.brighter = function(k) { | |
k = Math.pow(.7, arguments.length ? k : 1); | |
return d3_hsl(this.h, this.s, this.l / k); | |
}; | |
d3_hslPrototype.darker = function(k) { | |
k = Math.pow(.7, arguments.length ? k : 1); | |
return d3_hsl(this.h, this.s, k * this.l); | |
}; | |
d3_hslPrototype.rgb = function() { | |
return d3_hsl_rgb(this.h, this.s, this.l); | |
}; | |
function d3_hsl_rgb(h, s, l) { | |
var m1, m2; | |
h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; | |
s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; | |
l = l < 0 ? 0 : l > 1 ? 1 : l; | |
m2 = l <= .5 ? l * (1 + s) : l + s - l * s; | |
m1 = 2 * l - m2; | |
function v(h) { | |
if (h > 360) h -= 360; else if (h < 0) h += 360; | |
if (h < 60) return m1 + (m2 - m1) * h / 60; | |
if (h < 180) return m2; | |
if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; | |
return m1; | |
} | |
function vv(h) { | |
return Math.round(v(h) * 255); | |
} | |
return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); | |
} | |
var π = Math.PI, ε = 1e-6, ε2 = ε * ε, d3_radians = π / 180, d3_degrees = 180 / π; | |
function d3_sgn(x) { | |
return x > 0 ? 1 : x < 0 ? -1 : 0; | |
} | |
function d3_acos(x) { | |
return x > 1 ? 0 : x < -1 ? π : Math.acos(x); | |
} | |
function d3_asin(x) { | |
return x > 1 ? π / 2 : x < -1 ? -π / 2 : Math.asin(x); | |
} | |
function d3_sinh(x) { | |
return (Math.exp(x) - Math.exp(-x)) / 2; | |
} | |
function d3_cosh(x) { | |
return (Math.exp(x) + Math.exp(-x)) / 2; | |
} | |
function d3_haversin(x) { | |
return (x = Math.sin(x / 2)) * x; | |
} | |
d3.hcl = function(h, c, l) { | |
return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l); | |
}; | |
function d3_hcl(h, c, l) { | |
return new d3_Hcl(h, c, l); | |
} | |
function d3_Hcl(h, c, l) { | |
this.h = h; | |
this.c = c; | |
this.l = l; | |
} | |
var d3_hclPrototype = d3_Hcl.prototype = new d3_Color(); | |
d3_hclPrototype.brighter = function(k) { | |
return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); | |
}; | |
d3_hclPrototype.darker = function(k) { | |
return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); | |
}; | |
d3_hclPrototype.rgb = function() { | |
return d3_hcl_lab(this.h, this.c, this.l).rgb(); | |
}; | |
function d3_hcl_lab(h, c, l) { | |
if (isNaN(h)) h = 0; | |
if (isNaN(c)) c = 0; | |
return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); | |
} | |
d3.lab = function(l, a, b) { | |
return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b); | |
}; | |
function d3_lab(l, a, b) { | |
return new d3_Lab(l, a, b); | |
} | |
function d3_Lab(l, a, b) { | |
this.l = l; | |
this.a = a; | |
this.b = b; | |
} | |
var d3_lab_K = 18; | |
var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; | |
var d3_labPrototype = d3_Lab.prototype = new d3_Color(); | |
d3_labPrototype.brighter = function(k) { | |
return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); | |
}; | |
d3_labPrototype.darker = function(k) { | |
return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); | |
}; | |
d3_labPrototype.rgb = function() { | |
return d3_lab_rgb(this.l, this.a, this.b); | |
}; | |
function d3_lab_rgb(l, a, b) { | |
var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; | |
x = d3_lab_xyz(x) * d3_lab_X; | |
y = d3_lab_xyz(y) * d3_lab_Y; | |
z = d3_lab_xyz(z) * d3_lab_Z; | |
return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); | |
} | |
function d3_lab_hcl(l, a, b) { | |
return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l); | |
} | |
function d3_lab_xyz(x) { | |
return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; | |
} | |
function d3_xyz_lab(x) { | |
return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; | |
} | |
function d3_xyz_rgb(r) { | |
return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); | |
} | |
d3.rgb = function(r, g, b) { | |
return arguments.length === 1 ? r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : d3_rgb(~~r, ~~g, ~~b); | |
}; | |
function d3_rgb(r, g, b) { | |
return new d3_Rgb(r, g, b); | |
} | |
function d3_Rgb(r, g, b) { | |
this.r = r; | |
this.g = g; | |
this.b = b; | |
} | |
var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color(); | |
d3_rgbPrototype.brighter = function(k) { | |
k = Math.pow(.7, arguments.length ? k : 1); | |
var r = this.r, g = this.g, b = this.b, i = 30; | |
if (!r && !g && !b) return d3_rgb(i, i, i); | |
if (r && r < i) r = i; | |
if (g && g < i) g = i; | |
if (b && b < i) b = i; | |
return d3_rgb(Math.min(255, Math.floor(r / k)), Math.min(255, Math.floor(g / k)), Math.min(255, Math.floor(b / k))); | |
}; | |
d3_rgbPrototype.darker = function(k) { | |
k = Math.pow(.7, arguments.length ? k : 1); | |
return d3_rgb(Math.floor(k * this.r), Math.floor(k * this.g), Math.floor(k * this.b)); | |
}; | |
d3_rgbPrototype.hsl = function() { | |
return d3_rgb_hsl(this.r, this.g, this.b); | |
}; | |
d3_rgbPrototype.toString = function() { | |
return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); | |
}; | |
function d3_rgb_hex(v) { | |
return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); | |
} | |
function d3_rgb_parse(format, rgb, hsl) { | |
var r = 0, g = 0, b = 0, m1, m2, name; | |
m1 = /([a-z]+)\((.*)\)/i.exec(format); | |
if (m1) { | |
m2 = m1[2].split(","); | |
switch (m1[1]) { | |
case "hsl": | |
{ | |
return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); | |
} | |
case "rgb": | |
{ | |
return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); | |
} | |
} | |
} | |
if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b); | |
if (format != null && format.charAt(0) === "#") { | |
if (format.length === 4) { | |
r = format.charAt(1); | |
r += r; | |
g = format.charAt(2); | |
g += g; | |
b = format.charAt(3); | |
b += b; | |
} else if (format.length === 7) { | |
r = format.substring(1, 3); | |
g = format.substring(3, 5); | |
b = format.substring(5, 7); | |
} | |
r = parseInt(r, 16); | |
g = parseInt(g, 16); | |
b = parseInt(b, 16); | |
} | |
return rgb(r, g, b); | |
} | |
function d3_rgb_hsl(r, g, b) { | |
var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; | |
if (d) { | |
s = l < .5 ? d / (max + min) : d / (2 - max - min); | |
if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; | |
h *= 60; | |
} else { | |
h = NaN; | |
s = l > 0 && l < 1 ? 0 : h; | |
} | |
return d3_hsl(h, s, l); | |
} | |
function d3_rgb_lab(r, g, b) { | |
r = d3_rgb_xyz(r); | |
g = d3_rgb_xyz(g); | |
b = d3_rgb_xyz(b); | |
var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); | |
return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); | |
} | |
function d3_rgb_xyz(r) { | |
return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); | |
} | |
function d3_rgb_parseNumber(c) { | |
var f = parseFloat(c); | |
return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; | |
} | |
var d3_rgb_names = d3.map({ | |
aliceblue: "#f0f8ff", | |
antiquewhite: "#faebd7", | |
aqua: "#00ffff", | |
aquamarine: "#7fffd4", | |
azure: "#f0ffff", | |
beige: "#f5f5dc", | |
bisque: "#ffe4c4", | |
black: "#000000", | |
blanchedalmond: "#ffebcd", | |
blue: "#0000ff", | |
blueviolet: "#8a2be2", | |
brown: "#a52a2a", | |
burlywood: "#deb887", | |
cadetblue: "#5f9ea0", | |
chartreuse: "#7fff00", | |
chocolate: "#d2691e", | |
coral: "#ff7f50", | |
cornflowerblue: "#6495ed", | |
cornsilk: "#fff8dc", | |
crimson: "#dc143c", | |
cyan: "#00ffff", | |
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: "#ff00ff", | |
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: "#778899", | |
lightslategrey: "#778899", | |
lightsteelblue: "#b0c4de", | |
lightyellow: "#ffffe0", | |
lime: "#00ff00", | |
limegreen: "#32cd32", | |
linen: "#faf0e6", | |
magenta: "#ff00ff", | |
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", | |
red: "#ff0000", | |
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: "#ffffff", | |
whitesmoke: "#f5f5f5", | |
yellow: "#ffff00", | |
yellowgreen: "#9acd32" | |
}); | |
d3_rgb_names.forEach(function(key, value) { | |
d3_rgb_names.set(key, d3_rgb_parse(value, d3_rgb, d3_hsl_rgb)); | |
}); | |
function d3_functor(v) { | |
return typeof v === "function" ? v : function() { | |
return v; | |
}; | |
} | |
d3.functor = d3_functor; | |
function d3_identity(d) { | |
return d; | |
} | |
d3.xhr = d3_xhrType(d3_identity); | |
function d3_xhrType(response) { | |
return function(url, mimeType, callback) { | |
if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, | |
mimeType = null; | |
return d3_xhr(url, mimeType, response, callback); | |
}; | |
} | |
function d3_xhr(url, mimeType, response, callback) { | |
var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; | |
if (d3_window.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); | |
"onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { | |
request.readyState > 3 && respond(); | |
}; | |
function respond() { | |
var status = request.status, result; | |
if (!status && request.responseText || status >= 200 && status < 300 || status === 304) { | |
try { | |
result = response.call(xhr, request); | |
} catch (e) { | |
dispatch.error.call(xhr, e); | |
return; | |
} | |
dispatch.load.call(xhr, result); | |
} else { | |
dispatch.error.call(xhr, request); | |
} | |
} | |
request.onprogress = function(event) { | |
var o = d3.event; | |
d3.event = event; | |
try { | |
dispatch.progress.call(xhr, request); | |
} finally { | |
d3.event = o; | |
} | |
}; | |
xhr.header = function(name, value) { | |
name = (name + "").toLowerCase(); | |
if (arguments.length < 2) return headers[name]; | |
if (value == null) delete headers[name]; else headers[name] = value + ""; | |
return xhr; | |
}; | |
xhr.mimeType = function(value) { | |
if (!arguments.length) return mimeType; | |
mimeType = value == null ? null : value + ""; | |
return xhr; | |
}; | |
xhr.responseType = function(value) { | |
if (!arguments.length) return responseType; | |
responseType = value; | |
return xhr; | |
}; | |
xhr.response = function(value) { | |
response = value; | |
return xhr; | |
}; | |
[ "get", "post" ].forEach(function(method) { | |
xhr[method] = function() { | |
return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); | |
}; | |
}); | |
xhr.send = function(method, data, callback) { | |
if (arguments.length === 2 && typeof data === "function") callback = data, data = null; | |
request.open(method, url, true); | |
if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; | |
if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); | |
if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); | |
if (responseType != null) request.responseType = responseType; | |
if (callback != null) xhr.on("error", callback).on("load", function(request) { | |
callback(null, request); | |
}); | |
request.send(data == null ? null : data); | |
return xhr; | |
}; | |
xhr.abort = function() { | |
request.abort(); | |
return xhr; | |
}; | |
d3.rebind(xhr, dispatch, "on"); | |
return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); | |
} | |
function d3_xhr_fixCallback(callback) { | |
return callback.length === 1 ? function(error, request) { | |
callback(error == null ? request : null); | |
} : callback; | |
} | |
d3.dsv = function(delimiter, mimeType) { | |
var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); | |
function dsv(url, row, callback) { | |
if (arguments.length < 3) callback = row, row = null; | |
var xhr = d3.xhr(url, mimeType, callback); | |
xhr.row = function(_) { | |
return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; | |
}; | |
return xhr.row(row); | |
} | |
function response(request) { | |
return dsv.parse(request.responseText); | |
} | |
function typedResponse(f) { | |
return function(request) { | |
return dsv.parse(request.responseText, f); | |
}; | |
} | |
dsv.parse = function(text, f) { | |
var o; | |
return dsv.parseRows(text, function(row, i) { | |
if (o) return o(row, i - 1); | |
var a = new Function("d", "return {" + row.map(function(name, i) { | |
return JSON.stringify(name) + ": d[" + i + "]"; | |
}).join(",") + "}"); | |
o = f ? function(row, i) { | |
return f(a(row), i); | |
} : a; | |
}); | |
}; | |
dsv.parseRows = function(text, f) { | |
var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; | |
function token() { | |
if (I >= N) return EOF; | |
if (eol) return eol = false, EOL; | |
var j = I; | |
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; | |
var 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.substring(j + 1, i).replace(/""/g, '"'); | |
} | |
while (I < N) { | |
var c = text.charCodeAt(I++), k = 1; | |
if (c === 10) eol = true; else if (c === 13) { | |
eol = true; | |
if (text.charCodeAt(I) === 10) ++I, ++k; | |
} else if (c !== delimiterCode) continue; | |
return text.substring(j, I - k); | |
} | |
return text.substring(j); | |
} | |
while ((t = token()) !== EOF) { | |
var a = []; | |
while (t !== EOL && t !== EOF) { | |
a.push(t); | |
t = token(); | |
} | |
if (f && !(a = f(a, n++))) continue; | |
rows.push(a); | |
} | |
return rows; | |
}; | |
dsv.format = function(rows) { | |
if (Array.isArray(rows[0])) return dsv.formatRows(rows); | |
var fieldSet = new d3_Set(), fields = []; | |
rows.forEach(function(row) { | |
for (var field in row) { | |
if (!fieldSet.has(field)) { | |
fields.push(fieldSet.add(field)); | |
} | |
} | |
}); | |
return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { | |
return fields.map(function(field) { | |
return formatValue(row[field]); | |
}).join(delimiter); | |
})).join("\n"); | |
}; | |
dsv.formatRows = function(rows) { | |
return rows.map(formatRow).join("\n"); | |
}; | |
function formatRow(row) { | |
return row.map(formatValue).join(delimiter); | |
} | |
function formatValue(text) { | |
return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; | |
} | |
return dsv; | |
}; | |
d3.csv = d3.dsv(",", "text/csv"); | |
d3.tsv = d3.dsv(" ", "text/tab-separated-values"); | |
var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout; | |
d3.timer = function(callback, delay, then) { | |
if (arguments.length < 3) { | |
if (arguments.length < 2) delay = 0; else if (!isFinite(delay)) return; | |
then = Date.now(); | |
} | |
var time = then + delay; | |
var timer = { | |
callback: callback, | |
time: time, | |
next: null | |
}; | |
if (d3_timer_queueTail) d3_timer_queueTail.next = timer; else d3_timer_queueHead = timer; | |
d3_timer_queueTail = timer; | |
if (!d3_timer_interval) { | |
d3_timer_timeout = clearTimeout(d3_timer_timeout); | |
d3_timer_interval = 1; | |
d3_timer_frame(d3_timer_step); | |
} | |
}; | |
function d3_timer_step() { | |
var now = d3_timer_mark(), delay = d3_timer_sweep() - now; | |
if (delay > 24) { | |
if (isFinite(delay)) { | |
clearTimeout(d3_timer_timeout); | |
d3_timer_timeout = setTimeout(d3_timer_step, delay); | |
} | |
d3_timer_interval = 0; | |
} else { | |
d3_timer_interval = 1; | |
d3_timer_frame(d3_timer_step); | |
} | |
} | |
d3.timer.flush = function() { | |
d3_timer_mark(); | |
d3_timer_sweep(); | |
}; | |
function d3_timer_mark() { | |
var now = Date.now(), timer = d3_timer_queueHead; | |
while (timer) { | |
if (now >= timer.time) timer.flush = timer.callback(now - timer.time); | |
timer = timer.next; | |
} | |
return now; | |
} | |
function d3_timer_sweep() { | |
var t0, t1 = d3_timer_queueHead, time = Infinity; | |
while (t1) { | |
if (t1.flush) { | |
t1 = t0 ? t0.next = t1.next : d3_timer_queueHead = t1.next; | |
} else { | |
if (t1.time < time) time = t1.time; | |
t1 = (t0 = t1).next; | |
} | |
} | |
d3_timer_queueTail = t0; | |
return time; | |
} | |
var d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) { | |
setTimeout(callback, 17); | |
}; | |
var d3_format_decimalPoint = ".", d3_format_thousandsSeparator = ",", d3_format_grouping = [ 3, 3 ], d3_format_currencySymbol = "$"; | |
var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); | |
d3.formatPrefix = function(value, precision) { | |
var i = 0; | |
if (value) { | |
if (value < 0) value *= -1; | |
if (precision) value = d3.round(value, d3_format_precision(value, precision)); | |
i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); | |
i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3)); | |
} | |
return d3_formatPrefixes[8 + i / 3]; | |
}; | |
function d3_formatPrefix(d, i) { | |
var k = Math.pow(10, Math.abs(8 - i) * 3); | |
return { | |
scale: i > 8 ? function(d) { | |
return d / k; | |
} : function(d) { | |
return d * k; | |
}, | |
symbol: d | |
}; | |
} | |
d3.round = function(x, n) { | |
return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); | |
}; | |
d3.format = function(specifier) { | |
var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", base = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, suffix = "", integer = false; | |
if (precision) precision = +precision.substring(1); | |
if (zfill || fill === "0" && align === "=") { | |
zfill = fill = "0"; | |
align = "="; | |
if (comma) width -= Math.floor((width - 1) / 4); | |
} | |
switch (type) { | |
case "n": | |
comma = true; | |
type = "g"; | |
break; | |
case "%": | |
scale = 100; | |
suffix = "%"; | |
type = "f"; | |
break; | |
case "p": | |
scale = 100; | |
suffix = "%"; | |
type = "r"; | |
break; | |
case "b": | |
case "o": | |
case "x": | |
case "X": | |
if (base === "#") base = "0" + type.toLowerCase(); | |
case "c": | |
case "d": | |
integer = true; | |
precision = 0; | |
break; | |
case "s": | |
scale = -1; | |
type = "r"; | |
break; | |
} | |
if (base === "#") base = ""; else if (base === "$") base = d3_format_currencySymbol; | |
if (type == "r" && !precision) type = "g"; | |
if (precision != null) { | |
if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); | |
} | |
type = d3_format_types.get(type) || d3_format_typeDefault; | |
var zcomma = zfill && comma; | |
return function(value) { | |
if (integer && value % 1) return ""; | |
var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; | |
if (scale < 0) { | |
var prefix = d3.formatPrefix(value, precision); | |
value = prefix.scale(value); | |
suffix = prefix.symbol; | |
} else { | |
value *= scale; | |
} | |
value = type(value, precision); | |
if (!zfill && comma) value = d3_format_group(value); | |
var length = base.length + value.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; | |
if (zcomma) value = d3_format_group(padding + value); | |
if (d3_format_decimalPoint) value.replace(".", d3_format_decimalPoint); | |
negative += base; | |
return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + suffix; | |
}; | |
}; | |
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; | |
var d3_format_types = d3.map({ | |
b: function(x) { | |
return x.toString(2); | |
}, | |
c: function(x) { | |
return String.fromCharCode(x); | |
}, | |
o: function(x) { | |
return x.toString(8); | |
}, | |
x: function(x) { | |
return x.toString(16); | |
}, | |
X: function(x) { | |
return x.toString(16).toUpperCase(); | |
}, | |
g: function(x, p) { | |
return x.toPrecision(p); | |
}, | |
e: function(x, p) { | |
return x.toExponential(p); | |
}, | |
f: function(x, p) { | |
return x.toFixed(p); | |
}, | |
r: function(x, p) { | |
return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); | |
} | |
}); | |
function d3_format_precision(x, p) { | |
return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); | |
} | |
function d3_format_typeDefault(x) { | |
return x + ""; | |
} | |
var d3_format_group = d3_identity; | |
if (d3_format_grouping) { | |
var d3_format_groupingLength = d3_format_grouping.length; | |
d3_format_group = function(value) { | |
var i = value.lastIndexOf("."), f = i >= 0 ? "." + value.substring(i + 1) : (i = value.length, | |
""), t = [], j = 0, g = d3_format_grouping[0]; | |
while (i > 0 && g > 0) { | |
t.push(value.substring(i -= g, i + g)); | |
g = d3_format_grouping[j = (j + 1) % d3_format_groupingLength]; | |
} | |
return t.reverse().join(d3_format_thousandsSeparator || "") + f; | |
}; | |
} | |
d3.geo = {}; | |
function d3_adder() {} | |
d3_adder.prototype = { | |
s: 0, | |
t: 0, | |
add: function(y) { | |
d3_adderSum(y, this.t, d3_adderTemp); | |
d3_adderSum(d3_adderTemp.s, this.s, this); | |
if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; | |
}, | |
reset: function() { | |
this.s = this.t = 0; | |
}, | |
valueOf: function() { | |
return this.s; | |
} | |
}; | |
var d3_adderTemp = new d3_adder(); | |
function d3_adderSum(a, b, o) { | |
var x = o.s = a + b, bv = x - a, av = x - bv; | |
o.t = a - av + (b - bv); | |
} | |
d3.geo.stream = function(object, listener) { | |
if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { | |
d3_geo_streamObjectType[object.type](object, listener); | |
} else { | |
d3_geo_streamGeometry(object, listener); | |
} | |
}; | |
function d3_geo_streamGeometry(geometry, listener) { | |
if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { | |
d3_geo_streamGeometryType[geometry.type](geometry, listener); | |
} | |
} | |
var d3_geo_streamObjectType = { | |
Feature: function(feature, listener) { | |
d3_geo_streamGeometry(feature.geometry, listener); | |
}, | |
FeatureCollection: function(object, listener) { | |
var features = object.features, i = -1, n = features.length; | |
while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); | |
} | |
}; | |
var d3_geo_streamGeometryType = { | |
Sphere: function(object, listener) { | |
listener.sphere(); | |
}, | |
Point: function(object, listener) { | |
var coordinate = object.coordinates; | |
listener.point(coordinate[0], coordinate[1]); | |
}, | |
MultiPoint: function(object, listener) { | |
var coordinates = object.coordinates, i = -1, n = coordinates.length, coordinate; | |
while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]); | |
}, | |
LineString: function(object, listener) { | |
d3_geo_streamLine(object.coordinates, listener, 0); | |
}, | |
MultiLineString: function(object, listener) { | |
var coordinates = object.coordinates, i = -1, n = coordinates.length; | |
while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); | |
}, | |
Polygon: function(object, listener) { | |
d3_geo_streamPolygon(object.coordinates, listener); | |
}, | |
MultiPolygon: function(object, listener) { | |
var coordinates = object.coordinates, i = -1, n = coordinates.length; | |
while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); | |
}, | |
GeometryCollection: function(object, listener) { | |
var geometries = object.geometries, i = -1, n = geometries.length; | |
while (++i < n) d3_geo_streamGeometry(geometries[i], listener); | |
} | |
}; | |
function d3_geo_streamLine(coordinates, listener, closed) { | |
var i = -1, n = coordinates.length - closed, coordinate; | |
listener.lineStart(); | |
while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]); | |
listener.lineEnd(); | |
} | |
function d3_geo_streamPolygon(coordinates, listener) { | |
var i = -1, n = coordinates.length; | |
listener.polygonStart(); | |
while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); | |
listener.polygonEnd(); | |
} | |
d3.geo.area = function(object) { | |
d3_geo_areaSum = 0; | |
d3.geo.stream(object, d3_geo_area); | |
return d3_geo_areaSum; | |
}; | |
var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); | |
var d3_geo_area = { | |
sphere: function() { | |
d3_geo_areaSum += 4 * π; | |
}, | |
point: d3_noop, | |
lineStart: d3_noop, | |
lineEnd: d3_noop, | |
polygonStart: function() { | |
d3_geo_areaRingSum.reset(); | |
d3_geo_area.lineStart = d3_geo_areaRingStart; | |
}, | |
polygonEnd: function() { | |
var area = 2 * d3_geo_areaRingSum; | |
d3_geo_areaSum += area < 0 ? 4 * π + area : area; | |
d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; | |
} | |
}; | |
function d3_geo_areaRingStart() { | |
var λ00, φ00, λ0, cosφ0, sinφ0; | |
d3_geo_area.point = function(λ, φ) { | |
d3_geo_area.point = nextPoint; | |
λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), | |
sinφ0 = Math.sin(φ); | |
}; | |
function nextPoint(λ, φ) { | |
λ *= d3_radians; | |
φ = φ * d3_radians / 2 + π / 4; | |
var dλ = λ - λ0, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(dλ), v = k * Math.sin(dλ); | |
d3_geo_areaRingSum.add(Math.atan2(v, u)); | |
λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; | |
} | |
d3_geo_area.lineEnd = function() { | |
nextPoint(λ00, φ00); | |
}; | |
} | |
function d3_geo_cartesian(spherical) { | |
var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); | |
return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; | |
} | |
function d3_geo_cartesianDot(a, b) { | |
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; | |
} | |
function d3_geo_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 d3_geo_cartesianAdd(a, b) { | |
a[0] += b[0]; | |
a[1] += b[1]; | |
a[2] += b[2]; | |
} | |
function d3_geo_cartesianScale(vector, k) { | |
return [ vector[0] * k, vector[1] * k, vector[2] * k ]; | |
} | |
function d3_geo_cartesianNormalize(d) { | |
var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); | |
d[0] /= l; | |
d[1] /= l; | |
d[2] /= l; | |
} | |
function d3_geo_spherical(cartesian) { | |
return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; | |
} | |
function d3_geo_sphericalEqual(a, b) { | |
return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε; | |
} | |
d3.geo.bounds = function() { | |
var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; | |
var bound = { | |
point: point, | |
lineStart: lineStart, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
bound.point = ringPoint; | |
bound.lineStart = ringStart; | |
bound.lineEnd = ringEnd; | |
dλSum = 0; | |
d3_geo_area.polygonStart(); | |
}, | |
polygonEnd: function() { | |
d3_geo_area.polygonEnd(); | |
bound.point = point; | |
bound.lineStart = lineStart; | |
bound.lineEnd = lineEnd; | |
if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; | |
range[0] = λ0, range[1] = λ1; | |
} | |
}; | |
function point(λ, φ) { | |
ranges.push(range = [ λ0 = λ, λ1 = λ ]); | |
if (φ < φ0) φ0 = φ; | |
if (φ > φ1) φ1 = φ; | |
} | |
function linePoint(λ, φ) { | |
var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); | |
if (p0) { | |
var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); | |
d3_geo_cartesianNormalize(inflection); | |
inflection = d3_geo_spherical(inflection); | |
var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = Math.abs(dλ) > 180; | |
if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { | |
var φi = inflection[1] * d3_degrees; | |
if (φi > φ1) φ1 = φi; | |
} else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { | |
var φi = -inflection[1] * d3_degrees; | |
if (φi < φ0) φ0 = φi; | |
} else { | |
if (φ < φ0) φ0 = φ; | |
if (φ > φ1) φ1 = φ; | |
} | |
if (antimeridian) { | |
if (λ < λ_) { | |
if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; | |
} else { | |
if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; | |
} | |
} else { | |
if (λ1 >= λ0) { | |
if (λ < λ0) λ0 = λ; | |
if (λ > λ1) λ1 = λ; | |
} else { | |
if (λ > λ_) { | |
if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; | |
} else { | |
if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; | |
} | |
} | |
} | |
} else { | |
point(λ, φ); | |
} | |
p0 = p, λ_ = λ; | |
} | |
function lineStart() { | |
bound.point = linePoint; | |
} | |
function lineEnd() { | |
range[0] = λ0, range[1] = λ1; | |
bound.point = point; | |
p0 = null; | |
} | |
function ringPoint(λ, φ) { | |
if (p0) { | |
var dλ = λ - λ_; | |
dλSum += Math.abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; | |
} else λ__ = λ, φ__ = φ; | |
d3_geo_area.point(λ, φ); | |
linePoint(λ, φ); | |
} | |
function ringStart() { | |
d3_geo_area.lineStart(); | |
} | |
function ringEnd() { | |
ringPoint(λ__, φ__); | |
d3_geo_area.lineEnd(); | |
if (Math.abs(dλSum) > ε) λ0 = -(λ1 = 180); | |
range[0] = λ0, range[1] = λ1; | |
p0 = null; | |
} | |
function angle(λ0, λ1) { | |
return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; | |
} | |
function compareRanges(a, b) { | |
return a[0] - b[0]; | |
} | |
function withinRange(x, range) { | |
return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; | |
} | |
return function(feature) { | |
φ1 = λ1 = -(λ0 = φ0 = Infinity); | |
ranges = []; | |
d3.geo.stream(feature, bound); | |
var n = ranges.length; | |
if (n) { | |
ranges.sort(compareRanges); | |
for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { | |
b = ranges[i]; | |
if (withinRange(b[0], a) || withinRange(b[1], a)) { | |
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); | |
} | |
} | |
var best = -Infinity, dλ; | |
for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { | |
b = merged[i]; | |
if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; | |
} | |
} | |
ranges = range = null; | |
return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; | |
}; | |
}(); | |
d3.geo.centroid = function(object) { | |
d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; | |
d3.geo.stream(object, d3_geo_centroid); | |
var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; | |
if (m < ε2) { | |
x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; | |
if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; | |
m = x * x + y * y + z * z; | |
if (m < ε2) return [ NaN, NaN ]; | |
} | |
return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; | |
}; | |
var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; | |
var d3_geo_centroid = { | |
sphere: d3_noop, | |
point: d3_geo_centroidPoint, | |
lineStart: d3_geo_centroidLineStart, | |
lineEnd: d3_geo_centroidLineEnd, | |
polygonStart: function() { | |
d3_geo_centroid.lineStart = d3_geo_centroidRingStart; | |
}, | |
polygonEnd: function() { | |
d3_geo_centroid.lineStart = d3_geo_centroidLineStart; | |
} | |
}; | |
function d3_geo_centroidPoint(λ, φ) { | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians); | |
d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); | |
} | |
function d3_geo_centroidPointXYZ(x, y, z) { | |
++d3_geo_centroidW0; | |
d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; | |
d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; | |
d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; | |
} | |
function d3_geo_centroidLineStart() { | |
var x0, y0, z0; | |
d3_geo_centroid.point = function(λ, φ) { | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians); | |
x0 = cosφ * Math.cos(λ); | |
y0 = cosφ * Math.sin(λ); | |
z0 = Math.sin(φ); | |
d3_geo_centroid.point = nextPoint; | |
d3_geo_centroidPointXYZ(x0, y0, z0); | |
}; | |
function nextPoint(λ, φ) { | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.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); | |
d3_geo_centroidW1 += w; | |
d3_geo_centroidX1 += w * (x0 + (x0 = x)); | |
d3_geo_centroidY1 += w * (y0 + (y0 = y)); | |
d3_geo_centroidZ1 += w * (z0 + (z0 = z)); | |
d3_geo_centroidPointXYZ(x0, y0, z0); | |
} | |
} | |
function d3_geo_centroidLineEnd() { | |
d3_geo_centroid.point = d3_geo_centroidPoint; | |
} | |
function d3_geo_centroidRingStart() { | |
var λ00, φ00, x0, y0, z0; | |
d3_geo_centroid.point = function(λ, φ) { | |
λ00 = λ, φ00 = φ; | |
d3_geo_centroid.point = nextPoint; | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians); | |
x0 = cosφ * Math.cos(λ); | |
y0 = cosφ * Math.sin(λ); | |
z0 = Math.sin(φ); | |
d3_geo_centroidPointXYZ(x0, y0, z0); | |
}; | |
d3_geo_centroid.lineEnd = function() { | |
nextPoint(λ00, φ00); | |
d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; | |
d3_geo_centroid.point = d3_geo_centroidPoint; | |
}; | |
function nextPoint(λ, φ) { | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); | |
d3_geo_centroidX2 += v * cx; | |
d3_geo_centroidY2 += v * cy; | |
d3_geo_centroidZ2 += v * cz; | |
d3_geo_centroidW1 += w; | |
d3_geo_centroidX1 += w * (x0 + (x0 = x)); | |
d3_geo_centroidY1 += w * (y0 + (y0 = y)); | |
d3_geo_centroidZ1 += w * (z0 + (z0 = z)); | |
d3_geo_centroidPointXYZ(x0, y0, z0); | |
} | |
} | |
function d3_true() { | |
return true; | |
} | |
function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) { | |
var subject = [], clip = []; | |
segments.forEach(function(segment) { | |
if ((n = segment.length - 1) <= 0) return; | |
var n, p0 = segment[0], p1 = segment[n]; | |
if (d3_geo_sphericalEqual(p0, p1)) { | |
listener.lineStart(); | |
for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); | |
listener.lineEnd(); | |
return; | |
} | |
var a = { | |
point: p0, | |
points: segment, | |
other: null, | |
visited: false, | |
entry: true, | |
subject: true | |
}, b = { | |
point: p0, | |
points: [ p0 ], | |
other: a, | |
visited: false, | |
entry: false, | |
subject: false | |
}; | |
a.other = b; | |
subject.push(a); | |
clip.push(b); | |
a = { | |
point: p1, | |
points: [ p1 ], | |
other: null, | |
visited: false, | |
entry: false, | |
subject: true | |
}; | |
b = { | |
point: p1, | |
points: [ p1 ], | |
other: a, | |
visited: false, | |
entry: true, | |
subject: false | |
}; | |
a.other = b; | |
subject.push(a); | |
clip.push(b); | |
}); | |
clip.sort(compare); | |
d3_geo_clipPolygonLinkCircular(subject); | |
d3_geo_clipPolygonLinkCircular(clip); | |
if (!subject.length) return; | |
if (inside) for (var i = 1, e = !inside(clip[0].point), n = clip.length; i < n; ++i) { | |
clip[i].entry = e = !e; | |
} | |
var start = subject[0], current, points, point; | |
while (1) { | |
current = start; | |
while (current.visited) if ((current = current.next) === start) return; | |
points = current.points; | |
listener.lineStart(); | |
do { | |
current.visited = current.other.visited = true; | |
if (current.entry) { | |
if (current.subject) { | |
for (var i = 0; i < points.length; i++) listener.point((point = points[i])[0], point[1]); | |
} else { | |
interpolate(current.point, current.next.point, 1, listener); | |
} | |
current = current.next; | |
} else { | |
if (current.subject) { | |
points = current.prev.points; | |
for (var i = points.length; --i >= 0; ) listener.point((point = points[i])[0], point[1]); | |
} else { | |
interpolate(current.point, current.prev.point, -1, listener); | |
} | |
current = current.prev; | |
} | |
current = current.other; | |
points = current.points; | |
} while (!current.visited); | |
listener.lineEnd(); | |
} | |
} | |
function d3_geo_clipPolygonLinkCircular(array) { | |
if (!(n = array.length)) return; | |
var n, i = 0, a = array[0], b; | |
while (++i < n) { | |
a.next = b = array[i]; | |
b.prev = a; | |
a = b; | |
} | |
a.next = b = array[0]; | |
b.prev = a; | |
} | |
function d3_geo_clip(pointVisible, clipLine, interpolate, polygonContains) { | |
return function(listener) { | |
var line = clipLine(listener); | |
var clip = { | |
point: point, | |
lineStart: lineStart, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
clip.point = pointRing; | |
clip.lineStart = ringStart; | |
clip.lineEnd = ringEnd; | |
segments = []; | |
polygon = []; | |
listener.polygonStart(); | |
}, | |
polygonEnd: function() { | |
clip.point = point; | |
clip.lineStart = lineStart; | |
clip.lineEnd = lineEnd; | |
segments = d3.merge(segments); | |
if (segments.length) { | |
d3_geo_clipPolygon(segments, d3_geo_clipSort, null, interpolate, listener); | |
} else if (polygonContains(polygon)) { | |
listener.lineStart(); | |
interpolate(null, null, 1, listener); | |
listener.lineEnd(); | |
} | |
listener.polygonEnd(); | |
segments = polygon = null; | |
}, | |
sphere: function() { | |
listener.polygonStart(); | |
listener.lineStart(); | |
interpolate(null, null, 1, listener); | |
listener.lineEnd(); | |
listener.polygonEnd(); | |
} | |
}; | |
function point(λ, φ) { | |
if (pointVisible(λ, φ)) listener.point(λ, φ); | |
} | |
function pointLine(λ, φ) { | |
line.point(λ, φ); | |
} | |
function lineStart() { | |
clip.point = pointLine; | |
line.lineStart(); | |
} | |
function lineEnd() { | |
clip.point = point; | |
line.lineEnd(); | |
} | |
var segments; | |
var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygon, ring; | |
function pointRing(λ, φ) { | |
ringListener.point(λ, φ); | |
ring.push([ λ, φ ]); | |
} | |
function ringStart() { | |
ringListener.lineStart(); | |
ring = []; | |
} | |
function ringEnd() { | |
pointRing(ring[0][0], ring[0][1]); | |
ringListener.lineEnd(); | |
var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; | |
ring.pop(); | |
polygon.push(ring); | |
ring = null; | |
if (!n) return; | |
if (clean & 1) { | |
segment = ringSegments[0]; | |
var n = segment.length - 1, i = -1, point; | |
listener.lineStart(); | |
while (++i < n) listener.point((point = segment[i])[0], point[1]); | |
listener.lineEnd(); | |
return; | |
} | |
if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); | |
segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); | |
} | |
return clip; | |
}; | |
} | |
function d3_geo_clipSegmentLength1(segment) { | |
return segment.length > 1; | |
} | |
function d3_geo_clipBufferListener() { | |
var lines = [], line; | |
return { | |
lineStart: function() { | |
lines.push(line = []); | |
}, | |
point: function(λ, φ) { | |
line.push([ λ, φ ]); | |
}, | |
lineEnd: d3_noop, | |
buffer: function() { | |
var buffer = lines; | |
lines = []; | |
line = null; | |
return buffer; | |
}, | |
rejoin: function() { | |
if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); | |
} | |
}; | |
} | |
function d3_geo_clipSort(a, b) { | |
return ((a = a.point)[0] < 0 ? a[1] - π / 2 - ε : π / 2 - a[1]) - ((b = b.point)[0] < 0 ? b[1] - π / 2 - ε : π / 2 - b[1]); | |
} | |
function d3_geo_pointInPolygon(point, polygon) { | |
var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, polar = false, southPole = false, winding = 0; | |
d3_geo_areaRingSum.reset(); | |
for (var i = 0, n = polygon.length; i < n; ++i) { | |
var ring = polygon[i], m = ring.length; | |
if (!m) continue; | |
var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; | |
while (true) { | |
if (j === m) j = 0; | |
point = ring[j]; | |
var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, antimeridian = Math.abs(dλ) > π, k = sinφ0 * sinφ; | |
d3_geo_areaRingSum.add(Math.atan2(k * Math.sin(dλ), cosφ0 * cosφ + k * Math.cos(dλ))); | |
if (Math.abs(φ) < ε) southPole = true; | |
polarAngle += antimeridian ? dλ + (dλ >= 0 ? 2 : -2) * π : dλ; | |
if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { | |
var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); | |
d3_geo_cartesianNormalize(arc); | |
var intersection = d3_geo_cartesianCross(meridianNormal, arc); | |
d3_geo_cartesianNormalize(intersection); | |
var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); | |
if (parallel > φarc) { | |
winding += antimeridian ^ dλ >= 0 ? 1 : -1; | |
} | |
} | |
if (!j++) break; | |
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; | |
} | |
if (Math.abs(polarAngle) > ε) polar = true; | |
} | |
return (!southPole && !polar && d3_geo_areaRingSum < 0 || polarAngle < -ε) ^ winding & 1; | |
} | |
var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, d3_geo_clipAntimeridianPolygonContains); | |
function d3_geo_clipAntimeridianLine(listener) { | |
var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; | |
return { | |
lineStart: function() { | |
listener.lineStart(); | |
clean = 1; | |
}, | |
point: function(λ1, φ1) { | |
var sλ1 = λ1 > 0 ? π : -π, dλ = Math.abs(λ1 - λ0); | |
if (Math.abs(dλ - π) < ε) { | |
listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2); | |
listener.point(sλ0, φ0); | |
listener.lineEnd(); | |
listener.lineStart(); | |
listener.point(sλ1, φ0); | |
listener.point(λ1, φ0); | |
clean = 0; | |
} else if (sλ0 !== sλ1 && dλ >= π) { | |
if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; | |
if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; | |
φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); | |
listener.point(sλ0, φ0); | |
listener.lineEnd(); | |
listener.lineStart(); | |
listener.point(sλ1, φ0); | |
clean = 0; | |
} | |
listener.point(λ0 = λ1, φ0 = φ1); | |
sλ0 = sλ1; | |
}, | |
lineEnd: function() { | |
listener.lineEnd(); | |
λ0 = φ0 = NaN; | |
}, | |
clean: function() { | |
return 2 - clean; | |
} | |
}; | |
} | |
function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { | |
var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); | |
return Math.abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; | |
} | |
function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { | |
var φ; | |
if (from == null) { | |
φ = direction * π / 2; | |
listener.point(-π, φ); | |
listener.point(0, φ); | |
listener.point(π, φ); | |
listener.point(π, 0); | |
listener.point(π, -φ); | |
listener.point(0, -φ); | |
listener.point(-π, -φ); | |
listener.point(-π, 0); | |
listener.point(-π, φ); | |
} else if (Math.abs(from[0] - to[0]) > ε) { | |
var s = (from[0] < to[0] ? 1 : -1) * π; | |
φ = direction * s / 2; | |
listener.point(-s, φ); | |
listener.point(0, φ); | |
listener.point(s, φ); | |
} else { | |
listener.point(to[0], to[1]); | |
} | |
} | |
var d3_geo_clipAntimeridianPoint = [ -π, 0 ]; | |
function d3_geo_clipAntimeridianPolygonContains(polygon) { | |
return d3_geo_pointInPolygon(d3_geo_clipAntimeridianPoint, polygon); | |
} | |
function d3_geo_clipCircle(radius) { | |
var cr = Math.cos(radius), smallRadius = cr > 0, point = [ radius, 0 ], notHemisphere = Math.abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); | |
return d3_geo_clip(visible, clipLine, interpolate, polygonContains); | |
function visible(λ, φ) { | |
return Math.cos(λ) * Math.cos(φ) > cr; | |
} | |
function clipLine(listener) { | |
var point0, c0, v0, v00, clean; | |
return { | |
lineStart: function() { | |
v00 = v0 = false; | |
clean = 1; | |
}, | |
point: function(λ, φ) { | |
var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; | |
if (!point0 && (v00 = v0 = v)) listener.lineStart(); | |
if (v !== v0) { | |
point2 = intersect(point0, point1); | |
if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { | |
point1[0] += ε; | |
point1[1] += ε; | |
v = visible(point1[0], point1[1]); | |
} | |
} | |
if (v !== v0) { | |
clean = 0; | |
if (v) { | |
listener.lineStart(); | |
point2 = intersect(point1, point0); | |
listener.point(point2[0], point2[1]); | |
} else { | |
point2 = intersect(point0, point1); | |
listener.point(point2[0], point2[1]); | |
listener.lineEnd(); | |
} | |
point0 = point2; | |
} else if (notHemisphere && point0 && smallRadius ^ v) { | |
var t; | |
if (!(c & c0) && (t = intersect(point1, point0, true))) { | |
clean = 0; | |
if (smallRadius) { | |
listener.lineStart(); | |
listener.point(t[0][0], t[0][1]); | |
listener.point(t[1][0], t[1][1]); | |
listener.lineEnd(); | |
} else { | |
listener.point(t[1][0], t[1][1]); | |
listener.lineEnd(); | |
listener.lineStart(); | |
listener.point(t[0][0], t[0][1]); | |
} | |
} | |
} | |
if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { | |
listener.point(point1[0], point1[1]); | |
} | |
point0 = point1, v0 = v, c0 = c; | |
}, | |
lineEnd: function() { | |
if (v0) listener.lineEnd(); | |
point0 = null; | |
}, | |
clean: function() { | |
return clean | (v00 && v0) << 1; | |
} | |
}; | |
} | |
function intersect(a, b, two) { | |
var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); | |
var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; | |
if (!determinant) return !two && a; | |
var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); | |
d3_geo_cartesianAdd(A, B); | |
var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); | |
if (t2 < 0) return; | |
var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); | |
d3_geo_cartesianAdd(q, A); | |
q = d3_geo_spherical(q); | |
if (!two) return q; | |
var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; | |
if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; | |
var δλ = λ1 - λ0, polar = Math.abs(δλ - π) < ε, meridian = polar || δλ < ε; | |
if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; | |
if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (Math.abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { | |
var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); | |
d3_geo_cartesianAdd(q1, A); | |
return [ q, d3_geo_spherical(q1) ]; | |
} | |
} | |
function code(λ, φ) { | |
var r = smallRadius ? radius : π - radius, code = 0; | |
if (λ < -r) code |= 1; else if (λ > r) code |= 2; | |
if (φ < -r) code |= 4; else if (φ > r) code |= 8; | |
return code; | |
} | |
function polygonContains(polygon) { | |
return d3_geo_pointInPolygon(point, polygon); | |
} | |
} | |
var d3_geo_clipViewMAX = 1e9; | |
function d3_geo_clipView(x0, y0, x1, y1) { | |
return function(listener) { | |
var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), segments, polygon, ring; | |
var clip = { | |
point: point, | |
lineStart: lineStart, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
listener = bufferListener; | |
segments = []; | |
polygon = []; | |
}, | |
polygonEnd: function() { | |
listener = listener_; | |
if ((segments = d3.merge(segments)).length) { | |
listener.polygonStart(); | |
d3_geo_clipPolygon(segments, compare, inside, interpolate, listener); | |
listener.polygonEnd(); | |
} else if (insidePolygon([ x0, y0 ])) { | |
listener.polygonStart(), listener.lineStart(); | |
interpolate(null, null, 1, listener); | |
listener.lineEnd(), listener.polygonEnd(); | |
} | |
segments = polygon = ring = null; | |
} | |
}; | |
function inside(point) { | |
var a = corner(point, -1), i = insidePolygon([ a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0 ]); | |
return i; | |
} | |
function insidePolygon(p) { | |
var wn = 0, n = polygon.length, y = p[1]; | |
for (var i = 0; i < n; ++i) { | |
for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { | |
b = v[j]; | |
if (a[1] <= y) { | |
if (b[1] > y && isLeft(a, b, p) > 0) ++wn; | |
} else { | |
if (b[1] <= y && isLeft(a, b, p) < 0) --wn; | |
} | |
a = b; | |
} | |
} | |
return wn !== 0; | |
} | |
function isLeft(a, b, c) { | |
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); | |
} | |
function interpolate(from, to, direction, listener) { | |
var a = 0, a1 = 0; | |
if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { | |
do { | |
listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); | |
} while ((a = (a + direction + 4) % 4) !== a1); | |
} else { | |
listener.point(to[0], to[1]); | |
} | |
} | |
function visible(x, y) { | |
return x0 <= x && x <= x1 && y0 <= y && y <= y1; | |
} | |
function point(x, y) { | |
if (visible(x, y)) listener.point(x, y); | |
} | |
var x__, y__, v__, x_, y_, v_, first; | |
function lineStart() { | |
clip.point = linePoint; | |
if (polygon) polygon.push(ring = []); | |
first = true; | |
v_ = false; | |
x_ = y_ = NaN; | |
} | |
function lineEnd() { | |
if (segments) { | |
linePoint(x__, y__); | |
if (v__ && v_) bufferListener.rejoin(); | |
segments.push(bufferListener.buffer()); | |
} | |
clip.point = point; | |
if (v_) listener.lineEnd(); | |
} | |
function linePoint(x, y) { | |
x = Math.max(-d3_geo_clipViewMAX, Math.min(d3_geo_clipViewMAX, x)); | |
y = Math.max(-d3_geo_clipViewMAX, Math.min(d3_geo_clipViewMAX, y)); | |
var v = visible(x, y); | |
if (polygon) ring.push([ x, y ]); | |
if (first) { | |
x__ = x, y__ = y, v__ = v; | |
first = false; | |
if (v) { | |
listener.lineStart(); | |
listener.point(x, y); | |
} | |
} else { | |
if (v && v_) listener.point(x, y); else { | |
var a = [ x_, y_ ], b = [ x, y ]; | |
if (clipLine(a, b)) { | |
if (!v_) { | |
listener.lineStart(); | |
listener.point(a[0], a[1]); | |
} | |
listener.point(b[0], b[1]); | |
if (!v) listener.lineEnd(); | |
} else if (v) { | |
listener.lineStart(); | |
listener.point(x, y); | |
} | |
} | |
} | |
x_ = x, y_ = y, v_ = v; | |
} | |
return clip; | |
}; | |
function corner(p, direction) { | |
return Math.abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : Math.abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : Math.abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; | |
} | |
function compare(a, b) { | |
return comparePoints(a.point, b.point); | |
} | |
function comparePoints(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 clipLine(a, b) { | |
var dx = b[0] - a[0], dy = b[1] - a[1], t = [ 0, 1 ]; | |
if (Math.abs(dx) < ε && Math.abs(dy) < ε) return x0 <= a[0] && a[0] <= x1 && y0 <= a[1] && a[1] <= y1; | |
if (d3_geo_clipViewT(x0 - a[0], dx, t) && d3_geo_clipViewT(a[0] - x1, -dx, t) && d3_geo_clipViewT(y0 - a[1], dy, t) && d3_geo_clipViewT(a[1] - y1, -dy, t)) { | |
if (t[1] < 1) { | |
b[0] = a[0] + t[1] * dx; | |
b[1] = a[1] + t[1] * dy; | |
} | |
if (t[0] > 0) { | |
a[0] += t[0] * dx; | |
a[1] += t[0] * dy; | |
} | |
return true; | |
} | |
return false; | |
} | |
} | |
function d3_geo_clipViewT(num, denominator, t) { | |
if (Math.abs(denominator) < ε) return num <= 0; | |
var u = num / denominator; | |
if (denominator > 0) { | |
if (u > t[1]) return false; | |
if (u > t[0]) t[0] = u; | |
} else { | |
if (u < t[0]) return false; | |
if (u < t[1]) t[1] = u; | |
} | |
return true; | |
} | |
function d3_geo_compose(a, b) { | |
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 compose; | |
} | |
function d3_geo_conic(projectAt) { | |
var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); | |
p.parallels = function(_) { | |
if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; | |
return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); | |
}; | |
return p; | |
} | |
function d3_geo_conicEqualArea(φ0, φ1) { | |
var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; | |
function forward(λ, φ) { | |
var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; | |
return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; | |
} | |
forward.invert = function(x, y) { | |
var ρ0_y = ρ0 - y; | |
return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; | |
}; | |
return forward; | |
} | |
(d3.geo.conicEqualArea = function() { | |
return d3_geo_conic(d3_geo_conicEqualArea); | |
}).raw = d3_geo_conicEqualArea; | |
d3.geo.albers = function() { | |
return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); | |
}; | |
d3.geo.albersUsa = function() { | |
var lower48 = d3.geo.albers(); | |
var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); | |
var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); | |
var point, pointStream = { | |
point: function(x, y) { | |
point = [ x, y ]; | |
} | |
}, lower48Point, alaskaPoint, hawaiiPoint; | |
function albersUsa(coordinates) { | |
var x = coordinates[0], y = coordinates[1]; | |
point = null; | |
(lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); | |
return 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 >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); | |
}; | |
albersUsa.stream = function(stream) { | |
var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); | |
return { | |
point: function(x, y) { | |
lower48Stream.point(x, y); | |
alaskaStream.point(x, y); | |
hawaiiStream.point(x, y); | |
}, | |
sphere: function() { | |
lower48Stream.sphere(); | |
alaskaStream.sphere(); | |
hawaiiStream.sphere(); | |
}, | |
lineStart: function() { | |
lower48Stream.lineStart(); | |
alaskaStream.lineStart(); | |
hawaiiStream.lineStart(); | |
}, | |
lineEnd: function() { | |
lower48Stream.lineEnd(); | |
alaskaStream.lineEnd(); | |
hawaiiStream.lineEnd(); | |
}, | |
polygonStart: function() { | |
lower48Stream.polygonStart(); | |
alaskaStream.polygonStart(); | |
hawaiiStream.polygonStart(); | |
}, | |
polygonEnd: function() { | |
lower48Stream.polygonEnd(); | |
alaskaStream.polygonEnd(); | |
hawaiiStream.polygonEnd(); | |
} | |
}; | |
}; | |
albersUsa.precision = function(_) { | |
if (!arguments.length) return lower48.precision(); | |
lower48.precision(_); | |
alaska.precision(_); | |
hawaii.precision(_); | |
return albersUsa; | |
}; | |
albersUsa.scale = function(_) { | |
if (!arguments.length) return lower48.scale(); | |
lower48.scale(_); | |
alaska.scale(_ * .35); | |
hawaii.scale(_); | |
return albersUsa.translate(lower48.translate()); | |
}; | |
albersUsa.translate = function(_) { | |
if (!arguments.length) return lower48.translate(); | |
var k = lower48.scale(), x = +_[0], y = +_[1]; | |
lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; | |
alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; | |
hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; | |
return albersUsa; | |
}; | |
return albersUsa.scale(1070); | |
}; | |
var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { | |
point: d3_noop, | |
lineStart: d3_noop, | |
lineEnd: d3_noop, | |
polygonStart: function() { | |
d3_geo_pathAreaPolygon = 0; | |
d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; | |
}, | |
polygonEnd: function() { | |
d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; | |
d3_geo_pathAreaSum += Math.abs(d3_geo_pathAreaPolygon / 2); | |
} | |
}; | |
function d3_geo_pathAreaRingStart() { | |
var x00, y00, x0, y0; | |
d3_geo_pathArea.point = function(x, y) { | |
d3_geo_pathArea.point = nextPoint; | |
x00 = x0 = x, y00 = y0 = y; | |
}; | |
function nextPoint(x, y) { | |
d3_geo_pathAreaPolygon += y0 * x - x0 * y; | |
x0 = x, y0 = y; | |
} | |
d3_geo_pathArea.lineEnd = function() { | |
nextPoint(x00, y00); | |
}; | |
} | |
var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; | |
var d3_geo_pathBounds = { | |
point: d3_geo_pathBoundsPoint, | |
lineStart: d3_noop, | |
lineEnd: d3_noop, | |
polygonStart: d3_noop, | |
polygonEnd: d3_noop | |
}; | |
function d3_geo_pathBoundsPoint(x, y) { | |
if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; | |
if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; | |
if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; | |
if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; | |
} | |
function d3_geo_pathBuffer() { | |
var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; | |
var stream = { | |
point: point, | |
lineStart: function() { | |
stream.point = pointLineStart; | |
}, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
stream.lineEnd = lineEndPolygon; | |
}, | |
polygonEnd: function() { | |
stream.lineEnd = lineEnd; | |
stream.point = point; | |
}, | |
pointRadius: function(_) { | |
pointCircle = d3_geo_pathBufferCircle(_); | |
return stream; | |
}, | |
result: function() { | |
if (buffer.length) { | |
var result = buffer.join(""); | |
buffer = []; | |
return result; | |
} | |
} | |
}; | |
function point(x, y) { | |
buffer.push("M", x, ",", y, pointCircle); | |
} | |
function pointLineStart(x, y) { | |
buffer.push("M", x, ",", y); | |
stream.point = pointLine; | |
} | |
function pointLine(x, y) { | |
buffer.push("L", x, ",", y); | |
} | |
function lineEnd() { | |
stream.point = point; | |
} | |
function lineEndPolygon() { | |
buffer.push("Z"); | |
} | |
return stream; | |
} | |
function d3_geo_pathBufferCircle(radius) { | |
return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; | |
} | |
var d3_geo_pathCentroid = { | |
point: d3_geo_pathCentroidPoint, | |
lineStart: d3_geo_pathCentroidLineStart, | |
lineEnd: d3_geo_pathCentroidLineEnd, | |
polygonStart: function() { | |
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; | |
}, | |
polygonEnd: function() { | |
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; | |
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; | |
d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; | |
} | |
}; | |
function d3_geo_pathCentroidPoint(x, y) { | |
d3_geo_centroidX0 += x; | |
d3_geo_centroidY0 += y; | |
++d3_geo_centroidZ0; | |
} | |
function d3_geo_pathCentroidLineStart() { | |
var x0, y0; | |
d3_geo_pathCentroid.point = function(x, y) { | |
d3_geo_pathCentroid.point = nextPoint; | |
d3_geo_pathCentroidPoint(x0 = x, y0 = y); | |
}; | |
function nextPoint(x, y) { | |
var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); | |
d3_geo_centroidX1 += z * (x0 + x) / 2; | |
d3_geo_centroidY1 += z * (y0 + y) / 2; | |
d3_geo_centroidZ1 += z; | |
d3_geo_pathCentroidPoint(x0 = x, y0 = y); | |
} | |
} | |
function d3_geo_pathCentroidLineEnd() { | |
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; | |
} | |
function d3_geo_pathCentroidRingStart() { | |
var x00, y00, x0, y0; | |
d3_geo_pathCentroid.point = function(x, y) { | |
d3_geo_pathCentroid.point = nextPoint; | |
d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); | |
}; | |
function nextPoint(x, y) { | |
var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); | |
d3_geo_centroidX1 += z * (x0 + x) / 2; | |
d3_geo_centroidY1 += z * (y0 + y) / 2; | |
d3_geo_centroidZ1 += z; | |
z = y0 * x - x0 * y; | |
d3_geo_centroidX2 += z * (x0 + x); | |
d3_geo_centroidY2 += z * (y0 + y); | |
d3_geo_centroidZ2 += z * 3; | |
d3_geo_pathCentroidPoint(x0 = x, y0 = y); | |
} | |
d3_geo_pathCentroid.lineEnd = function() { | |
nextPoint(x00, y00); | |
}; | |
} | |
function d3_geo_pathContext(context) { | |
var pointRadius = 4.5; | |
var stream = { | |
point: point, | |
lineStart: function() { | |
stream.point = pointLineStart; | |
}, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
stream.lineEnd = lineEndPolygon; | |
}, | |
polygonEnd: function() { | |
stream.lineEnd = lineEnd; | |
stream.point = point; | |
}, | |
pointRadius: function(_) { | |
pointRadius = _; | |
return stream; | |
}, | |
result: d3_noop | |
}; | |
function point(x, y) { | |
context.moveTo(x, y); | |
context.arc(x, y, pointRadius, 0, 2 * π); | |
} | |
function pointLineStart(x, y) { | |
context.moveTo(x, y); | |
stream.point = pointLine; | |
} | |
function pointLine(x, y) { | |
context.lineTo(x, y); | |
} | |
function lineEnd() { | |
stream.point = point; | |
} | |
function lineEndPolygon() { | |
context.closePath(); | |
} | |
return stream; | |
} | |
function d3_geo_resample(project) { | |
var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; | |
function resample(stream) { | |
var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; | |
var resample = { | |
point: point, | |
lineStart: lineStart, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
stream.polygonStart(); | |
resample.lineStart = ringStart; | |
}, | |
polygonEnd: function() { | |
stream.polygonEnd(); | |
resample.lineStart = lineStart; | |
} | |
}; | |
function point(x, y) { | |
x = project(x, y); | |
stream.point(x[0], x[1]); | |
} | |
function lineStart() { | |
x0 = NaN; | |
resample.point = linePoint; | |
stream.lineStart(); | |
} | |
function linePoint(λ, φ) { | |
var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); | |
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); | |
stream.point(x0, y0); | |
} | |
function lineEnd() { | |
resample.point = point; | |
stream.lineEnd(); | |
} | |
function ringStart() { | |
lineStart(); | |
resample.point = ringPoint; | |
resample.lineEnd = ringEnd; | |
} | |
function ringPoint(λ, φ) { | |
linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; | |
resample.point = linePoint; | |
} | |
function ringEnd() { | |
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); | |
resample.lineEnd = lineEnd; | |
lineEnd(); | |
} | |
return resample; | |
} | |
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { | |
var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; | |
if (d2 > 4 * δ2 && depth--) { | |
var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; | |
if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { | |
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); | |
stream.point(x2, y2); | |
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); | |
} | |
} | |
} | |
resample.precision = function(_) { | |
if (!arguments.length) return Math.sqrt(δ2); | |
maxDepth = (δ2 = _ * _) > 0 && 16; | |
return resample; | |
}; | |
return resample; | |
} | |
d3.geo.path = function() { | |
var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; | |
function path(object) { | |
if (object) { | |
if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); | |
if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); | |
d3.geo.stream(object, cacheStream); | |
} | |
return contextStream.result(); | |
} | |
path.area = function(object) { | |
d3_geo_pathAreaSum = 0; | |
d3.geo.stream(object, projectStream(d3_geo_pathArea)); | |
return d3_geo_pathAreaSum; | |
}; | |
path.centroid = function(object) { | |
d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; | |
d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); | |
return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; | |
}; | |
path.bounds = function(object) { | |
d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); | |
d3.geo.stream(object, projectStream(d3_geo_pathBounds)); | |
return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; | |
}; | |
path.projection = function(_) { | |
if (!arguments.length) return projection; | |
projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; | |
return reset(); | |
}; | |
path.context = function(_) { | |
if (!arguments.length) return context; | |
contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); | |
if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); | |
return reset(); | |
}; | |
path.pointRadius = function(_) { | |
if (!arguments.length) return pointRadius; | |
pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); | |
return path; | |
}; | |
function reset() { | |
cacheStream = null; | |
return path; | |
} | |
return path.projection(d3.geo.albersUsa()).context(null); | |
}; | |
function d3_geo_pathProjectStream(project) { | |
var resample = d3_geo_resample(function(λ, φ) { | |
return project([ λ * d3_degrees, φ * d3_degrees ]); | |
}); | |
return function(stream) { | |
stream = resample(stream); | |
return { | |
point: function(λ, φ) { | |
stream.point(λ * d3_radians, φ * d3_radians); | |
}, | |
sphere: function() { | |
stream.sphere(); | |
}, | |
lineStart: function() { | |
stream.lineStart(); | |
}, | |
lineEnd: function() { | |
stream.lineEnd(); | |
}, | |
polygonStart: function() { | |
stream.polygonStart(); | |
}, | |
polygonEnd: function() { | |
stream.polygonEnd(); | |
} | |
}; | |
}; | |
} | |
d3.geo.projection = d3_geo_projection; | |
d3.geo.projectionMutator = d3_geo_projectionMutator; | |
function d3_geo_projection(project) { | |
return d3_geo_projectionMutator(function() { | |
return project; | |
})(); | |
} | |
function d3_geo_projectionMutator(projectAt) { | |
var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { | |
x = project(x, y); | |
return [ x[0] * k + δx, δy - x[1] * k ]; | |
}), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; | |
function projection(point) { | |
point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); | |
return [ point[0] * k + δx, δy - point[1] * k ]; | |
} | |
function invert(point) { | |
point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); | |
return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; | |
} | |
projection.stream = function(output) { | |
if (stream) stream.valid = false; | |
stream = d3_geo_projectionRadiansRotate(rotate, preclip(projectResample(postclip(output)))); | |
stream.valid = true; | |
return stream; | |
}; | |
projection.clipAngle = function(_) { | |
if (!arguments.length) return clipAngle; | |
preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); | |
return invalidate(); | |
}; | |
projection.clipExtent = function(_) { | |
if (!arguments.length) return clipExtent; | |
clipExtent = _; | |
postclip = _ == null ? d3_identity : d3_geo_clipView(_[0][0], _[0][1], _[1][0], _[1][1]); | |
return invalidate(); | |
}; | |
projection.scale = function(_) { | |
if (!arguments.length) return k; | |
k = +_; | |
return reset(); | |
}; | |
projection.translate = function(_) { | |
if (!arguments.length) return [ x, y ]; | |
x = +_[0]; | |
y = +_[1]; | |
return reset(); | |
}; | |
projection.center = function(_) { | |
if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; | |
λ = _[0] % 360 * d3_radians; | |
φ = _[1] % 360 * d3_radians; | |
return reset(); | |
}; | |
projection.rotate = function(_) { | |
if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; | |
δλ = _[0] % 360 * d3_radians; | |
δφ = _[1] % 360 * d3_radians; | |
δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; | |
return reset(); | |
}; | |
d3.rebind(projection, projectResample, "precision"); | |
function reset() { | |
projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); | |
var center = project(λ, φ); | |
δx = x - center[0] * k; | |
δy = y + center[1] * k; | |
return invalidate(); | |
} | |
function invalidate() { | |
if (stream) { | |
stream.valid = false; | |
stream = null; | |
} | |
return projection; | |
} | |
return function() { | |
project = projectAt.apply(this, arguments); | |
projection.invert = project.invert && invert; | |
return reset(); | |
}; | |
} | |
function d3_geo_projectionRadiansRotate(rotate, stream) { | |
return { | |
point: function(x, y) { | |
y = rotate(x * d3_radians, y * d3_radians), x = y[0]; | |
stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]); | |
}, | |
sphere: function() { | |
stream.sphere(); | |
}, | |
lineStart: function() { | |
stream.lineStart(); | |
}, | |
lineEnd: function() { | |
stream.lineEnd(); | |
}, | |
polygonStart: function() { | |
stream.polygonStart(); | |
}, | |
polygonEnd: function() { | |
stream.polygonEnd(); | |
} | |
}; | |
} | |
function d3_geo_equirectangular(λ, φ) { | |
return [ λ, φ ]; | |
} | |
(d3.geo.equirectangular = function() { | |
return d3_geo_projection(d3_geo_equirectangular); | |
}).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; | |
d3.geo.rotation = function(rotate) { | |
rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); | |
function forward(coordinates) { | |
coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); | |
return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; | |
} | |
forward.invert = function(coordinates) { | |
coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); | |
return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; | |
}; | |
return forward; | |
}; | |
function d3_geo_rotation(δλ, δφ, δγ) { | |
return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_equirectangular; | |
} | |
function d3_geo_forwardRotationλ(δλ) { | |
return function(λ, φ) { | |
return λ += δλ, [ λ > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ ]; | |
}; | |
} | |
function d3_geo_rotationλ(δλ) { | |
var rotation = d3_geo_forwardRotationλ(δλ); | |
rotation.invert = d3_geo_forwardRotationλ(-δλ); | |
return rotation; | |
} | |
function d3_geo_rotationφγ(δφ, δγ) { | |
var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); | |
function rotation(λ, φ) { | |
var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; | |
return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; | |
} | |
rotation.invert = function(λ, φ) { | |
var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; | |
return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; | |
}; | |
return rotation; | |
} | |
d3.geo.circle = function() { | |
var origin = [ 0, 0 ], angle, precision = 6, interpolate; | |
function circle() { | |
var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; | |
interpolate(null, null, 1, { | |
point: function(x, y) { | |
ring.push(x = rotate(x, y)); | |
x[0] *= d3_degrees, x[1] *= d3_degrees; | |
} | |
}); | |
return { | |
type: "Polygon", | |
coordinates: [ ring ] | |
}; | |
} | |
circle.origin = function(x) { | |
if (!arguments.length) return origin; | |
origin = x; | |
return circle; | |
}; | |
circle.angle = function(x) { | |
if (!arguments.length) return angle; | |
interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); | |
return circle; | |
}; | |
circle.precision = function(_) { | |
if (!arguments.length) return precision; | |
interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); | |
return circle; | |
}; | |
return circle.angle(90); | |
}; | |
function d3_geo_circleInterpolate(radius, precision) { | |
var cr = Math.cos(radius), sr = Math.sin(radius); | |
return function(from, to, direction, listener) { | |
if (from != null) { | |
from = d3_geo_circleAngle(cr, from); | |
to = d3_geo_circleAngle(cr, to); | |
if (direction > 0 ? from < to : from > to) from += direction * 2 * π; | |
} else { | |
from = radius + direction * 2 * π; | |
to = radius; | |
} | |
var point; | |
for (var step = direction * precision, t = from; direction > 0 ? t > to : t < to; t -= step) { | |
listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); | |
} | |
}; | |
} | |
function d3_geo_circleAngle(cr, point) { | |
var a = d3_geo_cartesian(point); | |
a[0] -= cr; | |
d3_geo_cartesianNormalize(a); | |
var angle = d3_acos(-a[1]); | |
return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); | |
} | |
d3.geo.distance = function(a, b) { | |
var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; | |
return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); | |
}; | |
d3.geo.graticule = function() { | |
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() | |
}; | |
} | |
function lines() { | |
return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { | |
return Math.abs(x % DX) > ε; | |
}).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { | |
return Math.abs(y % DY) > ε; | |
}).map(y)); | |
} | |
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)) ] | |
}; | |
}; | |
graticule.extent = function(_) { | |
if (!arguments.length) return graticule.minorExtent(); | |
return graticule.majorExtent(_).minorExtent(_); | |
}; | |
graticule.majorExtent = 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); | |
}; | |
graticule.minorExtent = 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); | |
}; | |
graticule.step = function(_) { | |
if (!arguments.length) return graticule.minorStep(); | |
return graticule.majorStep(_).minorStep(_); | |
}; | |
graticule.majorStep = function(_) { | |
if (!arguments.length) return [ DX, DY ]; | |
DX = +_[0], DY = +_[1]; | |
return graticule; | |
}; | |
graticule.minorStep = function(_) { | |
if (!arguments.length) return [ dx, dy ]; | |
dx = +_[0], dy = +_[1]; | |
return graticule; | |
}; | |
graticule.precision = function(_) { | |
if (!arguments.length) return precision; | |
precision = +_; | |
x = d3_geo_graticuleX(y0, y1, 90); | |
y = d3_geo_graticuleY(x0, x1, precision); | |
X = d3_geo_graticuleX(Y0, Y1, 90); | |
Y = d3_geo_graticuleY(X0, X1, precision); | |
return graticule; | |
}; | |
return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); | |
}; | |
function d3_geo_graticuleX(y0, y1, dy) { | |
var y = d3.range(y0, y1 - ε, dy).concat(y1); | |
return function(x) { | |
return y.map(function(y) { | |
return [ x, y ]; | |
}); | |
}; | |
} | |
function d3_geo_graticuleY(x0, x1, dx) { | |
var x = d3.range(x0, x1 - ε, dx).concat(x1); | |
return function(y) { | |
return x.map(function(x) { | |
return [ x, y ]; | |
}); | |
}; | |
} | |
function d3_source(d) { | |
return d.source; | |
} | |
function d3_target(d) { | |
return d.target; | |
} | |
d3.geo.greatArc = function() { | |
var source = d3_source, source_, target = d3_target, target_; | |
function greatArc() { | |
return { | |
type: "LineString", | |
coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] | |
}; | |
} | |
greatArc.distance = function() { | |
return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); | |
}; | |
greatArc.source = function(_) { | |
if (!arguments.length) return source; | |
source = _, source_ = typeof _ === "function" ? null : _; | |
return greatArc; | |
}; | |
greatArc.target = function(_) { | |
if (!arguments.length) return target; | |
target = _, target_ = typeof _ === "function" ? null : _; | |
return greatArc; | |
}; | |
greatArc.precision = function() { | |
return arguments.length ? greatArc : 0; | |
}; | |
return greatArc; | |
}; | |
d3.geo.interpolate = function(source, target) { | |
return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); | |
}; | |
function d3_geo_interpolate(x0, y0, x1, y1) { | |
var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); | |
var interpolate = d ? function(t) { | |
var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; | |
return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; | |
} : function() { | |
return [ x0 * d3_degrees, y0 * d3_degrees ]; | |
}; | |
interpolate.distance = d; | |
return interpolate; | |
} | |
d3.geo.length = function(object) { | |
d3_geo_lengthSum = 0; | |
d3.geo.stream(object, d3_geo_length); | |
return d3_geo_lengthSum; | |
}; | |
var d3_geo_lengthSum; | |
var d3_geo_length = { | |
sphere: d3_noop, | |
point: d3_noop, | |
lineStart: d3_geo_lengthLineStart, | |
lineEnd: d3_noop, | |
polygonStart: d3_noop, | |
polygonEnd: d3_noop | |
}; | |
function d3_geo_lengthLineStart() { | |
var λ0, sinφ0, cosφ0; | |
d3_geo_length.point = function(λ, φ) { | |
λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); | |
d3_geo_length.point = nextPoint; | |
}; | |
d3_geo_length.lineEnd = function() { | |
d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; | |
}; | |
function nextPoint(λ, φ) { | |
var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = Math.abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); | |
d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); | |
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; | |
} | |
} | |
function d3_geo_azimuthal(scale, angle) { | |
function azimuthal(λ, φ) { | |
var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); | |
return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; | |
} | |
azimuthal.invert = function(x, y) { | |
var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); | |
return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; | |
}; | |
return azimuthal; | |
} | |
var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { | |
return Math.sqrt(2 / (1 + cosλcosφ)); | |
}, function(ρ) { | |
return 2 * Math.asin(ρ / 2); | |
}); | |
(d3.geo.azimuthalEqualArea = function() { | |
return d3_geo_projection(d3_geo_azimuthalEqualArea); | |
}).raw = d3_geo_azimuthalEqualArea; | |
var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { | |
var c = Math.acos(cosλcosφ); | |
return c && c / Math.sin(c); | |
}, d3_identity); | |
(d3.geo.azimuthalEquidistant = function() { | |
return d3_geo_projection(d3_geo_azimuthalEquidistant); | |
}).raw = d3_geo_azimuthalEquidistant; | |
function d3_geo_conicConformal(φ0, φ1) { | |
var cosφ0 = Math.cos(φ0), t = function(φ) { | |
return Math.tan(π / 4 + φ / 2); | |
}, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; | |
if (!n) return d3_geo_mercator; | |
function forward(λ, φ) { | |
var ρ = Math.abs(Math.abs(φ) - π / 2) < ε ? 0 : F / Math.pow(t(φ), n); | |
return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; | |
} | |
forward.invert = function(x, y) { | |
var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); | |
return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - π / 2 ]; | |
}; | |
return forward; | |
} | |
(d3.geo.conicConformal = function() { | |
return d3_geo_conic(d3_geo_conicConformal); | |
}).raw = d3_geo_conicConformal; | |
function d3_geo_conicEquidistant(φ0, φ1) { | |
var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; | |
if (Math.abs(n) < ε) return d3_geo_equirectangular; | |
function forward(λ, φ) { | |
var ρ = G - φ; | |
return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; | |
} | |
forward.invert = function(x, y) { | |
var ρ0_y = G - y; | |
return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; | |
}; | |
return forward; | |
} | |
(d3.geo.conicEquidistant = function() { | |
return d3_geo_conic(d3_geo_conicEquidistant); | |
}).raw = d3_geo_conicEquidistant; | |
var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { | |
return 1 / cosλcosφ; | |
}, Math.atan); | |
(d3.geo.gnomonic = function() { | |
return d3_geo_projection(d3_geo_gnomonic); | |
}).raw = d3_geo_gnomonic; | |
function d3_geo_mercator(λ, φ) { | |
return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; | |
} | |
d3_geo_mercator.invert = function(x, y) { | |
return [ x, 2 * Math.atan(Math.exp(y)) - π / 2 ]; | |
}; | |
function d3_geo_mercatorProjection(project) { | |
var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; | |
m.scale = function() { | |
var v = scale.apply(m, arguments); | |
return v === m ? clipAuto ? m.clipExtent(null) : m : v; | |
}; | |
m.translate = function() { | |
var v = translate.apply(m, arguments); | |
return v === m ? clipAuto ? m.clipExtent(null) : m : v; | |
}; | |
m.clipExtent = function(_) { | |
var v = clipExtent.apply(m, arguments); | |
if (v === m) { | |
if (clipAuto = _ == null) { | |
var k = π * scale(), t = translate(); | |
clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); | |
} | |
} else if (clipAuto) { | |
v = null; | |
} | |
return v; | |
}; | |
return m.clipExtent(null); | |
} | |
(d3.geo.mercator = function() { | |
return d3_geo_mercatorProjection(d3_geo_mercator); | |
}).raw = d3_geo_mercator; | |
var d3_geo_orthographic = d3_geo_azimuthal(function() { | |
return 1; | |
}, Math.asin); | |
(d3.geo.orthographic = function() { | |
return d3_geo_projection(d3_geo_orthographic); | |
}).raw = d3_geo_orthographic; | |
var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { | |
return 1 / (1 + cosλcosφ); | |
}, function(ρ) { | |
return 2 * Math.atan(ρ); | |
}); | |
(d3.geo.stereographic = function() { | |
return d3_geo_projection(d3_geo_stereographic); | |
}).raw = d3_geo_stereographic; | |
function d3_geo_transverseMercator(λ, φ) { | |
var B = Math.cos(φ) * Math.sin(λ); | |
return [ Math.log((1 + B) / (1 - B)) / 2, Math.atan2(Math.tan(φ), Math.cos(λ)) ]; | |
} | |
d3_geo_transverseMercator.invert = function(x, y) { | |
return [ Math.atan2(d3_sinh(x), Math.cos(y)), d3_asin(Math.sin(y) / d3_cosh(x)) ]; | |
}; | |
(d3.geo.transverseMercator = function() { | |
return d3_geo_mercatorProjection(d3_geo_transverseMercator); | |
}).raw = d3_geo_transverseMercator; | |
d3.geom = {}; | |
d3.svg = {}; | |
function d3_svg_line(projection) { | |
var x = d3_svg_lineX, y = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; | |
function line(data) { | |
var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); | |
function segment() { | |
segments.push("M", interpolate(projection(points), tension)); | |
} | |
while (++i < n) { | |
if (defined.call(this, d = data[i], i)) { | |
points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); | |
} else if (points.length) { | |
segment(); | |
points = []; | |
} | |
} | |
if (points.length) segment(); | |
return segments.length ? segments.join("") : null; | |
} | |
line.x = function(_) { | |
if (!arguments.length) return x; | |
x = _; | |
return line; | |
}; | |
line.y = function(_) { | |
if (!arguments.length) return y; | |
y = _; | |
return line; | |
}; | |
line.defined = function(_) { | |
if (!arguments.length) return defined; | |
defined = _; | |
return line; | |
}; | |
line.interpolate = function(_) { | |
if (!arguments.length) return interpolateKey; | |
if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; | |
return line; | |
}; | |
line.tension = function(_) { | |
if (!arguments.length) return tension; | |
tension = _; | |
return line; | |
}; | |
return line; | |
} | |
d3.svg.line = function() { | |
return d3_svg_line(d3_identity); | |
}; | |
function d3_svg_lineX(d) { | |
return d[0]; | |
} | |
function d3_svg_lineY(d) { | |
return d[1]; | |
} | |
var d3_svg_lineInterpolators = d3.map({ | |
linear: d3_svg_lineLinear, | |
"linear-closed": d3_svg_lineLinearClosed, | |
step: d3_svg_lineStep, | |
"step-before": d3_svg_lineStepBefore, | |
"step-after": d3_svg_lineStepAfter, | |
basis: d3_svg_lineBasis, | |
"basis-open": d3_svg_lineBasisOpen, | |
"basis-closed": d3_svg_lineBasisClosed, | |
bundle: d3_svg_lineBundle, | |
cardinal: d3_svg_lineCardinal, | |
"cardinal-open": d3_svg_lineCardinalOpen, | |
"cardinal-closed": d3_svg_lineCardinalClosed, | |
monotone: d3_svg_lineMonotone | |
}); | |
d3_svg_lineInterpolators.forEach(function(key, value) { | |
value.key = key; | |
value.closed = /-closed$/.test(key); | |
}); | |
function d3_svg_lineLinear(points) { | |
return points.join("L"); | |
} | |
function d3_svg_lineLinearClosed(points) { | |
return d3_svg_lineLinear(points) + "Z"; | |
} | |
function d3_svg_lineStep(points) { | |
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; | |
while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); | |
if (n > 1) path.push("H", p[0]); | |
return path.join(""); | |
} | |
function d3_svg_lineStepBefore(points) { | |
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; | |
while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); | |
return path.join(""); | |
} | |
function d3_svg_lineStepAfter(points) { | |
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; | |
while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); | |
return path.join(""); | |
} | |
function d3_svg_lineCardinalOpen(points, tension) { | |
return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension)); | |
} | |
function d3_svg_lineCardinalClosed(points, tension) { | |
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), | |
points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); | |
} | |
function d3_svg_lineCardinal(points, tension) { | |
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); | |
} | |
function d3_svg_lineHermite(points, tangents) { | |
if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { | |
return d3_svg_lineLinear(points); | |
} | |
var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; | |
if (quad) { | |
path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; | |
p0 = points[1]; | |
pi = 2; | |
} | |
if (tangents.length > 1) { | |
t = tangents[1]; | |
p = points[pi]; | |
pi++; | |
path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; | |
for (var i = 2; i < tangents.length; i++, pi++) { | |
p = points[pi]; | |
t = tangents[i]; | |
path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; | |
} | |
} | |
if (quad) { | |
var lp = points[pi]; | |
path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; | |
} | |
return path; | |
} | |
function d3_svg_lineCardinalTangents(points, tension) { | |
var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; | |
while (++i < n) { | |
p0 = p1; | |
p1 = p2; | |
p2 = points[i]; | |
tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); | |
} | |
return tangents; | |
} | |
function d3_svg_lineBasis(points) { | |
if (points.length < 3) return d3_svg_lineLinear(points); | |
var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; | |
points.push(points[n - 1]); | |
while (++i <= n) { | |
pi = points[i]; | |
px.shift(); | |
px.push(pi[0]); | |
py.shift(); | |
py.push(pi[1]); | |
d3_svg_lineBasisBezier(path, px, py); | |
} | |
points.pop(); | |
path.push("L", pi); | |
return path.join(""); | |
} | |
function d3_svg_lineBasisOpen(points) { | |
if (points.length < 4) return d3_svg_lineLinear(points); | |
var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; | |
while (++i < 3) { | |
pi = points[i]; | |
px.push(pi[0]); | |
py.push(pi[1]); | |
} | |
path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); | |
--i; | |
while (++i < n) { | |
pi = points[i]; | |
px.shift(); | |
px.push(pi[0]); | |
py.shift(); | |
py.push(pi[1]); | |
d3_svg_lineBasisBezier(path, px, py); | |
} | |
return path.join(""); | |
} | |
function d3_svg_lineBasisClosed(points) { | |
var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; | |
while (++i < 4) { | |
pi = points[i % n]; | |
px.push(pi[0]); | |
py.push(pi[1]); | |
} | |
path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; | |
--i; | |
while (++i < m) { | |
pi = points[i % n]; | |
px.shift(); | |
px.push(pi[0]); | |
py.shift(); | |
py.push(pi[1]); | |
d3_svg_lineBasisBezier(path, px, py); | |
} | |
return path.join(""); | |
} | |
function d3_svg_lineBundle(points, tension) { | |
var n = points.length - 1; | |
if (n) { | |
var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; | |
while (++i <= n) { | |
p = points[i]; | |
t = i / n; | |
p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); | |
p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); | |
} | |
} | |
return d3_svg_lineBasis(points); | |
} | |
function d3_svg_lineDot4(a, b) { | |
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; | |
} | |
var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; | |
function d3_svg_lineBasisBezier(path, x, y) { | |
path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); | |
} | |
function d3_svg_lineSlope(p0, p1) { | |
return (p1[1] - p0[1]) / (p1[0] - p0[0]); | |
} | |
function d3_svg_lineFiniteDifferences(points) { | |
var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); | |
while (++i < j) { | |
m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; | |
} | |
m[i] = d; | |
return m; | |
} | |
function d3_svg_lineMonotoneTangents(points) { | |
var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; | |
while (++i < j) { | |
d = d3_svg_lineSlope(points[i], points[i + 1]); | |
if (Math.abs(d) < 1e-6) { | |
m[i] = m[i + 1] = 0; | |
} else { | |
a = m[i] / d; | |
b = m[i + 1] / d; | |
s = a * a + b * b; | |
if (s > 9) { | |
s = d * 3 / Math.sqrt(s); | |
m[i] = s * a; | |
m[i + 1] = s * b; | |
} | |
} | |
} | |
i = -1; | |
while (++i <= j) { | |
s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); | |
tangents.push([ s || 0, m[i] * s || 0 ]); | |
} | |
return tangents; | |
} | |
function d3_svg_lineMonotone(points) { | |
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); | |
} | |
d3.geom.hull = function(vertices) { | |
var x = d3_svg_lineX, y = d3_svg_lineY; | |
if (arguments.length) return hull(vertices); | |
function hull(data) { | |
if (data.length < 3) return []; | |
var fx = d3_functor(x), fy = d3_functor(y), n = data.length, vertices, plen = n - 1, points = [], stack = [], d, i, j, h = 0, x1, y1, x2, y2, u, v, a, sp; | |
if (fx === d3_svg_lineX && y === d3_svg_lineY) vertices = data; else for (i = 0, | |
vertices = []; i < n; ++i) { | |
vertices.push([ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]); | |
} | |
for (i = 1; i < n; ++i) { | |
if (vertices[i][1] < vertices[h][1] || vertices[i][1] == vertices[h][1] && vertices[i][0] < vertices[h][0]) h = i; | |
} | |
for (i = 0; i < n; ++i) { | |
if (i === h) continue; | |
y1 = vertices[i][1] - vertices[h][1]; | |
x1 = vertices[i][0] - vertices[h][0]; | |
points.push({ | |
angle: Math.atan2(y1, x1), | |
index: i | |
}); | |
} | |
points.sort(function(a, b) { | |
return a.angle - b.angle; | |
}); | |
a = points[0].angle; | |
v = points[0].index; | |
u = 0; | |
for (i = 1; i < plen; ++i) { | |
j = points[i].index; | |
if (a == points[i].angle) { | |
x1 = vertices[v][0] - vertices[h][0]; | |
y1 = vertices[v][1] - vertices[h][1]; | |
x2 = vertices[j][0] - vertices[h][0]; | |
y2 = vertices[j][1] - vertices[h][1]; | |
if (x1 * x1 + y1 * y1 >= x2 * x2 + y2 * y2) { | |
points[i].index = -1; | |
continue; | |
} else { | |
points[u].index = -1; | |
} | |
} | |
a = points[i].angle; | |
u = i; | |
v = j; | |
} | |
stack.push(h); | |
for (i = 0, j = 0; i < 2; ++j) { | |
if (points[j].index > -1) { | |
stack.push(points[j].index); | |
i++; | |
} | |
} | |
sp = stack.length; | |
for (;j < plen; ++j) { | |
if (points[j].index < 0) continue; | |
while (!d3_geom_hullCCW(stack[sp - 2], stack[sp - 1], points[j].index, vertices)) { | |
--sp; | |
} | |
stack[sp++] = points[j].index; | |
} | |
var poly = []; | |
for (i = sp - 1; i >= 0; --i) poly.push(data[stack[i]]); | |
return poly; | |
} | |
hull.x = function(_) { | |
return arguments.length ? (x = _, hull) : x; | |
}; | |
hull.y = function(_) { | |
return arguments.length ? (y = _, hull) : y; | |
}; | |
return hull; | |
}; | |
function d3_geom_hullCCW(i1, i2, i3, v) { | |
var t, a, b, c, d, e, f; | |
t = v[i1]; | |
a = t[0]; | |
b = t[1]; | |
t = v[i2]; | |
c = t[0]; | |
d = t[1]; | |
t = v[i3]; | |
e = t[0]; | |
f = t[1]; | |
return (f - b) * (c - a) - (d - b) * (e - a) > 0; | |
} | |
d3.geom.polygon = function(coordinates) { | |
d3_subclass(coordinates, d3_geom_polygonPrototype); | |
return coordinates; | |
}; | |
var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; | |
d3_geom_polygonPrototype.area = function() { | |
var i = -1, n = this.length, a, b = this[n - 1], area = 0; | |
while (++i < n) { | |
a = b; | |
b = this[i]; | |
area += a[1] * b[0] - a[0] * b[1]; | |
} | |
return area * .5; | |
}; | |
d3_geom_polygonPrototype.centroid = function(k) { | |
var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; | |
if (!arguments.length) k = -1 / (6 * this.area()); | |
while (++i < n) { | |
a = b; | |
b = this[i]; | |
c = a[0] * b[1] - b[0] * a[1]; | |
x += (a[0] + b[0]) * c; | |
y += (a[1] + b[1]) * c; | |
} | |
return [ x * k, y * k ]; | |
}; | |
d3_geom_polygonPrototype.clip = function(subject) { | |
var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; | |
while (++i < n) { | |
input = subject.slice(); | |
subject.length = 0; | |
b = this[i]; | |
c = input[(m = input.length - closed) - 1]; | |
j = -1; | |
while (++j < m) { | |
d = input[j]; | |
if (d3_geom_polygonInside(d, a, b)) { | |
if (!d3_geom_polygonInside(c, a, b)) { | |
subject.push(d3_geom_polygonIntersect(c, d, a, b)); | |
} | |
subject.push(d); | |
} else if (d3_geom_polygonInside(c, a, b)) { | |
subject.push(d3_geom_polygonIntersect(c, d, a, b)); | |
} | |
c = d; | |
} | |
if (closed) subject.push(subject[0]); | |
a = b; | |
} | |
return subject; | |
}; | |
function d3_geom_polygonInside(p, a, b) { | |
return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); | |
} | |
function d3_geom_polygonIntersect(c, d, a, b) { | |
var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); | |
return [ x1 + ua * x21, y1 + ua * y21 ]; | |
} | |
function d3_geom_polygonClosed(coordinates) { | |
var a = coordinates[0], b = coordinates[coordinates.length - 1]; | |
return !(a[0] - b[0] || a[1] - b[1]); | |
} | |
d3.geom.delaunay = function(vertices) { | |
var edges = vertices.map(function() { | |
return []; | |
}), triangles = []; | |
d3_geom_voronoiTessellate(vertices, function(e) { | |
edges[e.region.l.index].push(vertices[e.region.r.index]); | |
}); | |
edges.forEach(function(edge, i) { | |
var v = vertices[i], cx = v[0], cy = v[1]; | |
edge.forEach(function(v) { | |
v.angle = Math.atan2(v[0] - cx, v[1] - cy); | |
}); | |
edge.sort(function(a, b) { | |
return a.angle - b.angle; | |
}); | |
for (var j = 0, m = edge.length - 1; j < m; j++) { | |
triangles.push([ v, edge[j], edge[j + 1] ]); | |
} | |
}); | |
return triangles; | |
}; | |
d3.geom.voronoi = function(points) { | |
var x = d3_svg_lineX, y = d3_svg_lineY, clipPolygon = null; | |
if (arguments.length) return voronoi(points); | |
function voronoi(data) { | |
var points, polygons = data.map(function() { | |
return []; | |
}), fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length, Z = 1e6; | |
if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; else for (points = new Array(n), | |
i = 0; i < n; ++i) { | |
points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]; | |
} | |
d3_geom_voronoiTessellate(points, function(e) { | |
var s1, s2, x1, x2, y1, y2; | |
if (e.a === 1 && e.b >= 0) { | |
s1 = e.ep.r; | |
s2 = e.ep.l; | |
} else { | |
s1 = e.ep.l; | |
s2 = e.ep.r; | |
} | |
if (e.a === 1) { | |
y1 = s1 ? s1.y : -Z; | |
x1 = e.c - e.b * y1; | |
y2 = s2 ? s2.y : Z; | |
x2 = e.c - e.b * y2; | |
} else { | |
x1 = s1 ? s1.x : -Z; | |
y1 = e.c - e.a * x1; | |
x2 = s2 ? s2.x : Z; | |
y2 = e.c - e.a * x2; | |
} | |
var v1 = [ x1, y1 ], v2 = [ x2, y2 ]; | |
polygons[e.region.l.index].push(v1, v2); | |
polygons[e.region.r.index].push(v1, v2); | |
}); | |
polygons = polygons.map(function(polygon, i) { | |
var cx = points[i][0], cy = points[i][1], angle = polygon.map(function(v) { | |
return Math.atan2(v[0] - cx, v[1] - cy); | |
}), order = d3.range(polygon.length).sort(function(a, b) { | |
return angle[a] - angle[b]; | |
}); | |
return order.filter(function(d, i) { | |
return !i || angle[d] - angle[order[i - 1]] > ε; | |
}).map(function(d) { | |
return polygon[d]; | |
}); | |
}); | |
polygons.forEach(function(polygon, i) { | |
var n = polygon.length; | |
if (!n) return polygon.push([ -Z, -Z ], [ -Z, Z ], [ Z, Z ], [ Z, -Z ]); | |
if (n > 2) return; | |
var p0 = points[i], p1 = polygon[0], p2 = polygon[1], x0 = p0[0], y0 = p0[1], x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], dx = Math.abs(x2 - x1), dy = y2 - y1; | |
if (Math.abs(dy) < ε) { | |
var y = y0 < y1 ? -Z : Z; | |
polygon.push([ -Z, y ], [ Z, y ]); | |
} else if (dx < ε) { | |
var x = x0 < x1 ? -Z : Z; | |
polygon.push([ x, -Z ], [ x, Z ]); | |
} else { | |
var y = (x2 - x1) * (y1 - y0) < (x1 - x0) * (y2 - y1) ? Z : -Z, z = Math.abs(dy) - dx; | |
if (Math.abs(z) < ε) { | |
polygon.push([ dy < 0 ? y : -y, y ]); | |
} else { | |
if (z > 0) y *= -1; | |
polygon.push([ -Z, y ], [ Z, y ]); | |
} | |
} | |
}); | |
if (clipPolygon) for (i = 0; i < n; ++i) clipPolygon.clip(polygons[i]); | |
for (i = 0; i < n; ++i) polygons[i].point = data[i]; | |
return polygons; | |
} | |
voronoi.x = function(_) { | |
return arguments.length ? (x = _, voronoi) : x; | |
}; | |
voronoi.y = function(_) { | |
return arguments.length ? (y = _, voronoi) : y; | |
}; | |
voronoi.clipExtent = function(_) { | |
if (!arguments.length) return clipPolygon && [ clipPolygon[0], clipPolygon[2] ]; | |
if (_ == null) clipPolygon = null; else { | |
var x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], y2 = +_[1][1]; | |
clipPolygon = d3.geom.polygon([ [ x1, y1 ], [ x1, y2 ], [ x2, y2 ], [ x2, y1 ] ]); | |
} | |
return voronoi; | |
}; | |
voronoi.size = function(_) { | |
if (!arguments.length) return clipPolygon && clipPolygon[2]; | |
return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); | |
}; | |
voronoi.links = function(data) { | |
var points, graph = data.map(function() { | |
return []; | |
}), links = [], fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length; | |
if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; else for (points = new Array(n), | |
i = 0; i < n; ++i) { | |
points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]; | |
} | |
d3_geom_voronoiTessellate(points, function(e) { | |
var l = e.region.l.index, r = e.region.r.index; | |
if (graph[l][r]) return; | |
graph[l][r] = graph[r][l] = true; | |
links.push({ | |
source: data[l], | |
target: data[r] | |
}); | |
}); | |
return links; | |
}; | |
voronoi.triangles = function(data) { | |
if (x === d3_svg_lineX && y === d3_svg_lineY) return d3.geom.delaunay(data); | |
var points = new Array(n), fx = d3_functor(x), fy = d3_functor(y), d, i = -1, n = data.length; | |
while (++i < n) { | |
(points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]).data = d; | |
} | |
return d3.geom.delaunay(points).map(function(triangle) { | |
return triangle.map(function(point) { | |
return point.data; | |
}); | |
}); | |
}; | |
return voronoi; | |
}; | |
var d3_geom_voronoiOpposite = { | |
l: "r", | |
r: "l" | |
}; | |
function d3_geom_voronoiTessellate(points, callback) { | |
var Sites = { | |
list: points.map(function(v, i) { | |
return { | |
index: i, | |
x: v[0], | |
y: v[1] | |
}; | |
}).sort(function(a, b) { | |
return a.y < b.y ? -1 : a.y > b.y ? 1 : a.x < b.x ? -1 : a.x > b.x ? 1 : 0; | |
}), | |
bottomSite: null | |
}; | |
var EdgeList = { | |
list: [], | |
leftEnd: null, | |
rightEnd: null, | |
init: function() { | |
EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l"); | |
EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l"); | |
EdgeList.leftEnd.r = EdgeList.rightEnd; | |
EdgeList.rightEnd.l = EdgeList.leftEnd; | |
EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd); | |
}, | |
createHalfEdge: function(edge, side) { | |
return { | |
edge: edge, | |
side: side, | |
vertex: null, | |
l: null, | |
r: null | |
}; | |
}, | |
insert: function(lb, he) { | |
he.l = lb; | |
he.r = lb.r; | |
lb.r.l = he; | |
lb.r = he; | |
}, | |
leftBound: function(p) { | |
var he = EdgeList.leftEnd; | |
do { | |
he = he.r; | |
} while (he != EdgeList.rightEnd && Geom.rightOf(he, p)); | |
he = he.l; | |
return he; | |
}, | |
del: function(he) { | |
he.l.r = he.r; | |
he.r.l = he.l; | |
he.edge = null; | |
}, | |
right: function(he) { | |
return he.r; | |
}, | |
left: function(he) { | |
return he.l; | |
}, | |
leftRegion: function(he) { | |
return he.edge == null ? Sites.bottomSite : he.edge.region[he.side]; | |
}, | |
rightRegion: function(he) { | |
return he.edge == null ? Sites.bottomSite : he.edge.region[d3_geom_voronoiOpposite[he.side]]; | |
} | |
}; | |
var Geom = { | |
bisect: function(s1, s2) { | |
var newEdge = { | |
region: { | |
l: s1, | |
r: s2 | |
}, | |
ep: { | |
l: null, | |
r: null | |
} | |
}; | |
var dx = s2.x - s1.x, dy = s2.y - s1.y, adx = dx > 0 ? dx : -dx, ady = dy > 0 ? dy : -dy; | |
newEdge.c = s1.x * dx + s1.y * dy + (dx * dx + dy * dy) * .5; | |
if (adx > ady) { | |
newEdge.a = 1; | |
newEdge.b = dy / dx; | |
newEdge.c /= dx; | |
} else { | |
newEdge.b = 1; | |
newEdge.a = dx / dy; | |
newEdge.c /= dy; | |
} | |
return newEdge; | |
}, | |
intersect: function(el1, el2) { | |
var e1 = el1.edge, e2 = el2.edge; | |
if (!e1 || !e2 || e1.region.r == e2.region.r) { | |
return null; | |
} | |
var d = e1.a * e2.b - e1.b * e2.a; | |
if (Math.abs(d) < 1e-10) { | |
return null; | |
} | |
var xint = (e1.c * e2.b - e2.c * e1.b) / d, yint = (e2.c * e1.a - e1.c * e2.a) / d, e1r = e1.region.r, e2r = e2.region.r, el, e; | |
if (e1r.y < e2r.y || e1r.y == e2r.y && e1r.x < e2r.x) { | |
el = el1; | |
e = e1; | |
} else { | |
el = el2; | |
e = e2; | |
} | |
var rightOfSite = xint >= e.region.r.x; | |
if (rightOfSite && el.side === "l" || !rightOfSite && el.side === "r") { | |
return null; | |
} | |
return { | |
x: xint, | |
y: yint | |
}; | |
}, | |
rightOf: function(he, p) { | |
var e = he.edge, topsite = e.region.r, rightOfSite = p.x > topsite.x; | |
if (rightOfSite && he.side === "l") { | |
return 1; | |
} | |
if (!rightOfSite && he.side === "r") { | |
return 0; | |
} | |
if (e.a === 1) { | |
var dyp = p.y - topsite.y, dxp = p.x - topsite.x, fast = 0, above = 0; | |
if (!rightOfSite && e.b < 0 || rightOfSite && e.b >= 0) { | |
above = fast = dyp >= e.b * dxp; | |
} else { | |
above = p.x + p.y * e.b > e.c; | |
if (e.b < 0) { | |
above = !above; | |
} | |
if (!above) { | |
fast = 1; | |
} | |
} | |
if (!fast) { | |
var dxs = topsite.x - e.region.l.x; | |
above = e.b * (dxp * dxp - dyp * dyp) < dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b); | |
if (e.b < 0) { | |
above = !above; | |
} | |
} | |
} else { | |
var yl = e.c - e.a * p.x, t1 = p.y - yl, t2 = p.x - topsite.x, t3 = yl - topsite.y; | |
above = t1 * t1 > t2 * t2 + t3 * t3; | |
} | |
return he.side === "l" ? above : !above; | |
}, | |
endPoint: function(edge, side, site) { | |
edge.ep[side] = site; | |
if (!edge.ep[d3_geom_voronoiOpposite[side]]) return; | |
callback(edge); | |
}, | |
distance: function(s, t) { | |
var dx = s.x - t.x, dy = s.y - t.y; | |
return Math.sqrt(dx * dx + dy * dy); | |
} | |
}; | |
var EventQueue = { | |
list: [], | |
insert: function(he, site, offset) { | |
he.vertex = site; | |
he.ystar = site.y + offset; | |
for (var i = 0, list = EventQueue.list, l = list.length; i < l; i++) { | |
var next = list[i]; | |
if (he.ystar > next.ystar || he.ystar == next.ystar && site.x > next.vertex.x) { | |
continue; | |
} else { | |
break; | |
} | |
} | |
list.splice(i, 0, he); | |
}, | |
del: function(he) { | |
for (var i = 0, ls = EventQueue.list, l = ls.length; i < l && ls[i] != he; ++i) {} | |
ls.splice(i, 1); | |
}, | |
empty: function() { | |
return EventQueue.list.length === 0; | |
}, | |
nextEvent: function(he) { | |
for (var i = 0, ls = EventQueue.list, l = ls.length; i < l; ++i) { | |
if (ls[i] == he) return ls[i + 1]; | |
} | |
return null; | |
}, | |
min: function() { | |
var elem = EventQueue.list[0]; | |
return { | |
x: elem.vertex.x, | |
y: elem.ystar | |
}; | |
}, | |
extractMin: function() { | |
return EventQueue.list.shift(); | |
} | |
}; | |
EdgeList.init(); | |
Sites.bottomSite = Sites.list.shift(); | |
var newSite = Sites.list.shift(), newIntStar; | |
var lbnd, rbnd, llbnd, rrbnd, bisector; | |
var bot, top, temp, p, v; | |
var e, pm; | |
while (true) { | |
if (!EventQueue.empty()) { | |
newIntStar = EventQueue.min(); | |
} | |
if (newSite && (EventQueue.empty() || newSite.y < newIntStar.y || newSite.y == newIntStar.y && newSite.x < newIntStar.x)) { | |
lbnd = EdgeList.leftBound(newSite); | |
rbnd = EdgeList.right(lbnd); | |
bot = EdgeList.rightRegion(lbnd); | |
e = Geom.bisect(bot, newSite); | |
bisector = EdgeList.createHalfEdge(e, "l"); | |
EdgeList.insert(lbnd, bisector); | |
p = Geom.intersect(lbnd, bisector); | |
if (p) { | |
EventQueue.del(lbnd); | |
EventQueue.insert(lbnd, p, Geom.distance(p, newSite)); | |
} | |
lbnd = bisector; | |
bisector = EdgeList.createHalfEdge(e, "r"); | |
EdgeList.insert(lbnd, bisector); | |
p = Geom.intersect(bisector, rbnd); | |
if (p) { | |
EventQueue.insert(bisector, p, Geom.distance(p, newSite)); | |
} | |
newSite = Sites.list.shift(); | |
} else if (!EventQueue.empty()) { | |
lbnd = EventQueue.extractMin(); | |
llbnd = EdgeList.left(lbnd); | |
rbnd = EdgeList.right(lbnd); | |
rrbnd = EdgeList.right(rbnd); | |
bot = EdgeList.leftRegion(lbnd); | |
top = EdgeList.rightRegion(rbnd); | |
v = lbnd.vertex; | |
Geom.endPoint(lbnd.edge, lbnd.side, v); | |
Geom.endPoint(rbnd.edge, rbnd.side, v); | |
EdgeList.del(lbnd); | |
EventQueue.del(rbnd); | |
EdgeList.del(rbnd); | |
pm = "l"; | |
if (bot.y > top.y) { | |
temp = bot; | |
bot = top; | |
top = temp; | |
pm = "r"; | |
} | |
e = Geom.bisect(bot, top); | |
bisector = EdgeList.createHalfEdge(e, pm); | |
EdgeList.insert(llbnd, bisector); | |
Geom.endPoint(e, d3_geom_voronoiOpposite[pm], v); | |
p = Geom.intersect(llbnd, bisector); | |
if (p) { | |
EventQueue.del(llbnd); | |
EventQueue.insert(llbnd, p, Geom.distance(p, bot)); | |
} | |
p = Geom.intersect(bisector, rrbnd); | |
if (p) { | |
EventQueue.insert(bisector, p, Geom.distance(p, bot)); | |
} | |
} else { | |
break; | |
} | |
} | |
for (lbnd = EdgeList.right(EdgeList.leftEnd); lbnd != EdgeList.rightEnd; lbnd = EdgeList.right(lbnd)) { | |
callback(lbnd.edge); | |
} | |
} | |
d3.geom.quadtree = function(points, x1, y1, x2, y2) { | |
var x = d3_svg_lineX, y = d3_svg_lineY, compat; | |
if (compat = arguments.length) { | |
x = d3_geom_quadtreeCompatX; | |
y = d3_geom_quadtreeCompatY; | |
if (compat === 3) { | |
y2 = y1; | |
x2 = x1; | |
y1 = x1 = 0; | |
} | |
return quadtree(points); | |
} | |
function quadtree(data) { | |
var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; | |
if (x1 != null) { | |
x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; | |
} else { | |
x2_ = y2_ = -(x1_ = y1_ = Infinity); | |
xs = [], ys = []; | |
n = data.length; | |
if (compat) for (i = 0; i < n; ++i) { | |
d = data[i]; | |
if (d.x < x1_) x1_ = d.x; | |
if (d.y < y1_) y1_ = d.y; | |
if (d.x > x2_) x2_ = d.x; | |
if (d.y > y2_) y2_ = d.y; | |
xs.push(d.x); | |
ys.push(d.y); | |
} else for (i = 0; i < n; ++i) { | |
var x_ = +fx(d = data[i], i), y_ = +fy(d, i); | |
if (x_ < x1_) x1_ = x_; | |
if (y_ < y1_) y1_ = y_; | |
if (x_ > x2_) x2_ = x_; | |
if (y_ > y2_) y2_ = y_; | |
xs.push(x_); | |
ys.push(y_); | |
} | |
} | |
var dx = x2_ - x1_, dy = y2_ - y1_; | |
if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; | |
function insert(n, d, x, y, x1, y1, x2, y2) { | |
if (isNaN(x) || isNaN(y)) return; | |
if (n.leaf) { | |
var nx = n.x, ny = n.y; | |
if (nx != null) { | |
if (Math.abs(nx - x) + Math.abs(ny - y) < .01) { | |
insertChild(n, d, x, y, x1, y1, x2, y2); | |
} else { | |
var nPoint = n.point; | |
n.x = n.y = n.point = null; | |
insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); | |
insertChild(n, d, x, y, x1, y1, x2, y2); | |
} | |
} else { | |
n.x = x, n.y = y, n.point = d; | |
} | |
} else { | |
insertChild(n, d, x, y, x1, y1, x2, y2); | |
} | |
} | |
function insertChild(n, d, x, y, x1, y1, x2, y2) { | |
var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = x >= sx, bottom = y >= sy, i = (bottom << 1) + right; | |
n.leaf = false; | |
n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); | |
if (right) x1 = sx; else x2 = sx; | |
if (bottom) y1 = sy; else y2 = sy; | |
insert(n, d, x, y, x1, y1, x2, y2); | |
} | |
var root = d3_geom_quadtreeNode(); | |
root.add = function(d) { | |
insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); | |
}; | |
root.visit = function(f) { | |
d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); | |
}; | |
i = -1; | |
if (x1 == null) { | |
while (++i < n) { | |
insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); | |
} | |
--i; | |
} else data.forEach(root.add); | |
xs = ys = data = d = null; | |
return root; | |
} | |
quadtree.x = function(_) { | |
return arguments.length ? (x = _, quadtree) : x; | |
}; | |
quadtree.y = function(_) { | |
return arguments.length ? (y = _, quadtree) : y; | |
}; | |
quadtree.extent = function(_) { | |
if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; | |
if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], | |
y2 = +_[1][1]; | |
return quadtree; | |
}; | |
quadtree.size = function(_) { | |
if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; | |
if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; | |
return quadtree; | |
}; | |
return quadtree; | |
}; | |
function d3_geom_quadtreeCompatX(d) { | |
return d.x; | |
} | |
function d3_geom_quadtreeCompatY(d) { | |
return d.y; | |
} | |
function d3_geom_quadtreeNode() { | |
return { | |
leaf: true, | |
nodes: [], | |
point: null, | |
x: null, | |
y: null | |
}; | |
} | |
function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { | |
if (!f(node, x1, y1, x2, y2)) { | |
var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; | |
if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); | |
if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); | |
if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); | |
if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); | |
} | |
} | |
d3.interpolateRgb = d3_interpolateRgb; | |
function d3_interpolateRgb(a, b) { | |
a = d3.rgb(a); | |
b = d3.rgb(b); | |
var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; | |
return function(t) { | |
a.r = Math.round(ar + br * t); | |
a.g = Math.round(ag + bg * t); | |
a.b = Math.round(ab + bb * t); | |
return a; | |
}; | |
} | |
d3.interpolateObject = d3_interpolateObject; | |
function d3_interpolateObject(a, b) { | |
var i = {}, c = {}, k; | |
for (k in a) { | |
if (k in b) { | |
i[k] = d3_interpolate(a[k], b[k]); | |
} else { | |
c[k] = a[k]; | |
} | |
} | |
for (k in b) { | |
if (!(k in a)) { | |
c[k] = b[k]; | |
} | |
} | |
return function(t) { | |
for (k in i) c[k] = i[k](t); | |
return c; | |
}; | |
} | |
d3.interpolateNumber = d3_interpolateNumber; | |
function d3_interpolateNumber(a, b) { | |
b -= a = +a; | |
return function(t) { | |
return a + b * t; | |
}; | |
} | |
d3.interpolateString = d3_interpolateString; | |
function d3_interpolateString(a, b) { | |
var m, i, j, s0 = 0, s1 = 0, s = [], q = [], n, o; | |
a = a + "", b = b + ""; | |
d3_interpolate_number.lastIndex = 0; | |
for (i = 0; m = d3_interpolate_number.exec(b); ++i) { | |
if (m.index) s.push(b.substring(s0, s1 = m.index)); | |
q.push({ | |
i: s.length, | |
x: m[0] | |
}); | |
s.push(null); | |
s0 = d3_interpolate_number.lastIndex; | |
} | |
if (s0 < b.length) s.push(b.substring(s0)); | |
for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { | |
o = q[i]; | |
if (o.x == m[0]) { | |
if (o.i) { | |
if (s[o.i + 1] == null) { | |
s[o.i - 1] += o.x; | |
s.splice(o.i, 1); | |
for (j = i + 1; j < n; ++j) q[j].i--; | |
} else { | |
s[o.i - 1] += o.x + s[o.i + 1]; | |
s.splice(o.i, 2); | |
for (j = i + 1; j < n; ++j) q[j].i -= 2; | |
} | |
} else { | |
if (s[o.i + 1] == null) { | |
s[o.i] = o.x; | |
} else { | |
s[o.i] = o.x + s[o.i + 1]; | |
s.splice(o.i + 1, 1); | |
for (j = i + 1; j < n; ++j) q[j].i--; | |
} | |
} | |
q.splice(i, 1); | |
n--; | |
i--; | |
} else { | |
o.x = d3_interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); | |
} | |
} | |
while (i < n) { | |
o = q.pop(); | |
if (s[o.i + 1] == null) { | |
s[o.i] = o.x; | |
} else { | |
s[o.i] = o.x + s[o.i + 1]; | |
s.splice(o.i + 1, 1); | |
} | |
n--; | |
} | |
if (s.length === 1) { | |
return s[0] == null ? (o = q[0].x, function(t) { | |
return o(t) + ""; | |
}) : function() { | |
return b; | |
}; | |
} | |
return function(t) { | |
for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); | |
return s.join(""); | |
}; | |
} | |
var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; | |
d3.interpolate = d3_interpolate; | |
function d3_interpolate(a, b) { | |
var i = d3.interpolators.length, f; | |
while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; | |
return f; | |
} | |
d3.interpolators = [ function(a, b) { | |
var t = typeof b; | |
return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_Color ? d3_interpolateRgb : t === "object" ? Array.isArray(b) ? d3_interpolateArray : d3_interpolateObject : d3_interpolateNumber)(a, b); | |
} ]; | |
d3.interpolateArray = d3_interpolateArray; | |
function d3_interpolateArray(a, b) { | |
var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; | |
for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); | |
for (;i < na; ++i) c[i] = a[i]; | |
for (;i < nb; ++i) c[i] = b[i]; | |
return function(t) { | |
for (i = 0; i < n0; ++i) c[i] = x[i](t); | |
return c; | |
}; | |
} | |
var d3_ease_default = function() { | |
return d3_identity; | |
}; | |
var d3_ease = d3.map({ | |
linear: d3_ease_default, | |
poly: d3_ease_poly, | |
quad: function() { | |
return d3_ease_quad; | |
}, | |
cubic: function() { | |
return d3_ease_cubic; | |
}, | |
sin: function() { | |
return d3_ease_sin; | |
}, | |
exp: function() { | |
return d3_ease_exp; | |
}, | |
circle: function() { | |
return d3_ease_circle; | |
}, | |
elastic: d3_ease_elastic, | |
back: d3_ease_back, | |
bounce: function() { | |
return d3_ease_bounce; | |
} | |
}); | |
var d3_ease_mode = d3.map({ | |
"in": d3_identity, | |
out: d3_ease_reverse, | |
"in-out": d3_ease_reflect, | |
"out-in": function(f) { | |
return d3_ease_reflect(d3_ease_reverse(f)); | |
} | |
}); | |
d3.ease = function(name) { | |
var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in"; | |
t = d3_ease.get(t) || d3_ease_default; | |
m = d3_ease_mode.get(m) || d3_identity; | |
return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1)))); | |
}; | |
function d3_ease_clamp(f) { | |
return function(t) { | |
return t <= 0 ? 0 : t >= 1 ? 1 : f(t); | |
}; | |
} | |
function d3_ease_reverse(f) { | |
return function(t) { | |
return 1 - f(1 - t); | |
}; | |
} | |
function d3_ease_reflect(f) { | |
return function(t) { | |
return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); | |
}; | |
} | |
function d3_ease_quad(t) { | |
return t * t; | |
} | |
function d3_ease_cubic(t) { | |
return t * t * t; | |
} | |
function d3_ease_cubicInOut(t) { | |
if (t <= 0) return 0; | |
if (t >= 1) return 1; | |
var t2 = t * t, t3 = t2 * t; | |
return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); | |
} | |
function d3_ease_poly(e) { | |
return function(t) { | |
return Math.pow(t, e); | |
}; | |
} | |
function d3_ease_sin(t) { | |
return 1 - Math.cos(t * π / 2); | |
} | |
function d3_ease_exp(t) { | |
return Math.pow(2, 10 * (t - 1)); | |
} | |
function d3_ease_circle(t) { | |
return 1 - Math.sqrt(1 - t * t); | |
} | |
function d3_ease_elastic(a, p) { | |
var s; | |
if (arguments.length < 2) p = .45; | |
if (arguments.length) s = p / (2 * π) * Math.asin(1 / a); else a = 1, s = p / 4; | |
return function(t) { | |
return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * π / p); | |
}; | |
} | |
function d3_ease_back(s) { | |
if (!s) s = 1.70158; | |
return function(t) { | |
return t * t * ((s + 1) * t - s); | |
}; | |
} | |
function d3_ease_bounce(t) { | |
return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; | |
} | |
d3.interpolateHcl = d3_interpolateHcl; | |
function d3_interpolateHcl(a, b) { | |
a = d3.hcl(a); | |
b = d3.hcl(b); | |
var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; | |
if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; | |
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; | |
return function(t) { | |
a.h = ah + bh * t; | |
a.c = ac + bc * t; | |
a.l = al + bl * t; | |
return a; | |
}; | |
} | |
d3.interpolateHsl = d3_interpolateHsl; | |
function d3_interpolateHsl(a, b) { | |
a = d3.hsl(a); | |
b = d3.hsl(b); | |
var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; | |
if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; | |
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; | |
return function(t) { | |
a.h = ah + bh * t; | |
a.s = as + bs * t; | |
a.l = al + bl * t; | |
return a; | |
}; | |
} | |
d3.interpolateLab = d3_interpolateLab; | |
function d3_interpolateLab(a, b) { | |
a = d3.lab(a); | |
b = d3.lab(b); | |
var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; | |
return function(t) { | |
a.l = al + bl * t; | |
a.a = aa + ba * t; | |
a.b = ab + bb * t; | |
return a; | |
}; | |
} | |
d3.interpolateRound = d3_interpolateRound; | |
function d3_interpolateRound(a, b) { | |
b -= a; | |
return function(t) { | |
return Math.round(a + b * t); | |
}; | |
} | |
d3.transform = function(string) { | |
var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); | |
return (d3.transform = function(string) { | |
if (string != null) { | |
g.setAttribute("transform", string); | |
var t = g.transform.baseVal.consolidate(); | |
} | |
return new d3_transform(t ? t.matrix : d3_transformIdentity); | |
})(string); | |
}; | |
function d3_transform(m) { | |
var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; | |
if (r0[0] * r1[1] < r1[0] * r0[1]) { | |
r0[0] *= -1; | |
r0[1] *= -1; | |
kx *= -1; | |
kz *= -1; | |
} | |
this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; | |
this.translate = [ m.e, m.f ]; | |
this.scale = [ kx, ky ]; | |
this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; | |
} | |
d3_transform.prototype.toString = function() { | |
return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; | |
}; | |
function d3_transformDot(a, b) { | |
return a[0] * b[0] + a[1] * b[1]; | |
} | |
function d3_transformNormalize(a) { | |
var k = Math.sqrt(d3_transformDot(a, a)); | |
if (k) { | |
a[0] /= k; | |
a[1] /= k; | |
} | |
return k; | |
} | |
function d3_transformCombine(a, b, k) { | |
a[0] += k * b[0]; | |
a[1] += k * b[1]; | |
return a; | |
} | |
var d3_transformIdentity = { | |
a: 1, | |
b: 0, | |
c: 0, | |
d: 1, | |
e: 0, | |
f: 0 | |
}; | |
d3.interpolateTransform = d3_interpolateTransform; | |
function d3_interpolateTransform(a, b) { | |
var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; | |
if (ta[0] != tb[0] || ta[1] != tb[1]) { | |
s.push("translate(", null, ",", null, ")"); | |
q.push({ | |
i: 1, | |
x: d3_interpolateNumber(ta[0], tb[0]) | |
}, { | |
i: 3, | |
x: d3_interpolateNumber(ta[1], tb[1]) | |
}); | |
} else if (tb[0] || tb[1]) { | |
s.push("translate(" + tb + ")"); | |
} else { | |
s.push(""); | |
} | |
if (ra != rb) { | |
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; | |
q.push({ | |
i: s.push(s.pop() + "rotate(", null, ")") - 2, | |
x: d3_interpolateNumber(ra, rb) | |
}); | |
} else if (rb) { | |
s.push(s.pop() + "rotate(" + rb + ")"); | |
} | |
if (wa != wb) { | |
q.push({ | |
i: s.push(s.pop() + "skewX(", null, ")") - 2, | |
x: d3_interpolateNumber(wa, wb) | |
}); | |
} else if (wb) { | |
s.push(s.pop() + "skewX(" + wb + ")"); | |
} | |
if (ka[0] != kb[0] || ka[1] != kb[1]) { | |
n = s.push(s.pop() + "scale(", null, ",", null, ")"); | |
q.push({ | |
i: n - 4, | |
x: d3_interpolateNumber(ka[0], kb[0]) | |
}, { | |
i: n - 2, | |
x: d3_interpolateNumber(ka[1], kb[1]) | |
}); | |
} else if (kb[0] != 1 || kb[1] != 1) { | |
s.push(s.pop() + "scale(" + kb + ")"); | |
} | |
n = q.length; | |
return function(t) { | |
var i = -1, o; | |
while (++i < n) s[(o = q[i]).i] = o.x(t); | |
return s.join(""); | |
}; | |
} | |
function d3_uninterpolateNumber(a, b) { | |
b = b - (a = +a) ? 1 / (b - a) : 0; | |
return function(x) { | |
return (x - a) * b; | |
}; | |
} | |
function d3_uninterpolateClamp(a, b) { | |
b = b - (a = +a) ? 1 / (b - a) : 0; | |
return function(x) { | |
return Math.max(0, Math.min(1, (x - a) * b)); | |
}; | |
} | |
d3.layout = {}; | |
d3.layout.bundle = function() { | |
return function(links) { | |
var paths = [], i = -1, n = links.length; | |
while (++i < n) paths.push(d3_layout_bundlePath(links[i])); | |
return paths; | |
}; | |
}; | |
function d3_layout_bundlePath(link) { | |
var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; | |
while (start !== lca) { | |
start = start.parent; | |
points.push(start); | |
} | |
var k = points.length; | |
while (end !== lca) { | |
points.splice(k, 0, end); | |
end = end.parent; | |
} | |
return points; | |
} | |
function d3_layout_bundleAncestors(node) { | |
var ancestors = [], parent = node.parent; | |
while (parent != null) { | |
ancestors.push(node); | |
node = parent; | |
parent = parent.parent; | |
} | |
ancestors.push(node); | |
return ancestors; | |
} | |
function d3_layout_bundleLeastCommonAncestor(a, b) { | |
if (a === b) return a; | |
var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; | |
while (aNode === bNode) { | |
sharedNode = aNode; | |
aNode = aNodes.pop(); | |
bNode = bNodes.pop(); | |
} | |
return sharedNode; | |
} | |
d3.layout.chord = function() { | |
var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; | |
function relayout() { | |
var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; | |
chords = []; | |
groups = []; | |
k = 0, i = -1; | |
while (++i < n) { | |
x = 0, j = -1; | |
while (++j < n) { | |
x += matrix[i][j]; | |
} | |
groupSums.push(x); | |
subgroupIndex.push(d3.range(n)); | |
k += x; | |
} | |
if (sortGroups) { | |
groupIndex.sort(function(a, b) { | |
return sortGroups(groupSums[a], groupSums[b]); | |
}); | |
} | |
if (sortSubgroups) { | |
subgroupIndex.forEach(function(d, i) { | |
d.sort(function(a, b) { | |
return sortSubgroups(matrix[i][a], matrix[i][b]); | |
}); | |
}); | |
} | |
k = (2 * π - padding * n) / k; | |
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[di + "-" + dj] = { | |
index: di, | |
subindex: dj, | |
startAngle: a0, | |
endAngle: a1, | |
value: v | |
}; | |
} | |
groups[di] = { | |
index: di, | |
startAngle: x0, | |
endAngle: x, | |
value: (x - x0) / k | |
}; | |
x += padding; | |
} | |
i = -1; | |
while (++i < n) { | |
j = i - 1; | |
while (++j < n) { | |
var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; | |
if (source.value || target.value) { | |
chords.push(source.value < target.value ? { | |
source: target, | |
target: source | |
} : { | |
source: source, | |
target: target | |
}); | |
} | |
} | |
} | |
if (sortChords) resort(); | |
} | |
function resort() { | |
chords.sort(function(a, b) { | |
return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); | |
}); | |
} | |
chord.matrix = function(x) { | |
if (!arguments.length) return matrix; | |
n = (matrix = x) && matrix.length; | |
chords = groups = null; | |
return chord; | |
}; | |
chord.padding = function(x) { | |
if (!arguments.length) return padding; | |
padding = x; | |
chords = groups = null; | |
return chord; | |
}; | |
chord.sortGroups = function(x) { | |
if (!arguments.length) return sortGroups; | |
sortGroups = x; | |
chords = groups = null; | |
return chord; | |
}; | |
chord.sortSubgroups = function(x) { | |
if (!arguments.length) return sortSubgroups; | |
sortSubgroups = x; | |
chords = null; | |
return chord; | |
}; | |
chord.sortChords = function(x) { | |
if (!arguments.length) return sortChords; | |
sortChords = x; | |
if (chords) resort(); | |
return chord; | |
}; | |
chord.chords = function() { | |
if (!chords) relayout(); | |
return chords; | |
}; | |
chord.groups = function() { | |
if (!groups) relayout(); | |
return groups; | |
}; | |
return chord; | |
}; | |
d3.layout.force = function() { | |
var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, gravity = .1, theta = .8, nodes = [], links = [], distances, strengths, charges; | |
function repulse(node) { | |
return function(quad, x1, _, x2) { | |
if (quad.point !== node) { | |
var dx = quad.cx - node.x, dy = quad.cy - node.y, dn = 1 / Math.sqrt(dx * dx + dy * dy); | |
if ((x2 - x1) * dn < theta) { | |
var k = quad.charge * dn * dn; | |
node.px -= dx * k; | |
node.py -= dy * k; | |
return true; | |
} | |
if (quad.point && isFinite(dn)) { | |
var k = quad.pointCharge * dn * dn; | |
node.px -= dx * k; | |
node.py -= dy * k; | |
} | |
} | |
return !quad.charge; | |
}; | |
} | |
force.tick = function() { | |
if ((alpha *= .99) < .005) { | |
event.end({ | |
type: "end", | |
alpha: alpha = 0 | |
}); | |
return true; | |
} | |
var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; | |
for (i = 0; i < m; ++i) { | |
o = links[i]; | |
s = o.source; | |
t = o.target; | |
x = t.x - s.x; | |
y = t.y - s.y; | |
if (l = x * x + y * y) { | |
l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; | |
x *= l; | |
y *= l; | |
t.x -= x * (k = s.weight / (t.weight + s.weight)); | |
t.y -= y * k; | |
s.x += x * (k = 1 - k); | |
s.y += y * k; | |
} | |
} | |
if (k = alpha * gravity) { | |
x = size[0] / 2; | |
y = size[1] / 2; | |
i = -1; | |
if (k) while (++i < n) { | |
o = nodes[i]; | |
o.x += (x - o.x) * k; | |
o.y += (y - o.y) * k; | |
} | |
} | |
if (charge) { | |
d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); | |
i = -1; | |
while (++i < n) { | |
if (!(o = nodes[i]).fixed) { | |
q.visit(repulse(o)); | |
} | |
} | |
} | |
i = -1; | |
while (++i < n) { | |
o = nodes[i]; | |
if (o.fixed) { | |
o.x = o.px; | |
o.y = o.py; | |
} else { | |
o.x -= (o.px - (o.px = o.x)) * friction; | |
o.y -= (o.py - (o.py = o.y)) * friction; | |
} | |
} | |
event.tick({ | |
type: "tick", | |
alpha: alpha | |
}); | |
}; | |
force.nodes = function(x) { | |
if (!arguments.length) return nodes; | |
nodes = x; | |
return force; | |
}; | |
force.links = function(x) { | |
if (!arguments.length) return links; | |
links = x; | |
return force; | |
}; | |
force.size = function(x) { | |
if (!arguments.length) return size; | |
size = x; | |
return force; | |
}; | |
force.linkDistance = function(x) { | |
if (!arguments.length) return linkDistance; | |
linkDistance = typeof x === "function" ? x : +x; | |
return force; | |
}; | |
force.distance = force.linkDistance; | |
force.linkStrength = function(x) { | |
if (!arguments.length) return linkStrength; | |
linkStrength = typeof x === "function" ? x : +x; | |
return force; | |
}; | |
force.friction = function(x) { | |
if (!arguments.length) return friction; | |
friction = +x; | |
return force; | |
}; | |
force.charge = function(x) { | |
if (!arguments.length) return charge; | |
charge = typeof x === "function" ? x : +x; | |
return force; | |
}; | |
force.gravity = function(x) { | |
if (!arguments.length) return gravity; | |
gravity = +x; | |
return force; | |
}; | |
force.theta = function(x) { | |
if (!arguments.length) return theta; | |
theta = +x; | |
return force; | |
}; | |
force.alpha = function(x) { | |
if (!arguments.length) return alpha; | |
x = +x; | |
if (alpha) { | |
if (x > 0) alpha = x; else alpha = 0; | |
} else if (x > 0) { | |
event.start({ | |
type: "start", | |
alpha: alpha = x | |
}); | |
d3.timer(force.tick); | |
} | |
return force; | |
}; | |
force.start = function() { | |
var i, j, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; | |
for (i = 0; i < n; ++i) { | |
(o = nodes[i]).index = i; | |
o.weight = 0; | |
} | |
for (i = 0; i < m; ++i) { | |
o = links[i]; | |
if (typeof o.source == "number") o.source = nodes[o.source]; | |
if (typeof o.target == "number") o.target = nodes[o.target]; | |
++o.source.weight; | |
++o.target.weight; | |
} | |
for (i = 0; i < n; ++i) { | |
o = nodes[i]; | |
if (isNaN(o.x)) o.x = position("x", w); | |
if (isNaN(o.y)) o.y = position("y", h); | |
if (isNaN(o.px)) o.px = o.x; | |
if (isNaN(o.py)) o.py = o.y; | |
} | |
distances = []; | |
if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; | |
strengths = []; | |
if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; | |
charges = []; | |
if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; | |
function position(dimension, size) { | |
var neighbors = neighbor(i), j = -1, m = neighbors.length, x; | |
while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x; | |
return Math.random() * size; | |
} | |
function neighbor() { | |
if (!neighbors) { | |
neighbors = []; | |
for (j = 0; j < n; ++j) { | |
neighbors[j] = []; | |
} | |
for (j = 0; j < m; ++j) { | |
var o = links[j]; | |
neighbors[o.source.index].push(o.target); | |
neighbors[o.target.index].push(o.source); | |
} | |
} | |
return neighbors[i]; | |
} | |
return force.resume(); | |
}; | |
force.resume = function() { | |
return force.alpha(.1); | |
}; | |
force.stop = function() { | |
return force.alpha(0); | |
}; | |
force.drag = function() { | |
if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); | |
if (!arguments.length) return drag; | |
this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); | |
}; | |
function dragmove(d) { | |
d.px = d3.event.x, d.py = d3.event.y; | |
force.resume(); | |
} | |
return d3.rebind(force, event, "on"); | |
}; | |
function d3_layout_forceDragstart(d) { | |
d.fixed |= 2; | |
} | |
function d3_layout_forceDragend(d) { | |
d.fixed &= ~6; | |
} | |
function d3_layout_forceMouseover(d) { | |
d.fixed |= 4; | |
d.px = d.x, d.py = d.y; | |
} | |
function d3_layout_forceMouseout(d) { | |
d.fixed &= ~4; | |
} | |
function d3_layout_forceAccumulate(quad, alpha, charges) { | |
var cx = 0, cy = 0; | |
quad.charge = 0; | |
if (!quad.leaf) { | |
var nodes = quad.nodes, n = nodes.length, i = -1, c; | |
while (++i < n) { | |
c = nodes[i]; | |
if (c == null) continue; | |
d3_layout_forceAccumulate(c, alpha, charges); | |
quad.charge += c.charge; | |
cx += c.charge * c.cx; | |
cy += c.charge * c.cy; | |
} | |
} | |
if (quad.point) { | |
if (!quad.leaf) { | |
quad.point.x += Math.random() - .5; | |
quad.point.y += Math.random() - .5; | |
} | |
var k = alpha * charges[quad.point.index]; | |
quad.charge += quad.pointCharge = k; | |
cx += k * quad.point.x; | |
cy += k * quad.point.y; | |
} | |
quad.cx = cx / quad.charge; | |
quad.cy = cy / quad.charge; | |
} | |
var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1; | |
d3.layout.hierarchy = function() { | |
var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; | |
function recurse(node, depth, nodes) { | |
var childs = children.call(hierarchy, node, depth); | |
node.depth = depth; | |
nodes.push(node); | |
if (childs && (n = childs.length)) { | |
var i = -1, n, c = node.children = [], v = 0, j = depth + 1, d; | |
while (++i < n) { | |
d = recurse(childs[i], j, nodes); | |
d.parent = node; | |
c.push(d); | |
v += d.value; | |
} | |
if (sort) c.sort(sort); | |
if (value) node.value = v; | |
} else if (value) { | |
node.value = +value.call(hierarchy, node, depth) || 0; | |
} | |
return node; | |
} | |
function revalue(node, depth) { | |
var children = node.children, v = 0; | |
if (children && (n = children.length)) { | |
var i = -1, n, j = depth + 1; | |
while (++i < n) v += revalue(children[i], j); | |
} else if (value) { | |
v = +value.call(hierarchy, node, depth) || 0; | |
} | |
if (value) node.value = v; | |
return v; | |
} | |
function hierarchy(d) { | |
var nodes = []; | |
recurse(d, 0, nodes); | |
return nodes; | |
} | |
hierarchy.sort = function(x) { | |
if (!arguments.length) return sort; | |
sort = x; | |
return hierarchy; | |
}; | |
hierarchy.children = function(x) { | |
if (!arguments.length) return children; | |
children = x; | |
return hierarchy; | |
}; | |
hierarchy.value = function(x) { | |
if (!arguments.length) return value; | |
value = x; | |
return hierarchy; | |
}; | |
hierarchy.revalue = function(root) { | |
revalue(root, 0); | |
return root; | |
}; | |
return hierarchy; | |
}; | |
function d3_layout_hierarchyRebind(object, hierarchy) { | |
d3.rebind(object, hierarchy, "sort", "children", "value"); | |
object.nodes = object; | |
object.links = d3_layout_hierarchyLinks; | |
return object; | |
} | |
function d3_layout_hierarchyChildren(d) { | |
return d.children; | |
} | |
function d3_layout_hierarchyValue(d) { | |
return d.value; | |
} | |
function d3_layout_hierarchySort(a, b) { | |
return b.value - a.value; | |
} | |
function d3_layout_hierarchyLinks(nodes) { | |
return d3.merge(nodes.map(function(parent) { | |
return (parent.children || []).map(function(child) { | |
return { | |
source: parent, | |
target: child | |
}; | |
}); | |
})); | |
} | |
d3.layout.partition = function() { | |
var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; | |
function position(node, x, dx, dy) { | |
var children = node.children; | |
node.x = x; | |
node.y = node.depth * dy; | |
node.dx = dx; | |
node.dy = dy; | |
if (children && (n = children.length)) { | |
var i = -1, n, c, d; | |
dx = node.value ? dx / node.value : 0; | |
while (++i < n) { | |
position(c = children[i], x, d = c.value * dx, dy); | |
x += d; | |
} | |
} | |
} | |
function depth(node) { | |
var children = node.children, d = 0; | |
if (children && (n = children.length)) { | |
var i = -1, n; | |
while (++i < n) d = Math.max(d, depth(children[i])); | |
} | |
return 1 + d; | |
} | |
function partition(d, i) { | |
var nodes = hierarchy.call(this, d, i); | |
position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); | |
return nodes; | |
} | |
partition.size = function(x) { | |
if (!arguments.length) return size; | |
size = x; | |
return partition; | |
}; | |
return d3_layout_hierarchyRebind(partition, hierarchy); | |
}; | |
d3.layout.pie = function() { | |
var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = 2 * π; | |
function pie(data) { | |
var values = data.map(function(d, i) { | |
return +value.call(pie, d, i); | |
}); | |
var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle); | |
var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a) / d3.sum(values); | |
var index = d3.range(data.length); | |
if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { | |
return values[j] - values[i]; | |
} : function(i, j) { | |
return sort(data[i], data[j]); | |
}); | |
var arcs = []; | |
index.forEach(function(i) { | |
var d; | |
arcs[i] = { | |
data: data[i], | |
value: d = values[i], | |
startAngle: a, | |
endAngle: a += d * k | |
}; | |
}); | |
return arcs; | |
} | |
pie.value = function(x) { | |
if (!arguments.length) return value; | |
value = x; | |
return pie; | |
}; | |
pie.sort = function(x) { | |
if (!arguments.length) return sort; | |
sort = x; | |
return pie; | |
}; | |
pie.startAngle = function(x) { | |
if (!arguments.length) return startAngle; | |
startAngle = x; | |
return pie; | |
}; | |
pie.endAngle = function(x) { | |
if (!arguments.length) return endAngle; | |
endAngle = x; | |
return pie; | |
}; | |
return pie; | |
}; | |
var d3_layout_pieSortByValue = {}; | |
d3.layout.stack = function() { | |
var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; | |
function stack(data, index) { | |
var series = data.map(function(d, i) { | |
return values.call(stack, d, i); | |
}); | |
var points = series.map(function(d) { | |
return d.map(function(v, i) { | |
return [ x.call(stack, v, i), y.call(stack, v, i) ]; | |
}); | |
}); | |
var orders = order.call(stack, points, index); | |
series = d3.permute(series, orders); | |
points = d3.permute(points, orders); | |
var offsets = offset.call(stack, points, index); | |
var n = series.length, m = series[0].length, i, j, o; | |
for (j = 0; j < m; ++j) { | |
out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); | |
for (i = 1; i < n; ++i) { | |
out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); | |
} | |
} | |
return data; | |
} | |
stack.values = function(x) { | |
if (!arguments.length) return values; | |
values = x; | |
return stack; | |
}; | |
stack.order = function(x) { | |
if (!arguments.length) return order; | |
order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; | |
return stack; | |
}; | |
stack.offset = function(x) { | |
if (!arguments.length) return offset; | |
offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; | |
return stack; | |
}; | |
stack.x = function(z) { | |
if (!arguments.length) return x; | |
x = z; | |
return stack; | |
}; | |
stack.y = function(z) { | |
if (!arguments.length) return y; | |
y = z; | |
return stack; | |
}; | |
stack.out = function(z) { | |
if (!arguments.length) return out; | |
out = z; | |
return stack; | |
}; | |
return stack; | |
}; | |
function d3_layout_stackX(d) { | |
return d.x; | |
} | |
function d3_layout_stackY(d) { | |
return d.y; | |
} | |
function d3_layout_stackOut(d, y0, y) { | |
d.y0 = y0; | |
d.y = y; | |
} | |
var d3_layout_stackOrders = d3.map({ | |
"inside-out": function(data) { | |
var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { | |
return max[a] - max[b]; | |
}), top = 0, bottom = 0, tops = [], bottoms = []; | |
for (i = 0; i < n; ++i) { | |
j = index[i]; | |
if (top < bottom) { | |
top += sums[j]; | |
tops.push(j); | |
} else { | |
bottom += sums[j]; | |
bottoms.push(j); | |
} | |
} | |
return bottoms.reverse().concat(tops); | |
}, | |
reverse: function(data) { | |
return d3.range(data.length).reverse(); | |
}, | |
"default": d3_layout_stackOrderDefault | |
}); | |
var d3_layout_stackOffsets = d3.map({ | |
silhouette: function(data) { | |
var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; | |
for (j = 0; j < m; ++j) { | |
for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; | |
if (o > max) max = o; | |
sums.push(o); | |
} | |
for (j = 0; j < m; ++j) { | |
y0[j] = (max - sums[j]) / 2; | |
} | |
return y0; | |
}, | |
wiggle: function(data) { | |
var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; | |
y0[0] = o = o0 = 0; | |
for (j = 1; j < m; ++j) { | |
for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; | |
for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { | |
for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { | |
s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; | |
} | |
s2 += s3 * data[i][j][1]; | |
} | |
y0[j] = o -= s1 ? s2 / s1 * dx : 0; | |
if (o < o0) o0 = o; | |
} | |
for (j = 0; j < m; ++j) y0[j] -= o0; | |
return y0; | |
}, | |
expand: function(data) { | |
var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; | |
for (j = 0; j < m; ++j) { | |
for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; | |
if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; | |
} | |
for (j = 0; j < m; ++j) y0[j] = 0; | |
return y0; | |
}, | |
zero: d3_layout_stackOffsetZero | |
}); | |
function d3_layout_stackOrderDefault(data) { | |
return d3.range(data.length); | |
} | |
function d3_layout_stackOffsetZero(data) { | |
var j = -1, m = data[0].length, y0 = []; | |
while (++j < m) y0[j] = 0; | |
return y0; | |
} | |
function d3_layout_stackMaxIndex(array) { | |
var i = 1, j = 0, v = array[0][1], k, n = array.length; | |
for (;i < n; ++i) { | |
if ((k = array[i][1]) > v) { | |
j = i; | |
v = k; | |
} | |
} | |
return j; | |
} | |
function d3_layout_stackReduceSum(d) { | |
return d.reduce(d3_layout_stackSum, 0); | |
} | |
function d3_layout_stackSum(p, d) { | |
return p + d[1]; | |
} | |
d3.layout.histogram = function() { | |
var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; | |
function histogram(data, i) { | |
var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; | |
while (++i < m) { | |
bin = bins[i] = []; | |
bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); | |
bin.y = 0; | |
} | |
if (m > 0) { | |
i = -1; | |
while (++i < n) { | |
x = values[i]; | |
if (x >= range[0] && x <= range[1]) { | |
bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; | |
bin.y += k; | |
bin.push(data[i]); | |
} | |
} | |
} | |
return bins; | |
} | |
histogram.value = function(x) { | |
if (!arguments.length) return valuer; | |
valuer = x; | |
return histogram; | |
}; | |
histogram.range = function(x) { | |
if (!arguments.length) return ranger; | |
ranger = d3_functor(x); | |
return histogram; | |
}; | |
histogram.bins = function(x) { | |
if (!arguments.length) return binner; | |
binner = typeof x === "number" ? function(range) { | |
return d3_layout_histogramBinFixed(range, x); | |
} : d3_functor(x); | |
return histogram; | |
}; | |
histogram.frequency = function(x) { | |
if (!arguments.length) return frequency; | |
frequency = !!x; | |
return histogram; | |
}; | |
return histogram; | |
}; | |
function d3_layout_histogramBinSturges(range, values) { | |
return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); | |
} | |
function d3_layout_histogramBinFixed(range, n) { | |
var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; | |
while (++x <= n) f[x] = m * x + b; | |
return f; | |
} | |
function d3_layout_histogramRange(values) { | |
return [ d3.min(values), d3.max(values) ]; | |
} | |
d3.layout.tree = function() { | |
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; | |
function tree(d, i) { | |
var nodes = hierarchy.call(this, d, i), root = nodes[0]; | |
function firstWalk(node, previousSibling) { | |
var children = node.children, layout = node._tree; | |
if (children && (n = children.length)) { | |
var n, firstChild = children[0], previousChild, ancestor = firstChild, child, i = -1; | |
while (++i < n) { | |
child = children[i]; | |
firstWalk(child, previousChild); | |
ancestor = apportion(child, previousChild, ancestor); | |
previousChild = child; | |
} | |
d3_layout_treeShift(node); | |
var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); | |
if (previousSibling) { | |
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); | |
layout.mod = layout.prelim - midpoint; | |
} else { | |
layout.prelim = midpoint; | |
} | |
} else { | |
if (previousSibling) { | |
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); | |
} | |
} | |
} | |
function secondWalk(node, x) { | |
node.x = node._tree.prelim + x; | |
var children = node.children; | |
if (children && (n = children.length)) { | |
var i = -1, n; | |
x += node._tree.mod; | |
while (++i < n) { | |
secondWalk(children[i], x); | |
} | |
} | |
} | |
function apportion(node, previousSibling, ancestor) { | |
if (previousSibling) { | |
var vip = node, vop = node, vim = previousSibling, vom = node.parent.children[0], sip = vip._tree.mod, sop = vop._tree.mod, sim = vim._tree.mod, som = vom._tree.mod, shift; | |
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { | |
vom = d3_layout_treeLeft(vom); | |
vop = d3_layout_treeRight(vop); | |
vop._tree.ancestor = node; | |
shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); | |
if (shift > 0) { | |
d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); | |
sip += shift; | |
sop += shift; | |
} | |
sim += vim._tree.mod; | |
sip += vip._tree.mod; | |
som += vom._tree.mod; | |
sop += vop._tree.mod; | |
} | |
if (vim && !d3_layout_treeRight(vop)) { | |
vop._tree.thread = vim; | |
vop._tree.mod += sim - sop; | |
} | |
if (vip && !d3_layout_treeLeft(vom)) { | |
vom._tree.thread = vip; | |
vom._tree.mod += sip - som; | |
ancestor = node; | |
} | |
} | |
return ancestor; | |
} | |
d3_layout_treeVisitAfter(root, function(node, previousSibling) { | |
node._tree = { | |
ancestor: node, | |
prelim: 0, | |
mod: 0, | |
change: 0, | |
shift: 0, | |
number: previousSibling ? previousSibling._tree.number + 1 : 0 | |
}; | |
}); | |
firstWalk(root); | |
secondWalk(root, -root._tree.prelim); | |
var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), right = d3_layout_treeSearch(root, d3_layout_treeRightmost), deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2, y1 = deep.depth || 1; | |
d3_layout_treeVisitAfter(root, nodeSize ? function(node) { | |
node.x *= size[0]; | |
node.y = node.depth * size[1]; | |
delete node._tree; | |
} : function(node) { | |
node.x = (node.x - x0) / (x1 - x0) * size[0]; | |
node.y = node.depth / y1 * size[1]; | |
delete node._tree; | |
}); | |
return nodes; | |
} | |
tree.separation = function(x) { | |
if (!arguments.length) return separation; | |
separation = x; | |
return tree; | |
}; | |
tree.size = function(x) { | |
if (!arguments.length) return nodeSize ? null : size; | |
nodeSize = (size = x) == null; | |
return tree; | |
}; | |
tree.nodeSize = function(x) { | |
if (!arguments.length) return nodeSize ? size : null; | |
nodeSize = (size = x) != null; | |
return tree; | |
}; | |
return d3_layout_hierarchyRebind(tree, hierarchy); | |
}; | |
function d3_layout_treeSeparation(a, b) { | |
return a.parent == b.parent ? 1 : 2; | |
} | |
function d3_layout_treeLeft(node) { | |
var children = node.children; | |
return children && children.length ? children[0] : node._tree.thread; | |
} | |
function d3_layout_treeRight(node) { | |
var children = node.children, n; | |
return children && (n = children.length) ? children[n - 1] : node._tree.thread; | |
} | |
function d3_layout_treeSearch(node, compare) { | |
var children = node.children; | |
if (children && (n = children.length)) { | |
var child, n, i = -1; | |
while (++i < n) { | |
if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { | |
node = child; | |
} | |
} | |
} | |
return node; | |
} | |
function d3_layout_treeRightmost(a, b) { | |
return a.x - b.x; | |
} | |
function d3_layout_treeLeftmost(a, b) { | |
return b.x - a.x; | |
} | |
function d3_layout_treeDeepest(a, b) { | |
return a.depth - b.depth; | |
} | |
function d3_layout_treeVisitAfter(node, callback) { | |
function visit(node, previousSibling) { | |
var children = node.children; | |
if (children && (n = children.length)) { | |
var child, previousChild = null, i = -1, n; | |
while (++i < n) { | |
child = children[i]; | |
visit(child, previousChild); | |
previousChild = child; | |
} | |
} | |
callback(node, previousSibling); | |
} | |
visit(node, null); | |
} | |
function d3_layout_treeShift(node) { | |
var shift = 0, change = 0, children = node.children, i = children.length, child; | |
while (--i >= 0) { | |
child = children[i]._tree; | |
child.prelim += shift; | |
child.mod += shift; | |
shift += child.shift + (change += child.change); | |
} | |
} | |
function d3_layout_treeMove(ancestor, node, shift) { | |
ancestor = ancestor._tree; | |
node = node._tree; | |
var change = shift / (node.number - ancestor.number); | |
ancestor.change += change; | |
node.change -= change; | |
node.shift += shift; | |
node.prelim += shift; | |
node.mod += shift; | |
} | |
function d3_layout_treeAncestor(vim, node, ancestor) { | |
return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor; | |
} | |
d3.layout.pack = function() { | |
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; | |
function pack(d, i) { | |
var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { | |
return radius; | |
}; | |
root.x = root.y = 0; | |
d3_layout_treeVisitAfter(root, function(d) { | |
d.r = +r(d.value); | |
}); | |
d3_layout_treeVisitAfter(root, d3_layout_packSiblings); | |
if (padding) { | |
var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; | |
d3_layout_treeVisitAfter(root, function(d) { | |
d.r += dr; | |
}); | |
d3_layout_treeVisitAfter(root, d3_layout_packSiblings); | |
d3_layout_treeVisitAfter(root, function(d) { | |
d.r -= dr; | |
}); | |
} | |
d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); | |
return nodes; | |
} | |
pack.size = function(_) { | |
if (!arguments.length) return size; | |
size = _; | |
return pack; | |
}; | |
pack.radius = function(_) { | |
if (!arguments.length) return radius; | |
radius = _ == null || typeof _ === "function" ? _ : +_; | |
return pack; | |
}; | |
pack.padding = function(_) { | |
if (!arguments.length) return padding; | |
padding = +_; | |
return pack; | |
}; | |
return d3_layout_hierarchyRebind(pack, hierarchy); | |
}; | |
function d3_layout_packSort(a, b) { | |
return a.value - b.value; | |
} | |
function d3_layout_packInsert(a, b) { | |
var c = a._pack_next; | |
a._pack_next = b; | |
b._pack_prev = a; | |
b._pack_next = c; | |
c._pack_prev = b; | |
} | |
function d3_layout_packSplice(a, b) { | |
a._pack_next = b; | |
b._pack_prev = a; | |
} | |
function d3_layout_packIntersects(a, b) { | |
var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; | |
return .999 * dr * dr > dx * dx + dy * dy; | |
} | |
function d3_layout_packSiblings(node) { | |
if (!(nodes = node.children) || !(n = nodes.length)) return; | |
var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; | |
function bound(node) { | |
xMin = Math.min(node.x - node.r, xMin); | |
xMax = Math.max(node.x + node.r, xMax); | |
yMin = Math.min(node.y - node.r, yMin); | |
yMax = Math.max(node.y + node.r, yMax); | |
} | |
nodes.forEach(d3_layout_packLink); | |
a = nodes[0]; | |
a.x = -a.r; | |
a.y = 0; | |
bound(a); | |
if (n > 1) { | |
b = nodes[1]; | |
b.x = b.r; | |
b.y = 0; | |
bound(b); | |
if (n > 2) { | |
c = nodes[2]; | |
d3_layout_packPlace(a, b, c); | |
bound(c); | |
d3_layout_packInsert(a, c); | |
a._pack_prev = c; | |
d3_layout_packInsert(c, b); | |
b = a._pack_next; | |
for (i = 3; i < n; i++) { | |
d3_layout_packPlace(a, b, c = nodes[i]); | |
var isect = 0, s1 = 1, s2 = 1; | |
for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { | |
if (d3_layout_packIntersects(j, c)) { | |
isect = 1; | |
break; | |
} | |
} | |
if (isect == 1) { | |
for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { | |
if (d3_layout_packIntersects(k, c)) { | |
break; | |
} | |
} | |
} | |
if (isect) { | |
if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); | |
i--; | |
} else { | |
d3_layout_packInsert(a, c); | |
b = c; | |
bound(c); | |
} | |
} | |
} | |
} | |
var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; | |
for (i = 0; i < n; i++) { | |
c = nodes[i]; | |
c.x -= cx; | |
c.y -= cy; | |
cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); | |
} | |
node.r = cr; | |
nodes.forEach(d3_layout_packUnlink); | |
} | |
function d3_layout_packLink(node) { | |
node._pack_next = node._pack_prev = node; | |
} | |
function d3_layout_packUnlink(node) { | |
delete node._pack_next; | |
delete node._pack_prev; | |
} | |
function d3_layout_packTransform(node, x, y, k) { | |
var children = node.children; | |
node.x = x += k * node.x; | |
node.y = y += k * node.y; | |
node.r *= k; | |
if (children) { | |
var i = -1, n = children.length; | |
while (++i < n) d3_layout_packTransform(children[i], x, y, k); | |
} | |
} | |
function d3_layout_packPlace(a, b, c) { | |
var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; | |
if (db && (dx || dy)) { | |
var da = b.r + c.r, dc = dx * dx + dy * dy; | |
da *= da; | |
db *= db; | |
var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); | |
c.x = a.x + x * dx + y * dy; | |
c.y = a.y + x * dy - y * dx; | |
} else { | |
c.x = a.x + db; | |
c.y = a.y; | |
} | |
} | |
d3.layout.cluster = function() { | |
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; | |
function cluster(d, i) { | |
var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; | |
d3_layout_treeVisitAfter(root, function(node) { | |
var children = node.children; | |
if (children && children.length) { | |
node.x = d3_layout_clusterX(children); | |
node.y = d3_layout_clusterY(children); | |
} else { | |
node.x = previousNode ? x += separation(node, previousNode) : 0; | |
node.y = 0; | |
previousNode = node; | |
} | |
}); | |
var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; | |
d3_layout_treeVisitAfter(root, nodeSize ? function(node) { | |
node.x = (node.x - root.x) * size[0]; | |
node.y = (root.y - node.y) * size[1]; | |
} : function(node) { | |
node.x = (node.x - x0) / (x1 - x0) * size[0]; | |
node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; | |
}); | |
return nodes; | |
} | |
cluster.separation = function(x) { | |
if (!arguments.length) return separation; | |
separation = x; | |
return cluster; | |
}; | |
cluster.size = function(x) { | |
if (!arguments.length) return nodeSize ? null : size; | |
nodeSize = (size = x) == null; | |
return cluster; | |
}; | |
cluster.nodeSize = function(x) { | |
if (!arguments.length) return nodeSize ? size : null; | |
nodeSize = (size = x) != null; | |
return cluster; | |
}; | |
return d3_layout_hierarchyRebind(cluster, hierarchy); | |
}; | |
function d3_layout_clusterY(children) { | |
return 1 + d3.max(children, function(child) { | |
return child.y; | |
}); | |
} | |
function d3_layout_clusterX(children) { | |
return children.reduce(function(x, child) { | |
return x + child.x; | |
}, 0) / children.length; | |
} | |
function d3_layout_clusterLeft(node) { | |
var children = node.children; | |
return children && children.length ? d3_layout_clusterLeft(children[0]) : node; | |
} | |
function d3_layout_clusterRight(node) { | |
var children = node.children, n; | |
return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; | |
} | |
d3.layout.treemap = function() { | |
var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); | |
function scale(children, k) { | |
var i = -1, n = children.length, child, area; | |
while (++i < n) { | |
area = (child = children[i]).value * (k < 0 ? 0 : k); | |
child.area = isNaN(area) || area <= 0 ? 0 : area; | |
} | |
} | |
function squarify(node) { | |
var children = node.children; | |
if (children && children.length) { | |
var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; | |
scale(remaining, rect.dx * rect.dy / node.value); | |
row.area = 0; | |
while ((n = remaining.length) > 0) { | |
row.push(child = remaining[n - 1]); | |
row.area += child.area; | |
if (mode !== "squarify" || (score = worst(row, u)) <= best) { | |
remaining.pop(); | |
best = score; | |
} else { | |
row.area -= row.pop().area; | |
position(row, u, rect, false); | |
u = Math.min(rect.dx, rect.dy); | |
row.length = row.area = 0; | |
best = Infinity; | |
} | |
} | |
if (row.length) { | |
position(row, u, rect, true); | |
row.length = row.area = 0; | |
} | |
children.forEach(squarify); | |
} | |
} | |
function stickify(node) { | |
var children = node.children; | |
if (children && children.length) { | |
var rect = pad(node), remaining = children.slice(), child, row = []; | |
scale(remaining, rect.dx * rect.dy / node.value); | |
row.area = 0; | |
while (child = remaining.pop()) { | |
row.push(child); | |
row.area += child.area; | |
if (child.z != null) { | |
position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); | |
row.length = row.area = 0; | |
} | |
} | |
children.forEach(stickify); | |
} | |
} | |
function worst(row, u) { | |
var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; | |
while (++i < n) { | |
if (!(r = row[i].area)) continue; | |
if (r < rmin) rmin = r; | |
if (r > rmax) rmax = r; | |
} | |
s *= s; | |
u *= u; | |
return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; | |
} | |
function position(row, u, rect, flush) { | |
var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; | |
if (u == rect.dx) { | |
if (flush || v > rect.dy) v = rect.dy; | |
while (++i < n) { | |
o = row[i]; | |
o.x = x; | |
o.y = y; | |
o.dy = v; | |
x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); | |
} | |
o.z = true; | |
o.dx += rect.x + rect.dx - x; | |
rect.y += v; | |
rect.dy -= v; | |
} else { | |
if (flush || v > rect.dx) v = rect.dx; | |
while (++i < n) { | |
o = row[i]; | |
o.x = x; | |
o.y = y; | |
o.dx = v; | |
y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); | |
} | |
o.z = false; | |
o.dy += rect.y + rect.dy - y; | |
rect.x += v; | |
rect.dx -= v; | |
} | |
} | |
function treemap(d) { | |
var nodes = stickies || hierarchy(d), root = nodes[0]; | |
root.x = 0; | |
root.y = 0; | |
root.dx = size[0]; | |
root.dy = size[1]; | |
if (stickies) hierarchy.revalue(root); | |
scale([ root ], root.dx * root.dy / root.value); | |
(stickies ? stickify : squarify)(root); | |
if (sticky) stickies = nodes; | |
return nodes; | |
} | |
treemap.size = function(x) { | |
if (!arguments.length) return size; | |
size = x; | |
return treemap; | |
}; | |
treemap.padding = function(x) { | |
if (!arguments.length) return padding; | |
function padFunction(node) { | |
var p = x.call(treemap, node, node.depth); | |
return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); | |
} | |
function padConstant(node) { | |
return d3_layout_treemapPad(node, x); | |
} | |
var type; | |
pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], | |
padConstant) : padConstant; | |
return treemap; | |
}; | |
treemap.round = function(x) { | |
if (!arguments.length) return round != Number; | |
round = x ? Math.round : Number; | |
return treemap; | |
}; | |
treemap.sticky = function(x) { | |
if (!arguments.length) return sticky; | |
sticky = x; | |
stickies = null; | |
return treemap; | |
}; | |
treemap.ratio = function(x) { | |
if (!arguments.length) return ratio; | |
ratio = x; | |
return treemap; | |
}; | |
treemap.mode = function(x) { | |
if (!arguments.length) return mode; | |
mode = x + ""; | |
return treemap; | |
}; | |
return d3_layout_hierarchyRebind(treemap, hierarchy); | |
}; | |
function d3_layout_treemapPadNull(node) { | |
return { | |
x: node.x, | |
y: node.y, | |
dx: node.dx, | |
dy: node.dy | |
}; | |
} | |
function d3_layout_treemapPad(node, padding) { | |
var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; | |
if (dx < 0) { | |
x += dx / 2; | |
dx = 0; | |
} | |
if (dy < 0) { | |
y += dy / 2; | |
dy = 0; | |
} | |
return { | |
x: x, | |
y: y, | |
dx: dx, | |
dy: dy | |
}; | |
} | |
d3.random = { | |
normal: function(µ, σ) { | |
var n = arguments.length; | |
if (n < 2) σ = 1; | |
if (n < 1) µ = 0; | |
return function() { | |
var x, y, r; | |
do { | |
x = Math.random() * 2 - 1; | |
y = Math.random() * 2 - 1; | |
r = x * x + y * y; | |
} while (!r || r > 1); | |
return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); | |
}; | |
}, | |
logNormal: function() { | |
var random = d3.random.normal.apply(d3, arguments); | |
return function() { | |
return Math.exp(random()); | |
}; | |
}, | |
irwinHall: function(m) { | |
return function() { | |
for (var s = 0, j = 0; j < m; j++) s += Math.random(); | |
return s / m; | |
}; | |
} | |
}; | |
d3.scale = {}; | |
function d3_scaleExtent(domain) { | |
var start = domain[0], stop = domain[domain.length - 1]; | |
return start < stop ? [ start, stop ] : [ stop, start ]; | |
} | |
function d3_scaleRange(scale) { | |
return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); | |
} | |
function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { | |
var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); | |
return function(x) { | |
return i(u(x)); | |
}; | |
} | |
function d3_scale_nice(domain, nice) { | |
var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; | |
if (x1 < x0) { | |
dx = i0, i0 = i1, i1 = dx; | |
dx = x0, x0 = x1, x1 = dx; | |
} | |
domain[i0] = nice.floor(x0); | |
domain[i1] = nice.ceil(x1); | |
return domain; | |
} | |
function d3_scale_niceStep(step) { | |
return step ? { | |
floor: function(x) { | |
return Math.floor(x / step) * step; | |
}, | |
ceil: function(x) { | |
return Math.ceil(x / step) * step; | |
} | |
} : d3_scale_niceIdentity; | |
} | |
var d3_scale_niceIdentity = { | |
floor: d3_identity, | |
ceil: d3_identity | |
}; | |
function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { | |
var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; | |
if (domain[k] < domain[0]) { | |
domain = domain.slice().reverse(); | |
range = range.slice().reverse(); | |
} | |
while (++j <= k) { | |
u.push(uninterpolate(domain[j - 1], domain[j])); | |
i.push(interpolate(range[j - 1], range[j])); | |
} | |
return function(x) { | |
var j = d3.bisect(domain, x, 1, k) - 1; | |
return i[j](u[j](x)); | |
}; | |
} | |
d3.scale.linear = function() { | |
return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); | |
}; | |
function d3_scale_linear(domain, range, interpolate, clamp) { | |
var output, input; | |
function rescale() { | |
var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; | |
output = linear(domain, range, uninterpolate, interpolate); | |
input = linear(range, domain, uninterpolate, d3_interpolate); | |
return scale; | |
} | |
function scale(x) { | |
return output(x); | |
} | |
scale.invert = function(y) { | |
return input(y); | |
}; | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
domain = x.map(Number); | |
return rescale(); | |
}; | |
scale.range = function(x) { | |
if (!arguments.length) return range; | |
range = x; | |
return rescale(); | |
}; | |
scale.rangeRound = function(x) { | |
return scale.range(x).interpolate(d3_interpolateRound); | |
}; | |
scale.clamp = function(x) { | |
if (!arguments.length) return clamp; | |
clamp = x; | |
return rescale(); | |
}; | |
scale.interpolate = function(x) { | |
if (!arguments.length) return interpolate; | |
interpolate = x; | |
return rescale(); | |
}; | |
scale.ticks = function(m) { | |
return d3_scale_linearTicks(domain, m); | |
}; | |
scale.tickFormat = function(m, format) { | |
return d3_scale_linearTickFormat(domain, m, format); | |
}; | |
scale.nice = function(m) { | |
d3_scale_linearNice(domain, m); | |
return rescale(); | |
}; | |
scale.copy = function() { | |
return d3_scale_linear(domain, range, interpolate, clamp); | |
}; | |
return rescale(); | |
} | |
function d3_scale_linearRebind(scale, linear) { | |
return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); | |
} | |
function d3_scale_linearNice(domain, m) { | |
return d3_scale_nice(domain, d3_scale_niceStep(m ? d3_scale_linearTickRange(domain, m)[2] : d3_scale_linearNiceStep(domain))); | |
} | |
function d3_scale_linearNiceStep(domain) { | |
var extent = d3_scaleExtent(domain), span = extent[1] - extent[0]; | |
return Math.pow(10, Math.round(Math.log(span) / Math.LN10) - 1); | |
} | |
function d3_scale_linearTickRange(domain, m) { | |
var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; | |
if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; | |
extent[0] = Math.ceil(extent[0] / step) * step; | |
extent[1] = Math.floor(extent[1] / step) * step + step * .5; | |
extent[2] = step; | |
return extent; | |
} | |
function d3_scale_linearTicks(domain, m) { | |
return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); | |
} | |
function d3_scale_linearTickFormat(domain, m, format) { | |
var precision = -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01); | |
return d3.format(format ? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) { | |
return [ b, c, d, e, f, g, h, i || "." + (precision - (j === "%") * 2), j ].join(""); | |
}) : ",." + precision + "f"); | |
} | |
d3.scale.log = function() { | |
return d3_scale_log(d3.scale.linear().domain([ 0, Math.LN10 ]), 10, d3_scale_logp, d3_scale_powp, [ 1, 10 ]); | |
}; | |
function d3_scale_log(linear, base, log, pow, domain) { | |
function scale(x) { | |
return linear(log(x)); | |
} | |
scale.invert = function(x) { | |
return pow(linear.invert(x)); | |
}; | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
if (x[0] < 0) log = d3_scale_logn, pow = d3_scale_pown; else log = d3_scale_logp, | |
pow = d3_scale_powp; | |
linear.domain((domain = x.map(Number)).map(log)); | |
return scale; | |
}; | |
scale.base = function(_) { | |
if (!arguments.length) return base; | |
base = +_; | |
return scale; | |
}; | |
scale.nice = function() { | |
function floor(x) { | |
return Math.pow(base, Math.floor(Math.log(x) / Math.log(base))); | |
} | |
function ceil(x) { | |
return Math.pow(base, Math.ceil(Math.log(x) / Math.log(base))); | |
} | |
linear.domain(d3_scale_nice(domain, log === d3_scale_logp ? { | |
floor: floor, | |
ceil: ceil | |
} : { | |
floor: function(x) { | |
return -ceil(-x); | |
}, | |
ceil: function(x) { | |
return -floor(-x); | |
} | |
}).map(log)); | |
return scale; | |
}; | |
scale.ticks = function() { | |
var extent = d3_scaleExtent(linear.domain()), ticks = []; | |
if (extent.every(isFinite)) { | |
var b = Math.log(base), i = Math.floor(extent[0] / b), j = Math.ceil(extent[1] / b), u = pow(extent[0]), v = pow(extent[1]), n = base % 1 ? 2 : base; | |
if (log === d3_scale_logn) { | |
ticks.push(-Math.pow(base, -i)); | |
for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(-Math.pow(base, -i) * k); | |
} else { | |
for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(Math.pow(base, i) * k); | |
ticks.push(Math.pow(base, i)); | |
} | |
for (i = 0; ticks[i] < u; i++) {} | |
for (j = ticks.length; ticks[j - 1] > v; j--) {} | |
ticks = ticks.slice(i, j); | |
} | |
return ticks; | |
}; | |
scale.tickFormat = function(n, format) { | |
if (!arguments.length) return d3_scale_logFormat; | |
if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); | |
var b = Math.log(base), k = Math.max(.1, n / scale.ticks().length), f = log === d3_scale_logn ? (e = -1e-12, | |
Math.floor) : (e = 1e-12, Math.ceil), e; | |
return function(d) { | |
return d / pow(b * f(log(d) / b + e)) <= k ? format(d) : ""; | |
}; | |
}; | |
scale.copy = function() { | |
return d3_scale_log(linear.copy(), base, log, pow, domain); | |
}; | |
return d3_scale_linearRebind(scale, linear); | |
} | |
var d3_scale_logFormat = d3.format(".0e"); | |
function d3_scale_logp(x) { | |
return Math.log(x < 0 ? 0 : x); | |
} | |
function d3_scale_powp(x) { | |
return Math.exp(x); | |
} | |
function d3_scale_logn(x) { | |
return -Math.log(x > 0 ? 0 : -x); | |
} | |
function d3_scale_pown(x) { | |
return -Math.exp(-x); | |
} | |
d3.scale.pow = function() { | |
return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); | |
}; | |
function d3_scale_pow(linear, exponent, domain) { | |
var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); | |
function scale(x) { | |
return linear(powp(x)); | |
} | |
scale.invert = function(x) { | |
return powb(linear.invert(x)); | |
}; | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
linear.domain((domain = x.map(Number)).map(powp)); | |
return scale; | |
}; | |
scale.ticks = function(m) { | |
return d3_scale_linearTicks(domain, m); | |
}; | |
scale.tickFormat = function(m, format) { | |
return d3_scale_linearTickFormat(domain, m, format); | |
}; | |
scale.nice = function(m) { | |
return scale.domain(d3_scale_linearNice(domain, m)); | |
}; | |
scale.exponent = function(x) { | |
if (!arguments.length) return exponent; | |
powp = d3_scale_powPow(exponent = x); | |
powb = d3_scale_powPow(1 / exponent); | |
linear.domain(domain.map(powp)); | |
return scale; | |
}; | |
scale.copy = function() { | |
return d3_scale_pow(linear.copy(), exponent, domain); | |
}; | |
return d3_scale_linearRebind(scale, linear); | |
} | |
function d3_scale_powPow(e) { | |
return function(x) { | |
return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); | |
}; | |
} | |
d3.scale.sqrt = function() { | |
return d3.scale.pow().exponent(.5); | |
}; | |
d3.scale.ordinal = function() { | |
return d3_scale_ordinal([], { | |
t: "range", | |
a: [ [] ] | |
}); | |
}; | |
function d3_scale_ordinal(domain, ranger) { | |
var index, range, rangeBand; | |
function scale(x) { | |
return range[((index.get(x) || index.set(x, domain.push(x))) - 1) % range.length]; | |
} | |
function steps(start, step) { | |
return d3.range(domain.length).map(function(i) { | |
return start + step * i; | |
}); | |
} | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
domain = []; | |
index = new d3_Map(); | |
var i = -1, n = x.length, xi; | |
while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); | |
return scale[ranger.t].apply(scale, ranger.a); | |
}; | |
scale.range = function(x) { | |
if (!arguments.length) return range; | |
range = x; | |
rangeBand = 0; | |
ranger = { | |
t: "range", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangePoints = function(x, padding) { | |
if (arguments.length < 2) padding = 0; | |
var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding); | |
range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); | |
rangeBand = 0; | |
ranger = { | |
t: "rangePoints", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangeBands = function(x, padding, outerPadding) { | |
if (arguments.length < 2) padding = 0; | |
if (arguments.length < 3) outerPadding = padding; | |
var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); | |
range = steps(start + step * outerPadding, step); | |
if (reverse) range.reverse(); | |
rangeBand = step * (1 - padding); | |
ranger = { | |
t: "rangeBands", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangeRoundBands = function(x, padding, outerPadding) { | |
if (arguments.length < 2) padding = 0; | |
if (arguments.length < 3) outerPadding = padding; | |
var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step; | |
range = steps(start + Math.round(error / 2), step); | |
if (reverse) range.reverse(); | |
rangeBand = Math.round(step * (1 - padding)); | |
ranger = { | |
t: "rangeRoundBands", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangeBand = function() { | |
return rangeBand; | |
}; | |
scale.rangeExtent = function() { | |
return d3_scaleExtent(ranger.a[0]); | |
}; | |
scale.copy = function() { | |
return d3_scale_ordinal(domain, ranger); | |
}; | |
return scale.domain(domain); | |
} | |
d3.scale.category10 = function() { | |
return d3.scale.ordinal().range(d3_category10); | |
}; | |
d3.scale.category20 = function() { | |
return d3.scale.ordinal().range(d3_category20); | |
}; | |
d3.scale.category20b = function() { | |
return d3.scale.ordinal().range(d3_category20b); | |
}; | |
d3.scale.category20c = function() { | |
return d3.scale.ordinal().range(d3_category20c); | |
}; | |
var d3_category10 = [ "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf" ]; | |
var d3_category20 = [ "#1f77b4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c", "#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5", "#8c564b", "#c49c94", "#e377c2", "#f7b6d2", "#7f7f7f", "#c7c7c7", "#bcbd22", "#dbdb8d", "#17becf", "#9edae5" ]; | |
var d3_category20b = [ "#393b79", "#5254a3", "#6b6ecf", "#9c9ede", "#637939", "#8ca252", "#b5cf6b", "#cedb9c", "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94", "#843c39", "#ad494a", "#d6616b", "#e7969c", "#7b4173", "#a55194", "#ce6dbd", "#de9ed6" ]; | |
var d3_category20c = [ "#3182bd", "#6baed6", "#9ecae1", "#c6dbef", "#e6550d", "#fd8d3c", "#fdae6b", "#fdd0a2", "#31a354", "#74c476", "#a1d99b", "#c7e9c0", "#756bb1", "#9e9ac8", "#bcbddc", "#dadaeb", "#636363", "#969696", "#bdbdbd", "#d9d9d9" ]; | |
d3.scale.quantile = function() { | |
return d3_scale_quantile([], []); | |
}; | |
function d3_scale_quantile(domain, range) { | |
var thresholds; | |
function rescale() { | |
var k = 0, q = range.length; | |
thresholds = []; | |
while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); | |
return scale; | |
} | |
function scale(x) { | |
if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; | |
} | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
domain = x.filter(function(d) { | |
return !isNaN(d); | |
}).sort(d3.ascending); | |
return rescale(); | |
}; | |
scale.range = function(x) { | |
if (!arguments.length) return range; | |
range = x; | |
return rescale(); | |
}; | |
scale.quantiles = function() { | |
return thresholds; | |
}; | |
scale.invertExtent = function(y) { | |
y = range.indexOf(y); | |
return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; | |
}; | |
scale.copy = function() { | |
return d3_scale_quantile(domain, range); | |
}; | |
return rescale(); | |
} | |
d3.scale.quantize = function() { | |
return d3_scale_quantize(0, 1, [ 0, 1 ]); | |
}; | |
function d3_scale_quantize(x0, x1, range) { | |
var kx, i; | |
function scale(x) { | |
return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; | |
} | |
function rescale() { | |
kx = range.length / (x1 - x0); | |
i = range.length - 1; | |
return scale; | |
} | |
scale.domain = function(x) { | |
if (!arguments.length) return [ x0, x1 ]; | |
x0 = +x[0]; | |
x1 = +x[x.length - 1]; | |
return rescale(); | |
}; | |
scale.range = function(x) { | |
if (!arguments.length) return range; | |
range = x; | |
return rescale(); | |
}; | |
scale.invertExtent = function(y) { | |
y = range.indexOf(y); | |
y = y < 0 ? NaN : y / kx + x0; | |
return [ y, y + 1 / kx ]; | |
}; | |
scale.copy = function() { | |
return d3_scale_quantize(x0, x1, range); | |
}; | |
return rescale(); | |
} | |
d3.scale.threshold = function() { | |
return d3_scale_threshold([ .5 ], [ 0, 1 ]); | |
}; | |
function d3_scale_threshold(domain, range) { | |
function scale(x) { | |
if (x <= x) return range[d3.bisect(domain, x)]; | |
} | |
scale.domain = function(_) { | |
if (!arguments.length) return domain; | |
domain = _; | |
return scale; | |
}; | |
scale.range = function(_) { | |
if (!arguments.length) return range; | |
range = _; | |
return scale; | |
}; | |
scale.invertExtent = function(y) { | |
y = range.indexOf(y); | |
return [ domain[y - 1], domain[y] ]; | |
}; | |
scale.copy = function() { | |
return d3_scale_threshold(domain, range); | |
}; | |
return scale; | |
} | |
d3.scale.identity = function() { | |
return d3_scale_identity([ 0, 1 ]); | |
}; | |
function d3_scale_identity(domain) { | |
function identity(x) { | |
return +x; | |
} | |
identity.invert = identity; | |
identity.domain = identity.range = function(x) { | |
if (!arguments.length) return domain; | |
domain = x.map(identity); | |
return identity; | |
}; | |
identity.ticks = function(m) { | |
return d3_scale_linearTicks(domain, m); | |
}; | |
identity.tickFormat = function(m, format) { | |
return d3_scale_linearTickFormat(domain, m, format); | |
}; | |
identity.copy = function() { | |
return d3_scale_identity(domain); | |
}; | |
return identity; | |
} | |
d3.svg.arc = function() { | |
var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; | |
function arc() { | |
var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0, | |
a0 = a1, a1 = da), a1 - a0), df = da < π ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1); | |
return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z"; | |
} | |
arc.innerRadius = function(v) { | |
if (!arguments.length) return innerRadius; | |
innerRadius = d3_functor(v); | |
return arc; | |
}; | |
arc.outerRadius = function(v) { | |
if (!arguments.length) return outerRadius; | |
outerRadius = d3_functor(v); | |
return arc; | |
}; | |
arc.startAngle = function(v) { | |
if (!arguments.length) return startAngle; | |
startAngle = d3_functor(v); | |
return arc; | |
}; | |
arc.endAngle = function(v) { | |
if (!arguments.length) return endAngle; | |
endAngle = d3_functor(v); | |
return arc; | |
}; | |
arc.centroid = function() { | |
var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; | |
return [ Math.cos(a) * r, Math.sin(a) * r ]; | |
}; | |
return arc; | |
}; | |
var d3_svg_arcOffset = -π / 2, d3_svg_arcMax = 2 * π - 1e-6; | |
function d3_svg_arcInnerRadius(d) { | |
return d.innerRadius; | |
} | |
function d3_svg_arcOuterRadius(d) { | |
return d.outerRadius; | |
} | |
function d3_svg_arcStartAngle(d) { | |
return d.startAngle; | |
} | |
function d3_svg_arcEndAngle(d) { | |
return d.endAngle; | |
} | |
d3.svg.line.radial = function() { | |
var line = d3_svg_line(d3_svg_lineRadial); | |
line.radius = line.x, delete line.x; | |
line.angle = line.y, delete line.y; | |
return line; | |
}; | |
function d3_svg_lineRadial(points) { | |
var point, i = -1, n = points.length, r, a; | |
while (++i < n) { | |
point = points[i]; | |
r = point[0]; | |
a = point[1] + d3_svg_arcOffset; | |
point[0] = r * Math.cos(a); | |
point[1] = r * Math.sin(a); | |
} | |
return points; | |
} | |
function d3_svg_area(projection) { | |
var x0 = d3_svg_lineX, x1 = d3_svg_lineX, y0 = 0, y1 = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; | |
function area(data) { | |
var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { | |
return x; | |
} : d3_functor(x1), fy1 = y0 === y1 ? function() { | |
return y; | |
} : d3_functor(y1), x, y; | |
function segment() { | |
segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); | |
} | |
while (++i < n) { | |
if (defined.call(this, d = data[i], i)) { | |
points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); | |
points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); | |
} else if (points0.length) { | |
segment(); | |
points0 = []; | |
points1 = []; | |
} | |
} | |
if (points0.length) segment(); | |
return segments.length ? segments.join("") : null; | |
} | |
area.x = function(_) { | |
if (!arguments.length) return x1; | |
x0 = x1 = _; | |
return area; | |
}; | |
area.x0 = function(_) { | |
if (!arguments.length) return x0; | |
x0 = _; | |
return area; | |
}; | |
area.x1 = function(_) { | |
if (!arguments.length) return x1; | |
x1 = _; | |
return area; | |
}; | |
area.y = function(_) { | |
if (!arguments.length) return y1; | |
y0 = y1 = _; | |
return area; | |
}; | |
area.y0 = function(_) { | |
if (!arguments.length) return y0; | |
y0 = _; | |
return area; | |
}; | |
area.y1 = function(_) { | |
if (!arguments.length) return y1; | |
y1 = _; | |
return area; | |
}; | |
area.defined = function(_) { | |
if (!arguments.length) return defined; | |
defined = _; | |
return area; | |
}; | |
area.interpolate = function(_) { | |
if (!arguments.length) return interpolateKey; | |
if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; | |
interpolateReverse = interpolate.reverse || interpolate; | |
L = interpolate.closed ? "M" : "L"; | |
return area; | |
}; | |
area.tension = function(_) { | |
if (!arguments.length) return tension; | |
tension = _; | |
return area; | |
}; | |
return area; | |
} | |
d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; | |
d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; | |
d3.svg.area = function() { | |
return d3_svg_area(d3_identity); | |
}; | |
d3.svg.area.radial = function() { | |
var area = d3_svg_area(d3_svg_lineRadial); | |
area.radius = area.x, delete area.x; | |
area.innerRadius = area.x0, delete area.x0; | |
area.outerRadius = area.x1, delete area.x1; | |
area.angle = area.y, delete area.y; | |
area.startAngle = area.y0, delete area.y0; | |
area.endAngle = area.y1, delete area.y1; | |
return area; | |
}; | |
d3.svg.chord = function() { | |
var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; | |
function chord(d, i) { | |
var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); | |
return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; | |
} | |
function subgroup(self, f, d, i) { | |
var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; | |
return { | |
r: r, | |
a0: a0, | |
a1: a1, | |
p0: [ r * Math.cos(a0), r * Math.sin(a0) ], | |
p1: [ r * Math.cos(a1), r * Math.sin(a1) ] | |
}; | |
} | |
function equals(a, b) { | |
return a.a0 == b.a0 && a.a1 == b.a1; | |
} | |
function arc(r, p, a) { | |
return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; | |
} | |
function curve(r0, p0, r1, p1) { | |
return "Q 0,0 " + p1; | |
} | |
chord.radius = function(v) { | |
if (!arguments.length) return radius; | |
radius = d3_functor(v); | |
return chord; | |
}; | |
chord.source = function(v) { | |
if (!arguments.length) return source; | |
source = d3_functor(v); | |
return chord; | |
}; | |
chord.target = function(v) { | |
if (!arguments.length) return target; | |
target = d3_functor(v); | |
return chord; | |
}; | |
chord.startAngle = function(v) { | |
if (!arguments.length) return startAngle; | |
startAngle = d3_functor(v); | |
return chord; | |
}; | |
chord.endAngle = function(v) { | |
if (!arguments.length) return endAngle; | |
endAngle = d3_functor(v); | |
return chord; | |
}; | |
return chord; | |
}; | |
function d3_svg_chordRadius(d) { | |
return d.radius; | |
} | |
d3.svg.diagonal = function() { | |
var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; | |
function diagonal(d, i) { | |
var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { | |
x: p0.x, | |
y: m | |
}, { | |
x: p3.x, | |
y: m | |
}, p3 ]; | |
p = p.map(projection); | |
return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; | |
} | |
diagonal.source = function(x) { | |
if (!arguments.length) return source; | |
source = d3_functor(x); | |
return diagonal; | |
}; | |
diagonal.target = function(x) { | |
if (!arguments.length) return target; | |
target = d3_functor(x); | |
return diagonal; | |
}; | |
diagonal.projection = function(x) { | |
if (!arguments.length) return projection; | |
projection = x; | |
return diagonal; | |
}; | |
return diagonal; | |
}; | |
function d3_svg_diagonalProjection(d) { | |
return [ d.x, d.y ]; | |
} | |
d3.svg.diagonal.radial = function() { | |
var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; | |
diagonal.projection = function(x) { | |
return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; | |
}; | |
return diagonal; | |
}; | |
function d3_svg_diagonalRadialProjection(projection) { | |
return function() { | |
var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset; | |
return [ r * Math.cos(a), r * Math.sin(a) ]; | |
}; | |
} | |
d3.svg.symbol = function() { | |
var type = d3_svg_symbolType, size = d3_svg_symbolSize; | |
function symbol(d, i) { | |
return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); | |
} | |
symbol.type = function(x) { | |
if (!arguments.length) return type; | |
type = d3_functor(x); | |
return symbol; | |
}; | |
symbol.size = function(x) { | |
if (!arguments.length) return size; | |
size = d3_functor(x); | |
return symbol; | |
}; | |
return symbol; | |
}; | |
function d3_svg_symbolSize() { | |
return 64; | |
} | |
function d3_svg_symbolType() { | |
return "circle"; | |
} | |
function d3_svg_symbolCircle(size) { | |
var r = Math.sqrt(size / π); | |
return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; | |
} | |
var d3_svg_symbols = d3.map({ | |
circle: d3_svg_symbolCircle, | |
cross: function(size) { | |
var r = Math.sqrt(size / 5) / 2; | |
return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; | |
}, | |
diamond: function(size) { | |
var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; | |
return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; | |
}, | |
square: function(size) { | |
var r = Math.sqrt(size) / 2; | |
return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; | |
}, | |
"triangle-down": function(size) { | |
var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; | |
return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; | |
}, | |
"triangle-up": function(size) { | |
var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; | |
return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; | |
} | |
}); | |
d3.svg.symbolTypes = d3_svg_symbols.keys(); | |
var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); | |
function d3_transition(groups, id) { | |
d3_subclass(groups, d3_transitionPrototype); | |
groups.id = id; | |
return groups; | |
} | |
var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; | |
d3_transitionPrototype.call = d3_selectionPrototype.call; | |
d3_transitionPrototype.empty = d3_selectionPrototype.empty; | |
d3_transitionPrototype.node = d3_selectionPrototype.node; | |
d3_transitionPrototype.size = d3_selectionPrototype.size; | |
d3.transition = function(selection) { | |
return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition(); | |
}; | |
d3.transition.prototype = d3_transitionPrototype; | |
d3_transitionPrototype.select = function(selector) { | |
var id = this.id, subgroups = [], subgroup, subnode, node; | |
selector = d3_selection_selector(selector); | |
for (var j = -1, m = this.length; ++j < m; ) { | |
subgroups.push(subgroup = []); | |
for (var group = this[j], i = -1, n = group.length; ++i < n; ) { | |
if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { | |
if ("__data__" in node) subnode.__data__ = node.__data__; | |
d3_transitionNode(subnode, i, id, node.__transition__[id]); | |
subgroup.push(subnode); | |
} else { | |
subgroup.push(null); | |
} | |
} | |
} | |
return d3_transition(subgroups, id); | |
}; | |
d3_transitionPrototype.selectAll = function(selector) { | |
var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition; | |
selector = d3_selection_selectorAll(selector); | |
for (var j = -1, m = this.length; ++j < m; ) { | |
for (var group = this[j], i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) { | |
transition = node.__transition__[id]; | |
subnodes = selector.call(node, node.__data__, i, j); | |
subgroups.push(subgroup = []); | |
for (var k = -1, o = subnodes.length; ++k < o; ) { | |
if (subnode = subnodes[k]) d3_transitionNode(subnode, k, id, transition); | |
subgroup.push(subnode); | |
} | |
} | |
} | |
} | |
return d3_transition(subgroups, id); | |
}; | |
d3_transitionPrototype.filter = function(filter) { | |
var subgroups = [], subgroup, group, node; | |
if (typeof filter !== "function") filter = d3_selection_filter(filter); | |
for (var j = 0, m = this.length; j < m; j++) { | |
subgroups.push(subgroup = []); | |
for (var group = this[j], i = 0, n = group.length; i < n; i++) { | |
if ((node = group[i]) && filter.call(node, node.__data__, i)) { | |
subgroup.push(node); | |
} | |
} | |
} | |
return d3_transition(subgroups, this.id, this.time).ease(this.ease()); | |
}; | |
d3_transitionPrototype.tween = function(name, tween) { | |
var id = this.id; | |
if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); | |
return d3_selection_each(this, tween == null ? function(node) { | |
node.__transition__[id].tween.remove(name); | |
} : function(node) { | |
node.__transition__[id].tween.set(name, tween); | |
}); | |
}; | |
function d3_transition_tween(groups, name, value, tween) { | |
var id = groups.id; | |
return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { | |
node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); | |
} : (value = tween(value), function(node) { | |
node.__transition__[id].tween.set(name, value); | |
})); | |
} | |
d3_transitionPrototype.attr = function(nameNS, value) { | |
if (arguments.length < 2) { | |
for (value in nameNS) this.attr(value, nameNS[value]); | |
return this; | |
} | |
var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); | |
function attrNull() { | |
this.removeAttribute(name); | |
} | |
function attrNullNS() { | |
this.removeAttributeNS(name.space, name.local); | |
} | |
function attrTween(b) { | |
return b == null ? attrNull : (b += "", function() { | |
var a = this.getAttribute(name), i; | |
return a !== b && (i = interpolate(a, b), function(t) { | |
this.setAttribute(name, i(t)); | |
}); | |
}); | |
} | |
function attrTweenNS(b) { | |
return b == null ? attrNullNS : (b += "", function() { | |
var a = this.getAttributeNS(name.space, name.local), i; | |
return a !== b && (i = interpolate(a, b), function(t) { | |
this.setAttributeNS(name.space, name.local, i(t)); | |
}); | |
}); | |
} | |
return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); | |
}; | |
d3_transitionPrototype.attrTween = function(nameNS, tween) { | |
var name = d3.ns.qualify(nameNS); | |
function attrTween(d, i) { | |
var f = tween.call(this, d, i, this.getAttribute(name)); | |
return f && function(t) { | |
this.setAttribute(name, f(t)); | |
}; | |
} | |
function attrTweenNS(d, i) { | |
var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); | |
return f && function(t) { | |
this.setAttributeNS(name.space, name.local, f(t)); | |
}; | |
} | |
return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); | |
}; | |
d3_transitionPrototype.style = function(name, value, priority) { | |
var n = arguments.length; | |
if (n < 3) { | |
if (typeof name !== "string") { | |
if (n < 2) value = ""; | |
for (priority in name) this.style(priority, name[priority], value); | |
return this; | |
} | |
priority = ""; | |
} | |
function styleNull() { | |
this.style.removeProperty(name); | |
} | |
function styleString(b) { | |
return b == null ? styleNull : (b += "", function() { | |
var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; | |
return a !== b && (i = d3_interpolate(a, b), function(t) { | |
this.style.setProperty(name, i(t), priority); | |
}); | |
}); | |
} | |
return d3_transition_tween(this, "style." + name, value, styleString); | |
}; | |
d3_transitionPrototype.styleTween = function(name, tween, priority) { | |
if (arguments.length < 3) priority = ""; | |
function styleTween(d, i) { | |
var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); | |
return f && function(t) { | |
this.style.setProperty(name, f(t), priority); | |
}; | |
} | |
return this.tween("style." + name, styleTween); | |
}; | |
d3_transitionPrototype.text = function(value) { | |
return d3_transition_tween(this, "text", value, d3_transition_text); | |
}; | |
function d3_transition_text(b) { | |
if (b == null) b = ""; | |
return function() { | |
this.textContent = b; | |
}; | |
} | |
d3_transitionPrototype.remove = function() { | |
return this.each("end.transition", function() { | |
var p; | |
if (!this.__transition__ && (p = this.parentNode)) p.removeChild(this); | |
}); | |
}; | |
d3_transitionPrototype.ease = function(value) { | |
var id = this.id; | |
if (arguments.length < 1) return this.node().__transition__[id].ease; | |
if (typeof value !== "function") value = d3.ease.apply(d3, arguments); | |
return d3_selection_each(this, function(node) { | |
node.__transition__[id].ease = value; | |
}); | |
}; | |
d3_transitionPrototype.delay = function(value) { | |
var id = this.id; | |
return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { | |
node.__transition__[id].delay = value.call(node, node.__data__, i, j) | 0; | |
} : (value |= 0, function(node) { | |
node.__transition__[id].delay = value; | |
})); | |
}; | |
d3_transitionPrototype.duration = function(value) { | |
var id = this.id; | |
return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { | |
node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j) | 0); | |
} : (value = Math.max(1, value | 0), function(node) { | |
node.__transition__[id].duration = value; | |
})); | |
}; | |
d3_transitionPrototype.each = function(type, listener) { | |
var id = this.id; | |
if (arguments.length < 2) { | |
var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; | |
d3_transitionInheritId = id; | |
d3_selection_each(this, function(node, i, j) { | |
d3_transitionInherit = node.__transition__[id]; | |
type.call(node, node.__data__, i, j); | |
}); | |
d3_transitionInherit = inherit; | |
d3_transitionInheritId = inheritId; | |
} else { | |
d3_selection_each(this, function(node) { | |
var transition = node.__transition__[id]; | |
(transition.event || (transition.event = d3.dispatch("start", "end"))).on(type, listener); | |
}); | |
} | |
return this; | |
}; | |
d3_transitionPrototype.transition = function() { | |
var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition; | |
for (var j = 0, m = this.length; j < m; j++) { | |
subgroups.push(subgroup = []); | |
for (var group = this[j], i = 0, n = group.length; i < n; i++) { | |
if (node = group[i]) { | |
transition = Object.create(node.__transition__[id0]); | |
transition.delay += transition.duration; | |
d3_transitionNode(node, i, id1, transition); | |
} | |
subgroup.push(node); | |
} | |
} | |
return d3_transition(subgroups, id1); | |
}; | |
function d3_transitionNode(node, i, id, inherit) { | |
var lock = node.__transition__ || (node.__transition__ = { | |
active: 0, | |
count: 0 | |
}), transition = lock[id]; | |
if (!transition) { | |
var time = inherit.time; | |
transition = lock[id] = { | |
tween: new d3_Map(), | |
time: time, | |
ease: inherit.ease, | |
delay: inherit.delay, | |
duration: inherit.duration | |
}; | |
++lock.count; | |
d3.timer(function(elapsed) { | |
var d = node.__data__, ease = transition.ease, delay = transition.delay, duration = transition.duration, tweened = []; | |
return delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time), 1; | |
function start(elapsed) { | |
if (lock.active > id) return stop(); | |
lock.active = id; | |
transition.event && transition.event.start.call(node, d, i); | |
transition.tween.forEach(function(key, value) { | |
if (value = value.call(node, d, i)) { | |
tweened.push(value); | |
} | |
}); | |
if (!tick(elapsed)) d3.timer(tick, 0, time); | |
return 1; | |
} | |
function tick(elapsed) { | |
if (lock.active !== id) return stop(); | |
var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length; | |
while (n > 0) { | |
tweened[--n].call(node, e); | |
} | |
if (t >= 1) { | |
stop(); | |
transition.event && transition.event.end.call(node, d, i); | |
return 1; | |
} | |
} | |
function stop() { | |
if (--lock.count) delete lock[id]; else delete node.__transition__; | |
return 1; | |
} | |
}, 0, time); | |
return transition; | |
} | |
} | |
d3.svg.axis = function() { | |
var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, tickMajorSize = 6, tickMinorSize = 6, tickEndSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_, tickSubdivide = 0; | |
function axis(g) { | |
g.each(function() { | |
var g = d3.select(this); | |
var ticks = tickValues == null ? scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain() : tickValues, tickFormat = tickFormat_ == null ? scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String : tickFormat_; | |
var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide), subtick = g.selectAll(".tick.minor").data(subticks, String), subtickEnter = subtick.enter().insert("line", ".tick").attr("class", "tick minor").style("opacity", 1e-6), subtickExit = d3.transition(subtick.exit()).style("opacity", 1e-6).remove(), subtickUpdate = d3.transition(subtick).style("opacity", 1); | |
var tick = g.selectAll(".tick.major").data(ticks, String), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick major").style("opacity", 1e-6), tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(), tickUpdate = d3.transition(tick).style("opacity", 1), tickTransform; | |
var range = d3_scaleRange(scale), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), | |
d3.transition(path)); | |
var scale1 = scale.copy(), scale0 = this.__chart__ || scale1; | |
this.__chart__ = scale1; | |
tickEnter.append("line"); | |
tickEnter.append("text"); | |
var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); | |
switch (orient) { | |
case "bottom": | |
{ | |
tickTransform = d3_svg_axisX; | |
subtickEnter.attr("y2", tickMinorSize); | |
subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize); | |
lineEnter.attr("y2", tickMajorSize); | |
textEnter.attr("y", Math.max(tickMajorSize, 0) + tickPadding); | |
lineUpdate.attr("x2", 0).attr("y2", tickMajorSize); | |
textUpdate.attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding); | |
text.attr("dy", ".71em").style("text-anchor", "middle"); | |
pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize); | |
break; | |
} | |
case "top": | |
{ | |
tickTransform = d3_svg_axisX; | |
subtickEnter.attr("y2", -tickMinorSize); | |
subtickUpdate.attr("x2", 0).attr("y2", -tickMinorSize); | |
lineEnter.attr("y2", -tickMajorSize); | |
textEnter.attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)); | |
lineUpdate.attr("x2", 0).attr("y2", -tickMajorSize); | |
textUpdate.attr("x", 0).attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)); | |
text.attr("dy", "0em").style("text-anchor", "middle"); | |
pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize); | |
break; | |
} | |
case "left": | |
{ | |
tickTransform = d3_svg_axisY; | |
subtickEnter.attr("x2", -tickMinorSize); | |
subtickUpdate.attr("x2", -tickMinorSize).attr("y2", 0); | |
lineEnter.attr("x2", -tickMajorSize); | |
textEnter.attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)); | |
lineUpdate.attr("x2", -tickMajorSize).attr("y2", 0); | |
textUpdate.attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("y", 0); | |
text.attr("dy", ".32em").style("text-anchor", "end"); | |
pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize); | |
break; | |
} | |
case "right": | |
{ | |
tickTransform = d3_svg_axisY; | |
subtickEnter.attr("x2", tickMinorSize); | |
subtickUpdate.attr("x2", tickMinorSize).attr("y2", 0); | |
lineEnter.attr("x2", tickMajorSize); | |
textEnter.attr("x", Math.max(tickMajorSize, 0) + tickPadding); | |
lineUpdate.attr("x2", tickMajorSize).attr("y2", 0); | |
textUpdate.attr("x", Math.max(tickMajorSize, 0) + tickPadding).attr("y", 0); | |
text.attr("dy", ".32em").style("text-anchor", "start"); | |
pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize); | |
break; | |
} | |
} | |
if (scale.rangeBand) { | |
var dx = scale1.rangeBand() / 2, x = function(d) { | |
return scale1(d) + dx; | |
}; | |
tickEnter.call(tickTransform, x); | |
tickUpdate.call(tickTransform, x); | |
} else { | |
tickEnter.call(tickTransform, scale0); | |
tickUpdate.call(tickTransform, scale1); | |
tickExit.call(tickTransform, scale1); | |
subtickEnter.call(tickTransform, scale0); | |
subtickUpdate.call(tickTransform, scale1); | |
subtickExit.call(tickTransform, scale1); | |
} | |
}); | |
} | |
axis.scale = function(x) { | |
if (!arguments.length) return scale; | |
scale = x; | |
return axis; | |
}; | |
axis.orient = function(x) { | |
if (!arguments.length) return orient; | |
orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; | |
return axis; | |
}; | |
axis.ticks = function() { | |
if (!arguments.length) return tickArguments_; | |
tickArguments_ = arguments; | |
return axis; | |
}; | |
axis.tickValues = function(x) { | |
if (!arguments.length) return tickValues; | |
tickValues = x; | |
return axis; | |
}; | |
axis.tickFormat = function(x) { | |
if (!arguments.length) return tickFormat_; | |
tickFormat_ = x; | |
return axis; | |
}; | |
axis.tickSize = function(x, y) { | |
if (!arguments.length) return tickMajorSize; | |
var n = arguments.length - 1; | |
tickMajorSize = +x; | |
tickMinorSize = n > 1 ? +y : tickMajorSize; | |
tickEndSize = n > 0 ? +arguments[n] : tickMajorSize; | |
return axis; | |
}; | |
axis.tickPadding = function(x) { | |
if (!arguments.length) return tickPadding; | |
tickPadding = +x; | |
return axis; | |
}; | |
axis.tickSubdivide = function(x) { | |
if (!arguments.length) return tickSubdivide; | |
tickSubdivide = +x; | |
return axis; | |
}; | |
return axis; | |
}; | |
var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { | |
top: 1, | |
right: 1, | |
bottom: 1, | |
left: 1 | |
}; | |
function d3_svg_axisX(selection, x) { | |
selection.attr("transform", function(d) { | |
return "translate(" + x(d) + ",0)"; | |
}); | |
} | |
function d3_svg_axisY(selection, y) { | |
selection.attr("transform", function(d) { | |
return "translate(0," + y(d) + ")"; | |
}); | |
} | |
function d3_svg_axisSubdivide(scale, ticks, m) { | |
subticks = []; | |
if (m && ticks.length > 1) { | |
var extent = d3_scaleExtent(scale.domain()), subticks, i = -1, n = ticks.length, d = (ticks[1] - ticks[0]) / ++m, j, v; | |
while (++i < n) { | |
for (j = m; --j > 0; ) { | |
if ((v = +ticks[i] - j * d) >= extent[0]) { | |
subticks.push(v); | |
} | |
} | |
} | |
for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1]; ) { | |
subticks.push(v); | |
} | |
} | |
return subticks; | |
} | |
d3.svg.brush = function() { | |
var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, resizes = d3_svg_brushResizes[0], extent = [ [ 0, 0 ], [ 0, 0 ] ], clamp = [ true, true ], extentDomain; | |
function brush(g) { | |
g.each(function() { | |
var g = d3.select(this), bg = g.selectAll(".background").data([ 0 ]), fg = g.selectAll(".extent").data([ 0 ]), tz = g.selectAll(".resize").data(resizes, String), e; | |
g.style("pointer-events", "all").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); | |
bg.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); | |
fg.enter().append("rect").attr("class", "extent").style("cursor", "move"); | |
tz.enter().append("g").attr("class", function(d) { | |
return "resize " + d; | |
}).style("cursor", function(d) { | |
return d3_svg_brushCursor[d]; | |
}).append("rect").attr("x", function(d) { | |
return /[ew]$/.test(d) ? -3 : null; | |
}).attr("y", function(d) { | |
return /^[ns]/.test(d) ? -3 : null; | |
}).attr("width", 6).attr("height", 6).style("visibility", "hidden"); | |
tz.style("display", brush.empty() ? "none" : null); | |
tz.exit().remove(); | |
if (x) { | |
e = d3_scaleRange(x); | |
bg.attr("x", e[0]).attr("width", e[1] - e[0]); | |
redrawX(g); | |
} | |
if (y) { | |
e = d3_scaleRange(y); | |
bg.attr("y", e[0]).attr("height", e[1] - e[0]); | |
redrawY(g); | |
} | |
redraw(g); | |
}); | |
} | |
function redraw(g) { | |
g.selectAll(".resize").attr("transform", function(d) { | |
return "translate(" + extent[+/e$/.test(d)][0] + "," + extent[+/^s/.test(d)][1] + ")"; | |
}); | |
} | |
function redrawX(g) { | |
g.select(".extent").attr("x", extent[0][0]); | |
g.selectAll(".extent,.n>rect,.s>rect").attr("width", extent[1][0] - extent[0][0]); | |
} | |
function redrawY(g) { | |
g.select(".extent").attr("y", extent[0][1]); | |
g.selectAll(".extent,.e>rect,.w>rect").attr("height", extent[1][1] - extent[0][1]); | |
} | |
function brushstart() { | |
var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress("brush"), center, origin = mouse(), offset; | |
var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup); | |
if (d3.event.changedTouches) { | |
w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); | |
} else { | |
w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); | |
} | |
if (dragging) { | |
origin[0] = extent[0][0] - origin[0]; | |
origin[1] = extent[0][1] - origin[1]; | |
} else if (resizing) { | |
var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); | |
offset = [ extent[1 - ex][0] - origin[0], extent[1 - ey][1] - origin[1] ]; | |
origin[0] = extent[ex][0]; | |
origin[1] = extent[ey][1]; | |
} else if (d3.event.altKey) center = origin.slice(); | |
g.style("pointer-events", "none").selectAll(".resize").style("display", null); | |
d3.select("body").style("cursor", eventTarget.style("cursor")); | |
event_({ | |
type: "brushstart" | |
}); | |
brushmove(); | |
function mouse() { | |
var touches = d3.event.changedTouches; | |
return touches ? d3.touches(target, touches)[0] : d3.mouse(target); | |
} | |
function keydown() { | |
if (d3.event.keyCode == 32) { | |
if (!dragging) { | |
center = null; | |
origin[0] -= extent[1][0]; | |
origin[1] -= extent[1][1]; | |
dragging = 2; | |
} | |
d3_eventPreventDefault(); | |
} | |
} | |
function keyup() { | |
if (d3.event.keyCode == 32 && dragging == 2) { | |
origin[0] += extent[1][0]; | |
origin[1] += extent[1][1]; | |
dragging = 0; | |
d3_eventPreventDefault(); | |
} | |
} | |
function brushmove() { | |
var point = mouse(), moved = false; | |
if (offset) { | |
point[0] += offset[0]; | |
point[1] += offset[1]; | |
} | |
if (!dragging) { | |
if (d3.event.altKey) { | |
if (!center) center = [ (extent[0][0] + extent[1][0]) / 2, (extent[0][1] + extent[1][1]) / 2 ]; | |
origin[0] = extent[+(point[0] < center[0])][0]; | |
origin[1] = extent[+(point[1] < center[1])][1]; | |
} else center = null; | |
} | |
if (resizingX && move1(point, x, 0)) { | |
redrawX(g); | |
moved = true; | |
} | |
if (resizingY && move1(point, y, 1)) { | |
redrawY(g); | |
moved = true; | |
} | |
if (moved) { | |
redraw(g); | |
event_({ | |
type: "brush", | |
mode: dragging ? "move" : "resize" | |
}); | |
} | |
} | |
function move1(point, scale, i) { | |
var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], size = extent[1][i] - extent[0][i], min, max; | |
if (dragging) { | |
r0 -= position; | |
r1 -= size + position; | |
} | |
min = clamp[i] ? Math.max(r0, Math.min(r1, point[i])) : point[i]; | |
if (dragging) { | |
max = (min += position) + size; | |
} else { | |
if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); | |
if (position < min) { | |
max = min; | |
min = position; | |
} else { | |
max = position; | |
} | |
} | |
if (extent[0][i] !== min || extent[1][i] !== max) { | |
extentDomain = null; | |
extent[0][i] = min; | |
extent[1][i] = max; | |
return true; | |
} | |
} | |
function brushend() { | |
brushmove(); | |
g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); | |
d3.select("body").style("cursor", null); | |
w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); | |
dragRestore(); | |
event_({ | |
type: "brushend" | |
}); | |
} | |
} | |
brush.x = function(z) { | |
if (!arguments.length) return x; | |
x = z; | |
resizes = d3_svg_brushResizes[!x << 1 | !y]; | |
return brush; | |
}; | |
brush.y = function(z) { | |
if (!arguments.length) return y; | |
y = z; | |
resizes = d3_svg_brushResizes[!x << 1 | !y]; | |
return brush; | |
}; | |
brush.clamp = function(z) { | |
if (!arguments.length) return x && y ? clamp : x || y ? clamp[+!x] : null; | |
if (x && y) clamp = [ !!z[0], !!z[1] ]; else if (x || y) clamp[+!x] = !!z; | |
return brush; | |
}; | |
brush.extent = function(z) { | |
var x0, x1, y0, y1, t; | |
if (!arguments.length) { | |
z = extentDomain || extent; | |
if (x) { | |
x0 = z[0][0], x1 = z[1][0]; | |
if (!extentDomain) { | |
x0 = extent[0][0], x1 = extent[1][0]; | |
if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); | |
if (x1 < x0) t = x0, x0 = x1, x1 = t; | |
} | |
} | |
if (y) { | |
y0 = z[0][1], y1 = z[1][1]; | |
if (!extentDomain) { | |
y0 = extent[0][1], y1 = extent[1][1]; | |
if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); | |
if (y1 < y0) t = y0, y0 = y1, y1 = t; | |
} | |
} | |
return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; | |
} | |
extentDomain = [ [ 0, 0 ], [ 0, 0 ] ]; | |
if (x) { | |
x0 = z[0], x1 = z[1]; | |
if (y) x0 = x0[0], x1 = x1[0]; | |
extentDomain[0][0] = x0, extentDomain[1][0] = x1; | |
if (x.invert) x0 = x(x0), x1 = x(x1); | |
if (x1 < x0) t = x0, x0 = x1, x1 = t; | |
extent[0][0] = x0 | 0, extent[1][0] = x1 | 0; | |
} | |
if (y) { | |
y0 = z[0], y1 = z[1]; | |
if (x) y0 = y0[1], y1 = y1[1]; | |
extentDomain[0][1] = y0, extentDomain[1][1] = y1; | |
if (y.invert) y0 = y(y0), y1 = y(y1); | |
if (y1 < y0) t = y0, y0 = y1, y1 = t; | |
extent[0][1] = y0 | 0, extent[1][1] = y1 | 0; | |
} | |
return brush; | |
}; | |
brush.clear = function() { | |
extentDomain = null; | |
extent[0][0] = extent[0][1] = extent[1][0] = extent[1][1] = 0; | |
return brush; | |
}; | |
brush.empty = function() { | |
return x && extent[0][0] === extent[1][0] || y && extent[0][1] === extent[1][1]; | |
}; | |
return d3.rebind(brush, event, "on"); | |
}; | |
var d3_svg_brushCursor = { | |
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 d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; | |
d3.time = {}; | |
var d3_time = Date, d3_time_daySymbols = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; | |
function d3_time_utc() { | |
this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); | |
} | |
d3_time_utc.prototype = { | |
getDate: function() { | |
return this._.getUTCDate(); | |
}, | |
getDay: function() { | |
return this._.getUTCDay(); | |
}, | |
getFullYear: function() { | |
return this._.getUTCFullYear(); | |
}, | |
getHours: function() { | |
return this._.getUTCHours(); | |
}, | |
getMilliseconds: function() { | |
return this._.getUTCMilliseconds(); | |
}, | |
getMinutes: function() { | |
return this._.getUTCMinutes(); | |
}, | |
getMonth: function() { | |
return this._.getUTCMonth(); | |
}, | |
getSeconds: function() { | |
return this._.getUTCSeconds(); | |
}, | |
getTime: function() { | |
return this._.getTime(); | |
}, | |
getTimezoneOffset: function() { | |
return 0; | |
}, | |
valueOf: function() { | |
return this._.valueOf(); | |
}, | |
setDate: function() { | |
d3_time_prototype.setUTCDate.apply(this._, arguments); | |
}, | |
setDay: function() { | |
d3_time_prototype.setUTCDay.apply(this._, arguments); | |
}, | |
setFullYear: function() { | |
d3_time_prototype.setUTCFullYear.apply(this._, arguments); | |
}, | |
setHours: function() { | |
d3_time_prototype.setUTCHours.apply(this._, arguments); | |
}, | |
setMilliseconds: function() { | |
d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); | |
}, | |
setMinutes: function() { | |
d3_time_prototype.setUTCMinutes.apply(this._, arguments); | |
}, | |
setMonth: function() { | |
d3_time_prototype.setUTCMonth.apply(this._, arguments); | |
}, | |
setSeconds: function() { | |
d3_time_prototype.setUTCSeconds.apply(this._, arguments); | |
}, | |
setTime: function() { | |
d3_time_prototype.setTime.apply(this._, arguments); | |
} | |
}; | |
var d3_time_prototype = Date.prototype; | |
var d3_time_formatDateTime = "%a %b %e %X %Y", d3_time_formatDate = "%m/%d/%Y", d3_time_formatTime = "%H:%M:%S"; | |
var d3_time_days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], d3_time_dayAbbreviations = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], d3_time_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], d3_time_monthAbbreviations = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; | |
function d3_time_interval(local, step, number) { | |
function round(date) { | |
var d0 = local(date), d1 = offset(d0, 1); | |
return date - d0 < d1 - date ? d0 : d1; | |
} | |
function ceil(date) { | |
step(date = local(new d3_time(date - 1)), 1); | |
return date; | |
} | |
function offset(date, k) { | |
step(date = new d3_time(+date), k); | |
return date; | |
} | |
function range(t0, t1, dt) { | |
var time = ceil(t0), times = []; | |
if (dt > 1) { | |
while (time < t1) { | |
if (!(number(time) % dt)) times.push(new Date(+time)); | |
step(time, 1); | |
} | |
} else { | |
while (time < t1) times.push(new Date(+time)), step(time, 1); | |
} | |
return times; | |
} | |
function range_utc(t0, t1, dt) { | |
try { | |
d3_time = d3_time_utc; | |
var utc = new d3_time_utc(); | |
utc._ = t0; | |
return range(utc, t1, dt); | |
} finally { | |
d3_time = Date; | |
} | |
} | |
local.floor = local; | |
local.round = round; | |
local.ceil = ceil; | |
local.offset = offset; | |
local.range = range; | |
var utc = local.utc = d3_time_interval_utc(local); | |
utc.floor = utc; | |
utc.round = d3_time_interval_utc(round); | |
utc.ceil = d3_time_interval_utc(ceil); | |
utc.offset = d3_time_interval_utc(offset); | |
utc.range = range_utc; | |
return local; | |
} | |
function d3_time_interval_utc(method) { | |
return function(date, k) { | |
try { | |
d3_time = d3_time_utc; | |
var utc = new d3_time_utc(); | |
utc._ = date; | |
return method(utc, k)._; | |
} finally { | |
d3_time = Date; | |
} | |
}; | |
} | |
d3.time.year = d3_time_interval(function(date) { | |
date = d3.time.day(date); | |
date.setMonth(0, 1); | |
return date; | |
}, function(date, offset) { | |
date.setFullYear(date.getFullYear() + offset); | |
}, function(date) { | |
return date.getFullYear(); | |
}); | |
d3.time.years = d3.time.year.range; | |
d3.time.years.utc = d3.time.year.utc.range; | |
d3.time.day = d3_time_interval(function(date) { | |
var day = new d3_time(2e3, 0); | |
day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); | |
return day; | |
}, function(date, offset) { | |
date.setDate(date.getDate() + offset); | |
}, function(date) { | |
return date.getDate() - 1; | |
}); | |
d3.time.days = d3.time.day.range; | |
d3.time.days.utc = d3.time.day.utc.range; | |
d3.time.dayOfYear = function(date) { | |
var year = d3.time.year(date); | |
return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); | |
}; | |
d3_time_daySymbols.forEach(function(day, i) { | |
day = day.toLowerCase(); | |
i = 7 - i; | |
var interval = d3.time[day] = d3_time_interval(function(date) { | |
(date = d3.time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); | |
return date; | |
}, function(date, offset) { | |
date.setDate(date.getDate() + Math.floor(offset) * 7); | |
}, function(date) { | |
var day = d3.time.year(date).getDay(); | |
return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); | |
}); | |
d3.time[day + "s"] = interval.range; | |
d3.time[day + "s"].utc = interval.utc.range; | |
d3.time[day + "OfYear"] = function(date) { | |
var day = d3.time.year(date).getDay(); | |
return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7); | |
}; | |
}); | |
d3.time.week = d3.time.sunday; | |
d3.time.weeks = d3.time.sunday.range; | |
d3.time.weeks.utc = d3.time.sunday.utc.range; | |
d3.time.weekOfYear = d3.time.sundayOfYear; | |
d3.time.format = function(template) { | |
var n = template.length; | |
function format(date) { | |
var string = [], i = -1, j = 0, c, p, f; | |
while (++i < n) { | |
if (template.charCodeAt(i) === 37) { | |
string.push(template.substring(j, i)); | |
if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); | |
if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); | |
string.push(c); | |
j = i + 1; | |
} | |
} | |
string.push(template.substring(j, i)); | |
return string.join(""); | |
} | |
format.parse = function(string) { | |
var d = { | |
y: 1900, | |
m: 0, | |
d: 1, | |
H: 0, | |
M: 0, | |
S: 0, | |
L: 0 | |
}, i = d3_time_parse(d, template, string, 0); | |
if (i != string.length) return null; | |
if ("p" in d) d.H = d.H % 12 + d.p * 12; | |
var date = new d3_time(); | |
if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { | |
date.setFullYear(d.y, 0, 1); | |
date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); | |
} else date.setFullYear(d.y, d.m, d.d); | |
date.setHours(d.H, d.M, d.S, d.L); | |
return date; | |
}; | |
format.toString = function() { | |
return template; | |
}; | |
return format; | |
}; | |
function d3_time_parse(date, template, string, j) { | |
var c, p, i = 0, n = template.length, m = string.length; | |
while (i < n) { | |
if (j >= m) return -1; | |
c = template.charCodeAt(i++); | |
if (c === 37) { | |
p = d3_time_parsers[template.charAt(i++)]; | |
if (!p || (j = p(date, string, j)) < 0) return -1; | |
} else if (c != string.charCodeAt(j++)) { | |
return -1; | |
} | |
} | |
return j; | |
} | |
function d3_time_formatRe(names) { | |
return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); | |
} | |
function d3_time_formatLookup(names) { | |
var map = new d3_Map(), i = -1, n = names.length; | |
while (++i < n) map.set(names[i].toLowerCase(), i); | |
return map; | |
} | |
function d3_time_formatPad(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); | |
} | |
var d3_time_dayRe = d3_time_formatRe(d3_time_days), d3_time_dayLookup = d3_time_formatLookup(d3_time_days), d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations), d3_time_dayAbbrevLookup = d3_time_formatLookup(d3_time_dayAbbreviations), d3_time_monthRe = d3_time_formatRe(d3_time_months), d3_time_monthLookup = d3_time_formatLookup(d3_time_months), d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations), d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations), d3_time_percentRe = /^%/; | |
var d3_time_formatPads = { | |
"-": "", | |
_: " ", | |
"0": "0" | |
}; | |
var d3_time_formats = { | |
a: function(d) { | |
return d3_time_dayAbbreviations[d.getDay()]; | |
}, | |
A: function(d) { | |
return d3_time_days[d.getDay()]; | |
}, | |
b: function(d) { | |
return d3_time_monthAbbreviations[d.getMonth()]; | |
}, | |
B: function(d) { | |
return d3_time_months[d.getMonth()]; | |
}, | |
c: d3.time.format(d3_time_formatDateTime), | |
d: function(d, p) { | |
return d3_time_formatPad(d.getDate(), p, 2); | |
}, | |
e: function(d, p) { | |
return d3_time_formatPad(d.getDate(), p, 2); | |
}, | |
H: function(d, p) { | |
return d3_time_formatPad(d.getHours(), p, 2); | |
}, | |
I: function(d, p) { | |
return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); | |
}, | |
j: function(d, p) { | |
return d3_time_formatPad(1 + d3.time.dayOfYear(d), p, 3); | |
}, | |
L: function(d, p) { | |
return d3_time_formatPad(d.getMilliseconds(), p, 3); | |
}, | |
m: function(d, p) { | |
return d3_time_formatPad(d.getMonth() + 1, p, 2); | |
}, | |
M: function(d, p) { | |
return d3_time_formatPad(d.getMinutes(), p, 2); | |
}, | |
p: function(d) { | |
return d.getHours() >= 12 ? "PM" : "AM"; | |
}, | |
S: function(d, p) { | |
return d3_time_formatPad(d.getSeconds(), p, 2); | |
}, | |
U: function(d, p) { | |
return d3_time_formatPad(d3.time.sundayOfYear(d), p, 2); | |
}, | |
w: function(d) { | |
return d.getDay(); | |
}, | |
W: function(d, p) { | |
return d3_time_formatPad(d3.time.mondayOfYear(d), p, 2); | |
}, | |
x: d3.time.format(d3_time_formatDate), | |
X: d3.time.format(d3_time_formatTime), | |
y: function(d, p) { | |
return d3_time_formatPad(d.getFullYear() % 100, p, 2); | |
}, | |
Y: function(d, p) { | |
return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); | |
}, | |
Z: d3_time_zone, | |
"%": function() { | |
return "%"; | |
} | |
}; | |
var d3_time_parsers = { | |
a: d3_time_parseWeekdayAbbrev, | |
A: d3_time_parseWeekday, | |
b: d3_time_parseMonthAbbrev, | |
B: d3_time_parseMonth, | |
c: d3_time_parseLocaleFull, | |
d: d3_time_parseDay, | |
e: d3_time_parseDay, | |
H: d3_time_parseHour24, | |
I: d3_time_parseHour24, | |
j: d3_time_parseDayOfYear, | |
L: d3_time_parseMilliseconds, | |
m: d3_time_parseMonthNumber, | |
M: d3_time_parseMinutes, | |
p: d3_time_parseAmPm, | |
S: d3_time_parseSeconds, | |
U: d3_time_parseWeekNumberSunday, | |
w: d3_time_parseWeekdayNumber, | |
W: d3_time_parseWeekNumberMonday, | |
x: d3_time_parseLocaleDate, | |
X: d3_time_parseLocaleTime, | |
y: d3_time_parseYear, | |
Y: d3_time_parseFullYear, | |
"%": d3_time_parseLiteralPercent | |
}; | |
function d3_time_parseWeekdayAbbrev(date, string, i) { | |
d3_time_dayAbbrevRe.lastIndex = 0; | |
var n = d3_time_dayAbbrevRe.exec(string.substring(i)); | |
return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; | |
} | |
function d3_time_parseWeekday(date, string, i) { | |
d3_time_dayRe.lastIndex = 0; | |
var n = d3_time_dayRe.exec(string.substring(i)); | |
return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; | |
} | |
function d3_time_parseWeekdayNumber(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 1)); | |
return n ? (date.w = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseWeekNumberSunday(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i)); | |
return n ? (date.U = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseWeekNumberMonday(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i)); | |
return n ? (date.W = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseMonthAbbrev(date, string, i) { | |
d3_time_monthAbbrevRe.lastIndex = 0; | |
var n = d3_time_monthAbbrevRe.exec(string.substring(i)); | |
return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; | |
} | |
function d3_time_parseMonth(date, string, i) { | |
d3_time_monthRe.lastIndex = 0; | |
var n = d3_time_monthRe.exec(string.substring(i)); | |
return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; | |
} | |
function d3_time_parseLocaleFull(date, string, i) { | |
return d3_time_parse(date, d3_time_formats.c.toString(), string, i); | |
} | |
function d3_time_parseLocaleDate(date, string, i) { | |
return d3_time_parse(date, d3_time_formats.x.toString(), string, i); | |
} | |
function d3_time_parseLocaleTime(date, string, i) { | |
return d3_time_parse(date, d3_time_formats.X.toString(), string, i); | |
} | |
function d3_time_parseFullYear(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 4)); | |
return n ? (date.y = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseYear(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 2)); | |
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; | |
} | |
function d3_time_expandYear(d) { | |
return d + (d > 68 ? 1900 : 2e3); | |
} | |
function d3_time_parseMonthNumber(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 2)); | |
return n ? (date.m = n[0] - 1, i + n[0].length) : -1; | |
} | |
function d3_time_parseDay(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 2)); | |
return n ? (date.d = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseDayOfYear(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 3)); | |
return n ? (date.j = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseHour24(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 2)); | |
return n ? (date.H = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseMinutes(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 2)); | |
return n ? (date.M = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseSeconds(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 2)); | |
return n ? (date.S = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseMilliseconds(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.substring(i, i + 3)); | |
return n ? (date.L = +n[0], i + n[0].length) : -1; | |
} | |
var d3_time_numberRe = /^\s*\d+/; | |
function d3_time_parseAmPm(date, string, i) { | |
var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase()); | |
return n == null ? -1 : (date.p = n, i); | |
} | |
var d3_time_amPmLookup = d3.map({ | |
am: 0, | |
pm: 1 | |
}); | |
function d3_time_zone(d) { | |
var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(Math.abs(z) / 60), zm = Math.abs(z) % 60; | |
return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); | |
} | |
function d3_time_parseLiteralPercent(date, string, i) { | |
d3_time_percentRe.lastIndex = 0; | |
var n = d3_time_percentRe.exec(string.substring(i, i + 1)); | |
return n ? i + n[0].length : -1; | |
} | |
d3.time.format.utc = function(template) { | |
var local = d3.time.format(template); | |
function format(date) { | |
try { | |
d3_time = d3_time_utc; | |
var utc = new d3_time(); | |
utc._ = date; | |
return local(utc); | |
} finally { | |
d3_time = Date; | |
} | |
} | |
format.parse = function(string) { | |
try { | |
d3_time = d3_time_utc; | |
var date = local.parse(string); | |
return date && date._; | |
} finally { | |
d3_time = Date; | |
} | |
}; | |
format.toString = local.toString; | |
return format; | |
}; | |
var d3_time_formatIso = d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ"); | |
d3.time.format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; | |
function d3_time_formatIsoNative(date) { | |
return date.toISOString(); | |
} | |
d3_time_formatIsoNative.parse = function(string) { | |
var date = new Date(string); | |
return isNaN(date) ? null : date; | |
}; | |
d3_time_formatIsoNative.toString = d3_time_formatIso.toString; | |
d3.time.second = d3_time_interval(function(date) { | |
return new d3_time(Math.floor(date / 1e3) * 1e3); | |
}, function(date, offset) { | |
date.setTime(date.getTime() + Math.floor(offset) * 1e3); | |
}, function(date) { | |
return date.getSeconds(); | |
}); | |
d3.time.seconds = d3.time.second.range; | |
d3.time.seconds.utc = d3.time.second.utc.range; | |
d3.time.minute = d3_time_interval(function(date) { | |
return new d3_time(Math.floor(date / 6e4) * 6e4); | |
}, function(date, offset) { | |
date.setTime(date.getTime() + Math.floor(offset) * 6e4); | |
}, function(date) { | |
return date.getMinutes(); | |
}); | |
d3.time.minutes = d3.time.minute.range; | |
d3.time.minutes.utc = d3.time.minute.utc.range; | |
d3.time.hour = d3_time_interval(function(date) { | |
var timezone = date.getTimezoneOffset() / 60; | |
return new d3_time((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); | |
}, function(date, offset) { | |
date.setTime(date.getTime() + Math.floor(offset) * 36e5); | |
}, function(date) { | |
return date.getHours(); | |
}); | |
d3.time.hours = d3.time.hour.range; | |
d3.time.hours.utc = d3.time.hour.utc.range; | |
d3.time.month = d3_time_interval(function(date) { | |
date = d3.time.day(date); | |
date.setDate(1); | |
return date; | |
}, function(date, offset) { | |
date.setMonth(date.getMonth() + offset); | |
}, function(date) { | |
return date.getMonth(); | |
}); | |
d3.time.months = d3.time.month.range; | |
d3.time.months.utc = d3.time.month.utc.range; | |
function d3_time_scale(linear, methods, format) { | |
function scale(x) { | |
return linear(x); | |
} | |
scale.invert = function(x) { | |
return d3_time_scaleDate(linear.invert(x)); | |
}; | |
scale.domain = function(x) { | |
if (!arguments.length) return linear.domain().map(d3_time_scaleDate); | |
linear.domain(x); | |
return scale; | |
}; | |
scale.nice = function(m) { | |
return scale.domain(d3_scale_nice(scale.domain(), m)); | |
}; | |
scale.ticks = function(m, k) { | |
var extent = d3_scaleExtent(scale.domain()); | |
if (typeof m !== "function") { | |
var span = extent[1] - extent[0], target = span / m, i = d3.bisect(d3_time_scaleSteps, target); | |
if (i == d3_time_scaleSteps.length) return methods.year(extent, m); | |
if (!i) return linear.ticks(m).map(d3_time_scaleDate); | |
if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i; | |
m = methods[i]; | |
k = m[1]; | |
m = m[0].range; | |
} | |
return m(extent[0], new Date(+extent[1] + 1), k); | |
}; | |
scale.tickFormat = function() { | |
return format; | |
}; | |
scale.copy = function() { | |
return d3_time_scale(linear.copy(), methods, format); | |
}; | |
return d3_scale_linearRebind(scale, linear); | |
} | |
function d3_time_scaleDate(t) { | |
return new Date(t); | |
} | |
function d3_time_scaleFormat(formats) { | |
return function(date) { | |
var i = formats.length - 1, f = formats[i]; | |
while (!f[1](date)) f = formats[--i]; | |
return f[0](date); | |
}; | |
} | |
function d3_time_scaleSetYear(y) { | |
var d = new Date(y, 0, 1); | |
d.setFullYear(y); | |
return d; | |
} | |
function d3_time_scaleGetYear(d) { | |
var y = d.getFullYear(), d0 = d3_time_scaleSetYear(y), d1 = d3_time_scaleSetYear(y + 1); | |
return y + (d - d0) / (d1 - d0); | |
} | |
var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; | |
var d3_time_scaleLocalMethods = [ [ d3.time.second, 1 ], [ d3.time.second, 5 ], [ d3.time.second, 15 ], [ d3.time.second, 30 ], [ d3.time.minute, 1 ], [ d3.time.minute, 5 ], [ d3.time.minute, 15 ], [ d3.time.minute, 30 ], [ d3.time.hour, 1 ], [ d3.time.hour, 3 ], [ d3.time.hour, 6 ], [ d3.time.hour, 12 ], [ d3.time.day, 1 ], [ d3.time.day, 2 ], [ d3.time.week, 1 ], [ d3.time.month, 1 ], [ d3.time.month, 3 ], [ d3.time.year, 1 ] ]; | |
var d3_time_scaleLocalFormats = [ [ d3.time.format("%Y"), d3_true ], [ d3.time.format("%B"), function(d) { | |
return d.getMonth(); | |
} ], [ d3.time.format("%b %d"), function(d) { | |
return d.getDate() != 1; | |
} ], [ d3.time.format("%a %d"), function(d) { | |
return d.getDay() && d.getDate() != 1; | |
} ], [ d3.time.format("%I %p"), function(d) { | |
return d.getHours(); | |
} ], [ d3.time.format("%I:%M"), function(d) { | |
return d.getMinutes(); | |
} ], [ d3.time.format(":%S"), function(d) { | |
return d.getSeconds(); | |
} ], [ d3.time.format(".%L"), function(d) { | |
return d.getMilliseconds(); | |
} ] ]; | |
var d3_time_scaleLinear = d3.scale.linear(), d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); | |
d3_time_scaleLocalMethods.year = function(extent, m) { | |
return d3_time_scaleLinear.domain(extent.map(d3_time_scaleGetYear)).ticks(m).map(d3_time_scaleSetYear); | |
}; | |
d3.time.scale = function() { | |
return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); | |
}; | |
var d3_time_scaleUTCMethods = d3_time_scaleLocalMethods.map(function(m) { | |
return [ m[0].utc, m[1] ]; | |
}); | |
var d3_time_scaleUTCFormats = [ [ d3.time.format.utc("%Y"), d3_true ], [ d3.time.format.utc("%B"), function(d) { | |
return d.getUTCMonth(); | |
} ], [ d3.time.format.utc("%b %d"), function(d) { | |
return d.getUTCDate() != 1; | |
} ], [ d3.time.format.utc("%a %d"), function(d) { | |
return d.getUTCDay() && d.getUTCDate() != 1; | |
} ], [ d3.time.format.utc("%I %p"), function(d) { | |
return d.getUTCHours(); | |
} ], [ d3.time.format.utc("%I:%M"), function(d) { | |
return d.getUTCMinutes(); | |
} ], [ d3.time.format.utc(":%S"), function(d) { | |
return d.getUTCSeconds(); | |
} ], [ d3.time.format.utc(".%L"), function(d) { | |
return d.getUTCMilliseconds(); | |
} ] ]; | |
var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats); | |
function d3_time_scaleUTCSetYear(y) { | |
var d = new Date(Date.UTC(y, 0, 1)); | |
d.setUTCFullYear(y); | |
return d; | |
} | |
function d3_time_scaleUTCGetYear(d) { | |
var y = d.getUTCFullYear(), d0 = d3_time_scaleUTCSetYear(y), d1 = d3_time_scaleUTCSetYear(y + 1); | |
return y + (d - d0) / (d1 - d0); | |
} | |
d3_time_scaleUTCMethods.year = function(extent, m) { | |
return d3_time_scaleLinear.domain(extent.map(d3_time_scaleUTCGetYear)).ticks(m).map(d3_time_scaleUTCSetYear); | |
}; | |
d3.time.scale.utc = function() { | |
return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat); | |
}; | |
d3.text = d3_xhrType(function(request) { | |
return request.responseText; | |
}); | |
d3.json = function(url, callback) { | |
return d3_xhr(url, "application/json", d3_json, callback); | |
}; | |
function d3_json(request) { | |
return JSON.parse(request.responseText); | |
} | |
d3.html = function(url, callback) { | |
return d3_xhr(url, "text/html", d3_html, callback); | |
}; | |
function d3_html(request) { | |
var range = d3_document.createRange(); | |
range.selectNode(d3_document.body); | |
return range.createContextualFragment(request.responseText); | |
} | |
d3.xml = d3_xhrType(function(request) { | |
return request.responseXML; | |
}); | |
return d3; | |
}(); | |
},{}]},{},[]) | |
//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvdG1wL2QzMTEzNjYtMTEyODEtdjJtOXVyL25vZGVfbW9kdWxlcy9kMy9pbmRleC1icm93c2VyaWZ5LmpzIiwiL3RtcC9kMzExMzY2LTExMjgxLXYybTl1ci9ub2RlX21vZHVsZXMvZDMvZDMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe3JlcXVpcmUoXCIuL2QzXCIpO1xubW9kdWxlLmV4cG9ydHMgPSBkMztcbihmdW5jdGlvbiAoKSB7IGRlbGV0ZSB0aGlzLmQzOyB9KSgpOyAvLyB1bnNldCBnbG9iYWxcblxufSkoKSIsImQzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkMyA9IHtcbiAgICB2ZXJzaW9uOiBcIjMuMi40XCJcbiAgfTtcbiAgaWYgKCFEYXRlLm5vdykgRGF0ZS5ub3cgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlKCk7XG4gIH07XG4gIHZhciBkM19kb2N1bWVudCA9IGRvY3VtZW50LCBkM19kb2N1bWVudEVsZW1lbnQgPSBkM19kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIGQzX3dpbmRvdyA9IHdpbmRvdztcbiAgdHJ5IHtcbiAgICBkM19kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLnN0eWxlLnNldFByb3BlcnR5KFwib3BhY2l0eVwiLCAwLCBcIlwiKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB2YXIgZDNfZWxlbWVudF9wcm90b3R5cGUgPSBkM193aW5kb3cuRWxlbWVudC5wcm90b3R5cGUsIGQzX2VsZW1lbnRfc2V0QXR0cmlidXRlID0gZDNfZWxlbWVudF9wcm90b3R5cGUuc2V0QXR0cmlidXRlLCBkM19lbGVtZW50X3NldEF0dHJpYnV0ZU5TID0gZDNfZWxlbWVudF9wcm90b3R5cGUuc2V0QXR0cmlidXRlTlMsIGQzX3N0eWxlX3Byb3RvdHlwZSA9IGQzX3dpbmRvdy5DU1NTdHlsZURlY2xhcmF0aW9uLnByb3RvdHlwZSwgZDNfc3R5bGVfc2V0UHJvcGVydHkgPSBkM19zdHlsZV9wcm90b3R5cGUuc2V0UHJvcGVydHk7XG4gICAgZDNfZWxlbWVudF9wcm90b3R5cGUuc2V0QXR0cmlidXRlID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICAgIGQzX2VsZW1lbnRfc2V0QXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSwgdmFsdWUgKyBcIlwiKTtcbiAgICB9O1xuICAgIGQzX2VsZW1lbnRfcHJvdG90eXBlLnNldEF0dHJpYnV0ZU5TID0gZnVuY3Rpb24oc3BhY2UsIGxvY2FsLCB2YWx1ZSkge1xuICAgICAgZDNfZWxlbWVudF9zZXRBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIHNwYWNlLCBsb2NhbCwgdmFsdWUgKyBcIlwiKTtcbiAgICB9O1xuICAgIGQzX3N0eWxlX3Byb3RvdHlwZS5zZXRQcm9wZXJ0eSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICAgICAgZDNfc3R5bGVfc2V0UHJvcGVydHkuY2FsbCh0aGlzLCBuYW1lLCB2YWx1ZSArIFwiXCIsIHByaW9yaXR5KTtcbiAgICB9O1xuICB9XG4gIGQzLmFzY2VuZGluZyA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IGEgPj0gYiA/IDAgOiBOYU47XG4gIH07XG4gIGQzLmRlc2NlbmRpbmcgPSBmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGIgPCBhID8gLTEgOiBiID4gYSA/IDEgOiBiID49IGEgPyAwIDogTmFOO1xuICB9O1xuICBkMy5taW4gPSBmdW5jdGlvbihhcnJheSwgZikge1xuICAgIHZhciBpID0gLTEsIG4gPSBhcnJheS5sZW5ndGgsIGEsIGI7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHdoaWxlICgrK2kgPCBuICYmICEoKGEgPSBhcnJheVtpXSkgIT0gbnVsbCAmJiBhIDw9IGEpKSBhID0gdW5kZWZpbmVkO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGFycmF5W2ldKSAhPSBudWxsICYmIGEgPiBiKSBhID0gYjtcbiAgICB9IGVsc2Uge1xuICAgICAgd2hpbGUgKCsraSA8IG4gJiYgISgoYSA9IGYuY2FsbChhcnJheSwgYXJyYXlbaV0sIGkpKSAhPSBudWxsICYmIGEgPD0gYSkpIGEgPSB1bmRlZmluZWQ7XG4gICAgICB3aGlsZSAoKytpIDwgbikgaWYgKChiID0gZi5jYWxsKGFycmF5LCBhcnJheVtpXSwgaSkpICE9IG51bGwgJiYgYSA+IGIpIGEgPSBiO1xuICAgIH1cbiAgICByZXR1cm4gYTtcbiAgfTtcbiAgZDMubWF4ID0gZnVuY3Rpb24oYXJyYXksIGYpIHtcbiAgICB2YXIgaSA9IC0xLCBuID0gYXJyYXkubGVuZ3RoLCBhLCBiO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICB3aGlsZSAoKytpIDwgbiAmJiAhKChhID0gYXJyYXlbaV0pICE9IG51bGwgJiYgYSA8PSBhKSkgYSA9IHVuZGVmaW5lZDtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBhcnJheVtpXSkgIT0gbnVsbCAmJiBiID4gYSkgYSA9IGI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlICgrK2kgPCBuICYmICEoKGEgPSBmLmNhbGwoYXJyYXksIGFycmF5W2ldLCBpKSkgIT0gbnVsbCAmJiBhIDw9IGEpKSBhID0gdW5kZWZpbmVkO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIGlmICgoYiA9IGYuY2FsbChhcnJheSwgYXJyYXlbaV0sIGkpKSAhPSBudWxsICYmIGIgPiBhKSBhID0gYjtcbiAgICB9XG4gICAgcmV0dXJuIGE7XG4gIH07XG4gIGQzLmV4dGVudCA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gICAgdmFyIGkgPSAtMSwgbiA9IGFycmF5Lmxlbmd0aCwgYSwgYiwgYztcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgd2hpbGUgKCsraSA8IG4gJiYgISgoYSA9IGMgPSBhcnJheVtpXSkgIT0gbnVsbCAmJiBhIDw9IGEpKSBhID0gYyA9IHVuZGVmaW5lZDtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKGIgPSBhcnJheVtpXSkgIT0gbnVsbCkge1xuICAgICAgICBpZiAoYSA+IGIpIGEgPSBiO1xuICAgICAgICBpZiAoYyA8IGIpIGMgPSBiO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAoKytpIDwgbiAmJiAhKChhID0gYyA9IGYuY2FsbChhcnJheSwgYXJyYXlbaV0sIGkpKSAhPSBudWxsICYmIGEgPD0gYSkpIGEgPSB1bmRlZmluZWQ7XG4gICAgICB3aGlsZSAoKytpIDwgbikgaWYgKChiID0gZi5jYWxsKGFycmF5LCBhcnJheVtpXSwgaSkpICE9IG51bGwpIHtcbiAgICAgICAgaWYgKGEgPiBiKSBhID0gYjtcbiAgICAgICAgaWYgKGMgPCBiKSBjID0gYjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFsgYSwgYyBdO1xuICB9O1xuICBkMy5zdW0gPSBmdW5jdGlvbihhcnJheSwgZikge1xuICAgIHZhciBzID0gMCwgbiA9IGFycmF5Lmxlbmd0aCwgYSwgaSA9IC0xO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFpc05hTihhID0gK2FycmF5W2ldKSkgcyArPSBhO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFpc05hTihhID0gK2YuY2FsbChhcnJheSwgYXJyYXlbaV0sIGkpKSkgcyArPSBhO1xuICAgIH1cbiAgICByZXR1cm4gcztcbiAgfTtcbiAgZnVuY3Rpb24gZDNfbnVtYmVyKHgpIHtcbiAgICByZXR1cm4geCAhPSBudWxsICYmICFpc05hTih4KTtcbiAgfVxuICBkMy5tZWFuID0gZnVuY3Rpb24oYXJyYXksIGYpIHtcbiAgICB2YXIgbiA9IGFycmF5Lmxlbmd0aCwgYSwgbSA9IDAsIGkgPSAtMSwgaiA9IDA7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoZDNfbnVtYmVyKGEgPSBhcnJheVtpXSkpIG0gKz0gKGEgLSBtKSAvICsrajtcbiAgICB9IGVsc2Uge1xuICAgICAgd2hpbGUgKCsraSA8IG4pIGlmIChkM19udW1iZXIoYSA9IGYuY2FsbChhcnJheSwgYXJyYXlbaV0sIGkpKSkgbSArPSAoYSAtIG0pIC8gKytqO1xuICAgIH1cbiAgICByZXR1cm4gaiA/IG0gOiB1bmRlZmluZWQ7XG4gIH07XG4gIGQzLnF1YW50aWxlID0gZnVuY3Rpb24odmFsdWVzLCBwKSB7XG4gICAgdmFyIEggPSAodmFsdWVzLmxlbmd0aCAtIDEpICogcCArIDEsIGggPSBNYXRoLmZsb29yKEgpLCB2ID0gK3ZhbHVlc1toIC0gMV0sIGUgPSBIIC0gaDtcbiAgICByZXR1cm4gZSA/IHYgKyBlICogKHZhbHVlc1toXSAtIHYpIDogdjtcbiAgfTtcbiAgZDMubWVkaWFuID0gZnVuY3Rpb24oYXJyYXksIGYpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIGFycmF5ID0gYXJyYXkubWFwKGYpO1xuICAgIGFycmF5ID0gYXJyYXkuZmlsdGVyKGQzX251bWJlcik7XG4gICAgcmV0dXJuIGFycmF5Lmxlbmd0aCA/IGQzLnF1YW50aWxlKGFycmF5LnNvcnQoZDMuYXNjZW5kaW5nKSwgLjUpIDogdW5kZWZpbmVkO1xuICB9O1xuICBkMy5iaXNlY3RvciA9IGZ1bmN0aW9uKGYpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbGVmdDogZnVuY3Rpb24oYSwgeCwgbG8sIGhpKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykgbG8gPSAwO1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDQpIGhpID0gYS5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChsbyA8IGhpKSB7XG4gICAgICAgICAgdmFyIG1pZCA9IGxvICsgaGkgPj4+IDE7XG4gICAgICAgICAgaWYgKGYuY2FsbChhLCBhW21pZF0sIG1pZCkgPCB4KSBsbyA9IG1pZCArIDE7IGVsc2UgaGkgPSBtaWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxvO1xuICAgICAgfSxcbiAgICAgIHJpZ2h0OiBmdW5jdGlvbihhLCB4LCBsbywgaGkpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSBsbyA9IDA7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgNCkgaGkgPSBhLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGxvIDwgaGkpIHtcbiAgICAgICAgICB2YXIgbWlkID0gbG8gKyBoaSA+Pj4gMTtcbiAgICAgICAgICBpZiAoeCA8IGYuY2FsbChhLCBhW21pZF0sIG1pZCkpIGhpID0gbWlkOyBlbHNlIGxvID0gbWlkICsgMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG87XG4gICAgICB9XG4gICAgfTtcbiAgfTtcbiAgdmFyIGQzX2Jpc2VjdG9yID0gZDMuYmlzZWN0b3IoZnVuY3Rpb24oZCkge1xuICAgIHJldHVybiBkO1xuICB9KTtcbiAgZDMuYmlzZWN0TGVmdCA9IGQzX2Jpc2VjdG9yLmxlZnQ7XG4gIGQzLmJpc2VjdCA9IGQzLmJpc2VjdFJpZ2h0ID0gZDNfYmlzZWN0b3IucmlnaHQ7XG4gIGQzLnNodWZmbGUgPSBmdW5jdGlvbihhcnJheSkge1xuICAgIHZhciBtID0gYXJyYXkubGVuZ3RoLCB0LCBpO1xuICAgIHdoaWxlIChtKSB7XG4gICAgICBpID0gTWF0aC5yYW5kb20oKSAqIG0tLSB8IDA7XG4gICAgICB0ID0gYXJyYXlbbV0sIGFycmF5W21dID0gYXJyYXlbaV0sIGFycmF5W2ldID0gdDtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9O1xuICBkMy5wZXJtdXRlID0gZnVuY3Rpb24oYXJyYXksIGluZGV4ZXMpIHtcbiAgICB2YXIgcGVybXV0ZXMgPSBbXSwgaSA9IC0xLCBuID0gaW5kZXhlcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIHBlcm11dGVzW2ldID0gYXJyYXlbaW5kZXhlc1tpXV07XG4gICAgcmV0dXJuIHBlcm11dGVzO1xuICB9O1xuICBkMy56aXAgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIShuID0gYXJndW1lbnRzLmxlbmd0aCkpIHJldHVybiBbXTtcbiAgICBmb3IgKHZhciBpID0gLTEsIG0gPSBkMy5taW4oYXJndW1lbnRzLCBkM196aXBMZW5ndGgpLCB6aXBzID0gbmV3IEFycmF5KG0pOyArK2kgPCBtOyApIHtcbiAgICAgIGZvciAodmFyIGogPSAtMSwgbiwgemlwID0gemlwc1tpXSA9IG5ldyBBcnJheShuKTsgKytqIDwgbjsgKSB7XG4gICAgICAgIHppcFtqXSA9IGFyZ3VtZW50c1tqXVtpXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHppcHM7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3ppcExlbmd0aChkKSB7XG4gICAgcmV0dXJuIGQubGVuZ3RoO1xuICB9XG4gIGQzLnRyYW5zcG9zZSA9IGZ1bmN0aW9uKG1hdHJpeCkge1xuICAgIHJldHVybiBkMy56aXAuYXBwbHkoZDMsIG1hdHJpeCk7XG4gIH07XG4gIGQzLmtleXMgPSBmdW5jdGlvbihtYXApIHtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBtYXApIGtleXMucHVzaChrZXkpO1xuICAgIHJldHVybiBrZXlzO1xuICB9O1xuICBkMy52YWx1ZXMgPSBmdW5jdGlvbihtYXApIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG1hcCkgdmFsdWVzLnB1c2gobWFwW2tleV0pO1xuICAgIHJldHVybiB2YWx1ZXM7XG4gIH07XG4gIGQzLmVudHJpZXMgPSBmdW5jdGlvbihtYXApIHtcbiAgICB2YXIgZW50cmllcyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBtYXApIGVudHJpZXMucHVzaCh7XG4gICAgICBrZXk6IGtleSxcbiAgICAgIHZhbHVlOiBtYXBba2V5XVxuICAgIH0pO1xuICAgIHJldHVybiBlbnRyaWVzO1xuICB9O1xuICBkMy5tZXJnZSA9IGZ1bmN0aW9uKGFycmF5cykge1xuICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFtdLCBhcnJheXMpO1xuICB9O1xuICBkMy5yYW5nZSA9IGZ1bmN0aW9uKHN0YXJ0LCBzdG9wLCBzdGVwKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgICBzdGVwID0gMTtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgICBzdG9wID0gc3RhcnQ7XG4gICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKChzdG9wIC0gc3RhcnQpIC8gc3RlcCA9PT0gSW5maW5pdHkpIHRocm93IG5ldyBFcnJvcihcImluZmluaXRlIHJhbmdlXCIpO1xuICAgIHZhciByYW5nZSA9IFtdLCBrID0gZDNfcmFuZ2VfaW50ZWdlclNjYWxlKE1hdGguYWJzKHN0ZXApKSwgaSA9IC0xLCBqO1xuICAgIHN0YXJ0ICo9IGssIHN0b3AgKj0gaywgc3RlcCAqPSBrO1xuICAgIGlmIChzdGVwIDwgMCkgd2hpbGUgKChqID0gc3RhcnQgKyBzdGVwICogKytpKSA+IHN0b3ApIHJhbmdlLnB1c2goaiAvIGspOyBlbHNlIHdoaWxlICgoaiA9IHN0YXJ0ICsgc3RlcCAqICsraSkgPCBzdG9wKSByYW5nZS5wdXNoKGogLyBrKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3JhbmdlX2ludGVnZXJTY2FsZSh4KSB7XG4gICAgdmFyIGsgPSAxO1xuICAgIHdoaWxlICh4ICogayAlIDEpIGsgKj0gMTA7XG4gICAgcmV0dXJuIGs7XG4gIH1cbiAgZnVuY3Rpb24gZDNfY2xhc3MoY3RvciwgcHJvcGVydGllcykge1xuICAgIHRyeSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gcHJvcGVydGllcykge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3Rvci5wcm90b3R5cGUsIGtleSwge1xuICAgICAgICAgIHZhbHVlOiBwcm9wZXJ0aWVzW2tleV0sXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY3Rvci5wcm90b3R5cGUgPSBwcm9wZXJ0aWVzO1xuICAgIH1cbiAgfVxuICBkMy5tYXAgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICB2YXIgbWFwID0gbmV3IGQzX01hcCgpO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIG1hcC5zZXQoa2V5LCBvYmplY3Rba2V5XSk7XG4gICAgcmV0dXJuIG1hcDtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfTWFwKCkge31cbiAgZDNfY2xhc3MoZDNfTWFwLCB7XG4gICAgaGFzOiBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBkM19tYXBfcHJlZml4ICsga2V5IGluIHRoaXM7XG4gICAgfSxcbiAgICBnZXQ6IGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIHRoaXNbZDNfbWFwX3ByZWZpeCArIGtleV07XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzW2QzX21hcF9wcmVmaXggKyBrZXldID0gdmFsdWU7XG4gICAgfSxcbiAgICByZW1vdmU6IGZ1bmN0aW9uKGtleSkge1xuICAgICAga2V5ID0gZDNfbWFwX3ByZWZpeCArIGtleTtcbiAgICAgIHJldHVybiBrZXkgaW4gdGhpcyAmJiBkZWxldGUgdGhpc1trZXldO1xuICAgIH0sXG4gICAga2V5czogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIga2V5cyA9IFtdO1xuICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGtleXM7XG4gICAgfSxcbiAgICB2YWx1ZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICAgICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH0sXG4gICAgZW50cmllczogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcyA9IFtdO1xuICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICAgICAgZW50cmllcy5wdXNoKHtcbiAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBlbnRyaWVzO1xuICAgIH0sXG4gICAgZm9yRWFjaDogZnVuY3Rpb24oZikge1xuICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMpIHtcbiAgICAgICAgaWYgKGtleS5jaGFyQ29kZUF0KDApID09PSBkM19tYXBfcHJlZml4Q29kZSkge1xuICAgICAgICAgIGYuY2FsbCh0aGlzLCBrZXkuc3Vic3RyaW5nKDEpLCB0aGlzW2tleV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgdmFyIGQzX21hcF9wcmVmaXggPSBcIlxcMFwiLCBkM19tYXBfcHJlZml4Q29kZSA9IGQzX21hcF9wcmVmaXguY2hhckNvZGVBdCgwKTtcbiAgZDMubmVzdCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBuZXN0ID0ge30sIGtleXMgPSBbXSwgc29ydEtleXMgPSBbXSwgc29ydFZhbHVlcywgcm9sbHVwO1xuICAgIGZ1bmN0aW9uIG1hcChtYXBUeXBlLCBhcnJheSwgZGVwdGgpIHtcbiAgICAgIGlmIChkZXB0aCA+PSBrZXlzLmxlbmd0aCkgcmV0dXJuIHJvbGx1cCA/IHJvbGx1cC5jYWxsKG5lc3QsIGFycmF5KSA6IHNvcnRWYWx1ZXMgPyBhcnJheS5zb3J0KHNvcnRWYWx1ZXMpIDogYXJyYXk7XG4gICAgICB2YXIgaSA9IC0xLCBuID0gYXJyYXkubGVuZ3RoLCBrZXkgPSBrZXlzW2RlcHRoKytdLCBrZXlWYWx1ZSwgb2JqZWN0LCBzZXR0ZXIsIHZhbHVlc0J5S2V5ID0gbmV3IGQzX01hcCgpLCB2YWx1ZXM7XG4gICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICBpZiAodmFsdWVzID0gdmFsdWVzQnlLZXkuZ2V0KGtleVZhbHVlID0ga2V5KG9iamVjdCA9IGFycmF5W2ldKSkpIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChvYmplY3QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlc0J5S2V5LnNldChrZXlWYWx1ZSwgWyBvYmplY3QgXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtYXBUeXBlKSB7XG4gICAgICAgIG9iamVjdCA9IG1hcFR5cGUoKTtcbiAgICAgICAgc2V0dGVyID0gZnVuY3Rpb24oa2V5VmFsdWUsIHZhbHVlcykge1xuICAgICAgICAgIG9iamVjdC5zZXQoa2V5VmFsdWUsIG1hcChtYXBUeXBlLCB2YWx1ZXMsIGRlcHRoKSk7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmplY3QgPSB7fTtcbiAgICAgICAgc2V0dGVyID0gZnVuY3Rpb24oa2V5VmFsdWUsIHZhbHVlcykge1xuICAgICAgICAgIG9iamVjdFtrZXlWYWx1ZV0gPSBtYXAobWFwVHlwZSwgdmFsdWVzLCBkZXB0aCk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICB2YWx1ZXNCeUtleS5mb3JFYWNoKHNldHRlcik7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cbiAgICBmdW5jdGlvbiBlbnRyaWVzKG1hcCwgZGVwdGgpIHtcbiAgICAgIGlmIChkZXB0aCA+PSBrZXlzLmxlbmd0aCkgcmV0dXJuIG1hcDtcbiAgICAgIHZhciBhcnJheSA9IFtdLCBzb3J0S2V5ID0gc29ydEtleXNbZGVwdGgrK107XG4gICAgICBtYXAuZm9yRWFjaChmdW5jdGlvbihrZXksIGtleU1hcCkge1xuICAgICAgICBhcnJheS5wdXNoKHtcbiAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICB2YWx1ZXM6IGVudHJpZXMoa2V5TWFwLCBkZXB0aClcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBzb3J0S2V5ID8gYXJyYXkuc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgICAgIHJldHVybiBzb3J0S2V5KGEua2V5LCBiLmtleSk7XG4gICAgICB9KSA6IGFycmF5O1xuICAgIH1cbiAgICBuZXN0Lm1hcCA9IGZ1bmN0aW9uKGFycmF5LCBtYXBUeXBlKSB7XG4gICAgICByZXR1cm4gbWFwKG1hcFR5cGUsIGFycmF5LCAwKTtcbiAgICB9O1xuICAgIG5lc3QuZW50cmllcyA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICByZXR1cm4gZW50cmllcyhtYXAoZDMubWFwLCBhcnJheSwgMCksIDApO1xuICAgIH07XG4gICAgbmVzdC5rZXkgPSBmdW5jdGlvbihkKSB7XG4gICAgICBrZXlzLnB1c2goZCk7XG4gICAgICByZXR1cm4gbmVzdDtcbiAgICB9O1xuICAgIG5lc3Quc29ydEtleXMgPSBmdW5jdGlvbihvcmRlcikge1xuICAgICAgc29ydEtleXNba2V5cy5sZW5ndGggLSAxXSA9IG9yZGVyO1xuICAgICAgcmV0dXJuIG5lc3Q7XG4gICAgfTtcbiAgICBuZXN0LnNvcnRWYWx1ZXMgPSBmdW5jdGlvbihvcmRlcikge1xuICAgICAgc29ydFZhbHVlcyA9IG9yZGVyO1xuICAgICAgcmV0dXJuIG5lc3Q7XG4gICAgfTtcbiAgICBuZXN0LnJvbGx1cCA9IGZ1bmN0aW9uKGYpIHtcbiAgICAgIHJvbGx1cCA9IGY7XG4gICAgICByZXR1cm4gbmVzdDtcbiAgICB9O1xuICAgIHJldHVybiBuZXN0O1xuICB9O1xuICBkMy5zZXQgPSBmdW5jdGlvbihhcnJheSkge1xuICAgIHZhciBzZXQgPSBuZXcgZDNfU2V0KCk7XG4gICAgaWYgKGFycmF5KSBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSBzZXQuYWRkKGFycmF5W2ldKTtcbiAgICByZXR1cm4gc2V0O1xuICB9O1xuICBmdW5jdGlvbiBkM19TZXQoKSB7fVxuICBkM19jbGFzcyhkM19TZXQsIHtcbiAgICBoYXM6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZDNfbWFwX3ByZWZpeCArIHZhbHVlIGluIHRoaXM7XG4gICAgfSxcbiAgICBhZGQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICB0aGlzW2QzX21hcF9wcmVmaXggKyB2YWx1ZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gICAgcmVtb3ZlOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgdmFsdWUgPSBkM19tYXBfcHJlZml4ICsgdmFsdWU7XG4gICAgICByZXR1cm4gdmFsdWUgaW4gdGhpcyAmJiBkZWxldGUgdGhpc1t2YWx1ZV07XG4gICAgfSxcbiAgICB2YWx1ZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9LFxuICAgIGZvckVhY2g6IGZ1bmN0aW9uKGYpIHtcbiAgICAgIGZvciAodmFyIHZhbHVlIGluIHRoaXMpIHtcbiAgICAgICAgaWYgKHZhbHVlLmNoYXJDb2RlQXQoMCkgPT09IGQzX21hcF9wcmVmaXhDb2RlKSB7XG4gICAgICAgICAgZi5jYWxsKHRoaXMsIHZhbHVlLnN1YnN0cmluZygxKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICBkMy5iZWhhdmlvciA9IHt9O1xuICBkMy5yZWJpbmQgPSBmdW5jdGlvbih0YXJnZXQsIHNvdXJjZSkge1xuICAgIHZhciBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGgsIG1ldGhvZDtcbiAgICB3aGlsZSAoKytpIDwgbikgdGFyZ2V0W21ldGhvZCA9IGFyZ3VtZW50c1tpXV0gPSBkM19yZWJpbmQodGFyZ2V0LCBzb3VyY2UsIHNvdXJjZVttZXRob2RdKTtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9O1xuICBmdW5jdGlvbiBkM19yZWJpbmQodGFyZ2V0LCBzb3VyY2UsIG1ldGhvZCkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2YWx1ZSA9IG1ldGhvZC5hcHBseShzb3VyY2UsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHNvdXJjZSA/IHRhcmdldCA6IHZhbHVlO1xuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZDNfdmVuZG9yU3ltYm9sKG9iamVjdCwgbmFtZSkge1xuICAgIGlmIChuYW1lIGluIG9iamVjdCkgcmV0dXJuIG5hbWU7XG4gICAgbmFtZSA9IG5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnN1YnN0cmluZygxKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IGQzX3ZlbmRvclByZWZpeGVzLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgdmFyIHByZWZpeE5hbWUgPSBkM192ZW5kb3JQcmVmaXhlc1tpXSArIG5hbWU7XG4gICAgICBpZiAocHJlZml4TmFtZSBpbiBvYmplY3QpIHJldHVybiBwcmVmaXhOYW1lO1xuICAgIH1cbiAgfVxuICB2YXIgZDNfdmVuZG9yUHJlZml4ZXMgPSBbIFwid2Via2l0XCIsIFwibXNcIiwgXCJtb3pcIiwgXCJNb3pcIiwgXCJvXCIsIFwiT1wiIF07XG4gIHZhciBkM19hcnJheSA9IGQzX2FycmF5U2xpY2U7XG4gIGZ1bmN0aW9uIGQzX2FycmF5Q29weShwc2V1ZG9hcnJheSkge1xuICAgIHZhciBpID0gLTEsIG4gPSBwc2V1ZG9hcnJheS5sZW5ndGgsIGFycmF5ID0gW107XG4gICAgd2hpbGUgKCsraSA8IG4pIGFycmF5LnB1c2gocHNldWRvYXJyYXlbaV0pO1xuICAgIHJldHVybiBhcnJheTtcbiAgfVxuICBmdW5jdGlvbiBkM19hcnJheVNsaWNlKHBzZXVkb2FycmF5KSB7XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHBzZXVkb2FycmF5KTtcbiAgfVxuICB0cnkge1xuICAgIGQzX2FycmF5KGQzX2RvY3VtZW50RWxlbWVudC5jaGlsZE5vZGVzKVswXS5ub2RlVHlwZTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGQzX2FycmF5ID0gZDNfYXJyYXlDb3B5O1xuICB9XG4gIGZ1bmN0aW9uIGQzX25vb3AoKSB7fVxuICBkMy5kaXNwYXRjaCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBkaXNwYXRjaCA9IG5ldyBkM19kaXNwYXRjaCgpLCBpID0gLTEsIG4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBkaXNwYXRjaFthcmd1bWVudHNbaV1dID0gZDNfZGlzcGF0Y2hfZXZlbnQoZGlzcGF0Y2gpO1xuICAgIHJldHVybiBkaXNwYXRjaDtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfZGlzcGF0Y2goKSB7fVxuICBkM19kaXNwYXRjaC5wcm90b3R5cGUub24gPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICAgIHZhciBpID0gdHlwZS5pbmRleE9mKFwiLlwiKSwgbmFtZSA9IFwiXCI7XG4gICAgaWYgKGkgPj0gMCkge1xuICAgICAgbmFtZSA9IHR5cGUuc3Vic3RyaW5nKGkgKyAxKTtcbiAgICAgIHR5cGUgPSB0eXBlLnN1YnN0cmluZygwLCBpKTtcbiAgICB9XG4gICAgaWYgKHR5cGUpIHJldHVybiBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IHRoaXNbdHlwZV0ub24obmFtZSkgOiB0aGlzW3R5cGVdLm9uKG5hbWUsIGxpc3RlbmVyKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIGZvciAodHlwZSBpbiB0aGlzKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KHR5cGUpKSB0aGlzW3R5cGVdLm9uKG5hbWUsIG51bGwpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICB9O1xuICBmdW5jdGlvbiBkM19kaXNwYXRjaF9ldmVudChkaXNwYXRjaCkge1xuICAgIHZhciBsaXN0ZW5lcnMgPSBbXSwgbGlzdGVuZXJCeU5hbWUgPSBuZXcgZDNfTWFwKCk7XG4gICAgZnVuY3Rpb24gZXZlbnQoKSB7XG4gICAgICB2YXIgeiA9IGxpc3RlbmVycywgaSA9IC0xLCBuID0gei5sZW5ndGgsIGw7XG4gICAgICB3aGlsZSAoKytpIDwgbikgaWYgKGwgPSB6W2ldLm9uKSBsLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gZGlzcGF0Y2g7XG4gICAgfVxuICAgIGV2ZW50Lm9uID0gZnVuY3Rpb24obmFtZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsID0gbGlzdGVuZXJCeU5hbWUuZ2V0KG5hbWUpLCBpO1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSByZXR1cm4gbCAmJiBsLm9uO1xuICAgICAgaWYgKGwpIHtcbiAgICAgICAgbC5vbiA9IG51bGw7XG4gICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5zbGljZSgwLCBpID0gbGlzdGVuZXJzLmluZGV4T2YobCkpLmNvbmNhdChsaXN0ZW5lcnMuc2xpY2UoaSArIDEpKTtcbiAgICAgICAgbGlzdGVuZXJCeU5hbWUucmVtb3ZlKG5hbWUpO1xuICAgICAgfVxuICAgICAgaWYgKGxpc3RlbmVyKSBsaXN0ZW5lcnMucHVzaChsaXN0ZW5lckJ5TmFtZS5zZXQobmFtZSwge1xuICAgICAgICBvbjogbGlzdGVuZXJcbiAgICAgIH0pKTtcbiAgICAgIHJldHVybiBkaXNwYXRjaDtcbiAgICB9O1xuICAgIHJldHVybiBldmVudDtcbiAgfVxuICBkMy5ldmVudCA9IG51bGw7XG4gIGZ1bmN0aW9uIGQzX2V2ZW50UHJldmVudERlZmF1bHQoKSB7XG4gICAgZDMuZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuICBmdW5jdGlvbiBkM19ldmVudFNvdXJjZSgpIHtcbiAgICB2YXIgZSA9IGQzLmV2ZW50LCBzO1xuICAgIHdoaWxlIChzID0gZS5zb3VyY2VFdmVudCkgZSA9IHM7XG4gICAgcmV0dXJuIGU7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZXZlbnREaXNwYXRjaCh0YXJnZXQpIHtcbiAgICB2YXIgZGlzcGF0Y2ggPSBuZXcgZDNfZGlzcGF0Y2goKSwgaSA9IDAsIG4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBkaXNwYXRjaFthcmd1bWVudHNbaV1dID0gZDNfZGlzcGF0Y2hfZXZlbnQoZGlzcGF0Y2gpO1xuICAgIGRpc3BhdGNoLm9mID0gZnVuY3Rpb24odGhpeiwgYXJndW1lbnR6KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oZTEpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB2YXIgZTAgPSBlMS5zb3VyY2VFdmVudCA9IGQzLmV2ZW50O1xuICAgICAgICAgIGUxLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgICBkMy5ldmVudCA9IGUxO1xuICAgICAgICAgIGRpc3BhdGNoW2UxLnR5cGVdLmFwcGx5KHRoaXosIGFyZ3VtZW50eik7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgZDMuZXZlbnQgPSBlMDtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBkaXNwYXRjaDtcbiAgfVxuICBkMy5yZXF1b3RlID0gZnVuY3Rpb24ocykge1xuICAgIHJldHVybiBzLnJlcGxhY2UoZDNfcmVxdW90ZV9yZSwgXCJcXFxcJCZcIik7XG4gIH07XG4gIHZhciBkM19yZXF1b3RlX3JlID0gL1tcXFxcXFxeXFwkXFwqXFwrXFw/XFx8XFxbXFxdXFwoXFwpXFwuXFx7XFx9XS9nO1xuICB2YXIgZDNfc3ViY2xhc3MgPSB7fS5fX3Byb3RvX18gPyBmdW5jdGlvbihvYmplY3QsIHByb3RvdHlwZSkge1xuICAgIG9iamVjdC5fX3Byb3RvX18gPSBwcm90b3R5cGU7XG4gIH0gOiBmdW5jdGlvbihvYmplY3QsIHByb3RvdHlwZSkge1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHByb3RvdHlwZSkgb2JqZWN0W3Byb3BlcnR5XSA9IHByb3RvdHlwZVtwcm9wZXJ0eV07XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3NlbGVjdGlvbihncm91cHMpIHtcbiAgICBkM19zdWJjbGFzcyhncm91cHMsIGQzX3NlbGVjdGlvblByb3RvdHlwZSk7XG4gICAgcmV0dXJuIGdyb3VwcztcbiAgfVxuICB2YXIgZDNfc2VsZWN0ID0gZnVuY3Rpb24ocywgbikge1xuICAgIHJldHVybiBuLnF1ZXJ5U2VsZWN0b3Iocyk7XG4gIH0sIGQzX3NlbGVjdEFsbCA9IGZ1bmN0aW9uKHMsIG4pIHtcbiAgICByZXR1cm4gbi5xdWVyeVNlbGVjdG9yQWxsKHMpO1xuICB9LCBkM19zZWxlY3RNYXRjaGVyID0gZDNfZG9jdW1lbnRFbGVtZW50W2QzX3ZlbmRvclN5bWJvbChkM19kb2N1bWVudEVsZW1lbnQsIFwibWF0Y2hlc1NlbGVjdG9yXCIpXSwgZDNfc2VsZWN0TWF0Y2hlcyA9IGZ1bmN0aW9uKG4sIHMpIHtcbiAgICByZXR1cm4gZDNfc2VsZWN0TWF0Y2hlci5jYWxsKG4sIHMpO1xuICB9O1xuICBpZiAodHlwZW9mIFNpenpsZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgZDNfc2VsZWN0ID0gZnVuY3Rpb24ocywgbikge1xuICAgICAgcmV0dXJuIFNpenpsZShzLCBuKVswXSB8fCBudWxsO1xuICAgIH07XG4gICAgZDNfc2VsZWN0QWxsID0gZnVuY3Rpb24ocywgbikge1xuICAgICAgcmV0dXJuIFNpenpsZS51bmlxdWVTb3J0KFNpenpsZShzLCBuKSk7XG4gICAgfTtcbiAgICBkM19zZWxlY3RNYXRjaGVzID0gU2l6emxlLm1hdGNoZXNTZWxlY3RvcjtcbiAgfVxuICBkMy5zZWxlY3Rpb24gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfc2VsZWN0aW9uUm9vdDtcbiAgfTtcbiAgdmFyIGQzX3NlbGVjdGlvblByb3RvdHlwZSA9IGQzLnNlbGVjdGlvbi5wcm90b3R5cGUgPSBbXTtcbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLnNlbGVjdCA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgdmFyIHN1Ymdyb3VwcyA9IFtdLCBzdWJncm91cCwgc3Vibm9kZSwgZ3JvdXAsIG5vZGU7XG4gICAgc2VsZWN0b3IgPSBkM19zZWxlY3Rpb25fc2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgIGZvciAodmFyIGogPSAtMSwgbSA9IHRoaXMubGVuZ3RoOyArK2ogPCBtOyApIHtcbiAgICAgIHN1Ymdyb3Vwcy5wdXNoKHN1Ymdyb3VwID0gW10pO1xuICAgICAgc3ViZ3JvdXAucGFyZW50Tm9kZSA9IChncm91cCA9IHRoaXNbal0pLnBhcmVudE5vZGU7XG4gICAgICBmb3IgKHZhciBpID0gLTEsIG4gPSBncm91cC5sZW5ndGg7ICsraSA8IG47ICkge1xuICAgICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgICAgc3ViZ3JvdXAucHVzaChzdWJub2RlID0gc2VsZWN0b3IuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBqKSk7XG4gICAgICAgICAgaWYgKHN1Ym5vZGUgJiYgXCJfX2RhdGFfX1wiIGluIG5vZGUpIHN1Ym5vZGUuX19kYXRhX18gPSBub2RlLl9fZGF0YV9fO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN1Ymdyb3VwLnB1c2gobnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGQzX3NlbGVjdGlvbihzdWJncm91cHMpO1xuICB9O1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fc2VsZWN0b3Ioc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgPyBzZWxlY3RvciA6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGQzX3NlbGVjdChzZWxlY3RvciwgdGhpcyk7XG4gICAgfTtcbiAgfVxuICBkM19zZWxlY3Rpb25Qcm90b3R5cGUuc2VsZWN0QWxsID0gZnVuY3Rpb24oc2VsZWN0b3IpIHtcbiAgICB2YXIgc3ViZ3JvdXBzID0gW10sIHN1Ymdyb3VwLCBub2RlO1xuICAgIHNlbGVjdG9yID0gZDNfc2VsZWN0aW9uX3NlbGVjdG9yQWxsKHNlbGVjdG9yKTtcbiAgICBmb3IgKHZhciBqID0gLTEsIG0gPSB0aGlzLmxlbmd0aDsgKytqIDwgbTsgKSB7XG4gICAgICBmb3IgKHZhciBncm91cCA9IHRoaXNbal0sIGkgPSAtMSwgbiA9IGdyb3VwLmxlbmd0aDsgKytpIDwgbjsgKSB7XG4gICAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgICAgICBzdWJncm91cHMucHVzaChzdWJncm91cCA9IGQzX2FycmF5KHNlbGVjdG9yLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgaikpKTtcbiAgICAgICAgICBzdWJncm91cC5wYXJlbnROb2RlID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZDNfc2VsZWN0aW9uKHN1Ymdyb3Vwcyk7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3NlbGVjdGlvbl9zZWxlY3RvckFsbChzZWxlY3Rvcikge1xuICAgIHJldHVybiB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiA/IHNlbGVjdG9yIDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZDNfc2VsZWN0QWxsKHNlbGVjdG9yLCB0aGlzKTtcbiAgICB9O1xuICB9XG4gIHZhciBkM19uc1ByZWZpeCA9IHtcbiAgICBzdmc6IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIixcbiAgICB4aHRtbDogXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCIsXG4gICAgeGxpbms6IFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiLFxuICAgIHhtbDogXCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VcIixcbiAgICB4bWxuczogXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zL1wiXG4gIH07XG4gIGQzLm5zID0ge1xuICAgIHByZWZpeDogZDNfbnNQcmVmaXgsXG4gICAgcXVhbGlmeTogZnVuY3Rpb24obmFtZSkge1xuICAgICAgdmFyIGkgPSBuYW1lLmluZGV4T2YoXCI6XCIpLCBwcmVmaXggPSBuYW1lO1xuICAgICAgaWYgKGkgPj0gMCkge1xuICAgICAgICBwcmVmaXggPSBuYW1lLnN1YnN0cmluZygwLCBpKTtcbiAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKGkgKyAxKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkM19uc1ByZWZpeC5oYXNPd25Qcm9wZXJ0eShwcmVmaXgpID8ge1xuICAgICAgICBzcGFjZTogZDNfbnNQcmVmaXhbcHJlZml4XSxcbiAgICAgICAgbG9jYWw6IG5hbWVcbiAgICAgIH0gOiBuYW1lO1xuICAgIH1cbiAgfTtcbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLmF0dHIgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHZhciBub2RlID0gdGhpcy5ub2RlKCk7XG4gICAgICAgIG5hbWUgPSBkMy5ucy5xdWFsaWZ5KG5hbWUpO1xuICAgICAgICByZXR1cm4gbmFtZS5sb2NhbCA/IG5vZGUuZ2V0QXR0cmlidXRlTlMobmFtZS5zcGFjZSwgbmFtZS5sb2NhbCkgOiBub2RlLmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFsdWUgaW4gbmFtZSkgdGhpcy5lYWNoKGQzX3NlbGVjdGlvbl9hdHRyKHZhbHVlLCBuYW1lW3ZhbHVlXSkpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmVhY2goZDNfc2VsZWN0aW9uX2F0dHIobmFtZSwgdmFsdWUpKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc2VsZWN0aW9uX2F0dHIobmFtZSwgdmFsdWUpIHtcbiAgICBuYW1lID0gZDMubnMucXVhbGlmeShuYW1lKTtcbiAgICBmdW5jdGlvbiBhdHRyTnVsbCgpIHtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBhdHRyTnVsbE5TKCkge1xuICAgICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGVOUyhuYW1lLnNwYWNlLCBuYW1lLmxvY2FsKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYXR0ckNvbnN0YW50KCkge1xuICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBhdHRyQ29uc3RhbnROUygpIHtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlTlMobmFtZS5zcGFjZSwgbmFtZS5sb2NhbCwgdmFsdWUpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBhdHRyRnVuY3Rpb24oKSB7XG4gICAgICB2YXIgeCA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICBpZiAoeCA9PSBudWxsKSB0aGlzLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTsgZWxzZSB0aGlzLnNldEF0dHJpYnV0ZShuYW1lLCB4KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYXR0ckZ1bmN0aW9uTlMoKSB7XG4gICAgICB2YXIgeCA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICBpZiAoeCA9PSBudWxsKSB0aGlzLnJlbW92ZUF0dHJpYnV0ZU5TKG5hbWUuc3BhY2UsIG5hbWUubG9jYWwpOyBlbHNlIHRoaXMuc2V0QXR0cmlidXRlTlMobmFtZS5zcGFjZSwgbmFtZS5sb2NhbCwgeCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZSA9PSBudWxsID8gbmFtZS5sb2NhbCA/IGF0dHJOdWxsTlMgOiBhdHRyTnVsbCA6IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gbmFtZS5sb2NhbCA/IGF0dHJGdW5jdGlvbk5TIDogYXR0ckZ1bmN0aW9uIDogbmFtZS5sb2NhbCA/IGF0dHJDb25zdGFudE5TIDogYXR0ckNvbnN0YW50O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2NvbGxhcHNlKHMpIHtcbiAgICByZXR1cm4gcy50cmltKCkucmVwbGFjZSgvXFxzKy9nLCBcIiBcIik7XG4gIH1cbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLmNsYXNzZWQgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHZhciBub2RlID0gdGhpcy5ub2RlKCksIG4gPSAobmFtZSA9IG5hbWUudHJpbSgpLnNwbGl0KC9efFxccysvZykpLmxlbmd0aCwgaSA9IC0xO1xuICAgICAgICBpZiAodmFsdWUgPSBub2RlLmNsYXNzTGlzdCkge1xuICAgICAgICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoIXZhbHVlLmNvbnRhaW5zKG5hbWVbaV0pKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWUgPSBub2RlLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpO1xuICAgICAgICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoIWQzX3NlbGVjdGlvbl9jbGFzc2VkUmUobmFtZVtpXSkudGVzdCh2YWx1ZSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFsdWUgaW4gbmFtZSkgdGhpcy5lYWNoKGQzX3NlbGVjdGlvbl9jbGFzc2VkKHZhbHVlLCBuYW1lW3ZhbHVlXSkpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmVhY2goZDNfc2VsZWN0aW9uX2NsYXNzZWQobmFtZSwgdmFsdWUpKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc2VsZWN0aW9uX2NsYXNzZWRSZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoXCIoPzpefFxcXFxzKylcIiArIGQzLnJlcXVvdGUobmFtZSkgKyBcIig/OlxcXFxzK3wkKVwiLCBcImdcIik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc2VsZWN0aW9uX2NsYXNzZWQobmFtZSwgdmFsdWUpIHtcbiAgICBuYW1lID0gbmFtZS50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoZDNfc2VsZWN0aW9uX2NsYXNzZWROYW1lKTtcbiAgICB2YXIgbiA9IG5hbWUubGVuZ3RoO1xuICAgIGZ1bmN0aW9uIGNsYXNzZWRDb25zdGFudCgpIHtcbiAgICAgIHZhciBpID0gLTE7XG4gICAgICB3aGlsZSAoKytpIDwgbikgbmFtZVtpXSh0aGlzLCB2YWx1ZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNsYXNzZWRGdW5jdGlvbigpIHtcbiAgICAgIHZhciBpID0gLTEsIHggPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIG5hbWVbaV0odGhpcywgeCk7XG4gICAgfVxuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiA/IGNsYXNzZWRGdW5jdGlvbiA6IGNsYXNzZWRDb25zdGFudDtcbiAgfVxuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fY2xhc3NlZE5hbWUobmFtZSkge1xuICAgIHZhciByZSA9IGQzX3NlbGVjdGlvbl9jbGFzc2VkUmUobmFtZSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUsIHZhbHVlKSB7XG4gICAgICBpZiAoYyA9IG5vZGUuY2xhc3NMaXN0KSByZXR1cm4gdmFsdWUgPyBjLmFkZChuYW1lKSA6IGMucmVtb3ZlKG5hbWUpO1xuICAgICAgdmFyIGMgPSBub2RlLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpIHx8IFwiXCI7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgcmUubGFzdEluZGV4ID0gMDtcbiAgICAgICAgaWYgKCFyZS50ZXN0KGMpKSBub2RlLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIGQzX2NvbGxhcHNlKGMgKyBcIiBcIiArIG5hbWUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgZDNfY29sbGFwc2UoYy5yZXBsYWNlKHJlLCBcIiBcIikpKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIGQzX3NlbGVjdGlvblByb3RvdHlwZS5zdHlsZSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICAgIHZhciBuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICBpZiAobiA8IDMpIHtcbiAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICBpZiAobiA8IDIpIHZhbHVlID0gXCJcIjtcbiAgICAgICAgZm9yIChwcmlvcml0eSBpbiBuYW1lKSB0aGlzLmVhY2goZDNfc2VsZWN0aW9uX3N0eWxlKHByaW9yaXR5LCBuYW1lW3ByaW9yaXR5XSwgdmFsdWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBpZiAobiA8IDIpIHJldHVybiBkM193aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLm5vZGUoKSwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKTtcbiAgICAgIHByaW9yaXR5ID0gXCJcIjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZWFjaChkM19zZWxlY3Rpb25fc3R5bGUobmFtZSwgdmFsdWUsIHByaW9yaXR5KSk7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3NlbGVjdGlvbl9zdHlsZShuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpIHtcbiAgICBmdW5jdGlvbiBzdHlsZU51bGwoKSB7XG4gICAgICB0aGlzLnN0eWxlLnJlbW92ZVByb3BlcnR5KG5hbWUpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzdHlsZUNvbnN0YW50KCkge1xuICAgICAgdGhpcy5zdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzdHlsZUZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHggPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgaWYgKHggPT0gbnVsbCkgdGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKTsgZWxzZSB0aGlzLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHgsIHByaW9yaXR5KTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGwgPyBzdHlsZU51bGwgOiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiA/IHN0eWxlRnVuY3Rpb24gOiBzdHlsZUNvbnN0YW50O1xuICB9XG4gIGQzX3NlbGVjdGlvblByb3RvdHlwZS5wcm9wZXJ0eSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3RyaW5nXCIpIHJldHVybiB0aGlzLm5vZGUoKVtuYW1lXTtcbiAgICAgIGZvciAodmFsdWUgaW4gbmFtZSkgdGhpcy5lYWNoKGQzX3NlbGVjdGlvbl9wcm9wZXJ0eSh2YWx1ZSwgbmFtZVt2YWx1ZV0pKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5lYWNoKGQzX3NlbGVjdGlvbl9wcm9wZXJ0eShuYW1lLCB2YWx1ZSkpO1xuICB9O1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fcHJvcGVydHkobmFtZSwgdmFsdWUpIHtcbiAgICBmdW5jdGlvbiBwcm9wZXJ0eU51bGwoKSB7XG4gICAgICBkZWxldGUgdGhpc1tuYW1lXTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHJvcGVydHlDb25zdGFudCgpIHtcbiAgICAgIHRoaXNbbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHJvcGVydHlGdW5jdGlvbigpIHtcbiAgICAgIHZhciB4ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIGlmICh4ID09IG51bGwpIGRlbGV0ZSB0aGlzW25hbWVdOyBlbHNlIHRoaXNbbmFtZV0gPSB4O1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/IHByb3BlcnR5TnVsbCA6IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gcHJvcGVydHlGdW5jdGlvbiA6IHByb3BlcnR5Q29uc3RhbnQ7XG4gIH1cbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy5lYWNoKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB0aGlzLnRleHRDb250ZW50ID0gdiA9PSBudWxsID8gXCJcIiA6IHY7XG4gICAgfSA6IHZhbHVlID09IG51bGwgPyBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMudGV4dENvbnRlbnQgPSBcIlwiO1xuICAgIH0gOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMudGV4dENvbnRlbnQgPSB2YWx1ZTtcbiAgICB9KSA6IHRoaXMubm9kZSgpLnRleHRDb250ZW50O1xuICB9O1xuICBkM19zZWxlY3Rpb25Qcm90b3R5cGUuaHRtbCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLmVhY2godHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHRoaXMuaW5uZXJIVE1MID0gdiA9PSBudWxsID8gXCJcIiA6IHY7XG4gICAgfSA6IHZhbHVlID09IG51bGwgPyBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuaW5uZXJIVE1MID0gXCJcIjtcbiAgICB9IDogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmlubmVySFRNTCA9IHZhbHVlO1xuICAgIH0pIDogdGhpcy5ub2RlKCkuaW5uZXJIVE1MO1xuICB9O1xuICBkM19zZWxlY3Rpb25Qcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24obmFtZSkge1xuICAgIG5hbWUgPSBkM19zZWxlY3Rpb25fY3JlYXRvcihuYW1lKTtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3QoZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5hcHBlbmRDaGlsZChuYW1lLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuICAgIH0pO1xuICB9O1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fY3JlYXRvcihuYW1lKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBuYW1lID09PSBcImZ1bmN0aW9uXCIgPyBuYW1lIDogKG5hbWUgPSBkMy5ucy5xdWFsaWZ5KG5hbWUpKS5sb2NhbCA/IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGQzX2RvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhuYW1lLnNwYWNlLCBuYW1lLmxvY2FsKTtcbiAgICB9IDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZDNfZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHRoaXMubmFtZXNwYWNlVVJJLCBuYW1lKTtcbiAgICB9O1xuICB9XG4gIGQzX3NlbGVjdGlvblByb3RvdHlwZS5pbnNlcnQgPSBmdW5jdGlvbihuYW1lLCBiZWZvcmUpIHtcbiAgICBuYW1lID0gZDNfc2VsZWN0aW9uX2NyZWF0b3IobmFtZSk7XG4gICAgYmVmb3JlID0gZDNfc2VsZWN0aW9uX3NlbGVjdG9yKGJlZm9yZSk7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0QmVmb3JlKG5hbWUuYXBwbHkodGhpcywgYXJndW1lbnRzKSwgYmVmb3JlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuICAgIH0pO1xuICB9O1xuICBkM19zZWxlY3Rpb25Qcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XG4gICAgICBpZiAocGFyZW50KSBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcyk7XG4gICAgfSk7XG4gIH07XG4gIGQzX3NlbGVjdGlvblByb3RvdHlwZS5kYXRhID0gZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgIHZhciBpID0gLTEsIG4gPSB0aGlzLmxlbmd0aCwgZ3JvdXAsIG5vZGU7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2YWx1ZSA9IG5ldyBBcnJheShuID0gKGdyb3VwID0gdGhpc1swXSkubGVuZ3RoKTtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgICAgICB2YWx1ZVtpXSA9IG5vZGUuX19kYXRhX187XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYmluZChncm91cCwgZ3JvdXBEYXRhKSB7XG4gICAgICB2YXIgaSwgbiA9IGdyb3VwLmxlbmd0aCwgbSA9IGdyb3VwRGF0YS5sZW5ndGgsIG4wID0gTWF0aC5taW4obiwgbSksIHVwZGF0ZU5vZGVzID0gbmV3IEFycmF5KG0pLCBlbnRlck5vZGVzID0gbmV3IEFycmF5KG0pLCBleGl0Tm9kZXMgPSBuZXcgQXJyYXkobiksIG5vZGUsIG5vZGVEYXRhO1xuICAgICAgaWYgKGtleSkge1xuICAgICAgICB2YXIgbm9kZUJ5S2V5VmFsdWUgPSBuZXcgZDNfTWFwKCksIGRhdGFCeUtleVZhbHVlID0gbmV3IGQzX01hcCgpLCBrZXlWYWx1ZXMgPSBbXSwga2V5VmFsdWU7XG4gICAgICAgIGZvciAoaSA9IC0xOyArK2kgPCBuOyApIHtcbiAgICAgICAgICBrZXlWYWx1ZSA9IGtleS5jYWxsKG5vZGUgPSBncm91cFtpXSwgbm9kZS5fX2RhdGFfXywgaSk7XG4gICAgICAgICAgaWYgKG5vZGVCeUtleVZhbHVlLmhhcyhrZXlWYWx1ZSkpIHtcbiAgICAgICAgICAgIGV4aXROb2Rlc1tpXSA9IG5vZGU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5vZGVCeUtleVZhbHVlLnNldChrZXlWYWx1ZSwgbm9kZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGtleVZhbHVlcy5wdXNoKGtleVZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAtMTsgKytpIDwgbTsgKSB7XG4gICAgICAgICAga2V5VmFsdWUgPSBrZXkuY2FsbChncm91cERhdGEsIG5vZGVEYXRhID0gZ3JvdXBEYXRhW2ldLCBpKTtcbiAgICAgICAgICBpZiAobm9kZSA9IG5vZGVCeUtleVZhbHVlLmdldChrZXlWYWx1ZSkpIHtcbiAgICAgICAgICAgIHVwZGF0ZU5vZGVzW2ldID0gbm9kZTtcbiAgICAgICAgICAgIG5vZGUuX19kYXRhX18gPSBub2RlRGF0YTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFkYXRhQnlLZXlWYWx1ZS5oYXMoa2V5VmFsdWUpKSB7XG4gICAgICAgICAgICBlbnRlck5vZGVzW2ldID0gZDNfc2VsZWN0aW9uX2RhdGFOb2RlKG5vZGVEYXRhKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGF0YUJ5S2V5VmFsdWUuc2V0KGtleVZhbHVlLCBub2RlRGF0YSk7XG4gICAgICAgICAgbm9kZUJ5S2V5VmFsdWUucmVtb3ZlKGtleVZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAtMTsgKytpIDwgbjsgKSB7XG4gICAgICAgICAgaWYgKG5vZGVCeUtleVZhbHVlLmhhcyhrZXlWYWx1ZXNbaV0pKSB7XG4gICAgICAgICAgICBleGl0Tm9kZXNbaV0gPSBncm91cFtpXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoaSA9IC0xOyArK2kgPCBuMDsgKSB7XG4gICAgICAgICAgbm9kZSA9IGdyb3VwW2ldO1xuICAgICAgICAgIG5vZGVEYXRhID0gZ3JvdXBEYXRhW2ldO1xuICAgICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICBub2RlLl9fZGF0YV9fID0gbm9kZURhdGE7XG4gICAgICAgICAgICB1cGRhdGVOb2Rlc1tpXSA9IG5vZGU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVudGVyTm9kZXNbaV0gPSBkM19zZWxlY3Rpb25fZGF0YU5vZGUobm9kZURhdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKDtpIDwgbTsgKytpKSB7XG4gICAgICAgICAgZW50ZXJOb2Rlc1tpXSA9IGQzX3NlbGVjdGlvbl9kYXRhTm9kZShncm91cERhdGFbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoO2kgPCBuOyArK2kpIHtcbiAgICAgICAgICBleGl0Tm9kZXNbaV0gPSBncm91cFtpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZW50ZXJOb2Rlcy51cGRhdGUgPSB1cGRhdGVOb2RlcztcbiAgICAgIGVudGVyTm9kZXMucGFyZW50Tm9kZSA9IHVwZGF0ZU5vZGVzLnBhcmVudE5vZGUgPSBleGl0Tm9kZXMucGFyZW50Tm9kZSA9IGdyb3VwLnBhcmVudE5vZGU7XG4gICAgICBlbnRlci5wdXNoKGVudGVyTm9kZXMpO1xuICAgICAgdXBkYXRlLnB1c2godXBkYXRlTm9kZXMpO1xuICAgICAgZXhpdC5wdXNoKGV4aXROb2Rlcyk7XG4gICAgfVxuICAgIHZhciBlbnRlciA9IGQzX3NlbGVjdGlvbl9lbnRlcihbXSksIHVwZGF0ZSA9IGQzX3NlbGVjdGlvbihbXSksIGV4aXQgPSBkM19zZWxlY3Rpb24oW10pO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgYmluZChncm91cCA9IHRoaXNbaV0sIHZhbHVlLmNhbGwoZ3JvdXAsIGdyb3VwLnBhcmVudE5vZGUuX19kYXRhX18sIGkpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgYmluZChncm91cCA9IHRoaXNbaV0sIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdXBkYXRlLmVudGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZW50ZXI7XG4gICAgfTtcbiAgICB1cGRhdGUuZXhpdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGV4aXQ7XG4gICAgfTtcbiAgICByZXR1cm4gdXBkYXRlO1xuICB9O1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fZGF0YU5vZGUoZGF0YSkge1xuICAgIHJldHVybiB7XG4gICAgICBfX2RhdGFfXzogZGF0YVxuICAgIH07XG4gIH1cbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLmRhdHVtID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHRoaXMucHJvcGVydHkoXCJfX2RhdGFfX1wiLCB2YWx1ZSkgOiB0aGlzLnByb3BlcnR5KFwiX19kYXRhX19cIik7XG4gIH07XG4gIGQzX3NlbGVjdGlvblByb3RvdHlwZS5maWx0ZXIgPSBmdW5jdGlvbihmaWx0ZXIpIHtcbiAgICB2YXIgc3ViZ3JvdXBzID0gW10sIHN1Ymdyb3VwLCBncm91cCwgbm9kZTtcbiAgICBpZiAodHlwZW9mIGZpbHRlciAhPT0gXCJmdW5jdGlvblwiKSBmaWx0ZXIgPSBkM19zZWxlY3Rpb25fZmlsdGVyKGZpbHRlcik7XG4gICAgZm9yICh2YXIgaiA9IDAsIG0gPSB0aGlzLmxlbmd0aDsgaiA8IG07IGorKykge1xuICAgICAgc3ViZ3JvdXBzLnB1c2goc3ViZ3JvdXAgPSBbXSk7XG4gICAgICBzdWJncm91cC5wYXJlbnROb2RlID0gKGdyb3VwID0gdGhpc1tqXSkucGFyZW50Tm9kZTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBuID0gZ3JvdXAubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiBmaWx0ZXIuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpKSkge1xuICAgICAgICAgIHN1Ymdyb3VwLnB1c2gobm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGQzX3NlbGVjdGlvbihzdWJncm91cHMpO1xuICB9O1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fZmlsdGVyKHNlbGVjdG9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGQzX3NlbGVjdE1hdGNoZXModGhpcywgc2VsZWN0b3IpO1xuICAgIH07XG4gIH1cbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLm9yZGVyID0gZnVuY3Rpb24oKSB7XG4gICAgZm9yICh2YXIgaiA9IC0xLCBtID0gdGhpcy5sZW5ndGg7ICsraiA8IG07ICkge1xuICAgICAgZm9yICh2YXIgZ3JvdXAgPSB0aGlzW2pdLCBpID0gZ3JvdXAubGVuZ3RoIC0gMSwgbmV4dCA9IGdyb3VwW2ldLCBub2RlOyAtLWkgPj0gMDsgKSB7XG4gICAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgICAgICBpZiAobmV4dCAmJiBuZXh0ICE9PSBub2RlLm5leHRTaWJsaW5nKSBuZXh0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIG5leHQpO1xuICAgICAgICAgIG5leHQgPSBub2RlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICBkM19zZWxlY3Rpb25Qcm90b3R5cGUuc29ydCA9IGZ1bmN0aW9uKGNvbXBhcmF0b3IpIHtcbiAgICBjb21wYXJhdG9yID0gZDNfc2VsZWN0aW9uX3NvcnRDb21wYXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgZm9yICh2YXIgaiA9IC0xLCBtID0gdGhpcy5sZW5ndGg7ICsraiA8IG07ICkgdGhpc1tqXS5zb3J0KGNvbXBhcmF0b3IpO1xuICAgIHJldHVybiB0aGlzLm9yZGVyKCk7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3NlbGVjdGlvbl9zb3J0Q29tcGFyYXRvcihjb21wYXJhdG9yKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSBjb21wYXJhdG9yID0gZDMuYXNjZW5kaW5nO1xuICAgIHJldHVybiBmdW5jdGlvbihhLCBiKSB7XG4gICAgICByZXR1cm4gIWEgLSAhYiB8fCBjb21wYXJhdG9yKGEuX19kYXRhX18sIGIuX19kYXRhX18pO1xuICAgIH07XG4gIH1cbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLmVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgIHJldHVybiBkM19zZWxlY3Rpb25fZWFjaCh0aGlzLCBmdW5jdGlvbihub2RlLCBpLCBqKSB7XG4gICAgICBjYWxsYmFjay5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGopO1xuICAgIH0pO1xuICB9O1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fZWFjaChncm91cHMsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIgaiA9IDAsIG0gPSBncm91cHMubGVuZ3RoOyBqIDwgbTsgaisrKSB7XG4gICAgICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgaSA9IDAsIG4gPSBncm91cC5sZW5ndGgsIG5vZGU7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkgY2FsbGJhY2sobm9kZSwgaSwgaik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBncm91cHM7XG4gIH1cbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLmNhbGwgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgIHZhciBhcmdzID0gZDNfYXJyYXkoYXJndW1lbnRzKTtcbiAgICBjYWxsYmFjay5hcHBseShhcmdzWzBdID0gdGhpcywgYXJncyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG4gIGQzX3NlbGVjdGlvblByb3RvdHlwZS5lbXB0eSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAhdGhpcy5ub2RlKCk7XG4gIH07XG4gIGQzX3NlbGVjdGlvblByb3RvdHlwZS5ub2RlID0gZnVuY3Rpb24oKSB7XG4gICAgZm9yICh2YXIgaiA9IDAsIG0gPSB0aGlzLmxlbmd0aDsgaiA8IG07IGorKykge1xuICAgICAgZm9yICh2YXIgZ3JvdXAgPSB0aGlzW2pdLCBpID0gMCwgbiA9IGdyb3VwLmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgICB2YXIgbm9kZSA9IGdyb3VwW2ldO1xuICAgICAgICBpZiAobm9kZSkgcmV0dXJuIG5vZGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9O1xuICBkM19zZWxlY3Rpb25Qcm90b3R5cGUuc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBuID0gMDtcbiAgICB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICArK247XG4gICAgfSk7XG4gICAgcmV0dXJuIG47XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3NlbGVjdGlvbl9lbnRlcihzZWxlY3Rpb24pIHtcbiAgICBkM19zdWJjbGFzcyhzZWxlY3Rpb24sIGQzX3NlbGVjdGlvbl9lbnRlclByb3RvdHlwZSk7XG4gICAgcmV0dXJuIHNlbGVjdGlvbjtcbiAgfVxuICB2YXIgZDNfc2VsZWN0aW9uX2VudGVyUHJvdG90eXBlID0gW107XG4gIGQzLnNlbGVjdGlvbi5lbnRlciA9IGQzX3NlbGVjdGlvbl9lbnRlcjtcbiAgZDMuc2VsZWN0aW9uLmVudGVyLnByb3RvdHlwZSA9IGQzX3NlbGVjdGlvbl9lbnRlclByb3RvdHlwZTtcbiAgZDNfc2VsZWN0aW9uX2VudGVyUHJvdG90eXBlLmFwcGVuZCA9IGQzX3NlbGVjdGlvblByb3RvdHlwZS5hcHBlbmQ7XG4gIGQzX3NlbGVjdGlvbl9lbnRlclByb3RvdHlwZS5lbXB0eSA9IGQzX3NlbGVjdGlvblByb3RvdHlwZS5lbXB0eTtcbiAgZDNfc2VsZWN0aW9uX2VudGVyUHJvdG90eXBlLm5vZGUgPSBkM19zZWxlY3Rpb25Qcm90b3R5cGUubm9kZTtcbiAgZDNfc2VsZWN0aW9uX2VudGVyUHJvdG90eXBlLmNhbGwgPSBkM19zZWxlY3Rpb25Qcm90b3R5cGUuY2FsbDtcbiAgZDNfc2VsZWN0aW9uX2VudGVyUHJvdG90eXBlLnNpemUgPSBkM19zZWxlY3Rpb25Qcm90b3R5cGUuc2l6ZTtcbiAgZDNfc2VsZWN0aW9uX2VudGVyUHJvdG90eXBlLnNlbGVjdCA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgdmFyIHN1Ymdyb3VwcyA9IFtdLCBzdWJncm91cCwgc3Vibm9kZSwgdXBncm91cCwgZ3JvdXAsIG5vZGU7XG4gICAgZm9yICh2YXIgaiA9IC0xLCBtID0gdGhpcy5sZW5ndGg7ICsraiA8IG07ICkge1xuICAgICAgdXBncm91cCA9IChncm91cCA9IHRoaXNbal0pLnVwZGF0ZTtcbiAgICAgIHN1Ymdyb3Vwcy5wdXNoKHN1Ymdyb3VwID0gW10pO1xuICAgICAgc3ViZ3JvdXAucGFyZW50Tm9kZSA9IGdyb3VwLnBhcmVudE5vZGU7XG4gICAgICBmb3IgKHZhciBpID0gLTEsIG4gPSBncm91cC5sZW5ndGg7ICsraSA8IG47ICkge1xuICAgICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgICAgc3ViZ3JvdXAucHVzaCh1cGdyb3VwW2ldID0gc3Vibm9kZSA9IHNlbGVjdG9yLmNhbGwoZ3JvdXAucGFyZW50Tm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgaikpO1xuICAgICAgICAgIHN1Ym5vZGUuX19kYXRhX18gPSBub2RlLl9fZGF0YV9fO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN1Ymdyb3VwLnB1c2gobnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGQzX3NlbGVjdGlvbihzdWJncm91cHMpO1xuICB9O1xuICBkM19zZWxlY3Rpb25fZW50ZXJQcm90b3R5cGUuaW5zZXJ0ID0gZnVuY3Rpb24obmFtZSwgYmVmb3JlKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSBiZWZvcmUgPSBkM19zZWxlY3Rpb25fZW50ZXJJbnNlcnRCZWZvcmUodGhpcyk7XG4gICAgcmV0dXJuIGQzX3NlbGVjdGlvblByb3RvdHlwZS5pbnNlcnQuY2FsbCh0aGlzLCBuYW1lLCBiZWZvcmUpO1xuICB9O1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fZW50ZXJJbnNlcnRCZWZvcmUoZW50ZXIpIHtcbiAgICB2YXIgaTAsIGowO1xuICAgIHJldHVybiBmdW5jdGlvbihkLCBpLCBqKSB7XG4gICAgICB2YXIgZ3JvdXAgPSBlbnRlcltqXS51cGRhdGUsIG4gPSBncm91cC5sZW5ndGgsIG5vZGU7XG4gICAgICBpZiAoaiAhPSBqMCkgajAgPSBqLCBpMCA9IDA7XG4gICAgICBpZiAoaSA+PSBpMCkgaTAgPSBpICsgMTtcbiAgICAgIHdoaWxlICghKG5vZGUgPSBncm91cFtpMF0pICYmICsraTAgPCBuKSA7XG4gICAgICByZXR1cm4gbm9kZTtcbiAgICB9O1xuICB9XG4gIGQzX3NlbGVjdGlvblByb3RvdHlwZS50cmFuc2l0aW9uID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGlkID0gZDNfdHJhbnNpdGlvbkluaGVyaXRJZCB8fCArK2QzX3RyYW5zaXRpb25JZCwgc3ViZ3JvdXBzID0gW10sIHN1Ymdyb3VwLCBub2RlLCB0cmFuc2l0aW9uID0gZDNfdHJhbnNpdGlvbkluaGVyaXQgfHwge1xuICAgICAgdGltZTogRGF0ZS5ub3coKSxcbiAgICAgIGVhc2U6IGQzX2Vhc2VfY3ViaWNJbk91dCxcbiAgICAgIGRlbGF5OiAwLFxuICAgICAgZHVyYXRpb246IDI1MFxuICAgIH07XG4gICAgZm9yICh2YXIgaiA9IC0xLCBtID0gdGhpcy5sZW5ndGg7ICsraiA8IG07ICkge1xuICAgICAgc3ViZ3JvdXBzLnB1c2goc3ViZ3JvdXAgPSBbXSk7XG4gICAgICBmb3IgKHZhciBncm91cCA9IHRoaXNbal0sIGkgPSAtMSwgbiA9IGdyb3VwLmxlbmd0aDsgKytpIDwgbjsgKSB7XG4gICAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIGQzX3RyYW5zaXRpb25Ob2RlKG5vZGUsIGksIGlkLCB0cmFuc2l0aW9uKTtcbiAgICAgICAgc3ViZ3JvdXAucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGQzX3RyYW5zaXRpb24oc3ViZ3JvdXBzLCBpZCk7XG4gIH07XG4gIGQzLnNlbGVjdCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICB2YXIgZ3JvdXAgPSBbIHR5cGVvZiBub2RlID09PSBcInN0cmluZ1wiID8gZDNfc2VsZWN0KG5vZGUsIGQzX2RvY3VtZW50KSA6IG5vZGUgXTtcbiAgICBncm91cC5wYXJlbnROb2RlID0gZDNfZG9jdW1lbnRFbGVtZW50O1xuICAgIHJldHVybiBkM19zZWxlY3Rpb24oWyBncm91cCBdKTtcbiAgfTtcbiAgZDMuc2VsZWN0QWxsID0gZnVuY3Rpb24obm9kZXMpIHtcbiAgICB2YXIgZ3JvdXAgPSBkM19hcnJheSh0eXBlb2Ygbm9kZXMgPT09IFwic3RyaW5nXCIgPyBkM19zZWxlY3RBbGwobm9kZXMsIGQzX2RvY3VtZW50KSA6IG5vZGVzKTtcbiAgICBncm91cC5wYXJlbnROb2RlID0gZDNfZG9jdW1lbnRFbGVtZW50O1xuICAgIHJldHVybiBkM19zZWxlY3Rpb24oWyBncm91cCBdKTtcbiAgfTtcbiAgdmFyIGQzX3NlbGVjdGlvblJvb3QgPSBkMy5zZWxlY3QoZDNfZG9jdW1lbnRFbGVtZW50KTtcbiAgZDNfc2VsZWN0aW9uUHJvdG90eXBlLm9uID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIsIGNhcHR1cmUpIHtcbiAgICB2YXIgbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgaWYgKG4gPCAzKSB7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgaWYgKG4gPCAyKSBsaXN0ZW5lciA9IGZhbHNlO1xuICAgICAgICBmb3IgKGNhcHR1cmUgaW4gdHlwZSkgdGhpcy5lYWNoKGQzX3NlbGVjdGlvbl9vbihjYXB0dXJlLCB0eXBlW2NhcHR1cmVdLCBsaXN0ZW5lcikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmIChuIDwgMikgcmV0dXJuIChuID0gdGhpcy5ub2RlKClbXCJfX29uXCIgKyB0eXBlXSkgJiYgbi5fO1xuICAgICAgY2FwdHVyZSA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5lYWNoKGQzX3NlbGVjdGlvbl9vbih0eXBlLCBsaXN0ZW5lciwgY2FwdHVyZSkpO1xuICB9O1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fb24odHlwZSwgbGlzdGVuZXIsIGNhcHR1cmUpIHtcbiAgICB2YXIgbmFtZSA9IFwiX19vblwiICsgdHlwZSwgaSA9IHR5cGUuaW5kZXhPZihcIi5cIiksIHdyYXAgPSBkM19zZWxlY3Rpb25fb25MaXN0ZW5lcjtcbiAgICBpZiAoaSA+IDApIHR5cGUgPSB0eXBlLnN1YnN0cmluZygwLCBpKTtcbiAgICB2YXIgZmlsdGVyID0gZDNfc2VsZWN0aW9uX29uRmlsdGVycy5nZXQodHlwZSk7XG4gICAgaWYgKGZpbHRlcikgdHlwZSA9IGZpbHRlciwgd3JhcCA9IGQzX3NlbGVjdGlvbl9vbkZpbHRlcjtcbiAgICBmdW5jdGlvbiBvblJlbW92ZSgpIHtcbiAgICAgIHZhciBsID0gdGhpc1tuYW1lXTtcbiAgICAgIGlmIChsKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsLCBsLiQpO1xuICAgICAgICBkZWxldGUgdGhpc1tuYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24gb25BZGQoKSB7XG4gICAgICB2YXIgbCA9IHdyYXAobGlzdGVuZXIsIGQzX2FycmF5KGFyZ3VtZW50cykpO1xuICAgICAgb25SZW1vdmUuY2FsbCh0aGlzKTtcbiAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCB0aGlzW25hbWVdID0gbCwgbC4kID0gY2FwdHVyZSk7XG4gICAgICBsLl8gPSBsaXN0ZW5lcjtcbiAgICB9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsKCkge1xuICAgICAgdmFyIHJlID0gbmV3IFJlZ0V4cChcIl5fX29uKFteLl0rKVwiICsgZDMucmVxdW90ZSh0eXBlKSArIFwiJFwiKSwgbWF0Y2g7XG4gICAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMpIHtcbiAgICAgICAgaWYgKG1hdGNoID0gbmFtZS5tYXRjaChyZSkpIHtcbiAgICAgICAgICB2YXIgbCA9IHRoaXNbbmFtZV07XG4gICAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKG1hdGNoWzFdLCBsLCBsLiQpO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzW25hbWVdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpID8gbGlzdGVuZXIgPyBvbkFkZCA6IG9uUmVtb3ZlIDogbGlzdGVuZXIgPyBkM19ub29wIDogcmVtb3ZlQWxsO1xuICB9XG4gIHZhciBkM19zZWxlY3Rpb25fb25GaWx0ZXJzID0gZDMubWFwKHtcbiAgICBtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxuICAgIG1vdXNlbGVhdmU6IFwibW91c2VvdXRcIlxuICB9KTtcbiAgZDNfc2VsZWN0aW9uX29uRmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uKGspIHtcbiAgICBpZiAoXCJvblwiICsgayBpbiBkM19kb2N1bWVudCkgZDNfc2VsZWN0aW9uX29uRmlsdGVycy5yZW1vdmUoayk7XG4gIH0pO1xuICBmdW5jdGlvbiBkM19zZWxlY3Rpb25fb25MaXN0ZW5lcihsaXN0ZW5lciwgYXJndW1lbnR6KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcbiAgICAgIHZhciBvID0gZDMuZXZlbnQ7XG4gICAgICBkMy5ldmVudCA9IGU7XG4gICAgICBhcmd1bWVudHpbMF0gPSB0aGlzLl9fZGF0YV9fO1xuICAgICAgdHJ5IHtcbiAgICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnR6KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGQzLmV2ZW50ID0gbztcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX3NlbGVjdGlvbl9vbkZpbHRlcihsaXN0ZW5lciwgYXJndW1lbnR6KSB7XG4gICAgdmFyIGwgPSBkM19zZWxlY3Rpb25fb25MaXN0ZW5lcihsaXN0ZW5lciwgYXJndW1lbnR6KTtcbiAgICByZXR1cm4gZnVuY3Rpb24oZSkge1xuICAgICAgdmFyIHRhcmdldCA9IHRoaXMsIHJlbGF0ZWQgPSBlLnJlbGF0ZWRUYXJnZXQ7XG4gICAgICBpZiAoIXJlbGF0ZWQgfHwgcmVsYXRlZCAhPT0gdGFyZ2V0ICYmICEocmVsYXRlZC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbih0YXJnZXQpICYgOCkpIHtcbiAgICAgICAgbC5jYWxsKHRhcmdldCwgZSk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuICB2YXIgZDNfZXZlbnRfZHJhZ1NlbGVjdCA9IGQzX3ZlbmRvclN5bWJvbChkM19kb2N1bWVudEVsZW1lbnQuc3R5bGUsIFwidXNlclNlbGVjdFwiKTtcbiAgZnVuY3Rpb24gZDNfZXZlbnRfZHJhZ1N1cHByZXNzKHR5cGUpIHtcbiAgICB2YXIgc2VsZWN0c3RhcnQgPSBcInNlbGVjdHN0YXJ0LlwiICsgdHlwZSwgZHJhZ3N0YXJ0ID0gXCJkcmFnc3RhcnQuXCIgKyB0eXBlLCBjbGljayA9IFwiY2xpY2suXCIgKyB0eXBlLCB3ID0gZDMuc2VsZWN0KGQzX3dpbmRvdykub24oc2VsZWN0c3RhcnQsIGQzX2V2ZW50UHJldmVudERlZmF1bHQpLm9uKGRyYWdzdGFydCwgZDNfZXZlbnRQcmV2ZW50RGVmYXVsdCksIHN0eWxlID0gZDNfZG9jdW1lbnRFbGVtZW50LnN0eWxlLCBzZWxlY3QgPSBzdHlsZVtkM19ldmVudF9kcmFnU2VsZWN0XTtcbiAgICBzdHlsZVtkM19ldmVudF9kcmFnU2VsZWN0XSA9IFwibm9uZVwiO1xuICAgIHJldHVybiBmdW5jdGlvbihzdXBwcmVzc0NsaWNrKSB7XG4gICAgICB3Lm9uKHNlbGVjdHN0YXJ0LCBudWxsKS5vbihkcmFnc3RhcnQsIG51bGwpO1xuICAgICAgc3R5bGVbZDNfZXZlbnRfZHJhZ1NlbGVjdF0gPSBzZWxlY3Q7XG4gICAgICBpZiAoc3VwcHJlc3NDbGljaykge1xuICAgICAgICBmdW5jdGlvbiBvZmYoKSB7XG4gICAgICAgICAgdy5vbihjbGljaywgbnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgdy5vbihjbGljaywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgZDNfZXZlbnRQcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIG9mZigpO1xuICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgc2V0VGltZW91dChvZmYsIDApO1xuICAgICAgfVxuICAgIH07XG4gIH1cbiAgZDMubW91c2UgPSBmdW5jdGlvbihjb250YWluZXIpIHtcbiAgICByZXR1cm4gZDNfbW91c2VQb2ludChjb250YWluZXIsIGQzX2V2ZW50U291cmNlKCkpO1xuICB9O1xuICB2YXIgZDNfbW91c2VfYnVnNDQwODMgPSAvV2ViS2l0Ly50ZXN0KGQzX3dpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50KSA/IC0xIDogMDtcbiAgZnVuY3Rpb24gZDNfbW91c2VQb2ludChjb250YWluZXIsIGUpIHtcbiAgICB2YXIgc3ZnID0gY29udGFpbmVyLm93bmVyU1ZHRWxlbWVudCB8fCBjb250YWluZXI7XG4gICAgaWYgKHN2Zy5jcmVhdGVTVkdQb2ludCkge1xuICAgICAgdmFyIHBvaW50ID0gc3ZnLmNyZWF0ZVNWR1BvaW50KCk7XG4gICAgICBpZiAoZDNfbW91c2VfYnVnNDQwODMgPCAwICYmIChkM193aW5kb3cuc2Nyb2xsWCB8fCBkM193aW5kb3cuc2Nyb2xsWSkpIHtcbiAgICAgICAgc3ZnID0gZDMuc2VsZWN0KFwiYm9keVwiKS5hcHBlbmQoXCJzdmdcIikuc3R5bGUoe1xuICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgIGxlZnQ6IDAsXG4gICAgICAgICAgbWFyZ2luOiAwLFxuICAgICAgICAgIHBhZGRpbmc6IDAsXG4gICAgICAgICAgYm9yZGVyOiBcIm5vbmVcIlxuICAgICAgICB9LCBcImltcG9ydGFudFwiKTtcbiAgICAgICAgdmFyIGN0bSA9IHN2Z1swXVswXS5nZXRTY3JlZW5DVE0oKTtcbiAgICAgICAgZDNfbW91c2VfYnVnNDQwODMgPSAhKGN0bS5mIHx8IGN0bS5lKTtcbiAgICAgICAgc3ZnLnJlbW92ZSgpO1xuICAgICAgfVxuICAgICAgaWYgKGQzX21vdXNlX2J1ZzQ0MDgzKSB7XG4gICAgICAgIHBvaW50LnggPSBlLnBhZ2VYO1xuICAgICAgICBwb2ludC55ID0gZS5wYWdlWTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvaW50LnggPSBlLmNsaWVudFg7XG4gICAgICAgIHBvaW50LnkgPSBlLmNsaWVudFk7XG4gICAgICB9XG4gICAgICBwb2ludCA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShjb250YWluZXIuZ2V0U2NyZWVuQ1RNKCkuaW52ZXJzZSgpKTtcbiAgICAgIHJldHVybiBbIHBvaW50LngsIHBvaW50LnkgXTtcbiAgICB9XG4gICAgdmFyIHJlY3QgPSBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIFsgZS5jbGllbnRYIC0gcmVjdC5sZWZ0IC0gY29udGFpbmVyLmNsaWVudExlZnQsIGUuY2xpZW50WSAtIHJlY3QudG9wIC0gY29udGFpbmVyLmNsaWVudFRvcCBdO1xuICB9XG4gIGQzLnRvdWNoZXMgPSBmdW5jdGlvbihjb250YWluZXIsIHRvdWNoZXMpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHRvdWNoZXMgPSBkM19ldmVudFNvdXJjZSgpLnRvdWNoZXM7XG4gICAgcmV0dXJuIHRvdWNoZXMgPyBkM19hcnJheSh0b3VjaGVzKS5tYXAoZnVuY3Rpb24odG91Y2gpIHtcbiAgICAgIHZhciBwb2ludCA9IGQzX21vdXNlUG9pbnQoY29udGFpbmVyLCB0b3VjaCk7XG4gICAgICBwb2ludC5pZGVudGlmaWVyID0gdG91Y2guaWRlbnRpZmllcjtcbiAgICAgIHJldHVybiBwb2ludDtcbiAgICB9KSA6IFtdO1xuICB9O1xuICBkMy5iZWhhdmlvci5kcmFnID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGV2ZW50ID0gZDNfZXZlbnREaXNwYXRjaChkcmFnLCBcImRyYWdcIiwgXCJkcmFnc3RhcnRcIiwgXCJkcmFnZW5kXCIpLCBvcmlnaW4gPSBudWxsO1xuICAgIGZ1bmN0aW9uIGRyYWcoKSB7XG4gICAgICB0aGlzLm9uKFwibW91c2Vkb3duLmRyYWdcIiwgbW91c2Vkb3duKS5vbihcInRvdWNoc3RhcnQuZHJhZ1wiLCBtb3VzZWRvd24pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBtb3VzZWRvd24oKSB7XG4gICAgICB2YXIgdGFyZ2V0ID0gdGhpcywgZXZlbnRfID0gZXZlbnQub2YodGFyZ2V0LCBhcmd1bWVudHMpLCBldmVudFRhcmdldCA9IGQzLmV2ZW50LnRhcmdldCwgdG91Y2hJZCA9IGQzLmV2ZW50LnRvdWNoZXMgPyBkMy5ldmVudC5jaGFuZ2VkVG91Y2hlc1swXS5pZGVudGlmaWVyIDogbnVsbCwgb2Zmc2V0LCBvcmlnaW5fID0gcG9pbnQoKSwgbW92ZWQgPSAwLCBkcmFnUmVzdG9yZSA9IGQzX2V2ZW50X2RyYWdTdXBwcmVzcyh0b3VjaElkICE9IG51bGwgPyBcImRyYWctXCIgKyB0b3VjaElkIDogXCJkcmFnXCIpO1xuICAgICAgdmFyIHcgPSBkMy5zZWxlY3QoZDNfd2luZG93KS5vbih0b3VjaElkICE9IG51bGwgPyBcInRvdWNobW92ZS5kcmFnLVwiICsgdG91Y2hJZCA6IFwibW91c2Vtb3ZlLmRyYWdcIiwgZHJhZ21vdmUpLm9uKHRvdWNoSWQgIT0gbnVsbCA/IFwidG91Y2hlbmQuZHJhZy1cIiArIHRvdWNoSWQgOiBcIm1vdXNldXAuZHJhZ1wiLCBkcmFnZW5kLCB0cnVlKTtcbiAgICAgIGlmIChvcmlnaW4pIHtcbiAgICAgICAgb2Zmc2V0ID0gb3JpZ2luLmFwcGx5KHRhcmdldCwgYXJndW1lbnRzKTtcbiAgICAgICAgb2Zmc2V0ID0gWyBvZmZzZXQueCAtIG9yaWdpbl9bMF0sIG9mZnNldC55IC0gb3JpZ2luX1sxXSBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2Zmc2V0ID0gWyAwLCAwIF07XG4gICAgICB9XG4gICAgICBldmVudF8oe1xuICAgICAgICB0eXBlOiBcImRyYWdzdGFydFwiXG4gICAgICB9KTtcbiAgICAgIGZ1bmN0aW9uIHBvaW50KCkge1xuICAgICAgICB2YXIgcCA9IHRhcmdldC5wYXJlbnROb2RlO1xuICAgICAgICByZXR1cm4gdG91Y2hJZCAhPSBudWxsID8gZDMudG91Y2hlcyhwKS5maWx0ZXIoZnVuY3Rpb24ocCkge1xuICAgICAgICAgIHJldHVybiBwLmlkZW50aWZpZXIgPT09IHRvdWNoSWQ7XG4gICAgICAgIH0pWzBdIDogZDMubW91c2UocCk7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBkcmFnbW92ZSgpIHtcbiAgICAgICAgaWYgKCF0YXJnZXQucGFyZW50Tm9kZSkgcmV0dXJuIGRyYWdlbmQoKTtcbiAgICAgICAgdmFyIHAgPSBwb2ludCgpLCBkeCA9IHBbMF0gLSBvcmlnaW5fWzBdLCBkeSA9IHBbMV0gLSBvcmlnaW5fWzFdO1xuICAgICAgICBtb3ZlZCB8PSBkeCB8IGR5O1xuICAgICAgICBvcmlnaW5fID0gcDtcbiAgICAgICAgZXZlbnRfKHtcbiAgICAgICAgICB0eXBlOiBcImRyYWdcIixcbiAgICAgICAgICB4OiBwWzBdICsgb2Zmc2V0WzBdLFxuICAgICAgICAgIHk6IHBbMV0gKyBvZmZzZXRbMV0sXG4gICAgICAgICAgZHg6IGR4LFxuICAgICAgICAgIGR5OiBkeVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGRyYWdlbmQoKSB7XG4gICAgICAgIHcub24odG91Y2hJZCAhPSBudWxsID8gXCJ0b3VjaG1vdmUuZHJhZy1cIiArIHRvdWNoSWQgOiBcIm1vdXNlbW92ZS5kcmFnXCIsIG51bGwpLm9uKHRvdWNoSWQgIT0gbnVsbCA/IFwidG91Y2hlbmQuZHJhZy1cIiArIHRvdWNoSWQgOiBcIm1vdXNldXAuZHJhZ1wiLCBudWxsKTtcbiAgICAgICAgZHJhZ1Jlc3RvcmUobW92ZWQgJiYgZDMuZXZlbnQudGFyZ2V0ID09PSBldmVudFRhcmdldCk7XG4gICAgICAgIGV2ZW50Xyh7XG4gICAgICAgICAgdHlwZTogXCJkcmFnZW5kXCJcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGRyYWcub3JpZ2luID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gb3JpZ2luO1xuICAgICAgb3JpZ2luID0geDtcbiAgICAgIHJldHVybiBkcmFnO1xuICAgIH07XG4gICAgcmV0dXJuIGQzLnJlYmluZChkcmFnLCBldmVudCwgXCJvblwiKTtcbiAgfTtcbiAgZDMuYmVoYXZpb3Iuem9vbSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0cmFuc2xhdGUgPSBbIDAsIDAgXSwgdHJhbnNsYXRlMCwgc2NhbGUgPSAxLCBkaXN0YW5jZTAsIHNjYWxlMCwgc2NhbGVFeHRlbnQgPSBkM19iZWhhdmlvcl96b29tSW5maW5pdHksIGV2ZW50ID0gZDNfZXZlbnREaXNwYXRjaCh6b29tLCBcInpvb21cIiksIHgwLCB4MSwgeTAsIHkxLCB0b3VjaHRpbWU7XG4gICAgZnVuY3Rpb24gem9vbSgpIHtcbiAgICAgIHRoaXMub24oXCJtb3VzZWRvd24uem9vbVwiLCBtb3VzZWRvd24pLm9uKFwibW91c2Vtb3ZlLnpvb21cIiwgbW91c2Vtb3ZlKS5vbihkM19iZWhhdmlvcl96b29tV2hlZWwgKyBcIi56b29tXCIsIG1vdXNld2hlZWwpLm9uKFwiZGJsY2xpY2suem9vbVwiLCBkYmxjbGljaykub24oXCJ0b3VjaHN0YXJ0Lnpvb21cIiwgdG91Y2hzdGFydCkub24oXCJ0b3VjaG1vdmUuem9vbVwiLCB0b3VjaG1vdmUpLm9uKFwidG91Y2hlbmQuem9vbVwiLCB0b3VjaHN0YXJ0KTtcbiAgICB9XG4gICAgem9vbS50cmFuc2xhdGUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0cmFuc2xhdGU7XG4gICAgICB0cmFuc2xhdGUgPSB4Lm1hcChOdW1iZXIpO1xuICAgICAgcmVzY2FsZSgpO1xuICAgICAgcmV0dXJuIHpvb207XG4gICAgfTtcbiAgICB6b29tLnNjYWxlID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2NhbGU7XG4gICAgICBzY2FsZSA9ICt4O1xuICAgICAgcmVzY2FsZSgpO1xuICAgICAgcmV0dXJuIHpvb207XG4gICAgfTtcbiAgICB6b29tLnNjYWxlRXh0ZW50ID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2NhbGVFeHRlbnQ7XG4gICAgICBzY2FsZUV4dGVudCA9IHggPT0gbnVsbCA/IGQzX2JlaGF2aW9yX3pvb21JbmZpbml0eSA6IHgubWFwKE51bWJlcik7XG4gICAgICByZXR1cm4gem9vbTtcbiAgICB9O1xuICAgIHpvb20ueCA9IGZ1bmN0aW9uKHopIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHgxO1xuICAgICAgeDEgPSB6O1xuICAgICAgeDAgPSB6LmNvcHkoKTtcbiAgICAgIHRyYW5zbGF0ZSA9IFsgMCwgMCBdO1xuICAgICAgc2NhbGUgPSAxO1xuICAgICAgcmV0dXJuIHpvb207XG4gICAgfTtcbiAgICB6b29tLnkgPSBmdW5jdGlvbih6KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB5MTtcbiAgICAgIHkxID0gejtcbiAgICAgIHkwID0gei5jb3B5KCk7XG4gICAgICB0cmFuc2xhdGUgPSBbIDAsIDAgXTtcbiAgICAgIHNjYWxlID0gMTtcbiAgICAgIHJldHVybiB6b29tO1xuICAgIH07XG4gICAgZnVuY3Rpb24gbG9jYXRpb24ocCkge1xuICAgICAgcmV0dXJuIFsgKHBbMF0gLSB0cmFuc2xhdGVbMF0pIC8gc2NhbGUsIChwWzFdIC0gdHJhbnNsYXRlWzFdKSAvIHNjYWxlIF07XG4gICAgfVxuICAgIGZ1bmN0aW9uIHBvaW50KGwpIHtcbiAgICAgIHJldHVybiBbIGxbMF0gKiBzY2FsZSArIHRyYW5zbGF0ZVswXSwgbFsxXSAqIHNjYWxlICsgdHJhbnNsYXRlWzFdIF07XG4gICAgfVxuICAgIGZ1bmN0aW9uIHNjYWxlVG8ocykge1xuICAgICAgc2NhbGUgPSBNYXRoLm1heChzY2FsZUV4dGVudFswXSwgTWF0aC5taW4oc2NhbGVFeHRlbnRbMV0sIHMpKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gdHJhbnNsYXRlVG8ocCwgbCkge1xuICAgICAgbCA9IHBvaW50KGwpO1xuICAgICAgdHJhbnNsYXRlWzBdICs9IHBbMF0gLSBsWzBdO1xuICAgICAgdHJhbnNsYXRlWzFdICs9IHBbMV0gLSBsWzFdO1xuICAgIH1cbiAgICBmdW5jdGlvbiByZXNjYWxlKCkge1xuICAgICAgaWYgKHgxKSB4MS5kb21haW4oeDAucmFuZ2UoKS5tYXAoZnVuY3Rpb24oeCkge1xuICAgICAgICByZXR1cm4gKHggLSB0cmFuc2xhdGVbMF0pIC8gc2NhbGU7XG4gICAgICB9KS5tYXAoeDAuaW52ZXJ0KSk7XG4gICAgICBpZiAoeTEpIHkxLmRvbWFpbih5MC5yYW5nZSgpLm1hcChmdW5jdGlvbih5KSB7XG4gICAgICAgIHJldHVybiAoeSAtIHRyYW5zbGF0ZVsxXSkgLyBzY2FsZTtcbiAgICAgIH0pLm1hcCh5MC5pbnZlcnQpKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZGlzcGF0Y2goZXZlbnQpIHtcbiAgICAgIHJlc2NhbGUoKTtcbiAgICAgIGQzLmV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudCh7XG4gICAgICAgIHR5cGU6IFwiem9vbVwiLFxuICAgICAgICBzY2FsZTogc2NhbGUsXG4gICAgICAgIHRyYW5zbGF0ZTogdHJhbnNsYXRlXG4gICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gbW91c2Vkb3duKCkge1xuICAgICAgdmFyIHRhcmdldCA9IHRoaXMsIGV2ZW50XyA9IGV2ZW50Lm9mKHRhcmdldCwgYXJndW1lbnRzKSwgZXZlbnRUYXJnZXQgPSBkMy5ldmVudC50YXJnZXQsIG1vdmVkID0gMCwgdyA9IGQzLnNlbGVjdChkM193aW5kb3cpLm9uKFwibW91c2Vtb3ZlLnpvb21cIiwgbW91c2Vtb3ZlKS5vbihcIm1vdXNldXAuem9vbVwiLCBtb3VzZXVwKSwgbCA9IGxvY2F0aW9uKGQzLm1vdXNlKHRhcmdldCkpLCBkcmFnUmVzdG9yZSA9IGQzX2V2ZW50X2RyYWdTdXBwcmVzcyhcInpvb21cIik7XG4gICAgICBmdW5jdGlvbiBtb3VzZW1vdmUoKSB7XG4gICAgICAgIG1vdmVkID0gMTtcbiAgICAgICAgdHJhbnNsYXRlVG8oZDMubW91c2UodGFyZ2V0KSwgbCk7XG4gICAgICAgIGRpc3BhdGNoKGV2ZW50Xyk7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBtb3VzZXVwKCkge1xuICAgICAgICB3Lm9uKFwibW91c2Vtb3ZlLnpvb21cIiwgbnVsbCkub24oXCJtb3VzZXVwLnpvb21cIiwgbnVsbCk7XG4gICAgICAgIGRyYWdSZXN0b3JlKG1vdmVkICYmIGQzLmV2ZW50LnRhcmdldCA9PT0gZXZlbnRUYXJnZXQpO1xuICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBtb3VzZXdoZWVsKCkge1xuICAgICAgaWYgKCF0cmFuc2xhdGUwKSB0cmFuc2xhdGUwID0gbG9jYXRpb24oZDMubW91c2UodGhpcykpO1xuICAgICAgc2NhbGVUbyhNYXRoLnBvdygyLCBkM19iZWhhdmlvcl96b29tRGVsdGEoKSAqIC4wMDIpICogc2NhbGUpO1xuICAgICAgdHJhbnNsYXRlVG8oZDMubW91c2UodGhpcyksIHRyYW5zbGF0ZTApO1xuICAgICAgZGlzcGF0Y2goZXZlbnQub2YodGhpcywgYXJndW1lbnRzKSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIG1vdXNlbW92ZSgpIHtcbiAgICAgIHRyYW5zbGF0ZTAgPSBudWxsO1xuICAgIH1cbiAgICBmdW5jdGlvbiBkYmxjbGljaygpIHtcbiAgICAgIHZhciBwID0gZDMubW91c2UodGhpcyksIGwgPSBsb2NhdGlvbihwKSwgayA9IE1hdGgubG9nKHNjYWxlKSAvIE1hdGguTE4yO1xuICAgICAgc2NhbGVUbyhNYXRoLnBvdygyLCBkMy5ldmVudC5zaGlmdEtleSA/IE1hdGguY2VpbChrKSAtIDEgOiBNYXRoLmZsb29yKGspICsgMSkpO1xuICAgICAgdHJhbnNsYXRlVG8ocCwgbCk7XG4gICAgICBkaXNwYXRjaChldmVudC5vZih0aGlzLCBhcmd1bWVudHMpKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gdG91Y2hzdGFydCgpIHtcbiAgICAgIHZhciB0b3VjaGVzID0gZDMudG91Y2hlcyh0aGlzKSwgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIHNjYWxlMCA9IHNjYWxlO1xuICAgICAgdHJhbnNsYXRlMCA9IHt9O1xuICAgICAgZGlzdGFuY2UwID0gMDtcbiAgICAgIHRvdWNoZXMuZm9yRWFjaChmdW5jdGlvbih0KSB7XG4gICAgICAgIHRyYW5zbGF0ZTBbdC5pZGVudGlmaWVyXSA9IGxvY2F0aW9uKHQpO1xuICAgICAgfSk7XG4gICAgICBpZiAodG91Y2hlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgaWYgKG5vdyAtIHRvdWNodGltZSA8IDUwMCkge1xuICAgICAgICAgIHZhciBwID0gdG91Y2hlc1swXSwgbCA9IGxvY2F0aW9uKHRvdWNoZXNbMF0pO1xuICAgICAgICAgIHNjYWxlVG8oc2NhbGUgKiAyKTtcbiAgICAgICAgICB0cmFuc2xhdGVUbyhwLCBsKTtcbiAgICAgICAgICBkaXNwYXRjaChldmVudC5vZih0aGlzLCBhcmd1bWVudHMpKTtcbiAgICAgICAgfVxuICAgICAgICB0b3VjaHRpbWUgPSBub3c7XG4gICAgICB9IGVsc2UgaWYgKHRvdWNoZXMubGVuZ3RoID4gMSkge1xuICAgICAgICB2YXIgcCA9IHRvdWNoZXNbMF0sIHEgPSB0b3VjaGVzWzFdLCBkeCA9IHBbMF0gLSBxWzBdLCBkeSA9IHBbMV0gLSBxWzFdO1xuICAgICAgICBkaXN0YW5jZTAgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24gdG91Y2htb3ZlKCkge1xuICAgICAgdmFyIHRvdWNoZXMgPSBkMy50b3VjaGVzKHRoaXMpLCBwMCA9IHRvdWNoZXNbMF0sIGwwID0gdHJhbnNsYXRlMFtwMC5pZGVudGlmaWVyXTtcbiAgICAgIGlmIChwMSA9IHRvdWNoZXNbMV0pIHtcbiAgICAgICAgdmFyIHAxLCBsMSA9IHRyYW5zbGF0ZTBbcDEuaWRlbnRpZmllcl0sIHNjYWxlMSA9IGQzLmV2ZW50LnNjYWxlO1xuICAgICAgICBpZiAoc2NhbGUxID09IG51bGwpIHtcbiAgICAgICAgICB2YXIgZGlzdGFuY2UxID0gKGRpc3RhbmNlMSA9IHAxWzBdIC0gcDBbMF0pICogZGlzdGFuY2UxICsgKGRpc3RhbmNlMSA9IHAxWzFdIC0gcDBbMV0pICogZGlzdGFuY2UxO1xuICAgICAgICAgIHNjYWxlMSA9IGRpc3RhbmNlMCAmJiBNYXRoLnNxcnQoZGlzdGFuY2UxIC8gZGlzdGFuY2UwKTtcbiAgICAgICAgfVxuICAgICAgICBwMCA9IFsgKHAwWzBdICsgcDFbMF0pIC8gMiwgKHAwWzFdICsgcDFbMV0pIC8gMiBdO1xuICAgICAgICBsMCA9IFsgKGwwWzBdICsgbDFbMF0pIC8gMiwgKGwwWzFdICsgbDFbMV0pIC8gMiBdO1xuICAgICAgICBzY2FsZVRvKHNjYWxlMSAqIHNjYWxlMCk7XG4gICAgICB9XG4gICAgICB0cmFuc2xhdGVUbyhwMCwgbDApO1xuICAgICAgdG91Y2h0aW1lID0gbnVsbDtcbiAgICAgIGRpc3BhdGNoKGV2ZW50Lm9mKHRoaXMsIGFyZ3VtZW50cykpO1xuICAgIH1cbiAgICByZXR1cm4gZDMucmViaW5kKHpvb20sIGV2ZW50LCBcIm9uXCIpO1xuICB9O1xuICB2YXIgZDNfYmVoYXZpb3Jfem9vbUluZmluaXR5ID0gWyAwLCBJbmZpbml0eSBdO1xuICB2YXIgZDNfYmVoYXZpb3Jfem9vbURlbHRhLCBkM19iZWhhdmlvcl96b29tV2hlZWwgPSBcIm9ud2hlZWxcIiBpbiBkM19kb2N1bWVudCA/IChkM19iZWhhdmlvcl96b29tRGVsdGEgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gLWQzLmV2ZW50LmRlbHRhWSAqIChkMy5ldmVudC5kZWx0YU1vZGUgPyAxMjAgOiAxKTtcbiAgfSwgXCJ3aGVlbFwiKSA6IFwib25tb3VzZXdoZWVsXCIgaW4gZDNfZG9jdW1lbnQgPyAoZDNfYmVoYXZpb3Jfem9vbURlbHRhID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzLmV2ZW50LndoZWVsRGVsdGE7XG4gIH0sIFwibW91c2V3aGVlbFwiKSA6IChkM19iZWhhdmlvcl96b29tRGVsdGEgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gLWQzLmV2ZW50LmRldGFpbDtcbiAgfSwgXCJNb3pNb3VzZVBpeGVsU2Nyb2xsXCIpO1xuICBmdW5jdGlvbiBkM19Db2xvcigpIHt9XG4gIGQzX0NvbG9yLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnJnYigpICsgXCJcIjtcbiAgfTtcbiAgZDMuaHNsID0gZnVuY3Rpb24oaCwgcywgbCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gaCBpbnN0YW5jZW9mIGQzX0hzbCA/IGQzX2hzbChoLmgsIGgucywgaC5sKSA6IGQzX3JnYl9wYXJzZShcIlwiICsgaCwgZDNfcmdiX2hzbCwgZDNfaHNsKSA6IGQzX2hzbCgraCwgK3MsICtsKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfaHNsKGgsIHMsIGwpIHtcbiAgICByZXR1cm4gbmV3IGQzX0hzbChoLCBzLCBsKTtcbiAgfVxuICBmdW5jdGlvbiBkM19Ic2woaCwgcywgbCkge1xuICAgIHRoaXMuaCA9IGg7XG4gICAgdGhpcy5zID0gcztcbiAgICB0aGlzLmwgPSBsO1xuICB9XG4gIHZhciBkM19oc2xQcm90b3R5cGUgPSBkM19Ic2wucHJvdG90eXBlID0gbmV3IGQzX0NvbG9yKCk7XG4gIGQzX2hzbFByb3RvdHlwZS5icmlnaHRlciA9IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gTWF0aC5wb3coLjcsIGFyZ3VtZW50cy5sZW5ndGggPyBrIDogMSk7XG4gICAgcmV0dXJuIGQzX2hzbCh0aGlzLmgsIHRoaXMucywgdGhpcy5sIC8gayk7XG4gIH07XG4gIGQzX2hzbFByb3RvdHlwZS5kYXJrZXIgPSBmdW5jdGlvbihrKSB7XG4gICAgayA9IE1hdGgucG93KC43LCBhcmd1bWVudHMubGVuZ3RoID8gayA6IDEpO1xuICAgIHJldHVybiBkM19oc2wodGhpcy5oLCB0aGlzLnMsIGsgKiB0aGlzLmwpO1xuICB9O1xuICBkM19oc2xQcm90b3R5cGUucmdiID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX2hzbF9yZ2IodGhpcy5oLCB0aGlzLnMsIHRoaXMubCk7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2hzbF9yZ2IoaCwgcywgbCkge1xuICAgIHZhciBtMSwgbTI7XG4gICAgaCA9IGlzTmFOKGgpID8gMCA6IChoICU9IDM2MCkgPCAwID8gaCArIDM2MCA6IGg7XG4gICAgcyA9IGlzTmFOKHMpID8gMCA6IHMgPCAwID8gMCA6IHMgPiAxID8gMSA6IHM7XG4gICAgbCA9IGwgPCAwID8gMCA6IGwgPiAxID8gMSA6IGw7XG4gICAgbTIgPSBsIDw9IC41ID8gbCAqICgxICsgcykgOiBsICsgcyAtIGwgKiBzO1xuICAgIG0xID0gMiAqIGwgLSBtMjtcbiAgICBmdW5jdGlvbiB2KGgpIHtcbiAgICAgIGlmIChoID4gMzYwKSBoIC09IDM2MDsgZWxzZSBpZiAoaCA8IDApIGggKz0gMzYwO1xuICAgICAgaWYgKGggPCA2MCkgcmV0dXJuIG0xICsgKG0yIC0gbTEpICogaCAvIDYwO1xuICAgICAgaWYgKGggPCAxODApIHJldHVybiBtMjtcbiAgICAgIGlmIChoIDwgMjQwKSByZXR1cm4gbTEgKyAobTIgLSBtMSkgKiAoMjQwIC0gaCkgLyA2MDtcbiAgICAgIHJldHVybiBtMTtcbiAgICB9XG4gICAgZnVuY3Rpb24gdnYoaCkge1xuICAgICAgcmV0dXJuIE1hdGgucm91bmQodihoKSAqIDI1NSk7XG4gICAgfVxuICAgIHJldHVybiBkM19yZ2IodnYoaCArIDEyMCksIHZ2KGgpLCB2dihoIC0gMTIwKSk7XG4gIH1cbiAgdmFyIM+AID0gTWF0aC5QSSwgzrUgPSAxZS02LCDOtTIgPSDOtSAqIM61LCBkM19yYWRpYW5zID0gz4AgLyAxODAsIGQzX2RlZ3JlZXMgPSAxODAgLyDPgDtcbiAgZnVuY3Rpb24gZDNfc2duKHgpIHtcbiAgICByZXR1cm4geCA+IDAgPyAxIDogeCA8IDAgPyAtMSA6IDA7XG4gIH1cbiAgZnVuY3Rpb24gZDNfYWNvcyh4KSB7XG4gICAgcmV0dXJuIHggPiAxID8gMCA6IHggPCAtMSA/IM+AIDogTWF0aC5hY29zKHgpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2FzaW4oeCkge1xuICAgIHJldHVybiB4ID4gMSA/IM+AIC8gMiA6IHggPCAtMSA/IC3PgCAvIDIgOiBNYXRoLmFzaW4oeCk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc2luaCh4KSB7XG4gICAgcmV0dXJuIChNYXRoLmV4cCh4KSAtIE1hdGguZXhwKC14KSkgLyAyO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2Nvc2goeCkge1xuICAgIHJldHVybiAoTWF0aC5leHAoeCkgKyBNYXRoLmV4cCgteCkpIC8gMjtcbiAgfVxuICBmdW5jdGlvbiBkM19oYXZlcnNpbih4KSB7XG4gICAgcmV0dXJuICh4ID0gTWF0aC5zaW4oeCAvIDIpKSAqIHg7XG4gIH1cbiAgZDMuaGNsID0gZnVuY3Rpb24oaCwgYywgbCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gaCBpbnN0YW5jZW9mIGQzX0hjbCA/IGQzX2hjbChoLmgsIGguYywgaC5sKSA6IGggaW5zdGFuY2VvZiBkM19MYWIgPyBkM19sYWJfaGNsKGgubCwgaC5hLCBoLmIpIDogZDNfbGFiX2hjbCgoaCA9IGQzX3JnYl9sYWIoKGggPSBkMy5yZ2IoaCkpLnIsIGguZywgaC5iKSkubCwgaC5hLCBoLmIpIDogZDNfaGNsKCtoLCArYywgK2wpO1xuICB9O1xuICBmdW5jdGlvbiBkM19oY2woaCwgYywgbCkge1xuICAgIHJldHVybiBuZXcgZDNfSGNsKGgsIGMsIGwpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX0hjbChoLCBjLCBsKSB7XG4gICAgdGhpcy5oID0gaDtcbiAgICB0aGlzLmMgPSBjO1xuICAgIHRoaXMubCA9IGw7XG4gIH1cbiAgdmFyIGQzX2hjbFByb3RvdHlwZSA9IGQzX0hjbC5wcm90b3R5cGUgPSBuZXcgZDNfQ29sb3IoKTtcbiAgZDNfaGNsUHJvdG90eXBlLmJyaWdodGVyID0gZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBkM19oY2wodGhpcy5oLCB0aGlzLmMsIE1hdGgubWluKDEwMCwgdGhpcy5sICsgZDNfbGFiX0sgKiAoYXJndW1lbnRzLmxlbmd0aCA/IGsgOiAxKSkpO1xuICB9O1xuICBkM19oY2xQcm90b3R5cGUuZGFya2VyID0gZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBkM19oY2wodGhpcy5oLCB0aGlzLmMsIE1hdGgubWF4KDAsIHRoaXMubCAtIGQzX2xhYl9LICogKGFyZ3VtZW50cy5sZW5ndGggPyBrIDogMSkpKTtcbiAgfTtcbiAgZDNfaGNsUHJvdG90eXBlLnJnYiA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19oY2xfbGFiKHRoaXMuaCwgdGhpcy5jLCB0aGlzLmwpLnJnYigpO1xuICB9O1xuICBmdW5jdGlvbiBkM19oY2xfbGFiKGgsIGMsIGwpIHtcbiAgICBpZiAoaXNOYU4oaCkpIGggPSAwO1xuICAgIGlmIChpc05hTihjKSkgYyA9IDA7XG4gICAgcmV0dXJuIGQzX2xhYihsLCBNYXRoLmNvcyhoICo9IGQzX3JhZGlhbnMpICogYywgTWF0aC5zaW4oaCkgKiBjKTtcbiAgfVxuICBkMy5sYWIgPSBmdW5jdGlvbihsLCBhLCBiKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyBsIGluc3RhbmNlb2YgZDNfTGFiID8gZDNfbGFiKGwubCwgbC5hLCBsLmIpIDogbCBpbnN0YW5jZW9mIGQzX0hjbCA/IGQzX2hjbF9sYWIobC5sLCBsLmMsIGwuaCkgOiBkM19yZ2JfbGFiKChsID0gZDMucmdiKGwpKS5yLCBsLmcsIGwuYikgOiBkM19sYWIoK2wsICthLCArYik7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2xhYihsLCBhLCBiKSB7XG4gICAgcmV0dXJuIG5ldyBkM19MYWIobCwgYSwgYik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfTGFiKGwsIGEsIGIpIHtcbiAgICB0aGlzLmwgPSBsO1xuICAgIHRoaXMuYSA9IGE7XG4gICAgdGhpcy5iID0gYjtcbiAgfVxuICB2YXIgZDNfbGFiX0sgPSAxODtcbiAgdmFyIGQzX2xhYl9YID0gLjk1MDQ3LCBkM19sYWJfWSA9IDEsIGQzX2xhYl9aID0gMS4wODg4MztcbiAgdmFyIGQzX2xhYlByb3RvdHlwZSA9IGQzX0xhYi5wcm90b3R5cGUgPSBuZXcgZDNfQ29sb3IoKTtcbiAgZDNfbGFiUHJvdG90eXBlLmJyaWdodGVyID0gZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBkM19sYWIoTWF0aC5taW4oMTAwLCB0aGlzLmwgKyBkM19sYWJfSyAqIChhcmd1bWVudHMubGVuZ3RoID8gayA6IDEpKSwgdGhpcy5hLCB0aGlzLmIpO1xuICB9O1xuICBkM19sYWJQcm90b3R5cGUuZGFya2VyID0gZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBkM19sYWIoTWF0aC5tYXgoMCwgdGhpcy5sIC0gZDNfbGFiX0sgKiAoYXJndW1lbnRzLmxlbmd0aCA/IGsgOiAxKSksIHRoaXMuYSwgdGhpcy5iKTtcbiAgfTtcbiAgZDNfbGFiUHJvdG90eXBlLnJnYiA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19sYWJfcmdiKHRoaXMubCwgdGhpcy5hLCB0aGlzLmIpO1xuICB9O1xuICBmdW5jdGlvbiBkM19sYWJfcmdiKGwsIGEsIGIpIHtcbiAgICB2YXIgeSA9IChsICsgMTYpIC8gMTE2LCB4ID0geSArIGEgLyA1MDAsIHogPSB5IC0gYiAvIDIwMDtcbiAgICB4ID0gZDNfbGFiX3h5eih4KSAqIGQzX2xhYl9YO1xuICAgIHkgPSBkM19sYWJfeHl6KHkpICogZDNfbGFiX1k7XG4gICAgeiA9IGQzX2xhYl94eXooeikgKiBkM19sYWJfWjtcbiAgICByZXR1cm4gZDNfcmdiKGQzX3h5el9yZ2IoMy4yNDA0NTQyICogeCAtIDEuNTM3MTM4NSAqIHkgLSAuNDk4NTMxNCAqIHopLCBkM194eXpfcmdiKC0uOTY5MjY2ICogeCArIDEuODc2MDEwOCAqIHkgKyAuMDQxNTU2ICogeiksIGQzX3h5el9yZ2IoLjA1NTY0MzQgKiB4IC0gLjIwNDAyNTkgKiB5ICsgMS4wNTcyMjUyICogeikpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xhYl9oY2wobCwgYSwgYikge1xuICAgIHJldHVybiBsID4gMCA/IGQzX2hjbChNYXRoLmF0YW4yKGIsIGEpICogZDNfZGVncmVlcywgTWF0aC5zcXJ0KGEgKiBhICsgYiAqIGIpLCBsKSA6IGQzX2hjbChOYU4sIE5hTiwgbCk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGFiX3h5eih4KSB7XG4gICAgcmV0dXJuIHggPiAuMjA2ODkzMDM0ID8geCAqIHggKiB4IDogKHggLSA0IC8gMjkpIC8gNy43ODcwMzc7XG4gIH1cbiAgZnVuY3Rpb24gZDNfeHl6X2xhYih4KSB7XG4gICAgcmV0dXJuIHggPiAuMDA4ODU2ID8gTWF0aC5wb3coeCwgMSAvIDMpIDogNy43ODcwMzcgKiB4ICsgNCAvIDI5O1xuICB9XG4gIGZ1bmN0aW9uIGQzX3h5el9yZ2Iocikge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKDI1NSAqIChyIDw9IC4wMDMwNCA/IDEyLjkyICogciA6IDEuMDU1ICogTWF0aC5wb3cociwgMSAvIDIuNCkgLSAuMDU1KSk7XG4gIH1cbiAgZDMucmdiID0gZnVuY3Rpb24ociwgZywgYikge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gciBpbnN0YW5jZW9mIGQzX1JnYiA/IGQzX3JnYihyLnIsIHIuZywgci5iKSA6IGQzX3JnYl9wYXJzZShcIlwiICsgciwgZDNfcmdiLCBkM19oc2xfcmdiKSA6IGQzX3JnYih+fnIsIH5+Zywgfn5iKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfcmdiKHIsIGcsIGIpIHtcbiAgICByZXR1cm4gbmV3IGQzX1JnYihyLCBnLCBiKTtcbiAgfVxuICBmdW5jdGlvbiBkM19SZ2IociwgZywgYikge1xuICAgIHRoaXMuciA9IHI7XG4gICAgdGhpcy5nID0gZztcbiAgICB0aGlzLmIgPSBiO1xuICB9XG4gIHZhciBkM19yZ2JQcm90b3R5cGUgPSBkM19SZ2IucHJvdG90eXBlID0gbmV3IGQzX0NvbG9yKCk7XG4gIGQzX3JnYlByb3RvdHlwZS5icmlnaHRlciA9IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gTWF0aC5wb3coLjcsIGFyZ3VtZW50cy5sZW5ndGggPyBrIDogMSk7XG4gICAgdmFyIHIgPSB0aGlzLnIsIGcgPSB0aGlzLmcsIGIgPSB0aGlzLmIsIGkgPSAzMDtcbiAgICBpZiAoIXIgJiYgIWcgJiYgIWIpIHJldHVybiBkM19yZ2IoaSwgaSwgaSk7XG4gICAgaWYgKHIgJiYgciA8IGkpIHIgPSBpO1xuICAgIGlmIChnICYmIGcgPCBpKSBnID0gaTtcbiAgICBpZiAoYiAmJiBiIDwgaSkgYiA9IGk7XG4gICAgcmV0dXJuIGQzX3JnYihNYXRoLm1pbigyNTUsIE1hdGguZmxvb3IociAvIGspKSwgTWF0aC5taW4oMjU1LCBNYXRoLmZsb29yKGcgLyBrKSksIE1hdGgubWluKDI1NSwgTWF0aC5mbG9vcihiIC8gaykpKTtcbiAgfTtcbiAgZDNfcmdiUHJvdG90eXBlLmRhcmtlciA9IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gTWF0aC5wb3coLjcsIGFyZ3VtZW50cy5sZW5ndGggPyBrIDogMSk7XG4gICAgcmV0dXJuIGQzX3JnYihNYXRoLmZsb29yKGsgKiB0aGlzLnIpLCBNYXRoLmZsb29yKGsgKiB0aGlzLmcpLCBNYXRoLmZsb29yKGsgKiB0aGlzLmIpKTtcbiAgfTtcbiAgZDNfcmdiUHJvdG90eXBlLmhzbCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19yZ2JfaHNsKHRoaXMuciwgdGhpcy5nLCB0aGlzLmIpO1xuICB9O1xuICBkM19yZ2JQcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCIjXCIgKyBkM19yZ2JfaGV4KHRoaXMucikgKyBkM19yZ2JfaGV4KHRoaXMuZykgKyBkM19yZ2JfaGV4KHRoaXMuYik7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3JnYl9oZXgodikge1xuICAgIHJldHVybiB2IDwgMTYgPyBcIjBcIiArIE1hdGgubWF4KDAsIHYpLnRvU3RyaW5nKDE2KSA6IE1hdGgubWluKDI1NSwgdikudG9TdHJpbmcoMTYpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3JnYl9wYXJzZShmb3JtYXQsIHJnYiwgaHNsKSB7XG4gICAgdmFyIHIgPSAwLCBnID0gMCwgYiA9IDAsIG0xLCBtMiwgbmFtZTtcbiAgICBtMSA9IC8oW2Etel0rKVxcKCguKilcXCkvaS5leGVjKGZvcm1hdCk7XG4gICAgaWYgKG0xKSB7XG4gICAgICBtMiA9IG0xWzJdLnNwbGl0KFwiLFwiKTtcbiAgICAgIHN3aXRjaCAobTFbMV0pIHtcbiAgICAgICBjYXNlIFwiaHNsXCI6XG4gICAgICAgIHtcbiAgICAgICAgICByZXR1cm4gaHNsKHBhcnNlRmxvYXQobTJbMF0pLCBwYXJzZUZsb2F0KG0yWzFdKSAvIDEwMCwgcGFyc2VGbG9hdChtMlsyXSkgLyAxMDApO1xuICAgICAgICB9XG5cbiAgICAgICBjYXNlIFwicmdiXCI6XG4gICAgICAgIHtcbiAgICAgICAgICByZXR1cm4gcmdiKGQzX3JnYl9wYXJzZU51bWJlcihtMlswXSksIGQzX3JnYl9wYXJzZU51bWJlcihtMlsxXSksIGQzX3JnYl9wYXJzZU51bWJlcihtMlsyXSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChuYW1lID0gZDNfcmdiX25hbWVzLmdldChmb3JtYXQpKSByZXR1cm4gcmdiKG5hbWUuciwgbmFtZS5nLCBuYW1lLmIpO1xuICAgIGlmIChmb3JtYXQgIT0gbnVsbCAmJiBmb3JtYXQuY2hhckF0KDApID09PSBcIiNcIikge1xuICAgICAgaWYgKGZvcm1hdC5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgciA9IGZvcm1hdC5jaGFyQXQoMSk7XG4gICAgICAgIHIgKz0gcjtcbiAgICAgICAgZyA9IGZvcm1hdC5jaGFyQXQoMik7XG4gICAgICAgIGcgKz0gZztcbiAgICAgICAgYiA9IGZvcm1hdC5jaGFyQXQoMyk7XG4gICAgICAgIGIgKz0gYjtcbiAgICAgIH0gZWxzZSBpZiAoZm9ybWF0Lmxlbmd0aCA9PT0gNykge1xuICAgICAgICByID0gZm9ybWF0LnN1YnN0cmluZygxLCAzKTtcbiAgICAgICAgZyA9IGZvcm1hdC5zdWJzdHJpbmcoMywgNSk7XG4gICAgICAgIGIgPSBmb3JtYXQuc3Vic3RyaW5nKDUsIDcpO1xuICAgICAgfVxuICAgICAgciA9IHBhcnNlSW50KHIsIDE2KTtcbiAgICAgIGcgPSBwYXJzZUludChnLCAxNik7XG4gICAgICBiID0gcGFyc2VJbnQoYiwgMTYpO1xuICAgIH1cbiAgICByZXR1cm4gcmdiKHIsIGcsIGIpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3JnYl9oc2wociwgZywgYikge1xuICAgIHZhciBtaW4gPSBNYXRoLm1pbihyIC89IDI1NSwgZyAvPSAyNTUsIGIgLz0gMjU1KSwgbWF4ID0gTWF0aC5tYXgociwgZywgYiksIGQgPSBtYXggLSBtaW4sIGgsIHMsIGwgPSAobWF4ICsgbWluKSAvIDI7XG4gICAgaWYgKGQpIHtcbiAgICAgIHMgPSBsIDwgLjUgPyBkIC8gKG1heCArIG1pbikgOiBkIC8gKDIgLSBtYXggLSBtaW4pO1xuICAgICAgaWYgKHIgPT0gbWF4KSBoID0gKGcgLSBiKSAvIGQgKyAoZyA8IGIgPyA2IDogMCk7IGVsc2UgaWYgKGcgPT0gbWF4KSBoID0gKGIgLSByKSAvIGQgKyAyOyBlbHNlIGggPSAociAtIGcpIC8gZCArIDQ7XG4gICAgICBoICo9IDYwO1xuICAgIH0gZWxzZSB7XG4gICAgICBoID0gTmFOO1xuICAgICAgcyA9IGwgPiAwICYmIGwgPCAxID8gMCA6IGg7XG4gICAgfVxuICAgIHJldHVybiBkM19oc2woaCwgcywgbCk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfcmdiX2xhYihyLCBnLCBiKSB7XG4gICAgciA9IGQzX3JnYl94eXoocik7XG4gICAgZyA9IGQzX3JnYl94eXooZyk7XG4gICAgYiA9IGQzX3JnYl94eXooYik7XG4gICAgdmFyIHggPSBkM194eXpfbGFiKCguNDEyNDU2NCAqIHIgKyAuMzU3NTc2MSAqIGcgKyAuMTgwNDM3NSAqIGIpIC8gZDNfbGFiX1gpLCB5ID0gZDNfeHl6X2xhYigoLjIxMjY3MjkgKiByICsgLjcxNTE1MjIgKiBnICsgLjA3MjE3NSAqIGIpIC8gZDNfbGFiX1kpLCB6ID0gZDNfeHl6X2xhYigoLjAxOTMzMzkgKiByICsgLjExOTE5MiAqIGcgKyAuOTUwMzA0MSAqIGIpIC8gZDNfbGFiX1opO1xuICAgIHJldHVybiBkM19sYWIoMTE2ICogeSAtIDE2LCA1MDAgKiAoeCAtIHkpLCAyMDAgKiAoeSAtIHopKTtcbiAgfVxuICBmdW5jdGlvbiBkM19yZ2JfeHl6KHIpIHtcbiAgICByZXR1cm4gKHIgLz0gMjU1KSA8PSAuMDQwNDUgPyByIC8gMTIuOTIgOiBNYXRoLnBvdygociArIC4wNTUpIC8gMS4wNTUsIDIuNCk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfcmdiX3BhcnNlTnVtYmVyKGMpIHtcbiAgICB2YXIgZiA9IHBhcnNlRmxvYXQoYyk7XG4gICAgcmV0dXJuIGMuY2hhckF0KGMubGVuZ3RoIC0gMSkgPT09IFwiJVwiID8gTWF0aC5yb3VuZChmICogMi41NSkgOiBmO1xuICB9XG4gIHZhciBkM19yZ2JfbmFtZXMgPSBkMy5tYXAoe1xuICAgIGFsaWNlYmx1ZTogXCIjZjBmOGZmXCIsXG4gICAgYW50aXF1ZXdoaXRlOiBcIiNmYWViZDdcIixcbiAgICBhcXVhOiBcIiMwMGZmZmZcIixcbiAgICBhcXVhbWFyaW5lOiBcIiM3ZmZmZDRcIixcbiAgICBhenVyZTogXCIjZjBmZmZmXCIsXG4gICAgYmVpZ2U6IFwiI2Y1ZjVkY1wiLFxuICAgIGJpc3F1ZTogXCIjZmZlNGM0XCIsXG4gICAgYmxhY2s6IFwiIzAwMDAwMFwiLFxuICAgIGJsYW5jaGVkYWxtb25kOiBcIiNmZmViY2RcIixcbiAgICBibHVlOiBcIiMwMDAwZmZcIixcbiAgICBibHVldmlvbGV0OiBcIiM4YTJiZTJcIixcbiAgICBicm93bjogXCIjYTUyYTJhXCIsXG4gICAgYnVybHl3b29kOiBcIiNkZWI4ODdcIixcbiAgICBjYWRldGJsdWU6IFwiIzVmOWVhMFwiLFxuICAgIGNoYXJ0cmV1c2U6IFwiIzdmZmYwMFwiLFxuICAgIGNob2NvbGF0ZTogXCIjZDI2OTFlXCIsXG4gICAgY29yYWw6IFwiI2ZmN2Y1MFwiLFxuICAgIGNvcm5mbG93ZXJibHVlOiBcIiM2NDk1ZWRcIixcbiAgICBjb3Juc2lsazogXCIjZmZmOGRjXCIsXG4gICAgY3JpbXNvbjogXCIjZGMxNDNjXCIsXG4gICAgY3lhbjogXCIjMDBmZmZmXCIsXG4gICAgZGFya2JsdWU6IFwiIzAwMDA4YlwiLFxuICAgIGRhcmtjeWFuOiBcIiMwMDhiOGJcIixcbiAgICBkYXJrZ29sZGVucm9kOiBcIiNiODg2MGJcIixcbiAgICBkYXJrZ3JheTogXCIjYTlhOWE5XCIsXG4gICAgZGFya2dyZWVuOiBcIiMwMDY0MDBcIixcbiAgICBkYXJrZ3JleTogXCIjYTlhOWE5XCIsXG4gICAgZGFya2toYWtpOiBcIiNiZGI3NmJcIixcbiAgICBkYXJrbWFnZW50YTogXCIjOGIwMDhiXCIsXG4gICAgZGFya29saXZlZ3JlZW46IFwiIzU1NmIyZlwiLFxuICAgIGRhcmtvcmFuZ2U6IFwiI2ZmOGMwMFwiLFxuICAgIGRhcmtvcmNoaWQ6IFwiIzk5MzJjY1wiLFxuICAgIGRhcmtyZWQ6IFwiIzhiMDAwMFwiLFxuICAgIGRhcmtzYWxtb246IFwiI2U5OTY3YVwiLFxuICAgIGRhcmtzZWFncmVlbjogXCIjOGZiYzhmXCIsXG4gICAgZGFya3NsYXRlYmx1ZTogXCIjNDgzZDhiXCIsXG4gICAgZGFya3NsYXRlZ3JheTogXCIjMmY0ZjRmXCIsXG4gICAgZGFya3NsYXRlZ3JleTogXCIjMmY0ZjRmXCIsXG4gICAgZGFya3R1cnF1b2lzZTogXCIjMDBjZWQxXCIsXG4gICAgZGFya3Zpb2xldDogXCIjOTQwMGQzXCIsXG4gICAgZGVlcHBpbms6IFwiI2ZmMTQ5M1wiLFxuICAgIGRlZXBza3libHVlOiBcIiMwMGJmZmZcIixcbiAgICBkaW1ncmF5OiBcIiM2OTY5NjlcIixcbiAgICBkaW1ncmV5OiBcIiM2OTY5NjlcIixcbiAgICBkb2RnZXJibHVlOiBcIiMxZTkwZmZcIixcbiAgICBmaXJlYnJpY2s6IFwiI2IyMjIyMlwiLFxuICAgIGZsb3JhbHdoaXRlOiBcIiNmZmZhZjBcIixcbiAgICBmb3Jlc3RncmVlbjogXCIjMjI4YjIyXCIsXG4gICAgZnVjaHNpYTogXCIjZmYwMGZmXCIsXG4gICAgZ2FpbnNib3JvOiBcIiNkY2RjZGNcIixcbiAgICBnaG9zdHdoaXRlOiBcIiNmOGY4ZmZcIixcbiAgICBnb2xkOiBcIiNmZmQ3MDBcIixcbiAgICBnb2xkZW5yb2Q6IFwiI2RhYTUyMFwiLFxuICAgIGdyYXk6IFwiIzgwODA4MFwiLFxuICAgIGdyZWVuOiBcIiMwMDgwMDBcIixcbiAgICBncmVlbnllbGxvdzogXCIjYWRmZjJmXCIsXG4gICAgZ3JleTogXCIjODA4MDgwXCIsXG4gICAgaG9uZXlkZXc6IFwiI2YwZmZmMFwiLFxuICAgIGhvdHBpbms6IFwiI2ZmNjliNFwiLFxuICAgIGluZGlhbnJlZDogXCIjY2Q1YzVjXCIsXG4gICAgaW5kaWdvOiBcIiM0YjAwODJcIixcbiAgICBpdm9yeTogXCIjZmZmZmYwXCIsXG4gICAga2hha2k6IFwiI2YwZTY4Y1wiLFxuICAgIGxhdmVuZGVyOiBcIiNlNmU2ZmFcIixcbiAgICBsYXZlbmRlcmJsdXNoOiBcIiNmZmYwZjVcIixcbiAgICBsYXduZ3JlZW46IFwiIzdjZmMwMFwiLFxuICAgIGxlbW9uY2hpZmZvbjogXCIjZmZmYWNkXCIsXG4gICAgbGlnaHRibHVlOiBcIiNhZGQ4ZTZcIixcbiAgICBsaWdodGNvcmFsOiBcIiNmMDgwODBcIixcbiAgICBsaWdodGN5YW46IFwiI2UwZmZmZlwiLFxuICAgIGxpZ2h0Z29sZGVucm9keWVsbG93OiBcIiNmYWZhZDJcIixcbiAgICBsaWdodGdyYXk6IFwiI2QzZDNkM1wiLFxuICAgIGxpZ2h0Z3JlZW46IFwiIzkwZWU5MFwiLFxuICAgIGxpZ2h0Z3JleTogXCIjZDNkM2QzXCIsXG4gICAgbGlnaHRwaW5rOiBcIiNmZmI2YzFcIixcbiAgICBsaWdodHNhbG1vbjogXCIjZmZhMDdhXCIsXG4gICAgbGlnaHRzZWFncmVlbjogXCIjMjBiMmFhXCIsXG4gICAgbGlnaHRza3libHVlOiBcIiM4N2NlZmFcIixcbiAgICBsaWdodHNsYXRlZ3JheTogXCIjNzc4ODk5XCIsXG4gICAgbGlnaHRzbGF0ZWdyZXk6IFwiIzc3ODg5OVwiLFxuICAgIGxpZ2h0c3RlZWxibHVlOiBcIiNiMGM0ZGVcIixcbiAgICBsaWdodHllbGxvdzogXCIjZmZmZmUwXCIsXG4gICAgbGltZTogXCIjMDBmZjAwXCIsXG4gICAgbGltZWdyZWVuOiBcIiMzMmNkMzJcIixcbiAgICBsaW5lbjogXCIjZmFmMGU2XCIsXG4gICAgbWFnZW50YTogXCIjZmYwMGZmXCIsXG4gICAgbWFyb29uOiBcIiM4MDAwMDBcIixcbiAgICBtZWRpdW1hcXVhbWFyaW5lOiBcIiM2NmNkYWFcIixcbiAgICBtZWRpdW1ibHVlOiBcIiMwMDAwY2RcIixcbiAgICBtZWRpdW1vcmNoaWQ6IFwiI2JhNTVkM1wiLFxuICAgIG1lZGl1bXB1cnBsZTogXCIjOTM3MGRiXCIsXG4gICAgbWVkaXVtc2VhZ3JlZW46IFwiIzNjYjM3MVwiLFxuICAgIG1lZGl1bXNsYXRlYmx1ZTogXCIjN2I2OGVlXCIsXG4gICAgbWVkaXVtc3ByaW5nZ3JlZW46IFwiIzAwZmE5YVwiLFxuICAgIG1lZGl1bXR1cnF1b2lzZTogXCIjNDhkMWNjXCIsXG4gICAgbWVkaXVtdmlvbGV0cmVkOiBcIiNjNzE1ODVcIixcbiAgICBtaWRuaWdodGJsdWU6IFwiIzE5MTk3MFwiLFxuICAgIG1pbnRjcmVhbTogXCIjZjVmZmZhXCIsXG4gICAgbWlzdHlyb3NlOiBcIiNmZmU0ZTFcIixcbiAgICBtb2NjYXNpbjogXCIjZmZlNGI1XCIsXG4gICAgbmF2YWpvd2hpdGU6IFwiI2ZmZGVhZFwiLFxuICAgIG5hdnk6IFwiIzAwMDA4MFwiLFxuICAgIG9sZGxhY2U6IFwiI2ZkZjVlNlwiLFxuICAgIG9saXZlOiBcIiM4MDgwMDBcIixcbiAgICBvbGl2ZWRyYWI6IFwiIzZiOGUyM1wiLFxuICAgIG9yYW5nZTogXCIjZmZhNTAwXCIsXG4gICAgb3JhbmdlcmVkOiBcIiNmZjQ1MDBcIixcbiAgICBvcmNoaWQ6IFwiI2RhNzBkNlwiLFxuICAgIHBhbGVnb2xkZW5yb2Q6IFwiI2VlZThhYVwiLFxuICAgIHBhbGVncmVlbjogXCIjOThmYjk4XCIsXG4gICAgcGFsZXR1cnF1b2lzZTogXCIjYWZlZWVlXCIsXG4gICAgcGFsZXZpb2xldHJlZDogXCIjZGI3MDkzXCIsXG4gICAgcGFwYXlhd2hpcDogXCIjZmZlZmQ1XCIsXG4gICAgcGVhY2hwdWZmOiBcIiNmZmRhYjlcIixcbiAgICBwZXJ1OiBcIiNjZDg1M2ZcIixcbiAgICBwaW5rOiBcIiNmZmMwY2JcIixcbiAgICBwbHVtOiBcIiNkZGEwZGRcIixcbiAgICBwb3dkZXJibHVlOiBcIiNiMGUwZTZcIixcbiAgICBwdXJwbGU6IFwiIzgwMDA4MFwiLFxuICAgIHJlZDogXCIjZmYwMDAwXCIsXG4gICAgcm9zeWJyb3duOiBcIiNiYzhmOGZcIixcbiAgICByb3lhbGJsdWU6IFwiIzQxNjllMVwiLFxuICAgIHNhZGRsZWJyb3duOiBcIiM4YjQ1MTNcIixcbiAgICBzYWxtb246IFwiI2ZhODA3MlwiLFxuICAgIHNhbmR5YnJvd246IFwiI2Y0YTQ2MFwiLFxuICAgIHNlYWdyZWVuOiBcIiMyZThiNTdcIixcbiAgICBzZWFzaGVsbDogXCIjZmZmNWVlXCIsXG4gICAgc2llbm5hOiBcIiNhMDUyMmRcIixcbiAgICBzaWx2ZXI6IFwiI2MwYzBjMFwiLFxuICAgIHNreWJsdWU6IFwiIzg3Y2VlYlwiLFxuICAgIHNsYXRlYmx1ZTogXCIjNmE1YWNkXCIsXG4gICAgc2xhdGVncmF5OiBcIiM3MDgwOTBcIixcbiAgICBzbGF0ZWdyZXk6IFwiIzcwODA5MFwiLFxuICAgIHNub3c6IFwiI2ZmZmFmYVwiLFxuICAgIHNwcmluZ2dyZWVuOiBcIiMwMGZmN2ZcIixcbiAgICBzdGVlbGJsdWU6IFwiIzQ2ODJiNFwiLFxuICAgIHRhbjogXCIjZDJiNDhjXCIsXG4gICAgdGVhbDogXCIjMDA4MDgwXCIsXG4gICAgdGhpc3RsZTogXCIjZDhiZmQ4XCIsXG4gICAgdG9tYXRvOiBcIiNmZjYzNDdcIixcbiAgICB0dXJxdW9pc2U6IFwiIzQwZTBkMFwiLFxuICAgIHZpb2xldDogXCIjZWU4MmVlXCIsXG4gICAgd2hlYXQ6IFwiI2Y1ZGViM1wiLFxuICAgIHdoaXRlOiBcIiNmZmZmZmZcIixcbiAgICB3aGl0ZXNtb2tlOiBcIiNmNWY1ZjVcIixcbiAgICB5ZWxsb3c6IFwiI2ZmZmYwMFwiLFxuICAgIHllbGxvd2dyZWVuOiBcIiM5YWNkMzJcIlxuICB9KTtcbiAgZDNfcmdiX25hbWVzLmZvckVhY2goZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIGQzX3JnYl9uYW1lcy5zZXQoa2V5LCBkM19yZ2JfcGFyc2UodmFsdWUsIGQzX3JnYiwgZDNfaHNsX3JnYikpO1xuICB9KTtcbiAgZnVuY3Rpb24gZDNfZnVuY3Rvcih2KSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2ID09PSBcImZ1bmN0aW9uXCIgPyB2IDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdjtcbiAgICB9O1xuICB9XG4gIGQzLmZ1bmN0b3IgPSBkM19mdW5jdG9yO1xuICBmdW5jdGlvbiBkM19pZGVudGl0eShkKSB7XG4gICAgcmV0dXJuIGQ7XG4gIH1cbiAgZDMueGhyID0gZDNfeGhyVHlwZShkM19pZGVudGl0eSk7XG4gIGZ1bmN0aW9uIGQzX3hoclR5cGUocmVzcG9uc2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24odXJsLCBtaW1lVHlwZSwgY2FsbGJhY2spIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyICYmIHR5cGVvZiBtaW1lVHlwZSA9PT0gXCJmdW5jdGlvblwiKSBjYWxsYmFjayA9IG1pbWVUeXBlLCBcbiAgICAgIG1pbWVUeXBlID0gbnVsbDtcbiAgICAgIHJldHVybiBkM194aHIodXJsLCBtaW1lVHlwZSwgcmVzcG9uc2UsIGNhbGxiYWNrKTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX3hocih1cmwsIG1pbWVUeXBlLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgeGhyID0ge30sIGRpc3BhdGNoID0gZDMuZGlzcGF0Y2goXCJwcm9ncmVzc1wiLCBcImxvYWRcIiwgXCJlcnJvclwiKSwgaGVhZGVycyA9IHt9LCByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCksIHJlc3BvbnNlVHlwZSA9IG51bGw7XG4gICAgaWYgKGQzX3dpbmRvdy5YRG9tYWluUmVxdWVzdCAmJiAhKFwid2l0aENyZWRlbnRpYWxzXCIgaW4gcmVxdWVzdCkgJiYgL14oaHR0cChzKT86KT9cXC9cXC8vLnRlc3QodXJsKSkgcmVxdWVzdCA9IG5ldyBYRG9tYWluUmVxdWVzdCgpO1xuICAgIFwib25sb2FkXCIgaW4gcmVxdWVzdCA/IHJlcXVlc3Qub25sb2FkID0gcmVxdWVzdC5vbmVycm9yID0gcmVzcG9uZCA6IHJlcXVlc3Qub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXF1ZXN0LnJlYWR5U3RhdGUgPiAzICYmIHJlc3BvbmQoKTtcbiAgICB9O1xuICAgIGZ1bmN0aW9uIHJlc3BvbmQoKSB7XG4gICAgICB2YXIgc3RhdHVzID0gcmVxdWVzdC5zdGF0dXMsIHJlc3VsdDtcbiAgICAgIGlmICghc3RhdHVzICYmIHJlcXVlc3QucmVzcG9uc2VUZXh0IHx8IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwIHx8IHN0YXR1cyA9PT0gMzA0KSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmVzdWx0ID0gcmVzcG9uc2UuY2FsbCh4aHIsIHJlcXVlc3QpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgZGlzcGF0Y2guZXJyb3IuY2FsbCh4aHIsIGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBkaXNwYXRjaC5sb2FkLmNhbGwoeGhyLCByZXN1bHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGlzcGF0Y2guZXJyb3IuY2FsbCh4aHIsIHJlcXVlc3QpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXF1ZXN0Lm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIG8gPSBkMy5ldmVudDtcbiAgICAgIGQzLmV2ZW50ID0gZXZlbnQ7XG4gICAgICB0cnkge1xuICAgICAgICBkaXNwYXRjaC5wcm9ncmVzcy5jYWxsKHhociwgcmVxdWVzdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBkMy5ldmVudCA9IG87XG4gICAgICB9XG4gICAgfTtcbiAgICB4aHIuaGVhZGVyID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICAgIG5hbWUgPSAobmFtZSArIFwiXCIpLnRvTG93ZXJDYXNlKCk7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHJldHVybiBoZWFkZXJzW25hbWVdO1xuICAgICAgaWYgKHZhbHVlID09IG51bGwpIGRlbGV0ZSBoZWFkZXJzW25hbWVdOyBlbHNlIGhlYWRlcnNbbmFtZV0gPSB2YWx1ZSArIFwiXCI7XG4gICAgICByZXR1cm4geGhyO1xuICAgIH07XG4gICAgeGhyLm1pbWVUeXBlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIG1pbWVUeXBlO1xuICAgICAgbWltZVR5cGUgPSB2YWx1ZSA9PSBudWxsID8gbnVsbCA6IHZhbHVlICsgXCJcIjtcbiAgICAgIHJldHVybiB4aHI7XG4gICAgfTtcbiAgICB4aHIucmVzcG9uc2VUeXBlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHJlc3BvbnNlVHlwZTtcbiAgICAgIHJlc3BvbnNlVHlwZSA9IHZhbHVlO1xuICAgICAgcmV0dXJuIHhocjtcbiAgICB9O1xuICAgIHhoci5yZXNwb25zZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXNwb25zZSA9IHZhbHVlO1xuICAgICAgcmV0dXJuIHhocjtcbiAgICB9O1xuICAgIFsgXCJnZXRcIiwgXCJwb3N0XCIgXS5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgeGhyW21ldGhvZF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHhoci5zZW5kLmFwcGx5KHhociwgWyBtZXRob2QgXS5jb25jYXQoZDNfYXJyYXkoYXJndW1lbnRzKSkpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgICB4aHIuc2VuZCA9IGZ1bmN0aW9uKG1ldGhvZCwgZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyICYmIHR5cGVvZiBkYXRhID09PSBcImZ1bmN0aW9uXCIpIGNhbGxiYWNrID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gICAgICByZXF1ZXN0Lm9wZW4obWV0aG9kLCB1cmwsIHRydWUpO1xuICAgICAgaWYgKG1pbWVUeXBlICE9IG51bGwgJiYgIShcImFjY2VwdFwiIGluIGhlYWRlcnMpKSBoZWFkZXJzW1wiYWNjZXB0XCJdID0gbWltZVR5cGUgKyBcIiwqLypcIjtcbiAgICAgIGlmIChyZXF1ZXN0LnNldFJlcXVlc3RIZWFkZXIpIGZvciAodmFyIG5hbWUgaW4gaGVhZGVycykgcmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKG5hbWUsIGhlYWRlcnNbbmFtZV0pO1xuICAgICAgaWYgKG1pbWVUeXBlICE9IG51bGwgJiYgcmVxdWVzdC5vdmVycmlkZU1pbWVUeXBlKSByZXF1ZXN0Lm92ZXJyaWRlTWltZVR5cGUobWltZVR5cGUpO1xuICAgICAgaWYgKHJlc3BvbnNlVHlwZSAhPSBudWxsKSByZXF1ZXN0LnJlc3BvbnNlVHlwZSA9IHJlc3BvbnNlVHlwZTtcbiAgICAgIGlmIChjYWxsYmFjayAhPSBudWxsKSB4aHIub24oXCJlcnJvclwiLCBjYWxsYmFjaykub24oXCJsb2FkXCIsIGZ1bmN0aW9uKHJlcXVlc3QpIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVxdWVzdCk7XG4gICAgICB9KTtcbiAgICAgIHJlcXVlc3Quc2VuZChkYXRhID09IG51bGwgPyBudWxsIDogZGF0YSk7XG4gICAgICByZXR1cm4geGhyO1xuICAgIH07XG4gICAgeGhyLmFib3J0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXF1ZXN0LmFib3J0KCk7XG4gICAgICByZXR1cm4geGhyO1xuICAgIH07XG4gICAgZDMucmViaW5kKHhociwgZGlzcGF0Y2gsIFwib25cIik7XG4gICAgcmV0dXJuIGNhbGxiYWNrID09IG51bGwgPyB4aHIgOiB4aHIuZ2V0KGQzX3hocl9maXhDYWxsYmFjayhjYWxsYmFjaykpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3hocl9maXhDYWxsYmFjayhjYWxsYmFjaykge1xuICAgIHJldHVybiBjYWxsYmFjay5sZW5ndGggPT09IDEgPyBmdW5jdGlvbihlcnJvciwgcmVxdWVzdCkge1xuICAgICAgY2FsbGJhY2soZXJyb3IgPT0gbnVsbCA/IHJlcXVlc3QgOiBudWxsKTtcbiAgICB9IDogY2FsbGJhY2s7XG4gIH1cbiAgZDMuZHN2ID0gZnVuY3Rpb24oZGVsaW1pdGVyLCBtaW1lVHlwZSkge1xuICAgIHZhciByZUZvcm1hdCA9IG5ldyBSZWdFeHAoJ1tcIicgKyBkZWxpbWl0ZXIgKyBcIlxcbl1cIiksIGRlbGltaXRlckNvZGUgPSBkZWxpbWl0ZXIuY2hhckNvZGVBdCgwKTtcbiAgICBmdW5jdGlvbiBkc3YodXJsLCByb3csIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIGNhbGxiYWNrID0gcm93LCByb3cgPSBudWxsO1xuICAgICAgdmFyIHhociA9IGQzLnhocih1cmwsIG1pbWVUeXBlLCBjYWxsYmFjayk7XG4gICAgICB4aHIucm93ID0gZnVuY3Rpb24oXykge1xuICAgICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHhoci5yZXNwb25zZSgocm93ID0gXykgPT0gbnVsbCA/IHJlc3BvbnNlIDogdHlwZWRSZXNwb25zZShfKSkgOiByb3c7XG4gICAgICB9O1xuICAgICAgcmV0dXJuIHhoci5yb3cocm93KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcmVzcG9uc2UocmVxdWVzdCkge1xuICAgICAgcmV0dXJuIGRzdi5wYXJzZShyZXF1ZXN0LnJlc3BvbnNlVGV4dCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHR5cGVkUmVzcG9uc2UoZikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIGRzdi5wYXJzZShyZXF1ZXN0LnJlc3BvbnNlVGV4dCwgZik7XG4gICAgICB9O1xuICAgIH1cbiAgICBkc3YucGFyc2UgPSBmdW5jdGlvbih0ZXh0LCBmKSB7XG4gICAgICB2YXIgbztcbiAgICAgIHJldHVybiBkc3YucGFyc2VSb3dzKHRleHQsIGZ1bmN0aW9uKHJvdywgaSkge1xuICAgICAgICBpZiAobykgcmV0dXJuIG8ocm93LCBpIC0gMSk7XG4gICAgICAgIHZhciBhID0gbmV3IEZ1bmN0aW9uKFwiZFwiLCBcInJldHVybiB7XCIgKyByb3cubWFwKGZ1bmN0aW9uKG5hbWUsIGkpIHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobmFtZSkgKyBcIjogZFtcIiArIGkgKyBcIl1cIjtcbiAgICAgICAgfSkuam9pbihcIixcIikgKyBcIn1cIik7XG4gICAgICAgIG8gPSBmID8gZnVuY3Rpb24ocm93LCBpKSB7XG4gICAgICAgICAgcmV0dXJuIGYoYShyb3cpLCBpKTtcbiAgICAgICAgfSA6IGE7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIGRzdi5wYXJzZVJvd3MgPSBmdW5jdGlvbih0ZXh0LCBmKSB7XG4gICAgICB2YXIgRU9MID0ge30sIEVPRiA9IHt9LCByb3dzID0gW10sIE4gPSB0ZXh0Lmxlbmd0aCwgSSA9IDAsIG4gPSAwLCB0LCBlb2w7XG4gICAgICBmdW5jdGlvbiB0b2tlbigpIHtcbiAgICAgICAgaWYgKEkgPj0gTikgcmV0dXJuIEVPRjtcbiAgICAgICAgaWYgKGVvbCkgcmV0dXJuIGVvbCA9IGZhbHNlLCBFT0w7XG4gICAgICAgIHZhciBqID0gSTtcbiAgICAgICAgaWYgKHRleHQuY2hhckNvZGVBdChqKSA9PT0gMzQpIHtcbiAgICAgICAgICB2YXIgaSA9IGo7XG4gICAgICAgICAgd2hpbGUgKGkrKyA8IE4pIHtcbiAgICAgICAgICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoaSkgPT09IDM0KSB7XG4gICAgICAgICAgICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoaSArIDEpICE9PSAzNCkgYnJlYWs7XG4gICAgICAgICAgICAgICsraTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgSSA9IGkgKyAyO1xuICAgICAgICAgIHZhciBjID0gdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgICAgICBpZiAoYyA9PT0gMTMpIHtcbiAgICAgICAgICAgIGVvbCA9IHRydWU7XG4gICAgICAgICAgICBpZiAodGV4dC5jaGFyQ29kZUF0KGkgKyAyKSA9PT0gMTApICsrSTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09IDEwKSB7XG4gICAgICAgICAgICBlb2wgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGV4dC5zdWJzdHJpbmcoaiArIDEsIGkpLnJlcGxhY2UoL1wiXCIvZywgJ1wiJyk7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKEkgPCBOKSB7XG4gICAgICAgICAgdmFyIGMgPSB0ZXh0LmNoYXJDb2RlQXQoSSsrKSwgayA9IDE7XG4gICAgICAgICAgaWYgKGMgPT09IDEwKSBlb2wgPSB0cnVlOyBlbHNlIGlmIChjID09PSAxMykge1xuICAgICAgICAgICAgZW9sID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoSSkgPT09IDEwKSArK0ksICsraztcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgIT09IGRlbGltaXRlckNvZGUpIGNvbnRpbnVlO1xuICAgICAgICAgIHJldHVybiB0ZXh0LnN1YnN0cmluZyhqLCBJIC0gayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRleHQuc3Vic3RyaW5nKGopO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCh0ID0gdG9rZW4oKSkgIT09IEVPRikge1xuICAgICAgICB2YXIgYSA9IFtdO1xuICAgICAgICB3aGlsZSAodCAhPT0gRU9MICYmIHQgIT09IEVPRikge1xuICAgICAgICAgIGEucHVzaCh0KTtcbiAgICAgICAgICB0ID0gdG9rZW4oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZiAmJiAhKGEgPSBmKGEsIG4rKykpKSBjb250aW51ZTtcbiAgICAgICAgcm93cy5wdXNoKGEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJvd3M7XG4gICAgfTtcbiAgICBkc3YuZm9ybWF0ID0gZnVuY3Rpb24ocm93cykge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkocm93c1swXSkpIHJldHVybiBkc3YuZm9ybWF0Um93cyhyb3dzKTtcbiAgICAgIHZhciBmaWVsZFNldCA9IG5ldyBkM19TZXQoKSwgZmllbGRzID0gW107XG4gICAgICByb3dzLmZvckVhY2goZnVuY3Rpb24ocm93KSB7XG4gICAgICAgIGZvciAodmFyIGZpZWxkIGluIHJvdykge1xuICAgICAgICAgIGlmICghZmllbGRTZXQuaGFzKGZpZWxkKSkge1xuICAgICAgICAgICAgZmllbGRzLnB1c2goZmllbGRTZXQuYWRkKGZpZWxkKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBbIGZpZWxkcy5tYXAoZm9ybWF0VmFsdWUpLmpvaW4oZGVsaW1pdGVyKSBdLmNvbmNhdChyb3dzLm1hcChmdW5jdGlvbihyb3cpIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkcy5tYXAoZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgICAgICByZXR1cm4gZm9ybWF0VmFsdWUocm93W2ZpZWxkXSk7XG4gICAgICAgIH0pLmpvaW4oZGVsaW1pdGVyKTtcbiAgICAgIH0pKS5qb2luKFwiXFxuXCIpO1xuICAgIH07XG4gICAgZHN2LmZvcm1hdFJvd3MgPSBmdW5jdGlvbihyb3dzKSB7XG4gICAgICByZXR1cm4gcm93cy5tYXAoZm9ybWF0Um93KS5qb2luKFwiXFxuXCIpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gZm9ybWF0Um93KHJvdykge1xuICAgICAgcmV0dXJuIHJvdy5tYXAoZm9ybWF0VmFsdWUpLmpvaW4oZGVsaW1pdGVyKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZm9ybWF0VmFsdWUodGV4dCkge1xuICAgICAgcmV0dXJuIHJlRm9ybWF0LnRlc3QodGV4dCkgPyAnXCInICsgdGV4dC5yZXBsYWNlKC9cXFwiL2csICdcIlwiJykgKyAnXCInIDogdGV4dDtcbiAgICB9XG4gICAgcmV0dXJuIGRzdjtcbiAgfTtcbiAgZDMuY3N2ID0gZDMuZHN2KFwiLFwiLCBcInRleHQvY3N2XCIpO1xuICBkMy50c3YgPSBkMy5kc3YoXCJcdFwiLCBcInRleHQvdGFiLXNlcGFyYXRlZC12YWx1ZXNcIik7XG4gIHZhciBkM190aW1lcl9xdWV1ZUhlYWQsIGQzX3RpbWVyX3F1ZXVlVGFpbCwgZDNfdGltZXJfaW50ZXJ2YWwsIGQzX3RpbWVyX3RpbWVvdXQ7XG4gIGQzLnRpbWVyID0gZnVuY3Rpb24oY2FsbGJhY2ssIGRlbGF5LCB0aGVuKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIGRlbGF5ID0gMDsgZWxzZSBpZiAoIWlzRmluaXRlKGRlbGF5KSkgcmV0dXJuO1xuICAgICAgdGhlbiA9IERhdGUubm93KCk7XG4gICAgfVxuICAgIHZhciB0aW1lID0gdGhlbiArIGRlbGF5O1xuICAgIHZhciB0aW1lciA9IHtcbiAgICAgIGNhbGxiYWNrOiBjYWxsYmFjayxcbiAgICAgIHRpbWU6IHRpbWUsXG4gICAgICBuZXh0OiBudWxsXG4gICAgfTtcbiAgICBpZiAoZDNfdGltZXJfcXVldWVUYWlsKSBkM190aW1lcl9xdWV1ZVRhaWwubmV4dCA9IHRpbWVyOyBlbHNlIGQzX3RpbWVyX3F1ZXVlSGVhZCA9IHRpbWVyO1xuICAgIGQzX3RpbWVyX3F1ZXVlVGFpbCA9IHRpbWVyO1xuICAgIGlmICghZDNfdGltZXJfaW50ZXJ2YWwpIHtcbiAgICAgIGQzX3RpbWVyX3RpbWVvdXQgPSBjbGVhclRpbWVvdXQoZDNfdGltZXJfdGltZW91dCk7XG4gICAgICBkM190aW1lcl9pbnRlcnZhbCA9IDE7XG4gICAgICBkM190aW1lcl9mcmFtZShkM190aW1lcl9zdGVwKTtcbiAgICB9XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3RpbWVyX3N0ZXAoKSB7XG4gICAgdmFyIG5vdyA9IGQzX3RpbWVyX21hcmsoKSwgZGVsYXkgPSBkM190aW1lcl9zd2VlcCgpIC0gbm93O1xuICAgIGlmIChkZWxheSA+IDI0KSB7XG4gICAgICBpZiAoaXNGaW5pdGUoZGVsYXkpKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChkM190aW1lcl90aW1lb3V0KTtcbiAgICAgICAgZDNfdGltZXJfdGltZW91dCA9IHNldFRpbWVvdXQoZDNfdGltZXJfc3RlcCwgZGVsYXkpO1xuICAgICAgfVxuICAgICAgZDNfdGltZXJfaW50ZXJ2YWwgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBkM190aW1lcl9pbnRlcnZhbCA9IDE7XG4gICAgICBkM190aW1lcl9mcmFtZShkM190aW1lcl9zdGVwKTtcbiAgICB9XG4gIH1cbiAgZDMudGltZXIuZmx1c2ggPSBmdW5jdGlvbigpIHtcbiAgICBkM190aW1lcl9tYXJrKCk7XG4gICAgZDNfdGltZXJfc3dlZXAoKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfdGltZXJfbWFyaygpIHtcbiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKSwgdGltZXIgPSBkM190aW1lcl9xdWV1ZUhlYWQ7XG4gICAgd2hpbGUgKHRpbWVyKSB7XG4gICAgICBpZiAobm93ID49IHRpbWVyLnRpbWUpIHRpbWVyLmZsdXNoID0gdGltZXIuY2FsbGJhY2sobm93IC0gdGltZXIudGltZSk7XG4gICAgICB0aW1lciA9IHRpbWVyLm5leHQ7XG4gICAgfVxuICAgIHJldHVybiBub3c7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZXJfc3dlZXAoKSB7XG4gICAgdmFyIHQwLCB0MSA9IGQzX3RpbWVyX3F1ZXVlSGVhZCwgdGltZSA9IEluZmluaXR5O1xuICAgIHdoaWxlICh0MSkge1xuICAgICAgaWYgKHQxLmZsdXNoKSB7XG4gICAgICAgIHQxID0gdDAgPyB0MC5uZXh0ID0gdDEubmV4dCA6IGQzX3RpbWVyX3F1ZXVlSGVhZCA9IHQxLm5leHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodDEudGltZSA8IHRpbWUpIHRpbWUgPSB0MS50aW1lO1xuICAgICAgICB0MSA9ICh0MCA9IHQxKS5uZXh0O1xuICAgICAgfVxuICAgIH1cbiAgICBkM190aW1lcl9xdWV1ZVRhaWwgPSB0MDtcbiAgICByZXR1cm4gdGltZTtcbiAgfVxuICB2YXIgZDNfdGltZXJfZnJhbWUgPSBkM193aW5kb3dbZDNfdmVuZG9yU3ltYm9sKGQzX3dpbmRvdywgXCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWVcIildIHx8IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgc2V0VGltZW91dChjYWxsYmFjaywgMTcpO1xuICB9O1xuICB2YXIgZDNfZm9ybWF0X2RlY2ltYWxQb2ludCA9IFwiLlwiLCBkM19mb3JtYXRfdGhvdXNhbmRzU2VwYXJhdG9yID0gXCIsXCIsIGQzX2Zvcm1hdF9ncm91cGluZyA9IFsgMywgMyBdLCBkM19mb3JtYXRfY3VycmVuY3lTeW1ib2wgPSBcIiRcIjtcbiAgdmFyIGQzX2Zvcm1hdFByZWZpeGVzID0gWyBcInlcIiwgXCJ6XCIsIFwiYVwiLCBcImZcIiwgXCJwXCIsIFwiblwiLCBcIsK1XCIsIFwibVwiLCBcIlwiLCBcImtcIiwgXCJNXCIsIFwiR1wiLCBcIlRcIiwgXCJQXCIsIFwiRVwiLCBcIlpcIiwgXCJZXCIgXS5tYXAoZDNfZm9ybWF0UHJlZml4KTtcbiAgZDMuZm9ybWF0UHJlZml4ID0gZnVuY3Rpb24odmFsdWUsIHByZWNpc2lvbikge1xuICAgIHZhciBpID0gMDtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIGlmICh2YWx1ZSA8IDApIHZhbHVlICo9IC0xO1xuICAgICAgaWYgKHByZWNpc2lvbikgdmFsdWUgPSBkMy5yb3VuZCh2YWx1ZSwgZDNfZm9ybWF0X3ByZWNpc2lvbih2YWx1ZSwgcHJlY2lzaW9uKSk7XG4gICAgICBpID0gMSArIE1hdGguZmxvb3IoMWUtMTIgKyBNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMTApO1xuICAgICAgaSA9IE1hdGgubWF4KC0yNCwgTWF0aC5taW4oMjQsIE1hdGguZmxvb3IoKGkgPD0gMCA/IGkgKyAxIDogaSAtIDEpIC8gMykgKiAzKSk7XG4gICAgfVxuICAgIHJldHVybiBkM19mb3JtYXRQcmVmaXhlc1s4ICsgaSAvIDNdO1xuICB9O1xuICBmdW5jdGlvbiBkM19mb3JtYXRQcmVmaXgoZCwgaSkge1xuICAgIHZhciBrID0gTWF0aC5wb3coMTAsIE1hdGguYWJzKDggLSBpKSAqIDMpO1xuICAgIHJldHVybiB7XG4gICAgICBzY2FsZTogaSA+IDggPyBmdW5jdGlvbihkKSB7XG4gICAgICAgIHJldHVybiBkIC8gaztcbiAgICAgIH0gOiBmdW5jdGlvbihkKSB7XG4gICAgICAgIHJldHVybiBkICogaztcbiAgICAgIH0sXG4gICAgICBzeW1ib2w6IGRcbiAgICB9O1xuICB9XG4gIGQzLnJvdW5kID0gZnVuY3Rpb24oeCwgbikge1xuICAgIHJldHVybiBuID8gTWF0aC5yb3VuZCh4ICogKG4gPSBNYXRoLnBvdygxMCwgbikpKSAvIG4gOiBNYXRoLnJvdW5kKHgpO1xuICB9O1xuICBkMy5mb3JtYXQgPSBmdW5jdGlvbihzcGVjaWZpZXIpIHtcbiAgICB2YXIgbWF0Y2ggPSBkM19mb3JtYXRfcmUuZXhlYyhzcGVjaWZpZXIpLCBmaWxsID0gbWF0Y2hbMV0gfHwgXCIgXCIsIGFsaWduID0gbWF0Y2hbMl0gfHwgXCI+XCIsIHNpZ24gPSBtYXRjaFszXSB8fCBcIlwiLCBiYXNlID0gbWF0Y2hbNF0gfHwgXCJcIiwgemZpbGwgPSBtYXRjaFs1XSwgd2lkdGggPSArbWF0Y2hbNl0sIGNvbW1hID0gbWF0Y2hbN10sIHByZWNpc2lvbiA9IG1hdGNoWzhdLCB0eXBlID0gbWF0Y2hbOV0sIHNjYWxlID0gMSwgc3VmZml4ID0gXCJcIiwgaW50ZWdlciA9IGZhbHNlO1xuICAgIGlmIChwcmVjaXNpb24pIHByZWNpc2lvbiA9ICtwcmVjaXNpb24uc3Vic3RyaW5nKDEpO1xuICAgIGlmICh6ZmlsbCB8fCBmaWxsID09PSBcIjBcIiAmJiBhbGlnbiA9PT0gXCI9XCIpIHtcbiAgICAgIHpmaWxsID0gZmlsbCA9IFwiMFwiO1xuICAgICAgYWxpZ24gPSBcIj1cIjtcbiAgICAgIGlmIChjb21tYSkgd2lkdGggLT0gTWF0aC5mbG9vcigod2lkdGggLSAxKSAvIDQpO1xuICAgIH1cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgY2FzZSBcIm5cIjpcbiAgICAgIGNvbW1hID0gdHJ1ZTtcbiAgICAgIHR5cGUgPSBcImdcIjtcbiAgICAgIGJyZWFrO1xuXG4gICAgIGNhc2UgXCIlXCI6XG4gICAgICBzY2FsZSA9IDEwMDtcbiAgICAgIHN1ZmZpeCA9IFwiJVwiO1xuICAgICAgdHlwZSA9IFwiZlwiO1xuICAgICAgYnJlYWs7XG5cbiAgICAgY2FzZSBcInBcIjpcbiAgICAgIHNjYWxlID0gMTAwO1xuICAgICAgc3VmZml4ID0gXCIlXCI7XG4gICAgICB0eXBlID0gXCJyXCI7XG4gICAgICBicmVhaztcblxuICAgICBjYXNlIFwiYlwiOlxuICAgICBjYXNlIFwib1wiOlxuICAgICBjYXNlIFwieFwiOlxuICAgICBjYXNlIFwiWFwiOlxuICAgICAgaWYgKGJhc2UgPT09IFwiI1wiKSBiYXNlID0gXCIwXCIgKyB0eXBlLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgY2FzZSBcImNcIjpcbiAgICAgY2FzZSBcImRcIjpcbiAgICAgIGludGVnZXIgPSB0cnVlO1xuICAgICAgcHJlY2lzaW9uID0gMDtcbiAgICAgIGJyZWFrO1xuXG4gICAgIGNhc2UgXCJzXCI6XG4gICAgICBzY2FsZSA9IC0xO1xuICAgICAgdHlwZSA9IFwiclwiO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGlmIChiYXNlID09PSBcIiNcIikgYmFzZSA9IFwiXCI7IGVsc2UgaWYgKGJhc2UgPT09IFwiJFwiKSBiYXNlID0gZDNfZm9ybWF0X2N1cnJlbmN5U3ltYm9sO1xuICAgIGlmICh0eXBlID09IFwiclwiICYmICFwcmVjaXNpb24pIHR5cGUgPSBcImdcIjtcbiAgICBpZiAocHJlY2lzaW9uICE9IG51bGwpIHtcbiAgICAgIGlmICh0eXBlID09IFwiZ1wiKSBwcmVjaXNpb24gPSBNYXRoLm1heCgxLCBNYXRoLm1pbigyMSwgcHJlY2lzaW9uKSk7IGVsc2UgaWYgKHR5cGUgPT0gXCJlXCIgfHwgdHlwZSA9PSBcImZcIikgcHJlY2lzaW9uID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMjAsIHByZWNpc2lvbikpO1xuICAgIH1cbiAgICB0eXBlID0gZDNfZm9ybWF0X3R5cGVzLmdldCh0eXBlKSB8fCBkM19mb3JtYXRfdHlwZURlZmF1bHQ7XG4gICAgdmFyIHpjb21tYSA9IHpmaWxsICYmIGNvbW1hO1xuICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKGludGVnZXIgJiYgdmFsdWUgJSAxKSByZXR1cm4gXCJcIjtcbiAgICAgIHZhciBuZWdhdGl2ZSA9IHZhbHVlIDwgMCB8fCB2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwID8gKHZhbHVlID0gLXZhbHVlLCBcIi1cIikgOiBzaWduO1xuICAgICAgaWYgKHNjYWxlIDwgMCkge1xuICAgICAgICB2YXIgcHJlZml4ID0gZDMuZm9ybWF0UHJlZml4KHZhbHVlLCBwcmVjaXNpb24pO1xuICAgICAgICB2YWx1ZSA9IHByZWZpeC5zY2FsZSh2YWx1ZSk7XG4gICAgICAgIHN1ZmZpeCA9IHByZWZpeC5zeW1ib2w7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZSAqPSBzY2FsZTtcbiAgICAgIH1cbiAgICAgIHZhbHVlID0gdHlwZSh2YWx1ZSwgcHJlY2lzaW9uKTtcbiAgICAgIGlmICghemZpbGwgJiYgY29tbWEpIHZhbHVlID0gZDNfZm9ybWF0X2dyb3VwKHZhbHVlKTtcbiAgICAgIHZhciBsZW5ndGggPSBiYXNlLmxlbmd0aCArIHZhbHVlLmxlbmd0aCArICh6Y29tbWEgPyAwIDogbmVnYXRpdmUubGVuZ3RoKSwgcGFkZGluZyA9IGxlbmd0aCA8IHdpZHRoID8gbmV3IEFycmF5KGxlbmd0aCA9IHdpZHRoIC0gbGVuZ3RoICsgMSkuam9pbihmaWxsKSA6IFwiXCI7XG4gICAgICBpZiAoemNvbW1hKSB2YWx1ZSA9IGQzX2Zvcm1hdF9ncm91cChwYWRkaW5nICsgdmFsdWUpO1xuICAgICAgaWYgKGQzX2Zvcm1hdF9kZWNpbWFsUG9pbnQpIHZhbHVlLnJlcGxhY2UoXCIuXCIsIGQzX2Zvcm1hdF9kZWNpbWFsUG9pbnQpO1xuICAgICAgbmVnYXRpdmUgKz0gYmFzZTtcbiAgICAgIHJldHVybiAoYWxpZ24gPT09IFwiPFwiID8gbmVnYXRpdmUgKyB2YWx1ZSArIHBhZGRpbmcgOiBhbGlnbiA9PT0gXCI+XCIgPyBwYWRkaW5nICsgbmVnYXRpdmUgKyB2YWx1ZSA6IGFsaWduID09PSBcIl5cIiA/IHBhZGRpbmcuc3Vic3RyaW5nKDAsIGxlbmd0aCA+Pj0gMSkgKyBuZWdhdGl2ZSArIHZhbHVlICsgcGFkZGluZy5zdWJzdHJpbmcobGVuZ3RoKSA6IG5lZ2F0aXZlICsgKHpjb21tYSA/IHZhbHVlIDogcGFkZGluZyArIHZhbHVlKSkgKyBzdWZmaXg7XG4gICAgfTtcbiAgfTtcbiAgdmFyIGQzX2Zvcm1hdF9yZSA9IC8oPzooW157XSk/KFs8Pj1eXSkpPyhbK1xcLSBdKT8oWyQjXSk/KDApPyhcXGQrKT8oLCk/KFxcLi0/XFxkKyk/KFthLXolXSk/L2k7XG4gIHZhciBkM19mb3JtYXRfdHlwZXMgPSBkMy5tYXAoe1xuICAgIGI6IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiB4LnRvU3RyaW5nKDIpO1xuICAgIH0sXG4gICAgYzogZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoeCk7XG4gICAgfSxcbiAgICBvOiBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4geC50b1N0cmluZyg4KTtcbiAgICB9LFxuICAgIHg6IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiB4LnRvU3RyaW5nKDE2KTtcbiAgICB9LFxuICAgIFg6IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiB4LnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuICAgIH0sXG4gICAgZzogZnVuY3Rpb24oeCwgcCkge1xuICAgICAgcmV0dXJuIHgudG9QcmVjaXNpb24ocCk7XG4gICAgfSxcbiAgICBlOiBmdW5jdGlvbih4LCBwKSB7XG4gICAgICByZXR1cm4geC50b0V4cG9uZW50aWFsKHApO1xuICAgIH0sXG4gICAgZjogZnVuY3Rpb24oeCwgcCkge1xuICAgICAgcmV0dXJuIHgudG9GaXhlZChwKTtcbiAgICB9LFxuICAgIHI6IGZ1bmN0aW9uKHgsIHApIHtcbiAgICAgIHJldHVybiAoeCA9IGQzLnJvdW5kKHgsIGQzX2Zvcm1hdF9wcmVjaXNpb24oeCwgcCkpKS50b0ZpeGVkKE1hdGgubWF4KDAsIE1hdGgubWluKDIwLCBkM19mb3JtYXRfcHJlY2lzaW9uKHggKiAoMSArIDFlLTE1KSwgcCkpKSk7XG4gICAgfVxuICB9KTtcbiAgZnVuY3Rpb24gZDNfZm9ybWF0X3ByZWNpc2lvbih4LCBwKSB7XG4gICAgcmV0dXJuIHAgLSAoeCA/IE1hdGguY2VpbChNYXRoLmxvZyh4KSAvIE1hdGguTE4xMCkgOiAxKTtcbiAgfVxuICBmdW5jdGlvbiBkM19mb3JtYXRfdHlwZURlZmF1bHQoeCkge1xuICAgIHJldHVybiB4ICsgXCJcIjtcbiAgfVxuICB2YXIgZDNfZm9ybWF0X2dyb3VwID0gZDNfaWRlbnRpdHk7XG4gIGlmIChkM19mb3JtYXRfZ3JvdXBpbmcpIHtcbiAgICB2YXIgZDNfZm9ybWF0X2dyb3VwaW5nTGVuZ3RoID0gZDNfZm9ybWF0X2dyb3VwaW5nLmxlbmd0aDtcbiAgICBkM19mb3JtYXRfZ3JvdXAgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgdmFyIGkgPSB2YWx1ZS5sYXN0SW5kZXhPZihcIi5cIiksIGYgPSBpID49IDAgPyBcIi5cIiArIHZhbHVlLnN1YnN0cmluZyhpICsgMSkgOiAoaSA9IHZhbHVlLmxlbmd0aCwgXG4gICAgICBcIlwiKSwgdCA9IFtdLCBqID0gMCwgZyA9IGQzX2Zvcm1hdF9ncm91cGluZ1swXTtcbiAgICAgIHdoaWxlIChpID4gMCAmJiBnID4gMCkge1xuICAgICAgICB0LnB1c2godmFsdWUuc3Vic3RyaW5nKGkgLT0gZywgaSArIGcpKTtcbiAgICAgICAgZyA9IGQzX2Zvcm1hdF9ncm91cGluZ1tqID0gKGogKyAxKSAlIGQzX2Zvcm1hdF9ncm91cGluZ0xlbmd0aF07XG4gICAgICB9XG4gICAgICByZXR1cm4gdC5yZXZlcnNlKCkuam9pbihkM19mb3JtYXRfdGhvdXNhbmRzU2VwYXJhdG9yIHx8IFwiXCIpICsgZjtcbiAgICB9O1xuICB9XG4gIGQzLmdlbyA9IHt9O1xuICBmdW5jdGlvbiBkM19hZGRlcigpIHt9XG4gIGQzX2FkZGVyLnByb3RvdHlwZSA9IHtcbiAgICBzOiAwLFxuICAgIHQ6IDAsXG4gICAgYWRkOiBmdW5jdGlvbih5KSB7XG4gICAgICBkM19hZGRlclN1bSh5LCB0aGlzLnQsIGQzX2FkZGVyVGVtcCk7XG4gICAgICBkM19hZGRlclN1bShkM19hZGRlclRlbXAucywgdGhpcy5zLCB0aGlzKTtcbiAgICAgIGlmICh0aGlzLnMpIHRoaXMudCArPSBkM19hZGRlclRlbXAudDsgZWxzZSB0aGlzLnMgPSBkM19hZGRlclRlbXAudDtcbiAgICB9LFxuICAgIHJlc2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMucyA9IHRoaXMudCA9IDA7XG4gICAgfSxcbiAgICB2YWx1ZU9mOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnM7XG4gICAgfVxuICB9O1xuICB2YXIgZDNfYWRkZXJUZW1wID0gbmV3IGQzX2FkZGVyKCk7XG4gIGZ1bmN0aW9uIGQzX2FkZGVyU3VtKGEsIGIsIG8pIHtcbiAgICB2YXIgeCA9IG8ucyA9IGEgKyBiLCBidiA9IHggLSBhLCBhdiA9IHggLSBidjtcbiAgICBvLnQgPSBhIC0gYXYgKyAoYiAtIGJ2KTtcbiAgfVxuICBkMy5nZW8uc3RyZWFtID0gZnVuY3Rpb24ob2JqZWN0LCBsaXN0ZW5lcikge1xuICAgIGlmIChvYmplY3QgJiYgZDNfZ2VvX3N0cmVhbU9iamVjdFR5cGUuaGFzT3duUHJvcGVydHkob2JqZWN0LnR5cGUpKSB7XG4gICAgICBkM19nZW9fc3RyZWFtT2JqZWN0VHlwZVtvYmplY3QudHlwZV0ob2JqZWN0LCBsaXN0ZW5lcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGQzX2dlb19zdHJlYW1HZW9tZXRyeShvYmplY3QsIGxpc3RlbmVyKTtcbiAgICB9XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2dlb19zdHJlYW1HZW9tZXRyeShnZW9tZXRyeSwgbGlzdGVuZXIpIHtcbiAgICBpZiAoZ2VvbWV0cnkgJiYgZDNfZ2VvX3N0cmVhbUdlb21ldHJ5VHlwZS5oYXNPd25Qcm9wZXJ0eShnZW9tZXRyeS50eXBlKSkge1xuICAgICAgZDNfZ2VvX3N0cmVhbUdlb21ldHJ5VHlwZVtnZW9tZXRyeS50eXBlXShnZW9tZXRyeSwgbGlzdGVuZXIpO1xuICAgIH1cbiAgfVxuICB2YXIgZDNfZ2VvX3N0cmVhbU9iamVjdFR5cGUgPSB7XG4gICAgRmVhdHVyZTogZnVuY3Rpb24oZmVhdHVyZSwgbGlzdGVuZXIpIHtcbiAgICAgIGQzX2dlb19zdHJlYW1HZW9tZXRyeShmZWF0dXJlLmdlb21ldHJ5LCBsaXN0ZW5lcik7XG4gICAgfSxcbiAgICBGZWF0dXJlQ29sbGVjdGlvbjogZnVuY3Rpb24ob2JqZWN0LCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGZlYXR1cmVzID0gb2JqZWN0LmZlYXR1cmVzLCBpID0gLTEsIG4gPSBmZWF0dXJlcy5sZW5ndGg7XG4gICAgICB3aGlsZSAoKytpIDwgbikgZDNfZ2VvX3N0cmVhbUdlb21ldHJ5KGZlYXR1cmVzW2ldLmdlb21ldHJ5LCBsaXN0ZW5lcik7XG4gICAgfVxuICB9O1xuICB2YXIgZDNfZ2VvX3N0cmVhbUdlb21ldHJ5VHlwZSA9IHtcbiAgICBTcGhlcmU6IGZ1bmN0aW9uKG9iamVjdCwgbGlzdGVuZXIpIHtcbiAgICAgIGxpc3RlbmVyLnNwaGVyZSgpO1xuICAgIH0sXG4gICAgUG9pbnQ6IGZ1bmN0aW9uKG9iamVjdCwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBjb29yZGluYXRlID0gb2JqZWN0LmNvb3JkaW5hdGVzO1xuICAgICAgbGlzdGVuZXIucG9pbnQoY29vcmRpbmF0ZVswXSwgY29vcmRpbmF0ZVsxXSk7XG4gICAgfSxcbiAgICBNdWx0aVBvaW50OiBmdW5jdGlvbihvYmplY3QsIGxpc3RlbmVyKSB7XG4gICAgICB2YXIgY29vcmRpbmF0ZXMgPSBvYmplY3QuY29vcmRpbmF0ZXMsIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aCwgY29vcmRpbmF0ZTtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBjb29yZGluYXRlID0gY29vcmRpbmF0ZXNbaV0sIGxpc3RlbmVyLnBvaW50KGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0pO1xuICAgIH0sXG4gICAgTGluZVN0cmluZzogZnVuY3Rpb24ob2JqZWN0LCBsaXN0ZW5lcikge1xuICAgICAgZDNfZ2VvX3N0cmVhbUxpbmUob2JqZWN0LmNvb3JkaW5hdGVzLCBsaXN0ZW5lciwgMCk7XG4gICAgfSxcbiAgICBNdWx0aUxpbmVTdHJpbmc6IGZ1bmN0aW9uKG9iamVjdCwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBjb29yZGluYXRlcyA9IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIGQzX2dlb19zdHJlYW1MaW5lKGNvb3JkaW5hdGVzW2ldLCBsaXN0ZW5lciwgMCk7XG4gICAgfSxcbiAgICBQb2x5Z29uOiBmdW5jdGlvbihvYmplY3QsIGxpc3RlbmVyKSB7XG4gICAgICBkM19nZW9fc3RyZWFtUG9seWdvbihvYmplY3QuY29vcmRpbmF0ZXMsIGxpc3RlbmVyKTtcbiAgICB9LFxuICAgIE11bHRpUG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGNvb3JkaW5hdGVzID0gb2JqZWN0LmNvb3JkaW5hdGVzLCBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gICAgICB3aGlsZSAoKytpIDwgbikgZDNfZ2VvX3N0cmVhbVBvbHlnb24oY29vcmRpbmF0ZXNbaV0sIGxpc3RlbmVyKTtcbiAgICB9LFxuICAgIEdlb21ldHJ5Q29sbGVjdGlvbjogZnVuY3Rpb24ob2JqZWN0LCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGdlb21ldHJpZXMgPSBvYmplY3QuZ2VvbWV0cmllcywgaSA9IC0xLCBuID0gZ2VvbWV0cmllcy5sZW5ndGg7XG4gICAgICB3aGlsZSAoKytpIDwgbikgZDNfZ2VvX3N0cmVhbUdlb21ldHJ5KGdlb21ldHJpZXNbaV0sIGxpc3RlbmVyKTtcbiAgICB9XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2dlb19zdHJlYW1MaW5lKGNvb3JkaW5hdGVzLCBsaXN0ZW5lciwgY2xvc2VkKSB7XG4gICAgdmFyIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aCAtIGNsb3NlZCwgY29vcmRpbmF0ZTtcbiAgICBsaXN0ZW5lci5saW5lU3RhcnQoKTtcbiAgICB3aGlsZSAoKytpIDwgbikgY29vcmRpbmF0ZSA9IGNvb3JkaW5hdGVzW2ldLCBsaXN0ZW5lci5wb2ludChjb29yZGluYXRlWzBdLCBjb29yZGluYXRlWzFdKTtcbiAgICBsaXN0ZW5lci5saW5lRW5kKCk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3N0cmVhbVBvbHlnb24oY29vcmRpbmF0ZXMsIGxpc3RlbmVyKSB7XG4gICAgdmFyIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICBsaXN0ZW5lci5wb2x5Z29uU3RhcnQoKTtcbiAgICB3aGlsZSAoKytpIDwgbikgZDNfZ2VvX3N0cmVhbUxpbmUoY29vcmRpbmF0ZXNbaV0sIGxpc3RlbmVyLCAxKTtcbiAgICBsaXN0ZW5lci5wb2x5Z29uRW5kKCk7XG4gIH1cbiAgZDMuZ2VvLmFyZWEgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBkM19nZW9fYXJlYVN1bSA9IDA7XG4gICAgZDMuZ2VvLnN0cmVhbShvYmplY3QsIGQzX2dlb19hcmVhKTtcbiAgICByZXR1cm4gZDNfZ2VvX2FyZWFTdW07XG4gIH07XG4gIHZhciBkM19nZW9fYXJlYVN1bSwgZDNfZ2VvX2FyZWFSaW5nU3VtID0gbmV3IGQzX2FkZGVyKCk7XG4gIHZhciBkM19nZW9fYXJlYSA9IHtcbiAgICBzcGhlcmU6IGZ1bmN0aW9uKCkge1xuICAgICAgZDNfZ2VvX2FyZWFTdW0gKz0gNCAqIM+AO1xuICAgIH0sXG4gICAgcG9pbnQ6IGQzX25vb3AsXG4gICAgbGluZVN0YXJ0OiBkM19ub29wLFxuICAgIGxpbmVFbmQ6IGQzX25vb3AsXG4gICAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgIGQzX2dlb19hcmVhUmluZ1N1bS5yZXNldCgpO1xuICAgICAgZDNfZ2VvX2FyZWEubGluZVN0YXJ0ID0gZDNfZ2VvX2FyZWFSaW5nU3RhcnQ7XG4gICAgfSxcbiAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmVhID0gMiAqIGQzX2dlb19hcmVhUmluZ1N1bTtcbiAgICAgIGQzX2dlb19hcmVhU3VtICs9IGFyZWEgPCAwID8gNCAqIM+AICsgYXJlYSA6IGFyZWE7XG4gICAgICBkM19nZW9fYXJlYS5saW5lU3RhcnQgPSBkM19nZW9fYXJlYS5saW5lRW5kID0gZDNfZ2VvX2FyZWEucG9pbnQgPSBkM19ub29wO1xuICAgIH1cbiAgfTtcbiAgZnVuY3Rpb24gZDNfZ2VvX2FyZWFSaW5nU3RhcnQoKSB7XG4gICAgdmFyIM67MDAsIM+GMDAsIM67MCwgY29zz4YwLCBzaW7PhjA7XG4gICAgZDNfZ2VvX2FyZWEucG9pbnQgPSBmdW5jdGlvbijOuywgz4YpIHtcbiAgICAgIGQzX2dlb19hcmVhLnBvaW50ID0gbmV4dFBvaW50O1xuICAgICAgzrswID0gKM67MDAgPSDOuykgKiBkM19yYWRpYW5zLCBjb3PPhjAgPSBNYXRoLmNvcyjPhiA9ICjPhjAwID0gz4YpICogZDNfcmFkaWFucyAvIDIgKyDPgCAvIDQpLCBcbiAgICAgIHNpbs+GMCA9IE1hdGguc2luKM+GKTtcbiAgICB9O1xuICAgIGZ1bmN0aW9uIG5leHRQb2ludCjOuywgz4YpIHtcbiAgICAgIM67ICo9IGQzX3JhZGlhbnM7XG4gICAgICDPhiA9IM+GICogZDNfcmFkaWFucyAvIDIgKyDPgCAvIDQ7XG4gICAgICB2YXIgZM67ID0gzrsgLSDOuzAsIGNvc8+GID0gTWF0aC5jb3Moz4YpLCBzaW7PhiA9IE1hdGguc2luKM+GKSwgayA9IHNpbs+GMCAqIHNpbs+GLCB1ID0gY29zz4YwICogY29zz4YgKyBrICogTWF0aC5jb3MoZM67KSwgdiA9IGsgKiBNYXRoLnNpbihkzrspO1xuICAgICAgZDNfZ2VvX2FyZWFSaW5nU3VtLmFkZChNYXRoLmF0YW4yKHYsIHUpKTtcbiAgICAgIM67MCA9IM67LCBjb3PPhjAgPSBjb3PPhiwgc2luz4YwID0gc2luz4Y7XG4gICAgfVxuICAgIGQzX2dlb19hcmVhLmxpbmVFbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIG5leHRQb2ludCjOuzAwLCDPhjAwKTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19jYXJ0ZXNpYW4oc3BoZXJpY2FsKSB7XG4gICAgdmFyIM67ID0gc3BoZXJpY2FsWzBdLCDPhiA9IHNwaGVyaWNhbFsxXSwgY29zz4YgPSBNYXRoLmNvcyjPhik7XG4gICAgcmV0dXJuIFsgY29zz4YgKiBNYXRoLmNvcyjOuyksIGNvc8+GICogTWF0aC5zaW4ozrspLCBNYXRoLnNpbijPhikgXTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fY2FydGVzaWFuRG90KGEsIGIpIHtcbiAgICByZXR1cm4gYVswXSAqIGJbMF0gKyBhWzFdICogYlsxXSArIGFbMl0gKiBiWzJdO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19jYXJ0ZXNpYW5Dcm9zcyhhLCBiKSB7XG4gICAgcmV0dXJuIFsgYVsxXSAqIGJbMl0gLSBhWzJdICogYlsxXSwgYVsyXSAqIGJbMF0gLSBhWzBdICogYlsyXSwgYVswXSAqIGJbMV0gLSBhWzFdICogYlswXSBdO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19jYXJ0ZXNpYW5BZGQoYSwgYikge1xuICAgIGFbMF0gKz0gYlswXTtcbiAgICBhWzFdICs9IGJbMV07XG4gICAgYVsyXSArPSBiWzJdO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19jYXJ0ZXNpYW5TY2FsZSh2ZWN0b3IsIGspIHtcbiAgICByZXR1cm4gWyB2ZWN0b3JbMF0gKiBrLCB2ZWN0b3JbMV0gKiBrLCB2ZWN0b3JbMl0gKiBrIF07XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NhcnRlc2lhbk5vcm1hbGl6ZShkKSB7XG4gICAgdmFyIGwgPSBNYXRoLnNxcnQoZFswXSAqIGRbMF0gKyBkWzFdICogZFsxXSArIGRbMl0gKiBkWzJdKTtcbiAgICBkWzBdIC89IGw7XG4gICAgZFsxXSAvPSBsO1xuICAgIGRbMl0gLz0gbDtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fc3BoZXJpY2FsKGNhcnRlc2lhbikge1xuICAgIHJldHVybiBbIE1hdGguYXRhbjIoY2FydGVzaWFuWzFdLCBjYXJ0ZXNpYW5bMF0pLCBkM19hc2luKGNhcnRlc2lhblsyXSkgXTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fc3BoZXJpY2FsRXF1YWwoYSwgYikge1xuICAgIHJldHVybiBNYXRoLmFicyhhWzBdIC0gYlswXSkgPCDOtSAmJiBNYXRoLmFicyhhWzFdIC0gYlsxXSkgPCDOtTtcbiAgfVxuICBkMy5nZW8uYm91bmRzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIM67MCwgz4YwLCDOuzEsIM+GMSwgzrtfLCDOu19fLCDPhl9fLCBwMCwgZM67U3VtLCByYW5nZXMsIHJhbmdlO1xuICAgIHZhciBib3VuZCA9IHtcbiAgICAgIHBvaW50OiBwb2ludCxcbiAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgbGluZUVuZDogbGluZUVuZCxcbiAgICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGJvdW5kLnBvaW50ID0gcmluZ1BvaW50O1xuICAgICAgICBib3VuZC5saW5lU3RhcnQgPSByaW5nU3RhcnQ7XG4gICAgICAgIGJvdW5kLmxpbmVFbmQgPSByaW5nRW5kO1xuICAgICAgICBkzrtTdW0gPSAwO1xuICAgICAgICBkM19nZW9fYXJlYS5wb2x5Z29uU3RhcnQoKTtcbiAgICAgIH0sXG4gICAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICAgICAgZDNfZ2VvX2FyZWEucG9seWdvbkVuZCgpO1xuICAgICAgICBib3VuZC5wb2ludCA9IHBvaW50O1xuICAgICAgICBib3VuZC5saW5lU3RhcnQgPSBsaW5lU3RhcnQ7XG4gICAgICAgIGJvdW5kLmxpbmVFbmQgPSBsaW5lRW5kO1xuICAgICAgICBpZiAoZDNfZ2VvX2FyZWFSaW5nU3VtIDwgMCkgzrswID0gLSjOuzEgPSAxODApLCDPhjAgPSAtKM+GMSA9IDkwKTsgZWxzZSBpZiAoZM67U3VtID4gzrUpIM+GMSA9IDkwOyBlbHNlIGlmIChkzrtTdW0gPCAtzrUpIM+GMCA9IC05MDtcbiAgICAgICAgcmFuZ2VbMF0gPSDOuzAsIHJhbmdlWzFdID0gzrsxO1xuICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gcG9pbnQozrssIM+GKSB7XG4gICAgICByYW5nZXMucHVzaChyYW5nZSA9IFsgzrswID0gzrssIM67MSA9IM67IF0pO1xuICAgICAgaWYgKM+GIDwgz4YwKSDPhjAgPSDPhjtcbiAgICAgIGlmICjPhiA+IM+GMSkgz4YxID0gz4Y7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGxpbmVQb2ludCjOuywgz4YpIHtcbiAgICAgIHZhciBwID0gZDNfZ2VvX2NhcnRlc2lhbihbIM67ICogZDNfcmFkaWFucywgz4YgKiBkM19yYWRpYW5zIF0pO1xuICAgICAgaWYgKHAwKSB7XG4gICAgICAgIHZhciBub3JtYWwgPSBkM19nZW9fY2FydGVzaWFuQ3Jvc3MocDAsIHApLCBlcXVhdG9yaWFsID0gWyBub3JtYWxbMV0sIC1ub3JtYWxbMF0sIDAgXSwgaW5mbGVjdGlvbiA9IGQzX2dlb19jYXJ0ZXNpYW5Dcm9zcyhlcXVhdG9yaWFsLCBub3JtYWwpO1xuICAgICAgICBkM19nZW9fY2FydGVzaWFuTm9ybWFsaXplKGluZmxlY3Rpb24pO1xuICAgICAgICBpbmZsZWN0aW9uID0gZDNfZ2VvX3NwaGVyaWNhbChpbmZsZWN0aW9uKTtcbiAgICAgICAgdmFyIGTOuyA9IM67IC0gzrtfLCBzID0gZM67ID4gMCA/IDEgOiAtMSwgzrtpID0gaW5mbGVjdGlvblswXSAqIGQzX2RlZ3JlZXMgKiBzLCBhbnRpbWVyaWRpYW4gPSBNYXRoLmFicyhkzrspID4gMTgwO1xuICAgICAgICBpZiAoYW50aW1lcmlkaWFuIF4gKHMgKiDOu18gPCDOu2kgJiYgzrtpIDwgcyAqIM67KSkge1xuICAgICAgICAgIHZhciDPhmkgPSBpbmZsZWN0aW9uWzFdICogZDNfZGVncmVlcztcbiAgICAgICAgICBpZiAoz4ZpID4gz4YxKSDPhjEgPSDPhmk7XG4gICAgICAgIH0gZWxzZSBpZiAozrtpID0gKM67aSArIDM2MCkgJSAzNjAgLSAxODAsIGFudGltZXJpZGlhbiBeIChzICogzrtfIDwgzrtpICYmIM67aSA8IHMgKiDOuykpIHtcbiAgICAgICAgICB2YXIgz4ZpID0gLWluZmxlY3Rpb25bMV0gKiBkM19kZWdyZWVzO1xuICAgICAgICAgIGlmICjPhmkgPCDPhjApIM+GMCA9IM+GaTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoz4YgPCDPhjApIM+GMCA9IM+GO1xuICAgICAgICAgIGlmICjPhiA+IM+GMSkgz4YxID0gz4Y7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFudGltZXJpZGlhbikge1xuICAgICAgICAgIGlmICjOuyA8IM67Xykge1xuICAgICAgICAgICAgaWYgKGFuZ2xlKM67MCwgzrspID4gYW5nbGUozrswLCDOuzEpKSDOuzEgPSDOuztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGFuZ2xlKM67LCDOuzEpID4gYW5nbGUozrswLCDOuzEpKSDOuzAgPSDOuztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKM67MSA+PSDOuzApIHtcbiAgICAgICAgICAgIGlmICjOuyA8IM67MCkgzrswID0gzrs7XG4gICAgICAgICAgICBpZiAozrsgPiDOuzEpIM67MSA9IM67O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAozrsgPiDOu18pIHtcbiAgICAgICAgICAgICAgaWYgKGFuZ2xlKM67MCwgzrspID4gYW5nbGUozrswLCDOuzEpKSDOuzEgPSDOuztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChhbmdsZSjOuywgzrsxKSA+IGFuZ2xlKM67MCwgzrsxKSkgzrswID0gzrs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwb2ludCjOuywgz4YpO1xuICAgICAgfVxuICAgICAgcDAgPSBwLCDOu18gPSDOuztcbiAgICB9XG4gICAgZnVuY3Rpb24gbGluZVN0YXJ0KCkge1xuICAgICAgYm91bmQucG9pbnQgPSBsaW5lUG9pbnQ7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7XG4gICAgICByYW5nZVswXSA9IM67MCwgcmFuZ2VbMV0gPSDOuzE7XG4gICAgICBib3VuZC5wb2ludCA9IHBvaW50O1xuICAgICAgcDAgPSBudWxsO1xuICAgIH1cbiAgICBmdW5jdGlvbiByaW5nUG9pbnQozrssIM+GKSB7XG4gICAgICBpZiAocDApIHtcbiAgICAgICAgdmFyIGTOuyA9IM67IC0gzrtfO1xuICAgICAgICBkzrtTdW0gKz0gTWF0aC5hYnMoZM67KSA+IDE4MCA/IGTOuyArIChkzrsgPiAwID8gMzYwIDogLTM2MCkgOiBkzrs7XG4gICAgICB9IGVsc2UgzrtfXyA9IM67LCDPhl9fID0gz4Y7XG4gICAgICBkM19nZW9fYXJlYS5wb2ludCjOuywgz4YpO1xuICAgICAgbGluZVBvaW50KM67LCDPhik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJpbmdTdGFydCgpIHtcbiAgICAgIGQzX2dlb19hcmVhLmxpbmVTdGFydCgpO1xuICAgIH1cbiAgICBmdW5jdGlvbiByaW5nRW5kKCkge1xuICAgICAgcmluZ1BvaW50KM67X18sIM+GX18pO1xuICAgICAgZDNfZ2VvX2FyZWEubGluZUVuZCgpO1xuICAgICAgaWYgKE1hdGguYWJzKGTOu1N1bSkgPiDOtSkgzrswID0gLSjOuzEgPSAxODApO1xuICAgICAgcmFuZ2VbMF0gPSDOuzAsIHJhbmdlWzFdID0gzrsxO1xuICAgICAgcDAgPSBudWxsO1xuICAgIH1cbiAgICBmdW5jdGlvbiBhbmdsZSjOuzAsIM67MSkge1xuICAgICAgcmV0dXJuICjOuzEgLT0gzrswKSA8IDAgPyDOuzEgKyAzNjAgOiDOuzE7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNvbXBhcmVSYW5nZXMoYSwgYikge1xuICAgICAgcmV0dXJuIGFbMF0gLSBiWzBdO1xuICAgIH1cbiAgICBmdW5jdGlvbiB3aXRoaW5SYW5nZSh4LCByYW5nZSkge1xuICAgICAgcmV0dXJuIHJhbmdlWzBdIDw9IHJhbmdlWzFdID8gcmFuZ2VbMF0gPD0geCAmJiB4IDw9IHJhbmdlWzFdIDogeCA8IHJhbmdlWzBdIHx8IHJhbmdlWzFdIDwgeDtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGZlYXR1cmUpIHtcbiAgICAgIM+GMSA9IM67MSA9IC0ozrswID0gz4YwID0gSW5maW5pdHkpO1xuICAgICAgcmFuZ2VzID0gW107XG4gICAgICBkMy5nZW8uc3RyZWFtKGZlYXR1cmUsIGJvdW5kKTtcbiAgICAgIHZhciBuID0gcmFuZ2VzLmxlbmd0aDtcbiAgICAgIGlmIChuKSB7XG4gICAgICAgIHJhbmdlcy5zb3J0KGNvbXBhcmVSYW5nZXMpO1xuICAgICAgICBmb3IgKHZhciBpID0gMSwgYSA9IHJhbmdlc1swXSwgYiwgbWVyZ2VkID0gWyBhIF07IGkgPCBuOyArK2kpIHtcbiAgICAgICAgICBiID0gcmFuZ2VzW2ldO1xuICAgICAgICAgIGlmICh3aXRoaW5SYW5nZShiWzBdLCBhKSB8fCB3aXRoaW5SYW5nZShiWzFdLCBhKSkge1xuICAgICAgICAgICAgaWYgKGFuZ2xlKGFbMF0sIGJbMV0pID4gYW5nbGUoYVswXSwgYVsxXSkpIGFbMV0gPSBiWzFdO1xuICAgICAgICAgICAgaWYgKGFuZ2xlKGJbMF0sIGFbMV0pID4gYW5nbGUoYVswXSwgYVsxXSkpIGFbMF0gPSBiWzBdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtZXJnZWQucHVzaChhID0gYik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBiZXN0ID0gLUluZmluaXR5LCBkzrs7XG4gICAgICAgIGZvciAodmFyIG4gPSBtZXJnZWQubGVuZ3RoIC0gMSwgaSA9IDAsIGEgPSBtZXJnZWRbbl0sIGI7IGkgPD0gbjsgYSA9IGIsICsraSkge1xuICAgICAgICAgIGIgPSBtZXJnZWRbaV07XG4gICAgICAgICAgaWYgKChkzrsgPSBhbmdsZShhWzFdLCBiWzBdKSkgPiBiZXN0KSBiZXN0ID0gZM67LCDOuzAgPSBiWzBdLCDOuzEgPSBhWzFdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByYW5nZXMgPSByYW5nZSA9IG51bGw7XG4gICAgICByZXR1cm4gzrswID09PSBJbmZpbml0eSB8fCDPhjAgPT09IEluZmluaXR5ID8gWyBbIE5hTiwgTmFOIF0sIFsgTmFOLCBOYU4gXSBdIDogWyBbIM67MCwgz4YwIF0sIFsgzrsxLCDPhjEgXSBdO1xuICAgIH07XG4gIH0oKTtcbiAgZDMuZ2VvLmNlbnRyb2lkID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgZDNfZ2VvX2NlbnRyb2lkVzAgPSBkM19nZW9fY2VudHJvaWRXMSA9IGQzX2dlb19jZW50cm9pZFgwID0gZDNfZ2VvX2NlbnRyb2lkWTAgPSBkM19nZW9fY2VudHJvaWRaMCA9IGQzX2dlb19jZW50cm9pZFgxID0gZDNfZ2VvX2NlbnRyb2lkWTEgPSBkM19nZW9fY2VudHJvaWRaMSA9IGQzX2dlb19jZW50cm9pZFgyID0gZDNfZ2VvX2NlbnRyb2lkWTIgPSBkM19nZW9fY2VudHJvaWRaMiA9IDA7XG4gICAgZDMuZ2VvLnN0cmVhbShvYmplY3QsIGQzX2dlb19jZW50cm9pZCk7XG4gICAgdmFyIHggPSBkM19nZW9fY2VudHJvaWRYMiwgeSA9IGQzX2dlb19jZW50cm9pZFkyLCB6ID0gZDNfZ2VvX2NlbnRyb2lkWjIsIG0gPSB4ICogeCArIHkgKiB5ICsgeiAqIHo7XG4gICAgaWYgKG0gPCDOtTIpIHtcbiAgICAgIHggPSBkM19nZW9fY2VudHJvaWRYMSwgeSA9IGQzX2dlb19jZW50cm9pZFkxLCB6ID0gZDNfZ2VvX2NlbnRyb2lkWjE7XG4gICAgICBpZiAoZDNfZ2VvX2NlbnRyb2lkVzEgPCDOtSkgeCA9IGQzX2dlb19jZW50cm9pZFgwLCB5ID0gZDNfZ2VvX2NlbnRyb2lkWTAsIHogPSBkM19nZW9fY2VudHJvaWRaMDtcbiAgICAgIG0gPSB4ICogeCArIHkgKiB5ICsgeiAqIHo7XG4gICAgICBpZiAobSA8IM61MikgcmV0dXJuIFsgTmFOLCBOYU4gXTtcbiAgICB9XG4gICAgcmV0dXJuIFsgTWF0aC5hdGFuMih5LCB4KSAqIGQzX2RlZ3JlZXMsIGQzX2FzaW4oeiAvIE1hdGguc3FydChtKSkgKiBkM19kZWdyZWVzIF07XG4gIH07XG4gIHZhciBkM19nZW9fY2VudHJvaWRXMCwgZDNfZ2VvX2NlbnRyb2lkVzEsIGQzX2dlb19jZW50cm9pZFgwLCBkM19nZW9fY2VudHJvaWRZMCwgZDNfZ2VvX2NlbnRyb2lkWjAsIGQzX2dlb19jZW50cm9pZFgxLCBkM19nZW9fY2VudHJvaWRZMSwgZDNfZ2VvX2NlbnRyb2lkWjEsIGQzX2dlb19jZW50cm9pZFgyLCBkM19nZW9fY2VudHJvaWRZMiwgZDNfZ2VvX2NlbnRyb2lkWjI7XG4gIHZhciBkM19nZW9fY2VudHJvaWQgPSB7XG4gICAgc3BoZXJlOiBkM19ub29wLFxuICAgIHBvaW50OiBkM19nZW9fY2VudHJvaWRQb2ludCxcbiAgICBsaW5lU3RhcnQ6IGQzX2dlb19jZW50cm9pZExpbmVTdGFydCxcbiAgICBsaW5lRW5kOiBkM19nZW9fY2VudHJvaWRMaW5lRW5kLFxuICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICBkM19nZW9fY2VudHJvaWQubGluZVN0YXJ0ID0gZDNfZ2VvX2NlbnRyb2lkUmluZ1N0YXJ0O1xuICAgIH0sXG4gICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgICBkM19nZW9fY2VudHJvaWQubGluZVN0YXJ0ID0gZDNfZ2VvX2NlbnRyb2lkTGluZVN0YXJ0O1xuICAgIH1cbiAgfTtcbiAgZnVuY3Rpb24gZDNfZ2VvX2NlbnRyb2lkUG9pbnQozrssIM+GKSB7XG4gICAgzrsgKj0gZDNfcmFkaWFucztcbiAgICB2YXIgY29zz4YgPSBNYXRoLmNvcyjPhiAqPSBkM19yYWRpYW5zKTtcbiAgICBkM19nZW9fY2VudHJvaWRQb2ludFhZWihjb3PPhiAqIE1hdGguY29zKM67KSwgY29zz4YgKiBNYXRoLnNpbijOuyksIE1hdGguc2luKM+GKSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NlbnRyb2lkUG9pbnRYWVooeCwgeSwgeikge1xuICAgICsrZDNfZ2VvX2NlbnRyb2lkVzA7XG4gICAgZDNfZ2VvX2NlbnRyb2lkWDAgKz0gKHggLSBkM19nZW9fY2VudHJvaWRYMCkgLyBkM19nZW9fY2VudHJvaWRXMDtcbiAgICBkM19nZW9fY2VudHJvaWRZMCArPSAoeSAtIGQzX2dlb19jZW50cm9pZFkwKSAvIGQzX2dlb19jZW50cm9pZFcwO1xuICAgIGQzX2dlb19jZW50cm9pZFowICs9ICh6IC0gZDNfZ2VvX2NlbnRyb2lkWjApIC8gZDNfZ2VvX2NlbnRyb2lkVzA7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NlbnRyb2lkTGluZVN0YXJ0KCkge1xuICAgIHZhciB4MCwgeTAsIHowO1xuICAgIGQzX2dlb19jZW50cm9pZC5wb2ludCA9IGZ1bmN0aW9uKM67LCDPhikge1xuICAgICAgzrsgKj0gZDNfcmFkaWFucztcbiAgICAgIHZhciBjb3PPhiA9IE1hdGguY29zKM+GICo9IGQzX3JhZGlhbnMpO1xuICAgICAgeDAgPSBjb3PPhiAqIE1hdGguY29zKM67KTtcbiAgICAgIHkwID0gY29zz4YgKiBNYXRoLnNpbijOuyk7XG4gICAgICB6MCA9IE1hdGguc2luKM+GKTtcbiAgICAgIGQzX2dlb19jZW50cm9pZC5wb2ludCA9IG5leHRQb2ludDtcbiAgICAgIGQzX2dlb19jZW50cm9pZFBvaW50WFlaKHgwLCB5MCwgejApO1xuICAgIH07XG4gICAgZnVuY3Rpb24gbmV4dFBvaW50KM67LCDPhikge1xuICAgICAgzrsgKj0gZDNfcmFkaWFucztcbiAgICAgIHZhciBjb3PPhiA9IE1hdGguY29zKM+GICo9IGQzX3JhZGlhbnMpLCB4ID0gY29zz4YgKiBNYXRoLmNvcyjOuyksIHkgPSBjb3PPhiAqIE1hdGguc2luKM67KSwgeiA9IE1hdGguc2luKM+GKSwgdyA9IE1hdGguYXRhbjIoTWF0aC5zcXJ0KCh3ID0geTAgKiB6IC0gejAgKiB5KSAqIHcgKyAodyA9IHowICogeCAtIHgwICogeikgKiB3ICsgKHcgPSB4MCAqIHkgLSB5MCAqIHgpICogdyksIHgwICogeCArIHkwICogeSArIHowICogeik7XG4gICAgICBkM19nZW9fY2VudHJvaWRXMSArPSB3O1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkWDEgKz0gdyAqICh4MCArICh4MCA9IHgpKTtcbiAgICAgIGQzX2dlb19jZW50cm9pZFkxICs9IHcgKiAoeTAgKyAoeTAgPSB5KSk7XG4gICAgICBkM19nZW9fY2VudHJvaWRaMSArPSB3ICogKHowICsgKHowID0geikpO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkUG9pbnRYWVooeDAsIHkwLCB6MCk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19jZW50cm9pZExpbmVFbmQoKSB7XG4gICAgZDNfZ2VvX2NlbnRyb2lkLnBvaW50ID0gZDNfZ2VvX2NlbnRyb2lkUG9pbnQ7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NlbnRyb2lkUmluZ1N0YXJ0KCkge1xuICAgIHZhciDOuzAwLCDPhjAwLCB4MCwgeTAsIHowO1xuICAgIGQzX2dlb19jZW50cm9pZC5wb2ludCA9IGZ1bmN0aW9uKM67LCDPhikge1xuICAgICAgzrswMCA9IM67LCDPhjAwID0gz4Y7XG4gICAgICBkM19nZW9fY2VudHJvaWQucG9pbnQgPSBuZXh0UG9pbnQ7XG4gICAgICDOuyAqPSBkM19yYWRpYW5zO1xuICAgICAgdmFyIGNvc8+GID0gTWF0aC5jb3Moz4YgKj0gZDNfcmFkaWFucyk7XG4gICAgICB4MCA9IGNvc8+GICogTWF0aC5jb3MozrspO1xuICAgICAgeTAgPSBjb3PPhiAqIE1hdGguc2luKM67KTtcbiAgICAgIHowID0gTWF0aC5zaW4oz4YpO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkUG9pbnRYWVooeDAsIHkwLCB6MCk7XG4gICAgfTtcbiAgICBkM19nZW9fY2VudHJvaWQubGluZUVuZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgbmV4dFBvaW50KM67MDAsIM+GMDApO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkLmxpbmVFbmQgPSBkM19nZW9fY2VudHJvaWRMaW5lRW5kO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkLnBvaW50ID0gZDNfZ2VvX2NlbnRyb2lkUG9pbnQ7XG4gICAgfTtcbiAgICBmdW5jdGlvbiBuZXh0UG9pbnQozrssIM+GKSB7XG4gICAgICDOuyAqPSBkM19yYWRpYW5zO1xuICAgICAgdmFyIGNvc8+GID0gTWF0aC5jb3Moz4YgKj0gZDNfcmFkaWFucyksIHggPSBjb3PPhiAqIE1hdGguY29zKM67KSwgeSA9IGNvc8+GICogTWF0aC5zaW4ozrspLCB6ID0gTWF0aC5zaW4oz4YpLCBjeCA9IHkwICogeiAtIHowICogeSwgY3kgPSB6MCAqIHggLSB4MCAqIHosIGN6ID0geDAgKiB5IC0geTAgKiB4LCBtID0gTWF0aC5zcXJ0KGN4ICogY3ggKyBjeSAqIGN5ICsgY3ogKiBjeiksIHUgPSB4MCAqIHggKyB5MCAqIHkgKyB6MCAqIHosIHYgPSBtICYmIC1kM19hY29zKHUpIC8gbSwgdyA9IE1hdGguYXRhbjIobSwgdSk7XG4gICAgICBkM19nZW9fY2VudHJvaWRYMiArPSB2ICogY3g7XG4gICAgICBkM19nZW9fY2VudHJvaWRZMiArPSB2ICogY3k7XG4gICAgICBkM19nZW9fY2VudHJvaWRaMiArPSB2ICogY3o7XG4gICAgICBkM19nZW9fY2VudHJvaWRXMSArPSB3O1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkWDEgKz0gdyAqICh4MCArICh4MCA9IHgpKTtcbiAgICAgIGQzX2dlb19jZW50cm9pZFkxICs9IHcgKiAoeTAgKyAoeTAgPSB5KSk7XG4gICAgICBkM19nZW9fY2VudHJvaWRaMSArPSB3ICogKHowICsgKHowID0geikpO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkUG9pbnRYWVooeDAsIHkwLCB6MCk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGQzX3RydWUoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NsaXBQb2x5Z29uKHNlZ21lbnRzLCBjb21wYXJlLCBpbnNpZGUsIGludGVycG9sYXRlLCBsaXN0ZW5lcikge1xuICAgIHZhciBzdWJqZWN0ID0gW10sIGNsaXAgPSBbXTtcbiAgICBzZWdtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKHNlZ21lbnQpIHtcbiAgICAgIGlmICgobiA9IHNlZ21lbnQubGVuZ3RoIC0gMSkgPD0gMCkgcmV0dXJuO1xuICAgICAgdmFyIG4sIHAwID0gc2VnbWVudFswXSwgcDEgPSBzZWdtZW50W25dO1xuICAgICAgaWYgKGQzX2dlb19zcGhlcmljYWxFcXVhbChwMCwgcDEpKSB7XG4gICAgICAgIGxpc3RlbmVyLmxpbmVTdGFydCgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkgbGlzdGVuZXIucG9pbnQoKHAwID0gc2VnbWVudFtpXSlbMF0sIHAwWzFdKTtcbiAgICAgICAgbGlzdGVuZXIubGluZUVuZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgYSA9IHtcbiAgICAgICAgcG9pbnQ6IHAwLFxuICAgICAgICBwb2ludHM6IHNlZ21lbnQsXG4gICAgICAgIG90aGVyOiBudWxsLFxuICAgICAgICB2aXNpdGVkOiBmYWxzZSxcbiAgICAgICAgZW50cnk6IHRydWUsXG4gICAgICAgIHN1YmplY3Q6IHRydWVcbiAgICAgIH0sIGIgPSB7XG4gICAgICAgIHBvaW50OiBwMCxcbiAgICAgICAgcG9pbnRzOiBbIHAwIF0sXG4gICAgICAgIG90aGVyOiBhLFxuICAgICAgICB2aXNpdGVkOiBmYWxzZSxcbiAgICAgICAgZW50cnk6IGZhbHNlLFxuICAgICAgICBzdWJqZWN0OiBmYWxzZVxuICAgICAgfTtcbiAgICAgIGEub3RoZXIgPSBiO1xuICAgICAgc3ViamVjdC5wdXNoKGEpO1xuICAgICAgY2xpcC5wdXNoKGIpO1xuICAgICAgYSA9IHtcbiAgICAgICAgcG9pbnQ6IHAxLFxuICAgICAgICBwb2ludHM6IFsgcDEgXSxcbiAgICAgICAgb3RoZXI6IG51bGwsXG4gICAgICAgIHZpc2l0ZWQ6IGZhbHNlLFxuICAgICAgICBlbnRyeTogZmFsc2UsXG4gICAgICAgIHN1YmplY3Q6IHRydWVcbiAgICAgIH07XG4gICAgICBiID0ge1xuICAgICAgICBwb2ludDogcDEsXG4gICAgICAgIHBvaW50czogWyBwMSBdLFxuICAgICAgICBvdGhlcjogYSxcbiAgICAgICAgdmlzaXRlZDogZmFsc2UsXG4gICAgICAgIGVudHJ5OiB0cnVlLFxuICAgICAgICBzdWJqZWN0OiBmYWxzZVxuICAgICAgfTtcbiAgICAgIGEub3RoZXIgPSBiO1xuICAgICAgc3ViamVjdC5wdXNoKGEpO1xuICAgICAgY2xpcC5wdXNoKGIpO1xuICAgIH0pO1xuICAgIGNsaXAuc29ydChjb21wYXJlKTtcbiAgICBkM19nZW9fY2xpcFBvbHlnb25MaW5rQ2lyY3VsYXIoc3ViamVjdCk7XG4gICAgZDNfZ2VvX2NsaXBQb2x5Z29uTGlua0NpcmN1bGFyKGNsaXApO1xuICAgIGlmICghc3ViamVjdC5sZW5ndGgpIHJldHVybjtcbiAgICBpZiAoaW5zaWRlKSBmb3IgKHZhciBpID0gMSwgZSA9ICFpbnNpZGUoY2xpcFswXS5wb2ludCksIG4gPSBjbGlwLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgY2xpcFtpXS5lbnRyeSA9IGUgPSAhZTtcbiAgICB9XG4gICAgdmFyIHN0YXJ0ID0gc3ViamVjdFswXSwgY3VycmVudCwgcG9pbnRzLCBwb2ludDtcbiAgICB3aGlsZSAoMSkge1xuICAgICAgY3VycmVudCA9IHN0YXJ0O1xuICAgICAgd2hpbGUgKGN1cnJlbnQudmlzaXRlZCkgaWYgKChjdXJyZW50ID0gY3VycmVudC5uZXh0KSA9PT0gc3RhcnQpIHJldHVybjtcbiAgICAgIHBvaW50cyA9IGN1cnJlbnQucG9pbnRzO1xuICAgICAgbGlzdGVuZXIubGluZVN0YXJ0KCk7XG4gICAgICBkbyB7XG4gICAgICAgIGN1cnJlbnQudmlzaXRlZCA9IGN1cnJlbnQub3RoZXIudmlzaXRlZCA9IHRydWU7XG4gICAgICAgIGlmIChjdXJyZW50LmVudHJ5KSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnQuc3ViamVjdCkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIGxpc3RlbmVyLnBvaW50KChwb2ludCA9IHBvaW50c1tpXSlbMF0sIHBvaW50WzFdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW50ZXJwb2xhdGUoY3VycmVudC5wb2ludCwgY3VycmVudC5uZXh0LnBvaW50LCAxLCBsaXN0ZW5lcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5leHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnQuc3ViamVjdCkge1xuICAgICAgICAgICAgcG9pbnRzID0gY3VycmVudC5wcmV2LnBvaW50cztcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBwb2ludHMubGVuZ3RoOyAtLWkgPj0gMDsgKSBsaXN0ZW5lci5wb2ludCgocG9pbnQgPSBwb2ludHNbaV0pWzBdLCBwb2ludFsxXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGludGVycG9sYXRlKGN1cnJlbnQucG9pbnQsIGN1cnJlbnQucHJldi5wb2ludCwgLTEsIGxpc3RlbmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQucHJldjtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50ID0gY3VycmVudC5vdGhlcjtcbiAgICAgICAgcG9pbnRzID0gY3VycmVudC5wb2ludHM7XG4gICAgICB9IHdoaWxlICghY3VycmVudC52aXNpdGVkKTtcbiAgICAgIGxpc3RlbmVyLmxpbmVFbmQoKTtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NsaXBQb2x5Z29uTGlua0NpcmN1bGFyKGFycmF5KSB7XG4gICAgaWYgKCEobiA9IGFycmF5Lmxlbmd0aCkpIHJldHVybjtcbiAgICB2YXIgbiwgaSA9IDAsIGEgPSBhcnJheVswXSwgYjtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgYS5uZXh0ID0gYiA9IGFycmF5W2ldO1xuICAgICAgYi5wcmV2ID0gYTtcbiAgICAgIGEgPSBiO1xuICAgIH1cbiAgICBhLm5leHQgPSBiID0gYXJyYXlbMF07XG4gICAgYi5wcmV2ID0gYTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fY2xpcChwb2ludFZpc2libGUsIGNsaXBMaW5lLCBpbnRlcnBvbGF0ZSwgcG9seWdvbkNvbnRhaW5zKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGxpc3RlbmVyKSB7XG4gICAgICB2YXIgbGluZSA9IGNsaXBMaW5lKGxpc3RlbmVyKTtcbiAgICAgIHZhciBjbGlwID0ge1xuICAgICAgICBwb2ludDogcG9pbnQsXG4gICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICBsaW5lRW5kOiBsaW5lRW5kLFxuICAgICAgICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGNsaXAucG9pbnQgPSBwb2ludFJpbmc7XG4gICAgICAgICAgY2xpcC5saW5lU3RhcnQgPSByaW5nU3RhcnQ7XG4gICAgICAgICAgY2xpcC5saW5lRW5kID0gcmluZ0VuZDtcbiAgICAgICAgICBzZWdtZW50cyA9IFtdO1xuICAgICAgICAgIHBvbHlnb24gPSBbXTtcbiAgICAgICAgICBsaXN0ZW5lci5wb2x5Z29uU3RhcnQoKTtcbiAgICAgICAgfSxcbiAgICAgICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY2xpcC5wb2ludCA9IHBvaW50O1xuICAgICAgICAgIGNsaXAubGluZVN0YXJ0ID0gbGluZVN0YXJ0O1xuICAgICAgICAgIGNsaXAubGluZUVuZCA9IGxpbmVFbmQ7XG4gICAgICAgICAgc2VnbWVudHMgPSBkMy5tZXJnZShzZWdtZW50cyk7XG4gICAgICAgICAgaWYgKHNlZ21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgZDNfZ2VvX2NsaXBQb2x5Z29uKHNlZ21lbnRzLCBkM19nZW9fY2xpcFNvcnQsIG51bGwsIGludGVycG9sYXRlLCBsaXN0ZW5lcik7XG4gICAgICAgICAgfSBlbHNlIGlmIChwb2x5Z29uQ29udGFpbnMocG9seWdvbikpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgaW50ZXJwb2xhdGUobnVsbCwgbnVsbCwgMSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgbGlzdGVuZXIubGluZUVuZCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsaXN0ZW5lci5wb2x5Z29uRW5kKCk7XG4gICAgICAgICAgc2VnbWVudHMgPSBwb2x5Z29uID0gbnVsbDtcbiAgICAgICAgfSxcbiAgICAgICAgc3BoZXJlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBsaXN0ZW5lci5wb2x5Z29uU3RhcnQoKTtcbiAgICAgICAgICBsaXN0ZW5lci5saW5lU3RhcnQoKTtcbiAgICAgICAgICBpbnRlcnBvbGF0ZShudWxsLCBudWxsLCAxLCBsaXN0ZW5lcik7XG4gICAgICAgICAgbGlzdGVuZXIubGluZUVuZCgpO1xuICAgICAgICAgIGxpc3RlbmVyLnBvbHlnb25FbmQoKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGZ1bmN0aW9uIHBvaW50KM67LCDPhikge1xuICAgICAgICBpZiAocG9pbnRWaXNpYmxlKM67LCDPhikpIGxpc3RlbmVyLnBvaW50KM67LCDPhik7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBwb2ludExpbmUozrssIM+GKSB7XG4gICAgICAgIGxpbmUucG9pbnQozrssIM+GKTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGxpbmVTdGFydCgpIHtcbiAgICAgICAgY2xpcC5wb2ludCA9IHBvaW50TGluZTtcbiAgICAgICAgbGluZS5saW5lU3RhcnQoKTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7XG4gICAgICAgIGNsaXAucG9pbnQgPSBwb2ludDtcbiAgICAgICAgbGluZS5saW5lRW5kKCk7XG4gICAgICB9XG4gICAgICB2YXIgc2VnbWVudHM7XG4gICAgICB2YXIgYnVmZmVyID0gZDNfZ2VvX2NsaXBCdWZmZXJMaXN0ZW5lcigpLCByaW5nTGlzdGVuZXIgPSBjbGlwTGluZShidWZmZXIpLCBwb2x5Z29uLCByaW5nO1xuICAgICAgZnVuY3Rpb24gcG9pbnRSaW5nKM67LCDPhikge1xuICAgICAgICByaW5nTGlzdGVuZXIucG9pbnQozrssIM+GKTtcbiAgICAgICAgcmluZy5wdXNoKFsgzrssIM+GIF0pO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gcmluZ1N0YXJ0KCkge1xuICAgICAgICByaW5nTGlzdGVuZXIubGluZVN0YXJ0KCk7XG4gICAgICAgIHJpbmcgPSBbXTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIHJpbmdFbmQoKSB7XG4gICAgICAgIHBvaW50UmluZyhyaW5nWzBdWzBdLCByaW5nWzBdWzFdKTtcbiAgICAgICAgcmluZ0xpc3RlbmVyLmxpbmVFbmQoKTtcbiAgICAgICAgdmFyIGNsZWFuID0gcmluZ0xpc3RlbmVyLmNsZWFuKCksIHJpbmdTZWdtZW50cyA9IGJ1ZmZlci5idWZmZXIoKSwgc2VnbWVudCwgbiA9IHJpbmdTZWdtZW50cy5sZW5ndGg7XG4gICAgICAgIHJpbmcucG9wKCk7XG4gICAgICAgIHBvbHlnb24ucHVzaChyaW5nKTtcbiAgICAgICAgcmluZyA9IG51bGw7XG4gICAgICAgIGlmICghbikgcmV0dXJuO1xuICAgICAgICBpZiAoY2xlYW4gJiAxKSB7XG4gICAgICAgICAgc2VnbWVudCA9IHJpbmdTZWdtZW50c1swXTtcbiAgICAgICAgICB2YXIgbiA9IHNlZ21lbnQubGVuZ3RoIC0gMSwgaSA9IC0xLCBwb2ludDtcbiAgICAgICAgICBsaXN0ZW5lci5saW5lU3RhcnQoKTtcbiAgICAgICAgICB3aGlsZSAoKytpIDwgbikgbGlzdGVuZXIucG9pbnQoKHBvaW50ID0gc2VnbWVudFtpXSlbMF0sIHBvaW50WzFdKTtcbiAgICAgICAgICBsaXN0ZW5lci5saW5lRW5kKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuID4gMSAmJiBjbGVhbiAmIDIpIHJpbmdTZWdtZW50cy5wdXNoKHJpbmdTZWdtZW50cy5wb3AoKS5jb25jYXQocmluZ1NlZ21lbnRzLnNoaWZ0KCkpKTtcbiAgICAgICAgc2VnbWVudHMucHVzaChyaW5nU2VnbWVudHMuZmlsdGVyKGQzX2dlb19jbGlwU2VnbWVudExlbmd0aDEpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjbGlwO1xuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NsaXBTZWdtZW50TGVuZ3RoMShzZWdtZW50KSB7XG4gICAgcmV0dXJuIHNlZ21lbnQubGVuZ3RoID4gMTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fY2xpcEJ1ZmZlckxpc3RlbmVyKCkge1xuICAgIHZhciBsaW5lcyA9IFtdLCBsaW5lO1xuICAgIHJldHVybiB7XG4gICAgICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBsaW5lcy5wdXNoKGxpbmUgPSBbXSk7XG4gICAgICB9LFxuICAgICAgcG9pbnQ6IGZ1bmN0aW9uKM67LCDPhikge1xuICAgICAgICBsaW5lLnB1c2goWyDOuywgz4YgXSk7XG4gICAgICB9LFxuICAgICAgbGluZUVuZDogZDNfbm9vcCxcbiAgICAgIGJ1ZmZlcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBidWZmZXIgPSBsaW5lcztcbiAgICAgICAgbGluZXMgPSBbXTtcbiAgICAgICAgbGluZSA9IG51bGw7XG4gICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgICB9LFxuICAgICAgcmVqb2luOiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA+IDEpIGxpbmVzLnB1c2gobGluZXMucG9wKCkuY29uY2F0KGxpbmVzLnNoaWZ0KCkpKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19jbGlwU29ydChhLCBiKSB7XG4gICAgcmV0dXJuICgoYSA9IGEucG9pbnQpWzBdIDwgMCA/IGFbMV0gLSDPgCAvIDIgLSDOtSA6IM+AIC8gMiAtIGFbMV0pIC0gKChiID0gYi5wb2ludClbMF0gPCAwID8gYlsxXSAtIM+AIC8gMiAtIM61IDogz4AgLyAyIC0gYlsxXSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3BvaW50SW5Qb2x5Z29uKHBvaW50LCBwb2x5Z29uKSB7XG4gICAgdmFyIG1lcmlkaWFuID0gcG9pbnRbMF0sIHBhcmFsbGVsID0gcG9pbnRbMV0sIG1lcmlkaWFuTm9ybWFsID0gWyBNYXRoLnNpbihtZXJpZGlhbiksIC1NYXRoLmNvcyhtZXJpZGlhbiksIDAgXSwgcG9sYXJBbmdsZSA9IDAsIHBvbGFyID0gZmFsc2UsIHNvdXRoUG9sZSA9IGZhbHNlLCB3aW5kaW5nID0gMDtcbiAgICBkM19nZW9fYXJlYVJpbmdTdW0ucmVzZXQoKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IHBvbHlnb24ubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICB2YXIgcmluZyA9IHBvbHlnb25baV0sIG0gPSByaW5nLmxlbmd0aDtcbiAgICAgIGlmICghbSkgY29udGludWU7XG4gICAgICB2YXIgcG9pbnQwID0gcmluZ1swXSwgzrswID0gcG9pbnQwWzBdLCDPhjAgPSBwb2ludDBbMV0gLyAyICsgz4AgLyA0LCBzaW7PhjAgPSBNYXRoLnNpbijPhjApLCBjb3PPhjAgPSBNYXRoLmNvcyjPhjApLCBqID0gMTtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChqID09PSBtKSBqID0gMDtcbiAgICAgICAgcG9pbnQgPSByaW5nW2pdO1xuICAgICAgICB2YXIgzrsgPSBwb2ludFswXSwgz4YgPSBwb2ludFsxXSAvIDIgKyDPgCAvIDQsIHNpbs+GID0gTWF0aC5zaW4oz4YpLCBjb3PPhiA9IE1hdGguY29zKM+GKSwgZM67ID0gzrsgLSDOuzAsIGFudGltZXJpZGlhbiA9IE1hdGguYWJzKGTOuykgPiDPgCwgayA9IHNpbs+GMCAqIHNpbs+GO1xuICAgICAgICBkM19nZW9fYXJlYVJpbmdTdW0uYWRkKE1hdGguYXRhbjIoayAqIE1hdGguc2luKGTOuyksIGNvc8+GMCAqIGNvc8+GICsgayAqIE1hdGguY29zKGTOuykpKTtcbiAgICAgICAgaWYgKE1hdGguYWJzKM+GKSA8IM61KSBzb3V0aFBvbGUgPSB0cnVlO1xuICAgICAgICBwb2xhckFuZ2xlICs9IGFudGltZXJpZGlhbiA/IGTOuyArIChkzrsgPj0gMCA/IDIgOiAtMikgKiDPgCA6IGTOuztcbiAgICAgICAgaWYgKGFudGltZXJpZGlhbiBeIM67MCA+PSBtZXJpZGlhbiBeIM67ID49IG1lcmlkaWFuKSB7XG4gICAgICAgICAgdmFyIGFyYyA9IGQzX2dlb19jYXJ0ZXNpYW5Dcm9zcyhkM19nZW9fY2FydGVzaWFuKHBvaW50MCksIGQzX2dlb19jYXJ0ZXNpYW4ocG9pbnQpKTtcbiAgICAgICAgICBkM19nZW9fY2FydGVzaWFuTm9ybWFsaXplKGFyYyk7XG4gICAgICAgICAgdmFyIGludGVyc2VjdGlvbiA9IGQzX2dlb19jYXJ0ZXNpYW5Dcm9zcyhtZXJpZGlhbk5vcm1hbCwgYXJjKTtcbiAgICAgICAgICBkM19nZW9fY2FydGVzaWFuTm9ybWFsaXplKGludGVyc2VjdGlvbik7XG4gICAgICAgICAgdmFyIM+GYXJjID0gKGFudGltZXJpZGlhbiBeIGTOuyA+PSAwID8gLTEgOiAxKSAqIGQzX2FzaW4oaW50ZXJzZWN0aW9uWzJdKTtcbiAgICAgICAgICBpZiAocGFyYWxsZWwgPiDPhmFyYykge1xuICAgICAgICAgICAgd2luZGluZyArPSBhbnRpbWVyaWRpYW4gXiBkzrsgPj0gMCA/IDEgOiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFqKyspIGJyZWFrO1xuICAgICAgICDOuzAgPSDOuywgc2luz4YwID0gc2luz4YsIGNvc8+GMCA9IGNvc8+GLCBwb2ludDAgPSBwb2ludDtcbiAgICAgIH1cbiAgICAgIGlmIChNYXRoLmFicyhwb2xhckFuZ2xlKSA+IM61KSBwb2xhciA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiAoIXNvdXRoUG9sZSAmJiAhcG9sYXIgJiYgZDNfZ2VvX2FyZWFSaW5nU3VtIDwgMCB8fCBwb2xhckFuZ2xlIDwgLc61KSBeIHdpbmRpbmcgJiAxO1xuICB9XG4gIHZhciBkM19nZW9fY2xpcEFudGltZXJpZGlhbiA9IGQzX2dlb19jbGlwKGQzX3RydWUsIGQzX2dlb19jbGlwQW50aW1lcmlkaWFuTGluZSwgZDNfZ2VvX2NsaXBBbnRpbWVyaWRpYW5JbnRlcnBvbGF0ZSwgZDNfZ2VvX2NsaXBBbnRpbWVyaWRpYW5Qb2x5Z29uQ29udGFpbnMpO1xuICBmdW5jdGlvbiBkM19nZW9fY2xpcEFudGltZXJpZGlhbkxpbmUobGlzdGVuZXIpIHtcbiAgICB2YXIgzrswID0gTmFOLCDPhjAgPSBOYU4sIHPOuzAgPSBOYU4sIGNsZWFuO1xuICAgIHJldHVybiB7XG4gICAgICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBsaXN0ZW5lci5saW5lU3RhcnQoKTtcbiAgICAgICAgY2xlYW4gPSAxO1xuICAgICAgfSxcbiAgICAgIHBvaW50OiBmdW5jdGlvbijOuzEsIM+GMSkge1xuICAgICAgICB2YXIgc867MSA9IM67MSA+IDAgPyDPgCA6IC3PgCwgZM67ID0gTWF0aC5hYnMozrsxIC0gzrswKTtcbiAgICAgICAgaWYgKE1hdGguYWJzKGTOuyAtIM+AKSA8IM61KSB7XG4gICAgICAgICAgbGlzdGVuZXIucG9pbnQozrswLCDPhjAgPSAoz4YwICsgz4YxKSAvIDIgPiAwID8gz4AgLyAyIDogLc+AIC8gMik7XG4gICAgICAgICAgbGlzdGVuZXIucG9pbnQoc867MCwgz4YwKTtcbiAgICAgICAgICBsaXN0ZW5lci5saW5lRW5kKCk7XG4gICAgICAgICAgbGlzdGVuZXIubGluZVN0YXJ0KCk7XG4gICAgICAgICAgbGlzdGVuZXIucG9pbnQoc867MSwgz4YwKTtcbiAgICAgICAgICBsaXN0ZW5lci5wb2ludCjOuzEsIM+GMCk7XG4gICAgICAgICAgY2xlYW4gPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKHPOuzAgIT09IHPOuzEgJiYgZM67ID49IM+AKSB7XG4gICAgICAgICAgaWYgKE1hdGguYWJzKM67MCAtIHPOuzApIDwgzrUpIM67MCAtPSBzzrswICogzrU7XG4gICAgICAgICAgaWYgKE1hdGguYWJzKM67MSAtIHPOuzEpIDwgzrUpIM67MSAtPSBzzrsxICogzrU7XG4gICAgICAgICAgz4YwID0gZDNfZ2VvX2NsaXBBbnRpbWVyaWRpYW5JbnRlcnNlY3QozrswLCDPhjAsIM67MSwgz4YxKTtcbiAgICAgICAgICBsaXN0ZW5lci5wb2ludChzzrswLCDPhjApO1xuICAgICAgICAgIGxpc3RlbmVyLmxpbmVFbmQoKTtcbiAgICAgICAgICBsaXN0ZW5lci5saW5lU3RhcnQoKTtcbiAgICAgICAgICBsaXN0ZW5lci5wb2ludChzzrsxLCDPhjApO1xuICAgICAgICAgIGNsZWFuID0gMDtcbiAgICAgICAgfVxuICAgICAgICBsaXN0ZW5lci5wb2ludCjOuzAgPSDOuzEsIM+GMCA9IM+GMSk7XG4gICAgICAgIHPOuzAgPSBzzrsxO1xuICAgICAgfSxcbiAgICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBsaXN0ZW5lci5saW5lRW5kKCk7XG4gICAgICAgIM67MCA9IM+GMCA9IE5hTjtcbiAgICAgIH0sXG4gICAgICBjbGVhbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiAyIC0gY2xlYW47XG4gICAgICB9XG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fY2xpcEFudGltZXJpZGlhbkludGVyc2VjdCjOuzAsIM+GMCwgzrsxLCDPhjEpIHtcbiAgICB2YXIgY29zz4YwLCBjb3PPhjEsIHNpbs67MF/OuzEgPSBNYXRoLnNpbijOuzAgLSDOuzEpO1xuICAgIHJldHVybiBNYXRoLmFicyhzaW7OuzBfzrsxKSA+IM61ID8gTWF0aC5hdGFuKChNYXRoLnNpbijPhjApICogKGNvc8+GMSA9IE1hdGguY29zKM+GMSkpICogTWF0aC5zaW4ozrsxKSAtIE1hdGguc2luKM+GMSkgKiAoY29zz4YwID0gTWF0aC5jb3Moz4YwKSkgKiBNYXRoLnNpbijOuzApKSAvIChjb3PPhjAgKiBjb3PPhjEgKiBzaW7OuzBfzrsxKSkgOiAoz4YwICsgz4YxKSAvIDI7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NsaXBBbnRpbWVyaWRpYW5JbnRlcnBvbGF0ZShmcm9tLCB0bywgZGlyZWN0aW9uLCBsaXN0ZW5lcikge1xuICAgIHZhciDPhjtcbiAgICBpZiAoZnJvbSA9PSBudWxsKSB7XG4gICAgICDPhiA9IGRpcmVjdGlvbiAqIM+AIC8gMjtcbiAgICAgIGxpc3RlbmVyLnBvaW50KC3PgCwgz4YpO1xuICAgICAgbGlzdGVuZXIucG9pbnQoMCwgz4YpO1xuICAgICAgbGlzdGVuZXIucG9pbnQoz4AsIM+GKTtcbiAgICAgIGxpc3RlbmVyLnBvaW50KM+ALCAwKTtcbiAgICAgIGxpc3RlbmVyLnBvaW50KM+ALCAtz4YpO1xuICAgICAgbGlzdGVuZXIucG9pbnQoMCwgLc+GKTtcbiAgICAgIGxpc3RlbmVyLnBvaW50KC3PgCwgLc+GKTtcbiAgICAgIGxpc3RlbmVyLnBvaW50KC3PgCwgMCk7XG4gICAgICBsaXN0ZW5lci5wb2ludCgtz4AsIM+GKTtcbiAgICB9IGVsc2UgaWYgKE1hdGguYWJzKGZyb21bMF0gLSB0b1swXSkgPiDOtSkge1xuICAgICAgdmFyIHMgPSAoZnJvbVswXSA8IHRvWzBdID8gMSA6IC0xKSAqIM+AO1xuICAgICAgz4YgPSBkaXJlY3Rpb24gKiBzIC8gMjtcbiAgICAgIGxpc3RlbmVyLnBvaW50KC1zLCDPhik7XG4gICAgICBsaXN0ZW5lci5wb2ludCgwLCDPhik7XG4gICAgICBsaXN0ZW5lci5wb2ludChzLCDPhik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3RlbmVyLnBvaW50KHRvWzBdLCB0b1sxXSk7XG4gICAgfVxuICB9XG4gIHZhciBkM19nZW9fY2xpcEFudGltZXJpZGlhblBvaW50ID0gWyAtz4AsIDAgXTtcbiAgZnVuY3Rpb24gZDNfZ2VvX2NsaXBBbnRpbWVyaWRpYW5Qb2x5Z29uQ29udGFpbnMocG9seWdvbikge1xuICAgIHJldHVybiBkM19nZW9fcG9pbnRJblBvbHlnb24oZDNfZ2VvX2NsaXBBbnRpbWVyaWRpYW5Qb2ludCwgcG9seWdvbik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NsaXBDaXJjbGUocmFkaXVzKSB7XG4gICAgdmFyIGNyID0gTWF0aC5jb3MocmFkaXVzKSwgc21hbGxSYWRpdXMgPSBjciA+IDAsIHBvaW50ID0gWyByYWRpdXMsIDAgXSwgbm90SGVtaXNwaGVyZSA9IE1hdGguYWJzKGNyKSA+IM61LCBpbnRlcnBvbGF0ZSA9IGQzX2dlb19jaXJjbGVJbnRlcnBvbGF0ZShyYWRpdXMsIDYgKiBkM19yYWRpYW5zKTtcbiAgICByZXR1cm4gZDNfZ2VvX2NsaXAodmlzaWJsZSwgY2xpcExpbmUsIGludGVycG9sYXRlLCBwb2x5Z29uQ29udGFpbnMpO1xuICAgIGZ1bmN0aW9uIHZpc2libGUozrssIM+GKSB7XG4gICAgICByZXR1cm4gTWF0aC5jb3MozrspICogTWF0aC5jb3Moz4YpID4gY3I7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNsaXBMaW5lKGxpc3RlbmVyKSB7XG4gICAgICB2YXIgcG9pbnQwLCBjMCwgdjAsIHYwMCwgY2xlYW47XG4gICAgICByZXR1cm4ge1xuICAgICAgICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHYwMCA9IHYwID0gZmFsc2U7XG4gICAgICAgICAgY2xlYW4gPSAxO1xuICAgICAgICB9LFxuICAgICAgICBwb2ludDogZnVuY3Rpb24ozrssIM+GKSB7XG4gICAgICAgICAgdmFyIHBvaW50MSA9IFsgzrssIM+GIF0sIHBvaW50MiwgdiA9IHZpc2libGUozrssIM+GKSwgYyA9IHNtYWxsUmFkaXVzID8gdiA/IDAgOiBjb2RlKM67LCDPhikgOiB2ID8gY29kZSjOuyArICjOuyA8IDAgPyDPgCA6IC3PgCksIM+GKSA6IDA7XG4gICAgICAgICAgaWYgKCFwb2ludDAgJiYgKHYwMCA9IHYwID0gdikpIGxpc3RlbmVyLmxpbmVTdGFydCgpO1xuICAgICAgICAgIGlmICh2ICE9PSB2MCkge1xuICAgICAgICAgICAgcG9pbnQyID0gaW50ZXJzZWN0KHBvaW50MCwgcG9pbnQxKTtcbiAgICAgICAgICAgIGlmIChkM19nZW9fc3BoZXJpY2FsRXF1YWwocG9pbnQwLCBwb2ludDIpIHx8IGQzX2dlb19zcGhlcmljYWxFcXVhbChwb2ludDEsIHBvaW50MikpIHtcbiAgICAgICAgICAgICAgcG9pbnQxWzBdICs9IM61O1xuICAgICAgICAgICAgICBwb2ludDFbMV0gKz0gzrU7XG4gICAgICAgICAgICAgIHYgPSB2aXNpYmxlKHBvaW50MVswXSwgcG9pbnQxWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHYgIT09IHYwKSB7XG4gICAgICAgICAgICBjbGVhbiA9IDA7XG4gICAgICAgICAgICBpZiAodikge1xuICAgICAgICAgICAgICBsaXN0ZW5lci5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgICAgcG9pbnQyID0gaW50ZXJzZWN0KHBvaW50MSwgcG9pbnQwKTtcbiAgICAgICAgICAgICAgbGlzdGVuZXIucG9pbnQocG9pbnQyWzBdLCBwb2ludDJbMV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcG9pbnQyID0gaW50ZXJzZWN0KHBvaW50MCwgcG9pbnQxKTtcbiAgICAgICAgICAgICAgbGlzdGVuZXIucG9pbnQocG9pbnQyWzBdLCBwb2ludDJbMV0pO1xuICAgICAgICAgICAgICBsaXN0ZW5lci5saW5lRW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwb2ludDAgPSBwb2ludDI7XG4gICAgICAgICAgfSBlbHNlIGlmIChub3RIZW1pc3BoZXJlICYmIHBvaW50MCAmJiBzbWFsbFJhZGl1cyBeIHYpIHtcbiAgICAgICAgICAgIHZhciB0O1xuICAgICAgICAgICAgaWYgKCEoYyAmIGMwKSAmJiAodCA9IGludGVyc2VjdChwb2ludDEsIHBvaW50MCwgdHJ1ZSkpKSB7XG4gICAgICAgICAgICAgIGNsZWFuID0gMDtcbiAgICAgICAgICAgICAgaWYgKHNtYWxsUmFkaXVzKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIubGluZVN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIucG9pbnQodFswXVswXSwgdFswXVsxXSk7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIucG9pbnQodFsxXVswXSwgdFsxXVsxXSk7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIubGluZUVuZCgpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLnBvaW50KHRbMV1bMF0sIHRbMV1bMV0pO1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLmxpbmVFbmQoKTtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lci5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lci5wb2ludCh0WzBdWzBdLCB0WzBdWzFdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodiAmJiAoIXBvaW50MCB8fCAhZDNfZ2VvX3NwaGVyaWNhbEVxdWFsKHBvaW50MCwgcG9pbnQxKSkpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyLnBvaW50KHBvaW50MVswXSwgcG9pbnQxWzFdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcG9pbnQwID0gcG9pbnQxLCB2MCA9IHYsIGMwID0gYztcbiAgICAgICAgfSxcbiAgICAgICAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKHYwKSBsaXN0ZW5lci5saW5lRW5kKCk7XG4gICAgICAgICAgcG9pbnQwID0gbnVsbDtcbiAgICAgICAgfSxcbiAgICAgICAgY2xlYW46IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBjbGVhbiB8ICh2MDAgJiYgdjApIDw8IDE7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICAgIGZ1bmN0aW9uIGludGVyc2VjdChhLCBiLCB0d28pIHtcbiAgICAgIHZhciBwYSA9IGQzX2dlb19jYXJ0ZXNpYW4oYSksIHBiID0gZDNfZ2VvX2NhcnRlc2lhbihiKTtcbiAgICAgIHZhciBuMSA9IFsgMSwgMCwgMCBdLCBuMiA9IGQzX2dlb19jYXJ0ZXNpYW5Dcm9zcyhwYSwgcGIpLCBuMm4yID0gZDNfZ2VvX2NhcnRlc2lhbkRvdChuMiwgbjIpLCBuMW4yID0gbjJbMF0sIGRldGVybWluYW50ID0gbjJuMiAtIG4xbjIgKiBuMW4yO1xuICAgICAgaWYgKCFkZXRlcm1pbmFudCkgcmV0dXJuICF0d28gJiYgYTtcbiAgICAgIHZhciBjMSA9IGNyICogbjJuMiAvIGRldGVybWluYW50LCBjMiA9IC1jciAqIG4xbjIgLyBkZXRlcm1pbmFudCwgbjF4bjIgPSBkM19nZW9fY2FydGVzaWFuQ3Jvc3MobjEsIG4yKSwgQSA9IGQzX2dlb19jYXJ0ZXNpYW5TY2FsZShuMSwgYzEpLCBCID0gZDNfZ2VvX2NhcnRlc2lhblNjYWxlKG4yLCBjMik7XG4gICAgICBkM19nZW9fY2FydGVzaWFuQWRkKEEsIEIpO1xuICAgICAgdmFyIHUgPSBuMXhuMiwgdyA9IGQzX2dlb19jYXJ0ZXNpYW5Eb3QoQSwgdSksIHV1ID0gZDNfZ2VvX2NhcnRlc2lhbkRvdCh1LCB1KSwgdDIgPSB3ICogdyAtIHV1ICogKGQzX2dlb19jYXJ0ZXNpYW5Eb3QoQSwgQSkgLSAxKTtcbiAgICAgIGlmICh0MiA8IDApIHJldHVybjtcbiAgICAgIHZhciB0ID0gTWF0aC5zcXJ0KHQyKSwgcSA9IGQzX2dlb19jYXJ0ZXNpYW5TY2FsZSh1LCAoLXcgLSB0KSAvIHV1KTtcbiAgICAgIGQzX2dlb19jYXJ0ZXNpYW5BZGQocSwgQSk7XG4gICAgICBxID0gZDNfZ2VvX3NwaGVyaWNhbChxKTtcbiAgICAgIGlmICghdHdvKSByZXR1cm4gcTtcbiAgICAgIHZhciDOuzAgPSBhWzBdLCDOuzEgPSBiWzBdLCDPhjAgPSBhWzFdLCDPhjEgPSBiWzFdLCB6O1xuICAgICAgaWYgKM67MSA8IM67MCkgeiA9IM67MCwgzrswID0gzrsxLCDOuzEgPSB6O1xuICAgICAgdmFyIM60zrsgPSDOuzEgLSDOuzAsIHBvbGFyID0gTWF0aC5hYnMozrTOuyAtIM+AKSA8IM61LCBtZXJpZGlhbiA9IHBvbGFyIHx8IM60zrsgPCDOtTtcbiAgICAgIGlmICghcG9sYXIgJiYgz4YxIDwgz4YwKSB6ID0gz4YwLCDPhjAgPSDPhjEsIM+GMSA9IHo7XG4gICAgICBpZiAobWVyaWRpYW4gPyBwb2xhciA/IM+GMCArIM+GMSA+IDAgXiBxWzFdIDwgKE1hdGguYWJzKHFbMF0gLSDOuzApIDwgzrUgPyDPhjAgOiDPhjEpIDogz4YwIDw9IHFbMV0gJiYgcVsxXSA8PSDPhjEgOiDOtM67ID4gz4AgXiAozrswIDw9IHFbMF0gJiYgcVswXSA8PSDOuzEpKSB7XG4gICAgICAgIHZhciBxMSA9IGQzX2dlb19jYXJ0ZXNpYW5TY2FsZSh1LCAoLXcgKyB0KSAvIHV1KTtcbiAgICAgICAgZDNfZ2VvX2NhcnRlc2lhbkFkZChxMSwgQSk7XG4gICAgICAgIHJldHVybiBbIHEsIGQzX2dlb19zcGhlcmljYWwocTEpIF07XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNvZGUozrssIM+GKSB7XG4gICAgICB2YXIgciA9IHNtYWxsUmFkaXVzID8gcmFkaXVzIDogz4AgLSByYWRpdXMsIGNvZGUgPSAwO1xuICAgICAgaWYgKM67IDwgLXIpIGNvZGUgfD0gMTsgZWxzZSBpZiAozrsgPiByKSBjb2RlIHw9IDI7XG4gICAgICBpZiAoz4YgPCAtcikgY29kZSB8PSA0OyBlbHNlIGlmICjPhiA+IHIpIGNvZGUgfD0gODtcbiAgICAgIHJldHVybiBjb2RlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBwb2x5Z29uQ29udGFpbnMocG9seWdvbikge1xuICAgICAgcmV0dXJuIGQzX2dlb19wb2ludEluUG9seWdvbihwb2ludCwgcG9seWdvbik7XG4gICAgfVxuICB9XG4gIHZhciBkM19nZW9fY2xpcFZpZXdNQVggPSAxZTk7XG4gIGZ1bmN0aW9uIGQzX2dlb19jbGlwVmlldyh4MCwgeTAsIHgxLCB5MSkge1xuICAgIHJldHVybiBmdW5jdGlvbihsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3RlbmVyXyA9IGxpc3RlbmVyLCBidWZmZXJMaXN0ZW5lciA9IGQzX2dlb19jbGlwQnVmZmVyTGlzdGVuZXIoKSwgc2VnbWVudHMsIHBvbHlnb24sIHJpbmc7XG4gICAgICB2YXIgY2xpcCA9IHtcbiAgICAgICAgcG9pbnQ6IHBvaW50LFxuICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgbGluZUVuZDogbGluZUVuZCxcbiAgICAgICAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBsaXN0ZW5lciA9IGJ1ZmZlckxpc3RlbmVyO1xuICAgICAgICAgIHNlZ21lbnRzID0gW107XG4gICAgICAgICAgcG9seWdvbiA9IFtdO1xuICAgICAgICB9LFxuICAgICAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBsaXN0ZW5lciA9IGxpc3RlbmVyXztcbiAgICAgICAgICBpZiAoKHNlZ21lbnRzID0gZDMubWVyZ2Uoc2VnbWVudHMpKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyLnBvbHlnb25TdGFydCgpO1xuICAgICAgICAgICAgZDNfZ2VvX2NsaXBQb2x5Z29uKHNlZ21lbnRzLCBjb21wYXJlLCBpbnNpZGUsIGludGVycG9sYXRlLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICBsaXN0ZW5lci5wb2x5Z29uRW5kKCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChpbnNpZGVQb2x5Z29uKFsgeDAsIHkwIF0pKSB7XG4gICAgICAgICAgICBsaXN0ZW5lci5wb2x5Z29uU3RhcnQoKSwgbGlzdGVuZXIubGluZVN0YXJ0KCk7XG4gICAgICAgICAgICBpbnRlcnBvbGF0ZShudWxsLCBudWxsLCAxLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICBsaXN0ZW5lci5saW5lRW5kKCksIGxpc3RlbmVyLnBvbHlnb25FbmQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VnbWVudHMgPSBwb2x5Z29uID0gcmluZyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBmdW5jdGlvbiBpbnNpZGUocG9pbnQpIHtcbiAgICAgICAgdmFyIGEgPSBjb3JuZXIocG9pbnQsIC0xKSwgaSA9IGluc2lkZVBvbHlnb24oWyBhID09PSAwIHx8IGEgPT09IDMgPyB4MCA6IHgxLCBhID4gMSA/IHkxIDogeTAgXSk7XG4gICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gaW5zaWRlUG9seWdvbihwKSB7XG4gICAgICAgIHZhciB3biA9IDAsIG4gPSBwb2x5Z29uLmxlbmd0aCwgeSA9IHBbMV07XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IDEsIHYgPSBwb2x5Z29uW2ldLCBtID0gdi5sZW5ndGgsIGEgPSB2WzBdLCBiOyBqIDwgbTsgKytqKSB7XG4gICAgICAgICAgICBiID0gdltqXTtcbiAgICAgICAgICAgIGlmIChhWzFdIDw9IHkpIHtcbiAgICAgICAgICAgICAgaWYgKGJbMV0gPiB5ICYmIGlzTGVmdChhLCBiLCBwKSA+IDApICsrd247XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAoYlsxXSA8PSB5ICYmIGlzTGVmdChhLCBiLCBwKSA8IDApIC0td247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhID0gYjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHduICE9PSAwO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gaXNMZWZ0KGEsIGIsIGMpIHtcbiAgICAgICAgcmV0dXJuIChiWzBdIC0gYVswXSkgKiAoY1sxXSAtIGFbMV0pIC0gKGNbMF0gLSBhWzBdKSAqIChiWzFdIC0gYVsxXSk7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBpbnRlcnBvbGF0ZShmcm9tLCB0bywgZGlyZWN0aW9uLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgYSA9IDAsIGExID0gMDtcbiAgICAgICAgaWYgKGZyb20gPT0gbnVsbCB8fCAoYSA9IGNvcm5lcihmcm9tLCBkaXJlY3Rpb24pKSAhPT0gKGExID0gY29ybmVyKHRvLCBkaXJlY3Rpb24pKSB8fCBjb21wYXJlUG9pbnRzKGZyb20sIHRvKSA8IDAgXiBkaXJlY3Rpb24gPiAwKSB7XG4gICAgICAgICAgZG8ge1xuICAgICAgICAgICAgbGlzdGVuZXIucG9pbnQoYSA9PT0gMCB8fCBhID09PSAzID8geDAgOiB4MSwgYSA+IDEgPyB5MSA6IHkwKTtcbiAgICAgICAgICB9IHdoaWxlICgoYSA9IChhICsgZGlyZWN0aW9uICsgNCkgJSA0KSAhPT0gYTEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxpc3RlbmVyLnBvaW50KHRvWzBdLCB0b1sxXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIHZpc2libGUoeCwgeSkge1xuICAgICAgICByZXR1cm4geDAgPD0geCAmJiB4IDw9IHgxICYmIHkwIDw9IHkgJiYgeSA8PSB5MTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIHBvaW50KHgsIHkpIHtcbiAgICAgICAgaWYgKHZpc2libGUoeCwgeSkpIGxpc3RlbmVyLnBvaW50KHgsIHkpO1xuICAgICAgfVxuICAgICAgdmFyIHhfXywgeV9fLCB2X18sIHhfLCB5Xywgdl8sIGZpcnN0O1xuICAgICAgZnVuY3Rpb24gbGluZVN0YXJ0KCkge1xuICAgICAgICBjbGlwLnBvaW50ID0gbGluZVBvaW50O1xuICAgICAgICBpZiAocG9seWdvbikgcG9seWdvbi5wdXNoKHJpbmcgPSBbXSk7XG4gICAgICAgIGZpcnN0ID0gdHJ1ZTtcbiAgICAgICAgdl8gPSBmYWxzZTtcbiAgICAgICAgeF8gPSB5XyA9IE5hTjtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7XG4gICAgICAgIGlmIChzZWdtZW50cykge1xuICAgICAgICAgIGxpbmVQb2ludCh4X18sIHlfXyk7XG4gICAgICAgICAgaWYgKHZfXyAmJiB2XykgYnVmZmVyTGlzdGVuZXIucmVqb2luKCk7XG4gICAgICAgICAgc2VnbWVudHMucHVzaChidWZmZXJMaXN0ZW5lci5idWZmZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgY2xpcC5wb2ludCA9IHBvaW50O1xuICAgICAgICBpZiAodl8pIGxpc3RlbmVyLmxpbmVFbmQoKTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGxpbmVQb2ludCh4LCB5KSB7XG4gICAgICAgIHggPSBNYXRoLm1heCgtZDNfZ2VvX2NsaXBWaWV3TUFYLCBNYXRoLm1pbihkM19nZW9fY2xpcFZpZXdNQVgsIHgpKTtcbiAgICAgICAgeSA9IE1hdGgubWF4KC1kM19nZW9fY2xpcFZpZXdNQVgsIE1hdGgubWluKGQzX2dlb19jbGlwVmlld01BWCwgeSkpO1xuICAgICAgICB2YXIgdiA9IHZpc2libGUoeCwgeSk7XG4gICAgICAgIGlmIChwb2x5Z29uKSByaW5nLnB1c2goWyB4LCB5IF0pO1xuICAgICAgICBpZiAoZmlyc3QpIHtcbiAgICAgICAgICB4X18gPSB4LCB5X18gPSB5LCB2X18gPSB2O1xuICAgICAgICAgIGZpcnN0ID0gZmFsc2U7XG4gICAgICAgICAgaWYgKHYpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgbGlzdGVuZXIucG9pbnQoeCwgeSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh2ICYmIHZfKSBsaXN0ZW5lci5wb2ludCh4LCB5KTsgZWxzZSB7XG4gICAgICAgICAgICB2YXIgYSA9IFsgeF8sIHlfIF0sIGIgPSBbIHgsIHkgXTtcbiAgICAgICAgICAgIGlmIChjbGlwTGluZShhLCBiKSkge1xuICAgICAgICAgICAgICBpZiAoIXZfKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIubGluZVN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIucG9pbnQoYVswXSwgYVsxXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGlzdGVuZXIucG9pbnQoYlswXSwgYlsxXSk7XG4gICAgICAgICAgICAgIGlmICghdikgbGlzdGVuZXIubGluZUVuZCgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2KSB7XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpbmVTdGFydCgpO1xuICAgICAgICAgICAgICBsaXN0ZW5lci5wb2ludCh4LCB5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgeF8gPSB4LCB5XyA9IHksIHZfID0gdjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjbGlwO1xuICAgIH07XG4gICAgZnVuY3Rpb24gY29ybmVyKHAsIGRpcmVjdGlvbikge1xuICAgICAgcmV0dXJuIE1hdGguYWJzKHBbMF0gLSB4MCkgPCDOtSA/IGRpcmVjdGlvbiA+IDAgPyAwIDogMyA6IE1hdGguYWJzKHBbMF0gLSB4MSkgPCDOtSA/IGRpcmVjdGlvbiA+IDAgPyAyIDogMSA6IE1hdGguYWJzKHBbMV0gLSB5MCkgPCDOtSA/IGRpcmVjdGlvbiA+IDAgPyAxIDogMCA6IGRpcmVjdGlvbiA+IDAgPyAzIDogMjtcbiAgICB9XG4gICAgZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gICAgICByZXR1cm4gY29tcGFyZVBvaW50cyhhLnBvaW50LCBiLnBvaW50KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY29tcGFyZVBvaW50cyhhLCBiKSB7XG4gICAgICB2YXIgY2EgPSBjb3JuZXIoYSwgMSksIGNiID0gY29ybmVyKGIsIDEpO1xuICAgICAgcmV0dXJuIGNhICE9PSBjYiA/IGNhIC0gY2IgOiBjYSA9PT0gMCA/IGJbMV0gLSBhWzFdIDogY2EgPT09IDEgPyBhWzBdIC0gYlswXSA6IGNhID09PSAyID8gYVsxXSAtIGJbMV0gOiBiWzBdIC0gYVswXTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2xpcExpbmUoYSwgYikge1xuICAgICAgdmFyIGR4ID0gYlswXSAtIGFbMF0sIGR5ID0gYlsxXSAtIGFbMV0sIHQgPSBbIDAsIDEgXTtcbiAgICAgIGlmIChNYXRoLmFicyhkeCkgPCDOtSAmJiBNYXRoLmFicyhkeSkgPCDOtSkgcmV0dXJuIHgwIDw9IGFbMF0gJiYgYVswXSA8PSB4MSAmJiB5MCA8PSBhWzFdICYmIGFbMV0gPD0geTE7XG4gICAgICBpZiAoZDNfZ2VvX2NsaXBWaWV3VCh4MCAtIGFbMF0sIGR4LCB0KSAmJiBkM19nZW9fY2xpcFZpZXdUKGFbMF0gLSB4MSwgLWR4LCB0KSAmJiBkM19nZW9fY2xpcFZpZXdUKHkwIC0gYVsxXSwgZHksIHQpICYmIGQzX2dlb19jbGlwVmlld1QoYVsxXSAtIHkxLCAtZHksIHQpKSB7XG4gICAgICAgIGlmICh0WzFdIDwgMSkge1xuICAgICAgICAgIGJbMF0gPSBhWzBdICsgdFsxXSAqIGR4O1xuICAgICAgICAgIGJbMV0gPSBhWzFdICsgdFsxXSAqIGR5O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0WzBdID4gMCkge1xuICAgICAgICAgIGFbMF0gKz0gdFswXSAqIGR4O1xuICAgICAgICAgIGFbMV0gKz0gdFswXSAqIGR5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fY2xpcFZpZXdUKG51bSwgZGVub21pbmF0b3IsIHQpIHtcbiAgICBpZiAoTWF0aC5hYnMoZGVub21pbmF0b3IpIDwgzrUpIHJldHVybiBudW0gPD0gMDtcbiAgICB2YXIgdSA9IG51bSAvIGRlbm9taW5hdG9yO1xuICAgIGlmIChkZW5vbWluYXRvciA+IDApIHtcbiAgICAgIGlmICh1ID4gdFsxXSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKHUgPiB0WzBdKSB0WzBdID0gdTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHUgPCB0WzBdKSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAodSA8IHRbMV0pIHRbMV0gPSB1O1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fY29tcG9zZShhLCBiKSB7XG4gICAgZnVuY3Rpb24gY29tcG9zZSh4LCB5KSB7XG4gICAgICByZXR1cm4geCA9IGEoeCwgeSksIGIoeFswXSwgeFsxXSk7XG4gICAgfVxuICAgIGlmIChhLmludmVydCAmJiBiLmludmVydCkgY29tcG9zZS5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgICByZXR1cm4geCA9IGIuaW52ZXJ0KHgsIHkpLCB4ICYmIGEuaW52ZXJ0KHhbMF0sIHhbMV0pO1xuICAgIH07XG4gICAgcmV0dXJuIGNvbXBvc2U7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NvbmljKHByb2plY3RBdCkge1xuICAgIHZhciDPhjAgPSAwLCDPhjEgPSDPgCAvIDMsIG0gPSBkM19nZW9fcHJvamVjdGlvbk11dGF0b3IocHJvamVjdEF0KSwgcCA9IG0oz4YwLCDPhjEpO1xuICAgIHAucGFyYWxsZWxzID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gWyDPhjAgLyDPgCAqIDE4MCwgz4YxIC8gz4AgKiAxODAgXTtcbiAgICAgIHJldHVybiBtKM+GMCA9IF9bMF0gKiDPgCAvIDE4MCwgz4YxID0gX1sxXSAqIM+AIC8gMTgwKTtcbiAgICB9O1xuICAgIHJldHVybiBwO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19jb25pY0VxdWFsQXJlYSjPhjAsIM+GMSkge1xuICAgIHZhciBzaW7PhjAgPSBNYXRoLnNpbijPhjApLCBuID0gKHNpbs+GMCArIE1hdGguc2luKM+GMSkpIC8gMiwgQyA9IDEgKyBzaW7PhjAgKiAoMiAqIG4gLSBzaW7PhjApLCDPgTAgPSBNYXRoLnNxcnQoQykgLyBuO1xuICAgIGZ1bmN0aW9uIGZvcndhcmQozrssIM+GKSB7XG4gICAgICB2YXIgz4EgPSBNYXRoLnNxcnQoQyAtIDIgKiBuICogTWF0aC5zaW4oz4YpKSAvIG47XG4gICAgICByZXR1cm4gWyDPgSAqIE1hdGguc2luKM67ICo9IG4pLCDPgTAgLSDPgSAqIE1hdGguY29zKM67KSBdO1xuICAgIH1cbiAgICBmb3J3YXJkLmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgIHZhciDPgTBfeSA9IM+BMCAtIHk7XG4gICAgICByZXR1cm4gWyBNYXRoLmF0YW4yKHgsIM+BMF95KSAvIG4sIGQzX2FzaW4oKEMgLSAoeCAqIHggKyDPgTBfeSAqIM+BMF95KSAqIG4gKiBuKSAvICgyICogbikpIF07XG4gICAgfTtcbiAgICByZXR1cm4gZm9yd2FyZDtcbiAgfVxuICAoZDMuZ2VvLmNvbmljRXF1YWxBcmVhID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX2dlb19jb25pYyhkM19nZW9fY29uaWNFcXVhbEFyZWEpO1xuICB9KS5yYXcgPSBkM19nZW9fY29uaWNFcXVhbEFyZWE7XG4gIGQzLmdlby5hbGJlcnMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDMuZ2VvLmNvbmljRXF1YWxBcmVhKCkucm90YXRlKFsgOTYsIDAgXSkuY2VudGVyKFsgLS42LCAzOC43IF0pLnBhcmFsbGVscyhbIDI5LjUsIDQ1LjUgXSkuc2NhbGUoMTA3MCk7XG4gIH07XG4gIGQzLmdlby5hbGJlcnNVc2EgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgbG93ZXI0OCA9IGQzLmdlby5hbGJlcnMoKTtcbiAgICB2YXIgYWxhc2thID0gZDMuZ2VvLmNvbmljRXF1YWxBcmVhKCkucm90YXRlKFsgMTU0LCAwIF0pLmNlbnRlcihbIC0yLCA1OC41IF0pLnBhcmFsbGVscyhbIDU1LCA2NSBdKTtcbiAgICB2YXIgaGF3YWlpID0gZDMuZ2VvLmNvbmljRXF1YWxBcmVhKCkucm90YXRlKFsgMTU3LCAwIF0pLmNlbnRlcihbIC0zLCAxOS45IF0pLnBhcmFsbGVscyhbIDgsIDE4IF0pO1xuICAgIHZhciBwb2ludCwgcG9pbnRTdHJlYW0gPSB7XG4gICAgICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgICAgICBwb2ludCA9IFsgeCwgeSBdO1xuICAgICAgfVxuICAgIH0sIGxvd2VyNDhQb2ludCwgYWxhc2thUG9pbnQsIGhhd2FpaVBvaW50O1xuICAgIGZ1bmN0aW9uIGFsYmVyc1VzYShjb29yZGluYXRlcykge1xuICAgICAgdmFyIHggPSBjb29yZGluYXRlc1swXSwgeSA9IGNvb3JkaW5hdGVzWzFdO1xuICAgICAgcG9pbnQgPSBudWxsO1xuICAgICAgKGxvd2VyNDhQb2ludCh4LCB5KSwgcG9pbnQpIHx8IChhbGFza2FQb2ludCh4LCB5KSwgcG9pbnQpIHx8IGhhd2FpaVBvaW50KHgsIHkpO1xuICAgICAgcmV0dXJuIHBvaW50O1xuICAgIH1cbiAgICBhbGJlcnNVc2EuaW52ZXJ0ID0gZnVuY3Rpb24oY29vcmRpbmF0ZXMpIHtcbiAgICAgIHZhciBrID0gbG93ZXI0OC5zY2FsZSgpLCB0ID0gbG93ZXI0OC50cmFuc2xhdGUoKSwgeCA9IChjb29yZGluYXRlc1swXSAtIHRbMF0pIC8gaywgeSA9IChjb29yZGluYXRlc1sxXSAtIHRbMV0pIC8gaztcbiAgICAgIHJldHVybiAoeSA+PSAuMTIgJiYgeSA8IC4yMzQgJiYgeCA+PSAtLjQyNSAmJiB4IDwgLS4yMTQgPyBhbGFza2EgOiB5ID49IC4xNjYgJiYgeSA8IC4yMzQgJiYgeCA+PSAtLjIxNCAmJiB4IDwgLS4xMTUgPyBoYXdhaWkgOiBsb3dlcjQ4KS5pbnZlcnQoY29vcmRpbmF0ZXMpO1xuICAgIH07XG4gICAgYWxiZXJzVXNhLnN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgdmFyIGxvd2VyNDhTdHJlYW0gPSBsb3dlcjQ4LnN0cmVhbShzdHJlYW0pLCBhbGFza2FTdHJlYW0gPSBhbGFza2Euc3RyZWFtKHN0cmVhbSksIGhhd2FpaVN0cmVhbSA9IGhhd2FpaS5zdHJlYW0oc3RyZWFtKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgICAgICAgbG93ZXI0OFN0cmVhbS5wb2ludCh4LCB5KTtcbiAgICAgICAgICBhbGFza2FTdHJlYW0ucG9pbnQoeCwgeSk7XG4gICAgICAgICAgaGF3YWlpU3RyZWFtLnBvaW50KHgsIHkpO1xuICAgICAgICB9LFxuICAgICAgICBzcGhlcmU6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGxvd2VyNDhTdHJlYW0uc3BoZXJlKCk7XG4gICAgICAgICAgYWxhc2thU3RyZWFtLnNwaGVyZSgpO1xuICAgICAgICAgIGhhd2FpaVN0cmVhbS5zcGhlcmUoKTtcbiAgICAgICAgfSxcbiAgICAgICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBsb3dlcjQ4U3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAgIGFsYXNrYVN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICBoYXdhaWlTdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGxvd2VyNDhTdHJlYW0ubGluZUVuZCgpO1xuICAgICAgICAgIGFsYXNrYVN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgICAgaGF3YWlpU3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgfSxcbiAgICAgICAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBsb3dlcjQ4U3RyZWFtLnBvbHlnb25TdGFydCgpO1xuICAgICAgICAgIGFsYXNrYVN0cmVhbS5wb2x5Z29uU3RhcnQoKTtcbiAgICAgICAgICBoYXdhaWlTdHJlYW0ucG9seWdvblN0YXJ0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGxvd2VyNDhTdHJlYW0ucG9seWdvbkVuZCgpO1xuICAgICAgICAgIGFsYXNrYVN0cmVhbS5wb2x5Z29uRW5kKCk7XG4gICAgICAgICAgaGF3YWlpU3RyZWFtLnBvbHlnb25FbmQoKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9O1xuICAgIGFsYmVyc1VzYS5wcmVjaXNpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsb3dlcjQ4LnByZWNpc2lvbigpO1xuICAgICAgbG93ZXI0OC5wcmVjaXNpb24oXyk7XG4gICAgICBhbGFza2EucHJlY2lzaW9uKF8pO1xuICAgICAgaGF3YWlpLnByZWNpc2lvbihfKTtcbiAgICAgIHJldHVybiBhbGJlcnNVc2E7XG4gICAgfTtcbiAgICBhbGJlcnNVc2Euc2NhbGUgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsb3dlcjQ4LnNjYWxlKCk7XG4gICAgICBsb3dlcjQ4LnNjYWxlKF8pO1xuICAgICAgYWxhc2thLnNjYWxlKF8gKiAuMzUpO1xuICAgICAgaGF3YWlpLnNjYWxlKF8pO1xuICAgICAgcmV0dXJuIGFsYmVyc1VzYS50cmFuc2xhdGUobG93ZXI0OC50cmFuc2xhdGUoKSk7XG4gICAgfTtcbiAgICBhbGJlcnNVc2EudHJhbnNsYXRlID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbG93ZXI0OC50cmFuc2xhdGUoKTtcbiAgICAgIHZhciBrID0gbG93ZXI0OC5zY2FsZSgpLCB4ID0gK19bMF0sIHkgPSArX1sxXTtcbiAgICAgIGxvd2VyNDhQb2ludCA9IGxvd2VyNDgudHJhbnNsYXRlKF8pLmNsaXBFeHRlbnQoWyBbIHggLSAuNDU1ICogaywgeSAtIC4yMzggKiBrIF0sIFsgeCArIC40NTUgKiBrLCB5ICsgLjIzOCAqIGsgXSBdKS5zdHJlYW0ocG9pbnRTdHJlYW0pLnBvaW50O1xuICAgICAgYWxhc2thUG9pbnQgPSBhbGFza2EudHJhbnNsYXRlKFsgeCAtIC4zMDcgKiBrLCB5ICsgLjIwMSAqIGsgXSkuY2xpcEV4dGVudChbIFsgeCAtIC40MjUgKiBrICsgzrUsIHkgKyAuMTIgKiBrICsgzrUgXSwgWyB4IC0gLjIxNCAqIGsgLSDOtSwgeSArIC4yMzQgKiBrIC0gzrUgXSBdKS5zdHJlYW0ocG9pbnRTdHJlYW0pLnBvaW50O1xuICAgICAgaGF3YWlpUG9pbnQgPSBoYXdhaWkudHJhbnNsYXRlKFsgeCAtIC4yMDUgKiBrLCB5ICsgLjIxMiAqIGsgXSkuY2xpcEV4dGVudChbIFsgeCAtIC4yMTQgKiBrICsgzrUsIHkgKyAuMTY2ICogayArIM61IF0sIFsgeCAtIC4xMTUgKiBrIC0gzrUsIHkgKyAuMjM0ICogayAtIM61IF0gXSkuc3RyZWFtKHBvaW50U3RyZWFtKS5wb2ludDtcbiAgICAgIHJldHVybiBhbGJlcnNVc2E7XG4gICAgfTtcbiAgICByZXR1cm4gYWxiZXJzVXNhLnNjYWxlKDEwNzApO1xuICB9O1xuICB2YXIgZDNfZ2VvX3BhdGhBcmVhU3VtLCBkM19nZW9fcGF0aEFyZWFQb2x5Z29uLCBkM19nZW9fcGF0aEFyZWEgPSB7XG4gICAgcG9pbnQ6IGQzX25vb3AsXG4gICAgbGluZVN0YXJ0OiBkM19ub29wLFxuICAgIGxpbmVFbmQ6IGQzX25vb3AsXG4gICAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgIGQzX2dlb19wYXRoQXJlYVBvbHlnb24gPSAwO1xuICAgICAgZDNfZ2VvX3BhdGhBcmVhLmxpbmVTdGFydCA9IGQzX2dlb19wYXRoQXJlYVJpbmdTdGFydDtcbiAgICB9LFxuICAgIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgZDNfZ2VvX3BhdGhBcmVhLmxpbmVTdGFydCA9IGQzX2dlb19wYXRoQXJlYS5saW5lRW5kID0gZDNfZ2VvX3BhdGhBcmVhLnBvaW50ID0gZDNfbm9vcDtcbiAgICAgIGQzX2dlb19wYXRoQXJlYVN1bSArPSBNYXRoLmFicyhkM19nZW9fcGF0aEFyZWFQb2x5Z29uIC8gMik7XG4gICAgfVxuICB9O1xuICBmdW5jdGlvbiBkM19nZW9fcGF0aEFyZWFSaW5nU3RhcnQoKSB7XG4gICAgdmFyIHgwMCwgeTAwLCB4MCwgeTA7XG4gICAgZDNfZ2VvX3BhdGhBcmVhLnBvaW50ID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgZDNfZ2VvX3BhdGhBcmVhLnBvaW50ID0gbmV4dFBvaW50O1xuICAgICAgeDAwID0geDAgPSB4LCB5MDAgPSB5MCA9IHk7XG4gICAgfTtcbiAgICBmdW5jdGlvbiBuZXh0UG9pbnQoeCwgeSkge1xuICAgICAgZDNfZ2VvX3BhdGhBcmVhUG9seWdvbiArPSB5MCAqIHggLSB4MCAqIHk7XG4gICAgICB4MCA9IHgsIHkwID0geTtcbiAgICB9XG4gICAgZDNfZ2VvX3BhdGhBcmVhLmxpbmVFbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIG5leHRQb2ludCh4MDAsIHkwMCk7XG4gICAgfTtcbiAgfVxuICB2YXIgZDNfZ2VvX3BhdGhCb3VuZHNYMCwgZDNfZ2VvX3BhdGhCb3VuZHNZMCwgZDNfZ2VvX3BhdGhCb3VuZHNYMSwgZDNfZ2VvX3BhdGhCb3VuZHNZMTtcbiAgdmFyIGQzX2dlb19wYXRoQm91bmRzID0ge1xuICAgIHBvaW50OiBkM19nZW9fcGF0aEJvdW5kc1BvaW50LFxuICAgIGxpbmVTdGFydDogZDNfbm9vcCxcbiAgICBsaW5lRW5kOiBkM19ub29wLFxuICAgIHBvbHlnb25TdGFydDogZDNfbm9vcCxcbiAgICBwb2x5Z29uRW5kOiBkM19ub29wXG4gIH07XG4gIGZ1bmN0aW9uIGQzX2dlb19wYXRoQm91bmRzUG9pbnQoeCwgeSkge1xuICAgIGlmICh4IDwgZDNfZ2VvX3BhdGhCb3VuZHNYMCkgZDNfZ2VvX3BhdGhCb3VuZHNYMCA9IHg7XG4gICAgaWYgKHggPiBkM19nZW9fcGF0aEJvdW5kc1gxKSBkM19nZW9fcGF0aEJvdW5kc1gxID0geDtcbiAgICBpZiAoeSA8IGQzX2dlb19wYXRoQm91bmRzWTApIGQzX2dlb19wYXRoQm91bmRzWTAgPSB5O1xuICAgIGlmICh5ID4gZDNfZ2VvX3BhdGhCb3VuZHNZMSkgZDNfZ2VvX3BhdGhCb3VuZHNZMSA9IHk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3BhdGhCdWZmZXIoKSB7XG4gICAgdmFyIHBvaW50Q2lyY2xlID0gZDNfZ2VvX3BhdGhCdWZmZXJDaXJjbGUoNC41KSwgYnVmZmVyID0gW107XG4gICAgdmFyIHN0cmVhbSA9IHtcbiAgICAgIHBvaW50OiBwb2ludCxcbiAgICAgIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHN0cmVhbS5wb2ludCA9IHBvaW50TGluZVN0YXJ0O1xuICAgICAgfSxcbiAgICAgIGxpbmVFbmQ6IGxpbmVFbmQsXG4gICAgICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBzdHJlYW0ubGluZUVuZCA9IGxpbmVFbmRQb2x5Z29uO1xuICAgICAgfSxcbiAgICAgIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBzdHJlYW0ubGluZUVuZCA9IGxpbmVFbmQ7XG4gICAgICAgIHN0cmVhbS5wb2ludCA9IHBvaW50O1xuICAgICAgfSxcbiAgICAgIHBvaW50UmFkaXVzOiBmdW5jdGlvbihfKSB7XG4gICAgICAgIHBvaW50Q2lyY2xlID0gZDNfZ2VvX3BhdGhCdWZmZXJDaXJjbGUoXyk7XG4gICAgICAgIHJldHVybiBzdHJlYW07XG4gICAgICB9LFxuICAgICAgcmVzdWx0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gYnVmZmVyLmpvaW4oXCJcIik7XG4gICAgICAgICAgYnVmZmVyID0gW107XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gcG9pbnQoeCwgeSkge1xuICAgICAgYnVmZmVyLnB1c2goXCJNXCIsIHgsIFwiLFwiLCB5LCBwb2ludENpcmNsZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHBvaW50TGluZVN0YXJ0KHgsIHkpIHtcbiAgICAgIGJ1ZmZlci5wdXNoKFwiTVwiLCB4LCBcIixcIiwgeSk7XG4gICAgICBzdHJlYW0ucG9pbnQgPSBwb2ludExpbmU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHBvaW50TGluZSh4LCB5KSB7XG4gICAgICBidWZmZXIucHVzaChcIkxcIiwgeCwgXCIsXCIsIHkpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBsaW5lRW5kKCkge1xuICAgICAgc3RyZWFtLnBvaW50ID0gcG9pbnQ7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGxpbmVFbmRQb2x5Z29uKCkge1xuICAgICAgYnVmZmVyLnB1c2goXCJaXCIpO1xuICAgIH1cbiAgICByZXR1cm4gc3RyZWFtO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19wYXRoQnVmZmVyQ2lyY2xlKHJhZGl1cykge1xuICAgIHJldHVybiBcIm0wLFwiICsgcmFkaXVzICsgXCJhXCIgKyByYWRpdXMgKyBcIixcIiArIHJhZGl1cyArIFwiIDAgMSwxIDAsXCIgKyAtMiAqIHJhZGl1cyArIFwiYVwiICsgcmFkaXVzICsgXCIsXCIgKyByYWRpdXMgKyBcIiAwIDEsMSAwLFwiICsgMiAqIHJhZGl1cyArIFwielwiO1xuICB9XG4gIHZhciBkM19nZW9fcGF0aENlbnRyb2lkID0ge1xuICAgIHBvaW50OiBkM19nZW9fcGF0aENlbnRyb2lkUG9pbnQsXG4gICAgbGluZVN0YXJ0OiBkM19nZW9fcGF0aENlbnRyb2lkTGluZVN0YXJ0LFxuICAgIGxpbmVFbmQ6IGQzX2dlb19wYXRoQ2VudHJvaWRMaW5lRW5kLFxuICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICBkM19nZW9fcGF0aENlbnRyb2lkLmxpbmVTdGFydCA9IGQzX2dlb19wYXRoQ2VudHJvaWRSaW5nU3RhcnQ7XG4gICAgfSxcbiAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICAgIGQzX2dlb19wYXRoQ2VudHJvaWQucG9pbnQgPSBkM19nZW9fcGF0aENlbnRyb2lkUG9pbnQ7XG4gICAgICBkM19nZW9fcGF0aENlbnRyb2lkLmxpbmVTdGFydCA9IGQzX2dlb19wYXRoQ2VudHJvaWRMaW5lU3RhcnQ7XG4gICAgICBkM19nZW9fcGF0aENlbnRyb2lkLmxpbmVFbmQgPSBkM19nZW9fcGF0aENlbnRyb2lkTGluZUVuZDtcbiAgICB9XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2dlb19wYXRoQ2VudHJvaWRQb2ludCh4LCB5KSB7XG4gICAgZDNfZ2VvX2NlbnRyb2lkWDAgKz0geDtcbiAgICBkM19nZW9fY2VudHJvaWRZMCArPSB5O1xuICAgICsrZDNfZ2VvX2NlbnRyb2lkWjA7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3BhdGhDZW50cm9pZExpbmVTdGFydCgpIHtcbiAgICB2YXIgeDAsIHkwO1xuICAgIGQzX2dlb19wYXRoQ2VudHJvaWQucG9pbnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgICBkM19nZW9fcGF0aENlbnRyb2lkLnBvaW50ID0gbmV4dFBvaW50O1xuICAgICAgZDNfZ2VvX3BhdGhDZW50cm9pZFBvaW50KHgwID0geCwgeTAgPSB5KTtcbiAgICB9O1xuICAgIGZ1bmN0aW9uIG5leHRQb2ludCh4LCB5KSB7XG4gICAgICB2YXIgZHggPSB4IC0geDAsIGR5ID0geSAtIHkwLCB6ID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbiAgICAgIGQzX2dlb19jZW50cm9pZFgxICs9IHogKiAoeDAgKyB4KSAvIDI7XG4gICAgICBkM19nZW9fY2VudHJvaWRZMSArPSB6ICogKHkwICsgeSkgLyAyO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkWjEgKz0gejtcbiAgICAgIGQzX2dlb19wYXRoQ2VudHJvaWRQb2ludCh4MCA9IHgsIHkwID0geSk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19wYXRoQ2VudHJvaWRMaW5lRW5kKCkge1xuICAgIGQzX2dlb19wYXRoQ2VudHJvaWQucG9pbnQgPSBkM19nZW9fcGF0aENlbnRyb2lkUG9pbnQ7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3BhdGhDZW50cm9pZFJpbmdTdGFydCgpIHtcbiAgICB2YXIgeDAwLCB5MDAsIHgwLCB5MDtcbiAgICBkM19nZW9fcGF0aENlbnRyb2lkLnBvaW50ID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgZDNfZ2VvX3BhdGhDZW50cm9pZC5wb2ludCA9IG5leHRQb2ludDtcbiAgICAgIGQzX2dlb19wYXRoQ2VudHJvaWRQb2ludCh4MDAgPSB4MCA9IHgsIHkwMCA9IHkwID0geSk7XG4gICAgfTtcbiAgICBmdW5jdGlvbiBuZXh0UG9pbnQoeCwgeSkge1xuICAgICAgdmFyIGR4ID0geCAtIHgwLCBkeSA9IHkgLSB5MCwgeiA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG4gICAgICBkM19nZW9fY2VudHJvaWRYMSArPSB6ICogKHgwICsgeCkgLyAyO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkWTEgKz0geiAqICh5MCArIHkpIC8gMjtcbiAgICAgIGQzX2dlb19jZW50cm9pZFoxICs9IHo7XG4gICAgICB6ID0geTAgKiB4IC0geDAgKiB5O1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkWDIgKz0geiAqICh4MCArIHgpO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkWTIgKz0geiAqICh5MCArIHkpO1xuICAgICAgZDNfZ2VvX2NlbnRyb2lkWjIgKz0geiAqIDM7XG4gICAgICBkM19nZW9fcGF0aENlbnRyb2lkUG9pbnQoeDAgPSB4LCB5MCA9IHkpO1xuICAgIH1cbiAgICBkM19nZW9fcGF0aENlbnRyb2lkLmxpbmVFbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIG5leHRQb2ludCh4MDAsIHkwMCk7XG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fcGF0aENvbnRleHQoY29udGV4dCkge1xuICAgIHZhciBwb2ludFJhZGl1cyA9IDQuNTtcbiAgICB2YXIgc3RyZWFtID0ge1xuICAgICAgcG9pbnQ6IHBvaW50LFxuICAgICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgc3RyZWFtLnBvaW50ID0gcG9pbnRMaW5lU3RhcnQ7XG4gICAgICB9LFxuICAgICAgbGluZUVuZDogbGluZUVuZCxcbiAgICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHN0cmVhbS5saW5lRW5kID0gbGluZUVuZFBvbHlnb247XG4gICAgICB9LFxuICAgICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHN0cmVhbS5saW5lRW5kID0gbGluZUVuZDtcbiAgICAgICAgc3RyZWFtLnBvaW50ID0gcG9pbnQ7XG4gICAgICB9LFxuICAgICAgcG9pbnRSYWRpdXM6IGZ1bmN0aW9uKF8pIHtcbiAgICAgICAgcG9pbnRSYWRpdXMgPSBfO1xuICAgICAgICByZXR1cm4gc3RyZWFtO1xuICAgICAgfSxcbiAgICAgIHJlc3VsdDogZDNfbm9vcFxuICAgIH07XG4gICAgZnVuY3Rpb24gcG9pbnQoeCwgeSkge1xuICAgICAgY29udGV4dC5tb3ZlVG8oeCwgeSk7XG4gICAgICBjb250ZXh0LmFyYyh4LCB5LCBwb2ludFJhZGl1cywgMCwgMiAqIM+AKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcG9pbnRMaW5lU3RhcnQoeCwgeSkge1xuICAgICAgY29udGV4dC5tb3ZlVG8oeCwgeSk7XG4gICAgICBzdHJlYW0ucG9pbnQgPSBwb2ludExpbmU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHBvaW50TGluZSh4LCB5KSB7XG4gICAgICBjb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gbGluZUVuZCgpIHtcbiAgICAgIHN0cmVhbS5wb2ludCA9IHBvaW50O1xuICAgIH1cbiAgICBmdW5jdGlvbiBsaW5lRW5kUG9seWdvbigpIHtcbiAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgfVxuICAgIHJldHVybiBzdHJlYW07XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3Jlc2FtcGxlKHByb2plY3QpIHtcbiAgICB2YXIgzrQyID0gLjUsIGNvc01pbkRpc3RhbmNlID0gTWF0aC5jb3MoMzAgKiBkM19yYWRpYW5zKSwgbWF4RGVwdGggPSAxNjtcbiAgICBmdW5jdGlvbiByZXNhbXBsZShzdHJlYW0pIHtcbiAgICAgIHZhciDOuzAwLCDPhjAwLCB4MDAsIHkwMCwgYTAwLCBiMDAsIGMwMCwgzrswLCB4MCwgeTAsIGEwLCBiMCwgYzA7XG4gICAgICB2YXIgcmVzYW1wbGUgPSB7XG4gICAgICAgIHBvaW50OiBwb2ludCxcbiAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgIGxpbmVFbmQ6IGxpbmVFbmQsXG4gICAgICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgc3RyZWFtLnBvbHlnb25TdGFydCgpO1xuICAgICAgICAgIHJlc2FtcGxlLmxpbmVTdGFydCA9IHJpbmdTdGFydDtcbiAgICAgICAgfSxcbiAgICAgICAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgc3RyZWFtLnBvbHlnb25FbmQoKTtcbiAgICAgICAgICByZXNhbXBsZS5saW5lU3RhcnQgPSBsaW5lU3RhcnQ7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBmdW5jdGlvbiBwb2ludCh4LCB5KSB7XG4gICAgICAgIHggPSBwcm9qZWN0KHgsIHkpO1xuICAgICAgICBzdHJlYW0ucG9pbnQoeFswXSwgeFsxXSk7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBsaW5lU3RhcnQoKSB7XG4gICAgICAgIHgwID0gTmFOO1xuICAgICAgICByZXNhbXBsZS5wb2ludCA9IGxpbmVQb2ludDtcbiAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gbGluZVBvaW50KM67LCDPhikge1xuICAgICAgICB2YXIgYyA9IGQzX2dlb19jYXJ0ZXNpYW4oWyDOuywgz4YgXSksIHAgPSBwcm9qZWN0KM67LCDPhik7XG4gICAgICAgIHJlc2FtcGxlTGluZVRvKHgwLCB5MCwgzrswLCBhMCwgYjAsIGMwLCB4MCA9IHBbMF0sIHkwID0gcFsxXSwgzrswID0gzrssIGEwID0gY1swXSwgYjAgPSBjWzFdLCBjMCA9IGNbMl0sIG1heERlcHRoLCBzdHJlYW0pO1xuICAgICAgICBzdHJlYW0ucG9pbnQoeDAsIHkwKTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7XG4gICAgICAgIHJlc2FtcGxlLnBvaW50ID0gcG9pbnQ7XG4gICAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiByaW5nU3RhcnQoKSB7XG4gICAgICAgIGxpbmVTdGFydCgpO1xuICAgICAgICByZXNhbXBsZS5wb2ludCA9IHJpbmdQb2ludDtcbiAgICAgICAgcmVzYW1wbGUubGluZUVuZCA9IHJpbmdFbmQ7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiByaW5nUG9pbnQozrssIM+GKSB7XG4gICAgICAgIGxpbmVQb2ludCjOuzAwID0gzrssIM+GMDAgPSDPhiksIHgwMCA9IHgwLCB5MDAgPSB5MCwgYTAwID0gYTAsIGIwMCA9IGIwLCBjMDAgPSBjMDtcbiAgICAgICAgcmVzYW1wbGUucG9pbnQgPSBsaW5lUG9pbnQ7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiByaW5nRW5kKCkge1xuICAgICAgICByZXNhbXBsZUxpbmVUbyh4MCwgeTAsIM67MCwgYTAsIGIwLCBjMCwgeDAwLCB5MDAsIM67MDAsIGEwMCwgYjAwLCBjMDAsIG1heERlcHRoLCBzdHJlYW0pO1xuICAgICAgICByZXNhbXBsZS5saW5lRW5kID0gbGluZUVuZDtcbiAgICAgICAgbGluZUVuZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc2FtcGxlO1xuICAgIH1cbiAgICBmdW5jdGlvbiByZXNhbXBsZUxpbmVUbyh4MCwgeTAsIM67MCwgYTAsIGIwLCBjMCwgeDEsIHkxLCDOuzEsIGExLCBiMSwgYzEsIGRlcHRoLCBzdHJlYW0pIHtcbiAgICAgIHZhciBkeCA9IHgxIC0geDAsIGR5ID0geTEgLSB5MCwgZDIgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgIGlmIChkMiA+IDQgKiDOtDIgJiYgZGVwdGgtLSkge1xuICAgICAgICB2YXIgYSA9IGEwICsgYTEsIGIgPSBiMCArIGIxLCBjID0gYzAgKyBjMSwgbSA9IE1hdGguc3FydChhICogYSArIGIgKiBiICsgYyAqIGMpLCDPhjIgPSBNYXRoLmFzaW4oYyAvPSBtKSwgzrsyID0gTWF0aC5hYnMoTWF0aC5hYnMoYykgLSAxKSA8IM61ID8gKM67MCArIM67MSkgLyAyIDogTWF0aC5hdGFuMihiLCBhKSwgcCA9IHByb2plY3QozrsyLCDPhjIpLCB4MiA9IHBbMF0sIHkyID0gcFsxXSwgZHgyID0geDIgLSB4MCwgZHkyID0geTIgLSB5MCwgZHogPSBkeSAqIGR4MiAtIGR4ICogZHkyO1xuICAgICAgICBpZiAoZHogKiBkeiAvIGQyID4gzrQyIHx8IE1hdGguYWJzKChkeCAqIGR4MiArIGR5ICogZHkyKSAvIGQyIC0gLjUpID4gLjMgfHwgYTAgKiBhMSArIGIwICogYjEgKyBjMCAqIGMxIDwgY29zTWluRGlzdGFuY2UpIHtcbiAgICAgICAgICByZXNhbXBsZUxpbmVUbyh4MCwgeTAsIM67MCwgYTAsIGIwLCBjMCwgeDIsIHkyLCDOuzIsIGEgLz0gbSwgYiAvPSBtLCBjLCBkZXB0aCwgc3RyZWFtKTtcbiAgICAgICAgICBzdHJlYW0ucG9pbnQoeDIsIHkyKTtcbiAgICAgICAgICByZXNhbXBsZUxpbmVUbyh4MiwgeTIsIM67MiwgYSwgYiwgYywgeDEsIHkxLCDOuzEsIGExLCBiMSwgYzEsIGRlcHRoLCBzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJlc2FtcGxlLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIE1hdGguc3FydCjOtDIpO1xuICAgICAgbWF4RGVwdGggPSAozrQyID0gXyAqIF8pID4gMCAmJiAxNjtcbiAgICAgIHJldHVybiByZXNhbXBsZTtcbiAgICB9O1xuICAgIHJldHVybiByZXNhbXBsZTtcbiAgfVxuICBkMy5nZW8ucGF0aCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBwb2ludFJhZGl1cyA9IDQuNSwgcHJvamVjdGlvbiwgY29udGV4dCwgcHJvamVjdFN0cmVhbSwgY29udGV4dFN0cmVhbSwgY2FjaGVTdHJlYW07XG4gICAgZnVuY3Rpb24gcGF0aChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwb2ludFJhZGl1cyA9PT0gXCJmdW5jdGlvblwiKSBjb250ZXh0U3RyZWFtLnBvaW50UmFkaXVzKCtwb2ludFJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgICAgICAgaWYgKCFjYWNoZVN0cmVhbSB8fCAhY2FjaGVTdHJlYW0udmFsaWQpIGNhY2hlU3RyZWFtID0gcHJvamVjdFN0cmVhbShjb250ZXh0U3RyZWFtKTtcbiAgICAgICAgZDMuZ2VvLnN0cmVhbShvYmplY3QsIGNhY2hlU3RyZWFtKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb250ZXh0U3RyZWFtLnJlc3VsdCgpO1xuICAgIH1cbiAgICBwYXRoLmFyZWEgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIGQzX2dlb19wYXRoQXJlYVN1bSA9IDA7XG4gICAgICBkMy5nZW8uc3RyZWFtKG9iamVjdCwgcHJvamVjdFN0cmVhbShkM19nZW9fcGF0aEFyZWEpKTtcbiAgICAgIHJldHVybiBkM19nZW9fcGF0aEFyZWFTdW07XG4gICAgfTtcbiAgICBwYXRoLmNlbnRyb2lkID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICBkM19nZW9fY2VudHJvaWRYMCA9IGQzX2dlb19jZW50cm9pZFkwID0gZDNfZ2VvX2NlbnRyb2lkWjAgPSBkM19nZW9fY2VudHJvaWRYMSA9IGQzX2dlb19jZW50cm9pZFkxID0gZDNfZ2VvX2NlbnRyb2lkWjEgPSBkM19nZW9fY2VudHJvaWRYMiA9IGQzX2dlb19jZW50cm9pZFkyID0gZDNfZ2VvX2NlbnRyb2lkWjIgPSAwO1xuICAgICAgZDMuZ2VvLnN0cmVhbShvYmplY3QsIHByb2plY3RTdHJlYW0oZDNfZ2VvX3BhdGhDZW50cm9pZCkpO1xuICAgICAgcmV0dXJuIGQzX2dlb19jZW50cm9pZFoyID8gWyBkM19nZW9fY2VudHJvaWRYMiAvIGQzX2dlb19jZW50cm9pZFoyLCBkM19nZW9fY2VudHJvaWRZMiAvIGQzX2dlb19jZW50cm9pZFoyIF0gOiBkM19nZW9fY2VudHJvaWRaMSA/IFsgZDNfZ2VvX2NlbnRyb2lkWDEgLyBkM19nZW9fY2VudHJvaWRaMSwgZDNfZ2VvX2NlbnRyb2lkWTEgLyBkM19nZW9fY2VudHJvaWRaMSBdIDogZDNfZ2VvX2NlbnRyb2lkWjAgPyBbIGQzX2dlb19jZW50cm9pZFgwIC8gZDNfZ2VvX2NlbnRyb2lkWjAsIGQzX2dlb19jZW50cm9pZFkwIC8gZDNfZ2VvX2NlbnRyb2lkWjAgXSA6IFsgTmFOLCBOYU4gXTtcbiAgICB9O1xuICAgIHBhdGguYm91bmRzID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICBkM19nZW9fcGF0aEJvdW5kc1gxID0gZDNfZ2VvX3BhdGhCb3VuZHNZMSA9IC0oZDNfZ2VvX3BhdGhCb3VuZHNYMCA9IGQzX2dlb19wYXRoQm91bmRzWTAgPSBJbmZpbml0eSk7XG4gICAgICBkMy5nZW8uc3RyZWFtKG9iamVjdCwgcHJvamVjdFN0cmVhbShkM19nZW9fcGF0aEJvdW5kcykpO1xuICAgICAgcmV0dXJuIFsgWyBkM19nZW9fcGF0aEJvdW5kc1gwLCBkM19nZW9fcGF0aEJvdW5kc1kwIF0sIFsgZDNfZ2VvX3BhdGhCb3VuZHNYMSwgZDNfZ2VvX3BhdGhCb3VuZHNZMSBdIF07XG4gICAgfTtcbiAgICBwYXRoLnByb2plY3Rpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBwcm9qZWN0aW9uO1xuICAgICAgcHJvamVjdFN0cmVhbSA9IChwcm9qZWN0aW9uID0gXykgPyBfLnN0cmVhbSB8fCBkM19nZW9fcGF0aFByb2plY3RTdHJlYW0oXykgOiBkM19pZGVudGl0eTtcbiAgICAgIHJldHVybiByZXNldCgpO1xuICAgIH07XG4gICAgcGF0aC5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY29udGV4dDtcbiAgICAgIGNvbnRleHRTdHJlYW0gPSAoY29udGV4dCA9IF8pID09IG51bGwgPyBuZXcgZDNfZ2VvX3BhdGhCdWZmZXIoKSA6IG5ldyBkM19nZW9fcGF0aENvbnRleHQoXyk7XG4gICAgICBpZiAodHlwZW9mIHBvaW50UmFkaXVzICE9PSBcImZ1bmN0aW9uXCIpIGNvbnRleHRTdHJlYW0ucG9pbnRSYWRpdXMocG9pbnRSYWRpdXMpO1xuICAgICAgcmV0dXJuIHJlc2V0KCk7XG4gICAgfTtcbiAgICBwYXRoLnBvaW50UmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcG9pbnRSYWRpdXM7XG4gICAgICBwb2ludFJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogKGNvbnRleHRTdHJlYW0ucG9pbnRSYWRpdXMoK18pLCArXyk7XG4gICAgICByZXR1cm4gcGF0aDtcbiAgICB9O1xuICAgIGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgICAgY2FjaGVTdHJlYW0gPSBudWxsO1xuICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfVxuICAgIHJldHVybiBwYXRoLnByb2plY3Rpb24oZDMuZ2VvLmFsYmVyc1VzYSgpKS5jb250ZXh0KG51bGwpO1xuICB9O1xuICBmdW5jdGlvbiBkM19nZW9fcGF0aFByb2plY3RTdHJlYW0ocHJvamVjdCkge1xuICAgIHZhciByZXNhbXBsZSA9IGQzX2dlb19yZXNhbXBsZShmdW5jdGlvbijOuywgz4YpIHtcbiAgICAgIHJldHVybiBwcm9qZWN0KFsgzrsgKiBkM19kZWdyZWVzLCDPhiAqIGQzX2RlZ3JlZXMgXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgc3RyZWFtID0gcmVzYW1wbGUoc3RyZWFtKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBvaW50OiBmdW5jdGlvbijOuywgz4YpIHtcbiAgICAgICAgICBzdHJlYW0ucG9pbnQozrsgKiBkM19yYWRpYW5zLCDPhiAqIGQzX3JhZGlhbnMpO1xuICAgICAgICB9LFxuICAgICAgICBzcGhlcmU6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHN0cmVhbS5zcGhlcmUoKTtcbiAgICAgICAgfSxcbiAgICAgICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBzdHJlYW0ubGluZVN0YXJ0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgIH0sXG4gICAgICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgc3RyZWFtLnBvbHlnb25TdGFydCgpO1xuICAgICAgICB9LFxuICAgICAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBzdHJlYW0ucG9seWdvbkVuZCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH07XG4gIH1cbiAgZDMuZ2VvLnByb2plY3Rpb24gPSBkM19nZW9fcHJvamVjdGlvbjtcbiAgZDMuZ2VvLnByb2plY3Rpb25NdXRhdG9yID0gZDNfZ2VvX3Byb2plY3Rpb25NdXRhdG9yO1xuICBmdW5jdGlvbiBkM19nZW9fcHJvamVjdGlvbihwcm9qZWN0KSB7XG4gICAgcmV0dXJuIGQzX2dlb19wcm9qZWN0aW9uTXV0YXRvcihmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwcm9qZWN0O1xuICAgIH0pKCk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3Byb2plY3Rpb25NdXRhdG9yKHByb2plY3RBdCkge1xuICAgIHZhciBwcm9qZWN0LCByb3RhdGUsIHByb2plY3RSb3RhdGUsIHByb2plY3RSZXNhbXBsZSA9IGQzX2dlb19yZXNhbXBsZShmdW5jdGlvbih4LCB5KSB7XG4gICAgICB4ID0gcHJvamVjdCh4LCB5KTtcbiAgICAgIHJldHVybiBbIHhbMF0gKiBrICsgzrR4LCDOtHkgLSB4WzFdICogayBdO1xuICAgIH0pLCBrID0gMTUwLCB4ID0gNDgwLCB5ID0gMjUwLCDOuyA9IDAsIM+GID0gMCwgzrTOuyA9IDAsIM60z4YgPSAwLCDOtM6zID0gMCwgzrR4LCDOtHksIHByZWNsaXAgPSBkM19nZW9fY2xpcEFudGltZXJpZGlhbiwgcG9zdGNsaXAgPSBkM19pZGVudGl0eSwgY2xpcEFuZ2xlID0gbnVsbCwgY2xpcEV4dGVudCA9IG51bGwsIHN0cmVhbTtcbiAgICBmdW5jdGlvbiBwcm9qZWN0aW9uKHBvaW50KSB7XG4gICAgICBwb2ludCA9IHByb2plY3RSb3RhdGUocG9pbnRbMF0gKiBkM19yYWRpYW5zLCBwb2ludFsxXSAqIGQzX3JhZGlhbnMpO1xuICAgICAgcmV0dXJuIFsgcG9pbnRbMF0gKiBrICsgzrR4LCDOtHkgLSBwb2ludFsxXSAqIGsgXTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaW52ZXJ0KHBvaW50KSB7XG4gICAgICBwb2ludCA9IHByb2plY3RSb3RhdGUuaW52ZXJ0KChwb2ludFswXSAtIM60eCkgLyBrLCAozrR5IC0gcG9pbnRbMV0pIC8gayk7XG4gICAgICByZXR1cm4gcG9pbnQgJiYgWyBwb2ludFswXSAqIGQzX2RlZ3JlZXMsIHBvaW50WzFdICogZDNfZGVncmVlcyBdO1xuICAgIH1cbiAgICBwcm9qZWN0aW9uLnN0cmVhbSA9IGZ1bmN0aW9uKG91dHB1dCkge1xuICAgICAgaWYgKHN0cmVhbSkgc3RyZWFtLnZhbGlkID0gZmFsc2U7XG4gICAgICBzdHJlYW0gPSBkM19nZW9fcHJvamVjdGlvblJhZGlhbnNSb3RhdGUocm90YXRlLCBwcmVjbGlwKHByb2plY3RSZXNhbXBsZShwb3N0Y2xpcChvdXRwdXQpKSkpO1xuICAgICAgc3RyZWFtLnZhbGlkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBzdHJlYW07XG4gICAgfTtcbiAgICBwcm9qZWN0aW9uLmNsaXBBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGNsaXBBbmdsZTtcbiAgICAgIHByZWNsaXAgPSBfID09IG51bGwgPyAoY2xpcEFuZ2xlID0gXywgZDNfZ2VvX2NsaXBBbnRpbWVyaWRpYW4pIDogZDNfZ2VvX2NsaXBDaXJjbGUoKGNsaXBBbmdsZSA9ICtfKSAqIGQzX3JhZGlhbnMpO1xuICAgICAgcmV0dXJuIGludmFsaWRhdGUoKTtcbiAgICB9O1xuICAgIHByb2plY3Rpb24uY2xpcEV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGNsaXBFeHRlbnQ7XG4gICAgICBjbGlwRXh0ZW50ID0gXztcbiAgICAgIHBvc3RjbGlwID0gXyA9PSBudWxsID8gZDNfaWRlbnRpdHkgOiBkM19nZW9fY2xpcFZpZXcoX1swXVswXSwgX1swXVsxXSwgX1sxXVswXSwgX1sxXVsxXSk7XG4gICAgICByZXR1cm4gaW52YWxpZGF0ZSgpO1xuICAgIH07XG4gICAgcHJvamVjdGlvbi5zY2FsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGs7XG4gICAgICBrID0gK187XG4gICAgICByZXR1cm4gcmVzZXQoKTtcbiAgICB9O1xuICAgIHByb2plY3Rpb24udHJhbnNsYXRlID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gWyB4LCB5IF07XG4gICAgICB4ID0gK19bMF07XG4gICAgICB5ID0gK19bMV07XG4gICAgICByZXR1cm4gcmVzZXQoKTtcbiAgICB9O1xuICAgIHByb2plY3Rpb24uY2VudGVyID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gWyDOuyAqIGQzX2RlZ3JlZXMsIM+GICogZDNfZGVncmVlcyBdO1xuICAgICAgzrsgPSBfWzBdICUgMzYwICogZDNfcmFkaWFucztcbiAgICAgIM+GID0gX1sxXSAlIDM2MCAqIGQzX3JhZGlhbnM7XG4gICAgICByZXR1cm4gcmVzZXQoKTtcbiAgICB9O1xuICAgIHByb2plY3Rpb24ucm90YXRlID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gWyDOtM67ICogZDNfZGVncmVlcywgzrTPhiAqIGQzX2RlZ3JlZXMsIM60zrMgKiBkM19kZWdyZWVzIF07XG4gICAgICDOtM67ID0gX1swXSAlIDM2MCAqIGQzX3JhZGlhbnM7XG4gICAgICDOtM+GID0gX1sxXSAlIDM2MCAqIGQzX3JhZGlhbnM7XG4gICAgICDOtM6zID0gXy5sZW5ndGggPiAyID8gX1syXSAlIDM2MCAqIGQzX3JhZGlhbnMgOiAwO1xuICAgICAgcmV0dXJuIHJlc2V0KCk7XG4gICAgfTtcbiAgICBkMy5yZWJpbmQocHJvamVjdGlvbiwgcHJvamVjdFJlc2FtcGxlLCBcInByZWNpc2lvblwiKTtcbiAgICBmdW5jdGlvbiByZXNldCgpIHtcbiAgICAgIHByb2plY3RSb3RhdGUgPSBkM19nZW9fY29tcG9zZShyb3RhdGUgPSBkM19nZW9fcm90YXRpb24ozrTOuywgzrTPhiwgzrTOsyksIHByb2plY3QpO1xuICAgICAgdmFyIGNlbnRlciA9IHByb2plY3QozrssIM+GKTtcbiAgICAgIM60eCA9IHggLSBjZW50ZXJbMF0gKiBrO1xuICAgICAgzrR5ID0geSArIGNlbnRlclsxXSAqIGs7XG4gICAgICByZXR1cm4gaW52YWxpZGF0ZSgpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpbnZhbGlkYXRlKCkge1xuICAgICAgaWYgKHN0cmVhbSkge1xuICAgICAgICBzdHJlYW0udmFsaWQgPSBmYWxzZTtcbiAgICAgICAgc3RyZWFtID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcm9qZWN0aW9uO1xuICAgIH1cbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBwcm9qZWN0ID0gcHJvamVjdEF0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICBwcm9qZWN0aW9uLmludmVydCA9IHByb2plY3QuaW52ZXJ0ICYmIGludmVydDtcbiAgICAgIHJldHVybiByZXNldCgpO1xuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3Byb2plY3Rpb25SYWRpYW5zUm90YXRlKHJvdGF0ZSwgc3RyZWFtKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgICAgIHkgPSByb3RhdGUoeCAqIGQzX3JhZGlhbnMsIHkgKiBkM19yYWRpYW5zKSwgeCA9IHlbMF07XG4gICAgICAgIHN0cmVhbS5wb2ludCh4ID4gz4AgPyB4IC0gMiAqIM+AIDogeCA8IC3PgCA/IHggKyAyICogz4AgOiB4LCB5WzFdKTtcbiAgICAgIH0sXG4gICAgICBzcGhlcmU6IGZ1bmN0aW9uKCkge1xuICAgICAgICBzdHJlYW0uc3BoZXJlKCk7XG4gICAgICB9LFxuICAgICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgfSxcbiAgICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgfSxcbiAgICAgIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHN0cmVhbS5wb2x5Z29uU3RhcnQoKTtcbiAgICAgIH0sXG4gICAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHtcbiAgICAgICAgc3RyZWFtLnBvbHlnb25FbmQoKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19lcXVpcmVjdGFuZ3VsYXIozrssIM+GKSB7XG4gICAgcmV0dXJuIFsgzrssIM+GIF07XG4gIH1cbiAgKGQzLmdlby5lcXVpcmVjdGFuZ3VsYXIgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfZ2VvX3Byb2plY3Rpb24oZDNfZ2VvX2VxdWlyZWN0YW5ndWxhcik7XG4gIH0pLnJhdyA9IGQzX2dlb19lcXVpcmVjdGFuZ3VsYXIuaW52ZXJ0ID0gZDNfZ2VvX2VxdWlyZWN0YW5ndWxhcjtcbiAgZDMuZ2VvLnJvdGF0aW9uID0gZnVuY3Rpb24ocm90YXRlKSB7XG4gICAgcm90YXRlID0gZDNfZ2VvX3JvdGF0aW9uKHJvdGF0ZVswXSAlIDM2MCAqIGQzX3JhZGlhbnMsIHJvdGF0ZVsxXSAqIGQzX3JhZGlhbnMsIHJvdGF0ZS5sZW5ndGggPiAyID8gcm90YXRlWzJdICogZDNfcmFkaWFucyA6IDApO1xuICAgIGZ1bmN0aW9uIGZvcndhcmQoY29vcmRpbmF0ZXMpIHtcbiAgICAgIGNvb3JkaW5hdGVzID0gcm90YXRlKGNvb3JkaW5hdGVzWzBdICogZDNfcmFkaWFucywgY29vcmRpbmF0ZXNbMV0gKiBkM19yYWRpYW5zKTtcbiAgICAgIHJldHVybiBjb29yZGluYXRlc1swXSAqPSBkM19kZWdyZWVzLCBjb29yZGluYXRlc1sxXSAqPSBkM19kZWdyZWVzLCBjb29yZGluYXRlcztcbiAgICB9XG4gICAgZm9yd2FyZC5pbnZlcnQgPSBmdW5jdGlvbihjb29yZGluYXRlcykge1xuICAgICAgY29vcmRpbmF0ZXMgPSByb3RhdGUuaW52ZXJ0KGNvb3JkaW5hdGVzWzBdICogZDNfcmFkaWFucywgY29vcmRpbmF0ZXNbMV0gKiBkM19yYWRpYW5zKTtcbiAgICAgIHJldHVybiBjb29yZGluYXRlc1swXSAqPSBkM19kZWdyZWVzLCBjb29yZGluYXRlc1sxXSAqPSBkM19kZWdyZWVzLCBjb29yZGluYXRlcztcbiAgICB9O1xuICAgIHJldHVybiBmb3J3YXJkO1xuICB9O1xuICBmdW5jdGlvbiBkM19nZW9fcm90YXRpb24ozrTOuywgzrTPhiwgzrTOsykge1xuICAgIHJldHVybiDOtM67ID8gzrTPhiB8fCDOtM6zID8gZDNfZ2VvX2NvbXBvc2UoZDNfZ2VvX3JvdGF0aW9uzrsozrTOuyksIGQzX2dlb19yb3RhdGlvbs+GzrMozrTPhiwgzrTOsykpIDogZDNfZ2VvX3JvdGF0aW9uzrsozrTOuykgOiDOtM+GIHx8IM60zrMgPyBkM19nZW9fcm90YXRpb27Phs6zKM60z4YsIM60zrMpIDogZDNfZ2VvX2VxdWlyZWN0YW5ndWxhcjtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fZm9yd2FyZFJvdGF0aW9uzrsozrTOuykge1xuICAgIHJldHVybiBmdW5jdGlvbijOuywgz4YpIHtcbiAgICAgIHJldHVybiDOuyArPSDOtM67LCBbIM67ID4gz4AgPyDOuyAtIDIgKiDPgCA6IM67IDwgLc+AID8gzrsgKyAyICogz4AgOiDOuywgz4YgXTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19yb3RhdGlvbs67KM60zrspIHtcbiAgICB2YXIgcm90YXRpb24gPSBkM19nZW9fZm9yd2FyZFJvdGF0aW9uzrsozrTOuyk7XG4gICAgcm90YXRpb24uaW52ZXJ0ID0gZDNfZ2VvX2ZvcndhcmRSb3RhdGlvbs67KC3OtM67KTtcbiAgICByZXR1cm4gcm90YXRpb247XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX3JvdGF0aW9uz4bOsyjOtM+GLCDOtM6zKSB7XG4gICAgdmFyIGNvc860z4YgPSBNYXRoLmNvcyjOtM+GKSwgc2luzrTPhiA9IE1hdGguc2luKM60z4YpLCBjb3POtM6zID0gTWF0aC5jb3MozrTOsyksIHNpbs60zrMgPSBNYXRoLnNpbijOtM6zKTtcbiAgICBmdW5jdGlvbiByb3RhdGlvbijOuywgz4YpIHtcbiAgICAgIHZhciBjb3PPhiA9IE1hdGguY29zKM+GKSwgeCA9IE1hdGguY29zKM67KSAqIGNvc8+GLCB5ID0gTWF0aC5zaW4ozrspICogY29zz4YsIHogPSBNYXRoLnNpbijPhiksIGsgPSB6ICogY29zzrTPhiArIHggKiBzaW7OtM+GO1xuICAgICAgcmV0dXJuIFsgTWF0aC5hdGFuMih5ICogY29zzrTOsyAtIGsgKiBzaW7OtM6zLCB4ICogY29zzrTPhiAtIHogKiBzaW7OtM+GKSwgZDNfYXNpbihrICogY29zzrTOsyArIHkgKiBzaW7OtM6zKSBdO1xuICAgIH1cbiAgICByb3RhdGlvbi5pbnZlcnQgPSBmdW5jdGlvbijOuywgz4YpIHtcbiAgICAgIHZhciBjb3PPhiA9IE1hdGguY29zKM+GKSwgeCA9IE1hdGguY29zKM67KSAqIGNvc8+GLCB5ID0gTWF0aC5zaW4ozrspICogY29zz4YsIHogPSBNYXRoLnNpbijPhiksIGsgPSB6ICogY29zzrTOsyAtIHkgKiBzaW7OtM6zO1xuICAgICAgcmV0dXJuIFsgTWF0aC5hdGFuMih5ICogY29zzrTOsyArIHogKiBzaW7OtM6zLCB4ICogY29zzrTPhiArIGsgKiBzaW7OtM+GKSwgZDNfYXNpbihrICogY29zzrTPhiAtIHggKiBzaW7OtM+GKSBdO1xuICAgIH07XG4gICAgcmV0dXJuIHJvdGF0aW9uO1xuICB9XG4gIGQzLmdlby5jaXJjbGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgb3JpZ2luID0gWyAwLCAwIF0sIGFuZ2xlLCBwcmVjaXNpb24gPSA2LCBpbnRlcnBvbGF0ZTtcbiAgICBmdW5jdGlvbiBjaXJjbGUoKSB7XG4gICAgICB2YXIgY2VudGVyID0gdHlwZW9mIG9yaWdpbiA9PT0gXCJmdW5jdGlvblwiID8gb3JpZ2luLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBvcmlnaW4sIHJvdGF0ZSA9IGQzX2dlb19yb3RhdGlvbigtY2VudGVyWzBdICogZDNfcmFkaWFucywgLWNlbnRlclsxXSAqIGQzX3JhZGlhbnMsIDApLmludmVydCwgcmluZyA9IFtdO1xuICAgICAgaW50ZXJwb2xhdGUobnVsbCwgbnVsbCwgMSwge1xuICAgICAgICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgICAgICAgIHJpbmcucHVzaCh4ID0gcm90YXRlKHgsIHkpKTtcbiAgICAgICAgICB4WzBdICo9IGQzX2RlZ3JlZXMsIHhbMV0gKj0gZDNfZGVncmVlcztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcIlBvbHlnb25cIixcbiAgICAgICAgY29vcmRpbmF0ZXM6IFsgcmluZyBdXG4gICAgICB9O1xuICAgIH1cbiAgICBjaXJjbGUub3JpZ2luID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gb3JpZ2luO1xuICAgICAgb3JpZ2luID0geDtcbiAgICAgIHJldHVybiBjaXJjbGU7XG4gICAgfTtcbiAgICBjaXJjbGUuYW5nbGUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBhbmdsZTtcbiAgICAgIGludGVycG9sYXRlID0gZDNfZ2VvX2NpcmNsZUludGVycG9sYXRlKChhbmdsZSA9ICt4KSAqIGQzX3JhZGlhbnMsIHByZWNpc2lvbiAqIGQzX3JhZGlhbnMpO1xuICAgICAgcmV0dXJuIGNpcmNsZTtcbiAgICB9O1xuICAgIGNpcmNsZS5wcmVjaXNpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBwcmVjaXNpb247XG4gICAgICBpbnRlcnBvbGF0ZSA9IGQzX2dlb19jaXJjbGVJbnRlcnBvbGF0ZShhbmdsZSAqIGQzX3JhZGlhbnMsIChwcmVjaXNpb24gPSArXykgKiBkM19yYWRpYW5zKTtcbiAgICAgIHJldHVybiBjaXJjbGU7XG4gICAgfTtcbiAgICByZXR1cm4gY2lyY2xlLmFuZ2xlKDkwKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfZ2VvX2NpcmNsZUludGVycG9sYXRlKHJhZGl1cywgcHJlY2lzaW9uKSB7XG4gICAgdmFyIGNyID0gTWF0aC5jb3MocmFkaXVzKSwgc3IgPSBNYXRoLnNpbihyYWRpdXMpO1xuICAgIHJldHVybiBmdW5jdGlvbihmcm9tLCB0bywgZGlyZWN0aW9uLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKGZyb20gIT0gbnVsbCkge1xuICAgICAgICBmcm9tID0gZDNfZ2VvX2NpcmNsZUFuZ2xlKGNyLCBmcm9tKTtcbiAgICAgICAgdG8gPSBkM19nZW9fY2lyY2xlQW5nbGUoY3IsIHRvKTtcbiAgICAgICAgaWYgKGRpcmVjdGlvbiA+IDAgPyBmcm9tIDwgdG8gOiBmcm9tID4gdG8pIGZyb20gKz0gZGlyZWN0aW9uICogMiAqIM+AO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZnJvbSA9IHJhZGl1cyArIGRpcmVjdGlvbiAqIDIgKiDPgDtcbiAgICAgICAgdG8gPSByYWRpdXM7XG4gICAgICB9XG4gICAgICB2YXIgcG9pbnQ7XG4gICAgICBmb3IgKHZhciBzdGVwID0gZGlyZWN0aW9uICogcHJlY2lzaW9uLCB0ID0gZnJvbTsgZGlyZWN0aW9uID4gMCA/IHQgPiB0byA6IHQgPCB0bzsgdCAtPSBzdGVwKSB7XG4gICAgICAgIGxpc3RlbmVyLnBvaW50KChwb2ludCA9IGQzX2dlb19zcGhlcmljYWwoWyBjciwgLXNyICogTWF0aC5jb3ModCksIC1zciAqIE1hdGguc2luKHQpIF0pKVswXSwgcG9pbnRbMV0pO1xuICAgICAgfVxuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvX2NpcmNsZUFuZ2xlKGNyLCBwb2ludCkge1xuICAgIHZhciBhID0gZDNfZ2VvX2NhcnRlc2lhbihwb2ludCk7XG4gICAgYVswXSAtPSBjcjtcbiAgICBkM19nZW9fY2FydGVzaWFuTm9ybWFsaXplKGEpO1xuICAgIHZhciBhbmdsZSA9IGQzX2Fjb3MoLWFbMV0pO1xuICAgIHJldHVybiAoKC1hWzJdIDwgMCA/IC1hbmdsZSA6IGFuZ2xlKSArIDIgKiBNYXRoLlBJIC0gzrUpICUgKDIgKiBNYXRoLlBJKTtcbiAgfVxuICBkMy5nZW8uZGlzdGFuY2UgPSBmdW5jdGlvbihhLCBiKSB7XG4gICAgdmFyIM6UzrsgPSAoYlswXSAtIGFbMF0pICogZDNfcmFkaWFucywgz4YwID0gYVsxXSAqIGQzX3JhZGlhbnMsIM+GMSA9IGJbMV0gKiBkM19yYWRpYW5zLCBzaW7OlM67ID0gTWF0aC5zaW4ozpTOuyksIGNvc86UzrsgPSBNYXRoLmNvcyjOlM67KSwgc2luz4YwID0gTWF0aC5zaW4oz4YwKSwgY29zz4YwID0gTWF0aC5jb3Moz4YwKSwgc2luz4YxID0gTWF0aC5zaW4oz4YxKSwgY29zz4YxID0gTWF0aC5jb3Moz4YxKSwgdDtcbiAgICByZXR1cm4gTWF0aC5hdGFuMihNYXRoLnNxcnQoKHQgPSBjb3PPhjEgKiBzaW7OlM67KSAqIHQgKyAodCA9IGNvc8+GMCAqIHNpbs+GMSAtIHNpbs+GMCAqIGNvc8+GMSAqIGNvc86UzrspICogdCksIHNpbs+GMCAqIHNpbs+GMSArIGNvc8+GMCAqIGNvc8+GMSAqIGNvc86UzrspO1xuICB9O1xuICBkMy5nZW8uZ3JhdGljdWxlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHgxLCB4MCwgWDEsIFgwLCB5MSwgeTAsIFkxLCBZMCwgZHggPSAxMCwgZHkgPSBkeCwgRFggPSA5MCwgRFkgPSAzNjAsIHgsIHksIFgsIFksIHByZWNpc2lvbiA9IDIuNTtcbiAgICBmdW5jdGlvbiBncmF0aWN1bGUoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcIk11bHRpTGluZVN0cmluZ1wiLFxuICAgICAgICBjb29yZGluYXRlczogbGluZXMoKVxuICAgICAgfTtcbiAgICB9XG4gICAgZnVuY3Rpb24gbGluZXMoKSB7XG4gICAgICByZXR1cm4gZDMucmFuZ2UoTWF0aC5jZWlsKFgwIC8gRFgpICogRFgsIFgxLCBEWCkubWFwKFgpLmNvbmNhdChkMy5yYW5nZShNYXRoLmNlaWwoWTAgLyBEWSkgKiBEWSwgWTEsIERZKS5tYXAoWSkpLmNvbmNhdChkMy5yYW5nZShNYXRoLmNlaWwoeDAgLyBkeCkgKiBkeCwgeDEsIGR4KS5maWx0ZXIoZnVuY3Rpb24oeCkge1xuICAgICAgICByZXR1cm4gTWF0aC5hYnMoeCAlIERYKSA+IM61O1xuICAgICAgfSkubWFwKHgpKS5jb25jYXQoZDMucmFuZ2UoTWF0aC5jZWlsKHkwIC8gZHkpICogZHksIHkxLCBkeSkuZmlsdGVyKGZ1bmN0aW9uKHkpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzKHkgJSBEWSkgPiDOtTtcbiAgICAgIH0pLm1hcCh5KSk7XG4gICAgfVxuICAgIGdyYXRpY3VsZS5saW5lcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGxpbmVzKCkubWFwKGZ1bmN0aW9uKGNvb3JkaW5hdGVzKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogXCJMaW5lU3RyaW5nXCIsXG4gICAgICAgICAgY29vcmRpbmF0ZXM6IGNvb3JkaW5hdGVzXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9O1xuICAgIGdyYXRpY3VsZS5vdXRsaW5lID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcIlBvbHlnb25cIixcbiAgICAgICAgY29vcmRpbmF0ZXM6IFsgWChYMCkuY29uY2F0KFkoWTEpLnNsaWNlKDEpLCBYKFgxKS5yZXZlcnNlKCkuc2xpY2UoMSksIFkoWTApLnJldmVyc2UoKS5zbGljZSgxKSkgXVxuICAgICAgfTtcbiAgICB9O1xuICAgIGdyYXRpY3VsZS5leHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBncmF0aWN1bGUubWlub3JFeHRlbnQoKTtcbiAgICAgIHJldHVybiBncmF0aWN1bGUubWFqb3JFeHRlbnQoXykubWlub3JFeHRlbnQoXyk7XG4gICAgfTtcbiAgICBncmF0aWN1bGUubWFqb3JFeHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBbIFsgWDAsIFkwIF0sIFsgWDEsIFkxIF0gXTtcbiAgICAgIFgwID0gK19bMF1bMF0sIFgxID0gK19bMV1bMF07XG4gICAgICBZMCA9ICtfWzBdWzFdLCBZMSA9ICtfWzFdWzFdO1xuICAgICAgaWYgKFgwID4gWDEpIF8gPSBYMCwgWDAgPSBYMSwgWDEgPSBfO1xuICAgICAgaWYgKFkwID4gWTEpIF8gPSBZMCwgWTAgPSBZMSwgWTEgPSBfO1xuICAgICAgcmV0dXJuIGdyYXRpY3VsZS5wcmVjaXNpb24ocHJlY2lzaW9uKTtcbiAgICB9O1xuICAgIGdyYXRpY3VsZS5taW5vckV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFsgWyB4MCwgeTAgXSwgWyB4MSwgeTEgXSBdO1xuICAgICAgeDAgPSArX1swXVswXSwgeDEgPSArX1sxXVswXTtcbiAgICAgIHkwID0gK19bMF1bMV0sIHkxID0gK19bMV1bMV07XG4gICAgICBpZiAoeDAgPiB4MSkgXyA9IHgwLCB4MCA9IHgxLCB4MSA9IF87XG4gICAgICBpZiAoeTAgPiB5MSkgXyA9IHkwLCB5MCA9IHkxLCB5MSA9IF87XG4gICAgICByZXR1cm4gZ3JhdGljdWxlLnByZWNpc2lvbihwcmVjaXNpb24pO1xuICAgIH07XG4gICAgZ3JhdGljdWxlLnN0ZXAgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBncmF0aWN1bGUubWlub3JTdGVwKCk7XG4gICAgICByZXR1cm4gZ3JhdGljdWxlLm1ham9yU3RlcChfKS5taW5vclN0ZXAoXyk7XG4gICAgfTtcbiAgICBncmF0aWN1bGUubWFqb3JTdGVwID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gWyBEWCwgRFkgXTtcbiAgICAgIERYID0gK19bMF0sIERZID0gK19bMV07XG4gICAgICByZXR1cm4gZ3JhdGljdWxlO1xuICAgIH07XG4gICAgZ3JhdGljdWxlLm1pbm9yU3RlcCA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFsgZHgsIGR5IF07XG4gICAgICBkeCA9ICtfWzBdLCBkeSA9ICtfWzFdO1xuICAgICAgcmV0dXJuIGdyYXRpY3VsZTtcbiAgICB9O1xuICAgIGdyYXRpY3VsZS5wcmVjaXNpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBwcmVjaXNpb247XG4gICAgICBwcmVjaXNpb24gPSArXztcbiAgICAgIHggPSBkM19nZW9fZ3JhdGljdWxlWCh5MCwgeTEsIDkwKTtcbiAgICAgIHkgPSBkM19nZW9fZ3JhdGljdWxlWSh4MCwgeDEsIHByZWNpc2lvbik7XG4gICAgICBYID0gZDNfZ2VvX2dyYXRpY3VsZVgoWTAsIFkxLCA5MCk7XG4gICAgICBZID0gZDNfZ2VvX2dyYXRpY3VsZVkoWDAsIFgxLCBwcmVjaXNpb24pO1xuICAgICAgcmV0dXJuIGdyYXRpY3VsZTtcbiAgICB9O1xuICAgIHJldHVybiBncmF0aWN1bGUubWFqb3JFeHRlbnQoWyBbIC0xODAsIC05MCArIM61IF0sIFsgMTgwLCA5MCAtIM61IF0gXSkubWlub3JFeHRlbnQoWyBbIC0xODAsIC04MCAtIM61IF0sIFsgMTgwLCA4MCArIM61IF0gXSk7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2dlb19ncmF0aWN1bGVYKHkwLCB5MSwgZHkpIHtcbiAgICB2YXIgeSA9IGQzLnJhbmdlKHkwLCB5MSAtIM61LCBkeSkuY29uY2F0KHkxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHkubWFwKGZ1bmN0aW9uKHkpIHtcbiAgICAgICAgcmV0dXJuIFsgeCwgeSBdO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9fZ3JhdGljdWxlWSh4MCwgeDEsIGR4KSB7XG4gICAgdmFyIHggPSBkMy5yYW5nZSh4MCwgeDEgLSDOtSwgZHgpLmNvbmNhdCh4MSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHkpIHtcbiAgICAgIHJldHVybiB4Lm1hcChmdW5jdGlvbih4KSB7XG4gICAgICAgIHJldHVybiBbIHgsIHkgXTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZDNfc291cmNlKGQpIHtcbiAgICByZXR1cm4gZC5zb3VyY2U7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGFyZ2V0KGQpIHtcbiAgICByZXR1cm4gZC50YXJnZXQ7XG4gIH1cbiAgZDMuZ2VvLmdyZWF0QXJjID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNvdXJjZSA9IGQzX3NvdXJjZSwgc291cmNlXywgdGFyZ2V0ID0gZDNfdGFyZ2V0LCB0YXJnZXRfO1xuICAgIGZ1bmN0aW9uIGdyZWF0QXJjKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogXCJMaW5lU3RyaW5nXCIsXG4gICAgICAgIGNvb3JkaW5hdGVzOiBbIHNvdXJjZV8gfHwgc291cmNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHRhcmdldF8gfHwgdGFyZ2V0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgXVxuICAgICAgfTtcbiAgICB9XG4gICAgZ3JlYXRBcmMuZGlzdGFuY2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkMy5nZW8uZGlzdGFuY2Uoc291cmNlXyB8fCBzb3VyY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKSwgdGFyZ2V0XyB8fCB0YXJnZXQuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gICAgfTtcbiAgICBncmVhdEFyYy5zb3VyY2UgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzb3VyY2U7XG4gICAgICBzb3VyY2UgPSBfLCBzb3VyY2VfID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IG51bGwgOiBfO1xuICAgICAgcmV0dXJuIGdyZWF0QXJjO1xuICAgIH07XG4gICAgZ3JlYXRBcmMudGFyZ2V0ID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGFyZ2V0O1xuICAgICAgdGFyZ2V0ID0gXywgdGFyZ2V0XyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBudWxsIDogXztcbiAgICAgIHJldHVybiBncmVhdEFyYztcbiAgICB9O1xuICAgIGdyZWF0QXJjLnByZWNpc2lvbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyBncmVhdEFyYyA6IDA7XG4gICAgfTtcbiAgICByZXR1cm4gZ3JlYXRBcmM7XG4gIH07XG4gIGQzLmdlby5pbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0KSB7XG4gICAgcmV0dXJuIGQzX2dlb19pbnRlcnBvbGF0ZShzb3VyY2VbMF0gKiBkM19yYWRpYW5zLCBzb3VyY2VbMV0gKiBkM19yYWRpYW5zLCB0YXJnZXRbMF0gKiBkM19yYWRpYW5zLCB0YXJnZXRbMV0gKiBkM19yYWRpYW5zKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfZ2VvX2ludGVycG9sYXRlKHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgdmFyIGN5MCA9IE1hdGguY29zKHkwKSwgc3kwID0gTWF0aC5zaW4oeTApLCBjeTEgPSBNYXRoLmNvcyh5MSksIHN5MSA9IE1hdGguc2luKHkxKSwga3gwID0gY3kwICogTWF0aC5jb3MoeDApLCBreTAgPSBjeTAgKiBNYXRoLnNpbih4MCksIGt4MSA9IGN5MSAqIE1hdGguY29zKHgxKSwga3kxID0gY3kxICogTWF0aC5zaW4oeDEpLCBkID0gMiAqIE1hdGguYXNpbihNYXRoLnNxcnQoZDNfaGF2ZXJzaW4oeTEgLSB5MCkgKyBjeTAgKiBjeTEgKiBkM19oYXZlcnNpbih4MSAtIHgwKSkpLCBrID0gMSAvIE1hdGguc2luKGQpO1xuICAgIHZhciBpbnRlcnBvbGF0ZSA9IGQgPyBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgQiA9IE1hdGguc2luKHQgKj0gZCkgKiBrLCBBID0gTWF0aC5zaW4oZCAtIHQpICogaywgeCA9IEEgKiBreDAgKyBCICoga3gxLCB5ID0gQSAqIGt5MCArIEIgKiBreTEsIHogPSBBICogc3kwICsgQiAqIHN5MTtcbiAgICAgIHJldHVybiBbIE1hdGguYXRhbjIoeSwgeCkgKiBkM19kZWdyZWVzLCBNYXRoLmF0YW4yKHosIE1hdGguc3FydCh4ICogeCArIHkgKiB5KSkgKiBkM19kZWdyZWVzIF07XG4gICAgfSA6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIFsgeDAgKiBkM19kZWdyZWVzLCB5MCAqIGQzX2RlZ3JlZXMgXTtcbiAgICB9O1xuICAgIGludGVycG9sYXRlLmRpc3RhbmNlID0gZDtcbiAgICByZXR1cm4gaW50ZXJwb2xhdGU7XG4gIH1cbiAgZDMuZ2VvLmxlbmd0aCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGQzX2dlb19sZW5ndGhTdW0gPSAwO1xuICAgIGQzLmdlby5zdHJlYW0ob2JqZWN0LCBkM19nZW9fbGVuZ3RoKTtcbiAgICByZXR1cm4gZDNfZ2VvX2xlbmd0aFN1bTtcbiAgfTtcbiAgdmFyIGQzX2dlb19sZW5ndGhTdW07XG4gIHZhciBkM19nZW9fbGVuZ3RoID0ge1xuICAgIHNwaGVyZTogZDNfbm9vcCxcbiAgICBwb2ludDogZDNfbm9vcCxcbiAgICBsaW5lU3RhcnQ6IGQzX2dlb19sZW5ndGhMaW5lU3RhcnQsXG4gICAgbGluZUVuZDogZDNfbm9vcCxcbiAgICBwb2x5Z29uU3RhcnQ6IGQzX25vb3AsXG4gICAgcG9seWdvbkVuZDogZDNfbm9vcFxuICB9O1xuICBmdW5jdGlvbiBkM19nZW9fbGVuZ3RoTGluZVN0YXJ0KCkge1xuICAgIHZhciDOuzAsIHNpbs+GMCwgY29zz4YwO1xuICAgIGQzX2dlb19sZW5ndGgucG9pbnQgPSBmdW5jdGlvbijOuywgz4YpIHtcbiAgICAgIM67MCA9IM67ICogZDNfcmFkaWFucywgc2luz4YwID0gTWF0aC5zaW4oz4YgKj0gZDNfcmFkaWFucyksIGNvc8+GMCA9IE1hdGguY29zKM+GKTtcbiAgICAgIGQzX2dlb19sZW5ndGgucG9pbnQgPSBuZXh0UG9pbnQ7XG4gICAgfTtcbiAgICBkM19nZW9fbGVuZ3RoLmxpbmVFbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGQzX2dlb19sZW5ndGgucG9pbnQgPSBkM19nZW9fbGVuZ3RoLmxpbmVFbmQgPSBkM19ub29wO1xuICAgIH07XG4gICAgZnVuY3Rpb24gbmV4dFBvaW50KM67LCDPhikge1xuICAgICAgdmFyIHNpbs+GID0gTWF0aC5zaW4oz4YgKj0gZDNfcmFkaWFucyksIGNvc8+GID0gTWF0aC5jb3Moz4YpLCB0ID0gTWF0aC5hYnMoKM67ICo9IGQzX3JhZGlhbnMpIC0gzrswKSwgY29zzpTOuyA9IE1hdGguY29zKHQpO1xuICAgICAgZDNfZ2VvX2xlbmd0aFN1bSArPSBNYXRoLmF0YW4yKE1hdGguc3FydCgodCA9IGNvc8+GICogTWF0aC5zaW4odCkpICogdCArICh0ID0gY29zz4YwICogc2luz4YgLSBzaW7PhjAgKiBjb3PPhiAqIGNvc86UzrspICogdCksIHNpbs+GMCAqIHNpbs+GICsgY29zz4YwICogY29zz4YgKiBjb3POlM67KTtcbiAgICAgIM67MCA9IM67LCBzaW7PhjAgPSBzaW7PhiwgY29zz4YwID0gY29zz4Y7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGQzX2dlb19hemltdXRoYWwoc2NhbGUsIGFuZ2xlKSB7XG4gICAgZnVuY3Rpb24gYXppbXV0aGFsKM67LCDPhikge1xuICAgICAgdmFyIGNvc867ID0gTWF0aC5jb3MozrspLCBjb3PPhiA9IE1hdGguY29zKM+GKSwgayA9IHNjYWxlKGNvc867ICogY29zz4YpO1xuICAgICAgcmV0dXJuIFsgayAqIGNvc8+GICogTWF0aC5zaW4ozrspLCBrICogTWF0aC5zaW4oz4YpIF07XG4gICAgfVxuICAgIGF6aW11dGhhbC5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgICB2YXIgz4EgPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSksIGMgPSBhbmdsZSjPgSksIHNpbmMgPSBNYXRoLnNpbihjKSwgY29zYyA9IE1hdGguY29zKGMpO1xuICAgICAgcmV0dXJuIFsgTWF0aC5hdGFuMih4ICogc2luYywgz4EgKiBjb3NjKSwgTWF0aC5hc2luKM+BICYmIHkgKiBzaW5jIC8gz4EpIF07XG4gICAgfTtcbiAgICByZXR1cm4gYXppbXV0aGFsO1xuICB9XG4gIHZhciBkM19nZW9fYXppbXV0aGFsRXF1YWxBcmVhID0gZDNfZ2VvX2F6aW11dGhhbChmdW5jdGlvbihjb3POu2Nvc8+GKSB7XG4gICAgcmV0dXJuIE1hdGguc3FydCgyIC8gKDEgKyBjb3POu2Nvc8+GKSk7XG4gIH0sIGZ1bmN0aW9uKM+BKSB7XG4gICAgcmV0dXJuIDIgKiBNYXRoLmFzaW4oz4EgLyAyKTtcbiAgfSk7XG4gIChkMy5nZW8uYXppbXV0aGFsRXF1YWxBcmVhID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX2dlb19wcm9qZWN0aW9uKGQzX2dlb19hemltdXRoYWxFcXVhbEFyZWEpO1xuICB9KS5yYXcgPSBkM19nZW9fYXppbXV0aGFsRXF1YWxBcmVhO1xuICB2YXIgZDNfZ2VvX2F6aW11dGhhbEVxdWlkaXN0YW50ID0gZDNfZ2VvX2F6aW11dGhhbChmdW5jdGlvbihjb3POu2Nvc8+GKSB7XG4gICAgdmFyIGMgPSBNYXRoLmFjb3MoY29zzrtjb3PPhik7XG4gICAgcmV0dXJuIGMgJiYgYyAvIE1hdGguc2luKGMpO1xuICB9LCBkM19pZGVudGl0eSk7XG4gIChkMy5nZW8uYXppbXV0aGFsRXF1aWRpc3RhbnQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfZ2VvX3Byb2plY3Rpb24oZDNfZ2VvX2F6aW11dGhhbEVxdWlkaXN0YW50KTtcbiAgfSkucmF3ID0gZDNfZ2VvX2F6aW11dGhhbEVxdWlkaXN0YW50O1xuICBmdW5jdGlvbiBkM19nZW9fY29uaWNDb25mb3JtYWwoz4YwLCDPhjEpIHtcbiAgICB2YXIgY29zz4YwID0gTWF0aC5jb3Moz4YwKSwgdCA9IGZ1bmN0aW9uKM+GKSB7XG4gICAgICByZXR1cm4gTWF0aC50YW4oz4AgLyA0ICsgz4YgLyAyKTtcbiAgICB9LCBuID0gz4YwID09PSDPhjEgPyBNYXRoLnNpbijPhjApIDogTWF0aC5sb2coY29zz4YwIC8gTWF0aC5jb3Moz4YxKSkgLyBNYXRoLmxvZyh0KM+GMSkgLyB0KM+GMCkpLCBGID0gY29zz4YwICogTWF0aC5wb3codCjPhjApLCBuKSAvIG47XG4gICAgaWYgKCFuKSByZXR1cm4gZDNfZ2VvX21lcmNhdG9yO1xuICAgIGZ1bmN0aW9uIGZvcndhcmQozrssIM+GKSB7XG4gICAgICB2YXIgz4EgPSBNYXRoLmFicyhNYXRoLmFicyjPhikgLSDPgCAvIDIpIDwgzrUgPyAwIDogRiAvIE1hdGgucG93KHQoz4YpLCBuKTtcbiAgICAgIHJldHVybiBbIM+BICogTWF0aC5zaW4obiAqIM67KSwgRiAtIM+BICogTWF0aC5jb3MobiAqIM67KSBdO1xuICAgIH1cbiAgICBmb3J3YXJkLmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgIHZhciDPgTBfeSA9IEYgLSB5LCDPgSA9IGQzX3NnbihuKSAqIE1hdGguc3FydCh4ICogeCArIM+BMF95ICogz4EwX3kpO1xuICAgICAgcmV0dXJuIFsgTWF0aC5hdGFuMih4LCDPgTBfeSkgLyBuLCAyICogTWF0aC5hdGFuKE1hdGgucG93KEYgLyDPgSwgMSAvIG4pKSAtIM+AIC8gMiBdO1xuICAgIH07XG4gICAgcmV0dXJuIGZvcndhcmQ7XG4gIH1cbiAgKGQzLmdlby5jb25pY0NvbmZvcm1hbCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19nZW9fY29uaWMoZDNfZ2VvX2NvbmljQ29uZm9ybWFsKTtcbiAgfSkucmF3ID0gZDNfZ2VvX2NvbmljQ29uZm9ybWFsO1xuICBmdW5jdGlvbiBkM19nZW9fY29uaWNFcXVpZGlzdGFudCjPhjAsIM+GMSkge1xuICAgIHZhciBjb3PPhjAgPSBNYXRoLmNvcyjPhjApLCBuID0gz4YwID09PSDPhjEgPyBNYXRoLnNpbijPhjApIDogKGNvc8+GMCAtIE1hdGguY29zKM+GMSkpIC8gKM+GMSAtIM+GMCksIEcgPSBjb3PPhjAgLyBuICsgz4YwO1xuICAgIGlmIChNYXRoLmFicyhuKSA8IM61KSByZXR1cm4gZDNfZ2VvX2VxdWlyZWN0YW5ndWxhcjtcbiAgICBmdW5jdGlvbiBmb3J3YXJkKM67LCDPhikge1xuICAgICAgdmFyIM+BID0gRyAtIM+GO1xuICAgICAgcmV0dXJuIFsgz4EgKiBNYXRoLnNpbihuICogzrspLCBHIC0gz4EgKiBNYXRoLmNvcyhuICogzrspIF07XG4gICAgfVxuICAgIGZvcndhcmQuaW52ZXJ0ID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgdmFyIM+BMF95ID0gRyAtIHk7XG4gICAgICByZXR1cm4gWyBNYXRoLmF0YW4yKHgsIM+BMF95KSAvIG4sIEcgLSBkM19zZ24obikgKiBNYXRoLnNxcnQoeCAqIHggKyDPgTBfeSAqIM+BMF95KSBdO1xuICAgIH07XG4gICAgcmV0dXJuIGZvcndhcmQ7XG4gIH1cbiAgKGQzLmdlby5jb25pY0VxdWlkaXN0YW50ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX2dlb19jb25pYyhkM19nZW9fY29uaWNFcXVpZGlzdGFudCk7XG4gIH0pLnJhdyA9IGQzX2dlb19jb25pY0VxdWlkaXN0YW50O1xuICB2YXIgZDNfZ2VvX2dub21vbmljID0gZDNfZ2VvX2F6aW11dGhhbChmdW5jdGlvbihjb3POu2Nvc8+GKSB7XG4gICAgcmV0dXJuIDEgLyBjb3POu2Nvc8+GO1xuICB9LCBNYXRoLmF0YW4pO1xuICAoZDMuZ2VvLmdub21vbmljID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX2dlb19wcm9qZWN0aW9uKGQzX2dlb19nbm9tb25pYyk7XG4gIH0pLnJhdyA9IGQzX2dlb19nbm9tb25pYztcbiAgZnVuY3Rpb24gZDNfZ2VvX21lcmNhdG9yKM67LCDPhikge1xuICAgIHJldHVybiBbIM67LCBNYXRoLmxvZyhNYXRoLnRhbijPgCAvIDQgKyDPhiAvIDIpKSBdO1xuICB9XG4gIGQzX2dlb19tZXJjYXRvci5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgcmV0dXJuIFsgeCwgMiAqIE1hdGguYXRhbihNYXRoLmV4cCh5KSkgLSDPgCAvIDIgXTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfZ2VvX21lcmNhdG9yUHJvamVjdGlvbihwcm9qZWN0KSB7XG4gICAgdmFyIG0gPSBkM19nZW9fcHJvamVjdGlvbihwcm9qZWN0KSwgc2NhbGUgPSBtLnNjYWxlLCB0cmFuc2xhdGUgPSBtLnRyYW5zbGF0ZSwgY2xpcEV4dGVudCA9IG0uY2xpcEV4dGVudCwgY2xpcEF1dG87XG4gICAgbS5zY2FsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHYgPSBzY2FsZS5hcHBseShtLCBhcmd1bWVudHMpO1xuICAgICAgcmV0dXJuIHYgPT09IG0gPyBjbGlwQXV0byA/IG0uY2xpcEV4dGVudChudWxsKSA6IG0gOiB2O1xuICAgIH07XG4gICAgbS50cmFuc2xhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2ID0gdHJhbnNsYXRlLmFwcGx5KG0sIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdiA9PT0gbSA/IGNsaXBBdXRvID8gbS5jbGlwRXh0ZW50KG51bGwpIDogbSA6IHY7XG4gICAgfTtcbiAgICBtLmNsaXBFeHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgICB2YXIgdiA9IGNsaXBFeHRlbnQuYXBwbHkobSwgYXJndW1lbnRzKTtcbiAgICAgIGlmICh2ID09PSBtKSB7XG4gICAgICAgIGlmIChjbGlwQXV0byA9IF8gPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBrID0gz4AgKiBzY2FsZSgpLCB0ID0gdHJhbnNsYXRlKCk7XG4gICAgICAgICAgY2xpcEV4dGVudChbIFsgdFswXSAtIGssIHRbMV0gLSBrIF0sIFsgdFswXSArIGssIHRbMV0gKyBrIF0gXSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY2xpcEF1dG8pIHtcbiAgICAgICAgdiA9IG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gdjtcbiAgICB9O1xuICAgIHJldHVybiBtLmNsaXBFeHRlbnQobnVsbCk7XG4gIH1cbiAgKGQzLmdlby5tZXJjYXRvciA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19nZW9fbWVyY2F0b3JQcm9qZWN0aW9uKGQzX2dlb19tZXJjYXRvcik7XG4gIH0pLnJhdyA9IGQzX2dlb19tZXJjYXRvcjtcbiAgdmFyIGQzX2dlb19vcnRob2dyYXBoaWMgPSBkM19nZW9fYXppbXV0aGFsKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAxO1xuICB9LCBNYXRoLmFzaW4pO1xuICAoZDMuZ2VvLm9ydGhvZ3JhcGhpYyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19nZW9fcHJvamVjdGlvbihkM19nZW9fb3J0aG9ncmFwaGljKTtcbiAgfSkucmF3ID0gZDNfZ2VvX29ydGhvZ3JhcGhpYztcbiAgdmFyIGQzX2dlb19zdGVyZW9ncmFwaGljID0gZDNfZ2VvX2F6aW11dGhhbChmdW5jdGlvbihjb3POu2Nvc8+GKSB7XG4gICAgcmV0dXJuIDEgLyAoMSArIGNvc867Y29zz4YpO1xuICB9LCBmdW5jdGlvbijPgSkge1xuICAgIHJldHVybiAyICogTWF0aC5hdGFuKM+BKTtcbiAgfSk7XG4gIChkMy5nZW8uc3RlcmVvZ3JhcGhpYyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19nZW9fcHJvamVjdGlvbihkM19nZW9fc3RlcmVvZ3JhcGhpYyk7XG4gIH0pLnJhdyA9IGQzX2dlb19zdGVyZW9ncmFwaGljO1xuICBmdW5jdGlvbiBkM19nZW9fdHJhbnN2ZXJzZU1lcmNhdG9yKM67LCDPhikge1xuICAgIHZhciBCID0gTWF0aC5jb3Moz4YpICogTWF0aC5zaW4ozrspO1xuICAgIHJldHVybiBbIE1hdGgubG9nKCgxICsgQikgLyAoMSAtIEIpKSAvIDIsIE1hdGguYXRhbjIoTWF0aC50YW4oz4YpLCBNYXRoLmNvcyjOuykpIF07XG4gIH1cbiAgZDNfZ2VvX3RyYW5zdmVyc2VNZXJjYXRvci5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgcmV0dXJuIFsgTWF0aC5hdGFuMihkM19zaW5oKHgpLCBNYXRoLmNvcyh5KSksIGQzX2FzaW4oTWF0aC5zaW4oeSkgLyBkM19jb3NoKHgpKSBdO1xuICB9O1xuICAoZDMuZ2VvLnRyYW5zdmVyc2VNZXJjYXRvciA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19nZW9fbWVyY2F0b3JQcm9qZWN0aW9uKGQzX2dlb190cmFuc3ZlcnNlTWVyY2F0b3IpO1xuICB9KS5yYXcgPSBkM19nZW9fdHJhbnN2ZXJzZU1lcmNhdG9yO1xuICBkMy5nZW9tID0ge307XG4gIGQzLnN2ZyA9IHt9O1xuICBmdW5jdGlvbiBkM19zdmdfbGluZShwcm9qZWN0aW9uKSB7XG4gICAgdmFyIHggPSBkM19zdmdfbGluZVgsIHkgPSBkM19zdmdfbGluZVksIGRlZmluZWQgPSBkM190cnVlLCBpbnRlcnBvbGF0ZSA9IGQzX3N2Z19saW5lTGluZWFyLCBpbnRlcnBvbGF0ZUtleSA9IGludGVycG9sYXRlLmtleSwgdGVuc2lvbiA9IC43O1xuICAgIGZ1bmN0aW9uIGxpbmUoZGF0YSkge1xuICAgICAgdmFyIHNlZ21lbnRzID0gW10sIHBvaW50cyA9IFtdLCBpID0gLTEsIG4gPSBkYXRhLmxlbmd0aCwgZCwgZnggPSBkM19mdW5jdG9yKHgpLCBmeSA9IGQzX2Z1bmN0b3IoeSk7XG4gICAgICBmdW5jdGlvbiBzZWdtZW50KCkge1xuICAgICAgICBzZWdtZW50cy5wdXNoKFwiTVwiLCBpbnRlcnBvbGF0ZShwcm9qZWN0aW9uKHBvaW50cyksIHRlbnNpb24pKTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgIGlmIChkZWZpbmVkLmNhbGwodGhpcywgZCA9IGRhdGFbaV0sIGkpKSB7XG4gICAgICAgICAgcG9pbnRzLnB1c2goWyArZnguY2FsbCh0aGlzLCBkLCBpKSwgK2Z5LmNhbGwodGhpcywgZCwgaSkgXSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRzLmxlbmd0aCkge1xuICAgICAgICAgIHNlZ21lbnQoKTtcbiAgICAgICAgICBwb2ludHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHBvaW50cy5sZW5ndGgpIHNlZ21lbnQoKTtcbiAgICAgIHJldHVybiBzZWdtZW50cy5sZW5ndGggPyBzZWdtZW50cy5qb2luKFwiXCIpIDogbnVsbDtcbiAgICB9XG4gICAgbGluZS54ID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4geDtcbiAgICAgIHggPSBfO1xuICAgICAgcmV0dXJuIGxpbmU7XG4gICAgfTtcbiAgICBsaW5lLnkgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB5O1xuICAgICAgeSA9IF87XG4gICAgICByZXR1cm4gbGluZTtcbiAgICB9O1xuICAgIGxpbmUuZGVmaW5lZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGRlZmluZWQ7XG4gICAgICBkZWZpbmVkID0gXztcbiAgICAgIHJldHVybiBsaW5lO1xuICAgIH07XG4gICAgbGluZS5pbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGludGVycG9sYXRlS2V5O1xuICAgICAgaWYgKHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIpIGludGVycG9sYXRlS2V5ID0gaW50ZXJwb2xhdGUgPSBfOyBlbHNlIGludGVycG9sYXRlS2V5ID0gKGludGVycG9sYXRlID0gZDNfc3ZnX2xpbmVJbnRlcnBvbGF0b3JzLmdldChfKSB8fCBkM19zdmdfbGluZUxpbmVhcikua2V5O1xuICAgICAgcmV0dXJuIGxpbmU7XG4gICAgfTtcbiAgICBsaW5lLnRlbnNpb24gPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0ZW5zaW9uO1xuICAgICAgdGVuc2lvbiA9IF87XG4gICAgICByZXR1cm4gbGluZTtcbiAgICB9O1xuICAgIHJldHVybiBsaW5lO1xuICB9XG4gIGQzLnN2Zy5saW5lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX3N2Z19saW5lKGQzX2lkZW50aXR5KTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVYKGQpIHtcbiAgICByZXR1cm4gZFswXTtcbiAgfVxuICBmdW5jdGlvbiBkM19zdmdfbGluZVkoZCkge1xuICAgIHJldHVybiBkWzFdO1xuICB9XG4gIHZhciBkM19zdmdfbGluZUludGVycG9sYXRvcnMgPSBkMy5tYXAoe1xuICAgIGxpbmVhcjogZDNfc3ZnX2xpbmVMaW5lYXIsXG4gICAgXCJsaW5lYXItY2xvc2VkXCI6IGQzX3N2Z19saW5lTGluZWFyQ2xvc2VkLFxuICAgIHN0ZXA6IGQzX3N2Z19saW5lU3RlcCxcbiAgICBcInN0ZXAtYmVmb3JlXCI6IGQzX3N2Z19saW5lU3RlcEJlZm9yZSxcbiAgICBcInN0ZXAtYWZ0ZXJcIjogZDNfc3ZnX2xpbmVTdGVwQWZ0ZXIsXG4gICAgYmFzaXM6IGQzX3N2Z19saW5lQmFzaXMsXG4gICAgXCJiYXNpcy1vcGVuXCI6IGQzX3N2Z19saW5lQmFzaXNPcGVuLFxuICAgIFwiYmFzaXMtY2xvc2VkXCI6IGQzX3N2Z19saW5lQmFzaXNDbG9zZWQsXG4gICAgYnVuZGxlOiBkM19zdmdfbGluZUJ1bmRsZSxcbiAgICBjYXJkaW5hbDogZDNfc3ZnX2xpbmVDYXJkaW5hbCxcbiAgICBcImNhcmRpbmFsLW9wZW5cIjogZDNfc3ZnX2xpbmVDYXJkaW5hbE9wZW4sXG4gICAgXCJjYXJkaW5hbC1jbG9zZWRcIjogZDNfc3ZnX2xpbmVDYXJkaW5hbENsb3NlZCxcbiAgICBtb25vdG9uZTogZDNfc3ZnX2xpbmVNb25vdG9uZVxuICB9KTtcbiAgZDNfc3ZnX2xpbmVJbnRlcnBvbGF0b3JzLmZvckVhY2goZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIHZhbHVlLmtleSA9IGtleTtcbiAgICB2YWx1ZS5jbG9zZWQgPSAvLWNsb3NlZCQvLnRlc3Qoa2V5KTtcbiAgfSk7XG4gIGZ1bmN0aW9uIGQzX3N2Z19saW5lTGluZWFyKHBvaW50cykge1xuICAgIHJldHVybiBwb2ludHMuam9pbihcIkxcIik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVMaW5lYXJDbG9zZWQocG9pbnRzKSB7XG4gICAgcmV0dXJuIGQzX3N2Z19saW5lTGluZWFyKHBvaW50cykgKyBcIlpcIjtcbiAgfVxuICBmdW5jdGlvbiBkM19zdmdfbGluZVN0ZXAocG9pbnRzKSB7XG4gICAgdmFyIGkgPSAwLCBuID0gcG9pbnRzLmxlbmd0aCwgcCA9IHBvaW50c1swXSwgcGF0aCA9IFsgcFswXSwgXCIsXCIsIHBbMV0gXTtcbiAgICB3aGlsZSAoKytpIDwgbikgcGF0aC5wdXNoKFwiSFwiLCAocFswXSArIChwID0gcG9pbnRzW2ldKVswXSkgLyAyLCBcIlZcIiwgcFsxXSk7XG4gICAgaWYgKG4gPiAxKSBwYXRoLnB1c2goXCJIXCIsIHBbMF0pO1xuICAgIHJldHVybiBwYXRoLmpvaW4oXCJcIik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVTdGVwQmVmb3JlKHBvaW50cykge1xuICAgIHZhciBpID0gMCwgbiA9IHBvaW50cy5sZW5ndGgsIHAgPSBwb2ludHNbMF0sIHBhdGggPSBbIHBbMF0sIFwiLFwiLCBwWzFdIF07XG4gICAgd2hpbGUgKCsraSA8IG4pIHBhdGgucHVzaChcIlZcIiwgKHAgPSBwb2ludHNbaV0pWzFdLCBcIkhcIiwgcFswXSk7XG4gICAgcmV0dXJuIHBhdGguam9pbihcIlwiKTtcbiAgfVxuICBmdW5jdGlvbiBkM19zdmdfbGluZVN0ZXBBZnRlcihwb2ludHMpIHtcbiAgICB2YXIgaSA9IDAsIG4gPSBwb2ludHMubGVuZ3RoLCBwID0gcG9pbnRzWzBdLCBwYXRoID0gWyBwWzBdLCBcIixcIiwgcFsxXSBdO1xuICAgIHdoaWxlICgrK2kgPCBuKSBwYXRoLnB1c2goXCJIXCIsIChwID0gcG9pbnRzW2ldKVswXSwgXCJWXCIsIHBbMV0pO1xuICAgIHJldHVybiBwYXRoLmpvaW4oXCJcIik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVDYXJkaW5hbE9wZW4ocG9pbnRzLCB0ZW5zaW9uKSB7XG4gICAgcmV0dXJuIHBvaW50cy5sZW5ndGggPCA0ID8gZDNfc3ZnX2xpbmVMaW5lYXIocG9pbnRzKSA6IHBvaW50c1sxXSArIGQzX3N2Z19saW5lSGVybWl0ZShwb2ludHMuc2xpY2UoMSwgcG9pbnRzLmxlbmd0aCAtIDEpLCBkM19zdmdfbGluZUNhcmRpbmFsVGFuZ2VudHMocG9pbnRzLCB0ZW5zaW9uKSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVDYXJkaW5hbENsb3NlZChwb2ludHMsIHRlbnNpb24pIHtcbiAgICByZXR1cm4gcG9pbnRzLmxlbmd0aCA8IDMgPyBkM19zdmdfbGluZUxpbmVhcihwb2ludHMpIDogcG9pbnRzWzBdICsgZDNfc3ZnX2xpbmVIZXJtaXRlKChwb2ludHMucHVzaChwb2ludHNbMF0pLCBcbiAgICBwb2ludHMpLCBkM19zdmdfbGluZUNhcmRpbmFsVGFuZ2VudHMoWyBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDJdIF0uY29uY2F0KHBvaW50cywgWyBwb2ludHNbMV0gXSksIHRlbnNpb24pKTtcbiAgfVxuICBmdW5jdGlvbiBkM19zdmdfbGluZUNhcmRpbmFsKHBvaW50cywgdGVuc2lvbikge1xuICAgIHJldHVybiBwb2ludHMubGVuZ3RoIDwgMyA/IGQzX3N2Z19saW5lTGluZWFyKHBvaW50cykgOiBwb2ludHNbMF0gKyBkM19zdmdfbGluZUhlcm1pdGUocG9pbnRzLCBkM19zdmdfbGluZUNhcmRpbmFsVGFuZ2VudHMocG9pbnRzLCB0ZW5zaW9uKSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVIZXJtaXRlKHBvaW50cywgdGFuZ2VudHMpIHtcbiAgICBpZiAodGFuZ2VudHMubGVuZ3RoIDwgMSB8fCBwb2ludHMubGVuZ3RoICE9IHRhbmdlbnRzLmxlbmd0aCAmJiBwb2ludHMubGVuZ3RoICE9IHRhbmdlbnRzLmxlbmd0aCArIDIpIHtcbiAgICAgIHJldHVybiBkM19zdmdfbGluZUxpbmVhcihwb2ludHMpO1xuICAgIH1cbiAgICB2YXIgcXVhZCA9IHBvaW50cy5sZW5ndGggIT0gdGFuZ2VudHMubGVuZ3RoLCBwYXRoID0gXCJcIiwgcDAgPSBwb2ludHNbMF0sIHAgPSBwb2ludHNbMV0sIHQwID0gdGFuZ2VudHNbMF0sIHQgPSB0MCwgcGkgPSAxO1xuICAgIGlmIChxdWFkKSB7XG4gICAgICBwYXRoICs9IFwiUVwiICsgKHBbMF0gLSB0MFswXSAqIDIgLyAzKSArIFwiLFwiICsgKHBbMV0gLSB0MFsxXSAqIDIgLyAzKSArIFwiLFwiICsgcFswXSArIFwiLFwiICsgcFsxXTtcbiAgICAgIHAwID0gcG9pbnRzWzFdO1xuICAgICAgcGkgPSAyO1xuICAgIH1cbiAgICBpZiAodGFuZ2VudHMubGVuZ3RoID4gMSkge1xuICAgICAgdCA9IHRhbmdlbnRzWzFdO1xuICAgICAgcCA9IHBvaW50c1twaV07XG4gICAgICBwaSsrO1xuICAgICAgcGF0aCArPSBcIkNcIiArIChwMFswXSArIHQwWzBdKSArIFwiLFwiICsgKHAwWzFdICsgdDBbMV0pICsgXCIsXCIgKyAocFswXSAtIHRbMF0pICsgXCIsXCIgKyAocFsxXSAtIHRbMV0pICsgXCIsXCIgKyBwWzBdICsgXCIsXCIgKyBwWzFdO1xuICAgICAgZm9yICh2YXIgaSA9IDI7IGkgPCB0YW5nZW50cy5sZW5ndGg7IGkrKywgcGkrKykge1xuICAgICAgICBwID0gcG9pbnRzW3BpXTtcbiAgICAgICAgdCA9IHRhbmdlbnRzW2ldO1xuICAgICAgICBwYXRoICs9IFwiU1wiICsgKHBbMF0gLSB0WzBdKSArIFwiLFwiICsgKHBbMV0gLSB0WzFdKSArIFwiLFwiICsgcFswXSArIFwiLFwiICsgcFsxXTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHF1YWQpIHtcbiAgICAgIHZhciBscCA9IHBvaW50c1twaV07XG4gICAgICBwYXRoICs9IFwiUVwiICsgKHBbMF0gKyB0WzBdICogMiAvIDMpICsgXCIsXCIgKyAocFsxXSArIHRbMV0gKiAyIC8gMykgKyBcIixcIiArIGxwWzBdICsgXCIsXCIgKyBscFsxXTtcbiAgICB9XG4gICAgcmV0dXJuIHBhdGg7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVDYXJkaW5hbFRhbmdlbnRzKHBvaW50cywgdGVuc2lvbikge1xuICAgIHZhciB0YW5nZW50cyA9IFtdLCBhID0gKDEgLSB0ZW5zaW9uKSAvIDIsIHAwLCBwMSA9IHBvaW50c1swXSwgcDIgPSBwb2ludHNbMV0sIGkgPSAxLCBuID0gcG9pbnRzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgcDAgPSBwMTtcbiAgICAgIHAxID0gcDI7XG4gICAgICBwMiA9IHBvaW50c1tpXTtcbiAgICAgIHRhbmdlbnRzLnB1c2goWyBhICogKHAyWzBdIC0gcDBbMF0pLCBhICogKHAyWzFdIC0gcDBbMV0pIF0pO1xuICAgIH1cbiAgICByZXR1cm4gdGFuZ2VudHM7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVCYXNpcyhwb2ludHMpIHtcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA8IDMpIHJldHVybiBkM19zdmdfbGluZUxpbmVhcihwb2ludHMpO1xuICAgIHZhciBpID0gMSwgbiA9IHBvaW50cy5sZW5ndGgsIHBpID0gcG9pbnRzWzBdLCB4MCA9IHBpWzBdLCB5MCA9IHBpWzFdLCBweCA9IFsgeDAsIHgwLCB4MCwgKHBpID0gcG9pbnRzWzFdKVswXSBdLCBweSA9IFsgeTAsIHkwLCB5MCwgcGlbMV0gXSwgcGF0aCA9IFsgeDAsIFwiLFwiLCB5MCwgXCJMXCIsIGQzX3N2Z19saW5lRG90NChkM19zdmdfbGluZUJhc2lzQmV6aWVyMywgcHgpLCBcIixcIiwgZDNfc3ZnX2xpbmVEb3Q0KGQzX3N2Z19saW5lQmFzaXNCZXppZXIzLCBweSkgXTtcbiAgICBwb2ludHMucHVzaChwb2ludHNbbiAtIDFdKTtcbiAgICB3aGlsZSAoKytpIDw9IG4pIHtcbiAgICAgIHBpID0gcG9pbnRzW2ldO1xuICAgICAgcHguc2hpZnQoKTtcbiAgICAgIHB4LnB1c2gocGlbMF0pO1xuICAgICAgcHkuc2hpZnQoKTtcbiAgICAgIHB5LnB1c2gocGlbMV0pO1xuICAgICAgZDNfc3ZnX2xpbmVCYXNpc0JlemllcihwYXRoLCBweCwgcHkpO1xuICAgIH1cbiAgICBwb2ludHMucG9wKCk7XG4gICAgcGF0aC5wdXNoKFwiTFwiLCBwaSk7XG4gICAgcmV0dXJuIHBhdGguam9pbihcIlwiKTtcbiAgfVxuICBmdW5jdGlvbiBkM19zdmdfbGluZUJhc2lzT3Blbihwb2ludHMpIHtcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA8IDQpIHJldHVybiBkM19zdmdfbGluZUxpbmVhcihwb2ludHMpO1xuICAgIHZhciBwYXRoID0gW10sIGkgPSAtMSwgbiA9IHBvaW50cy5sZW5ndGgsIHBpLCBweCA9IFsgMCBdLCBweSA9IFsgMCBdO1xuICAgIHdoaWxlICgrK2kgPCAzKSB7XG4gICAgICBwaSA9IHBvaW50c1tpXTtcbiAgICAgIHB4LnB1c2gocGlbMF0pO1xuICAgICAgcHkucHVzaChwaVsxXSk7XG4gICAgfVxuICAgIHBhdGgucHVzaChkM19zdmdfbGluZURvdDQoZDNfc3ZnX2xpbmVCYXNpc0JlemllcjMsIHB4KSArIFwiLFwiICsgZDNfc3ZnX2xpbmVEb3Q0KGQzX3N2Z19saW5lQmFzaXNCZXppZXIzLCBweSkpO1xuICAgIC0taTtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgcGkgPSBwb2ludHNbaV07XG4gICAgICBweC5zaGlmdCgpO1xuICAgICAgcHgucHVzaChwaVswXSk7XG4gICAgICBweS5zaGlmdCgpO1xuICAgICAgcHkucHVzaChwaVsxXSk7XG4gICAgICBkM19zdmdfbGluZUJhc2lzQmV6aWVyKHBhdGgsIHB4LCBweSk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoLmpvaW4oXCJcIik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVCYXNpc0Nsb3NlZChwb2ludHMpIHtcbiAgICB2YXIgcGF0aCwgaSA9IC0xLCBuID0gcG9pbnRzLmxlbmd0aCwgbSA9IG4gKyA0LCBwaSwgcHggPSBbXSwgcHkgPSBbXTtcbiAgICB3aGlsZSAoKytpIDwgNCkge1xuICAgICAgcGkgPSBwb2ludHNbaSAlIG5dO1xuICAgICAgcHgucHVzaChwaVswXSk7XG4gICAgICBweS5wdXNoKHBpWzFdKTtcbiAgICB9XG4gICAgcGF0aCA9IFsgZDNfc3ZnX2xpbmVEb3Q0KGQzX3N2Z19saW5lQmFzaXNCZXppZXIzLCBweCksIFwiLFwiLCBkM19zdmdfbGluZURvdDQoZDNfc3ZnX2xpbmVCYXNpc0JlemllcjMsIHB5KSBdO1xuICAgIC0taTtcbiAgICB3aGlsZSAoKytpIDwgbSkge1xuICAgICAgcGkgPSBwb2ludHNbaSAlIG5dO1xuICAgICAgcHguc2hpZnQoKTtcbiAgICAgIHB4LnB1c2gocGlbMF0pO1xuICAgICAgcHkuc2hpZnQoKTtcbiAgICAgIHB5LnB1c2gocGlbMV0pO1xuICAgICAgZDNfc3ZnX2xpbmVCYXNpc0JlemllcihwYXRoLCBweCwgcHkpO1xuICAgIH1cbiAgICByZXR1cm4gcGF0aC5qb2luKFwiXCIpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3N2Z19saW5lQnVuZGxlKHBvaW50cywgdGVuc2lvbikge1xuICAgIHZhciBuID0gcG9pbnRzLmxlbmd0aCAtIDE7XG4gICAgaWYgKG4pIHtcbiAgICAgIHZhciB4MCA9IHBvaW50c1swXVswXSwgeTAgPSBwb2ludHNbMF1bMV0sIGR4ID0gcG9pbnRzW25dWzBdIC0geDAsIGR5ID0gcG9pbnRzW25dWzFdIC0geTAsIGkgPSAtMSwgcCwgdDtcbiAgICAgIHdoaWxlICgrK2kgPD0gbikge1xuICAgICAgICBwID0gcG9pbnRzW2ldO1xuICAgICAgICB0ID0gaSAvIG47XG4gICAgICAgIHBbMF0gPSB0ZW5zaW9uICogcFswXSArICgxIC0gdGVuc2lvbikgKiAoeDAgKyB0ICogZHgpO1xuICAgICAgICBwWzFdID0gdGVuc2lvbiAqIHBbMV0gKyAoMSAtIHRlbnNpb24pICogKHkwICsgdCAqIGR5KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGQzX3N2Z19saW5lQmFzaXMocG9pbnRzKTtcbiAgfVxuICBmdW5jdGlvbiBkM19zdmdfbGluZURvdDQoYSwgYikge1xuICAgIHJldHVybiBhWzBdICogYlswXSArIGFbMV0gKiBiWzFdICsgYVsyXSAqIGJbMl0gKyBhWzNdICogYlszXTtcbiAgfVxuICB2YXIgZDNfc3ZnX2xpbmVCYXNpc0JlemllcjEgPSBbIDAsIDIgLyAzLCAxIC8gMywgMCBdLCBkM19zdmdfbGluZUJhc2lzQmV6aWVyMiA9IFsgMCwgMSAvIDMsIDIgLyAzLCAwIF0sIGQzX3N2Z19saW5lQmFzaXNCZXppZXIzID0gWyAwLCAxIC8gNiwgMiAvIDMsIDEgLyA2IF07XG4gIGZ1bmN0aW9uIGQzX3N2Z19saW5lQmFzaXNCZXppZXIocGF0aCwgeCwgeSkge1xuICAgIHBhdGgucHVzaChcIkNcIiwgZDNfc3ZnX2xpbmVEb3Q0KGQzX3N2Z19saW5lQmFzaXNCZXppZXIxLCB4KSwgXCIsXCIsIGQzX3N2Z19saW5lRG90NChkM19zdmdfbGluZUJhc2lzQmV6aWVyMSwgeSksIFwiLFwiLCBkM19zdmdfbGluZURvdDQoZDNfc3ZnX2xpbmVCYXNpc0JlemllcjIsIHgpLCBcIixcIiwgZDNfc3ZnX2xpbmVEb3Q0KGQzX3N2Z19saW5lQmFzaXNCZXppZXIyLCB5KSwgXCIsXCIsIGQzX3N2Z19saW5lRG90NChkM19zdmdfbGluZUJhc2lzQmV6aWVyMywgeCksIFwiLFwiLCBkM19zdmdfbGluZURvdDQoZDNfc3ZnX2xpbmVCYXNpc0JlemllcjMsIHkpKTtcbiAgfVxuICBmdW5jdGlvbiBkM19zdmdfbGluZVNsb3BlKHAwLCBwMSkge1xuICAgIHJldHVybiAocDFbMV0gLSBwMFsxXSkgLyAocDFbMF0gLSBwMFswXSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVGaW5pdGVEaWZmZXJlbmNlcyhwb2ludHMpIHtcbiAgICB2YXIgaSA9IDAsIGogPSBwb2ludHMubGVuZ3RoIC0gMSwgbSA9IFtdLCBwMCA9IHBvaW50c1swXSwgcDEgPSBwb2ludHNbMV0sIGQgPSBtWzBdID0gZDNfc3ZnX2xpbmVTbG9wZShwMCwgcDEpO1xuICAgIHdoaWxlICgrK2kgPCBqKSB7XG4gICAgICBtW2ldID0gKGQgKyAoZCA9IGQzX3N2Z19saW5lU2xvcGUocDAgPSBwMSwgcDEgPSBwb2ludHNbaSArIDFdKSkpIC8gMjtcbiAgICB9XG4gICAgbVtpXSA9IGQ7XG4gICAgcmV0dXJuIG07XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVNb25vdG9uZVRhbmdlbnRzKHBvaW50cykge1xuICAgIHZhciB0YW5nZW50cyA9IFtdLCBkLCBhLCBiLCBzLCBtID0gZDNfc3ZnX2xpbmVGaW5pdGVEaWZmZXJlbmNlcyhwb2ludHMpLCBpID0gLTEsIGogPSBwb2ludHMubGVuZ3RoIC0gMTtcbiAgICB3aGlsZSAoKytpIDwgaikge1xuICAgICAgZCA9IGQzX3N2Z19saW5lU2xvcGUocG9pbnRzW2ldLCBwb2ludHNbaSArIDFdKTtcbiAgICAgIGlmIChNYXRoLmFicyhkKSA8IDFlLTYpIHtcbiAgICAgICAgbVtpXSA9IG1baSArIDFdID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGEgPSBtW2ldIC8gZDtcbiAgICAgICAgYiA9IG1baSArIDFdIC8gZDtcbiAgICAgICAgcyA9IGEgKiBhICsgYiAqIGI7XG4gICAgICAgIGlmIChzID4gOSkge1xuICAgICAgICAgIHMgPSBkICogMyAvIE1hdGguc3FydChzKTtcbiAgICAgICAgICBtW2ldID0gcyAqIGE7XG4gICAgICAgICAgbVtpICsgMV0gPSBzICogYjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpID0gLTE7XG4gICAgd2hpbGUgKCsraSA8PSBqKSB7XG4gICAgICBzID0gKHBvaW50c1tNYXRoLm1pbihqLCBpICsgMSldWzBdIC0gcG9pbnRzW01hdGgubWF4KDAsIGkgLSAxKV1bMF0pIC8gKDYgKiAoMSArIG1baV0gKiBtW2ldKSk7XG4gICAgICB0YW5nZW50cy5wdXNoKFsgcyB8fCAwLCBtW2ldICogcyB8fCAwIF0pO1xuICAgIH1cbiAgICByZXR1cm4gdGFuZ2VudHM7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2xpbmVNb25vdG9uZShwb2ludHMpIHtcbiAgICByZXR1cm4gcG9pbnRzLmxlbmd0aCA8IDMgPyBkM19zdmdfbGluZUxpbmVhcihwb2ludHMpIDogcG9pbnRzWzBdICsgZDNfc3ZnX2xpbmVIZXJtaXRlKHBvaW50cywgZDNfc3ZnX2xpbmVNb25vdG9uZVRhbmdlbnRzKHBvaW50cykpO1xuICB9XG4gIGQzLmdlb20uaHVsbCA9IGZ1bmN0aW9uKHZlcnRpY2VzKSB7XG4gICAgdmFyIHggPSBkM19zdmdfbGluZVgsIHkgPSBkM19zdmdfbGluZVk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBodWxsKHZlcnRpY2VzKTtcbiAgICBmdW5jdGlvbiBodWxsKGRhdGEpIHtcbiAgICAgIGlmIChkYXRhLmxlbmd0aCA8IDMpIHJldHVybiBbXTtcbiAgICAgIHZhciBmeCA9IGQzX2Z1bmN0b3IoeCksIGZ5ID0gZDNfZnVuY3Rvcih5KSwgbiA9IGRhdGEubGVuZ3RoLCB2ZXJ0aWNlcywgcGxlbiA9IG4gLSAxLCBwb2ludHMgPSBbXSwgc3RhY2sgPSBbXSwgZCwgaSwgaiwgaCA9IDAsIHgxLCB5MSwgeDIsIHkyLCB1LCB2LCBhLCBzcDtcbiAgICAgIGlmIChmeCA9PT0gZDNfc3ZnX2xpbmVYICYmIHkgPT09IGQzX3N2Z19saW5lWSkgdmVydGljZXMgPSBkYXRhOyBlbHNlIGZvciAoaSA9IDAsIFxuICAgICAgdmVydGljZXMgPSBbXTsgaSA8IG47ICsraSkge1xuICAgICAgICB2ZXJ0aWNlcy5wdXNoKFsgK2Z4LmNhbGwodGhpcywgZCA9IGRhdGFbaV0sIGkpLCArZnkuY2FsbCh0aGlzLCBkLCBpKSBdKTtcbiAgICAgIH1cbiAgICAgIGZvciAoaSA9IDE7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgaWYgKHZlcnRpY2VzW2ldWzFdIDwgdmVydGljZXNbaF1bMV0gfHwgdmVydGljZXNbaV1bMV0gPT0gdmVydGljZXNbaF1bMV0gJiYgdmVydGljZXNbaV1bMF0gPCB2ZXJ0aWNlc1toXVswXSkgaCA9IGk7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmIChpID09PSBoKSBjb250aW51ZTtcbiAgICAgICAgeTEgPSB2ZXJ0aWNlc1tpXVsxXSAtIHZlcnRpY2VzW2hdWzFdO1xuICAgICAgICB4MSA9IHZlcnRpY2VzW2ldWzBdIC0gdmVydGljZXNbaF1bMF07XG4gICAgICAgIHBvaW50cy5wdXNoKHtcbiAgICAgICAgICBhbmdsZTogTWF0aC5hdGFuMih5MSwgeDEpLFxuICAgICAgICAgIGluZGV4OiBpXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcG9pbnRzLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICByZXR1cm4gYS5hbmdsZSAtIGIuYW5nbGU7XG4gICAgICB9KTtcbiAgICAgIGEgPSBwb2ludHNbMF0uYW5nbGU7XG4gICAgICB2ID0gcG9pbnRzWzBdLmluZGV4O1xuICAgICAgdSA9IDA7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgcGxlbjsgKytpKSB7XG4gICAgICAgIGogPSBwb2ludHNbaV0uaW5kZXg7XG4gICAgICAgIGlmIChhID09IHBvaW50c1tpXS5hbmdsZSkge1xuICAgICAgICAgIHgxID0gdmVydGljZXNbdl1bMF0gLSB2ZXJ0aWNlc1toXVswXTtcbiAgICAgICAgICB5MSA9IHZlcnRpY2VzW3ZdWzFdIC0gdmVydGljZXNbaF1bMV07XG4gICAgICAgICAgeDIgPSB2ZXJ0aWNlc1tqXVswXSAtIHZlcnRpY2VzW2hdWzBdO1xuICAgICAgICAgIHkyID0gdmVydGljZXNbal1bMV0gLSB2ZXJ0aWNlc1toXVsxXTtcbiAgICAgICAgICBpZiAoeDEgKiB4MSArIHkxICogeTEgPj0geDIgKiB4MiArIHkyICogeTIpIHtcbiAgICAgICAgICAgIHBvaW50c1tpXS5pbmRleCA9IC0xO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBvaW50c1t1XS5pbmRleCA9IC0xO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhID0gcG9pbnRzW2ldLmFuZ2xlO1xuICAgICAgICB1ID0gaTtcbiAgICAgICAgdiA9IGo7XG4gICAgICB9XG4gICAgICBzdGFjay5wdXNoKGgpO1xuICAgICAgZm9yIChpID0gMCwgaiA9IDA7IGkgPCAyOyArK2opIHtcbiAgICAgICAgaWYgKHBvaW50c1tqXS5pbmRleCA+IC0xKSB7XG4gICAgICAgICAgc3RhY2sucHVzaChwb2ludHNbal0uaW5kZXgpO1xuICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc3AgPSBzdGFjay5sZW5ndGg7XG4gICAgICBmb3IgKDtqIDwgcGxlbjsgKytqKSB7XG4gICAgICAgIGlmIChwb2ludHNbal0uaW5kZXggPCAwKSBjb250aW51ZTtcbiAgICAgICAgd2hpbGUgKCFkM19nZW9tX2h1bGxDQ1coc3RhY2tbc3AgLSAyXSwgc3RhY2tbc3AgLSAxXSwgcG9pbnRzW2pdLmluZGV4LCB2ZXJ0aWNlcykpIHtcbiAgICAgICAgICAtLXNwO1xuICAgICAgICB9XG4gICAgICAgIHN0YWNrW3NwKytdID0gcG9pbnRzW2pdLmluZGV4O1xuICAgICAgfVxuICAgICAgdmFyIHBvbHkgPSBbXTtcbiAgICAgIGZvciAoaSA9IHNwIC0gMTsgaSA+PSAwOyAtLWkpIHBvbHkucHVzaChkYXRhW3N0YWNrW2ldXSk7XG4gICAgICByZXR1cm4gcG9seTtcbiAgICB9XG4gICAgaHVsbC54ID0gZnVuY3Rpb24oXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeCA9IF8sIGh1bGwpIDogeDtcbiAgICB9O1xuICAgIGh1bGwueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkgPSBfLCBodWxsKSA6IHk7XG4gICAgfTtcbiAgICByZXR1cm4gaHVsbDtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfZ2VvbV9odWxsQ0NXKGkxLCBpMiwgaTMsIHYpIHtcbiAgICB2YXIgdCwgYSwgYiwgYywgZCwgZSwgZjtcbiAgICB0ID0gdltpMV07XG4gICAgYSA9IHRbMF07XG4gICAgYiA9IHRbMV07XG4gICAgdCA9IHZbaTJdO1xuICAgIGMgPSB0WzBdO1xuICAgIGQgPSB0WzFdO1xuICAgIHQgPSB2W2kzXTtcbiAgICBlID0gdFswXTtcbiAgICBmID0gdFsxXTtcbiAgICByZXR1cm4gKGYgLSBiKSAqIChjIC0gYSkgLSAoZCAtIGIpICogKGUgLSBhKSA+IDA7XG4gIH1cbiAgZDMuZ2VvbS5wb2x5Z29uID0gZnVuY3Rpb24oY29vcmRpbmF0ZXMpIHtcbiAgICBkM19zdWJjbGFzcyhjb29yZGluYXRlcywgZDNfZ2VvbV9wb2x5Z29uUHJvdG90eXBlKTtcbiAgICByZXR1cm4gY29vcmRpbmF0ZXM7XG4gIH07XG4gIHZhciBkM19nZW9tX3BvbHlnb25Qcm90b3R5cGUgPSBkMy5nZW9tLnBvbHlnb24ucHJvdG90eXBlID0gW107XG4gIGQzX2dlb21fcG9seWdvblByb3RvdHlwZS5hcmVhID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGkgPSAtMSwgbiA9IHRoaXMubGVuZ3RoLCBhLCBiID0gdGhpc1tuIC0gMV0sIGFyZWEgPSAwO1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBhID0gYjtcbiAgICAgIGIgPSB0aGlzW2ldO1xuICAgICAgYXJlYSArPSBhWzFdICogYlswXSAtIGFbMF0gKiBiWzFdO1xuICAgIH1cbiAgICByZXR1cm4gYXJlYSAqIC41O1xuICB9O1xuICBkM19nZW9tX3BvbHlnb25Qcm90b3R5cGUuY2VudHJvaWQgPSBmdW5jdGlvbihrKSB7XG4gICAgdmFyIGkgPSAtMSwgbiA9IHRoaXMubGVuZ3RoLCB4ID0gMCwgeSA9IDAsIGEsIGIgPSB0aGlzW24gLSAxXSwgYztcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIGsgPSAtMSAvICg2ICogdGhpcy5hcmVhKCkpO1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBhID0gYjtcbiAgICAgIGIgPSB0aGlzW2ldO1xuICAgICAgYyA9IGFbMF0gKiBiWzFdIC0gYlswXSAqIGFbMV07XG4gICAgICB4ICs9IChhWzBdICsgYlswXSkgKiBjO1xuICAgICAgeSArPSAoYVsxXSArIGJbMV0pICogYztcbiAgICB9XG4gICAgcmV0dXJuIFsgeCAqIGssIHkgKiBrIF07XG4gIH07XG4gIGQzX2dlb21fcG9seWdvblByb3RvdHlwZS5jbGlwID0gZnVuY3Rpb24oc3ViamVjdCkge1xuICAgIHZhciBpbnB1dCwgY2xvc2VkID0gZDNfZ2VvbV9wb2x5Z29uQ2xvc2VkKHN1YmplY3QpLCBpID0gLTEsIG4gPSB0aGlzLmxlbmd0aCAtIGQzX2dlb21fcG9seWdvbkNsb3NlZCh0aGlzKSwgaiwgbSwgYSA9IHRoaXNbbiAtIDFdLCBiLCBjLCBkO1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBpbnB1dCA9IHN1YmplY3Quc2xpY2UoKTtcbiAgICAgIHN1YmplY3QubGVuZ3RoID0gMDtcbiAgICAgIGIgPSB0aGlzW2ldO1xuICAgICAgYyA9IGlucHV0WyhtID0gaW5wdXQubGVuZ3RoIC0gY2xvc2VkKSAtIDFdO1xuICAgICAgaiA9IC0xO1xuICAgICAgd2hpbGUgKCsraiA8IG0pIHtcbiAgICAgICAgZCA9IGlucHV0W2pdO1xuICAgICAgICBpZiAoZDNfZ2VvbV9wb2x5Z29uSW5zaWRlKGQsIGEsIGIpKSB7XG4gICAgICAgICAgaWYgKCFkM19nZW9tX3BvbHlnb25JbnNpZGUoYywgYSwgYikpIHtcbiAgICAgICAgICAgIHN1YmplY3QucHVzaChkM19nZW9tX3BvbHlnb25JbnRlcnNlY3QoYywgZCwgYSwgYikpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzdWJqZWN0LnB1c2goZCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZDNfZ2VvbV9wb2x5Z29uSW5zaWRlKGMsIGEsIGIpKSB7XG4gICAgICAgICAgc3ViamVjdC5wdXNoKGQzX2dlb21fcG9seWdvbkludGVyc2VjdChjLCBkLCBhLCBiKSk7XG4gICAgICAgIH1cbiAgICAgICAgYyA9IGQ7XG4gICAgICB9XG4gICAgICBpZiAoY2xvc2VkKSBzdWJqZWN0LnB1c2goc3ViamVjdFswXSk7XG4gICAgICBhID0gYjtcbiAgICB9XG4gICAgcmV0dXJuIHN1YmplY3Q7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2dlb21fcG9seWdvbkluc2lkZShwLCBhLCBiKSB7XG4gICAgcmV0dXJuIChiWzBdIC0gYVswXSkgKiAocFsxXSAtIGFbMV0pIDwgKGJbMV0gLSBhWzFdKSAqIChwWzBdIC0gYVswXSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvbV9wb2x5Z29uSW50ZXJzZWN0KGMsIGQsIGEsIGIpIHtcbiAgICB2YXIgeDEgPSBjWzBdLCB4MyA9IGFbMF0sIHgyMSA9IGRbMF0gLSB4MSwgeDQzID0gYlswXSAtIHgzLCB5MSA9IGNbMV0sIHkzID0gYVsxXSwgeTIxID0gZFsxXSAtIHkxLCB5NDMgPSBiWzFdIC0geTMsIHVhID0gKHg0MyAqICh5MSAtIHkzKSAtIHk0MyAqICh4MSAtIHgzKSkgLyAoeTQzICogeDIxIC0geDQzICogeTIxKTtcbiAgICByZXR1cm4gWyB4MSArIHVhICogeDIxLCB5MSArIHVhICogeTIxIF07XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvbV9wb2x5Z29uQ2xvc2VkKGNvb3JkaW5hdGVzKSB7XG4gICAgdmFyIGEgPSBjb29yZGluYXRlc1swXSwgYiA9IGNvb3JkaW5hdGVzW2Nvb3JkaW5hdGVzLmxlbmd0aCAtIDFdO1xuICAgIHJldHVybiAhKGFbMF0gLSBiWzBdIHx8IGFbMV0gLSBiWzFdKTtcbiAgfVxuICBkMy5nZW9tLmRlbGF1bmF5ID0gZnVuY3Rpb24odmVydGljZXMpIHtcbiAgICB2YXIgZWRnZXMgPSB2ZXJ0aWNlcy5tYXAoZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfSksIHRyaWFuZ2xlcyA9IFtdO1xuICAgIGQzX2dlb21fdm9yb25vaVRlc3NlbGxhdGUodmVydGljZXMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGVkZ2VzW2UucmVnaW9uLmwuaW5kZXhdLnB1c2godmVydGljZXNbZS5yZWdpb24uci5pbmRleF0pO1xuICAgIH0pO1xuICAgIGVkZ2VzLmZvckVhY2goZnVuY3Rpb24oZWRnZSwgaSkge1xuICAgICAgdmFyIHYgPSB2ZXJ0aWNlc1tpXSwgY3ggPSB2WzBdLCBjeSA9IHZbMV07XG4gICAgICBlZGdlLmZvckVhY2goZnVuY3Rpb24odikge1xuICAgICAgICB2LmFuZ2xlID0gTWF0aC5hdGFuMih2WzBdIC0gY3gsIHZbMV0gLSBjeSk7XG4gICAgICB9KTtcbiAgICAgIGVkZ2Uuc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgICAgIHJldHVybiBhLmFuZ2xlIC0gYi5hbmdsZTtcbiAgICAgIH0pO1xuICAgICAgZm9yICh2YXIgaiA9IDAsIG0gPSBlZGdlLmxlbmd0aCAtIDE7IGogPCBtOyBqKyspIHtcbiAgICAgICAgdHJpYW5nbGVzLnB1c2goWyB2LCBlZGdlW2pdLCBlZGdlW2ogKyAxXSBdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gdHJpYW5nbGVzO1xuICB9O1xuICBkMy5nZW9tLnZvcm9ub2kgPSBmdW5jdGlvbihwb2ludHMpIHtcbiAgICB2YXIgeCA9IGQzX3N2Z19saW5lWCwgeSA9IGQzX3N2Z19saW5lWSwgY2xpcFBvbHlnb24gPSBudWxsO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdm9yb25vaShwb2ludHMpO1xuICAgIGZ1bmN0aW9uIHZvcm9ub2koZGF0YSkge1xuICAgICAgdmFyIHBvaW50cywgcG9seWdvbnMgPSBkYXRhLm1hcChmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfSksIGZ4ID0gZDNfZnVuY3Rvcih4KSwgZnkgPSBkM19mdW5jdG9yKHkpLCBkLCBpLCBuID0gZGF0YS5sZW5ndGgsIFogPSAxZTY7XG4gICAgICBpZiAoZnggPT09IGQzX3N2Z19saW5lWCAmJiBmeSA9PT0gZDNfc3ZnX2xpbmVZKSBwb2ludHMgPSBkYXRhOyBlbHNlIGZvciAocG9pbnRzID0gbmV3IEFycmF5KG4pLCBcbiAgICAgIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIHBvaW50c1tpXSA9IFsgK2Z4LmNhbGwodGhpcywgZCA9IGRhdGFbaV0sIGkpLCArZnkuY2FsbCh0aGlzLCBkLCBpKSBdO1xuICAgICAgfVxuICAgICAgZDNfZ2VvbV92b3Jvbm9pVGVzc2VsbGF0ZShwb2ludHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgdmFyIHMxLCBzMiwgeDEsIHgyLCB5MSwgeTI7XG4gICAgICAgIGlmIChlLmEgPT09IDEgJiYgZS5iID49IDApIHtcbiAgICAgICAgICBzMSA9IGUuZXAucjtcbiAgICAgICAgICBzMiA9IGUuZXAubDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzMSA9IGUuZXAubDtcbiAgICAgICAgICBzMiA9IGUuZXAucjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZS5hID09PSAxKSB7XG4gICAgICAgICAgeTEgPSBzMSA/IHMxLnkgOiAtWjtcbiAgICAgICAgICB4MSA9IGUuYyAtIGUuYiAqIHkxO1xuICAgICAgICAgIHkyID0gczIgPyBzMi55IDogWjtcbiAgICAgICAgICB4MiA9IGUuYyAtIGUuYiAqIHkyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHgxID0gczEgPyBzMS54IDogLVo7XG4gICAgICAgICAgeTEgPSBlLmMgLSBlLmEgKiB4MTtcbiAgICAgICAgICB4MiA9IHMyID8gczIueCA6IFo7XG4gICAgICAgICAgeTIgPSBlLmMgLSBlLmEgKiB4MjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdjEgPSBbIHgxLCB5MSBdLCB2MiA9IFsgeDIsIHkyIF07XG4gICAgICAgIHBvbHlnb25zW2UucmVnaW9uLmwuaW5kZXhdLnB1c2godjEsIHYyKTtcbiAgICAgICAgcG9seWdvbnNbZS5yZWdpb24uci5pbmRleF0ucHVzaCh2MSwgdjIpO1xuICAgICAgfSk7XG4gICAgICBwb2x5Z29ucyA9IHBvbHlnb25zLm1hcChmdW5jdGlvbihwb2x5Z29uLCBpKSB7XG4gICAgICAgIHZhciBjeCA9IHBvaW50c1tpXVswXSwgY3kgPSBwb2ludHNbaV1bMV0sIGFuZ2xlID0gcG9seWdvbi5tYXAoZnVuY3Rpb24odikge1xuICAgICAgICAgIHJldHVybiBNYXRoLmF0YW4yKHZbMF0gLSBjeCwgdlsxXSAtIGN5KTtcbiAgICAgICAgfSksIG9yZGVyID0gZDMucmFuZ2UocG9seWdvbi5sZW5ndGgpLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICAgIHJldHVybiBhbmdsZVthXSAtIGFuZ2xlW2JdO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG9yZGVyLmZpbHRlcihmdW5jdGlvbihkLCBpKSB7XG4gICAgICAgICAgcmV0dXJuICFpIHx8IGFuZ2xlW2RdIC0gYW5nbGVbb3JkZXJbaSAtIDFdXSA+IM61O1xuICAgICAgICB9KS5tYXAoZnVuY3Rpb24oZCkge1xuICAgICAgICAgIHJldHVybiBwb2x5Z29uW2RdO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcG9seWdvbnMuZm9yRWFjaChmdW5jdGlvbihwb2x5Z29uLCBpKSB7XG4gICAgICAgIHZhciBuID0gcG9seWdvbi5sZW5ndGg7XG4gICAgICAgIGlmICghbikgcmV0dXJuIHBvbHlnb24ucHVzaChbIC1aLCAtWiBdLCBbIC1aLCBaIF0sIFsgWiwgWiBdLCBbIFosIC1aIF0pO1xuICAgICAgICBpZiAobiA+IDIpIHJldHVybjtcbiAgICAgICAgdmFyIHAwID0gcG9pbnRzW2ldLCBwMSA9IHBvbHlnb25bMF0sIHAyID0gcG9seWdvblsxXSwgeDAgPSBwMFswXSwgeTAgPSBwMFsxXSwgeDEgPSBwMVswXSwgeTEgPSBwMVsxXSwgeDIgPSBwMlswXSwgeTIgPSBwMlsxXSwgZHggPSBNYXRoLmFicyh4MiAtIHgxKSwgZHkgPSB5MiAtIHkxO1xuICAgICAgICBpZiAoTWF0aC5hYnMoZHkpIDwgzrUpIHtcbiAgICAgICAgICB2YXIgeSA9IHkwIDwgeTEgPyAtWiA6IFo7XG4gICAgICAgICAgcG9seWdvbi5wdXNoKFsgLVosIHkgXSwgWyBaLCB5IF0pO1xuICAgICAgICB9IGVsc2UgaWYgKGR4IDwgzrUpIHtcbiAgICAgICAgICB2YXIgeCA9IHgwIDwgeDEgPyAtWiA6IFo7XG4gICAgICAgICAgcG9seWdvbi5wdXNoKFsgeCwgLVogXSwgWyB4LCBaIF0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB5ID0gKHgyIC0geDEpICogKHkxIC0geTApIDwgKHgxIC0geDApICogKHkyIC0geTEpID8gWiA6IC1aLCB6ID0gTWF0aC5hYnMoZHkpIC0gZHg7XG4gICAgICAgICAgaWYgKE1hdGguYWJzKHopIDwgzrUpIHtcbiAgICAgICAgICAgIHBvbHlnb24ucHVzaChbIGR5IDwgMCA/IHkgOiAteSwgeSBdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHogPiAwKSB5ICo9IC0xO1xuICAgICAgICAgICAgcG9seWdvbi5wdXNoKFsgLVosIHkgXSwgWyBaLCB5IF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAoY2xpcFBvbHlnb24pIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIGNsaXBQb2x5Z29uLmNsaXAocG9seWdvbnNbaV0pO1xuICAgICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgcG9seWdvbnNbaV0ucG9pbnQgPSBkYXRhW2ldO1xuICAgICAgcmV0dXJuIHBvbHlnb25zO1xuICAgIH1cbiAgICB2b3Jvbm9pLnggPSBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4ID0gXywgdm9yb25vaSkgOiB4O1xuICAgIH07XG4gICAgdm9yb25vaS55ID0gZnVuY3Rpb24oXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeSA9IF8sIHZvcm9ub2kpIDogeTtcbiAgICB9O1xuICAgIHZvcm9ub2kuY2xpcEV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGNsaXBQb2x5Z29uICYmIFsgY2xpcFBvbHlnb25bMF0sIGNsaXBQb2x5Z29uWzJdIF07XG4gICAgICBpZiAoXyA9PSBudWxsKSBjbGlwUG9seWdvbiA9IG51bGw7IGVsc2Uge1xuICAgICAgICB2YXIgeDEgPSArX1swXVswXSwgeTEgPSArX1swXVsxXSwgeDIgPSArX1sxXVswXSwgeTIgPSArX1sxXVsxXTtcbiAgICAgICAgY2xpcFBvbHlnb24gPSBkMy5nZW9tLnBvbHlnb24oWyBbIHgxLCB5MSBdLCBbIHgxLCB5MiBdLCBbIHgyLCB5MiBdLCBbIHgyLCB5MSBdIF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZvcm9ub2k7XG4gICAgfTtcbiAgICB2b3Jvbm9pLnNpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBjbGlwUG9seWdvbiAmJiBjbGlwUG9seWdvblsyXTtcbiAgICAgIHJldHVybiB2b3Jvbm9pLmNsaXBFeHRlbnQoXyAmJiBbIFsgMCwgMCBdLCBfIF0pO1xuICAgIH07XG4gICAgdm9yb25vaS5saW5rcyA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHZhciBwb2ludHMsIGdyYXBoID0gZGF0YS5tYXAoZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0pLCBsaW5rcyA9IFtdLCBmeCA9IGQzX2Z1bmN0b3IoeCksIGZ5ID0gZDNfZnVuY3Rvcih5KSwgZCwgaSwgbiA9IGRhdGEubGVuZ3RoO1xuICAgICAgaWYgKGZ4ID09PSBkM19zdmdfbGluZVggJiYgZnkgPT09IGQzX3N2Z19saW5lWSkgcG9pbnRzID0gZGF0YTsgZWxzZSBmb3IgKHBvaW50cyA9IG5ldyBBcnJheShuKSwgXG4gICAgICBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgICBwb2ludHNbaV0gPSBbICtmeC5jYWxsKHRoaXMsIGQgPSBkYXRhW2ldLCBpKSwgK2Z5LmNhbGwodGhpcywgZCwgaSkgXTtcbiAgICAgIH1cbiAgICAgIGQzX2dlb21fdm9yb25vaVRlc3NlbGxhdGUocG9pbnRzLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIHZhciBsID0gZS5yZWdpb24ubC5pbmRleCwgciA9IGUucmVnaW9uLnIuaW5kZXg7XG4gICAgICAgIGlmIChncmFwaFtsXVtyXSkgcmV0dXJuO1xuICAgICAgICBncmFwaFtsXVtyXSA9IGdyYXBoW3JdW2xdID0gdHJ1ZTtcbiAgICAgICAgbGlua3MucHVzaCh7XG4gICAgICAgICAgc291cmNlOiBkYXRhW2xdLFxuICAgICAgICAgIHRhcmdldDogZGF0YVtyXVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGxpbmtzO1xuICAgIH07XG4gICAgdm9yb25vaS50cmlhbmdsZXMgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgICBpZiAoeCA9PT0gZDNfc3ZnX2xpbmVYICYmIHkgPT09IGQzX3N2Z19saW5lWSkgcmV0dXJuIGQzLmdlb20uZGVsYXVuYXkoZGF0YSk7XG4gICAgICB2YXIgcG9pbnRzID0gbmV3IEFycmF5KG4pLCBmeCA9IGQzX2Z1bmN0b3IoeCksIGZ5ID0gZDNfZnVuY3Rvcih5KSwgZCwgaSA9IC0xLCBuID0gZGF0YS5sZW5ndGg7XG4gICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAocG9pbnRzW2ldID0gWyArZnguY2FsbCh0aGlzLCBkID0gZGF0YVtpXSwgaSksICtmeS5jYWxsKHRoaXMsIGQsIGkpIF0pLmRhdGEgPSBkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGQzLmdlb20uZGVsYXVuYXkocG9pbnRzKS5tYXAoZnVuY3Rpb24odHJpYW5nbGUpIHtcbiAgICAgICAgcmV0dXJuIHRyaWFuZ2xlLm1hcChmdW5jdGlvbihwb2ludCkge1xuICAgICAgICAgIHJldHVybiBwb2ludC5kYXRhO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIHZvcm9ub2k7XG4gIH07XG4gIHZhciBkM19nZW9tX3Zvcm9ub2lPcHBvc2l0ZSA9IHtcbiAgICBsOiBcInJcIixcbiAgICByOiBcImxcIlxuICB9O1xuICBmdW5jdGlvbiBkM19nZW9tX3Zvcm9ub2lUZXNzZWxsYXRlKHBvaW50cywgY2FsbGJhY2spIHtcbiAgICB2YXIgU2l0ZXMgPSB7XG4gICAgICBsaXN0OiBwb2ludHMubWFwKGZ1bmN0aW9uKHYsIGkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICB4OiB2WzBdLFxuICAgICAgICAgIHk6IHZbMV1cbiAgICAgICAgfTtcbiAgICAgIH0pLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICByZXR1cm4gYS55IDwgYi55ID8gLTEgOiBhLnkgPiBiLnkgPyAxIDogYS54IDwgYi54ID8gLTEgOiBhLnggPiBiLnggPyAxIDogMDtcbiAgICAgIH0pLFxuICAgICAgYm90dG9tU2l0ZTogbnVsbFxuICAgIH07XG4gICAgdmFyIEVkZ2VMaXN0ID0ge1xuICAgICAgbGlzdDogW10sXG4gICAgICBsZWZ0RW5kOiBudWxsLFxuICAgICAgcmlnaHRFbmQ6IG51bGwsXG4gICAgICBpbml0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgRWRnZUxpc3QubGVmdEVuZCA9IEVkZ2VMaXN0LmNyZWF0ZUhhbGZFZGdlKG51bGwsIFwibFwiKTtcbiAgICAgICAgRWRnZUxpc3QucmlnaHRFbmQgPSBFZGdlTGlzdC5jcmVhdGVIYWxmRWRnZShudWxsLCBcImxcIik7XG4gICAgICAgIEVkZ2VMaXN0LmxlZnRFbmQuciA9IEVkZ2VMaXN0LnJpZ2h0RW5kO1xuICAgICAgICBFZGdlTGlzdC5yaWdodEVuZC5sID0gRWRnZUxpc3QubGVmdEVuZDtcbiAgICAgICAgRWRnZUxpc3QubGlzdC51bnNoaWZ0KEVkZ2VMaXN0LmxlZnRFbmQsIEVkZ2VMaXN0LnJpZ2h0RW5kKTtcbiAgICAgIH0sXG4gICAgICBjcmVhdGVIYWxmRWRnZTogZnVuY3Rpb24oZWRnZSwgc2lkZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVkZ2U6IGVkZ2UsXG4gICAgICAgICAgc2lkZTogc2lkZSxcbiAgICAgICAgICB2ZXJ0ZXg6IG51bGwsXG4gICAgICAgICAgbDogbnVsbCxcbiAgICAgICAgICByOiBudWxsXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgaW5zZXJ0OiBmdW5jdGlvbihsYiwgaGUpIHtcbiAgICAgICAgaGUubCA9IGxiO1xuICAgICAgICBoZS5yID0gbGIucjtcbiAgICAgICAgbGIuci5sID0gaGU7XG4gICAgICAgIGxiLnIgPSBoZTtcbiAgICAgIH0sXG4gICAgICBsZWZ0Qm91bmQ6IGZ1bmN0aW9uKHApIHtcbiAgICAgICAgdmFyIGhlID0gRWRnZUxpc3QubGVmdEVuZDtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIGhlID0gaGUucjtcbiAgICAgICAgfSB3aGlsZSAoaGUgIT0gRWRnZUxpc3QucmlnaHRFbmQgJiYgR2VvbS5yaWdodE9mKGhlLCBwKSk7XG4gICAgICAgIGhlID0gaGUubDtcbiAgICAgICAgcmV0dXJuIGhlO1xuICAgICAgfSxcbiAgICAgIGRlbDogZnVuY3Rpb24oaGUpIHtcbiAgICAgICAgaGUubC5yID0gaGUucjtcbiAgICAgICAgaGUuci5sID0gaGUubDtcbiAgICAgICAgaGUuZWRnZSA9IG51bGw7XG4gICAgICB9LFxuICAgICAgcmlnaHQ6IGZ1bmN0aW9uKGhlKSB7XG4gICAgICAgIHJldHVybiBoZS5yO1xuICAgICAgfSxcbiAgICAgIGxlZnQ6IGZ1bmN0aW9uKGhlKSB7XG4gICAgICAgIHJldHVybiBoZS5sO1xuICAgICAgfSxcbiAgICAgIGxlZnRSZWdpb246IGZ1bmN0aW9uKGhlKSB7XG4gICAgICAgIHJldHVybiBoZS5lZGdlID09IG51bGwgPyBTaXRlcy5ib3R0b21TaXRlIDogaGUuZWRnZS5yZWdpb25baGUuc2lkZV07XG4gICAgICB9LFxuICAgICAgcmlnaHRSZWdpb246IGZ1bmN0aW9uKGhlKSB7XG4gICAgICAgIHJldHVybiBoZS5lZGdlID09IG51bGwgPyBTaXRlcy5ib3R0b21TaXRlIDogaGUuZWRnZS5yZWdpb25bZDNfZ2VvbV92b3Jvbm9pT3Bwb3NpdGVbaGUuc2lkZV1dO1xuICAgICAgfVxuICAgIH07XG4gICAgdmFyIEdlb20gPSB7XG4gICAgICBiaXNlY3Q6IGZ1bmN0aW9uKHMxLCBzMikge1xuICAgICAgICB2YXIgbmV3RWRnZSA9IHtcbiAgICAgICAgICByZWdpb246IHtcbiAgICAgICAgICAgIGw6IHMxLFxuICAgICAgICAgICAgcjogczJcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVwOiB7XG4gICAgICAgICAgICBsOiBudWxsLFxuICAgICAgICAgICAgcjogbnVsbFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGR4ID0gczIueCAtIHMxLngsIGR5ID0gczIueSAtIHMxLnksIGFkeCA9IGR4ID4gMCA/IGR4IDogLWR4LCBhZHkgPSBkeSA+IDAgPyBkeSA6IC1keTtcbiAgICAgICAgbmV3RWRnZS5jID0gczEueCAqIGR4ICsgczEueSAqIGR5ICsgKGR4ICogZHggKyBkeSAqIGR5KSAqIC41O1xuICAgICAgICBpZiAoYWR4ID4gYWR5KSB7XG4gICAgICAgICAgbmV3RWRnZS5hID0gMTtcbiAgICAgICAgICBuZXdFZGdlLmIgPSBkeSAvIGR4O1xuICAgICAgICAgIG5ld0VkZ2UuYyAvPSBkeDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdFZGdlLmIgPSAxO1xuICAgICAgICAgIG5ld0VkZ2UuYSA9IGR4IC8gZHk7XG4gICAgICAgICAgbmV3RWRnZS5jIC89IGR5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdFZGdlO1xuICAgICAgfSxcbiAgICAgIGludGVyc2VjdDogZnVuY3Rpb24oZWwxLCBlbDIpIHtcbiAgICAgICAgdmFyIGUxID0gZWwxLmVkZ2UsIGUyID0gZWwyLmVkZ2U7XG4gICAgICAgIGlmICghZTEgfHwgIWUyIHx8IGUxLnJlZ2lvbi5yID09IGUyLnJlZ2lvbi5yKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGQgPSBlMS5hICogZTIuYiAtIGUxLmIgKiBlMi5hO1xuICAgICAgICBpZiAoTWF0aC5hYnMoZCkgPCAxZS0xMCkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHZhciB4aW50ID0gKGUxLmMgKiBlMi5iIC0gZTIuYyAqIGUxLmIpIC8gZCwgeWludCA9IChlMi5jICogZTEuYSAtIGUxLmMgKiBlMi5hKSAvIGQsIGUxciA9IGUxLnJlZ2lvbi5yLCBlMnIgPSBlMi5yZWdpb24uciwgZWwsIGU7XG4gICAgICAgIGlmIChlMXIueSA8IGUyci55IHx8IGUxci55ID09IGUyci55ICYmIGUxci54IDwgZTJyLngpIHtcbiAgICAgICAgICBlbCA9IGVsMTtcbiAgICAgICAgICBlID0gZTE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZWwgPSBlbDI7XG4gICAgICAgICAgZSA9IGUyO1xuICAgICAgICB9XG4gICAgICAgIHZhciByaWdodE9mU2l0ZSA9IHhpbnQgPj0gZS5yZWdpb24uci54O1xuICAgICAgICBpZiAocmlnaHRPZlNpdGUgJiYgZWwuc2lkZSA9PT0gXCJsXCIgfHwgIXJpZ2h0T2ZTaXRlICYmIGVsLnNpZGUgPT09IFwiclwiKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB4OiB4aW50LFxuICAgICAgICAgIHk6IHlpbnRcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICByaWdodE9mOiBmdW5jdGlvbihoZSwgcCkge1xuICAgICAgICB2YXIgZSA9IGhlLmVkZ2UsIHRvcHNpdGUgPSBlLnJlZ2lvbi5yLCByaWdodE9mU2l0ZSA9IHAueCA+IHRvcHNpdGUueDtcbiAgICAgICAgaWYgKHJpZ2h0T2ZTaXRlICYmIGhlLnNpZGUgPT09IFwibFwiKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyaWdodE9mU2l0ZSAmJiBoZS5zaWRlID09PSBcInJcIikge1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlLmEgPT09IDEpIHtcbiAgICAgICAgICB2YXIgZHlwID0gcC55IC0gdG9wc2l0ZS55LCBkeHAgPSBwLnggLSB0b3BzaXRlLngsIGZhc3QgPSAwLCBhYm92ZSA9IDA7XG4gICAgICAgICAgaWYgKCFyaWdodE9mU2l0ZSAmJiBlLmIgPCAwIHx8IHJpZ2h0T2ZTaXRlICYmIGUuYiA+PSAwKSB7XG4gICAgICAgICAgICBhYm92ZSA9IGZhc3QgPSBkeXAgPj0gZS5iICogZHhwO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhYm92ZSA9IHAueCArIHAueSAqIGUuYiA+IGUuYztcbiAgICAgICAgICAgIGlmIChlLmIgPCAwKSB7XG4gICAgICAgICAgICAgIGFib3ZlID0gIWFib3ZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhYm92ZSkge1xuICAgICAgICAgICAgICBmYXN0ID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFmYXN0KSB7XG4gICAgICAgICAgICB2YXIgZHhzID0gdG9wc2l0ZS54IC0gZS5yZWdpb24ubC54O1xuICAgICAgICAgICAgYWJvdmUgPSBlLmIgKiAoZHhwICogZHhwIC0gZHlwICogZHlwKSA8IGR4cyAqIGR5cCAqICgxICsgMiAqIGR4cCAvIGR4cyArIGUuYiAqIGUuYik7XG4gICAgICAgICAgICBpZiAoZS5iIDwgMCkge1xuICAgICAgICAgICAgICBhYm92ZSA9ICFhYm92ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHlsID0gZS5jIC0gZS5hICogcC54LCB0MSA9IHAueSAtIHlsLCB0MiA9IHAueCAtIHRvcHNpdGUueCwgdDMgPSB5bCAtIHRvcHNpdGUueTtcbiAgICAgICAgICBhYm92ZSA9IHQxICogdDEgPiB0MiAqIHQyICsgdDMgKiB0MztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGUuc2lkZSA9PT0gXCJsXCIgPyBhYm92ZSA6ICFhYm92ZTtcbiAgICAgIH0sXG4gICAgICBlbmRQb2ludDogZnVuY3Rpb24oZWRnZSwgc2lkZSwgc2l0ZSkge1xuICAgICAgICBlZGdlLmVwW3NpZGVdID0gc2l0ZTtcbiAgICAgICAgaWYgKCFlZGdlLmVwW2QzX2dlb21fdm9yb25vaU9wcG9zaXRlW3NpZGVdXSkgcmV0dXJuO1xuICAgICAgICBjYWxsYmFjayhlZGdlKTtcbiAgICAgIH0sXG4gICAgICBkaXN0YW5jZTogZnVuY3Rpb24ocywgdCkge1xuICAgICAgICB2YXIgZHggPSBzLnggLSB0LngsIGR5ID0gcy55IC0gdC55O1xuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHZhciBFdmVudFF1ZXVlID0ge1xuICAgICAgbGlzdDogW10sXG4gICAgICBpbnNlcnQ6IGZ1bmN0aW9uKGhlLCBzaXRlLCBvZmZzZXQpIHtcbiAgICAgICAgaGUudmVydGV4ID0gc2l0ZTtcbiAgICAgICAgaGUueXN0YXIgPSBzaXRlLnkgKyBvZmZzZXQ7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsaXN0ID0gRXZlbnRRdWV1ZS5saXN0LCBsID0gbGlzdC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICB2YXIgbmV4dCA9IGxpc3RbaV07XG4gICAgICAgICAgaWYgKGhlLnlzdGFyID4gbmV4dC55c3RhciB8fCBoZS55c3RhciA9PSBuZXh0LnlzdGFyICYmIHNpdGUueCA+IG5leHQudmVydGV4LngpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGlzdC5zcGxpY2UoaSwgMCwgaGUpO1xuICAgICAgfSxcbiAgICAgIGRlbDogZnVuY3Rpb24oaGUpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxzID0gRXZlbnRRdWV1ZS5saXN0LCBsID0gbHMubGVuZ3RoOyBpIDwgbCAmJiBsc1tpXSAhPSBoZTsgKytpKSB7fVxuICAgICAgICBscy5zcGxpY2UoaSwgMSk7XG4gICAgICB9LFxuICAgICAgZW1wdHk6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gRXZlbnRRdWV1ZS5saXN0Lmxlbmd0aCA9PT0gMDtcbiAgICAgIH0sXG4gICAgICBuZXh0RXZlbnQ6IGZ1bmN0aW9uKGhlKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBscyA9IEV2ZW50UXVldWUubGlzdCwgbCA9IGxzLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgICAgICAgIGlmIChsc1tpXSA9PSBoZSkgcmV0dXJuIGxzW2kgKyAxXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0sXG4gICAgICBtaW46IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZWxlbSA9IEV2ZW50UXVldWUubGlzdFswXTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB4OiBlbGVtLnZlcnRleC54LFxuICAgICAgICAgIHk6IGVsZW0ueXN0YXJcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBleHRyYWN0TWluOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIEV2ZW50UXVldWUubGlzdC5zaGlmdCgpO1xuICAgICAgfVxuICAgIH07XG4gICAgRWRnZUxpc3QuaW5pdCgpO1xuICAgIFNpdGVzLmJvdHRvbVNpdGUgPSBTaXRlcy5saXN0LnNoaWZ0KCk7XG4gICAgdmFyIG5ld1NpdGUgPSBTaXRlcy5saXN0LnNoaWZ0KCksIG5ld0ludFN0YXI7XG4gICAgdmFyIGxibmQsIHJibmQsIGxsYm5kLCBycmJuZCwgYmlzZWN0b3I7XG4gICAgdmFyIGJvdCwgdG9wLCB0ZW1wLCBwLCB2O1xuICAgIHZhciBlLCBwbTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKCFFdmVudFF1ZXVlLmVtcHR5KCkpIHtcbiAgICAgICAgbmV3SW50U3RhciA9IEV2ZW50UXVldWUubWluKCk7XG4gICAgICB9XG4gICAgICBpZiAobmV3U2l0ZSAmJiAoRXZlbnRRdWV1ZS5lbXB0eSgpIHx8IG5ld1NpdGUueSA8IG5ld0ludFN0YXIueSB8fCBuZXdTaXRlLnkgPT0gbmV3SW50U3Rhci55ICYmIG5ld1NpdGUueCA8IG5ld0ludFN0YXIueCkpIHtcbiAgICAgICAgbGJuZCA9IEVkZ2VMaXN0LmxlZnRCb3VuZChuZXdTaXRlKTtcbiAgICAgICAgcmJuZCA9IEVkZ2VMaXN0LnJpZ2h0KGxibmQpO1xuICAgICAgICBib3QgPSBFZGdlTGlzdC5yaWdodFJlZ2lvbihsYm5kKTtcbiAgICAgICAgZSA9IEdlb20uYmlzZWN0KGJvdCwgbmV3U2l0ZSk7XG4gICAgICAgIGJpc2VjdG9yID0gRWRnZUxpc3QuY3JlYXRlSGFsZkVkZ2UoZSwgXCJsXCIpO1xuICAgICAgICBFZGdlTGlzdC5pbnNlcnQobGJuZCwgYmlzZWN0b3IpO1xuICAgICAgICBwID0gR2VvbS5pbnRlcnNlY3QobGJuZCwgYmlzZWN0b3IpO1xuICAgICAgICBpZiAocCkge1xuICAgICAgICAgIEV2ZW50UXVldWUuZGVsKGxibmQpO1xuICAgICAgICAgIEV2ZW50UXVldWUuaW5zZXJ0KGxibmQsIHAsIEdlb20uZGlzdGFuY2UocCwgbmV3U2l0ZSkpO1xuICAgICAgICB9XG4gICAgICAgIGxibmQgPSBiaXNlY3RvcjtcbiAgICAgICAgYmlzZWN0b3IgPSBFZGdlTGlzdC5jcmVhdGVIYWxmRWRnZShlLCBcInJcIik7XG4gICAgICAgIEVkZ2VMaXN0Lmluc2VydChsYm5kLCBiaXNlY3Rvcik7XG4gICAgICAgIHAgPSBHZW9tLmludGVyc2VjdChiaXNlY3RvciwgcmJuZCk7XG4gICAgICAgIGlmIChwKSB7XG4gICAgICAgICAgRXZlbnRRdWV1ZS5pbnNlcnQoYmlzZWN0b3IsIHAsIEdlb20uZGlzdGFuY2UocCwgbmV3U2l0ZSkpO1xuICAgICAgICB9XG4gICAgICAgIG5ld1NpdGUgPSBTaXRlcy5saXN0LnNoaWZ0KCk7XG4gICAgICB9IGVsc2UgaWYgKCFFdmVudFF1ZXVlLmVtcHR5KCkpIHtcbiAgICAgICAgbGJuZCA9IEV2ZW50UXVldWUuZXh0cmFjdE1pbigpO1xuICAgICAgICBsbGJuZCA9IEVkZ2VMaXN0LmxlZnQobGJuZCk7XG4gICAgICAgIHJibmQgPSBFZGdlTGlzdC5yaWdodChsYm5kKTtcbiAgICAgICAgcnJibmQgPSBFZGdlTGlzdC5yaWdodChyYm5kKTtcbiAgICAgICAgYm90ID0gRWRnZUxpc3QubGVmdFJlZ2lvbihsYm5kKTtcbiAgICAgICAgdG9wID0gRWRnZUxpc3QucmlnaHRSZWdpb24ocmJuZCk7XG4gICAgICAgIHYgPSBsYm5kLnZlcnRleDtcbiAgICAgICAgR2VvbS5lbmRQb2ludChsYm5kLmVkZ2UsIGxibmQuc2lkZSwgdik7XG4gICAgICAgIEdlb20uZW5kUG9pbnQocmJuZC5lZGdlLCByYm5kLnNpZGUsIHYpO1xuICAgICAgICBFZGdlTGlzdC5kZWwobGJuZCk7XG4gICAgICAgIEV2ZW50UXVldWUuZGVsKHJibmQpO1xuICAgICAgICBFZGdlTGlzdC5kZWwocmJuZCk7XG4gICAgICAgIHBtID0gXCJsXCI7XG4gICAgICAgIGlmIChib3QueSA+IHRvcC55KSB7XG4gICAgICAgICAgdGVtcCA9IGJvdDtcbiAgICAgICAgICBib3QgPSB0b3A7XG4gICAgICAgICAgdG9wID0gdGVtcDtcbiAgICAgICAgICBwbSA9IFwiclwiO1xuICAgICAgICB9XG4gICAgICAgIGUgPSBHZW9tLmJpc2VjdChib3QsIHRvcCk7XG4gICAgICAgIGJpc2VjdG9yID0gRWRnZUxpc3QuY3JlYXRlSGFsZkVkZ2UoZSwgcG0pO1xuICAgICAgICBFZGdlTGlzdC5pbnNlcnQobGxibmQsIGJpc2VjdG9yKTtcbiAgICAgICAgR2VvbS5lbmRQb2ludChlLCBkM19nZW9tX3Zvcm9ub2lPcHBvc2l0ZVtwbV0sIHYpO1xuICAgICAgICBwID0gR2VvbS5pbnRlcnNlY3QobGxibmQsIGJpc2VjdG9yKTtcbiAgICAgICAgaWYgKHApIHtcbiAgICAgICAgICBFdmVudFF1ZXVlLmRlbChsbGJuZCk7XG4gICAgICAgICAgRXZlbnRRdWV1ZS5pbnNlcnQobGxibmQsIHAsIEdlb20uZGlzdGFuY2UocCwgYm90KSk7XG4gICAgICAgIH1cbiAgICAgICAgcCA9IEdlb20uaW50ZXJzZWN0KGJpc2VjdG9yLCBycmJuZCk7XG4gICAgICAgIGlmIChwKSB7XG4gICAgICAgICAgRXZlbnRRdWV1ZS5pbnNlcnQoYmlzZWN0b3IsIHAsIEdlb20uZGlzdGFuY2UocCwgYm90KSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxibmQgPSBFZGdlTGlzdC5yaWdodChFZGdlTGlzdC5sZWZ0RW5kKTsgbGJuZCAhPSBFZGdlTGlzdC5yaWdodEVuZDsgbGJuZCA9IEVkZ2VMaXN0LnJpZ2h0KGxibmQpKSB7XG4gICAgICBjYWxsYmFjayhsYm5kLmVkZ2UpO1xuICAgIH1cbiAgfVxuICBkMy5nZW9tLnF1YWR0cmVlID0gZnVuY3Rpb24ocG9pbnRzLCB4MSwgeTEsIHgyLCB5Mikge1xuICAgIHZhciB4ID0gZDNfc3ZnX2xpbmVYLCB5ID0gZDNfc3ZnX2xpbmVZLCBjb21wYXQ7XG4gICAgaWYgKGNvbXBhdCA9IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHggPSBkM19nZW9tX3F1YWR0cmVlQ29tcGF0WDtcbiAgICAgIHkgPSBkM19nZW9tX3F1YWR0cmVlQ29tcGF0WTtcbiAgICAgIGlmIChjb21wYXQgPT09IDMpIHtcbiAgICAgICAgeTIgPSB5MTtcbiAgICAgICAgeDIgPSB4MTtcbiAgICAgICAgeTEgPSB4MSA9IDA7XG4gICAgICB9XG4gICAgICByZXR1cm4gcXVhZHRyZWUocG9pbnRzKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcXVhZHRyZWUoZGF0YSkge1xuICAgICAgdmFyIGQsIGZ4ID0gZDNfZnVuY3Rvcih4KSwgZnkgPSBkM19mdW5jdG9yKHkpLCB4cywgeXMsIGksIG4sIHgxXywgeTFfLCB4Ml8sIHkyXztcbiAgICAgIGlmICh4MSAhPSBudWxsKSB7XG4gICAgICAgIHgxXyA9IHgxLCB5MV8gPSB5MSwgeDJfID0geDIsIHkyXyA9IHkyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeDJfID0geTJfID0gLSh4MV8gPSB5MV8gPSBJbmZpbml0eSk7XG4gICAgICAgIHhzID0gW10sIHlzID0gW107XG4gICAgICAgIG4gPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgaWYgKGNvbXBhdCkgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgICAgIGQgPSBkYXRhW2ldO1xuICAgICAgICAgIGlmIChkLnggPCB4MV8pIHgxXyA9IGQueDtcbiAgICAgICAgICBpZiAoZC55IDwgeTFfKSB5MV8gPSBkLnk7XG4gICAgICAgICAgaWYgKGQueCA+IHgyXykgeDJfID0gZC54O1xuICAgICAgICAgIGlmIChkLnkgPiB5Ml8pIHkyXyA9IGQueTtcbiAgICAgICAgICB4cy5wdXNoKGQueCk7XG4gICAgICAgICAgeXMucHVzaChkLnkpO1xuICAgICAgICB9IGVsc2UgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgICAgIHZhciB4XyA9ICtmeChkID0gZGF0YVtpXSwgaSksIHlfID0gK2Z5KGQsIGkpO1xuICAgICAgICAgIGlmICh4XyA8IHgxXykgeDFfID0geF87XG4gICAgICAgICAgaWYgKHlfIDwgeTFfKSB5MV8gPSB5XztcbiAgICAgICAgICBpZiAoeF8gPiB4Ml8pIHgyXyA9IHhfO1xuICAgICAgICAgIGlmICh5XyA+IHkyXykgeTJfID0geV87XG4gICAgICAgICAgeHMucHVzaCh4Xyk7XG4gICAgICAgICAgeXMucHVzaCh5Xyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBkeCA9IHgyXyAtIHgxXywgZHkgPSB5Ml8gLSB5MV87XG4gICAgICBpZiAoZHggPiBkeSkgeTJfID0geTFfICsgZHg7IGVsc2UgeDJfID0geDFfICsgZHk7XG4gICAgICBmdW5jdGlvbiBpbnNlcnQobiwgZCwgeCwgeSwgeDEsIHkxLCB4MiwgeTIpIHtcbiAgICAgICAgaWYgKGlzTmFOKHgpIHx8IGlzTmFOKHkpKSByZXR1cm47XG4gICAgICAgIGlmIChuLmxlYWYpIHtcbiAgICAgICAgICB2YXIgbnggPSBuLngsIG55ID0gbi55O1xuICAgICAgICAgIGlmIChueCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMobnggLSB4KSArIE1hdGguYWJzKG55IC0geSkgPCAuMDEpIHtcbiAgICAgICAgICAgICAgaW5zZXJ0Q2hpbGQobiwgZCwgeCwgeSwgeDEsIHkxLCB4MiwgeTIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdmFyIG5Qb2ludCA9IG4ucG9pbnQ7XG4gICAgICAgICAgICAgIG4ueCA9IG4ueSA9IG4ucG9pbnQgPSBudWxsO1xuICAgICAgICAgICAgICBpbnNlcnRDaGlsZChuLCBuUG9pbnQsIG54LCBueSwgeDEsIHkxLCB4MiwgeTIpO1xuICAgICAgICAgICAgICBpbnNlcnRDaGlsZChuLCBkLCB4LCB5LCB4MSwgeTEsIHgyLCB5Mik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG4ueCA9IHgsIG4ueSA9IHksIG4ucG9pbnQgPSBkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbnNlcnRDaGlsZChuLCBkLCB4LCB5LCB4MSwgeTEsIHgyLCB5Mik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGluc2VydENoaWxkKG4sIGQsIHgsIHksIHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgICAgIHZhciBzeCA9ICh4MSArIHgyKSAqIC41LCBzeSA9ICh5MSArIHkyKSAqIC41LCByaWdodCA9IHggPj0gc3gsIGJvdHRvbSA9IHkgPj0gc3ksIGkgPSAoYm90dG9tIDw8IDEpICsgcmlnaHQ7XG4gICAgICAgIG4ubGVhZiA9IGZhbHNlO1xuICAgICAgICBuID0gbi5ub2Rlc1tpXSB8fCAobi5ub2Rlc1tpXSA9IGQzX2dlb21fcXVhZHRyZWVOb2RlKCkpO1xuICAgICAgICBpZiAocmlnaHQpIHgxID0gc3g7IGVsc2UgeDIgPSBzeDtcbiAgICAgICAgaWYgKGJvdHRvbSkgeTEgPSBzeTsgZWxzZSB5MiA9IHN5O1xuICAgICAgICBpbnNlcnQobiwgZCwgeCwgeSwgeDEsIHkxLCB4MiwgeTIpO1xuICAgICAgfVxuICAgICAgdmFyIHJvb3QgPSBkM19nZW9tX3F1YWR0cmVlTm9kZSgpO1xuICAgICAgcm9vdC5hZGQgPSBmdW5jdGlvbihkKSB7XG4gICAgICAgIGluc2VydChyb290LCBkLCArZngoZCwgKytpKSwgK2Z5KGQsIGkpLCB4MV8sIHkxXywgeDJfLCB5Ml8pO1xuICAgICAgfTtcbiAgICAgIHJvb3QudmlzaXQgPSBmdW5jdGlvbihmKSB7XG4gICAgICAgIGQzX2dlb21fcXVhZHRyZWVWaXNpdChmLCByb290LCB4MV8sIHkxXywgeDJfLCB5Ml8pO1xuICAgICAgfTtcbiAgICAgIGkgPSAtMTtcbiAgICAgIGlmICh4MSA9PSBudWxsKSB7XG4gICAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgaW5zZXJ0KHJvb3QsIGRhdGFbaV0sIHhzW2ldLCB5c1tpXSwgeDFfLCB5MV8sIHgyXywgeTJfKTtcbiAgICAgICAgfVxuICAgICAgICAtLWk7XG4gICAgICB9IGVsc2UgZGF0YS5mb3JFYWNoKHJvb3QuYWRkKTtcbiAgICAgIHhzID0geXMgPSBkYXRhID0gZCA9IG51bGw7XG4gICAgICByZXR1cm4gcm9vdDtcbiAgICB9XG4gICAgcXVhZHRyZWUueCA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSBfLCBxdWFkdHJlZSkgOiB4O1xuICAgIH07XG4gICAgcXVhZHRyZWUueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkgPSBfLCBxdWFkdHJlZSkgOiB5O1xuICAgIH07XG4gICAgcXVhZHRyZWUuZXh0ZW50ID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4geDEgPT0gbnVsbCA/IG51bGwgOiBbIFsgeDEsIHkxIF0sIFsgeDIsIHkyIF0gXTtcbiAgICAgIGlmIChfID09IG51bGwpIHgxID0geTEgPSB4MiA9IHkyID0gbnVsbDsgZWxzZSB4MSA9ICtfWzBdWzBdLCB5MSA9ICtfWzBdWzFdLCB4MiA9ICtfWzFdWzBdLCBcbiAgICAgIHkyID0gK19bMV1bMV07XG4gICAgICByZXR1cm4gcXVhZHRyZWU7XG4gICAgfTtcbiAgICBxdWFkdHJlZS5zaXplID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4geDEgPT0gbnVsbCA/IG51bGwgOiBbIHgyIC0geDEsIHkyIC0geTEgXTtcbiAgICAgIGlmIChfID09IG51bGwpIHgxID0geTEgPSB4MiA9IHkyID0gbnVsbDsgZWxzZSB4MSA9IHkxID0gMCwgeDIgPSArX1swXSwgeTIgPSArX1sxXTtcbiAgICAgIHJldHVybiBxdWFkdHJlZTtcbiAgICB9O1xuICAgIHJldHVybiBxdWFkdHJlZTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfZ2VvbV9xdWFkdHJlZUNvbXBhdFgoZCkge1xuICAgIHJldHVybiBkLng7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvbV9xdWFkdHJlZUNvbXBhdFkoZCkge1xuICAgIHJldHVybiBkLnk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZ2VvbV9xdWFkdHJlZU5vZGUoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxlYWY6IHRydWUsXG4gICAgICBub2RlczogW10sXG4gICAgICBwb2ludDogbnVsbCxcbiAgICAgIHg6IG51bGwsXG4gICAgICB5OiBudWxsXG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBkM19nZW9tX3F1YWR0cmVlVmlzaXQoZiwgbm9kZSwgeDEsIHkxLCB4MiwgeTIpIHtcbiAgICBpZiAoIWYobm9kZSwgeDEsIHkxLCB4MiwgeTIpKSB7XG4gICAgICB2YXIgc3ggPSAoeDEgKyB4MikgKiAuNSwgc3kgPSAoeTEgKyB5MikgKiAuNSwgY2hpbGRyZW4gPSBub2RlLm5vZGVzO1xuICAgICAgaWYgKGNoaWxkcmVuWzBdKSBkM19nZW9tX3F1YWR0cmVlVmlzaXQoZiwgY2hpbGRyZW5bMF0sIHgxLCB5MSwgc3gsIHN5KTtcbiAgICAgIGlmIChjaGlsZHJlblsxXSkgZDNfZ2VvbV9xdWFkdHJlZVZpc2l0KGYsIGNoaWxkcmVuWzFdLCBzeCwgeTEsIHgyLCBzeSk7XG4gICAgICBpZiAoY2hpbGRyZW5bMl0pIGQzX2dlb21fcXVhZHRyZWVWaXNpdChmLCBjaGlsZHJlblsyXSwgeDEsIHN5LCBzeCwgeTIpO1xuICAgICAgaWYgKGNoaWxkcmVuWzNdKSBkM19nZW9tX3F1YWR0cmVlVmlzaXQoZiwgY2hpbGRyZW5bM10sIHN4LCBzeSwgeDIsIHkyKTtcbiAgICB9XG4gIH1cbiAgZDMuaW50ZXJwb2xhdGVSZ2IgPSBkM19pbnRlcnBvbGF0ZVJnYjtcbiAgZnVuY3Rpb24gZDNfaW50ZXJwb2xhdGVSZ2IoYSwgYikge1xuICAgIGEgPSBkMy5yZ2IoYSk7XG4gICAgYiA9IGQzLnJnYihiKTtcbiAgICB2YXIgYXIgPSBhLnIsIGFnID0gYS5nLCBhYiA9IGEuYiwgYnIgPSBiLnIgLSBhciwgYmcgPSBiLmcgLSBhZywgYmIgPSBiLmIgLSBhYjtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgYS5yID0gTWF0aC5yb3VuZChhciArIGJyICogdCk7XG4gICAgICBhLmcgPSBNYXRoLnJvdW5kKGFnICsgYmcgKiB0KTtcbiAgICAgIGEuYiA9IE1hdGgucm91bmQoYWIgKyBiYiAqIHQpO1xuICAgICAgcmV0dXJuIGE7XG4gICAgfTtcbiAgfVxuICBkMy5pbnRlcnBvbGF0ZU9iamVjdCA9IGQzX2ludGVycG9sYXRlT2JqZWN0O1xuICBmdW5jdGlvbiBkM19pbnRlcnBvbGF0ZU9iamVjdChhLCBiKSB7XG4gICAgdmFyIGkgPSB7fSwgYyA9IHt9LCBrO1xuICAgIGZvciAoayBpbiBhKSB7XG4gICAgICBpZiAoayBpbiBiKSB7XG4gICAgICAgIGlba10gPSBkM19pbnRlcnBvbGF0ZShhW2tdLCBiW2tdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNba10gPSBhW2tdO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGsgaW4gYikge1xuICAgICAgaWYgKCEoayBpbiBhKSkge1xuICAgICAgICBjW2tdID0gYltrXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIGZvciAoayBpbiBpKSBjW2tdID0gaVtrXSh0KTtcbiAgICAgIHJldHVybiBjO1xuICAgIH07XG4gIH1cbiAgZDMuaW50ZXJwb2xhdGVOdW1iZXIgPSBkM19pbnRlcnBvbGF0ZU51bWJlcjtcbiAgZnVuY3Rpb24gZDNfaW50ZXJwb2xhdGVOdW1iZXIoYSwgYikge1xuICAgIGIgLT0gYSA9ICthO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICByZXR1cm4gYSArIGIgKiB0O1xuICAgIH07XG4gIH1cbiAgZDMuaW50ZXJwb2xhdGVTdHJpbmcgPSBkM19pbnRlcnBvbGF0ZVN0cmluZztcbiAgZnVuY3Rpb24gZDNfaW50ZXJwb2xhdGVTdHJpbmcoYSwgYikge1xuICAgIHZhciBtLCBpLCBqLCBzMCA9IDAsIHMxID0gMCwgcyA9IFtdLCBxID0gW10sIG4sIG87XG4gICAgYSA9IGEgKyBcIlwiLCBiID0gYiArIFwiXCI7XG4gICAgZDNfaW50ZXJwb2xhdGVfbnVtYmVyLmxhc3RJbmRleCA9IDA7XG4gICAgZm9yIChpID0gMDsgbSA9IGQzX2ludGVycG9sYXRlX251bWJlci5leGVjKGIpOyArK2kpIHtcbiAgICAgIGlmIChtLmluZGV4KSBzLnB1c2goYi5zdWJzdHJpbmcoczAsIHMxID0gbS5pbmRleCkpO1xuICAgICAgcS5wdXNoKHtcbiAgICAgICAgaTogcy5sZW5ndGgsXG4gICAgICAgIHg6IG1bMF1cbiAgICAgIH0pO1xuICAgICAgcy5wdXNoKG51bGwpO1xuICAgICAgczAgPSBkM19pbnRlcnBvbGF0ZV9udW1iZXIubGFzdEluZGV4O1xuICAgIH1cbiAgICBpZiAoczAgPCBiLmxlbmd0aCkgcy5wdXNoKGIuc3Vic3RyaW5nKHMwKSk7XG4gICAgZm9yIChpID0gMCwgbiA9IHEubGVuZ3RoOyAobSA9IGQzX2ludGVycG9sYXRlX251bWJlci5leGVjKGEpKSAmJiBpIDwgbjsgKytpKSB7XG4gICAgICBvID0gcVtpXTtcbiAgICAgIGlmIChvLnggPT0gbVswXSkge1xuICAgICAgICBpZiAoby5pKSB7XG4gICAgICAgICAgaWYgKHNbby5pICsgMV0gPT0gbnVsbCkge1xuICAgICAgICAgICAgc1tvLmkgLSAxXSArPSBvLng7XG4gICAgICAgICAgICBzLnNwbGljZShvLmksIDEpO1xuICAgICAgICAgICAgZm9yIChqID0gaSArIDE7IGogPCBuOyArK2opIHFbal0uaS0tO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzW28uaSAtIDFdICs9IG8ueCArIHNbby5pICsgMV07XG4gICAgICAgICAgICBzLnNwbGljZShvLmksIDIpO1xuICAgICAgICAgICAgZm9yIChqID0gaSArIDE7IGogPCBuOyArK2opIHFbal0uaSAtPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoc1tvLmkgKyAxXSA9PSBudWxsKSB7XG4gICAgICAgICAgICBzW28uaV0gPSBvLng7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNbby5pXSA9IG8ueCArIHNbby5pICsgMV07XG4gICAgICAgICAgICBzLnNwbGljZShvLmkgKyAxLCAxKTtcbiAgICAgICAgICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbjsgKytqKSBxW2pdLmktLTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcS5zcGxpY2UoaSwgMSk7XG4gICAgICAgIG4tLTtcbiAgICAgICAgaS0tO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgby54ID0gZDNfaW50ZXJwb2xhdGVOdW1iZXIocGFyc2VGbG9hdChtWzBdKSwgcGFyc2VGbG9hdChvLngpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgd2hpbGUgKGkgPCBuKSB7XG4gICAgICBvID0gcS5wb3AoKTtcbiAgICAgIGlmIChzW28uaSArIDFdID09IG51bGwpIHtcbiAgICAgICAgc1tvLmldID0gby54O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc1tvLmldID0gby54ICsgc1tvLmkgKyAxXTtcbiAgICAgICAgcy5zcGxpY2Uoby5pICsgMSwgMSk7XG4gICAgICB9XG4gICAgICBuLS07XG4gICAgfVxuICAgIGlmIChzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIHNbMF0gPT0gbnVsbCA/IChvID0gcVswXS54LCBmdW5jdGlvbih0KSB7XG4gICAgICAgIHJldHVybiBvKHQpICsgXCJcIjtcbiAgICAgIH0pIDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBiO1xuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHNbKG8gPSBxW2ldKS5pXSA9IG8ueCh0KTtcbiAgICAgIHJldHVybiBzLmpvaW4oXCJcIik7XG4gICAgfTtcbiAgfVxuICB2YXIgZDNfaW50ZXJwb2xhdGVfbnVtYmVyID0gL1stK10/KD86XFxkK1xcLj9cXGQqfFxcLj9cXGQrKSg/OltlRV1bLStdP1xcZCspPy9nO1xuICBkMy5pbnRlcnBvbGF0ZSA9IGQzX2ludGVycG9sYXRlO1xuICBmdW5jdGlvbiBkM19pbnRlcnBvbGF0ZShhLCBiKSB7XG4gICAgdmFyIGkgPSBkMy5pbnRlcnBvbGF0b3JzLmxlbmd0aCwgZjtcbiAgICB3aGlsZSAoLS1pID49IDAgJiYgIShmID0gZDMuaW50ZXJwb2xhdG9yc1tpXShhLCBiKSkpIDtcbiAgICByZXR1cm4gZjtcbiAgfVxuICBkMy5pbnRlcnBvbGF0b3JzID0gWyBmdW5jdGlvbihhLCBiKSB7XG4gICAgdmFyIHQgPSB0eXBlb2YgYjtcbiAgICByZXR1cm4gKHQgPT09IFwic3RyaW5nXCIgPyBkM19yZ2JfbmFtZXMuaGFzKGIpIHx8IC9eKCN8cmdiXFwofGhzbFxcKCkvLnRlc3QoYikgPyBkM19pbnRlcnBvbGF0ZVJnYiA6IGQzX2ludGVycG9sYXRlU3RyaW5nIDogYiBpbnN0YW5jZW9mIGQzX0NvbG9yID8gZDNfaW50ZXJwb2xhdGVSZ2IgOiB0ID09PSBcIm9iamVjdFwiID8gQXJyYXkuaXNBcnJheShiKSA/IGQzX2ludGVycG9sYXRlQXJyYXkgOiBkM19pbnRlcnBvbGF0ZU9iamVjdCA6IGQzX2ludGVycG9sYXRlTnVtYmVyKShhLCBiKTtcbiAgfSBdO1xuICBkMy5pbnRlcnBvbGF0ZUFycmF5ID0gZDNfaW50ZXJwb2xhdGVBcnJheTtcbiAgZnVuY3Rpb24gZDNfaW50ZXJwb2xhdGVBcnJheShhLCBiKSB7XG4gICAgdmFyIHggPSBbXSwgYyA9IFtdLCBuYSA9IGEubGVuZ3RoLCBuYiA9IGIubGVuZ3RoLCBuMCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aCksIGk7XG4gICAgZm9yIChpID0gMDsgaSA8IG4wOyArK2kpIHgucHVzaChkM19pbnRlcnBvbGF0ZShhW2ldLCBiW2ldKSk7XG4gICAgZm9yICg7aSA8IG5hOyArK2kpIGNbaV0gPSBhW2ldO1xuICAgIGZvciAoO2kgPCBuYjsgKytpKSBjW2ldID0gYltpXTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgZm9yIChpID0gMDsgaSA8IG4wOyArK2kpIGNbaV0gPSB4W2ldKHQpO1xuICAgICAgcmV0dXJuIGM7XG4gICAgfTtcbiAgfVxuICB2YXIgZDNfZWFzZV9kZWZhdWx0ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX2lkZW50aXR5O1xuICB9O1xuICB2YXIgZDNfZWFzZSA9IGQzLm1hcCh7XG4gICAgbGluZWFyOiBkM19lYXNlX2RlZmF1bHQsXG4gICAgcG9seTogZDNfZWFzZV9wb2x5LFxuICAgIHF1YWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGQzX2Vhc2VfcXVhZDtcbiAgICB9LFxuICAgIGN1YmljOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkM19lYXNlX2N1YmljO1xuICAgIH0sXG4gICAgc2luOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkM19lYXNlX3NpbjtcbiAgICB9LFxuICAgIGV4cDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZDNfZWFzZV9leHA7XG4gICAgfSxcbiAgICBjaXJjbGU6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGQzX2Vhc2VfY2lyY2xlO1xuICAgIH0sXG4gICAgZWxhc3RpYzogZDNfZWFzZV9lbGFzdGljLFxuICAgIGJhY2s6IGQzX2Vhc2VfYmFjayxcbiAgICBib3VuY2U6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGQzX2Vhc2VfYm91bmNlO1xuICAgIH1cbiAgfSk7XG4gIHZhciBkM19lYXNlX21vZGUgPSBkMy5tYXAoe1xuICAgIFwiaW5cIjogZDNfaWRlbnRpdHksXG4gICAgb3V0OiBkM19lYXNlX3JldmVyc2UsXG4gICAgXCJpbi1vdXRcIjogZDNfZWFzZV9yZWZsZWN0LFxuICAgIFwib3V0LWluXCI6IGZ1bmN0aW9uKGYpIHtcbiAgICAgIHJldHVybiBkM19lYXNlX3JlZmxlY3QoZDNfZWFzZV9yZXZlcnNlKGYpKTtcbiAgICB9XG4gIH0pO1xuICBkMy5lYXNlID0gZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBpID0gbmFtZS5pbmRleE9mKFwiLVwiKSwgdCA9IGkgPj0gMCA/IG5hbWUuc3Vic3RyaW5nKDAsIGkpIDogbmFtZSwgbSA9IGkgPj0gMCA/IG5hbWUuc3Vic3RyaW5nKGkgKyAxKSA6IFwiaW5cIjtcbiAgICB0ID0gZDNfZWFzZS5nZXQodCkgfHwgZDNfZWFzZV9kZWZhdWx0O1xuICAgIG0gPSBkM19lYXNlX21vZGUuZ2V0KG0pIHx8IGQzX2lkZW50aXR5O1xuICAgIHJldHVybiBkM19lYXNlX2NsYW1wKG0odC5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKSkpO1xuICB9O1xuICBmdW5jdGlvbiBkM19lYXNlX2NsYW1wKGYpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgcmV0dXJuIHQgPD0gMCA/IDAgOiB0ID49IDEgPyAxIDogZih0KTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2Vhc2VfcmV2ZXJzZShmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHJldHVybiAxIC0gZigxIC0gdCk7XG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBkM19lYXNlX3JlZmxlY3QoZikge1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICByZXR1cm4gLjUgKiAodCA8IC41ID8gZigyICogdCkgOiAyIC0gZigyIC0gMiAqIHQpKTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2Vhc2VfcXVhZCh0KSB7XG4gICAgcmV0dXJuIHQgKiB0O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2Vhc2VfY3ViaWModCkge1xuICAgIHJldHVybiB0ICogdCAqIHQ7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZWFzZV9jdWJpY0luT3V0KHQpIHtcbiAgICBpZiAodCA8PSAwKSByZXR1cm4gMDtcbiAgICBpZiAodCA+PSAxKSByZXR1cm4gMTtcbiAgICB2YXIgdDIgPSB0ICogdCwgdDMgPSB0MiAqIHQ7XG4gICAgcmV0dXJuIDQgKiAodCA8IC41ID8gdDMgOiAzICogKHQgLSB0MikgKyB0MyAtIC43NSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZWFzZV9wb2x5KGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgcmV0dXJuIE1hdGgucG93KHQsIGUpO1xuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZDNfZWFzZV9zaW4odCkge1xuICAgIHJldHVybiAxIC0gTWF0aC5jb3ModCAqIM+AIC8gMik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfZWFzZV9leHAodCkge1xuICAgIHJldHVybiBNYXRoLnBvdygyLCAxMCAqICh0IC0gMSkpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2Vhc2VfY2lyY2xlKHQpIHtcbiAgICByZXR1cm4gMSAtIE1hdGguc3FydCgxIC0gdCAqIHQpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2Vhc2VfZWxhc3RpYyhhLCBwKSB7XG4gICAgdmFyIHM7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSBwID0gLjQ1O1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSBzID0gcCAvICgyICogz4ApICogTWF0aC5hc2luKDEgLyBhKTsgZWxzZSBhID0gMSwgcyA9IHAgLyA0O1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICByZXR1cm4gMSArIGEgKiBNYXRoLnBvdygyLCAxMCAqIC10KSAqIE1hdGguc2luKCh0IC0gcykgKiAyICogz4AgLyBwKTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2Vhc2VfYmFjayhzKSB7XG4gICAgaWYgKCFzKSBzID0gMS43MDE1ODtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgcmV0dXJuIHQgKiB0ICogKChzICsgMSkgKiB0IC0gcyk7XG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBkM19lYXNlX2JvdW5jZSh0KSB7XG4gICAgcmV0dXJuIHQgPCAxIC8gMi43NSA/IDcuNTYyNSAqIHQgKiB0IDogdCA8IDIgLyAyLjc1ID8gNy41NjI1ICogKHQgLT0gMS41IC8gMi43NSkgKiB0ICsgLjc1IDogdCA8IDIuNSAvIDIuNzUgPyA3LjU2MjUgKiAodCAtPSAyLjI1IC8gMi43NSkgKiB0ICsgLjkzNzUgOiA3LjU2MjUgKiAodCAtPSAyLjYyNSAvIDIuNzUpICogdCArIC45ODQzNzU7XG4gIH1cbiAgZDMuaW50ZXJwb2xhdGVIY2wgPSBkM19pbnRlcnBvbGF0ZUhjbDtcbiAgZnVuY3Rpb24gZDNfaW50ZXJwb2xhdGVIY2woYSwgYikge1xuICAgIGEgPSBkMy5oY2woYSk7XG4gICAgYiA9IGQzLmhjbChiKTtcbiAgICB2YXIgYWggPSBhLmgsIGFjID0gYS5jLCBhbCA9IGEubCwgYmggPSBiLmggLSBhaCwgYmMgPSBiLmMgLSBhYywgYmwgPSBiLmwgLSBhbDtcbiAgICBpZiAoaXNOYU4oYmMpKSBiYyA9IDAsIGFjID0gaXNOYU4oYWMpID8gYi5jIDogYWM7XG4gICAgaWYgKGlzTmFOKGJoKSkgYmggPSAwLCBhaCA9IGlzTmFOKGFoKSA/IGIuaCA6IGFoOyBlbHNlIGlmIChiaCA+IDE4MCkgYmggLT0gMzYwOyBlbHNlIGlmIChiaCA8IC0xODApIGJoICs9IDM2MDtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgYS5oID0gYWggKyBiaCAqIHQ7XG4gICAgICBhLmMgPSBhYyArIGJjICogdDtcbiAgICAgIGEubCA9IGFsICsgYmwgKiB0O1xuICAgICAgcmV0dXJuIGE7XG4gICAgfTtcbiAgfVxuICBkMy5pbnRlcnBvbGF0ZUhzbCA9IGQzX2ludGVycG9sYXRlSHNsO1xuICBmdW5jdGlvbiBkM19pbnRlcnBvbGF0ZUhzbChhLCBiKSB7XG4gICAgYSA9IGQzLmhzbChhKTtcbiAgICBiID0gZDMuaHNsKGIpO1xuICAgIHZhciBhaCA9IGEuaCwgYXMgPSBhLnMsIGFsID0gYS5sLCBiaCA9IGIuaCAtIGFoLCBicyA9IGIucyAtIGFzLCBibCA9IGIubCAtIGFsO1xuICAgIGlmIChpc05hTihicykpIGJzID0gMCwgYXMgPSBpc05hTihhcykgPyBiLnMgOiBhcztcbiAgICBpZiAoaXNOYU4oYmgpKSBiaCA9IDAsIGFoID0gaXNOYU4oYWgpID8gYi5oIDogYWg7IGVsc2UgaWYgKGJoID4gMTgwKSBiaCAtPSAzNjA7IGVsc2UgaWYgKGJoIDwgLTE4MCkgYmggKz0gMzYwO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICBhLmggPSBhaCArIGJoICogdDtcbiAgICAgIGEucyA9IGFzICsgYnMgKiB0O1xuICAgICAgYS5sID0gYWwgKyBibCAqIHQ7XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuICB9XG4gIGQzLmludGVycG9sYXRlTGFiID0gZDNfaW50ZXJwb2xhdGVMYWI7XG4gIGZ1bmN0aW9uIGQzX2ludGVycG9sYXRlTGFiKGEsIGIpIHtcbiAgICBhID0gZDMubGFiKGEpO1xuICAgIGIgPSBkMy5sYWIoYik7XG4gICAgdmFyIGFsID0gYS5sLCBhYSA9IGEuYSwgYWIgPSBhLmIsIGJsID0gYi5sIC0gYWwsIGJhID0gYi5hIC0gYWEsIGJiID0gYi5iIC0gYWI7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIGEubCA9IGFsICsgYmwgKiB0O1xuICAgICAgYS5hID0gYWEgKyBiYSAqIHQ7XG4gICAgICBhLmIgPSBhYiArIGJiICogdDtcbiAgICAgIHJldHVybiBhO1xuICAgIH07XG4gIH1cbiAgZDMuaW50ZXJwb2xhdGVSb3VuZCA9IGQzX2ludGVycG9sYXRlUm91bmQ7XG4gIGZ1bmN0aW9uIGQzX2ludGVycG9sYXRlUm91bmQoYSwgYikge1xuICAgIGIgLT0gYTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgcmV0dXJuIE1hdGgucm91bmQoYSArIGIgKiB0KTtcbiAgICB9O1xuICB9XG4gIGQzLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKHN0cmluZykge1xuICAgIHZhciBnID0gZDNfZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKGQzLm5zLnByZWZpeC5zdmcsIFwiZ1wiKTtcbiAgICByZXR1cm4gKGQzLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKHN0cmluZykge1xuICAgICAgaWYgKHN0cmluZyAhPSBudWxsKSB7XG4gICAgICAgIGcuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIHN0cmluZyk7XG4gICAgICAgIHZhciB0ID0gZy50cmFuc2Zvcm0uYmFzZVZhbC5jb25zb2xpZGF0ZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBkM190cmFuc2Zvcm0odCA/IHQubWF0cml4IDogZDNfdHJhbnNmb3JtSWRlbnRpdHkpO1xuICAgIH0pKHN0cmluZyk7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3RyYW5zZm9ybShtKSB7XG4gICAgdmFyIHIwID0gWyBtLmEsIG0uYiBdLCByMSA9IFsgbS5jLCBtLmQgXSwga3ggPSBkM190cmFuc2Zvcm1Ob3JtYWxpemUocjApLCBreiA9IGQzX3RyYW5zZm9ybURvdChyMCwgcjEpLCBreSA9IGQzX3RyYW5zZm9ybU5vcm1hbGl6ZShkM190cmFuc2Zvcm1Db21iaW5lKHIxLCByMCwgLWt6KSkgfHwgMDtcbiAgICBpZiAocjBbMF0gKiByMVsxXSA8IHIxWzBdICogcjBbMV0pIHtcbiAgICAgIHIwWzBdICo9IC0xO1xuICAgICAgcjBbMV0gKj0gLTE7XG4gICAgICBreCAqPSAtMTtcbiAgICAgIGt6ICo9IC0xO1xuICAgIH1cbiAgICB0aGlzLnJvdGF0ZSA9IChreCA/IE1hdGguYXRhbjIocjBbMV0sIHIwWzBdKSA6IE1hdGguYXRhbjIoLXIxWzBdLCByMVsxXSkpICogZDNfZGVncmVlcztcbiAgICB0aGlzLnRyYW5zbGF0ZSA9IFsgbS5lLCBtLmYgXTtcbiAgICB0aGlzLnNjYWxlID0gWyBreCwga3kgXTtcbiAgICB0aGlzLnNrZXcgPSBreSA/IE1hdGguYXRhbjIoa3osIGt5KSAqIGQzX2RlZ3JlZXMgOiAwO1xuICB9XG4gIGQzX3RyYW5zZm9ybS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCJ0cmFuc2xhdGUoXCIgKyB0aGlzLnRyYW5zbGF0ZSArIFwiKXJvdGF0ZShcIiArIHRoaXMucm90YXRlICsgXCIpc2tld1goXCIgKyB0aGlzLnNrZXcgKyBcIilzY2FsZShcIiArIHRoaXMuc2NhbGUgKyBcIilcIjtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfdHJhbnNmb3JtRG90KGEsIGIpIHtcbiAgICByZXR1cm4gYVswXSAqIGJbMF0gKyBhWzFdICogYlsxXTtcbiAgfVxuICBmdW5jdGlvbiBkM190cmFuc2Zvcm1Ob3JtYWxpemUoYSkge1xuICAgIHZhciBrID0gTWF0aC5zcXJ0KGQzX3RyYW5zZm9ybURvdChhLCBhKSk7XG4gICAgaWYgKGspIHtcbiAgICAgIGFbMF0gLz0gaztcbiAgICAgIGFbMV0gLz0gaztcbiAgICB9XG4gICAgcmV0dXJuIGs7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdHJhbnNmb3JtQ29tYmluZShhLCBiLCBrKSB7XG4gICAgYVswXSArPSBrICogYlswXTtcbiAgICBhWzFdICs9IGsgKiBiWzFdO1xuICAgIHJldHVybiBhO1xuICB9XG4gIHZhciBkM190cmFuc2Zvcm1JZGVudGl0eSA9IHtcbiAgICBhOiAxLFxuICAgIGI6IDAsXG4gICAgYzogMCxcbiAgICBkOiAxLFxuICAgIGU6IDAsXG4gICAgZjogMFxuICB9O1xuICBkMy5pbnRlcnBvbGF0ZVRyYW5zZm9ybSA9IGQzX2ludGVycG9sYXRlVHJhbnNmb3JtO1xuICBmdW5jdGlvbiBkM19pbnRlcnBvbGF0ZVRyYW5zZm9ybShhLCBiKSB7XG4gICAgdmFyIHMgPSBbXSwgcSA9IFtdLCBuLCBBID0gZDMudHJhbnNmb3JtKGEpLCBCID0gZDMudHJhbnNmb3JtKGIpLCB0YSA9IEEudHJhbnNsYXRlLCB0YiA9IEIudHJhbnNsYXRlLCByYSA9IEEucm90YXRlLCByYiA9IEIucm90YXRlLCB3YSA9IEEuc2tldywgd2IgPSBCLnNrZXcsIGthID0gQS5zY2FsZSwga2IgPSBCLnNjYWxlO1xuICAgIGlmICh0YVswXSAhPSB0YlswXSB8fCB0YVsxXSAhPSB0YlsxXSkge1xuICAgICAgcy5wdXNoKFwidHJhbnNsYXRlKFwiLCBudWxsLCBcIixcIiwgbnVsbCwgXCIpXCIpO1xuICAgICAgcS5wdXNoKHtcbiAgICAgICAgaTogMSxcbiAgICAgICAgeDogZDNfaW50ZXJwb2xhdGVOdW1iZXIodGFbMF0sIHRiWzBdKVxuICAgICAgfSwge1xuICAgICAgICBpOiAzLFxuICAgICAgICB4OiBkM19pbnRlcnBvbGF0ZU51bWJlcih0YVsxXSwgdGJbMV0pXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRiWzBdIHx8IHRiWzFdKSB7XG4gICAgICBzLnB1c2goXCJ0cmFuc2xhdGUoXCIgKyB0YiArIFwiKVwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcy5wdXNoKFwiXCIpO1xuICAgIH1cbiAgICBpZiAocmEgIT0gcmIpIHtcbiAgICAgIGlmIChyYSAtIHJiID4gMTgwKSByYiArPSAzNjA7IGVsc2UgaWYgKHJiIC0gcmEgPiAxODApIHJhICs9IDM2MDtcbiAgICAgIHEucHVzaCh7XG4gICAgICAgIGk6IHMucHVzaChzLnBvcCgpICsgXCJyb3RhdGUoXCIsIG51bGwsIFwiKVwiKSAtIDIsXG4gICAgICAgIHg6IGQzX2ludGVycG9sYXRlTnVtYmVyKHJhLCByYilcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocmIpIHtcbiAgICAgIHMucHVzaChzLnBvcCgpICsgXCJyb3RhdGUoXCIgKyByYiArIFwiKVwiKTtcbiAgICB9XG4gICAgaWYgKHdhICE9IHdiKSB7XG4gICAgICBxLnB1c2goe1xuICAgICAgICBpOiBzLnB1c2gocy5wb3AoKSArIFwic2tld1goXCIsIG51bGwsIFwiKVwiKSAtIDIsXG4gICAgICAgIHg6IGQzX2ludGVycG9sYXRlTnVtYmVyKHdhLCB3YilcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAod2IpIHtcbiAgICAgIHMucHVzaChzLnBvcCgpICsgXCJza2V3WChcIiArIHdiICsgXCIpXCIpO1xuICAgIH1cbiAgICBpZiAoa2FbMF0gIT0ga2JbMF0gfHwga2FbMV0gIT0ga2JbMV0pIHtcbiAgICAgIG4gPSBzLnB1c2gocy5wb3AoKSArIFwic2NhbGUoXCIsIG51bGwsIFwiLFwiLCBudWxsLCBcIilcIik7XG4gICAgICBxLnB1c2goe1xuICAgICAgICBpOiBuIC0gNCxcbiAgICAgICAgeDogZDNfaW50ZXJwb2xhdGVOdW1iZXIoa2FbMF0sIGtiWzBdKVxuICAgICAgfSwge1xuICAgICAgICBpOiBuIC0gMixcbiAgICAgICAgeDogZDNfaW50ZXJwb2xhdGVOdW1iZXIoa2FbMV0sIGtiWzFdKVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChrYlswXSAhPSAxIHx8IGtiWzFdICE9IDEpIHtcbiAgICAgIHMucHVzaChzLnBvcCgpICsgXCJzY2FsZShcIiArIGtiICsgXCIpXCIpO1xuICAgIH1cbiAgICBuID0gcS5sZW5ndGg7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBpID0gLTEsIG87XG4gICAgICB3aGlsZSAoKytpIDwgbikgc1sobyA9IHFbaV0pLmldID0gby54KHQpO1xuICAgICAgcmV0dXJuIHMuam9pbihcIlwiKTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX3VuaW50ZXJwb2xhdGVOdW1iZXIoYSwgYikge1xuICAgIGIgPSBiIC0gKGEgPSArYSkgPyAxIC8gKGIgLSBhKSA6IDA7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiAoeCAtIGEpICogYjtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX3VuaW50ZXJwb2xhdGVDbGFtcChhLCBiKSB7XG4gICAgYiA9IGIgLSAoYSA9ICthKSA/IDEgLyAoYiAtIGEpIDogMDtcbiAgICByZXR1cm4gZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWluKDEsICh4IC0gYSkgKiBiKSk7XG4gICAgfTtcbiAgfVxuICBkMy5sYXlvdXQgPSB7fTtcbiAgZDMubGF5b3V0LmJ1bmRsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmdW5jdGlvbihsaW5rcykge1xuICAgICAgdmFyIHBhdGhzID0gW10sIGkgPSAtMSwgbiA9IGxpbmtzLmxlbmd0aDtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBwYXRocy5wdXNoKGQzX2xheW91dF9idW5kbGVQYXRoKGxpbmtzW2ldKSk7XG4gICAgICByZXR1cm4gcGF0aHM7XG4gICAgfTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2J1bmRsZVBhdGgobGluaykge1xuICAgIHZhciBzdGFydCA9IGxpbmsuc291cmNlLCBlbmQgPSBsaW5rLnRhcmdldCwgbGNhID0gZDNfbGF5b3V0X2J1bmRsZUxlYXN0Q29tbW9uQW5jZXN0b3Ioc3RhcnQsIGVuZCksIHBvaW50cyA9IFsgc3RhcnQgXTtcbiAgICB3aGlsZSAoc3RhcnQgIT09IGxjYSkge1xuICAgICAgc3RhcnQgPSBzdGFydC5wYXJlbnQ7XG4gICAgICBwb2ludHMucHVzaChzdGFydCk7XG4gICAgfVxuICAgIHZhciBrID0gcG9pbnRzLmxlbmd0aDtcbiAgICB3aGlsZSAoZW5kICE9PSBsY2EpIHtcbiAgICAgIHBvaW50cy5zcGxpY2UoaywgMCwgZW5kKTtcbiAgICAgIGVuZCA9IGVuZC5wYXJlbnQ7XG4gICAgfVxuICAgIHJldHVybiBwb2ludHM7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2J1bmRsZUFuY2VzdG9ycyhub2RlKSB7XG4gICAgdmFyIGFuY2VzdG9ycyA9IFtdLCBwYXJlbnQgPSBub2RlLnBhcmVudDtcbiAgICB3aGlsZSAocGFyZW50ICE9IG51bGwpIHtcbiAgICAgIGFuY2VzdG9ycy5wdXNoKG5vZGUpO1xuICAgICAgbm9kZSA9IHBhcmVudDtcbiAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7XG4gICAgfVxuICAgIGFuY2VzdG9ycy5wdXNoKG5vZGUpO1xuICAgIHJldHVybiBhbmNlc3RvcnM7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2J1bmRsZUxlYXN0Q29tbW9uQW5jZXN0b3IoYSwgYikge1xuICAgIGlmIChhID09PSBiKSByZXR1cm4gYTtcbiAgICB2YXIgYU5vZGVzID0gZDNfbGF5b3V0X2J1bmRsZUFuY2VzdG9ycyhhKSwgYk5vZGVzID0gZDNfbGF5b3V0X2J1bmRsZUFuY2VzdG9ycyhiKSwgYU5vZGUgPSBhTm9kZXMucG9wKCksIGJOb2RlID0gYk5vZGVzLnBvcCgpLCBzaGFyZWROb2RlID0gbnVsbDtcbiAgICB3aGlsZSAoYU5vZGUgPT09IGJOb2RlKSB7XG4gICAgICBzaGFyZWROb2RlID0gYU5vZGU7XG4gICAgICBhTm9kZSA9IGFOb2Rlcy5wb3AoKTtcbiAgICAgIGJOb2RlID0gYk5vZGVzLnBvcCgpO1xuICAgIH1cbiAgICByZXR1cm4gc2hhcmVkTm9kZTtcbiAgfVxuICBkMy5sYXlvdXQuY2hvcmQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgY2hvcmQgPSB7fSwgY2hvcmRzLCBncm91cHMsIG1hdHJpeCwgbiwgcGFkZGluZyA9IDAsIHNvcnRHcm91cHMsIHNvcnRTdWJncm91cHMsIHNvcnRDaG9yZHM7XG4gICAgZnVuY3Rpb24gcmVsYXlvdXQoKSB7XG4gICAgICB2YXIgc3ViZ3JvdXBzID0ge30sIGdyb3VwU3VtcyA9IFtdLCBncm91cEluZGV4ID0gZDMucmFuZ2UobiksIHN1Ymdyb3VwSW5kZXggPSBbXSwgaywgeCwgeDAsIGksIGo7XG4gICAgICBjaG9yZHMgPSBbXTtcbiAgICAgIGdyb3VwcyA9IFtdO1xuICAgICAgayA9IDAsIGkgPSAtMTtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgIHggPSAwLCBqID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2ogPCBuKSB7XG4gICAgICAgICAgeCArPSBtYXRyaXhbaV1bal07XG4gICAgICAgIH1cbiAgICAgICAgZ3JvdXBTdW1zLnB1c2goeCk7XG4gICAgICAgIHN1Ymdyb3VwSW5kZXgucHVzaChkMy5yYW5nZShuKSk7XG4gICAgICAgIGsgKz0geDtcbiAgICAgIH1cbiAgICAgIGlmIChzb3J0R3JvdXBzKSB7XG4gICAgICAgIGdyb3VwSW5kZXguc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgICAgICAgcmV0dXJuIHNvcnRHcm91cHMoZ3JvdXBTdW1zW2FdLCBncm91cFN1bXNbYl0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChzb3J0U3ViZ3JvdXBzKSB7XG4gICAgICAgIHN1Ymdyb3VwSW5kZXguZm9yRWFjaChmdW5jdGlvbihkLCBpKSB7XG4gICAgICAgICAgZC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBzb3J0U3ViZ3JvdXBzKG1hdHJpeFtpXVthXSwgbWF0cml4W2ldW2JdKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBrID0gKDIgKiDPgCAtIHBhZGRpbmcgKiBuKSAvIGs7XG4gICAgICB4ID0gMCwgaSA9IC0xO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgeDAgPSB4LCBqID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2ogPCBuKSB7XG4gICAgICAgICAgdmFyIGRpID0gZ3JvdXBJbmRleFtpXSwgZGogPSBzdWJncm91cEluZGV4W2RpXVtqXSwgdiA9IG1hdHJpeFtkaV1bZGpdLCBhMCA9IHgsIGExID0geCArPSB2ICogaztcbiAgICAgICAgICBzdWJncm91cHNbZGkgKyBcIi1cIiArIGRqXSA9IHtcbiAgICAgICAgICAgIGluZGV4OiBkaSxcbiAgICAgICAgICAgIHN1YmluZGV4OiBkaixcbiAgICAgICAgICAgIHN0YXJ0QW5nbGU6IGEwLFxuICAgICAgICAgICAgZW5kQW5nbGU6IGExLFxuICAgICAgICAgICAgdmFsdWU6IHZcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGdyb3Vwc1tkaV0gPSB7XG4gICAgICAgICAgaW5kZXg6IGRpLFxuICAgICAgICAgIHN0YXJ0QW5nbGU6IHgwLFxuICAgICAgICAgIGVuZEFuZ2xlOiB4LFxuICAgICAgICAgIHZhbHVlOiAoeCAtIHgwKSAvIGtcbiAgICAgICAgfTtcbiAgICAgICAgeCArPSBwYWRkaW5nO1xuICAgICAgfVxuICAgICAgaSA9IC0xO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgaiA9IGkgLSAxO1xuICAgICAgICB3aGlsZSAoKytqIDwgbikge1xuICAgICAgICAgIHZhciBzb3VyY2UgPSBzdWJncm91cHNbaSArIFwiLVwiICsgal0sIHRhcmdldCA9IHN1Ymdyb3Vwc1tqICsgXCItXCIgKyBpXTtcbiAgICAgICAgICBpZiAoc291cmNlLnZhbHVlIHx8IHRhcmdldC52YWx1ZSkge1xuICAgICAgICAgICAgY2hvcmRzLnB1c2goc291cmNlLnZhbHVlIDwgdGFyZ2V0LnZhbHVlID8ge1xuICAgICAgICAgICAgICBzb3VyY2U6IHRhcmdldCxcbiAgICAgICAgICAgICAgdGFyZ2V0OiBzb3VyY2VcbiAgICAgICAgICAgIH0gOiB7XG4gICAgICAgICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgICAgICAgICB0YXJnZXQ6IHRhcmdldFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc29ydENob3JkcykgcmVzb3J0KCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlc29ydCgpIHtcbiAgICAgIGNob3Jkcy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHNvcnRDaG9yZHMoKGEuc291cmNlLnZhbHVlICsgYS50YXJnZXQudmFsdWUpIC8gMiwgKGIuc291cmNlLnZhbHVlICsgYi50YXJnZXQudmFsdWUpIC8gMik7XG4gICAgICB9KTtcbiAgICB9XG4gICAgY2hvcmQubWF0cml4ID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbWF0cml4O1xuICAgICAgbiA9IChtYXRyaXggPSB4KSAmJiBtYXRyaXgubGVuZ3RoO1xuICAgICAgY2hvcmRzID0gZ3JvdXBzID0gbnVsbDtcbiAgICAgIHJldHVybiBjaG9yZDtcbiAgICB9O1xuICAgIGNob3JkLnBhZGRpbmcgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBwYWRkaW5nO1xuICAgICAgcGFkZGluZyA9IHg7XG4gICAgICBjaG9yZHMgPSBncm91cHMgPSBudWxsO1xuICAgICAgcmV0dXJuIGNob3JkO1xuICAgIH07XG4gICAgY2hvcmQuc29ydEdyb3VwcyA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNvcnRHcm91cHM7XG4gICAgICBzb3J0R3JvdXBzID0geDtcbiAgICAgIGNob3JkcyA9IGdyb3VwcyA9IG51bGw7XG4gICAgICByZXR1cm4gY2hvcmQ7XG4gICAgfTtcbiAgICBjaG9yZC5zb3J0U3ViZ3JvdXBzID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc29ydFN1Ymdyb3VwcztcbiAgICAgIHNvcnRTdWJncm91cHMgPSB4O1xuICAgICAgY2hvcmRzID0gbnVsbDtcbiAgICAgIHJldHVybiBjaG9yZDtcbiAgICB9O1xuICAgIGNob3JkLnNvcnRDaG9yZHMgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzb3J0Q2hvcmRzO1xuICAgICAgc29ydENob3JkcyA9IHg7XG4gICAgICBpZiAoY2hvcmRzKSByZXNvcnQoKTtcbiAgICAgIHJldHVybiBjaG9yZDtcbiAgICB9O1xuICAgIGNob3JkLmNob3JkcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCFjaG9yZHMpIHJlbGF5b3V0KCk7XG4gICAgICByZXR1cm4gY2hvcmRzO1xuICAgIH07XG4gICAgY2hvcmQuZ3JvdXBzID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIWdyb3VwcykgcmVsYXlvdXQoKTtcbiAgICAgIHJldHVybiBncm91cHM7XG4gICAgfTtcbiAgICByZXR1cm4gY2hvcmQ7XG4gIH07XG4gIGQzLmxheW91dC5mb3JjZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBmb3JjZSA9IHt9LCBldmVudCA9IGQzLmRpc3BhdGNoKFwic3RhcnRcIiwgXCJ0aWNrXCIsIFwiZW5kXCIpLCBzaXplID0gWyAxLCAxIF0sIGRyYWcsIGFscGhhLCBmcmljdGlvbiA9IC45LCBsaW5rRGlzdGFuY2UgPSBkM19sYXlvdXRfZm9yY2VMaW5rRGlzdGFuY2UsIGxpbmtTdHJlbmd0aCA9IGQzX2xheW91dF9mb3JjZUxpbmtTdHJlbmd0aCwgY2hhcmdlID0gLTMwLCBncmF2aXR5ID0gLjEsIHRoZXRhID0gLjgsIG5vZGVzID0gW10sIGxpbmtzID0gW10sIGRpc3RhbmNlcywgc3RyZW5ndGhzLCBjaGFyZ2VzO1xuICAgIGZ1bmN0aW9uIHJlcHVsc2Uobm9kZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHF1YWQsIHgxLCBfLCB4Mikge1xuICAgICAgICBpZiAocXVhZC5wb2ludCAhPT0gbm9kZSkge1xuICAgICAgICAgIHZhciBkeCA9IHF1YWQuY3ggLSBub2RlLngsIGR5ID0gcXVhZC5jeSAtIG5vZGUueSwgZG4gPSAxIC8gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbiAgICAgICAgICBpZiAoKHgyIC0geDEpICogZG4gPCB0aGV0YSkge1xuICAgICAgICAgICAgdmFyIGsgPSBxdWFkLmNoYXJnZSAqIGRuICogZG47XG4gICAgICAgICAgICBub2RlLnB4IC09IGR4ICogaztcbiAgICAgICAgICAgIG5vZGUucHkgLT0gZHkgKiBrO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChxdWFkLnBvaW50ICYmIGlzRmluaXRlKGRuKSkge1xuICAgICAgICAgICAgdmFyIGsgPSBxdWFkLnBvaW50Q2hhcmdlICogZG4gKiBkbjtcbiAgICAgICAgICAgIG5vZGUucHggLT0gZHggKiBrO1xuICAgICAgICAgICAgbm9kZS5weSAtPSBkeSAqIGs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhcXVhZC5jaGFyZ2U7XG4gICAgICB9O1xuICAgIH1cbiAgICBmb3JjZS50aWNrID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoKGFscGhhICo9IC45OSkgPCAuMDA1KSB7XG4gICAgICAgIGV2ZW50LmVuZCh7XG4gICAgICAgICAgdHlwZTogXCJlbmRcIixcbiAgICAgICAgICBhbHBoYTogYWxwaGEgPSAwXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBuID0gbm9kZXMubGVuZ3RoLCBtID0gbGlua3MubGVuZ3RoLCBxLCBpLCBvLCBzLCB0LCBsLCBrLCB4LCB5O1xuICAgICAgZm9yIChpID0gMDsgaSA8IG07ICsraSkge1xuICAgICAgICBvID0gbGlua3NbaV07XG4gICAgICAgIHMgPSBvLnNvdXJjZTtcbiAgICAgICAgdCA9IG8udGFyZ2V0O1xuICAgICAgICB4ID0gdC54IC0gcy54O1xuICAgICAgICB5ID0gdC55IC0gcy55O1xuICAgICAgICBpZiAobCA9IHggKiB4ICsgeSAqIHkpIHtcbiAgICAgICAgICBsID0gYWxwaGEgKiBzdHJlbmd0aHNbaV0gKiAoKGwgPSBNYXRoLnNxcnQobCkpIC0gZGlzdGFuY2VzW2ldKSAvIGw7XG4gICAgICAgICAgeCAqPSBsO1xuICAgICAgICAgIHkgKj0gbDtcbiAgICAgICAgICB0LnggLT0geCAqIChrID0gcy53ZWlnaHQgLyAodC53ZWlnaHQgKyBzLndlaWdodCkpO1xuICAgICAgICAgIHQueSAtPSB5ICogaztcbiAgICAgICAgICBzLnggKz0geCAqIChrID0gMSAtIGspO1xuICAgICAgICAgIHMueSArPSB5ICogaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGsgPSBhbHBoYSAqIGdyYXZpdHkpIHtcbiAgICAgICAgeCA9IHNpemVbMF0gLyAyO1xuICAgICAgICB5ID0gc2l6ZVsxXSAvIDI7XG4gICAgICAgIGkgPSAtMTtcbiAgICAgICAgaWYgKGspIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgbyA9IG5vZGVzW2ldO1xuICAgICAgICAgIG8ueCArPSAoeCAtIG8ueCkgKiBrO1xuICAgICAgICAgIG8ueSArPSAoeSAtIG8ueSkgKiBrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoY2hhcmdlKSB7XG4gICAgICAgIGQzX2xheW91dF9mb3JjZUFjY3VtdWxhdGUocSA9IGQzLmdlb20ucXVhZHRyZWUobm9kZXMpLCBhbHBoYSwgY2hhcmdlcyk7XG4gICAgICAgIGkgPSAtMTtcbiAgICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgICBpZiAoIShvID0gbm9kZXNbaV0pLmZpeGVkKSB7XG4gICAgICAgICAgICBxLnZpc2l0KHJlcHVsc2UobykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaSA9IC0xO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgbyA9IG5vZGVzW2ldO1xuICAgICAgICBpZiAoby5maXhlZCkge1xuICAgICAgICAgIG8ueCA9IG8ucHg7XG4gICAgICAgICAgby55ID0gby5weTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvLnggLT0gKG8ucHggLSAoby5weCA9IG8ueCkpICogZnJpY3Rpb247XG4gICAgICAgICAgby55IC09IChvLnB5IC0gKG8ucHkgPSBvLnkpKSAqIGZyaWN0aW9uO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBldmVudC50aWNrKHtcbiAgICAgICAgdHlwZTogXCJ0aWNrXCIsXG4gICAgICAgIGFscGhhOiBhbHBoYVxuICAgICAgfSk7XG4gICAgfTtcbiAgICBmb3JjZS5ub2RlcyA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIG5vZGVzO1xuICAgICAgbm9kZXMgPSB4O1xuICAgICAgcmV0dXJuIGZvcmNlO1xuICAgIH07XG4gICAgZm9yY2UubGlua3MgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsaW5rcztcbiAgICAgIGxpbmtzID0geDtcbiAgICAgIHJldHVybiBmb3JjZTtcbiAgICB9O1xuICAgIGZvcmNlLnNpemUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzaXplO1xuICAgICAgc2l6ZSA9IHg7XG4gICAgICByZXR1cm4gZm9yY2U7XG4gICAgfTtcbiAgICBmb3JjZS5saW5rRGlzdGFuY2UgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsaW5rRGlzdGFuY2U7XG4gICAgICBsaW5rRGlzdGFuY2UgPSB0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiID8geCA6ICt4O1xuICAgICAgcmV0dXJuIGZvcmNlO1xuICAgIH07XG4gICAgZm9yY2UuZGlzdGFuY2UgPSBmb3JjZS5saW5rRGlzdGFuY2U7XG4gICAgZm9yY2UubGlua1N0cmVuZ3RoID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbGlua1N0cmVuZ3RoO1xuICAgICAgbGlua1N0cmVuZ3RoID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiAreDtcbiAgICAgIHJldHVybiBmb3JjZTtcbiAgICB9O1xuICAgIGZvcmNlLmZyaWN0aW9uID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZnJpY3Rpb247XG4gICAgICBmcmljdGlvbiA9ICt4O1xuICAgICAgcmV0dXJuIGZvcmNlO1xuICAgIH07XG4gICAgZm9yY2UuY2hhcmdlID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2hhcmdlO1xuICAgICAgY2hhcmdlID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiAreDtcbiAgICAgIHJldHVybiBmb3JjZTtcbiAgICB9O1xuICAgIGZvcmNlLmdyYXZpdHkgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBncmF2aXR5O1xuICAgICAgZ3Jhdml0eSA9ICt4O1xuICAgICAgcmV0dXJuIGZvcmNlO1xuICAgIH07XG4gICAgZm9yY2UudGhldGEgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGV0YTtcbiAgICAgIHRoZXRhID0gK3g7XG4gICAgICByZXR1cm4gZm9yY2U7XG4gICAgfTtcbiAgICBmb3JjZS5hbHBoYSA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGFscGhhO1xuICAgICAgeCA9ICt4O1xuICAgICAgaWYgKGFscGhhKSB7XG4gICAgICAgIGlmICh4ID4gMCkgYWxwaGEgPSB4OyBlbHNlIGFscGhhID0gMDtcbiAgICAgIH0gZWxzZSBpZiAoeCA+IDApIHtcbiAgICAgICAgZXZlbnQuc3RhcnQoe1xuICAgICAgICAgIHR5cGU6IFwic3RhcnRcIixcbiAgICAgICAgICBhbHBoYTogYWxwaGEgPSB4XG4gICAgICAgIH0pO1xuICAgICAgICBkMy50aW1lcihmb3JjZS50aWNrKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmb3JjZTtcbiAgICB9O1xuICAgIGZvcmNlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgaiwgbiA9IG5vZGVzLmxlbmd0aCwgbSA9IGxpbmtzLmxlbmd0aCwgdyA9IHNpemVbMF0sIGggPSBzaXplWzFdLCBuZWlnaGJvcnMsIG87XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIChvID0gbm9kZXNbaV0pLmluZGV4ID0gaTtcbiAgICAgICAgby53ZWlnaHQgPSAwO1xuICAgICAgfVxuICAgICAgZm9yIChpID0gMDsgaSA8IG07ICsraSkge1xuICAgICAgICBvID0gbGlua3NbaV07XG4gICAgICAgIGlmICh0eXBlb2Ygby5zb3VyY2UgPT0gXCJudW1iZXJcIikgby5zb3VyY2UgPSBub2Rlc1tvLnNvdXJjZV07XG4gICAgICAgIGlmICh0eXBlb2Ygby50YXJnZXQgPT0gXCJudW1iZXJcIikgby50YXJnZXQgPSBub2Rlc1tvLnRhcmdldF07XG4gICAgICAgICsrby5zb3VyY2Uud2VpZ2h0O1xuICAgICAgICArK28udGFyZ2V0LndlaWdodDtcbiAgICAgIH1cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgbyA9IG5vZGVzW2ldO1xuICAgICAgICBpZiAoaXNOYU4oby54KSkgby54ID0gcG9zaXRpb24oXCJ4XCIsIHcpO1xuICAgICAgICBpZiAoaXNOYU4oby55KSkgby55ID0gcG9zaXRpb24oXCJ5XCIsIGgpO1xuICAgICAgICBpZiAoaXNOYU4oby5weCkpIG8ucHggPSBvLng7XG4gICAgICAgIGlmIChpc05hTihvLnB5KSkgby5weSA9IG8ueTtcbiAgICAgIH1cbiAgICAgIGRpc3RhbmNlcyA9IFtdO1xuICAgICAgaWYgKHR5cGVvZiBsaW5rRGlzdGFuY2UgPT09IFwiZnVuY3Rpb25cIikgZm9yIChpID0gMDsgaSA8IG07ICsraSkgZGlzdGFuY2VzW2ldID0gK2xpbmtEaXN0YW5jZS5jYWxsKHRoaXMsIGxpbmtzW2ldLCBpKTsgZWxzZSBmb3IgKGkgPSAwOyBpIDwgbTsgKytpKSBkaXN0YW5jZXNbaV0gPSBsaW5rRGlzdGFuY2U7XG4gICAgICBzdHJlbmd0aHMgPSBbXTtcbiAgICAgIGlmICh0eXBlb2YgbGlua1N0cmVuZ3RoID09PSBcImZ1bmN0aW9uXCIpIGZvciAoaSA9IDA7IGkgPCBtOyArK2kpIHN0cmVuZ3Roc1tpXSA9ICtsaW5rU3RyZW5ndGguY2FsbCh0aGlzLCBsaW5rc1tpXSwgaSk7IGVsc2UgZm9yIChpID0gMDsgaSA8IG07ICsraSkgc3RyZW5ndGhzW2ldID0gbGlua1N0cmVuZ3RoO1xuICAgICAgY2hhcmdlcyA9IFtdO1xuICAgICAgaWYgKHR5cGVvZiBjaGFyZ2UgPT09IFwiZnVuY3Rpb25cIikgZm9yIChpID0gMDsgaSA8IG47ICsraSkgY2hhcmdlc1tpXSA9ICtjaGFyZ2UuY2FsbCh0aGlzLCBub2Rlc1tpXSwgaSk7IGVsc2UgZm9yIChpID0gMDsgaSA8IG47ICsraSkgY2hhcmdlc1tpXSA9IGNoYXJnZTtcbiAgICAgIGZ1bmN0aW9uIHBvc2l0aW9uKGRpbWVuc2lvbiwgc2l6ZSkge1xuICAgICAgICB2YXIgbmVpZ2hib3JzID0gbmVpZ2hib3IoaSksIGogPSAtMSwgbSA9IG5laWdoYm9ycy5sZW5ndGgsIHg7XG4gICAgICAgIHdoaWxlICgrK2ogPCBtKSBpZiAoIWlzTmFOKHggPSBuZWlnaGJvcnNbal1bZGltZW5zaW9uXSkpIHJldHVybiB4O1xuICAgICAgICByZXR1cm4gTWF0aC5yYW5kb20oKSAqIHNpemU7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBuZWlnaGJvcigpIHtcbiAgICAgICAgaWYgKCFuZWlnaGJvcnMpIHtcbiAgICAgICAgICBuZWlnaGJvcnMgPSBbXTtcbiAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbjsgKytqKSB7XG4gICAgICAgICAgICBuZWlnaGJvcnNbal0gPSBbXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yIChqID0gMDsgaiA8IG07ICsraikge1xuICAgICAgICAgICAgdmFyIG8gPSBsaW5rc1tqXTtcbiAgICAgICAgICAgIG5laWdoYm9yc1tvLnNvdXJjZS5pbmRleF0ucHVzaChvLnRhcmdldCk7XG4gICAgICAgICAgICBuZWlnaGJvcnNbby50YXJnZXQuaW5kZXhdLnB1c2goby5zb3VyY2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmVpZ2hib3JzW2ldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZvcmNlLnJlc3VtZSgpO1xuICAgIH07XG4gICAgZm9yY2UucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZm9yY2UuYWxwaGEoLjEpO1xuICAgIH07XG4gICAgZm9yY2Uuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGZvcmNlLmFscGhhKDApO1xuICAgIH07XG4gICAgZm9yY2UuZHJhZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCFkcmFnKSBkcmFnID0gZDMuYmVoYXZpb3IuZHJhZygpLm9yaWdpbihkM19pZGVudGl0eSkub24oXCJkcmFnc3RhcnQuZm9yY2VcIiwgZDNfbGF5b3V0X2ZvcmNlRHJhZ3N0YXJ0KS5vbihcImRyYWcuZm9yY2VcIiwgZHJhZ21vdmUpLm9uKFwiZHJhZ2VuZC5mb3JjZVwiLCBkM19sYXlvdXRfZm9yY2VEcmFnZW5kKTtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGRyYWc7XG4gICAgICB0aGlzLm9uKFwibW91c2VvdmVyLmZvcmNlXCIsIGQzX2xheW91dF9mb3JjZU1vdXNlb3Zlcikub24oXCJtb3VzZW91dC5mb3JjZVwiLCBkM19sYXlvdXRfZm9yY2VNb3VzZW91dCkuY2FsbChkcmFnKTtcbiAgICB9O1xuICAgIGZ1bmN0aW9uIGRyYWdtb3ZlKGQpIHtcbiAgICAgIGQucHggPSBkMy5ldmVudC54LCBkLnB5ID0gZDMuZXZlbnQueTtcbiAgICAgIGZvcmNlLnJlc3VtZSgpO1xuICAgIH1cbiAgICByZXR1cm4gZDMucmViaW5kKGZvcmNlLCBldmVudCwgXCJvblwiKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2ZvcmNlRHJhZ3N0YXJ0KGQpIHtcbiAgICBkLmZpeGVkIHw9IDI7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2ZvcmNlRHJhZ2VuZChkKSB7XG4gICAgZC5maXhlZCAmPSB+NjtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfZm9yY2VNb3VzZW92ZXIoZCkge1xuICAgIGQuZml4ZWQgfD0gNDtcbiAgICBkLnB4ID0gZC54LCBkLnB5ID0gZC55O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9mb3JjZU1vdXNlb3V0KGQpIHtcbiAgICBkLmZpeGVkICY9IH40O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9mb3JjZUFjY3VtdWxhdGUocXVhZCwgYWxwaGEsIGNoYXJnZXMpIHtcbiAgICB2YXIgY3ggPSAwLCBjeSA9IDA7XG4gICAgcXVhZC5jaGFyZ2UgPSAwO1xuICAgIGlmICghcXVhZC5sZWFmKSB7XG4gICAgICB2YXIgbm9kZXMgPSBxdWFkLm5vZGVzLCBuID0gbm9kZXMubGVuZ3RoLCBpID0gLTEsIGM7XG4gICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICBjID0gbm9kZXNbaV07XG4gICAgICAgIGlmIChjID09IG51bGwpIGNvbnRpbnVlO1xuICAgICAgICBkM19sYXlvdXRfZm9yY2VBY2N1bXVsYXRlKGMsIGFscGhhLCBjaGFyZ2VzKTtcbiAgICAgICAgcXVhZC5jaGFyZ2UgKz0gYy5jaGFyZ2U7XG4gICAgICAgIGN4ICs9IGMuY2hhcmdlICogYy5jeDtcbiAgICAgICAgY3kgKz0gYy5jaGFyZ2UgKiBjLmN5O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocXVhZC5wb2ludCkge1xuICAgICAgaWYgKCFxdWFkLmxlYWYpIHtcbiAgICAgICAgcXVhZC5wb2ludC54ICs9IE1hdGgucmFuZG9tKCkgLSAuNTtcbiAgICAgICAgcXVhZC5wb2ludC55ICs9IE1hdGgucmFuZG9tKCkgLSAuNTtcbiAgICAgIH1cbiAgICAgIHZhciBrID0gYWxwaGEgKiBjaGFyZ2VzW3F1YWQucG9pbnQuaW5kZXhdO1xuICAgICAgcXVhZC5jaGFyZ2UgKz0gcXVhZC5wb2ludENoYXJnZSA9IGs7XG4gICAgICBjeCArPSBrICogcXVhZC5wb2ludC54O1xuICAgICAgY3kgKz0gayAqIHF1YWQucG9pbnQueTtcbiAgICB9XG4gICAgcXVhZC5jeCA9IGN4IC8gcXVhZC5jaGFyZ2U7XG4gICAgcXVhZC5jeSA9IGN5IC8gcXVhZC5jaGFyZ2U7XG4gIH1cbiAgdmFyIGQzX2xheW91dF9mb3JjZUxpbmtEaXN0YW5jZSA9IDIwLCBkM19sYXlvdXRfZm9yY2VMaW5rU3RyZW5ndGggPSAxO1xuICBkMy5sYXlvdXQuaGllcmFyY2h5ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNvcnQgPSBkM19sYXlvdXRfaGllcmFyY2h5U29ydCwgY2hpbGRyZW4gPSBkM19sYXlvdXRfaGllcmFyY2h5Q2hpbGRyZW4sIHZhbHVlID0gZDNfbGF5b3V0X2hpZXJhcmNoeVZhbHVlO1xuICAgIGZ1bmN0aW9uIHJlY3Vyc2Uobm9kZSwgZGVwdGgsIG5vZGVzKSB7XG4gICAgICB2YXIgY2hpbGRzID0gY2hpbGRyZW4uY2FsbChoaWVyYXJjaHksIG5vZGUsIGRlcHRoKTtcbiAgICAgIG5vZGUuZGVwdGggPSBkZXB0aDtcbiAgICAgIG5vZGVzLnB1c2gobm9kZSk7XG4gICAgICBpZiAoY2hpbGRzICYmIChuID0gY2hpbGRzLmxlbmd0aCkpIHtcbiAgICAgICAgdmFyIGkgPSAtMSwgbiwgYyA9IG5vZGUuY2hpbGRyZW4gPSBbXSwgdiA9IDAsIGogPSBkZXB0aCArIDEsIGQ7XG4gICAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgZCA9IHJlY3Vyc2UoY2hpbGRzW2ldLCBqLCBub2Rlcyk7XG4gICAgICAgICAgZC5wYXJlbnQgPSBub2RlO1xuICAgICAgICAgIGMucHVzaChkKTtcbiAgICAgICAgICB2ICs9IGQudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNvcnQpIGMuc29ydChzb3J0KTtcbiAgICAgICAgaWYgKHZhbHVlKSBub2RlLnZhbHVlID0gdjtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUpIHtcbiAgICAgICAgbm9kZS52YWx1ZSA9ICt2YWx1ZS5jYWxsKGhpZXJhcmNoeSwgbm9kZSwgZGVwdGgpIHx8IDA7XG4gICAgICB9XG4gICAgICByZXR1cm4gbm9kZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcmV2YWx1ZShub2RlLCBkZXB0aCkge1xuICAgICAgdmFyIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbiwgdiA9IDA7XG4gICAgICBpZiAoY2hpbGRyZW4gJiYgKG4gPSBjaGlsZHJlbi5sZW5ndGgpKSB7XG4gICAgICAgIHZhciBpID0gLTEsIG4sIGogPSBkZXB0aCArIDE7XG4gICAgICAgIHdoaWxlICgrK2kgPCBuKSB2ICs9IHJldmFsdWUoY2hpbGRyZW5baV0sIGopO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZSkge1xuICAgICAgICB2ID0gK3ZhbHVlLmNhbGwoaGllcmFyY2h5LCBub2RlLCBkZXB0aCkgfHwgMDtcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZSkgbm9kZS52YWx1ZSA9IHY7XG4gICAgICByZXR1cm4gdjtcbiAgICB9XG4gICAgZnVuY3Rpb24gaGllcmFyY2h5KGQpIHtcbiAgICAgIHZhciBub2RlcyA9IFtdO1xuICAgICAgcmVjdXJzZShkLCAwLCBub2Rlcyk7XG4gICAgICByZXR1cm4gbm9kZXM7XG4gICAgfVxuICAgIGhpZXJhcmNoeS5zb3J0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc29ydDtcbiAgICAgIHNvcnQgPSB4O1xuICAgICAgcmV0dXJuIGhpZXJhcmNoeTtcbiAgICB9O1xuICAgIGhpZXJhcmNoeS5jaGlsZHJlbiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGNoaWxkcmVuO1xuICAgICAgY2hpbGRyZW4gPSB4O1xuICAgICAgcmV0dXJuIGhpZXJhcmNoeTtcbiAgICB9O1xuICAgIGhpZXJhcmNoeS52YWx1ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHZhbHVlO1xuICAgICAgdmFsdWUgPSB4O1xuICAgICAgcmV0dXJuIGhpZXJhcmNoeTtcbiAgICB9O1xuICAgIGhpZXJhcmNoeS5yZXZhbHVlID0gZnVuY3Rpb24ocm9vdCkge1xuICAgICAgcmV2YWx1ZShyb290LCAwKTtcbiAgICAgIHJldHVybiByb290O1xuICAgIH07XG4gICAgcmV0dXJuIGhpZXJhcmNoeTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2hpZXJhcmNoeVJlYmluZChvYmplY3QsIGhpZXJhcmNoeSkge1xuICAgIGQzLnJlYmluZChvYmplY3QsIGhpZXJhcmNoeSwgXCJzb3J0XCIsIFwiY2hpbGRyZW5cIiwgXCJ2YWx1ZVwiKTtcbiAgICBvYmplY3Qubm9kZXMgPSBvYmplY3Q7XG4gICAgb2JqZWN0LmxpbmtzID0gZDNfbGF5b3V0X2hpZXJhcmNoeUxpbmtzO1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2hpZXJhcmNoeUNoaWxkcmVuKGQpIHtcbiAgICByZXR1cm4gZC5jaGlsZHJlbjtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfaGllcmFyY2h5VmFsdWUoZCkge1xuICAgIHJldHVybiBkLnZhbHVlO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9oaWVyYXJjaHlTb3J0KGEsIGIpIHtcbiAgICByZXR1cm4gYi52YWx1ZSAtIGEudmFsdWU7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2hpZXJhcmNoeUxpbmtzKG5vZGVzKSB7XG4gICAgcmV0dXJuIGQzLm1lcmdlKG5vZGVzLm1hcChmdW5jdGlvbihwYXJlbnQpIHtcbiAgICAgIHJldHVybiAocGFyZW50LmNoaWxkcmVuIHx8IFtdKS5tYXAoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzb3VyY2U6IHBhcmVudCxcbiAgICAgICAgICB0YXJnZXQ6IGNoaWxkXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9KSk7XG4gIH1cbiAgZDMubGF5b3V0LnBhcnRpdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBoaWVyYXJjaHkgPSBkMy5sYXlvdXQuaGllcmFyY2h5KCksIHNpemUgPSBbIDEsIDEgXTtcbiAgICBmdW5jdGlvbiBwb3NpdGlvbihub2RlLCB4LCBkeCwgZHkpIHtcbiAgICAgIHZhciBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW47XG4gICAgICBub2RlLnggPSB4O1xuICAgICAgbm9kZS55ID0gbm9kZS5kZXB0aCAqIGR5O1xuICAgICAgbm9kZS5keCA9IGR4O1xuICAgICAgbm9kZS5keSA9IGR5O1xuICAgICAgaWYgKGNoaWxkcmVuICYmIChuID0gY2hpbGRyZW4ubGVuZ3RoKSkge1xuICAgICAgICB2YXIgaSA9IC0xLCBuLCBjLCBkO1xuICAgICAgICBkeCA9IG5vZGUudmFsdWUgPyBkeCAvIG5vZGUudmFsdWUgOiAwO1xuICAgICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAgIHBvc2l0aW9uKGMgPSBjaGlsZHJlbltpXSwgeCwgZCA9IGMudmFsdWUgKiBkeCwgZHkpO1xuICAgICAgICAgIHggKz0gZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBkZXB0aChub2RlKSB7XG4gICAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuLCBkID0gMDtcbiAgICAgIGlmIChjaGlsZHJlbiAmJiAobiA9IGNoaWxkcmVuLmxlbmd0aCkpIHtcbiAgICAgICAgdmFyIGkgPSAtMSwgbjtcbiAgICAgICAgd2hpbGUgKCsraSA8IG4pIGQgPSBNYXRoLm1heChkLCBkZXB0aChjaGlsZHJlbltpXSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIDEgKyBkO1xuICAgIH1cbiAgICBmdW5jdGlvbiBwYXJ0aXRpb24oZCwgaSkge1xuICAgICAgdmFyIG5vZGVzID0gaGllcmFyY2h5LmNhbGwodGhpcywgZCwgaSk7XG4gICAgICBwb3NpdGlvbihub2Rlc1swXSwgMCwgc2l6ZVswXSwgc2l6ZVsxXSAvIGRlcHRoKG5vZGVzWzBdKSk7XG4gICAgICByZXR1cm4gbm9kZXM7XG4gICAgfVxuICAgIHBhcnRpdGlvbi5zaXplID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2l6ZTtcbiAgICAgIHNpemUgPSB4O1xuICAgICAgcmV0dXJuIHBhcnRpdGlvbjtcbiAgICB9O1xuICAgIHJldHVybiBkM19sYXlvdXRfaGllcmFyY2h5UmViaW5kKHBhcnRpdGlvbiwgaGllcmFyY2h5KTtcbiAgfTtcbiAgZDMubGF5b3V0LnBpZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB2YWx1ZSA9IE51bWJlciwgc29ydCA9IGQzX2xheW91dF9waWVTb3J0QnlWYWx1ZSwgc3RhcnRBbmdsZSA9IDAsIGVuZEFuZ2xlID0gMiAqIM+AO1xuICAgIGZ1bmN0aW9uIHBpZShkYXRhKSB7XG4gICAgICB2YXIgdmFsdWVzID0gZGF0YS5tYXAoZnVuY3Rpb24oZCwgaSkge1xuICAgICAgICByZXR1cm4gK3ZhbHVlLmNhbGwocGllLCBkLCBpKTtcbiAgICAgIH0pO1xuICAgICAgdmFyIGEgPSArKHR5cGVvZiBzdGFydEFuZ2xlID09PSBcImZ1bmN0aW9uXCIgPyBzdGFydEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBzdGFydEFuZ2xlKTtcbiAgICAgIHZhciBrID0gKCh0eXBlb2YgZW5kQW5nbGUgPT09IFwiZnVuY3Rpb25cIiA/IGVuZEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBlbmRBbmdsZSkgLSBhKSAvIGQzLnN1bSh2YWx1ZXMpO1xuICAgICAgdmFyIGluZGV4ID0gZDMucmFuZ2UoZGF0YS5sZW5ndGgpO1xuICAgICAgaWYgKHNvcnQgIT0gbnVsbCkgaW5kZXguc29ydChzb3J0ID09PSBkM19sYXlvdXRfcGllU29ydEJ5VmFsdWUgPyBmdW5jdGlvbihpLCBqKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXNbal0gLSB2YWx1ZXNbaV07XG4gICAgICB9IDogZnVuY3Rpb24oaSwgaikge1xuICAgICAgICByZXR1cm4gc29ydChkYXRhW2ldLCBkYXRhW2pdKTtcbiAgICAgIH0pO1xuICAgICAgdmFyIGFyY3MgPSBbXTtcbiAgICAgIGluZGV4LmZvckVhY2goZnVuY3Rpb24oaSkge1xuICAgICAgICB2YXIgZDtcbiAgICAgICAgYXJjc1tpXSA9IHtcbiAgICAgICAgICBkYXRhOiBkYXRhW2ldLFxuICAgICAgICAgIHZhbHVlOiBkID0gdmFsdWVzW2ldLFxuICAgICAgICAgIHN0YXJ0QW5nbGU6IGEsXG4gICAgICAgICAgZW5kQW5nbGU6IGEgKz0gZCAqIGtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFyY3M7XG4gICAgfVxuICAgIHBpZS52YWx1ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHZhbHVlO1xuICAgICAgdmFsdWUgPSB4O1xuICAgICAgcmV0dXJuIHBpZTtcbiAgICB9O1xuICAgIHBpZS5zb3J0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc29ydDtcbiAgICAgIHNvcnQgPSB4O1xuICAgICAgcmV0dXJuIHBpZTtcbiAgICB9O1xuICAgIHBpZS5zdGFydEFuZ2xlID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc3RhcnRBbmdsZTtcbiAgICAgIHN0YXJ0QW5nbGUgPSB4O1xuICAgICAgcmV0dXJuIHBpZTtcbiAgICB9O1xuICAgIHBpZS5lbmRBbmdsZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGVuZEFuZ2xlO1xuICAgICAgZW5kQW5nbGUgPSB4O1xuICAgICAgcmV0dXJuIHBpZTtcbiAgICB9O1xuICAgIHJldHVybiBwaWU7XG4gIH07XG4gIHZhciBkM19sYXlvdXRfcGllU29ydEJ5VmFsdWUgPSB7fTtcbiAgZDMubGF5b3V0LnN0YWNrID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZhbHVlcyA9IGQzX2lkZW50aXR5LCBvcmRlciA9IGQzX2xheW91dF9zdGFja09yZGVyRGVmYXVsdCwgb2Zmc2V0ID0gZDNfbGF5b3V0X3N0YWNrT2Zmc2V0WmVybywgb3V0ID0gZDNfbGF5b3V0X3N0YWNrT3V0LCB4ID0gZDNfbGF5b3V0X3N0YWNrWCwgeSA9IGQzX2xheW91dF9zdGFja1k7XG4gICAgZnVuY3Rpb24gc3RhY2soZGF0YSwgaW5kZXgpIHtcbiAgICAgIHZhciBzZXJpZXMgPSBkYXRhLm1hcChmdW5jdGlvbihkLCBpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXMuY2FsbChzdGFjaywgZCwgaSk7XG4gICAgICB9KTtcbiAgICAgIHZhciBwb2ludHMgPSBzZXJpZXMubWFwKGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgcmV0dXJuIGQubWFwKGZ1bmN0aW9uKHYsIGkpIHtcbiAgICAgICAgICByZXR1cm4gWyB4LmNhbGwoc3RhY2ssIHYsIGkpLCB5LmNhbGwoc3RhY2ssIHYsIGkpIF07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICB2YXIgb3JkZXJzID0gb3JkZXIuY2FsbChzdGFjaywgcG9pbnRzLCBpbmRleCk7XG4gICAgICBzZXJpZXMgPSBkMy5wZXJtdXRlKHNlcmllcywgb3JkZXJzKTtcbiAgICAgIHBvaW50cyA9IGQzLnBlcm11dGUocG9pbnRzLCBvcmRlcnMpO1xuICAgICAgdmFyIG9mZnNldHMgPSBvZmZzZXQuY2FsbChzdGFjaywgcG9pbnRzLCBpbmRleCk7XG4gICAgICB2YXIgbiA9IHNlcmllcy5sZW5ndGgsIG0gPSBzZXJpZXNbMF0ubGVuZ3RoLCBpLCBqLCBvO1xuICAgICAgZm9yIChqID0gMDsgaiA8IG07ICsraikge1xuICAgICAgICBvdXQuY2FsbChzdGFjaywgc2VyaWVzWzBdW2pdLCBvID0gb2Zmc2V0c1tqXSwgcG9pbnRzWzBdW2pdWzFdKTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IG47ICsraSkge1xuICAgICAgICAgIG91dC5jYWxsKHN0YWNrLCBzZXJpZXNbaV1bal0sIG8gKz0gcG9pbnRzW2kgLSAxXVtqXVsxXSwgcG9pbnRzW2ldW2pdWzFdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIHN0YWNrLnZhbHVlcyA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHZhbHVlcztcbiAgICAgIHZhbHVlcyA9IHg7XG4gICAgICByZXR1cm4gc3RhY2s7XG4gICAgfTtcbiAgICBzdGFjay5vcmRlciA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIG9yZGVyO1xuICAgICAgb3JkZXIgPSB0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiID8geCA6IGQzX2xheW91dF9zdGFja09yZGVycy5nZXQoeCkgfHwgZDNfbGF5b3V0X3N0YWNrT3JkZXJEZWZhdWx0O1xuICAgICAgcmV0dXJuIHN0YWNrO1xuICAgIH07XG4gICAgc3RhY2sub2Zmc2V0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gb2Zmc2V0O1xuICAgICAgb2Zmc2V0ID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiBkM19sYXlvdXRfc3RhY2tPZmZzZXRzLmdldCh4KSB8fCBkM19sYXlvdXRfc3RhY2tPZmZzZXRaZXJvO1xuICAgICAgcmV0dXJuIHN0YWNrO1xuICAgIH07XG4gICAgc3RhY2sueCA9IGZ1bmN0aW9uKHopIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHg7XG4gICAgICB4ID0gejtcbiAgICAgIHJldHVybiBzdGFjaztcbiAgICB9O1xuICAgIHN0YWNrLnkgPSBmdW5jdGlvbih6KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB5O1xuICAgICAgeSA9IHo7XG4gICAgICByZXR1cm4gc3RhY2s7XG4gICAgfTtcbiAgICBzdGFjay5vdXQgPSBmdW5jdGlvbih6KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBvdXQ7XG4gICAgICBvdXQgPSB6O1xuICAgICAgcmV0dXJuIHN0YWNrO1xuICAgIH07XG4gICAgcmV0dXJuIHN0YWNrO1xuICB9O1xuICBmdW5jdGlvbiBkM19sYXlvdXRfc3RhY2tYKGQpIHtcbiAgICByZXR1cm4gZC54O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9zdGFja1koZCkge1xuICAgIHJldHVybiBkLnk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3N0YWNrT3V0KGQsIHkwLCB5KSB7XG4gICAgZC55MCA9IHkwO1xuICAgIGQueSA9IHk7XG4gIH1cbiAgdmFyIGQzX2xheW91dF9zdGFja09yZGVycyA9IGQzLm1hcCh7XG4gICAgXCJpbnNpZGUtb3V0XCI6IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHZhciBuID0gZGF0YS5sZW5ndGgsIGksIGosIG1heCA9IGRhdGEubWFwKGQzX2xheW91dF9zdGFja01heEluZGV4KSwgc3VtcyA9IGRhdGEubWFwKGQzX2xheW91dF9zdGFja1JlZHVjZVN1bSksIGluZGV4ID0gZDMucmFuZ2Uobikuc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgICAgIHJldHVybiBtYXhbYV0gLSBtYXhbYl07XG4gICAgICB9KSwgdG9wID0gMCwgYm90dG9tID0gMCwgdG9wcyA9IFtdLCBib3R0b21zID0gW107XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGogPSBpbmRleFtpXTtcbiAgICAgICAgaWYgKHRvcCA8IGJvdHRvbSkge1xuICAgICAgICAgIHRvcCArPSBzdW1zW2pdO1xuICAgICAgICAgIHRvcHMucHVzaChqKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBib3R0b20gKz0gc3Vtc1tqXTtcbiAgICAgICAgICBib3R0b21zLnB1c2goaik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBib3R0b21zLnJldmVyc2UoKS5jb25jYXQodG9wcyk7XG4gICAgfSxcbiAgICByZXZlcnNlOiBmdW5jdGlvbihkYXRhKSB7XG4gICAgICByZXR1cm4gZDMucmFuZ2UoZGF0YS5sZW5ndGgpLnJldmVyc2UoKTtcbiAgICB9LFxuICAgIFwiZGVmYXVsdFwiOiBkM19sYXlvdXRfc3RhY2tPcmRlckRlZmF1bHRcbiAgfSk7XG4gIHZhciBkM19sYXlvdXRfc3RhY2tPZmZzZXRzID0gZDMubWFwKHtcbiAgICBzaWxob3VldHRlOiBmdW5jdGlvbihkYXRhKSB7XG4gICAgICB2YXIgbiA9IGRhdGEubGVuZ3RoLCBtID0gZGF0YVswXS5sZW5ndGgsIHN1bXMgPSBbXSwgbWF4ID0gMCwgaSwgaiwgbywgeTAgPSBbXTtcbiAgICAgIGZvciAoaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICAgICAgZm9yIChpID0gMCwgbyA9IDA7IGkgPCBuOyBpKyspIG8gKz0gZGF0YVtpXVtqXVsxXTtcbiAgICAgICAgaWYgKG8gPiBtYXgpIG1heCA9IG87XG4gICAgICAgIHN1bXMucHVzaChvKTtcbiAgICAgIH1cbiAgICAgIGZvciAoaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICAgICAgeTBbal0gPSAobWF4IC0gc3Vtc1tqXSkgLyAyO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHkwO1xuICAgIH0sXG4gICAgd2lnZ2xlOiBmdW5jdGlvbihkYXRhKSB7XG4gICAgICB2YXIgbiA9IGRhdGEubGVuZ3RoLCB4ID0gZGF0YVswXSwgbSA9IHgubGVuZ3RoLCBpLCBqLCBrLCBzMSwgczIsIHMzLCBkeCwgbywgbzAsIHkwID0gW107XG4gICAgICB5MFswXSA9IG8gPSBvMCA9IDA7XG4gICAgICBmb3IgKGogPSAxOyBqIDwgbTsgKytqKSB7XG4gICAgICAgIGZvciAoaSA9IDAsIHMxID0gMDsgaSA8IG47ICsraSkgczEgKz0gZGF0YVtpXVtqXVsxXTtcbiAgICAgICAgZm9yIChpID0gMCwgczIgPSAwLCBkeCA9IHhbal1bMF0gLSB4W2ogLSAxXVswXTsgaSA8IG47ICsraSkge1xuICAgICAgICAgIGZvciAoayA9IDAsIHMzID0gKGRhdGFbaV1bal1bMV0gLSBkYXRhW2ldW2ogLSAxXVsxXSkgLyAoMiAqIGR4KTsgayA8IGk7ICsraykge1xuICAgICAgICAgICAgczMgKz0gKGRhdGFba11bal1bMV0gLSBkYXRhW2tdW2ogLSAxXVsxXSkgLyBkeDtcbiAgICAgICAgICB9XG4gICAgICAgICAgczIgKz0gczMgKiBkYXRhW2ldW2pdWzFdO1xuICAgICAgICB9XG4gICAgICAgIHkwW2pdID0gbyAtPSBzMSA/IHMyIC8gczEgKiBkeCA6IDA7XG4gICAgICAgIGlmIChvIDwgbzApIG8wID0gbztcbiAgICAgIH1cbiAgICAgIGZvciAoaiA9IDA7IGogPCBtOyArK2opIHkwW2pdIC09IG8wO1xuICAgICAgcmV0dXJuIHkwO1xuICAgIH0sXG4gICAgZXhwYW5kOiBmdW5jdGlvbihkYXRhKSB7XG4gICAgICB2YXIgbiA9IGRhdGEubGVuZ3RoLCBtID0gZGF0YVswXS5sZW5ndGgsIGsgPSAxIC8gbiwgaSwgaiwgbywgeTAgPSBbXTtcbiAgICAgIGZvciAoaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICAgICAgZm9yIChpID0gMCwgbyA9IDA7IGkgPCBuOyBpKyspIG8gKz0gZGF0YVtpXVtqXVsxXTtcbiAgICAgICAgaWYgKG8pIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIGRhdGFbaV1bal1bMV0gLz0gbzsgZWxzZSBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBkYXRhW2ldW2pdWzFdID0gaztcbiAgICAgIH1cbiAgICAgIGZvciAoaiA9IDA7IGogPCBtOyArK2opIHkwW2pdID0gMDtcbiAgICAgIHJldHVybiB5MDtcbiAgICB9LFxuICAgIHplcm86IGQzX2xheW91dF9zdGFja09mZnNldFplcm9cbiAgfSk7XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9zdGFja09yZGVyRGVmYXVsdChkYXRhKSB7XG4gICAgcmV0dXJuIGQzLnJhbmdlKGRhdGEubGVuZ3RoKTtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfc3RhY2tPZmZzZXRaZXJvKGRhdGEpIHtcbiAgICB2YXIgaiA9IC0xLCBtID0gZGF0YVswXS5sZW5ndGgsIHkwID0gW107XG4gICAgd2hpbGUgKCsraiA8IG0pIHkwW2pdID0gMDtcbiAgICByZXR1cm4geTA7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3N0YWNrTWF4SW5kZXgoYXJyYXkpIHtcbiAgICB2YXIgaSA9IDEsIGogPSAwLCB2ID0gYXJyYXlbMF1bMV0sIGssIG4gPSBhcnJheS5sZW5ndGg7XG4gICAgZm9yICg7aSA8IG47ICsraSkge1xuICAgICAgaWYgKChrID0gYXJyYXlbaV1bMV0pID4gdikge1xuICAgICAgICBqID0gaTtcbiAgICAgICAgdiA9IGs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBqO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9zdGFja1JlZHVjZVN1bShkKSB7XG4gICAgcmV0dXJuIGQucmVkdWNlKGQzX2xheW91dF9zdGFja1N1bSwgMCk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3N0YWNrU3VtKHAsIGQpIHtcbiAgICByZXR1cm4gcCArIGRbMV07XG4gIH1cbiAgZDMubGF5b3V0Lmhpc3RvZ3JhbSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBmcmVxdWVuY3kgPSB0cnVlLCB2YWx1ZXIgPSBOdW1iZXIsIHJhbmdlciA9IGQzX2xheW91dF9oaXN0b2dyYW1SYW5nZSwgYmlubmVyID0gZDNfbGF5b3V0X2hpc3RvZ3JhbUJpblN0dXJnZXM7XG4gICAgZnVuY3Rpb24gaGlzdG9ncmFtKGRhdGEsIGkpIHtcbiAgICAgIHZhciBiaW5zID0gW10sIHZhbHVlcyA9IGRhdGEubWFwKHZhbHVlciwgdGhpcyksIHJhbmdlID0gcmFuZ2VyLmNhbGwodGhpcywgdmFsdWVzLCBpKSwgdGhyZXNob2xkcyA9IGJpbm5lci5jYWxsKHRoaXMsIHJhbmdlLCB2YWx1ZXMsIGkpLCBiaW4sIGkgPSAtMSwgbiA9IHZhbHVlcy5sZW5ndGgsIG0gPSB0aHJlc2hvbGRzLmxlbmd0aCAtIDEsIGsgPSBmcmVxdWVuY3kgPyAxIDogMSAvIG4sIHg7XG4gICAgICB3aGlsZSAoKytpIDwgbSkge1xuICAgICAgICBiaW4gPSBiaW5zW2ldID0gW107XG4gICAgICAgIGJpbi5keCA9IHRocmVzaG9sZHNbaSArIDFdIC0gKGJpbi54ID0gdGhyZXNob2xkc1tpXSk7XG4gICAgICAgIGJpbi55ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtID4gMCkge1xuICAgICAgICBpID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgeCA9IHZhbHVlc1tpXTtcbiAgICAgICAgICBpZiAoeCA+PSByYW5nZVswXSAmJiB4IDw9IHJhbmdlWzFdKSB7XG4gICAgICAgICAgICBiaW4gPSBiaW5zW2QzLmJpc2VjdCh0aHJlc2hvbGRzLCB4LCAxLCBtKSAtIDFdO1xuICAgICAgICAgICAgYmluLnkgKz0gaztcbiAgICAgICAgICAgIGJpbi5wdXNoKGRhdGFbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGJpbnM7XG4gICAgfVxuICAgIGhpc3RvZ3JhbS52YWx1ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHZhbHVlcjtcbiAgICAgIHZhbHVlciA9IHg7XG4gICAgICByZXR1cm4gaGlzdG9ncmFtO1xuICAgIH07XG4gICAgaGlzdG9ncmFtLnJhbmdlID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcmFuZ2VyO1xuICAgICAgcmFuZ2VyID0gZDNfZnVuY3Rvcih4KTtcbiAgICAgIHJldHVybiBoaXN0b2dyYW07XG4gICAgfTtcbiAgICBoaXN0b2dyYW0uYmlucyA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGJpbm5lcjtcbiAgICAgIGJpbm5lciA9IHR5cGVvZiB4ID09PSBcIm51bWJlclwiID8gZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIGQzX2xheW91dF9oaXN0b2dyYW1CaW5GaXhlZChyYW5nZSwgeCk7XG4gICAgICB9IDogZDNfZnVuY3Rvcih4KTtcbiAgICAgIHJldHVybiBoaXN0b2dyYW07XG4gICAgfTtcbiAgICBoaXN0b2dyYW0uZnJlcXVlbmN5ID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZnJlcXVlbmN5O1xuICAgICAgZnJlcXVlbmN5ID0gISF4O1xuICAgICAgcmV0dXJuIGhpc3RvZ3JhbTtcbiAgICB9O1xuICAgIHJldHVybiBoaXN0b2dyYW07XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9oaXN0b2dyYW1CaW5TdHVyZ2VzKHJhbmdlLCB2YWx1ZXMpIHtcbiAgICByZXR1cm4gZDNfbGF5b3V0X2hpc3RvZ3JhbUJpbkZpeGVkKHJhbmdlLCBNYXRoLmNlaWwoTWF0aC5sb2codmFsdWVzLmxlbmd0aCkgLyBNYXRoLkxOMiArIDEpKTtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfaGlzdG9ncmFtQmluRml4ZWQocmFuZ2UsIG4pIHtcbiAgICB2YXIgeCA9IC0xLCBiID0gK3JhbmdlWzBdLCBtID0gKHJhbmdlWzFdIC0gYikgLyBuLCBmID0gW107XG4gICAgd2hpbGUgKCsreCA8PSBuKSBmW3hdID0gbSAqIHggKyBiO1xuICAgIHJldHVybiBmO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9oaXN0b2dyYW1SYW5nZSh2YWx1ZXMpIHtcbiAgICByZXR1cm4gWyBkMy5taW4odmFsdWVzKSwgZDMubWF4KHZhbHVlcykgXTtcbiAgfVxuICBkMy5sYXlvdXQudHJlZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBoaWVyYXJjaHkgPSBkMy5sYXlvdXQuaGllcmFyY2h5KCkuc29ydChudWxsKS52YWx1ZShudWxsKSwgc2VwYXJhdGlvbiA9IGQzX2xheW91dF90cmVlU2VwYXJhdGlvbiwgc2l6ZSA9IFsgMSwgMSBdLCBub2RlU2l6ZSA9IGZhbHNlO1xuICAgIGZ1bmN0aW9uIHRyZWUoZCwgaSkge1xuICAgICAgdmFyIG5vZGVzID0gaGllcmFyY2h5LmNhbGwodGhpcywgZCwgaSksIHJvb3QgPSBub2Rlc1swXTtcbiAgICAgIGZ1bmN0aW9uIGZpcnN0V2Fsayhub2RlLCBwcmV2aW91c1NpYmxpbmcpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbiwgbGF5b3V0ID0gbm9kZS5fdHJlZTtcbiAgICAgICAgaWYgKGNoaWxkcmVuICYmIChuID0gY2hpbGRyZW4ubGVuZ3RoKSkge1xuICAgICAgICAgIHZhciBuLCBmaXJzdENoaWxkID0gY2hpbGRyZW5bMF0sIHByZXZpb3VzQ2hpbGQsIGFuY2VzdG9yID0gZmlyc3RDaGlsZCwgY2hpbGQsIGkgPSAtMTtcbiAgICAgICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcbiAgICAgICAgICAgIGZpcnN0V2FsayhjaGlsZCwgcHJldmlvdXNDaGlsZCk7XG4gICAgICAgICAgICBhbmNlc3RvciA9IGFwcG9ydGlvbihjaGlsZCwgcHJldmlvdXNDaGlsZCwgYW5jZXN0b3IpO1xuICAgICAgICAgICAgcHJldmlvdXNDaGlsZCA9IGNoaWxkO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkM19sYXlvdXRfdHJlZVNoaWZ0KG5vZGUpO1xuICAgICAgICAgIHZhciBtaWRwb2ludCA9IC41ICogKGZpcnN0Q2hpbGQuX3RyZWUucHJlbGltICsgY2hpbGQuX3RyZWUucHJlbGltKTtcbiAgICAgICAgICBpZiAocHJldmlvdXNTaWJsaW5nKSB7XG4gICAgICAgICAgICBsYXlvdXQucHJlbGltID0gcHJldmlvdXNTaWJsaW5nLl90cmVlLnByZWxpbSArIHNlcGFyYXRpb24obm9kZSwgcHJldmlvdXNTaWJsaW5nKTtcbiAgICAgICAgICAgIGxheW91dC5tb2QgPSBsYXlvdXQucHJlbGltIC0gbWlkcG9pbnQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxheW91dC5wcmVsaW0gPSBtaWRwb2ludDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHByZXZpb3VzU2libGluZykge1xuICAgICAgICAgICAgbGF5b3V0LnByZWxpbSA9IHByZXZpb3VzU2libGluZy5fdHJlZS5wcmVsaW0gKyBzZXBhcmF0aW9uKG5vZGUsIHByZXZpb3VzU2libGluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBzZWNvbmRXYWxrKG5vZGUsIHgpIHtcbiAgICAgICAgbm9kZS54ID0gbm9kZS5fdHJlZS5wcmVsaW0gKyB4O1xuICAgICAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xuICAgICAgICBpZiAoY2hpbGRyZW4gJiYgKG4gPSBjaGlsZHJlbi5sZW5ndGgpKSB7XG4gICAgICAgICAgdmFyIGkgPSAtMSwgbjtcbiAgICAgICAgICB4ICs9IG5vZGUuX3RyZWUubW9kO1xuICAgICAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgICBzZWNvbmRXYWxrKGNoaWxkcmVuW2ldLCB4KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGFwcG9ydGlvbihub2RlLCBwcmV2aW91c1NpYmxpbmcsIGFuY2VzdG9yKSB7XG4gICAgICAgIGlmIChwcmV2aW91c1NpYmxpbmcpIHtcbiAgICAgICAgICB2YXIgdmlwID0gbm9kZSwgdm9wID0gbm9kZSwgdmltID0gcHJldmlvdXNTaWJsaW5nLCB2b20gPSBub2RlLnBhcmVudC5jaGlsZHJlblswXSwgc2lwID0gdmlwLl90cmVlLm1vZCwgc29wID0gdm9wLl90cmVlLm1vZCwgc2ltID0gdmltLl90cmVlLm1vZCwgc29tID0gdm9tLl90cmVlLm1vZCwgc2hpZnQ7XG4gICAgICAgICAgd2hpbGUgKHZpbSA9IGQzX2xheW91dF90cmVlUmlnaHQodmltKSwgdmlwID0gZDNfbGF5b3V0X3RyZWVMZWZ0KHZpcCksIHZpbSAmJiB2aXApIHtcbiAgICAgICAgICAgIHZvbSA9IGQzX2xheW91dF90cmVlTGVmdCh2b20pO1xuICAgICAgICAgICAgdm9wID0gZDNfbGF5b3V0X3RyZWVSaWdodCh2b3ApO1xuICAgICAgICAgICAgdm9wLl90cmVlLmFuY2VzdG9yID0gbm9kZTtcbiAgICAgICAgICAgIHNoaWZ0ID0gdmltLl90cmVlLnByZWxpbSArIHNpbSAtIHZpcC5fdHJlZS5wcmVsaW0gLSBzaXAgKyBzZXBhcmF0aW9uKHZpbSwgdmlwKTtcbiAgICAgICAgICAgIGlmIChzaGlmdCA+IDApIHtcbiAgICAgICAgICAgICAgZDNfbGF5b3V0X3RyZWVNb3ZlKGQzX2xheW91dF90cmVlQW5jZXN0b3IodmltLCBub2RlLCBhbmNlc3RvciksIG5vZGUsIHNoaWZ0KTtcbiAgICAgICAgICAgICAgc2lwICs9IHNoaWZ0O1xuICAgICAgICAgICAgICBzb3AgKz0gc2hpZnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaW0gKz0gdmltLl90cmVlLm1vZDtcbiAgICAgICAgICAgIHNpcCArPSB2aXAuX3RyZWUubW9kO1xuICAgICAgICAgICAgc29tICs9IHZvbS5fdHJlZS5tb2Q7XG4gICAgICAgICAgICBzb3AgKz0gdm9wLl90cmVlLm1vZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHZpbSAmJiAhZDNfbGF5b3V0X3RyZWVSaWdodCh2b3ApKSB7XG4gICAgICAgICAgICB2b3AuX3RyZWUudGhyZWFkID0gdmltO1xuICAgICAgICAgICAgdm9wLl90cmVlLm1vZCArPSBzaW0gLSBzb3A7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2aXAgJiYgIWQzX2xheW91dF90cmVlTGVmdCh2b20pKSB7XG4gICAgICAgICAgICB2b20uX3RyZWUudGhyZWFkID0gdmlwO1xuICAgICAgICAgICAgdm9tLl90cmVlLm1vZCArPSBzaXAgLSBzb207XG4gICAgICAgICAgICBhbmNlc3RvciA9IG5vZGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbmNlc3RvcjtcbiAgICAgIH1cbiAgICAgIGQzX2xheW91dF90cmVlVmlzaXRBZnRlcihyb290LCBmdW5jdGlvbihub2RlLCBwcmV2aW91c1NpYmxpbmcpIHtcbiAgICAgICAgbm9kZS5fdHJlZSA9IHtcbiAgICAgICAgICBhbmNlc3Rvcjogbm9kZSxcbiAgICAgICAgICBwcmVsaW06IDAsXG4gICAgICAgICAgbW9kOiAwLFxuICAgICAgICAgIGNoYW5nZTogMCxcbiAgICAgICAgICBzaGlmdDogMCxcbiAgICAgICAgICBudW1iZXI6IHByZXZpb3VzU2libGluZyA/IHByZXZpb3VzU2libGluZy5fdHJlZS5udW1iZXIgKyAxIDogMFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICBmaXJzdFdhbGsocm9vdCk7XG4gICAgICBzZWNvbmRXYWxrKHJvb3QsIC1yb290Ll90cmVlLnByZWxpbSk7XG4gICAgICB2YXIgbGVmdCA9IGQzX2xheW91dF90cmVlU2VhcmNoKHJvb3QsIGQzX2xheW91dF90cmVlTGVmdG1vc3QpLCByaWdodCA9IGQzX2xheW91dF90cmVlU2VhcmNoKHJvb3QsIGQzX2xheW91dF90cmVlUmlnaHRtb3N0KSwgZGVlcCA9IGQzX2xheW91dF90cmVlU2VhcmNoKHJvb3QsIGQzX2xheW91dF90cmVlRGVlcGVzdCksIHgwID0gbGVmdC54IC0gc2VwYXJhdGlvbihsZWZ0LCByaWdodCkgLyAyLCB4MSA9IHJpZ2h0LnggKyBzZXBhcmF0aW9uKHJpZ2h0LCBsZWZ0KSAvIDIsIHkxID0gZGVlcC5kZXB0aCB8fCAxO1xuICAgICAgZDNfbGF5b3V0X3RyZWVWaXNpdEFmdGVyKHJvb3QsIG5vZGVTaXplID8gZnVuY3Rpb24obm9kZSkge1xuICAgICAgICBub2RlLnggKj0gc2l6ZVswXTtcbiAgICAgICAgbm9kZS55ID0gbm9kZS5kZXB0aCAqIHNpemVbMV07XG4gICAgICAgIGRlbGV0ZSBub2RlLl90cmVlO1xuICAgICAgfSA6IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgbm9kZS54ID0gKG5vZGUueCAtIHgwKSAvICh4MSAtIHgwKSAqIHNpemVbMF07XG4gICAgICAgIG5vZGUueSA9IG5vZGUuZGVwdGggLyB5MSAqIHNpemVbMV07XG4gICAgICAgIGRlbGV0ZSBub2RlLl90cmVlO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gbm9kZXM7XG4gICAgfVxuICAgIHRyZWUuc2VwYXJhdGlvbiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNlcGFyYXRpb247XG4gICAgICBzZXBhcmF0aW9uID0geDtcbiAgICAgIHJldHVybiB0cmVlO1xuICAgIH07XG4gICAgdHJlZS5zaXplID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbm9kZVNpemUgPyBudWxsIDogc2l6ZTtcbiAgICAgIG5vZGVTaXplID0gKHNpemUgPSB4KSA9PSBudWxsO1xuICAgICAgcmV0dXJuIHRyZWU7XG4gICAgfTtcbiAgICB0cmVlLm5vZGVTaXplID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbm9kZVNpemUgPyBzaXplIDogbnVsbDtcbiAgICAgIG5vZGVTaXplID0gKHNpemUgPSB4KSAhPSBudWxsO1xuICAgICAgcmV0dXJuIHRyZWU7XG4gICAgfTtcbiAgICByZXR1cm4gZDNfbGF5b3V0X2hpZXJhcmNoeVJlYmluZCh0cmVlLCBoaWVyYXJjaHkpO1xuICB9O1xuICBmdW5jdGlvbiBkM19sYXlvdXRfdHJlZVNlcGFyYXRpb24oYSwgYikge1xuICAgIHJldHVybiBhLnBhcmVudCA9PSBiLnBhcmVudCA/IDEgOiAyO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF90cmVlTGVmdChub2RlKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjtcbiAgICByZXR1cm4gY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoID8gY2hpbGRyZW5bMF0gOiBub2RlLl90cmVlLnRocmVhZDtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfdHJlZVJpZ2h0KG5vZGUpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuLCBuO1xuICAgIHJldHVybiBjaGlsZHJlbiAmJiAobiA9IGNoaWxkcmVuLmxlbmd0aCkgPyBjaGlsZHJlbltuIC0gMV0gOiBub2RlLl90cmVlLnRocmVhZDtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfdHJlZVNlYXJjaChub2RlLCBjb21wYXJlKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjtcbiAgICBpZiAoY2hpbGRyZW4gJiYgKG4gPSBjaGlsZHJlbi5sZW5ndGgpKSB7XG4gICAgICB2YXIgY2hpbGQsIG4sIGkgPSAtMTtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgIGlmIChjb21wYXJlKGNoaWxkID0gZDNfbGF5b3V0X3RyZWVTZWFyY2goY2hpbGRyZW5baV0sIGNvbXBhcmUpLCBub2RlKSA+IDApIHtcbiAgICAgICAgICBub2RlID0gY2hpbGQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3RyZWVSaWdodG1vc3QoYSwgYikge1xuICAgIHJldHVybiBhLnggLSBiLng7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3RyZWVMZWZ0bW9zdChhLCBiKSB7XG4gICAgcmV0dXJuIGIueCAtIGEueDtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfdHJlZURlZXBlc3QoYSwgYikge1xuICAgIHJldHVybiBhLmRlcHRoIC0gYi5kZXB0aDtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfdHJlZVZpc2l0QWZ0ZXIobm9kZSwgY2FsbGJhY2spIHtcbiAgICBmdW5jdGlvbiB2aXNpdChub2RlLCBwcmV2aW91c1NpYmxpbmcpIHtcbiAgICAgIHZhciBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW47XG4gICAgICBpZiAoY2hpbGRyZW4gJiYgKG4gPSBjaGlsZHJlbi5sZW5ndGgpKSB7XG4gICAgICAgIHZhciBjaGlsZCwgcHJldmlvdXNDaGlsZCA9IG51bGwsIGkgPSAtMSwgbjtcbiAgICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgICBjaGlsZCA9IGNoaWxkcmVuW2ldO1xuICAgICAgICAgIHZpc2l0KGNoaWxkLCBwcmV2aW91c0NoaWxkKTtcbiAgICAgICAgICBwcmV2aW91c0NoaWxkID0gY2hpbGQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNhbGxiYWNrKG5vZGUsIHByZXZpb3VzU2libGluZyk7XG4gICAgfVxuICAgIHZpc2l0KG5vZGUsIG51bGwpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF90cmVlU2hpZnQobm9kZSkge1xuICAgIHZhciBzaGlmdCA9IDAsIGNoYW5nZSA9IDAsIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbiwgaSA9IGNoaWxkcmVuLmxlbmd0aCwgY2hpbGQ7XG4gICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICBjaGlsZCA9IGNoaWxkcmVuW2ldLl90cmVlO1xuICAgICAgY2hpbGQucHJlbGltICs9IHNoaWZ0O1xuICAgICAgY2hpbGQubW9kICs9IHNoaWZ0O1xuICAgICAgc2hpZnQgKz0gY2hpbGQuc2hpZnQgKyAoY2hhbmdlICs9IGNoaWxkLmNoYW5nZSk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF90cmVlTW92ZShhbmNlc3Rvciwgbm9kZSwgc2hpZnQpIHtcbiAgICBhbmNlc3RvciA9IGFuY2VzdG9yLl90cmVlO1xuICAgIG5vZGUgPSBub2RlLl90cmVlO1xuICAgIHZhciBjaGFuZ2UgPSBzaGlmdCAvIChub2RlLm51bWJlciAtIGFuY2VzdG9yLm51bWJlcik7XG4gICAgYW5jZXN0b3IuY2hhbmdlICs9IGNoYW5nZTtcbiAgICBub2RlLmNoYW5nZSAtPSBjaGFuZ2U7XG4gICAgbm9kZS5zaGlmdCArPSBzaGlmdDtcbiAgICBub2RlLnByZWxpbSArPSBzaGlmdDtcbiAgICBub2RlLm1vZCArPSBzaGlmdDtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfdHJlZUFuY2VzdG9yKHZpbSwgbm9kZSwgYW5jZXN0b3IpIHtcbiAgICByZXR1cm4gdmltLl90cmVlLmFuY2VzdG9yLnBhcmVudCA9PSBub2RlLnBhcmVudCA/IHZpbS5fdHJlZS5hbmNlc3RvciA6IGFuY2VzdG9yO1xuICB9XG4gIGQzLmxheW91dC5wYWNrID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGhpZXJhcmNoeSA9IGQzLmxheW91dC5oaWVyYXJjaHkoKS5zb3J0KGQzX2xheW91dF9wYWNrU29ydCksIHBhZGRpbmcgPSAwLCBzaXplID0gWyAxLCAxIF0sIHJhZGl1cztcbiAgICBmdW5jdGlvbiBwYWNrKGQsIGkpIHtcbiAgICAgIHZhciBub2RlcyA9IGhpZXJhcmNoeS5jYWxsKHRoaXMsIGQsIGkpLCByb290ID0gbm9kZXNbMF0sIHcgPSBzaXplWzBdLCBoID0gc2l6ZVsxXSwgciA9IHJhZGl1cyA9PSBudWxsID8gTWF0aC5zcXJ0IDogdHlwZW9mIHJhZGl1cyA9PT0gXCJmdW5jdGlvblwiID8gcmFkaXVzIDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiByYWRpdXM7XG4gICAgICB9O1xuICAgICAgcm9vdC54ID0gcm9vdC55ID0gMDtcbiAgICAgIGQzX2xheW91dF90cmVlVmlzaXRBZnRlcihyb290LCBmdW5jdGlvbihkKSB7XG4gICAgICAgIGQuciA9ICtyKGQudmFsdWUpO1xuICAgICAgfSk7XG4gICAgICBkM19sYXlvdXRfdHJlZVZpc2l0QWZ0ZXIocm9vdCwgZDNfbGF5b3V0X3BhY2tTaWJsaW5ncyk7XG4gICAgICBpZiAocGFkZGluZykge1xuICAgICAgICB2YXIgZHIgPSBwYWRkaW5nICogKHJhZGl1cyA/IDEgOiBNYXRoLm1heCgyICogcm9vdC5yIC8gdywgMiAqIHJvb3QuciAvIGgpKSAvIDI7XG4gICAgICAgIGQzX2xheW91dF90cmVlVmlzaXRBZnRlcihyb290LCBmdW5jdGlvbihkKSB7XG4gICAgICAgICAgZC5yICs9IGRyO1xuICAgICAgICB9KTtcbiAgICAgICAgZDNfbGF5b3V0X3RyZWVWaXNpdEFmdGVyKHJvb3QsIGQzX2xheW91dF9wYWNrU2libGluZ3MpO1xuICAgICAgICBkM19sYXlvdXRfdHJlZVZpc2l0QWZ0ZXIocm9vdCwgZnVuY3Rpb24oZCkge1xuICAgICAgICAgIGQuciAtPSBkcjtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBkM19sYXlvdXRfcGFja1RyYW5zZm9ybShyb290LCB3IC8gMiwgaCAvIDIsIHJhZGl1cyA/IDEgOiAxIC8gTWF0aC5tYXgoMiAqIHJvb3QuciAvIHcsIDIgKiByb290LnIgLyBoKSk7XG4gICAgICByZXR1cm4gbm9kZXM7XG4gICAgfVxuICAgIHBhY2suc2l6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNpemU7XG4gICAgICBzaXplID0gXztcbiAgICAgIHJldHVybiBwYWNrO1xuICAgIH07XG4gICAgcGFjay5yYWRpdXMgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiByYWRpdXM7XG4gICAgICByYWRpdXMgPSBfID09IG51bGwgfHwgdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiArXztcbiAgICAgIHJldHVybiBwYWNrO1xuICAgIH07XG4gICAgcGFjay5wYWRkaW5nID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcGFkZGluZztcbiAgICAgIHBhZGRpbmcgPSArXztcbiAgICAgIHJldHVybiBwYWNrO1xuICAgIH07XG4gICAgcmV0dXJuIGQzX2xheW91dF9oaWVyYXJjaHlSZWJpbmQocGFjaywgaGllcmFyY2h5KTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3BhY2tTb3J0KGEsIGIpIHtcbiAgICByZXR1cm4gYS52YWx1ZSAtIGIudmFsdWU7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3BhY2tJbnNlcnQoYSwgYikge1xuICAgIHZhciBjID0gYS5fcGFja19uZXh0O1xuICAgIGEuX3BhY2tfbmV4dCA9IGI7XG4gICAgYi5fcGFja19wcmV2ID0gYTtcbiAgICBiLl9wYWNrX25leHQgPSBjO1xuICAgIGMuX3BhY2tfcHJldiA9IGI7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3BhY2tTcGxpY2UoYSwgYikge1xuICAgIGEuX3BhY2tfbmV4dCA9IGI7XG4gICAgYi5fcGFja19wcmV2ID0gYTtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfcGFja0ludGVyc2VjdHMoYSwgYikge1xuICAgIHZhciBkeCA9IGIueCAtIGEueCwgZHkgPSBiLnkgLSBhLnksIGRyID0gYS5yICsgYi5yO1xuICAgIHJldHVybiAuOTk5ICogZHIgKiBkciA+IGR4ICogZHggKyBkeSAqIGR5O1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9wYWNrU2libGluZ3Mobm9kZSkge1xuICAgIGlmICghKG5vZGVzID0gbm9kZS5jaGlsZHJlbikgfHwgIShuID0gbm9kZXMubGVuZ3RoKSkgcmV0dXJuO1xuICAgIHZhciBub2RlcywgeE1pbiA9IEluZmluaXR5LCB4TWF4ID0gLUluZmluaXR5LCB5TWluID0gSW5maW5pdHksIHlNYXggPSAtSW5maW5pdHksIGEsIGIsIGMsIGksIGosIGssIG47XG4gICAgZnVuY3Rpb24gYm91bmQobm9kZSkge1xuICAgICAgeE1pbiA9IE1hdGgubWluKG5vZGUueCAtIG5vZGUuciwgeE1pbik7XG4gICAgICB4TWF4ID0gTWF0aC5tYXgobm9kZS54ICsgbm9kZS5yLCB4TWF4KTtcbiAgICAgIHlNaW4gPSBNYXRoLm1pbihub2RlLnkgLSBub2RlLnIsIHlNaW4pO1xuICAgICAgeU1heCA9IE1hdGgubWF4KG5vZGUueSArIG5vZGUuciwgeU1heCk7XG4gICAgfVxuICAgIG5vZGVzLmZvckVhY2goZDNfbGF5b3V0X3BhY2tMaW5rKTtcbiAgICBhID0gbm9kZXNbMF07XG4gICAgYS54ID0gLWEucjtcbiAgICBhLnkgPSAwO1xuICAgIGJvdW5kKGEpO1xuICAgIGlmIChuID4gMSkge1xuICAgICAgYiA9IG5vZGVzWzFdO1xuICAgICAgYi54ID0gYi5yO1xuICAgICAgYi55ID0gMDtcbiAgICAgIGJvdW5kKGIpO1xuICAgICAgaWYgKG4gPiAyKSB7XG4gICAgICAgIGMgPSBub2Rlc1syXTtcbiAgICAgICAgZDNfbGF5b3V0X3BhY2tQbGFjZShhLCBiLCBjKTtcbiAgICAgICAgYm91bmQoYyk7XG4gICAgICAgIGQzX2xheW91dF9wYWNrSW5zZXJ0KGEsIGMpO1xuICAgICAgICBhLl9wYWNrX3ByZXYgPSBjO1xuICAgICAgICBkM19sYXlvdXRfcGFja0luc2VydChjLCBiKTtcbiAgICAgICAgYiA9IGEuX3BhY2tfbmV4dDtcbiAgICAgICAgZm9yIChpID0gMzsgaSA8IG47IGkrKykge1xuICAgICAgICAgIGQzX2xheW91dF9wYWNrUGxhY2UoYSwgYiwgYyA9IG5vZGVzW2ldKTtcbiAgICAgICAgICB2YXIgaXNlY3QgPSAwLCBzMSA9IDEsIHMyID0gMTtcbiAgICAgICAgICBmb3IgKGogPSBiLl9wYWNrX25leHQ7IGogIT09IGI7IGogPSBqLl9wYWNrX25leHQsIHMxKyspIHtcbiAgICAgICAgICAgIGlmIChkM19sYXlvdXRfcGFja0ludGVyc2VjdHMoaiwgYykpIHtcbiAgICAgICAgICAgICAgaXNlY3QgPSAxO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGlzZWN0ID09IDEpIHtcbiAgICAgICAgICAgIGZvciAoayA9IGEuX3BhY2tfcHJldjsgayAhPT0gai5fcGFja19wcmV2OyBrID0gay5fcGFja19wcmV2LCBzMisrKSB7XG4gICAgICAgICAgICAgIGlmIChkM19sYXlvdXRfcGFja0ludGVyc2VjdHMoaywgYykpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaXNlY3QpIHtcbiAgICAgICAgICAgIGlmIChzMSA8IHMyIHx8IHMxID09IHMyICYmIGIuciA8IGEucikgZDNfbGF5b3V0X3BhY2tTcGxpY2UoYSwgYiA9IGopOyBlbHNlIGQzX2xheW91dF9wYWNrU3BsaWNlKGEgPSBrLCBiKTtcbiAgICAgICAgICAgIGktLTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZDNfbGF5b3V0X3BhY2tJbnNlcnQoYSwgYyk7XG4gICAgICAgICAgICBiID0gYztcbiAgICAgICAgICAgIGJvdW5kKGMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB2YXIgY3ggPSAoeE1pbiArIHhNYXgpIC8gMiwgY3kgPSAoeU1pbiArIHlNYXgpIC8gMiwgY3IgPSAwO1xuICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgIGMgPSBub2Rlc1tpXTtcbiAgICAgIGMueCAtPSBjeDtcbiAgICAgIGMueSAtPSBjeTtcbiAgICAgIGNyID0gTWF0aC5tYXgoY3IsIGMuciArIE1hdGguc3FydChjLnggKiBjLnggKyBjLnkgKiBjLnkpKTtcbiAgICB9XG4gICAgbm9kZS5yID0gY3I7XG4gICAgbm9kZXMuZm9yRWFjaChkM19sYXlvdXRfcGFja1VubGluayk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3BhY2tMaW5rKG5vZGUpIHtcbiAgICBub2RlLl9wYWNrX25leHQgPSBub2RlLl9wYWNrX3ByZXYgPSBub2RlO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9wYWNrVW5saW5rKG5vZGUpIHtcbiAgICBkZWxldGUgbm9kZS5fcGFja19uZXh0O1xuICAgIGRlbGV0ZSBub2RlLl9wYWNrX3ByZXY7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X3BhY2tUcmFuc2Zvcm0obm9kZSwgeCwgeSwgaykge1xuICAgIHZhciBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW47XG4gICAgbm9kZS54ID0geCArPSBrICogbm9kZS54O1xuICAgIG5vZGUueSA9IHkgKz0gayAqIG5vZGUueTtcbiAgICBub2RlLnIgKj0gaztcbiAgICBpZiAoY2hpbGRyZW4pIHtcbiAgICAgIHZhciBpID0gLTEsIG4gPSBjaGlsZHJlbi5sZW5ndGg7XG4gICAgICB3aGlsZSAoKytpIDwgbikgZDNfbGF5b3V0X3BhY2tUcmFuc2Zvcm0oY2hpbGRyZW5baV0sIHgsIHksIGspO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfcGFja1BsYWNlKGEsIGIsIGMpIHtcbiAgICB2YXIgZGIgPSBhLnIgKyBjLnIsIGR4ID0gYi54IC0gYS54LCBkeSA9IGIueSAtIGEueTtcbiAgICBpZiAoZGIgJiYgKGR4IHx8IGR5KSkge1xuICAgICAgdmFyIGRhID0gYi5yICsgYy5yLCBkYyA9IGR4ICogZHggKyBkeSAqIGR5O1xuICAgICAgZGEgKj0gZGE7XG4gICAgICBkYiAqPSBkYjtcbiAgICAgIHZhciB4ID0gLjUgKyAoZGIgLSBkYSkgLyAoMiAqIGRjKSwgeSA9IE1hdGguc3FydChNYXRoLm1heCgwLCAyICogZGEgKiAoZGIgKyBkYykgLSAoZGIgLT0gZGMpICogZGIgLSBkYSAqIGRhKSkgLyAoMiAqIGRjKTtcbiAgICAgIGMueCA9IGEueCArIHggKiBkeCArIHkgKiBkeTtcbiAgICAgIGMueSA9IGEueSArIHggKiBkeSAtIHkgKiBkeDtcbiAgICB9IGVsc2Uge1xuICAgICAgYy54ID0gYS54ICsgZGI7XG4gICAgICBjLnkgPSBhLnk7XG4gICAgfVxuICB9XG4gIGQzLmxheW91dC5jbHVzdGVyID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGhpZXJhcmNoeSA9IGQzLmxheW91dC5oaWVyYXJjaHkoKS5zb3J0KG51bGwpLnZhbHVlKG51bGwpLCBzZXBhcmF0aW9uID0gZDNfbGF5b3V0X3RyZWVTZXBhcmF0aW9uLCBzaXplID0gWyAxLCAxIF0sIG5vZGVTaXplID0gZmFsc2U7XG4gICAgZnVuY3Rpb24gY2x1c3RlcihkLCBpKSB7XG4gICAgICB2YXIgbm9kZXMgPSBoaWVyYXJjaHkuY2FsbCh0aGlzLCBkLCBpKSwgcm9vdCA9IG5vZGVzWzBdLCBwcmV2aW91c05vZGUsIHggPSAwO1xuICAgICAgZDNfbGF5b3V0X3RyZWVWaXNpdEFmdGVyKHJvb3QsIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjtcbiAgICAgICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgIG5vZGUueCA9IGQzX2xheW91dF9jbHVzdGVyWChjaGlsZHJlbik7XG4gICAgICAgICAgbm9kZS55ID0gZDNfbGF5b3V0X2NsdXN0ZXJZKGNoaWxkcmVuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBub2RlLnggPSBwcmV2aW91c05vZGUgPyB4ICs9IHNlcGFyYXRpb24obm9kZSwgcHJldmlvdXNOb2RlKSA6IDA7XG4gICAgICAgICAgbm9kZS55ID0gMDtcbiAgICAgICAgICBwcmV2aW91c05vZGUgPSBub2RlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHZhciBsZWZ0ID0gZDNfbGF5b3V0X2NsdXN0ZXJMZWZ0KHJvb3QpLCByaWdodCA9IGQzX2xheW91dF9jbHVzdGVyUmlnaHQocm9vdCksIHgwID0gbGVmdC54IC0gc2VwYXJhdGlvbihsZWZ0LCByaWdodCkgLyAyLCB4MSA9IHJpZ2h0LnggKyBzZXBhcmF0aW9uKHJpZ2h0LCBsZWZ0KSAvIDI7XG4gICAgICBkM19sYXlvdXRfdHJlZVZpc2l0QWZ0ZXIocm9vdCwgbm9kZVNpemUgPyBmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIG5vZGUueCA9IChub2RlLnggLSByb290LngpICogc2l6ZVswXTtcbiAgICAgICAgbm9kZS55ID0gKHJvb3QueSAtIG5vZGUueSkgKiBzaXplWzFdO1xuICAgICAgfSA6IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgbm9kZS54ID0gKG5vZGUueCAtIHgwKSAvICh4MSAtIHgwKSAqIHNpemVbMF07XG4gICAgICAgIG5vZGUueSA9ICgxIC0gKHJvb3QueSA/IG5vZGUueSAvIHJvb3QueSA6IDEpKSAqIHNpemVbMV07XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBub2RlcztcbiAgICB9XG4gICAgY2x1c3Rlci5zZXBhcmF0aW9uID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2VwYXJhdGlvbjtcbiAgICAgIHNlcGFyYXRpb24gPSB4O1xuICAgICAgcmV0dXJuIGNsdXN0ZXI7XG4gICAgfTtcbiAgICBjbHVzdGVyLnNpemUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBub2RlU2l6ZSA/IG51bGwgOiBzaXplO1xuICAgICAgbm9kZVNpemUgPSAoc2l6ZSA9IHgpID09IG51bGw7XG4gICAgICByZXR1cm4gY2x1c3RlcjtcbiAgICB9O1xuICAgIGNsdXN0ZXIubm9kZVNpemUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBub2RlU2l6ZSA/IHNpemUgOiBudWxsO1xuICAgICAgbm9kZVNpemUgPSAoc2l6ZSA9IHgpICE9IG51bGw7XG4gICAgICByZXR1cm4gY2x1c3RlcjtcbiAgICB9O1xuICAgIHJldHVybiBkM19sYXlvdXRfaGllcmFyY2h5UmViaW5kKGNsdXN0ZXIsIGhpZXJhcmNoeSk7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9jbHVzdGVyWShjaGlsZHJlbikge1xuICAgIHJldHVybiAxICsgZDMubWF4KGNoaWxkcmVuLCBmdW5jdGlvbihjaGlsZCkge1xuICAgICAgcmV0dXJuIGNoaWxkLnk7XG4gICAgfSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2NsdXN0ZXJYKGNoaWxkcmVuKSB7XG4gICAgcmV0dXJuIGNoaWxkcmVuLnJlZHVjZShmdW5jdGlvbih4LCBjaGlsZCkge1xuICAgICAgcmV0dXJuIHggKyBjaGlsZC54O1xuICAgIH0sIDApIC8gY2hpbGRyZW4ubGVuZ3RoO1xuICB9XG4gIGZ1bmN0aW9uIGQzX2xheW91dF9jbHVzdGVyTGVmdChub2RlKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjtcbiAgICByZXR1cm4gY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoID8gZDNfbGF5b3V0X2NsdXN0ZXJMZWZ0KGNoaWxkcmVuWzBdKSA6IG5vZGU7XG4gIH1cbiAgZnVuY3Rpb24gZDNfbGF5b3V0X2NsdXN0ZXJSaWdodChub2RlKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbiwgbjtcbiAgICByZXR1cm4gY2hpbGRyZW4gJiYgKG4gPSBjaGlsZHJlbi5sZW5ndGgpID8gZDNfbGF5b3V0X2NsdXN0ZXJSaWdodChjaGlsZHJlbltuIC0gMV0pIDogbm9kZTtcbiAgfVxuICBkMy5sYXlvdXQudHJlZW1hcCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBoaWVyYXJjaHkgPSBkMy5sYXlvdXQuaGllcmFyY2h5KCksIHJvdW5kID0gTWF0aC5yb3VuZCwgc2l6ZSA9IFsgMSwgMSBdLCBwYWRkaW5nID0gbnVsbCwgcGFkID0gZDNfbGF5b3V0X3RyZWVtYXBQYWROdWxsLCBzdGlja3kgPSBmYWxzZSwgc3RpY2tpZXMsIG1vZGUgPSBcInNxdWFyaWZ5XCIsIHJhdGlvID0gLjUgKiAoMSArIE1hdGguc3FydCg1KSk7XG4gICAgZnVuY3Rpb24gc2NhbGUoY2hpbGRyZW4sIGspIHtcbiAgICAgIHZhciBpID0gLTEsIG4gPSBjaGlsZHJlbi5sZW5ndGgsIGNoaWxkLCBhcmVhO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgYXJlYSA9IChjaGlsZCA9IGNoaWxkcmVuW2ldKS52YWx1ZSAqIChrIDwgMCA/IDAgOiBrKTtcbiAgICAgICAgY2hpbGQuYXJlYSA9IGlzTmFOKGFyZWEpIHx8IGFyZWEgPD0gMCA/IDAgOiBhcmVhO1xuICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBzcXVhcmlmeShub2RlKSB7XG4gICAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xuICAgICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICB2YXIgcmVjdCA9IHBhZChub2RlKSwgcm93ID0gW10sIHJlbWFpbmluZyA9IGNoaWxkcmVuLnNsaWNlKCksIGNoaWxkLCBiZXN0ID0gSW5maW5pdHksIHNjb3JlLCB1ID0gbW9kZSA9PT0gXCJzbGljZVwiID8gcmVjdC5keCA6IG1vZGUgPT09IFwiZGljZVwiID8gcmVjdC5keSA6IG1vZGUgPT09IFwic2xpY2UtZGljZVwiID8gbm9kZS5kZXB0aCAmIDEgPyByZWN0LmR5IDogcmVjdC5keCA6IE1hdGgubWluKHJlY3QuZHgsIHJlY3QuZHkpLCBuO1xuICAgICAgICBzY2FsZShyZW1haW5pbmcsIHJlY3QuZHggKiByZWN0LmR5IC8gbm9kZS52YWx1ZSk7XG4gICAgICAgIHJvdy5hcmVhID0gMDtcbiAgICAgICAgd2hpbGUgKChuID0gcmVtYWluaW5nLmxlbmd0aCkgPiAwKSB7XG4gICAgICAgICAgcm93LnB1c2goY2hpbGQgPSByZW1haW5pbmdbbiAtIDFdKTtcbiAgICAgICAgICByb3cuYXJlYSArPSBjaGlsZC5hcmVhO1xuICAgICAgICAgIGlmIChtb2RlICE9PSBcInNxdWFyaWZ5XCIgfHwgKHNjb3JlID0gd29yc3Qocm93LCB1KSkgPD0gYmVzdCkge1xuICAgICAgICAgICAgcmVtYWluaW5nLnBvcCgpO1xuICAgICAgICAgICAgYmVzdCA9IHNjb3JlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByb3cuYXJlYSAtPSByb3cucG9wKCkuYXJlYTtcbiAgICAgICAgICAgIHBvc2l0aW9uKHJvdywgdSwgcmVjdCwgZmFsc2UpO1xuICAgICAgICAgICAgdSA9IE1hdGgubWluKHJlY3QuZHgsIHJlY3QuZHkpO1xuICAgICAgICAgICAgcm93Lmxlbmd0aCA9IHJvdy5hcmVhID0gMDtcbiAgICAgICAgICAgIGJlc3QgPSBJbmZpbml0eTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJvdy5sZW5ndGgpIHtcbiAgICAgICAgICBwb3NpdGlvbihyb3csIHUsIHJlY3QsIHRydWUpO1xuICAgICAgICAgIHJvdy5sZW5ndGggPSByb3cuYXJlYSA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgY2hpbGRyZW4uZm9yRWFjaChzcXVhcmlmeSk7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHN0aWNraWZ5KG5vZGUpIHtcbiAgICAgIHZhciBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW47XG4gICAgICBpZiAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICAgIHZhciByZWN0ID0gcGFkKG5vZGUpLCByZW1haW5pbmcgPSBjaGlsZHJlbi5zbGljZSgpLCBjaGlsZCwgcm93ID0gW107XG4gICAgICAgIHNjYWxlKHJlbWFpbmluZywgcmVjdC5keCAqIHJlY3QuZHkgLyBub2RlLnZhbHVlKTtcbiAgICAgICAgcm93LmFyZWEgPSAwO1xuICAgICAgICB3aGlsZSAoY2hpbGQgPSByZW1haW5pbmcucG9wKCkpIHtcbiAgICAgICAgICByb3cucHVzaChjaGlsZCk7XG4gICAgICAgICAgcm93LmFyZWEgKz0gY2hpbGQuYXJlYTtcbiAgICAgICAgICBpZiAoY2hpbGQueiAhPSBudWxsKSB7XG4gICAgICAgICAgICBwb3NpdGlvbihyb3csIGNoaWxkLnogPyByZWN0LmR4IDogcmVjdC5keSwgcmVjdCwgIXJlbWFpbmluZy5sZW5ndGgpO1xuICAgICAgICAgICAgcm93Lmxlbmd0aCA9IHJvdy5hcmVhID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2hpbGRyZW4uZm9yRWFjaChzdGlja2lmeSk7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHdvcnN0KHJvdywgdSkge1xuICAgICAgdmFyIHMgPSByb3cuYXJlYSwgciwgcm1heCA9IDAsIHJtaW4gPSBJbmZpbml0eSwgaSA9IC0xLCBuID0gcm93Lmxlbmd0aDtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgIGlmICghKHIgPSByb3dbaV0uYXJlYSkpIGNvbnRpbnVlO1xuICAgICAgICBpZiAociA8IHJtaW4pIHJtaW4gPSByO1xuICAgICAgICBpZiAociA+IHJtYXgpIHJtYXggPSByO1xuICAgICAgfVxuICAgICAgcyAqPSBzO1xuICAgICAgdSAqPSB1O1xuICAgICAgcmV0dXJuIHMgPyBNYXRoLm1heCh1ICogcm1heCAqIHJhdGlvIC8gcywgcyAvICh1ICogcm1pbiAqIHJhdGlvKSkgOiBJbmZpbml0eTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcG9zaXRpb24ocm93LCB1LCByZWN0LCBmbHVzaCkge1xuICAgICAgdmFyIGkgPSAtMSwgbiA9IHJvdy5sZW5ndGgsIHggPSByZWN0LngsIHkgPSByZWN0LnksIHYgPSB1ID8gcm91bmQocm93LmFyZWEgLyB1KSA6IDAsIG87XG4gICAgICBpZiAodSA9PSByZWN0LmR4KSB7XG4gICAgICAgIGlmIChmbHVzaCB8fCB2ID4gcmVjdC5keSkgdiA9IHJlY3QuZHk7XG4gICAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgbyA9IHJvd1tpXTtcbiAgICAgICAgICBvLnggPSB4O1xuICAgICAgICAgIG8ueSA9IHk7XG4gICAgICAgICAgby5keSA9IHY7XG4gICAgICAgICAgeCArPSBvLmR4ID0gTWF0aC5taW4ocmVjdC54ICsgcmVjdC5keCAtIHgsIHYgPyByb3VuZChvLmFyZWEgLyB2KSA6IDApO1xuICAgICAgICB9XG4gICAgICAgIG8ueiA9IHRydWU7XG4gICAgICAgIG8uZHggKz0gcmVjdC54ICsgcmVjdC5keCAtIHg7XG4gICAgICAgIHJlY3QueSArPSB2O1xuICAgICAgICByZWN0LmR5IC09IHY7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmx1c2ggfHwgdiA+IHJlY3QuZHgpIHYgPSByZWN0LmR4O1xuICAgICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAgIG8gPSByb3dbaV07XG4gICAgICAgICAgby54ID0geDtcbiAgICAgICAgICBvLnkgPSB5O1xuICAgICAgICAgIG8uZHggPSB2O1xuICAgICAgICAgIHkgKz0gby5keSA9IE1hdGgubWluKHJlY3QueSArIHJlY3QuZHkgLSB5LCB2ID8gcm91bmQoby5hcmVhIC8gdikgOiAwKTtcbiAgICAgICAgfVxuICAgICAgICBvLnogPSBmYWxzZTtcbiAgICAgICAgby5keSArPSByZWN0LnkgKyByZWN0LmR5IC0geTtcbiAgICAgICAgcmVjdC54ICs9IHY7XG4gICAgICAgIHJlY3QuZHggLT0gdjtcbiAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24gdHJlZW1hcChkKSB7XG4gICAgICB2YXIgbm9kZXMgPSBzdGlja2llcyB8fCBoaWVyYXJjaHkoZCksIHJvb3QgPSBub2Rlc1swXTtcbiAgICAgIHJvb3QueCA9IDA7XG4gICAgICByb290LnkgPSAwO1xuICAgICAgcm9vdC5keCA9IHNpemVbMF07XG4gICAgICByb290LmR5ID0gc2l6ZVsxXTtcbiAgICAgIGlmIChzdGlja2llcykgaGllcmFyY2h5LnJldmFsdWUocm9vdCk7XG4gICAgICBzY2FsZShbIHJvb3QgXSwgcm9vdC5keCAqIHJvb3QuZHkgLyByb290LnZhbHVlKTtcbiAgICAgIChzdGlja2llcyA/IHN0aWNraWZ5IDogc3F1YXJpZnkpKHJvb3QpO1xuICAgICAgaWYgKHN0aWNreSkgc3RpY2tpZXMgPSBub2RlcztcbiAgICAgIHJldHVybiBub2RlcztcbiAgICB9XG4gICAgdHJlZW1hcC5zaXplID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc2l6ZTtcbiAgICAgIHNpemUgPSB4O1xuICAgICAgcmV0dXJuIHRyZWVtYXA7XG4gICAgfTtcbiAgICB0cmVlbWFwLnBhZGRpbmcgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBwYWRkaW5nO1xuICAgICAgZnVuY3Rpb24gcGFkRnVuY3Rpb24obm9kZSkge1xuICAgICAgICB2YXIgcCA9IHguY2FsbCh0cmVlbWFwLCBub2RlLCBub2RlLmRlcHRoKTtcbiAgICAgICAgcmV0dXJuIHAgPT0gbnVsbCA/IGQzX2xheW91dF90cmVlbWFwUGFkTnVsbChub2RlKSA6IGQzX2xheW91dF90cmVlbWFwUGFkKG5vZGUsIHR5cGVvZiBwID09PSBcIm51bWJlclwiID8gWyBwLCBwLCBwLCBwIF0gOiBwKTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIHBhZENvbnN0YW50KG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIGQzX2xheW91dF90cmVlbWFwUGFkKG5vZGUsIHgpO1xuICAgICAgfVxuICAgICAgdmFyIHR5cGU7XG4gICAgICBwYWQgPSAocGFkZGluZyA9IHgpID09IG51bGwgPyBkM19sYXlvdXRfdHJlZW1hcFBhZE51bGwgOiAodHlwZSA9IHR5cGVvZiB4KSA9PT0gXCJmdW5jdGlvblwiID8gcGFkRnVuY3Rpb24gOiB0eXBlID09PSBcIm51bWJlclwiID8gKHggPSBbIHgsIHgsIHgsIHggXSwgXG4gICAgICBwYWRDb25zdGFudCkgOiBwYWRDb25zdGFudDtcbiAgICAgIHJldHVybiB0cmVlbWFwO1xuICAgIH07XG4gICAgdHJlZW1hcC5yb3VuZCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHJvdW5kICE9IE51bWJlcjtcbiAgICAgIHJvdW5kID0geCA/IE1hdGgucm91bmQgOiBOdW1iZXI7XG4gICAgICByZXR1cm4gdHJlZW1hcDtcbiAgICB9O1xuICAgIHRyZWVtYXAuc3RpY2t5ID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc3RpY2t5O1xuICAgICAgc3RpY2t5ID0geDtcbiAgICAgIHN0aWNraWVzID0gbnVsbDtcbiAgICAgIHJldHVybiB0cmVlbWFwO1xuICAgIH07XG4gICAgdHJlZW1hcC5yYXRpbyA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHJhdGlvO1xuICAgICAgcmF0aW8gPSB4O1xuICAgICAgcmV0dXJuIHRyZWVtYXA7XG4gICAgfTtcbiAgICB0cmVlbWFwLm1vZGUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBtb2RlO1xuICAgICAgbW9kZSA9IHggKyBcIlwiO1xuICAgICAgcmV0dXJuIHRyZWVtYXA7XG4gICAgfTtcbiAgICByZXR1cm4gZDNfbGF5b3V0X2hpZXJhcmNoeVJlYmluZCh0cmVlbWFwLCBoaWVyYXJjaHkpO1xuICB9O1xuICBmdW5jdGlvbiBkM19sYXlvdXRfdHJlZW1hcFBhZE51bGwobm9kZSkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiBub2RlLngsXG4gICAgICB5OiBub2RlLnksXG4gICAgICBkeDogbm9kZS5keCxcbiAgICAgIGR5OiBub2RlLmR5XG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBkM19sYXlvdXRfdHJlZW1hcFBhZChub2RlLCBwYWRkaW5nKSB7XG4gICAgdmFyIHggPSBub2RlLnggKyBwYWRkaW5nWzNdLCB5ID0gbm9kZS55ICsgcGFkZGluZ1swXSwgZHggPSBub2RlLmR4IC0gcGFkZGluZ1sxXSAtIHBhZGRpbmdbM10sIGR5ID0gbm9kZS5keSAtIHBhZGRpbmdbMF0gLSBwYWRkaW5nWzJdO1xuICAgIGlmIChkeCA8IDApIHtcbiAgICAgIHggKz0gZHggLyAyO1xuICAgICAgZHggPSAwO1xuICAgIH1cbiAgICBpZiAoZHkgPCAwKSB7XG4gICAgICB5ICs9IGR5IC8gMjtcbiAgICAgIGR5ID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5LFxuICAgICAgZHg6IGR4LFxuICAgICAgZHk6IGR5XG4gICAgfTtcbiAgfVxuICBkMy5yYW5kb20gPSB7XG4gICAgbm9ybWFsOiBmdW5jdGlvbijCtSwgz4MpIHtcbiAgICAgIHZhciBuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgIGlmIChuIDwgMikgz4MgPSAxO1xuICAgICAgaWYgKG4gPCAxKSDCtSA9IDA7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB4LCB5LCByO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgeCA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgICAgICB5ID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgICAgIHIgPSB4ICogeCArIHkgKiB5O1xuICAgICAgICB9IHdoaWxlICghciB8fCByID4gMSk7XG4gICAgICAgIHJldHVybiDCtSArIM+DICogeCAqIE1hdGguc3FydCgtMiAqIE1hdGgubG9nKHIpIC8gcik7XG4gICAgICB9O1xuICAgIH0sXG4gICAgbG9nTm9ybWFsOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByYW5kb20gPSBkMy5yYW5kb20ubm9ybWFsLmFwcGx5KGQzLCBhcmd1bWVudHMpO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gTWF0aC5leHAocmFuZG9tKCkpO1xuICAgICAgfTtcbiAgICB9LFxuICAgIGlyd2luSGFsbDogZnVuY3Rpb24obSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBmb3IgKHZhciBzID0gMCwgaiA9IDA7IGogPCBtOyBqKyspIHMgKz0gTWF0aC5yYW5kb20oKTtcbiAgICAgICAgcmV0dXJuIHMgLyBtO1xuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIGQzLnNjYWxlID0ge307XG4gIGZ1bmN0aW9uIGQzX3NjYWxlRXh0ZW50KGRvbWFpbikge1xuICAgIHZhciBzdGFydCA9IGRvbWFpblswXSwgc3RvcCA9IGRvbWFpbltkb21haW4ubGVuZ3RoIC0gMV07XG4gICAgcmV0dXJuIHN0YXJ0IDwgc3RvcCA/IFsgc3RhcnQsIHN0b3AgXSA6IFsgc3RvcCwgc3RhcnQgXTtcbiAgfVxuICBmdW5jdGlvbiBkM19zY2FsZVJhbmdlKHNjYWxlKSB7XG4gICAgcmV0dXJuIHNjYWxlLnJhbmdlRXh0ZW50ID8gc2NhbGUucmFuZ2VFeHRlbnQoKSA6IGQzX3NjYWxlRXh0ZW50KHNjYWxlLnJhbmdlKCkpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3NjYWxlX2JpbGluZWFyKGRvbWFpbiwgcmFuZ2UsIHVuaW50ZXJwb2xhdGUsIGludGVycG9sYXRlKSB7XG4gICAgdmFyIHUgPSB1bmludGVycG9sYXRlKGRvbWFpblswXSwgZG9tYWluWzFdKSwgaSA9IGludGVycG9sYXRlKHJhbmdlWzBdLCByYW5nZVsxXSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiBpKHUoeCkpO1xuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZDNfc2NhbGVfbmljZShkb21haW4sIG5pY2UpIHtcbiAgICB2YXIgaTAgPSAwLCBpMSA9IGRvbWFpbi5sZW5ndGggLSAxLCB4MCA9IGRvbWFpbltpMF0sIHgxID0gZG9tYWluW2kxXSwgZHg7XG4gICAgaWYgKHgxIDwgeDApIHtcbiAgICAgIGR4ID0gaTAsIGkwID0gaTEsIGkxID0gZHg7XG4gICAgICBkeCA9IHgwLCB4MCA9IHgxLCB4MSA9IGR4O1xuICAgIH1cbiAgICBkb21haW5baTBdID0gbmljZS5mbG9vcih4MCk7XG4gICAgZG9tYWluW2kxXSA9IG5pY2UuY2VpbCh4MSk7XG4gICAgcmV0dXJuIGRvbWFpbjtcbiAgfVxuICBmdW5jdGlvbiBkM19zY2FsZV9uaWNlU3RlcChzdGVwKSB7XG4gICAgcmV0dXJuIHN0ZXAgPyB7XG4gICAgICBmbG9vcjogZnVuY3Rpb24oeCkge1xuICAgICAgICByZXR1cm4gTWF0aC5mbG9vcih4IC8gc3RlcCkgKiBzdGVwO1xuICAgICAgfSxcbiAgICAgIGNlaWw6IGZ1bmN0aW9uKHgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguY2VpbCh4IC8gc3RlcCkgKiBzdGVwO1xuICAgICAgfVxuICAgIH0gOiBkM19zY2FsZV9uaWNlSWRlbnRpdHk7XG4gIH1cbiAgdmFyIGQzX3NjYWxlX25pY2VJZGVudGl0eSA9IHtcbiAgICBmbG9vcjogZDNfaWRlbnRpdHksXG4gICAgY2VpbDogZDNfaWRlbnRpdHlcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc2NhbGVfcG9seWxpbmVhcihkb21haW4sIHJhbmdlLCB1bmludGVycG9sYXRlLCBpbnRlcnBvbGF0ZSkge1xuICAgIHZhciB1ID0gW10sIGkgPSBbXSwgaiA9IDAsIGsgPSBNYXRoLm1pbihkb21haW4ubGVuZ3RoLCByYW5nZS5sZW5ndGgpIC0gMTtcbiAgICBpZiAoZG9tYWluW2tdIDwgZG9tYWluWzBdKSB7XG4gICAgICBkb21haW4gPSBkb21haW4uc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgICByYW5nZSA9IHJhbmdlLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIH1cbiAgICB3aGlsZSAoKytqIDw9IGspIHtcbiAgICAgIHUucHVzaCh1bmludGVycG9sYXRlKGRvbWFpbltqIC0gMV0sIGRvbWFpbltqXSkpO1xuICAgICAgaS5wdXNoKGludGVycG9sYXRlKHJhbmdlW2ogLSAxXSwgcmFuZ2Vbal0pKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciBqID0gZDMuYmlzZWN0KGRvbWFpbiwgeCwgMSwgaykgLSAxO1xuICAgICAgcmV0dXJuIGlbal0odVtqXSh4KSk7XG4gICAgfTtcbiAgfVxuICBkMy5zY2FsZS5saW5lYXIgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfc2NhbGVfbGluZWFyKFsgMCwgMSBdLCBbIDAsIDEgXSwgZDNfaW50ZXJwb2xhdGUsIGZhbHNlKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc2NhbGVfbGluZWFyKGRvbWFpbiwgcmFuZ2UsIGludGVycG9sYXRlLCBjbGFtcCkge1xuICAgIHZhciBvdXRwdXQsIGlucHV0O1xuICAgIGZ1bmN0aW9uIHJlc2NhbGUoKSB7XG4gICAgICB2YXIgbGluZWFyID0gTWF0aC5taW4oZG9tYWluLmxlbmd0aCwgcmFuZ2UubGVuZ3RoKSA+IDIgPyBkM19zY2FsZV9wb2x5bGluZWFyIDogZDNfc2NhbGVfYmlsaW5lYXIsIHVuaW50ZXJwb2xhdGUgPSBjbGFtcCA/IGQzX3VuaW50ZXJwb2xhdGVDbGFtcCA6IGQzX3VuaW50ZXJwb2xhdGVOdW1iZXI7XG4gICAgICBvdXRwdXQgPSBsaW5lYXIoZG9tYWluLCByYW5nZSwgdW5pbnRlcnBvbGF0ZSwgaW50ZXJwb2xhdGUpO1xuICAgICAgaW5wdXQgPSBsaW5lYXIocmFuZ2UsIGRvbWFpbiwgdW5pbnRlcnBvbGF0ZSwgZDNfaW50ZXJwb2xhdGUpO1xuICAgICAgcmV0dXJuIHNjYWxlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzY2FsZSh4KSB7XG4gICAgICByZXR1cm4gb3V0cHV0KHgpO1xuICAgIH1cbiAgICBzY2FsZS5pbnZlcnQgPSBmdW5jdGlvbih5KSB7XG4gICAgICByZXR1cm4gaW5wdXQoeSk7XG4gICAgfTtcbiAgICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBkb21haW47XG4gICAgICBkb21haW4gPSB4Lm1hcChOdW1iZXIpO1xuICAgICAgcmV0dXJuIHJlc2NhbGUoKTtcbiAgICB9O1xuICAgIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcmFuZ2U7XG4gICAgICByYW5nZSA9IHg7XG4gICAgICByZXR1cm4gcmVzY2FsZSgpO1xuICAgIH07XG4gICAgc2NhbGUucmFuZ2VSb3VuZCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiBzY2FsZS5yYW5nZSh4KS5pbnRlcnBvbGF0ZShkM19pbnRlcnBvbGF0ZVJvdW5kKTtcbiAgICB9O1xuICAgIHNjYWxlLmNsYW1wID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY2xhbXA7XG4gICAgICBjbGFtcCA9IHg7XG4gICAgICByZXR1cm4gcmVzY2FsZSgpO1xuICAgIH07XG4gICAgc2NhbGUuaW50ZXJwb2xhdGUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBpbnRlcnBvbGF0ZTtcbiAgICAgIGludGVycG9sYXRlID0geDtcbiAgICAgIHJldHVybiByZXNjYWxlKCk7XG4gICAgfTtcbiAgICBzY2FsZS50aWNrcyA9IGZ1bmN0aW9uKG0pIHtcbiAgICAgIHJldHVybiBkM19zY2FsZV9saW5lYXJUaWNrcyhkb21haW4sIG0pO1xuICAgIH07XG4gICAgc2NhbGUudGlja0Zvcm1hdCA9IGZ1bmN0aW9uKG0sIGZvcm1hdCkge1xuICAgICAgcmV0dXJuIGQzX3NjYWxlX2xpbmVhclRpY2tGb3JtYXQoZG9tYWluLCBtLCBmb3JtYXQpO1xuICAgIH07XG4gICAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKG0pIHtcbiAgICAgIGQzX3NjYWxlX2xpbmVhck5pY2UoZG9tYWluLCBtKTtcbiAgICAgIHJldHVybiByZXNjYWxlKCk7XG4gICAgfTtcbiAgICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZDNfc2NhbGVfbGluZWFyKGRvbWFpbiwgcmFuZ2UsIGludGVycG9sYXRlLCBjbGFtcCk7XG4gICAgfTtcbiAgICByZXR1cm4gcmVzY2FsZSgpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3NjYWxlX2xpbmVhclJlYmluZChzY2FsZSwgbGluZWFyKSB7XG4gICAgcmV0dXJuIGQzLnJlYmluZChzY2FsZSwgbGluZWFyLCBcInJhbmdlXCIsIFwicmFuZ2VSb3VuZFwiLCBcImludGVycG9sYXRlXCIsIFwiY2xhbXBcIik7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc2NhbGVfbGluZWFyTmljZShkb21haW4sIG0pIHtcbiAgICByZXR1cm4gZDNfc2NhbGVfbmljZShkb21haW4sIGQzX3NjYWxlX25pY2VTdGVwKG0gPyBkM19zY2FsZV9saW5lYXJUaWNrUmFuZ2UoZG9tYWluLCBtKVsyXSA6IGQzX3NjYWxlX2xpbmVhck5pY2VTdGVwKGRvbWFpbikpKTtcbiAgfVxuICBmdW5jdGlvbiBkM19zY2FsZV9saW5lYXJOaWNlU3RlcChkb21haW4pIHtcbiAgICB2YXIgZXh0ZW50ID0gZDNfc2NhbGVFeHRlbnQoZG9tYWluKSwgc3BhbiA9IGV4dGVudFsxXSAtIGV4dGVudFswXTtcbiAgICByZXR1cm4gTWF0aC5wb3coMTAsIE1hdGgucm91bmQoTWF0aC5sb2coc3BhbikgLyBNYXRoLkxOMTApIC0gMSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc2NhbGVfbGluZWFyVGlja1JhbmdlKGRvbWFpbiwgbSkge1xuICAgIHZhciBleHRlbnQgPSBkM19zY2FsZUV4dGVudChkb21haW4pLCBzcGFuID0gZXh0ZW50WzFdIC0gZXh0ZW50WzBdLCBzdGVwID0gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoTWF0aC5sb2coc3BhbiAvIG0pIC8gTWF0aC5MTjEwKSksIGVyciA9IG0gLyBzcGFuICogc3RlcDtcbiAgICBpZiAoZXJyIDw9IC4xNSkgc3RlcCAqPSAxMDsgZWxzZSBpZiAoZXJyIDw9IC4zNSkgc3RlcCAqPSA1OyBlbHNlIGlmIChlcnIgPD0gLjc1KSBzdGVwICo9IDI7XG4gICAgZXh0ZW50WzBdID0gTWF0aC5jZWlsKGV4dGVudFswXSAvIHN0ZXApICogc3RlcDtcbiAgICBleHRlbnRbMV0gPSBNYXRoLmZsb29yKGV4dGVudFsxXSAvIHN0ZXApICogc3RlcCArIHN0ZXAgKiAuNTtcbiAgICBleHRlbnRbMl0gPSBzdGVwO1xuICAgIHJldHVybiBleHRlbnQ7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc2NhbGVfbGluZWFyVGlja3MoZG9tYWluLCBtKSB7XG4gICAgcmV0dXJuIGQzLnJhbmdlLmFwcGx5KGQzLCBkM19zY2FsZV9saW5lYXJUaWNrUmFuZ2UoZG9tYWluLCBtKSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc2NhbGVfbGluZWFyVGlja0Zvcm1hdChkb21haW4sIG0sIGZvcm1hdCkge1xuICAgIHZhciBwcmVjaXNpb24gPSAtTWF0aC5mbG9vcihNYXRoLmxvZyhkM19zY2FsZV9saW5lYXJUaWNrUmFuZ2UoZG9tYWluLCBtKVsyXSkgLyBNYXRoLkxOMTAgKyAuMDEpO1xuICAgIHJldHVybiBkMy5mb3JtYXQoZm9ybWF0ID8gZm9ybWF0LnJlcGxhY2UoZDNfZm9ybWF0X3JlLCBmdW5jdGlvbihhLCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBpLCBqKSB7XG4gICAgICByZXR1cm4gWyBiLCBjLCBkLCBlLCBmLCBnLCBoLCBpIHx8IFwiLlwiICsgKHByZWNpc2lvbiAtIChqID09PSBcIiVcIikgKiAyKSwgaiBdLmpvaW4oXCJcIik7XG4gICAgfSkgOiBcIiwuXCIgKyBwcmVjaXNpb24gKyBcImZcIik7XG4gIH1cbiAgZDMuc2NhbGUubG9nID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX3NjYWxlX2xvZyhkMy5zY2FsZS5saW5lYXIoKS5kb21haW4oWyAwLCBNYXRoLkxOMTAgXSksIDEwLCBkM19zY2FsZV9sb2dwLCBkM19zY2FsZV9wb3dwLCBbIDEsIDEwIF0pO1xuICB9O1xuICBmdW5jdGlvbiBkM19zY2FsZV9sb2cobGluZWFyLCBiYXNlLCBsb2csIHBvdywgZG9tYWluKSB7XG4gICAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgICAgcmV0dXJuIGxpbmVhcihsb2coeCkpO1xuICAgIH1cbiAgICBzY2FsZS5pbnZlcnQgPSBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gcG93KGxpbmVhci5pbnZlcnQoeCkpO1xuICAgIH07XG4gICAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZG9tYWluO1xuICAgICAgaWYgKHhbMF0gPCAwKSBsb2cgPSBkM19zY2FsZV9sb2duLCBwb3cgPSBkM19zY2FsZV9wb3duOyBlbHNlIGxvZyA9IGQzX3NjYWxlX2xvZ3AsIFxuICAgICAgcG93ID0gZDNfc2NhbGVfcG93cDtcbiAgICAgIGxpbmVhci5kb21haW4oKGRvbWFpbiA9IHgubWFwKE51bWJlcikpLm1hcChsb2cpKTtcbiAgICAgIHJldHVybiBzY2FsZTtcbiAgICB9O1xuICAgIHNjYWxlLmJhc2UgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBiYXNlO1xuICAgICAgYmFzZSA9ICtfO1xuICAgICAgcmV0dXJuIHNjYWxlO1xuICAgIH07XG4gICAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgZnVuY3Rpb24gZmxvb3IoeCkge1xuICAgICAgICByZXR1cm4gTWF0aC5wb3coYmFzZSwgTWF0aC5mbG9vcihNYXRoLmxvZyh4KSAvIE1hdGgubG9nKGJhc2UpKSk7XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBjZWlsKHgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucG93KGJhc2UsIE1hdGguY2VpbChNYXRoLmxvZyh4KSAvIE1hdGgubG9nKGJhc2UpKSk7XG4gICAgICB9XG4gICAgICBsaW5lYXIuZG9tYWluKGQzX3NjYWxlX25pY2UoZG9tYWluLCBsb2cgPT09IGQzX3NjYWxlX2xvZ3AgPyB7XG4gICAgICAgIGZsb29yOiBmbG9vcixcbiAgICAgICAgY2VpbDogY2VpbFxuICAgICAgfSA6IHtcbiAgICAgICAgZmxvb3I6IGZ1bmN0aW9uKHgpIHtcbiAgICAgICAgICByZXR1cm4gLWNlaWwoLXgpO1xuICAgICAgICB9LFxuICAgICAgICBjZWlsOiBmdW5jdGlvbih4KSB7XG4gICAgICAgICAgcmV0dXJuIC1mbG9vcigteCk7XG4gICAgICAgIH1cbiAgICAgIH0pLm1hcChsb2cpKTtcbiAgICAgIHJldHVybiBzY2FsZTtcbiAgICB9O1xuICAgIHNjYWxlLnRpY2tzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZXh0ZW50ID0gZDNfc2NhbGVFeHRlbnQobGluZWFyLmRvbWFpbigpKSwgdGlja3MgPSBbXTtcbiAgICAgIGlmIChleHRlbnQuZXZlcnkoaXNGaW5pdGUpKSB7XG4gICAgICAgIHZhciBiID0gTWF0aC5sb2coYmFzZSksIGkgPSBNYXRoLmZsb29yKGV4dGVudFswXSAvIGIpLCBqID0gTWF0aC5jZWlsKGV4dGVudFsxXSAvIGIpLCB1ID0gcG93KGV4dGVudFswXSksIHYgPSBwb3coZXh0ZW50WzFdKSwgbiA9IGJhc2UgJSAxID8gMiA6IGJhc2U7XG4gICAgICAgIGlmIChsb2cgPT09IGQzX3NjYWxlX2xvZ24pIHtcbiAgICAgICAgICB0aWNrcy5wdXNoKC1NYXRoLnBvdyhiYXNlLCAtaSkpO1xuICAgICAgICAgIGZvciAoO2krKyA8IGo7ICkgZm9yICh2YXIgayA9IG4gLSAxOyBrID4gMDsgay0tKSB0aWNrcy5wdXNoKC1NYXRoLnBvdyhiYXNlLCAtaSkgKiBrKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKDtpIDwgajsgaSsrKSBmb3IgKHZhciBrID0gMTsgayA8IG47IGsrKykgdGlja3MucHVzaChNYXRoLnBvdyhiYXNlLCBpKSAqIGspO1xuICAgICAgICAgIHRpY2tzLnB1c2goTWF0aC5wb3coYmFzZSwgaSkpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoaSA9IDA7IHRpY2tzW2ldIDwgdTsgaSsrKSB7fVxuICAgICAgICBmb3IgKGogPSB0aWNrcy5sZW5ndGg7IHRpY2tzW2ogLSAxXSA+IHY7IGotLSkge31cbiAgICAgICAgdGlja3MgPSB0aWNrcy5zbGljZShpLCBqKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aWNrcztcbiAgICB9O1xuICAgIHNjYWxlLnRpY2tGb3JtYXQgPSBmdW5jdGlvbihuLCBmb3JtYXQpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGQzX3NjYWxlX2xvZ0Zvcm1hdDtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikgZm9ybWF0ID0gZDNfc2NhbGVfbG9nRm9ybWF0OyBlbHNlIGlmICh0eXBlb2YgZm9ybWF0ICE9PSBcImZ1bmN0aW9uXCIpIGZvcm1hdCA9IGQzLmZvcm1hdChmb3JtYXQpO1xuICAgICAgdmFyIGIgPSBNYXRoLmxvZyhiYXNlKSwgayA9IE1hdGgubWF4KC4xLCBuIC8gc2NhbGUudGlja3MoKS5sZW5ndGgpLCBmID0gbG9nID09PSBkM19zY2FsZV9sb2duID8gKGUgPSAtMWUtMTIsIFxuICAgICAgTWF0aC5mbG9vcikgOiAoZSA9IDFlLTEyLCBNYXRoLmNlaWwpLCBlO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgcmV0dXJuIGQgLyBwb3coYiAqIGYobG9nKGQpIC8gYiArIGUpKSA8PSBrID8gZm9ybWF0KGQpIDogXCJcIjtcbiAgICAgIH07XG4gICAgfTtcbiAgICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZDNfc2NhbGVfbG9nKGxpbmVhci5jb3B5KCksIGJhc2UsIGxvZywgcG93LCBkb21haW4pO1xuICAgIH07XG4gICAgcmV0dXJuIGQzX3NjYWxlX2xpbmVhclJlYmluZChzY2FsZSwgbGluZWFyKTtcbiAgfVxuICB2YXIgZDNfc2NhbGVfbG9nRm9ybWF0ID0gZDMuZm9ybWF0KFwiLjBlXCIpO1xuICBmdW5jdGlvbiBkM19zY2FsZV9sb2dwKHgpIHtcbiAgICByZXR1cm4gTWF0aC5sb2coeCA8IDAgPyAwIDogeCk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc2NhbGVfcG93cCh4KSB7XG4gICAgcmV0dXJuIE1hdGguZXhwKHgpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3NjYWxlX2xvZ24oeCkge1xuICAgIHJldHVybiAtTWF0aC5sb2coeCA+IDAgPyAwIDogLXgpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3NjYWxlX3Bvd24oeCkge1xuICAgIHJldHVybiAtTWF0aC5leHAoLXgpO1xuICB9XG4gIGQzLnNjYWxlLnBvdyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19zY2FsZV9wb3coZDMuc2NhbGUubGluZWFyKCksIDEsIFsgMCwgMSBdKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc2NhbGVfcG93KGxpbmVhciwgZXhwb25lbnQsIGRvbWFpbikge1xuICAgIHZhciBwb3dwID0gZDNfc2NhbGVfcG93UG93KGV4cG9uZW50KSwgcG93YiA9IGQzX3NjYWxlX3Bvd1BvdygxIC8gZXhwb25lbnQpO1xuICAgIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICAgIHJldHVybiBsaW5lYXIocG93cCh4KSk7XG4gICAgfVxuICAgIHNjYWxlLmludmVydCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiBwb3diKGxpbmVhci5pbnZlcnQoeCkpO1xuICAgIH07XG4gICAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZG9tYWluO1xuICAgICAgbGluZWFyLmRvbWFpbigoZG9tYWluID0geC5tYXAoTnVtYmVyKSkubWFwKHBvd3ApKTtcbiAgICAgIHJldHVybiBzY2FsZTtcbiAgICB9O1xuICAgIHNjYWxlLnRpY2tzID0gZnVuY3Rpb24obSkge1xuICAgICAgcmV0dXJuIGQzX3NjYWxlX2xpbmVhclRpY2tzKGRvbWFpbiwgbSk7XG4gICAgfTtcbiAgICBzY2FsZS50aWNrRm9ybWF0ID0gZnVuY3Rpb24obSwgZm9ybWF0KSB7XG4gICAgICByZXR1cm4gZDNfc2NhbGVfbGluZWFyVGlja0Zvcm1hdChkb21haW4sIG0sIGZvcm1hdCk7XG4gICAgfTtcbiAgICBzY2FsZS5uaWNlID0gZnVuY3Rpb24obSkge1xuICAgICAgcmV0dXJuIHNjYWxlLmRvbWFpbihkM19zY2FsZV9saW5lYXJOaWNlKGRvbWFpbiwgbSkpO1xuICAgIH07XG4gICAgc2NhbGUuZXhwb25lbnQgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBleHBvbmVudDtcbiAgICAgIHBvd3AgPSBkM19zY2FsZV9wb3dQb3coZXhwb25lbnQgPSB4KTtcbiAgICAgIHBvd2IgPSBkM19zY2FsZV9wb3dQb3coMSAvIGV4cG9uZW50KTtcbiAgICAgIGxpbmVhci5kb21haW4oZG9tYWluLm1hcChwb3dwKSk7XG4gICAgICByZXR1cm4gc2NhbGU7XG4gICAgfTtcbiAgICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZDNfc2NhbGVfcG93KGxpbmVhci5jb3B5KCksIGV4cG9uZW50LCBkb21haW4pO1xuICAgIH07XG4gICAgcmV0dXJuIGQzX3NjYWxlX2xpbmVhclJlYmluZChzY2FsZSwgbGluZWFyKTtcbiAgfVxuICBmdW5jdGlvbiBkM19zY2FsZV9wb3dQb3coZSkge1xuICAgIHJldHVybiBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4geCA8IDAgPyAtTWF0aC5wb3coLXgsIGUpIDogTWF0aC5wb3coeCwgZSk7XG4gICAgfTtcbiAgfVxuICBkMy5zY2FsZS5zcXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzLnNjYWxlLnBvdygpLmV4cG9uZW50KC41KTtcbiAgfTtcbiAgZDMuc2NhbGUub3JkaW5hbCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM19zY2FsZV9vcmRpbmFsKFtdLCB7XG4gICAgICB0OiBcInJhbmdlXCIsXG4gICAgICBhOiBbIFtdIF1cbiAgICB9KTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc2NhbGVfb3JkaW5hbChkb21haW4sIHJhbmdlcikge1xuICAgIHZhciBpbmRleCwgcmFuZ2UsIHJhbmdlQmFuZDtcbiAgICBmdW5jdGlvbiBzY2FsZSh4KSB7XG4gICAgICByZXR1cm4gcmFuZ2VbKChpbmRleC5nZXQoeCkgfHwgaW5kZXguc2V0KHgsIGRvbWFpbi5wdXNoKHgpKSkgLSAxKSAlIHJhbmdlLmxlbmd0aF07XG4gICAgfVxuICAgIGZ1bmN0aW9uIHN0ZXBzKHN0YXJ0LCBzdGVwKSB7XG4gICAgICByZXR1cm4gZDMucmFuZ2UoZG9tYWluLmxlbmd0aCkubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgICAgcmV0dXJuIHN0YXJ0ICsgc3RlcCAqIGk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZG9tYWluO1xuICAgICAgZG9tYWluID0gW107XG4gICAgICBpbmRleCA9IG5ldyBkM19NYXAoKTtcbiAgICAgIHZhciBpID0gLTEsIG4gPSB4Lmxlbmd0aCwgeGk7XG4gICAgICB3aGlsZSAoKytpIDwgbikgaWYgKCFpbmRleC5oYXMoeGkgPSB4W2ldKSkgaW5kZXguc2V0KHhpLCBkb21haW4ucHVzaCh4aSkpO1xuICAgICAgcmV0dXJuIHNjYWxlW3Jhbmdlci50XS5hcHBseShzY2FsZSwgcmFuZ2VyLmEpO1xuICAgIH07XG4gICAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiByYW5nZTtcbiAgICAgIHJhbmdlID0geDtcbiAgICAgIHJhbmdlQmFuZCA9IDA7XG4gICAgICByYW5nZXIgPSB7XG4gICAgICAgIHQ6IFwicmFuZ2VcIixcbiAgICAgICAgYTogYXJndW1lbnRzXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHNjYWxlO1xuICAgIH07XG4gICAgc2NhbGUucmFuZ2VQb2ludHMgPSBmdW5jdGlvbih4LCBwYWRkaW5nKSB7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHBhZGRpbmcgPSAwO1xuICAgICAgdmFyIHN0YXJ0ID0geFswXSwgc3RvcCA9IHhbMV0sIHN0ZXAgPSAoc3RvcCAtIHN0YXJ0KSAvIChNYXRoLm1heCgxLCBkb21haW4ubGVuZ3RoIC0gMSkgKyBwYWRkaW5nKTtcbiAgICAgIHJhbmdlID0gc3RlcHMoZG9tYWluLmxlbmd0aCA8IDIgPyAoc3RhcnQgKyBzdG9wKSAvIDIgOiBzdGFydCArIHN0ZXAgKiBwYWRkaW5nIC8gMiwgc3RlcCk7XG4gICAgICByYW5nZUJhbmQgPSAwO1xuICAgICAgcmFuZ2VyID0ge1xuICAgICAgICB0OiBcInJhbmdlUG9pbnRzXCIsXG4gICAgICAgIGE6IGFyZ3VtZW50c1xuICAgICAgfTtcbiAgICAgIHJldHVybiBzY2FsZTtcbiAgICB9O1xuICAgIHNjYWxlLnJhbmdlQmFuZHMgPSBmdW5jdGlvbih4LCBwYWRkaW5nLCBvdXRlclBhZGRpbmcpIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikgcGFkZGluZyA9IDA7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIG91dGVyUGFkZGluZyA9IHBhZGRpbmc7XG4gICAgICB2YXIgcmV2ZXJzZSA9IHhbMV0gPCB4WzBdLCBzdGFydCA9IHhbcmV2ZXJzZSAtIDBdLCBzdG9wID0geFsxIC0gcmV2ZXJzZV0sIHN0ZXAgPSAoc3RvcCAtIHN0YXJ0KSAvIChkb21haW4ubGVuZ3RoIC0gcGFkZGluZyArIDIgKiBvdXRlclBhZGRpbmcpO1xuICAgICAgcmFuZ2UgPSBzdGVwcyhzdGFydCArIHN0ZXAgKiBvdXRlclBhZGRpbmcsIHN0ZXApO1xuICAgICAgaWYgKHJldmVyc2UpIHJhbmdlLnJldmVyc2UoKTtcbiAgICAgIHJhbmdlQmFuZCA9IHN0ZXAgKiAoMSAtIHBhZGRpbmcpO1xuICAgICAgcmFuZ2VyID0ge1xuICAgICAgICB0OiBcInJhbmdlQmFuZHNcIixcbiAgICAgICAgYTogYXJndW1lbnRzXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHNjYWxlO1xuICAgIH07XG4gICAgc2NhbGUucmFuZ2VSb3VuZEJhbmRzID0gZnVuY3Rpb24oeCwgcGFkZGluZywgb3V0ZXJQYWRkaW5nKSB7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHBhZGRpbmcgPSAwO1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSBvdXRlclBhZGRpbmcgPSBwYWRkaW5nO1xuICAgICAgdmFyIHJldmVyc2UgPSB4WzFdIDwgeFswXSwgc3RhcnQgPSB4W3JldmVyc2UgLSAwXSwgc3RvcCA9IHhbMSAtIHJldmVyc2VdLCBzdGVwID0gTWF0aC5mbG9vcigoc3RvcCAtIHN0YXJ0KSAvIChkb21haW4ubGVuZ3RoIC0gcGFkZGluZyArIDIgKiBvdXRlclBhZGRpbmcpKSwgZXJyb3IgPSBzdG9wIC0gc3RhcnQgLSAoZG9tYWluLmxlbmd0aCAtIHBhZGRpbmcpICogc3RlcDtcbiAgICAgIHJhbmdlID0gc3RlcHMoc3RhcnQgKyBNYXRoLnJvdW5kKGVycm9yIC8gMiksIHN0ZXApO1xuICAgICAgaWYgKHJldmVyc2UpIHJhbmdlLnJldmVyc2UoKTtcbiAgICAgIHJhbmdlQmFuZCA9IE1hdGgucm91bmQoc3RlcCAqICgxIC0gcGFkZGluZykpO1xuICAgICAgcmFuZ2VyID0ge1xuICAgICAgICB0OiBcInJhbmdlUm91bmRCYW5kc1wiLFxuICAgICAgICBhOiBhcmd1bWVudHNcbiAgICAgIH07XG4gICAgICByZXR1cm4gc2NhbGU7XG4gICAgfTtcbiAgICBzY2FsZS5yYW5nZUJhbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiByYW5nZUJhbmQ7XG4gICAgfTtcbiAgICBzY2FsZS5yYW5nZUV4dGVudCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGQzX3NjYWxlRXh0ZW50KHJhbmdlci5hWzBdKTtcbiAgICB9O1xuICAgIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkM19zY2FsZV9vcmRpbmFsKGRvbWFpbiwgcmFuZ2VyKTtcbiAgICB9O1xuICAgIHJldHVybiBzY2FsZS5kb21haW4oZG9tYWluKTtcbiAgfVxuICBkMy5zY2FsZS5jYXRlZ29yeTEwID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzLnNjYWxlLm9yZGluYWwoKS5yYW5nZShkM19jYXRlZ29yeTEwKTtcbiAgfTtcbiAgZDMuc2NhbGUuY2F0ZWdvcnkyMCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkMy5zY2FsZS5vcmRpbmFsKCkucmFuZ2UoZDNfY2F0ZWdvcnkyMCk7XG4gIH07XG4gIGQzLnNjYWxlLmNhdGVnb3J5MjBiID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzLnNjYWxlLm9yZGluYWwoKS5yYW5nZShkM19jYXRlZ29yeTIwYik7XG4gIH07XG4gIGQzLnNjYWxlLmNhdGVnb3J5MjBjID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzLnNjYWxlLm9yZGluYWwoKS5yYW5nZShkM19jYXRlZ29yeTIwYyk7XG4gIH07XG4gIHZhciBkM19jYXRlZ29yeTEwID0gWyBcIiMxZjc3YjRcIiwgXCIjZmY3ZjBlXCIsIFwiIzJjYTAyY1wiLCBcIiNkNjI3MjhcIiwgXCIjOTQ2N2JkXCIsIFwiIzhjNTY0YlwiLCBcIiNlMzc3YzJcIiwgXCIjN2Y3ZjdmXCIsIFwiI2JjYmQyMlwiLCBcIiMxN2JlY2ZcIiBdO1xuICB2YXIgZDNfY2F0ZWdvcnkyMCA9IFsgXCIjMWY3N2I0XCIsIFwiI2FlYzdlOFwiLCBcIiNmZjdmMGVcIiwgXCIjZmZiYjc4XCIsIFwiIzJjYTAyY1wiLCBcIiM5OGRmOGFcIiwgXCIjZDYyNzI4XCIsIFwiI2ZmOTg5NlwiLCBcIiM5NDY3YmRcIiwgXCIjYzViMGQ1XCIsIFwiIzhjNTY0YlwiLCBcIiNjNDljOTRcIiwgXCIjZTM3N2MyXCIsIFwiI2Y3YjZkMlwiLCBcIiM3ZjdmN2ZcIiwgXCIjYzdjN2M3XCIsIFwiI2JjYmQyMlwiLCBcIiNkYmRiOGRcIiwgXCIjMTdiZWNmXCIsIFwiIzllZGFlNVwiIF07XG4gIHZhciBkM19jYXRlZ29yeTIwYiA9IFsgXCIjMzkzYjc5XCIsIFwiIzUyNTRhM1wiLCBcIiM2YjZlY2ZcIiwgXCIjOWM5ZWRlXCIsIFwiIzYzNzkzOVwiLCBcIiM4Y2EyNTJcIiwgXCIjYjVjZjZiXCIsIFwiI2NlZGI5Y1wiLCBcIiM4YzZkMzFcIiwgXCIjYmQ5ZTM5XCIsIFwiI2U3YmE1MlwiLCBcIiNlN2NiOTRcIiwgXCIjODQzYzM5XCIsIFwiI2FkNDk0YVwiLCBcIiNkNjYxNmJcIiwgXCIjZTc5NjljXCIsIFwiIzdiNDE3M1wiLCBcIiNhNTUxOTRcIiwgXCIjY2U2ZGJkXCIsIFwiI2RlOWVkNlwiIF07XG4gIHZhciBkM19jYXRlZ29yeTIwYyA9IFsgXCIjMzE4MmJkXCIsIFwiIzZiYWVkNlwiLCBcIiM5ZWNhZTFcIiwgXCIjYzZkYmVmXCIsIFwiI2U2NTUwZFwiLCBcIiNmZDhkM2NcIiwgXCIjZmRhZTZiXCIsIFwiI2ZkZDBhMlwiLCBcIiMzMWEzNTRcIiwgXCIjNzRjNDc2XCIsIFwiI2ExZDk5YlwiLCBcIiNjN2U5YzBcIiwgXCIjNzU2YmIxXCIsIFwiIzllOWFjOFwiLCBcIiNiY2JkZGNcIiwgXCIjZGFkYWViXCIsIFwiIzYzNjM2M1wiLCBcIiM5Njk2OTZcIiwgXCIjYmRiZGJkXCIsIFwiI2Q5ZDlkOVwiIF07XG4gIGQzLnNjYWxlLnF1YW50aWxlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGQzX3NjYWxlX3F1YW50aWxlKFtdLCBbXSk7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3NjYWxlX3F1YW50aWxlKGRvbWFpbiwgcmFuZ2UpIHtcbiAgICB2YXIgdGhyZXNob2xkcztcbiAgICBmdW5jdGlvbiByZXNjYWxlKCkge1xuICAgICAgdmFyIGsgPSAwLCBxID0gcmFuZ2UubGVuZ3RoO1xuICAgICAgdGhyZXNob2xkcyA9IFtdO1xuICAgICAgd2hpbGUgKCsrayA8IHEpIHRocmVzaG9sZHNbayAtIDFdID0gZDMucXVhbnRpbGUoZG9tYWluLCBrIC8gcSk7XG4gICAgICByZXR1cm4gc2NhbGU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICAgIGlmICghaXNOYU4oeCA9ICt4KSkgcmV0dXJuIHJhbmdlW2QzLmJpc2VjdCh0aHJlc2hvbGRzLCB4KV07XG4gICAgfVxuICAgIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGRvbWFpbjtcbiAgICAgIGRvbWFpbiA9IHguZmlsdGVyKGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgcmV0dXJuICFpc05hTihkKTtcbiAgICAgIH0pLnNvcnQoZDMuYXNjZW5kaW5nKTtcbiAgICAgIHJldHVybiByZXNjYWxlKCk7XG4gICAgfTtcbiAgICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHJhbmdlO1xuICAgICAgcmFuZ2UgPSB4O1xuICAgICAgcmV0dXJuIHJlc2NhbGUoKTtcbiAgICB9O1xuICAgIHNjYWxlLnF1YW50aWxlcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRocmVzaG9sZHM7XG4gICAgfTtcbiAgICBzY2FsZS5pbnZlcnRFeHRlbnQgPSBmdW5jdGlvbih5KSB7XG4gICAgICB5ID0gcmFuZ2UuaW5kZXhPZih5KTtcbiAgICAgIHJldHVybiB5IDwgMCA/IFsgTmFOLCBOYU4gXSA6IFsgeSA+IDAgPyB0aHJlc2hvbGRzW3kgLSAxXSA6IGRvbWFpblswXSwgeSA8IHRocmVzaG9sZHMubGVuZ3RoID8gdGhyZXNob2xkc1t5XSA6IGRvbWFpbltkb21haW4ubGVuZ3RoIC0gMV0gXTtcbiAgICB9O1xuICAgIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkM19zY2FsZV9xdWFudGlsZShkb21haW4sIHJhbmdlKTtcbiAgICB9O1xuICAgIHJldHVybiByZXNjYWxlKCk7XG4gIH1cbiAgZDMuc2NhbGUucXVhbnRpemUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfc2NhbGVfcXVhbnRpemUoMCwgMSwgWyAwLCAxIF0pO1xuICB9O1xuICBmdW5jdGlvbiBkM19zY2FsZV9xdWFudGl6ZSh4MCwgeDEsIHJhbmdlKSB7XG4gICAgdmFyIGt4LCBpO1xuICAgIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICAgIHJldHVybiByYW5nZVtNYXRoLm1heCgwLCBNYXRoLm1pbihpLCBNYXRoLmZsb29yKGt4ICogKHggLSB4MCkpKSldO1xuICAgIH1cbiAgICBmdW5jdGlvbiByZXNjYWxlKCkge1xuICAgICAga3ggPSByYW5nZS5sZW5ndGggLyAoeDEgLSB4MCk7XG4gICAgICBpID0gcmFuZ2UubGVuZ3RoIC0gMTtcbiAgICAgIHJldHVybiBzY2FsZTtcbiAgICB9XG4gICAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gWyB4MCwgeDEgXTtcbiAgICAgIHgwID0gK3hbMF07XG4gICAgICB4MSA9ICt4W3gubGVuZ3RoIC0gMV07XG4gICAgICByZXR1cm4gcmVzY2FsZSgpO1xuICAgIH07XG4gICAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiByYW5nZTtcbiAgICAgIHJhbmdlID0geDtcbiAgICAgIHJldHVybiByZXNjYWxlKCk7XG4gICAgfTtcbiAgICBzY2FsZS5pbnZlcnRFeHRlbnQgPSBmdW5jdGlvbih5KSB7XG4gICAgICB5ID0gcmFuZ2UuaW5kZXhPZih5KTtcbiAgICAgIHkgPSB5IDwgMCA/IE5hTiA6IHkgLyBreCArIHgwO1xuICAgICAgcmV0dXJuIFsgeSwgeSArIDEgLyBreCBdO1xuICAgIH07XG4gICAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGQzX3NjYWxlX3F1YW50aXplKHgwLCB4MSwgcmFuZ2UpO1xuICAgIH07XG4gICAgcmV0dXJuIHJlc2NhbGUoKTtcbiAgfVxuICBkMy5zY2FsZS50aHJlc2hvbGQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfc2NhbGVfdGhyZXNob2xkKFsgLjUgXSwgWyAwLCAxIF0pO1xuICB9O1xuICBmdW5jdGlvbiBkM19zY2FsZV90aHJlc2hvbGQoZG9tYWluLCByYW5nZSkge1xuICAgIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICAgIGlmICh4IDw9IHgpIHJldHVybiByYW5nZVtkMy5iaXNlY3QoZG9tYWluLCB4KV07XG4gICAgfVxuICAgIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGRvbWFpbjtcbiAgICAgIGRvbWFpbiA9IF87XG4gICAgICByZXR1cm4gc2NhbGU7XG4gICAgfTtcbiAgICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHJhbmdlO1xuICAgICAgcmFuZ2UgPSBfO1xuICAgICAgcmV0dXJuIHNjYWxlO1xuICAgIH07XG4gICAgc2NhbGUuaW52ZXJ0RXh0ZW50ID0gZnVuY3Rpb24oeSkge1xuICAgICAgeSA9IHJhbmdlLmluZGV4T2YoeSk7XG4gICAgICByZXR1cm4gWyBkb21haW5beSAtIDFdLCBkb21haW5beV0gXTtcbiAgICB9O1xuICAgIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkM19zY2FsZV90aHJlc2hvbGQoZG9tYWluLCByYW5nZSk7XG4gICAgfTtcbiAgICByZXR1cm4gc2NhbGU7XG4gIH1cbiAgZDMuc2NhbGUuaWRlbnRpdHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfc2NhbGVfaWRlbnRpdHkoWyAwLCAxIF0pO1xuICB9O1xuICBmdW5jdGlvbiBkM19zY2FsZV9pZGVudGl0eShkb21haW4pIHtcbiAgICBmdW5jdGlvbiBpZGVudGl0eSh4KSB7XG4gICAgICByZXR1cm4gK3g7XG4gICAgfVxuICAgIGlkZW50aXR5LmludmVydCA9IGlkZW50aXR5O1xuICAgIGlkZW50aXR5LmRvbWFpbiA9IGlkZW50aXR5LnJhbmdlID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZG9tYWluO1xuICAgICAgZG9tYWluID0geC5tYXAoaWRlbnRpdHkpO1xuICAgICAgcmV0dXJuIGlkZW50aXR5O1xuICAgIH07XG4gICAgaWRlbnRpdHkudGlja3MgPSBmdW5jdGlvbihtKSB7XG4gICAgICByZXR1cm4gZDNfc2NhbGVfbGluZWFyVGlja3MoZG9tYWluLCBtKTtcbiAgICB9O1xuICAgIGlkZW50aXR5LnRpY2tGb3JtYXQgPSBmdW5jdGlvbihtLCBmb3JtYXQpIHtcbiAgICAgIHJldHVybiBkM19zY2FsZV9saW5lYXJUaWNrRm9ybWF0KGRvbWFpbiwgbSwgZm9ybWF0KTtcbiAgICB9O1xuICAgIGlkZW50aXR5LmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkM19zY2FsZV9pZGVudGl0eShkb21haW4pO1xuICAgIH07XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGQzLnN2Zy5hcmMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaW5uZXJSYWRpdXMgPSBkM19zdmdfYXJjSW5uZXJSYWRpdXMsIG91dGVyUmFkaXVzID0gZDNfc3ZnX2FyY091dGVyUmFkaXVzLCBzdGFydEFuZ2xlID0gZDNfc3ZnX2FyY1N0YXJ0QW5nbGUsIGVuZEFuZ2xlID0gZDNfc3ZnX2FyY0VuZEFuZ2xlO1xuICAgIGZ1bmN0aW9uIGFyYygpIHtcbiAgICAgIHZhciByMCA9IGlubmVyUmFkaXVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHIxID0gb3V0ZXJSYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSwgYTAgPSBzdGFydEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgKyBkM19zdmdfYXJjT2Zmc2V0LCBhMSA9IGVuZEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgKyBkM19zdmdfYXJjT2Zmc2V0LCBkYSA9IChhMSA8IGEwICYmIChkYSA9IGEwLCBcbiAgICAgIGEwID0gYTEsIGExID0gZGEpLCBhMSAtIGEwKSwgZGYgPSBkYSA8IM+AID8gXCIwXCIgOiBcIjFcIiwgYzAgPSBNYXRoLmNvcyhhMCksIHMwID0gTWF0aC5zaW4oYTApLCBjMSA9IE1hdGguY29zKGExKSwgczEgPSBNYXRoLnNpbihhMSk7XG4gICAgICByZXR1cm4gZGEgPj0gZDNfc3ZnX2FyY01heCA/IHIwID8gXCJNMCxcIiArIHIxICsgXCJBXCIgKyByMSArIFwiLFwiICsgcjEgKyBcIiAwIDEsMSAwLFwiICsgLXIxICsgXCJBXCIgKyByMSArIFwiLFwiICsgcjEgKyBcIiAwIDEsMSAwLFwiICsgcjEgKyBcIk0wLFwiICsgcjAgKyBcIkFcIiArIHIwICsgXCIsXCIgKyByMCArIFwiIDAgMSwwIDAsXCIgKyAtcjAgKyBcIkFcIiArIHIwICsgXCIsXCIgKyByMCArIFwiIDAgMSwwIDAsXCIgKyByMCArIFwiWlwiIDogXCJNMCxcIiArIHIxICsgXCJBXCIgKyByMSArIFwiLFwiICsgcjEgKyBcIiAwIDEsMSAwLFwiICsgLXIxICsgXCJBXCIgKyByMSArIFwiLFwiICsgcjEgKyBcIiAwIDEsMSAwLFwiICsgcjEgKyBcIlpcIiA6IHIwID8gXCJNXCIgKyByMSAqIGMwICsgXCIsXCIgKyByMSAqIHMwICsgXCJBXCIgKyByMSArIFwiLFwiICsgcjEgKyBcIiAwIFwiICsgZGYgKyBcIiwxIFwiICsgcjEgKiBjMSArIFwiLFwiICsgcjEgKiBzMSArIFwiTFwiICsgcjAgKiBjMSArIFwiLFwiICsgcjAgKiBzMSArIFwiQVwiICsgcjAgKyBcIixcIiArIHIwICsgXCIgMCBcIiArIGRmICsgXCIsMCBcIiArIHIwICogYzAgKyBcIixcIiArIHIwICogczAgKyBcIlpcIiA6IFwiTVwiICsgcjEgKiBjMCArIFwiLFwiICsgcjEgKiBzMCArIFwiQVwiICsgcjEgKyBcIixcIiArIHIxICsgXCIgMCBcIiArIGRmICsgXCIsMSBcIiArIHIxICogYzEgKyBcIixcIiArIHIxICogczEgKyBcIkwwLDBcIiArIFwiWlwiO1xuICAgIH1cbiAgICBhcmMuaW5uZXJSYWRpdXMgPSBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBpbm5lclJhZGl1cztcbiAgICAgIGlubmVyUmFkaXVzID0gZDNfZnVuY3Rvcih2KTtcbiAgICAgIHJldHVybiBhcmM7XG4gICAgfTtcbiAgICBhcmMub3V0ZXJSYWRpdXMgPSBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBvdXRlclJhZGl1cztcbiAgICAgIG91dGVyUmFkaXVzID0gZDNfZnVuY3Rvcih2KTtcbiAgICAgIHJldHVybiBhcmM7XG4gICAgfTtcbiAgICBhcmMuc3RhcnRBbmdsZSA9IGZ1bmN0aW9uKHYpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHN0YXJ0QW5nbGU7XG4gICAgICBzdGFydEFuZ2xlID0gZDNfZnVuY3Rvcih2KTtcbiAgICAgIHJldHVybiBhcmM7XG4gICAgfTtcbiAgICBhcmMuZW5kQW5nbGUgPSBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBlbmRBbmdsZTtcbiAgICAgIGVuZEFuZ2xlID0gZDNfZnVuY3Rvcih2KTtcbiAgICAgIHJldHVybiBhcmM7XG4gICAgfTtcbiAgICBhcmMuY2VudHJvaWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByID0gKGlubmVyUmFkaXVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgKyBvdXRlclJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSAvIDIsIGEgPSAoc3RhcnRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpICsgZW5kQW5nbGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgLyAyICsgZDNfc3ZnX2FyY09mZnNldDtcbiAgICAgIHJldHVybiBbIE1hdGguY29zKGEpICogciwgTWF0aC5zaW4oYSkgKiByIF07XG4gICAgfTtcbiAgICByZXR1cm4gYXJjO1xuICB9O1xuICB2YXIgZDNfc3ZnX2FyY09mZnNldCA9IC3PgCAvIDIsIGQzX3N2Z19hcmNNYXggPSAyICogz4AgLSAxZS02O1xuICBmdW5jdGlvbiBkM19zdmdfYXJjSW5uZXJSYWRpdXMoZCkge1xuICAgIHJldHVybiBkLmlubmVyUmFkaXVzO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3N2Z19hcmNPdXRlclJhZGl1cyhkKSB7XG4gICAgcmV0dXJuIGQub3V0ZXJSYWRpdXM7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2FyY1N0YXJ0QW5nbGUoZCkge1xuICAgIHJldHVybiBkLnN0YXJ0QW5nbGU7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2FyY0VuZEFuZ2xlKGQpIHtcbiAgICByZXR1cm4gZC5lbmRBbmdsZTtcbiAgfVxuICBkMy5zdmcubGluZS5yYWRpYWwgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgbGluZSA9IGQzX3N2Z19saW5lKGQzX3N2Z19saW5lUmFkaWFsKTtcbiAgICBsaW5lLnJhZGl1cyA9IGxpbmUueCwgZGVsZXRlIGxpbmUueDtcbiAgICBsaW5lLmFuZ2xlID0gbGluZS55LCBkZWxldGUgbGluZS55O1xuICAgIHJldHVybiBsaW5lO1xuICB9O1xuICBmdW5jdGlvbiBkM19zdmdfbGluZVJhZGlhbChwb2ludHMpIHtcbiAgICB2YXIgcG9pbnQsIGkgPSAtMSwgbiA9IHBvaW50cy5sZW5ndGgsIHIsIGE7XG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgciA9IHBvaW50WzBdO1xuICAgICAgYSA9IHBvaW50WzFdICsgZDNfc3ZnX2FyY09mZnNldDtcbiAgICAgIHBvaW50WzBdID0gciAqIE1hdGguY29zKGEpO1xuICAgICAgcG9pbnRbMV0gPSByICogTWF0aC5zaW4oYSk7XG4gICAgfVxuICAgIHJldHVybiBwb2ludHM7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2FyZWEocHJvamVjdGlvbikge1xuICAgIHZhciB4MCA9IGQzX3N2Z19saW5lWCwgeDEgPSBkM19zdmdfbGluZVgsIHkwID0gMCwgeTEgPSBkM19zdmdfbGluZVksIGRlZmluZWQgPSBkM190cnVlLCBpbnRlcnBvbGF0ZSA9IGQzX3N2Z19saW5lTGluZWFyLCBpbnRlcnBvbGF0ZUtleSA9IGludGVycG9sYXRlLmtleSwgaW50ZXJwb2xhdGVSZXZlcnNlID0gaW50ZXJwb2xhdGUsIEwgPSBcIkxcIiwgdGVuc2lvbiA9IC43O1xuICAgIGZ1bmN0aW9uIGFyZWEoZGF0YSkge1xuICAgICAgdmFyIHNlZ21lbnRzID0gW10sIHBvaW50czAgPSBbXSwgcG9pbnRzMSA9IFtdLCBpID0gLTEsIG4gPSBkYXRhLmxlbmd0aCwgZCwgZngwID0gZDNfZnVuY3Rvcih4MCksIGZ5MCA9IGQzX2Z1bmN0b3IoeTApLCBmeDEgPSB4MCA9PT0geDEgPyBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHg7XG4gICAgICB9IDogZDNfZnVuY3Rvcih4MSksIGZ5MSA9IHkwID09PSB5MSA/IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4geTtcbiAgICAgIH0gOiBkM19mdW5jdG9yKHkxKSwgeCwgeTtcbiAgICAgIGZ1bmN0aW9uIHNlZ21lbnQoKSB7XG4gICAgICAgIHNlZ21lbnRzLnB1c2goXCJNXCIsIGludGVycG9sYXRlKHByb2plY3Rpb24ocG9pbnRzMSksIHRlbnNpb24pLCBMLCBpbnRlcnBvbGF0ZVJldmVyc2UocHJvamVjdGlvbihwb2ludHMwLnJldmVyc2UoKSksIHRlbnNpb24pLCBcIlpcIik7XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICBpZiAoZGVmaW5lZC5jYWxsKHRoaXMsIGQgPSBkYXRhW2ldLCBpKSkge1xuICAgICAgICAgIHBvaW50czAucHVzaChbIHggPSArZngwLmNhbGwodGhpcywgZCwgaSksIHkgPSArZnkwLmNhbGwodGhpcywgZCwgaSkgXSk7XG4gICAgICAgICAgcG9pbnRzMS5wdXNoKFsgK2Z4MS5jYWxsKHRoaXMsIGQsIGkpLCArZnkxLmNhbGwodGhpcywgZCwgaSkgXSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRzMC5sZW5ndGgpIHtcbiAgICAgICAgICBzZWdtZW50KCk7XG4gICAgICAgICAgcG9pbnRzMCA9IFtdO1xuICAgICAgICAgIHBvaW50czEgPSBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHBvaW50czAubGVuZ3RoKSBzZWdtZW50KCk7XG4gICAgICByZXR1cm4gc2VnbWVudHMubGVuZ3RoID8gc2VnbWVudHMuam9pbihcIlwiKSA6IG51bGw7XG4gICAgfVxuICAgIGFyZWEueCA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHgxO1xuICAgICAgeDAgPSB4MSA9IF87XG4gICAgICByZXR1cm4gYXJlYTtcbiAgICB9O1xuICAgIGFyZWEueDAgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB4MDtcbiAgICAgIHgwID0gXztcbiAgICAgIHJldHVybiBhcmVhO1xuICAgIH07XG4gICAgYXJlYS54MSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHgxO1xuICAgICAgeDEgPSBfO1xuICAgICAgcmV0dXJuIGFyZWE7XG4gICAgfTtcbiAgICBhcmVhLnkgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB5MTtcbiAgICAgIHkwID0geTEgPSBfO1xuICAgICAgcmV0dXJuIGFyZWE7XG4gICAgfTtcbiAgICBhcmVhLnkwID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4geTA7XG4gICAgICB5MCA9IF87XG4gICAgICByZXR1cm4gYXJlYTtcbiAgICB9O1xuICAgIGFyZWEueTEgPSBmdW5jdGlvbihfKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB5MTtcbiAgICAgIHkxID0gXztcbiAgICAgIHJldHVybiBhcmVhO1xuICAgIH07XG4gICAgYXJlYS5kZWZpbmVkID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZGVmaW5lZDtcbiAgICAgIGRlZmluZWQgPSBfO1xuICAgICAgcmV0dXJuIGFyZWE7XG4gICAgfTtcbiAgICBhcmVhLmludGVycG9sYXRlID0gZnVuY3Rpb24oXykge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gaW50ZXJwb2xhdGVLZXk7XG4gICAgICBpZiAodHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIikgaW50ZXJwb2xhdGVLZXkgPSBpbnRlcnBvbGF0ZSA9IF87IGVsc2UgaW50ZXJwb2xhdGVLZXkgPSAoaW50ZXJwb2xhdGUgPSBkM19zdmdfbGluZUludGVycG9sYXRvcnMuZ2V0KF8pIHx8IGQzX3N2Z19saW5lTGluZWFyKS5rZXk7XG4gICAgICBpbnRlcnBvbGF0ZVJldmVyc2UgPSBpbnRlcnBvbGF0ZS5yZXZlcnNlIHx8IGludGVycG9sYXRlO1xuICAgICAgTCA9IGludGVycG9sYXRlLmNsb3NlZCA/IFwiTVwiIDogXCJMXCI7XG4gICAgICByZXR1cm4gYXJlYTtcbiAgICB9O1xuICAgIGFyZWEudGVuc2lvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRlbnNpb247XG4gICAgICB0ZW5zaW9uID0gXztcbiAgICAgIHJldHVybiBhcmVhO1xuICAgIH07XG4gICAgcmV0dXJuIGFyZWE7XG4gIH1cbiAgZDNfc3ZnX2xpbmVTdGVwQmVmb3JlLnJldmVyc2UgPSBkM19zdmdfbGluZVN0ZXBBZnRlcjtcbiAgZDNfc3ZnX2xpbmVTdGVwQWZ0ZXIucmV2ZXJzZSA9IGQzX3N2Z19saW5lU3RlcEJlZm9yZTtcbiAgZDMuc3ZnLmFyZWEgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfc3ZnX2FyZWEoZDNfaWRlbnRpdHkpO1xuICB9O1xuICBkMy5zdmcuYXJlYS5yYWRpYWwgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYXJlYSA9IGQzX3N2Z19hcmVhKGQzX3N2Z19saW5lUmFkaWFsKTtcbiAgICBhcmVhLnJhZGl1cyA9IGFyZWEueCwgZGVsZXRlIGFyZWEueDtcbiAgICBhcmVhLmlubmVyUmFkaXVzID0gYXJlYS54MCwgZGVsZXRlIGFyZWEueDA7XG4gICAgYXJlYS5vdXRlclJhZGl1cyA9IGFyZWEueDEsIGRlbGV0ZSBhcmVhLngxO1xuICAgIGFyZWEuYW5nbGUgPSBhcmVhLnksIGRlbGV0ZSBhcmVhLnk7XG4gICAgYXJlYS5zdGFydEFuZ2xlID0gYXJlYS55MCwgZGVsZXRlIGFyZWEueTA7XG4gICAgYXJlYS5lbmRBbmdsZSA9IGFyZWEueTEsIGRlbGV0ZSBhcmVhLnkxO1xuICAgIHJldHVybiBhcmVhO1xuICB9O1xuICBkMy5zdmcuY2hvcmQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgc291cmNlID0gZDNfc291cmNlLCB0YXJnZXQgPSBkM190YXJnZXQsIHJhZGl1cyA9IGQzX3N2Z19jaG9yZFJhZGl1cywgc3RhcnRBbmdsZSA9IGQzX3N2Z19hcmNTdGFydEFuZ2xlLCBlbmRBbmdsZSA9IGQzX3N2Z19hcmNFbmRBbmdsZTtcbiAgICBmdW5jdGlvbiBjaG9yZChkLCBpKSB7XG4gICAgICB2YXIgcyA9IHN1Ymdyb3VwKHRoaXMsIHNvdXJjZSwgZCwgaSksIHQgPSBzdWJncm91cCh0aGlzLCB0YXJnZXQsIGQsIGkpO1xuICAgICAgcmV0dXJuIFwiTVwiICsgcy5wMCArIGFyYyhzLnIsIHMucDEsIHMuYTEgLSBzLmEwKSArIChlcXVhbHMocywgdCkgPyBjdXJ2ZShzLnIsIHMucDEsIHMuciwgcy5wMCkgOiBjdXJ2ZShzLnIsIHMucDEsIHQuciwgdC5wMCkgKyBhcmModC5yLCB0LnAxLCB0LmExIC0gdC5hMCkgKyBjdXJ2ZSh0LnIsIHQucDEsIHMuciwgcy5wMCkpICsgXCJaXCI7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHN1Ymdyb3VwKHNlbGYsIGYsIGQsIGkpIHtcbiAgICAgIHZhciBzdWJncm91cCA9IGYuY2FsbChzZWxmLCBkLCBpKSwgciA9IHJhZGl1cy5jYWxsKHNlbGYsIHN1Ymdyb3VwLCBpKSwgYTAgPSBzdGFydEFuZ2xlLmNhbGwoc2VsZiwgc3ViZ3JvdXAsIGkpICsgZDNfc3ZnX2FyY09mZnNldCwgYTEgPSBlbmRBbmdsZS5jYWxsKHNlbGYsIHN1Ymdyb3VwLCBpKSArIGQzX3N2Z19hcmNPZmZzZXQ7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByOiByLFxuICAgICAgICBhMDogYTAsXG4gICAgICAgIGExOiBhMSxcbiAgICAgICAgcDA6IFsgciAqIE1hdGguY29zKGEwKSwgciAqIE1hdGguc2luKGEwKSBdLFxuICAgICAgICBwMTogWyByICogTWF0aC5jb3MoYTEpLCByICogTWF0aC5zaW4oYTEpIF1cbiAgICAgIH07XG4gICAgfVxuICAgIGZ1bmN0aW9uIGVxdWFscyhhLCBiKSB7XG4gICAgICByZXR1cm4gYS5hMCA9PSBiLmEwICYmIGEuYTEgPT0gYi5hMTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYXJjKHIsIHAsIGEpIHtcbiAgICAgIHJldHVybiBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiAwIFwiICsgKyhhID4gz4ApICsgXCIsMSBcIiArIHA7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGN1cnZlKHIwLCBwMCwgcjEsIHAxKSB7XG4gICAgICByZXR1cm4gXCJRIDAsMCBcIiArIHAxO1xuICAgIH1cbiAgICBjaG9yZC5yYWRpdXMgPSBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiByYWRpdXM7XG4gICAgICByYWRpdXMgPSBkM19mdW5jdG9yKHYpO1xuICAgICAgcmV0dXJuIGNob3JkO1xuICAgIH07XG4gICAgY2hvcmQuc291cmNlID0gZnVuY3Rpb24odikge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc291cmNlO1xuICAgICAgc291cmNlID0gZDNfZnVuY3Rvcih2KTtcbiAgICAgIHJldHVybiBjaG9yZDtcbiAgICB9O1xuICAgIGNob3JkLnRhcmdldCA9IGZ1bmN0aW9uKHYpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRhcmdldDtcbiAgICAgIHRhcmdldCA9IGQzX2Z1bmN0b3Iodik7XG4gICAgICByZXR1cm4gY2hvcmQ7XG4gICAgfTtcbiAgICBjaG9yZC5zdGFydEFuZ2xlID0gZnVuY3Rpb24odikge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gc3RhcnRBbmdsZTtcbiAgICAgIHN0YXJ0QW5nbGUgPSBkM19mdW5jdG9yKHYpO1xuICAgICAgcmV0dXJuIGNob3JkO1xuICAgIH07XG4gICAgY2hvcmQuZW5kQW5nbGUgPSBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBlbmRBbmdsZTtcbiAgICAgIGVuZEFuZ2xlID0gZDNfZnVuY3Rvcih2KTtcbiAgICAgIHJldHVybiBjaG9yZDtcbiAgICB9O1xuICAgIHJldHVybiBjaG9yZDtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc3ZnX2Nob3JkUmFkaXVzKGQpIHtcbiAgICByZXR1cm4gZC5yYWRpdXM7XG4gIH1cbiAgZDMuc3ZnLmRpYWdvbmFsID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNvdXJjZSA9IGQzX3NvdXJjZSwgdGFyZ2V0ID0gZDNfdGFyZ2V0LCBwcm9qZWN0aW9uID0gZDNfc3ZnX2RpYWdvbmFsUHJvamVjdGlvbjtcbiAgICBmdW5jdGlvbiBkaWFnb25hbChkLCBpKSB7XG4gICAgICB2YXIgcDAgPSBzb3VyY2UuY2FsbCh0aGlzLCBkLCBpKSwgcDMgPSB0YXJnZXQuY2FsbCh0aGlzLCBkLCBpKSwgbSA9IChwMC55ICsgcDMueSkgLyAyLCBwID0gWyBwMCwge1xuICAgICAgICB4OiBwMC54LFxuICAgICAgICB5OiBtXG4gICAgICB9LCB7XG4gICAgICAgIHg6IHAzLngsXG4gICAgICAgIHk6IG1cbiAgICAgIH0sIHAzIF07XG4gICAgICBwID0gcC5tYXAocHJvamVjdGlvbik7XG4gICAgICByZXR1cm4gXCJNXCIgKyBwWzBdICsgXCJDXCIgKyBwWzFdICsgXCIgXCIgKyBwWzJdICsgXCIgXCIgKyBwWzNdO1xuICAgIH1cbiAgICBkaWFnb25hbC5zb3VyY2UgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzb3VyY2U7XG4gICAgICBzb3VyY2UgPSBkM19mdW5jdG9yKHgpO1xuICAgICAgcmV0dXJuIGRpYWdvbmFsO1xuICAgIH07XG4gICAgZGlhZ29uYWwudGFyZ2V0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGFyZ2V0O1xuICAgICAgdGFyZ2V0ID0gZDNfZnVuY3Rvcih4KTtcbiAgICAgIHJldHVybiBkaWFnb25hbDtcbiAgICB9O1xuICAgIGRpYWdvbmFsLnByb2plY3Rpb24gPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBwcm9qZWN0aW9uO1xuICAgICAgcHJvamVjdGlvbiA9IHg7XG4gICAgICByZXR1cm4gZGlhZ29uYWw7XG4gICAgfTtcbiAgICByZXR1cm4gZGlhZ29uYWw7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3N2Z19kaWFnb25hbFByb2plY3Rpb24oZCkge1xuICAgIHJldHVybiBbIGQueCwgZC55IF07XG4gIH1cbiAgZDMuc3ZnLmRpYWdvbmFsLnJhZGlhbCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBkaWFnb25hbCA9IGQzLnN2Zy5kaWFnb25hbCgpLCBwcm9qZWN0aW9uID0gZDNfc3ZnX2RpYWdvbmFsUHJvamVjdGlvbiwgcHJvamVjdGlvbl8gPSBkaWFnb25hbC5wcm9qZWN0aW9uO1xuICAgIGRpYWdvbmFsLnByb2plY3Rpb24gPSBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHByb2plY3Rpb25fKGQzX3N2Z19kaWFnb25hbFJhZGlhbFByb2plY3Rpb24ocHJvamVjdGlvbiA9IHgpKSA6IHByb2plY3Rpb247XG4gICAgfTtcbiAgICByZXR1cm4gZGlhZ29uYWw7XG4gIH07XG4gIGZ1bmN0aW9uIGQzX3N2Z19kaWFnb25hbFJhZGlhbFByb2plY3Rpb24ocHJvamVjdGlvbikge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBkID0gcHJvamVjdGlvbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpLCByID0gZFswXSwgYSA9IGRbMV0gKyBkM19zdmdfYXJjT2Zmc2V0O1xuICAgICAgcmV0dXJuIFsgciAqIE1hdGguY29zKGEpLCByICogTWF0aC5zaW4oYSkgXTtcbiAgICB9O1xuICB9XG4gIGQzLnN2Zy5zeW1ib2wgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgdHlwZSA9IGQzX3N2Z19zeW1ib2xUeXBlLCBzaXplID0gZDNfc3ZnX3N5bWJvbFNpemU7XG4gICAgZnVuY3Rpb24gc3ltYm9sKGQsIGkpIHtcbiAgICAgIHJldHVybiAoZDNfc3ZnX3N5bWJvbHMuZ2V0KHR5cGUuY2FsbCh0aGlzLCBkLCBpKSkgfHwgZDNfc3ZnX3N5bWJvbENpcmNsZSkoc2l6ZS5jYWxsKHRoaXMsIGQsIGkpKTtcbiAgICB9XG4gICAgc3ltYm9sLnR5cGUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0eXBlO1xuICAgICAgdHlwZSA9IGQzX2Z1bmN0b3IoeCk7XG4gICAgICByZXR1cm4gc3ltYm9sO1xuICAgIH07XG4gICAgc3ltYm9sLnNpemUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzaXplO1xuICAgICAgc2l6ZSA9IGQzX2Z1bmN0b3IoeCk7XG4gICAgICByZXR1cm4gc3ltYm9sO1xuICAgIH07XG4gICAgcmV0dXJuIHN5bWJvbDtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfc3ZnX3N5bWJvbFNpemUoKSB7XG4gICAgcmV0dXJuIDY0O1xuICB9XG4gIGZ1bmN0aW9uIGQzX3N2Z19zeW1ib2xUeXBlKCkge1xuICAgIHJldHVybiBcImNpcmNsZVwiO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3N2Z19zeW1ib2xDaXJjbGUoc2l6ZSkge1xuICAgIHZhciByID0gTWF0aC5zcXJ0KHNpemUgLyDPgCk7XG4gICAgcmV0dXJuIFwiTTAsXCIgKyByICsgXCJBXCIgKyByICsgXCIsXCIgKyByICsgXCIgMCAxLDEgMCxcIiArIC1yICsgXCJBXCIgKyByICsgXCIsXCIgKyByICsgXCIgMCAxLDEgMCxcIiArIHIgKyBcIlpcIjtcbiAgfVxuICB2YXIgZDNfc3ZnX3N5bWJvbHMgPSBkMy5tYXAoe1xuICAgIGNpcmNsZTogZDNfc3ZnX3N5bWJvbENpcmNsZSxcbiAgICBjcm9zczogZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgdmFyIHIgPSBNYXRoLnNxcnQoc2l6ZSAvIDUpIC8gMjtcbiAgICAgIHJldHVybiBcIk1cIiArIC0zICogciArIFwiLFwiICsgLXIgKyBcIkhcIiArIC1yICsgXCJWXCIgKyAtMyAqIHIgKyBcIkhcIiArIHIgKyBcIlZcIiArIC1yICsgXCJIXCIgKyAzICogciArIFwiVlwiICsgciArIFwiSFwiICsgciArIFwiVlwiICsgMyAqIHIgKyBcIkhcIiArIC1yICsgXCJWXCIgKyByICsgXCJIXCIgKyAtMyAqIHIgKyBcIlpcIjtcbiAgICB9LFxuICAgIGRpYW1vbmQ6IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgIHZhciByeSA9IE1hdGguc3FydChzaXplIC8gKDIgKiBkM19zdmdfc3ltYm9sVGFuMzApKSwgcnggPSByeSAqIGQzX3N2Z19zeW1ib2xUYW4zMDtcbiAgICAgIHJldHVybiBcIk0wLFwiICsgLXJ5ICsgXCJMXCIgKyByeCArIFwiLDBcIiArIFwiIDAsXCIgKyByeSArIFwiIFwiICsgLXJ4ICsgXCIsMFwiICsgXCJaXCI7XG4gICAgfSxcbiAgICBzcXVhcmU6IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgIHZhciByID0gTWF0aC5zcXJ0KHNpemUpIC8gMjtcbiAgICAgIHJldHVybiBcIk1cIiArIC1yICsgXCIsXCIgKyAtciArIFwiTFwiICsgciArIFwiLFwiICsgLXIgKyBcIiBcIiArIHIgKyBcIixcIiArIHIgKyBcIiBcIiArIC1yICsgXCIsXCIgKyByICsgXCJaXCI7XG4gICAgfSxcbiAgICBcInRyaWFuZ2xlLWRvd25cIjogZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgdmFyIHJ4ID0gTWF0aC5zcXJ0KHNpemUgLyBkM19zdmdfc3ltYm9sU3FydDMpLCByeSA9IHJ4ICogZDNfc3ZnX3N5bWJvbFNxcnQzIC8gMjtcbiAgICAgIHJldHVybiBcIk0wLFwiICsgcnkgKyBcIkxcIiArIHJ4ICsgXCIsXCIgKyAtcnkgKyBcIiBcIiArIC1yeCArIFwiLFwiICsgLXJ5ICsgXCJaXCI7XG4gICAgfSxcbiAgICBcInRyaWFuZ2xlLXVwXCI6IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgIHZhciByeCA9IE1hdGguc3FydChzaXplIC8gZDNfc3ZnX3N5bWJvbFNxcnQzKSwgcnkgPSByeCAqIGQzX3N2Z19zeW1ib2xTcXJ0MyAvIDI7XG4gICAgICByZXR1cm4gXCJNMCxcIiArIC1yeSArIFwiTFwiICsgcnggKyBcIixcIiArIHJ5ICsgXCIgXCIgKyAtcnggKyBcIixcIiArIHJ5ICsgXCJaXCI7XG4gICAgfVxuICB9KTtcbiAgZDMuc3ZnLnN5bWJvbFR5cGVzID0gZDNfc3ZnX3N5bWJvbHMua2V5cygpO1xuICB2YXIgZDNfc3ZnX3N5bWJvbFNxcnQzID0gTWF0aC5zcXJ0KDMpLCBkM19zdmdfc3ltYm9sVGFuMzAgPSBNYXRoLnRhbigzMCAqIGQzX3JhZGlhbnMpO1xuICBmdW5jdGlvbiBkM190cmFuc2l0aW9uKGdyb3VwcywgaWQpIHtcbiAgICBkM19zdWJjbGFzcyhncm91cHMsIGQzX3RyYW5zaXRpb25Qcm90b3R5cGUpO1xuICAgIGdyb3Vwcy5pZCA9IGlkO1xuICAgIHJldHVybiBncm91cHM7XG4gIH1cbiAgdmFyIGQzX3RyYW5zaXRpb25Qcm90b3R5cGUgPSBbXSwgZDNfdHJhbnNpdGlvbklkID0gMCwgZDNfdHJhbnNpdGlvbkluaGVyaXRJZCwgZDNfdHJhbnNpdGlvbkluaGVyaXQ7XG4gIGQzX3RyYW5zaXRpb25Qcm90b3R5cGUuY2FsbCA9IGQzX3NlbGVjdGlvblByb3RvdHlwZS5jYWxsO1xuICBkM190cmFuc2l0aW9uUHJvdG90eXBlLmVtcHR5ID0gZDNfc2VsZWN0aW9uUHJvdG90eXBlLmVtcHR5O1xuICBkM190cmFuc2l0aW9uUHJvdG90eXBlLm5vZGUgPSBkM19zZWxlY3Rpb25Qcm90b3R5cGUubm9kZTtcbiAgZDNfdHJhbnNpdGlvblByb3RvdHlwZS5zaXplID0gZDNfc2VsZWN0aW9uUHJvdG90eXBlLnNpemU7XG4gIGQzLnRyYW5zaXRpb24gPSBmdW5jdGlvbihzZWxlY3Rpb24pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IGQzX3RyYW5zaXRpb25Jbmhlcml0SWQgPyBzZWxlY3Rpb24udHJhbnNpdGlvbigpIDogc2VsZWN0aW9uIDogZDNfc2VsZWN0aW9uUm9vdC50cmFuc2l0aW9uKCk7XG4gIH07XG4gIGQzLnRyYW5zaXRpb24ucHJvdG90eXBlID0gZDNfdHJhbnNpdGlvblByb3RvdHlwZTtcbiAgZDNfdHJhbnNpdGlvblByb3RvdHlwZS5zZWxlY3QgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xuICAgIHZhciBpZCA9IHRoaXMuaWQsIHN1Ymdyb3VwcyA9IFtdLCBzdWJncm91cCwgc3Vibm9kZSwgbm9kZTtcbiAgICBzZWxlY3RvciA9IGQzX3NlbGVjdGlvbl9zZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgZm9yICh2YXIgaiA9IC0xLCBtID0gdGhpcy5sZW5ndGg7ICsraiA8IG07ICkge1xuICAgICAgc3ViZ3JvdXBzLnB1c2goc3ViZ3JvdXAgPSBbXSk7XG4gICAgICBmb3IgKHZhciBncm91cCA9IHRoaXNbal0sIGkgPSAtMSwgbiA9IGdyb3VwLmxlbmd0aDsgKytpIDwgbjsgKSB7XG4gICAgICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiAoc3Vibm9kZSA9IHNlbGVjdG9yLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgaikpKSB7XG4gICAgICAgICAgaWYgKFwiX19kYXRhX19cIiBpbiBub2RlKSBzdWJub2RlLl9fZGF0YV9fID0gbm9kZS5fX2RhdGFfXztcbiAgICAgICAgICBkM190cmFuc2l0aW9uTm9kZShzdWJub2RlLCBpLCBpZCwgbm9kZS5fX3RyYW5zaXRpb25fX1tpZF0pO1xuICAgICAgICAgIHN1Ymdyb3VwLnB1c2goc3Vibm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3ViZ3JvdXAucHVzaChudWxsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZDNfdHJhbnNpdGlvbihzdWJncm91cHMsIGlkKTtcbiAgfTtcbiAgZDNfdHJhbnNpdGlvblByb3RvdHlwZS5zZWxlY3RBbGwgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xuICAgIHZhciBpZCA9IHRoaXMuaWQsIHN1Ymdyb3VwcyA9IFtdLCBzdWJncm91cCwgc3Vibm9kZXMsIG5vZGUsIHN1Ym5vZGUsIHRyYW5zaXRpb247XG4gICAgc2VsZWN0b3IgPSBkM19zZWxlY3Rpb25fc2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICAgIGZvciAodmFyIGogPSAtMSwgbSA9IHRoaXMubGVuZ3RoOyArK2ogPCBtOyApIHtcbiAgICAgIGZvciAodmFyIGdyb3VwID0gdGhpc1tqXSwgaSA9IC0xLCBuID0gZ3JvdXAubGVuZ3RoOyArK2kgPCBuOyApIHtcbiAgICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICAgIHRyYW5zaXRpb24gPSBub2RlLl9fdHJhbnNpdGlvbl9fW2lkXTtcbiAgICAgICAgICBzdWJub2RlcyA9IHNlbGVjdG9yLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgaik7XG4gICAgICAgICAgc3ViZ3JvdXBzLnB1c2goc3ViZ3JvdXAgPSBbXSk7XG4gICAgICAgICAgZm9yICh2YXIgayA9IC0xLCBvID0gc3Vibm9kZXMubGVuZ3RoOyArK2sgPCBvOyApIHtcbiAgICAgICAgICAgIGlmIChzdWJub2RlID0gc3Vibm9kZXNba10pIGQzX3RyYW5zaXRpb25Ob2RlKHN1Ym5vZGUsIGssIGlkLCB0cmFuc2l0aW9uKTtcbiAgICAgICAgICAgIHN1Ymdyb3VwLnB1c2goc3Vibm9kZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkM190cmFuc2l0aW9uKHN1Ymdyb3VwcywgaWQpO1xuICB9O1xuICBkM190cmFuc2l0aW9uUHJvdG90eXBlLmZpbHRlciA9IGZ1bmN0aW9uKGZpbHRlcikge1xuICAgIHZhciBzdWJncm91cHMgPSBbXSwgc3ViZ3JvdXAsIGdyb3VwLCBub2RlO1xuICAgIGlmICh0eXBlb2YgZmlsdGVyICE9PSBcImZ1bmN0aW9uXCIpIGZpbHRlciA9IGQzX3NlbGVjdGlvbl9maWx0ZXIoZmlsdGVyKTtcbiAgICBmb3IgKHZhciBqID0gMCwgbSA9IHRoaXMubGVuZ3RoOyBqIDwgbTsgaisrKSB7XG4gICAgICBzdWJncm91cHMucHVzaChzdWJncm91cCA9IFtdKTtcbiAgICAgIGZvciAodmFyIGdyb3VwID0gdGhpc1tqXSwgaSA9IDAsIG4gPSBncm91cC5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgaWYgKChub2RlID0gZ3JvdXBbaV0pICYmIGZpbHRlci5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGkpKSB7XG4gICAgICAgICAgc3ViZ3JvdXAucHVzaChub2RlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZDNfdHJhbnNpdGlvbihzdWJncm91cHMsIHRoaXMuaWQsIHRoaXMudGltZSkuZWFzZSh0aGlzLmVhc2UoKSk7XG4gIH07XG4gIGQzX3RyYW5zaXRpb25Qcm90b3R5cGUudHdlZW4gPSBmdW5jdGlvbihuYW1lLCB0d2Vlbikge1xuICAgIHZhciBpZCA9IHRoaXMuaWQ7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSByZXR1cm4gdGhpcy5ub2RlKCkuX190cmFuc2l0aW9uX19baWRdLnR3ZWVuLmdldChuYW1lKTtcbiAgICByZXR1cm4gZDNfc2VsZWN0aW9uX2VhY2godGhpcywgdHdlZW4gPT0gbnVsbCA/IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIG5vZGUuX190cmFuc2l0aW9uX19baWRdLnR3ZWVuLnJlbW92ZShuYW1lKTtcbiAgICB9IDogZnVuY3Rpb24obm9kZSkge1xuICAgICAgbm9kZS5fX3RyYW5zaXRpb25fX1tpZF0udHdlZW4uc2V0KG5hbWUsIHR3ZWVuKTtcbiAgICB9KTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfdHJhbnNpdGlvbl90d2Vlbihncm91cHMsIG5hbWUsIHZhbHVlLCB0d2Vlbikge1xuICAgIHZhciBpZCA9IGdyb3Vwcy5pZDtcbiAgICByZXR1cm4gZDNfc2VsZWN0aW9uX2VhY2goZ3JvdXBzLCB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bmN0aW9uKG5vZGUsIGksIGopIHtcbiAgICAgIG5vZGUuX190cmFuc2l0aW9uX19baWRdLnR3ZWVuLnNldChuYW1lLCB0d2Vlbih2YWx1ZS5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGopKSk7XG4gICAgfSA6ICh2YWx1ZSA9IHR3ZWVuKHZhbHVlKSwgZnVuY3Rpb24obm9kZSkge1xuICAgICAgbm9kZS5fX3RyYW5zaXRpb25fX1tpZF0udHdlZW4uc2V0KG5hbWUsIHZhbHVlKTtcbiAgICB9KSk7XG4gIH1cbiAgZDNfdHJhbnNpdGlvblByb3RvdHlwZS5hdHRyID0gZnVuY3Rpb24obmFtZU5TLCB2YWx1ZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgZm9yICh2YWx1ZSBpbiBuYW1lTlMpIHRoaXMuYXR0cih2YWx1ZSwgbmFtZU5TW3ZhbHVlXSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdmFyIGludGVycG9sYXRlID0gbmFtZU5TID09IFwidHJhbnNmb3JtXCIgPyBkM19pbnRlcnBvbGF0ZVRyYW5zZm9ybSA6IGQzX2ludGVycG9sYXRlLCBuYW1lID0gZDMubnMucXVhbGlmeShuYW1lTlMpO1xuICAgIGZ1bmN0aW9uIGF0dHJOdWxsKCkge1xuICAgICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGF0dHJOdWxsTlMoKSB7XG4gICAgICB0aGlzLnJlbW92ZUF0dHJpYnV0ZU5TKG5hbWUuc3BhY2UsIG5hbWUubG9jYWwpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBhdHRyVHdlZW4oYikge1xuICAgICAgcmV0dXJuIGIgPT0gbnVsbCA/IGF0dHJOdWxsIDogKGIgKz0gXCJcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhID0gdGhpcy5nZXRBdHRyaWJ1dGUobmFtZSksIGk7XG4gICAgICAgIHJldHVybiBhICE9PSBiICYmIChpID0gaW50ZXJwb2xhdGUoYSwgYiksIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZShuYW1lLCBpKHQpKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYXR0clR3ZWVuTlMoYikge1xuICAgICAgcmV0dXJuIGIgPT0gbnVsbCA/IGF0dHJOdWxsTlMgOiAoYiArPSBcIlwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGEgPSB0aGlzLmdldEF0dHJpYnV0ZU5TKG5hbWUuc3BhY2UsIG5hbWUubG9jYWwpLCBpO1xuICAgICAgICByZXR1cm4gYSAhPT0gYiAmJiAoaSA9IGludGVycG9sYXRlKGEsIGIpLCBmdW5jdGlvbih0KSB7XG4gICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGVOUyhuYW1lLnNwYWNlLCBuYW1lLmxvY2FsLCBpKHQpKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGQzX3RyYW5zaXRpb25fdHdlZW4odGhpcywgXCJhdHRyLlwiICsgbmFtZU5TLCB2YWx1ZSwgbmFtZS5sb2NhbCA/IGF0dHJUd2Vlbk5TIDogYXR0clR3ZWVuKTtcbiAgfTtcbiAgZDNfdHJhbnNpdGlvblByb3RvdHlwZS5hdHRyVHdlZW4gPSBmdW5jdGlvbihuYW1lTlMsIHR3ZWVuKSB7XG4gICAgdmFyIG5hbWUgPSBkMy5ucy5xdWFsaWZ5KG5hbWVOUyk7XG4gICAgZnVuY3Rpb24gYXR0clR3ZWVuKGQsIGkpIHtcbiAgICAgIHZhciBmID0gdHdlZW4uY2FsbCh0aGlzLCBkLCBpLCB0aGlzLmdldEF0dHJpYnV0ZShuYW1lKSk7XG4gICAgICByZXR1cm4gZiAmJiBmdW5jdGlvbih0KSB7XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKG5hbWUsIGYodCkpO1xuICAgICAgfTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYXR0clR3ZWVuTlMoZCwgaSkge1xuICAgICAgdmFyIGYgPSB0d2Vlbi5jYWxsKHRoaXMsIGQsIGksIHRoaXMuZ2V0QXR0cmlidXRlTlMobmFtZS5zcGFjZSwgbmFtZS5sb2NhbCkpO1xuICAgICAgcmV0dXJuIGYgJiYgZnVuY3Rpb24odCkge1xuICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZU5TKG5hbWUuc3BhY2UsIG5hbWUubG9jYWwsIGYodCkpO1xuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudHdlZW4oXCJhdHRyLlwiICsgbmFtZU5TLCBuYW1lLmxvY2FsID8gYXR0clR3ZWVuTlMgOiBhdHRyVHdlZW4pO1xuICB9O1xuICBkM190cmFuc2l0aW9uUHJvdG90eXBlLnN0eWxlID0gZnVuY3Rpb24obmFtZSwgdmFsdWUsIHByaW9yaXR5KSB7XG4gICAgdmFyIG4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIGlmIChuIDwgMykge1xuICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGlmIChuIDwgMikgdmFsdWUgPSBcIlwiO1xuICAgICAgICBmb3IgKHByaW9yaXR5IGluIG5hbWUpIHRoaXMuc3R5bGUocHJpb3JpdHksIG5hbWVbcHJpb3JpdHldLCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcHJpb3JpdHkgPSBcIlwiO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzdHlsZU51bGwoKSB7XG4gICAgICB0aGlzLnN0eWxlLnJlbW92ZVByb3BlcnR5KG5hbWUpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzdHlsZVN0cmluZyhiKSB7XG4gICAgICByZXR1cm4gYiA9PSBudWxsID8gc3R5bGVOdWxsIDogKGIgKz0gXCJcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhID0gZDNfd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcywgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSwgaTtcbiAgICAgICAgcmV0dXJuIGEgIT09IGIgJiYgKGkgPSBkM19pbnRlcnBvbGF0ZShhLCBiKSwgZnVuY3Rpb24odCkge1xuICAgICAgICAgIHRoaXMuc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgaSh0KSwgcHJpb3JpdHkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZDNfdHJhbnNpdGlvbl90d2Vlbih0aGlzLCBcInN0eWxlLlwiICsgbmFtZSwgdmFsdWUsIHN0eWxlU3RyaW5nKTtcbiAgfTtcbiAgZDNfdHJhbnNpdGlvblByb3RvdHlwZS5zdHlsZVR3ZWVuID0gZnVuY3Rpb24obmFtZSwgdHdlZW4sIHByaW9yaXR5KSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSBwcmlvcml0eSA9IFwiXCI7XG4gICAgZnVuY3Rpb24gc3R5bGVUd2VlbihkLCBpKSB7XG4gICAgICB2YXIgZiA9IHR3ZWVuLmNhbGwodGhpcywgZCwgaSwgZDNfd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcywgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSk7XG4gICAgICByZXR1cm4gZiAmJiBmdW5jdGlvbih0KSB7XG4gICAgICAgIHRoaXMuc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgZih0KSwgcHJpb3JpdHkpO1xuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudHdlZW4oXCJzdHlsZS5cIiArIG5hbWUsIHN0eWxlVHdlZW4pO1xuICB9O1xuICBkM190cmFuc2l0aW9uUHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBkM190cmFuc2l0aW9uX3R3ZWVuKHRoaXMsIFwidGV4dFwiLCB2YWx1ZSwgZDNfdHJhbnNpdGlvbl90ZXh0KTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfdHJhbnNpdGlvbl90ZXh0KGIpIHtcbiAgICBpZiAoYiA9PSBudWxsKSBiID0gXCJcIjtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnRleHRDb250ZW50ID0gYjtcbiAgICB9O1xuICB9XG4gIGQzX3RyYW5zaXRpb25Qcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChcImVuZC50cmFuc2l0aW9uXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHA7XG4gICAgICBpZiAoIXRoaXMuX190cmFuc2l0aW9uX18gJiYgKHAgPSB0aGlzLnBhcmVudE5vZGUpKSBwLnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgIH0pO1xuICB9O1xuICBkM190cmFuc2l0aW9uUHJvdG90eXBlLmVhc2UgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciBpZCA9IHRoaXMuaWQ7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAxKSByZXR1cm4gdGhpcy5ub2RlKCkuX190cmFuc2l0aW9uX19baWRdLmVhc2U7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB2YWx1ZSA9IGQzLmVhc2UuYXBwbHkoZDMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGQzX3NlbGVjdGlvbl9lYWNoKHRoaXMsIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIG5vZGUuX190cmFuc2l0aW9uX19baWRdLmVhc2UgPSB2YWx1ZTtcbiAgICB9KTtcbiAgfTtcbiAgZDNfdHJhbnNpdGlvblByb3RvdHlwZS5kZWxheSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIGlkID0gdGhpcy5pZDtcbiAgICByZXR1cm4gZDNfc2VsZWN0aW9uX2VhY2godGhpcywgdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBmdW5jdGlvbihub2RlLCBpLCBqKSB7XG4gICAgICBub2RlLl9fdHJhbnNpdGlvbl9fW2lkXS5kZWxheSA9IHZhbHVlLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgaikgfCAwO1xuICAgIH0gOiAodmFsdWUgfD0gMCwgZnVuY3Rpb24obm9kZSkge1xuICAgICAgbm9kZS5fX3RyYW5zaXRpb25fX1tpZF0uZGVsYXkgPSB2YWx1ZTtcbiAgICB9KSk7XG4gIH07XG4gIGQzX3RyYW5zaXRpb25Qcm90b3R5cGUuZHVyYXRpb24gPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciBpZCA9IHRoaXMuaWQ7XG4gICAgcmV0dXJuIGQzX3NlbGVjdGlvbl9lYWNoKHRoaXMsIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gZnVuY3Rpb24obm9kZSwgaSwgaikge1xuICAgICAgbm9kZS5fX3RyYW5zaXRpb25fX1tpZF0uZHVyYXRpb24gPSBNYXRoLm1heCgxLCB2YWx1ZS5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGopIHwgMCk7XG4gICAgfSA6ICh2YWx1ZSA9IE1hdGgubWF4KDEsIHZhbHVlIHwgMCksIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIG5vZGUuX190cmFuc2l0aW9uX19baWRdLmR1cmF0aW9uID0gdmFsdWU7XG4gICAgfSkpO1xuICB9O1xuICBkM190cmFuc2l0aW9uUHJvdG90eXBlLmVhY2ggPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICAgIHZhciBpZCA9IHRoaXMuaWQ7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICB2YXIgaW5oZXJpdCA9IGQzX3RyYW5zaXRpb25Jbmhlcml0LCBpbmhlcml0SWQgPSBkM190cmFuc2l0aW9uSW5oZXJpdElkO1xuICAgICAgZDNfdHJhbnNpdGlvbkluaGVyaXRJZCA9IGlkO1xuICAgICAgZDNfc2VsZWN0aW9uX2VhY2godGhpcywgZnVuY3Rpb24obm9kZSwgaSwgaikge1xuICAgICAgICBkM190cmFuc2l0aW9uSW5oZXJpdCA9IG5vZGUuX190cmFuc2l0aW9uX19baWRdO1xuICAgICAgICB0eXBlLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgaik7XG4gICAgICB9KTtcbiAgICAgIGQzX3RyYW5zaXRpb25Jbmhlcml0ID0gaW5oZXJpdDtcbiAgICAgIGQzX3RyYW5zaXRpb25Jbmhlcml0SWQgPSBpbmhlcml0SWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGQzX3NlbGVjdGlvbl9lYWNoKHRoaXMsIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgdmFyIHRyYW5zaXRpb24gPSBub2RlLl9fdHJhbnNpdGlvbl9fW2lkXTtcbiAgICAgICAgKHRyYW5zaXRpb24uZXZlbnQgfHwgKHRyYW5zaXRpb24uZXZlbnQgPSBkMy5kaXNwYXRjaChcInN0YXJ0XCIsIFwiZW5kXCIpKSkub24odHlwZSwgbGlzdGVuZXIpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICBkM190cmFuc2l0aW9uUHJvdG90eXBlLnRyYW5zaXRpb24gPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaWQwID0gdGhpcy5pZCwgaWQxID0gKytkM190cmFuc2l0aW9uSWQsIHN1Ymdyb3VwcyA9IFtdLCBzdWJncm91cCwgZ3JvdXAsIG5vZGUsIHRyYW5zaXRpb247XG4gICAgZm9yICh2YXIgaiA9IDAsIG0gPSB0aGlzLmxlbmd0aDsgaiA8IG07IGorKykge1xuICAgICAgc3ViZ3JvdXBzLnB1c2goc3ViZ3JvdXAgPSBbXSk7XG4gICAgICBmb3IgKHZhciBncm91cCA9IHRoaXNbal0sIGkgPSAwLCBuID0gZ3JvdXAubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgICAgICB0cmFuc2l0aW9uID0gT2JqZWN0LmNyZWF0ZShub2RlLl9fdHJhbnNpdGlvbl9fW2lkMF0pO1xuICAgICAgICAgIHRyYW5zaXRpb24uZGVsYXkgKz0gdHJhbnNpdGlvbi5kdXJhdGlvbjtcbiAgICAgICAgICBkM190cmFuc2l0aW9uTm9kZShub2RlLCBpLCBpZDEsIHRyYW5zaXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHN1Ymdyb3VwLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkM190cmFuc2l0aW9uKHN1Ymdyb3VwcywgaWQxKTtcbiAgfTtcbiAgZnVuY3Rpb24gZDNfdHJhbnNpdGlvbk5vZGUobm9kZSwgaSwgaWQsIGluaGVyaXQpIHtcbiAgICB2YXIgbG9jayA9IG5vZGUuX190cmFuc2l0aW9uX18gfHwgKG5vZGUuX190cmFuc2l0aW9uX18gPSB7XG4gICAgICBhY3RpdmU6IDAsXG4gICAgICBjb3VudDogMFxuICAgIH0pLCB0cmFuc2l0aW9uID0gbG9ja1tpZF07XG4gICAgaWYgKCF0cmFuc2l0aW9uKSB7XG4gICAgICB2YXIgdGltZSA9IGluaGVyaXQudGltZTtcbiAgICAgIHRyYW5zaXRpb24gPSBsb2NrW2lkXSA9IHtcbiAgICAgICAgdHdlZW46IG5ldyBkM19NYXAoKSxcbiAgICAgICAgdGltZTogdGltZSxcbiAgICAgICAgZWFzZTogaW5oZXJpdC5lYXNlLFxuICAgICAgICBkZWxheTogaW5oZXJpdC5kZWxheSxcbiAgICAgICAgZHVyYXRpb246IGluaGVyaXQuZHVyYXRpb25cbiAgICAgIH07XG4gICAgICArK2xvY2suY291bnQ7XG4gICAgICBkMy50aW1lcihmdW5jdGlvbihlbGFwc2VkKSB7XG4gICAgICAgIHZhciBkID0gbm9kZS5fX2RhdGFfXywgZWFzZSA9IHRyYW5zaXRpb24uZWFzZSwgZGVsYXkgPSB0cmFuc2l0aW9uLmRlbGF5LCBkdXJhdGlvbiA9IHRyYW5zaXRpb24uZHVyYXRpb24sIHR3ZWVuZWQgPSBbXTtcbiAgICAgICAgcmV0dXJuIGRlbGF5IDw9IGVsYXBzZWQgPyBzdGFydChlbGFwc2VkKSA6IGQzLnRpbWVyKHN0YXJ0LCBkZWxheSwgdGltZSksIDE7XG4gICAgICAgIGZ1bmN0aW9uIHN0YXJ0KGVsYXBzZWQpIHtcbiAgICAgICAgICBpZiAobG9jay5hY3RpdmUgPiBpZCkgcmV0dXJuIHN0b3AoKTtcbiAgICAgICAgICBsb2NrLmFjdGl2ZSA9IGlkO1xuICAgICAgICAgIHRyYW5zaXRpb24uZXZlbnQgJiYgdHJhbnNpdGlvbi5ldmVudC5zdGFydC5jYWxsKG5vZGUsIGQsIGkpO1xuICAgICAgICAgIHRyYW5zaXRpb24udHdlZW4uZm9yRWFjaChmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPSB2YWx1ZS5jYWxsKG5vZGUsIGQsIGkpKSB7XG4gICAgICAgICAgICAgIHR3ZWVuZWQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKCF0aWNrKGVsYXBzZWQpKSBkMy50aW1lcih0aWNrLCAwLCB0aW1lKTtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiB0aWNrKGVsYXBzZWQpIHtcbiAgICAgICAgICBpZiAobG9jay5hY3RpdmUgIT09IGlkKSByZXR1cm4gc3RvcCgpO1xuICAgICAgICAgIHZhciB0ID0gKGVsYXBzZWQgLSBkZWxheSkgLyBkdXJhdGlvbiwgZSA9IGVhc2UodCksIG4gPSB0d2VlbmVkLmxlbmd0aDtcbiAgICAgICAgICB3aGlsZSAobiA+IDApIHtcbiAgICAgICAgICAgIHR3ZWVuZWRbLS1uXS5jYWxsKG5vZGUsIGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodCA+PSAxKSB7XG4gICAgICAgICAgICBzdG9wKCk7XG4gICAgICAgICAgICB0cmFuc2l0aW9uLmV2ZW50ICYmIHRyYW5zaXRpb24uZXZlbnQuZW5kLmNhbGwobm9kZSwgZCwgaSk7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gc3RvcCgpIHtcbiAgICAgICAgICBpZiAoLS1sb2NrLmNvdW50KSBkZWxldGUgbG9ja1tpZF07IGVsc2UgZGVsZXRlIG5vZGUuX190cmFuc2l0aW9uX187XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgIH0sIDAsIHRpbWUpO1xuICAgICAgcmV0dXJuIHRyYW5zaXRpb247XG4gICAgfVxuICB9XG4gIGQzLnN2Zy5heGlzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNjYWxlID0gZDMuc2NhbGUubGluZWFyKCksIG9yaWVudCA9IGQzX3N2Z19heGlzRGVmYXVsdE9yaWVudCwgdGlja01ham9yU2l6ZSA9IDYsIHRpY2tNaW5vclNpemUgPSA2LCB0aWNrRW5kU2l6ZSA9IDYsIHRpY2tQYWRkaW5nID0gMywgdGlja0FyZ3VtZW50c18gPSBbIDEwIF0sIHRpY2tWYWx1ZXMgPSBudWxsLCB0aWNrRm9ybWF0XywgdGlja1N1YmRpdmlkZSA9IDA7XG4gICAgZnVuY3Rpb24gYXhpcyhnKSB7XG4gICAgICBnLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBnID0gZDMuc2VsZWN0KHRoaXMpO1xuICAgICAgICB2YXIgdGlja3MgPSB0aWNrVmFsdWVzID09IG51bGwgPyBzY2FsZS50aWNrcyA/IHNjYWxlLnRpY2tzLmFwcGx5KHNjYWxlLCB0aWNrQXJndW1lbnRzXykgOiBzY2FsZS5kb21haW4oKSA6IHRpY2tWYWx1ZXMsIHRpY2tGb3JtYXQgPSB0aWNrRm9ybWF0XyA9PSBudWxsID8gc2NhbGUudGlja0Zvcm1hdCA/IHNjYWxlLnRpY2tGb3JtYXQuYXBwbHkoc2NhbGUsIHRpY2tBcmd1bWVudHNfKSA6IFN0cmluZyA6IHRpY2tGb3JtYXRfO1xuICAgICAgICB2YXIgc3VidGlja3MgPSBkM19zdmdfYXhpc1N1YmRpdmlkZShzY2FsZSwgdGlja3MsIHRpY2tTdWJkaXZpZGUpLCBzdWJ0aWNrID0gZy5zZWxlY3RBbGwoXCIudGljay5taW5vclwiKS5kYXRhKHN1YnRpY2tzLCBTdHJpbmcpLCBzdWJ0aWNrRW50ZXIgPSBzdWJ0aWNrLmVudGVyKCkuaW5zZXJ0KFwibGluZVwiLCBcIi50aWNrXCIpLmF0dHIoXCJjbGFzc1wiLCBcInRpY2sgbWlub3JcIikuc3R5bGUoXCJvcGFjaXR5XCIsIDFlLTYpLCBzdWJ0aWNrRXhpdCA9IGQzLnRyYW5zaXRpb24oc3VidGljay5leGl0KCkpLnN0eWxlKFwib3BhY2l0eVwiLCAxZS02KS5yZW1vdmUoKSwgc3VidGlja1VwZGF0ZSA9IGQzLnRyYW5zaXRpb24oc3VidGljaykuc3R5bGUoXCJvcGFjaXR5XCIsIDEpO1xuICAgICAgICB2YXIgdGljayA9IGcuc2VsZWN0QWxsKFwiLnRpY2subWFqb3JcIikuZGF0YSh0aWNrcywgU3RyaW5nKSwgdGlja0VudGVyID0gdGljay5lbnRlcigpLmluc2VydChcImdcIiwgXCIuZG9tYWluXCIpLmF0dHIoXCJjbGFzc1wiLCBcInRpY2sgbWFqb3JcIikuc3R5bGUoXCJvcGFjaXR5XCIsIDFlLTYpLCB0aWNrRXhpdCA9IGQzLnRyYW5zaXRpb24odGljay5leGl0KCkpLnN0eWxlKFwib3BhY2l0eVwiLCAxZS02KS5yZW1vdmUoKSwgdGlja1VwZGF0ZSA9IGQzLnRyYW5zaXRpb24odGljaykuc3R5bGUoXCJvcGFjaXR5XCIsIDEpLCB0aWNrVHJhbnNmb3JtO1xuICAgICAgICB2YXIgcmFuZ2UgPSBkM19zY2FsZVJhbmdlKHNjYWxlKSwgcGF0aCA9IGcuc2VsZWN0QWxsKFwiLmRvbWFpblwiKS5kYXRhKFsgMCBdKSwgcGF0aFVwZGF0ZSA9IChwYXRoLmVudGVyKCkuYXBwZW5kKFwicGF0aFwiKS5hdHRyKFwiY2xhc3NcIiwgXCJkb21haW5cIiksIFxuICAgICAgICBkMy50cmFuc2l0aW9uKHBhdGgpKTtcbiAgICAgICAgdmFyIHNjYWxlMSA9IHNjYWxlLmNvcHkoKSwgc2NhbGUwID0gdGhpcy5fX2NoYXJ0X18gfHwgc2NhbGUxO1xuICAgICAgICB0aGlzLl9fY2hhcnRfXyA9IHNjYWxlMTtcbiAgICAgICAgdGlja0VudGVyLmFwcGVuZChcImxpbmVcIik7XG4gICAgICAgIHRpY2tFbnRlci5hcHBlbmQoXCJ0ZXh0XCIpO1xuICAgICAgICB2YXIgbGluZUVudGVyID0gdGlja0VudGVyLnNlbGVjdChcImxpbmVcIiksIGxpbmVVcGRhdGUgPSB0aWNrVXBkYXRlLnNlbGVjdChcImxpbmVcIiksIHRleHQgPSB0aWNrLnNlbGVjdChcInRleHRcIikudGV4dCh0aWNrRm9ybWF0KSwgdGV4dEVudGVyID0gdGlja0VudGVyLnNlbGVjdChcInRleHRcIiksIHRleHRVcGRhdGUgPSB0aWNrVXBkYXRlLnNlbGVjdChcInRleHRcIik7XG4gICAgICAgIHN3aXRjaCAob3JpZW50KSB7XG4gICAgICAgICBjYXNlIFwiYm90dG9tXCI6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdGlja1RyYW5zZm9ybSA9IGQzX3N2Z19heGlzWDtcbiAgICAgICAgICAgIHN1YnRpY2tFbnRlci5hdHRyKFwieTJcIiwgdGlja01pbm9yU2l6ZSk7XG4gICAgICAgICAgICBzdWJ0aWNrVXBkYXRlLmF0dHIoXCJ4MlwiLCAwKS5hdHRyKFwieTJcIiwgdGlja01pbm9yU2l6ZSk7XG4gICAgICAgICAgICBsaW5lRW50ZXIuYXR0cihcInkyXCIsIHRpY2tNYWpvclNpemUpO1xuICAgICAgICAgICAgdGV4dEVudGVyLmF0dHIoXCJ5XCIsIE1hdGgubWF4KHRpY2tNYWpvclNpemUsIDApICsgdGlja1BhZGRpbmcpO1xuICAgICAgICAgICAgbGluZVVwZGF0ZS5hdHRyKFwieDJcIiwgMCkuYXR0cihcInkyXCIsIHRpY2tNYWpvclNpemUpO1xuICAgICAgICAgICAgdGV4dFVwZGF0ZS5hdHRyKFwieFwiLCAwKS5hdHRyKFwieVwiLCBNYXRoLm1heCh0aWNrTWFqb3JTaXplLCAwKSArIHRpY2tQYWRkaW5nKTtcbiAgICAgICAgICAgIHRleHQuYXR0cihcImR5XCIsIFwiLjcxZW1cIikuc3R5bGUoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKTtcbiAgICAgICAgICAgIHBhdGhVcGRhdGUuYXR0cihcImRcIiwgXCJNXCIgKyByYW5nZVswXSArIFwiLFwiICsgdGlja0VuZFNpemUgKyBcIlYwSFwiICsgcmFuZ2VbMV0gKyBcIlZcIiArIHRpY2tFbmRTaXplKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgY2FzZSBcInRvcFwiOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRpY2tUcmFuc2Zvcm0gPSBkM19zdmdfYXhpc1g7XG4gICAgICAgICAgICBzdWJ0aWNrRW50ZXIuYXR0cihcInkyXCIsIC10aWNrTWlub3JTaXplKTtcbiAgICAgICAgICAgIHN1YnRpY2tVcGRhdGUuYXR0cihcIngyXCIsIDApLmF0dHIoXCJ5MlwiLCAtdGlja01pbm9yU2l6ZSk7XG4gICAgICAgICAgICBsaW5lRW50ZXIuYXR0cihcInkyXCIsIC10aWNrTWFqb3JTaXplKTtcbiAgICAgICAgICAgIHRleHRFbnRlci5hdHRyKFwieVwiLCAtKE1hdGgubWF4KHRpY2tNYWpvclNpemUsIDApICsgdGlja1BhZGRpbmcpKTtcbiAgICAgICAgICAgIGxpbmVVcGRhdGUuYXR0cihcIngyXCIsIDApLmF0dHIoXCJ5MlwiLCAtdGlja01ham9yU2l6ZSk7XG4gICAgICAgICAgICB0ZXh0VXBkYXRlLmF0dHIoXCJ4XCIsIDApLmF0dHIoXCJ5XCIsIC0oTWF0aC5tYXgodGlja01ham9yU2l6ZSwgMCkgKyB0aWNrUGFkZGluZykpO1xuICAgICAgICAgICAgdGV4dC5hdHRyKFwiZHlcIiwgXCIwZW1cIikuc3R5bGUoXCJ0ZXh0LWFuY2hvclwiLCBcIm1pZGRsZVwiKTtcbiAgICAgICAgICAgIHBhdGhVcGRhdGUuYXR0cihcImRcIiwgXCJNXCIgKyByYW5nZVswXSArIFwiLFwiICsgLXRpY2tFbmRTaXplICsgXCJWMEhcIiArIHJhbmdlWzFdICsgXCJWXCIgKyAtdGlja0VuZFNpemUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICBjYXNlIFwibGVmdFwiOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRpY2tUcmFuc2Zvcm0gPSBkM19zdmdfYXhpc1k7XG4gICAgICAgICAgICBzdWJ0aWNrRW50ZXIuYXR0cihcIngyXCIsIC10aWNrTWlub3JTaXplKTtcbiAgICAgICAgICAgIHN1YnRpY2tVcGRhdGUuYXR0cihcIngyXCIsIC10aWNrTWlub3JTaXplKS5hdHRyKFwieTJcIiwgMCk7XG4gICAgICAgICAgICBsaW5lRW50ZXIuYXR0cihcIngyXCIsIC10aWNrTWFqb3JTaXplKTtcbiAgICAgICAgICAgIHRleHRFbnRlci5hdHRyKFwieFwiLCAtKE1hdGgubWF4KHRpY2tNYWpvclNpemUsIDApICsgdGlja1BhZGRpbmcpKTtcbiAgICAgICAgICAgIGxpbmVVcGRhdGUuYXR0cihcIngyXCIsIC10aWNrTWFqb3JTaXplKS5hdHRyKFwieTJcIiwgMCk7XG4gICAgICAgICAgICB0ZXh0VXBkYXRlLmF0dHIoXCJ4XCIsIC0oTWF0aC5tYXgodGlja01ham9yU2l6ZSwgMCkgKyB0aWNrUGFkZGluZykpLmF0dHIoXCJ5XCIsIDApO1xuICAgICAgICAgICAgdGV4dC5hdHRyKFwiZHlcIiwgXCIuMzJlbVwiKS5zdHlsZShcInRleHQtYW5jaG9yXCIsIFwiZW5kXCIpO1xuICAgICAgICAgICAgcGF0aFVwZGF0ZS5hdHRyKFwiZFwiLCBcIk1cIiArIC10aWNrRW5kU2l6ZSArIFwiLFwiICsgcmFuZ2VbMF0gKyBcIkgwVlwiICsgcmFuZ2VbMV0gKyBcIkhcIiArIC10aWNrRW5kU2l6ZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgIGNhc2UgXCJyaWdodFwiOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRpY2tUcmFuc2Zvcm0gPSBkM19zdmdfYXhpc1k7XG4gICAgICAgICAgICBzdWJ0aWNrRW50ZXIuYXR0cihcIngyXCIsIHRpY2tNaW5vclNpemUpO1xuICAgICAgICAgICAgc3VidGlja1VwZGF0ZS5hdHRyKFwieDJcIiwgdGlja01pbm9yU2l6ZSkuYXR0cihcInkyXCIsIDApO1xuICAgICAgICAgICAgbGluZUVudGVyLmF0dHIoXCJ4MlwiLCB0aWNrTWFqb3JTaXplKTtcbiAgICAgICAgICAgIHRleHRFbnRlci5hdHRyKFwieFwiLCBNYXRoLm1heCh0aWNrTWFqb3JTaXplLCAwKSArIHRpY2tQYWRkaW5nKTtcbiAgICAgICAgICAgIGxpbmVVcGRhdGUuYXR0cihcIngyXCIsIHRpY2tNYWpvclNpemUpLmF0dHIoXCJ5MlwiLCAwKTtcbiAgICAgICAgICAgIHRleHRVcGRhdGUuYXR0cihcInhcIiwgTWF0aC5tYXgodGlja01ham9yU2l6ZSwgMCkgKyB0aWNrUGFkZGluZykuYXR0cihcInlcIiwgMCk7XG4gICAgICAgICAgICB0ZXh0LmF0dHIoXCJkeVwiLCBcIi4zMmVtXCIpLnN0eWxlKFwidGV4dC1hbmNob3JcIiwgXCJzdGFydFwiKTtcbiAgICAgICAgICAgIHBhdGhVcGRhdGUuYXR0cihcImRcIiwgXCJNXCIgKyB0aWNrRW5kU2l6ZSArIFwiLFwiICsgcmFuZ2VbMF0gKyBcIkgwVlwiICsgcmFuZ2VbMV0gKyBcIkhcIiArIHRpY2tFbmRTaXplKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc2NhbGUucmFuZ2VCYW5kKSB7XG4gICAgICAgICAgdmFyIGR4ID0gc2NhbGUxLnJhbmdlQmFuZCgpIC8gMiwgeCA9IGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgICAgIHJldHVybiBzY2FsZTEoZCkgKyBkeDtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHRpY2tFbnRlci5jYWxsKHRpY2tUcmFuc2Zvcm0sIHgpO1xuICAgICAgICAgIHRpY2tVcGRhdGUuY2FsbCh0aWNrVHJhbnNmb3JtLCB4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aWNrRW50ZXIuY2FsbCh0aWNrVHJhbnNmb3JtLCBzY2FsZTApO1xuICAgICAgICAgIHRpY2tVcGRhdGUuY2FsbCh0aWNrVHJhbnNmb3JtLCBzY2FsZTEpO1xuICAgICAgICAgIHRpY2tFeGl0LmNhbGwodGlja1RyYW5zZm9ybSwgc2NhbGUxKTtcbiAgICAgICAgICBzdWJ0aWNrRW50ZXIuY2FsbCh0aWNrVHJhbnNmb3JtLCBzY2FsZTApO1xuICAgICAgICAgIHN1YnRpY2tVcGRhdGUuY2FsbCh0aWNrVHJhbnNmb3JtLCBzY2FsZTEpO1xuICAgICAgICAgIHN1YnRpY2tFeGl0LmNhbGwodGlja1RyYW5zZm9ybSwgc2NhbGUxKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIGF4aXMuc2NhbGUgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBzY2FsZTtcbiAgICAgIHNjYWxlID0geDtcbiAgICAgIHJldHVybiBheGlzO1xuICAgIH07XG4gICAgYXhpcy5vcmllbnQgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBvcmllbnQ7XG4gICAgICBvcmllbnQgPSB4IGluIGQzX3N2Z19heGlzT3JpZW50cyA/IHggKyBcIlwiIDogZDNfc3ZnX2F4aXNEZWZhdWx0T3JpZW50O1xuICAgICAgcmV0dXJuIGF4aXM7XG4gICAgfTtcbiAgICBheGlzLnRpY2tzID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aWNrQXJndW1lbnRzXztcbiAgICAgIHRpY2tBcmd1bWVudHNfID0gYXJndW1lbnRzO1xuICAgICAgcmV0dXJuIGF4aXM7XG4gICAgfTtcbiAgICBheGlzLnRpY2tWYWx1ZXMgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aWNrVmFsdWVzO1xuICAgICAgdGlja1ZhbHVlcyA9IHg7XG4gICAgICByZXR1cm4gYXhpcztcbiAgICB9O1xuICAgIGF4aXMudGlja0Zvcm1hdCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRpY2tGb3JtYXRfO1xuICAgICAgdGlja0Zvcm1hdF8gPSB4O1xuICAgICAgcmV0dXJuIGF4aXM7XG4gICAgfTtcbiAgICBheGlzLnRpY2tTaXplID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGlja01ham9yU2l6ZTtcbiAgICAgIHZhciBuID0gYXJndW1lbnRzLmxlbmd0aCAtIDE7XG4gICAgICB0aWNrTWFqb3JTaXplID0gK3g7XG4gICAgICB0aWNrTWlub3JTaXplID0gbiA+IDEgPyAreSA6IHRpY2tNYWpvclNpemU7XG4gICAgICB0aWNrRW5kU2l6ZSA9IG4gPiAwID8gK2FyZ3VtZW50c1tuXSA6IHRpY2tNYWpvclNpemU7XG4gICAgICByZXR1cm4gYXhpcztcbiAgICB9O1xuICAgIGF4aXMudGlja1BhZGRpbmcgPSBmdW5jdGlvbih4KSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aWNrUGFkZGluZztcbiAgICAgIHRpY2tQYWRkaW5nID0gK3g7XG4gICAgICByZXR1cm4gYXhpcztcbiAgICB9O1xuICAgIGF4aXMudGlja1N1YmRpdmlkZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRpY2tTdWJkaXZpZGU7XG4gICAgICB0aWNrU3ViZGl2aWRlID0gK3g7XG4gICAgICByZXR1cm4gYXhpcztcbiAgICB9O1xuICAgIHJldHVybiBheGlzO1xuICB9O1xuICB2YXIgZDNfc3ZnX2F4aXNEZWZhdWx0T3JpZW50ID0gXCJib3R0b21cIiwgZDNfc3ZnX2F4aXNPcmllbnRzID0ge1xuICAgIHRvcDogMSxcbiAgICByaWdodDogMSxcbiAgICBib3R0b206IDEsXG4gICAgbGVmdDogMVxuICB9O1xuICBmdW5jdGlvbiBkM19zdmdfYXhpc1goc2VsZWN0aW9uLCB4KSB7XG4gICAgc2VsZWN0aW9uLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgZnVuY3Rpb24oZCkge1xuICAgICAgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgeChkKSArIFwiLDApXCI7XG4gICAgfSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfc3ZnX2F4aXNZKHNlbGVjdGlvbiwgeSkge1xuICAgIHNlbGVjdGlvbi5hdHRyKFwidHJhbnNmb3JtXCIsIGZ1bmN0aW9uKGQpIHtcbiAgICAgIHJldHVybiBcInRyYW5zbGF0ZSgwLFwiICsgeShkKSArIFwiKVwiO1xuICAgIH0pO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3N2Z19heGlzU3ViZGl2aWRlKHNjYWxlLCB0aWNrcywgbSkge1xuICAgIHN1YnRpY2tzID0gW107XG4gICAgaWYgKG0gJiYgdGlja3MubGVuZ3RoID4gMSkge1xuICAgICAgdmFyIGV4dGVudCA9IGQzX3NjYWxlRXh0ZW50KHNjYWxlLmRvbWFpbigpKSwgc3VidGlja3MsIGkgPSAtMSwgbiA9IHRpY2tzLmxlbmd0aCwgZCA9ICh0aWNrc1sxXSAtIHRpY2tzWzBdKSAvICsrbSwgaiwgdjtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgIGZvciAoaiA9IG07IC0taiA+IDA7ICkge1xuICAgICAgICAgIGlmICgodiA9ICt0aWNrc1tpXSAtIGogKiBkKSA+PSBleHRlbnRbMF0pIHtcbiAgICAgICAgICAgIHN1YnRpY2tzLnB1c2godik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmb3IgKC0taSwgaiA9IDA7ICsraiA8IG0gJiYgKHYgPSArdGlja3NbaV0gKyBqICogZCkgPCBleHRlbnRbMV07ICkge1xuICAgICAgICBzdWJ0aWNrcy5wdXNoKHYpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3VidGlja3M7XG4gIH1cbiAgZDMuc3ZnLmJydXNoID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGV2ZW50ID0gZDNfZXZlbnREaXNwYXRjaChicnVzaCwgXCJicnVzaHN0YXJ0XCIsIFwiYnJ1c2hcIiwgXCJicnVzaGVuZFwiKSwgeCA9IG51bGwsIHkgPSBudWxsLCByZXNpemVzID0gZDNfc3ZnX2JydXNoUmVzaXplc1swXSwgZXh0ZW50ID0gWyBbIDAsIDAgXSwgWyAwLCAwIF0gXSwgY2xhbXAgPSBbIHRydWUsIHRydWUgXSwgZXh0ZW50RG9tYWluO1xuICAgIGZ1bmN0aW9uIGJydXNoKGcpIHtcbiAgICAgIGcuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGcgPSBkMy5zZWxlY3QodGhpcyksIGJnID0gZy5zZWxlY3RBbGwoXCIuYmFja2dyb3VuZFwiKS5kYXRhKFsgMCBdKSwgZmcgPSBnLnNlbGVjdEFsbChcIi5leHRlbnRcIikuZGF0YShbIDAgXSksIHR6ID0gZy5zZWxlY3RBbGwoXCIucmVzaXplXCIpLmRhdGEocmVzaXplcywgU3RyaW5nKSwgZTtcbiAgICAgICAgZy5zdHlsZShcInBvaW50ZXItZXZlbnRzXCIsIFwiYWxsXCIpLm9uKFwibW91c2Vkb3duLmJydXNoXCIsIGJydXNoc3RhcnQpLm9uKFwidG91Y2hzdGFydC5icnVzaFwiLCBicnVzaHN0YXJ0KTtcbiAgICAgICAgYmcuZW50ZXIoKS5hcHBlbmQoXCJyZWN0XCIpLmF0dHIoXCJjbGFzc1wiLCBcImJhY2tncm91bmRcIikuc3R5bGUoXCJ2aXNpYmlsaXR5XCIsIFwiaGlkZGVuXCIpLnN0eWxlKFwiY3Vyc29yXCIsIFwiY3Jvc3NoYWlyXCIpO1xuICAgICAgICBmZy5lbnRlcigpLmFwcGVuZChcInJlY3RcIikuYXR0cihcImNsYXNzXCIsIFwiZXh0ZW50XCIpLnN0eWxlKFwiY3Vyc29yXCIsIFwibW92ZVwiKTtcbiAgICAgICAgdHouZW50ZXIoKS5hcHBlbmQoXCJnXCIpLmF0dHIoXCJjbGFzc1wiLCBmdW5jdGlvbihkKSB7XG4gICAgICAgICAgcmV0dXJuIFwicmVzaXplIFwiICsgZDtcbiAgICAgICAgfSkuc3R5bGUoXCJjdXJzb3JcIiwgZnVuY3Rpb24oZCkge1xuICAgICAgICAgIHJldHVybiBkM19zdmdfYnJ1c2hDdXJzb3JbZF07XG4gICAgICAgIH0pLmFwcGVuZChcInJlY3RcIikuYXR0cihcInhcIiwgZnVuY3Rpb24oZCkge1xuICAgICAgICAgIHJldHVybiAvW2V3XSQvLnRlc3QoZCkgPyAtMyA6IG51bGw7XG4gICAgICAgIH0pLmF0dHIoXCJ5XCIsIGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgICByZXR1cm4gL15bbnNdLy50ZXN0KGQpID8gLTMgOiBudWxsO1xuICAgICAgICB9KS5hdHRyKFwid2lkdGhcIiwgNikuYXR0cihcImhlaWdodFwiLCA2KS5zdHlsZShcInZpc2liaWxpdHlcIiwgXCJoaWRkZW5cIik7XG4gICAgICAgIHR6LnN0eWxlKFwiZGlzcGxheVwiLCBicnVzaC5lbXB0eSgpID8gXCJub25lXCIgOiBudWxsKTtcbiAgICAgICAgdHouZXhpdCgpLnJlbW92ZSgpO1xuICAgICAgICBpZiAoeCkge1xuICAgICAgICAgIGUgPSBkM19zY2FsZVJhbmdlKHgpO1xuICAgICAgICAgIGJnLmF0dHIoXCJ4XCIsIGVbMF0pLmF0dHIoXCJ3aWR0aFwiLCBlWzFdIC0gZVswXSk7XG4gICAgICAgICAgcmVkcmF3WChnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoeSkge1xuICAgICAgICAgIGUgPSBkM19zY2FsZVJhbmdlKHkpO1xuICAgICAgICAgIGJnLmF0dHIoXCJ5XCIsIGVbMF0pLmF0dHIoXCJoZWlnaHRcIiwgZVsxXSAtIGVbMF0pO1xuICAgICAgICAgIHJlZHJhd1koZyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVkcmF3KGcpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlZHJhdyhnKSB7XG4gICAgICBnLnNlbGVjdEFsbChcIi5yZXNpemVcIikuYXR0cihcInRyYW5zZm9ybVwiLCBmdW5jdGlvbihkKSB7XG4gICAgICAgIHJldHVybiBcInRyYW5zbGF0ZShcIiArIGV4dGVudFsrL2UkLy50ZXN0KGQpXVswXSArIFwiLFwiICsgZXh0ZW50WysvXnMvLnRlc3QoZCldWzFdICsgXCIpXCI7XG4gICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcmVkcmF3WChnKSB7XG4gICAgICBnLnNlbGVjdChcIi5leHRlbnRcIikuYXR0cihcInhcIiwgZXh0ZW50WzBdWzBdKTtcbiAgICAgIGcuc2VsZWN0QWxsKFwiLmV4dGVudCwubj5yZWN0LC5zPnJlY3RcIikuYXR0cihcIndpZHRoXCIsIGV4dGVudFsxXVswXSAtIGV4dGVudFswXVswXSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlZHJhd1koZykge1xuICAgICAgZy5zZWxlY3QoXCIuZXh0ZW50XCIpLmF0dHIoXCJ5XCIsIGV4dGVudFswXVsxXSk7XG4gICAgICBnLnNlbGVjdEFsbChcIi5leHRlbnQsLmU+cmVjdCwudz5yZWN0XCIpLmF0dHIoXCJoZWlnaHRcIiwgZXh0ZW50WzFdWzFdIC0gZXh0ZW50WzBdWzFdKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYnJ1c2hzdGFydCgpIHtcbiAgICAgIHZhciB0YXJnZXQgPSB0aGlzLCBldmVudFRhcmdldCA9IGQzLnNlbGVjdChkMy5ldmVudC50YXJnZXQpLCBldmVudF8gPSBldmVudC5vZih0YXJnZXQsIGFyZ3VtZW50cyksIGcgPSBkMy5zZWxlY3QodGFyZ2V0KSwgcmVzaXppbmcgPSBldmVudFRhcmdldC5kYXR1bSgpLCByZXNpemluZ1ggPSAhL14obnxzKSQvLnRlc3QocmVzaXppbmcpICYmIHgsIHJlc2l6aW5nWSA9ICEvXihlfHcpJC8udGVzdChyZXNpemluZykgJiYgeSwgZHJhZ2dpbmcgPSBldmVudFRhcmdldC5jbGFzc2VkKFwiZXh0ZW50XCIpLCBkcmFnUmVzdG9yZSA9IGQzX2V2ZW50X2RyYWdTdXBwcmVzcyhcImJydXNoXCIpLCBjZW50ZXIsIG9yaWdpbiA9IG1vdXNlKCksIG9mZnNldDtcbiAgICAgIHZhciB3ID0gZDMuc2VsZWN0KGQzX3dpbmRvdykub24oXCJrZXlkb3duLmJydXNoXCIsIGtleWRvd24pLm9uKFwia2V5dXAuYnJ1c2hcIiwga2V5dXApO1xuICAgICAgaWYgKGQzLmV2ZW50LmNoYW5nZWRUb3VjaGVzKSB7XG4gICAgICAgIHcub24oXCJ0b3VjaG1vdmUuYnJ1c2hcIiwgYnJ1c2htb3ZlKS5vbihcInRvdWNoZW5kLmJydXNoXCIsIGJydXNoZW5kKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHcub24oXCJtb3VzZW1vdmUuYnJ1c2hcIiwgYnJ1c2htb3ZlKS5vbihcIm1vdXNldXAuYnJ1c2hcIiwgYnJ1c2hlbmQpO1xuICAgICAgfVxuICAgICAgaWYgKGRyYWdnaW5nKSB7XG4gICAgICAgIG9yaWdpblswXSA9IGV4dGVudFswXVswXSAtIG9yaWdpblswXTtcbiAgICAgICAgb3JpZ2luWzFdID0gZXh0ZW50WzBdWzFdIC0gb3JpZ2luWzFdO1xuICAgICAgfSBlbHNlIGlmIChyZXNpemluZykge1xuICAgICAgICB2YXIgZXggPSArL3ckLy50ZXN0KHJlc2l6aW5nKSwgZXkgPSArL15uLy50ZXN0KHJlc2l6aW5nKTtcbiAgICAgICAgb2Zmc2V0ID0gWyBleHRlbnRbMSAtIGV4XVswXSAtIG9yaWdpblswXSwgZXh0ZW50WzEgLSBleV1bMV0gLSBvcmlnaW5bMV0gXTtcbiAgICAgICAgb3JpZ2luWzBdID0gZXh0ZW50W2V4XVswXTtcbiAgICAgICAgb3JpZ2luWzFdID0gZXh0ZW50W2V5XVsxXTtcbiAgICAgIH0gZWxzZSBpZiAoZDMuZXZlbnQuYWx0S2V5KSBjZW50ZXIgPSBvcmlnaW4uc2xpY2UoKTtcbiAgICAgIGcuc3R5bGUoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIikuc2VsZWN0QWxsKFwiLnJlc2l6ZVwiKS5zdHlsZShcImRpc3BsYXlcIiwgbnVsbCk7XG4gICAgICBkMy5zZWxlY3QoXCJib2R5XCIpLnN0eWxlKFwiY3Vyc29yXCIsIGV2ZW50VGFyZ2V0LnN0eWxlKFwiY3Vyc29yXCIpKTtcbiAgICAgIGV2ZW50Xyh7XG4gICAgICAgIHR5cGU6IFwiYnJ1c2hzdGFydFwiXG4gICAgICB9KTtcbiAgICAgIGJydXNobW92ZSgpO1xuICAgICAgZnVuY3Rpb24gbW91c2UoKSB7XG4gICAgICAgIHZhciB0b3VjaGVzID0gZDMuZXZlbnQuY2hhbmdlZFRvdWNoZXM7XG4gICAgICAgIHJldHVybiB0b3VjaGVzID8gZDMudG91Y2hlcyh0YXJnZXQsIHRvdWNoZXMpWzBdIDogZDMubW91c2UodGFyZ2V0KTtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGtleWRvd24oKSB7XG4gICAgICAgIGlmIChkMy5ldmVudC5rZXlDb2RlID09IDMyKSB7XG4gICAgICAgICAgaWYgKCFkcmFnZ2luZykge1xuICAgICAgICAgICAgY2VudGVyID0gbnVsbDtcbiAgICAgICAgICAgIG9yaWdpblswXSAtPSBleHRlbnRbMV1bMF07XG4gICAgICAgICAgICBvcmlnaW5bMV0gLT0gZXh0ZW50WzFdWzFdO1xuICAgICAgICAgICAgZHJhZ2dpbmcgPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkM19ldmVudFByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGtleXVwKCkge1xuICAgICAgICBpZiAoZDMuZXZlbnQua2V5Q29kZSA9PSAzMiAmJiBkcmFnZ2luZyA9PSAyKSB7XG4gICAgICAgICAgb3JpZ2luWzBdICs9IGV4dGVudFsxXVswXTtcbiAgICAgICAgICBvcmlnaW5bMV0gKz0gZXh0ZW50WzFdWzFdO1xuICAgICAgICAgIGRyYWdnaW5nID0gMDtcbiAgICAgICAgICBkM19ldmVudFByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGJydXNobW92ZSgpIHtcbiAgICAgICAgdmFyIHBvaW50ID0gbW91c2UoKSwgbW92ZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKG9mZnNldCkge1xuICAgICAgICAgIHBvaW50WzBdICs9IG9mZnNldFswXTtcbiAgICAgICAgICBwb2ludFsxXSArPSBvZmZzZXRbMV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFkcmFnZ2luZykge1xuICAgICAgICAgIGlmIChkMy5ldmVudC5hbHRLZXkpIHtcbiAgICAgICAgICAgIGlmICghY2VudGVyKSBjZW50ZXIgPSBbIChleHRlbnRbMF1bMF0gKyBleHRlbnRbMV1bMF0pIC8gMiwgKGV4dGVudFswXVsxXSArIGV4dGVudFsxXVsxXSkgLyAyIF07XG4gICAgICAgICAgICBvcmlnaW5bMF0gPSBleHRlbnRbKyhwb2ludFswXSA8IGNlbnRlclswXSldWzBdO1xuICAgICAgICAgICAgb3JpZ2luWzFdID0gZXh0ZW50WysocG9pbnRbMV0gPCBjZW50ZXJbMV0pXVsxXTtcbiAgICAgICAgICB9IGVsc2UgY2VudGVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzaXppbmdYICYmIG1vdmUxKHBvaW50LCB4LCAwKSkge1xuICAgICAgICAgIHJlZHJhd1goZyk7XG4gICAgICAgICAgbW92ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNpemluZ1kgJiYgbW92ZTEocG9pbnQsIHksIDEpKSB7XG4gICAgICAgICAgcmVkcmF3WShnKTtcbiAgICAgICAgICBtb3ZlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vdmVkKSB7XG4gICAgICAgICAgcmVkcmF3KGcpO1xuICAgICAgICAgIGV2ZW50Xyh7XG4gICAgICAgICAgICB0eXBlOiBcImJydXNoXCIsXG4gICAgICAgICAgICBtb2RlOiBkcmFnZ2luZyA/IFwibW92ZVwiIDogXCJyZXNpemVcIlxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiBtb3ZlMShwb2ludCwgc2NhbGUsIGkpIHtcbiAgICAgICAgdmFyIHJhbmdlID0gZDNfc2NhbGVSYW5nZShzY2FsZSksIHIwID0gcmFuZ2VbMF0sIHIxID0gcmFuZ2VbMV0sIHBvc2l0aW9uID0gb3JpZ2luW2ldLCBzaXplID0gZXh0ZW50WzFdW2ldIC0gZXh0ZW50WzBdW2ldLCBtaW4sIG1heDtcbiAgICAgICAgaWYgKGRyYWdnaW5nKSB7XG4gICAgICAgICAgcjAgLT0gcG9zaXRpb247XG4gICAgICAgICAgcjEgLT0gc2l6ZSArIHBvc2l0aW9uO1xuICAgICAgICB9XG4gICAgICAgIG1pbiA9IGNsYW1wW2ldID8gTWF0aC5tYXgocjAsIE1hdGgubWluKHIxLCBwb2ludFtpXSkpIDogcG9pbnRbaV07XG4gICAgICAgIGlmIChkcmFnZ2luZykge1xuICAgICAgICAgIG1heCA9IChtaW4gKz0gcG9zaXRpb24pICsgc2l6ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoY2VudGVyKSBwb3NpdGlvbiA9IE1hdGgubWF4KHIwLCBNYXRoLm1pbihyMSwgMiAqIGNlbnRlcltpXSAtIG1pbikpO1xuICAgICAgICAgIGlmIChwb3NpdGlvbiA8IG1pbikge1xuICAgICAgICAgICAgbWF4ID0gbWluO1xuICAgICAgICAgICAgbWluID0gcG9zaXRpb247XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1heCA9IHBvc2l0aW9uO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZXh0ZW50WzBdW2ldICE9PSBtaW4gfHwgZXh0ZW50WzFdW2ldICE9PSBtYXgpIHtcbiAgICAgICAgICBleHRlbnREb21haW4gPSBudWxsO1xuICAgICAgICAgIGV4dGVudFswXVtpXSA9IG1pbjtcbiAgICAgICAgICBleHRlbnRbMV1baV0gPSBtYXg7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGJydXNoZW5kKCkge1xuICAgICAgICBicnVzaG1vdmUoKTtcbiAgICAgICAgZy5zdHlsZShcInBvaW50ZXItZXZlbnRzXCIsIFwiYWxsXCIpLnNlbGVjdEFsbChcIi5yZXNpemVcIikuc3R5bGUoXCJkaXNwbGF5XCIsIGJydXNoLmVtcHR5KCkgPyBcIm5vbmVcIiA6IG51bGwpO1xuICAgICAgICBkMy5zZWxlY3QoXCJib2R5XCIpLnN0eWxlKFwiY3Vyc29yXCIsIG51bGwpO1xuICAgICAgICB3Lm9uKFwibW91c2Vtb3ZlLmJydXNoXCIsIG51bGwpLm9uKFwibW91c2V1cC5icnVzaFwiLCBudWxsKS5vbihcInRvdWNobW92ZS5icnVzaFwiLCBudWxsKS5vbihcInRvdWNoZW5kLmJydXNoXCIsIG51bGwpLm9uKFwia2V5ZG93bi5icnVzaFwiLCBudWxsKS5vbihcImtleXVwLmJydXNoXCIsIG51bGwpO1xuICAgICAgICBkcmFnUmVzdG9yZSgpO1xuICAgICAgICBldmVudF8oe1xuICAgICAgICAgIHR5cGU6IFwiYnJ1c2hlbmRcIlxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgYnJ1c2gueCA9IGZ1bmN0aW9uKHopIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHg7XG4gICAgICB4ID0gejtcbiAgICAgIHJlc2l6ZXMgPSBkM19zdmdfYnJ1c2hSZXNpemVzWyF4IDw8IDEgfCAheV07XG4gICAgICByZXR1cm4gYnJ1c2g7XG4gICAgfTtcbiAgICBicnVzaC55ID0gZnVuY3Rpb24oeikge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4geTtcbiAgICAgIHkgPSB6O1xuICAgICAgcmVzaXplcyA9IGQzX3N2Z19icnVzaFJlc2l6ZXNbIXggPDwgMSB8ICF5XTtcbiAgICAgIHJldHVybiBicnVzaDtcbiAgICB9O1xuICAgIGJydXNoLmNsYW1wID0gZnVuY3Rpb24oeikge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4geCAmJiB5ID8gY2xhbXAgOiB4IHx8IHkgPyBjbGFtcFsrIXhdIDogbnVsbDtcbiAgICAgIGlmICh4ICYmIHkpIGNsYW1wID0gWyAhIXpbMF0sICEhelsxXSBdOyBlbHNlIGlmICh4IHx8IHkpIGNsYW1wWysheF0gPSAhIXo7XG4gICAgICByZXR1cm4gYnJ1c2g7XG4gICAgfTtcbiAgICBicnVzaC5leHRlbnQgPSBmdW5jdGlvbih6KSB7XG4gICAgICB2YXIgeDAsIHgxLCB5MCwgeTEsIHQ7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgeiA9IGV4dGVudERvbWFpbiB8fCBleHRlbnQ7XG4gICAgICAgIGlmICh4KSB7XG4gICAgICAgICAgeDAgPSB6WzBdWzBdLCB4MSA9IHpbMV1bMF07XG4gICAgICAgICAgaWYgKCFleHRlbnREb21haW4pIHtcbiAgICAgICAgICAgIHgwID0gZXh0ZW50WzBdWzBdLCB4MSA9IGV4dGVudFsxXVswXTtcbiAgICAgICAgICAgIGlmICh4LmludmVydCkgeDAgPSB4LmludmVydCh4MCksIHgxID0geC5pbnZlcnQoeDEpO1xuICAgICAgICAgICAgaWYgKHgxIDwgeDApIHQgPSB4MCwgeDAgPSB4MSwgeDEgPSB0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoeSkge1xuICAgICAgICAgIHkwID0gelswXVsxXSwgeTEgPSB6WzFdWzFdO1xuICAgICAgICAgIGlmICghZXh0ZW50RG9tYWluKSB7XG4gICAgICAgICAgICB5MCA9IGV4dGVudFswXVsxXSwgeTEgPSBleHRlbnRbMV1bMV07XG4gICAgICAgICAgICBpZiAoeS5pbnZlcnQpIHkwID0geS5pbnZlcnQoeTApLCB5MSA9IHkuaW52ZXJ0KHkxKTtcbiAgICAgICAgICAgIGlmICh5MSA8IHkwKSB0ID0geTAsIHkwID0geTEsIHkxID0gdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggJiYgeSA/IFsgWyB4MCwgeTAgXSwgWyB4MSwgeTEgXSBdIDogeCA/IFsgeDAsIHgxIF0gOiB5ICYmIFsgeTAsIHkxIF07XG4gICAgICB9XG4gICAgICBleHRlbnREb21haW4gPSBbIFsgMCwgMCBdLCBbIDAsIDAgXSBdO1xuICAgICAgaWYgKHgpIHtcbiAgICAgICAgeDAgPSB6WzBdLCB4MSA9IHpbMV07XG4gICAgICAgIGlmICh5KSB4MCA9IHgwWzBdLCB4MSA9IHgxWzBdO1xuICAgICAgICBleHRlbnREb21haW5bMF1bMF0gPSB4MCwgZXh0ZW50RG9tYWluWzFdWzBdID0geDE7XG4gICAgICAgIGlmICh4LmludmVydCkgeDAgPSB4KHgwKSwgeDEgPSB4KHgxKTtcbiAgICAgICAgaWYgKHgxIDwgeDApIHQgPSB4MCwgeDAgPSB4MSwgeDEgPSB0O1xuICAgICAgICBleHRlbnRbMF1bMF0gPSB4MCB8IDAsIGV4dGVudFsxXVswXSA9IHgxIHwgMDtcbiAgICAgIH1cbiAgICAgIGlmICh5KSB7XG4gICAgICAgIHkwID0gelswXSwgeTEgPSB6WzFdO1xuICAgICAgICBpZiAoeCkgeTAgPSB5MFsxXSwgeTEgPSB5MVsxXTtcbiAgICAgICAgZXh0ZW50RG9tYWluWzBdWzFdID0geTAsIGV4dGVudERvbWFpblsxXVsxXSA9IHkxO1xuICAgICAgICBpZiAoeS5pbnZlcnQpIHkwID0geSh5MCksIHkxID0geSh5MSk7XG4gICAgICAgIGlmICh5MSA8IHkwKSB0ID0geTAsIHkwID0geTEsIHkxID0gdDtcbiAgICAgICAgZXh0ZW50WzBdWzFdID0geTAgfCAwLCBleHRlbnRbMV1bMV0gPSB5MSB8IDA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnJ1c2g7XG4gICAgfTtcbiAgICBicnVzaC5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgZXh0ZW50RG9tYWluID0gbnVsbDtcbiAgICAgIGV4dGVudFswXVswXSA9IGV4dGVudFswXVsxXSA9IGV4dGVudFsxXVswXSA9IGV4dGVudFsxXVsxXSA9IDA7XG4gICAgICByZXR1cm4gYnJ1c2g7XG4gICAgfTtcbiAgICBicnVzaC5lbXB0eSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHggJiYgZXh0ZW50WzBdWzBdID09PSBleHRlbnRbMV1bMF0gfHwgeSAmJiBleHRlbnRbMF1bMV0gPT09IGV4dGVudFsxXVsxXTtcbiAgICB9O1xuICAgIHJldHVybiBkMy5yZWJpbmQoYnJ1c2gsIGV2ZW50LCBcIm9uXCIpO1xuICB9O1xuICB2YXIgZDNfc3ZnX2JydXNoQ3Vyc29yID0ge1xuICAgIG46IFwibnMtcmVzaXplXCIsXG4gICAgZTogXCJldy1yZXNpemVcIixcbiAgICBzOiBcIm5zLXJlc2l6ZVwiLFxuICAgIHc6IFwiZXctcmVzaXplXCIsXG4gICAgbnc6IFwibndzZS1yZXNpemVcIixcbiAgICBuZTogXCJuZXN3LXJlc2l6ZVwiLFxuICAgIHNlOiBcIm53c2UtcmVzaXplXCIsXG4gICAgc3c6IFwibmVzdy1yZXNpemVcIlxuICB9O1xuICB2YXIgZDNfc3ZnX2JydXNoUmVzaXplcyA9IFsgWyBcIm5cIiwgXCJlXCIsIFwic1wiLCBcIndcIiwgXCJud1wiLCBcIm5lXCIsIFwic2VcIiwgXCJzd1wiIF0sIFsgXCJlXCIsIFwid1wiIF0sIFsgXCJuXCIsIFwic1wiIF0sIFtdIF07XG4gIGQzLnRpbWUgPSB7fTtcbiAgdmFyIGQzX3RpbWUgPSBEYXRlLCBkM190aW1lX2RheVN5bWJvbHMgPSBbIFwiU3VuZGF5XCIsIFwiTW9uZGF5XCIsIFwiVHVlc2RheVwiLCBcIldlZG5lc2RheVwiLCBcIlRodXJzZGF5XCIsIFwiRnJpZGF5XCIsIFwiU2F0dXJkYXlcIiBdO1xuICBmdW5jdGlvbiBkM190aW1lX3V0YygpIHtcbiAgICB0aGlzLl8gPSBuZXcgRGF0ZShhcmd1bWVudHMubGVuZ3RoID4gMSA/IERhdGUuVVRDLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBhcmd1bWVudHNbMF0pO1xuICB9XG4gIGQzX3RpbWVfdXRjLnByb3RvdHlwZSA9IHtcbiAgICBnZXREYXRlOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl8uZ2V0VVRDRGF0ZSgpO1xuICAgIH0sXG4gICAgZ2V0RGF5OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl8uZ2V0VVRDRGF5KCk7XG4gICAgfSxcbiAgICBnZXRGdWxsWWVhcjogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgfSxcbiAgICBnZXRIb3VyczogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fLmdldFVUQ0hvdXJzKCk7XG4gICAgfSxcbiAgICBnZXRNaWxsaXNlY29uZHM6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuXy5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgICB9LFxuICAgIGdldE1pbnV0ZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuXy5nZXRVVENNaW51dGVzKCk7XG4gICAgfSxcbiAgICBnZXRNb250aDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fLmdldFVUQ01vbnRoKCk7XG4gICAgfSxcbiAgICBnZXRTZWNvbmRzOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl8uZ2V0VVRDU2Vjb25kcygpO1xuICAgIH0sXG4gICAgZ2V0VGltZTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fLmdldFRpbWUoKTtcbiAgICB9LFxuICAgIGdldFRpbWV6b25lT2Zmc2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0sXG4gICAgdmFsdWVPZjogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fLnZhbHVlT2YoKTtcbiAgICB9LFxuICAgIHNldERhdGU6IGZ1bmN0aW9uKCkge1xuICAgICAgZDNfdGltZV9wcm90b3R5cGUuc2V0VVRDRGF0ZS5hcHBseSh0aGlzLl8sIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBzZXREYXk6IGZ1bmN0aW9uKCkge1xuICAgICAgZDNfdGltZV9wcm90b3R5cGUuc2V0VVRDRGF5LmFwcGx5KHRoaXMuXywgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHNldEZ1bGxZZWFyOiBmdW5jdGlvbigpIHtcbiAgICAgIGQzX3RpbWVfcHJvdG90eXBlLnNldFVUQ0Z1bGxZZWFyLmFwcGx5KHRoaXMuXywgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHNldEhvdXJzOiBmdW5jdGlvbigpIHtcbiAgICAgIGQzX3RpbWVfcHJvdG90eXBlLnNldFVUQ0hvdXJzLmFwcGx5KHRoaXMuXywgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHNldE1pbGxpc2Vjb25kczogZnVuY3Rpb24oKSB7XG4gICAgICBkM190aW1lX3Byb3RvdHlwZS5zZXRVVENNaWxsaXNlY29uZHMuYXBwbHkodGhpcy5fLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgc2V0TWludXRlczogZnVuY3Rpb24oKSB7XG4gICAgICBkM190aW1lX3Byb3RvdHlwZS5zZXRVVENNaW51dGVzLmFwcGx5KHRoaXMuXywgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHNldE1vbnRoOiBmdW5jdGlvbigpIHtcbiAgICAgIGQzX3RpbWVfcHJvdG90eXBlLnNldFVUQ01vbnRoLmFwcGx5KHRoaXMuXywgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHNldFNlY29uZHM6IGZ1bmN0aW9uKCkge1xuICAgICAgZDNfdGltZV9wcm90b3R5cGUuc2V0VVRDU2Vjb25kcy5hcHBseSh0aGlzLl8sIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBzZXRUaW1lOiBmdW5jdGlvbigpIHtcbiAgICAgIGQzX3RpbWVfcHJvdG90eXBlLnNldFRpbWUuYXBwbHkodGhpcy5fLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbiAgdmFyIGQzX3RpbWVfcHJvdG90eXBlID0gRGF0ZS5wcm90b3R5cGU7XG4gIHZhciBkM190aW1lX2Zvcm1hdERhdGVUaW1lID0gXCIlYSAlYiAlZSAlWCAlWVwiLCBkM190aW1lX2Zvcm1hdERhdGUgPSBcIiVtLyVkLyVZXCIsIGQzX3RpbWVfZm9ybWF0VGltZSA9IFwiJUg6JU06JVNcIjtcbiAgdmFyIGQzX3RpbWVfZGF5cyA9IFsgXCJTdW5kYXlcIiwgXCJNb25kYXlcIiwgXCJUdWVzZGF5XCIsIFwiV2VkbmVzZGF5XCIsIFwiVGh1cnNkYXlcIiwgXCJGcmlkYXlcIiwgXCJTYXR1cmRheVwiIF0sIGQzX3RpbWVfZGF5QWJicmV2aWF0aW9ucyA9IFsgXCJTdW5cIiwgXCJNb25cIiwgXCJUdWVcIiwgXCJXZWRcIiwgXCJUaHVcIiwgXCJGcmlcIiwgXCJTYXRcIiBdLCBkM190aW1lX21vbnRocyA9IFsgXCJKYW51YXJ5XCIsIFwiRmVicnVhcnlcIiwgXCJNYXJjaFwiLCBcIkFwcmlsXCIsIFwiTWF5XCIsIFwiSnVuZVwiLCBcIkp1bHlcIiwgXCJBdWd1c3RcIiwgXCJTZXB0ZW1iZXJcIiwgXCJPY3RvYmVyXCIsIFwiTm92ZW1iZXJcIiwgXCJEZWNlbWJlclwiIF0sIGQzX3RpbWVfbW9udGhBYmJyZXZpYXRpb25zID0gWyBcIkphblwiLCBcIkZlYlwiLCBcIk1hclwiLCBcIkFwclwiLCBcIk1heVwiLCBcIkp1blwiLCBcIkp1bFwiLCBcIkF1Z1wiLCBcIlNlcFwiLCBcIk9jdFwiLCBcIk5vdlwiLCBcIkRlY1wiIF07XG4gIGZ1bmN0aW9uIGQzX3RpbWVfaW50ZXJ2YWwobG9jYWwsIHN0ZXAsIG51bWJlcikge1xuICAgIGZ1bmN0aW9uIHJvdW5kKGRhdGUpIHtcbiAgICAgIHZhciBkMCA9IGxvY2FsKGRhdGUpLCBkMSA9IG9mZnNldChkMCwgMSk7XG4gICAgICByZXR1cm4gZGF0ZSAtIGQwIDwgZDEgLSBkYXRlID8gZDAgOiBkMTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2VpbChkYXRlKSB7XG4gICAgICBzdGVwKGRhdGUgPSBsb2NhbChuZXcgZDNfdGltZShkYXRlIC0gMSkpLCAxKTtcbiAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBvZmZzZXQoZGF0ZSwgaykge1xuICAgICAgc3RlcChkYXRlID0gbmV3IGQzX3RpbWUoK2RhdGUpLCBrKTtcbiAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cbiAgICBmdW5jdGlvbiByYW5nZSh0MCwgdDEsIGR0KSB7XG4gICAgICB2YXIgdGltZSA9IGNlaWwodDApLCB0aW1lcyA9IFtdO1xuICAgICAgaWYgKGR0ID4gMSkge1xuICAgICAgICB3aGlsZSAodGltZSA8IHQxKSB7XG4gICAgICAgICAgaWYgKCEobnVtYmVyKHRpbWUpICUgZHQpKSB0aW1lcy5wdXNoKG5ldyBEYXRlKCt0aW1lKSk7XG4gICAgICAgICAgc3RlcCh0aW1lLCAxKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2hpbGUgKHRpbWUgPCB0MSkgdGltZXMucHVzaChuZXcgRGF0ZSgrdGltZSkpLCBzdGVwKHRpbWUsIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRpbWVzO1xuICAgIH1cbiAgICBmdW5jdGlvbiByYW5nZV91dGModDAsIHQxLCBkdCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZDNfdGltZSA9IGQzX3RpbWVfdXRjO1xuICAgICAgICB2YXIgdXRjID0gbmV3IGQzX3RpbWVfdXRjKCk7XG4gICAgICAgIHV0Yy5fID0gdDA7XG4gICAgICAgIHJldHVybiByYW5nZSh1dGMsIHQxLCBkdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBkM190aW1lID0gRGF0ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgbG9jYWwuZmxvb3IgPSBsb2NhbDtcbiAgICBsb2NhbC5yb3VuZCA9IHJvdW5kO1xuICAgIGxvY2FsLmNlaWwgPSBjZWlsO1xuICAgIGxvY2FsLm9mZnNldCA9IG9mZnNldDtcbiAgICBsb2NhbC5yYW5nZSA9IHJhbmdlO1xuICAgIHZhciB1dGMgPSBsb2NhbC51dGMgPSBkM190aW1lX2ludGVydmFsX3V0Yyhsb2NhbCk7XG4gICAgdXRjLmZsb29yID0gdXRjO1xuICAgIHV0Yy5yb3VuZCA9IGQzX3RpbWVfaW50ZXJ2YWxfdXRjKHJvdW5kKTtcbiAgICB1dGMuY2VpbCA9IGQzX3RpbWVfaW50ZXJ2YWxfdXRjKGNlaWwpO1xuICAgIHV0Yy5vZmZzZXQgPSBkM190aW1lX2ludGVydmFsX3V0YyhvZmZzZXQpO1xuICAgIHV0Yy5yYW5nZSA9IHJhbmdlX3V0YztcbiAgICByZXR1cm4gbG9jYWw7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9pbnRlcnZhbF91dGMobWV0aG9kKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUsIGspIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGQzX3RpbWUgPSBkM190aW1lX3V0YztcbiAgICAgICAgdmFyIHV0YyA9IG5ldyBkM190aW1lX3V0YygpO1xuICAgICAgICB1dGMuXyA9IGRhdGU7XG4gICAgICAgIHJldHVybiBtZXRob2QodXRjLCBrKS5fO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgZDNfdGltZSA9IERhdGU7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuICBkMy50aW1lLnllYXIgPSBkM190aW1lX2ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlID0gZDMudGltZS5kYXkoZGF0ZSk7XG4gICAgZGF0ZS5zZXRNb250aCgwLCAxKTtcbiAgICByZXR1cm4gZGF0ZTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgb2Zmc2V0KSB7XG4gICAgZGF0ZS5zZXRGdWxsWWVhcihkYXRlLmdldEZ1bGxZZWFyKCkgKyBvZmZzZXQpO1xuICB9LCBmdW5jdGlvbihkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgfSk7XG4gIGQzLnRpbWUueWVhcnMgPSBkMy50aW1lLnllYXIucmFuZ2U7XG4gIGQzLnRpbWUueWVhcnMudXRjID0gZDMudGltZS55ZWFyLnV0Yy5yYW5nZTtcbiAgZDMudGltZS5kYXkgPSBkM190aW1lX2ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICB2YXIgZGF5ID0gbmV3IGQzX3RpbWUoMmUzLCAwKTtcbiAgICBkYXkuc2V0RnVsbFllYXIoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCksIGRhdGUuZ2V0RGF0ZSgpKTtcbiAgICByZXR1cm4gZGF5O1xuICB9LCBmdW5jdGlvbihkYXRlLCBvZmZzZXQpIHtcbiAgICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBvZmZzZXQpO1xuICB9LCBmdW5jdGlvbihkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0RGF0ZSgpIC0gMTtcbiAgfSk7XG4gIGQzLnRpbWUuZGF5cyA9IGQzLnRpbWUuZGF5LnJhbmdlO1xuICBkMy50aW1lLmRheXMudXRjID0gZDMudGltZS5kYXkudXRjLnJhbmdlO1xuICBkMy50aW1lLmRheU9mWWVhciA9IGZ1bmN0aW9uKGRhdGUpIHtcbiAgICB2YXIgeWVhciA9IGQzLnRpbWUueWVhcihkYXRlKTtcbiAgICByZXR1cm4gTWF0aC5mbG9vcigoZGF0ZSAtIHllYXIgLSAoZGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpIC0geWVhci5nZXRUaW1lem9uZU9mZnNldCgpKSAqIDZlNCkgLyA4NjRlNSk7XG4gIH07XG4gIGQzX3RpbWVfZGF5U3ltYm9scy5mb3JFYWNoKGZ1bmN0aW9uKGRheSwgaSkge1xuICAgIGRheSA9IGRheS50b0xvd2VyQ2FzZSgpO1xuICAgIGkgPSA3IC0gaTtcbiAgICB2YXIgaW50ZXJ2YWwgPSBkMy50aW1lW2RheV0gPSBkM190aW1lX2ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgIChkYXRlID0gZDMudGltZS5kYXkoZGF0ZSkpLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgLSAoZGF0ZS5nZXREYXkoKSArIGkpICUgNyk7XG4gICAgICByZXR1cm4gZGF0ZTtcbiAgICB9LCBmdW5jdGlvbihkYXRlLCBvZmZzZXQpIHtcbiAgICAgIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIE1hdGguZmxvb3Iob2Zmc2V0KSAqIDcpO1xuICAgIH0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgIHZhciBkYXkgPSBkMy50aW1lLnllYXIoZGF0ZSkuZ2V0RGF5KCk7XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcigoZDMudGltZS5kYXlPZlllYXIoZGF0ZSkgKyAoZGF5ICsgaSkgJSA3KSAvIDcpIC0gKGRheSAhPT0gaSk7XG4gICAgfSk7XG4gICAgZDMudGltZVtkYXkgKyBcInNcIl0gPSBpbnRlcnZhbC5yYW5nZTtcbiAgICBkMy50aW1lW2RheSArIFwic1wiXS51dGMgPSBpbnRlcnZhbC51dGMucmFuZ2U7XG4gICAgZDMudGltZVtkYXkgKyBcIk9mWWVhclwiXSA9IGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgIHZhciBkYXkgPSBkMy50aW1lLnllYXIoZGF0ZSkuZ2V0RGF5KCk7XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcigoZDMudGltZS5kYXlPZlllYXIoZGF0ZSkgKyAoZGF5ICsgaSkgJSA3KSAvIDcpO1xuICAgIH07XG4gIH0pO1xuICBkMy50aW1lLndlZWsgPSBkMy50aW1lLnN1bmRheTtcbiAgZDMudGltZS53ZWVrcyA9IGQzLnRpbWUuc3VuZGF5LnJhbmdlO1xuICBkMy50aW1lLndlZWtzLnV0YyA9IGQzLnRpbWUuc3VuZGF5LnV0Yy5yYW5nZTtcbiAgZDMudGltZS53ZWVrT2ZZZWFyID0gZDMudGltZS5zdW5kYXlPZlllYXI7XG4gIGQzLnRpbWUuZm9ybWF0ID0gZnVuY3Rpb24odGVtcGxhdGUpIHtcbiAgICB2YXIgbiA9IHRlbXBsYXRlLmxlbmd0aDtcbiAgICBmdW5jdGlvbiBmb3JtYXQoZGF0ZSkge1xuICAgICAgdmFyIHN0cmluZyA9IFtdLCBpID0gLTEsIGogPSAwLCBjLCBwLCBmO1xuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgaWYgKHRlbXBsYXRlLmNoYXJDb2RlQXQoaSkgPT09IDM3KSB7XG4gICAgICAgICAgc3RyaW5nLnB1c2godGVtcGxhdGUuc3Vic3RyaW5nKGosIGkpKTtcbiAgICAgICAgICBpZiAoKHAgPSBkM190aW1lX2Zvcm1hdFBhZHNbYyA9IHRlbXBsYXRlLmNoYXJBdCgrK2kpXSkgIT0gbnVsbCkgYyA9IHRlbXBsYXRlLmNoYXJBdCgrK2kpO1xuICAgICAgICAgIGlmIChmID0gZDNfdGltZV9mb3JtYXRzW2NdKSBjID0gZihkYXRlLCBwID09IG51bGwgPyBjID09PSBcImVcIiA/IFwiIFwiIDogXCIwXCIgOiBwKTtcbiAgICAgICAgICBzdHJpbmcucHVzaChjKTtcbiAgICAgICAgICBqID0gaSArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN0cmluZy5wdXNoKHRlbXBsYXRlLnN1YnN0cmluZyhqLCBpKSk7XG4gICAgICByZXR1cm4gc3RyaW5nLmpvaW4oXCJcIik7XG4gICAgfVxuICAgIGZvcm1hdC5wYXJzZSA9IGZ1bmN0aW9uKHN0cmluZykge1xuICAgICAgdmFyIGQgPSB7XG4gICAgICAgIHk6IDE5MDAsXG4gICAgICAgIG06IDAsXG4gICAgICAgIGQ6IDEsXG4gICAgICAgIEg6IDAsXG4gICAgICAgIE06IDAsXG4gICAgICAgIFM6IDAsXG4gICAgICAgIEw6IDBcbiAgICAgIH0sIGkgPSBkM190aW1lX3BhcnNlKGQsIHRlbXBsYXRlLCBzdHJpbmcsIDApO1xuICAgICAgaWYgKGkgIT0gc3RyaW5nLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gICAgICBpZiAoXCJwXCIgaW4gZCkgZC5IID0gZC5IICUgMTIgKyBkLnAgKiAxMjtcbiAgICAgIHZhciBkYXRlID0gbmV3IGQzX3RpbWUoKTtcbiAgICAgIGlmIChcImpcIiBpbiBkKSBkYXRlLnNldEZ1bGxZZWFyKGQueSwgMCwgZC5qKTsgZWxzZSBpZiAoXCJ3XCIgaW4gZCAmJiAoXCJXXCIgaW4gZCB8fCBcIlVcIiBpbiBkKSkge1xuICAgICAgICBkYXRlLnNldEZ1bGxZZWFyKGQueSwgMCwgMSk7XG4gICAgICAgIGRhdGUuc2V0RnVsbFllYXIoZC55LCAwLCBcIldcIiBpbiBkID8gKGQudyArIDYpICUgNyArIGQuVyAqIDcgLSAoZGF0ZS5nZXREYXkoKSArIDUpICUgNyA6IGQudyArIGQuVSAqIDcgLSAoZGF0ZS5nZXREYXkoKSArIDYpICUgNyk7XG4gICAgICB9IGVsc2UgZGF0ZS5zZXRGdWxsWWVhcihkLnksIGQubSwgZC5kKTtcbiAgICAgIGRhdGUuc2V0SG91cnMoZC5ILCBkLk0sIGQuUywgZC5MKTtcbiAgICAgIHJldHVybiBkYXRlO1xuICAgIH07XG4gICAgZm9ybWF0LnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGVtcGxhdGU7XG4gICAgfTtcbiAgICByZXR1cm4gZm9ybWF0O1xuICB9O1xuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlKGRhdGUsIHRlbXBsYXRlLCBzdHJpbmcsIGopIHtcbiAgICB2YXIgYywgcCwgaSA9IDAsIG4gPSB0ZW1wbGF0ZS5sZW5ndGgsIG0gPSBzdHJpbmcubGVuZ3RoO1xuICAgIHdoaWxlIChpIDwgbikge1xuICAgICAgaWYgKGogPj0gbSkgcmV0dXJuIC0xO1xuICAgICAgYyA9IHRlbXBsYXRlLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgIGlmIChjID09PSAzNykge1xuICAgICAgICBwID0gZDNfdGltZV9wYXJzZXJzW3RlbXBsYXRlLmNoYXJBdChpKyspXTtcbiAgICAgICAgaWYgKCFwIHx8IChqID0gcChkYXRlLCBzdHJpbmcsIGopKSA8IDApIHJldHVybiAtMTtcbiAgICAgIH0gZWxzZSBpZiAoYyAhPSBzdHJpbmcuY2hhckNvZGVBdChqKyspKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGo7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9mb3JtYXRSZShuYW1lcykge1xuICAgIHJldHVybiBuZXcgUmVnRXhwKFwiXig/OlwiICsgbmFtZXMubWFwKGQzLnJlcXVvdGUpLmpvaW4oXCJ8XCIpICsgXCIpXCIsIFwiaVwiKTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX2Zvcm1hdExvb2t1cChuYW1lcykge1xuICAgIHZhciBtYXAgPSBuZXcgZDNfTWFwKCksIGkgPSAtMSwgbiA9IG5hbWVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgbWFwLnNldChuYW1lc1tpXS50b0xvd2VyQ2FzZSgpLCBpKTtcbiAgICByZXR1cm4gbWFwO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfZm9ybWF0UGFkKHZhbHVlLCBmaWxsLCB3aWR0aCkge1xuICAgIHZhciBzaWduID0gdmFsdWUgPCAwID8gXCItXCIgOiBcIlwiLCBzdHJpbmcgPSAoc2lnbiA/IC12YWx1ZSA6IHZhbHVlKSArIFwiXCIsIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG4gICAgcmV0dXJuIHNpZ24gKyAobGVuZ3RoIDwgd2lkdGggPyBuZXcgQXJyYXkod2lkdGggLSBsZW5ndGggKyAxKS5qb2luKGZpbGwpICsgc3RyaW5nIDogc3RyaW5nKTtcbiAgfVxuICB2YXIgZDNfdGltZV9kYXlSZSA9IGQzX3RpbWVfZm9ybWF0UmUoZDNfdGltZV9kYXlzKSwgZDNfdGltZV9kYXlMb29rdXAgPSBkM190aW1lX2Zvcm1hdExvb2t1cChkM190aW1lX2RheXMpLCBkM190aW1lX2RheUFiYnJldlJlID0gZDNfdGltZV9mb3JtYXRSZShkM190aW1lX2RheUFiYnJldmlhdGlvbnMpLCBkM190aW1lX2RheUFiYnJldkxvb2t1cCA9IGQzX3RpbWVfZm9ybWF0TG9va3VwKGQzX3RpbWVfZGF5QWJicmV2aWF0aW9ucyksIGQzX3RpbWVfbW9udGhSZSA9IGQzX3RpbWVfZm9ybWF0UmUoZDNfdGltZV9tb250aHMpLCBkM190aW1lX21vbnRoTG9va3VwID0gZDNfdGltZV9mb3JtYXRMb29rdXAoZDNfdGltZV9tb250aHMpLCBkM190aW1lX21vbnRoQWJicmV2UmUgPSBkM190aW1lX2Zvcm1hdFJlKGQzX3RpbWVfbW9udGhBYmJyZXZpYXRpb25zKSwgZDNfdGltZV9tb250aEFiYnJldkxvb2t1cCA9IGQzX3RpbWVfZm9ybWF0TG9va3VwKGQzX3RpbWVfbW9udGhBYmJyZXZpYXRpb25zKSwgZDNfdGltZV9wZXJjZW50UmUgPSAvXiUvO1xuICB2YXIgZDNfdGltZV9mb3JtYXRQYWRzID0ge1xuICAgIFwiLVwiOiBcIlwiLFxuICAgIF86IFwiIFwiLFxuICAgIFwiMFwiOiBcIjBcIlxuICB9O1xuICB2YXIgZDNfdGltZV9mb3JtYXRzID0ge1xuICAgIGE6IGZ1bmN0aW9uKGQpIHtcbiAgICAgIHJldHVybiBkM190aW1lX2RheUFiYnJldmlhdGlvbnNbZC5nZXREYXkoKV07XG4gICAgfSxcbiAgICBBOiBmdW5jdGlvbihkKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9kYXlzW2QuZ2V0RGF5KCldO1xuICAgIH0sXG4gICAgYjogZnVuY3Rpb24oZCkge1xuICAgICAgcmV0dXJuIGQzX3RpbWVfbW9udGhBYmJyZXZpYXRpb25zW2QuZ2V0TW9udGgoKV07XG4gICAgfSxcbiAgICBCOiBmdW5jdGlvbihkKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9tb250aHNbZC5nZXRNb250aCgpXTtcbiAgICB9LFxuICAgIGM6IGQzLnRpbWUuZm9ybWF0KGQzX3RpbWVfZm9ybWF0RGF0ZVRpbWUpLFxuICAgIGQ6IGZ1bmN0aW9uKGQsIHApIHtcbiAgICAgIHJldHVybiBkM190aW1lX2Zvcm1hdFBhZChkLmdldERhdGUoKSwgcCwgMik7XG4gICAgfSxcbiAgICBlOiBmdW5jdGlvbihkLCBwKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9mb3JtYXRQYWQoZC5nZXREYXRlKCksIHAsIDIpO1xuICAgIH0sXG4gICAgSDogZnVuY3Rpb24oZCwgcCkge1xuICAgICAgcmV0dXJuIGQzX3RpbWVfZm9ybWF0UGFkKGQuZ2V0SG91cnMoKSwgcCwgMik7XG4gICAgfSxcbiAgICBJOiBmdW5jdGlvbihkLCBwKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9mb3JtYXRQYWQoZC5nZXRIb3VycygpICUgMTIgfHwgMTIsIHAsIDIpO1xuICAgIH0sXG4gICAgajogZnVuY3Rpb24oZCwgcCkge1xuICAgICAgcmV0dXJuIGQzX3RpbWVfZm9ybWF0UGFkKDEgKyBkMy50aW1lLmRheU9mWWVhcihkKSwgcCwgMyk7XG4gICAgfSxcbiAgICBMOiBmdW5jdGlvbihkLCBwKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9mb3JtYXRQYWQoZC5nZXRNaWxsaXNlY29uZHMoKSwgcCwgMyk7XG4gICAgfSxcbiAgICBtOiBmdW5jdGlvbihkLCBwKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9mb3JtYXRQYWQoZC5nZXRNb250aCgpICsgMSwgcCwgMik7XG4gICAgfSxcbiAgICBNOiBmdW5jdGlvbihkLCBwKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9mb3JtYXRQYWQoZC5nZXRNaW51dGVzKCksIHAsIDIpO1xuICAgIH0sXG4gICAgcDogZnVuY3Rpb24oZCkge1xuICAgICAgcmV0dXJuIGQuZ2V0SG91cnMoKSA+PSAxMiA/IFwiUE1cIiA6IFwiQU1cIjtcbiAgICB9LFxuICAgIFM6IGZ1bmN0aW9uKGQsIHApIHtcbiAgICAgIHJldHVybiBkM190aW1lX2Zvcm1hdFBhZChkLmdldFNlY29uZHMoKSwgcCwgMik7XG4gICAgfSxcbiAgICBVOiBmdW5jdGlvbihkLCBwKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9mb3JtYXRQYWQoZDMudGltZS5zdW5kYXlPZlllYXIoZCksIHAsIDIpO1xuICAgIH0sXG4gICAgdzogZnVuY3Rpb24oZCkge1xuICAgICAgcmV0dXJuIGQuZ2V0RGF5KCk7XG4gICAgfSxcbiAgICBXOiBmdW5jdGlvbihkLCBwKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9mb3JtYXRQYWQoZDMudGltZS5tb25kYXlPZlllYXIoZCksIHAsIDIpO1xuICAgIH0sXG4gICAgeDogZDMudGltZS5mb3JtYXQoZDNfdGltZV9mb3JtYXREYXRlKSxcbiAgICBYOiBkMy50aW1lLmZvcm1hdChkM190aW1lX2Zvcm1hdFRpbWUpLFxuICAgIHk6IGZ1bmN0aW9uKGQsIHApIHtcbiAgICAgIHJldHVybiBkM190aW1lX2Zvcm1hdFBhZChkLmdldEZ1bGxZZWFyKCkgJSAxMDAsIHAsIDIpO1xuICAgIH0sXG4gICAgWTogZnVuY3Rpb24oZCwgcCkge1xuICAgICAgcmV0dXJuIGQzX3RpbWVfZm9ybWF0UGFkKGQuZ2V0RnVsbFllYXIoKSAlIDFlNCwgcCwgNCk7XG4gICAgfSxcbiAgICBaOiBkM190aW1lX3pvbmUsXG4gICAgXCIlXCI6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIFwiJVwiO1xuICAgIH1cbiAgfTtcbiAgdmFyIGQzX3RpbWVfcGFyc2VycyA9IHtcbiAgICBhOiBkM190aW1lX3BhcnNlV2Vla2RheUFiYnJldixcbiAgICBBOiBkM190aW1lX3BhcnNlV2Vla2RheSxcbiAgICBiOiBkM190aW1lX3BhcnNlTW9udGhBYmJyZXYsXG4gICAgQjogZDNfdGltZV9wYXJzZU1vbnRoLFxuICAgIGM6IGQzX3RpbWVfcGFyc2VMb2NhbGVGdWxsLFxuICAgIGQ6IGQzX3RpbWVfcGFyc2VEYXksXG4gICAgZTogZDNfdGltZV9wYXJzZURheSxcbiAgICBIOiBkM190aW1lX3BhcnNlSG91cjI0LFxuICAgIEk6IGQzX3RpbWVfcGFyc2VIb3VyMjQsXG4gICAgajogZDNfdGltZV9wYXJzZURheU9mWWVhcixcbiAgICBMOiBkM190aW1lX3BhcnNlTWlsbGlzZWNvbmRzLFxuICAgIG06IGQzX3RpbWVfcGFyc2VNb250aE51bWJlcixcbiAgICBNOiBkM190aW1lX3BhcnNlTWludXRlcyxcbiAgICBwOiBkM190aW1lX3BhcnNlQW1QbSxcbiAgICBTOiBkM190aW1lX3BhcnNlU2Vjb25kcyxcbiAgICBVOiBkM190aW1lX3BhcnNlV2Vla051bWJlclN1bmRheSxcbiAgICB3OiBkM190aW1lX3BhcnNlV2Vla2RheU51bWJlcixcbiAgICBXOiBkM190aW1lX3BhcnNlV2Vla051bWJlck1vbmRheSxcbiAgICB4OiBkM190aW1lX3BhcnNlTG9jYWxlRGF0ZSxcbiAgICBYOiBkM190aW1lX3BhcnNlTG9jYWxlVGltZSxcbiAgICB5OiBkM190aW1lX3BhcnNlWWVhcixcbiAgICBZOiBkM190aW1lX3BhcnNlRnVsbFllYXIsXG4gICAgXCIlXCI6IGQzX3RpbWVfcGFyc2VMaXRlcmFsUGVyY2VudFxuICB9O1xuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlV2Vla2RheUFiYnJldihkYXRlLCBzdHJpbmcsIGkpIHtcbiAgICBkM190aW1lX2RheUFiYnJldlJlLmxhc3RJbmRleCA9IDA7XG4gICAgdmFyIG4gPSBkM190aW1lX2RheUFiYnJldlJlLmV4ZWMoc3RyaW5nLnN1YnN0cmluZyhpKSk7XG4gICAgcmV0dXJuIG4gPyAoZGF0ZS53ID0gZDNfdGltZV9kYXlBYmJyZXZMb29rdXAuZ2V0KG5bMF0udG9Mb3dlckNhc2UoKSksIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlV2Vla2RheShkYXRlLCBzdHJpbmcsIGkpIHtcbiAgICBkM190aW1lX2RheVJlLmxhc3RJbmRleCA9IDA7XG4gICAgdmFyIG4gPSBkM190aW1lX2RheVJlLmV4ZWMoc3RyaW5nLnN1YnN0cmluZyhpKSk7XG4gICAgcmV0dXJuIG4gPyAoZGF0ZS53ID0gZDNfdGltZV9kYXlMb29rdXAuZ2V0KG5bMF0udG9Mb3dlckNhc2UoKSksIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlV2Vla2RheU51bWJlcihkYXRlLCBzdHJpbmcsIGkpIHtcbiAgICBkM190aW1lX251bWJlclJlLmxhc3RJbmRleCA9IDA7XG4gICAgdmFyIG4gPSBkM190aW1lX251bWJlclJlLmV4ZWMoc3RyaW5nLnN1YnN0cmluZyhpLCBpICsgMSkpO1xuICAgIHJldHVybiBuID8gKGRhdGUudyA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9wYXJzZVdlZWtOdW1iZXJTdW5kYXkoZGF0ZSwgc3RyaW5nLCBpKSB7XG4gICAgZDNfdGltZV9udW1iZXJSZS5sYXN0SW5kZXggPSAwO1xuICAgIHZhciBuID0gZDNfdGltZV9udW1iZXJSZS5leGVjKHN0cmluZy5zdWJzdHJpbmcoaSkpO1xuICAgIHJldHVybiBuID8gKGRhdGUuVSA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9wYXJzZVdlZWtOdW1iZXJNb25kYXkoZGF0ZSwgc3RyaW5nLCBpKSB7XG4gICAgZDNfdGltZV9udW1iZXJSZS5sYXN0SW5kZXggPSAwO1xuICAgIHZhciBuID0gZDNfdGltZV9udW1iZXJSZS5leGVjKHN0cmluZy5zdWJzdHJpbmcoaSkpO1xuICAgIHJldHVybiBuID8gKGRhdGUuVyA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9wYXJzZU1vbnRoQWJicmV2KGRhdGUsIHN0cmluZywgaSkge1xuICAgIGQzX3RpbWVfbW9udGhBYmJyZXZSZS5sYXN0SW5kZXggPSAwO1xuICAgIHZhciBuID0gZDNfdGltZV9tb250aEFiYnJldlJlLmV4ZWMoc3RyaW5nLnN1YnN0cmluZyhpKSk7XG4gICAgcmV0dXJuIG4gPyAoZGF0ZS5tID0gZDNfdGltZV9tb250aEFiYnJldkxvb2t1cC5nZXQoblswXS50b0xvd2VyQ2FzZSgpKSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfcGFyc2VNb250aChkYXRlLCBzdHJpbmcsIGkpIHtcbiAgICBkM190aW1lX21vbnRoUmUubGFzdEluZGV4ID0gMDtcbiAgICB2YXIgbiA9IGQzX3RpbWVfbW9udGhSZS5leGVjKHN0cmluZy5zdWJzdHJpbmcoaSkpO1xuICAgIHJldHVybiBuID8gKGRhdGUubSA9IGQzX3RpbWVfbW9udGhMb29rdXAuZ2V0KG5bMF0udG9Mb3dlckNhc2UoKSksIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlTG9jYWxlRnVsbChkYXRlLCBzdHJpbmcsIGkpIHtcbiAgICByZXR1cm4gZDNfdGltZV9wYXJzZShkYXRlLCBkM190aW1lX2Zvcm1hdHMuYy50b1N0cmluZygpLCBzdHJpbmcsIGkpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfcGFyc2VMb2NhbGVEYXRlKGRhdGUsIHN0cmluZywgaSkge1xuICAgIHJldHVybiBkM190aW1lX3BhcnNlKGRhdGUsIGQzX3RpbWVfZm9ybWF0cy54LnRvU3RyaW5nKCksIHN0cmluZywgaSk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9wYXJzZUxvY2FsZVRpbWUoZGF0ZSwgc3RyaW5nLCBpKSB7XG4gICAgcmV0dXJuIGQzX3RpbWVfcGFyc2UoZGF0ZSwgZDNfdGltZV9mb3JtYXRzLlgudG9TdHJpbmcoKSwgc3RyaW5nLCBpKTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlRnVsbFllYXIoZGF0ZSwgc3RyaW5nLCBpKSB7XG4gICAgZDNfdGltZV9udW1iZXJSZS5sYXN0SW5kZXggPSAwO1xuICAgIHZhciBuID0gZDNfdGltZV9udW1iZXJSZS5leGVjKHN0cmluZy5zdWJzdHJpbmcoaSwgaSArIDQpKTtcbiAgICByZXR1cm4gbiA/IChkYXRlLnkgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfcGFyc2VZZWFyKGRhdGUsIHN0cmluZywgaSkge1xuICAgIGQzX3RpbWVfbnVtYmVyUmUubGFzdEluZGV4ID0gMDtcbiAgICB2YXIgbiA9IGQzX3RpbWVfbnVtYmVyUmUuZXhlYyhzdHJpbmcuc3Vic3RyaW5nKGksIGkgKyAyKSk7XG4gICAgcmV0dXJuIG4gPyAoZGF0ZS55ID0gZDNfdGltZV9leHBhbmRZZWFyKCtuWzBdKSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfZXhwYW5kWWVhcihkKSB7XG4gICAgcmV0dXJuIGQgKyAoZCA+IDY4ID8gMTkwMCA6IDJlMyk7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9wYXJzZU1vbnRoTnVtYmVyKGRhdGUsIHN0cmluZywgaSkge1xuICAgIGQzX3RpbWVfbnVtYmVyUmUubGFzdEluZGV4ID0gMDtcbiAgICB2YXIgbiA9IGQzX3RpbWVfbnVtYmVyUmUuZXhlYyhzdHJpbmcuc3Vic3RyaW5nKGksIGkgKyAyKSk7XG4gICAgcmV0dXJuIG4gPyAoZGF0ZS5tID0gblswXSAtIDEsIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlRGF5KGRhdGUsIHN0cmluZywgaSkge1xuICAgIGQzX3RpbWVfbnVtYmVyUmUubGFzdEluZGV4ID0gMDtcbiAgICB2YXIgbiA9IGQzX3RpbWVfbnVtYmVyUmUuZXhlYyhzdHJpbmcuc3Vic3RyaW5nKGksIGkgKyAyKSk7XG4gICAgcmV0dXJuIG4gPyAoZGF0ZS5kID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlRGF5T2ZZZWFyKGRhdGUsIHN0cmluZywgaSkge1xuICAgIGQzX3RpbWVfbnVtYmVyUmUubGFzdEluZGV4ID0gMDtcbiAgICB2YXIgbiA9IGQzX3RpbWVfbnVtYmVyUmUuZXhlYyhzdHJpbmcuc3Vic3RyaW5nKGksIGkgKyAzKSk7XG4gICAgcmV0dXJuIG4gPyAoZGF0ZS5qID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlSG91cjI0KGRhdGUsIHN0cmluZywgaSkge1xuICAgIGQzX3RpbWVfbnVtYmVyUmUubGFzdEluZGV4ID0gMDtcbiAgICB2YXIgbiA9IGQzX3RpbWVfbnVtYmVyUmUuZXhlYyhzdHJpbmcuc3Vic3RyaW5nKGksIGkgKyAyKSk7XG4gICAgcmV0dXJuIG4gPyAoZGF0ZS5IID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3BhcnNlTWludXRlcyhkYXRlLCBzdHJpbmcsIGkpIHtcbiAgICBkM190aW1lX251bWJlclJlLmxhc3RJbmRleCA9IDA7XG4gICAgdmFyIG4gPSBkM190aW1lX251bWJlclJlLmV4ZWMoc3RyaW5nLnN1YnN0cmluZyhpLCBpICsgMikpO1xuICAgIHJldHVybiBuID8gKGRhdGUuTSA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9wYXJzZVNlY29uZHMoZGF0ZSwgc3RyaW5nLCBpKSB7XG4gICAgZDNfdGltZV9udW1iZXJSZS5sYXN0SW5kZXggPSAwO1xuICAgIHZhciBuID0gZDNfdGltZV9udW1iZXJSZS5leGVjKHN0cmluZy5zdWJzdHJpbmcoaSwgaSArIDIpKTtcbiAgICByZXR1cm4gbiA/IChkYXRlLlMgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfcGFyc2VNaWxsaXNlY29uZHMoZGF0ZSwgc3RyaW5nLCBpKSB7XG4gICAgZDNfdGltZV9udW1iZXJSZS5sYXN0SW5kZXggPSAwO1xuICAgIHZhciBuID0gZDNfdGltZV9udW1iZXJSZS5leGVjKHN0cmluZy5zdWJzdHJpbmcoaSwgaSArIDMpKTtcbiAgICByZXR1cm4gbiA/IChkYXRlLkwgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG4gIHZhciBkM190aW1lX251bWJlclJlID0gL15cXHMqXFxkKy87XG4gIGZ1bmN0aW9uIGQzX3RpbWVfcGFyc2VBbVBtKGRhdGUsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gZDNfdGltZV9hbVBtTG9va3VwLmdldChzdHJpbmcuc3Vic3RyaW5nKGksIGkgKz0gMikudG9Mb3dlckNhc2UoKSk7XG4gICAgcmV0dXJuIG4gPT0gbnVsbCA/IC0xIDogKGRhdGUucCA9IG4sIGkpO1xuICB9XG4gIHZhciBkM190aW1lX2FtUG1Mb29rdXAgPSBkMy5tYXAoe1xuICAgIGFtOiAwLFxuICAgIHBtOiAxXG4gIH0pO1xuICBmdW5jdGlvbiBkM190aW1lX3pvbmUoZCkge1xuICAgIHZhciB6ID0gZC5nZXRUaW1lem9uZU9mZnNldCgpLCB6cyA9IHogPiAwID8gXCItXCIgOiBcIitcIiwgemggPSB+fihNYXRoLmFicyh6KSAvIDYwKSwgem0gPSBNYXRoLmFicyh6KSAlIDYwO1xuICAgIHJldHVybiB6cyArIGQzX3RpbWVfZm9ybWF0UGFkKHpoLCBcIjBcIiwgMikgKyBkM190aW1lX2Zvcm1hdFBhZCh6bSwgXCIwXCIsIDIpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfcGFyc2VMaXRlcmFsUGVyY2VudChkYXRlLCBzdHJpbmcsIGkpIHtcbiAgICBkM190aW1lX3BlcmNlbnRSZS5sYXN0SW5kZXggPSAwO1xuICAgIHZhciBuID0gZDNfdGltZV9wZXJjZW50UmUuZXhlYyhzdHJpbmcuc3Vic3RyaW5nKGksIGkgKyAxKSk7XG4gICAgcmV0dXJuIG4gPyBpICsgblswXS5sZW5ndGggOiAtMTtcbiAgfVxuICBkMy50aW1lLmZvcm1hdC51dGMgPSBmdW5jdGlvbih0ZW1wbGF0ZSkge1xuICAgIHZhciBsb2NhbCA9IGQzLnRpbWUuZm9ybWF0KHRlbXBsYXRlKTtcbiAgICBmdW5jdGlvbiBmb3JtYXQoZGF0ZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZDNfdGltZSA9IGQzX3RpbWVfdXRjO1xuICAgICAgICB2YXIgdXRjID0gbmV3IGQzX3RpbWUoKTtcbiAgICAgICAgdXRjLl8gPSBkYXRlO1xuICAgICAgICByZXR1cm4gbG9jYWwodXRjKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGQzX3RpbWUgPSBEYXRlO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3JtYXQucGFyc2UgPSBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGQzX3RpbWUgPSBkM190aW1lX3V0YztcbiAgICAgICAgdmFyIGRhdGUgPSBsb2NhbC5wYXJzZShzdHJpbmcpO1xuICAgICAgICByZXR1cm4gZGF0ZSAmJiBkYXRlLl87XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBkM190aW1lID0gRGF0ZTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGZvcm1hdC50b1N0cmluZyA9IGxvY2FsLnRvU3RyaW5nO1xuICAgIHJldHVybiBmb3JtYXQ7XG4gIH07XG4gIHZhciBkM190aW1lX2Zvcm1hdElzbyA9IGQzLnRpbWUuZm9ybWF0LnV0YyhcIiVZLSVtLSVkVCVIOiVNOiVTLiVMWlwiKTtcbiAgZDMudGltZS5mb3JtYXQuaXNvID0gRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcgJiYgK25ldyBEYXRlKFwiMjAwMC0wMS0wMVQwMDowMDowMC4wMDBaXCIpID8gZDNfdGltZV9mb3JtYXRJc29OYXRpdmUgOiBkM190aW1lX2Zvcm1hdElzbztcbiAgZnVuY3Rpb24gZDNfdGltZV9mb3JtYXRJc29OYXRpdmUoZGF0ZSkge1xuICAgIHJldHVybiBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gIH1cbiAgZDNfdGltZV9mb3JtYXRJc29OYXRpdmUucGFyc2UgPSBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKHN0cmluZyk7XG4gICAgcmV0dXJuIGlzTmFOKGRhdGUpID8gbnVsbCA6IGRhdGU7XG4gIH07XG4gIGQzX3RpbWVfZm9ybWF0SXNvTmF0aXZlLnRvU3RyaW5nID0gZDNfdGltZV9mb3JtYXRJc28udG9TdHJpbmc7XG4gIGQzLnRpbWUuc2Vjb25kID0gZDNfdGltZV9pbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgcmV0dXJuIG5ldyBkM190aW1lKE1hdGguZmxvb3IoZGF0ZSAvIDFlMykgKiAxZTMpO1xuICB9LCBmdW5jdGlvbihkYXRlLCBvZmZzZXQpIHtcbiAgICBkYXRlLnNldFRpbWUoZGF0ZS5nZXRUaW1lKCkgKyBNYXRoLmZsb29yKG9mZnNldCkgKiAxZTMpO1xuICB9LCBmdW5jdGlvbihkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0U2Vjb25kcygpO1xuICB9KTtcbiAgZDMudGltZS5zZWNvbmRzID0gZDMudGltZS5zZWNvbmQucmFuZ2U7XG4gIGQzLnRpbWUuc2Vjb25kcy51dGMgPSBkMy50aW1lLnNlY29uZC51dGMucmFuZ2U7XG4gIGQzLnRpbWUubWludXRlID0gZDNfdGltZV9pbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgcmV0dXJuIG5ldyBkM190aW1lKE1hdGguZmxvb3IoZGF0ZSAvIDZlNCkgKiA2ZTQpO1xuICB9LCBmdW5jdGlvbihkYXRlLCBvZmZzZXQpIHtcbiAgICBkYXRlLnNldFRpbWUoZGF0ZS5nZXRUaW1lKCkgKyBNYXRoLmZsb29yKG9mZnNldCkgKiA2ZTQpO1xuICB9LCBmdW5jdGlvbihkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0TWludXRlcygpO1xuICB9KTtcbiAgZDMudGltZS5taW51dGVzID0gZDMudGltZS5taW51dGUucmFuZ2U7XG4gIGQzLnRpbWUubWludXRlcy51dGMgPSBkMy50aW1lLm1pbnV0ZS51dGMucmFuZ2U7XG4gIGQzLnRpbWUuaG91ciA9IGQzX3RpbWVfaW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIHZhciB0aW1lem9uZSA9IGRhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKSAvIDYwO1xuICAgIHJldHVybiBuZXcgZDNfdGltZSgoTWF0aC5mbG9vcihkYXRlIC8gMzZlNSAtIHRpbWV6b25lKSArIHRpbWV6b25lKSAqIDM2ZTUpO1xuICB9LCBmdW5jdGlvbihkYXRlLCBvZmZzZXQpIHtcbiAgICBkYXRlLnNldFRpbWUoZGF0ZS5nZXRUaW1lKCkgKyBNYXRoLmZsb29yKG9mZnNldCkgKiAzNmU1KTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSkge1xuICAgIHJldHVybiBkYXRlLmdldEhvdXJzKCk7XG4gIH0pO1xuICBkMy50aW1lLmhvdXJzID0gZDMudGltZS5ob3VyLnJhbmdlO1xuICBkMy50aW1lLmhvdXJzLnV0YyA9IGQzLnRpbWUuaG91ci51dGMucmFuZ2U7XG4gIGQzLnRpbWUubW9udGggPSBkM190aW1lX2ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlID0gZDMudGltZS5kYXkoZGF0ZSk7XG4gICAgZGF0ZS5zZXREYXRlKDEpO1xuICAgIHJldHVybiBkYXRlO1xuICB9LCBmdW5jdGlvbihkYXRlLCBvZmZzZXQpIHtcbiAgICBkYXRlLnNldE1vbnRoKGRhdGUuZ2V0TW9udGgoKSArIG9mZnNldCk7XG4gIH0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgICByZXR1cm4gZGF0ZS5nZXRNb250aCgpO1xuICB9KTtcbiAgZDMudGltZS5tb250aHMgPSBkMy50aW1lLm1vbnRoLnJhbmdlO1xuICBkMy50aW1lLm1vbnRocy51dGMgPSBkMy50aW1lLm1vbnRoLnV0Yy5yYW5nZTtcbiAgZnVuY3Rpb24gZDNfdGltZV9zY2FsZShsaW5lYXIsIG1ldGhvZHMsIGZvcm1hdCkge1xuICAgIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICAgIHJldHVybiBsaW5lYXIoeCk7XG4gICAgfVxuICAgIHNjYWxlLmludmVydCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiBkM190aW1lX3NjYWxlRGF0ZShsaW5lYXIuaW52ZXJ0KHgpKTtcbiAgICB9O1xuICAgIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxpbmVhci5kb21haW4oKS5tYXAoZDNfdGltZV9zY2FsZURhdGUpO1xuICAgICAgbGluZWFyLmRvbWFpbih4KTtcbiAgICAgIHJldHVybiBzY2FsZTtcbiAgICB9O1xuICAgIHNjYWxlLm5pY2UgPSBmdW5jdGlvbihtKSB7XG4gICAgICByZXR1cm4gc2NhbGUuZG9tYWluKGQzX3NjYWxlX25pY2Uoc2NhbGUuZG9tYWluKCksIG0pKTtcbiAgICB9O1xuICAgIHNjYWxlLnRpY2tzID0gZnVuY3Rpb24obSwgaykge1xuICAgICAgdmFyIGV4dGVudCA9IGQzX3NjYWxlRXh0ZW50KHNjYWxlLmRvbWFpbigpKTtcbiAgICAgIGlmICh0eXBlb2YgbSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHZhciBzcGFuID0gZXh0ZW50WzFdIC0gZXh0ZW50WzBdLCB0YXJnZXQgPSBzcGFuIC8gbSwgaSA9IGQzLmJpc2VjdChkM190aW1lX3NjYWxlU3RlcHMsIHRhcmdldCk7XG4gICAgICAgIGlmIChpID09IGQzX3RpbWVfc2NhbGVTdGVwcy5sZW5ndGgpIHJldHVybiBtZXRob2RzLnllYXIoZXh0ZW50LCBtKTtcbiAgICAgICAgaWYgKCFpKSByZXR1cm4gbGluZWFyLnRpY2tzKG0pLm1hcChkM190aW1lX3NjYWxlRGF0ZSk7XG4gICAgICAgIGlmIChNYXRoLmxvZyh0YXJnZXQgLyBkM190aW1lX3NjYWxlU3RlcHNbaSAtIDFdKSA8IE1hdGgubG9nKGQzX3RpbWVfc2NhbGVTdGVwc1tpXSAvIHRhcmdldCkpIC0taTtcbiAgICAgICAgbSA9IG1ldGhvZHNbaV07XG4gICAgICAgIGsgPSBtWzFdO1xuICAgICAgICBtID0gbVswXS5yYW5nZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtKGV4dGVudFswXSwgbmV3IERhdGUoK2V4dGVudFsxXSArIDEpLCBrKTtcbiAgICB9O1xuICAgIHNjYWxlLnRpY2tGb3JtYXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgfTtcbiAgICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZDNfdGltZV9zY2FsZShsaW5lYXIuY29weSgpLCBtZXRob2RzLCBmb3JtYXQpO1xuICAgIH07XG4gICAgcmV0dXJuIGQzX3NjYWxlX2xpbmVhclJlYmluZChzY2FsZSwgbGluZWFyKTtcbiAgfVxuICBmdW5jdGlvbiBkM190aW1lX3NjYWxlRGF0ZSh0KSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHQpO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfc2NhbGVGb3JtYXQoZm9ybWF0cykge1xuICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICB2YXIgaSA9IGZvcm1hdHMubGVuZ3RoIC0gMSwgZiA9IGZvcm1hdHNbaV07XG4gICAgICB3aGlsZSAoIWZbMV0oZGF0ZSkpIGYgPSBmb3JtYXRzWy0taV07XG4gICAgICByZXR1cm4gZlswXShkYXRlKTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfc2NhbGVTZXRZZWFyKHkpIHtcbiAgICB2YXIgZCA9IG5ldyBEYXRlKHksIDAsIDEpO1xuICAgIGQuc2V0RnVsbFllYXIoeSk7XG4gICAgcmV0dXJuIGQ7XG4gIH1cbiAgZnVuY3Rpb24gZDNfdGltZV9zY2FsZUdldFllYXIoZCkge1xuICAgIHZhciB5ID0gZC5nZXRGdWxsWWVhcigpLCBkMCA9IGQzX3RpbWVfc2NhbGVTZXRZZWFyKHkpLCBkMSA9IGQzX3RpbWVfc2NhbGVTZXRZZWFyKHkgKyAxKTtcbiAgICByZXR1cm4geSArIChkIC0gZDApIC8gKGQxIC0gZDApO1xuICB9XG4gIHZhciBkM190aW1lX3NjYWxlU3RlcHMgPSBbIDFlMywgNWUzLCAxNWUzLCAzZTQsIDZlNCwgM2U1LCA5ZTUsIDE4ZTUsIDM2ZTUsIDEwOGU1LCAyMTZlNSwgNDMyZTUsIDg2NGU1LCAxNzI4ZTUsIDYwNDhlNSwgMjU5MmU2LCA3Nzc2ZTYsIDMxNTM2ZTYgXTtcbiAgdmFyIGQzX3RpbWVfc2NhbGVMb2NhbE1ldGhvZHMgPSBbIFsgZDMudGltZS5zZWNvbmQsIDEgXSwgWyBkMy50aW1lLnNlY29uZCwgNSBdLCBbIGQzLnRpbWUuc2Vjb25kLCAxNSBdLCBbIGQzLnRpbWUuc2Vjb25kLCAzMCBdLCBbIGQzLnRpbWUubWludXRlLCAxIF0sIFsgZDMudGltZS5taW51dGUsIDUgXSwgWyBkMy50aW1lLm1pbnV0ZSwgMTUgXSwgWyBkMy50aW1lLm1pbnV0ZSwgMzAgXSwgWyBkMy50aW1lLmhvdXIsIDEgXSwgWyBkMy50aW1lLmhvdXIsIDMgXSwgWyBkMy50aW1lLmhvdXIsIDYgXSwgWyBkMy50aW1lLmhvdXIsIDEyIF0sIFsgZDMudGltZS5kYXksIDEgXSwgWyBkMy50aW1lLmRheSwgMiBdLCBbIGQzLnRpbWUud2VlaywgMSBdLCBbIGQzLnRpbWUubW9udGgsIDEgXSwgWyBkMy50aW1lLm1vbnRoLCAzIF0sIFsgZDMudGltZS55ZWFyLCAxIF0gXTtcbiAgdmFyIGQzX3RpbWVfc2NhbGVMb2NhbEZvcm1hdHMgPSBbIFsgZDMudGltZS5mb3JtYXQoXCIlWVwiKSwgZDNfdHJ1ZSBdLCBbIGQzLnRpbWUuZm9ybWF0KFwiJUJcIiksIGZ1bmN0aW9uKGQpIHtcbiAgICByZXR1cm4gZC5nZXRNb250aCgpO1xuICB9IF0sIFsgZDMudGltZS5mb3JtYXQoXCIlYiAlZFwiKSwgZnVuY3Rpb24oZCkge1xuICAgIHJldHVybiBkLmdldERhdGUoKSAhPSAxO1xuICB9IF0sIFsgZDMudGltZS5mb3JtYXQoXCIlYSAlZFwiKSwgZnVuY3Rpb24oZCkge1xuICAgIHJldHVybiBkLmdldERheSgpICYmIGQuZ2V0RGF0ZSgpICE9IDE7XG4gIH0gXSwgWyBkMy50aW1lLmZvcm1hdChcIiVJICVwXCIpLCBmdW5jdGlvbihkKSB7XG4gICAgcmV0dXJuIGQuZ2V0SG91cnMoKTtcbiAgfSBdLCBbIGQzLnRpbWUuZm9ybWF0KFwiJUk6JU1cIiksIGZ1bmN0aW9uKGQpIHtcbiAgICByZXR1cm4gZC5nZXRNaW51dGVzKCk7XG4gIH0gXSwgWyBkMy50aW1lLmZvcm1hdChcIjolU1wiKSwgZnVuY3Rpb24oZCkge1xuICAgIHJldHVybiBkLmdldFNlY29uZHMoKTtcbiAgfSBdLCBbIGQzLnRpbWUuZm9ybWF0KFwiLiVMXCIpLCBmdW5jdGlvbihkKSB7XG4gICAgcmV0dXJuIGQuZ2V0TWlsbGlzZWNvbmRzKCk7XG4gIH0gXSBdO1xuICB2YXIgZDNfdGltZV9zY2FsZUxpbmVhciA9IGQzLnNjYWxlLmxpbmVhcigpLCBkM190aW1lX3NjYWxlTG9jYWxGb3JtYXQgPSBkM190aW1lX3NjYWxlRm9ybWF0KGQzX3RpbWVfc2NhbGVMb2NhbEZvcm1hdHMpO1xuICBkM190aW1lX3NjYWxlTG9jYWxNZXRob2RzLnllYXIgPSBmdW5jdGlvbihleHRlbnQsIG0pIHtcbiAgICByZXR1cm4gZDNfdGltZV9zY2FsZUxpbmVhci5kb21haW4oZXh0ZW50Lm1hcChkM190aW1lX3NjYWxlR2V0WWVhcikpLnRpY2tzKG0pLm1hcChkM190aW1lX3NjYWxlU2V0WWVhcik7XG4gIH07XG4gIGQzLnRpbWUuc2NhbGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZDNfdGltZV9zY2FsZShkMy5zY2FsZS5saW5lYXIoKSwgZDNfdGltZV9zY2FsZUxvY2FsTWV0aG9kcywgZDNfdGltZV9zY2FsZUxvY2FsRm9ybWF0KTtcbiAgfTtcbiAgdmFyIGQzX3RpbWVfc2NhbGVVVENNZXRob2RzID0gZDNfdGltZV9zY2FsZUxvY2FsTWV0aG9kcy5tYXAoZnVuY3Rpb24obSkge1xuICAgIHJldHVybiBbIG1bMF0udXRjLCBtWzFdIF07XG4gIH0pO1xuICB2YXIgZDNfdGltZV9zY2FsZVVUQ0Zvcm1hdHMgPSBbIFsgZDMudGltZS5mb3JtYXQudXRjKFwiJVlcIiksIGQzX3RydWUgXSwgWyBkMy50aW1lLmZvcm1hdC51dGMoXCIlQlwiKSwgZnVuY3Rpb24oZCkge1xuICAgIHJldHVybiBkLmdldFVUQ01vbnRoKCk7XG4gIH0gXSwgWyBkMy50aW1lLmZvcm1hdC51dGMoXCIlYiAlZFwiKSwgZnVuY3Rpb24oZCkge1xuICAgIHJldHVybiBkLmdldFVUQ0RhdGUoKSAhPSAxO1xuICB9IF0sIFsgZDMudGltZS5mb3JtYXQudXRjKFwiJWEgJWRcIiksIGZ1bmN0aW9uKGQpIHtcbiAgICByZXR1cm4gZC5nZXRVVENEYXkoKSAmJiBkLmdldFVUQ0RhdGUoKSAhPSAxO1xuICB9IF0sIFsgZDMudGltZS5mb3JtYXQudXRjKFwiJUkgJXBcIiksIGZ1bmN0aW9uKGQpIHtcbiAgICByZXR1cm4gZC5nZXRVVENIb3VycygpO1xuICB9IF0sIFsgZDMudGltZS5mb3JtYXQudXRjKFwiJUk6JU1cIiksIGZ1bmN0aW9uKGQpIHtcbiAgICByZXR1cm4gZC5nZXRVVENNaW51dGVzKCk7XG4gIH0gXSwgWyBkMy50aW1lLmZvcm1hdC51dGMoXCI6JVNcIiksIGZ1bmN0aW9uKGQpIHtcbiAgICByZXR1cm4gZC5nZXRVVENTZWNvbmRzKCk7XG4gIH0gXSwgWyBkMy50aW1lLmZvcm1hdC51dGMoXCIuJUxcIiksIGZ1bmN0aW9uKGQpIHtcbiAgICByZXR1cm4gZC5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgfSBdIF07XG4gIHZhciBkM190aW1lX3NjYWxlVVRDRm9ybWF0ID0gZDNfdGltZV9zY2FsZUZvcm1hdChkM190aW1lX3NjYWxlVVRDRm9ybWF0cyk7XG4gIGZ1bmN0aW9uIGQzX3RpbWVfc2NhbGVVVENTZXRZZWFyKHkpIHtcbiAgICB2YXIgZCA9IG5ldyBEYXRlKERhdGUuVVRDKHksIDAsIDEpKTtcbiAgICBkLnNldFVUQ0Z1bGxZZWFyKHkpO1xuICAgIHJldHVybiBkO1xuICB9XG4gIGZ1bmN0aW9uIGQzX3RpbWVfc2NhbGVVVENHZXRZZWFyKGQpIHtcbiAgICB2YXIgeSA9IGQuZ2V0VVRDRnVsbFllYXIoKSwgZDAgPSBkM190aW1lX3NjYWxlVVRDU2V0WWVhcih5KSwgZDEgPSBkM190aW1lX3NjYWxlVVRDU2V0WWVhcih5ICsgMSk7XG4gICAgcmV0dXJuIHkgKyAoZCAtIGQwKSAvIChkMSAtIGQwKTtcbiAgfVxuICBkM190aW1lX3NjYWxlVVRDTWV0aG9kcy55ZWFyID0gZnVuY3Rpb24oZXh0ZW50LCBtKSB7XG4gICAgcmV0dXJuIGQzX3RpbWVfc2NhbGVMaW5lYXIuZG9tYWluKGV4dGVudC5tYXAoZDNfdGltZV9zY2FsZVVUQ0dldFllYXIpKS50aWNrcyhtKS5tYXAoZDNfdGltZV9zY2FsZVVUQ1NldFllYXIpO1xuICB9O1xuICBkMy50aW1lLnNjYWxlLnV0YyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkM190aW1lX3NjYWxlKGQzLnNjYWxlLmxpbmVhcigpLCBkM190aW1lX3NjYWxlVVRDTWV0aG9kcywgZDNfdGltZV9zY2FsZVVUQ0Zvcm1hdCk7XG4gIH07XG4gIGQzLnRleHQgPSBkM194aHJUeXBlKGZ1bmN0aW9uKHJlcXVlc3QpIHtcbiAgICByZXR1cm4gcmVxdWVzdC5yZXNwb25zZVRleHQ7XG4gIH0pO1xuICBkMy5qc29uID0gZnVuY3Rpb24odXJsLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBkM194aHIodXJsLCBcImFwcGxpY2F0aW9uL2pzb25cIiwgZDNfanNvbiwgY2FsbGJhY2spO1xuICB9O1xuICBmdW5jdGlvbiBkM19qc29uKHJlcXVlc3QpIHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyZXF1ZXN0LnJlc3BvbnNlVGV4dCk7XG4gIH1cbiAgZDMuaHRtbCA9IGZ1bmN0aW9uKHVybCwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gZDNfeGhyKHVybCwgXCJ0ZXh0L2h0bWxcIiwgZDNfaHRtbCwgY2FsbGJhY2spO1xuICB9O1xuICBmdW5jdGlvbiBkM19odG1sKHJlcXVlc3QpIHtcbiAgICB2YXIgcmFuZ2UgPSBkM19kb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNlbGVjdE5vZGUoZDNfZG9jdW1lbnQuYm9keSk7XG4gICAgcmV0dXJuIHJhbmdlLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChyZXF1ZXN0LnJlc3BvbnNlVGV4dCk7XG4gIH1cbiAgZDMueG1sID0gZDNfeGhyVHlwZShmdW5jdGlvbihyZXF1ZXN0KSB7XG4gICAgcmV0dXJuIHJlcXVlc3QucmVzcG9uc2VYTUw7XG4gIH0pO1xuICByZXR1cm4gZDM7XG59KCk7Il19 | |
;require=(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({"hypotrochoid":[function(require,module,exports){ | |
module.exports=require('KuXONk'); | |
},{}],"KuXONk":[function(require,module,exports){ | |
var cos = Math.cos | |
, sin = Math.sin | |
module.exports = hypotrochoid | |
function hypotrochoid(d, radii, t, output) { | |
output = output || [] | |
var x = 0 | |
, y = 0 | |
, i = 0 | |
, l = radii.length - 1 | |
, a | |
, b | |
var cosT = cos(t) | |
, sinT = sin(t) | |
for (; i < l; i += 1) { | |
b = radii[i+1] | |
a = radii[i] - b | |
x += a * cosT + d * cos(a / b * t) | |
y += a * sinT - d * sin(a / b * t) | |
} | |
output[0] = x | |
output[1] = y | |
return output | |
} | |
},{}]},{},[]) | |
//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvdG1wL2h5cG90cm9jaG9pZDExMzY2LTExMjgxLTY3NHRnYy9ub2RlX21vZHVsZXMvaHlwb3Ryb2Nob2lkL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGNvcyA9IE1hdGguY29zXG4gICwgc2luID0gTWF0aC5zaW5cblxubW9kdWxlLmV4cG9ydHMgPSBoeXBvdHJvY2hvaWRcblxuZnVuY3Rpb24gaHlwb3Ryb2Nob2lkKGQsIHJhZGlpLCB0LCBvdXRwdXQpIHtcbiAgb3V0cHV0ID0gb3V0cHV0IHx8IFtdXG5cbiAgdmFyIHggPSAwXG4gICAgLCB5ID0gMFxuICAgICwgaSA9IDBcbiAgICAsIGwgPSByYWRpaS5sZW5ndGggLSAxXG4gICAgLCBhXG4gICAgLCBiXG5cbiAgdmFyIGNvc1QgPSBjb3ModClcbiAgICAsIHNpblQgPSBzaW4odClcblxuICBmb3IgKDsgaSA8IGw7IGkgKz0gMSkge1xuICAgIGIgPSByYWRpaVtpKzFdXG4gICAgYSA9IHJhZGlpW2ldIC0gYlxuICAgIHggKz0gYSAqIGNvc1QgKyBkICogY29zKGEgLyBiICogdClcbiAgICB5ICs9IGEgKiBzaW5UIC0gZCAqIHNpbihhIC8gYiAqIHQpXG4gIH1cblxuICBvdXRwdXRbMF0gPSB4XG4gIG91dHB1dFsxXSA9IHlcblxuICByZXR1cm4gb3V0cHV0XG59XG4iXX0= | |
;var hypotrochoid = require('hypotrochoid') | |
, d3 = require('d3') | |
var ranged = range(0, 500, 1) | |
var points = ranged.map(function(t) { | |
return hypotrochoid(70, [50, 70, 82.5], t) | |
}) | |
function range(start, end, inc) { | |
var a = [] | |
for (var i = start; i < end; i += inc) a[a.length] = i | |
return a | |
} | |
var line = d3.svg.line() | |
.interpolate('basis') | |
.x(function(d) { return d[0] }) | |
.y(function(d) { return d[1] }) | |
var svg = d3.select('body').append('svg') | |
.attr('width', 512) | |
.attr('height', 512) | |
var stamp = svg.append('g') | |
.attr('transform', 'translate(256,256)') | |
var path = stamp.append('path') | |
.attr('d', line(points)) | |
.attr('stroke', '#000') | |
.attr('fill', 'none') | |
setInterval(function() { | |
var a = Math.random() * 190 + 10 | |
var b = Math.random() * 190 + 10 | |
var c = Math.random() * 190 + 10 | |
var h = 30 + Math.random() * 60 | |
ranged.forEach(function(t, i) { | |
points[i] = hypotrochoid(h, [a, b, c], t) | |
}) | |
path.transition() | |
.duration(2500) | |
.attr('d', line(points)) | |
}, 2500) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment