Skip to content

Instantly share code, notes, and snippets.

@saukap
Created October 14, 2015 07:37
Show Gist options
  • Save saukap/a607d619df3dd73f2882 to your computer and use it in GitHub Desktop.
Save saukap/a607d619df3dd73f2882 to your computer and use it in GitHub Desktop.
vega datalib.js for generating externs
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.dl = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
},{}],2:[function(require,module,exports){
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
factory((global.dsv = {}));
}(this, function (exports) { 'use strict';
var dsv = function(delimiter) {
var reFormat = new RegExp("[\"" + delimiter + "\n]"),
delimiterCode = delimiter.charCodeAt(0);
function parse(text, f) {
var o;
return 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;
});
}
function parseRows(text, f) {
var EOL = {}, // sentinel value for end-of-line
EOF = {}, // sentinel value for end-of-file
rows = [], // output rows
N = text.length,
I = 0, // current character index
n = 0, // the current line number
t, // the current token
eol; // is the current token followed by EOL?
function token() {
if (I >= N) return EOF; // special case: end of file
if (eol) return eol = false, EOL; // special case: end of line
// special case: quotes
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.slice(j + 1, i).replace(/""/g, "\"");
}
// common case: find next delimiter or newline
while (I < N) {
var c = text.charCodeAt(I++), k = 1;
if (c === 10) eol = true; // \n
else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n
else if (c !== delimiterCode) continue;
return text.slice(j, I - k);
}
// special case: last token before EOF
return text.slice(j);
}
while ((t = token()) !== EOF) {
var a = [];
while (t !== EOL && t !== EOF) {
a.push(t);
t = token();
}
if (f && (a = f(a, n++)) == null) continue;
rows.push(a);
}
return rows;
}
function format(rows) {
if (Array.isArray(rows[0])) return formatRows(rows); // deprecated; use formatRows
var fieldSet = Object.create(null), fields = [];
// Compute unique fields in order of discovery.
rows.forEach(function(row) {
for (var field in row) {
if (!((field += "") in fieldSet)) {
fields.push(fieldSet[field] = 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");
}
function formatRows(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 {
parse: parse,
parseRows: parseRows,
format: format,
formatRows: formatRows
};
}
exports.csv = dsv(",");
exports.tsv = dsv("\t");
exports.dsv = dsv;
}));
},{}],3:[function(require,module,exports){
if (typeof Map === "undefined") {
Map = function() { this.clear(); };
Map.prototype = {
set: function(k, v) { this._[k] = v; return this; },
get: function(k) { return this._[k]; },
has: function(k) { return k in this._; },
delete: function(k) { return k in this._ && delete this._[k]; },
clear: function() { this._ = Object.create(null); },
get size() { var n = 0; for (var k in this._) ++n; return n; },
forEach: function(c) { for (var k in this._) c(this._[k], k, this); }
};
} else (function() {
var m = new Map;
if (m.set(0, 0) !== m) {
m = m.set;
Map.prototype.set = function() { m.apply(this, arguments); return this; };
}
})();
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
factory((global.format = {}));
}(this, function (exports) { 'use strict';
var zhCn = {
decimal: ".",
thousands: ",",
grouping: [3],
currency: ["¥", ""]
};
var ruRu = {
decimal: ",",
thousands: "\xa0",
grouping: [3],
currency: ["", "\xa0руб."]
};
var ptBr = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["R$", ""]
};
var plPl = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["", "zł"]
};
var nlNl = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["€\xa0", ""]
};
var mkMk = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["", "\xa0ден."]
};
var itIt = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["€", ""]
};
var heIl = {
decimal: ".",
thousands: ",",
grouping: [3],
currency: ["₪", ""]
};
var frFr = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["", "\xa0€"]
};
var frCa = {
decimal: ",",
thousands: "\xa0",
grouping: [3],
currency: ["", "$"]
};
var fiFi = {
decimal: ",",
thousands: "\xa0",
grouping: [3],
currency: ["", "\xa0€"]
};
var esEs = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["", "\xa0€"]
};
var enUs = {
decimal: ".",
thousands: ",",
grouping: [3],
currency: ["$", ""]
};
var enGb = {
decimal: ".",
thousands: ",",
grouping: [3],
currency: ["£", ""]
};
var enCa = {
decimal: ".",
thousands: ",",
grouping: [3],
currency: ["$", ""]
};
var deDe = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["", "\xa0€"]
};
var caEs = {
decimal: ",",
thousands: ".",
grouping: [3],
currency: ["", "\xa0€"]
};
// Computes the decimal coefficient and exponent of the specified number x with
// significant digits p, where x is positive and p is in [1, 21] or undefined.
// For example, formatDecimal(1.23) returns ["123", 0].
function formatDecimal(x, p) {
if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
var i, coefficient = x.slice(0, i);
// The string returned by toExponential either has the form \d\.\d+e[-+]\d+
// (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
return [
coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
+x.slice(i + 1)
];
}
function exponent(x) {
return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
}
var prefixExponent;
function formatPrefixAuto(x, p) {
var d = formatDecimal(x, p);
if (!d) return x + "";
var coefficient = d[0],
exponent = d[1],
i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
n = coefficient.length;
return i === n ? coefficient
: i > n ? coefficient + new Array(i - n + 1).join("0")
: i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
: "0." + new Array(1 - i).join("0") + formatDecimal(x, p + i - 1)[0]; // less than 1y!
}
function formatRounded(x, p) {
var d = formatDecimal(x, p);
if (!d) return x + "";
var coefficient = d[0],
exponent = d[1];
return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
: coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
: coefficient + new Array(exponent - coefficient.length + 2).join("0");
}
function formatDefault(x, p) {
x = x.toPrecision(p);
out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
switch (x[i]) {
case ".": i0 = i1 = i; break;
case "0": if (i0 === 0) i0 = i; i1 = i; break;
case "e": break out;
default: if (i0 > 0) i0 = 0; break;
}
}
return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
}
var formatTypes = {
"": formatDefault,
"%": function(x, p) { return (x * 100).toFixed(p); },
"b": function(x) { return Math.round(x).toString(2); },
"c": function(x) { return x + ""; },
"d": function(x) { return Math.round(x).toString(10); },
"e": function(x, p) { return x.toExponential(p); },
"f": function(x, p) { return x.toFixed(p); },
"g": function(x, p) { return x.toPrecision(p); },
"o": function(x) { return Math.round(x).toString(8); },
"p": function(x, p) { return formatRounded(x * 100, p); },
"r": formatRounded,
"s": formatPrefixAuto,
"X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
"x": function(x) { return Math.round(x).toString(16); }
};
// [[fill]align][sign][symbol][0][width][,][.precision][type]
var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
function formatSpecifier(specifier) {
return new FormatSpecifier(specifier);
}
function FormatSpecifier(specifier) {
if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
var match,
fill = match[1] || " ",
align = match[2] || ">",
sign = match[3] || "-",
symbol = match[4] || "",
zero = !!match[5],
width = match[6] && +match[6],
comma = !!match[7],
precision = match[8] && +match[8].slice(1),
type = match[9] || "";
// The "n" type is an alias for ",g".
if (type === "n") comma = true, type = "g";
// Map invalid types to the default format.
else if (!formatTypes[type]) type = "";
// If zero fill is specified, padding goes after sign and before digits.
if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
this.fill = fill;
this.align = align;
this.sign = sign;
this.symbol = symbol;
this.zero = zero;
this.width = width;
this.comma = comma;
this.precision = precision;
this.type = type;
}
FormatSpecifier.prototype.toString = function() {
return this.fill
+ this.align
+ this.sign
+ this.symbol
+ (this.zero ? "0" : "")
+ (this.width == null ? "" : Math.max(1, this.width | 0))
+ (this.comma ? "," : "")
+ (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
+ this.type;
};
function formatGroup(grouping, thousands) {
return function(value, width) {
var i = value.length,
t = [],
j = 0,
g = grouping[0],
length = 0;
while (i > 0 && g > 0) {
if (length + g + 1 > width) g = Math.max(1, width - length);
t.push(value.substring(i -= g, i + g));
if ((length += g + 1) > width) break;
g = grouping[j = (j + 1) % grouping.length];
}
return t.reverse().join(thousands);
};
}
var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
function identity(x) {
return x;
}
function locale(locale) {
var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity,
currency = locale.currency,
decimal = locale.decimal;
function format(specifier) {
specifier = formatSpecifier(specifier);
var fill = specifier.fill,
align = specifier.align,
sign = specifier.sign,
symbol = specifier.symbol,
zero = specifier.zero,
width = specifier.width,
comma = specifier.comma,
precision = specifier.precision,
type = specifier.type;
// Compute the prefix and suffix.
// For SI-prefix, the suffix is lazily computed.
var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : "";
// What format function should we use?
// Is this an integer type?
// Can this type generate exponential notation?
var formatType = formatTypes[type],
maybeSuffix = !type || /[defgprs%]/.test(type);
// Set the default precision if not specified,
// or clamp the specified precision to the supported range.
// For significant precision, it must be in [1, 21].
// For fixed precision, it must be in [0, 20].
precision = precision == null ? (type ? 6 : 12)
: /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
: Math.max(0, Math.min(20, precision));
return function(value) {
var valuePrefix = prefix,
valueSuffix = suffix;
if (type === "c") {
valueSuffix = formatType(value) + valueSuffix;
value = "";
} else {
value = +value;
// Convert negative to positive, and compute the prefix.
// Note that -0 is not less than 0, but 1 / -0 is!
var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true);
// Perform the initial formatting.
value = formatType(value, precision);
// Compute the prefix and suffix.
valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
// Break the formatted value into the integer “value” part that can be
// grouped, and fractional or exponential “suffix” part that is not.
if (maybeSuffix) {
var i = -1, n = value.length, c;
while (++i < n) {
if (c = value.charCodeAt(i), 48 > c || c > 57) {
valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
value = value.slice(0, i);
break;
}
}
}
}
// If the fill character is not "0", grouping is applied before padding.
if (comma && !zero) value = group(value, Infinity);
// Compute the padding.
var length = valuePrefix.length + value.length + valueSuffix.length,
padding = length < width ? new Array(width - length + 1).join(fill) : "";
// If the fill character is "0", grouping is applied after padding.
if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
// Reconstruct the final output based on the desired alignment.
switch (align) {
case "<": return valuePrefix + value + valueSuffix + padding;
case "=": return valuePrefix + padding + value + valueSuffix;
case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);
}
return padding + valuePrefix + value + valueSuffix;
};
}
function formatPrefix(specifier, value) {
var f = format((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,
k = Math.pow(10, -e),
prefix = prefixes[8 + e / 3];
return function(value) {
return f(k * value) + prefix;
};
}
return {
format: format,
formatPrefix: formatPrefix
};
}
function precisionRound(step, max) {
return Math.max(0, exponent(Math.abs(max)) - exponent(Math.abs(step))) + 1;
}
function precisionPrefix(step, value) {
return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));
}
function precisionFixed(step) {
return Math.max(0, -exponent(Math.abs(step)));
}
var localeDefinitions = (new Map)
.set("ca-ES", caEs)
.set("de-DE", deDe)
.set("en-CA", enCa)
.set("en-GB", enGb)
.set("en-US", enUs)
.set("es-ES", esEs)
.set("fi-FI", fiFi)
.set("fr-CA", frCa)
.set("fr-FR", frFr)
.set("he-IL", heIl)
.set("it-IT", itIt)
.set("mk-MK", mkMk)
.set("nl-NL", nlNl)
.set("pl-PL", plPl)
.set("pt-BR", ptBr)
.set("ru-RU", ruRu)
.set("zh-CN", zhCn);
var defaultLocale = locale(enUs);
exports.format = defaultLocale.format;
exports.formatPrefix = defaultLocale.formatPrefix;
function localeFormat(definition) {
if (typeof definition === "string") {
definition = localeDefinitions.get(definition);
if (!definition) return null;
}
return locale(definition);
}
;
exports.localeFormat = localeFormat;
exports.formatSpecifier = formatSpecifier;
exports.precisionFixed = precisionFixed;
exports.precisionPrefix = precisionPrefix;
exports.precisionRound = precisionRound;
}));
},{}],4:[function(require,module,exports){
if (typeof Map === "undefined") {
Map = function() { this.clear(); };
Map.prototype = {
set: function(k, v) { this._[k] = v; return this; },
get: function(k) { return this._[k]; },
has: function(k) { return k in this._; },
delete: function(k) { return k in this._ && delete this._[k]; },
clear: function() { this._ = Object.create(null); },
get size() { var n = 0; for (var k in this._) ++n; return n; },
forEach: function(c) { for (var k in this._) c(this._[k], k, this); }
};
} else (function() {
var m = new Map;
if (m.set(0, 0) !== m) {
m = m.set;
Map.prototype.set = function() { m.apply(this, arguments); return this; };
}
})();
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
factory((global.timeFormat = {}));
}(this, function (exports) { 'use strict';
var zhCn = {
dateTime: "%a %b %e %X %Y",
date: "%Y/%-m/%-d",
time: "%H:%M:%S",
periods: ["上午", "下午"],
days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
shortDays: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
shortMonths: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
};
var ruRu = {
dateTime: "%A, %e %B %Y г. %X",
date: "%d.%m.%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"],
shortDays: ["вс", "пн", "вт", "ср", "чт", "пт", "сб"],
months: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"],
shortMonths: ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"]
};
var ptBr = {
dateTime: "%A, %e de %B de %Y. %X",
date: "%d/%m/%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"],
shortDays: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"],
months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
shortMonths: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"]
};
var plPl = {
dateTime: "%A, %e %B %Y, %X",
date: "%d/%m/%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"], // unused
days: ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"],
shortDays: ["Niedz.", "Pon.", "Wt.", "Śr.", "Czw.", "Pt.", "Sob."],
months: ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"],
shortMonths: ["Stycz.", "Luty", "Marz.", "Kwie.", "Maj", "Czerw.", "Lipc.", "Sierp.", "Wrz.", "Paźdz.", "Listop.", "Grudz."]/* In Polish language abbraviated months are not commonly used so there is a dispute about the proper abbraviations. */
};
var nlNl = {
dateTime: "%a %e %B %Y %T",
date: "%d-%m-%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"], // unused
days: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"],
shortDays: ["zo", "ma", "di", "wo", "do", "vr", "za"],
months: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"],
shortMonths: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
};
var mkMk = {
dateTime: "%A, %e %B %Y г. %X",
date: "%d.%m.%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["недела", "понеделник", "вторник", "среда", "четврток", "петок", "сабота"],
shortDays: ["нед", "пон", "вто", "сре", "чет", "пет", "саб"],
months: ["јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"],
shortMonths: ["јан", "фев", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "ное", "дек"]
};
var itIt = {
dateTime: "%A %e %B %Y, %X",
date: "%d/%m/%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"], // unused
days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"],
shortDays: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"],
months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"],
shortMonths: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"]
};
var heIl = {
dateTime: "%A, %e ב%B %Y %X",
date: "%d.%m.%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת"],
shortDays: ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"],
months: ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"],
shortMonths: ["ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳"]
};
var frFr = {
dateTime: "%A, le %e %B %Y, %X",
date: "%d/%m/%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"], // unused
days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
shortDays: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
shortMonths: ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."]
};
var frCa = {
dateTime: "%a %e %b %Y %X",
date: "%Y-%m-%d",
time: "%H:%M:%S",
periods: ["", ""],
days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
shortDays: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"],
months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
shortMonths: ["jan", "fév", "mar", "avr", "mai", "jui", "jul", "aoû", "sep", "oct", "nov", "déc"]
};
var fiFi = {
dateTime: "%A, %-d. %Bta %Y klo %X",
date: "%-d.%-m.%Y",
time: "%H:%M:%S",
periods: ["a.m.", "p.m."],
days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"],
shortDays: ["Su", "Ma", "Ti", "Ke", "To", "Pe", "La"],
months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"],
shortMonths: ["Tammi", "Helmi", "Maalis", "Huhti", "Touko", "Kesä", "Heinä", "Elo", "Syys", "Loka", "Marras", "Joulu"]
};
var esEs = {
dateTime: "%A, %e de %B de %Y, %X",
date: "%d/%m/%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"],
shortDays: ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"],
months: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"],
shortMonths: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"]
};
var enUs = {
dateTime: "%a %b %e %X %Y",
date: "%m/%d/%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
};
var enGb = {
dateTime: "%a %e %b %X %Y",
date: "%d/%m/%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
};
var enCa = {
dateTime: "%a %b %e %X %Y",
date: "%Y-%m-%d",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
};
var deDe = {
dateTime: "%A, der %e. %B %Y, %X",
date: "%d.%m.%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"], // unused
days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
};
var caEs = {
dateTime: "%A, %e de %B de %Y, %X",
date: "%d/%m/%Y",
time: "%H:%M:%S",
periods: ["AM", "PM"],
days: ["diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte"],
shortDays: ["dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds."],
months: ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"],
shortMonths: ["gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des."]
};
var t0 = new Date;
var t1 = new Date;
function newInterval(floori, offseti, count) {
function interval(date) {
return floori(date = new Date(+date)), date;
}
interval.floor = interval;
interval.round = function(date) {
var d0 = new Date(+date),
d1 = new Date(date - 1);
floori(d0), floori(d1), offseti(d1, 1);
return date - d0 < d1 - date ? d0 : d1;
};
interval.ceil = function(date) {
return floori(date = new Date(date - 1)), offseti(date, 1), date;
};
interval.offset = function(date, step) {
return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
};
interval.range = function(start, stop, step) {
var range = [];
start = new Date(start - 1);
stop = new Date(+stop);
step = step == null ? 1 : Math.floor(step);
if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
offseti(start, 1), floori(start);
if (start < stop) range.push(new Date(+start));
while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start));
return range;
};
interval.filter = function(test) {
return newInterval(function(date) {
while (floori(date), !test(date)) date.setTime(date - 1);
}, function(date, step) {
while (--step >= 0) while (offseti(date, 1), !test(date));
});
};
if (count) interval.count = function(start, end) {
t0.setTime(+start), t1.setTime(+end);
floori(t0), floori(t1);
return Math.floor(count(t0, t1));
};
return interval;
}
var day = newInterval(function(date) {
date.setHours(0, 0, 0, 0);
}, function(date, step) {
date.setDate(date.getDate() + step);
}, function(start, end) {
return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5;
});
function weekday(i) {
return newInterval(function(date) {
date.setHours(0, 0, 0, 0);
date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
}, function(date, step) {
date.setDate(date.getDate() + step * 7);
}, function(start, end) {
return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5;
});
}
var sunday = weekday(0);
var monday = weekday(1);
var year = newInterval(function(date) {
date.setHours(0, 0, 0, 0);
date.setMonth(0, 1);
}, function(date, step) {
date.setFullYear(date.getFullYear() + step);
}, function(start, end) {
return end.getFullYear() - start.getFullYear();
});
var utcDay = newInterval(function(date) {
date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
date.setUTCDate(date.getUTCDate() + step);
}, function(start, end) {
return (end - start) / 864e5;
});
function utcWeekday(i) {
return newInterval(function(date) {
date.setUTCHours(0, 0, 0, 0);
date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
}, function(date, step) {
date.setUTCDate(date.getUTCDate() + step * 7);
}, function(start, end) {
return (end - start) / 6048e5;
});
}
var utcSunday = utcWeekday(0);
var utcMonday = utcWeekday(1);
var utcYear = newInterval(function(date) {
date.setUTCHours(0, 0, 0, 0);
date.setUTCMonth(0, 1);
}, function(date, step) {
date.setUTCFullYear(date.getUTCFullYear() + step);
}, function(start, end) {
return end.getUTCFullYear() - start.getUTCFullYear();
});
function localDate(d) {
if (0 <= d.y && d.y < 100) {
var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
date.setFullYear(d.y);
return date;
}
return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
}
function utcDate(d) {
if (0 <= d.y && d.y < 100) {
var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
date.setUTCFullYear(d.y);
return date;
}
return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
}
function newYear(y) {
return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
}
function locale(locale) {
var locale_dateTime = locale.dateTime,
locale_date = locale.date,
locale_time = locale.time,
locale_periods = locale.periods,
locale_weekdays = locale.days,
locale_shortWeekdays = locale.shortDays,
locale_months = locale.months,
locale_shortMonths = locale.shortMonths;
var periodLookup = formatLookup(locale_periods),
weekdayRe = formatRe(locale_weekdays),
weekdayLookup = formatLookup(locale_weekdays),
shortWeekdayRe = formatRe(locale_shortWeekdays),
shortWeekdayLookup = formatLookup(locale_shortWeekdays),
monthRe = formatRe(locale_months),
monthLookup = formatLookup(locale_months),
shortMonthRe = formatRe(locale_shortMonths),
shortMonthLookup = formatLookup(locale_shortMonths);
var formats = {
"a": formatShortWeekday,
"A": formatWeekday,
"b": formatShortMonth,
"B": formatMonth,
"c": null,
"d": formatDayOfMonth,
"e": formatDayOfMonth,
"H": formatHour24,
"I": formatHour12,
"j": formatDayOfYear,
"L": formatMilliseconds,
"m": formatMonthNumber,
"M": formatMinutes,
"p": formatPeriod,
"S": formatSeconds,
"U": formatWeekNumberSunday,
"w": formatWeekdayNumber,
"W": formatWeekNumberMonday,
"x": null,
"X": null,
"y": formatYear,
"Y": formatFullYear,
"Z": formatZone,
"%": formatLiteralPercent
};
var utcFormats = {
"a": formatUTCShortWeekday,
"A": formatUTCWeekday,
"b": formatUTCShortMonth,
"B": formatUTCMonth,
"c": null,
"d": formatUTCDayOfMonth,
"e": formatUTCDayOfMonth,
"H": formatUTCHour24,
"I": formatUTCHour12,
"j": formatUTCDayOfYear,
"L": formatUTCMilliseconds,
"m": formatUTCMonthNumber,
"M": formatUTCMinutes,
"p": formatUTCPeriod,
"S": formatUTCSeconds,
"U": formatUTCWeekNumberSunday,
"w": formatUTCWeekdayNumber,
"W": formatUTCWeekNumberMonday,
"x": null,
"X": null,
"y": formatUTCYear,
"Y": formatUTCFullYear,
"Z": formatUTCZone,
"%": formatLiteralPercent
};
var parses = {
"a": parseShortWeekday,
"A": parseWeekday,
"b": parseShortMonth,
"B": parseMonth,
"c": parseLocaleDateTime,
"d": parseDayOfMonth,
"e": parseDayOfMonth,
"H": parseHour24,
"I": parseHour24,
"j": parseDayOfYear,
"L": parseMilliseconds,
"m": parseMonthNumber,
"M": parseMinutes,
"p": parsePeriod,
"S": parseSeconds,
"U": parseWeekNumberSunday,
"w": parseWeekdayNumber,
"W": parseWeekNumberMonday,
"x": parseLocaleDate,
"X": parseLocaleTime,
"y": parseYear,
"Y": parseFullYear,
"Z": parseZone,
"%": parseLiteralPercent
};
// These recursive directive definitions must be deferred.
formats.x = newFormat(locale_date, formats);
formats.X = newFormat(locale_time, formats);
formats.c = newFormat(locale_dateTime, formats);
utcFormats.x = newFormat(locale_date, utcFormats);
utcFormats.X = newFormat(locale_time, utcFormats);
utcFormats.c = newFormat(locale_dateTime, utcFormats);
function newFormat(specifier, formats) {
return function(date) {
var string = [],
i = -1,
j = 0,
n = specifier.length,
c,
pad,
format;
while (++i < n) {
if (specifier.charCodeAt(i) === 37) {
string.push(specifier.slice(j, i));
if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
if (format = formats[c]) c = format(date, pad == null ? (c === "e" ? " " : "0") : pad);
string.push(c);
j = i + 1;
}
}
string.push(specifier.slice(j, i));
return string.join("");
};
}
function newParse(specifier, newDate) {
return function(string) {
var d = newYear(1900),
i = parseSpecifier(d, specifier, string, 0);
if (i != string.length) return null;
// The am-pm flag is 0 for AM, and 1 for PM.
if ("p" in d) d.H = d.H % 12 + d.p * 12;
// If a time zone is specified, all fields are interpreted as UTC and then
// offset according to the specified time zone.
if ("Z" in d) {
if ("w" in d && ("W" in d || "U" in d)) {
var day = utcDate(newYear(d.y)).getUTCDay();
if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day;
d.m = 0;
d.d = d.w + d.U * 7 - (day + 6) % 7;
}
d.H += d.Z / 100 | 0;
d.M += d.Z % 100;
return utcDate(d);
}
// Otherwise, all fields are in local time.
if ("w" in d && ("W" in d || "U" in d)) {
var day = newDate(newYear(d.y)).getDay();
if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day;
d.m = 0;
d.d = d.w + d.U * 7 - (day + 6) % 7;
}
return newDate(d);
};
}
function parseSpecifier(d, specifier, string, j) {
var i = 0,
n = specifier.length,
m = string.length,
c,
parse;
while (i < n) {
if (j >= m) return -1;
c = specifier.charCodeAt(i++);
if (c === 37) {
c = specifier.charAt(i++);
parse = parses[c in pads ? specifier.charAt(i++) : c];
if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
} else if (c != string.charCodeAt(j++)) {
return -1;
}
}
return j;
}
function parseShortWeekday(d, string, i) {
var n = shortWeekdayRe.exec(string.slice(i));
return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
}
function parseWeekday(d, string, i) {
var n = weekdayRe.exec(string.slice(i));
return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
}
function parseShortMonth(d, string, i) {
var n = shortMonthRe.exec(string.slice(i));
return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
}
function parseMonth(d, string, i) {
var n = monthRe.exec(string.slice(i));
return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
}
function parseLocaleDateTime(d, string, i) {
return parseSpecifier(d, locale_dateTime, string, i);
}
function parseLocaleDate(d, string, i) {
return parseSpecifier(d, locale_date, string, i);
}
function parseLocaleTime(d, string, i) {
return parseSpecifier(d, locale_time, string, i);
}
function parsePeriod(d, string, i) {
var n = periodLookup.get(string.slice(i, i += 2).toLowerCase());
return n == null ? -1 : (d.p = n, i);
}
function formatShortWeekday(d) {
return locale_shortWeekdays[d.getDay()];
}
function formatWeekday(d) {
return locale_weekdays[d.getDay()];
}
function formatShortMonth(d) {
return locale_shortMonths[d.getMonth()];
}
function formatMonth(d) {
return locale_months[d.getMonth()];
}
function formatPeriod(d) {
return locale_periods[+(d.getHours() >= 12)];
}
function formatUTCShortWeekday(d) {
return locale_shortWeekdays[d.getUTCDay()];
}
function formatUTCWeekday(d) {
return locale_weekdays[d.getUTCDay()];
}
function formatUTCShortMonth(d) {
return locale_shortMonths[d.getUTCMonth()];
}
function formatUTCMonth(d) {
return locale_months[d.getUTCMonth()];
}
function formatUTCPeriod(d) {
return locale_periods[+(d.getUTCHours() >= 12)];
}
return {
format: function(specifier) {
var f = newFormat(specifier += "", formats);
f.parse = newParse(specifier, localDate);
f.toString = function() { return specifier; };
return f;
},
utcFormat: function(specifier) {
var f = newFormat(specifier += "", utcFormats);
f.parse = newParse(specifier, utcDate);
f.toString = function() { return specifier; };
return f;
}
};
}
var pads = {"-": "", "_": " ", "0": "0"};
var numberRe = /^\s*\d+/;
var percentRe = /^%/;
var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
function pad(value, fill, width) {
var sign = value < 0 ? "-" : "",
string = (sign ? -value : value) + "",
length = string.length;
return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
}
function requote(s) {
return s.replace(requoteRe, "\\$&");
}
function formatRe(names) {
return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
}
function formatLookup(names) {
var map = new Map, i = -1, n = names.length;
while (++i < n) map.set(names[i].toLowerCase(), i);
return map;
}
function parseWeekdayNumber(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 1));
return n ? (d.w = +n[0], i + n[0].length) : -1;
}
function parseWeekNumberSunday(d, string, i) {
var n = numberRe.exec(string.slice(i));
return n ? (d.U = +n[0], i + n[0].length) : -1;
}
function parseWeekNumberMonday(d, string, i) {
var n = numberRe.exec(string.slice(i));
return n ? (d.W = +n[0], i + n[0].length) : -1;
}
function parseFullYear(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 4));
return n ? (d.y = +n[0], i + n[0].length) : -1;
}
function parseYear(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
}
function parseZone(d, string, i) {
return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5))
? (d.Z = -string, i + 5) // sign differs from getTimezoneOffset!
: -1;
}
function parseMonthNumber(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
}
function parseDayOfMonth(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.d = +n[0], i + n[0].length) : -1;
}
function parseDayOfYear(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 3));
return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
}
function parseHour24(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.H = +n[0], i + n[0].length) : -1;
}
function parseMinutes(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.M = +n[0], i + n[0].length) : -1;
}
function parseSeconds(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.S = +n[0], i + n[0].length) : -1;
}
function parseMilliseconds(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 3));
return n ? (d.L = +n[0], i + n[0].length) : -1;
}
function parseLiteralPercent(d, string, i) {
var n = percentRe.exec(string.slice(i, i + 1));
return n ? i + n[0].length : -1;
}
function formatDayOfMonth(d, p) {
return pad(d.getDate(), p, 2);
}
function formatHour24(d, p) {
return pad(d.getHours(), p, 2);
}
function formatHour12(d, p) {
return pad(d.getHours() % 12 || 12, p, 2);
}
function formatDayOfYear(d, p) {
return pad(1 + day.count(year(d), d), p, 3);
}
function formatMilliseconds(d, p) {
return pad(d.getMilliseconds(), p, 3);
}
function formatMonthNumber(d, p) {
return pad(d.getMonth() + 1, p, 2);
}
function formatMinutes(d, p) {
return pad(d.getMinutes(), p, 2);
}
function formatSeconds(d, p) {
return pad(d.getSeconds(), p, 2);
}
function formatWeekNumberSunday(d, p) {
return pad(sunday.count(year(d), d), p, 2);
}
function formatWeekdayNumber(d) {
return d.getDay();
}
function formatWeekNumberMonday(d, p) {
return pad(monday.count(year(d), d), p, 2);
}
function formatYear(d, p) {
return pad(d.getFullYear() % 100, p, 2);
}
function formatFullYear(d, p) {
return pad(d.getFullYear() % 10000, p, 4);
}
function formatZone(d) {
var z = d.getTimezoneOffset();
return (z > 0 ? "-" : (z *= -1, "+"))
+ pad(z / 60 | 0, "0", 2)
+ pad(z % 60, "0", 2);
}
function formatUTCDayOfMonth(d, p) {
return pad(d.getUTCDate(), p, 2);
}
function formatUTCHour24(d, p) {
return pad(d.getUTCHours(), p, 2);
}
function formatUTCHour12(d, p) {
return pad(d.getUTCHours() % 12 || 12, p, 2);
}
function formatUTCDayOfYear(d, p) {
return pad(1 + utcDay.count(utcYear(d), d), p, 3);
}
function formatUTCMilliseconds(d, p) {
return pad(d.getUTCMilliseconds(), p, 3);
}
function formatUTCMonthNumber(d, p) {
return pad(d.getUTCMonth() + 1, p, 2);
}
function formatUTCMinutes(d, p) {
return pad(d.getUTCMinutes(), p, 2);
}
function formatUTCSeconds(d, p) {
return pad(d.getUTCSeconds(), p, 2);
}
function formatUTCWeekNumberSunday(d, p) {
return pad(utcSunday.count(utcYear(d), d), p, 2);
}
function formatUTCWeekdayNumber(d) {
return d.getUTCDay();
}
function formatUTCWeekNumberMonday(d, p) {
return pad(utcMonday.count(utcYear(d), d), p, 2);
}
function formatUTCYear(d, p) {
return pad(d.getUTCFullYear() % 100, p, 2);
}
function formatUTCFullYear(d, p) {
return pad(d.getUTCFullYear() % 10000, p, 4);
}
function formatUTCZone() {
return "+0000";
}
function formatLiteralPercent() {
return "%";
}
var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
function formatIsoNative(date) {
return date.toISOString();
}
formatIsoNative.parse = function(string) {
var date = new Date(string);
return isNaN(date) ? null : date;
};
formatIsoNative.toString = function() {
return isoSpecifier;
};
var formatIso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z")
? formatIsoNative
: enUs.utcFormat(isoSpecifier);
var isoFormat = formatIso;
var localeDefinitions = (new Map)
.set("ca-ES", caEs)
.set("de-DE", deDe)
.set("en-CA", enCa)
.set("en-GB", enGb)
.set("en-US", enUs)
.set("es-ES", esEs)
.set("fi-FI", fiFi)
.set("fr-CA", frCa)
.set("fr-FR", frFr)
.set("he-IL", heIl)
.set("it-IT", itIt)
.set("mk-MK", mkMk)
.set("nl-NL", nlNl)
.set("pl-PL", plPl)
.set("pt-BR", ptBr)
.set("ru-RU", ruRu)
.set("zh-CN", zhCn);
var defaultLocale = locale(enUs);
exports.format = defaultLocale.format;
exports.utcFormat = defaultLocale.utcFormat;
function localeFormat(definition) {
if (typeof definition === "string") {
definition = localeDefinitions.get(definition);
if (!definition) return null;
}
return locale(definition);
}
;
exports.localeFormat = localeFormat;
exports.isoFormat = isoFormat;
}));
},{}],5:[function(require,module,exports){
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
factory((global.time = {}));
}(this, function (exports) { 'use strict';
var t1 = new Date;
var t0 = new Date;
function newInterval(floori, offseti, count) {
function interval(date) {
return floori(date = new Date(+date)), date;
}
interval.floor = interval;
interval.round = function(date) {
var d0 = new Date(+date),
d1 = new Date(date - 1);
floori(d0), floori(d1), offseti(d1, 1);
return date - d0 < d1 - date ? d0 : d1;
};
interval.ceil = function(date) {
return floori(date = new Date(date - 1)), offseti(date, 1), date;
};
interval.offset = function(date, step) {
return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
};
interval.range = function(start, stop, step) {
var range = [];
start = new Date(start - 1);
stop = new Date(+stop);
step = step == null ? 1 : Math.floor(step);
if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
offseti(start, 1), floori(start);
if (start < stop) range.push(new Date(+start));
while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start));
return range;
};
interval.filter = function(test) {
return newInterval(function(date) {
while (floori(date), !test(date)) date.setTime(date - 1);
}, function(date, step) {
while (--step >= 0) while (offseti(date, 1), !test(date));
});
};
if (count) interval.count = function(start, end) {
t0.setTime(+start), t1.setTime(+end);
floori(t0), floori(t1);
return Math.floor(count(t0, t1));
};
return interval;
}
var second = newInterval(function(date) {
date.setMilliseconds(0);
}, function(date, step) {
date.setTime(+date + step * 1e3);
}, function(start, end) {
return (end - start) / 1e3;
});
exports.seconds = second.range;
var minute = newInterval(function(date) {
date.setSeconds(0, 0);
}, function(date, step) {
date.setTime(+date + step * 6e4);
}, function(start, end) {
return (end - start) / 6e4;
});
exports.minutes = minute.range;
var hour = newInterval(function(date) {
date.setMinutes(0, 0, 0);
}, function(date, step) {
date.setTime(+date + step * 36e5);
}, function(start, end) {
return (end - start) / 36e5;
});
exports.hours = hour.range;
var day = newInterval(function(date) {
date.setHours(0, 0, 0, 0);
}, function(date, step) {
date.setDate(date.getDate() + step);
}, function(start, end) {
return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5;
});
exports.days = day.range;
function weekday(i) {
return newInterval(function(date) {
date.setHours(0, 0, 0, 0);
date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
}, function(date, step) {
date.setDate(date.getDate() + step * 7);
}, function(start, end) {
return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5;
});
}
exports.sunday = weekday(0);
exports.sundays = exports.sunday.range;
exports.monday = weekday(1);
exports.mondays = exports.monday.range;
exports.tuesday = weekday(2);
exports.tuesdays = exports.tuesday.range;
exports.wednesday = weekday(3);
exports.wednesdays = exports.wednesday.range;
exports.thursday = weekday(4);
exports.thursdays = exports.thursday.range;
exports.friday = weekday(5);
exports.fridays = exports.friday.range;
exports.saturday = weekday(6);
exports.saturdays = exports.saturday.range;
var week = exports.sunday;
exports.weeks = week.range;
var month = newInterval(function(date) {
date.setHours(0, 0, 0, 0);
date.setDate(1);
}, function(date, step) {
date.setMonth(date.getMonth() + step);
}, function(start, end) {
return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
});
exports.months = month.range;
var year = newInterval(function(date) {
date.setHours(0, 0, 0, 0);
date.setMonth(0, 1);
}, function(date, step) {
date.setFullYear(date.getFullYear() + step);
}, function(start, end) {
return end.getFullYear() - start.getFullYear();
});
exports.years = year.range;
var utcSecond = newInterval(function(date) {
date.setUTCMilliseconds(0);
}, function(date, step) {
date.setTime(+date + step * 1e3);
}, function(start, end) {
return (end - start) / 1e3;
});
exports.utcSeconds = utcSecond.range;
var utcMinute = newInterval(function(date) {
date.setUTCSeconds(0, 0);
}, function(date, step) {
date.setTime(+date + step * 6e4);
}, function(start, end) {
return (end - start) / 6e4;
});
exports.utcMinutes = utcMinute.range;
var utcHour = newInterval(function(date) {
date.setUTCMinutes(0, 0, 0);
}, function(date, step) {
date.setTime(+date + step * 36e5);
}, function(start, end) {
return (end - start) / 36e5;
});
exports.utcHours = utcHour.range;
var utcDay = newInterval(function(date) {
date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
date.setUTCDate(date.getUTCDate() + step);
}, function(start, end) {
return (end - start) / 864e5;
});
exports.utcDays = utcDay.range;
function utcWeekday(i) {
return newInterval(function(date) {
date.setUTCHours(0, 0, 0, 0);
date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
}, function(date, step) {
date.setUTCDate(date.getUTCDate() + step * 7);
}, function(start, end) {
return (end - start) / 6048e5;
});
}
exports.utcSunday = utcWeekday(0);
exports.utcSundays = exports.utcSunday.range;
exports.utcMonday = utcWeekday(1);
exports.utcMondays = exports.utcMonday.range;
exports.utcTuesday = utcWeekday(2);
exports.utcTuesdays = exports.utcTuesday.range;
exports.utcWednesday = utcWeekday(3);
exports.utcWednesdays = exports.utcWednesday.range;
exports.utcThursday = utcWeekday(4);
exports.utcThursdays = exports.utcThursday.range;
exports.utcFriday = utcWeekday(5);
exports.utcFridays = exports.utcFriday.range;
exports.utcSaturday = utcWeekday(6);
exports.utcSaturdays = exports.utcSaturday.range;
var utcWeek = exports.utcSunday;
exports.utcWeeks = utcWeek.range;
var utcMonth = newInterval(function(date) {
date.setUTCHours(0, 0, 0, 0);
date.setUTCDate(1);
}, function(date, step) {
date.setUTCMonth(date.getUTCMonth() + step);
}, function(start, end) {
return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
});
exports.utcMonths = utcMonth.range;
var utcYear = newInterval(function(date) {
date.setUTCHours(0, 0, 0, 0);
date.setUTCMonth(0, 1);
}, function(date, step) {
date.setUTCFullYear(date.getUTCFullYear() + step);
}, function(start, end) {
return end.getUTCFullYear() - start.getUTCFullYear();
});
exports.utcYears = utcYear.range;
exports.interval = newInterval;
exports.second = second;
exports.minute = minute;
exports.hour = hour;
exports.day = day;
exports.week = week;
exports.month = month;
exports.year = year;
exports.utcSecond = utcSecond;
exports.utcMinute = utcMinute;
exports.utcHour = utcHour;
exports.utcDay = utcDay;
exports.utcWeek = utcWeek;
exports.utcMonth = utcMonth;
exports.utcYear = utcYear;
}));
},{}],6:[function(require,module,exports){
var util = require('../util'),
Measures = require('./measures'),
Collector = require('./collector');
function Aggregator() {
this._cells = {};
this._aggr = [];
this._stream = false;
}
var Flags = Aggregator.Flags = {
ADD_CELL: 1,
MOD_CELL: 2
};
var proto = Aggregator.prototype;
// Parameters
proto.stream = function(v) {
if (v == null) return this._stream;
this._stream = !!v;
this._aggr = [];
return this;
};
// key accessor to use for streaming removes
proto.key = function(key) {
if (key == null) return this._key;
this._key = util.$(key);
return this;
};
// Input: array of objects of the form
// {name: string, get: function}
proto.groupby = function(dims) {
this._dims = util.array(dims).map(function(d, i) {
d = util.isString(d) ? {name: d, get: util.$(d)}
: util.isFunction(d) ? {name: util.name(d) || d.name || ('_' + i), get: d}
: (d.name && util.isFunction(d.get)) ? d : null;
if (d == null) throw 'Invalid groupby argument: ' + d;
return d;
});
return this.clear();
};
// Input: array of objects of the form
// {name: string, ops: [string, ...]}
proto.summarize = function(fields) {
fields = summarize_args(fields);
this._count = true;
var aggr = (this._aggr = []),
m, f, i, j, op, as, get;
for (i=0; i<fields.length; ++i) {
for (j=0, m=[], f=fields[i]; j<f.ops.length; ++j) {
op = f.ops[j];
if (op !== 'count') this._count = false;
as = (f.as && f.as[j]) || (op + (f.name==='*' ? '' : '_'+f.name));
m.push(Measures[op](as));
}
get = f.get && util.$(f.get) ||
(f.name === '*' ? util.identity : util.$(f.name));
aggr.push({
name: f.name,
measures: Measures.create(
m,
this._stream, // streaming remove flag
get, // input tuple getter
this._assign) // output tuple setter
});
}
return this.clear();
};
// Convenience method to summarize by count
proto.count = function() {
return this.summarize({'*':'count'});
};
// Override to perform custom tuple value assignment
proto._assign = function(object, name, value) {
object[name] = value;
};
function summarize_args(fields) {
if (util.isArray(fields)) { return fields; }
if (fields == null) { return []; }
var a = [], name, ops;
for (name in fields) {
ops = util.array(fields[name]);
a.push({name: name, ops: ops});
}
return a;
}
// Cell Management
proto.clear = function() {
return (this._cells = {}, this);
};
proto._cellkey = function(x) {
var d = this._dims,
n = d.length, i,
k = String(d[0].get(x));
for (i=1; i<n; ++i) {
k += '|' + d[i].get(x);
}
return k;
};
proto._cell = function(x) {
var key = this._dims.length ? this._cellkey(x) : '';
return this._cells[key] || (this._cells[key] = this._newcell(x, key));
};
proto._newcell = function(x, key) {
var cell = {
num: 0,
tuple: this._newtuple(x, key),
flag: Flags.ADD_CELL,
aggs: {}
};
var aggr = this._aggr, i;
for (i=0; i<aggr.length; ++i) {
cell.aggs[aggr[i].name] = new aggr[i].measures(cell, cell.tuple);
}
if (cell.collect) {
cell.data = new Collector(this._key);
}
return cell;
};
proto._newtuple = function(x) {
var dims = this._dims,
t = {}, i, n;
for (i=0, n=dims.length; i<n; ++i) {
t[dims[i].name] = dims[i].get(x);
}
return this._ingest(t);
};
// Override to perform custom tuple ingestion
proto._ingest = util.identity;
// Process Tuples
proto._add = function(x) {
var cell = this._cell(x),
aggr = this._aggr, i;
cell.num += 1;
if (!this._count) { // skip if count-only
if (cell.collect) cell.data.add(x);
for (i=0; i<aggr.length; ++i) {
cell.aggs[aggr[i].name].add(x);
}
}
cell.flag |= Flags.MOD_CELL;
if (this._on_add) this._on_add(x, cell);
};
proto._rem = function(x) {
var cell = this._cell(x),
aggr = this._aggr, i;
cell.num -= 1;
if (!this._count) { // skip if count-only
if (cell.collect) cell.data.rem(x);
for (i=0; i<aggr.length; ++i) {
cell.aggs[aggr[i].name].rem(x);
}
}
cell.flag |= Flags.MOD_CELL;
if (this._on_rem) this._on_rem(x, cell);
};
proto._mod = function(curr, prev) {
var cell0 = this._cell(prev),
cell1 = this._cell(curr),
aggr = this._aggr, i;
if (cell0 !== cell1) {
cell0.num -= 1;
cell1.num += 1;
if (cell0.collect) cell0.data.rem(prev);
if (cell1.collect) cell1.data.add(curr);
} else if (cell0.collect && !util.isObject(curr)) {
cell0.data.rem(prev);
cell0.data.add(curr);
}
for (i=0; i<aggr.length; ++i) {
cell0.aggs[aggr[i].name].rem(prev);
cell1.aggs[aggr[i].name].add(curr);
}
cell0.flag |= Flags.MOD_CELL;
cell1.flag |= Flags.MOD_CELL;
if (this._on_mod) this._on_mod(curr, prev, cell0, cell1);
};
proto.result = function() {
var result = [],
aggr = this._aggr,
cell, i, k;
for (k in this._cells) {
cell = this._cells[k];
if (cell.num > 0) {
// consolidate collector values
if (cell.collect) {
cell.data.values();
}
// update tuple properties
for (i=0; i<aggr.length; ++i) {
cell.aggs[aggr[i].name].set();
}
// add output tuple
result.push(cell.tuple);
} else {
delete this._cells[k];
}
cell.flag = 0;
}
this._rems = false;
return result;
};
proto.changes = function(output) {
var changes = output || {add:[], rem:[], mod:[]},
aggr = this._aggr,
cell, flag, i, k;
for (k in this._cells) {
cell = this._cells[k];
flag = cell.flag;
// consolidate collector values
if (cell.collect) {
cell.data.values();
}
// update tuple properties
for (i=0; i<aggr.length; ++i) {
cell.aggs[aggr[i].name].set();
}
// organize output tuples
if (cell.num <= 0) {
changes.rem.push(cell.tuple); // if (flag === Flags.MOD_CELL) { ??
delete this._cells[k];
if (this._on_drop) this._on_drop(cell);
} else {
if (this._on_keep) this._on_keep(cell);
if (flag & Flags.ADD_CELL) {
changes.add.push(cell.tuple);
} else if (flag & Flags.MOD_CELL) {
changes.mod.push(cell.tuple);
}
}
cell.flag = 0;
}
this._rems = false;
return changes;
};
proto.execute = function(input) {
return this.clear().insert(input).result();
};
proto.insert = function(input) {
this._consolidate();
for (var i=0; i<input.length; ++i) {
this._add(input[i]);
}
return this;
};
proto.remove = function(input) {
if (!this._stream) {
throw 'Aggregator not configured for streaming removes.' +
' Call stream(true) prior to calling summarize.';
}
for (var i=0; i<input.length; ++i) {
this._rem(input[i]);
}
this._rems = true;
return this;
};
// consolidate removals
proto._consolidate = function() {
if (!this._rems) return;
for (var k in this._cells) {
if (this._cells[k].collect) {
this._cells[k].data.values();
}
}
this._rems = false;
};
module.exports = Aggregator;
},{"../util":28,"./collector":7,"./measures":9}],7:[function(require,module,exports){
var util = require('../util');
var stats = require('../stats');
var REM = '__dl_rem__';
function Collector(key) {
this._add = [];
this._rem = [];
this._key = key || null;
this._last = null;
}
var proto = Collector.prototype;
proto.add = function(v) {
this._add.push(v);
};
proto.rem = function(v) {
this._rem.push(v);
};
proto.values = function() {
this._get = null;
if (this._rem.length === 0) return this._add;
var a = this._add,
r = this._rem,
k = this._key,
x = Array(a.length - r.length),
i, j, n, m;
if (!util.isObject(r[0])) {
// processing raw values
m = stats.count.map(r);
for (i=0, j=0, n=a.length; i<n; ++i) {
if (m[a[i]] > 0) {
m[a[i]] -= 1;
} else {
x[j++] = a[i];
}
}
} else if (k) {
// has unique key field, so use that
m = util.toMap(r, k);
for (i=0, j=0, n=a.length; i<n; ++i) {
if (!m.hasOwnProperty(k(a[i]))) { x[j++] = a[i]; }
}
} else {
// no unique key, mark tuples directly
for (i=0, n=r.length; i<n; ++i) {
r[i][REM] = 1;
}
for (i=0, j=0, n=a.length; i<n; ++i) {
if (!a[i][REM]) { x[j++] = a[i]; }
}
for (i=0, n=r.length; i<n; ++i) {
delete r[i][REM];
}
}
this._rem = [];
return (this._add = x);
};
// memoizing statistics methods
proto.extent = function(get) {
if (this._get !== get || !this._ext) {
var v = this.values(),
i = stats.extent.index(v, get);
this._ext = [v[i[0]], v[i[1]]];
this._get = get;
}
return this._ext;
};
proto.argmin = function(get) {
return this.extent(get)[0];
};
proto.argmax = function(get) {
return this.extent(get)[1];
};
proto.min = function(get) {
var m = this.extent(get)[0];
return m ? get(m) : +Infinity;
};
proto.max = function(get) {
var m = this.extent(get)[1];
return m ? get(m) : -Infinity;
};
proto.quartile = function(get) {
if (this._get !== get || !this._q) {
this._q = stats.quartile(this.values(), get);
this._get = get;
}
return this._q;
};
proto.q1 = function(get) {
return this.quartile(get)[0];
};
proto.q2 = function(get) {
return this.quartile(get)[1];
};
proto.q3 = function(get) {
return this.quartile(get)[2];
};
module.exports = Collector;
},{"../stats":25,"../util":28}],8:[function(require,module,exports){
var util = require('../util');
var Aggregator = require('./aggregator');
module.exports = function() {
// flatten arguments into a single array
var args = [].reduce.call(arguments, function(a, x) {
return a.concat(util.array(x));
}, []);
// create and return an aggregator
return new Aggregator()
.groupby(args)
.summarize({'*':'values'});
};
},{"../util":28,"./aggregator":6}],9:[function(require,module,exports){
var util = require('../util');
var types = {
'values': measure({
name: 'values',
init: 'cell.collect = true;',
set: 'cell.data.values()', idx: -1
}),
'count': measure({
name: 'count',
set: 'cell.num'
}),
'missing': measure({
name: 'missing',
set: 'this.missing'
}),
'valid': measure({
name: 'valid',
set: 'this.valid'
}),
'sum': measure({
name: 'sum',
init: 'this.sum = 0;',
add: 'this.sum += v;',
rem: 'this.sum -= v;',
set: 'this.sum'
}),
'mean': measure({
name: 'mean',
init: 'this.mean = 0;',
add: 'var d = v - this.mean; this.mean += d / this.valid;',
rem: 'var d = v - this.mean; this.mean -= this.valid ? d / this.valid : this.mean;',
set: 'this.mean'
}),
'average': measure({
name: 'average',
set: 'this.mean',
req: ['mean'], idx: 1
}),
'variance': measure({
name: 'variance',
init: 'this.dev = 0;',
add: 'this.dev += d * (v - this.mean);',
rem: 'this.dev -= d * (v - this.mean);',
set: 'this.valid > 1 ? this.dev / (this.valid-1) : 0',
req: ['mean'], idx: 1
}),
'variancep': measure({
name: 'variancep',
set: 'this.valid > 1 ? this.dev / this.valid : 0',
req: ['variance'], idx: 2
}),
'stdev': measure({
name: 'stdev',
set: 'this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0',
req: ['variance'], idx: 2
}),
'stdevp': measure({
name: 'stdevp',
set: 'this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0',
req: ['variance'], idx: 2
}),
'median': measure({
name: 'median',
set: 'cell.data.q2(this.get)',
req: ['values'], idx: 3
}),
'q1': measure({
name: 'q1',
set: 'cell.data.q1(this.get)',
req: ['values'], idx: 3
}),
'q3': measure({
name: 'q3',
set: 'cell.data.q3(this.get)',
req: ['values'], idx: 3
}),
'distinct': measure({
name: 'distinct',
set: 'this.distinct(cell.data.values(), this.get)',
req: ['values'], idx: 3
}),
'argmin': measure({
name: 'argmin',
add: 'if (v < this.min) this.argmin = t;',
rem: 'if (v <= this.min) this.argmin = null;',
set: 'this.argmin = this.argmin || cell.data.argmin(this.get)',
req: ['min'], str: ['values'], idx: 3
}),
'argmax': measure({
name: 'argmax',
add: 'if (v > this.max) this.argmax = t;',
rem: 'if (v >= this.max) this.argmax = null;',
set: 'this.argmax = this.argmax || cell.data.argmax(this.get)',
req: ['max'], str: ['values'], idx: 3
}),
'min': measure({
name: 'min',
init: 'this.min = +Infinity;',
add: 'if (v < this.min) this.min = v;',
rem: 'if (v <= this.min) this.min = NaN;',
set: 'this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)',
str: ['values'], idx: 4
}),
'max': measure({
name: 'max',
init: 'this.max = -Infinity;',
add: 'if (v > this.max) this.max = v;',
rem: 'if (v >= this.max) this.max = NaN;',
set: 'this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)',
str: ['values'], idx: 4
}),
'modeskew': measure({
name: 'modeskew',
set: 'this.dev===0 ? 0 : (this.mean - cell.data.q2(this.get)) / Math.sqrt(this.dev/(this.valid-1))',
req: ['mean', 'stdev', 'median'], idx: 5
})
};
function measure(base) {
return function(out) {
var m = util.extend({init:'', add:'', rem:'', idx:0}, base);
m.out = out || base.name;
return m;
};
}
function resolve(agg, stream) {
function collect(m, a) {
function helper(r) { if (!m[r]) collect(m, m[r] = types[r]()); }
if (a.req) a.req.forEach(helper);
if (stream && a.str) a.str.forEach(helper);
return m;
}
var map = agg.reduce(
collect,
agg.reduce(function(m, a) { return (m[a.name] = a, m); }, {})
);
return util.vals(map).sort(function(a, b) { return a.idx - b.idx; });
}
function create(agg, stream, accessor, mutator) {
var all = resolve(agg, stream),
ctr = 'this.cell = cell; this.tuple = t; this.valid = 0; this.missing = 0;',
add = 'if (v==null) this.missing++; if (!this.isValid(v)) return; ++this.valid;',
rem = 'if (v==null) this.missing--; if (!this.isValid(v)) return; --this.valid;',
set = 'var t = this.tuple; var cell = this.cell;';
all.forEach(function(a) {
if (a.idx < 0) {
ctr = a.init + ctr;
add = a.add + add;
rem = a.rem + rem;
} else {
ctr += a.init;
add += a.add;
rem += a.rem;
}
});
agg.slice()
.sort(function(a, b) { return a.idx - b.idx; })
.forEach(function(a) {
set += 'this.assign(t,\''+a.out+'\','+a.set+');';
});
set += 'return t;';
/* jshint evil: true */
ctr = Function('cell', 't', ctr);
ctr.prototype.assign = mutator;
ctr.prototype.add = Function('t', 'var v = this.get(t);' + add);
ctr.prototype.rem = Function('t', 'var v = this.get(t);' + rem);
ctr.prototype.set = Function(set);
ctr.prototype.get = accessor;
ctr.prototype.distinct = require('../stats').count.distinct;
ctr.prototype.isValid = util.isValid;
ctr.fields = agg.map(util.$('out'));
return ctr;
}
types.create = create;
module.exports = types;
},{"../stats":25,"../util":28}],10:[function(require,module,exports){
var util = require('../util'),
time = require('../time'),
EPSILON = 1e-15;
function bins(opt) {
if (!opt) { throw Error("Missing binning options."); }
// determine range
var maxb = opt.maxbins || 15,
base = opt.base || 10,
logb = Math.log(base),
div = opt.div || [5, 2],
min = opt.min,
max = opt.max,
span = max - min,
step, level, minstep, precision, v, i, eps;
if (opt.step) {
// if step size is explicitly given, use that
step = opt.step;
} else if (opt.steps) {
// if provided, limit choice to acceptable step sizes
step = opt.steps[Math.min(
opt.steps.length - 1,
bisect(opt.steps, span/maxb, 0, opt.steps.length)
)];
} else {
// else use span to determine step size
level = Math.ceil(Math.log(maxb) / logb);
minstep = opt.minstep || 0;
step = Math.max(
minstep,
Math.pow(base, Math.round(Math.log(span) / logb) - level)
);
// increase step size if too many bins
do { step *= base; } while (Math.ceil(span/step) > maxb);
// decrease step size if allowed
for (i=0; i<div.length; ++i) {
v = step / div[i];
if (v >= minstep && span / v <= maxb) step = v;
}
}
// update precision, min and max
v = Math.log(step);
precision = v >= 0 ? 0 : ~~(-v / logb) + 1;
eps = Math.pow(base, -precision - 1);
min = Math.min(min, Math.floor(min / step + eps) * step);
max = Math.ceil(max / step) * step;
return {
start: min,
stop: max,
step: step,
unit: {precision: precision},
value: value,
index: index
};
}
function bisect(a, x, lo, hi) {
while (lo < hi) {
var mid = lo + hi >>> 1;
if (util.cmp(a[mid], x) < 0) { lo = mid + 1; }
else { hi = mid; }
}
return lo;
}
function value(v) {
return this.step * Math.floor(v / this.step + EPSILON);
}
function index(v) {
return Math.floor((v - this.start) / this.step + EPSILON);
}
function date_value(v) {
return this.unit.date(value.call(this, v));
}
function date_index(v) {
return index.call(this, this.unit.unit(v));
}
bins.date = function(opt) {
if (!opt) { throw Error("Missing date binning options."); }
// find time step, then bin
var units = opt.utc ? time.utc : time,
dmin = opt.min,
dmax = opt.max,
maxb = opt.maxbins || 20,
minb = opt.minbins || 4,
span = (+dmax) - (+dmin),
unit = opt.unit ? units[opt.unit] : units.find(span, minb, maxb),
spec = bins({
min: unit.min != null ? unit.min : unit.unit(dmin),
max: unit.max != null ? unit.max : unit.unit(dmax),
maxbins: maxb,
minstep: unit.minstep,
steps: unit.step
});
spec.unit = unit;
spec.index = date_index;
if (!opt.raw) spec.value = date_value;
return spec;
};
module.exports = bins;
},{"../time":27,"../util":28}],11:[function(require,module,exports){
var bins = require('./bins'),
gen = require('../generate'),
type = require('../import/type'),
util = require('../util'),
stats = require('../stats');
var qtype = {
'integer': 1,
'number': 1,
'date': 1
};
function $bin(values, f, opt) {
opt = options(values, f, opt);
var b = spec(opt);
return !b ? (opt.accessor || util.identity) :
util.$func('bin', b.unit.unit ?
function(x) { return b.value(b.unit.unit(x)); } :
function(x) { return b.value(x); }
)(opt.accessor);
}
function histogram(values, f, opt) {
opt = options(values, f, opt);
var b = spec(opt);
return b ?
numerical(values, opt.accessor, b) :
categorical(values, opt.accessor, opt && opt.sort);
}
function spec(opt) {
var t = opt.type, b = null;
if (t == null || qtype[t]) {
if (t === 'integer' && opt.minstep == null) opt.minstep = 1;
b = (t === 'date') ? bins.date(opt) : bins(opt);
}
return b;
}
function options() {
var a = arguments,
i = 0,
values = util.isArray(a[i]) ? a[i++] : null,
f = util.isFunction(a[i]) || util.isString(a[i]) ? util.$(a[i++]) : null,
opt = util.extend({}, a[i]);
if (values) {
opt.type = opt.type || type(values, f);
if (qtype[opt.type]) {
var ext = stats.extent(values, f);
opt = util.extend({min: ext[0], max: ext[1]}, opt);
}
}
if (f) { opt.accessor = f; }
return opt;
}
function numerical(values, f, b) {
var h = gen.range(b.start, b.stop + b.step/2, b.step)
.map(function(v) { return {value: b.value(v), count: 0}; });
for (var i=0, v, j; i<values.length; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) {
j = b.index(v);
if (j < 0 || j >= h.length || !isFinite(j)) continue;
h[j].count += 1;
}
}
h.bins = b;
return h;
}
function categorical(values, f, sort) {
var u = stats.unique(values, f),
c = stats.count.map(values, f);
return u.map(function(k) { return {value: k, count: c[k]}; })
.sort(util.comparator(sort ? '-count' : '+value'));
}
module.exports = {
$bin: $bin,
histogram: histogram
};
},{"../generate":13,"../import/type":22,"../stats":25,"../util":28,"./bins":10}],12:[function(require,module,exports){
var d3_time = require('d3-time'),
d3_timeF = require('d3-time-format'),
d3_numberF = require('d3-format'),
numberF = d3_numberF, // defaults to EN-US
timeF = d3_timeF; // defaults to EN-US
function numberLocale(l) {
var f = d3_numberF.localeFormat(l);
if (f == null) throw Error('Unrecognized locale: ' + l);
numberF = f;
}
function timeLocale(l) {
var f = d3_timeF.localeFormat(l);
if (f == null) throw Error('Unrecognized locale: ' + l);
timeF = f;
}
module.exports = {
// Update number formatter to use provided locale configuration.
// For more see https://github.com/d3/d3-format
numberLocale: numberLocale,
number: function(f) { return numberF.format(f); },
numberPrefix: function(f, v) { return numberF.formatPrefix(f, v); },
// Update time formatter to use provided locale configuration.
// For more see https://github.com/d3/d3-time-format
timeLocale: timeLocale,
time: function(f) { return timeF.format(f); },
utc: function(f) { return timeF.utcFormat(f); },
// Set number and time locale simultaneously.
locale: function(l) { numberLocale(l); timeLocale(l); },
// automatic formatting functions
auto: {
number: numberAutoFormat,
time: function() { return timeAutoFormat(); },
utc: function() { return utcAutoFormat(); }
}
};
var e10 = Math.sqrt(50),
e5 = Math.sqrt(10),
e2 = Math.sqrt(2);
function intervals(domain, count) {
if (!domain.length) domain = [0];
if (count == null) count = 10;
var start = domain[0],
stop = domain[domain.length - 1];
if (stop < start) { error = stop; stop = start; start = error; }
var span = (stop - start) || (count = 1, start || stop || 1),
step = Math.pow(10, Math.floor(Math.log(span / count) / Math.LN10)),
error = span / count / step;
// Filter ticks to get closer to the desired count.
if (error >= e10) step *= 10;
else if (error >= e5) step *= 5;
else if (error >= e2) step *= 2;
// Round start and stop values to step interval.
return [
Math.ceil(start / step) * step,
Math.floor(stop / step) * step + step / 2, // inclusive
step
];
}
function numberAutoFormat(domain, count, f) {
var range = intervals(domain, count);
if (f == null) {
f = ',.' + d3_numberF.precisionFixed(range[2]) + 'f';
} else {
switch (f = d3_numberF.formatSpecifier(f), f.type) {
case 's': {
var value = Math.max(Math.abs(range[0]), Math.abs(range[1]));
if (f.precision == null) f.precision = d3_numberF.precisionPrefix(range[2], value);
return numberF.formatPrefix(f, value);
}
case '':
case 'e':
case 'g':
case 'p':
case 'r': {
if (f.precision == null) f.precision = d3_numberF.precisionRound(range[2], Math.max(Math.abs(range[0]), Math.abs(range[1]))) - (f.type === 'e');
break;
}
case 'f':
case '%': {
if (f.precision == null) f.precision = d3_numberF.precisionFixed(range[2]) - (f.type === '%') * 2;
break;
}
}
}
return numberF.format(f);
}
function timeAutoFormat() {
var f = timeF.format,
formatMillisecond = f('.%L'),
formatSecond = f(':%S'),
formatMinute = f('%I:%M'),
formatHour = f('%I %p'),
formatDay = f('%a %d'),
formatWeek = f('%b %d'),
formatMonth = f('%B'),
formatYear = f('%Y');
return function(date) {
var d = +date;
return (d3_time.second(date) < d ? formatMillisecond
: d3_time.minute(date) < d ? formatSecond
: d3_time.hour(date) < d ? formatMinute
: d3_time.day(date) < d ? formatHour
: d3_time.month(date) < d ?
(d3_time.week(date) < d ? formatDay : formatWeek)
: d3_time.year(date) < d ? formatMonth
: formatYear)(date);
};
}
function utcAutoFormat() {
var f = timeF.utcFormat,
formatMillisecond = f('.%L'),
formatSecond = f(':%S'),
formatMinute = f('%I:%M'),
formatHour = f('%I %p'),
formatDay = f('%a %d'),
formatWeek = f('%b %d'),
formatMonth = f('%B'),
formatYear = f('%Y');
return function(date) {
var d = +date;
return (d3_time.utcSecond(date) < d ? formatMillisecond
: d3_time.utcMinute(date) < d ? formatSecond
: d3_time.utcHour(date) < d ? formatMinute
: d3_time.utcDay(date) < d ? formatHour
: d3_time.utcMonth(date) < d ?
(d3_time.utcWeek(date) < d ? formatDay : formatWeek)
: d3_time.utcYear(date) < d ? formatMonth
: formatYear)(date);
};
}
},{"d3-format":3,"d3-time":5,"d3-time-format":4}],13:[function(require,module,exports){
var gen = module.exports = {};
gen.repeat = function(val, n) {
var a = Array(n), i;
for (i=0; i<n; ++i) a[i] = val;
return a;
};
gen.zeros = function(n) {
return gen.repeat(0, n);
};
gen.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 = [], i = -1, j;
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j);
else while ((j = start + step * ++i) < stop) range.push(j);
return range;
};
gen.random = {};
gen.random.uniform = function(min, max) {
if (max === undefined) {
max = min === undefined ? 1 : min;
min = 0;
}
var d = max - min;
var f = function() {
return min + d * Math.random();
};
f.samples = function(n) { return gen.zeros(n).map(f); };
return f;
};
gen.random.integer = function(a, b) {
if (b === undefined) {
b = a;
a = 0;
}
var d = b - a;
var f = function() {
return a + Math.floor(d * Math.random());
};
f.samples = function(n) { return gen.zeros(n).map(f); };
return f;
};
gen.random.normal = function(mean, stdev) {
mean = mean || 0;
stdev = stdev || 1;
var next;
var f = function() {
var x = 0, y = 0, rds, c;
if (next !== undefined) {
x = next;
next = undefined;
return x;
}
do {
x = Math.random()*2-1;
y = Math.random()*2-1;
rds = x*x + y*y;
} while (rds === 0 || rds > 1);
c = Math.sqrt(-2*Math.log(rds)/rds); // Box-Muller transform
next = mean + y*c*stdev;
return mean + x*c*stdev;
};
f.samples = function(n) { return gen.zeros(n).map(f); };
return f;
};
},{}],14:[function(require,module,exports){
var util = require('../../util');
var d3_dsv = require('d3-dsv');
function dsv(data, format) {
if (data) {
var h = format.header;
data = (h ? h.join(format.delimiter) + '\n' : '') + data;
}
return d3_dsv.dsv(format.delimiter).parse(data);
}
dsv.delimiter = function(delim) {
var fmt = {delimiter: delim};
return function(data, format) {
return dsv(data, format ? util.extend(format, fmt) : fmt);
};
};
module.exports = dsv;
},{"../../util":28,"d3-dsv":2}],15:[function(require,module,exports){
var dsv = require('./dsv');
module.exports = {
json: require('./json'),
topojson: require('./topojson'),
treejson: require('./treejson'),
dsv: dsv,
csv: dsv.delimiter(','),
tsv: dsv.delimiter('\t')
};
},{"./dsv":14,"./json":16,"./topojson":17,"./treejson":18}],16:[function(require,module,exports){
var util = require('../../util');
module.exports = function(data, format) {
var d = util.isObject(data) && !util.isBuffer(data) ?
data : JSON.parse(data);
if (format && format.property) {
d = util.accessor(format.property)(d);
}
return d;
};
},{"../../util":28}],17:[function(require,module,exports){
(function (global){
var json = require('./json');
var reader = function(data, format) {
var topojson = reader.topojson;
if (topojson == null) { throw Error('TopoJSON library not loaded.'); }
var t = json(data, format), obj;
if (format && format.feature) {
if ((obj = t.objects[format.feature])) {
return topojson.feature(t, obj).features;
} else {
throw Error('Invalid TopoJSON object: ' + format.feature);
}
} else if (format && format.mesh) {
if ((obj = t.objects[format.mesh])) {
return [topojson.mesh(t, t.objects[format.mesh])];
} else {
throw Error('Invalid TopoJSON object: ' + format.mesh);
}
} else {
throw Error('Missing TopoJSON feature or mesh parameter.');
}
};
reader.topojson = (typeof window !== "undefined" ? window['topojson'] : typeof global !== "undefined" ? global['topojson'] : null);
module.exports = reader;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./json":16}],18:[function(require,module,exports){
var json = require('./json');
module.exports = function(data, format) {
data = json(data, format);
return toTable(data, (format && format.children));
};
function toTable(root, childrenField) {
childrenField = childrenField || 'children';
var table = [];
function visit(node) {
table.push(node);
var children = node[childrenField];
if (children) {
for (var i=0; i<children.length; ++i) {
visit(children[i], node);
}
}
}
visit(root, null);
return (table.root = root, table);
}
},{"./json":16}],19:[function(require,module,exports){
// Matches absolute URLs with optional protocol
// https://... file://... //...
var protocol_re = /^([A-Za-z]+:)?\/\//;
// Special treatment in node.js for the file: protocol
var fileProtocol = 'file://';
// Validate and cleanup URL to ensure that it is allowed to be accessed
// Returns cleaned up URL, or false if access is not allowed
function sanitizeUrl(opt) {
var url = opt.url;
if (!url && opt.file) { return fileProtocol + opt.file; }
// In case this is a relative url (has no host), prepend opt.baseURL
if (opt.baseURL && !protocol_re.test(url)) {
if (!startsWith(url, '/') && opt.baseURL[opt.baseURL.length-1] !== '/') {
url = '/' + url; // Ensure that there is a slash between the baseURL (e.g. hostname) and url
}
url = opt.baseURL + url;
}
// relative protocol, starts with '//'
if (!load.useXHR && startsWith(url, '//')) {
url = (opt.defaultProtocol || 'http') + ':' + url;
}
// If opt.domainWhiteList is set, only allows url, whose hostname
// * Is the same as the origin (window.location.hostname)
// * Equals one of the values in the whitelist
// * Is a proper subdomain of one of the values in the whitelist
if (opt.domainWhiteList) {
var domain, origin;
if (load.useXHR) {
var a = document.createElement('a');
a.href = url;
// From http://stackoverflow.com/questions/736513/how-do-i-parse-a-url-into-hostname-and-path-in-javascript
// IE doesn't populate all link properties when setting .href with a relative URL,
// however .href will return an absolute URL which then can be used on itself
// to populate these additional fields.
if (a.host === '') {
a.href = a.href;
}
domain = a.hostname.toLowerCase();
origin = window.location.hostname;
} else {
// relative protocol is broken: https://github.com/defunctzombie/node-url/issues/5
var parts = require('url').parse(url);
domain = parts.hostname;
origin = null;
}
if (origin !== domain) {
var whiteListed = opt.domainWhiteList.some(function(d) {
var idx = domain.length - d.length;
return d === domain ||
(idx > 1 && domain[idx-1] === '.' && domain.lastIndexOf(d) === idx);
});
if (!whiteListed) {
throw 'URL is not whitelisted: ' + url;
}
}
}
return url;
}
function load(opt, callback) {
var error = callback || function(e) { throw e; }, url;
try {
url = load.sanitizeUrl(opt); // enable override
} catch (err) {
error(err);
return;
}
if (!url) {
error('Invalid URL: ' + opt.url);
} else if (load.useXHR) {
// on client, use xhr
return xhr(url, callback);
} else if (startsWith(url, fileProtocol)) {
// on server, if url starts with 'file://', strip it and load from file
return file(url.slice(fileProtocol.length), callback);
} else if (url.indexOf('://') < 0) { // TODO better protocol check?
// on server, if no protocol assume file
return file(url, callback);
} else {
// for regular URLs on server
return http(url, callback);
}
}
function xhrHasResponse(request) {
var type = request.responseType;
return type && type !== 'text' ?
request.response : // null on error
request.responseText; // '' on error
}
function xhr(url, callback) {
var async = !!callback;
var request = new XMLHttpRequest();
// If IE does not support CORS, use XDomainRequest (copied from d3.xhr)
if (this.XDomainRequest &&
!('withCredentials' in request) &&
/^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest();
function respond() {
var status = request.status;
if (!status && xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) {
callback(null, request.responseText);
} else {
callback(request, null);
}
}
if (async) {
if ('onload' in request) {
request.onload = request.onerror = respond;
} else {
request.onreadystatechange = function() {
if (request.readyState > 3) respond();
};
}
}
request.open('GET', url, async);
request.send();
if (!async && xhrHasResponse(request)) {
return request.responseText;
}
}
function file(filename, callback) {
var fs = require('fs');
if (!callback) {
return fs.readFileSync(filename, 'utf8');
}
fs.readFile(filename, callback);
}
function http(url, callback) {
if (!callback) {
return require('sync-request')('GET', url).getBody();
}
var options = {url: url, encoding: null, gzip: true};
require('request')(options, function(error, response, body) {
if (!error && response.statusCode === 200) {
callback(null, body);
} else {
error = error ||
'Load failed with response code ' + response.statusCode + '.';
callback(error, null);
}
});
}
function startsWith(string, searchString) {
return string == null ? false : string.lastIndexOf(searchString, 0) === 0;
}
load.sanitizeUrl = sanitizeUrl;
load.useXHR = (typeof XMLHttpRequest !== 'undefined');
module.exports = load;
},{"fs":1,"request":1,"sync-request":1,"url":1}],20:[function(require,module,exports){
var util = require('../util');
var type = require('./type');
var formats = require('./formats');
function read(data, format) {
var type = (format && format.type) || 'json';
data = formats[type](data, format);
if (format && format.parse) parse(data, format.parse);
return data;
}
function parse(data, types) {
var cols, parsers, d, i, j, clen, len = data.length;
types = (types==='auto') ? type.inferAll(data) : util.duplicate(types);
cols = util.keys(types);
parsers = cols.map(function(c) { return type.parsers[types[c]]; });
for (i=0, clen=cols.length; i<len; ++i) {
d = data[i];
for (j=0; j<clen; ++j) {
d[cols[j]] = parsers[j](d[cols[j]]);
}
}
type.annotation(data, types);
}
read.formats = formats;
module.exports = read;
},{"../util":28,"./formats":15,"./type":22}],21:[function(require,module,exports){
var util = require('../util');
var load = require('./load');
var read = require('./read');
module.exports = util
.keys(read.formats)
.reduce(function(out, type) {
out[type] = function(opt, format, callback) {
// process arguments
if (util.isString(opt)) { opt = {url: opt}; }
if (arguments.length === 2 && util.isFunction(format)) {
callback = format;
format = undefined;
}
// set up read format
format = util.extend({parse: 'auto'}, format);
format.type = type;
// load data
var data = load(opt, callback ? function(error, data) {
if (error) { callback(error, null); return; }
try {
// data loaded, now parse it (async)
data = read(data, format);
callback(null, data);
} catch (e) {
callback(e, null);
}
} : undefined);
// data loaded, now parse it (sync)
if (!callback) return read(data, format);
};
return out;
}, {});
},{"../util":28,"./load":19,"./read":20}],22:[function(require,module,exports){
var util = require('../util');
var TYPES = '__types__';
var PARSERS = {
boolean: util.boolean,
integer: util.number,
number: util.number,
date: util.date,
string: function(x) { return x==='' ? null : x; }
};
var TESTS = {
boolean: function(x) { return x==='true' || x==='false' || util.isBoolean(x); },
integer: function(x) { return TESTS.number(x) && (x=+x) === ~~x; },
number: function(x) { return !isNaN(+x) && !util.isDate(x); },
date: function(x) { return !isNaN(Date.parse(x)); }
};
function annotation(data, types) {
if (!types) return data && data[TYPES] || null;
data[TYPES] = types;
}
function type(values, f) {
f = util.$(f);
var v, i, n;
// if data array has type annotations, use them
if (values[TYPES]) {
v = f(values[TYPES]);
if (util.isString(v)) return v;
}
for (i=0, n=values.length; !util.isValid(v) && i<n; ++i) {
v = f ? f(values[i]) : values[i];
}
return util.isDate(v) ? 'date' :
util.isNumber(v) ? 'number' :
util.isBoolean(v) ? 'boolean' :
util.isString(v) ? 'string' : null;
}
function typeAll(data, fields) {
if (!data.length) return;
fields = fields || util.keys(data[0]);
return fields.reduce(function(types, f) {
return (types[f] = type(data, f), types);
}, {});
}
function infer(values, f) {
f = util.$(f);
var i, j, v;
// types to test for, in precedence order
var types = ['boolean', 'integer', 'number', 'date'];
for (i=0; i<values.length; ++i) {
// get next value to test
v = f ? f(values[i]) : values[i];
// test value against remaining types
for (j=0; j<types.length; ++j) {
if (util.isValid(v) && !TESTS[types[j]](v)) {
types.splice(j, 1);
j -= 1;
}
}
// if no types left, return 'string'
if (types.length === 0) return 'string';
}
return types[0];
}
function inferAll(data, fields) {
fields = fields || util.keys(data[0]);
return fields.reduce(function(types, f) {
types[f] = infer(data, f);
return types;
}, {});
}
type.annotation = annotation;
type.all = typeAll;
type.infer = infer;
type.inferAll = inferAll;
type.parsers = PARSERS;
module.exports = type;
},{"../util":28}],23:[function(require,module,exports){
var util = require('./util');
var dl = {
version: '1.4.6',
load: require('./import/load'),
read: require('./import/read'),
type: require('./import/type'),
Aggregator: require('./aggregate/aggregator'),
groupby: require('./aggregate/groupby'),
bins: require('./bins/bins'),
$bin: require('./bins/histogram').$bin,
histogram: require('./bins/histogram').histogram,
format: require('./format'),
print: require('./print'),
template: require('./template'),
time: require('./time')
};
util.extend(dl, util);
util.extend(dl, require('./generate'));
util.extend(dl, require('./stats'));
util.extend(dl, require('./import/readers'));
module.exports = dl;
},{"./aggregate/aggregator":6,"./aggregate/groupby":8,"./bins/bins":10,"./bins/histogram":11,"./format":12,"./generate":13,"./import/load":19,"./import/read":20,"./import/readers":21,"./import/type":22,"./print":24,"./stats":25,"./template":26,"./time":27,"./util":28}],24:[function(require,module,exports){
var util = require('./util');
var type = require('./import/type');
var stats = require('./stats');
var template = require('./template');
var FMT = {
'date': '|time:"%m/%d/%Y %H:%M:%S"',
'number': '|number:".4f"',
'integer': '|number:"d"'
};
var POS = {
'number': 'left',
'integer': 'left'
};
module.exports.table = function(data, opt) {
opt = util.extend({separator:' ', minwidth: 8, maxwidth: 15}, opt);
var fields = opt.fields || util.keys(data[0]),
types = type.all(data);
if (opt.start || opt.limit) {
var a = opt.start || 0,
b = opt.limit ? a + opt.limit : data.length;
data = data.slice(a, b);
}
// determine char width of fields
var lens = fields.map(function(name) {
var format = FMT[types[name]] || '',
t = template('{{' + name + format + '}}'),
l = stats.max(data, function(x) { return t(x).length; });
l = Math.max(Math.min(name.length, opt.minwidth), l);
return opt.maxwidth > 0 ? Math.min(l, opt.maxwidth) : l;
});
// print header row
var head = fields.map(function(name, i) {
return util.truncate(util.pad(name, lens[i], 'center'), lens[i]);
}).join(opt.separator);
// build template function for each row
var tmpl = template(fields.map(function(name, i) {
return '{{' +
name +
(FMT[types[name]] || '') +
('|pad:' + lens[i] + ',' + (POS[types[name]] || 'right')) +
('|truncate:' + lens[i]) +
'}}';
}).join(opt.separator));
// print table
return head + "\n" + data.map(tmpl).join('\n');
};
module.exports.summary = function(s) {
s = s ? s.__summary__ ? s : stats.summary(s) : this;
var str = [], i, n;
for (i=0, n=s.length; i<n; ++i) {
str.push('-- ' + s[i].field + ' --');
if (s[i].type === 'string' || s[i].distinct < 10) {
str.push(printCategoricalProfile(s[i]));
} else {
str.push(printQuantitativeProfile(s[i]));
}
str.push('');
}
return str.join('\n');
};
function printQuantitativeProfile(p) {
return [
'valid: ' + p.valid,
'missing: ' + p.missing,
'distinct: ' + p.distinct,
'min: ' + p.min,
'max: ' + p.max,
'median: ' + p.median,
'mean: ' + p.mean,
'stdev: ' + p.stdev,
'modeskew: ' + p.modeskew
].join('\n');
}
function printCategoricalProfile(p) {
var list = [
'valid: ' + p.valid,
'missing: ' + p.missing,
'distinct: ' + p.distinct,
'top values: '
];
var u = p.unique;
var top = util.keys(u)
.sort(function(a,b) { return u[b] - u[a]; })
.slice(0, 6)
.map(function(v) { return ' \'' + v + '\' (' + u[v] + ')'; });
return list.concat(top).join('\n');
}
},{"./import/type":22,"./stats":25,"./template":26,"./util":28}],25:[function(require,module,exports){
var util = require('./util');
var type = require('./import/type');
var gen = require('./generate');
var stats = {};
// Collect unique values.
// Output: an array of unique values, in first-observed order
stats.unique = function(values, f, results) {
f = util.$(f);
results = results || [];
var u = {}, v, i, n;
for (i=0, n=values.length; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (v in u) continue;
u[v] = 1;
results.push(v);
}
return results;
};
// Return the length of the input array.
stats.count = function(values) {
return values && values.length || 0;
};
// Count the number of non-null, non-undefined, non-NaN values.
stats.count.valid = function(values, f) {
f = util.$(f);
var v, i, n, valid = 0;
for (i=0, n=values.length; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) valid += 1;
}
return valid;
};
// Count the number of null or undefined values.
stats.count.missing = function(values, f) {
f = util.$(f);
var v, i, n, count = 0;
for (i=0, n=values.length; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (v == null) count += 1;
}
return count;
};
// Count the number of distinct values.
// Null, undefined and NaN are each considered distinct values.
stats.count.distinct = function(values, f) {
f = util.$(f);
var u = {}, v, i, n, count = 0;
for (i=0, n=values.length; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (v in u) continue;
u[v] = 1;
count += 1;
}
return count;
};
// Construct a map from distinct values to occurrence counts.
stats.count.map = function(values, f) {
f = util.$(f);
var map = {}, v, i, n;
for (i=0, n=values.length; i<n; ++i) {
v = f ? f(values[i]) : values[i];
map[v] = (v in map) ? map[v] + 1 : 1;
}
return map;
};
// Compute the median of an array of numbers.
stats.median = function(values, f) {
if (f) values = values.map(util.$(f));
values = values.filter(util.isValid).sort(util.cmp);
return stats.quantile(values, 0.5);
};
// Computes the quartile boundaries of an array of numbers.
stats.quartile = function(values, f) {
if (f) values = values.map(util.$(f));
values = values.filter(util.isValid).sort(util.cmp);
var q = stats.quantile;
return [q(values, 0.25), q(values, 0.50), q(values, 0.75)];
};
// Compute the quantile of a sorted array of numbers.
// Adapted from the D3.js implementation.
stats.quantile = function(values, f, p) {
if (p === undefined) { p = f; f = util.identity; }
f = util.$(f);
var H = (values.length - 1) * p + 1,
h = Math.floor(H),
v = +f(values[h - 1]),
e = H - h;
return e ? v + e * (f(values[h]) - v) : v;
};
// Compute the sum of an array of numbers.
stats.sum = function(values, f) {
f = util.$(f);
for (var sum=0, i=0, n=values.length, v; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) sum += v;
}
return sum;
};
// Compute the mean (average) of an array of numbers.
stats.mean = function(values, f) {
f = util.$(f);
var mean = 0, delta, i, n, c, v;
for (i=0, c=0, n=values.length; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) {
delta = v - mean;
mean = mean + delta / (++c);
}
}
return mean;
};
// Compute the sample variance of an array of numbers.
stats.variance = function(values, f) {
f = util.$(f);
if (!util.isArray(values) || values.length < 2) return 0;
var mean = 0, M2 = 0, delta, i, c, v;
for (i=0, c=0; i<values.length; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) {
delta = v - mean;
mean = mean + delta / (++c);
M2 = M2 + delta * (v - mean);
}
}
M2 = M2 / (c - 1);
return M2;
};
// Compute the sample standard deviation of an array of numbers.
stats.stdev = function(values, f) {
return Math.sqrt(stats.variance(values, f));
};
// Compute the Pearson mode skewness ((median-mean)/stdev) of an array of numbers.
stats.modeskew = function(values, f) {
var avg = stats.mean(values, f),
med = stats.median(values, f),
std = stats.stdev(values, f);
return std === 0 ? 0 : (avg - med) / std;
};
// Find the minimum value in an array.
stats.min = function(values, f) {
return stats.extent(values, f)[0];
};
// Find the maximum value in an array.
stats.max = function(values, f) {
return stats.extent(values, f)[1];
};
// Find the minimum and maximum of an array of values.
stats.extent = function(values, f) {
f = util.$(f);
var a, b, v, i, n = values.length;
for (i=0; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) { a = b = v; break; }
}
for (; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) {
if (v < a) a = v;
if (v > b) b = v;
}
}
return [a, b];
};
// Find the integer indices of the minimum and maximum values.
stats.extent.index = function(values, f) {
f = util.$(f);
var x = -1, y = -1, a, b, v, i, n = values.length;
for (i=0; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) { a = b = v; x = y = i; break; }
}
for (; i<n; ++i) {
v = f ? f(values[i]) : values[i];
if (util.isValid(v)) {
if (v < a) { a = v; x = i; }
if (v > b) { b = v; y = i; }
}
}
return [x, y];
};
// Compute the dot product of two arrays of numbers.
stats.dot = function(values, a, b) {
var sum = 0, i, v;
if (!b) {
if (values.length !== a.length) {
throw Error('Array lengths must match.');
}
for (i=0; i<values.length; ++i) {
v = values[i] * a[i];
if (v === v) sum += v;
}
} else {
a = util.$(a);
b = util.$(b);
for (i=0; i<values.length; ++i) {
v = a(values[i]) * b(values[i]);
if (v === v) sum += v;
}
}
return sum;
};
// Compute ascending rank scores for an array of values.
// Ties are assigned their collective mean rank.
stats.rank = function(values, f) {
f = util.$(f) || util.identity;
var a = values.map(function(v, i) {
return {idx: i, val: f(v)};
})
.sort(util.comparator('val'));
var n = values.length,
r = Array(n),
tie = -1, p = {}, i, v, mu;
for (i=0; i<n; ++i) {
v = a[i].val;
if (tie < 0 && p === v) {
tie = i - 1;
} else if (tie > -1 && p !== v) {
mu = 1 + (i-1 + tie) / 2;
for (; tie<i; ++tie) r[a[tie].idx] = mu;
tie = -1;
}
r[a[i].idx] = i + 1;
p = v;
}
if (tie > -1) {
mu = 1 + (n-1 + tie) / 2;
for (; tie<n; ++tie) r[a[tie].idx] = mu;
}
return r;
};
// Compute the sample Pearson product-moment correlation of two arrays of numbers.
stats.cor = function(values, a, b) {
var fn = b;
b = fn ? values.map(util.$(b)) : a;
a = fn ? values.map(util.$(a)) : values;
var dot = stats.dot(a, b),
mua = stats.mean(a),
mub = stats.mean(b),
sda = stats.stdev(a),
sdb = stats.stdev(b),
n = values.length;
return (dot - n*mua*mub) / ((n-1) * sda * sdb);
};
// Compute the Spearman rank correlation of two arrays of values.
stats.cor.rank = function(values, a, b) {
var ra = b ? stats.rank(values, util.$(a)) : stats.rank(values),
rb = b ? stats.rank(values, util.$(b)) : stats.rank(a),
n = values.length, i, s, d;
for (i=0, s=0; i<n; ++i) {
d = ra[i] - rb[i];
s += d * d;
}
return 1 - 6*s / (n * (n*n-1));
};
// Compute the distance correlation of two arrays of numbers.
// http://en.wikipedia.org/wiki/Distance_correlation
stats.cor.dist = function(values, a, b) {
var X = b ? values.map(util.$(a)) : values,
Y = b ? values.map(util.$(b)) : a;
var A = stats.dist.mat(X),
B = stats.dist.mat(Y),
n = A.length,
i, aa, bb, ab;
for (i=0, aa=0, bb=0, ab=0; i<n; ++i) {
aa += A[i]*A[i];
bb += B[i]*B[i];
ab += A[i]*B[i];
}
return Math.sqrt(ab / Math.sqrt(aa*bb));
};
// Compute the vector distance between two arrays of numbers.
// Default is Euclidean (exp=2) distance, configurable via exp argument.
stats.dist = function(values, a, b, exp) {
var f = util.isFunction(b) || util.isString(b),
X = values,
Y = f ? values : a,
e = f ? exp : b,
L2 = e === 2 || e == null,
n = values.length, s = 0, d, i;
if (f) {
a = util.$(a);
b = util.$(b);
}
for (i=0; i<n; ++i) {
d = f ? (a(X[i])-b(Y[i])) : (X[i]-Y[i]);
s += L2 ? d*d : Math.pow(Math.abs(d), e);
}
return L2 ? Math.sqrt(s) : Math.pow(s, 1/e);
};
// Construct a mean-centered distance matrix for an array of numbers.
stats.dist.mat = function(X) {
var n = X.length,
m = n*n,
A = Array(m),
R = gen.zeros(n),
M = 0, v, i, j;
for (i=0; i<n; ++i) {
A[i*n+i] = 0;
for (j=i+1; j<n; ++j) {
A[i*n+j] = (v = Math.abs(X[i] - X[j]));
A[j*n+i] = v;
R[i] += v;
R[j] += v;
}
}
for (i=0; i<n; ++i) {
M += R[i];
R[i] /= n;
}
M /= m;
for (i=0; i<n; ++i) {
for (j=i; j<n; ++j) {
A[i*n+j] += M - R[i] - R[j];
A[j*n+i] = A[i*n+j];
}
}
return A;
};
// Compute the Shannon entropy (log base 2) of an array of counts.
stats.entropy = function(counts, f) {
f = util.$(f);
var i, p, s = 0, H = 0, n = counts.length;
for (i=0; i<n; ++i) {
s += (f ? f(counts[i]) : counts[i]);
}
if (s === 0) return 0;
for (i=0; i<n; ++i) {
p = (f ? f(counts[i]) : counts[i]) / s;
if (p) H += p * Math.log(p);
}
return -H / Math.LN2;
};
// Compute the mutual information between two discrete variables.
// Returns an array of the form [MI, MI_distance]
// MI_distance is defined as 1 - I(a,b) / H(a,b).
// http://en.wikipedia.org/wiki/Mutual_information
stats.mutual = function(values, a, b, counts) {
var x = counts ? values.map(util.$(a)) : values,
y = counts ? values.map(util.$(b)) : a,
z = counts ? values.map(util.$(counts)) : b;
var px = {},
py = {},
n = z.length,
s = 0, I = 0, H = 0, p, t, i;
for (i=0; i<n; ++i) {
px[x[i]] = 0;
py[y[i]] = 0;
}
for (i=0; i<n; ++i) {
px[x[i]] += z[i];
py[y[i]] += z[i];
s += z[i];
}
t = 1 / (s * Math.LN2);
for (i=0; i<n; ++i) {
if (z[i] === 0) continue;
p = (s * z[i]) / (px[x[i]] * py[y[i]]);
I += z[i] * t * Math.log(p);
H += z[i] * t * Math.log(z[i]/s);
}
return [I, 1 + I/H];
};
// Compute the mutual information between two discrete variables.
stats.mutual.info = function(values, a, b, counts) {
return stats.mutual(values, a, b, counts)[0];
};
// Compute the mutual information distance between two discrete variables.
// MI_distance is defined as 1 - I(a,b) / H(a,b).
stats.mutual.dist = function(values, a, b, counts) {
return stats.mutual(values, a, b, counts)[1];
};
// Compute a profile of summary statistics for a variable.
stats.profile = function(values, f) {
var mean = 0,
valid = 0,
missing = 0,
distinct = 0,
min = null,
max = null,
M2 = 0,
vals = [],
u = {}, delta, sd, i, v, x;
// compute summary stats
for (i=0; i<values.length; ++i) {
v = f ? f(values[i]) : values[i];
// update unique values
u[v] = (v in u) ? u[v] + 1 : (distinct += 1, 1);
if (v == null) {
++missing;
} else if (util.isValid(v)) {
// update stats
x = (typeof v === 'string') ? v.length : v;
if (min===null || x < min) min = x;
if (max===null || x > max) max = x;
delta = x - mean;
mean = mean + delta / (++valid);
M2 = M2 + delta * (x - mean);
vals.push(x);
}
}
M2 = M2 / (valid - 1);
sd = Math.sqrt(M2);
// sort values for median and iqr
vals.sort(util.cmp);
return {
type: type(values, f),
unique: u,
count: values.length,
valid: valid,
missing: missing,
distinct: distinct,
min: min,
max: max,
mean: mean,
stdev: sd,
median: (v = stats.quantile(vals, 0.5)),
q1: stats.quantile(vals, 0.25),
q3: stats.quantile(vals, 0.75),
modeskew: sd === 0 ? 0 : (mean - v) / sd
};
};
// Compute profiles for all variables in a data set.
stats.summary = function(data, fields) {
fields = fields || util.keys(data[0]);
var s = fields.map(function(f) {
var p = stats.profile(data, util.$(f));
return (p.field = f, p);
});
return (s.__summary__ = true, s);
};
module.exports = stats;
},{"./generate":13,"./import/type":22,"./util":28}],26:[function(require,module,exports){
var util = require('./util'),
format = require('./format');
var context = {
formats: [],
format_map: {},
truncate: util.truncate,
pad: util.pad
};
function template(text) {
var src = source(text, 'd');
src = 'var __t; return ' + src + ';';
/* jshint evil: true */
return (new Function('d', src)).bind(context);
}
template.source = source;
template.context = context;
module.exports = template;
// Clear cache of format objects.
// This can *break* prior template functions, so invoke with care!
template.clearFormatCache = function() {
context.formats = [];
context.format_map = {};
};
// Generate property access code for use within template source.
// object: the name of the object (variable) containing template data
// property: the property access string, verbatim from template tag
template.property = function(object, property) {
var src = util.field(property).map(util.str).join('][');
return object + '[' + src + ']';
};
// Generate source code for a template function.
// text: the template text
// variable: the name of the data object variable ('obj' by default)
// properties: optional hash for collecting all accessed properties
function source(text, variable, properties) {
variable = variable || 'obj';
var index = 0;
var src = '\'';
var regex = template_re;
// Compile the template source, escaping string literals appropriately.
text.replace(regex, function(match, interpolate, offset) {
src += text
.slice(index, offset)
.replace(template_escaper, template_escapeChar);
index = offset + match.length;
if (interpolate) {
src += '\'\n+((__t=(' +
template_var(interpolate, variable, properties) +
'))==null?\'\':__t)+\n\'';
}
// Adobe VMs need the match returned to produce the correct offest.
return match;
});
return src + '\'';
}
function template_var(text, variable, properties) {
var filters = text.match(filter_re);
var prop = filters.shift().trim();
var stringCast = true;
function strcall(fn) {
fn = fn || '';
if (stringCast) {
stringCast = false;
src = 'String(' + src + ')' + fn;
} else {
src += fn;
}
return src;
}
function date() {
return '(typeof ' + src + '==="number"?new Date('+src+'):'+src+')';
}
function number_format(fmt, key) {
a = template_format(args[0], key, fmt);
stringCast = false;
src = 'this.formats['+a+']('+src+')';
}
function time_format(fmt, key) {
a = template_format(args[0], key, fmt);
stringCast = false;
src = 'this.formats['+a+']('+date()+')';
}
if (properties) properties[prop] = 1;
var src = template.property(variable, prop);
for (var i=0; i<filters.length; ++i) {
var f = filters[i], args = null, pidx, a, b;
if ((pidx=f.indexOf(':')) > 0) {
f = f.slice(0, pidx);
args = filters[i].slice(pidx+1)
.match(args_re)
.map(function(s) { return s.trim(); });
}
f = f.trim();
switch (f) {
case 'length':
strcall('.length');
break;
case 'lower':
strcall('.toLowerCase()');
break;
case 'upper':
strcall('.toUpperCase()');
break;
case 'lower-locale':
strcall('.toLocaleLowerCase()');
break;
case 'upper-locale':
strcall('.toLocaleUpperCase()');
break;
case 'trim':
strcall('.trim()');
break;
case 'left':
a = util.number(args[0]);
strcall('.slice(0,' + a + ')');
break;
case 'right':
a = util.number(args[0]);
strcall('.slice(-' + a +')');
break;
case 'mid':
a = util.number(args[0]);
b = a + util.number(args[1]);
strcall('.slice(+'+a+','+b+')');
break;
case 'slice':
a = util.number(args[0]);
strcall('.slice('+ a +
(args.length > 1 ? ',' + util.number(args[1]) : '') +
')');
break;
case 'truncate':
a = util.number(args[0]);
b = args[1];
b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b;
src = 'this.truncate(' + strcall() + ',' + a + ',\'' + b + '\')';
break;
case 'pad':
a = util.number(args[0]);
b = args[1];
b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b;
src = 'this.pad(' + strcall() + ',' + a + ',\'' + b + '\')';
break;
case 'number':
number_format(format.number, 'number');
break;
case 'time':
time_format(format.time, 'time');
break;
case 'time-utc':
time_format(format.utc, 'time-utc');
break;
default:
throw Error('Unrecognized template filter: ' + f);
}
}
return src;
}
var template_re = /\{\{(.+?)\}\}|$/g,
filter_re = /(?:"[^"]*"|\'[^\']*\'|[^\|"]+|[^\|\']+)+/g,
args_re = /(?:"[^"]*"|\'[^\']*\'|[^,"]+|[^,\']+)+/g;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var template_escapes = {
'\'': '\'',
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var template_escaper = /\\|'|\r|\n|\u2028|\u2029/g;
function template_escapeChar(match) {
return '\\' + template_escapes[match];
}
function template_format(pattern, key, fmt) {
if ((pattern[0] === '\'' && pattern[pattern.length-1] === '\'') ||
(pattern[0] === '"' && pattern[pattern.length-1] === '"')) {
pattern = pattern.slice(1, -1);
} else {
throw Error('Format pattern must be quoted: ' + pattern);
}
key = key + ':' + pattern;
if (!context.format_map[key]) {
var f = fmt(pattern);
var i = context.formats.length;
context.formats.push(f);
context.format_map[key] = i;
}
return context.format_map[key];
}
},{"./format":12,"./util":28}],27:[function(require,module,exports){
var d3_time = require('d3-time');
var tempDate = new Date(),
baseDate = new Date(0, 0, 1).setFullYear(0), // Jan 1, 0 AD
utcBaseDate = new Date(Date.UTC(0, 0, 1)).setUTCFullYear(0);
function date(d) {
return (tempDate.setTime(+d), tempDate);
}
// create a time unit entry
function entry(type, date, unit, step, min, max) {
var e = {
type: type,
date: date,
unit: unit
};
if (step) {
e.step = step;
} else {
e.minstep = 1;
}
if (min != null) e.min = min;
if (max != null) e.max = max;
return e;
}
function create(type, unit, base, step, min, max) {
return entry(type,
function(d) { return unit.offset(base, d); },
function(d) { return unit.count(base, d); },
step, min, max);
}
var locale = [
create('second', d3_time.second, baseDate),
create('minute', d3_time.minute, baseDate),
create('hour', d3_time.hour, baseDate),
create('day', d3_time.day, baseDate, [1, 7]),
create('month', d3_time.month, baseDate, [1, 3, 6]),
create('year', d3_time.year, baseDate),
// periodic units
entry('seconds',
function(d) { return new Date(1970, 0, 1, 0, 0, d); },
function(d) { return date(d).getSeconds(); },
null, 0, 59
),
entry('minutes',
function(d) { return new Date(1970, 0, 1, 0, d); },
function(d) { return date(d).getMinutes(); },
null, 0, 59
),
entry('hours',
function(d) { return new Date(1970, 0, 1, d); },
function(d) { return date(d).getHours(); },
null, 0, 23
),
entry('weekdays',
function(d) { return new Date(1970, 0, 4+d); },
function(d) { return date(d).getDay(); },
[1], 0, 6
),
entry('dates',
function(d) { return new Date(1970, 0, d); },
function(d) { return date(d).getDate(); },
[1], 1, 31
),
entry('months',
function(d) { return new Date(1970, d % 12, 1); },
function(d) { return date(d).getMonth(); },
[1], 0, 11
)
];
var utc = [
create('second', d3_time.utcSecond, utcBaseDate),
create('minute', d3_time.utcMinute, utcBaseDate),
create('hour', d3_time.utcHour, utcBaseDate),
create('day', d3_time.utcDay, utcBaseDate, [1, 7]),
create('month', d3_time.utcMonth, utcBaseDate, [1, 3, 6]),
create('year', d3_time.utcYear, utcBaseDate),
// periodic units
entry('seconds',
function(d) { return new Date(Date.UTC(1970, 0, 1, 0, 0, d)); },
function(d) { return date(d).getUTCSeconds(); },
null, 0, 59
),
entry('minutes',
function(d) { return new Date(Date.UTC(1970, 0, 1, 0, d)); },
function(d) { return date(d).getUTCMinutes(); },
null, 0, 59
),
entry('hours',
function(d) { return new Date(Date.UTC(1970, 0, 1, d)); },
function(d) { return date(d).getUTCHours(); },
null, 0, 23
),
entry('weekdays',
function(d) { return new Date(Date.UTC(1970, 0, 4+d)); },
function(d) { return date(d).getUTCDay(); },
[1], 0, 6
),
entry('dates',
function(d) { return new Date(Date.UTC(1970, 0, d)); },
function(d) { return date(d).getUTCDate(); },
[1], 1, 31
),
entry('months',
function(d) { return new Date(Date.UTC(1970, d % 12, 1)); },
function(d) { return date(d).getUTCMonth(); },
[1], 0, 11
)
];
var STEPS = [
[31536e6, 5], // 1-year
[7776e6, 4], // 3-month
[2592e6, 4], // 1-month
[12096e5, 3], // 2-week
[6048e5, 3], // 1-week
[1728e5, 3], // 2-day
[864e5, 3], // 1-day
[432e5, 2], // 12-hour
[216e5, 2], // 6-hour
[108e5, 2], // 3-hour
[36e5, 2], // 1-hour
[18e5, 1], // 30-minute
[9e5, 1], // 15-minute
[3e5, 1], // 5-minute
[6e4, 1], // 1-minute
[3e4, 0], // 30-second
[15e3, 0], // 15-second
[5e3, 0], // 5-second
[1e3, 0] // 1-second
];
function find(units, span, minb, maxb) {
var step = STEPS[0], i, n, bins;
for (i=1, n=STEPS.length; i<n; ++i) {
step = STEPS[i];
if (span > step[0]) {
bins = span / step[0];
if (bins > maxb) {
return units[STEPS[i-1][1]];
}
if (bins >= minb) {
return units[step[1]];
}
}
}
return units[STEPS[n-1][1]];
}
function toUnitMap(units) {
var map = {}, i, n;
for (i=0, n=units.length; i<n; ++i) {
map[units[i].type] = units[i];
}
map.find = function(span, minb, maxb) {
return find(units, span, minb, maxb);
};
return map;
}
module.exports = toUnitMap(locale);
module.exports.utc = toUnitMap(utc);
},{"d3-time":5}],28:[function(require,module,exports){
var buffer = require('buffer'),
time = require('./time'),
utc = time.utc;
var u = module.exports = {};
// utility functions
var FNAME = '__name__';
u.namedfunc = function(name, f) { return (f[FNAME] = name, f); };
u.name = function(f) { return f==null ? null : f[FNAME]; };
u.identity = function(x) { return x; };
u.true = u.namedfunc('true', function() { return true; });
u.false = u.namedfunc('false', function() { return false; });
u.duplicate = function(obj) {
return JSON.parse(JSON.stringify(obj));
};
u.equal = function(a, b) {
return JSON.stringify(a) === JSON.stringify(b);
};
u.extend = function(obj) {
for (var x, name, i=1, len=arguments.length; i<len; ++i) {
x = arguments[i];
for (name in x) { obj[name] = x[name]; }
}
return obj;
};
u.length = function(x) {
return x != null && x.length != null ? x.length : null;
};
u.keys = function(x) {
var keys = [], k;
for (k in x) keys.push(k);
return keys;
};
u.vals = function(x) {
var vals = [], k;
for (k in x) vals.push(x[k]);
return vals;
};
u.toMap = function(list, f) {
return (f = u.$(f)) ?
list.reduce(function(obj, x) { return (obj[f(x)] = 1, obj); }, {}) :
list.reduce(function(obj, x) { return (obj[x] = 1, obj); }, {});
};
u.keystr = function(values) {
// use to ensure consistent key generation across modules
var n = values.length;
if (!n) return '';
for (var s=String(values[0]), i=1; i<n; ++i) {
s += '|' + String(values[i]);
}
return s;
};
// type checking functions
var toString = Object.prototype.toString;
u.isObject = function(obj) {
return obj === Object(obj);
};
u.isFunction = function(obj) {
return toString.call(obj) === '[object Function]';
};
u.isString = function(obj) {
return typeof value === 'string' || toString.call(obj) === '[object String]';
};
u.isArray = Array.isArray || function(obj) {
return toString.call(obj) === '[object Array]';
};
u.isNumber = function(obj) {
return typeof obj === 'number' || toString.call(obj) === '[object Number]';
};
u.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
};
u.isDate = function(obj) {
return toString.call(obj) === '[object Date]';
};
u.isValid = function(obj) {
return obj != null && obj === obj;
};
u.isBuffer = (buffer.Buffer && buffer.Buffer.isBuffer) || u.false;
// type coercion functions
u.number = function(s) {
return s == null || s === '' ? null : +s;
};
u.boolean = function(s) {
return s == null || s === '' ? null : s==='false' ? false : !!s;
};
u.date = function(s) {
return s == null || s === '' ? null : Date.parse(s);
};
u.array = function(x) {
return x != null ? (u.isArray(x) ? x : [x]) : [];
};
u.str = function(x) {
return u.isArray(x) ? '[' + x.map(u.str) + ']'
: u.isObject(x) ? JSON.stringify(x)
: u.isString(x) ? ('\''+util_escape_str(x)+'\'') : x;
};
var escape_str_re = /(^|[^\\])'/g;
function util_escape_str(x) {
return x.replace(escape_str_re, '$1\\\'');
}
// data access functions
var field_re = /\[(.*?)\]|[^.\[]+/g;
u.field = function(f) {
return String(f).match(field_re).map(function(d) {
return d[0] !== '[' ? d :
d[1] !== "'" && d[1] !== '"' ? d.slice(1, -1) :
d.slice(2, -2).replace(/\\(["'])/g, '$1');
});
};
u.accessor = function(f) {
var s;
return f==null || u.isFunction(f) ? f :
u.namedfunc(f, (s = u.field(f)).length > 1 ?
function(x) { return s.reduce(function(x,f) { return x[f]; }, x); } :
function(x) { return x[f]; }
);
};
// short-cut for accessor
u.$ = u.accessor;
u.mutator = function(f) {
var s;
return u.isString(f) && (s=u.field(f)).length > 1 ?
function(x, v) {
for (var i=0; i<s.length-1; ++i) x = x[s[i]];
x[s[i]] = v;
} :
function(x, v) { x[f] = v; };
};
u.$func = function(name, op) {
return function(f) {
f = u.$(f) || u.identity;
var n = name + (u.name(f) ? '_'+u.name(f) : '');
return u.namedfunc(n, function(d) { return op(f(d)); });
};
};
u.$valid = u.$func('valid', u.isValid);
u.$length = u.$func('length', u.length);
u.$in = function(f, values) {
f = u.$(f);
var map = u.isArray(values) ? u.toMap(values) : values;
return function(d) { return !!map[f(d)]; };
};
u.$year = u.$func('year', time.year.unit);
u.$month = u.$func('month', time.months.unit);
u.$date = u.$func('date', time.dates.unit);
u.$day = u.$func('day', time.weekdays.unit);
u.$hour = u.$func('hour', time.hours.unit);
u.$minute = u.$func('minute', time.minutes.unit);
u.$second = u.$func('second', time.seconds.unit);
u.$utcYear = u.$func('utcYear', utc.year.unit);
u.$utcMonth = u.$func('utcMonth', utc.months.unit);
u.$utcDate = u.$func('utcDate', utc.dates.unit);
u.$utcDay = u.$func('utcDay', utc.weekdays.unit);
u.$utcHour = u.$func('utcHour', utc.hours.unit);
u.$utcMinute = u.$func('utcMinute', utc.minutes.unit);
u.$utcSecond = u.$func('utcSecond', utc.seconds.unit);
// comparison / sorting functions
u.comparator = function(sort) {
var sign = [];
if (sort === undefined) sort = [];
sort = u.array(sort).map(function(f) {
var s = 1;
if (f[0] === '-') { s = -1; f = f.slice(1); }
else if (f[0] === '+') { s = +1; f = f.slice(1); }
sign.push(s);
return u.accessor(f);
});
return function(a,b) {
var i, n, f, x, y;
for (i=0, n=sort.length; i<n; ++i) {
f = sort[i]; x = f(a); y = f(b);
if (x < y) return -1 * sign[i];
if (x > y) return sign[i];
}
return 0;
};
};
u.cmp = function(a, b) {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else if (a >= b) {
return 0;
} else if (a === null) {
return -1;
} else if (b === null) {
return 1;
}
return NaN;
};
u.numcmp = function(a, b) { return a - b; };
u.stablesort = function(array, sortBy, keyFn) {
var indices = array.reduce(function(idx, v, i) {
return (idx[keyFn(v)] = i, idx);
}, {});
array.sort(function(a, b) {
var sa = sortBy(a),
sb = sortBy(b);
return sa < sb ? -1 : sa > sb ? 1
: (indices[keyFn(a)] - indices[keyFn(b)]);
});
return array;
};
// string functions
u.pad = function(s, length, pos, padchar) {
padchar = padchar || " ";
var d = length - s.length;
if (d <= 0) return s;
switch (pos) {
case 'left':
return strrep(d, padchar) + s;
case 'middle':
case 'center':
return strrep(Math.floor(d/2), padchar) +
s + strrep(Math.ceil(d/2), padchar);
default:
return s + strrep(d, padchar);
}
};
function strrep(n, str) {
var s = "", i;
for (i=0; i<n; ++i) s += str;
return s;
}
u.truncate = function(s, length, pos, word, ellipsis) {
var len = s.length;
if (len <= length) return s;
ellipsis = ellipsis !== undefined ? String(ellipsis) : '\u2026';
var l = Math.max(0, length - ellipsis.length);
switch (pos) {
case 'left':
return ellipsis + (word ? truncateOnWord(s,l,1) : s.slice(len-l));
case 'middle':
case 'center':
var l1 = Math.ceil(l/2), l2 = Math.floor(l/2);
return (word ? truncateOnWord(s,l1) : s.slice(0,l1)) +
ellipsis + (word ? truncateOnWord(s,l2,1) : s.slice(len-l2));
default:
return (word ? truncateOnWord(s,l) : s.slice(0,l)) + ellipsis;
}
};
function truncateOnWord(s, len, rev) {
var cnt = 0, tok = s.split(truncate_word_re);
if (rev) {
s = (tok = tok.reverse())
.filter(function(w) { cnt += w.length; return cnt <= len; })
.reverse();
} else {
s = tok.filter(function(w) { cnt += w.length; return cnt <= len; });
}
return s.length ? s.join('').trim() : tok[0].slice(0, len);
}
var truncate_word_re = /([\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u2028\u2029\u3000\uFEFF])/;
},{"./time":27,"buffer":1}]},{},[23])(23)
});
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2QzLWRzdi9idWlsZC9kc3YuanMiLCJub2RlX21vZHVsZXMvZDMtZm9ybWF0L2J1aWxkL2Zvcm1hdC5qcyIsIm5vZGVfbW9kdWxlcy9kMy10aW1lLWZvcm1hdC9idWlsZC90aW1lRm9ybWF0LmpzIiwibm9kZV9tb2R1bGVzL2QzLXRpbWUvYnVpbGQvdGltZS5qcyIsInNyYy9hZ2dyZWdhdGUvYWdncmVnYXRvci5qcyIsInNyYy9hZ2dyZWdhdGUvY29sbGVjdG9yLmpzIiwic3JjL2FnZ3JlZ2F0ZS9ncm91cGJ5LmpzIiwic3JjL2FnZ3JlZ2F0ZS9tZWFzdXJlcy5qcyIsInNyYy9iaW5zL2JpbnMuanMiLCJzcmMvYmlucy9oaXN0b2dyYW0uanMiLCJzcmMvZm9ybWF0LmpzIiwic3JjL2dlbmVyYXRlLmpzIiwic3JjL2ltcG9ydC9mb3JtYXRzL2Rzdi5qcyIsInNyYy9pbXBvcnQvZm9ybWF0cy9pbmRleC5qcyIsInNyYy9pbXBvcnQvZm9ybWF0cy9qc29uLmpzIiwic3JjL2ltcG9ydC9mb3JtYXRzL3RvcG9qc29uLmpzIiwic3JjL2ltcG9ydC9mb3JtYXRzL3RyZWVqc29uLmpzIiwic3JjL2ltcG9ydC9sb2FkLmpzIiwic3JjL2ltcG9ydC9yZWFkLmpzIiwic3JjL2ltcG9ydC9yZWFkZXJzLmpzIiwic3JjL2ltcG9ydC90eXBlLmpzIiwic3JjL2luZGV4LmpzIiwic3JjL3ByaW50LmpzIiwic3JjL3N0YXRzLmpzIiwic3JjL3RlbXBsYXRlLmpzIiwic3JjL3RpbWUuanMiLCJzcmMvdXRpbC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxY0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMTRCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLG51bGwsIihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IGZhY3RvcnkoZXhwb3J0cykgOlxuICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJ10sIGZhY3RvcnkpIDpcbiAgZmFjdG9yeSgoZ2xvYmFsLmRzdiA9IHt9KSk7XG59KHRoaXMsIGZ1bmN0aW9uIChleHBvcnRzKSB7ICd1c2Ugc3RyaWN0JztcblxuICB2YXIgZHN2ID0gZnVuY3Rpb24oZGVsaW1pdGVyKSB7XG4gICAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cChcIltcXFwiXCIgKyBkZWxpbWl0ZXIgKyBcIlxcbl1cIiksXG4gICAgICAgIGRlbGltaXRlckNvZGUgPSBkZWxpbWl0ZXIuY2hhckNvZGVBdCgwKTtcblxuICAgIGZ1bmN0aW9uIHBhcnNlKHRleHQsIGYpIHtcbiAgICAgIHZhciBvO1xuICAgICAgcmV0dXJuIHBhcnNlUm93cyh0ZXh0LCBmdW5jdGlvbihyb3csIGkpIHtcbiAgICAgICAgaWYgKG8pIHJldHVybiBvKHJvdywgaSAtIDEpO1xuICAgICAgICB2YXIgYSA9IG5ldyBGdW5jdGlvbihcImRcIiwgXCJyZXR1cm4ge1wiICsgcm93Lm1hcChmdW5jdGlvbihuYW1lLCBpKSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG5hbWUpICsgXCI6IGRbXCIgKyBpICsgXCJdXCI7XG4gICAgICAgIH0pLmpvaW4oXCIsXCIpICsgXCJ9XCIpO1xuICAgICAgICBvID0gZiA/IGZ1bmN0aW9uKHJvdywgaSkgeyByZXR1cm4gZihhKHJvdyksIGkpOyB9IDogYTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlUm93cyh0ZXh0LCBmKSB7XG4gICAgICB2YXIgRU9MID0ge30sIC8vIHNlbnRpbmVsIHZhbHVlIGZvciBlbmQtb2YtbGluZVxuICAgICAgICAgIEVPRiA9IHt9LCAvLyBzZW50aW5lbCB2YWx1ZSBmb3IgZW5kLW9mLWZpbGVcbiAgICAgICAgICByb3dzID0gW10sIC8vIG91dHB1dCByb3dzXG4gICAgICAgICAgTiA9IHRleHQubGVuZ3RoLFxuICAgICAgICAgIEkgPSAwLCAvLyBjdXJyZW50IGNoYXJhY3RlciBpbmRleFxuICAgICAgICAgIG4gPSAwLCAvLyB0aGUgY3VycmVudCBsaW5lIG51bWJlclxuICAgICAgICAgIHQsIC8vIHRoZSBjdXJyZW50IHRva2VuXG4gICAgICAgICAgZW9sOyAvLyBpcyB0aGUgY3VycmVudCB0b2tlbiBmb2xsb3dlZCBieSBFT0w/XG5cbiAgICAgIGZ1bmN0aW9uIHRva2VuKCkge1xuICAgICAgICBpZiAoSSA+PSBOKSByZXR1cm4gRU9GOyAvLyBzcGVjaWFsIGNhc2U6IGVuZCBvZiBmaWxlXG4gICAgICAgIGlmIChlb2wpIHJldHVybiBlb2wgPSBmYWxzZSwgRU9MOyAvLyBzcGVjaWFsIGNhc2U6IGVuZCBvZiBsaW5lXG5cbiAgICAgICAgLy8gc3BlY2lhbCBjYXNlOiBxdW90ZXNcbiAgICAgICAgdmFyIGogPSBJO1xuICAgICAgICBpZiAodGV4dC5jaGFyQ29kZUF0KGopID09PSAzNCkge1xuICAgICAgICAgIHZhciBpID0gajtcbiAgICAgICAgICB3aGlsZSAoaSsrIDwgTikge1xuICAgICAgICAgICAgaWYgKHRleHQuY2hhckNvZGVBdChpKSA9PT0gMzQpIHtcbiAgICAgICAgICAgICAgaWYgKHRleHQuY2hhckNvZGVBdChpICsgMSkgIT09IDM0KSBicmVhaztcbiAgICAgICAgICAgICAgKytpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBJID0gaSArIDI7XG4gICAgICAgICAgdmFyIGMgPSB0ZXh0LmNoYXJDb2RlQXQoaSArIDEpO1xuICAgICAgICAgIGlmIChjID09PSAxMykge1xuICAgICAgICAgICAgZW9sID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoaSArIDIpID09PSAxMCkgKytJO1xuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gMTApIHtcbiAgICAgICAgICAgIGVvbCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0ZXh0LnNsaWNlKGogKyAxLCBpKS5yZXBsYWNlKC9cIlwiL2csIFwiXFxcIlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNvbW1vbiBjYXNlOiBmaW5kIG5leHQgZGVsaW1pdGVyIG9yIG5ld2xpbmVcbiAgICAgICAgd2hpbGUgKEkgPCBOKSB7XG4gICAgICAgICAgdmFyIGMgPSB0ZXh0LmNoYXJDb2RlQXQoSSsrKSwgayA9IDE7XG4gICAgICAgICAgaWYgKGMgPT09IDEwKSBlb2wgPSB0cnVlOyAvLyBcXG5cbiAgICAgICAgICBlbHNlIGlmIChjID09PSAxMykgeyBlb2wgPSB0cnVlOyBpZiAodGV4dC5jaGFyQ29kZUF0KEkpID09PSAxMCkgKytJLCArK2s7IH0gLy8gXFxyfFxcclxcblxuICAgICAgICAgIGVsc2UgaWYgKGMgIT09IGRlbGltaXRlckNvZGUpIGNvbnRpbnVlO1xuICAgICAgICAgIHJldHVybiB0ZXh0LnNsaWNlKGosIEkgLSBrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNwZWNpYWwgY2FzZTogbGFzdCB0b2tlbiBiZWZvcmUgRU9GXG4gICAgICAgIHJldHVybiB0ZXh0LnNsaWNlKGopO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAoKHQgPSB0b2tlbigpKSAhPT0gRU9GKSB7XG4gICAgICAgIHZhciBhID0gW107XG4gICAgICAgIHdoaWxlICh0ICE9PSBFT0wgJiYgdCAhPT0gRU9GKSB7XG4gICAgICAgICAgYS5wdXNoKHQpO1xuICAgICAgICAgIHQgPSB0b2tlbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmICYmIChhID0gZihhLCBuKyspKSA9PSBudWxsKSBjb250aW51ZTtcbiAgICAgICAgcm93cy5wdXNoKGEpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcm93cztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmb3JtYXQocm93cykge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkocm93c1swXSkpIHJldHVybiBmb3JtYXRSb3dzKHJvd3MpOyAvLyBkZXByZWNhdGVkOyB1c2UgZm9ybWF0Um93c1xuICAgICAgdmFyIGZpZWxkU2V0ID0gT2JqZWN0LmNyZWF0ZShudWxsKSwgZmllbGRzID0gW107XG5cbiAgICAgIC8vIENvbXB1dGUgdW5pcXVlIGZpZWxkcyBpbiBvcmRlciBvZiBkaXNjb3ZlcnkuXG4gICAgICByb3dzLmZvckVhY2goZnVuY3Rpb24ocm93KSB7XG4gICAgICAgIGZvciAodmFyIGZpZWxkIGluIHJvdykge1xuICAgICAgICAgIGlmICghKChmaWVsZCArPSBcIlwiKSBpbiBmaWVsZFNldCkpIHtcbiAgICAgICAgICAgIGZpZWxkcy5wdXNoKGZpZWxkU2V0W2ZpZWxkXSA9IGZpZWxkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gW2ZpZWxkcy5tYXAoZm9ybWF0VmFsdWUpLmpvaW4oZGVsaW1pdGVyKV0uY29uY2F0KHJvd3MubWFwKGZ1bmN0aW9uKHJvdykge1xuICAgICAgICByZXR1cm4gZmllbGRzLm1hcChmdW5jdGlvbihmaWVsZCkge1xuICAgICAgICAgIHJldHVybiBmb3JtYXRWYWx1ZShyb3dbZmllbGRdKTtcbiAgICAgICAgfSkuam9pbihkZWxpbWl0ZXIpO1xuICAgICAgfSkpLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0Um93cyhyb3dzKSB7XG4gICAgICByZXR1cm4gcm93cy5tYXAoZm9ybWF0Um93KS5qb2luKFwiXFxuXCIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZvcm1hdFJvdyhyb3cpIHtcbiAgICAgIHJldHVybiByb3cubWFwKGZvcm1hdFZhbHVlKS5qb2luKGRlbGltaXRlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0VmFsdWUodGV4dCkge1xuICAgICAgcmV0dXJuIHJlRm9ybWF0LnRlc3QodGV4dCkgPyBcIlxcXCJcIiArIHRleHQucmVwbGFjZSgvXFxcIi9nLCBcIlxcXCJcXFwiXCIpICsgXCJcXFwiXCIgOiB0ZXh0O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwYXJzZTogcGFyc2UsXG4gICAgICBwYXJzZVJvd3M6IHBhcnNlUm93cyxcbiAgICAgIGZvcm1hdDogZm9ybWF0LFxuICAgICAgZm9ybWF0Um93czogZm9ybWF0Um93c1xuICAgIH07XG4gIH1cblxuICBleHBvcnRzLmNzdiA9IGRzdihcIixcIik7XG4gIGV4cG9ydHMudHN2ID0gZHN2KFwiXFx0XCIpO1xuXG4gIGV4cG9ydHMuZHN2ID0gZHN2O1xuXG59KSk7IiwiaWYgKHR5cGVvZiBNYXAgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgTWFwID0gZnVuY3Rpb24oKSB7IHRoaXMuY2xlYXIoKTsgfTtcbiAgTWFwLnByb3RvdHlwZSA9IHtcbiAgICBzZXQ6IGZ1bmN0aW9uKGssIHYpIHsgdGhpcy5fW2tdID0gdjsgcmV0dXJuIHRoaXM7IH0sXG4gICAgZ2V0OiBmdW5jdGlvbihrKSB7IHJldHVybiB0aGlzLl9ba107IH0sXG4gICAgaGFzOiBmdW5jdGlvbihrKSB7IHJldHVybiBrIGluIHRoaXMuXzsgfSxcbiAgICBkZWxldGU6IGZ1bmN0aW9uKGspIHsgcmV0dXJuIGsgaW4gdGhpcy5fICYmIGRlbGV0ZSB0aGlzLl9ba107IH0sXG4gICAgY2xlYXI6IGZ1bmN0aW9uKCkgeyB0aGlzLl8gPSBPYmplY3QuY3JlYXRlKG51bGwpOyB9LFxuICAgIGdldCBzaXplKCkgeyB2YXIgbiA9IDA7IGZvciAodmFyIGsgaW4gdGhpcy5fKSArK247IHJldHVybiBuOyB9LFxuICAgIGZvckVhY2g6IGZ1bmN0aW9uKGMpIHsgZm9yICh2YXIgayBpbiB0aGlzLl8pIGModGhpcy5fW2tdLCBrLCB0aGlzKTsgfVxuICB9O1xufSBlbHNlIChmdW5jdGlvbigpIHtcbiAgdmFyIG0gPSBuZXcgTWFwO1xuICBpZiAobS5zZXQoMCwgMCkgIT09IG0pIHtcbiAgICBtID0gbS5zZXQ7XG4gICAgTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbigpIHsgbS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyByZXR1cm4gdGhpczsgfTtcbiAgfVxufSkoKTtcblxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG4gIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSkgOlxuICBmYWN0b3J5KChnbG9iYWwuZm9ybWF0ID0ge30pKTtcbn0odGhpcywgZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG4gIHZhciB6aENuID0ge1xuICAgIGRlY2ltYWw6IFwiLlwiLFxuICAgIHRob3VzYW5kczogXCIsXCIsXG4gICAgZ3JvdXBpbmc6IFszXSxcbiAgICBjdXJyZW5jeTogW1wiwqVcIiwgXCJcIl1cbiAgfTtcblxuICB2YXIgcnVSdSA9IHtcbiAgICBkZWNpbWFsOiBcIixcIixcbiAgICB0aG91c2FuZHM6IFwiXFx4YTBcIixcbiAgICBncm91cGluZzogWzNdLFxuICAgIGN1cnJlbmN5OiBbXCJcIiwgXCJcXHhhMNGA0YPQsS5cIl1cbiAgfTtcblxuICB2YXIgcHRCciA9IHtcbiAgICBkZWNpbWFsOiBcIixcIixcbiAgICB0aG91c2FuZHM6IFwiLlwiLFxuICAgIGdyb3VwaW5nOiBbM10sXG4gICAgY3VycmVuY3k6IFtcIlIkXCIsIFwiXCJdXG4gIH07XG5cbiAgdmFyIHBsUGwgPSB7XG4gICAgZGVjaW1hbDogXCIsXCIsXG4gICAgdGhvdXNhbmRzOiBcIi5cIixcbiAgICBncm91cGluZzogWzNdLFxuICAgIGN1cnJlbmN5OiBbXCJcIiwgXCJ6xYJcIl1cbiAgfTtcblxuICB2YXIgbmxObCA9IHtcbiAgICBkZWNpbWFsOiBcIixcIixcbiAgICB0aG91c2FuZHM6IFwiLlwiLFxuICAgIGdyb3VwaW5nOiBbM10sXG4gICAgY3VycmVuY3k6IFtcIuKCrFxceGEwXCIsIFwiXCJdXG4gIH07XG5cbiAgdmFyIG1rTWsgPSB7XG4gICAgZGVjaW1hbDogXCIsXCIsXG4gICAgdGhvdXNhbmRzOiBcIi5cIixcbiAgICBncm91cGluZzogWzNdLFxuICAgIGN1cnJlbmN5OiBbXCJcIiwgXCJcXHhhMNC00LXQvS5cIl1cbiAgfTtcblxuICB2YXIgaXRJdCA9IHtcbiAgICBkZWNpbWFsOiBcIixcIixcbiAgICB0aG91c2FuZHM6IFwiLlwiLFxuICAgIGdyb3VwaW5nOiBbM10sXG4gICAgY3VycmVuY3k6IFtcIuKCrFwiLCBcIlwiXVxuICB9O1xuXG4gIHZhciBoZUlsID0ge1xuICAgIGRlY2ltYWw6IFwiLlwiLFxuICAgIHRob3VzYW5kczogXCIsXCIsXG4gICAgZ3JvdXBpbmc6IFszXSxcbiAgICBjdXJyZW5jeTogW1wi4oKqXCIsIFwiXCJdXG4gIH07XG5cbiAgdmFyIGZyRnIgPSB7XG4gICAgZGVjaW1hbDogXCIsXCIsXG4gICAgdGhvdXNhbmRzOiBcIi5cIixcbiAgICBncm91cGluZzogWzNdLFxuICAgIGN1cnJlbmN5OiBbXCJcIiwgXCJcXHhhMOKCrFwiXVxuICB9O1xuXG4gIHZhciBmckNhID0ge1xuICAgIGRlY2ltYWw6IFwiLFwiLFxuICAgIHRob3VzYW5kczogXCJcXHhhMFwiLFxuICAgIGdyb3VwaW5nOiBbM10sXG4gICAgY3VycmVuY3k6IFtcIlwiLCBcIiRcIl1cbiAgfTtcblxuICB2YXIgZmlGaSA9IHtcbiAgICBkZWNpbWFsOiBcIixcIixcbiAgICB0aG91c2FuZHM6IFwiXFx4YTBcIixcbiAgICBncm91cGluZzogWzNdLFxuICAgIGN1cnJlbmN5OiBbXCJcIiwgXCJcXHhhMOKCrFwiXVxuICB9O1xuXG4gIHZhciBlc0VzID0ge1xuICAgIGRlY2ltYWw6IFwiLFwiLFxuICAgIHRob3VzYW5kczogXCIuXCIsXG4gICAgZ3JvdXBpbmc6IFszXSxcbiAgICBjdXJyZW5jeTogW1wiXCIsIFwiXFx4YTDigqxcIl1cbiAgfTtcblxuICB2YXIgZW5VcyA9IHtcbiAgICBkZWNpbWFsOiBcIi5cIixcbiAgICB0aG91c2FuZHM6IFwiLFwiLFxuICAgIGdyb3VwaW5nOiBbM10sXG4gICAgY3VycmVuY3k6IFtcIiRcIiwgXCJcIl1cbiAgfTtcblxuICB2YXIgZW5HYiA9IHtcbiAgICBkZWNpbWFsOiBcIi5cIixcbiAgICB0aG91c2FuZHM6IFwiLFwiLFxuICAgIGdyb3VwaW5nOiBbM10sXG4gICAgY3VycmVuY3k6IFtcIsKjXCIsIFwiXCJdXG4gIH07XG5cbiAgdmFyIGVuQ2EgPSB7XG4gICAgZGVjaW1hbDogXCIuXCIsXG4gICAgdGhvdXNhbmRzOiBcIixcIixcbiAgICBncm91cGluZzogWzNdLFxuICAgIGN1cnJlbmN5OiBbXCIkXCIsIFwiXCJdXG4gIH07XG5cbiAgdmFyIGRlRGUgPSB7XG4gICAgZGVjaW1hbDogXCIsXCIsXG4gICAgdGhvdXNhbmRzOiBcIi5cIixcbiAgICBncm91cGluZzogWzNdLFxuICAgIGN1cnJlbmN5OiBbXCJcIiwgXCJcXHhhMOKCrFwiXVxuICB9O1xuXG4gIHZhciBjYUVzID0ge1xuICAgIGRlY2ltYWw6IFwiLFwiLFxuICAgIHRob3VzYW5kczogXCIuXCIsXG4gICAgZ3JvdXBpbmc6IFszXSxcbiAgICBjdXJyZW5jeTogW1wiXCIsIFwiXFx4YTDigqxcIl1cbiAgfTtcblxuXG4gIC8vIENvbXB1dGVzIHRoZSBkZWNpbWFsIGNvZWZmaWNpZW50IGFuZCBleHBvbmVudCBvZiB0aGUgc3BlY2lmaWVkIG51bWJlciB4IHdpdGhcbiAgLy8gc2lnbmlmaWNhbnQgZGlnaXRzIHAsIHdoZXJlIHggaXMgcG9zaXRpdmUgYW5kIHAgaXMgaW4gWzEsIDIxXSBvciB1bmRlZmluZWQuXG4gIC8vIEZvciBleGFtcGxlLCBmb3JtYXREZWNpbWFsKDEuMjMpIHJldHVybnMgW1wiMTIzXCIsIDBdLlxuICBmdW5jdGlvbiBmb3JtYXREZWNpbWFsKHgsIHApIHtcbiAgICBpZiAoKGkgPSAoeCA9IHAgPyB4LnRvRXhwb25lbnRpYWwocCAtIDEpIDogeC50b0V4cG9uZW50aWFsKCkpLmluZGV4T2YoXCJlXCIpKSA8IDApIHJldHVybiBudWxsOyAvLyBOYU4sIMKxSW5maW5pdHlcbiAgICB2YXIgaSwgY29lZmZpY2llbnQgPSB4LnNsaWNlKDAsIGkpO1xuXG4gICAgLy8gVGhlIHN0cmluZyByZXR1cm5lZCBieSB0b0V4cG9uZW50aWFsIGVpdGhlciBoYXMgdGhlIGZvcm0gXFxkXFwuXFxkK2VbLStdXFxkK1xuICAgIC8vIChlLmcuLCAxLjJlKzMpIG9yIHRoZSBmb3JtIFxcZGVbLStdXFxkKyAoZS5nLiwgMWUrMykuXG4gICAgcmV0dXJuIFtcbiAgICAgIGNvZWZmaWNpZW50Lmxlbmd0aCA+IDEgPyBjb2VmZmljaWVudFswXSArIGNvZWZmaWNpZW50LnNsaWNlKDIpIDogY29lZmZpY2llbnQsXG4gICAgICAreC5zbGljZShpICsgMSlcbiAgICBdO1xuICB9XG5cbiAgZnVuY3Rpb24gZXhwb25lbnQoeCkge1xuICAgIHJldHVybiB4ID0gZm9ybWF0RGVjaW1hbChNYXRoLmFicyh4KSksIHggPyB4WzFdIDogTmFOO1xuICB9XG5cbiAgdmFyIHByZWZpeEV4cG9uZW50O1xuXG4gIGZ1bmN0aW9uIGZvcm1hdFByZWZpeEF1dG8oeCwgcCkge1xuICAgIHZhciBkID0gZm9ybWF0RGVjaW1hbCh4LCBwKTtcbiAgICBpZiAoIWQpIHJldHVybiB4ICsgXCJcIjtcbiAgICB2YXIgY29lZmZpY2llbnQgPSBkWzBdLFxuICAgICAgICBleHBvbmVudCA9IGRbMV0sXG4gICAgICAgIGkgPSBleHBvbmVudCAtIChwcmVmaXhFeHBvbmVudCA9IE1hdGgubWF4KC04LCBNYXRoLm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50IC8gMykpKSAqIDMpICsgMSxcbiAgICAgICAgbiA9IGNvZWZmaWNpZW50Lmxlbmd0aDtcbiAgICByZXR1cm4gaSA9PT0gbiA/IGNvZWZmaWNpZW50XG4gICAgICAgIDogaSA+IG4gPyBjb2VmZmljaWVudCArIG5ldyBBcnJheShpIC0gbiArIDEpLmpvaW4oXCIwXCIpXG4gICAgICAgIDogaSA+IDAgPyBjb2VmZmljaWVudC5zbGljZSgwLCBpKSArIFwiLlwiICsgY29lZmZpY2llbnQuc2xpY2UoaSlcbiAgICAgICAgOiBcIjAuXCIgKyBuZXcgQXJyYXkoMSAtIGkpLmpvaW4oXCIwXCIpICsgZm9ybWF0RGVjaW1hbCh4LCBwICsgaSAtIDEpWzBdOyAvLyBsZXNzIHRoYW4gMXkhXG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRSb3VuZGVkKHgsIHApIHtcbiAgICB2YXIgZCA9IGZvcm1hdERlY2ltYWwoeCwgcCk7XG4gICAgaWYgKCFkKSByZXR1cm4geCArIFwiXCI7XG4gICAgdmFyIGNvZWZmaWNpZW50ID0gZFswXSxcbiAgICAgICAgZXhwb25lbnQgPSBkWzFdO1xuICAgIHJldHVybiBleHBvbmVudCA8IDAgPyBcIjAuXCIgKyBuZXcgQXJyYXkoLWV4cG9uZW50KS5qb2luKFwiMFwiKSArIGNvZWZmaWNpZW50XG4gICAgICAgIDogY29lZmZpY2llbnQubGVuZ3RoID4gZXhwb25lbnQgKyAxID8gY29lZmZpY2llbnQuc2xpY2UoMCwgZXhwb25lbnQgKyAxKSArIFwiLlwiICsgY29lZmZpY2llbnQuc2xpY2UoZXhwb25lbnQgKyAxKVxuICAgICAgICA6IGNvZWZmaWNpZW50ICsgbmV3IEFycmF5KGV4cG9uZW50IC0gY29lZmZpY2llbnQubGVuZ3RoICsgMikuam9pbihcIjBcIik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXREZWZhdWx0KHgsIHApIHtcbiAgICB4ID0geC50b1ByZWNpc2lvbihwKTtcblxuICAgIG91dDogZm9yICh2YXIgbiA9IHgubGVuZ3RoLCBpID0gMSwgaTAgPSAtMSwgaTE7IGkgPCBuOyArK2kpIHtcbiAgICAgIHN3aXRjaCAoeFtpXSkge1xuICAgICAgICBjYXNlIFwiLlwiOiBpMCA9IGkxID0gaTsgYnJlYWs7XG4gICAgICAgIGNhc2UgXCIwXCI6IGlmIChpMCA9PT0gMCkgaTAgPSBpOyBpMSA9IGk7IGJyZWFrO1xuICAgICAgICBjYXNlIFwiZVwiOiBicmVhayBvdXQ7XG4gICAgICAgIGRlZmF1bHQ6IGlmIChpMCA+IDApIGkwID0gMDsgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGkwID4gMCA/IHguc2xpY2UoMCwgaTApICsgeC5zbGljZShpMSArIDEpIDogeDtcbiAgfVxuXG4gIHZhciBmb3JtYXRUeXBlcyA9IHtcbiAgICBcIlwiOiBmb3JtYXREZWZhdWx0LFxuICAgIFwiJVwiOiBmdW5jdGlvbih4LCBwKSB7IHJldHVybiAoeCAqIDEwMCkudG9GaXhlZChwKTsgfSxcbiAgICBcImJcIjogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZygyKTsgfSxcbiAgICBcImNcIjogZnVuY3Rpb24oeCkgeyByZXR1cm4geCArIFwiXCI7IH0sXG4gICAgXCJkXCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoMTApOyB9LFxuICAgIFwiZVwiOiBmdW5jdGlvbih4LCBwKSB7IHJldHVybiB4LnRvRXhwb25lbnRpYWwocCk7IH0sXG4gICAgXCJmXCI6IGZ1bmN0aW9uKHgsIHApIHsgcmV0dXJuIHgudG9GaXhlZChwKTsgfSxcbiAgICBcImdcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4geC50b1ByZWNpc2lvbihwKTsgfSxcbiAgICBcIm9cIjogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZyg4KTsgfSxcbiAgICBcInBcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4gZm9ybWF0Um91bmRlZCh4ICogMTAwLCBwKTsgfSxcbiAgICBcInJcIjogZm9ybWF0Um91bmRlZCxcbiAgICBcInNcIjogZm9ybWF0UHJlZml4QXV0byxcbiAgICBcIlhcIjogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTsgfSxcbiAgICBcInhcIjogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZygxNik7IH1cbiAgfTtcblxuXG4gIC8vIFtbZmlsbF1hbGlnbl1bc2lnbl1bc3ltYm9sXVswXVt3aWR0aF1bLF1bLnByZWNpc2lvbl1bdHlwZV1cbiAgdmFyIHJlID0gL14oPzooLik/KFs8Pj1eXSkpPyhbK1xcLVxcKCBdKT8oWyQjXSk/KDApPyhcXGQrKT8oLCk/KFxcLlxcZCspPyhbYS16JV0pPyQvaTtcblxuICBmdW5jdGlvbiBmb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyKSB7XG4gICAgcmV0dXJuIG5ldyBGb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIEZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpIHtcbiAgICBpZiAoIShtYXRjaCA9IHJlLmV4ZWMoc3BlY2lmaWVyKSkpIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZm9ybWF0OiBcIiArIHNwZWNpZmllcik7XG5cbiAgICB2YXIgbWF0Y2gsXG4gICAgICAgIGZpbGwgPSBtYXRjaFsxXSB8fCBcIiBcIixcbiAgICAgICAgYWxpZ24gPSBtYXRjaFsyXSB8fCBcIj5cIixcbiAgICAgICAgc2lnbiA9IG1hdGNoWzNdIHx8IFwiLVwiLFxuICAgICAgICBzeW1ib2wgPSBtYXRjaFs0XSB8fCBcIlwiLFxuICAgICAgICB6ZXJvID0gISFtYXRjaFs1XSxcbiAgICAgICAgd2lkdGggPSBtYXRjaFs2XSAmJiArbWF0Y2hbNl0sXG4gICAgICAgIGNvbW1hID0gISFtYXRjaFs3XSxcbiAgICAgICAgcHJlY2lzaW9uID0gbWF0Y2hbOF0gJiYgK21hdGNoWzhdLnNsaWNlKDEpLFxuICAgICAgICB0eXBlID0gbWF0Y2hbOV0gfHwgXCJcIjtcblxuICAgIC8vIFRoZSBcIm5cIiB0eXBlIGlzIGFuIGFsaWFzIGZvciBcIixnXCIuXG4gICAgaWYgKHR5cGUgPT09IFwiblwiKSBjb21tYSA9IHRydWUsIHR5cGUgPSBcImdcIjtcblxuICAgIC8vIE1hcCBpbnZhbGlkIHR5cGVzIHRvIHRoZSBkZWZhdWx0IGZvcm1hdC5cbiAgICBlbHNlIGlmICghZm9ybWF0VHlwZXNbdHlwZV0pIHR5cGUgPSBcIlwiO1xuXG4gICAgLy8gSWYgemVybyBmaWxsIGlzIHNwZWNpZmllZCwgcGFkZGluZyBnb2VzIGFmdGVyIHNpZ24gYW5kIGJlZm9yZSBkaWdpdHMuXG4gICAgaWYgKHplcm8gfHwgKGZpbGwgPT09IFwiMFwiICYmIGFsaWduID09PSBcIj1cIikpIHplcm8gPSB0cnVlLCBmaWxsID0gXCIwXCIsIGFsaWduID0gXCI9XCI7XG5cbiAgICB0aGlzLmZpbGwgPSBmaWxsO1xuICAgIHRoaXMuYWxpZ24gPSBhbGlnbjtcbiAgICB0aGlzLnNpZ24gPSBzaWduO1xuICAgIHRoaXMuc3ltYm9sID0gc3ltYm9sO1xuICAgIHRoaXMuemVybyA9IHplcm87XG4gICAgdGhpcy53aWR0aCA9IHdpZHRoO1xuICAgIHRoaXMuY29tbWEgPSBjb21tYTtcbiAgICB0aGlzLnByZWNpc2lvbiA9IHByZWNpc2lvbjtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICB9XG5cbiAgRm9ybWF0U3BlY2lmaWVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmZpbGxcbiAgICAgICAgKyB0aGlzLmFsaWduXG4gICAgICAgICsgdGhpcy5zaWduXG4gICAgICAgICsgdGhpcy5zeW1ib2xcbiAgICAgICAgKyAodGhpcy56ZXJvID8gXCIwXCIgOiBcIlwiKVxuICAgICAgICArICh0aGlzLndpZHRoID09IG51bGwgPyBcIlwiIDogTWF0aC5tYXgoMSwgdGhpcy53aWR0aCB8IDApKVxuICAgICAgICArICh0aGlzLmNvbW1hID8gXCIsXCIgOiBcIlwiKVxuICAgICAgICArICh0aGlzLnByZWNpc2lvbiA9PSBudWxsID8gXCJcIiA6IFwiLlwiICsgTWF0aC5tYXgoMCwgdGhpcy5wcmVjaXNpb24gfCAwKSlcbiAgICAgICAgKyB0aGlzLnR5cGU7XG4gIH07XG5cbiAgZnVuY3Rpb24gZm9ybWF0R3JvdXAoZ3JvdXBpbmcsIHRob3VzYW5kcykge1xuICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSwgd2lkdGgpIHtcbiAgICAgIHZhciBpID0gdmFsdWUubGVuZ3RoLFxuICAgICAgICAgIHQgPSBbXSxcbiAgICAgICAgICBqID0gMCxcbiAgICAgICAgICBnID0gZ3JvdXBpbmdbMF0sXG4gICAgICAgICAgbGVuZ3RoID0gMDtcblxuICAgICAgd2hpbGUgKGkgPiAwICYmIGcgPiAwKSB7XG4gICAgICAgIGlmIChsZW5ndGggKyBnICsgMSA+IHdpZHRoKSBnID0gTWF0aC5tYXgoMSwgd2lkdGggLSBsZW5ndGgpO1xuICAgICAgICB0LnB1c2godmFsdWUuc3Vic3RyaW5nKGkgLT0gZywgaSArIGcpKTtcbiAgICAgICAgaWYgKChsZW5ndGggKz0gZyArIDEpID4gd2lkdGgpIGJyZWFrO1xuICAgICAgICBnID0gZ3JvdXBpbmdbaiA9IChqICsgMSkgJSBncm91cGluZy5sZW5ndGhdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdC5yZXZlcnNlKCkuam9pbih0aG91c2FuZHMpO1xuICAgIH07XG4gIH1cblxuICB2YXIgcHJlZml4ZXMgPSBbXCJ5XCIsXCJ6XCIsXCJhXCIsXCJmXCIsXCJwXCIsXCJuXCIsXCLCtVwiLFwibVwiLFwiXCIsXCJrXCIsXCJNXCIsXCJHXCIsXCJUXCIsXCJQXCIsXCJFXCIsXCJaXCIsXCJZXCJdO1xuXG4gIGZ1bmN0aW9uIGlkZW50aXR5KHgpIHtcbiAgICByZXR1cm4geDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxvY2FsZShsb2NhbGUpIHtcbiAgICB2YXIgZ3JvdXAgPSBsb2NhbGUuZ3JvdXBpbmcgJiYgbG9jYWxlLnRob3VzYW5kcyA/IGZvcm1hdEdyb3VwKGxvY2FsZS5ncm91cGluZywgbG9jYWxlLnRob3VzYW5kcykgOiBpZGVudGl0eSxcbiAgICAgICAgY3VycmVuY3kgPSBsb2NhbGUuY3VycmVuY3ksXG4gICAgICAgIGRlY2ltYWwgPSBsb2NhbGUuZGVjaW1hbDtcblxuICAgIGZ1bmN0aW9uIGZvcm1hdChzcGVjaWZpZXIpIHtcbiAgICAgIHNwZWNpZmllciA9IGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpO1xuXG4gICAgICB2YXIgZmlsbCA9IHNwZWNpZmllci5maWxsLFxuICAgICAgICAgIGFsaWduID0gc3BlY2lmaWVyLmFsaWduLFxuICAgICAgICAgIHNpZ24gPSBzcGVjaWZpZXIuc2lnbixcbiAgICAgICAgICBzeW1ib2wgPSBzcGVjaWZpZXIuc3ltYm9sLFxuICAgICAgICAgIHplcm8gPSBzcGVjaWZpZXIuemVybyxcbiAgICAgICAgICB3aWR0aCA9IHNwZWNpZmllci53aWR0aCxcbiAgICAgICAgICBjb21tYSA9IHNwZWNpZmllci5jb21tYSxcbiAgICAgICAgICBwcmVjaXNpb24gPSBzcGVjaWZpZXIucHJlY2lzaW9uLFxuICAgICAgICAgIHR5cGUgPSBzcGVjaWZpZXIudHlwZTtcblxuICAgICAgLy8gQ29tcHV0ZSB0aGUgcHJlZml4IGFuZCBzdWZmaXguXG4gICAgICAvLyBGb3IgU0ktcHJlZml4LCB0aGUgc3VmZml4IGlzIGxhemlseSBjb21wdXRlZC5cbiAgICAgIHZhciBwcmVmaXggPSBzeW1ib2wgPT09IFwiJFwiID8gY3VycmVuY3lbMF0gOiBzeW1ib2wgPT09IFwiI1wiICYmIC9bYm94WF0vLnRlc3QodHlwZSkgPyBcIjBcIiArIHR5cGUudG9Mb3dlckNhc2UoKSA6IFwiXCIsXG4gICAgICAgICAgc3VmZml4ID0gc3ltYm9sID09PSBcIiRcIiA/IGN1cnJlbmN5WzFdIDogL1slcF0vLnRlc3QodHlwZSkgPyBcIiVcIiA6IFwiXCI7XG5cbiAgICAgIC8vIFdoYXQgZm9ybWF0IGZ1bmN0aW9uIHNob3VsZCB3ZSB1c2U/XG4gICAgICAvLyBJcyB0aGlzIGFuIGludGVnZXIgdHlwZT9cbiAgICAgIC8vIENhbiB0aGlzIHR5cGUgZ2VuZXJhdGUgZXhwb25lbnRpYWwgbm90YXRpb24/XG4gICAgICB2YXIgZm9ybWF0VHlwZSA9IGZvcm1hdFR5cGVzW3R5cGVdLFxuICAgICAgICAgIG1heWJlU3VmZml4ID0gIXR5cGUgfHwgL1tkZWZncHJzJV0vLnRlc3QodHlwZSk7XG5cbiAgICAgIC8vIFNldCB0aGUgZGVmYXVsdCBwcmVjaXNpb24gaWYgbm90IHNwZWNpZmllZCxcbiAgICAgIC8vIG9yIGNsYW1wIHRoZSBzcGVjaWZpZWQgcHJlY2lzaW9uIHRvIHRoZSBzdXBwb3J0ZWQgcmFuZ2UuXG4gICAgICAvLyBGb3Igc2lnbmlmaWNhbnQgcHJlY2lzaW9uLCBpdCBtdXN0IGJlIGluIFsxLCAyMV0uXG4gICAgICAvLyBGb3IgZml4ZWQgcHJlY2lzaW9uLCBpdCBtdXN0IGJlIGluIFswLCAyMF0uXG4gICAgICBwcmVjaXNpb24gPSBwcmVjaXNpb24gPT0gbnVsbCA/ICh0eXBlID8gNiA6IDEyKVxuICAgICAgICAgIDogL1tncHJzXS8udGVzdCh0eXBlKSA/IE1hdGgubWF4KDEsIE1hdGgubWluKDIxLCBwcmVjaXNpb24pKVxuICAgICAgICAgIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oMjAsIHByZWNpc2lvbikpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgdmFyIHZhbHVlUHJlZml4ID0gcHJlZml4LFxuICAgICAgICAgICAgdmFsdWVTdWZmaXggPSBzdWZmaXg7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09IFwiY1wiKSB7XG4gICAgICAgICAgdmFsdWVTdWZmaXggPSBmb3JtYXRUeXBlKHZhbHVlKSArIHZhbHVlU3VmZml4O1xuICAgICAgICAgIHZhbHVlID0gXCJcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZSA9ICt2YWx1ZTtcblxuICAgICAgICAgIC8vIENvbnZlcnQgbmVnYXRpdmUgdG8gcG9zaXRpdmUsIGFuZCBjb21wdXRlIHRoZSBwcmVmaXguXG4gICAgICAgICAgLy8gTm90ZSB0aGF0IC0wIGlzIG5vdCBsZXNzIHRoYW4gMCwgYnV0IDEgLyAtMCBpcyFcbiAgICAgICAgICB2YXIgdmFsdWVOZWdhdGl2ZSA9ICh2YWx1ZSA8IDAgfHwgMSAvIHZhbHVlIDwgMCkgJiYgKHZhbHVlICo9IC0xLCB0cnVlKTtcblxuICAgICAgICAgIC8vIFBlcmZvcm0gdGhlIGluaXRpYWwgZm9ybWF0dGluZy5cbiAgICAgICAgICB2YWx1ZSA9IGZvcm1hdFR5cGUodmFsdWUsIHByZWNpc2lvbik7XG5cbiAgICAgICAgICAvLyBDb21wdXRlIHRoZSBwcmVmaXggYW5kIHN1ZmZpeC5cbiAgICAgICAgICB2YWx1ZVByZWZpeCA9ICh2YWx1ZU5lZ2F0aXZlID8gKHNpZ24gPT09IFwiKFwiID8gc2lnbiA6IFwiLVwiKSA6IHNpZ24gPT09IFwiLVwiIHx8IHNpZ24gPT09IFwiKFwiID8gXCJcIiA6IHNpZ24pICsgdmFsdWVQcmVmaXg7XG4gICAgICAgICAgdmFsdWVTdWZmaXggPSB2YWx1ZVN1ZmZpeCArICh0eXBlID09PSBcInNcIiA/IHByZWZpeGVzWzggKyBwcmVmaXhFeHBvbmVudCAvIDNdIDogXCJcIikgKyAodmFsdWVOZWdhdGl2ZSAmJiBzaWduID09PSBcIihcIiA/IFwiKVwiIDogXCJcIik7XG5cbiAgICAgICAgICAvLyBCcmVhayB0aGUgZm9ybWF0dGVkIHZhbHVlIGludG8gdGhlIGludGVnZXIg4oCcdmFsdWXigJ0gcGFydCB0aGF0IGNhbiBiZVxuICAgICAgICAgIC8vIGdyb3VwZWQsIGFuZCBmcmFjdGlvbmFsIG9yIGV4cG9uZW50aWFsIOKAnHN1ZmZpeOKAnSBwYXJ0IHRoYXQgaXMgbm90LlxuICAgICAgICAgIGlmIChtYXliZVN1ZmZpeCkge1xuICAgICAgICAgICAgdmFyIGkgPSAtMSwgbiA9IHZhbHVlLmxlbmd0aCwgYztcbiAgICAgICAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgICAgIGlmIChjID0gdmFsdWUuY2hhckNvZGVBdChpKSwgNDggPiBjIHx8IGMgPiA1Nykge1xuICAgICAgICAgICAgICAgIHZhbHVlU3VmZml4ID0gKGMgPT09IDQ2ID8gZGVjaW1hbCArIHZhbHVlLnNsaWNlKGkgKyAxKSA6IHZhbHVlLnNsaWNlKGkpKSArIHZhbHVlU3VmZml4O1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMCwgaSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgZmlsbCBjaGFyYWN0ZXIgaXMgbm90IFwiMFwiLCBncm91cGluZyBpcyBhcHBsaWVkIGJlZm9yZSBwYWRkaW5nLlxuICAgICAgICBpZiAoY29tbWEgJiYgIXplcm8pIHZhbHVlID0gZ3JvdXAodmFsdWUsIEluZmluaXR5KTtcblxuICAgICAgICAvLyBDb21wdXRlIHRoZSBwYWRkaW5nLlxuICAgICAgICB2YXIgbGVuZ3RoID0gdmFsdWVQcmVmaXgubGVuZ3RoICsgdmFsdWUubGVuZ3RoICsgdmFsdWVTdWZmaXgubGVuZ3RoLFxuICAgICAgICAgICAgcGFkZGluZyA9IGxlbmd0aCA8IHdpZHRoID8gbmV3IEFycmF5KHdpZHRoIC0gbGVuZ3RoICsgMSkuam9pbihmaWxsKSA6IFwiXCI7XG5cbiAgICAgICAgLy8gSWYgdGhlIGZpbGwgY2hhcmFjdGVyIGlzIFwiMFwiLCBncm91cGluZyBpcyBhcHBsaWVkIGFmdGVyIHBhZGRpbmcuXG4gICAgICAgIGlmIChjb21tYSAmJiB6ZXJvKSB2YWx1ZSA9IGdyb3VwKHBhZGRpbmcgKyB2YWx1ZSwgcGFkZGluZy5sZW5ndGggPyB3aWR0aCAtIHZhbHVlU3VmZml4Lmxlbmd0aCA6IEluZmluaXR5KSwgcGFkZGluZyA9IFwiXCI7XG5cbiAgICAgICAgLy8gUmVjb25zdHJ1Y3QgdGhlIGZpbmFsIG91dHB1dCBiYXNlZCBvbiB0aGUgZGVzaXJlZCBhbGlnbm1lbnQuXG4gICAgICAgIHN3aXRjaCAoYWxpZ24pIHtcbiAgICAgICAgICBjYXNlIFwiPFwiOiByZXR1cm4gdmFsdWVQcmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4ICsgcGFkZGluZztcbiAgICAgICAgICBjYXNlIFwiPVwiOiByZXR1cm4gdmFsdWVQcmVmaXggKyBwYWRkaW5nICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgICAgICBjYXNlIFwiXlwiOiByZXR1cm4gcGFkZGluZy5zbGljZSgwLCBsZW5ndGggPSBwYWRkaW5nLmxlbmd0aCA+PiAxKSArIHZhbHVlUHJlZml4ICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeCArIHBhZGRpbmcuc2xpY2UobGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFkZGluZyArIHZhbHVlUHJlZml4ICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0UHJlZml4KHNwZWNpZmllciwgdmFsdWUpIHtcbiAgICAgIHZhciBmID0gZm9ybWF0KChzcGVjaWZpZXIgPSBmb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyKSwgc3BlY2lmaWVyLnR5cGUgPSBcImZcIiwgc3BlY2lmaWVyKSksXG4gICAgICAgICAgZSA9IE1hdGgubWF4KC04LCBNYXRoLm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50KHZhbHVlKSAvIDMpKSkgKiAzLFxuICAgICAgICAgIGsgPSBNYXRoLnBvdygxMCwgLWUpLFxuICAgICAgICAgIHByZWZpeCA9IHByZWZpeGVzWzggKyBlIC8gM107XG4gICAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGYoayAqIHZhbHVlKSArIHByZWZpeDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZvcm1hdDogZm9ybWF0LFxuICAgICAgZm9ybWF0UHJlZml4OiBmb3JtYXRQcmVmaXhcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcHJlY2lzaW9uUm91bmQoc3RlcCwgbWF4KSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIGV4cG9uZW50KE1hdGguYWJzKG1heCkpIC0gZXhwb25lbnQoTWF0aC5hYnMoc3RlcCkpKSArIDE7XG4gIH1cblxuICBmdW5jdGlvbiBwcmVjaXNpb25QcmVmaXgoc3RlcCwgdmFsdWUpIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5tYXgoLTgsIE1hdGgubWluKDgsIE1hdGguZmxvb3IoZXhwb25lbnQodmFsdWUpIC8gMykpKSAqIDMgLSBleHBvbmVudChNYXRoLmFicyhzdGVwKSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJlY2lzaW9uRml4ZWQoc3RlcCkge1xuICAgIHJldHVybiBNYXRoLm1heCgwLCAtZXhwb25lbnQoTWF0aC5hYnMoc3RlcCkpKTtcbiAgfVxuXG4gIHZhciBsb2NhbGVEZWZpbml0aW9ucyA9IChuZXcgTWFwKVxuICAgICAgLnNldChcImNhLUVTXCIsIGNhRXMpXG4gICAgICAuc2V0KFwiZGUtREVcIiwgZGVEZSlcbiAgICAgIC5zZXQoXCJlbi1DQVwiLCBlbkNhKVxuICAgICAgLnNldChcImVuLUdCXCIsIGVuR2IpXG4gICAgICAuc2V0KFwiZW4tVVNcIiwgZW5VcylcbiAgICAgIC5zZXQoXCJlcy1FU1wiLCBlc0VzKVxuICAgICAgLnNldChcImZpLUZJXCIsIGZpRmkpXG4gICAgICAuc2V0KFwiZnItQ0FcIiwgZnJDYSlcbiAgICAgIC5zZXQoXCJmci1GUlwiLCBmckZyKVxuICAgICAgLnNldChcImhlLUlMXCIsIGhlSWwpXG4gICAgICAuc2V0KFwiaXQtSVRcIiwgaXRJdClcbiAgICAgIC5zZXQoXCJtay1NS1wiLCBta01rKVxuICAgICAgLnNldChcIm5sLU5MXCIsIG5sTmwpXG4gICAgICAuc2V0KFwicGwtUExcIiwgcGxQbClcbiAgICAgIC5zZXQoXCJwdC1CUlwiLCBwdEJyKVxuICAgICAgLnNldChcInJ1LVJVXCIsIHJ1UnUpXG4gICAgICAuc2V0KFwiemgtQ05cIiwgemhDbik7XG5cbiAgdmFyIGRlZmF1bHRMb2NhbGUgPSBsb2NhbGUoZW5Vcyk7XG4gIGV4cG9ydHMuZm9ybWF0ID0gZGVmYXVsdExvY2FsZS5mb3JtYXQ7XG4gIGV4cG9ydHMuZm9ybWF0UHJlZml4ID0gZGVmYXVsdExvY2FsZS5mb3JtYXRQcmVmaXg7XG5cbiAgZnVuY3Rpb24gbG9jYWxlRm9ybWF0KGRlZmluaXRpb24pIHtcbiAgICBpZiAodHlwZW9mIGRlZmluaXRpb24gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGRlZmluaXRpb24gPSBsb2NhbGVEZWZpbml0aW9ucy5nZXQoZGVmaW5pdGlvbik7XG4gICAgICBpZiAoIWRlZmluaXRpb24pIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbG9jYWxlKGRlZmluaXRpb24pO1xuICB9XG4gIDtcblxuICBleHBvcnRzLmxvY2FsZUZvcm1hdCA9IGxvY2FsZUZvcm1hdDtcbiAgZXhwb3J0cy5mb3JtYXRTcGVjaWZpZXIgPSBmb3JtYXRTcGVjaWZpZXI7XG4gIGV4cG9ydHMucHJlY2lzaW9uRml4ZWQgPSBwcmVjaXNpb25GaXhlZDtcbiAgZXhwb3J0cy5wcmVjaXNpb25QcmVmaXggPSBwcmVjaXNpb25QcmVmaXg7XG4gIGV4cG9ydHMucHJlY2lzaW9uUm91bmQgPSBwcmVjaXNpb25Sb3VuZDtcblxufSkpOyIsImlmICh0eXBlb2YgTWFwID09PSBcInVuZGVmaW5lZFwiKSB7XG4gIE1hcCA9IGZ1bmN0aW9uKCkgeyB0aGlzLmNsZWFyKCk7IH07XG4gIE1hcC5wcm90b3R5cGUgPSB7XG4gICAgc2V0OiBmdW5jdGlvbihrLCB2KSB7IHRoaXMuX1trXSA9IHY7IHJldHVybiB0aGlzOyB9LFxuICAgIGdldDogZnVuY3Rpb24oaykgeyByZXR1cm4gdGhpcy5fW2tdOyB9LFxuICAgIGhhczogZnVuY3Rpb24oaykgeyByZXR1cm4gayBpbiB0aGlzLl87IH0sXG4gICAgZGVsZXRlOiBmdW5jdGlvbihrKSB7IHJldHVybiBrIGluIHRoaXMuXyAmJiBkZWxldGUgdGhpcy5fW2tdOyB9LFxuICAgIGNsZWFyOiBmdW5jdGlvbigpIHsgdGhpcy5fID0gT2JqZWN0LmNyZWF0ZShudWxsKTsgfSxcbiAgICBnZXQgc2l6ZSgpIHsgdmFyIG4gPSAwOyBmb3IgKHZhciBrIGluIHRoaXMuXykgKytuOyByZXR1cm4gbjsgfSxcbiAgICBmb3JFYWNoOiBmdW5jdGlvbihjKSB7IGZvciAodmFyIGsgaW4gdGhpcy5fKSBjKHRoaXMuX1trXSwgaywgdGhpcyk7IH1cbiAgfTtcbn0gZWxzZSAoZnVuY3Rpb24oKSB7XG4gIHZhciBtID0gbmV3IE1hcDtcbiAgaWYgKG0uc2V0KDAsIDApICE9PSBtKSB7XG4gICAgbSA9IG0uc2V0O1xuICAgIE1hcC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24oKSB7IG0uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgcmV0dXJuIHRoaXM7IH07XG4gIH1cbn0pKCk7XG5cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IGZhY3RvcnkoZXhwb3J0cykgOlxuICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJ10sIGZhY3RvcnkpIDpcbiAgZmFjdG9yeSgoZ2xvYmFsLnRpbWVGb3JtYXQgPSB7fSkpO1xufSh0aGlzLCBmdW5jdGlvbiAoZXhwb3J0cykgeyAndXNlIHN0cmljdCc7XG5cbiAgdmFyIHpoQ24gPSB7XG4gICAgZGF0ZVRpbWU6IFwiJWEgJWIgJWUgJVggJVlcIixcbiAgICBkYXRlOiBcIiVZLyUtbS8lLWRcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wi5LiK5Y2IXCIsIFwi5LiL5Y2IXCJdLFxuICAgIGRheXM6IFtcIuaYn+acn+aXpVwiLCBcIuaYn+acn+S4gFwiLCBcIuaYn+acn+S6jFwiLCBcIuaYn+acn+S4iVwiLCBcIuaYn+acn+Wbm1wiLCBcIuaYn+acn+S6lFwiLCBcIuaYn+acn+WFrVwiXSxcbiAgICBzaG9ydERheXM6IFtcIuaYn+acn+aXpVwiLCBcIuaYn+acn+S4gFwiLCBcIuaYn+acn+S6jFwiLCBcIuaYn+acn+S4iVwiLCBcIuaYn+acn+Wbm1wiLCBcIuaYn+acn+S6lFwiLCBcIuaYn+acn+WFrVwiXSxcbiAgICBtb250aHM6IFtcIuS4gOaciFwiLCBcIuS6jOaciFwiLCBcIuS4ieaciFwiLCBcIuWbm+aciFwiLCBcIuS6lOaciFwiLCBcIuWFreaciFwiLCBcIuS4g+aciFwiLCBcIuWFq+aciFwiLCBcIuS5neaciFwiLCBcIuWNgeaciFwiLCBcIuWNgeS4gOaciFwiLCBcIuWNgeS6jOaciFwiXSxcbiAgICBzaG9ydE1vbnRoczogW1wi5LiA5pyIXCIsIFwi5LqM5pyIXCIsIFwi5LiJ5pyIXCIsIFwi5Zub5pyIXCIsIFwi5LqU5pyIXCIsIFwi5YWt5pyIXCIsIFwi5LiD5pyIXCIsIFwi5YWr5pyIXCIsIFwi5Lmd5pyIXCIsIFwi5Y2B5pyIXCIsIFwi5Y2B5LiA5pyIXCIsIFwi5Y2B5LqM5pyIXCJdXG4gIH07XG5cbiAgdmFyIHJ1UnUgPSB7XG4gICAgZGF0ZVRpbWU6IFwiJUEsICVlICVCICVZINCzLiAlWFwiLFxuICAgIGRhdGU6IFwiJWQuJW0uJVlcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgICBkYXlzOiBbXCLQstC+0YHQutGA0LXRgdC10L3RjNC1XCIsIFwi0L/QvtC90LXQtNC10LvRjNC90LjQulwiLCBcItCy0YLQvtGA0L3QuNC6XCIsIFwi0YHRgNC10LTQsFwiLCBcItGH0LXRgtCy0LXRgNCzXCIsIFwi0L/Rj9GC0L3QuNGG0LBcIiwgXCLRgdGD0LHQsdC+0YLQsFwiXSxcbiAgICBzaG9ydERheXM6IFtcItCy0YFcIiwgXCLQv9C9XCIsIFwi0LLRglwiLCBcItGB0YBcIiwgXCLRh9GCXCIsIFwi0L/RglwiLCBcItGB0LFcIl0sXG4gICAgbW9udGhzOiBbXCLRj9C90LLQsNGA0Y9cIiwgXCLRhNC10LLRgNCw0LvRj1wiLCBcItC80LDRgNGC0LBcIiwgXCLQsNC/0YDQtdC70Y9cIiwgXCLQvNCw0Y9cIiwgXCLQuNGO0L3Rj1wiLCBcItC40Y7Qu9GPXCIsIFwi0LDQstCz0YPRgdGC0LBcIiwgXCLRgdC10L3RgtGP0LHRgNGPXCIsIFwi0L7QutGC0Y/QsdGA0Y9cIiwgXCLQvdC+0Y/QsdGA0Y9cIiwgXCLQtNC10LrQsNCx0YDRj1wiXSxcbiAgICBzaG9ydE1vbnRoczogW1wi0Y/QvdCyXCIsIFwi0YTQtdCyXCIsIFwi0LzQsNGAXCIsIFwi0LDQv9GAXCIsIFwi0LzQsNC5XCIsIFwi0LjRjtC9XCIsIFwi0LjRjtC7XCIsIFwi0LDQstCzXCIsIFwi0YHQtdC9XCIsIFwi0L7QutGCXCIsIFwi0L3QvtGPXCIsIFwi0LTQtdC6XCJdXG4gIH07XG5cbiAgdmFyIHB0QnIgPSB7XG4gICAgZGF0ZVRpbWU6IFwiJUEsICVlIGRlICVCIGRlICVZLiAlWFwiLFxuICAgIGRhdGU6IFwiJWQvJW0vJVlcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgICBkYXlzOiBbXCJEb21pbmdvXCIsIFwiU2VndW5kYVwiLCBcIlRlcsOnYVwiLCBcIlF1YXJ0YVwiLCBcIlF1aW50YVwiLCBcIlNleHRhXCIsIFwiU8OhYmFkb1wiXSxcbiAgICBzaG9ydERheXM6IFtcIkRvbVwiLCBcIlNlZ1wiLCBcIlRlclwiLCBcIlF1YVwiLCBcIlF1aVwiLCBcIlNleFwiLCBcIlPDoWJcIl0sXG4gICAgbW9udGhzOiBbXCJKYW5laXJvXCIsIFwiRmV2ZXJlaXJvXCIsIFwiTWFyw6dvXCIsIFwiQWJyaWxcIiwgXCJNYWlvXCIsIFwiSnVuaG9cIiwgXCJKdWxob1wiLCBcIkFnb3N0b1wiLCBcIlNldGVtYnJvXCIsIFwiT3V0dWJyb1wiLCBcIk5vdmVtYnJvXCIsIFwiRGV6ZW1icm9cIl0sXG4gICAgc2hvcnRNb250aHM6IFtcIkphblwiLCBcIkZldlwiLCBcIk1hclwiLCBcIkFiclwiLCBcIk1haVwiLCBcIkp1blwiLCBcIkp1bFwiLCBcIkFnb1wiLCBcIlNldFwiLCBcIk91dFwiLCBcIk5vdlwiLCBcIkRlelwiXVxuICB9O1xuXG4gIHZhciBwbFBsID0ge1xuICAgIGRhdGVUaW1lOiBcIiVBLCAlZSAlQiAlWSwgJVhcIixcbiAgICBkYXRlOiBcIiVkLyVtLyVZXCIsXG4gICAgdGltZTogXCIlSDolTTolU1wiLFxuICAgIHBlcmlvZHM6IFtcIkFNXCIsIFwiUE1cIl0sIC8vIHVudXNlZFxuICAgIGRheXM6IFtcIk5pZWR6aWVsYVwiLCBcIlBvbmllZHppYcWCZWtcIiwgXCJXdG9yZWtcIiwgXCLFmnJvZGFcIiwgXCJDendhcnRla1wiLCBcIlBpxIV0ZWtcIiwgXCJTb2JvdGFcIl0sXG4gICAgc2hvcnREYXlzOiBbXCJOaWVkei5cIiwgXCJQb24uXCIsIFwiV3QuXCIsIFwixZpyLlwiLCBcIkN6dy5cIiwgXCJQdC5cIiwgXCJTb2IuXCJdLFxuICAgIG1vbnRoczogW1wiU3R5Y3plxYRcIiwgXCJMdXR5XCIsIFwiTWFyemVjXCIsIFwiS3dpZWNpZcWEXCIsIFwiTWFqXCIsIFwiQ3plcndpZWNcIiwgXCJMaXBpZWNcIiwgXCJTaWVycGllxYRcIiwgXCJXcnplc2llxYRcIiwgXCJQYcW6ZHppZXJuaWtcIiwgXCJMaXN0b3BhZFwiLCBcIkdydWR6aWXFhFwiXSxcbiAgICBzaG9ydE1vbnRoczogW1wiU3R5Y3ouXCIsIFwiTHV0eVwiLCBcIk1hcnouXCIsIFwiS3dpZS5cIiwgXCJNYWpcIiwgXCJDemVydy5cIiwgXCJMaXBjLlwiLCBcIlNpZXJwLlwiLCBcIldyei5cIiwgXCJQYcW6ZHouXCIsIFwiTGlzdG9wLlwiLCBcIkdydWR6LlwiXS8qIEluIFBvbGlzaCBsYW5ndWFnZSBhYmJyYXZpYXRlZCBtb250aHMgYXJlIG5vdCBjb21tb25seSB1c2VkIHNvIHRoZXJlIGlzIGEgZGlzcHV0ZSBhYm91dCB0aGUgcHJvcGVyIGFiYnJhdmlhdGlvbnMuICovXG4gIH07XG5cbiAgdmFyIG5sTmwgPSB7XG4gICAgZGF0ZVRpbWU6IFwiJWEgJWUgJUIgJVkgJVRcIixcbiAgICBkYXRlOiBcIiVkLSVtLSVZXCIsXG4gICAgdGltZTogXCIlSDolTTolU1wiLFxuICAgIHBlcmlvZHM6IFtcIkFNXCIsIFwiUE1cIl0sIC8vIHVudXNlZFxuICAgIGRheXM6IFtcInpvbmRhZ1wiLCBcIm1hYW5kYWdcIiwgXCJkaW5zZGFnXCIsIFwid29lbnNkYWdcIiwgXCJkb25kZXJkYWdcIiwgXCJ2cmlqZGFnXCIsIFwiemF0ZXJkYWdcIl0sXG4gICAgc2hvcnREYXlzOiBbXCJ6b1wiLCBcIm1hXCIsIFwiZGlcIiwgXCJ3b1wiLCBcImRvXCIsIFwidnJcIiwgXCJ6YVwiXSxcbiAgICBtb250aHM6IFtcImphbnVhcmlcIiwgXCJmZWJydWFyaVwiLCBcIm1hYXJ0XCIsIFwiYXByaWxcIiwgXCJtZWlcIiwgXCJqdW5pXCIsIFwianVsaVwiLCBcImF1Z3VzdHVzXCIsIFwic2VwdGVtYmVyXCIsIFwib2t0b2JlclwiLCBcIm5vdmVtYmVyXCIsIFwiZGVjZW1iZXJcIl0sXG4gICAgc2hvcnRNb250aHM6IFtcImphblwiLCBcImZlYlwiLCBcIm1ydFwiLCBcImFwclwiLCBcIm1laVwiLCBcImp1blwiLCBcImp1bFwiLCBcImF1Z1wiLCBcInNlcFwiLCBcIm9rdFwiLCBcIm5vdlwiLCBcImRlY1wiXVxuICB9O1xuXG4gIHZhciBta01rID0ge1xuICAgIGRhdGVUaW1lOiBcIiVBLCAlZSAlQiAlWSDQsy4gJVhcIixcbiAgICBkYXRlOiBcIiVkLiVtLiVZXCIsXG4gICAgdGltZTogXCIlSDolTTolU1wiLFxuICAgIHBlcmlvZHM6IFtcIkFNXCIsIFwiUE1cIl0sXG4gICAgZGF5czogW1wi0L3QtdC00LXQu9CwXCIsIFwi0L/QvtC90LXQtNC10LvQvdC40LpcIiwgXCLQstGC0L7RgNC90LjQulwiLCBcItGB0YDQtdC00LBcIiwgXCLRh9C10YLQstGA0YLQvtC6XCIsIFwi0L/QtdGC0L7QulwiLCBcItGB0LDQsdC+0YLQsFwiXSxcbiAgICBzaG9ydERheXM6IFtcItC90LXQtFwiLCBcItC/0L7QvVwiLCBcItCy0YLQvlwiLCBcItGB0YDQtVwiLCBcItGH0LXRglwiLCBcItC/0LXRglwiLCBcItGB0LDQsVwiXSxcbiAgICBtb250aHM6IFtcItGY0LDQvdGD0LDRgNC4XCIsIFwi0YTQtdCy0YDRg9Cw0YDQuFwiLCBcItC80LDRgNGCXCIsIFwi0LDQv9GA0LjQu1wiLCBcItC80LDRmFwiLCBcItGY0YPQvdC4XCIsIFwi0ZjRg9C70LhcIiwgXCLQsNCy0LPRg9GB0YJcIiwgXCLRgdC10L/RgtC10LzQstGA0LhcIiwgXCLQvtC60YLQvtC80LLRgNC4XCIsIFwi0L3QvtC10LzQstGA0LhcIiwgXCLQtNC10LrQtdC80LLRgNC4XCJdLFxuICAgIHNob3J0TW9udGhzOiBbXCLRmNCw0L1cIiwgXCLRhNC10LJcIiwgXCLQvNCw0YBcIiwgXCLQsNC/0YBcIiwgXCLQvNCw0ZhcIiwgXCLRmNGD0L1cIiwgXCLRmNGD0LtcIiwgXCLQsNCy0LNcIiwgXCLRgdC10L9cIiwgXCLQvtC60YJcIiwgXCLQvdC+0LVcIiwgXCLQtNC10LpcIl1cbiAgfTtcblxuICB2YXIgaXRJdCA9IHtcbiAgICBkYXRlVGltZTogXCIlQSAlZSAlQiAlWSwgJVhcIixcbiAgICBkYXRlOiBcIiVkLyVtLyVZXCIsXG4gICAgdGltZTogXCIlSDolTTolU1wiLFxuICAgIHBlcmlvZHM6IFtcIkFNXCIsIFwiUE1cIl0sIC8vIHVudXNlZFxuICAgIGRheXM6IFtcIkRvbWVuaWNhXCIsIFwiTHVuZWTDrFwiLCBcIk1hcnRlZMOsXCIsIFwiTWVyY29sZWTDrFwiLCBcIkdpb3ZlZMOsXCIsIFwiVmVuZXJkw6xcIiwgXCJTYWJhdG9cIl0sXG4gICAgc2hvcnREYXlzOiBbXCJEb21cIiwgXCJMdW5cIiwgXCJNYXJcIiwgXCJNZXJcIiwgXCJHaW9cIiwgXCJWZW5cIiwgXCJTYWJcIl0sXG4gICAgbW9udGhzOiBbXCJHZW5uYWlvXCIsIFwiRmViYnJhaW9cIiwgXCJNYXJ6b1wiLCBcIkFwcmlsZVwiLCBcIk1hZ2dpb1wiLCBcIkdpdWdub1wiLCBcIkx1Z2xpb1wiLCBcIkFnb3N0b1wiLCBcIlNldHRlbWJyZVwiLCBcIk90dG9icmVcIiwgXCJOb3ZlbWJyZVwiLCBcIkRpY2VtYnJlXCJdLFxuICAgIHNob3J0TW9udGhzOiBbXCJHZW5cIiwgXCJGZWJcIiwgXCJNYXJcIiwgXCJBcHJcIiwgXCJNYWdcIiwgXCJHaXVcIiwgXCJMdWdcIiwgXCJBZ29cIiwgXCJTZXRcIiwgXCJPdHRcIiwgXCJOb3ZcIiwgXCJEaWNcIl1cbiAgfTtcblxuICB2YXIgaGVJbCA9IHtcbiAgICBkYXRlVGltZTogXCIlQSwgJWUg15ElQiAlWSAlWFwiLFxuICAgIGRhdGU6IFwiJWQuJW0uJVlcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgICBkYXlzOiBbXCLXqNeQ16nXldefXCIsIFwi16nXoNeZXCIsIFwi16nXnNeZ16nXmVwiLCBcIteo15HXmdei15lcIiwgXCLXl9ee15nXqdeZXCIsIFwi16nXmdep15lcIiwgXCLXqdeR16pcIl0sXG4gICAgc2hvcnREYXlzOiBbXCLXkNezXCIsIFwi15HXs1wiLCBcIteS17NcIiwgXCLXk9ezXCIsIFwi15TXs1wiLCBcIteV17NcIiwgXCLXqdezXCJdLFxuICAgIG1vbnRoczogW1wi15nXoNeV15DXqFwiLCBcItek15HXqNeV15DXqFwiLCBcItee16jXpVwiLCBcIteQ16TXqNeZ15xcIiwgXCLXnteQ15lcIiwgXCLXmdeV16DXmVwiLCBcIteZ15XXnNeZXCIsIFwi15DXldeS15XXodeYXCIsIFwi16HXpNeY157XkdeoXCIsIFwi15DXlden15jXldeR16hcIiwgXCLXoNeV15HXnteR16hcIiwgXCLXk9em157XkdeoXCJdLFxuICAgIHNob3J0TW9udGhzOiBbXCLXmdeg15XXs1wiLCBcItek15HXqNezXCIsIFwi157XqNelXCIsIFwi15DXpNeo17NcIiwgXCLXnteQ15lcIiwgXCLXmdeV16DXmVwiLCBcIteZ15XXnNeZXCIsIFwi15DXldeS17NcIiwgXCLXodek15jXs1wiLCBcIteQ15XXp9ezXCIsIFwi16DXldeR17NcIiwgXCLXk9em157Xs1wiXVxuICB9O1xuXG4gIHZhciBmckZyID0ge1xuICAgIGRhdGVUaW1lOiBcIiVBLCBsZSAlZSAlQiAlWSwgJVhcIixcbiAgICBkYXRlOiBcIiVkLyVtLyVZXCIsXG4gICAgdGltZTogXCIlSDolTTolU1wiLFxuICAgIHBlcmlvZHM6IFtcIkFNXCIsIFwiUE1cIl0sIC8vIHVudXNlZFxuICAgIGRheXM6IFtcImRpbWFuY2hlXCIsIFwibHVuZGlcIiwgXCJtYXJkaVwiLCBcIm1lcmNyZWRpXCIsIFwiamV1ZGlcIiwgXCJ2ZW5kcmVkaVwiLCBcInNhbWVkaVwiXSxcbiAgICBzaG9ydERheXM6IFtcImRpbS5cIiwgXCJsdW4uXCIsIFwibWFyLlwiLCBcIm1lci5cIiwgXCJqZXUuXCIsIFwidmVuLlwiLCBcInNhbS5cIl0sXG4gICAgbW9udGhzOiBbXCJqYW52aWVyXCIsIFwiZsOpdnJpZXJcIiwgXCJtYXJzXCIsIFwiYXZyaWxcIiwgXCJtYWlcIiwgXCJqdWluXCIsIFwianVpbGxldFwiLCBcImFvw7t0XCIsIFwic2VwdGVtYnJlXCIsIFwib2N0b2JyZVwiLCBcIm5vdmVtYnJlXCIsIFwiZMOpY2VtYnJlXCJdLFxuICAgIHNob3J0TW9udGhzOiBbXCJqYW52LlwiLCBcImbDqXZyLlwiLCBcIm1hcnNcIiwgXCJhdnIuXCIsIFwibWFpXCIsIFwianVpblwiLCBcImp1aWwuXCIsIFwiYW/Du3RcIiwgXCJzZXB0LlwiLCBcIm9jdC5cIiwgXCJub3YuXCIsIFwiZMOpYy5cIl1cbiAgfTtcblxuICB2YXIgZnJDYSA9IHtcbiAgICBkYXRlVGltZTogXCIlYSAlZSAlYiAlWSAlWFwiLFxuICAgIGRhdGU6IFwiJVktJW0tJWRcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wiXCIsIFwiXCJdLFxuICAgIGRheXM6IFtcImRpbWFuY2hlXCIsIFwibHVuZGlcIiwgXCJtYXJkaVwiLCBcIm1lcmNyZWRpXCIsIFwiamV1ZGlcIiwgXCJ2ZW5kcmVkaVwiLCBcInNhbWVkaVwiXSxcbiAgICBzaG9ydERheXM6IFtcImRpbVwiLCBcImx1blwiLCBcIm1hclwiLCBcIm1lclwiLCBcImpldVwiLCBcInZlblwiLCBcInNhbVwiXSxcbiAgICBtb250aHM6IFtcImphbnZpZXJcIiwgXCJmw6l2cmllclwiLCBcIm1hcnNcIiwgXCJhdnJpbFwiLCBcIm1haVwiLCBcImp1aW5cIiwgXCJqdWlsbGV0XCIsIFwiYW/Du3RcIiwgXCJzZXB0ZW1icmVcIiwgXCJvY3RvYnJlXCIsIFwibm92ZW1icmVcIiwgXCJkw6ljZW1icmVcIl0sXG4gICAgc2hvcnRNb250aHM6IFtcImphblwiLCBcImbDqXZcIiwgXCJtYXJcIiwgXCJhdnJcIiwgXCJtYWlcIiwgXCJqdWlcIiwgXCJqdWxcIiwgXCJhb8O7XCIsIFwic2VwXCIsIFwib2N0XCIsIFwibm92XCIsIFwiZMOpY1wiXVxuICB9O1xuXG4gIHZhciBmaUZpID0ge1xuICAgIGRhdGVUaW1lOiBcIiVBLCAlLWQuICVCdGEgJVkga2xvICVYXCIsXG4gICAgZGF0ZTogXCIlLWQuJS1tLiVZXCIsXG4gICAgdGltZTogXCIlSDolTTolU1wiLFxuICAgIHBlcmlvZHM6IFtcImEubS5cIiwgXCJwLm0uXCJdLFxuICAgIGRheXM6IFtcInN1bm51bnRhaVwiLCBcIm1hYW5hbnRhaVwiLCBcInRpaXN0YWlcIiwgXCJrZXNraXZpaWtrb1wiLCBcInRvcnN0YWlcIiwgXCJwZXJqYW50YWlcIiwgXCJsYXVhbnRhaVwiXSxcbiAgICBzaG9ydERheXM6IFtcIlN1XCIsIFwiTWFcIiwgXCJUaVwiLCBcIktlXCIsIFwiVG9cIiwgXCJQZVwiLCBcIkxhXCJdLFxuICAgIG1vbnRoczogW1widGFtbWlrdXVcIiwgXCJoZWxtaWt1dVwiLCBcIm1hYWxpc2t1dVwiLCBcImh1aHRpa3V1XCIsIFwidG91a29rdXVcIiwgXCJrZXPDpGt1dVwiLCBcImhlaW7DpGt1dVwiLCBcImVsb2t1dVwiLCBcInN5eXNrdXVcIiwgXCJsb2tha3V1XCIsIFwibWFycmFza3V1XCIsIFwiam91bHVrdXVcIl0sXG4gICAgc2hvcnRNb250aHM6IFtcIlRhbW1pXCIsIFwiSGVsbWlcIiwgXCJNYWFsaXNcIiwgXCJIdWh0aVwiLCBcIlRvdWtvXCIsIFwiS2Vzw6RcIiwgXCJIZWluw6RcIiwgXCJFbG9cIiwgXCJTeXlzXCIsIFwiTG9rYVwiLCBcIk1hcnJhc1wiLCBcIkpvdWx1XCJdXG4gIH07XG5cbiAgdmFyIGVzRXMgPSB7XG4gICAgZGF0ZVRpbWU6IFwiJUEsICVlIGRlICVCIGRlICVZLCAlWFwiLFxuICAgIGRhdGU6IFwiJWQvJW0vJVlcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgICBkYXlzOiBbXCJkb21pbmdvXCIsIFwibHVuZXNcIiwgXCJtYXJ0ZXNcIiwgXCJtacOpcmNvbGVzXCIsIFwianVldmVzXCIsIFwidmllcm5lc1wiLCBcInPDoWJhZG9cIl0sXG4gICAgc2hvcnREYXlzOiBbXCJkb21cIiwgXCJsdW5cIiwgXCJtYXJcIiwgXCJtacOpXCIsIFwianVlXCIsIFwidmllXCIsIFwic8OhYlwiXSxcbiAgICBtb250aHM6IFtcImVuZXJvXCIsIFwiZmVicmVyb1wiLCBcIm1hcnpvXCIsIFwiYWJyaWxcIiwgXCJtYXlvXCIsIFwianVuaW9cIiwgXCJqdWxpb1wiLCBcImFnb3N0b1wiLCBcInNlcHRpZW1icmVcIiwgXCJvY3R1YnJlXCIsIFwibm92aWVtYnJlXCIsIFwiZGljaWVtYnJlXCJdLFxuICAgIHNob3J0TW9udGhzOiBbXCJlbmVcIiwgXCJmZWJcIiwgXCJtYXJcIiwgXCJhYnJcIiwgXCJtYXlcIiwgXCJqdW5cIiwgXCJqdWxcIiwgXCJhZ29cIiwgXCJzZXBcIiwgXCJvY3RcIiwgXCJub3ZcIiwgXCJkaWNcIl1cbiAgfTtcblxuICB2YXIgZW5VcyA9IHtcbiAgICBkYXRlVGltZTogXCIlYSAlYiAlZSAlWCAlWVwiLFxuICAgIGRhdGU6IFwiJW0vJWQvJVlcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgICBkYXlzOiBbXCJTdW5kYXlcIiwgXCJNb25kYXlcIiwgXCJUdWVzZGF5XCIsIFwiV2VkbmVzZGF5XCIsIFwiVGh1cnNkYXlcIiwgXCJGcmlkYXlcIiwgXCJTYXR1cmRheVwiXSxcbiAgICBzaG9ydERheXM6IFtcIlN1blwiLCBcIk1vblwiLCBcIlR1ZVwiLCBcIldlZFwiLCBcIlRodVwiLCBcIkZyaVwiLCBcIlNhdFwiXSxcbiAgICBtb250aHM6IFtcIkphbnVhcnlcIiwgXCJGZWJydWFyeVwiLCBcIk1hcmNoXCIsIFwiQXByaWxcIiwgXCJNYXlcIiwgXCJKdW5lXCIsIFwiSnVseVwiLCBcIkF1Z3VzdFwiLCBcIlNlcHRlbWJlclwiLCBcIk9jdG9iZXJcIiwgXCJOb3ZlbWJlclwiLCBcIkRlY2VtYmVyXCJdLFxuICAgIHNob3J0TW9udGhzOiBbXCJKYW5cIiwgXCJGZWJcIiwgXCJNYXJcIiwgXCJBcHJcIiwgXCJNYXlcIiwgXCJKdW5cIiwgXCJKdWxcIiwgXCJBdWdcIiwgXCJTZXBcIiwgXCJPY3RcIiwgXCJOb3ZcIiwgXCJEZWNcIl1cbiAgfTtcblxuICB2YXIgZW5HYiA9IHtcbiAgICBkYXRlVGltZTogXCIlYSAlZSAlYiAlWCAlWVwiLFxuICAgIGRhdGU6IFwiJWQvJW0vJVlcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgICBkYXlzOiBbXCJTdW5kYXlcIiwgXCJNb25kYXlcIiwgXCJUdWVzZGF5XCIsIFwiV2VkbmVzZGF5XCIsIFwiVGh1cnNkYXlcIiwgXCJGcmlkYXlcIiwgXCJTYXR1cmRheVwiXSxcbiAgICBzaG9ydERheXM6IFtcIlN1blwiLCBcIk1vblwiLCBcIlR1ZVwiLCBcIldlZFwiLCBcIlRodVwiLCBcIkZyaVwiLCBcIlNhdFwiXSxcbiAgICBtb250aHM6IFtcIkphbnVhcnlcIiwgXCJGZWJydWFyeVwiLCBcIk1hcmNoXCIsIFwiQXByaWxcIiwgXCJNYXlcIiwgXCJKdW5lXCIsIFwiSnVseVwiLCBcIkF1Z3VzdFwiLCBcIlNlcHRlbWJlclwiLCBcIk9jdG9iZXJcIiwgXCJOb3ZlbWJlclwiLCBcIkRlY2VtYmVyXCJdLFxuICAgIHNob3J0TW9udGhzOiBbXCJKYW5cIiwgXCJGZWJcIiwgXCJNYXJcIiwgXCJBcHJcIiwgXCJNYXlcIiwgXCJKdW5cIiwgXCJKdWxcIiwgXCJBdWdcIiwgXCJTZXBcIiwgXCJPY3RcIiwgXCJOb3ZcIiwgXCJEZWNcIl1cbiAgfTtcblxuICB2YXIgZW5DYSA9IHtcbiAgICBkYXRlVGltZTogXCIlYSAlYiAlZSAlWCAlWVwiLFxuICAgIGRhdGU6IFwiJVktJW0tJWRcIixcbiAgICB0aW1lOiBcIiVIOiVNOiVTXCIsXG4gICAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgICBkYXlzOiBbXCJTdW5kYXlcIiwgXCJNb25kYXlcIiwgXCJUdWVzZGF5XCIsIFwiV2VkbmVzZGF5XCIsIFwiVGh1cnNkYXlcIiwgXCJGcmlkYXlcIiwgXCJTYXR1cmRheVwiXSxcbiAgICBzaG9ydERheXM6IFtcIlN1blwiLCBcIk1vblwiLCBcIlR1ZVwiLCBcIldlZFwiLCBcIlRodVwiLCBcIkZyaVwiLCBcIlNhdFwiXSxcbiAgICBtb250aHM6IFtcIkphbnVhcnlcIiwgXCJGZWJydWFyeVwiLCBcIk1hcmNoXCIsIFwiQXByaWxcIiwgXCJNYXlcIiwgXCJKdW5lXCIsIFwiSnVseVwiLCBcIkF1Z3VzdFwiLCBcIlNlcHRlbWJlclwiLCBcIk9jdG9iZXJcIiwgXCJOb3ZlbWJlclwiLCBcIkRlY2VtYmVyXCJdLFxuICAgIHNob3J0TW9udGhzOiBbXCJKYW5cIiwgXCJGZWJcIiwgXCJNYXJcIiwgXCJBcHJcIiwgXCJNYXlcIiwgXCJKdW5cIiwgXCJKdWxcIiwgXCJBdWdcIiwgXCJTZXBcIiwgXCJPY3RcIiwgXCJOb3ZcIiwgXCJEZWNcIl1cbiAgfTtcblxuICB2YXIgZGVEZSA9IHtcbiAgICBkYXRlVGltZTogXCIlQSwgZGVyICVlLiAlQiAlWSwgJVhcIixcbiAgICBkYXRlOiBcIiVkLiVtLiVZXCIsXG4gICAgdGltZTogXCIlSDolTTolU1wiLFxuICAgIHBlcmlvZHM6IFtcIkFNXCIsIFwiUE1cIl0sIC8vIHVudXNlZFxuICAgIGRheXM6IFtcIlNvbm50YWdcIiwgXCJNb250YWdcIiwgXCJEaWVuc3RhZ1wiLCBcIk1pdHR3b2NoXCIsIFwiRG9ubmVyc3RhZ1wiLCBcIkZyZWl0YWdcIiwgXCJTYW1zdGFnXCJdLFxuICAgIHNob3J0RGF5czogW1wiU29cIiwgXCJNb1wiLCBcIkRpXCIsIFwiTWlcIiwgXCJEb1wiLCBcIkZyXCIsIFwiU2FcIl0sXG4gICAgbW9udGhzOiBbXCJKYW51YXJcIiwgXCJGZWJydWFyXCIsIFwiTcOkcnpcIiwgXCJBcHJpbFwiLCBcIk1haVwiLCBcIkp1bmlcIiwgXCJKdWxpXCIsIFwiQXVndXN0XCIsIFwiU2VwdGVtYmVyXCIsIFwiT2t0b2JlclwiLCBcIk5vdmVtYmVyXCIsIFwiRGV6ZW1iZXJcIl0sXG4gICAgc2hvcnRNb250aHM6IFtcIkphblwiLCBcIkZlYlwiLCBcIk1yelwiLCBcIkFwclwiLCBcIk1haVwiLCBcIkp1blwiLCBcIkp1bFwiLCBcIkF1Z1wiLCBcIlNlcFwiLCBcIk9rdFwiLCBcIk5vdlwiLCBcIkRlelwiXVxuICB9O1xuXG4gIHZhciBjYUVzID0ge1xuICAgIGRhdGVUaW1lOiBcIiVBLCAlZSBkZSAlQiBkZSAlWSwgJVhcIixcbiAgICBkYXRlOiBcIiVkLyVtLyVZXCIsXG4gICAgdGltZTogXCIlSDolTTolU1wiLFxuICAgIHBlcmlvZHM6IFtcIkFNXCIsIFwiUE1cIl0sXG4gICAgZGF5czogW1wiZGl1bWVuZ2VcIiwgXCJkaWxsdW5zXCIsIFwiZGltYXJ0c1wiLCBcImRpbWVjcmVzXCIsIFwiZGlqb3VzXCIsIFwiZGl2ZW5kcmVzXCIsIFwiZGlzc2FidGVcIl0sXG4gICAgc2hvcnREYXlzOiBbXCJkZy5cIiwgXCJkbC5cIiwgXCJkdC5cIiwgXCJkYy5cIiwgXCJkai5cIiwgXCJkdi5cIiwgXCJkcy5cIl0sXG4gICAgbW9udGhzOiBbXCJnZW5lclwiLCBcImZlYnJlclwiLCBcIm1hcsOnXCIsIFwiYWJyaWxcIiwgXCJtYWlnXCIsIFwianVueVwiLCBcImp1bGlvbFwiLCBcImFnb3N0XCIsIFwic2V0ZW1icmVcIiwgXCJvY3R1YnJlXCIsIFwibm92ZW1icmVcIiwgXCJkZXNlbWJyZVwiXSxcbiAgICBzaG9ydE1vbnRoczogW1wiZ2VuLlwiLCBcImZlYnIuXCIsIFwibWFyw6dcIiwgXCJhYnIuXCIsIFwibWFpZ1wiLCBcImp1bnlcIiwgXCJqdWwuXCIsIFwiYWcuXCIsIFwic2V0LlwiLCBcIm9jdC5cIiwgXCJub3YuXCIsIFwiZGVzLlwiXVxuICB9O1xuXG4gIHZhciB0MCA9IG5ldyBEYXRlO1xuICB2YXIgdDEgPSBuZXcgRGF0ZTtcblxuICBmdW5jdGlvbiBuZXdJbnRlcnZhbChmbG9vcmksIG9mZnNldGksIGNvdW50KSB7XG5cbiAgICBmdW5jdGlvbiBpbnRlcnZhbChkYXRlKSB7XG4gICAgICByZXR1cm4gZmxvb3JpKGRhdGUgPSBuZXcgRGF0ZSgrZGF0ZSkpLCBkYXRlO1xuICAgIH1cblxuICAgIGludGVydmFsLmZsb29yID0gaW50ZXJ2YWw7XG5cbiAgICBpbnRlcnZhbC5yb3VuZCA9IGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgIHZhciBkMCA9IG5ldyBEYXRlKCtkYXRlKSxcbiAgICAgICAgICBkMSA9IG5ldyBEYXRlKGRhdGUgLSAxKTtcbiAgICAgIGZsb29yaShkMCksIGZsb29yaShkMSksIG9mZnNldGkoZDEsIDEpO1xuICAgICAgcmV0dXJuIGRhdGUgLSBkMCA8IGQxIC0gZGF0ZSA/IGQwIDogZDE7XG4gICAgfTtcblxuICAgIGludGVydmFsLmNlaWwgPSBmdW5jdGlvbihkYXRlKSB7XG4gICAgICByZXR1cm4gZmxvb3JpKGRhdGUgPSBuZXcgRGF0ZShkYXRlIC0gMSkpLCBvZmZzZXRpKGRhdGUsIDEpLCBkYXRlO1xuICAgIH07XG5cbiAgICBpbnRlcnZhbC5vZmZzZXQgPSBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgICByZXR1cm4gb2Zmc2V0aShkYXRlID0gbmV3IERhdGUoK2RhdGUpLCBzdGVwID09IG51bGwgPyAxIDogTWF0aC5mbG9vcihzdGVwKSksIGRhdGU7XG4gICAgfTtcblxuICAgIGludGVydmFsLnJhbmdlID0gZnVuY3Rpb24oc3RhcnQsIHN0b3AsIHN0ZXApIHtcbiAgICAgIHZhciByYW5nZSA9IFtdO1xuICAgICAgc3RhcnQgPSBuZXcgRGF0ZShzdGFydCAtIDEpO1xuICAgICAgc3RvcCA9IG5ldyBEYXRlKCtzdG9wKTtcbiAgICAgIHN0ZXAgPSBzdGVwID09IG51bGwgPyAxIDogTWF0aC5mbG9vcihzdGVwKTtcbiAgICAgIGlmICghKHN0YXJ0IDwgc3RvcCkgfHwgIShzdGVwID4gMCkpIHJldHVybiByYW5nZTsgLy8gYWxzbyBoYW5kbGVzIEludmFsaWQgRGF0ZVxuICAgICAgb2Zmc2V0aShzdGFydCwgMSksIGZsb29yaShzdGFydCk7XG4gICAgICBpZiAoc3RhcnQgPCBzdG9wKSByYW5nZS5wdXNoKG5ldyBEYXRlKCtzdGFydCkpO1xuICAgICAgd2hpbGUgKG9mZnNldGkoc3RhcnQsIHN0ZXApLCBmbG9vcmkoc3RhcnQpLCBzdGFydCA8IHN0b3ApIHJhbmdlLnB1c2gobmV3IERhdGUoK3N0YXJ0KSk7XG4gICAgICByZXR1cm4gcmFuZ2U7XG4gICAgfTtcblxuICAgIGludGVydmFsLmZpbHRlciA9IGZ1bmN0aW9uKHRlc3QpIHtcbiAgICAgIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgIHdoaWxlIChmbG9vcmkoZGF0ZSksICF0ZXN0KGRhdGUpKSBkYXRlLnNldFRpbWUoZGF0ZSAtIDEpO1xuICAgICAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgICAgICB3aGlsZSAoLS1zdGVwID49IDApIHdoaWxlIChvZmZzZXRpKGRhdGUsIDEpLCAhdGVzdChkYXRlKSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgaWYgKGNvdW50KSBpbnRlcnZhbC5jb3VudCA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICAgIHQwLnNldFRpbWUoK3N0YXJ0KSwgdDEuc2V0VGltZSgrZW5kKTtcbiAgICAgIGZsb29yaSh0MCksIGZsb29yaSh0MSk7XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcihjb3VudCh0MCwgdDEpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGludGVydmFsO1xuICB9XG5cbiAgdmFyIGRheSA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpICsgc3RlcCk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKGVuZCAtIHN0YXJ0IC0gKGVuZC5nZXRUaW1lem9uZU9mZnNldCgpIC0gc3RhcnQuZ2V0VGltZXpvbmVPZmZzZXQoKSkgKiA2ZTQpIC8gODY0ZTU7XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIHdlZWtkYXkoaSkge1xuICAgIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xuICAgICAgZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpIC0gKGRhdGUuZ2V0RGF5KCkgKyA3IC0gaSkgJSA3KTtcbiAgICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBzdGVwICogNyk7XG4gICAgfSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgICAgcmV0dXJuIChlbmQgLSBzdGFydCAtIChlbmQuZ2V0VGltZXpvbmVPZmZzZXQoKSAtIHN0YXJ0LmdldFRpbWV6b25lT2Zmc2V0KCkpICogNmU0KSAvIDYwNDhlNTtcbiAgICB9KTtcbiAgfVxuXG4gIHZhciBzdW5kYXkgPSB3ZWVrZGF5KDApO1xuICB2YXIgbW9uZGF5ID0gd2Vla2RheSgxKTtcblxuICB2YXIgeWVhciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xuICAgIGRhdGUuc2V0TW9udGgoMCwgMSk7XG4gIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICBkYXRlLnNldEZ1bGxZZWFyKGRhdGUuZ2V0RnVsbFllYXIoKSArIHN0ZXApO1xuICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIGVuZC5nZXRGdWxsWWVhcigpIC0gc3RhcnQuZ2V0RnVsbFllYXIoKTtcbiAgfSk7XG5cbiAgdmFyIHV0Y0RheSA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRVVENEYXRlKGRhdGUuZ2V0VVRDRGF0ZSgpICsgc3RlcCk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIDg2NGU1O1xuICB9KTtcblxuICBmdW5jdGlvbiB1dGNXZWVrZGF5KGkpIHtcbiAgICByZXR1cm4gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgICAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbiAgICAgIGRhdGUuc2V0VVRDRGF0ZShkYXRlLmdldFVUQ0RhdGUoKSAtIChkYXRlLmdldFVUQ0RheSgpICsgNyAtIGkpICUgNyk7XG4gICAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgICAgZGF0ZS5zZXRVVENEYXRlKGRhdGUuZ2V0VVRDRGF0ZSgpICsgc3RlcCAqIDcpO1xuICAgIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICAgIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gNjA0OGU1O1xuICAgIH0pO1xuICB9XG5cbiAgdmFyIHV0Y1N1bmRheSA9IHV0Y1dlZWtkYXkoMCk7XG4gIHZhciB1dGNNb25kYXkgPSB1dGNXZWVrZGF5KDEpO1xuXG4gIHZhciB1dGNZZWFyID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0VVRDSG91cnMoMCwgMCwgMCwgMCk7XG4gICAgZGF0ZS5zZXRVVENNb250aCgwLCAxKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VVRDRnVsbFllYXIoZGF0ZS5nZXRVVENGdWxsWWVhcigpICsgc3RlcCk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gZW5kLmdldFVUQ0Z1bGxZZWFyKCkgLSBzdGFydC5nZXRVVENGdWxsWWVhcigpO1xuICB9KTtcblxuICBmdW5jdGlvbiBsb2NhbERhdGUoZCkge1xuICAgIGlmICgwIDw9IGQueSAmJiBkLnkgPCAxMDApIHtcbiAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoLTEsIGQubSwgZC5kLCBkLkgsIGQuTSwgZC5TLCBkLkwpO1xuICAgICAgZGF0ZS5zZXRGdWxsWWVhcihkLnkpO1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGF0ZShkLnksIGQubSwgZC5kLCBkLkgsIGQuTSwgZC5TLCBkLkwpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXRjRGF0ZShkKSB7XG4gICAgaWYgKDAgPD0gZC55ICYmIGQueSA8IDEwMCkge1xuICAgICAgdmFyIGRhdGUgPSBuZXcgRGF0ZShEYXRlLlVUQygtMSwgZC5tLCBkLmQsIGQuSCwgZC5NLCBkLlMsIGQuTCkpO1xuICAgICAgZGF0ZS5zZXRVVENGdWxsWWVhcihkLnkpO1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyhkLnksIGQubSwgZC5kLCBkLkgsIGQuTSwgZC5TLCBkLkwpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5ld1llYXIoeSkge1xuICAgIHJldHVybiB7eTogeSwgbTogMCwgZDogMSwgSDogMCwgTTogMCwgUzogMCwgTDogMH07XG4gIH1cblxuICBmdW5jdGlvbiBsb2NhbGUobG9jYWxlKSB7XG4gICAgdmFyIGxvY2FsZV9kYXRlVGltZSA9IGxvY2FsZS5kYXRlVGltZSxcbiAgICAgICAgbG9jYWxlX2RhdGUgPSBsb2NhbGUuZGF0ZSxcbiAgICAgICAgbG9jYWxlX3RpbWUgPSBsb2NhbGUudGltZSxcbiAgICAgICAgbG9jYWxlX3BlcmlvZHMgPSBsb2NhbGUucGVyaW9kcyxcbiAgICAgICAgbG9jYWxlX3dlZWtkYXlzID0gbG9jYWxlLmRheXMsXG4gICAgICAgIGxvY2FsZV9zaG9ydFdlZWtkYXlzID0gbG9jYWxlLnNob3J0RGF5cyxcbiAgICAgICAgbG9jYWxlX21vbnRocyA9IGxvY2FsZS5tb250aHMsXG4gICAgICAgIGxvY2FsZV9zaG9ydE1vbnRocyA9IGxvY2FsZS5zaG9ydE1vbnRocztcblxuICAgIHZhciBwZXJpb2RMb29rdXAgPSBmb3JtYXRMb29rdXAobG9jYWxlX3BlcmlvZHMpLFxuICAgICAgICB3ZWVrZGF5UmUgPSBmb3JtYXRSZShsb2NhbGVfd2Vla2RheXMpLFxuICAgICAgICB3ZWVrZGF5TG9va3VwID0gZm9ybWF0TG9va3VwKGxvY2FsZV93ZWVrZGF5cyksXG4gICAgICAgIHNob3J0V2Vla2RheVJlID0gZm9ybWF0UmUobG9jYWxlX3Nob3J0V2Vla2RheXMpLFxuICAgICAgICBzaG9ydFdlZWtkYXlMb29rdXAgPSBmb3JtYXRMb29rdXAobG9jYWxlX3Nob3J0V2Vla2RheXMpLFxuICAgICAgICBtb250aFJlID0gZm9ybWF0UmUobG9jYWxlX21vbnRocyksXG4gICAgICAgIG1vbnRoTG9va3VwID0gZm9ybWF0TG9va3VwKGxvY2FsZV9tb250aHMpLFxuICAgICAgICBzaG9ydE1vbnRoUmUgPSBmb3JtYXRSZShsb2NhbGVfc2hvcnRNb250aHMpLFxuICAgICAgICBzaG9ydE1vbnRoTG9va3VwID0gZm9ybWF0TG9va3VwKGxvY2FsZV9zaG9ydE1vbnRocyk7XG5cbiAgICB2YXIgZm9ybWF0cyA9IHtcbiAgICAgIFwiYVwiOiBmb3JtYXRTaG9ydFdlZWtkYXksXG4gICAgICBcIkFcIjogZm9ybWF0V2Vla2RheSxcbiAgICAgIFwiYlwiOiBmb3JtYXRTaG9ydE1vbnRoLFxuICAgICAgXCJCXCI6IGZvcm1hdE1vbnRoLFxuICAgICAgXCJjXCI6IG51bGwsXG4gICAgICBcImRcIjogZm9ybWF0RGF5T2ZNb250aCxcbiAgICAgIFwiZVwiOiBmb3JtYXREYXlPZk1vbnRoLFxuICAgICAgXCJIXCI6IGZvcm1hdEhvdXIyNCxcbiAgICAgIFwiSVwiOiBmb3JtYXRIb3VyMTIsXG4gICAgICBcImpcIjogZm9ybWF0RGF5T2ZZZWFyLFxuICAgICAgXCJMXCI6IGZvcm1hdE1pbGxpc2Vjb25kcyxcbiAgICAgIFwibVwiOiBmb3JtYXRNb250aE51bWJlcixcbiAgICAgIFwiTVwiOiBmb3JtYXRNaW51dGVzLFxuICAgICAgXCJwXCI6IGZvcm1hdFBlcmlvZCxcbiAgICAgIFwiU1wiOiBmb3JtYXRTZWNvbmRzLFxuICAgICAgXCJVXCI6IGZvcm1hdFdlZWtOdW1iZXJTdW5kYXksXG4gICAgICBcIndcIjogZm9ybWF0V2Vla2RheU51bWJlcixcbiAgICAgIFwiV1wiOiBmb3JtYXRXZWVrTnVtYmVyTW9uZGF5LFxuICAgICAgXCJ4XCI6IG51bGwsXG4gICAgICBcIlhcIjogbnVsbCxcbiAgICAgIFwieVwiOiBmb3JtYXRZZWFyLFxuICAgICAgXCJZXCI6IGZvcm1hdEZ1bGxZZWFyLFxuICAgICAgXCJaXCI6IGZvcm1hdFpvbmUsXG4gICAgICBcIiVcIjogZm9ybWF0TGl0ZXJhbFBlcmNlbnRcbiAgICB9O1xuXG4gICAgdmFyIHV0Y0Zvcm1hdHMgPSB7XG4gICAgICBcImFcIjogZm9ybWF0VVRDU2hvcnRXZWVrZGF5LFxuICAgICAgXCJBXCI6IGZvcm1hdFVUQ1dlZWtkYXksXG4gICAgICBcImJcIjogZm9ybWF0VVRDU2hvcnRNb250aCxcbiAgICAgIFwiQlwiOiBmb3JtYXRVVENNb250aCxcbiAgICAgIFwiY1wiOiBudWxsLFxuICAgICAgXCJkXCI6IGZvcm1hdFVUQ0RheU9mTW9udGgsXG4gICAgICBcImVcIjogZm9ybWF0VVRDRGF5T2ZNb250aCxcbiAgICAgIFwiSFwiOiBmb3JtYXRVVENIb3VyMjQsXG4gICAgICBcIklcIjogZm9ybWF0VVRDSG91cjEyLFxuICAgICAgXCJqXCI6IGZvcm1hdFVUQ0RheU9mWWVhcixcbiAgICAgIFwiTFwiOiBmb3JtYXRVVENNaWxsaXNlY29uZHMsXG4gICAgICBcIm1cIjogZm9ybWF0VVRDTW9udGhOdW1iZXIsXG4gICAgICBcIk1cIjogZm9ybWF0VVRDTWludXRlcyxcbiAgICAgIFwicFwiOiBmb3JtYXRVVENQZXJpb2QsXG4gICAgICBcIlNcIjogZm9ybWF0VVRDU2Vjb25kcyxcbiAgICAgIFwiVVwiOiBmb3JtYXRVVENXZWVrTnVtYmVyU3VuZGF5LFxuICAgICAgXCJ3XCI6IGZvcm1hdFVUQ1dlZWtkYXlOdW1iZXIsXG4gICAgICBcIldcIjogZm9ybWF0VVRDV2Vla051bWJlck1vbmRheSxcbiAgICAgIFwieFwiOiBudWxsLFxuICAgICAgXCJYXCI6IG51bGwsXG4gICAgICBcInlcIjogZm9ybWF0VVRDWWVhcixcbiAgICAgIFwiWVwiOiBmb3JtYXRVVENGdWxsWWVhcixcbiAgICAgIFwiWlwiOiBmb3JtYXRVVENab25lLFxuICAgICAgXCIlXCI6IGZvcm1hdExpdGVyYWxQZXJjZW50XG4gICAgfTtcblxuICAgIHZhciBwYXJzZXMgPSB7XG4gICAgICBcImFcIjogcGFyc2VTaG9ydFdlZWtkYXksXG4gICAgICBcIkFcIjogcGFyc2VXZWVrZGF5LFxuICAgICAgXCJiXCI6IHBhcnNlU2hvcnRNb250aCxcbiAgICAgIFwiQlwiOiBwYXJzZU1vbnRoLFxuICAgICAgXCJjXCI6IHBhcnNlTG9jYWxlRGF0ZVRpbWUsXG4gICAgICBcImRcIjogcGFyc2VEYXlPZk1vbnRoLFxuICAgICAgXCJlXCI6IHBhcnNlRGF5T2ZNb250aCxcbiAgICAgIFwiSFwiOiBwYXJzZUhvdXIyNCxcbiAgICAgIFwiSVwiOiBwYXJzZUhvdXIyNCxcbiAgICAgIFwialwiOiBwYXJzZURheU9mWWVhcixcbiAgICAgIFwiTFwiOiBwYXJzZU1pbGxpc2Vjb25kcyxcbiAgICAgIFwibVwiOiBwYXJzZU1vbnRoTnVtYmVyLFxuICAgICAgXCJNXCI6IHBhcnNlTWludXRlcyxcbiAgICAgIFwicFwiOiBwYXJzZVBlcmlvZCxcbiAgICAgIFwiU1wiOiBwYXJzZVNlY29uZHMsXG4gICAgICBcIlVcIjogcGFyc2VXZWVrTnVtYmVyU3VuZGF5LFxuICAgICAgXCJ3XCI6IHBhcnNlV2Vla2RheU51bWJlcixcbiAgICAgIFwiV1wiOiBwYXJzZVdlZWtOdW1iZXJNb25kYXksXG4gICAgICBcInhcIjogcGFyc2VMb2NhbGVEYXRlLFxuICAgICAgXCJYXCI6IHBhcnNlTG9jYWxlVGltZSxcbiAgICAgIFwieVwiOiBwYXJzZVllYXIsXG4gICAgICBcIllcIjogcGFyc2VGdWxsWWVhcixcbiAgICAgIFwiWlwiOiBwYXJzZVpvbmUsXG4gICAgICBcIiVcIjogcGFyc2VMaXRlcmFsUGVyY2VudFxuICAgIH07XG5cbiAgICAvLyBUaGVzZSByZWN1cnNpdmUgZGlyZWN0aXZlIGRlZmluaXRpb25zIG11c3QgYmUgZGVmZXJyZWQuXG4gICAgZm9ybWF0cy54ID0gbmV3Rm9ybWF0KGxvY2FsZV9kYXRlLCBmb3JtYXRzKTtcbiAgICBmb3JtYXRzLlggPSBuZXdGb3JtYXQobG9jYWxlX3RpbWUsIGZvcm1hdHMpO1xuICAgIGZvcm1hdHMuYyA9IG5ld0Zvcm1hdChsb2NhbGVfZGF0ZVRpbWUsIGZvcm1hdHMpO1xuICAgIHV0Y0Zvcm1hdHMueCA9IG5ld0Zvcm1hdChsb2NhbGVfZGF0ZSwgdXRjRm9ybWF0cyk7XG4gICAgdXRjRm9ybWF0cy5YID0gbmV3Rm9ybWF0KGxvY2FsZV90aW1lLCB1dGNGb3JtYXRzKTtcbiAgICB1dGNGb3JtYXRzLmMgPSBuZXdGb3JtYXQobG9jYWxlX2RhdGVUaW1lLCB1dGNGb3JtYXRzKTtcblxuICAgIGZ1bmN0aW9uIG5ld0Zvcm1hdChzcGVjaWZpZXIsIGZvcm1hdHMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgIHZhciBzdHJpbmcgPSBbXSxcbiAgICAgICAgICAgIGkgPSAtMSxcbiAgICAgICAgICAgIGogPSAwLFxuICAgICAgICAgICAgbiA9IHNwZWNpZmllci5sZW5ndGgsXG4gICAgICAgICAgICBjLFxuICAgICAgICAgICAgcGFkLFxuICAgICAgICAgICAgZm9ybWF0O1xuXG4gICAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgICAgaWYgKHNwZWNpZmllci5jaGFyQ29kZUF0KGkpID09PSAzNykge1xuICAgICAgICAgICAgc3RyaW5nLnB1c2goc3BlY2lmaWVyLnNsaWNlKGosIGkpKTtcbiAgICAgICAgICAgIGlmICgocGFkID0gcGFkc1tjID0gc3BlY2lmaWVyLmNoYXJBdCgrK2kpXSkgIT0gbnVsbCkgYyA9IHNwZWNpZmllci5jaGFyQXQoKytpKTtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPSBmb3JtYXRzW2NdKSBjID0gZm9ybWF0KGRhdGUsIHBhZCA9PSBudWxsID8gKGMgPT09IFwiZVwiID8gXCIgXCIgOiBcIjBcIikgOiBwYWQpO1xuICAgICAgICAgICAgc3RyaW5nLnB1c2goYyk7XG4gICAgICAgICAgICBqID0gaSArIDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3RyaW5nLnB1c2goc3BlY2lmaWVyLnNsaWNlKGosIGkpKTtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5qb2luKFwiXCIpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBuZXdQYXJzZShzcGVjaWZpZXIsIG5ld0RhdGUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgICAgdmFyIGQgPSBuZXdZZWFyKDE5MDApLFxuICAgICAgICAgICAgaSA9IHBhcnNlU3BlY2lmaWVyKGQsIHNwZWNpZmllciwgc3RyaW5nLCAwKTtcbiAgICAgICAgaWYgKGkgIT0gc3RyaW5nLmxlbmd0aCkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgLy8gVGhlIGFtLXBtIGZsYWcgaXMgMCBmb3IgQU0sIGFuZCAxIGZvciBQTS5cbiAgICAgICAgaWYgKFwicFwiIGluIGQpIGQuSCA9IGQuSCAlIDEyICsgZC5wICogMTI7XG5cbiAgICAgICAgLy8gSWYgYSB0aW1lIHpvbmUgaXMgc3BlY2lmaWVkLCBhbGwgZmllbGRzIGFyZSBpbnRlcnByZXRlZCBhcyBVVEMgYW5kIHRoZW5cbiAgICAgICAgLy8gb2Zmc2V0IGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIHRpbWUgem9uZS5cbiAgICAgICAgaWYgKFwiWlwiIGluIGQpIHtcbiAgICAgICAgICBpZiAoXCJ3XCIgaW4gZCAmJiAoXCJXXCIgaW4gZCB8fCBcIlVcIiBpbiBkKSkge1xuICAgICAgICAgICAgdmFyIGRheSA9IHV0Y0RhdGUobmV3WWVhcihkLnkpKS5nZXRVVENEYXkoKTtcbiAgICAgICAgICAgIGlmIChcIldcIiBpbiBkKSBkLlUgPSBkLlcsIGQudyA9IChkLncgKyA2KSAlIDcsIC0tZGF5O1xuICAgICAgICAgICAgZC5tID0gMDtcbiAgICAgICAgICAgIGQuZCA9IGQudyArIGQuVSAqIDcgLSAoZGF5ICsgNikgJSA3O1xuICAgICAgICAgIH1cbiAgICAgICAgICBkLkggKz0gZC5aIC8gMTAwIHwgMDtcbiAgICAgICAgICBkLk0gKz0gZC5aICUgMTAwO1xuICAgICAgICAgIHJldHVybiB1dGNEYXRlKGQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBhbGwgZmllbGRzIGFyZSBpbiBsb2NhbCB0aW1lLlxuICAgICAgICBpZiAoXCJ3XCIgaW4gZCAmJiAoXCJXXCIgaW4gZCB8fCBcIlVcIiBpbiBkKSkge1xuICAgICAgICAgIHZhciBkYXkgPSBuZXdEYXRlKG5ld1llYXIoZC55KSkuZ2V0RGF5KCk7XG4gICAgICAgICAgaWYgKFwiV1wiIGluIGQpIGQuVSA9IGQuVywgZC53ID0gKGQudyArIDYpICUgNywgLS1kYXk7XG4gICAgICAgICAgZC5tID0gMDtcbiAgICAgICAgICBkLmQgPSBkLncgKyBkLlUgKiA3IC0gKGRheSArIDYpICUgNztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3RGF0ZShkKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VTcGVjaWZpZXIoZCwgc3BlY2lmaWVyLCBzdHJpbmcsIGopIHtcbiAgICAgIHZhciBpID0gMCxcbiAgICAgICAgICBuID0gc3BlY2lmaWVyLmxlbmd0aCxcbiAgICAgICAgICBtID0gc3RyaW5nLmxlbmd0aCxcbiAgICAgICAgICBjLFxuICAgICAgICAgIHBhcnNlO1xuXG4gICAgICB3aGlsZSAoaSA8IG4pIHtcbiAgICAgICAgaWYgKGogPj0gbSkgcmV0dXJuIC0xO1xuICAgICAgICBjID0gc3BlY2lmaWVyLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgICAgaWYgKGMgPT09IDM3KSB7XG4gICAgICAgICAgYyA9IHNwZWNpZmllci5jaGFyQXQoaSsrKTtcbiAgICAgICAgICBwYXJzZSA9IHBhcnNlc1tjIGluIHBhZHMgPyBzcGVjaWZpZXIuY2hhckF0KGkrKykgOiBjXTtcbiAgICAgICAgICBpZiAoIXBhcnNlIHx8ICgoaiA9IHBhcnNlKGQsIHN0cmluZywgaikpIDwgMCkpIHJldHVybiAtMTtcbiAgICAgICAgfSBlbHNlIGlmIChjICE9IHN0cmluZy5jaGFyQ29kZUF0KGorKykpIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGo7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VTaG9ydFdlZWtkYXkoZCwgc3RyaW5nLCBpKSB7XG4gICAgICB2YXIgbiA9IHNob3J0V2Vla2RheVJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgICAgIHJldHVybiBuID8gKGQudyA9IHNob3J0V2Vla2RheUxvb2t1cC5nZXQoblswXS50b0xvd2VyQ2FzZSgpKSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlV2Vla2RheShkLCBzdHJpbmcsIGkpIHtcbiAgICAgIHZhciBuID0gd2Vla2RheVJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgICAgIHJldHVybiBuID8gKGQudyA9IHdlZWtkYXlMb29rdXAuZ2V0KG5bMF0udG9Mb3dlckNhc2UoKSksIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVNob3J0TW9udGgoZCwgc3RyaW5nLCBpKSB7XG4gICAgICB2YXIgbiA9IHNob3J0TW9udGhSZS5leGVjKHN0cmluZy5zbGljZShpKSk7XG4gICAgICByZXR1cm4gbiA/IChkLm0gPSBzaG9ydE1vbnRoTG9va3VwLmdldChuWzBdLnRvTG93ZXJDYXNlKCkpLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VNb250aChkLCBzdHJpbmcsIGkpIHtcbiAgICAgIHZhciBuID0gbW9udGhSZS5leGVjKHN0cmluZy5zbGljZShpKSk7XG4gICAgICByZXR1cm4gbiA/IChkLm0gPSBtb250aExvb2t1cC5nZXQoblswXS50b0xvd2VyQ2FzZSgpKSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTG9jYWxlRGF0ZVRpbWUoZCwgc3RyaW5nLCBpKSB7XG4gICAgICByZXR1cm4gcGFyc2VTcGVjaWZpZXIoZCwgbG9jYWxlX2RhdGVUaW1lLCBzdHJpbmcsIGkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTG9jYWxlRGF0ZShkLCBzdHJpbmcsIGkpIHtcbiAgICAgIHJldHVybiBwYXJzZVNwZWNpZmllcihkLCBsb2NhbGVfZGF0ZSwgc3RyaW5nLCBpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUxvY2FsZVRpbWUoZCwgc3RyaW5nLCBpKSB7XG4gICAgICByZXR1cm4gcGFyc2VTcGVjaWZpZXIoZCwgbG9jYWxlX3RpbWUsIHN0cmluZywgaSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VQZXJpb2QoZCwgc3RyaW5nLCBpKSB7XG4gICAgICB2YXIgbiA9IHBlcmlvZExvb2t1cC5nZXQoc3RyaW5nLnNsaWNlKGksIGkgKz0gMikudG9Mb3dlckNhc2UoKSk7XG4gICAgICByZXR1cm4gbiA9PSBudWxsID8gLTEgOiAoZC5wID0gbiwgaSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0U2hvcnRXZWVrZGF5KGQpIHtcbiAgICAgIHJldHVybiBsb2NhbGVfc2hvcnRXZWVrZGF5c1tkLmdldERheSgpXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmb3JtYXRXZWVrZGF5KGQpIHtcbiAgICAgIHJldHVybiBsb2NhbGVfd2Vla2RheXNbZC5nZXREYXkoKV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0U2hvcnRNb250aChkKSB7XG4gICAgICByZXR1cm4gbG9jYWxlX3Nob3J0TW9udGhzW2QuZ2V0TW9udGgoKV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0TW9udGgoZCkge1xuICAgICAgcmV0dXJuIGxvY2FsZV9tb250aHNbZC5nZXRNb250aCgpXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmb3JtYXRQZXJpb2QoZCkge1xuICAgICAgcmV0dXJuIGxvY2FsZV9wZXJpb2RzWysoZC5nZXRIb3VycygpID49IDEyKV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0VVRDU2hvcnRXZWVrZGF5KGQpIHtcbiAgICAgIHJldHVybiBsb2NhbGVfc2hvcnRXZWVrZGF5c1tkLmdldFVUQ0RheSgpXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmb3JtYXRVVENXZWVrZGF5KGQpIHtcbiAgICAgIHJldHVybiBsb2NhbGVfd2Vla2RheXNbZC5nZXRVVENEYXkoKV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0VVRDU2hvcnRNb250aChkKSB7XG4gICAgICByZXR1cm4gbG9jYWxlX3Nob3J0TW9udGhzW2QuZ2V0VVRDTW9udGgoKV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0VVRDTW9udGgoZCkge1xuICAgICAgcmV0dXJuIGxvY2FsZV9tb250aHNbZC5nZXRVVENNb250aCgpXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmb3JtYXRVVENQZXJpb2QoZCkge1xuICAgICAgcmV0dXJuIGxvY2FsZV9wZXJpb2RzWysoZC5nZXRVVENIb3VycygpID49IDEyKV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZvcm1hdDogZnVuY3Rpb24oc3BlY2lmaWVyKSB7XG4gICAgICAgIHZhciBmID0gbmV3Rm9ybWF0KHNwZWNpZmllciArPSBcIlwiLCBmb3JtYXRzKTtcbiAgICAgICAgZi5wYXJzZSA9IG5ld1BhcnNlKHNwZWNpZmllciwgbG9jYWxEYXRlKTtcbiAgICAgICAgZi50b1N0cmluZyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gc3BlY2lmaWVyOyB9O1xuICAgICAgICByZXR1cm4gZjtcbiAgICAgIH0sXG4gICAgICB1dGNGb3JtYXQ6IGZ1bmN0aW9uKHNwZWNpZmllcikge1xuICAgICAgICB2YXIgZiA9IG5ld0Zvcm1hdChzcGVjaWZpZXIgKz0gXCJcIiwgdXRjRm9ybWF0cyk7XG4gICAgICAgIGYucGFyc2UgPSBuZXdQYXJzZShzcGVjaWZpZXIsIHV0Y0RhdGUpO1xuICAgICAgICBmLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7IHJldHVybiBzcGVjaWZpZXI7IH07XG4gICAgICAgIHJldHVybiBmO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICB2YXIgcGFkcyA9IHtcIi1cIjogXCJcIiwgXCJfXCI6IFwiIFwiLCBcIjBcIjogXCIwXCJ9O1xuICB2YXIgbnVtYmVyUmUgPSAvXlxccypcXGQrLztcbiAgdmFyIHBlcmNlbnRSZSA9IC9eJS87XG4gIHZhciByZXF1b3RlUmUgPSAvW1xcXFxcXF5cXCRcXCpcXCtcXD9cXHxcXFtcXF1cXChcXClcXC5cXHtcXH1dL2c7XG5cbiAgZnVuY3Rpb24gcGFkKHZhbHVlLCBmaWxsLCB3aWR0aCkge1xuICAgIHZhciBzaWduID0gdmFsdWUgPCAwID8gXCItXCIgOiBcIlwiLFxuICAgICAgICBzdHJpbmcgPSAoc2lnbiA/IC12YWx1ZSA6IHZhbHVlKSArIFwiXCIsXG4gICAgICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG4gICAgcmV0dXJuIHNpZ24gKyAobGVuZ3RoIDwgd2lkdGggPyBuZXcgQXJyYXkod2lkdGggLSBsZW5ndGggKyAxKS5qb2luKGZpbGwpICsgc3RyaW5nIDogc3RyaW5nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcXVvdGUocykge1xuICAgIHJldHVybiBzLnJlcGxhY2UocmVxdW90ZVJlLCBcIlxcXFwkJlwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFJlKG5hbWVzKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoXCJeKD86XCIgKyBuYW1lcy5tYXAocmVxdW90ZSkuam9pbihcInxcIikgKyBcIilcIiwgXCJpXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0TG9va3VwKG5hbWVzKSB7XG4gICAgdmFyIG1hcCA9IG5ldyBNYXAsIGkgPSAtMSwgbiA9IG5hbWVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgbWFwLnNldChuYW1lc1tpXS50b0xvd2VyQ2FzZSgpLCBpKTtcbiAgICByZXR1cm4gbWFwO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VXZWVrZGF5TnVtYmVyKGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDEpKTtcbiAgICByZXR1cm4gbiA/IChkLncgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VXZWVrTnVtYmVyU3VuZGF5KGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICAgIHJldHVybiBuID8gKGQuVSA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVdlZWtOdW1iZXJNb25kYXkoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpKSk7XG4gICAgcmV0dXJuIG4gPyAoZC5XID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlRnVsbFllYXIoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgNCkpO1xuICAgIHJldHVybiBuID8gKGQueSA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVllYXIoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICAgIHJldHVybiBuID8gKGQueSA9ICtuWzBdICsgKCtuWzBdID4gNjggPyAxOTAwIDogMjAwMCksIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlWm9uZShkLCBzdHJpbmcsIGkpIHtcbiAgICByZXR1cm4gL15bKy1dXFxkezR9JC8udGVzdChzdHJpbmcgPSBzdHJpbmcuc2xpY2UoaSwgaSArIDUpKVxuICAgICAgICA/IChkLlogPSAtc3RyaW5nLCBpICsgNSkgLy8gc2lnbiBkaWZmZXJzIGZyb20gZ2V0VGltZXpvbmVPZmZzZXQhXG4gICAgICAgIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZU1vbnRoTnVtYmVyKGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgICByZXR1cm4gbiA/IChkLm0gPSBuWzBdIC0gMSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VEYXlPZk1vbnRoKGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgICByZXR1cm4gbiA/IChkLmQgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VEYXlPZlllYXIoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMykpO1xuICAgIHJldHVybiBuID8gKGQubSA9IDAsIGQuZCA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZUhvdXIyNChkLCBzdHJpbmcsIGkpIHtcbiAgICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAyKSk7XG4gICAgcmV0dXJuIG4gPyAoZC5IID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTWludXRlcyhkLCBzdHJpbmcsIGkpIHtcbiAgICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAyKSk7XG4gICAgcmV0dXJuIG4gPyAoZC5NID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlU2Vjb25kcyhkLCBzdHJpbmcsIGkpIHtcbiAgICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAyKSk7XG4gICAgcmV0dXJuIG4gPyAoZC5TID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTWlsbGlzZWNvbmRzKGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDMpKTtcbiAgICByZXR1cm4gbiA/IChkLkwgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VMaXRlcmFsUGVyY2VudChkLCBzdHJpbmcsIGkpIHtcbiAgICB2YXIgbiA9IHBlcmNlbnRSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMSkpO1xuICAgIHJldHVybiBuID8gaSArIG5bMF0ubGVuZ3RoIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXREYXlPZk1vbnRoKGQsIHApIHtcbiAgICByZXR1cm4gcGFkKGQuZ2V0RGF0ZSgpLCBwLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdEhvdXIyNChkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChkLmdldEhvdXJzKCksIHAsIDIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0SG91cjEyKGQsIHApIHtcbiAgICByZXR1cm4gcGFkKGQuZ2V0SG91cnMoKSAlIDEyIHx8IDEyLCBwLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdERheU9mWWVhcihkLCBwKSB7XG4gICAgcmV0dXJuIHBhZCgxICsgZGF5LmNvdW50KHllYXIoZCksIGQpLCBwLCAzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdE1pbGxpc2Vjb25kcyhkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChkLmdldE1pbGxpc2Vjb25kcygpLCBwLCAzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdE1vbnRoTnVtYmVyKGQsIHApIHtcbiAgICByZXR1cm4gcGFkKGQuZ2V0TW9udGgoKSArIDEsIHAsIDIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0TWludXRlcyhkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChkLmdldE1pbnV0ZXMoKSwgcCwgMik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRTZWNvbmRzKGQsIHApIHtcbiAgICByZXR1cm4gcGFkKGQuZ2V0U2Vjb25kcygpLCBwLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFdlZWtOdW1iZXJTdW5kYXkoZCwgcCkge1xuICAgIHJldHVybiBwYWQoc3VuZGF5LmNvdW50KHllYXIoZCksIGQpLCBwLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFdlZWtkYXlOdW1iZXIoZCkge1xuICAgIHJldHVybiBkLmdldERheSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0V2Vla051bWJlck1vbmRheShkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChtb25kYXkuY291bnQoeWVhcihkKSwgZCksIHAsIDIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0WWVhcihkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChkLmdldEZ1bGxZZWFyKCkgJSAxMDAsIHAsIDIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0RnVsbFllYXIoZCwgcCkge1xuICAgIHJldHVybiBwYWQoZC5nZXRGdWxsWWVhcigpICUgMTAwMDAsIHAsIDQpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0Wm9uZShkKSB7XG4gICAgdmFyIHogPSBkLmdldFRpbWV6b25lT2Zmc2V0KCk7XG4gICAgcmV0dXJuICh6ID4gMCA/IFwiLVwiIDogKHogKj0gLTEsIFwiK1wiKSlcbiAgICAgICAgKyBwYWQoeiAvIDYwIHwgMCwgXCIwXCIsIDIpXG4gICAgICAgICsgcGFkKHogJSA2MCwgXCIwXCIsIDIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0VVRDRGF5T2ZNb250aChkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChkLmdldFVUQ0RhdGUoKSwgcCwgMik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENIb3VyMjQoZCwgcCkge1xuICAgIHJldHVybiBwYWQoZC5nZXRVVENIb3VycygpLCBwLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ0hvdXIxMihkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChkLmdldFVUQ0hvdXJzKCkgJSAxMiB8fCAxMiwgcCwgMik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENEYXlPZlllYXIoZCwgcCkge1xuICAgIHJldHVybiBwYWQoMSArIHV0Y0RheS5jb3VudCh1dGNZZWFyKGQpLCBkKSwgcCwgMyk7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENNaWxsaXNlY29uZHMoZCwgcCkge1xuICAgIHJldHVybiBwYWQoZC5nZXRVVENNaWxsaXNlY29uZHMoKSwgcCwgMyk7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENNb250aE51bWJlcihkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChkLmdldFVUQ01vbnRoKCkgKyAxLCBwLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ01pbnV0ZXMoZCwgcCkge1xuICAgIHJldHVybiBwYWQoZC5nZXRVVENNaW51dGVzKCksIHAsIDIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0VVRDU2Vjb25kcyhkLCBwKSB7XG4gICAgcmV0dXJuIHBhZChkLmdldFVUQ1NlY29uZHMoKSwgcCwgMik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENXZWVrTnVtYmVyU3VuZGF5KGQsIHApIHtcbiAgICByZXR1cm4gcGFkKHV0Y1N1bmRheS5jb3VudCh1dGNZZWFyKGQpLCBkKSwgcCwgMik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRVVENXZWVrZGF5TnVtYmVyKGQpIHtcbiAgICByZXR1cm4gZC5nZXRVVENEYXkoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1dlZWtOdW1iZXJNb25kYXkoZCwgcCkge1xuICAgIHJldHVybiBwYWQodXRjTW9uZGF5LmNvdW50KHV0Y1llYXIoZCksIGQpLCBwLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1llYXIoZCwgcCkge1xuICAgIHJldHVybiBwYWQoZC5nZXRVVENGdWxsWWVhcigpICUgMTAwLCBwLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ0Z1bGxZZWFyKGQsIHApIHtcbiAgICByZXR1cm4gcGFkKGQuZ2V0VVRDRnVsbFllYXIoKSAlIDEwMDAwLCBwLCA0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1pvbmUoKSB7XG4gICAgcmV0dXJuIFwiKzAwMDBcIjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdExpdGVyYWxQZXJjZW50KCkge1xuICAgIHJldHVybiBcIiVcIjtcbiAgfVxuXG4gIHZhciBpc29TcGVjaWZpZXIgPSBcIiVZLSVtLSVkVCVIOiVNOiVTLiVMWlwiO1xuXG4gIGZ1bmN0aW9uIGZvcm1hdElzb05hdGl2ZShkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUudG9JU09TdHJpbmcoKTtcbiAgfVxuXG4gIGZvcm1hdElzb05hdGl2ZS5wYXJzZSA9IGZ1bmN0aW9uKHN0cmluZykge1xuICAgIHZhciBkYXRlID0gbmV3IERhdGUoc3RyaW5nKTtcbiAgICByZXR1cm4gaXNOYU4oZGF0ZSkgPyBudWxsIDogZGF0ZTtcbiAgfTtcblxuICBmb3JtYXRJc29OYXRpdmUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gaXNvU3BlY2lmaWVyO1xuICB9O1xuXG4gIHZhciBmb3JtYXRJc28gPSBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZyAmJiArbmV3IERhdGUoXCIyMDAwLTAxLTAxVDAwOjAwOjAwLjAwMFpcIilcbiAgICAgID8gZm9ybWF0SXNvTmF0aXZlXG4gICAgICA6IGVuVXMudXRjRm9ybWF0KGlzb1NwZWNpZmllcik7XG5cbiAgdmFyIGlzb0Zvcm1hdCA9IGZvcm1hdElzbztcblxuICB2YXIgbG9jYWxlRGVmaW5pdGlvbnMgPSAobmV3IE1hcClcbiAgICAgIC5zZXQoXCJjYS1FU1wiLCBjYUVzKVxuICAgICAgLnNldChcImRlLURFXCIsIGRlRGUpXG4gICAgICAuc2V0KFwiZW4tQ0FcIiwgZW5DYSlcbiAgICAgIC5zZXQoXCJlbi1HQlwiLCBlbkdiKVxuICAgICAgLnNldChcImVuLVVTXCIsIGVuVXMpXG4gICAgICAuc2V0KFwiZXMtRVNcIiwgZXNFcylcbiAgICAgIC5zZXQoXCJmaS1GSVwiLCBmaUZpKVxuICAgICAgLnNldChcImZyLUNBXCIsIGZyQ2EpXG4gICAgICAuc2V0KFwiZnItRlJcIiwgZnJGcilcbiAgICAgIC5zZXQoXCJoZS1JTFwiLCBoZUlsKVxuICAgICAgLnNldChcIml0LUlUXCIsIGl0SXQpXG4gICAgICAuc2V0KFwibWstTUtcIiwgbWtNaylcbiAgICAgIC5zZXQoXCJubC1OTFwiLCBubE5sKVxuICAgICAgLnNldChcInBsLVBMXCIsIHBsUGwpXG4gICAgICAuc2V0KFwicHQtQlJcIiwgcHRCcilcbiAgICAgIC5zZXQoXCJydS1SVVwiLCBydVJ1KVxuICAgICAgLnNldChcInpoLUNOXCIsIHpoQ24pO1xuXG4gIHZhciBkZWZhdWx0TG9jYWxlID0gbG9jYWxlKGVuVXMpO1xuICBleHBvcnRzLmZvcm1hdCA9IGRlZmF1bHRMb2NhbGUuZm9ybWF0O1xuICBleHBvcnRzLnV0Y0Zvcm1hdCA9IGRlZmF1bHRMb2NhbGUudXRjRm9ybWF0O1xuXG4gIGZ1bmN0aW9uIGxvY2FsZUZvcm1hdChkZWZpbml0aW9uKSB7XG4gICAgaWYgKHR5cGVvZiBkZWZpbml0aW9uID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBkZWZpbml0aW9uID0gbG9jYWxlRGVmaW5pdGlvbnMuZ2V0KGRlZmluaXRpb24pO1xuICAgICAgaWYgKCFkZWZpbml0aW9uKSByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGxvY2FsZShkZWZpbml0aW9uKTtcbiAgfVxuICA7XG5cbiAgZXhwb3J0cy5sb2NhbGVGb3JtYXQgPSBsb2NhbGVGb3JtYXQ7XG4gIGV4cG9ydHMuaXNvRm9ybWF0ID0gaXNvRm9ybWF0O1xuXG59KSk7IiwiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG4gIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSkgOlxuICBmYWN0b3J5KChnbG9iYWwudGltZSA9IHt9KSk7XG59KHRoaXMsIGZ1bmN0aW9uIChleHBvcnRzKSB7ICd1c2Ugc3RyaWN0JztcblxuICB2YXIgdDEgPSBuZXcgRGF0ZTtcblxuICB2YXIgdDAgPSBuZXcgRGF0ZTtcblxuICBmdW5jdGlvbiBuZXdJbnRlcnZhbChmbG9vcmksIG9mZnNldGksIGNvdW50KSB7XG5cbiAgICBmdW5jdGlvbiBpbnRlcnZhbChkYXRlKSB7XG4gICAgICByZXR1cm4gZmxvb3JpKGRhdGUgPSBuZXcgRGF0ZSgrZGF0ZSkpLCBkYXRlO1xuICAgIH1cblxuICAgIGludGVydmFsLmZsb29yID0gaW50ZXJ2YWw7XG5cbiAgICBpbnRlcnZhbC5yb3VuZCA9IGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgIHZhciBkMCA9IG5ldyBEYXRlKCtkYXRlKSxcbiAgICAgICAgICBkMSA9IG5ldyBEYXRlKGRhdGUgLSAxKTtcbiAgICAgIGZsb29yaShkMCksIGZsb29yaShkMSksIG9mZnNldGkoZDEsIDEpO1xuICAgICAgcmV0dXJuIGRhdGUgLSBkMCA8IGQxIC0gZGF0ZSA/IGQwIDogZDE7XG4gICAgfTtcblxuICAgIGludGVydmFsLmNlaWwgPSBmdW5jdGlvbihkYXRlKSB7XG4gICAgICByZXR1cm4gZmxvb3JpKGRhdGUgPSBuZXcgRGF0ZShkYXRlIC0gMSkpLCBvZmZzZXRpKGRhdGUsIDEpLCBkYXRlO1xuICAgIH07XG5cbiAgICBpbnRlcnZhbC5vZmZzZXQgPSBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgICByZXR1cm4gb2Zmc2V0aShkYXRlID0gbmV3IERhdGUoK2RhdGUpLCBzdGVwID09IG51bGwgPyAxIDogTWF0aC5mbG9vcihzdGVwKSksIGRhdGU7XG4gICAgfTtcblxuICAgIGludGVydmFsLnJhbmdlID0gZnVuY3Rpb24oc3RhcnQsIHN0b3AsIHN0ZXApIHtcbiAgICAgIHZhciByYW5nZSA9IFtdO1xuICAgICAgc3RhcnQgPSBuZXcgRGF0ZShzdGFydCAtIDEpO1xuICAgICAgc3RvcCA9IG5ldyBEYXRlKCtzdG9wKTtcbiAgICAgIHN0ZXAgPSBzdGVwID09IG51bGwgPyAxIDogTWF0aC5mbG9vcihzdGVwKTtcbiAgICAgIGlmICghKHN0YXJ0IDwgc3RvcCkgfHwgIShzdGVwID4gMCkpIHJldHVybiByYW5nZTsgLy8gYWxzbyBoYW5kbGVzIEludmFsaWQgRGF0ZVxuICAgICAgb2Zmc2V0aShzdGFydCwgMSksIGZsb29yaShzdGFydCk7XG4gICAgICBpZiAoc3RhcnQgPCBzdG9wKSByYW5nZS5wdXNoKG5ldyBEYXRlKCtzdGFydCkpO1xuICAgICAgd2hpbGUgKG9mZnNldGkoc3RhcnQsIHN0ZXApLCBmbG9vcmkoc3RhcnQpLCBzdGFydCA8IHN0b3ApIHJhbmdlLnB1c2gobmV3IERhdGUoK3N0YXJ0KSk7XG4gICAgICByZXR1cm4gcmFuZ2U7XG4gICAgfTtcblxuICAgIGludGVydmFsLmZpbHRlciA9IGZ1bmN0aW9uKHRlc3QpIHtcbiAgICAgIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgIHdoaWxlIChmbG9vcmkoZGF0ZSksICF0ZXN0KGRhdGUpKSBkYXRlLnNldFRpbWUoZGF0ZSAtIDEpO1xuICAgICAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgICAgICB3aGlsZSAoLS1zdGVwID49IDApIHdoaWxlIChvZmZzZXRpKGRhdGUsIDEpLCAhdGVzdChkYXRlKSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgaWYgKGNvdW50KSBpbnRlcnZhbC5jb3VudCA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICAgIHQwLnNldFRpbWUoK3N0YXJ0KSwgdDEuc2V0VGltZSgrZW5kKTtcbiAgICAgIGZsb29yaSh0MCksIGZsb29yaSh0MSk7XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcihjb3VudCh0MCwgdDEpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGludGVydmFsO1xuICB9XG5cbiAgdmFyIHNlY29uZCA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldE1pbGxpc2Vjb25kcygwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXAgKiAxZTMpO1xuICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyAxZTM7XG4gIH0pO1xuXG4gIGV4cG9ydHMuc2Vjb25kcyA9IHNlY29uZC5yYW5nZTtcblxuICB2YXIgbWludXRlID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0U2Vjb25kcygwLCAwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXAgKiA2ZTQpO1xuICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyA2ZTQ7XG4gIH0pO1xuXG4gIGV4cG9ydHMubWludXRlcyA9IG1pbnV0ZS5yYW5nZTtcblxuICB2YXIgaG91ciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldE1pbnV0ZXMoMCwgMCwgMCk7XG4gIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogMzZlNSk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIDM2ZTU7XG4gIH0pO1xuXG4gIGV4cG9ydHMuaG91cnMgPSBob3VyLnJhbmdlO1xuXG4gIHZhciBkYXkgPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIHN0ZXApO1xuICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIChlbmQgLSBzdGFydCAtIChlbmQuZ2V0VGltZXpvbmVPZmZzZXQoKSAtIHN0YXJ0LmdldFRpbWV6b25lT2Zmc2V0KCkpICogNmU0KSAvIDg2NGU1O1xuICB9KTtcblxuICBleHBvcnRzLmRheXMgPSBkYXkucmFuZ2U7XG5cbiAgZnVuY3Rpb24gd2Vla2RheShpKSB7XG4gICAgcmV0dXJuIG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gICAgICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgLSAoZGF0ZS5nZXREYXkoKSArIDcgLSBpKSAlIDcpO1xuICAgIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICAgIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIHN0ZXAgKiA3KTtcbiAgICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgICByZXR1cm4gKGVuZCAtIHN0YXJ0IC0gKGVuZC5nZXRUaW1lem9uZU9mZnNldCgpIC0gc3RhcnQuZ2V0VGltZXpvbmVPZmZzZXQoKSkgKiA2ZTQpIC8gNjA0OGU1O1xuICAgIH0pO1xuICB9XG5cbiAgZXhwb3J0cy5zdW5kYXkgPSB3ZWVrZGF5KDApO1xuXG4gIGV4cG9ydHMuc3VuZGF5cyA9IGV4cG9ydHMuc3VuZGF5LnJhbmdlO1xuXG4gIGV4cG9ydHMubW9uZGF5ID0gd2Vla2RheSgxKTtcblxuICBleHBvcnRzLm1vbmRheXMgPSBleHBvcnRzLm1vbmRheS5yYW5nZTtcblxuICBleHBvcnRzLnR1ZXNkYXkgPSB3ZWVrZGF5KDIpO1xuXG4gIGV4cG9ydHMudHVlc2RheXMgPSBleHBvcnRzLnR1ZXNkYXkucmFuZ2U7XG5cbiAgZXhwb3J0cy53ZWRuZXNkYXkgPSB3ZWVrZGF5KDMpO1xuXG4gIGV4cG9ydHMud2VkbmVzZGF5cyA9IGV4cG9ydHMud2VkbmVzZGF5LnJhbmdlO1xuXG4gIGV4cG9ydHMudGh1cnNkYXkgPSB3ZWVrZGF5KDQpO1xuXG4gIGV4cG9ydHMudGh1cnNkYXlzID0gZXhwb3J0cy50aHVyc2RheS5yYW5nZTtcblxuICBleHBvcnRzLmZyaWRheSA9IHdlZWtkYXkoNSk7XG5cbiAgZXhwb3J0cy5mcmlkYXlzID0gZXhwb3J0cy5mcmlkYXkucmFuZ2U7XG5cbiAgZXhwb3J0cy5zYXR1cmRheSA9IHdlZWtkYXkoNik7XG5cbiAgZXhwb3J0cy5zYXR1cmRheXMgPSBleHBvcnRzLnNhdHVyZGF5LnJhbmdlO1xuXG4gIHZhciB3ZWVrID0gZXhwb3J0cy5zdW5kYXk7XG5cbiAgZXhwb3J0cy53ZWVrcyA9IHdlZWsucmFuZ2U7XG5cbiAgdmFyIG1vbnRoID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gICAgZGF0ZS5zZXREYXRlKDEpO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRNb250aChkYXRlLmdldE1vbnRoKCkgKyBzdGVwKTtcbiAgfSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiBlbmQuZ2V0TW9udGgoKSAtIHN0YXJ0LmdldE1vbnRoKCkgKyAoZW5kLmdldEZ1bGxZZWFyKCkgLSBzdGFydC5nZXRGdWxsWWVhcigpKSAqIDEyO1xuICB9KTtcblxuICBleHBvcnRzLm1vbnRocyA9IG1vbnRoLnJhbmdlO1xuXG4gIHZhciB5ZWFyID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gICAgZGF0ZS5zZXRNb250aCgwLCAxKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0RnVsbFllYXIoZGF0ZS5nZXRGdWxsWWVhcigpICsgc3RlcCk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gZW5kLmdldEZ1bGxZZWFyKCkgLSBzdGFydC5nZXRGdWxsWWVhcigpO1xuICB9KTtcblxuICBleHBvcnRzLnllYXJzID0geWVhci5yYW5nZTtcblxuICB2YXIgdXRjU2Vjb25kID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0VVRDTWlsbGlzZWNvbmRzKDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgc3RlcCAqIDFlMyk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIDFlMztcbiAgfSk7XG5cbiAgZXhwb3J0cy51dGNTZWNvbmRzID0gdXRjU2Vjb25kLnJhbmdlO1xuXG4gIHZhciB1dGNNaW51dGUgPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgZGF0ZS5zZXRVVENTZWNvbmRzKDAsIDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgc3RlcCAqIDZlNCk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIDZlNDtcbiAgfSk7XG5cbiAgZXhwb3J0cy51dGNNaW51dGVzID0gdXRjTWludXRlLnJhbmdlO1xuXG4gIHZhciB1dGNIb3VyID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0VVRDTWludXRlcygwLCAwLCAwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXAgKiAzNmU1KTtcbiAgfSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gMzZlNTtcbiAgfSk7XG5cbiAgZXhwb3J0cy51dGNIb3VycyA9IHV0Y0hvdXIucmFuZ2U7XG5cbiAgdmFyIHV0Y0RheSA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRVVENEYXRlKGRhdGUuZ2V0VVRDRGF0ZSgpICsgc3RlcCk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIDg2NGU1O1xuICB9KTtcblxuICBleHBvcnRzLnV0Y0RheXMgPSB1dGNEYXkucmFuZ2U7XG5cbiAgZnVuY3Rpb24gdXRjV2Vla2RheShpKSB7XG4gICAgcmV0dXJuIG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgIGRhdGUuc2V0VVRDSG91cnMoMCwgMCwgMCwgMCk7XG4gICAgICBkYXRlLnNldFVUQ0RhdGUoZGF0ZS5nZXRVVENEYXRlKCkgLSAoZGF0ZS5nZXRVVENEYXkoKSArIDcgLSBpKSAlIDcpO1xuICAgIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICAgIGRhdGUuc2V0VVRDRGF0ZShkYXRlLmdldFVUQ0RhdGUoKSArIHN0ZXAgKiA3KTtcbiAgICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIDYwNDhlNTtcbiAgICB9KTtcbiAgfVxuXG4gIGV4cG9ydHMudXRjU3VuZGF5ID0gdXRjV2Vla2RheSgwKTtcblxuICBleHBvcnRzLnV0Y1N1bmRheXMgPSBleHBvcnRzLnV0Y1N1bmRheS5yYW5nZTtcblxuICBleHBvcnRzLnV0Y01vbmRheSA9IHV0Y1dlZWtkYXkoMSk7XG5cbiAgZXhwb3J0cy51dGNNb25kYXlzID0gZXhwb3J0cy51dGNNb25kYXkucmFuZ2U7XG5cbiAgZXhwb3J0cy51dGNUdWVzZGF5ID0gdXRjV2Vla2RheSgyKTtcblxuICBleHBvcnRzLnV0Y1R1ZXNkYXlzID0gZXhwb3J0cy51dGNUdWVzZGF5LnJhbmdlO1xuXG4gIGV4cG9ydHMudXRjV2VkbmVzZGF5ID0gdXRjV2Vla2RheSgzKTtcblxuICBleHBvcnRzLnV0Y1dlZG5lc2RheXMgPSBleHBvcnRzLnV0Y1dlZG5lc2RheS5yYW5nZTtcblxuICBleHBvcnRzLnV0Y1RodXJzZGF5ID0gdXRjV2Vla2RheSg0KTtcblxuICBleHBvcnRzLnV0Y1RodXJzZGF5cyA9IGV4cG9ydHMudXRjVGh1cnNkYXkucmFuZ2U7XG5cbiAgZXhwb3J0cy51dGNGcmlkYXkgPSB1dGNXZWVrZGF5KDUpO1xuXG4gIGV4cG9ydHMudXRjRnJpZGF5cyA9IGV4cG9ydHMudXRjRnJpZGF5LnJhbmdlO1xuXG4gIGV4cG9ydHMudXRjU2F0dXJkYXkgPSB1dGNXZWVrZGF5KDYpO1xuXG4gIGV4cG9ydHMudXRjU2F0dXJkYXlzID0gZXhwb3J0cy51dGNTYXR1cmRheS5yYW5nZTtcblxuICB2YXIgdXRjV2VlayA9IGV4cG9ydHMudXRjU3VuZGF5O1xuXG4gIGV4cG9ydHMudXRjV2Vla3MgPSB1dGNXZWVrLnJhbmdlO1xuXG4gIHZhciB1dGNNb250aCA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xuICAgIGRhdGUuc2V0VVRDRGF0ZSgxKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VVRDTW9udGgoZGF0ZS5nZXRVVENNb250aCgpICsgc3RlcCk7XG4gIH0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gZW5kLmdldFVUQ01vbnRoKCkgLSBzdGFydC5nZXRVVENNb250aCgpICsgKGVuZC5nZXRVVENGdWxsWWVhcigpIC0gc3RhcnQuZ2V0VVRDRnVsbFllYXIoKSkgKiAxMjtcbiAgfSk7XG5cbiAgZXhwb3J0cy51dGNNb250aHMgPSB1dGNNb250aC5yYW5nZTtcblxuICB2YXIgdXRjWWVhciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xuICAgIGRhdGUuc2V0VVRDTW9udGgoMCwgMSk7XG4gIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSArIHN0ZXApO1xuICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIGVuZC5nZXRVVENGdWxsWWVhcigpIC0gc3RhcnQuZ2V0VVRDRnVsbFllYXIoKTtcbiAgfSk7XG5cbiAgZXhwb3J0cy51dGNZZWFycyA9IHV0Y1llYXIucmFuZ2U7XG5cbiAgZXhwb3J0cy5pbnRlcnZhbCA9IG5ld0ludGVydmFsO1xuICBleHBvcnRzLnNlY29uZCA9IHNlY29uZDtcbiAgZXhwb3J0cy5taW51dGUgPSBtaW51dGU7XG4gIGV4cG9ydHMuaG91ciA9IGhvdXI7XG4gIGV4cG9ydHMuZGF5ID0gZGF5O1xuICBleHBvcnRzLndlZWsgPSB3ZWVrO1xuICBleHBvcnRzLm1vbnRoID0gbW9udGg7XG4gIGV4cG9ydHMueWVhciA9IHllYXI7XG4gIGV4cG9ydHMudXRjU2Vjb25kID0gdXRjU2Vjb25kO1xuICBleHBvcnRzLnV0Y01pbnV0ZSA9IHV0Y01pbnV0ZTtcbiAgZXhwb3J0cy51dGNIb3VyID0gdXRjSG91cjtcbiAgZXhwb3J0cy51dGNEYXkgPSB1dGNEYXk7XG4gIGV4cG9ydHMudXRjV2VlayA9IHV0Y1dlZWs7XG4gIGV4cG9ydHMudXRjTW9udGggPSB1dGNNb250aDtcbiAgZXhwb3J0cy51dGNZZWFyID0gdXRjWWVhcjtcblxufSkpOyIsInZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICAgIE1lYXN1cmVzID0gcmVxdWlyZSgnLi9tZWFzdXJlcycpLFxuICAgIENvbGxlY3RvciA9IHJlcXVpcmUoJy4vY29sbGVjdG9yJyk7XG5cbmZ1bmN0aW9uIEFnZ3JlZ2F0b3IoKSB7XG4gIHRoaXMuX2NlbGxzID0ge307XG4gIHRoaXMuX2FnZ3IgPSBbXTtcbiAgdGhpcy5fc3RyZWFtID0gZmFsc2U7XG59XG5cbnZhciBGbGFncyA9IEFnZ3JlZ2F0b3IuRmxhZ3MgPSB7XG4gIEFERF9DRUxMOiAxLFxuICBNT0RfQ0VMTDogMlxufTtcblxudmFyIHByb3RvID0gQWdncmVnYXRvci5wcm90b3R5cGU7XG5cbi8vIFBhcmFtZXRlcnNcblxucHJvdG8uc3RyZWFtID0gZnVuY3Rpb24odikge1xuICBpZiAodiA9PSBudWxsKSByZXR1cm4gdGhpcy5fc3RyZWFtO1xuICB0aGlzLl9zdHJlYW0gPSAhIXY7XG4gIHRoaXMuX2FnZ3IgPSBbXTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBrZXkgYWNjZXNzb3IgdG8gdXNlIGZvciBzdHJlYW1pbmcgcmVtb3Zlc1xucHJvdG8ua2V5ID0gZnVuY3Rpb24oa2V5KSB7XG4gIGlmIChrZXkgPT0gbnVsbCkgcmV0dXJuIHRoaXMuX2tleTtcbiAgdGhpcy5fa2V5ID0gdXRpbC4kKGtleSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gSW5wdXQ6IGFycmF5IG9mIG9iamVjdHMgb2YgdGhlIGZvcm1cbi8vIHtuYW1lOiBzdHJpbmcsIGdldDogZnVuY3Rpb259XG5wcm90by5ncm91cGJ5ID0gZnVuY3Rpb24oZGltcykge1xuICB0aGlzLl9kaW1zID0gdXRpbC5hcnJheShkaW1zKS5tYXAoZnVuY3Rpb24oZCwgaSkge1xuICAgIGQgPSB1dGlsLmlzU3RyaW5nKGQpID8ge25hbWU6IGQsIGdldDogdXRpbC4kKGQpfVxuICAgICAgOiB1dGlsLmlzRnVuY3Rpb24oZCkgPyB7bmFtZTogdXRpbC5uYW1lKGQpIHx8IGQubmFtZSB8fCAoJ18nICsgaSksIGdldDogZH1cbiAgICAgIDogKGQubmFtZSAmJiB1dGlsLmlzRnVuY3Rpb24oZC5nZXQpKSA/IGQgOiBudWxsO1xuICAgIGlmIChkID09IG51bGwpIHRocm93ICdJbnZhbGlkIGdyb3VwYnkgYXJndW1lbnQ6ICcgKyBkO1xuICAgIHJldHVybiBkO1xuICB9KTtcbiAgcmV0dXJuIHRoaXMuY2xlYXIoKTtcbn07XG5cbi8vIElucHV0OiBhcnJheSBvZiBvYmplY3RzIG9mIHRoZSBmb3JtXG4vLyB7bmFtZTogc3RyaW5nLCBvcHM6IFtzdHJpbmcsIC4uLl19XG5wcm90by5zdW1tYXJpemUgPSBmdW5jdGlvbihmaWVsZHMpIHtcbiAgZmllbGRzID0gc3VtbWFyaXplX2FyZ3MoZmllbGRzKTtcbiAgdGhpcy5fY291bnQgPSB0cnVlO1xuICB2YXIgYWdnciA9ICh0aGlzLl9hZ2dyID0gW10pLFxuICAgICAgbSwgZiwgaSwgaiwgb3AsIGFzLCBnZXQ7XG5cbiAgZm9yIChpPTA7IGk8ZmllbGRzLmxlbmd0aDsgKytpKSB7XG4gICAgZm9yIChqPTAsIG09W10sIGY9ZmllbGRzW2ldOyBqPGYub3BzLmxlbmd0aDsgKytqKSB7XG4gICAgICBvcCA9IGYub3BzW2pdO1xuICAgICAgaWYgKG9wICE9PSAnY291bnQnKSB0aGlzLl9jb3VudCA9IGZhbHNlO1xuICAgICAgYXMgPSAoZi5hcyAmJiBmLmFzW2pdKSB8fCAob3AgKyAoZi5uYW1lPT09JyonID8gJycgOiAnXycrZi5uYW1lKSk7XG4gICAgICBtLnB1c2goTWVhc3VyZXNbb3BdKGFzKSk7XG4gICAgfVxuICAgIGdldCA9IGYuZ2V0ICYmIHV0aWwuJChmLmdldCkgfHxcbiAgICAgIChmLm5hbWUgPT09ICcqJyA/IHV0aWwuaWRlbnRpdHkgOiB1dGlsLiQoZi5uYW1lKSk7XG4gICAgYWdnci5wdXNoKHtcbiAgICAgIG5hbWU6IGYubmFtZSxcbiAgICAgIG1lYXN1cmVzOiBNZWFzdXJlcy5jcmVhdGUoXG4gICAgICAgIG0sXG4gICAgICAgIHRoaXMuX3N0cmVhbSwgLy8gc3RyZWFtaW5nIHJlbW92ZSBmbGFnXG4gICAgICAgIGdldCwgICAgICAgICAgLy8gaW5wdXQgdHVwbGUgZ2V0dGVyXG4gICAgICAgIHRoaXMuX2Fzc2lnbikgLy8gb3V0cHV0IHR1cGxlIHNldHRlclxuICAgIH0pO1xuICB9XG4gIHJldHVybiB0aGlzLmNsZWFyKCk7XG59O1xuXG4vLyBDb252ZW5pZW5jZSBtZXRob2QgdG8gc3VtbWFyaXplIGJ5IGNvdW50XG5wcm90by5jb3VudCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5zdW1tYXJpemUoeycqJzonY291bnQnfSk7XG59O1xuXG4vLyBPdmVycmlkZSB0byBwZXJmb3JtIGN1c3RvbSB0dXBsZSB2YWx1ZSBhc3NpZ25tZW50XG5wcm90by5fYXNzaWduID0gZnVuY3Rpb24ob2JqZWN0LCBuYW1lLCB2YWx1ZSkge1xuICBvYmplY3RbbmFtZV0gPSB2YWx1ZTtcbn07XG5cbmZ1bmN0aW9uIHN1bW1hcml6ZV9hcmdzKGZpZWxkcykge1xuICBpZiAodXRpbC5pc0FycmF5KGZpZWxkcykpIHsgcmV0dXJuIGZpZWxkczsgfVxuICBpZiAoZmllbGRzID09IG51bGwpIHsgcmV0dXJuIFtdOyB9XG4gIHZhciBhID0gW10sIG5hbWUsIG9wcztcbiAgZm9yIChuYW1lIGluIGZpZWxkcykge1xuICAgIG9wcyA9IHV0aWwuYXJyYXkoZmllbGRzW25hbWVdKTtcbiAgICBhLnB1c2goe25hbWU6IG5hbWUsIG9wczogb3BzfSk7XG4gIH1cbiAgcmV0dXJuIGE7XG59XG5cbi8vIENlbGwgTWFuYWdlbWVudFxuXG5wcm90by5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gKHRoaXMuX2NlbGxzID0ge30sIHRoaXMpO1xufTtcblxucHJvdG8uX2NlbGxrZXkgPSBmdW5jdGlvbih4KSB7XG4gIHZhciBkID0gdGhpcy5fZGltcyxcbiAgICAgIG4gPSBkLmxlbmd0aCwgaSxcbiAgICAgIGsgPSBTdHJpbmcoZFswXS5nZXQoeCkpO1xuICBmb3IgKGk9MTsgaTxuOyArK2kpIHtcbiAgICBrICs9ICd8JyArIGRbaV0uZ2V0KHgpO1xuICB9XG4gIHJldHVybiBrO1xufTtcblxucHJvdG8uX2NlbGwgPSBmdW5jdGlvbih4KSB7XG4gIHZhciBrZXkgPSB0aGlzLl9kaW1zLmxlbmd0aCA/IHRoaXMuX2NlbGxrZXkoeCkgOiAnJztcbiAgcmV0dXJuIHRoaXMuX2NlbGxzW2tleV0gfHwgKHRoaXMuX2NlbGxzW2tleV0gPSB0aGlzLl9uZXdjZWxsKHgsIGtleSkpO1xufTtcblxucHJvdG8uX25ld2NlbGwgPSBmdW5jdGlvbih4LCBrZXkpIHtcbiAgdmFyIGNlbGwgPSB7XG4gICAgbnVtOiAgIDAsXG4gICAgdHVwbGU6IHRoaXMuX25ld3R1cGxlKHgsIGtleSksXG4gICAgZmxhZzogIEZsYWdzLkFERF9DRUxMLFxuICAgIGFnZ3M6ICB7fVxuICB9O1xuXG4gIHZhciBhZ2dyID0gdGhpcy5fYWdnciwgaTtcbiAgZm9yIChpPTA7IGk8YWdnci5sZW5ndGg7ICsraSkge1xuICAgIGNlbGwuYWdnc1thZ2dyW2ldLm5hbWVdID0gbmV3IGFnZ3JbaV0ubWVhc3VyZXMoY2VsbCwgY2VsbC50dXBsZSk7XG4gIH1cbiAgaWYgKGNlbGwuY29sbGVjdCkge1xuICAgIGNlbGwuZGF0YSA9IG5ldyBDb2xsZWN0b3IodGhpcy5fa2V5KTtcbiAgfVxuICByZXR1cm4gY2VsbDtcbn07XG5cbnByb3RvLl9uZXd0dXBsZSA9IGZ1bmN0aW9uKHgpIHtcbiAgdmFyIGRpbXMgPSB0aGlzLl9kaW1zLFxuICAgICAgdCA9IHt9LCBpLCBuO1xuICBmb3IgKGk9MCwgbj1kaW1zLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICB0W2RpbXNbaV0ubmFtZV0gPSBkaW1zW2ldLmdldCh4KTtcbiAgfVxuICByZXR1cm4gdGhpcy5faW5nZXN0KHQpO1xufTtcblxuLy8gT3ZlcnJpZGUgdG8gcGVyZm9ybSBjdXN0b20gdHVwbGUgaW5nZXN0aW9uXG5wcm90by5faW5nZXN0ID0gdXRpbC5pZGVudGl0eTtcblxuLy8gUHJvY2VzcyBUdXBsZXNcblxucHJvdG8uX2FkZCA9IGZ1bmN0aW9uKHgpIHtcbiAgdmFyIGNlbGwgPSB0aGlzLl9jZWxsKHgpLFxuICAgICAgYWdnciA9IHRoaXMuX2FnZ3IsIGk7XG5cbiAgY2VsbC5udW0gKz0gMTtcbiAgaWYgKCF0aGlzLl9jb3VudCkgeyAvLyBza2lwIGlmIGNvdW50LW9ubHlcbiAgICBpZiAoY2VsbC5jb2xsZWN0KSBjZWxsLmRhdGEuYWRkKHgpO1xuICAgIGZvciAoaT0wOyBpPGFnZ3IubGVuZ3RoOyArK2kpIHtcbiAgICAgIGNlbGwuYWdnc1thZ2dyW2ldLm5hbWVdLmFkZCh4KTtcbiAgICB9XG4gIH1cbiAgY2VsbC5mbGFnIHw9IEZsYWdzLk1PRF9DRUxMO1xuICBpZiAodGhpcy5fb25fYWRkKSB0aGlzLl9vbl9hZGQoeCwgY2VsbCk7XG59O1xuXG5wcm90by5fcmVtID0gZnVuY3Rpb24oeCkge1xuICB2YXIgY2VsbCA9IHRoaXMuX2NlbGwoeCksXG4gICAgICBhZ2dyID0gdGhpcy5fYWdnciwgaTtcblxuICBjZWxsLm51bSAtPSAxO1xuICBpZiAoIXRoaXMuX2NvdW50KSB7IC8vIHNraXAgaWYgY291bnQtb25seVxuICAgIGlmIChjZWxsLmNvbGxlY3QpIGNlbGwuZGF0YS5yZW0oeCk7XG4gICAgZm9yIChpPTA7IGk8YWdnci5sZW5ndGg7ICsraSkge1xuICAgICAgY2VsbC5hZ2dzW2FnZ3JbaV0ubmFtZV0ucmVtKHgpO1xuICAgIH1cbiAgfVxuICBjZWxsLmZsYWcgfD0gRmxhZ3MuTU9EX0NFTEw7XG4gIGlmICh0aGlzLl9vbl9yZW0pIHRoaXMuX29uX3JlbSh4LCBjZWxsKTtcbn07XG5cbnByb3RvLl9tb2QgPSBmdW5jdGlvbihjdXJyLCBwcmV2KSB7XG4gIHZhciBjZWxsMCA9IHRoaXMuX2NlbGwocHJldiksXG4gICAgICBjZWxsMSA9IHRoaXMuX2NlbGwoY3VyciksXG4gICAgICBhZ2dyID0gdGhpcy5fYWdnciwgaTtcblxuICBpZiAoY2VsbDAgIT09IGNlbGwxKSB7XG4gICAgY2VsbDAubnVtIC09IDE7XG4gICAgY2VsbDEubnVtICs9IDE7XG4gICAgaWYgKGNlbGwwLmNvbGxlY3QpIGNlbGwwLmRhdGEucmVtKHByZXYpO1xuICAgIGlmIChjZWxsMS5jb2xsZWN0KSBjZWxsMS5kYXRhLmFkZChjdXJyKTtcbiAgfSBlbHNlIGlmIChjZWxsMC5jb2xsZWN0ICYmICF1dGlsLmlzT2JqZWN0KGN1cnIpKSB7XG4gICAgY2VsbDAuZGF0YS5yZW0ocHJldik7XG4gICAgY2VsbDAuZGF0YS5hZGQoY3Vycik7XG4gIH1cblxuICBmb3IgKGk9MDsgaTxhZ2dyLmxlbmd0aDsgKytpKSB7XG4gICAgY2VsbDAuYWdnc1thZ2dyW2ldLm5hbWVdLnJlbShwcmV2KTtcbiAgICBjZWxsMS5hZ2dzW2FnZ3JbaV0ubmFtZV0uYWRkKGN1cnIpO1xuICB9XG4gIGNlbGwwLmZsYWcgfD0gRmxhZ3MuTU9EX0NFTEw7XG4gIGNlbGwxLmZsYWcgfD0gRmxhZ3MuTU9EX0NFTEw7XG4gIGlmICh0aGlzLl9vbl9tb2QpIHRoaXMuX29uX21vZChjdXJyLCBwcmV2LCBjZWxsMCwgY2VsbDEpO1xufTtcblxucHJvdG8ucmVzdWx0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciByZXN1bHQgPSBbXSxcbiAgICAgIGFnZ3IgPSB0aGlzLl9hZ2dyLFxuICAgICAgY2VsbCwgaSwgaztcblxuICBmb3IgKGsgaW4gdGhpcy5fY2VsbHMpIHtcbiAgICBjZWxsID0gdGhpcy5fY2VsbHNba107XG4gICAgaWYgKGNlbGwubnVtID4gMCkge1xuICAgICAgLy8gY29uc29saWRhdGUgY29sbGVjdG9yIHZhbHVlc1xuICAgICAgaWYgKGNlbGwuY29sbGVjdCkge1xuICAgICAgICBjZWxsLmRhdGEudmFsdWVzKCk7XG4gICAgICB9XG4gICAgICAvLyB1cGRhdGUgdHVwbGUgcHJvcGVydGllc1xuICAgICAgZm9yIChpPTA7IGk8YWdnci5sZW5ndGg7ICsraSkge1xuICAgICAgICBjZWxsLmFnZ3NbYWdncltpXS5uYW1lXS5zZXQoKTtcbiAgICAgIH1cbiAgICAgIC8vIGFkZCBvdXRwdXQgdHVwbGVcbiAgICAgIHJlc3VsdC5wdXNoKGNlbGwudHVwbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGUgdGhpcy5fY2VsbHNba107XG4gICAgfVxuICAgIGNlbGwuZmxhZyA9IDA7XG4gIH1cblxuICB0aGlzLl9yZW1zID0gZmFsc2U7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5wcm90by5jaGFuZ2VzID0gZnVuY3Rpb24ob3V0cHV0KSB7XG4gIHZhciBjaGFuZ2VzID0gb3V0cHV0IHx8IHthZGQ6W10sIHJlbTpbXSwgbW9kOltdfSxcbiAgICAgIGFnZ3IgPSB0aGlzLl9hZ2dyLFxuICAgICAgY2VsbCwgZmxhZywgaSwgaztcblxuICBmb3IgKGsgaW4gdGhpcy5fY2VsbHMpIHtcbiAgICBjZWxsID0gdGhpcy5fY2VsbHNba107XG4gICAgZmxhZyA9IGNlbGwuZmxhZztcblxuICAgIC8vIGNvbnNvbGlkYXRlIGNvbGxlY3RvciB2YWx1ZXNcbiAgICBpZiAoY2VsbC5jb2xsZWN0KSB7XG4gICAgICBjZWxsLmRhdGEudmFsdWVzKCk7XG4gICAgfVxuXG4gICAgLy8gdXBkYXRlIHR1cGxlIHByb3BlcnRpZXNcbiAgICBmb3IgKGk9MDsgaTxhZ2dyLmxlbmd0aDsgKytpKSB7XG4gICAgICBjZWxsLmFnZ3NbYWdncltpXS5uYW1lXS5zZXQoKTtcbiAgICB9XG5cbiAgICAvLyBvcmdhbml6ZSBvdXRwdXQgdHVwbGVzXG4gICAgaWYgKGNlbGwubnVtIDw9IDApIHtcbiAgICAgIGNoYW5nZXMucmVtLnB1c2goY2VsbC50dXBsZSk7IC8vIGlmIChmbGFnID09PSBGbGFncy5NT0RfQ0VMTCkgeyA/P1xuICAgICAgZGVsZXRlIHRoaXMuX2NlbGxzW2tdO1xuICAgICAgaWYgKHRoaXMuX29uX2Ryb3ApIHRoaXMuX29uX2Ryb3AoY2VsbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLl9vbl9rZWVwKSB0aGlzLl9vbl9rZWVwKGNlbGwpO1xuICAgICAgaWYgKGZsYWcgJiBGbGFncy5BRERfQ0VMTCkge1xuICAgICAgICBjaGFuZ2VzLmFkZC5wdXNoKGNlbGwudHVwbGUpO1xuICAgICAgfSBlbHNlIGlmIChmbGFnICYgRmxhZ3MuTU9EX0NFTEwpIHtcbiAgICAgICAgY2hhbmdlcy5tb2QucHVzaChjZWxsLnR1cGxlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjZWxsLmZsYWcgPSAwO1xuICB9XG5cbiAgdGhpcy5fcmVtcyA9IGZhbHNlO1xuICByZXR1cm4gY2hhbmdlcztcbn07XG5cbnByb3RvLmV4ZWN1dGUgPSBmdW5jdGlvbihpbnB1dCkge1xuICByZXR1cm4gdGhpcy5jbGVhcigpLmluc2VydChpbnB1dCkucmVzdWx0KCk7XG59O1xuXG5wcm90by5pbnNlcnQgPSBmdW5jdGlvbihpbnB1dCkge1xuICB0aGlzLl9jb25zb2xpZGF0ZSgpO1xuICBmb3IgKHZhciBpPTA7IGk8aW5wdXQubGVuZ3RoOyArK2kpIHtcbiAgICB0aGlzLl9hZGQoaW5wdXRbaV0pO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG8ucmVtb3ZlID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgaWYgKCF0aGlzLl9zdHJlYW0pIHtcbiAgICB0aHJvdyAnQWdncmVnYXRvciBub3QgY29uZmlndXJlZCBmb3Igc3RyZWFtaW5nIHJlbW92ZXMuJyArXG4gICAgICAnIENhbGwgc3RyZWFtKHRydWUpIHByaW9yIHRvIGNhbGxpbmcgc3VtbWFyaXplLic7XG4gIH1cbiAgZm9yICh2YXIgaT0wOyBpPGlucHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgdGhpcy5fcmVtKGlucHV0W2ldKTtcbiAgfVxuICB0aGlzLl9yZW1zID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBjb25zb2xpZGF0ZSByZW1vdmFsc1xucHJvdG8uX2NvbnNvbGlkYXRlID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5fcmVtcykgcmV0dXJuO1xuICBmb3IgKHZhciBrIGluIHRoaXMuX2NlbGxzKSB7XG4gICAgaWYgKHRoaXMuX2NlbGxzW2tdLmNvbGxlY3QpIHtcbiAgICAgIHRoaXMuX2NlbGxzW2tdLmRhdGEudmFsdWVzKCk7XG4gICAgfVxuICB9XG4gIHRoaXMuX3JlbXMgPSBmYWxzZTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQWdncmVnYXRvcjsiLCJ2YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKTtcbnZhciBzdGF0cyA9IHJlcXVpcmUoJy4uL3N0YXRzJyk7XG5cbnZhciBSRU0gPSAnX19kbF9yZW1fXyc7XG5cbmZ1bmN0aW9uIENvbGxlY3RvcihrZXkpIHtcbiAgdGhpcy5fYWRkID0gW107XG4gIHRoaXMuX3JlbSA9IFtdO1xuICB0aGlzLl9rZXkgPSBrZXkgfHwgbnVsbDtcbiAgdGhpcy5fbGFzdCA9IG51bGw7XG59XG5cbnZhciBwcm90byA9IENvbGxlY3Rvci5wcm90b3R5cGU7XG5cbnByb3RvLmFkZCA9IGZ1bmN0aW9uKHYpIHtcbiAgdGhpcy5fYWRkLnB1c2godik7XG59O1xuXG5wcm90by5yZW0gPSBmdW5jdGlvbih2KSB7XG4gIHRoaXMuX3JlbS5wdXNoKHYpO1xufTtcblxucHJvdG8udmFsdWVzID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX2dldCA9IG51bGw7XG4gIGlmICh0aGlzLl9yZW0ubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5fYWRkO1xuXG4gIHZhciBhID0gdGhpcy5fYWRkLFxuICAgICAgciA9IHRoaXMuX3JlbSxcbiAgICAgIGsgPSB0aGlzLl9rZXksXG4gICAgICB4ID0gQXJyYXkoYS5sZW5ndGggLSByLmxlbmd0aCksXG4gICAgICBpLCBqLCBuLCBtO1xuXG4gIGlmICghdXRpbC5pc09iamVjdChyWzBdKSkge1xuICAgIC8vIHByb2Nlc3NpbmcgcmF3IHZhbHVlc1xuICAgIG0gPSBzdGF0cy5jb3VudC5tYXAocik7XG4gICAgZm9yIChpPTAsIGo9MCwgbj1hLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgIGlmIChtW2FbaV1dID4gMCkge1xuICAgICAgICBtW2FbaV1dIC09IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4W2orK10gPSBhW2ldO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChrKSB7XG4gICAgLy8gaGFzIHVuaXF1ZSBrZXkgZmllbGQsIHNvIHVzZSB0aGF0XG4gICAgbSA9IHV0aWwudG9NYXAociwgayk7XG4gICAgZm9yIChpPTAsIGo9MCwgbj1hLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgIGlmICghbS5oYXNPd25Qcm9wZXJ0eShrKGFbaV0pKSkgeyB4W2orK10gPSBhW2ldOyB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIG5vIHVuaXF1ZSBrZXksIG1hcmsgdHVwbGVzIGRpcmVjdGx5XG4gICAgZm9yIChpPTAsIG49ci5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgICByW2ldW1JFTV0gPSAxO1xuICAgIH1cbiAgICBmb3IgKGk9MCwgaj0wLCBuPWEubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgaWYgKCFhW2ldW1JFTV0pIHsgeFtqKytdID0gYVtpXTsgfVxuICAgIH1cbiAgICBmb3IgKGk9MCwgbj1yLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgIGRlbGV0ZSByW2ldW1JFTV07XG4gICAgfVxuICB9XG5cbiAgdGhpcy5fcmVtID0gW107XG4gIHJldHVybiAodGhpcy5fYWRkID0geCk7XG59O1xuXG4vLyBtZW1vaXppbmcgc3RhdGlzdGljcyBtZXRob2RzXG5cbnByb3RvLmV4dGVudCA9IGZ1bmN0aW9uKGdldCkge1xuICBpZiAodGhpcy5fZ2V0ICE9PSBnZXQgfHwgIXRoaXMuX2V4dCkge1xuICAgIHZhciB2ID0gdGhpcy52YWx1ZXMoKSxcbiAgICAgICAgaSA9IHN0YXRzLmV4dGVudC5pbmRleCh2LCBnZXQpO1xuICAgIHRoaXMuX2V4dCA9IFt2W2lbMF1dLCB2W2lbMV1dXTtcbiAgICB0aGlzLl9nZXQgPSBnZXQ7ICAgIFxuICB9XG4gIHJldHVybiB0aGlzLl9leHQ7XG59O1xuXG5wcm90by5hcmdtaW4gPSBmdW5jdGlvbihnZXQpIHtcbiAgcmV0dXJuIHRoaXMuZXh0ZW50KGdldClbMF07XG59O1xuXG5wcm90by5hcmdtYXggPSBmdW5jdGlvbihnZXQpIHtcbiAgcmV0dXJuIHRoaXMuZXh0ZW50KGdldClbMV07XG59O1xuXG5wcm90by5taW4gPSBmdW5jdGlvbihnZXQpIHtcbiAgdmFyIG0gPSB0aGlzLmV4dGVudChnZXQpWzBdO1xuICByZXR1cm4gbSA/IGdldChtKSA6ICtJbmZpbml0eTtcbn07XG5cbnByb3RvLm1heCA9IGZ1bmN0aW9uKGdldCkge1xuICB2YXIgbSA9IHRoaXMuZXh0ZW50KGdldClbMV07XG4gIHJldHVybiBtID8gZ2V0KG0pIDogLUluZmluaXR5O1xufTtcblxucHJvdG8ucXVhcnRpbGUgPSBmdW5jdGlvbihnZXQpIHtcbiAgaWYgKHRoaXMuX2dldCAhPT0gZ2V0IHx8ICF0aGlzLl9xKSB7XG4gICAgdGhpcy5fcSA9IHN0YXRzLnF1YXJ0aWxlKHRoaXMudmFsdWVzKCksIGdldCk7XG4gICAgdGhpcy5fZ2V0ID0gZ2V0OyAgICBcbiAgfVxuICByZXR1cm4gdGhpcy5fcTtcbn07XG5cbnByb3RvLnExID0gZnVuY3Rpb24oZ2V0KSB7XG4gIHJldHVybiB0aGlzLnF1YXJ0aWxlKGdldClbMF07XG59O1xuXG5wcm90by5xMiA9IGZ1bmN0aW9uKGdldCkge1xuICByZXR1cm4gdGhpcy5xdWFydGlsZShnZXQpWzFdO1xufTtcblxucHJvdG8ucTMgPSBmdW5jdGlvbihnZXQpIHtcbiAgcmV0dXJuIHRoaXMucXVhcnRpbGUoZ2V0KVsyXTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdG9yO1xuIiwidmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG52YXIgQWdncmVnYXRvciA9IHJlcXVpcmUoJy4vYWdncmVnYXRvcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAvLyBmbGF0dGVuIGFyZ3VtZW50cyBpbnRvIGEgc2luZ2xlIGFycmF5XG4gIHZhciBhcmdzID0gW10ucmVkdWNlLmNhbGwoYXJndW1lbnRzLCBmdW5jdGlvbihhLCB4KSB7XG4gICAgcmV0dXJuIGEuY29uY2F0KHV0aWwuYXJyYXkoeCkpO1xuICB9LCBbXSk7XG4gIC8vIGNyZWF0ZSBhbmQgcmV0dXJuIGFuIGFnZ3JlZ2F0b3JcbiAgcmV0dXJuIG5ldyBBZ2dyZWdhdG9yKClcbiAgICAuZ3JvdXBieShhcmdzKVxuICAgIC5zdW1tYXJpemUoeycqJzondmFsdWVzJ30pO1xufTtcbiIsInZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xuXG52YXIgdHlwZXMgPSB7XG4gICd2YWx1ZXMnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAndmFsdWVzJyxcbiAgICBpbml0OiAnY2VsbC5jb2xsZWN0ID0gdHJ1ZTsnLFxuICAgIHNldDogICdjZWxsLmRhdGEudmFsdWVzKCknLCBpZHg6IC0xXG4gIH0pLFxuICAnY291bnQnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnY291bnQnLFxuICAgIHNldDogICdjZWxsLm51bSdcbiAgfSksXG4gICdtaXNzaW5nJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ21pc3NpbmcnLFxuICAgIHNldDogICd0aGlzLm1pc3NpbmcnXG4gIH0pLFxuICAndmFsaWQnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAndmFsaWQnLFxuICAgIHNldDogICd0aGlzLnZhbGlkJ1xuICB9KSxcbiAgJ3N1bSc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICdzdW0nLFxuICAgIGluaXQ6ICd0aGlzLnN1bSA9IDA7JyxcbiAgICBhZGQ6ICAndGhpcy5zdW0gKz0gdjsnLFxuICAgIHJlbTogICd0aGlzLnN1bSAtPSB2OycsXG4gICAgc2V0OiAgJ3RoaXMuc3VtJ1xuICB9KSxcbiAgJ21lYW4nOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnbWVhbicsXG4gICAgaW5pdDogJ3RoaXMubWVhbiA9IDA7JyxcbiAgICBhZGQ6ICAndmFyIGQgPSB2IC0gdGhpcy5tZWFuOyB0aGlzLm1lYW4gKz0gZCAvIHRoaXMudmFsaWQ7JyxcbiAgICByZW06ICAndmFyIGQgPSB2IC0gdGhpcy5tZWFuOyB0aGlzLm1lYW4gLT0gdGhpcy52YWxpZCA/IGQgLyB0aGlzLnZhbGlkIDogdGhpcy5tZWFuOycsXG4gICAgc2V0OiAgJ3RoaXMubWVhbidcbiAgfSksXG4gICdhdmVyYWdlJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ2F2ZXJhZ2UnLFxuICAgIHNldDogICd0aGlzLm1lYW4nLFxuICAgIHJlcTogIFsnbWVhbiddLCBpZHg6IDFcbiAgfSksXG4gICd2YXJpYW5jZSc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICd2YXJpYW5jZScsXG4gICAgaW5pdDogJ3RoaXMuZGV2ID0gMDsnLFxuICAgIGFkZDogICd0aGlzLmRldiArPSBkICogKHYgLSB0aGlzLm1lYW4pOycsXG4gICAgcmVtOiAgJ3RoaXMuZGV2IC09IGQgKiAodiAtIHRoaXMubWVhbik7JyxcbiAgICBzZXQ6ICAndGhpcy52YWxpZCA+IDEgPyB0aGlzLmRldiAvICh0aGlzLnZhbGlkLTEpIDogMCcsXG4gICAgcmVxOiAgWydtZWFuJ10sIGlkeDogMVxuICB9KSxcbiAgJ3ZhcmlhbmNlcCc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICd2YXJpYW5jZXAnLFxuICAgIHNldDogICd0aGlzLnZhbGlkID4gMSA/IHRoaXMuZGV2IC8gdGhpcy52YWxpZCA6IDAnLFxuICAgIHJlcTogIFsndmFyaWFuY2UnXSwgaWR4OiAyXG4gIH0pLFxuICAnc3RkZXYnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnc3RkZXYnLFxuICAgIHNldDogICd0aGlzLnZhbGlkID4gMSA/IE1hdGguc3FydCh0aGlzLmRldiAvICh0aGlzLnZhbGlkLTEpKSA6IDAnLFxuICAgIHJlcTogIFsndmFyaWFuY2UnXSwgaWR4OiAyXG4gIH0pLFxuICAnc3RkZXZwJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ3N0ZGV2cCcsXG4gICAgc2V0OiAgJ3RoaXMudmFsaWQgPiAxID8gTWF0aC5zcXJ0KHRoaXMuZGV2IC8gdGhpcy52YWxpZCkgOiAwJyxcbiAgICByZXE6ICBbJ3ZhcmlhbmNlJ10sIGlkeDogMlxuICB9KSxcbiAgJ21lZGlhbic6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICdtZWRpYW4nLFxuICAgIHNldDogICdjZWxsLmRhdGEucTIodGhpcy5nZXQpJyxcbiAgICByZXE6ICBbJ3ZhbHVlcyddLCBpZHg6IDNcbiAgfSksXG4gICdxMSc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICdxMScsXG4gICAgc2V0OiAgJ2NlbGwuZGF0YS5xMSh0aGlzLmdldCknLFxuICAgIHJlcTogIFsndmFsdWVzJ10sIGlkeDogM1xuICB9KSxcbiAgJ3EzJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ3EzJyxcbiAgICBzZXQ6ICAnY2VsbC5kYXRhLnEzKHRoaXMuZ2V0KScsXG4gICAgcmVxOiAgWyd2YWx1ZXMnXSwgaWR4OiAzXG4gIH0pLFxuICAnZGlzdGluY3QnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnZGlzdGluY3QnLFxuICAgIHNldDogICd0aGlzLmRpc3RpbmN0KGNlbGwuZGF0YS52YWx1ZXMoKSwgdGhpcy5nZXQpJyxcbiAgICByZXE6ICBbJ3ZhbHVlcyddLCBpZHg6IDNcbiAgfSksXG4gICdhcmdtaW4nOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnYXJnbWluJyxcbiAgICBhZGQ6ICAnaWYgKHYgPCB0aGlzLm1pbikgdGhpcy5hcmdtaW4gPSB0OycsXG4gICAgcmVtOiAgJ2lmICh2IDw9IHRoaXMubWluKSB0aGlzLmFyZ21pbiA9IG51bGw7JyxcbiAgICBzZXQ6ICAndGhpcy5hcmdtaW4gPSB0aGlzLmFyZ21pbiB8fCBjZWxsLmRhdGEuYXJnbWluKHRoaXMuZ2V0KScsXG4gICAgcmVxOiAgWydtaW4nXSwgc3RyOiBbJ3ZhbHVlcyddLCBpZHg6IDNcbiAgfSksXG4gICdhcmdtYXgnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnYXJnbWF4JyxcbiAgICBhZGQ6ICAnaWYgKHYgPiB0aGlzLm1heCkgdGhpcy5hcmdtYXggPSB0OycsXG4gICAgcmVtOiAgJ2lmICh2ID49IHRoaXMubWF4KSB0aGlzLmFyZ21heCA9IG51bGw7JyxcbiAgICBzZXQ6ICAndGhpcy5hcmdtYXggPSB0aGlzLmFyZ21heCB8fCBjZWxsLmRhdGEuYXJnbWF4KHRoaXMuZ2V0KScsXG4gICAgcmVxOiAgWydtYXgnXSwgc3RyOiBbJ3ZhbHVlcyddLCBpZHg6IDNcbiAgfSksXG4gICdtaW4nOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnbWluJyxcbiAgICBpbml0OiAndGhpcy5taW4gPSArSW5maW5pdHk7JyxcbiAgICBhZGQ6ICAnaWYgKHYgPCB0aGlzLm1pbikgdGhpcy5taW4gPSB2OycsXG4gICAgcmVtOiAgJ2lmICh2IDw9IHRoaXMubWluKSB0aGlzLm1pbiA9IE5hTjsnLFxuICAgIHNldDogICd0aGlzLm1pbiA9IChpc05hTih0aGlzLm1pbikgPyBjZWxsLmRhdGEubWluKHRoaXMuZ2V0KSA6IHRoaXMubWluKScsXG4gICAgc3RyOiAgWyd2YWx1ZXMnXSwgaWR4OiA0XG4gIH0pLFxuICAnbWF4JzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ21heCcsXG4gICAgaW5pdDogJ3RoaXMubWF4ID0gLUluZmluaXR5OycsXG4gICAgYWRkOiAgJ2lmICh2ID4gdGhpcy5tYXgpIHRoaXMubWF4ID0gdjsnLFxuICAgIHJlbTogICdpZiAodiA+PSB0aGlzLm1heCkgdGhpcy5tYXggPSBOYU47JyxcbiAgICBzZXQ6ICAndGhpcy5tYXggPSAoaXNOYU4odGhpcy5tYXgpID8gY2VsbC5kYXRhLm1heCh0aGlzLmdldCkgOiB0aGlzLm1heCknLFxuICAgIHN0cjogIFsndmFsdWVzJ10sIGlkeDogNFxuICB9KSxcbiAgJ21vZGVza2V3JzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ21vZGVza2V3JyxcbiAgICBzZXQ6ICAndGhpcy5kZXY9PT0wID8gMCA6ICh0aGlzLm1lYW4gLSBjZWxsLmRhdGEucTIodGhpcy5nZXQpKSAvIE1hdGguc3FydCh0aGlzLmRldi8odGhpcy52YWxpZC0xKSknLFxuICAgIHJlcTogIFsnbWVhbicsICdzdGRldicsICdtZWRpYW4nXSwgaWR4OiA1XG4gIH0pXG59O1xuXG5mdW5jdGlvbiBtZWFzdXJlKGJhc2UpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG91dCkge1xuICAgIHZhciBtID0gdXRpbC5leHRlbmQoe2luaXQ6JycsIGFkZDonJywgcmVtOicnLCBpZHg6MH0sIGJhc2UpO1xuICAgIG0ub3V0ID0gb3V0IHx8IGJhc2UubmFtZTtcbiAgICByZXR1cm4gbTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZShhZ2csIHN0cmVhbSkge1xuICBmdW5jdGlvbiBjb2xsZWN0KG0sIGEpIHtcbiAgICBmdW5jdGlvbiBoZWxwZXIocikgeyBpZiAoIW1bcl0pIGNvbGxlY3QobSwgbVtyXSA9IHR5cGVzW3JdKCkpOyB9XG4gICAgaWYgKGEucmVxKSBhLnJlcS5mb3JFYWNoKGhlbHBlcik7XG4gICAgaWYgKHN0cmVhbSAmJiBhLnN0cikgYS5zdHIuZm9yRWFjaChoZWxwZXIpO1xuICAgIHJldHVybiBtO1xuICB9XG4gIHZhciBtYXAgPSBhZ2cucmVkdWNlKFxuICAgIGNvbGxlY3QsXG4gICAgYWdnLnJlZHVjZShmdW5jdGlvbihtLCBhKSB7IHJldHVybiAobVthLm5hbWVdID0gYSwgbSk7IH0sIHt9KVxuICApO1xuICByZXR1cm4gdXRpbC52YWxzKG1hcCkuc29ydChmdW5jdGlvbihhLCBiKSB7IHJldHVybiBhLmlkeCAtIGIuaWR4OyB9KTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlKGFnZywgc3RyZWFtLCBhY2Nlc3NvciwgbXV0YXRvcikge1xuICB2YXIgYWxsID0gcmVzb2x2ZShhZ2csIHN0cmVhbSksXG4gICAgICBjdHIgPSAndGhpcy5jZWxsID0gY2VsbDsgdGhpcy50dXBsZSA9IHQ7IHRoaXMudmFsaWQgPSAwOyB0aGlzLm1pc3NpbmcgPSAwOycsXG4gICAgICBhZGQgPSAnaWYgKHY9PW51bGwpIHRoaXMubWlzc2luZysrOyBpZiAoIXRoaXMuaXNWYWxpZCh2KSkgcmV0dXJuOyArK3RoaXMudmFsaWQ7JyxcbiAgICAgIHJlbSA9ICdpZiAodj09bnVsbCkgdGhpcy5taXNzaW5nLS07IGlmICghdGhpcy5pc1ZhbGlkKHYpKSByZXR1cm47IC0tdGhpcy52YWxpZDsnLFxuICAgICAgc2V0ID0gJ3ZhciB0ID0gdGhpcy50dXBsZTsgdmFyIGNlbGwgPSB0aGlzLmNlbGw7JztcblxuICBhbGwuZm9yRWFjaChmdW5jdGlvbihhKSB7XG4gICAgaWYgKGEuaWR4IDwgMCkge1xuICAgICAgY3RyID0gYS5pbml0ICsgY3RyO1xuICAgICAgYWRkID0gYS5hZGQgKyBhZGQ7XG4gICAgICByZW0gPSBhLnJlbSArIHJlbTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3RyICs9IGEuaW5pdDtcbiAgICAgIGFkZCArPSBhLmFkZDtcbiAgICAgIHJlbSArPSBhLnJlbTtcbiAgICB9XG4gIH0pO1xuICBhZ2cuc2xpY2UoKVxuICAgIC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIGEuaWR4IC0gYi5pZHg7IH0pXG4gICAgLmZvckVhY2goZnVuY3Rpb24oYSkge1xuICAgICAgc2V0ICs9ICd0aGlzLmFzc2lnbih0LFxcJycrYS5vdXQrJ1xcJywnK2Euc2V0KycpOyc7XG4gICAgfSk7XG4gIHNldCArPSAncmV0dXJuIHQ7JztcblxuICAvKiBqc2hpbnQgZXZpbDogdHJ1ZSAqL1xuICBjdHIgPSBGdW5jdGlvbignY2VsbCcsICd0JywgY3RyKTtcbiAgY3RyLnByb3RvdHlwZS5hc3NpZ24gPSBtdXRhdG9yO1xuICBjdHIucHJvdG90eXBlLmFkZCA9IEZ1bmN0aW9uKCd0JywgJ3ZhciB2ID0gdGhpcy5nZXQodCk7JyArIGFkZCk7XG4gIGN0ci5wcm90b3R5cGUucmVtID0gRnVuY3Rpb24oJ3QnLCAndmFyIHYgPSB0aGlzLmdldCh0KTsnICsgcmVtKTtcbiAgY3RyLnByb3RvdHlwZS5zZXQgPSBGdW5jdGlvbihzZXQpO1xuICBjdHIucHJvdG90eXBlLmdldCA9IGFjY2Vzc29yO1xuICBjdHIucHJvdG90eXBlLmRpc3RpbmN0ID0gcmVxdWlyZSgnLi4vc3RhdHMnKS5jb3VudC5kaXN0aW5jdDtcbiAgY3RyLnByb3RvdHlwZS5pc1ZhbGlkID0gdXRpbC5pc1ZhbGlkO1xuICBjdHIuZmllbGRzID0gYWdnLm1hcCh1dGlsLiQoJ291dCcpKTtcbiAgcmV0dXJuIGN0cjtcbn1cblxudHlwZXMuY3JlYXRlID0gY3JlYXRlO1xubW9kdWxlLmV4cG9ydHMgPSB0eXBlczsiLCJ2YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgICB0aW1lID0gcmVxdWlyZSgnLi4vdGltZScpLFxuICAgIEVQU0lMT04gPSAxZS0xNTtcblxuZnVuY3Rpb24gYmlucyhvcHQpIHtcbiAgaWYgKCFvcHQpIHsgdGhyb3cgRXJyb3IoXCJNaXNzaW5nIGJpbm5pbmcgb3B0aW9ucy5cIik7IH1cblxuICAvLyBkZXRlcm1pbmUgcmFuZ2VcbiAgdmFyIG1heGIgPSBvcHQubWF4YmlucyB8fCAxNSxcbiAgICAgIGJhc2UgPSBvcHQuYmFzZSB8fCAxMCxcbiAgICAgIGxvZ2IgPSBNYXRoLmxvZyhiYXNlKSxcbiAgICAgIGRpdiA9IG9wdC5kaXYgfHwgWzUsIDJdLCAgICAgIFxuICAgICAgbWluID0gb3B0Lm1pbixcbiAgICAgIG1heCA9IG9wdC5tYXgsXG4gICAgICBzcGFuID0gbWF4IC0gbWluLFxuICAgICAgc3RlcCwgbGV2ZWwsIG1pbnN0ZXAsIHByZWNpc2lvbiwgdiwgaSwgZXBzO1xuXG4gIGlmIChvcHQuc3RlcCkge1xuICAgIC8vIGlmIHN0ZXAgc2l6ZSBpcyBleHBsaWNpdGx5IGdpdmVuLCB1c2UgdGhhdFxuICAgIHN0ZXAgPSBvcHQuc3RlcDtcbiAgfSBlbHNlIGlmIChvcHQuc3RlcHMpIHtcbiAgICAvLyBpZiBwcm92aWRlZCwgbGltaXQgY2hvaWNlIHRvIGFjY2VwdGFibGUgc3RlcCBzaXplc1xuICAgIHN0ZXAgPSBvcHQuc3RlcHNbTWF0aC5taW4oXG4gICAgICBvcHQuc3RlcHMubGVuZ3RoIC0gMSxcbiAgICAgIGJpc2VjdChvcHQuc3RlcHMsIHNwYW4vbWF4YiwgMCwgb3B0LnN0ZXBzLmxlbmd0aClcbiAgICApXTtcbiAgfSBlbHNlIHtcbiAgICAvLyBlbHNlIHVzZSBzcGFuIHRvIGRldGVybWluZSBzdGVwIHNpemVcbiAgICBsZXZlbCA9IE1hdGguY2VpbChNYXRoLmxvZyhtYXhiKSAvIGxvZ2IpO1xuICAgIG1pbnN0ZXAgPSBvcHQubWluc3RlcCB8fCAwO1xuICAgIHN0ZXAgPSBNYXRoLm1heChcbiAgICAgIG1pbnN0ZXAsXG4gICAgICBNYXRoLnBvdyhiYXNlLCBNYXRoLnJvdW5kKE1hdGgubG9nKHNwYW4pIC8gbG9nYikgLSBsZXZlbClcbiAgICApO1xuICAgIFxuICAgIC8vIGluY3JlYXNlIHN0ZXAgc2l6ZSBpZiB0b28gbWFueSBiaW5zXG4gICAgZG8geyBzdGVwICo9IGJhc2U7IH0gd2hpbGUgKE1hdGguY2VpbChzcGFuL3N0ZXApID4gbWF4Yik7XG5cbiAgICAvLyBkZWNyZWFzZSBzdGVwIHNpemUgaWYgYWxsb3dlZFxuICAgIGZvciAoaT0wOyBpPGRpdi5sZW5ndGg7ICsraSkge1xuICAgICAgdiA9IHN0ZXAgLyBkaXZbaV07XG4gICAgICBpZiAodiA+PSBtaW5zdGVwICYmIHNwYW4gLyB2IDw9IG1heGIpIHN0ZXAgPSB2O1xuICAgIH1cbiAgfVxuXG4gIC8vIHVwZGF0ZSBwcmVjaXNpb24sIG1pbiBhbmQgbWF4XG4gIHYgPSBNYXRoLmxvZyhzdGVwKTtcbiAgcHJlY2lzaW9uID0gdiA+PSAwID8gMCA6IH5+KC12IC8gbG9nYikgKyAxO1xuICBlcHMgPSBNYXRoLnBvdyhiYXNlLCAtcHJlY2lzaW9uIC0gMSk7XG4gIG1pbiA9IE1hdGgubWluKG1pbiwgTWF0aC5mbG9vcihtaW4gLyBzdGVwICsgZXBzKSAqIHN0ZXApO1xuICBtYXggPSBNYXRoLmNlaWwobWF4IC8gc3RlcCkgKiBzdGVwO1xuXG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IG1pbixcbiAgICBzdG9wOiAgbWF4LFxuICAgIHN0ZXA6ICBzdGVwLFxuICAgIHVuaXQ6ICB7cHJlY2lzaW9uOiBwcmVjaXNpb259LFxuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBpbmRleDogaW5kZXhcbiAgfTtcbn1cblxuZnVuY3Rpb24gYmlzZWN0KGEsIHgsIGxvLCBoaSkge1xuICB3aGlsZSAobG8gPCBoaSkge1xuICAgIHZhciBtaWQgPSBsbyArIGhpID4+PiAxO1xuICAgIGlmICh1dGlsLmNtcChhW21pZF0sIHgpIDwgMCkgeyBsbyA9IG1pZCArIDE7IH1cbiAgICBlbHNlIHsgaGkgPSBtaWQ7IH1cbiAgfVxuICByZXR1cm4gbG87XG59XG5cbmZ1bmN0aW9uIHZhbHVlKHYpIHtcbiAgcmV0dXJuIHRoaXMuc3RlcCAqIE1hdGguZmxvb3IodiAvIHRoaXMuc3RlcCArIEVQU0lMT04pO1xufVxuXG5mdW5jdGlvbiBpbmRleCh2KSB7XG4gIHJldHVybiBNYXRoLmZsb29yKCh2IC0gdGhpcy5zdGFydCkgLyB0aGlzLnN0ZXAgKyBFUFNJTE9OKTtcbn1cblxuZnVuY3Rpb24gZGF0ZV92YWx1ZSh2KSB7XG4gIHJldHVybiB0aGlzLnVuaXQuZGF0ZSh2YWx1ZS5jYWxsKHRoaXMsIHYpKTtcbn1cblxuZnVuY3Rpb24gZGF0ZV9pbmRleCh2KSB7XG4gIHJldHVybiBpbmRleC5jYWxsKHRoaXMsIHRoaXMudW5pdC51bml0KHYpKTtcbn1cblxuYmlucy5kYXRlID0gZnVuY3Rpb24ob3B0KSB7XG4gIGlmICghb3B0KSB7IHRocm93IEVycm9yKFwiTWlzc2luZyBkYXRlIGJpbm5pbmcgb3B0aW9ucy5cIik7IH1cblxuICAvLyBmaW5kIHRpbWUgc3RlcCwgdGhlbiBiaW5cbiAgdmFyIHVuaXRzID0gb3B0LnV0YyA/IHRpbWUudXRjIDogdGltZSxcbiAgICAgIGRtaW4gPSBvcHQubWluLFxuICAgICAgZG1heCA9IG9wdC5tYXgsXG4gICAgICBtYXhiID0gb3B0Lm1heGJpbnMgfHwgMjAsXG4gICAgICBtaW5iID0gb3B0Lm1pbmJpbnMgfHwgNCxcbiAgICAgIHNwYW4gPSAoK2RtYXgpIC0gKCtkbWluKSxcbiAgICAgIHVuaXQgPSBvcHQudW5pdCA/IHVuaXRzW29wdC51bml0XSA6IHVuaXRzLmZpbmQoc3BhbiwgbWluYiwgbWF4YiksXG4gICAgICBzcGVjID0gYmlucyh7XG4gICAgICAgIG1pbjogICAgIHVuaXQubWluICE9IG51bGwgPyB1bml0Lm1pbiA6IHVuaXQudW5pdChkbWluKSxcbiAgICAgICAgbWF4OiAgICAgdW5pdC5tYXggIT0gbnVsbCA/IHVuaXQubWF4IDogdW5pdC51bml0KGRtYXgpLFxuICAgICAgICBtYXhiaW5zOiBtYXhiLFxuICAgICAgICBtaW5zdGVwOiB1bml0Lm1pbnN0ZXAsXG4gICAgICAgIHN0ZXBzOiAgIHVuaXQuc3RlcFxuICAgICAgfSk7XG5cbiAgc3BlYy51bml0ID0gdW5pdDtcbiAgc3BlYy5pbmRleCA9IGRhdGVfaW5kZXg7XG4gIGlmICghb3B0LnJhdykgc3BlYy52YWx1ZSA9IGRhdGVfdmFsdWU7XG4gIHJldHVybiBzcGVjO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBiaW5zO1xuIiwidmFyIGJpbnMgPSByZXF1aXJlKCcuL2JpbnMnKSxcbiAgICBnZW4gID0gcmVxdWlyZSgnLi4vZ2VuZXJhdGUnKSxcbiAgICB0eXBlID0gcmVxdWlyZSgnLi4vaW1wb3J0L3R5cGUnKSxcbiAgICB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICAgIHN0YXRzID0gcmVxdWlyZSgnLi4vc3RhdHMnKTtcblxudmFyIHF0eXBlID0ge1xuICAnaW50ZWdlcic6IDEsXG4gICdudW1iZXInOiAxLFxuICAnZGF0ZSc6IDFcbn07XG5cbmZ1bmN0aW9uICRiaW4odmFsdWVzLCBmLCBvcHQpIHtcbiAgb3B0ID0gb3B0aW9ucyh2YWx1ZXMsIGYsIG9wdCk7XG4gIHZhciBiID0gc3BlYyhvcHQpO1xuICByZXR1cm4gIWIgPyAob3B0LmFjY2Vzc29yIHx8IHV0aWwuaWRlbnRpdHkpIDpcbiAgICB1dGlsLiRmdW5jKCdiaW4nLCBiLnVuaXQudW5pdCA/XG4gICAgICBmdW5jdGlvbih4KSB7IHJldHVybiBiLnZhbHVlKGIudW5pdC51bml0KHgpKTsgfSA6XG4gICAgICBmdW5jdGlvbih4KSB7IHJldHVybiBiLnZhbHVlKHgpOyB9XG4gICAgKShvcHQuYWNjZXNzb3IpO1xufVxuXG5mdW5jdGlvbiBoaXN0b2dyYW0odmFsdWVzLCBmLCBvcHQpIHtcbiAgb3B0ID0gb3B0aW9ucyh2YWx1ZXMsIGYsIG9wdCk7XG4gIHZhciBiID0gc3BlYyhvcHQpO1xuICByZXR1cm4gYiA/XG4gICAgbnVtZXJpY2FsKHZhbHVlcywgb3B0LmFjY2Vzc29yLCBiKSA6XG4gICAgY2F0ZWdvcmljYWwodmFsdWVzLCBvcHQuYWNjZXNzb3IsIG9wdCAmJiBvcHQuc29ydCk7XG59XG5cbmZ1bmN0aW9uIHNwZWMob3B0KSB7XG4gIHZhciB0ID0gb3B0LnR5cGUsIGIgPSBudWxsO1xuICBpZiAodCA9PSBudWxsIHx8IHF0eXBlW3RdKSB7XG4gICAgaWYgKHQgPT09ICdpbnRlZ2VyJyAmJiBvcHQubWluc3RlcCA9PSBudWxsKSBvcHQubWluc3RlcCA9IDE7XG4gICAgYiA9ICh0ID09PSAnZGF0ZScpID8gYmlucy5kYXRlKG9wdCkgOiBiaW5zKG9wdCk7XG4gIH1cbiAgcmV0dXJuIGI7XG59XG5cbmZ1bmN0aW9uIG9wdGlvbnMoKSB7XG4gIHZhciBhID0gYXJndW1lbnRzLFxuICAgICAgaSA9IDAsXG4gICAgICB2YWx1ZXMgPSB1dGlsLmlzQXJyYXkoYVtpXSkgPyBhW2krK10gOiBudWxsLFxuICAgICAgZiA9IHV0aWwuaXNGdW5jdGlvbihhW2ldKSB8fCB1dGlsLmlzU3RyaW5nKGFbaV0pID8gdXRpbC4kKGFbaSsrXSkgOiBudWxsLFxuICAgICAgb3B0ID0gdXRpbC5leHRlbmQoe30sIGFbaV0pO1xuICBcbiAgaWYgKHZhbHVlcykge1xuICAgIG9wdC50eXBlID0gb3B0LnR5cGUgfHwgdHlwZSh2YWx1ZXMsIGYpO1xuICAgIGlmIChxdHlwZVtvcHQudHlwZV0pIHtcbiAgICAgIHZhciBleHQgPSBzdGF0cy5leHRlbnQodmFsdWVzLCBmKTtcbiAgICAgIG9wdCA9IHV0aWwuZXh0ZW5kKHttaW46IGV4dFswXSwgbWF4OiBleHRbMV19LCBvcHQpO1xuICAgIH1cbiAgfVxuICBpZiAoZikgeyBvcHQuYWNjZXNzb3IgPSBmOyB9XG4gIHJldHVybiBvcHQ7XG59XG5cbmZ1bmN0aW9uIG51bWVyaWNhbCh2YWx1ZXMsIGYsIGIpIHtcbiAgdmFyIGggPSBnZW4ucmFuZ2UoYi5zdGFydCwgYi5zdG9wICsgYi5zdGVwLzIsIGIuc3RlcClcbiAgICAubWFwKGZ1bmN0aW9uKHYpIHsgcmV0dXJuIHt2YWx1ZTogYi52YWx1ZSh2KSwgY291bnQ6IDB9OyB9KTtcblxuICBmb3IgKHZhciBpPTAsIHYsIGo7IGk8dmFsdWVzLmxlbmd0aDsgKytpKSB7XG4gICAgdiA9IGYgPyBmKHZhbHVlc1tpXSkgOiB2YWx1ZXNbaV07XG4gICAgaWYgKHV0aWwuaXNWYWxpZCh2KSkge1xuICAgICAgaiA9IGIuaW5kZXgodik7XG4gICAgICBpZiAoaiA8IDAgfHwgaiA+PSBoLmxlbmd0aCB8fCAhaXNGaW5pdGUoaikpIGNvbnRpbnVlO1xuICAgICAgaFtqXS5jb3VudCArPSAxO1xuICAgIH1cbiAgfVxuICBoLmJpbnMgPSBiO1xuICByZXR1cm4gaDtcbn1cblxuZnVuY3Rpb24gY2F0ZWdvcmljYWwodmFsdWVzLCBmLCBzb3J0KSB7XG4gIHZhciB1ID0gc3RhdHMudW5pcXVlKHZhbHVlcywgZiksXG4gICAgICBjID0gc3RhdHMuY291bnQubWFwKHZhbHVlcywgZik7XG4gIHJldHVybiB1Lm1hcChmdW5jdGlvbihrKSB7IHJldHVybiB7dmFsdWU6IGssIGNvdW50OiBjW2tdfTsgfSlcbiAgICAuc29ydCh1dGlsLmNvbXBhcmF0b3Ioc29ydCA/ICctY291bnQnIDogJyt2YWx1ZScpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICRiaW46ICRiaW4sXG4gIGhpc3RvZ3JhbTogaGlzdG9ncmFtXG59OyIsInZhciBkM190aW1lID0gcmVxdWlyZSgnZDMtdGltZScpLFxuICAgIGQzX3RpbWVGID0gcmVxdWlyZSgnZDMtdGltZS1mb3JtYXQnKSxcbiAgICBkM19udW1iZXJGID0gcmVxdWlyZSgnZDMtZm9ybWF0JyksXG4gICAgbnVtYmVyRiA9IGQzX251bWJlckYsIC8vIGRlZmF1bHRzIHRvIEVOLVVTXG4gICAgdGltZUYgPSBkM190aW1lRjsgICAgIC8vIGRlZmF1bHRzIHRvIEVOLVVTXG5cbmZ1bmN0aW9uIG51bWJlckxvY2FsZShsKSB7XG4gIHZhciBmID0gZDNfbnVtYmVyRi5sb2NhbGVGb3JtYXQobCk7XG4gIGlmIChmID09IG51bGwpIHRocm93IEVycm9yKCdVbnJlY29nbml6ZWQgbG9jYWxlOiAnICsgbCk7XG4gIG51bWJlckYgPSBmO1xufVxuXG5mdW5jdGlvbiB0aW1lTG9jYWxlKGwpIHtcbiAgdmFyIGYgPSBkM190aW1lRi5sb2NhbGVGb3JtYXQobCk7XG4gIGlmIChmID09IG51bGwpIHRocm93IEVycm9yKCdVbnJlY29nbml6ZWQgbG9jYWxlOiAnICsgbCk7XG4gIHRpbWVGID0gZjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8vIFVwZGF0ZSBudW1iZXIgZm9ybWF0dGVyIHRvIHVzZSBwcm92aWRlZCBsb2NhbGUgY29uZmlndXJhdGlvbi5cbiAgLy8gRm9yIG1vcmUgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1mb3JtYXRcbiAgbnVtYmVyTG9jYWxlOiBudW1iZXJMb2NhbGUsXG4gIG51bWJlcjogICAgICAgZnVuY3Rpb24oZikgeyByZXR1cm4gbnVtYmVyRi5mb3JtYXQoZik7IH0sXG4gIG51bWJlclByZWZpeDogZnVuY3Rpb24oZiwgdikgeyByZXR1cm4gbnVtYmVyRi5mb3JtYXRQcmVmaXgoZiwgdik7IH0sXG5cbiAgLy8gVXBkYXRlIHRpbWUgZm9ybWF0dGVyIHRvIHVzZSBwcm92aWRlZCBsb2NhbGUgY29uZmlndXJhdGlvbi5cbiAgLy8gRm9yIG1vcmUgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy10aW1lLWZvcm1hdFxuICB0aW1lTG9jYWxlOiAgIHRpbWVMb2NhbGUsXG4gIHRpbWU6ICAgICAgICAgZnVuY3Rpb24oZikgeyByZXR1cm4gdGltZUYuZm9ybWF0KGYpOyB9LCAgXG4gIHV0YzogICAgICAgICAgZnVuY3Rpb24oZikgeyByZXR1cm4gdGltZUYudXRjRm9ybWF0KGYpOyB9LFxuXG4gIC8vIFNldCBudW1iZXIgYW5kIHRpbWUgbG9jYWxlIHNpbXVsdGFuZW91c2x5LlxuICBsb2NhbGU6ICAgICAgIGZ1bmN0aW9uKGwpIHsgbnVtYmVyTG9jYWxlKGwpOyB0aW1lTG9jYWxlKGwpOyB9LFxuXG4gIC8vIGF1dG9tYXRpYyBmb3JtYXR0aW5nIGZ1bmN0aW9uc1xuICBhdXRvOiB7XG4gICAgbnVtYmVyOiAgIG51bWJlckF1dG9Gb3JtYXQsXG4gICAgdGltZTogICAgIGZ1bmN0aW9uKCkgeyByZXR1cm4gdGltZUF1dG9Gb3JtYXQoKTsgfSxcbiAgICB1dGM6ICAgICAgZnVuY3Rpb24oKSB7IHJldHVybiB1dGNBdXRvRm9ybWF0KCk7IH1cbiAgfVxufTtcblxudmFyIGUxMCA9IE1hdGguc3FydCg1MCksXG4gICAgZTUgPSBNYXRoLnNxcnQoMTApLFxuICAgIGUyID0gTWF0aC5zcXJ0KDIpO1xuXG5mdW5jdGlvbiBpbnRlcnZhbHMoZG9tYWluLCBjb3VudCkge1xuICBpZiAoIWRvbWFpbi5sZW5ndGgpIGRvbWFpbiA9IFswXTtcbiAgaWYgKGNvdW50ID09IG51bGwpIGNvdW50ID0gMTA7XG5cbiAgdmFyIHN0YXJ0ID0gZG9tYWluWzBdLFxuICAgICAgc3RvcCA9IGRvbWFpbltkb21haW4ubGVuZ3RoIC0gMV07XG5cbiAgaWYgKHN0b3AgPCBzdGFydCkgeyBlcnJvciA9IHN0b3A7IHN0b3AgPSBzdGFydDsgc3RhcnQgPSBlcnJvcjsgfVxuXG4gIHZhciBzcGFuID0gKHN0b3AgLSBzdGFydCkgfHwgKGNvdW50ID0gMSwgc3RhcnQgfHwgc3RvcCB8fCAxKSxcbiAgICAgIHN0ZXAgPSBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihNYXRoLmxvZyhzcGFuIC8gY291bnQpIC8gTWF0aC5MTjEwKSksXG4gICAgICBlcnJvciA9IHNwYW4gLyBjb3VudCAvIHN0ZXA7XG5cbiAgLy8gRmlsdGVyIHRpY2tzIHRvIGdldCBjbG9zZXIgdG8gdGhlIGRlc2lyZWQgY291bnQuXG4gIGlmIChlcnJvciA+PSBlMTApIHN0ZXAgKj0gMTA7XG4gIGVsc2UgaWYgKGVycm9yID49IGU1KSBzdGVwICo9IDU7XG4gIGVsc2UgaWYgKGVycm9yID49IGUyKSBzdGVwICo9IDI7XG5cbiAgLy8gUm91bmQgc3RhcnQgYW5kIHN0b3AgdmFsdWVzIHRvIHN0ZXAgaW50ZXJ2YWwuXG4gIHJldHVybiBbXG4gICAgTWF0aC5jZWlsKHN0YXJ0IC8gc3RlcCkgKiBzdGVwLFxuICAgIE1hdGguZmxvb3Ioc3RvcCAvIHN0ZXApICogc3RlcCArIHN0ZXAgLyAyLCAvLyBpbmNsdXNpdmVcbiAgICBzdGVwXG4gIF07XG59XG5cbmZ1bmN0aW9uIG51bWJlckF1dG9Gb3JtYXQoZG9tYWluLCBjb3VudCwgZikge1xuICB2YXIgcmFuZ2UgPSBpbnRlcnZhbHMoZG9tYWluLCBjb3VudCk7XG4gIGlmIChmID09IG51bGwpIHtcbiAgICBmID0gJywuJyArIGQzX251bWJlckYucHJlY2lzaW9uRml4ZWQocmFuZ2VbMl0pICsgJ2YnO1xuICB9IGVsc2Uge1xuICAgIHN3aXRjaCAoZiA9IGQzX251bWJlckYuZm9ybWF0U3BlY2lmaWVyKGYpLCBmLnR5cGUpIHtcbiAgICAgIGNhc2UgJ3MnOiB7XG4gICAgICAgIHZhciB2YWx1ZSA9IE1hdGgubWF4KE1hdGguYWJzKHJhbmdlWzBdKSwgTWF0aC5hYnMocmFuZ2VbMV0pKTtcbiAgICAgICAgaWYgKGYucHJlY2lzaW9uID09IG51bGwpIGYucHJlY2lzaW9uID0gZDNfbnVtYmVyRi5wcmVjaXNpb25QcmVmaXgocmFuZ2VbMl0sIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIG51bWJlckYuZm9ybWF0UHJlZml4KGYsIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJyc6XG4gICAgICBjYXNlICdlJzpcbiAgICAgIGNhc2UgJ2cnOlxuICAgICAgY2FzZSAncCc6XG4gICAgICBjYXNlICdyJzoge1xuICAgICAgICBpZiAoZi5wcmVjaXNpb24gPT0gbnVsbCkgZi5wcmVjaXNpb24gPSBkM19udW1iZXJGLnByZWNpc2lvblJvdW5kKHJhbmdlWzJdLCBNYXRoLm1heChNYXRoLmFicyhyYW5nZVswXSksIE1hdGguYWJzKHJhbmdlWzFdKSkpIC0gKGYudHlwZSA9PT0gJ2UnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdmJzpcbiAgICAgIGNhc2UgJyUnOiB7XG4gICAgICAgIGlmIChmLnByZWNpc2lvbiA9PSBudWxsKSBmLnByZWNpc2lvbiA9IGQzX251bWJlckYucHJlY2lzaW9uRml4ZWQocmFuZ2VbMl0pIC0gKGYudHlwZSA9PT0gJyUnKSAqIDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVtYmVyRi5mb3JtYXQoZik7XG59XG5cbmZ1bmN0aW9uIHRpbWVBdXRvRm9ybWF0KCkge1xuICB2YXIgZiA9IHRpbWVGLmZvcm1hdCxcbiAgICAgIGZvcm1hdE1pbGxpc2Vjb25kID0gZignLiVMJyksXG4gICAgICBmb3JtYXRTZWNvbmQgPSBmKCc6JVMnKSxcbiAgICAgIGZvcm1hdE1pbnV0ZSA9IGYoJyVJOiVNJyksXG4gICAgICBmb3JtYXRIb3VyID0gZignJUkgJXAnKSxcbiAgICAgIGZvcm1hdERheSA9IGYoJyVhICVkJyksXG4gICAgICBmb3JtYXRXZWVrID0gZignJWIgJWQnKSxcbiAgICAgIGZvcm1hdE1vbnRoID0gZignJUInKSxcbiAgICAgIGZvcm1hdFllYXIgPSBmKCclWScpO1xuXG4gIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgdmFyIGQgPSArZGF0ZTtcbiAgICByZXR1cm4gKGQzX3RpbWUuc2Vjb25kKGRhdGUpIDwgZCA/IGZvcm1hdE1pbGxpc2Vjb25kXG4gICAgICAgIDogZDNfdGltZS5taW51dGUoZGF0ZSkgPCBkID8gZm9ybWF0U2Vjb25kXG4gICAgICAgIDogZDNfdGltZS5ob3VyKGRhdGUpIDwgZCA/IGZvcm1hdE1pbnV0ZVxuICAgICAgICA6IGQzX3RpbWUuZGF5KGRhdGUpIDwgZCA/IGZvcm1hdEhvdXJcbiAgICAgICAgOiBkM190aW1lLm1vbnRoKGRhdGUpIDwgZCA/XG4gICAgICAgICAgKGQzX3RpbWUud2VlayhkYXRlKSA8IGQgPyBmb3JtYXREYXkgOiBmb3JtYXRXZWVrKVxuICAgICAgICA6IGQzX3RpbWUueWVhcihkYXRlKSA8IGQgPyBmb3JtYXRNb250aFxuICAgICAgICA6IGZvcm1hdFllYXIpKGRhdGUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiB1dGNBdXRvRm9ybWF0KCkge1xuICB2YXIgZiA9IHRpbWVGLnV0Y0Zvcm1hdCxcbiAgICAgIGZvcm1hdE1pbGxpc2Vjb25kID0gZignLiVMJyksXG4gICAgICBmb3JtYXRTZWNvbmQgPSBmKCc6JVMnKSxcbiAgICAgIGZvcm1hdE1pbnV0ZSA9IGYoJyVJOiVNJyksXG4gICAgICBmb3JtYXRIb3VyID0gZignJUkgJXAnKSxcbiAgICAgIGZvcm1hdERheSA9IGYoJyVhICVkJyksXG4gICAgICBmb3JtYXRXZWVrID0gZignJWIgJWQnKSxcbiAgICAgIGZvcm1hdE1vbnRoID0gZignJUInKSxcbiAgICAgIGZvcm1hdFllYXIgPSBmKCclWScpO1xuXG4gIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgdmFyIGQgPSArZGF0ZTtcbiAgICByZXR1cm4gKGQzX3RpbWUudXRjU2Vjb25kKGRhdGUpIDwgZCA/IGZvcm1hdE1pbGxpc2Vjb25kXG4gICAgICAgIDogZDNfdGltZS51dGNNaW51dGUoZGF0ZSkgPCBkID8gZm9ybWF0U2Vjb25kXG4gICAgICAgIDogZDNfdGltZS51dGNIb3VyKGRhdGUpIDwgZCA/IGZvcm1hdE1pbnV0ZVxuICAgICAgICA6IGQzX3RpbWUudXRjRGF5KGRhdGUpIDwgZCA/IGZvcm1hdEhvdXJcbiAgICAgICAgOiBkM190aW1lLnV0Y01vbnRoKGRhdGUpIDwgZCA/XG4gICAgICAgICAgKGQzX3RpbWUudXRjV2VlayhkYXRlKSA8IGQgPyBmb3JtYXREYXkgOiBmb3JtYXRXZWVrKVxuICAgICAgICA6IGQzX3RpbWUudXRjWWVhcihkYXRlKSA8IGQgPyBmb3JtYXRNb250aFxuICAgICAgICA6IGZvcm1hdFllYXIpKGRhdGUpO1xuICB9O1xufVxuIiwidmFyIGdlbiA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbmdlbi5yZXBlYXQgPSBmdW5jdGlvbih2YWwsIG4pIHtcbiAgdmFyIGEgPSBBcnJheShuKSwgaTtcbiAgZm9yIChpPTA7IGk8bjsgKytpKSBhW2ldID0gdmFsO1xuICByZXR1cm4gYTtcbn07XG5cbmdlbi56ZXJvcyA9IGZ1bmN0aW9uKG4pIHtcbiAgcmV0dXJuIGdlbi5yZXBlYXQoMCwgbik7XG59O1xuXG5nZW4ucmFuZ2UgPSBmdW5jdGlvbihzdGFydCwgc3RvcCwgc3RlcCkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIHtcbiAgICBzdGVwID0gMTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHN0b3AgPSBzdGFydDtcbiAgICAgIHN0YXJ0ID0gMDtcbiAgICB9XG4gIH1cbiAgaWYgKChzdG9wIC0gc3RhcnQpIC8gc3RlcCA9PSBJbmZpbml0eSkgdGhyb3cgbmV3IEVycm9yKCdJbmZpbml0ZSByYW5nZScpO1xuICB2YXIgcmFuZ2UgPSBbXSwgaSA9IC0xLCBqO1xuICBpZiAoc3RlcCA8IDApIHdoaWxlICgoaiA9IHN0YXJ0ICsgc3RlcCAqICsraSkgPiBzdG9wKSByYW5nZS5wdXNoKGopO1xuICBlbHNlIHdoaWxlICgoaiA9IHN0YXJ0ICsgc3RlcCAqICsraSkgPCBzdG9wKSByYW5nZS5wdXNoKGopO1xuICByZXR1cm4gcmFuZ2U7XG59O1xuXG5nZW4ucmFuZG9tID0ge307XG5cbmdlbi5yYW5kb20udW5pZm9ybSA9IGZ1bmN0aW9uKG1pbiwgbWF4KSB7XG4gIGlmIChtYXggPT09IHVuZGVmaW5lZCkge1xuICAgIG1heCA9IG1pbiA9PT0gdW5kZWZpbmVkID8gMSA6IG1pbjtcbiAgICBtaW4gPSAwO1xuICB9XG4gIHZhciBkID0gbWF4IC0gbWluO1xuICB2YXIgZiA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBtaW4gKyBkICogTWF0aC5yYW5kb20oKTtcbiAgfTtcbiAgZi5zYW1wbGVzID0gZnVuY3Rpb24obikgeyByZXR1cm4gZ2VuLnplcm9zKG4pLm1hcChmKTsgfTtcbiAgcmV0dXJuIGY7XG59O1xuXG5nZW4ucmFuZG9tLmludGVnZXIgPSBmdW5jdGlvbihhLCBiKSB7XG4gIGlmIChiID09PSB1bmRlZmluZWQpIHtcbiAgICBiID0gYTtcbiAgICBhID0gMDtcbiAgfVxuICB2YXIgZCA9IGIgLSBhO1xuICB2YXIgZiA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhICsgTWF0aC5mbG9vcihkICogTWF0aC5yYW5kb20oKSk7XG4gIH07XG4gIGYuc2FtcGxlcyA9IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIGdlbi56ZXJvcyhuKS5tYXAoZik7IH07XG4gIHJldHVybiBmO1xufTtcblxuZ2VuLnJhbmRvbS5ub3JtYWwgPSBmdW5jdGlvbihtZWFuLCBzdGRldikge1xuICBtZWFuID0gbWVhbiB8fCAwO1xuICBzdGRldiA9IHN0ZGV2IHx8IDE7XG4gIHZhciBuZXh0O1xuICB2YXIgZiA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB4ID0gMCwgeSA9IDAsIHJkcywgYztcbiAgICBpZiAobmV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB4ID0gbmV4dDtcbiAgICAgIG5leHQgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4geDtcbiAgICB9XG4gICAgZG8ge1xuICAgICAgeCA9IE1hdGgucmFuZG9tKCkqMi0xO1xuICAgICAgeSA9IE1hdGgucmFuZG9tKCkqMi0xO1xuICAgICAgcmRzID0geCp4ICsgeSp5O1xuICAgIH0gd2hpbGUgKHJkcyA9PT0gMCB8fCByZHMgPiAxKTtcbiAgICBjID0gTWF0aC5zcXJ0KC0yKk1hdGgubG9nKHJkcykvcmRzKTsgLy8gQm94LU11bGxlciB0cmFuc2Zvcm1cbiAgICBuZXh0ID0gbWVhbiArIHkqYypzdGRldjtcbiAgICByZXR1cm4gbWVhbiArIHgqYypzdGRldjtcbiAgfTtcbiAgZi5zYW1wbGVzID0gZnVuY3Rpb24obikgeyByZXR1cm4gZ2VuLnplcm9zKG4pLm1hcChmKTsgfTtcbiAgcmV0dXJuIGY7XG59OyIsInZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xudmFyIGQzX2RzdiA9IHJlcXVpcmUoJ2QzLWRzdicpO1xuXG5mdW5jdGlvbiBkc3YoZGF0YSwgZm9ybWF0KSB7XG4gIGlmIChkYXRhKSB7XG4gICAgdmFyIGggPSBmb3JtYXQuaGVhZGVyO1xuICAgIGRhdGEgPSAoaCA/IGguam9pbihmb3JtYXQuZGVsaW1pdGVyKSArICdcXG4nIDogJycpICsgZGF0YTtcbiAgfVxuICByZXR1cm4gZDNfZHN2LmRzdihmb3JtYXQuZGVsaW1pdGVyKS5wYXJzZShkYXRhKTtcbn1cblxuZHN2LmRlbGltaXRlciA9IGZ1bmN0aW9uKGRlbGltKSB7XG4gIHZhciBmbXQgPSB7ZGVsaW1pdGVyOiBkZWxpbX07XG4gIHJldHVybiBmdW5jdGlvbihkYXRhLCBmb3JtYXQpIHtcbiAgICByZXR1cm4gZHN2KGRhdGEsIGZvcm1hdCA/IHV0aWwuZXh0ZW5kKGZvcm1hdCwgZm10KSA6IGZtdCk7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRzdjsiLCJ2YXIgZHN2ID0gcmVxdWlyZSgnLi9kc3YnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGpzb246IHJlcXVpcmUoJy4vanNvbicpLFxuICB0b3BvanNvbjogcmVxdWlyZSgnLi90b3BvanNvbicpLFxuICB0cmVlanNvbjogcmVxdWlyZSgnLi90cmVlanNvbicpLFxuICBkc3Y6IGRzdixcbiAgY3N2OiBkc3YuZGVsaW1pdGVyKCcsJyksXG4gIHRzdjogZHN2LmRlbGltaXRlcignXFx0Jylcbn07IiwidmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZGF0YSwgZm9ybWF0KSB7XG4gIHZhciBkID0gdXRpbC5pc09iamVjdChkYXRhKSAmJiAhdXRpbC5pc0J1ZmZlcihkYXRhKSA/XG4gICAgZGF0YSA6IEpTT04ucGFyc2UoZGF0YSk7XG4gIGlmIChmb3JtYXQgJiYgZm9ybWF0LnByb3BlcnR5KSB7XG4gICAgZCA9IHV0aWwuYWNjZXNzb3IoZm9ybWF0LnByb3BlcnR5KShkKTtcbiAgfVxuICByZXR1cm4gZDtcbn07XG4iLCJ2YXIganNvbiA9IHJlcXVpcmUoJy4vanNvbicpO1xuXG52YXIgcmVhZGVyID0gZnVuY3Rpb24oZGF0YSwgZm9ybWF0KSB7XG4gIHZhciB0b3BvanNvbiA9IHJlYWRlci50b3BvanNvbjtcbiAgaWYgKHRvcG9qc29uID09IG51bGwpIHsgdGhyb3cgRXJyb3IoJ1RvcG9KU09OIGxpYnJhcnkgbm90IGxvYWRlZC4nKTsgfVxuXG4gIHZhciB0ID0ganNvbihkYXRhLCBmb3JtYXQpLCBvYmo7XG5cbiAgaWYgKGZvcm1hdCAmJiBmb3JtYXQuZmVhdHVyZSkge1xuICAgIGlmICgob2JqID0gdC5vYmplY3RzW2Zvcm1hdC5mZWF0dXJlXSkpIHtcbiAgICAgIHJldHVybiB0b3BvanNvbi5mZWF0dXJlKHQsIG9iaikuZmVhdHVyZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIFRvcG9KU09OIG9iamVjdDogJyArIGZvcm1hdC5mZWF0dXJlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoZm9ybWF0ICYmIGZvcm1hdC5tZXNoKSB7XG4gICAgaWYgKChvYmogPSB0Lm9iamVjdHNbZm9ybWF0Lm1lc2hdKSkge1xuICAgICAgcmV0dXJuIFt0b3BvanNvbi5tZXNoKHQsIHQub2JqZWN0c1tmb3JtYXQubWVzaF0pXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgRXJyb3IoJ0ludmFsaWQgVG9wb0pTT04gb2JqZWN0OiAnICsgZm9ybWF0Lm1lc2gpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBFcnJvcignTWlzc2luZyBUb3BvSlNPTiBmZWF0dXJlIG9yIG1lc2ggcGFyYW1ldGVyLicpO1xuICB9XG59O1xuXG5yZWFkZXIudG9wb2pzb24gPSAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvd1sndG9wb2pzb24nXSA6IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWxbJ3RvcG9qc29uJ10gOiBudWxsKTtcbm1vZHVsZS5leHBvcnRzID0gcmVhZGVyOyIsInZhciBqc29uID0gcmVxdWlyZSgnLi9qc29uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZGF0YSwgZm9ybWF0KSB7XG4gIGRhdGEgPSBqc29uKGRhdGEsIGZvcm1hdCk7XG4gIHJldHVybiB0b1RhYmxlKGRhdGEsIChmb3JtYXQgJiYgZm9ybWF0LmNoaWxkcmVuKSk7XG59O1xuXG5mdW5jdGlvbiB0b1RhYmxlKHJvb3QsIGNoaWxkcmVuRmllbGQpIHtcbiAgY2hpbGRyZW5GaWVsZCA9IGNoaWxkcmVuRmllbGQgfHwgJ2NoaWxkcmVuJztcbiAgdmFyIHRhYmxlID0gW107XG4gIFxuICBmdW5jdGlvbiB2aXNpdChub2RlKSB7XG4gICAgdGFibGUucHVzaChub2RlKTtcbiAgICB2YXIgY2hpbGRyZW4gPSBub2RlW2NoaWxkcmVuRmllbGRdO1xuICAgIGlmIChjaGlsZHJlbikge1xuICAgICAgZm9yICh2YXIgaT0wOyBpPGNoaWxkcmVuLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZpc2l0KGNoaWxkcmVuW2ldLCBub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgXG4gIHZpc2l0KHJvb3QsIG51bGwpO1xuICByZXR1cm4gKHRhYmxlLnJvb3QgPSByb290LCB0YWJsZSk7XG59IiwiLy8gTWF0Y2hlcyBhYnNvbHV0ZSBVUkxzIHdpdGggb3B0aW9uYWwgcHJvdG9jb2xcbi8vICAgaHR0cHM6Ly8uLi4gICAgZmlsZTovLy4uLiAgICAvLy4uLlxudmFyIHByb3RvY29sX3JlID0gL14oW0EtWmEtel0rOik/XFwvXFwvLztcblxuLy8gU3BlY2lhbCB0cmVhdG1lbnQgaW4gbm9kZS5qcyBmb3IgdGhlIGZpbGU6IHByb3RvY29sXG52YXIgZmlsZVByb3RvY29sID0gJ2ZpbGU6Ly8nO1xuXG4vLyBWYWxpZGF0ZSBhbmQgY2xlYW51cCBVUkwgdG8gZW5zdXJlIHRoYXQgaXQgaXMgYWxsb3dlZCB0byBiZSBhY2Nlc3NlZFxuLy8gUmV0dXJucyBjbGVhbmVkIHVwIFVSTCwgb3IgZmFsc2UgaWYgYWNjZXNzIGlzIG5vdCBhbGxvd2VkXG5mdW5jdGlvbiBzYW5pdGl6ZVVybChvcHQpIHtcbiAgdmFyIHVybCA9IG9wdC51cmw7XG4gIGlmICghdXJsICYmIG9wdC5maWxlKSB7IHJldHVybiBmaWxlUHJvdG9jb2wgKyBvcHQuZmlsZTsgfVxuXG4gIC8vIEluIGNhc2UgdGhpcyBpcyBhIHJlbGF0aXZlIHVybCAoaGFzIG5vIGhvc3QpLCBwcmVwZW5kIG9wdC5iYXNlVVJMXG4gIGlmIChvcHQuYmFzZVVSTCAmJiAhcHJvdG9jb2xfcmUudGVzdCh1cmwpKSB7XG4gICAgaWYgKCFzdGFydHNXaXRoKHVybCwgJy8nKSAmJiBvcHQuYmFzZVVSTFtvcHQuYmFzZVVSTC5sZW5ndGgtMV0gIT09ICcvJykge1xuICAgICAgdXJsID0gJy8nICsgdXJsOyAvLyBFbnN1cmUgdGhhdCB0aGVyZSBpcyBhIHNsYXNoIGJldHdlZW4gdGhlIGJhc2VVUkwgKGUuZy4gaG9zdG5hbWUpIGFuZCB1cmxcbiAgICB9XG4gICAgdXJsID0gb3B0LmJhc2VVUkwgKyB1cmw7XG4gIH1cbiAgLy8gcmVsYXRpdmUgcHJvdG9jb2wsIHN0YXJ0cyB3aXRoICcvLydcbiAgaWYgKCFsb2FkLnVzZVhIUiAmJiBzdGFydHNXaXRoKHVybCwgJy8vJykpIHtcbiAgICB1cmwgPSAob3B0LmRlZmF1bHRQcm90b2NvbCB8fCAnaHR0cCcpICsgJzonICsgdXJsO1xuICB9XG4gIC8vIElmIG9wdC5kb21haW5XaGl0ZUxpc3QgaXMgc2V0LCBvbmx5IGFsbG93cyB1cmwsIHdob3NlIGhvc3RuYW1lXG4gIC8vICogSXMgdGhlIHNhbWUgYXMgdGhlIG9yaWdpbiAod2luZG93LmxvY2F0aW9uLmhvc3RuYW1lKVxuICAvLyAqIEVxdWFscyBvbmUgb2YgdGhlIHZhbHVlcyBpbiB0aGUgd2hpdGVsaXN0XG4gIC8vICogSXMgYSBwcm9wZXIgc3ViZG9tYWluIG9mIG9uZSBvZiB0aGUgdmFsdWVzIGluIHRoZSB3aGl0ZWxpc3RcbiAgaWYgKG9wdC5kb21haW5XaGl0ZUxpc3QpIHtcbiAgICB2YXIgZG9tYWluLCBvcmlnaW47XG4gICAgaWYgKGxvYWQudXNlWEhSKSB7XG4gICAgICB2YXIgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgIGEuaHJlZiA9IHVybDtcbiAgICAgIC8vIEZyb20gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy83MzY1MTMvaG93LWRvLWktcGFyc2UtYS11cmwtaW50by1ob3N0bmFtZS1hbmQtcGF0aC1pbi1qYXZhc2NyaXB0XG4gICAgICAvLyBJRSBkb2Vzbid0IHBvcHVsYXRlIGFsbCBsaW5rIHByb3BlcnRpZXMgd2hlbiBzZXR0aW5nIC5ocmVmIHdpdGggYSByZWxhdGl2ZSBVUkwsXG4gICAgICAvLyBob3dldmVyIC5ocmVmIHdpbGwgcmV0dXJuIGFuIGFic29sdXRlIFVSTCB3aGljaCB0aGVuIGNhbiBiZSB1c2VkIG9uIGl0c2VsZlxuICAgICAgLy8gdG8gcG9wdWxhdGUgdGhlc2UgYWRkaXRpb25hbCBmaWVsZHMuXG4gICAgICBpZiAoYS5ob3N0ID09PSAnJykge1xuICAgICAgICBhLmhyZWYgPSBhLmhyZWY7XG4gICAgICB9XG4gICAgICBkb21haW4gPSBhLmhvc3RuYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICBvcmlnaW4gPSB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHJlbGF0aXZlIHByb3RvY29sIGlzIGJyb2tlbjogaHR0cHM6Ly9naXRodWIuY29tL2RlZnVuY3R6b21iaWUvbm9kZS11cmwvaXNzdWVzLzVcbiAgICAgIHZhciBwYXJ0cyA9IHJlcXVpcmUoJ3VybCcpLnBhcnNlKHVybCk7XG4gICAgICBkb21haW4gPSBwYXJ0cy5ob3N0bmFtZTtcbiAgICAgIG9yaWdpbiA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKG9yaWdpbiAhPT0gZG9tYWluKSB7XG4gICAgICB2YXIgd2hpdGVMaXN0ZWQgPSBvcHQuZG9tYWluV2hpdGVMaXN0LnNvbWUoZnVuY3Rpb24oZCkge1xuICAgICAgICB2YXIgaWR4ID0gZG9tYWluLmxlbmd0aCAtIGQubGVuZ3RoO1xuICAgICAgICByZXR1cm4gZCA9PT0gZG9tYWluIHx8XG4gICAgICAgICAgKGlkeCA+IDEgJiYgZG9tYWluW2lkeC0xXSA9PT0gJy4nICYmIGRvbWFpbi5sYXN0SW5kZXhPZihkKSA9PT0gaWR4KTtcbiAgICAgIH0pO1xuICAgICAgaWYgKCF3aGl0ZUxpc3RlZCkge1xuICAgICAgICB0aHJvdyAnVVJMIGlzIG5vdCB3aGl0ZWxpc3RlZDogJyArIHVybDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVybDtcbn1cblxuZnVuY3Rpb24gbG9hZChvcHQsIGNhbGxiYWNrKSB7XG4gIHZhciBlcnJvciA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uKGUpIHsgdGhyb3cgZTsgfSwgdXJsO1xuXG4gIHRyeSB7XG4gICAgdXJsID0gbG9hZC5zYW5pdGl6ZVVybChvcHQpOyAvLyBlbmFibGUgb3ZlcnJpZGVcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3IoZXJyKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIXVybCkge1xuICAgIGVycm9yKCdJbnZhbGlkIFVSTDogJyArIG9wdC51cmwpO1xuICB9IGVsc2UgaWYgKGxvYWQudXNlWEhSKSB7XG4gICAgLy8gb24gY2xpZW50LCB1c2UgeGhyXG4gICAgcmV0dXJuIHhocih1cmwsIGNhbGxiYWNrKTtcbiAgfSBlbHNlIGlmIChzdGFydHNXaXRoKHVybCwgZmlsZVByb3RvY29sKSkge1xuICAgIC8vIG9uIHNlcnZlciwgaWYgdXJsIHN0YXJ0cyB3aXRoICdmaWxlOi8vJywgc3RyaXAgaXQgYW5kIGxvYWQgZnJvbSBmaWxlXG4gICAgcmV0dXJuIGZpbGUodXJsLnNsaWNlKGZpbGVQcm90b2NvbC5sZW5ndGgpLCBjYWxsYmFjayk7XG4gIH0gZWxzZSBpZiAodXJsLmluZGV4T2YoJzovLycpIDwgMCkgeyAvLyBUT0RPIGJldHRlciBwcm90b2NvbCBjaGVjaz9cbiAgICAvLyBvbiBzZXJ2ZXIsIGlmIG5vIHByb3RvY29sIGFzc3VtZSBmaWxlXG4gICAgcmV0dXJuIGZpbGUodXJsLCBjYWxsYmFjayk7XG4gIH0gZWxzZSB7XG4gICAgLy8gZm9yIHJlZ3VsYXIgVVJMcyBvbiBzZXJ2ZXJcbiAgICByZXR1cm4gaHR0cCh1cmwsIGNhbGxiYWNrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB4aHJIYXNSZXNwb25zZShyZXF1ZXN0KSB7XG4gIHZhciB0eXBlID0gcmVxdWVzdC5yZXNwb25zZVR5cGU7XG4gIHJldHVybiB0eXBlICYmIHR5cGUgIT09ICd0ZXh0JyA/XG4gICAgcmVxdWVzdC5yZXNwb25zZSA6IC8vIG51bGwgb24gZXJyb3JcbiAgICByZXF1ZXN0LnJlc3BvbnNlVGV4dDsgLy8gJycgb24gZXJyb3Jcbn1cblxuZnVuY3Rpb24geGhyKHVybCwgY2FsbGJhY2spIHtcbiAgdmFyIGFzeW5jID0gISFjYWxsYmFjaztcbiAgdmFyIHJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgLy8gSWYgSUUgZG9lcyBub3Qgc3VwcG9ydCBDT1JTLCB1c2UgWERvbWFpblJlcXVlc3QgKGNvcGllZCBmcm9tIGQzLnhocilcbiAgaWYgKHRoaXMuWERvbWFpblJlcXVlc3QgJiZcbiAgICAgICEoJ3dpdGhDcmVkZW50aWFscycgaW4gcmVxdWVzdCkgJiZcbiAgICAgIC9eKGh0dHAocyk/Oik/XFwvXFwvLy50ZXN0KHVybCkpIHJlcXVlc3QgPSBuZXcgWERvbWFpblJlcXVlc3QoKTtcblxuICBmdW5jdGlvbiByZXNwb25kKCkge1xuICAgIHZhciBzdGF0dXMgPSByZXF1ZXN0LnN0YXR1cztcbiAgICBpZiAoIXN0YXR1cyAmJiB4aHJIYXNSZXNwb25zZShyZXF1ZXN0KSB8fCBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMCB8fCBzdGF0dXMgPT09IDMwNCkge1xuICAgICAgY2FsbGJhY2sobnVsbCwgcmVxdWVzdC5yZXNwb25zZVRleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjayhyZXF1ZXN0LCBudWxsKTtcbiAgICB9XG4gIH1cblxuICBpZiAoYXN5bmMpIHtcbiAgICBpZiAoJ29ubG9hZCcgaW4gcmVxdWVzdCkge1xuICAgICAgcmVxdWVzdC5vbmxvYWQgPSByZXF1ZXN0Lm9uZXJyb3IgPSByZXNwb25kO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAocmVxdWVzdC5yZWFkeVN0YXRlID4gMykgcmVzcG9uZCgpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgXG4gIHJlcXVlc3Qub3BlbignR0VUJywgdXJsLCBhc3luYyk7XG4gIHJlcXVlc3Quc2VuZCgpO1xuICBcbiAgaWYgKCFhc3luYyAmJiB4aHJIYXNSZXNwb25zZShyZXF1ZXN0KSkge1xuICAgIHJldHVybiByZXF1ZXN0LnJlc3BvbnNlVGV4dDtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaWxlKGZpbGVuYW1lLCBjYWxsYmFjaykge1xuICB2YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyhmaWxlbmFtZSwgJ3V0ZjgnKTtcbiAgfVxuICBmcy5yZWFkRmlsZShmaWxlbmFtZSwgY2FsbGJhY2spO1xufVxuXG5mdW5jdGlvbiBodHRwKHVybCwgY2FsbGJhY2spIHtcbiAgaWYgKCFjYWxsYmFjaykge1xuICAgIHJldHVybiByZXF1aXJlKCdzeW5jLXJlcXVlc3QnKSgnR0VUJywgdXJsKS5nZXRCb2R5KCk7XG4gIH1cbiAgXG4gIHZhciBvcHRpb25zID0ge3VybDogdXJsLCBlbmNvZGluZzogbnVsbCwgZ3ppcDogdHJ1ZX07XG4gIHJlcXVpcmUoJ3JlcXVlc3QnKShvcHRpb25zLCBmdW5jdGlvbihlcnJvciwgcmVzcG9uc2UsIGJvZHkpIHtcbiAgICBpZiAoIWVycm9yICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgPT09IDIwMCkge1xuICAgICAgY2FsbGJhY2sobnVsbCwgYm9keSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yID0gZXJyb3IgfHxcbiAgICAgICAgJ0xvYWQgZmFpbGVkIHdpdGggcmVzcG9uc2UgY29kZSAnICsgcmVzcG9uc2Uuc3RhdHVzQ29kZSArICcuJztcbiAgICAgIGNhbGxiYWNrKGVycm9yLCBudWxsKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBzdGFydHNXaXRoKHN0cmluZywgc2VhcmNoU3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmcgPT0gbnVsbCA/IGZhbHNlIDogc3RyaW5nLmxhc3RJbmRleE9mKHNlYXJjaFN0cmluZywgMCkgPT09IDA7XG59XG5cbmxvYWQuc2FuaXRpemVVcmwgPSBzYW5pdGl6ZVVybDtcblxubG9hZC51c2VYSFIgPSAodHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICE9PSAndW5kZWZpbmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbG9hZDtcbiIsInZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xudmFyIHR5cGUgPSByZXF1aXJlKCcuL3R5cGUnKTtcbnZhciBmb3JtYXRzID0gcmVxdWlyZSgnLi9mb3JtYXRzJyk7XG5cbmZ1bmN0aW9uIHJlYWQoZGF0YSwgZm9ybWF0KSB7XG4gIHZhciB0eXBlID0gKGZvcm1hdCAmJiBmb3JtYXQudHlwZSkgfHwgJ2pzb24nO1xuICBkYXRhID0gZm9ybWF0c1t0eXBlXShkYXRhLCBmb3JtYXQpO1xuICBpZiAoZm9ybWF0ICYmIGZvcm1hdC5wYXJzZSkgcGFyc2UoZGF0YSwgZm9ybWF0LnBhcnNlKTtcbiAgcmV0dXJuIGRhdGE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlKGRhdGEsIHR5cGVzKSB7XG4gIHZhciBjb2xzLCBwYXJzZXJzLCBkLCBpLCBqLCBjbGVuLCBsZW4gPSBkYXRhLmxlbmd0aDtcblxuICB0eXBlcyA9ICh0eXBlcz09PSdhdXRvJykgPyB0eXBlLmluZmVyQWxsKGRhdGEpIDogdXRpbC5kdXBsaWNhdGUodHlwZXMpO1xuICBjb2xzID0gdXRpbC5rZXlzKHR5cGVzKTtcbiAgcGFyc2VycyA9IGNvbHMubWFwKGZ1bmN0aW9uKGMpIHsgcmV0dXJuIHR5cGUucGFyc2Vyc1t0eXBlc1tjXV07IH0pO1xuXG4gIGZvciAoaT0wLCBjbGVuPWNvbHMubGVuZ3RoOyBpPGxlbjsgKytpKSB7XG4gICAgZCA9IGRhdGFbaV07XG4gICAgZm9yIChqPTA7IGo8Y2xlbjsgKytqKSB7XG4gICAgICBkW2NvbHNbal1dID0gcGFyc2Vyc1tqXShkW2NvbHNbal1dKTtcbiAgICB9XG4gIH1cbiAgdHlwZS5hbm5vdGF0aW9uKGRhdGEsIHR5cGVzKTtcbn1cblxucmVhZC5mb3JtYXRzID0gZm9ybWF0cztcbm1vZHVsZS5leHBvcnRzID0gcmVhZDtcbiIsInZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xudmFyIGxvYWQgPSByZXF1aXJlKCcuL2xvYWQnKTtcbnZhciByZWFkID0gcmVxdWlyZSgnLi9yZWFkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gdXRpbFxuICAua2V5cyhyZWFkLmZvcm1hdHMpXG4gIC5yZWR1Y2UoZnVuY3Rpb24ob3V0LCB0eXBlKSB7XG4gICAgb3V0W3R5cGVdID0gZnVuY3Rpb24ob3B0LCBmb3JtYXQsIGNhbGxiYWNrKSB7XG4gICAgICAvLyBwcm9jZXNzIGFyZ3VtZW50c1xuICAgICAgaWYgKHV0aWwuaXNTdHJpbmcob3B0KSkgeyBvcHQgPSB7dXJsOiBvcHR9OyB9XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMiAmJiB1dGlsLmlzRnVuY3Rpb24oZm9ybWF0KSkge1xuICAgICAgICBjYWxsYmFjayA9IGZvcm1hdDtcbiAgICAgICAgZm9ybWF0ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICAvLyBzZXQgdXAgcmVhZCBmb3JtYXRcbiAgICAgIGZvcm1hdCA9IHV0aWwuZXh0ZW5kKHtwYXJzZTogJ2F1dG8nfSwgZm9ybWF0KTtcbiAgICAgIGZvcm1hdC50eXBlID0gdHlwZTtcblxuICAgICAgLy8gbG9hZCBkYXRhXG4gICAgICB2YXIgZGF0YSA9IGxvYWQob3B0LCBjYWxsYmFjayA/IGZ1bmN0aW9uKGVycm9yLCBkYXRhKSB7XG4gICAgICAgIGlmIChlcnJvcikgeyBjYWxsYmFjayhlcnJvciwgbnVsbCk7IHJldHVybjsgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIGRhdGEgbG9hZGVkLCBub3cgcGFyc2UgaXQgKGFzeW5jKVxuICAgICAgICAgIGRhdGEgPSByZWFkKGRhdGEsIGZvcm1hdCk7XG4gICAgICAgICAgY2FsbGJhY2sobnVsbCwgZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjYWxsYmFjayhlLCBudWxsKTtcbiAgICAgICAgfVxuICAgICAgfSA6IHVuZGVmaW5lZCk7XG4gICAgICBcbiAgICAgIC8vIGRhdGEgbG9hZGVkLCBub3cgcGFyc2UgaXQgKHN5bmMpXG4gICAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm4gcmVhZChkYXRhLCBmb3JtYXQpO1xuICAgIH07XG4gICAgcmV0dXJuIG91dDtcbiAgfSwge30pO1xuIiwidmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cbnZhciBUWVBFUyA9ICdfX3R5cGVzX18nO1xuXG52YXIgUEFSU0VSUyA9IHtcbiAgYm9vbGVhbjogdXRpbC5ib29sZWFuLFxuICBpbnRlZ2VyOiB1dGlsLm51bWJlcixcbiAgbnVtYmVyOiAgdXRpbC5udW1iZXIsXG4gIGRhdGU6ICAgIHV0aWwuZGF0ZSxcbiAgc3RyaW5nOiAgZnVuY3Rpb24oeCkgeyByZXR1cm4geD09PScnID8gbnVsbCA6IHg7IH1cbn07XG5cbnZhciBURVNUUyA9IHtcbiAgYm9vbGVhbjogZnVuY3Rpb24oeCkgeyByZXR1cm4geD09PSd0cnVlJyB8fCB4PT09J2ZhbHNlJyB8fCB1dGlsLmlzQm9vbGVhbih4KTsgfSxcbiAgaW50ZWdlcjogZnVuY3Rpb24oeCkgeyByZXR1cm4gVEVTVFMubnVtYmVyKHgpICYmICh4PSt4KSA9PT0gfn54OyB9LFxuICBudW1iZXI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuICFpc05hTigreCkgJiYgIXV0aWwuaXNEYXRlKHgpOyB9LFxuICBkYXRlOiBmdW5jdGlvbih4KSB7IHJldHVybiAhaXNOYU4oRGF0ZS5wYXJzZSh4KSk7IH1cbn07XG5cbmZ1bmN0aW9uIGFubm90YXRpb24oZGF0YSwgdHlwZXMpIHtcbiAgaWYgKCF0eXBlcykgcmV0dXJuIGRhdGEgJiYgZGF0YVtUWVBFU10gfHwgbnVsbDtcbiAgZGF0YVtUWVBFU10gPSB0eXBlcztcbn1cblxuZnVuY3Rpb24gdHlwZSh2YWx1ZXMsIGYpIHtcbiAgZiA9IHV0aWwuJChmKTtcbiAgdmFyIHYsIGksIG47XG5cbiAgLy8gaWYgZGF0YSBhcnJheSBoYXMgdHlwZSBhbm5vdGF0aW9ucywgdXNlIHRoZW1cbiAgaWYgKHZhbHVlc1tUWVBFU10pIHtcbiAgICB2ID0gZih2YWx1ZXNbVFlQRVNdKTtcbiAgICBpZiAodXRpbC5pc1N0cmluZyh2KSkgcmV0dXJuIHY7XG4gIH1cblxuICBmb3IgKGk9MCwgbj12YWx1ZXMubGVuZ3RoOyAhdXRpbC5pc1ZhbGlkKHYpICYmIGk8bjsgKytpKSB7XG4gICAgdiA9IGYgPyBmKHZhbHVlc1tpXSkgOiB2YWx1ZXNbaV07XG4gIH1cblxuICByZXR1cm4gdXRpbC5pc0RhdGUodikgPyAnZGF0ZScgOlxuICAgIHV0aWwuaXNOdW1iZXIodikgICAgPyAnbnVtYmVyJyA6XG4gICAgdXRpbC5pc0Jvb2xlYW4odikgICA/ICdib29sZWFuJyA6XG4gICAgdXRpbC5pc1N0cmluZyh2KSAgICA/ICdzdHJpbmcnIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gdHlwZUFsbChkYXRhLCBmaWVsZHMpIHtcbiAgaWYgKCFkYXRhLmxlbmd0aCkgcmV0dXJuO1xuICBmaWVsZHMgPSBmaWVsZHMgfHwgdXRpbC5rZXlzKGRhdGFbMF0pO1xuICByZXR1cm4gZmllbGRzLnJlZHVjZShmdW5jdGlvbih0eXBlcywgZikge1xuICAgIHJldHVybiAodHlwZXNbZl0gPSB0eXBlKGRhdGEsIGYpLCB0eXBlcyk7XG4gIH0sIHt9KTtcbn1cblxuZnVuY3Rpb24gaW5mZXIodmFsdWVzLCBmKSB7XG4gIGYgPSB1dGlsLiQoZik7XG4gIHZhciBpLCBqLCB2O1xuXG4gIC8vIHR5cGVzIHRvIHRlc3QgZm9yLCBpbiBwcmVjZWRlbmNlIG9yZGVyXG4gIHZhciB0eXBlcyA9IFsnYm9vbGVhbicsICdpbnRlZ2VyJywgJ251bWJlcicsICdkYXRlJ107XG5cbiAgZm9yIChpPTA7IGk8dmFsdWVzLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gZ2V0IG5leHQgdmFsdWUgdG8gdGVzdFxuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgIC8vIHRlc3QgdmFsdWUgYWdhaW5zdCByZW1haW5pbmcgdHlwZXNcbiAgICBmb3IgKGo9MDsgajx0eXBlcy5sZW5ndGg7ICsraikge1xuICAgICAgaWYgKHV0aWwuaXNWYWxpZCh2KSAmJiAhVEVTVFNbdHlwZXNbal1dKHYpKSB7XG4gICAgICAgIHR5cGVzLnNwbGljZShqLCAxKTtcbiAgICAgICAgaiAtPSAxO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBpZiBubyB0eXBlcyBsZWZ0LCByZXR1cm4gJ3N0cmluZydcbiAgICBpZiAodHlwZXMubGVuZ3RoID09PSAwKSByZXR1cm4gJ3N0cmluZyc7XG4gIH1cblxuICByZXR1cm4gdHlwZXNbMF07XG59XG5cbmZ1bmN0aW9uIGluZmVyQWxsKGRhdGEsIGZpZWxkcykge1xuICBmaWVsZHMgPSBmaWVsZHMgfHwgdXRpbC5rZXlzKGRhdGFbMF0pO1xuICByZXR1cm4gZmllbGRzLnJlZHVjZShmdW5jdGlvbih0eXBlcywgZikge1xuICAgIHR5cGVzW2ZdID0gaW5mZXIoZGF0YSwgZik7XG4gICAgcmV0dXJuIHR5cGVzO1xuICB9LCB7fSk7XG59XG5cbnR5cGUuYW5ub3RhdGlvbiA9IGFubm90YXRpb247XG50eXBlLmFsbCA9IHR5cGVBbGw7XG50eXBlLmluZmVyID0gaW5mZXI7XG50eXBlLmluZmVyQWxsID0gaW5mZXJBbGw7XG50eXBlLnBhcnNlcnMgPSBQQVJTRVJTO1xubW9kdWxlLmV4cG9ydHMgPSB0eXBlOyIsInZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG5cbnZhciBkbCA9IHtcbiAgdmVyc2lvbjogICAgJzEuNC42JyxcbiAgbG9hZDogICAgICAgcmVxdWlyZSgnLi9pbXBvcnQvbG9hZCcpLFxuICByZWFkOiAgICAgICByZXF1aXJlKCcuL2ltcG9ydC9yZWFkJyksXG4gIHR5cGU6ICAgICAgIHJlcXVpcmUoJy4vaW1wb3J0L3R5cGUnKSxcbiAgQWdncmVnYXRvcjogcmVxdWlyZSgnLi9hZ2dyZWdhdGUvYWdncmVnYXRvcicpLFxuICBncm91cGJ5OiAgICByZXF1aXJlKCcuL2FnZ3JlZ2F0ZS9ncm91cGJ5JyksXG4gIGJpbnM6ICAgICAgIHJlcXVpcmUoJy4vYmlucy9iaW5zJyksXG4gICRiaW46ICAgICAgIHJlcXVpcmUoJy4vYmlucy9oaXN0b2dyYW0nKS4kYmluLFxuICBoaXN0b2dyYW06ICByZXF1aXJlKCcuL2JpbnMvaGlzdG9ncmFtJykuaGlzdG9ncmFtLFxuICBmb3JtYXQ6ICAgICByZXF1aXJlKCcuL2Zvcm1hdCcpLFxuICBwcmludDogICAgICByZXF1aXJlKCcuL3ByaW50JyksXG4gIHRlbXBsYXRlOiAgIHJlcXVpcmUoJy4vdGVtcGxhdGUnKSxcbiAgdGltZTogICAgICAgcmVxdWlyZSgnLi90aW1lJylcbn07XG5cbnV0aWwuZXh0ZW5kKGRsLCB1dGlsKTtcbnV0aWwuZXh0ZW5kKGRsLCByZXF1aXJlKCcuL2dlbmVyYXRlJykpO1xudXRpbC5leHRlbmQoZGwsIHJlcXVpcmUoJy4vc3RhdHMnKSk7XG51dGlsLmV4dGVuZChkbCwgcmVxdWlyZSgnLi9pbXBvcnQvcmVhZGVycycpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBkbDsiLCJ2YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xudmFyIHR5cGUgPSByZXF1aXJlKCcuL2ltcG9ydC90eXBlJyk7XG52YXIgc3RhdHMgPSByZXF1aXJlKCcuL3N0YXRzJyk7XG52YXIgdGVtcGxhdGUgPSByZXF1aXJlKCcuL3RlbXBsYXRlJyk7XG5cbnZhciBGTVQgPSB7XG4gICdkYXRlJzogICAgJ3x0aW1lOlwiJW0vJWQvJVkgJUg6JU06JVNcIicsXG4gICdudW1iZXInOiAgJ3xudW1iZXI6XCIuNGZcIicsXG4gICdpbnRlZ2VyJzogJ3xudW1iZXI6XCJkXCInXG59O1xuXG52YXIgUE9TID0ge1xuICAnbnVtYmVyJzogICdsZWZ0JyxcbiAgJ2ludGVnZXInOiAnbGVmdCdcbn07XG5cbm1vZHVsZS5leHBvcnRzLnRhYmxlID0gZnVuY3Rpb24oZGF0YSwgb3B0KSB7XG4gIG9wdCA9IHV0aWwuZXh0ZW5kKHtzZXBhcmF0b3I6JyAnLCBtaW53aWR0aDogOCwgbWF4d2lkdGg6IDE1fSwgb3B0KTtcbiAgdmFyIGZpZWxkcyA9IG9wdC5maWVsZHMgfHwgdXRpbC5rZXlzKGRhdGFbMF0pLFxuICAgICAgdHlwZXMgPSB0eXBlLmFsbChkYXRhKTtcblxuICBpZiAob3B0LnN0YXJ0IHx8IG9wdC5saW1pdCkge1xuICAgIHZhciBhID0gb3B0LnN0YXJ0IHx8IDAsXG4gICAgICAgIGIgPSBvcHQubGltaXQgPyBhICsgb3B0LmxpbWl0IDogZGF0YS5sZW5ndGg7XG4gICAgZGF0YSA9IGRhdGEuc2xpY2UoYSwgYik7XG4gIH1cblxuICAvLyBkZXRlcm1pbmUgY2hhciB3aWR0aCBvZiBmaWVsZHNcbiAgdmFyIGxlbnMgPSBmaWVsZHMubWFwKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgZm9ybWF0ID0gRk1UW3R5cGVzW25hbWVdXSB8fCAnJyxcbiAgICAgICAgdCA9IHRlbXBsYXRlKCd7eycgKyBuYW1lICsgZm9ybWF0ICsgJ319JyksXG4gICAgICAgIGwgPSBzdGF0cy5tYXgoZGF0YSwgZnVuY3Rpb24oeCkgeyByZXR1cm4gdCh4KS5sZW5ndGg7IH0pO1xuICAgIGwgPSBNYXRoLm1heChNYXRoLm1pbihuYW1lLmxlbmd0aCwgb3B0Lm1pbndpZHRoKSwgbCk7XG4gICAgcmV0dXJuIG9wdC5tYXh3aWR0aCA+IDAgPyBNYXRoLm1pbihsLCBvcHQubWF4d2lkdGgpIDogbDtcbiAgfSk7XG5cbiAgLy8gcHJpbnQgaGVhZGVyIHJvd1xuICB2YXIgaGVhZCA9IGZpZWxkcy5tYXAoZnVuY3Rpb24obmFtZSwgaSkge1xuICAgIHJldHVybiB1dGlsLnRydW5jYXRlKHV0aWwucGFkKG5hbWUsIGxlbnNbaV0sICdjZW50ZXInKSwgbGVuc1tpXSk7XG4gIH0pLmpvaW4ob3B0LnNlcGFyYXRvcik7XG5cbiAgLy8gYnVpbGQgdGVtcGxhdGUgZnVuY3Rpb24gZm9yIGVhY2ggcm93XG4gIHZhciB0bXBsID0gdGVtcGxhdGUoZmllbGRzLm1hcChmdW5jdGlvbihuYW1lLCBpKSB7XG4gICAgcmV0dXJuICd7eycgK1xuICAgICAgbmFtZSArXG4gICAgICAoRk1UW3R5cGVzW25hbWVdXSB8fCAnJykgK1xuICAgICAgKCd8cGFkOicgKyBsZW5zW2ldICsgJywnICsgKFBPU1t0eXBlc1tuYW1lXV0gfHwgJ3JpZ2h0JykpICtcbiAgICAgICgnfHRydW5jYXRlOicgKyBsZW5zW2ldKSArXG4gICAgJ319JztcbiAgfSkuam9pbihvcHQuc2VwYXJhdG9yKSk7XG5cbiAgLy8gcHJpbnQgdGFibGVcbiAgcmV0dXJuIGhlYWQgKyBcIlxcblwiICsgZGF0YS5tYXAodG1wbCkuam9pbignXFxuJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5zdW1tYXJ5ID0gZnVuY3Rpb24ocykge1xuICBzID0gcyA/IHMuX19zdW1tYXJ5X18gPyBzIDogc3RhdHMuc3VtbWFyeShzKSA6IHRoaXM7XG4gIHZhciBzdHIgPSBbXSwgaSwgbjtcbiAgZm9yIChpPTAsIG49cy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgc3RyLnB1c2goJy0tICcgKyBzW2ldLmZpZWxkICsgJyAtLScpO1xuICAgIGlmIChzW2ldLnR5cGUgPT09ICdzdHJpbmcnIHx8IHNbaV0uZGlzdGluY3QgPCAxMCkge1xuICAgICAgc3RyLnB1c2gocHJpbnRDYXRlZ29yaWNhbFByb2ZpbGUoc1tpXSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIucHVzaChwcmludFF1YW50aXRhdGl2ZVByb2ZpbGUoc1tpXSkpO1xuICAgIH1cbiAgICBzdHIucHVzaCgnJyk7XG4gIH1cbiAgcmV0dXJuIHN0ci5qb2luKCdcXG4nKTtcbn07XG5cbmZ1bmN0aW9uIHByaW50UXVhbnRpdGF0aXZlUHJvZmlsZShwKSB7XG4gIHJldHVybiBbXG4gICAgJ3ZhbGlkOiAgICAnICsgcC52YWxpZCxcbiAgICAnbWlzc2luZzogICcgKyBwLm1pc3NpbmcsXG4gICAgJ2Rpc3RpbmN0OiAnICsgcC5kaXN0aW5jdCxcbiAgICAnbWluOiAgICAgICcgKyBwLm1pbixcbiAgICAnbWF4OiAgICAgICcgKyBwLm1heCxcbiAgICAnbWVkaWFuOiAgICcgKyBwLm1lZGlhbixcbiAgICAnbWVhbjogICAgICcgKyBwLm1lYW4sXG4gICAgJ3N0ZGV2OiAgICAnICsgcC5zdGRldixcbiAgICAnbW9kZXNrZXc6ICcgKyBwLm1vZGVza2V3XG4gIF0uam9pbignXFxuJyk7XG59XG5cbmZ1bmN0aW9uIHByaW50Q2F0ZWdvcmljYWxQcm9maWxlKHApIHtcbiAgdmFyIGxpc3QgPSBbXG4gICAgJ3ZhbGlkOiAgICAnICsgcC52YWxpZCxcbiAgICAnbWlzc2luZzogICcgKyBwLm1pc3NpbmcsXG4gICAgJ2Rpc3RpbmN0OiAnICsgcC5kaXN0aW5jdCxcbiAgICAndG9wIHZhbHVlczogJ1xuICBdO1xuICB2YXIgdSA9IHAudW5pcXVlO1xuICB2YXIgdG9wID0gdXRpbC5rZXlzKHUpXG4gICAgLnNvcnQoZnVuY3Rpb24oYSxiKSB7IHJldHVybiB1W2JdIC0gdVthXTsgfSlcbiAgICAuc2xpY2UoMCwgNilcbiAgICAubWFwKGZ1bmN0aW9uKHYpIHsgcmV0dXJuICcgXFwnJyArIHYgKyAnXFwnICgnICsgdVt2XSArICcpJzsgfSk7XG4gIHJldHVybiBsaXN0LmNvbmNhdCh0b3ApLmpvaW4oJ1xcbicpO1xufSIsInZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG52YXIgdHlwZSA9IHJlcXVpcmUoJy4vaW1wb3J0L3R5cGUnKTtcbnZhciBnZW4gPSByZXF1aXJlKCcuL2dlbmVyYXRlJyk7XG52YXIgc3RhdHMgPSB7fTtcblxuLy8gQ29sbGVjdCB1bmlxdWUgdmFsdWVzLlxuLy8gT3V0cHV0OiBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzLCBpbiBmaXJzdC1vYnNlcnZlZCBvcmRlclxuc3RhdHMudW5pcXVlID0gZnVuY3Rpb24odmFsdWVzLCBmLCByZXN1bHRzKSB7XG4gIGYgPSB1dGlsLiQoZik7XG4gIHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuICB2YXIgdSA9IHt9LCB2LCBpLCBuO1xuICBmb3IgKGk9MCwgbj12YWx1ZXMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgIGlmICh2IGluIHUpIGNvbnRpbnVlO1xuICAgIHVbdl0gPSAxO1xuICAgIHJlc3VsdHMucHVzaCh2KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0cztcbn07XG5cbi8vIFJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dCBhcnJheS5cbnN0YXRzLmNvdW50ID0gZnVuY3Rpb24odmFsdWVzKSB7XG4gIHJldHVybiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aCB8fCAwO1xufTtcblxuLy8gQ291bnQgdGhlIG51bWJlciBvZiBub24tbnVsbCwgbm9uLXVuZGVmaW5lZCwgbm9uLU5hTiB2YWx1ZXMuXG5zdGF0cy5jb3VudC52YWxpZCA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICBmID0gdXRpbC4kKGYpO1xuICB2YXIgdiwgaSwgbiwgdmFsaWQgPSAwO1xuICBmb3IgKGk9MCwgbj12YWx1ZXMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgIGlmICh1dGlsLmlzVmFsaWQodikpIHZhbGlkICs9IDE7XG4gIH1cbiAgcmV0dXJuIHZhbGlkO1xufTtcblxuLy8gQ291bnQgdGhlIG51bWJlciBvZiBudWxsIG9yIHVuZGVmaW5lZCB2YWx1ZXMuXG5zdGF0cy5jb3VudC5taXNzaW5nID0gZnVuY3Rpb24odmFsdWVzLCBmKSB7XG4gIGYgPSB1dGlsLiQoZik7XG4gIHZhciB2LCBpLCBuLCBjb3VudCA9IDA7XG4gIGZvciAoaT0wLCBuPXZhbHVlcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgdiA9IGYgPyBmKHZhbHVlc1tpXSkgOiB2YWx1ZXNbaV07XG4gICAgaWYgKHYgPT0gbnVsbCkgY291bnQgKz0gMTtcbiAgfVxuICByZXR1cm4gY291bnQ7XG59O1xuXG4vLyBDb3VudCB0aGUgbnVtYmVyIG9mIGRpc3RpbmN0IHZhbHVlcy5cbi8vIE51bGwsIHVuZGVmaW5lZCBhbmQgTmFOIGFyZSBlYWNoIGNvbnNpZGVyZWQgZGlzdGluY3QgdmFsdWVzLlxuc3RhdHMuY291bnQuZGlzdGluY3QgPSBmdW5jdGlvbih2YWx1ZXMsIGYpIHtcbiAgZiA9IHV0aWwuJChmKTtcbiAgdmFyIHUgPSB7fSwgdiwgaSwgbiwgY291bnQgPSAwO1xuICBmb3IgKGk9MCwgbj12YWx1ZXMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgIGlmICh2IGluIHUpIGNvbnRpbnVlO1xuICAgIHVbdl0gPSAxO1xuICAgIGNvdW50ICs9IDE7XG4gIH1cbiAgcmV0dXJuIGNvdW50O1xufTtcblxuLy8gQ29uc3RydWN0IGEgbWFwIGZyb20gZGlzdGluY3QgdmFsdWVzIHRvIG9jY3VycmVuY2UgY291bnRzLlxuc3RhdHMuY291bnQubWFwID0gZnVuY3Rpb24odmFsdWVzLCBmKSB7XG4gIGYgPSB1dGlsLiQoZik7XG4gIHZhciBtYXAgPSB7fSwgdiwgaSwgbjtcbiAgZm9yIChpPTAsIG49dmFsdWVzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICB2ID0gZiA/IGYodmFsdWVzW2ldKSA6IHZhbHVlc1tpXTtcbiAgICBtYXBbdl0gPSAodiBpbiBtYXApID8gbWFwW3ZdICsgMSA6IDE7XG4gIH1cbiAgcmV0dXJuIG1hcDtcbn07XG5cbi8vIENvbXB1dGUgdGhlIG1lZGlhbiBvZiBhbiBhcnJheSBvZiBudW1iZXJzLlxuc3RhdHMubWVkaWFuID0gZnVuY3Rpb24odmFsdWVzLCBmKSB7XG4gIGlmIChmKSB2YWx1ZXMgPSB2YWx1ZXMubWFwKHV0aWwuJChmKSk7XG4gIHZhbHVlcyA9IHZhbHVlcy5maWx0ZXIodXRpbC5pc1ZhbGlkKS5zb3J0KHV0aWwuY21wKTtcbiAgcmV0dXJuIHN0YXRzLnF1YW50aWxlKHZhbHVlcywgMC41KTtcbn07XG5cbi8vIENvbXB1dGVzIHRoZSBxdWFydGlsZSBib3VuZGFyaWVzIG9mIGFuIGFycmF5IG9mIG51bWJlcnMuXG5zdGF0cy5xdWFydGlsZSA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICBpZiAoZikgdmFsdWVzID0gdmFsdWVzLm1hcCh1dGlsLiQoZikpO1xuICB2YWx1ZXMgPSB2YWx1ZXMuZmlsdGVyKHV0aWwuaXNWYWxpZCkuc29ydCh1dGlsLmNtcCk7XG4gIHZhciBxID0gc3RhdHMucXVhbnRpbGU7XG4gIHJldHVybiBbcSh2YWx1ZXMsIDAuMjUpLCBxKHZhbHVlcywgMC41MCksIHEodmFsdWVzLCAwLjc1KV07XG59O1xuXG4vLyBDb21wdXRlIHRoZSBxdWFudGlsZSBvZiBhIHNvcnRlZCBhcnJheSBvZiBudW1iZXJzLlxuLy8gQWRhcHRlZCBmcm9tIHRoZSBEMy5qcyBpbXBsZW1lbnRhdGlvbi5cbnN0YXRzLnF1YW50aWxlID0gZnVuY3Rpb24odmFsdWVzLCBmLCBwKSB7XG4gIGlmIChwID09PSB1bmRlZmluZWQpIHsgcCA9IGY7IGYgPSB1dGlsLmlkZW50aXR5OyB9XG4gIGYgPSB1dGlsLiQoZik7XG4gIHZhciBIID0gKHZhbHVlcy5sZW5ndGggLSAxKSAqIHAgKyAxLFxuICAgICAgaCA9IE1hdGguZmxvb3IoSCksXG4gICAgICB2ID0gK2YodmFsdWVzW2ggLSAxXSksXG4gICAgICBlID0gSCAtIGg7XG4gIHJldHVybiBlID8gdiArIGUgKiAoZih2YWx1ZXNbaF0pIC0gdikgOiB2O1xufTtcblxuLy8gQ29tcHV0ZSB0aGUgc3VtIG9mIGFuIGFycmF5IG9mIG51bWJlcnMuXG5zdGF0cy5zdW0gPSBmdW5jdGlvbih2YWx1ZXMsIGYpIHtcbiAgZiA9IHV0aWwuJChmKTtcbiAgZm9yICh2YXIgc3VtPTAsIGk9MCwgbj12YWx1ZXMubGVuZ3RoLCB2OyBpPG47ICsraSkge1xuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgIGlmICh1dGlsLmlzVmFsaWQodikpIHN1bSArPSB2O1xuICB9XG4gIHJldHVybiBzdW07XG59O1xuXG4vLyBDb21wdXRlIHRoZSBtZWFuIChhdmVyYWdlKSBvZiBhbiBhcnJheSBvZiBudW1iZXJzLlxuc3RhdHMubWVhbiA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICBmID0gdXRpbC4kKGYpO1xuICB2YXIgbWVhbiA9IDAsIGRlbHRhLCBpLCBuLCBjLCB2O1xuICBmb3IgKGk9MCwgYz0wLCBuPXZhbHVlcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgdiA9IGYgPyBmKHZhbHVlc1tpXSkgOiB2YWx1ZXNbaV07XG4gICAgaWYgKHV0aWwuaXNWYWxpZCh2KSkge1xuICAgICAgZGVsdGEgPSB2IC0gbWVhbjtcbiAgICAgIG1lYW4gPSBtZWFuICsgZGVsdGEgLyAoKytjKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1lYW47XG59O1xuXG4vLyBDb21wdXRlIHRoZSBzYW1wbGUgdmFyaWFuY2Ugb2YgYW4gYXJyYXkgb2YgbnVtYmVycy5cbnN0YXRzLnZhcmlhbmNlID0gZnVuY3Rpb24odmFsdWVzLCBmKSB7XG4gIGYgPSB1dGlsLiQoZik7XG4gIGlmICghdXRpbC5pc0FycmF5KHZhbHVlcykgfHwgdmFsdWVzLmxlbmd0aCA8IDIpIHJldHVybiAwO1xuICB2YXIgbWVhbiA9IDAsIE0yID0gMCwgZGVsdGEsIGksIGMsIHY7XG4gIGZvciAoaT0wLCBjPTA7IGk8dmFsdWVzLmxlbmd0aDsgKytpKSB7XG4gICAgdiA9IGYgPyBmKHZhbHVlc1tpXSkgOiB2YWx1ZXNbaV07XG4gICAgaWYgKHV0aWwuaXNWYWxpZCh2KSkge1xuICAgICAgZGVsdGEgPSB2IC0gbWVhbjtcbiAgICAgIG1lYW4gPSBtZWFuICsgZGVsdGEgLyAoKytjKTtcbiAgICAgIE0yID0gTTIgKyBkZWx0YSAqICh2IC0gbWVhbik7XG4gICAgfVxuICB9XG4gIE0yID0gTTIgLyAoYyAtIDEpO1xuICByZXR1cm4gTTI7XG59O1xuXG4vLyBDb21wdXRlIHRoZSBzYW1wbGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIGFuIGFycmF5IG9mIG51bWJlcnMuXG5zdGF0cy5zdGRldiA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICByZXR1cm4gTWF0aC5zcXJ0KHN0YXRzLnZhcmlhbmNlKHZhbHVlcywgZikpO1xufTtcblxuLy8gQ29tcHV0ZSB0aGUgUGVhcnNvbiBtb2RlIHNrZXduZXNzICgobWVkaWFuLW1lYW4pL3N0ZGV2KSBvZiBhbiBhcnJheSBvZiBudW1iZXJzLlxuc3RhdHMubW9kZXNrZXcgPSBmdW5jdGlvbih2YWx1ZXMsIGYpIHtcbiAgdmFyIGF2ZyA9IHN0YXRzLm1lYW4odmFsdWVzLCBmKSxcbiAgICAgIG1lZCA9IHN0YXRzLm1lZGlhbih2YWx1ZXMsIGYpLFxuICAgICAgc3RkID0gc3RhdHMuc3RkZXYodmFsdWVzLCBmKTtcbiAgcmV0dXJuIHN0ZCA9PT0gMCA/IDAgOiAoYXZnIC0gbWVkKSAvIHN0ZDtcbn07XG5cbi8vIEZpbmQgdGhlIG1pbmltdW0gdmFsdWUgaW4gYW4gYXJyYXkuXG5zdGF0cy5taW4gPSBmdW5jdGlvbih2YWx1ZXMsIGYpIHtcbiAgcmV0dXJuIHN0YXRzLmV4dGVudCh2YWx1ZXMsIGYpWzBdO1xufTtcblxuLy8gRmluZCB0aGUgbWF4aW11bSB2YWx1ZSBpbiBhbiBhcnJheS5cbnN0YXRzLm1heCA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICByZXR1cm4gc3RhdHMuZXh0ZW50KHZhbHVlcywgZilbMV07XG59O1xuXG4vLyBGaW5kIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIG9mIGFuIGFycmF5IG9mIHZhbHVlcy5cbnN0YXRzLmV4dGVudCA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICBmID0gdXRpbC4kKGYpO1xuICB2YXIgYSwgYiwgdiwgaSwgbiA9IHZhbHVlcy5sZW5ndGg7XG4gIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgIGlmICh1dGlsLmlzVmFsaWQodikpIHsgYSA9IGIgPSB2OyBicmVhazsgfVxuICB9XG4gIGZvciAoOyBpPG47ICsraSkge1xuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgIGlmICh1dGlsLmlzVmFsaWQodikpIHtcbiAgICAgIGlmICh2IDwgYSkgYSA9IHY7XG4gICAgICBpZiAodiA+IGIpIGIgPSB2O1xuICAgIH1cbiAgfVxuICByZXR1cm4gW2EsIGJdO1xufTtcblxuLy8gRmluZCB0aGUgaW50ZWdlciBpbmRpY2VzIG9mIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlcy5cbnN0YXRzLmV4dGVudC5pbmRleCA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICBmID0gdXRpbC4kKGYpO1xuICB2YXIgeCA9IC0xLCB5ID0gLTEsIGEsIGIsIHYsIGksIG4gPSB2YWx1ZXMubGVuZ3RoO1xuICBmb3IgKGk9MDsgaTxuOyArK2kpIHtcbiAgICB2ID0gZiA/IGYodmFsdWVzW2ldKSA6IHZhbHVlc1tpXTtcbiAgICBpZiAodXRpbC5pc1ZhbGlkKHYpKSB7IGEgPSBiID0gdjsgeCA9IHkgPSBpOyBicmVhazsgfVxuICB9XG4gIGZvciAoOyBpPG47ICsraSkge1xuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgIGlmICh1dGlsLmlzVmFsaWQodikpIHtcbiAgICAgIGlmICh2IDwgYSkgeyBhID0gdjsgeCA9IGk7IH1cbiAgICAgIGlmICh2ID4gYikgeyBiID0gdjsgeSA9IGk7IH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIFt4LCB5XTtcbn07XG5cbi8vIENvbXB1dGUgdGhlIGRvdCBwcm9kdWN0IG9mIHR3byBhcnJheXMgb2YgbnVtYmVycy5cbnN0YXRzLmRvdCA9IGZ1bmN0aW9uKHZhbHVlcywgYSwgYikge1xuICB2YXIgc3VtID0gMCwgaSwgdjtcbiAgaWYgKCFiKSB7XG4gICAgaWYgKHZhbHVlcy5sZW5ndGggIT09IGEubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBFcnJvcignQXJyYXkgbGVuZ3RocyBtdXN0IG1hdGNoLicpO1xuICAgIH1cbiAgICBmb3IgKGk9MDsgaTx2YWx1ZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHYgPSB2YWx1ZXNbaV0gKiBhW2ldO1xuICAgICAgaWYgKHYgPT09IHYpIHN1bSArPSB2O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBhID0gdXRpbC4kKGEpO1xuICAgIGIgPSB1dGlsLiQoYik7XG4gICAgZm9yIChpPTA7IGk8dmFsdWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICB2ID0gYSh2YWx1ZXNbaV0pICogYih2YWx1ZXNbaV0pO1xuICAgICAgaWYgKHYgPT09IHYpIHN1bSArPSB2O1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3VtO1xufTtcblxuLy8gQ29tcHV0ZSBhc2NlbmRpbmcgcmFuayBzY29yZXMgZm9yIGFuIGFycmF5IG9mIHZhbHVlcy5cbi8vIFRpZXMgYXJlIGFzc2lnbmVkIHRoZWlyIGNvbGxlY3RpdmUgbWVhbiByYW5rLlxuc3RhdHMucmFuayA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICBmID0gdXRpbC4kKGYpIHx8IHV0aWwuaWRlbnRpdHk7XG4gIHZhciBhID0gdmFsdWVzLm1hcChmdW5jdGlvbih2LCBpKSB7XG4gICAgICByZXR1cm4ge2lkeDogaSwgdmFsOiBmKHYpfTtcbiAgICB9KVxuICAgIC5zb3J0KHV0aWwuY29tcGFyYXRvcigndmFsJykpO1xuXG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgIHIgPSBBcnJheShuKSxcbiAgICAgIHRpZSA9IC0xLCBwID0ge30sIGksIHYsIG11O1xuXG4gIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgIHYgPSBhW2ldLnZhbDtcbiAgICBpZiAodGllIDwgMCAmJiBwID09PSB2KSB7XG4gICAgICB0aWUgPSBpIC0gMTtcbiAgICB9IGVsc2UgaWYgKHRpZSA+IC0xICYmIHAgIT09IHYpIHtcbiAgICAgIG11ID0gMSArIChpLTEgKyB0aWUpIC8gMjtcbiAgICAgIGZvciAoOyB0aWU8aTsgKyt0aWUpIHJbYVt0aWVdLmlkeF0gPSBtdTtcbiAgICAgIHRpZSA9IC0xO1xuICAgIH1cbiAgICByW2FbaV0uaWR4XSA9IGkgKyAxO1xuICAgIHAgPSB2O1xuICB9XG5cbiAgaWYgKHRpZSA+IC0xKSB7XG4gICAgbXUgPSAxICsgKG4tMSArIHRpZSkgLyAyO1xuICAgIGZvciAoOyB0aWU8bjsgKyt0aWUpIHJbYVt0aWVdLmlkeF0gPSBtdTtcbiAgfVxuXG4gIHJldHVybiByO1xufTtcblxuLy8gQ29tcHV0ZSB0aGUgc2FtcGxlIFBlYXJzb24gcHJvZHVjdC1tb21lbnQgY29ycmVsYXRpb24gb2YgdHdvIGFycmF5cyBvZiBudW1iZXJzLlxuc3RhdHMuY29yID0gZnVuY3Rpb24odmFsdWVzLCBhLCBiKSB7XG4gIHZhciBmbiA9IGI7XG4gIGIgPSBmbiA/IHZhbHVlcy5tYXAodXRpbC4kKGIpKSA6IGE7XG4gIGEgPSBmbiA/IHZhbHVlcy5tYXAodXRpbC4kKGEpKSA6IHZhbHVlcztcblxuICB2YXIgZG90ID0gc3RhdHMuZG90KGEsIGIpLFxuICAgICAgbXVhID0gc3RhdHMubWVhbihhKSxcbiAgICAgIG11YiA9IHN0YXRzLm1lYW4oYiksXG4gICAgICBzZGEgPSBzdGF0cy5zdGRldihhKSxcbiAgICAgIHNkYiA9IHN0YXRzLnN0ZGV2KGIpLFxuICAgICAgbiA9IHZhbHVlcy5sZW5ndGg7XG5cbiAgcmV0dXJuIChkb3QgLSBuKm11YSptdWIpIC8gKChuLTEpICogc2RhICogc2RiKTtcbn07XG5cbi8vIENvbXB1dGUgdGhlIFNwZWFybWFuIHJhbmsgY29ycmVsYXRpb24gb2YgdHdvIGFycmF5cyBvZiB2YWx1ZXMuXG5zdGF0cy5jb3IucmFuayA9IGZ1bmN0aW9uKHZhbHVlcywgYSwgYikge1xuICB2YXIgcmEgPSBiID8gc3RhdHMucmFuayh2YWx1ZXMsIHV0aWwuJChhKSkgOiBzdGF0cy5yYW5rKHZhbHVlcyksXG4gICAgICByYiA9IGIgPyBzdGF0cy5yYW5rKHZhbHVlcywgdXRpbC4kKGIpKSA6IHN0YXRzLnJhbmsoYSksXG4gICAgICBuID0gdmFsdWVzLmxlbmd0aCwgaSwgcywgZDtcblxuICBmb3IgKGk9MCwgcz0wOyBpPG47ICsraSkge1xuICAgIGQgPSByYVtpXSAtIHJiW2ldO1xuICAgIHMgKz0gZCAqIGQ7XG4gIH1cblxuICByZXR1cm4gMSAtIDYqcyAvIChuICogKG4qbi0xKSk7XG59O1xuXG4vLyBDb21wdXRlIHRoZSBkaXN0YW5jZSBjb3JyZWxhdGlvbiBvZiB0d28gYXJyYXlzIG9mIG51bWJlcnMuXG4vLyBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Rpc3RhbmNlX2NvcnJlbGF0aW9uXG5zdGF0cy5jb3IuZGlzdCA9IGZ1bmN0aW9uKHZhbHVlcywgYSwgYikge1xuICB2YXIgWCA9IGIgPyB2YWx1ZXMubWFwKHV0aWwuJChhKSkgOiB2YWx1ZXMsXG4gICAgICBZID0gYiA/IHZhbHVlcy5tYXAodXRpbC4kKGIpKSA6IGE7XG5cbiAgdmFyIEEgPSBzdGF0cy5kaXN0Lm1hdChYKSxcbiAgICAgIEIgPSBzdGF0cy5kaXN0Lm1hdChZKSxcbiAgICAgIG4gPSBBLmxlbmd0aCxcbiAgICAgIGksIGFhLCBiYiwgYWI7XG5cbiAgZm9yIChpPTAsIGFhPTAsIGJiPTAsIGFiPTA7IGk8bjsgKytpKSB7XG4gICAgYWEgKz0gQVtpXSpBW2ldO1xuICAgIGJiICs9IEJbaV0qQltpXTtcbiAgICBhYiArPSBBW2ldKkJbaV07XG4gIH1cblxuICByZXR1cm4gTWF0aC5zcXJ0KGFiIC8gTWF0aC5zcXJ0KGFhKmJiKSk7XG59O1xuXG4vLyBDb21wdXRlIHRoZSB2ZWN0b3IgZGlzdGFuY2UgYmV0d2VlbiB0d28gYXJyYXlzIG9mIG51bWJlcnMuXG4vLyBEZWZhdWx0IGlzIEV1Y2xpZGVhbiAoZXhwPTIpIGRpc3RhbmNlLCBjb25maWd1cmFibGUgdmlhIGV4cCBhcmd1bWVudC5cbnN0YXRzLmRpc3QgPSBmdW5jdGlvbih2YWx1ZXMsIGEsIGIsIGV4cCkge1xuICB2YXIgZiA9IHV0aWwuaXNGdW5jdGlvbihiKSB8fCB1dGlsLmlzU3RyaW5nKGIpLFxuICAgICAgWCA9IHZhbHVlcyxcbiAgICAgIFkgPSBmID8gdmFsdWVzIDogYSxcbiAgICAgIGUgPSBmID8gZXhwIDogYixcbiAgICAgIEwyID0gZSA9PT0gMiB8fCBlID09IG51bGwsXG4gICAgICBuID0gdmFsdWVzLmxlbmd0aCwgcyA9IDAsIGQsIGk7XG4gIGlmIChmKSB7XG4gICAgYSA9IHV0aWwuJChhKTtcbiAgICBiID0gdXRpbC4kKGIpO1xuICB9XG4gIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgIGQgPSBmID8gKGEoWFtpXSktYihZW2ldKSkgOiAoWFtpXS1ZW2ldKTtcbiAgICBzICs9IEwyID8gZCpkIDogTWF0aC5wb3coTWF0aC5hYnMoZCksIGUpO1xuICB9XG4gIHJldHVybiBMMiA/IE1hdGguc3FydChzKSA6IE1hdGgucG93KHMsIDEvZSk7XG59O1xuXG4vLyBDb25zdHJ1Y3QgYSBtZWFuLWNlbnRlcmVkIGRpc3RhbmNlIG1hdHJpeCBmb3IgYW4gYXJyYXkgb2YgbnVtYmVycy5cbnN0YXRzLmRpc3QubWF0ID0gZnVuY3Rpb24oWCkge1xuICB2YXIgbiA9IFgubGVuZ3RoLFxuICAgICAgbSA9IG4qbixcbiAgICAgIEEgPSBBcnJheShtKSxcbiAgICAgIFIgPSBnZW4uemVyb3MobiksXG4gICAgICBNID0gMCwgdiwgaSwgajtcblxuICBmb3IgKGk9MDsgaTxuOyArK2kpIHtcbiAgICBBW2kqbitpXSA9IDA7XG4gICAgZm9yIChqPWkrMTsgajxuOyArK2opIHtcbiAgICAgIEFbaSpuK2pdID0gKHYgPSBNYXRoLmFicyhYW2ldIC0gWFtqXSkpO1xuICAgICAgQVtqKm4raV0gPSB2O1xuICAgICAgUltpXSArPSB2O1xuICAgICAgUltqXSArPSB2O1xuICAgIH1cbiAgfVxuXG4gIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgIE0gKz0gUltpXTtcbiAgICBSW2ldIC89IG47XG4gIH1cbiAgTSAvPSBtO1xuXG4gIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgIGZvciAoaj1pOyBqPG47ICsraikge1xuICAgICAgQVtpKm4ral0gKz0gTSAtIFJbaV0gLSBSW2pdO1xuICAgICAgQVtqKm4raV0gPSBBW2kqbitqXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gQTtcbn07XG5cbi8vIENvbXB1dGUgdGhlIFNoYW5ub24gZW50cm9weSAobG9nIGJhc2UgMikgb2YgYW4gYXJyYXkgb2YgY291bnRzLlxuc3RhdHMuZW50cm9weSA9IGZ1bmN0aW9uKGNvdW50cywgZikge1xuICBmID0gdXRpbC4kKGYpO1xuICB2YXIgaSwgcCwgcyA9IDAsIEggPSAwLCBuID0gY291bnRzLmxlbmd0aDtcbiAgZm9yIChpPTA7IGk8bjsgKytpKSB7XG4gICAgcyArPSAoZiA/IGYoY291bnRzW2ldKSA6IGNvdW50c1tpXSk7XG4gIH1cbiAgaWYgKHMgPT09IDApIHJldHVybiAwO1xuICBmb3IgKGk9MDsgaTxuOyArK2kpIHtcbiAgICBwID0gKGYgPyBmKGNvdW50c1tpXSkgOiBjb3VudHNbaV0pIC8gcztcbiAgICBpZiAocCkgSCArPSBwICogTWF0aC5sb2cocCk7XG4gIH1cbiAgcmV0dXJuIC1IIC8gTWF0aC5MTjI7XG59O1xuXG4vLyBDb21wdXRlIHRoZSBtdXR1YWwgaW5mb3JtYXRpb24gYmV0d2VlbiB0d28gZGlzY3JldGUgdmFyaWFibGVzLlxuLy8gUmV0dXJucyBhbiBhcnJheSBvZiB0aGUgZm9ybSBbTUksIE1JX2Rpc3RhbmNlXSBcbi8vIE1JX2Rpc3RhbmNlIGlzIGRlZmluZWQgYXMgMSAtIEkoYSxiKSAvIEgoYSxiKS5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTXV0dWFsX2luZm9ybWF0aW9uXG5zdGF0cy5tdXR1YWwgPSBmdW5jdGlvbih2YWx1ZXMsIGEsIGIsIGNvdW50cykge1xuICB2YXIgeCA9IGNvdW50cyA/IHZhbHVlcy5tYXAodXRpbC4kKGEpKSA6IHZhbHVlcyxcbiAgICAgIHkgPSBjb3VudHMgPyB2YWx1ZXMubWFwKHV0aWwuJChiKSkgOiBhLFxuICAgICAgeiA9IGNvdW50cyA/IHZhbHVlcy5tYXAodXRpbC4kKGNvdW50cykpIDogYjtcblxuICB2YXIgcHggPSB7fSxcbiAgICAgIHB5ID0ge30sXG4gICAgICBuID0gei5sZW5ndGgsXG4gICAgICBzID0gMCwgSSA9IDAsIEggPSAwLCBwLCB0LCBpO1xuXG4gIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgIHB4W3hbaV1dID0gMDtcbiAgICBweVt5W2ldXSA9IDA7XG4gIH1cblxuICBmb3IgKGk9MDsgaTxuOyArK2kpIHtcbiAgICBweFt4W2ldXSArPSB6W2ldO1xuICAgIHB5W3lbaV1dICs9IHpbaV07XG4gICAgcyArPSB6W2ldO1xuICB9XG5cbiAgdCA9IDEgLyAocyAqIE1hdGguTE4yKTtcbiAgZm9yIChpPTA7IGk8bjsgKytpKSB7XG4gICAgaWYgKHpbaV0gPT09IDApIGNvbnRpbnVlO1xuICAgIHAgPSAocyAqIHpbaV0pIC8gKHB4W3hbaV1dICogcHlbeVtpXV0pO1xuICAgIEkgKz0geltpXSAqIHQgKiBNYXRoLmxvZyhwKTtcbiAgICBIICs9IHpbaV0gKiB0ICogTWF0aC5sb2coeltpXS9zKTtcbiAgfVxuXG4gIHJldHVybiBbSSwgMSArIEkvSF07XG59O1xuXG4vLyBDb21wdXRlIHRoZSBtdXR1YWwgaW5mb3JtYXRpb24gYmV0d2VlbiB0d28gZGlzY3JldGUgdmFyaWFibGVzLlxuc3RhdHMubXV0dWFsLmluZm8gPSBmdW5jdGlvbih2YWx1ZXMsIGEsIGIsIGNvdW50cykge1xuICByZXR1cm4gc3RhdHMubXV0dWFsKHZhbHVlcywgYSwgYiwgY291bnRzKVswXTtcbn07XG5cbi8vIENvbXB1dGUgdGhlIG11dHVhbCBpbmZvcm1hdGlvbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byBkaXNjcmV0ZSB2YXJpYWJsZXMuXG4vLyBNSV9kaXN0YW5jZSBpcyBkZWZpbmVkIGFzIDEgLSBJKGEsYikgLyBIKGEsYikuXG5zdGF0cy5tdXR1YWwuZGlzdCA9IGZ1bmN0aW9uKHZhbHVlcywgYSwgYiwgY291bnRzKSB7XG4gIHJldHVybiBzdGF0cy5tdXR1YWwodmFsdWVzLCBhLCBiLCBjb3VudHMpWzFdO1xufTtcblxuLy8gQ29tcHV0ZSBhIHByb2ZpbGUgb2Ygc3VtbWFyeSBzdGF0aXN0aWNzIGZvciBhIHZhcmlhYmxlLlxuc3RhdHMucHJvZmlsZSA9IGZ1bmN0aW9uKHZhbHVlcywgZikge1xuICB2YXIgbWVhbiA9IDAsXG4gICAgICB2YWxpZCA9IDAsXG4gICAgICBtaXNzaW5nID0gMCxcbiAgICAgIGRpc3RpbmN0ID0gMCxcbiAgICAgIG1pbiA9IG51bGwsXG4gICAgICBtYXggPSBudWxsLFxuICAgICAgTTIgPSAwLFxuICAgICAgdmFscyA9IFtdLFxuICAgICAgdSA9IHt9LCBkZWx0YSwgc2QsIGksIHYsIHg7XG5cbiAgLy8gY29tcHV0ZSBzdW1tYXJ5IHN0YXRzXG4gIGZvciAoaT0wOyBpPHZhbHVlcy5sZW5ndGg7ICsraSkge1xuICAgIHYgPSBmID8gZih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuXG4gICAgLy8gdXBkYXRlIHVuaXF1ZSB2YWx1ZXNcbiAgICB1W3ZdID0gKHYgaW4gdSkgPyB1W3ZdICsgMSA6IChkaXN0aW5jdCArPSAxLCAxKTtcblxuICAgIGlmICh2ID09IG51bGwpIHtcbiAgICAgICsrbWlzc2luZztcbiAgICB9IGVsc2UgaWYgKHV0aWwuaXNWYWxpZCh2KSkge1xuICAgICAgLy8gdXBkYXRlIHN0YXRzXG4gICAgICB4ID0gKHR5cGVvZiB2ID09PSAnc3RyaW5nJykgPyB2Lmxlbmd0aCA6IHY7XG4gICAgICBpZiAobWluPT09bnVsbCB8fCB4IDwgbWluKSBtaW4gPSB4O1xuICAgICAgaWYgKG1heD09PW51bGwgfHwgeCA+IG1heCkgbWF4ID0geDtcbiAgICAgIGRlbHRhID0geCAtIG1lYW47XG4gICAgICBtZWFuID0gbWVhbiArIGRlbHRhIC8gKCsrdmFsaWQpO1xuICAgICAgTTIgPSBNMiArIGRlbHRhICogKHggLSBtZWFuKTtcbiAgICAgIHZhbHMucHVzaCh4KTtcbiAgICB9XG4gIH1cbiAgTTIgPSBNMiAvICh2YWxpZCAtIDEpO1xuICBzZCA9IE1hdGguc3FydChNMik7XG5cbiAgLy8gc29ydCB2YWx1ZXMgZm9yIG1lZGlhbiBhbmQgaXFyXG4gIHZhbHMuc29ydCh1dGlsLmNtcCk7XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAgICAgdHlwZSh2YWx1ZXMsIGYpLFxuICAgIHVuaXF1ZTogICB1LFxuICAgIGNvdW50OiAgICB2YWx1ZXMubGVuZ3RoLFxuICAgIHZhbGlkOiAgICB2YWxpZCxcbiAgICBtaXNzaW5nOiAgbWlzc2luZyxcbiAgICBkaXN0aW5jdDogZGlzdGluY3QsXG4gICAgbWluOiAgICAgIG1pbixcbiAgICBtYXg6ICAgICAgbWF4LFxuICAgIG1lYW46ICAgICBtZWFuLFxuICAgIHN0ZGV2OiAgICBzZCxcbiAgICBtZWRpYW46ICAgKHYgPSBzdGF0cy5xdWFudGlsZSh2YWxzLCAwLjUpKSxcbiAgICBxMTogICAgICAgc3RhdHMucXVhbnRpbGUodmFscywgMC4yNSksXG4gICAgcTM6ICAgICAgIHN0YXRzLnF1YW50aWxlKHZhbHMsIDAuNzUpLFxuICAgIG1vZGVza2V3OiBzZCA9PT0gMCA/IDAgOiAobWVhbiAtIHYpIC8gc2RcbiAgfTtcbn07XG5cbi8vIENvbXB1dGUgcHJvZmlsZXMgZm9yIGFsbCB2YXJpYWJsZXMgaW4gYSBkYXRhIHNldC5cbnN0YXRzLnN1bW1hcnkgPSBmdW5jdGlvbihkYXRhLCBmaWVsZHMpIHtcbiAgZmllbGRzID0gZmllbGRzIHx8IHV0aWwua2V5cyhkYXRhWzBdKTtcbiAgdmFyIHMgPSBmaWVsZHMubWFwKGZ1bmN0aW9uKGYpIHtcbiAgICB2YXIgcCA9IHN0YXRzLnByb2ZpbGUoZGF0YSwgdXRpbC4kKGYpKTtcbiAgICByZXR1cm4gKHAuZmllbGQgPSBmLCBwKTtcbiAgfSk7XG4gIHJldHVybiAocy5fX3N1bW1hcnlfXyA9IHRydWUsIHMpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBzdGF0czsiLCJ2YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpLFxuICAgIGZvcm1hdCA9IHJlcXVpcmUoJy4vZm9ybWF0Jyk7XG5cbnZhciBjb250ZXh0ID0ge1xuICBmb3JtYXRzOiAgICBbXSxcbiAgZm9ybWF0X21hcDoge30sXG4gIHRydW5jYXRlOiAgIHV0aWwudHJ1bmNhdGUsXG4gIHBhZDogICAgICAgIHV0aWwucGFkXG59O1xuXG5mdW5jdGlvbiB0ZW1wbGF0ZSh0ZXh0KSB7XG4gIHZhciBzcmMgPSBzb3VyY2UodGV4dCwgJ2QnKTtcbiAgc3JjID0gJ3ZhciBfX3Q7IHJldHVybiAnICsgc3JjICsgJzsnO1xuXG4gIC8qIGpzaGludCBldmlsOiB0cnVlICovXG4gIHJldHVybiAobmV3IEZ1bmN0aW9uKCdkJywgc3JjKSkuYmluZChjb250ZXh0KTtcbn1cblxudGVtcGxhdGUuc291cmNlID0gc291cmNlO1xudGVtcGxhdGUuY29udGV4dCA9IGNvbnRleHQ7XG5tb2R1bGUuZXhwb3J0cyA9IHRlbXBsYXRlO1xuXG4vLyBDbGVhciBjYWNoZSBvZiBmb3JtYXQgb2JqZWN0cy5cbi8vIFRoaXMgY2FuICpicmVhayogcHJpb3IgdGVtcGxhdGUgZnVuY3Rpb25zLCBzbyBpbnZva2Ugd2l0aCBjYXJlIVxudGVtcGxhdGUuY2xlYXJGb3JtYXRDYWNoZSA9IGZ1bmN0aW9uKCkge1xuICBjb250ZXh0LmZvcm1hdHMgPSBbXTtcbiAgY29udGV4dC5mb3JtYXRfbWFwID0ge307XG59O1xuXG4vLyBHZW5lcmF0ZSBwcm9wZXJ0eSBhY2Nlc3MgY29kZSBmb3IgdXNlIHdpdGhpbiB0ZW1wbGF0ZSBzb3VyY2UuXG4vLyBvYmplY3Q6IHRoZSBuYW1lIG9mIHRoZSBvYmplY3QgKHZhcmlhYmxlKSBjb250YWluaW5nIHRlbXBsYXRlIGRhdGFcbi8vIHByb3BlcnR5OiB0aGUgcHJvcGVydHkgYWNjZXNzIHN0cmluZywgdmVyYmF0aW0gZnJvbSB0ZW1wbGF0ZSB0YWdcbnRlbXBsYXRlLnByb3BlcnR5ID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkge1xuICB2YXIgc3JjID0gdXRpbC5maWVsZChwcm9wZXJ0eSkubWFwKHV0aWwuc3RyKS5qb2luKCddWycpO1xuICByZXR1cm4gb2JqZWN0ICsgJ1snICsgc3JjICsgJ10nO1xufTtcblxuLy8gR2VuZXJhdGUgc291cmNlIGNvZGUgZm9yIGEgdGVtcGxhdGUgZnVuY3Rpb24uXG4vLyB0ZXh0OiB0aGUgdGVtcGxhdGUgdGV4dFxuLy8gdmFyaWFibGU6IHRoZSBuYW1lIG9mIHRoZSBkYXRhIG9iamVjdCB2YXJpYWJsZSAoJ29iaicgYnkgZGVmYXVsdClcbi8vIHByb3BlcnRpZXM6IG9wdGlvbmFsIGhhc2ggZm9yIGNvbGxlY3RpbmcgYWxsIGFjY2Vzc2VkIHByb3BlcnRpZXNcbmZ1bmN0aW9uIHNvdXJjZSh0ZXh0LCB2YXJpYWJsZSwgcHJvcGVydGllcykge1xuICB2YXJpYWJsZSA9IHZhcmlhYmxlIHx8ICdvYmonO1xuICB2YXIgaW5kZXggPSAwO1xuICB2YXIgc3JjID0gJ1xcJyc7XG4gIHZhciByZWdleCA9IHRlbXBsYXRlX3JlO1xuXG4gIC8vIENvbXBpbGUgdGhlIHRlbXBsYXRlIHNvdXJjZSwgZXNjYXBpbmcgc3RyaW5nIGxpdGVyYWxzIGFwcHJvcHJpYXRlbHkuXG4gIHRleHQucmVwbGFjZShyZWdleCwgZnVuY3Rpb24obWF0Y2gsIGludGVycG9sYXRlLCBvZmZzZXQpIHtcbiAgICBzcmMgKz0gdGV4dFxuICAgICAgLnNsaWNlKGluZGV4LCBvZmZzZXQpXG4gICAgICAucmVwbGFjZSh0ZW1wbGF0ZV9lc2NhcGVyLCB0ZW1wbGF0ZV9lc2NhcGVDaGFyKTtcbiAgICBpbmRleCA9IG9mZnNldCArIG1hdGNoLmxlbmd0aDtcblxuICAgIGlmIChpbnRlcnBvbGF0ZSkge1xuICAgICAgc3JjICs9ICdcXCdcXG4rKChfX3Q9KCcgK1xuICAgICAgICB0ZW1wbGF0ZV92YXIoaW50ZXJwb2xhdGUsIHZhcmlhYmxlLCBwcm9wZXJ0aWVzKSArXG4gICAgICAgICcpKT09bnVsbD9cXCdcXCc6X190KStcXG5cXCcnO1xuICAgIH1cblxuICAgIC8vIEFkb2JlIFZNcyBuZWVkIHRoZSBtYXRjaCByZXR1cm5lZCB0byBwcm9kdWNlIHRoZSBjb3JyZWN0IG9mZmVzdC5cbiAgICByZXR1cm4gbWF0Y2g7XG4gIH0pO1xuICByZXR1cm4gc3JjICsgJ1xcJyc7XG59XG5cbmZ1bmN0aW9uIHRlbXBsYXRlX3Zhcih0ZXh0LCB2YXJpYWJsZSwgcHJvcGVydGllcykge1xuICB2YXIgZmlsdGVycyA9IHRleHQubWF0Y2goZmlsdGVyX3JlKTtcbiAgdmFyIHByb3AgPSBmaWx0ZXJzLnNoaWZ0KCkudHJpbSgpO1xuICB2YXIgc3RyaW5nQ2FzdCA9IHRydWU7XG5cbiAgZnVuY3Rpb24gc3RyY2FsbChmbikge1xuICAgIGZuID0gZm4gfHwgJyc7XG4gICAgaWYgKHN0cmluZ0Nhc3QpIHtcbiAgICAgIHN0cmluZ0Nhc3QgPSBmYWxzZTtcbiAgICAgIHNyYyA9ICdTdHJpbmcoJyArIHNyYyArICcpJyArIGZuO1xuICAgIH0gZWxzZSB7XG4gICAgICBzcmMgKz0gZm47XG4gICAgfVxuICAgIHJldHVybiBzcmM7XG4gIH1cblxuICBmdW5jdGlvbiBkYXRlKCkge1xuICAgIHJldHVybiAnKHR5cGVvZiAnICsgc3JjICsgJz09PVwibnVtYmVyXCI/bmV3IERhdGUoJytzcmMrJyk6JytzcmMrJyknO1xuICB9XG5cbiAgZnVuY3Rpb24gbnVtYmVyX2Zvcm1hdChmbXQsIGtleSkge1xuICAgIGEgPSB0ZW1wbGF0ZV9mb3JtYXQoYXJnc1swXSwga2V5LCBmbXQpO1xuICAgIHN0cmluZ0Nhc3QgPSBmYWxzZTtcbiAgICBzcmMgPSAndGhpcy5mb3JtYXRzWycrYSsnXSgnK3NyYysnKSc7XG4gIH1cbiAgXG4gIGZ1bmN0aW9uIHRpbWVfZm9ybWF0KGZtdCwga2V5KSB7XG4gICAgYSA9IHRlbXBsYXRlX2Zvcm1hdChhcmdzWzBdLCBrZXksIGZtdCk7XG4gICAgc3RyaW5nQ2FzdCA9IGZhbHNlO1xuICAgIHNyYyA9ICd0aGlzLmZvcm1hdHNbJythKyddKCcrZGF0ZSgpKycpJztcbiAgfVxuXG4gIGlmIChwcm9wZXJ0aWVzKSBwcm9wZXJ0aWVzW3Byb3BdID0gMTtcbiAgdmFyIHNyYyA9IHRlbXBsYXRlLnByb3BlcnR5KHZhcmlhYmxlLCBwcm9wKTtcblxuICBmb3IgKHZhciBpPTA7IGk8ZmlsdGVycy5sZW5ndGg7ICsraSkge1xuICAgIHZhciBmID0gZmlsdGVyc1tpXSwgYXJncyA9IG51bGwsIHBpZHgsIGEsIGI7XG5cbiAgICBpZiAoKHBpZHg9Zi5pbmRleE9mKCc6JykpID4gMCkge1xuICAgICAgZiA9IGYuc2xpY2UoMCwgcGlkeCk7XG4gICAgICBhcmdzID0gZmlsdGVyc1tpXS5zbGljZShwaWR4KzEpXG4gICAgICAgIC5tYXRjaChhcmdzX3JlKVxuICAgICAgICAubWFwKGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHMudHJpbSgpOyB9KTtcbiAgICB9XG4gICAgZiA9IGYudHJpbSgpO1xuXG4gICAgc3dpdGNoIChmKSB7XG4gICAgICBjYXNlICdsZW5ndGgnOlxuICAgICAgICBzdHJjYWxsKCcubGVuZ3RoJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbG93ZXInOlxuICAgICAgICBzdHJjYWxsKCcudG9Mb3dlckNhc2UoKScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3VwcGVyJzpcbiAgICAgICAgc3RyY2FsbCgnLnRvVXBwZXJDYXNlKCknKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdsb3dlci1sb2NhbGUnOlxuICAgICAgICBzdHJjYWxsKCcudG9Mb2NhbGVMb3dlckNhc2UoKScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3VwcGVyLWxvY2FsZSc6XG4gICAgICAgIHN0cmNhbGwoJy50b0xvY2FsZVVwcGVyQ2FzZSgpJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndHJpbSc6XG4gICAgICAgIHN0cmNhbGwoJy50cmltKCknKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgYSA9IHV0aWwubnVtYmVyKGFyZ3NbMF0pO1xuICAgICAgICBzdHJjYWxsKCcuc2xpY2UoMCwnICsgYSArICcpJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICBhID0gdXRpbC5udW1iZXIoYXJnc1swXSk7XG4gICAgICAgIHN0cmNhbGwoJy5zbGljZSgtJyArIGEgKycpJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWlkJzpcbiAgICAgICAgYSA9IHV0aWwubnVtYmVyKGFyZ3NbMF0pO1xuICAgICAgICBiID0gYSArIHV0aWwubnVtYmVyKGFyZ3NbMV0pO1xuICAgICAgICBzdHJjYWxsKCcuc2xpY2UoKycrYSsnLCcrYisnKScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3NsaWNlJzpcbiAgICAgICAgYSA9IHV0aWwubnVtYmVyKGFyZ3NbMF0pO1xuICAgICAgICBzdHJjYWxsKCcuc2xpY2UoJysgYSArXG4gICAgICAgICAgKGFyZ3MubGVuZ3RoID4gMSA/ICcsJyArIHV0aWwubnVtYmVyKGFyZ3NbMV0pIDogJycpICtcbiAgICAgICAgICAnKScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RydW5jYXRlJzpcbiAgICAgICAgYSA9IHV0aWwubnVtYmVyKGFyZ3NbMF0pO1xuICAgICAgICBiID0gYXJnc1sxXTtcbiAgICAgICAgYiA9IChiIT09J2xlZnQnICYmIGIhPT0nbWlkZGxlJyAmJiBiIT09J2NlbnRlcicpID8gJ3JpZ2h0JyA6IGI7XG4gICAgICAgIHNyYyA9ICd0aGlzLnRydW5jYXRlKCcgKyBzdHJjYWxsKCkgKyAnLCcgKyBhICsgJyxcXCcnICsgYiArICdcXCcpJztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdwYWQnOlxuICAgICAgICBhID0gdXRpbC5udW1iZXIoYXJnc1swXSk7XG4gICAgICAgIGIgPSBhcmdzWzFdO1xuICAgICAgICBiID0gKGIhPT0nbGVmdCcgJiYgYiE9PSdtaWRkbGUnICYmIGIhPT0nY2VudGVyJykgPyAncmlnaHQnIDogYjtcbiAgICAgICAgc3JjID0gJ3RoaXMucGFkKCcgKyBzdHJjYWxsKCkgKyAnLCcgKyBhICsgJyxcXCcnICsgYiArICdcXCcpJztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICBudW1iZXJfZm9ybWF0KGZvcm1hdC5udW1iZXIsICdudW1iZXInKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0aW1lJzpcbiAgICAgICAgdGltZV9mb3JtYXQoZm9ybWF0LnRpbWUsICd0aW1lJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndGltZS11dGMnOlxuICAgICAgICB0aW1lX2Zvcm1hdChmb3JtYXQudXRjLCAndGltZS11dGMnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBFcnJvcignVW5yZWNvZ25pemVkIHRlbXBsYXRlIGZpbHRlcjogJyArIGYpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzcmM7XG59XG5cbnZhciB0ZW1wbGF0ZV9yZSA9IC9cXHtcXHsoLis/KVxcfVxcfXwkL2csXG4gICAgZmlsdGVyX3JlID0gLyg/OlwiW15cIl0qXCJ8XFwnW15cXCddKlxcJ3xbXlxcfFwiXSt8W15cXHxcXCddKykrL2csXG4gICAgYXJnc19yZSA9IC8oPzpcIlteXCJdKlwifFxcJ1teXFwnXSpcXCd8W14sXCJdK3xbXixcXCddKykrL2c7XG5cbi8vIENlcnRhaW4gY2hhcmFjdGVycyBuZWVkIHRvIGJlIGVzY2FwZWQgc28gdGhhdCB0aGV5IGNhbiBiZSBwdXQgaW50byBhXG4vLyBzdHJpbmcgbGl0ZXJhbC5cbnZhciB0ZW1wbGF0ZV9lc2NhcGVzID0ge1xuICAnXFwnJzogICAgICdcXCcnLFxuICAnXFxcXCc6ICAgICAnXFxcXCcsXG4gICdcXHInOiAgICAgJ3InLFxuICAnXFxuJzogICAgICduJyxcbiAgJ1xcdTIwMjgnOiAndTIwMjgnLFxuICAnXFx1MjAyOSc6ICd1MjAyOSdcbn07XG5cbnZhciB0ZW1wbGF0ZV9lc2NhcGVyID0gL1xcXFx8J3xcXHJ8XFxufFxcdTIwMjh8XFx1MjAyOS9nO1xuXG5mdW5jdGlvbiB0ZW1wbGF0ZV9lc2NhcGVDaGFyKG1hdGNoKSB7XG4gIHJldHVybiAnXFxcXCcgKyB0ZW1wbGF0ZV9lc2NhcGVzW21hdGNoXTtcbn1cblxuZnVuY3Rpb24gdGVtcGxhdGVfZm9ybWF0KHBhdHRlcm4sIGtleSwgZm10KSB7XG4gIGlmICgocGF0dGVyblswXSA9PT0gJ1xcJycgJiYgcGF0dGVybltwYXR0ZXJuLmxlbmd0aC0xXSA9PT0gJ1xcJycpIHx8XG4gICAgICAocGF0dGVyblswXSA9PT0gJ1wiJyAgJiYgcGF0dGVybltwYXR0ZXJuLmxlbmd0aC0xXSA9PT0gJ1wiJykpIHtcbiAgICBwYXR0ZXJuID0gcGF0dGVybi5zbGljZSgxLCAtMSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Zvcm1hdCBwYXR0ZXJuIG11c3QgYmUgcXVvdGVkOiAnICsgcGF0dGVybik7XG4gIH1cbiAga2V5ID0ga2V5ICsgJzonICsgcGF0dGVybjtcbiAgaWYgKCFjb250ZXh0LmZvcm1hdF9tYXBba2V5XSkge1xuICAgIHZhciBmID0gZm10KHBhdHRlcm4pO1xuICAgIHZhciBpID0gY29udGV4dC5mb3JtYXRzLmxlbmd0aDtcbiAgICBjb250ZXh0LmZvcm1hdHMucHVzaChmKTtcbiAgICBjb250ZXh0LmZvcm1hdF9tYXBba2V5XSA9IGk7XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQuZm9ybWF0X21hcFtrZXldO1xufVxuIiwidmFyIGQzX3RpbWUgPSByZXF1aXJlKCdkMy10aW1lJyk7XG5cbnZhciB0ZW1wRGF0ZSA9IG5ldyBEYXRlKCksXG4gICAgYmFzZURhdGUgPSBuZXcgRGF0ZSgwLCAwLCAxKS5zZXRGdWxsWWVhcigwKSwgLy8gSmFuIDEsIDAgQURcbiAgICB1dGNCYXNlRGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDKDAsIDAsIDEpKS5zZXRVVENGdWxsWWVhcigwKTtcblxuZnVuY3Rpb24gZGF0ZShkKSB7XG4gIHJldHVybiAodGVtcERhdGUuc2V0VGltZSgrZCksIHRlbXBEYXRlKTtcbn1cblxuLy8gY3JlYXRlIGEgdGltZSB1bml0IGVudHJ5XG5mdW5jdGlvbiBlbnRyeSh0eXBlLCBkYXRlLCB1bml0LCBzdGVwLCBtaW4sIG1heCkge1xuICB2YXIgZSA9IHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIGRhdGU6IGRhdGUsXG4gICAgdW5pdDogdW5pdFxuICB9O1xuICBpZiAoc3RlcCkge1xuICAgIGUuc3RlcCA9IHN0ZXA7XG4gIH0gZWxzZSB7XG4gICAgZS5taW5zdGVwID0gMTtcbiAgfVxuICBpZiAobWluICE9IG51bGwpIGUubWluID0gbWluO1xuICBpZiAobWF4ICE9IG51bGwpIGUubWF4ID0gbWF4O1xuICByZXR1cm4gZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlKHR5cGUsIHVuaXQsIGJhc2UsIHN0ZXAsIG1pbiwgbWF4KSB7XG4gIHJldHVybiBlbnRyeSh0eXBlLFxuICAgIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHVuaXQub2Zmc2V0KGJhc2UsIGQpOyB9LFxuICAgIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHVuaXQuY291bnQoYmFzZSwgZCk7IH0sXG4gICAgc3RlcCwgbWluLCBtYXgpO1xufVxuXG52YXIgbG9jYWxlID0gW1xuICBjcmVhdGUoJ3NlY29uZCcsIGQzX3RpbWUuc2Vjb25kLCBiYXNlRGF0ZSksXG4gIGNyZWF0ZSgnbWludXRlJywgZDNfdGltZS5taW51dGUsIGJhc2VEYXRlKSxcbiAgY3JlYXRlKCdob3VyJywgICBkM190aW1lLmhvdXIsICAgYmFzZURhdGUpLFxuICBjcmVhdGUoJ2RheScsICAgIGQzX3RpbWUuZGF5LCAgICBiYXNlRGF0ZSwgWzEsIDddKSxcbiAgY3JlYXRlKCdtb250aCcsICBkM190aW1lLm1vbnRoLCAgYmFzZURhdGUsIFsxLCAzLCA2XSksXG4gIGNyZWF0ZSgneWVhcicsICAgZDNfdGltZS55ZWFyLCAgIGJhc2VEYXRlKSxcblxuICAvLyBwZXJpb2RpYyB1bml0c1xuICBlbnRyeSgnc2Vjb25kcycsXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gbmV3IERhdGUoMTk3MCwgMCwgMSwgMCwgMCwgZCk7IH0sXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gZGF0ZShkKS5nZXRTZWNvbmRzKCk7IH0sXG4gICAgbnVsbCwgMCwgNTlcbiAgKSxcbiAgZW50cnkoJ21pbnV0ZXMnLFxuICAgIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIG5ldyBEYXRlKDE5NzAsIDAsIDEsIDAsIGQpOyB9LFxuICAgIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGRhdGUoZCkuZ2V0TWludXRlcygpOyB9LFxuICAgIG51bGwsIDAsIDU5XG4gICksXG4gIGVudHJ5KCdob3VycycsXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gbmV3IERhdGUoMTk3MCwgMCwgMSwgZCk7IH0sXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gZGF0ZShkKS5nZXRIb3VycygpOyB9LFxuICAgIG51bGwsIDAsIDIzXG4gICksXG4gIGVudHJ5KCd3ZWVrZGF5cycsXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gbmV3IERhdGUoMTk3MCwgMCwgNCtkKTsgfSxcbiAgICBmdW5jdGlvbihkKSB7IHJldHVybiBkYXRlKGQpLmdldERheSgpOyB9LFxuICAgIFsxXSwgMCwgNlxuICApLFxuICBlbnRyeSgnZGF0ZXMnLFxuICAgIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIG5ldyBEYXRlKDE5NzAsIDAsIGQpOyB9LFxuICAgIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGRhdGUoZCkuZ2V0RGF0ZSgpOyB9LFxuICAgIFsxXSwgMSwgMzFcbiAgKSxcbiAgZW50cnkoJ21vbnRocycsXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gbmV3IERhdGUoMTk3MCwgZCAlIDEyLCAxKTsgfSxcbiAgICBmdW5jdGlvbihkKSB7IHJldHVybiBkYXRlKGQpLmdldE1vbnRoKCk7IH0sXG4gICAgWzFdLCAwLCAxMVxuICApXG5dO1xuXG52YXIgdXRjID0gW1xuICBjcmVhdGUoJ3NlY29uZCcsIGQzX3RpbWUudXRjU2Vjb25kLCB1dGNCYXNlRGF0ZSksXG4gIGNyZWF0ZSgnbWludXRlJywgZDNfdGltZS51dGNNaW51dGUsIHV0Y0Jhc2VEYXRlKSxcbiAgY3JlYXRlKCdob3VyJywgICBkM190aW1lLnV0Y0hvdXIsICAgdXRjQmFzZURhdGUpLFxuICBjcmVhdGUoJ2RheScsICAgIGQzX3RpbWUudXRjRGF5LCAgICB1dGNCYXNlRGF0ZSwgWzEsIDddKSxcbiAgY3JlYXRlKCdtb250aCcsICBkM190aW1lLnV0Y01vbnRoLCAgdXRjQmFzZURhdGUsIFsxLCAzLCA2XSksXG4gIGNyZWF0ZSgneWVhcicsICAgZDNfdGltZS51dGNZZWFyLCAgIHV0Y0Jhc2VEYXRlKSxcblxuICAvLyBwZXJpb2RpYyB1bml0c1xuICBlbnRyeSgnc2Vjb25kcycsXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoMTk3MCwgMCwgMSwgMCwgMCwgZCkpOyB9LFxuICAgIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGRhdGUoZCkuZ2V0VVRDU2Vjb25kcygpOyB9LFxuICAgIG51bGwsIDAsIDU5XG4gICksXG4gIGVudHJ5KCdtaW51dGVzJyxcbiAgICBmdW5jdGlvbihkKSB7IHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQygxOTcwLCAwLCAxLCAwLCBkKSk7IH0sXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gZGF0ZShkKS5nZXRVVENNaW51dGVzKCk7IH0sXG4gICAgbnVsbCwgMCwgNTlcbiAgKSxcbiAgZW50cnkoJ2hvdXJzJyxcbiAgICBmdW5jdGlvbihkKSB7IHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQygxOTcwLCAwLCAxLCBkKSk7IH0sXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gZGF0ZShkKS5nZXRVVENIb3VycygpOyB9LFxuICAgIG51bGwsIDAsIDIzXG4gICksXG4gIGVudHJ5KCd3ZWVrZGF5cycsXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoMTk3MCwgMCwgNCtkKSk7IH0sXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gZGF0ZShkKS5nZXRVVENEYXkoKTsgfSxcbiAgICBbMV0sIDAsIDZcbiAgKSxcbiAgZW50cnkoJ2RhdGVzJyxcbiAgICBmdW5jdGlvbihkKSB7IHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQygxOTcwLCAwLCBkKSk7IH0sXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4gZGF0ZShkKS5nZXRVVENEYXRlKCk7IH0sXG4gICAgWzFdLCAxLCAzMVxuICApLFxuICBlbnRyeSgnbW9udGhzJyxcbiAgICBmdW5jdGlvbihkKSB7IHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQygxOTcwLCBkICUgMTIsIDEpKTsgfSxcbiAgICBmdW5jdGlvbihkKSB7IHJldHVybiBkYXRlKGQpLmdldFVUQ01vbnRoKCk7IH0sXG4gICAgWzFdLCAwLCAxMVxuICApXG5dO1xuXG52YXIgU1RFUFMgPSBbXG4gIFszMTUzNmU2LCA1XSwgIC8vIDEteWVhclxuICBbNzc3NmU2LCA0XSwgICAvLyAzLW1vbnRoXG4gIFsyNTkyZTYsIDRdLCAgIC8vIDEtbW9udGhcbiAgWzEyMDk2ZTUsIDNdLCAgLy8gMi13ZWVrXG4gIFs2MDQ4ZTUsIDNdLCAgIC8vIDEtd2Vla1xuICBbMTcyOGU1LCAzXSwgICAvLyAyLWRheVxuICBbODY0ZTUsIDNdLCAgICAvLyAxLWRheVxuICBbNDMyZTUsIDJdLCAgICAvLyAxMi1ob3VyXG4gIFsyMTZlNSwgMl0sICAgIC8vIDYtaG91clxuICBbMTA4ZTUsIDJdLCAgICAvLyAzLWhvdXJcbiAgWzM2ZTUsIDJdLCAgICAgLy8gMS1ob3VyXG4gIFsxOGU1LCAxXSwgICAgIC8vIDMwLW1pbnV0ZVxuICBbOWU1LCAxXSwgICAgICAvLyAxNS1taW51dGVcbiAgWzNlNSwgMV0sICAgICAgLy8gNS1taW51dGVcbiAgWzZlNCwgMV0sICAgICAgLy8gMS1taW51dGVcbiAgWzNlNCwgMF0sICAgICAgLy8gMzAtc2Vjb25kXG4gIFsxNWUzLCAwXSwgICAgIC8vIDE1LXNlY29uZFxuICBbNWUzLCAwXSwgICAgICAvLyA1LXNlY29uZFxuICBbMWUzLCAwXSAgICAgICAvLyAxLXNlY29uZFxuXTtcblxuZnVuY3Rpb24gZmluZCh1bml0cywgc3BhbiwgbWluYiwgbWF4Yikge1xuICB2YXIgc3RlcCA9IFNURVBTWzBdLCBpLCBuLCBiaW5zO1xuXG4gIGZvciAoaT0xLCBuPVNURVBTLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBzdGVwID0gU1RFUFNbaV07XG4gICAgaWYgKHNwYW4gPiBzdGVwWzBdKSB7XG4gICAgICBiaW5zID0gc3BhbiAvIHN0ZXBbMF07XG4gICAgICBpZiAoYmlucyA+IG1heGIpIHtcbiAgICAgICAgcmV0dXJuIHVuaXRzW1NURVBTW2ktMV1bMV1dO1xuICAgICAgfVxuICAgICAgaWYgKGJpbnMgPj0gbWluYikge1xuICAgICAgICByZXR1cm4gdW5pdHNbc3RlcFsxXV07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB1bml0c1tTVEVQU1tuLTFdWzFdXTtcbn1cblxuZnVuY3Rpb24gdG9Vbml0TWFwKHVuaXRzKSB7XG4gIHZhciBtYXAgPSB7fSwgaSwgbjtcbiAgZm9yIChpPTAsIG49dW5pdHMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIG1hcFt1bml0c1tpXS50eXBlXSA9IHVuaXRzW2ldO1xuICB9XG4gIG1hcC5maW5kID0gZnVuY3Rpb24oc3BhbiwgbWluYiwgbWF4Yikge1xuICAgIHJldHVybiBmaW5kKHVuaXRzLCBzcGFuLCBtaW5iLCBtYXhiKTtcbiAgfTtcbiAgcmV0dXJuIG1hcDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b1VuaXRNYXAobG9jYWxlKTtcbm1vZHVsZS5leHBvcnRzLnV0YyA9IHRvVW5pdE1hcCh1dGMpO1xuIiwidmFyIGJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLFxuICAgIHRpbWUgPSByZXF1aXJlKCcuL3RpbWUnKSxcbiAgICB1dGMgPSB0aW1lLnV0YztcblxudmFyIHUgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyB1dGlsaXR5IGZ1bmN0aW9uc1xuXG52YXIgRk5BTUUgPSAnX19uYW1lX18nO1xuXG51Lm5hbWVkZnVuYyA9IGZ1bmN0aW9uKG5hbWUsIGYpIHsgcmV0dXJuIChmW0ZOQU1FXSA9IG5hbWUsIGYpOyB9O1xuXG51Lm5hbWUgPSBmdW5jdGlvbihmKSB7IHJldHVybiBmPT1udWxsID8gbnVsbCA6IGZbRk5BTUVdOyB9O1xuXG51LmlkZW50aXR5ID0gZnVuY3Rpb24oeCkgeyByZXR1cm4geDsgfTtcblxudS50cnVlID0gdS5uYW1lZGZ1bmMoJ3RydWUnLCBmdW5jdGlvbigpIHsgcmV0dXJuIHRydWU7IH0pO1xuXG51LmZhbHNlID0gdS5uYW1lZGZ1bmMoJ2ZhbHNlJywgZnVuY3Rpb24oKSB7IHJldHVybiBmYWxzZTsgfSk7XG5cbnUuZHVwbGljYXRlID0gZnVuY3Rpb24ob2JqKSB7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpO1xufTtcblxudS5lcXVhbCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGEpID09PSBKU09OLnN0cmluZ2lmeShiKTtcbn07XG5cbnUuZXh0ZW5kID0gZnVuY3Rpb24ob2JqKSB7XG4gIGZvciAodmFyIHgsIG5hbWUsIGk9MSwgbGVuPWFyZ3VtZW50cy5sZW5ndGg7IGk8bGVuOyArK2kpIHtcbiAgICB4ID0gYXJndW1lbnRzW2ldO1xuICAgIGZvciAobmFtZSBpbiB4KSB7IG9ialtuYW1lXSA9IHhbbmFtZV07IH1cbiAgfVxuICByZXR1cm4gb2JqO1xufTtcblxudS5sZW5ndGggPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiB4ICE9IG51bGwgJiYgeC5sZW5ndGggIT0gbnVsbCA/IHgubGVuZ3RoIDogbnVsbDtcbn07XG5cbnUua2V5cyA9IGZ1bmN0aW9uKHgpIHtcbiAgdmFyIGtleXMgPSBbXSwgaztcbiAgZm9yIChrIGluIHgpIGtleXMucHVzaChrKTtcbiAgcmV0dXJuIGtleXM7XG59O1xuXG51LnZhbHMgPSBmdW5jdGlvbih4KSB7XG4gIHZhciB2YWxzID0gW10sIGs7XG4gIGZvciAoayBpbiB4KSB2YWxzLnB1c2goeFtrXSk7XG4gIHJldHVybiB2YWxzO1xufTtcblxudS50b01hcCA9IGZ1bmN0aW9uKGxpc3QsIGYpIHtcbiAgcmV0dXJuIChmID0gdS4kKGYpKSA/XG4gICAgbGlzdC5yZWR1Y2UoZnVuY3Rpb24ob2JqLCB4KSB7IHJldHVybiAob2JqW2YoeCldID0gMSwgb2JqKTsgfSwge30pIDpcbiAgICBsaXN0LnJlZHVjZShmdW5jdGlvbihvYmosIHgpIHsgcmV0dXJuIChvYmpbeF0gPSAxLCBvYmopOyB9LCB7fSk7XG59O1xuXG51LmtleXN0ciA9IGZ1bmN0aW9uKHZhbHVlcykge1xuICAvLyB1c2UgdG8gZW5zdXJlIGNvbnNpc3RlbnQga2V5IGdlbmVyYXRpb24gYWNyb3NzIG1vZHVsZXNcbiAgdmFyIG4gPSB2YWx1ZXMubGVuZ3RoO1xuICBpZiAoIW4pIHJldHVybiAnJztcbiAgZm9yICh2YXIgcz1TdHJpbmcodmFsdWVzWzBdKSwgaT0xOyBpPG47ICsraSkge1xuICAgIHMgKz0gJ3wnICsgU3RyaW5nKHZhbHVlc1tpXSk7XG4gIH1cbiAgcmV0dXJuIHM7XG59O1xuXG4vLyB0eXBlIGNoZWNraW5nIGZ1bmN0aW9uc1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG51LmlzT2JqZWN0ID0gZnVuY3Rpb24ob2JqKSB7XG4gIHJldHVybiBvYmogPT09IE9iamVjdChvYmopO1xufTtcblxudS5pc0Z1bmN0aW9uID0gZnVuY3Rpb24ob2JqKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG51LmlzU3RyaW5nID0gZnVuY3Rpb24ob2JqKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG59O1xuXG51LmlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uKG9iaikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxudS5pc051bWJlciA9IGZ1bmN0aW9uKG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ251bWJlcicgfHwgdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBOdW1iZXJdJztcbn07XG5cbnUuaXNCb29sZWFuID0gZnVuY3Rpb24ob2JqKSB7XG4gIHJldHVybiBvYmogPT09IHRydWUgfHwgb2JqID09PSBmYWxzZSB8fCB0b1N0cmluZy5jYWxsKG9iaikgPT0gJ1tvYmplY3QgQm9vbGVhbl0nO1xufTtcblxudS5pc0RhdGUgPSBmdW5jdGlvbihvYmopIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufTtcblxudS5pc1ZhbGlkID0gZnVuY3Rpb24ob2JqKSB7XG4gIHJldHVybiBvYmogIT0gbnVsbCAmJiBvYmogPT09IG9iajtcbn07XG5cbnUuaXNCdWZmZXIgPSAoYnVmZmVyLkJ1ZmZlciAmJiBidWZmZXIuQnVmZmVyLmlzQnVmZmVyKSB8fCB1LmZhbHNlO1xuXG4vLyB0eXBlIGNvZXJjaW9uIGZ1bmN0aW9uc1xuXG51Lm51bWJlciA9IGZ1bmN0aW9uKHMpIHtcbiAgcmV0dXJuIHMgPT0gbnVsbCB8fCBzID09PSAnJyA/IG51bGwgOiArcztcbn07XG5cbnUuYm9vbGVhbiA9IGZ1bmN0aW9uKHMpIHtcbiAgcmV0dXJuIHMgPT0gbnVsbCB8fCBzID09PSAnJyA/IG51bGwgOiBzPT09J2ZhbHNlJyA/IGZhbHNlIDogISFzO1xufTtcblxudS5kYXRlID0gZnVuY3Rpb24ocykge1xuICByZXR1cm4gcyA9PSBudWxsIHx8IHMgPT09ICcnID8gbnVsbCA6IERhdGUucGFyc2Uocyk7XG59O1xuXG51LmFycmF5ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4geCAhPSBudWxsID8gKHUuaXNBcnJheSh4KSA/IHggOiBbeF0pIDogW107XG59O1xuXG51LnN0ciA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIHUuaXNBcnJheSh4KSA/ICdbJyArIHgubWFwKHUuc3RyKSArICddJ1xuICAgIDogdS5pc09iamVjdCh4KSA/IEpTT04uc3RyaW5naWZ5KHgpXG4gICAgOiB1LmlzU3RyaW5nKHgpID8gKCdcXCcnK3V0aWxfZXNjYXBlX3N0cih4KSsnXFwnJykgOiB4O1xufTtcblxudmFyIGVzY2FwZV9zdHJfcmUgPSAvKF58W15cXFxcXSknL2c7XG5cbmZ1bmN0aW9uIHV0aWxfZXNjYXBlX3N0cih4KSB7XG4gIHJldHVybiB4LnJlcGxhY2UoZXNjYXBlX3N0cl9yZSwgJyQxXFxcXFxcJycpO1xufVxuXG4vLyBkYXRhIGFjY2VzcyBmdW5jdGlvbnNcblxudmFyIGZpZWxkX3JlID0gL1xcWyguKj8pXFxdfFteLlxcW10rL2c7XG5cbnUuZmllbGQgPSBmdW5jdGlvbihmKSB7XG4gIHJldHVybiBTdHJpbmcoZikubWF0Y2goZmllbGRfcmUpLm1hcChmdW5jdGlvbihkKSB7XG4gICAgcmV0dXJuIGRbMF0gIT09ICdbJyA/IGQgOlxuICAgICAgZFsxXSAhPT0gXCInXCIgJiYgZFsxXSAhPT0gJ1wiJyA/IGQuc2xpY2UoMSwgLTEpIDpcbiAgICAgIGQuc2xpY2UoMiwgLTIpLnJlcGxhY2UoL1xcXFwoW1wiJ10pL2csICckMScpO1xuICB9KTtcbn07XG5cbnUuYWNjZXNzb3IgPSBmdW5jdGlvbihmKSB7XG4gIHZhciBzO1xuICByZXR1cm4gZj09bnVsbCB8fCB1LmlzRnVuY3Rpb24oZikgPyBmIDpcbiAgICB1Lm5hbWVkZnVuYyhmLCAocyA9IHUuZmllbGQoZikpLmxlbmd0aCA+IDEgP1xuICAgICAgZnVuY3Rpb24oeCkgeyByZXR1cm4gcy5yZWR1Y2UoZnVuY3Rpb24oeCxmKSB7IHJldHVybiB4W2ZdOyB9LCB4KTsgfSA6XG4gICAgICBmdW5jdGlvbih4KSB7IHJldHVybiB4W2ZdOyB9XG4gICAgKTtcbn07XG5cbi8vIHNob3J0LWN1dCBmb3IgYWNjZXNzb3JcbnUuJCA9IHUuYWNjZXNzb3I7XG5cbnUubXV0YXRvciA9IGZ1bmN0aW9uKGYpIHtcbiAgdmFyIHM7XG4gIHJldHVybiB1LmlzU3RyaW5nKGYpICYmIChzPXUuZmllbGQoZikpLmxlbmd0aCA+IDEgP1xuICAgIGZ1bmN0aW9uKHgsIHYpIHtcbiAgICAgIGZvciAodmFyIGk9MDsgaTxzLmxlbmd0aC0xOyArK2kpIHggPSB4W3NbaV1dO1xuICAgICAgeFtzW2ldXSA9IHY7XG4gICAgfSA6XG4gICAgZnVuY3Rpb24oeCwgdikgeyB4W2ZdID0gdjsgfTtcbn07XG5cblxudS4kZnVuYyA9IGZ1bmN0aW9uKG5hbWUsIG9wKSB7XG4gIHJldHVybiBmdW5jdGlvbihmKSB7XG4gICAgZiA9IHUuJChmKSB8fCB1LmlkZW50aXR5O1xuICAgIHZhciBuID0gbmFtZSArICh1Lm5hbWUoZikgPyAnXycrdS5uYW1lKGYpIDogJycpO1xuICAgIHJldHVybiB1Lm5hbWVkZnVuYyhuLCBmdW5jdGlvbihkKSB7IHJldHVybiBvcChmKGQpKTsgfSk7XG4gIH07XG59O1xuXG51LiR2YWxpZCAgPSB1LiRmdW5jKCd2YWxpZCcsIHUuaXNWYWxpZCk7XG51LiRsZW5ndGggPSB1LiRmdW5jKCdsZW5ndGgnLCB1Lmxlbmd0aCk7XG5cbnUuJGluID0gZnVuY3Rpb24oZiwgdmFsdWVzKSB7XG4gIGYgPSB1LiQoZik7XG4gIHZhciBtYXAgPSB1LmlzQXJyYXkodmFsdWVzKSA/IHUudG9NYXAodmFsdWVzKSA6IHZhbHVlcztcbiAgcmV0dXJuIGZ1bmN0aW9uKGQpIHsgcmV0dXJuICEhbWFwW2YoZCldOyB9O1xufTtcblxudS4keWVhciAgID0gdS4kZnVuYygneWVhcicsIHRpbWUueWVhci51bml0KTtcbnUuJG1vbnRoICA9IHUuJGZ1bmMoJ21vbnRoJywgdGltZS5tb250aHMudW5pdCk7XG51LiRkYXRlICAgPSB1LiRmdW5jKCdkYXRlJywgdGltZS5kYXRlcy51bml0KTtcbnUuJGRheSAgICA9IHUuJGZ1bmMoJ2RheScsIHRpbWUud2Vla2RheXMudW5pdCk7XG51LiRob3VyICAgPSB1LiRmdW5jKCdob3VyJywgdGltZS5ob3Vycy51bml0KTtcbnUuJG1pbnV0ZSA9IHUuJGZ1bmMoJ21pbnV0ZScsIHRpbWUubWludXRlcy51bml0KTtcbnUuJHNlY29uZCA9IHUuJGZ1bmMoJ3NlY29uZCcsIHRpbWUuc2Vjb25kcy51bml0KTtcblxudS4kdXRjWWVhciAgID0gdS4kZnVuYygndXRjWWVhcicsIHV0Yy55ZWFyLnVuaXQpO1xudS4kdXRjTW9udGggID0gdS4kZnVuYygndXRjTW9udGgnLCB1dGMubW9udGhzLnVuaXQpO1xudS4kdXRjRGF0ZSAgID0gdS4kZnVuYygndXRjRGF0ZScsIHV0Yy5kYXRlcy51bml0KTtcbnUuJHV0Y0RheSAgICA9IHUuJGZ1bmMoJ3V0Y0RheScsIHV0Yy53ZWVrZGF5cy51bml0KTtcbnUuJHV0Y0hvdXIgICA9IHUuJGZ1bmMoJ3V0Y0hvdXInLCB1dGMuaG91cnMudW5pdCk7XG51LiR1dGNNaW51dGUgPSB1LiRmdW5jKCd1dGNNaW51dGUnLCB1dGMubWludXRlcy51bml0KTtcbnUuJHV0Y1NlY29uZCA9IHUuJGZ1bmMoJ3V0Y1NlY29uZCcsIHV0Yy5zZWNvbmRzLnVuaXQpO1xuXG4vLyBjb21wYXJpc29uIC8gc29ydGluZyBmdW5jdGlvbnNcblxudS5jb21wYXJhdG9yID0gZnVuY3Rpb24oc29ydCkge1xuICB2YXIgc2lnbiA9IFtdO1xuICBpZiAoc29ydCA9PT0gdW5kZWZpbmVkKSBzb3J0ID0gW107XG4gIHNvcnQgPSB1LmFycmF5KHNvcnQpLm1hcChmdW5jdGlvbihmKSB7XG4gICAgdmFyIHMgPSAxO1xuICAgIGlmICAgICAgKGZbMF0gPT09ICctJykgeyBzID0gLTE7IGYgPSBmLnNsaWNlKDEpOyB9XG4gICAgZWxzZSBpZiAoZlswXSA9PT0gJysnKSB7IHMgPSArMTsgZiA9IGYuc2xpY2UoMSk7IH1cbiAgICBzaWduLnB1c2gocyk7XG4gICAgcmV0dXJuIHUuYWNjZXNzb3IoZik7XG4gIH0pO1xuICByZXR1cm4gZnVuY3Rpb24oYSxiKSB7XG4gICAgdmFyIGksIG4sIGYsIHgsIHk7XG4gICAgZm9yIChpPTAsIG49c29ydC5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgICBmID0gc29ydFtpXTsgeCA9IGYoYSk7IHkgPSBmKGIpO1xuICAgICAgaWYgKHggPCB5KSByZXR1cm4gLTEgKiBzaWduW2ldO1xuICAgICAgaWYgKHggPiB5KSByZXR1cm4gc2lnbltpXTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH07XG59O1xuXG51LmNtcCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgaWYgKGEgPCBiKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9IGVsc2UgaWYgKGEgPiBiKSB7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSBpZiAoYSA+PSBiKSB7XG4gICAgcmV0dXJuIDA7XG4gIH0gZWxzZSBpZiAoYSA9PT0gbnVsbCkge1xuICAgIHJldHVybiAtMTtcbiAgfSBlbHNlIGlmIChiID09PSBudWxsKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIE5hTjtcbn07XG5cbnUubnVtY21wID0gZnVuY3Rpb24oYSwgYikgeyByZXR1cm4gYSAtIGI7IH07XG5cbnUuc3RhYmxlc29ydCA9IGZ1bmN0aW9uKGFycmF5LCBzb3J0QnksIGtleUZuKSB7XG4gIHZhciBpbmRpY2VzID0gYXJyYXkucmVkdWNlKGZ1bmN0aW9uKGlkeCwgdiwgaSkge1xuICAgIHJldHVybiAoaWR4W2tleUZuKHYpXSA9IGksIGlkeCk7XG4gIH0sIHt9KTtcblxuICBhcnJheS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgc2EgPSBzb3J0QnkoYSksXG4gICAgICAgIHNiID0gc29ydEJ5KGIpO1xuICAgIHJldHVybiBzYSA8IHNiID8gLTEgOiBzYSA+IHNiID8gMVxuICAgICAgICAgOiAoaW5kaWNlc1trZXlGbihhKV0gLSBpbmRpY2VzW2tleUZuKGIpXSk7XG4gIH0pO1xuXG4gIHJldHVybiBhcnJheTtcbn07XG5cblxuLy8gc3RyaW5nIGZ1bmN0aW9uc1xuXG51LnBhZCA9IGZ1bmN0aW9uKHMsIGxlbmd0aCwgcG9zLCBwYWRjaGFyKSB7XG4gIHBhZGNoYXIgPSBwYWRjaGFyIHx8IFwiIFwiO1xuICB2YXIgZCA9IGxlbmd0aCAtIHMubGVuZ3RoO1xuICBpZiAoZCA8PSAwKSByZXR1cm4gcztcbiAgc3dpdGNoIChwb3MpIHtcbiAgICBjYXNlICdsZWZ0JzpcbiAgICAgIHJldHVybiBzdHJyZXAoZCwgcGFkY2hhcikgKyBzO1xuICAgIGNhc2UgJ21pZGRsZSc6XG4gICAgY2FzZSAnY2VudGVyJzpcbiAgICAgIHJldHVybiBzdHJyZXAoTWF0aC5mbG9vcihkLzIpLCBwYWRjaGFyKSArXG4gICAgICAgICBzICsgc3RycmVwKE1hdGguY2VpbChkLzIpLCBwYWRjaGFyKTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHMgKyBzdHJyZXAoZCwgcGFkY2hhcik7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHN0cnJlcChuLCBzdHIpIHtcbiAgdmFyIHMgPSBcIlwiLCBpO1xuICBmb3IgKGk9MDsgaTxuOyArK2kpIHMgKz0gc3RyO1xuICByZXR1cm4gcztcbn1cblxudS50cnVuY2F0ZSA9IGZ1bmN0aW9uKHMsIGxlbmd0aCwgcG9zLCB3b3JkLCBlbGxpcHNpcykge1xuICB2YXIgbGVuID0gcy5sZW5ndGg7XG4gIGlmIChsZW4gPD0gbGVuZ3RoKSByZXR1cm4gcztcbiAgZWxsaXBzaXMgPSBlbGxpcHNpcyAhPT0gdW5kZWZpbmVkID8gU3RyaW5nKGVsbGlwc2lzKSA6ICdcXHUyMDI2JztcbiAgdmFyIGwgPSBNYXRoLm1heCgwLCBsZW5ndGggLSBlbGxpcHNpcy5sZW5ndGgpO1xuXG4gIHN3aXRjaCAocG9zKSB7XG4gICAgY2FzZSAnbGVmdCc6XG4gICAgICByZXR1cm4gZWxsaXBzaXMgKyAod29yZCA/IHRydW5jYXRlT25Xb3JkKHMsbCwxKSA6IHMuc2xpY2UobGVuLWwpKTtcbiAgICBjYXNlICdtaWRkbGUnOlxuICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgICB2YXIgbDEgPSBNYXRoLmNlaWwobC8yKSwgbDIgPSBNYXRoLmZsb29yKGwvMik7XG4gICAgICByZXR1cm4gKHdvcmQgPyB0cnVuY2F0ZU9uV29yZChzLGwxKSA6IHMuc2xpY2UoMCxsMSkpICtcbiAgICAgICAgZWxsaXBzaXMgKyAod29yZCA/IHRydW5jYXRlT25Xb3JkKHMsbDIsMSkgOiBzLnNsaWNlKGxlbi1sMikpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gKHdvcmQgPyB0cnVuY2F0ZU9uV29yZChzLGwpIDogcy5zbGljZSgwLGwpKSArIGVsbGlwc2lzO1xuICB9XG59O1xuXG5mdW5jdGlvbiB0cnVuY2F0ZU9uV29yZChzLCBsZW4sIHJldikge1xuICB2YXIgY250ID0gMCwgdG9rID0gcy5zcGxpdCh0cnVuY2F0ZV93b3JkX3JlKTtcbiAgaWYgKHJldikge1xuICAgIHMgPSAodG9rID0gdG9rLnJldmVyc2UoKSlcbiAgICAgIC5maWx0ZXIoZnVuY3Rpb24odykgeyBjbnQgKz0gdy5sZW5ndGg7IHJldHVybiBjbnQgPD0gbGVuOyB9KVxuICAgICAgLnJldmVyc2UoKTtcbiAgfSBlbHNlIHtcbiAgICBzID0gdG9rLmZpbHRlcihmdW5jdGlvbih3KSB7IGNudCArPSB3Lmxlbmd0aDsgcmV0dXJuIGNudCA8PSBsZW47IH0pO1xuICB9XG4gIHJldHVybiBzLmxlbmd0aCA/IHMuam9pbignJykudHJpbSgpIDogdG9rWzBdLnNsaWNlKDAsIGxlbik7XG59XG5cbnZhciB0cnVuY2F0ZV93b3JkX3JlID0gLyhbXFx1MDAwOVxcdTAwMEFcXHUwMDBCXFx1MDAwQ1xcdTAwMERcXHUwMDIwXFx1MDBBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMEFcXHUyMDJGXFx1MjA1RlxcdTIwMjhcXHUyMDI5XFx1MzAwMFxcdUZFRkZdKS87XG4iXX0=
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment