You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
12449 lines
1.1 MiB
12449 lines
1.1 MiB
(function webpackUniversalModuleDefinition(root, factory) {
|
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
module.exports = factory(factory.toString()).default;
|
|
else if(typeof exports === 'object')
|
|
exports["Quagga"] = factory(factory.toString()).default;
|
|
else
|
|
root["Quagga"] = factory(factory.toString()).default;
|
|
})(this, function(__factorySource__) {
|
|
return /******/ (function(modules) { // webpackBootstrap
|
|
/******/ // The module cache
|
|
/******/ var installedModules = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/
|
|
/******/ // Check if module is in cache
|
|
/******/ if(installedModules[moduleId])
|
|
/******/ return installedModules[moduleId].e;
|
|
/******/
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = installedModules[moduleId] = {
|
|
/******/ e: {},
|
|
/******/ i: moduleId,
|
|
/******/ l: false
|
|
/******/ };
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.e, module, module.e, __webpack_require__);
|
|
/******/
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.l = true;
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.e;
|
|
/******/ }
|
|
/******/
|
|
/******/
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = modules;
|
|
/******/
|
|
/******/ // expose the module cache
|
|
/******/ __webpack_require__.c = installedModules;
|
|
/******/
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "/";
|
|
/******/
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(__webpack_require__.s = 154);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree.
|
|
*/
|
|
'use strict';
|
|
|
|
var logDisabled_ = false;
|
|
|
|
// Utility methods.
|
|
var utils = {
|
|
disableLog: function(bool) {
|
|
if (typeof bool !== 'boolean') {
|
|
return new Error('Argument type: ' + typeof bool +
|
|
'. Please use a boolean.');
|
|
}
|
|
logDisabled_ = bool;
|
|
return (bool) ? 'adapter.js logging disabled' :
|
|
'adapter.js logging enabled';
|
|
},
|
|
|
|
log: function() {
|
|
if (typeof window === 'object') {
|
|
if (logDisabled_) {
|
|
return;
|
|
}
|
|
console.log.apply(console, arguments);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Extract browser version out of the provided user agent string.
|
|
* @param {!string} uastring userAgent string.
|
|
* @param {!string} expr Regular expression used as match criteria.
|
|
* @param {!number} pos position in the version string to be returned.
|
|
* @return {!number} browser version.
|
|
*/
|
|
extractVersion: function(uastring, expr, pos) {
|
|
var match = uastring.match(expr);
|
|
return match && match.length >= pos && parseInt(match[pos], 10);
|
|
},
|
|
|
|
/**
|
|
* Browser detector.
|
|
* @return {object} result containing browser, version and minVersion
|
|
* properties.
|
|
*/
|
|
detectBrowser: function() {
|
|
// Returned result object.
|
|
var result = {};
|
|
result.browser = null;
|
|
result.version = null;
|
|
result.minVersion = null;
|
|
|
|
if (typeof window === 'undefined' || !window.navigator) {
|
|
result.browser = 'Not a browser.';
|
|
return result;
|
|
} else if (navigator.mozGetUserMedia) {
|
|
// Firefox.
|
|
result.browser = 'firefox';
|
|
result.version = this.extractVersion(navigator.userAgent,
|
|
/Firefox\/([0-9]+)\./, 1);
|
|
result.minVersion = 31;
|
|
} else if (navigator.webkitGetUserMedia && window.webkitRTCPeerConnection) {
|
|
// Chrome, Chromium, WebView, Opera and other WebKit browsers.
|
|
result.browser = 'chrome';
|
|
result.version = this.extractVersion(navigator.userAgent,
|
|
/Chrom(e|ium)\/([0-9]+)\./, 2);
|
|
result.minVersion = 38;
|
|
} else if(navigator.mediaDevices &&
|
|
navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)) {
|
|
// Edge.
|
|
result.browser = 'edge';
|
|
result.version = this.extractVersion(navigator.userAgent,
|
|
/Edge\/(\d+).(\d+)$/, 2);
|
|
result.minVersion = 10547;
|
|
} else {
|
|
result.browser = 'Not a supported browser.';
|
|
return result;
|
|
}
|
|
|
|
// Warn if version is less than minVersion.
|
|
if (result.version < result.minVersion) {
|
|
utils.log('Browser: ' + result.browser + ' Version: ' + result.version +
|
|
' < minimum supported version: ' + result.minVersion +
|
|
'\n some things might not work!');
|
|
}
|
|
|
|
return result;
|
|
}
|
|
};
|
|
|
|
// Export.
|
|
module.e = {
|
|
log: utils.log,
|
|
disableLog: utils.disableLog,
|
|
browserDetails: utils.detectBrowser(),
|
|
extractVersion: utils.extractVersion
|
|
};
|
|
|
|
|
|
/***/ },
|
|
/* 1 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(module, global) {var checkGlobal = __webpack_require__(104);
|
|
|
|
/** Used to determine if values are of the language type `Object`. */
|
|
var objectTypes = {
|
|
'function': true,
|
|
'object': true
|
|
};
|
|
|
|
/** Detect free variable `exports`. */
|
|
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
|
|
? exports
|
|
: undefined;
|
|
|
|
/** Detect free variable `module`. */
|
|
var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
|
|
? module
|
|
: undefined;
|
|
|
|
/** Detect free variable `global` from Node.js. */
|
|
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
|
|
|
|
/** Detect free variable `self`. */
|
|
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
|
|
|
|
/** Detect free variable `window`. */
|
|
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
|
|
|
|
/** Detect `this` as the global object. */
|
|
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
|
|
|
|
/**
|
|
* Used as a reference to the global object.
|
|
*
|
|
* The `this` value is used if it's the global object to avoid Greasemonkey's
|
|
* restricted `window` object, otherwise the `window` object is used.
|
|
*/
|
|
var root = freeGlobal ||
|
|
((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
|
|
freeSelf || thisGlobal || Function('return this')();
|
|
|
|
module.e = root;
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(48)(module), (function() { return this; }())))
|
|
|
|
/***/ },
|
|
/* 2 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
|
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObject({});
|
|
* // => true
|
|
*
|
|
* _.isObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObject(_.noop);
|
|
* // => true
|
|
*
|
|
* _.isObject(null);
|
|
* // => false
|
|
*/
|
|
function isObject(value) {
|
|
var type = typeof value;
|
|
return !!value && (type == 'object' || type == 'function');
|
|
}
|
|
|
|
module.e = isObject;
|
|
|
|
|
|
/***/ },
|
|
/* 3 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var getNative = __webpack_require__(12),
|
|
root = __webpack_require__(1);
|
|
|
|
/* Built-in method references that are verified to be native. */
|
|
var Map = getNative(root, 'Map');
|
|
|
|
module.e = Map;
|
|
|
|
|
|
/***/ },
|
|
/* 4 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `Array` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @type {Function}
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArray([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArray(document.body.children);
|
|
* // => false
|
|
*
|
|
* _.isArray('abc');
|
|
* // => false
|
|
*
|
|
* _.isArray(_.noop);
|
|
* // => false
|
|
*/
|
|
var isArray = Array.isArray;
|
|
|
|
module.e = isArray;
|
|
|
|
|
|
/***/ },
|
|
/* 5 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
function BarcodeReader(config) {
|
|
this._row = [];
|
|
this.config = config || {};
|
|
return this;
|
|
}
|
|
|
|
BarcodeReader.prototype._nextUnset = function (line, start) {
|
|
var i;
|
|
|
|
if (start === undefined) {
|
|
start = 0;
|
|
}
|
|
for (i = start; i < line.length; i++) {
|
|
if (!line[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
return line.length;
|
|
};
|
|
|
|
BarcodeReader.prototype._matchPattern = function (counter, code) {
|
|
var i,
|
|
error = 0,
|
|
singleError = 0,
|
|
modulo = this.MODULO,
|
|
maxSingleError = this.SINGLE_CODE_ERROR || 1;
|
|
|
|
for (i = 0; i < counter.length; i++) {
|
|
singleError = Math.abs(code[i] - counter[i]);
|
|
if (singleError > maxSingleError) {
|
|
return Number.MAX_VALUE;
|
|
}
|
|
error += singleError;
|
|
}
|
|
return error / modulo;
|
|
};
|
|
|
|
BarcodeReader.prototype._nextSet = function (line, offset) {
|
|
var i;
|
|
|
|
offset = offset || 0;
|
|
for (i = offset; i < line.length; i++) {
|
|
if (line[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
return line.length;
|
|
};
|
|
|
|
BarcodeReader.prototype._normalize = function (counter, correction) {
|
|
var i,
|
|
self = this,
|
|
sum = 0,
|
|
ratio,
|
|
numOnes = 0,
|
|
normalized = new Array(counter.length),
|
|
norm = 0,
|
|
modulo = self.MODULO;
|
|
|
|
if (correction) {
|
|
self._correct(counter, correction);
|
|
}
|
|
for (i = 0; i < counter.length; i++) {
|
|
sum += counter[i];
|
|
}
|
|
ratio = sum / (modulo - numOnes);
|
|
for (i = 0; i < counter.length; i++) {
|
|
norm = counter[i] === 1 ? counter[i] : counter[i] / ratio;
|
|
normalized[i] = norm;
|
|
}
|
|
return normalized;
|
|
};
|
|
|
|
BarcodeReader.prototype._correctBars = function (counter, correction, indices) {
|
|
var length = indices.length,
|
|
tmp = 0;
|
|
while (length--) {
|
|
tmp = counter[indices[length]] * (1 - (1 - correction) / 2);
|
|
if (tmp > 1) {
|
|
counter[indices[length]] = tmp;
|
|
}
|
|
}
|
|
};
|
|
|
|
BarcodeReader.prototype._matchTrace = function (cmpCounter, epsilon) {
|
|
var counter = [],
|
|
i,
|
|
self = this,
|
|
offset = self._nextSet(self._row),
|
|
isWhite = !self._row[offset],
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0
|
|
},
|
|
error;
|
|
|
|
if (cmpCounter) {
|
|
for (i = 0; i < cmpCounter.length; i++) {
|
|
counter.push(0);
|
|
}
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
error = self._matchPattern(counter, cmpCounter);
|
|
|
|
if (error < epsilon) {
|
|
bestMatch.start = i - offset;
|
|
bestMatch.end = i;
|
|
bestMatch.counter = counter;
|
|
return bestMatch;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
} else {
|
|
counter.push(0);
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
counterPos++;
|
|
counter.push(0);
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if cmpCounter was not given
|
|
bestMatch.start = offset;
|
|
bestMatch.end = self._row.length - 1;
|
|
bestMatch.counter = counter;
|
|
return bestMatch;
|
|
};
|
|
|
|
BarcodeReader.prototype.decodePattern = function (pattern) {
|
|
var self = this,
|
|
result;
|
|
|
|
self._row = pattern;
|
|
result = self._decode();
|
|
if (result === null) {
|
|
self._row.reverse();
|
|
result = self._decode();
|
|
if (result) {
|
|
result.direction = BarcodeReader.DIRECTION.REVERSE;
|
|
result.start = self._row.length - result.start;
|
|
result.end = self._row.length - result.end;
|
|
}
|
|
} else {
|
|
result.direction = BarcodeReader.DIRECTION.FORWARD;
|
|
}
|
|
if (result) {
|
|
result.format = self.FORMAT;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
BarcodeReader.prototype._matchRange = function (start, end, value) {
|
|
var i;
|
|
|
|
start = start < 0 ? 0 : start;
|
|
for (i = start; i < end; i++) {
|
|
if (this._row[i] !== value) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
BarcodeReader.prototype._fillCounters = function (offset, end, isWhite) {
|
|
var self = this,
|
|
counterPos = 0,
|
|
i,
|
|
counters = [];
|
|
|
|
isWhite = typeof isWhite !== 'undefined' ? isWhite : true;
|
|
offset = typeof offset !== 'undefined' ? offset : self._nextUnset(self._row);
|
|
end = end || self._row.length;
|
|
|
|
counters[counterPos] = 0;
|
|
for (i = offset; i < end; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counters[counterPos]++;
|
|
} else {
|
|
counterPos++;
|
|
counters[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return counters;
|
|
};
|
|
|
|
Object.defineProperty(BarcodeReader.prototype, "FORMAT", {
|
|
value: 'unknown',
|
|
writeable: false
|
|
});
|
|
|
|
BarcodeReader.DIRECTION = {
|
|
FORWARD: 1,
|
|
REVERSE: -1
|
|
};
|
|
|
|
BarcodeReader.Exception = {
|
|
StartNotFoundException: "Start-Info was not found!",
|
|
CodeNotFoundException: "Code could not be found!",
|
|
PatternNotFoundException: "Pattern could not be found!"
|
|
};
|
|
|
|
BarcodeReader.CONFIG_KEYS = {};
|
|
|
|
/* harmony default export */ exports["a"] = BarcodeReader;
|
|
|
|
/***/ },
|
|
/* 6 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = clone
|
|
|
|
/**
|
|
* Creates a new vec2 initialized with values from an existing vector
|
|
*
|
|
* @param {vec2} a vector to clone
|
|
* @returns {vec2} a new 2D vector
|
|
*/
|
|
function clone(a) {
|
|
var out = new Float32Array(2)
|
|
out[0] = a[0]
|
|
out[1] = a[1]
|
|
return out
|
|
}
|
|
|
|
/***/ },
|
|
/* 7 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|
* and has a `typeof` result of "object".
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObjectLike({});
|
|
* // => true
|
|
*
|
|
* _.isObjectLike([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObjectLike(_.noop);
|
|
* // => false
|
|
*
|
|
* _.isObjectLike(null);
|
|
* // => false
|
|
*/
|
|
function isObjectLike(value) {
|
|
return !!value && typeof value == 'object';
|
|
}
|
|
|
|
module.e = isObjectLike;
|
|
|
|
|
|
/***/ },
|
|
/* 8 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony default export */ exports["a"] = {
|
|
init: function init(arr, val) {
|
|
var l = arr.length;
|
|
while (l--) {
|
|
arr[l] = val;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Shuffles the content of an array
|
|
* @return {Array} the array itself shuffled
|
|
*/
|
|
shuffle: function shuffle(arr) {
|
|
var i = arr.length - 1,
|
|
j,
|
|
x;
|
|
for (i; i >= 0; i--) {
|
|
j = Math.floor(Math.random() * i);
|
|
x = arr[i];
|
|
arr[i] = arr[j];
|
|
arr[j] = x;
|
|
}
|
|
return arr;
|
|
},
|
|
|
|
toPointList: function toPointList(arr) {
|
|
var i,
|
|
j,
|
|
row = [],
|
|
rows = [];
|
|
for (i = 0; i < arr.length; i++) {
|
|
row = [];
|
|
for (j = 0; j < arr[i].length; j++) {
|
|
row[j] = arr[i][j];
|
|
}
|
|
rows[i] = "[" + row.join(",") + "]";
|
|
}
|
|
return "[" + rows.join(",\r\n") + "]";
|
|
},
|
|
|
|
/**
|
|
* returns the elements which's score is bigger than the threshold
|
|
* @return {Array} the reduced array
|
|
*/
|
|
threshold: function threshold(arr, _threshold, scoreFunc) {
|
|
var i,
|
|
queue = [];
|
|
for (i = 0; i < arr.length; i++) {
|
|
if (scoreFunc.apply(arr, [arr[i]]) >= _threshold) {
|
|
queue.push(arr[i]);
|
|
}
|
|
}
|
|
return queue;
|
|
},
|
|
|
|
maxIndex: function maxIndex(arr) {
|
|
var i,
|
|
max = 0;
|
|
for (i = 0; i < arr.length; i++) {
|
|
if (arr[i] > arr[max]) {
|
|
max = i;
|
|
}
|
|
}
|
|
return max;
|
|
},
|
|
|
|
max: function max(arr) {
|
|
var i,
|
|
max = 0;
|
|
for (i = 0; i < arr.length; i++) {
|
|
if (arr[i] > max) {
|
|
max = arr[i];
|
|
}
|
|
}
|
|
return max;
|
|
},
|
|
|
|
sum: function sum(arr) {
|
|
var length = arr.length,
|
|
sum = 0;
|
|
|
|
while (length--) {
|
|
sum += arr[length];
|
|
}
|
|
return sum;
|
|
}
|
|
};
|
|
|
|
/***/ },
|
|
/* 9 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony default export */ exports["a"] = {
|
|
drawRect: function drawRect(pos, size, ctx, style) {
|
|
ctx.strokeStyle = style.color;
|
|
ctx.fillStyle = style.color;
|
|
ctx.lineWidth = 1;
|
|
ctx.beginPath();
|
|
ctx.strokeRect(pos.x, pos.y, size.x, size.y);
|
|
},
|
|
drawPath: function drawPath(path, def, ctx, style) {
|
|
ctx.strokeStyle = style.color;
|
|
ctx.fillStyle = style.color;
|
|
ctx.lineWidth = style.lineWidth;
|
|
ctx.beginPath();
|
|
ctx.moveTo(path[0][def.x], path[0][def.y]);
|
|
for (var j = 1; j < path.length; j++) {
|
|
ctx.lineTo(path[j][def.x], path[j][def.y]);
|
|
}
|
|
ctx.closePath();
|
|
ctx.stroke();
|
|
},
|
|
drawImage: function drawImage(imageData, size, ctx) {
|
|
var canvasData = ctx.getImageData(0, 0, size.x, size.y),
|
|
data = canvasData.data,
|
|
imageDataPos = imageData.length,
|
|
canvasDataPos = data.length,
|
|
value;
|
|
|
|
if (canvasDataPos / imageDataPos !== 4) {
|
|
return false;
|
|
}
|
|
while (imageDataPos--) {
|
|
value = imageData[imageDataPos];
|
|
data[--canvasDataPos] = 255;
|
|
data[--canvasDataPos] = value;
|
|
data[--canvasDataPos] = value;
|
|
data[--canvasDataPos] = value;
|
|
}
|
|
ctx.putImageData(canvasData, 0, 0);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/***/ },
|
|
/* 10 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__barcode_reader__ = __webpack_require__(5);
|
|
|
|
|
|
function EANReader(opts) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].call(this, opts);
|
|
}
|
|
|
|
var properties = {
|
|
CODE_L_START: { value: 0 },
|
|
MODULO: { value: 7 },
|
|
CODE_G_START: { value: 10 },
|
|
START_PATTERN: { value: [1 / 3 * 7, 1 / 3 * 7, 1 / 3 * 7] },
|
|
STOP_PATTERN: { value: [1 / 3 * 7, 1 / 3 * 7, 1 / 3 * 7] },
|
|
MIDDLE_PATTERN: { value: [1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7] },
|
|
CODE_PATTERN: { value: [[3, 2, 1, 1], [2, 2, 2, 1], [2, 1, 2, 2], [1, 4, 1, 1], [1, 1, 3, 2], [1, 2, 3, 1], [1, 1, 1, 4], [1, 3, 1, 2], [1, 2, 1, 3], [3, 1, 1, 2], [1, 1, 2, 3], [1, 2, 2, 2], [2, 2, 1, 2], [1, 1, 4, 1], [2, 3, 1, 1], [1, 3, 2, 1], [4, 1, 1, 1], [2, 1, 3, 1], [3, 1, 2, 1], [2, 1, 1, 3]] },
|
|
CODE_FREQUENCY: { value: [0, 11, 13, 14, 19, 25, 28, 21, 22, 26] },
|
|
SINGLE_CODE_ERROR: { value: 0.67 },
|
|
AVG_CODE_ERROR: { value: 0.27 },
|
|
FORMAT: { value: "ean_13", writeable: false }
|
|
};
|
|
|
|
EANReader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].prototype, properties);
|
|
EANReader.prototype.constructor = EANReader;
|
|
|
|
EANReader.prototype._decodeCode = function (start, coderange) {
|
|
var counter = [0, 0, 0, 0],
|
|
i,
|
|
self = this,
|
|
offset = start,
|
|
isWhite = !self._row[offset],
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: start,
|
|
end: start
|
|
},
|
|
code,
|
|
error,
|
|
normalized;
|
|
|
|
if (!coderange) {
|
|
coderange = self.CODE_PATTERN.length;
|
|
}
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
for (code = 0; code < coderange; code++) {
|
|
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
|
|
if (error < bestMatch.error) {
|
|
bestMatch.code = code;
|
|
bestMatch.error = error;
|
|
}
|
|
}
|
|
bestMatch.end = i;
|
|
if (bestMatch.error > self.AVG_CODE_ERROR) {
|
|
return null;
|
|
}
|
|
return bestMatch;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
EANReader.prototype._findPattern = function (pattern, offset, isWhite, tryHarder, epsilon) {
|
|
var counter = [],
|
|
self = this,
|
|
i,
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0,
|
|
end: 0
|
|
},
|
|
error,
|
|
j,
|
|
sum,
|
|
normalized;
|
|
|
|
if (!offset) {
|
|
offset = self._nextSet(self._row);
|
|
}
|
|
|
|
if (isWhite === undefined) {
|
|
isWhite = false;
|
|
}
|
|
|
|
if (tryHarder === undefined) {
|
|
tryHarder = true;
|
|
}
|
|
|
|
if (epsilon === undefined) {
|
|
epsilon = self.AVG_CODE_ERROR;
|
|
}
|
|
|
|
for (i = 0; i < pattern.length; i++) {
|
|
counter[i] = 0;
|
|
}
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
sum = 0;
|
|
for (j = 0; j < counter.length; j++) {
|
|
sum += counter[j];
|
|
}
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
error = self._matchPattern(normalized, pattern);
|
|
|
|
if (error < epsilon) {
|
|
bestMatch.error = error;
|
|
bestMatch.start = i - sum;
|
|
bestMatch.end = i;
|
|
return bestMatch;
|
|
}
|
|
}
|
|
if (tryHarder) {
|
|
for (j = 0; j < counter.length - 2; j++) {
|
|
counter[j] = counter[j + 2];
|
|
}
|
|
counter[counter.length - 2] = 0;
|
|
counter[counter.length - 1] = 0;
|
|
counterPos--;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
EANReader.prototype._findStart = function () {
|
|
var self = this,
|
|
leadingWhitespaceStart,
|
|
offset = self._nextSet(self._row),
|
|
startInfo;
|
|
|
|
while (!startInfo) {
|
|
startInfo = self._findPattern(self.START_PATTERN, offset);
|
|
if (!startInfo) {
|
|
return null;
|
|
}
|
|
leadingWhitespaceStart = startInfo.start - (startInfo.end - startInfo.start);
|
|
if (leadingWhitespaceStart >= 0) {
|
|
if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) {
|
|
return startInfo;
|
|
}
|
|
}
|
|
offset = startInfo.end;
|
|
startInfo = null;
|
|
}
|
|
};
|
|
|
|
EANReader.prototype._verifyTrailingWhitespace = function (endInfo) {
|
|
var self = this,
|
|
trailingWhitespaceEnd;
|
|
|
|
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start);
|
|
if (trailingWhitespaceEnd < self._row.length) {
|
|
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
|
|
return endInfo;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
EANReader.prototype._findEnd = function (offset, isWhite) {
|
|
var self = this,
|
|
endInfo = self._findPattern(self.STOP_PATTERN, offset, isWhite, false);
|
|
|
|
return endInfo !== null ? self._verifyTrailingWhitespace(endInfo) : null;
|
|
};
|
|
|
|
EANReader.prototype._calculateFirstDigit = function (codeFrequency) {
|
|
var i,
|
|
self = this;
|
|
|
|
for (i = 0; i < self.CODE_FREQUENCY.length; i++) {
|
|
if (codeFrequency === self.CODE_FREQUENCY[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
EANReader.prototype._decodePayload = function (code, result, decodedCodes) {
|
|
var i,
|
|
self = this,
|
|
codeFrequency = 0x0,
|
|
firstDigit;
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
code = self._decodeCode(code.end);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
if (code.code >= self.CODE_G_START) {
|
|
code.code = code.code - self.CODE_G_START;
|
|
codeFrequency |= 1 << 5 - i;
|
|
} else {
|
|
codeFrequency |= 0 << 5 - i;
|
|
}
|
|
result.push(code.code);
|
|
decodedCodes.push(code);
|
|
}
|
|
|
|
firstDigit = self._calculateFirstDigit(codeFrequency);
|
|
if (firstDigit === null) {
|
|
return null;
|
|
}
|
|
result.unshift(firstDigit);
|
|
|
|
code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false);
|
|
if (code === null) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(code);
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
code = self._decodeCode(code.end, self.CODE_G_START);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(code);
|
|
result.push(code.code);
|
|
}
|
|
|
|
return code;
|
|
};
|
|
|
|
EANReader.prototype._decode = function () {
|
|
var startInfo,
|
|
self = this,
|
|
code,
|
|
result = [],
|
|
decodedCodes = [];
|
|
|
|
startInfo = self._findStart();
|
|
if (!startInfo) {
|
|
return null;
|
|
}
|
|
code = {
|
|
code: startInfo.code,
|
|
start: startInfo.start,
|
|
end: startInfo.end
|
|
};
|
|
decodedCodes.push(code);
|
|
code = self._decodePayload(code, result, decodedCodes);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
code = self._findEnd(code.end, false);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
|
|
decodedCodes.push(code);
|
|
|
|
// Checksum
|
|
if (!self._checksum(result)) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
code: result.join(""),
|
|
start: startInfo.start,
|
|
end: code.end,
|
|
codeset: "",
|
|
startInfo: startInfo,
|
|
decodedCodes: decodedCodes
|
|
};
|
|
};
|
|
|
|
EANReader.prototype._checksum = function (result) {
|
|
var sum = 0,
|
|
i;
|
|
|
|
for (i = result.length - 2; i >= 0; i -= 2) {
|
|
sum += result[i];
|
|
}
|
|
sum *= 3;
|
|
for (i = result.length - 1; i >= 0; i -= 2) {
|
|
sum += result[i];
|
|
}
|
|
return sum % 10 === 0;
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = EANReader;
|
|
|
|
/***/ },
|
|
/* 11 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var eq = __webpack_require__(15);
|
|
|
|
/**
|
|
* Gets the index at which the first occurrence of `key` is found in `array`
|
|
* of key-value pairs.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to search.
|
|
* @param {*} key The key to search for.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function assocIndexOf(array, key) {
|
|
var length = array.length;
|
|
while (length--) {
|
|
if (eq(array[length][0], key)) {
|
|
return length;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
module.e = assocIndexOf;
|
|
|
|
|
|
/***/ },
|
|
/* 12 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isNative = __webpack_require__(140);
|
|
|
|
/**
|
|
* Gets the native function at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {string} key The key of the method to get.
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|
*/
|
|
function getNative(object, key) {
|
|
var value = object[key];
|
|
return isNative(value) ? value : undefined;
|
|
}
|
|
|
|
module.e = getNative;
|
|
|
|
|
|
/***/ },
|
|
/* 13 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Checks if `value` is suitable for use as unique object key.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
|
*/
|
|
function isKeyable(value) {
|
|
var type = typeof value;
|
|
return type == 'number' || type == 'boolean' ||
|
|
(type == 'string' && value != '__proto__') || value == null;
|
|
}
|
|
|
|
module.e = isKeyable;
|
|
|
|
|
|
/***/ },
|
|
/* 14 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var getNative = __webpack_require__(12);
|
|
|
|
/* Built-in method references that are verified to be native. */
|
|
var nativeCreate = getNative(Object, 'create');
|
|
|
|
module.e = nativeCreate;
|
|
|
|
|
|
/***/ },
|
|
/* 15 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
|
|
* comparison between two values to determine if they are equivalent.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'user': 'fred' };
|
|
* var other = { 'user': 'fred' };
|
|
*
|
|
* _.eq(object, object);
|
|
* // => true
|
|
*
|
|
* _.eq(object, other);
|
|
* // => false
|
|
*
|
|
* _.eq('a', 'a');
|
|
* // => true
|
|
*
|
|
* _.eq('a', Object('a'));
|
|
* // => false
|
|
*
|
|
* _.eq(NaN, NaN);
|
|
* // => true
|
|
*/
|
|
function eq(value, other) {
|
|
return value === other || (value !== value && other !== other);
|
|
}
|
|
|
|
module.e = eq;
|
|
|
|
|
|
/***/ },
|
|
/* 16 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isObject = __webpack_require__(2);
|
|
|
|
/** `Object#toString` result references. */
|
|
var funcTag = '[object Function]',
|
|
genTag = '[object GeneratorFunction]';
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objectToString = objectProto.toString;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Function` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isFunction(_);
|
|
* // => true
|
|
*
|
|
* _.isFunction(/abc/);
|
|
* // => false
|
|
*/
|
|
function isFunction(value) {
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|
// in Safari 8 which returns 'object' for typed array and weak map constructors,
|
|
// and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
|
|
var tag = isObject(value) ? objectToString.call(value) : '';
|
|
return tag == funcTag || tag == genTag;
|
|
}
|
|
|
|
module.e = isFunction;
|
|
|
|
|
|
/***/ },
|
|
/* 17 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__cluster__ = __webpack_require__(51);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__array_helper__ = __webpack_require__(8);
|
|
/* harmony export */ exports["f"] = imageRef;/* unused harmony export computeIntegralImage2 *//* unused harmony export computeIntegralImage *//* unused harmony export thresholdImage *//* unused harmony export computeHistogram *//* unused harmony export sharpenLine *//* unused harmony export determineOtsuThreshold *//* harmony export */ exports["c"] = otsuThreshold;/* unused harmony export computeBinaryImage *//* harmony export */ exports["d"] = cluster;/* unused harmony export dilate *//* unused harmony export erode *//* unused harmony export subtract *//* unused harmony export bitwiseOr *//* unused harmony export countNonZero *//* harmony export */ exports["e"] = topGeneric;/* unused harmony export grayArrayFromImage *//* unused harmony export grayArrayFromContext *//* harmony export */ exports["i"] = grayAndHalfSampleFromCanvasData;/* harmony export */ exports["j"] = computeGray;/* unused harmony export loadImageArray *//* harmony export */ exports["g"] = halfSample;/* harmony export */ exports["a"] = hsv2rgb;/* unused harmony export _computeDivisors *//* harmony export */ exports["b"] = calculatePatchSize;/* unused harmony export _parseCSSDimensionValues *//* harmony export */ exports["h"] = computeImageArea;
|
|
|
|
var vec2 = {
|
|
clone: __webpack_require__(6)
|
|
};
|
|
var vec3 = {
|
|
clone: __webpack_require__(78)
|
|
};
|
|
|
|
/**
|
|
* @param x x-coordinate
|
|
* @param y y-coordinate
|
|
* @return ImageReference {x,y} Coordinate
|
|
*/
|
|
function imageRef(x, y) {
|
|
var that = {
|
|
x: x,
|
|
y: y,
|
|
toVec2: function toVec2() {
|
|
return vec2.clone([this.x, this.y]);
|
|
},
|
|
toVec3: function toVec3() {
|
|
return vec3.clone([this.x, this.y, 1]);
|
|
},
|
|
round: function round() {
|
|
this.x = this.x > 0.0 ? Math.floor(this.x + 0.5) : Math.floor(this.x - 0.5);
|
|
this.y = this.y > 0.0 ? Math.floor(this.y + 0.5) : Math.floor(this.y - 0.5);
|
|
return this;
|
|
}
|
|
};
|
|
return that;
|
|
};
|
|
|
|
/**
|
|
* Computes an integral image of a given grayscale image.
|
|
* @param imageDataContainer {ImageDataContainer} the image to be integrated
|
|
*/
|
|
function computeIntegralImage2(imageWrapper, integralWrapper) {
|
|
var imageData = imageWrapper.data;
|
|
var width = imageWrapper.size.x;
|
|
var height = imageWrapper.size.y;
|
|
var integralImageData = integralWrapper.data;
|
|
var sum = 0,
|
|
posA = 0,
|
|
posB = 0,
|
|
posC = 0,
|
|
posD = 0,
|
|
x,
|
|
y;
|
|
|
|
// sum up first column
|
|
posB = width;
|
|
sum = 0;
|
|
for (y = 1; y < height; y++) {
|
|
sum += imageData[posA];
|
|
integralImageData[posB] += sum;
|
|
posA += width;
|
|
posB += width;
|
|
}
|
|
|
|
posA = 0;
|
|
posB = 1;
|
|
sum = 0;
|
|
for (x = 1; x < width; x++) {
|
|
sum += imageData[posA];
|
|
integralImageData[posB] += sum;
|
|
posA++;
|
|
posB++;
|
|
}
|
|
|
|
for (y = 1; y < height; y++) {
|
|
posA = y * width + 1;
|
|
posB = (y - 1) * width + 1;
|
|
posC = y * width;
|
|
posD = (y - 1) * width;
|
|
for (x = 1; x < width; x++) {
|
|
integralImageData[posA] += imageData[posA] + integralImageData[posB] + integralImageData[posC] - integralImageData[posD];
|
|
posA++;
|
|
posB++;
|
|
posC++;
|
|
posD++;
|
|
}
|
|
}
|
|
};
|
|
|
|
function computeIntegralImage(imageWrapper, integralWrapper) {
|
|
var imageData = imageWrapper.data;
|
|
var width = imageWrapper.size.x;
|
|
var height = imageWrapper.size.y;
|
|
var integralImageData = integralWrapper.data;
|
|
var sum = 0;
|
|
|
|
// sum up first row
|
|
for (var i = 0; i < width; i++) {
|
|
sum += imageData[i];
|
|
integralImageData[i] = sum;
|
|
}
|
|
|
|
for (var v = 1; v < height; v++) {
|
|
sum = 0;
|
|
for (var u = 0; u < width; u++) {
|
|
sum += imageData[v * width + u];
|
|
integralImageData[v * width + u] = sum + integralImageData[(v - 1) * width + u];
|
|
}
|
|
}
|
|
};
|
|
|
|
function thresholdImage(imageWrapper, threshold, targetWrapper) {
|
|
if (!targetWrapper) {
|
|
targetWrapper = imageWrapper;
|
|
}
|
|
var imageData = imageWrapper.data,
|
|
length = imageData.length,
|
|
targetData = targetWrapper.data;
|
|
|
|
while (length--) {
|
|
targetData[length] = imageData[length] < threshold ? 1 : 0;
|
|
}
|
|
};
|
|
|
|
function computeHistogram(imageWrapper, bitsPerPixel) {
|
|
if (!bitsPerPixel) {
|
|
bitsPerPixel = 8;
|
|
}
|
|
var imageData = imageWrapper.data,
|
|
length = imageData.length,
|
|
bitShift = 8 - bitsPerPixel,
|
|
bucketCnt = 1 << bitsPerPixel,
|
|
hist = new Int32Array(bucketCnt);
|
|
|
|
while (length--) {
|
|
hist[imageData[length] >> bitShift]++;
|
|
}
|
|
return hist;
|
|
};
|
|
|
|
function sharpenLine(line) {
|
|
var i,
|
|
length = line.length,
|
|
left = line[0],
|
|
center = line[1],
|
|
right;
|
|
|
|
for (i = 1; i < length - 1; i++) {
|
|
right = line[i + 1];
|
|
// -1 4 -1 kernel
|
|
line[i - 1] = center * 2 - left - right & 255;
|
|
left = center;
|
|
center = right;
|
|
}
|
|
return line;
|
|
};
|
|
|
|
function determineOtsuThreshold(imageWrapper, bitsPerPixel) {
|
|
if (!bitsPerPixel) {
|
|
bitsPerPixel = 8;
|
|
}
|
|
var hist,
|
|
threshold,
|
|
bitShift = 8 - bitsPerPixel;
|
|
|
|
function px(init, end) {
|
|
var sum = 0,
|
|
i;
|
|
for (i = init; i <= end; i++) {
|
|
sum += hist[i];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
function mx(init, end) {
|
|
var i,
|
|
sum = 0;
|
|
|
|
for (i = init; i <= end; i++) {
|
|
sum += i * hist[i];
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
function determineThreshold() {
|
|
var vet = [0],
|
|
p1,
|
|
p2,
|
|
p12,
|
|
k,
|
|
m1,
|
|
m2,
|
|
m12,
|
|
max = (1 << bitsPerPixel) - 1;
|
|
|
|
hist = computeHistogram(imageWrapper, bitsPerPixel);
|
|
for (k = 1; k < max; k++) {
|
|
p1 = px(0, k);
|
|
p2 = px(k + 1, max);
|
|
p12 = p1 * p2;
|
|
if (p12 === 0) {
|
|
p12 = 1;
|
|
}
|
|
m1 = mx(0, k) * p2;
|
|
m2 = mx(k + 1, max) * p1;
|
|
m12 = m1 - m2;
|
|
vet[k] = m12 * m12 / p12;
|
|
}
|
|
return /* harmony import */__WEBPACK_IMPORTED_MODULE_1__array_helper__["a"].maxIndex(vet);
|
|
}
|
|
|
|
threshold = determineThreshold();
|
|
return threshold << bitShift;
|
|
};
|
|
|
|
function otsuThreshold(imageWrapper, targetWrapper) {
|
|
var threshold = determineOtsuThreshold(imageWrapper);
|
|
|
|
thresholdImage(imageWrapper, threshold, targetWrapper);
|
|
return threshold;
|
|
};
|
|
|
|
// local thresholding
|
|
function computeBinaryImage(imageWrapper, integralWrapper, targetWrapper) {
|
|
computeIntegralImage(imageWrapper, integralWrapper);
|
|
|
|
if (!targetWrapper) {
|
|
targetWrapper = imageWrapper;
|
|
}
|
|
var imageData = imageWrapper.data;
|
|
var targetData = targetWrapper.data;
|
|
var width = imageWrapper.size.x;
|
|
var height = imageWrapper.size.y;
|
|
var integralImageData = integralWrapper.data;
|
|
var sum = 0,
|
|
v,
|
|
u,
|
|
kernel = 3,
|
|
A,
|
|
B,
|
|
C,
|
|
D,
|
|
avg,
|
|
size = (kernel * 2 + 1) * (kernel * 2 + 1);
|
|
|
|
// clear out top & bottom-border
|
|
for (v = 0; v <= kernel; v++) {
|
|
for (u = 0; u < width; u++) {
|
|
targetData[v * width + u] = 0;
|
|
targetData[(height - 1 - v) * width + u] = 0;
|
|
}
|
|
}
|
|
|
|
// clear out left & right border
|
|
for (v = kernel; v < height - kernel; v++) {
|
|
for (u = 0; u <= kernel; u++) {
|
|
targetData[v * width + u] = 0;
|
|
targetData[v * width + (width - 1 - u)] = 0;
|
|
}
|
|
}
|
|
|
|
for (v = kernel + 1; v < height - kernel - 1; v++) {
|
|
for (u = kernel + 1; u < width - kernel; u++) {
|
|
A = integralImageData[(v - kernel - 1) * width + (u - kernel - 1)];
|
|
B = integralImageData[(v - kernel - 1) * width + (u + kernel)];
|
|
C = integralImageData[(v + kernel) * width + (u - kernel - 1)];
|
|
D = integralImageData[(v + kernel) * width + (u + kernel)];
|
|
sum = D - C - B + A;
|
|
avg = sum / size;
|
|
targetData[v * width + u] = imageData[v * width + u] > avg + 5 ? 0 : 1;
|
|
}
|
|
}
|
|
};
|
|
|
|
function cluster(points, threshold, property) {
|
|
var i,
|
|
k,
|
|
cluster,
|
|
point,
|
|
clusters = [];
|
|
|
|
if (!property) {
|
|
property = "rad";
|
|
}
|
|
|
|
function addToCluster(newPoint) {
|
|
var found = false;
|
|
for (k = 0; k < clusters.length; k++) {
|
|
cluster = clusters[k];
|
|
if (cluster.fits(newPoint)) {
|
|
cluster.add(newPoint);
|
|
found = true;
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
// iterate over each cloud
|
|
for (i = 0; i < points.length; i++) {
|
|
point = /* harmony import */__WEBPACK_IMPORTED_MODULE_0__cluster__["a"].createPoint(points[i], i, property);
|
|
if (!addToCluster(point)) {
|
|
clusters.push(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__cluster__["a"].create(point, threshold));
|
|
}
|
|
}
|
|
return clusters;
|
|
};
|
|
|
|
var Tracer = {
|
|
trace: function trace(points, vec) {
|
|
var iteration,
|
|
maxIterations = 10,
|
|
top = [],
|
|
result = [],
|
|
centerPos = 0,
|
|
currentPos = 0;
|
|
|
|
function trace(idx, forward) {
|
|
var from,
|
|
to,
|
|
toIdx,
|
|
predictedPos,
|
|
thresholdX = 1,
|
|
thresholdY = Math.abs(vec[1] / 10),
|
|
found = false;
|
|
|
|
function match(pos, predicted) {
|
|
if (pos.x > predicted.x - thresholdX && pos.x < predicted.x + thresholdX && pos.y > predicted.y - thresholdY && pos.y < predicted.y + thresholdY) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// check if the next index is within the vec specifications
|
|
// if not, check as long as the threshold is met
|
|
|
|
from = points[idx];
|
|
if (forward) {
|
|
predictedPos = {
|
|
x: from.x + vec[0],
|
|
y: from.y + vec[1]
|
|
};
|
|
} else {
|
|
predictedPos = {
|
|
x: from.x - vec[0],
|
|
y: from.y - vec[1]
|
|
};
|
|
}
|
|
|
|
toIdx = forward ? idx + 1 : idx - 1;
|
|
to = points[toIdx];
|
|
while (to && (found = match(to, predictedPos)) !== true && Math.abs(to.y - from.y) < vec[1]) {
|
|
toIdx = forward ? toIdx + 1 : toIdx - 1;
|
|
to = points[toIdx];
|
|
}
|
|
|
|
return found ? toIdx : null;
|
|
}
|
|
|
|
for (iteration = 0; iteration < maxIterations; iteration++) {
|
|
// randomly select point to start with
|
|
centerPos = Math.floor(Math.random() * points.length);
|
|
|
|
// trace forward
|
|
top = [];
|
|
currentPos = centerPos;
|
|
top.push(points[currentPos]);
|
|
while ((currentPos = trace(currentPos, true)) !== null) {
|
|
top.push(points[currentPos]);
|
|
}
|
|
if (centerPos > 0) {
|
|
currentPos = centerPos;
|
|
while ((currentPos = trace(currentPos, false)) !== null) {
|
|
top.push(points[currentPos]);
|
|
}
|
|
}
|
|
|
|
if (top.length > result.length) {
|
|
result = top;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
};/* unused harmony export Tracer */
|
|
|
|
var DILATE = 1;/* unused harmony export DILATE */
|
|
var ERODE = 2;/* unused harmony export ERODE */
|
|
|
|
function dilate(inImageWrapper, outImageWrapper) {
|
|
var v,
|
|
u,
|
|
inImageData = inImageWrapper.data,
|
|
outImageData = outImageWrapper.data,
|
|
height = inImageWrapper.size.y,
|
|
width = inImageWrapper.size.x,
|
|
sum,
|
|
yStart1,
|
|
yStart2,
|
|
xStart1,
|
|
xStart2;
|
|
|
|
for (v = 1; v < height - 1; v++) {
|
|
for (u = 1; u < width - 1; u++) {
|
|
yStart1 = v - 1;
|
|
yStart2 = v + 1;
|
|
xStart1 = u - 1;
|
|
xStart2 = u + 1;
|
|
sum = inImageData[yStart1 * width + xStart1] + inImageData[yStart1 * width + xStart2] + inImageData[v * width + u] + inImageData[yStart2 * width + xStart1] + inImageData[yStart2 * width + xStart2];
|
|
outImageData[v * width + u] = sum > 0 ? 1 : 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
function erode(inImageWrapper, outImageWrapper) {
|
|
var v,
|
|
u,
|
|
inImageData = inImageWrapper.data,
|
|
outImageData = outImageWrapper.data,
|
|
height = inImageWrapper.size.y,
|
|
width = inImageWrapper.size.x,
|
|
sum,
|
|
yStart1,
|
|
yStart2,
|
|
xStart1,
|
|
xStart2;
|
|
|
|
for (v = 1; v < height - 1; v++) {
|
|
for (u = 1; u < width - 1; u++) {
|
|
yStart1 = v - 1;
|
|
yStart2 = v + 1;
|
|
xStart1 = u - 1;
|
|
xStart2 = u + 1;
|
|
sum = inImageData[yStart1 * width + xStart1] + inImageData[yStart1 * width + xStart2] + inImageData[v * width + u] + inImageData[yStart2 * width + xStart1] + inImageData[yStart2 * width + xStart2];
|
|
outImageData[v * width + u] = sum === 5 ? 1 : 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
function subtract(aImageWrapper, bImageWrapper, resultImageWrapper) {
|
|
if (!resultImageWrapper) {
|
|
resultImageWrapper = aImageWrapper;
|
|
}
|
|
var length = aImageWrapper.data.length,
|
|
aImageData = aImageWrapper.data,
|
|
bImageData = bImageWrapper.data,
|
|
cImageData = resultImageWrapper.data;
|
|
|
|
while (length--) {
|
|
cImageData[length] = aImageData[length] - bImageData[length];
|
|
}
|
|
};
|
|
|
|
function bitwiseOr(aImageWrapper, bImageWrapper, resultImageWrapper) {
|
|
if (!resultImageWrapper) {
|
|
resultImageWrapper = aImageWrapper;
|
|
}
|
|
var length = aImageWrapper.data.length,
|
|
aImageData = aImageWrapper.data,
|
|
bImageData = bImageWrapper.data,
|
|
cImageData = resultImageWrapper.data;
|
|
|
|
while (length--) {
|
|
cImageData[length] = aImageData[length] || bImageData[length];
|
|
}
|
|
};
|
|
|
|
function countNonZero(imageWrapper) {
|
|
var length = imageWrapper.data.length,
|
|
data = imageWrapper.data,
|
|
sum = 0;
|
|
|
|
while (length--) {
|
|
sum += data[length];
|
|
}
|
|
return sum;
|
|
};
|
|
|
|
function topGeneric(list, top, scoreFunc) {
|
|
var i,
|
|
minIdx = 0,
|
|
min = 0,
|
|
queue = [],
|
|
score,
|
|
hit,
|
|
pos;
|
|
|
|
for (i = 0; i < top; i++) {
|
|
queue[i] = {
|
|
score: 0,
|
|
item: null
|
|
};
|
|
}
|
|
|
|
for (i = 0; i < list.length; i++) {
|
|
score = scoreFunc.apply(this, [list[i]]);
|
|
if (score > min) {
|
|
hit = queue[minIdx];
|
|
hit.score = score;
|
|
hit.item = list[i];
|
|
min = Number.MAX_VALUE;
|
|
for (pos = 0; pos < top; pos++) {
|
|
if (queue[pos].score < min) {
|
|
min = queue[pos].score;
|
|
minIdx = pos;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return queue;
|
|
};
|
|
|
|
function grayArrayFromImage(htmlImage, offsetX, ctx, array) {
|
|
ctx.drawImage(htmlImage, offsetX, 0, htmlImage.width, htmlImage.height);
|
|
var ctxData = ctx.getImageData(offsetX, 0, htmlImage.width, htmlImage.height).data;
|
|
computeGray(ctxData, array);
|
|
};
|
|
|
|
function grayArrayFromContext(ctx, size, offset, array) {
|
|
var ctxData = ctx.getImageData(offset.x, offset.y, size.x, size.y).data;
|
|
computeGray(ctxData, array);
|
|
};
|
|
|
|
function grayAndHalfSampleFromCanvasData(canvasData, size, outArray) {
|
|
var topRowIdx = 0;
|
|
var bottomRowIdx = size.x;
|
|
var endIdx = Math.floor(canvasData.length / 4);
|
|
var outWidth = size.x / 2;
|
|
var outImgIdx = 0;
|
|
var inWidth = size.x;
|
|
var i;
|
|
|
|
while (bottomRowIdx < endIdx) {
|
|
for (i = 0; i < outWidth; i++) {
|
|
outArray[outImgIdx] = Math.floor((0.299 * canvasData[topRowIdx * 4 + 0] + 0.587 * canvasData[topRowIdx * 4 + 1] + 0.114 * canvasData[topRowIdx * 4 + 2] + (0.299 * canvasData[(topRowIdx + 1) * 4 + 0] + 0.587 * canvasData[(topRowIdx + 1) * 4 + 1] + 0.114 * canvasData[(topRowIdx + 1) * 4 + 2]) + (0.299 * canvasData[bottomRowIdx * 4 + 0] + 0.587 * canvasData[bottomRowIdx * 4 + 1] + 0.114 * canvasData[bottomRowIdx * 4 + 2]) + (0.299 * canvasData[(bottomRowIdx + 1) * 4 + 0] + 0.587 * canvasData[(bottomRowIdx + 1) * 4 + 1] + 0.114 * canvasData[(bottomRowIdx + 1) * 4 + 2])) / 4);
|
|
outImgIdx++;
|
|
topRowIdx = topRowIdx + 2;
|
|
bottomRowIdx = bottomRowIdx + 2;
|
|
}
|
|
topRowIdx = topRowIdx + inWidth;
|
|
bottomRowIdx = bottomRowIdx + inWidth;
|
|
}
|
|
};
|
|
|
|
function computeGray(imageData, outArray, config) {
|
|
var l = imageData.length / 4 | 0,
|
|
i,
|
|
singleChannel = config && config.singleChannel === true;
|
|
|
|
if (singleChannel) {
|
|
for (i = 0; i < l; i++) {
|
|
outArray[i] = imageData[i * 4 + 0];
|
|
}
|
|
} else {
|
|
for (i = 0; i < l; i++) {
|
|
outArray[i] = Math.floor(0.299 * imageData[i * 4 + 0] + 0.587 * imageData[i * 4 + 1] + 0.114 * imageData[i * 4 + 2]);
|
|
}
|
|
}
|
|
};
|
|
|
|
function loadImageArray(src, callback, canvas) {
|
|
if (!canvas) {
|
|
canvas = document.createElement('canvas');
|
|
}
|
|
var img = new Image();
|
|
img.callback = callback;
|
|
img.onload = function () {
|
|
canvas.width = this.width;
|
|
canvas.height = this.height;
|
|
var ctx = canvas.getContext('2d');
|
|
ctx.drawImage(this, 0, 0);
|
|
var array = new Uint8Array(this.width * this.height);
|
|
ctx.drawImage(this, 0, 0);
|
|
var data = ctx.getImageData(0, 0, this.width, this.height).data;
|
|
computeGray(data, array);
|
|
this.callback(array, {
|
|
x: this.width,
|
|
y: this.height
|
|
}, this);
|
|
};
|
|
img.src = src;
|
|
};
|
|
|
|
/**
|
|
* @param inImg {ImageWrapper} input image to be sampled
|
|
* @param outImg {ImageWrapper} to be stored in
|
|
*/
|
|
function halfSample(inImgWrapper, outImgWrapper) {
|
|
var inImg = inImgWrapper.data;
|
|
var inWidth = inImgWrapper.size.x;
|
|
var outImg = outImgWrapper.data;
|
|
var topRowIdx = 0;
|
|
var bottomRowIdx = inWidth;
|
|
var endIdx = inImg.length;
|
|
var outWidth = inWidth / 2;
|
|
var outImgIdx = 0;
|
|
while (bottomRowIdx < endIdx) {
|
|
for (var i = 0; i < outWidth; i++) {
|
|
outImg[outImgIdx] = Math.floor((inImg[topRowIdx] + inImg[topRowIdx + 1] + inImg[bottomRowIdx] + inImg[bottomRowIdx + 1]) / 4);
|
|
outImgIdx++;
|
|
topRowIdx = topRowIdx + 2;
|
|
bottomRowIdx = bottomRowIdx + 2;
|
|
}
|
|
topRowIdx = topRowIdx + inWidth;
|
|
bottomRowIdx = bottomRowIdx + inWidth;
|
|
}
|
|
};
|
|
|
|
function hsv2rgb(hsv, rgb) {
|
|
var h = hsv[0],
|
|
s = hsv[1],
|
|
v = hsv[2],
|
|
c = v * s,
|
|
x = c * (1 - Math.abs(h / 60 % 2 - 1)),
|
|
m = v - c,
|
|
r = 0,
|
|
g = 0,
|
|
b = 0;
|
|
|
|
rgb = rgb || [0, 0, 0];
|
|
|
|
if (h < 60) {
|
|
r = c;
|
|
g = x;
|
|
} else if (h < 120) {
|
|
r = x;
|
|
g = c;
|
|
} else if (h < 180) {
|
|
g = c;
|
|
b = x;
|
|
} else if (h < 240) {
|
|
g = x;
|
|
b = c;
|
|
} else if (h < 300) {
|
|
r = x;
|
|
b = c;
|
|
} else if (h < 360) {
|
|
r = c;
|
|
b = x;
|
|
}
|
|
rgb[0] = (r + m) * 255 | 0;
|
|
rgb[1] = (g + m) * 255 | 0;
|
|
rgb[2] = (b + m) * 255 | 0;
|
|
return rgb;
|
|
};
|
|
|
|
function _computeDivisors(n) {
|
|
var largeDivisors = [],
|
|
divisors = [],
|
|
i;
|
|
|
|
for (i = 1; i < Math.sqrt(n) + 1; i++) {
|
|
if (n % i === 0) {
|
|
divisors.push(i);
|
|
if (i !== n / i) {
|
|
largeDivisors.unshift(Math.floor(n / i));
|
|
}
|
|
}
|
|
}
|
|
return divisors.concat(largeDivisors);
|
|
};
|
|
|
|
function _computeIntersection(arr1, arr2) {
|
|
var i = 0,
|
|
j = 0,
|
|
result = [];
|
|
|
|
while (i < arr1.length && j < arr2.length) {
|
|
if (arr1[i] === arr2[j]) {
|
|
result.push(arr1[i]);
|
|
i++;
|
|
j++;
|
|
} else if (arr1[i] > arr2[j]) {
|
|
j++;
|
|
} else {
|
|
i++;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
|
|
function calculatePatchSize(patchSize, imgSize) {
|
|
var divisorsX = _computeDivisors(imgSize.x),
|
|
divisorsY = _computeDivisors(imgSize.y),
|
|
wideSide = Math.max(imgSize.x, imgSize.y),
|
|
common = _computeIntersection(divisorsX, divisorsY),
|
|
nrOfPatchesList = [8, 10, 15, 20, 32, 60, 80],
|
|
nrOfPatchesMap = {
|
|
"x-small": 5,
|
|
"small": 4,
|
|
"medium": 3,
|
|
"large": 2,
|
|
"x-large": 1
|
|
},
|
|
nrOfPatchesIdx = nrOfPatchesMap[patchSize] || nrOfPatchesMap.medium,
|
|
nrOfPatches = nrOfPatchesList[nrOfPatchesIdx],
|
|
desiredPatchSize = Math.floor(wideSide / nrOfPatches),
|
|
optimalPatchSize;
|
|
|
|
function findPatchSizeForDivisors(divisors) {
|
|
var i = 0,
|
|
found = divisors[Math.floor(divisors.length / 2)];
|
|
|
|
while (i < divisors.length - 1 && divisors[i] < desiredPatchSize) {
|
|
i++;
|
|
}
|
|
if (i > 0) {
|
|
if (Math.abs(divisors[i] - desiredPatchSize) > Math.abs(divisors[i - 1] - desiredPatchSize)) {
|
|
found = divisors[i - 1];
|
|
} else {
|
|
found = divisors[i];
|
|
}
|
|
}
|
|
if (desiredPatchSize / found < nrOfPatchesList[nrOfPatchesIdx + 1] / nrOfPatchesList[nrOfPatchesIdx] && desiredPatchSize / found > nrOfPatchesList[nrOfPatchesIdx - 1] / nrOfPatchesList[nrOfPatchesIdx]) {
|
|
return { x: found, y: found };
|
|
}
|
|
return null;
|
|
}
|
|
|
|
optimalPatchSize = findPatchSizeForDivisors(common);
|
|
if (!optimalPatchSize) {
|
|
optimalPatchSize = findPatchSizeForDivisors(_computeDivisors(wideSide));
|
|
if (!optimalPatchSize) {
|
|
optimalPatchSize = findPatchSizeForDivisors(_computeDivisors(desiredPatchSize * nrOfPatches));
|
|
}
|
|
}
|
|
return optimalPatchSize;
|
|
};
|
|
|
|
function _parseCSSDimensionValues(value) {
|
|
var dimension = {
|
|
value: parseFloat(value),
|
|
unit: value.indexOf("%") === value.length - 1 ? "%" : "%"
|
|
};
|
|
|
|
return dimension;
|
|
};
|
|
|
|
var _dimensionsConverters = {
|
|
top: function top(dimension, context) {
|
|
if (dimension.unit === "%") {
|
|
return Math.floor(context.height * (dimension.value / 100));
|
|
}
|
|
},
|
|
right: function right(dimension, context) {
|
|
if (dimension.unit === "%") {
|
|
return Math.floor(context.width - context.width * (dimension.value / 100));
|
|
}
|
|
},
|
|
bottom: function bottom(dimension, context) {
|
|
if (dimension.unit === "%") {
|
|
return Math.floor(context.height - context.height * (dimension.value / 100));
|
|
}
|
|
},
|
|
left: function left(dimension, context) {
|
|
if (dimension.unit === "%") {
|
|
return Math.floor(context.width * (dimension.value / 100));
|
|
}
|
|
}
|
|
};/* unused harmony export _dimensionsConverters */
|
|
|
|
function computeImageArea(inputWidth, inputHeight, area) {
|
|
var context = { width: inputWidth, height: inputHeight };
|
|
|
|
var parsedArea = Object.keys(area).reduce(function (result, key) {
|
|
var value = area[key],
|
|
parsed = _parseCSSDimensionValues(value),
|
|
calculated = _dimensionsConverters[key](parsed, context);
|
|
|
|
result[key] = calculated;
|
|
return result;
|
|
}, {});
|
|
|
|
return {
|
|
sx: parsedArea.left,
|
|
sy: parsedArea.top,
|
|
sw: parsedArea.right - parsedArea.left,
|
|
sh: parsedArea.bottom - parsedArea.top
|
|
};
|
|
};
|
|
|
|
/***/ },
|
|
/* 18 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__subImage__ = __webpack_require__(53);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_cv_utils__ = __webpack_require__(17);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_array_helper__ = __webpack_require__(8);
|
|
|
|
|
|
|
|
var vec2 = {
|
|
clone: __webpack_require__(6)
|
|
};
|
|
|
|
/**
|
|
* Represents a basic image combining the data and size.
|
|
* In addition, some methods for manipulation are contained.
|
|
* @param size {x,y} The size of the image in pixel
|
|
* @param data {Array} If given, a flat array containing the pixel data
|
|
* @param ArrayType {Type} If given, the desired DataType of the Array (may be typed/non-typed)
|
|
* @param initialize {Boolean} Indicating if the array should be initialized on creation.
|
|
* @returns {ImageWrapper}
|
|
*/
|
|
function ImageWrapper(size, data, ArrayType, initialize) {
|
|
if (!data) {
|
|
if (ArrayType) {
|
|
this.data = new ArrayType(size.x * size.y);
|
|
if (ArrayType === Array && initialize) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_2__common_array_helper__["a"].init(this.data, 0);
|
|
}
|
|
} else {
|
|
this.data = new Uint8Array(size.x * size.y);
|
|
if (Uint8Array === Array && initialize) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_2__common_array_helper__["a"].init(this.data, 0);
|
|
}
|
|
}
|
|
} else {
|
|
this.data = data;
|
|
}
|
|
this.size = size;
|
|
}
|
|
|
|
/**
|
|
* tests if a position is within the image with a given offset
|
|
* @param imgRef {x, y} The location to test
|
|
* @param border Number the padding value in pixel
|
|
* @returns {Boolean} true if location inside the image's border, false otherwise
|
|
* @see cvd/image.h
|
|
*/
|
|
ImageWrapper.prototype.inImageWithBorder = function (imgRef, border) {
|
|
return imgRef.x >= border && imgRef.y >= border && imgRef.x < this.size.x - border && imgRef.y < this.size.y - border;
|
|
};
|
|
|
|
/**
|
|
* Performs bilinear sampling
|
|
* @param inImg Image to extract sample from
|
|
* @param x the x-coordinate
|
|
* @param y the y-coordinate
|
|
* @returns the sampled value
|
|
* @see cvd/vision.h
|
|
*/
|
|
ImageWrapper.sample = function (inImg, x, y) {
|
|
var lx = Math.floor(x);
|
|
var ly = Math.floor(y);
|
|
var w = inImg.size.x;
|
|
var base = ly * inImg.size.x + lx;
|
|
var a = inImg.data[base + 0];
|
|
var b = inImg.data[base + 1];
|
|
var c = inImg.data[base + w];
|
|
var d = inImg.data[base + w + 1];
|
|
var e = a - b;
|
|
x -= lx;
|
|
y -= ly;
|
|
|
|
var result = Math.floor(x * (y * (e - c + d) - e) + y * (c - a) + a);
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Initializes a given array. Sets each element to zero.
|
|
* @param array {Array} The array to initialize
|
|
*/
|
|
ImageWrapper.clearArray = function (array) {
|
|
var l = array.length;
|
|
while (l--) {
|
|
array[l] = 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Creates a {SubImage} from the current image ({this}).
|
|
* @param from {ImageRef} The position where to start the {SubImage} from. (top-left corner)
|
|
* @param size {ImageRef} The size of the resulting image
|
|
* @returns {SubImage} A shared part of the original image
|
|
*/
|
|
ImageWrapper.prototype.subImage = function (from, size) {
|
|
return new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__subImage__["a"](from, size, this);
|
|
};
|
|
|
|
/**
|
|
* Creates an {ImageWrapper) and copies the needed underlying image-data area
|
|
* @param imageWrapper {ImageWrapper} The target {ImageWrapper} where the data should be copied
|
|
* @param from {ImageRef} The location where to copy from (top-left location)
|
|
*/
|
|
ImageWrapper.prototype.subImageAsCopy = function (imageWrapper, from) {
|
|
var sizeY = imageWrapper.size.y,
|
|
sizeX = imageWrapper.size.x;
|
|
var x, y;
|
|
for (x = 0; x < sizeX; x++) {
|
|
for (y = 0; y < sizeY; y++) {
|
|
imageWrapper.data[y * sizeX + x] = this.data[(from.y + y) * this.size.x + from.x + x];
|
|
}
|
|
}
|
|
};
|
|
|
|
ImageWrapper.prototype.copyTo = function (imageWrapper) {
|
|
var length = this.data.length,
|
|
srcData = this.data,
|
|
dstData = imageWrapper.data;
|
|
|
|
while (length--) {
|
|
dstData[length] = srcData[length];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Retrieves a given pixel position from the image
|
|
* @param x {Number} The x-position
|
|
* @param y {Number} The y-position
|
|
* @returns {Number} The grayscale value at the pixel-position
|
|
*/
|
|
ImageWrapper.prototype.get = function (x, y) {
|
|
return this.data[y * this.size.x + x];
|
|
};
|
|
|
|
/**
|
|
* Retrieves a given pixel position from the image
|
|
* @param x {Number} The x-position
|
|
* @param y {Number} The y-position
|
|
* @returns {Number} The grayscale value at the pixel-position
|
|
*/
|
|
ImageWrapper.prototype.getSafe = function (x, y) {
|
|
var i;
|
|
|
|
if (!this.indexMapping) {
|
|
this.indexMapping = {
|
|
x: [],
|
|
y: []
|
|
};
|
|
for (i = 0; i < this.size.x; i++) {
|
|
this.indexMapping.x[i] = i;
|
|
this.indexMapping.x[i + this.size.x] = i;
|
|
}
|
|
for (i = 0; i < this.size.y; i++) {
|
|
this.indexMapping.y[i] = i;
|
|
this.indexMapping.y[i + this.size.y] = i;
|
|
}
|
|
}
|
|
return this.data[this.indexMapping.y[y + this.size.y] * this.size.x + this.indexMapping.x[x + this.size.x]];
|
|
};
|
|
|
|
/**
|
|
* Sets a given pixel position in the image
|
|
* @param x {Number} The x-position
|
|
* @param y {Number} The y-position
|
|
* @param value {Number} The grayscale value to set
|
|
* @returns {ImageWrapper} The Image itself (for possible chaining)
|
|
*/
|
|
ImageWrapper.prototype.set = function (x, y, value) {
|
|
this.data[y * this.size.x + x] = value;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Sets the border of the image (1 pixel) to zero
|
|
*/
|
|
ImageWrapper.prototype.zeroBorder = function () {
|
|
var i,
|
|
width = this.size.x,
|
|
height = this.size.y,
|
|
data = this.data;
|
|
for (i = 0; i < width; i++) {
|
|
data[i] = data[(height - 1) * width + i] = 0;
|
|
}
|
|
for (i = 1; i < height - 1; i++) {
|
|
data[i * width] = data[i * width + (width - 1)] = 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Inverts a binary image in place
|
|
*/
|
|
ImageWrapper.prototype.invert = function () {
|
|
var data = this.data,
|
|
length = data.length;
|
|
|
|
while (length--) {
|
|
data[length] = data[length] ? 0 : 1;
|
|
}
|
|
};
|
|
|
|
ImageWrapper.prototype.convolve = function (kernel) {
|
|
var x,
|
|
y,
|
|
kx,
|
|
ky,
|
|
kSize = kernel.length / 2 | 0,
|
|
accu = 0;
|
|
for (y = 0; y < this.size.y; y++) {
|
|
for (x = 0; x < this.size.x; x++) {
|
|
accu = 0;
|
|
for (ky = -kSize; ky <= kSize; ky++) {
|
|
for (kx = -kSize; kx <= kSize; kx++) {
|
|
accu += kernel[ky + kSize][kx + kSize] * this.getSafe(x + kx, y + ky);
|
|
}
|
|
}
|
|
this.data[y * this.size.x + x] = accu;
|
|
}
|
|
}
|
|
};
|
|
|
|
ImageWrapper.prototype.moments = function (labelcount) {
|
|
var data = this.data,
|
|
x,
|
|
y,
|
|
height = this.size.y,
|
|
width = this.size.x,
|
|
val,
|
|
ysq,
|
|
labelsum = [],
|
|
i,
|
|
label,
|
|
mu11,
|
|
mu02,
|
|
mu20,
|
|
x_,
|
|
y_,
|
|
tmp,
|
|
result = [],
|
|
PI = Math.PI,
|
|
PI_4 = PI / 4;
|
|
|
|
if (labelcount <= 0) {
|
|
return result;
|
|
}
|
|
|
|
for (i = 0; i < labelcount; i++) {
|
|
labelsum[i] = {
|
|
m00: 0,
|
|
m01: 0,
|
|
m10: 0,
|
|
m11: 0,
|
|
m02: 0,
|
|
m20: 0,
|
|
theta: 0,
|
|
rad: 0
|
|
};
|
|
}
|
|
|
|
for (y = 0; y < height; y++) {
|
|
ysq = y * y;
|
|
for (x = 0; x < width; x++) {
|
|
val = data[y * width + x];
|
|
if (val > 0) {
|
|
label = labelsum[val - 1];
|
|
label.m00 += 1;
|
|
label.m01 += y;
|
|
label.m10 += x;
|
|
label.m11 += x * y;
|
|
label.m02 += ysq;
|
|
label.m20 += x * x;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < labelcount; i++) {
|
|
label = labelsum[i];
|
|
if (!isNaN(label.m00) && label.m00 !== 0) {
|
|
x_ = label.m10 / label.m00;
|
|
y_ = label.m01 / label.m00;
|
|
mu11 = label.m11 / label.m00 - x_ * y_;
|
|
mu02 = label.m02 / label.m00 - y_ * y_;
|
|
mu20 = label.m20 / label.m00 - x_ * x_;
|
|
tmp = (mu02 - mu20) / (2 * mu11);
|
|
tmp = 0.5 * Math.atan(tmp) + (mu11 >= 0 ? PI_4 : -PI_4) + PI;
|
|
label.theta = (tmp * 180 / PI + 90) % 180 - 90;
|
|
if (label.theta < 0) {
|
|
label.theta += 180;
|
|
}
|
|
label.rad = tmp > PI ? tmp - PI : tmp;
|
|
label.vec = vec2.clone([Math.cos(tmp), Math.sin(tmp)]);
|
|
result.push(label);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Displays the {ImageWrapper} in a given canvas
|
|
* @param canvas {Canvas} The canvas element to write to
|
|
* @param scale {Number} Scale which is applied to each pixel-value
|
|
*/
|
|
ImageWrapper.prototype.show = function (canvas, scale) {
|
|
var ctx, frame, data, current, pixel, x, y;
|
|
|
|
if (!scale) {
|
|
scale = 1.0;
|
|
}
|
|
ctx = canvas.getContext('2d');
|
|
canvas.width = this.size.x;
|
|
canvas.height = this.size.y;
|
|
frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
data = frame.data;
|
|
current = 0;
|
|
for (y = 0; y < this.size.y; y++) {
|
|
for (x = 0; x < this.size.x; x++) {
|
|
pixel = y * this.size.x + x;
|
|
current = this.get(x, y) * scale;
|
|
data[pixel * 4 + 0] = current;
|
|
data[pixel * 4 + 1] = current;
|
|
data[pixel * 4 + 2] = current;
|
|
data[pixel * 4 + 3] = 255;
|
|
}
|
|
}
|
|
//frame.data = data;
|
|
ctx.putImageData(frame, 0, 0);
|
|
};
|
|
|
|
/**
|
|
* Displays the {SubImage} in a given canvas
|
|
* @param canvas {Canvas} The canvas element to write to
|
|
* @param scale {Number} Scale which is applied to each pixel-value
|
|
*/
|
|
ImageWrapper.prototype.overlay = function (canvas, scale, from) {
|
|
if (!scale || scale < 0 || scale > 360) {
|
|
scale = 360;
|
|
}
|
|
var hsv = [0, 1, 1];
|
|
var rgb = [0, 0, 0];
|
|
var whiteRgb = [255, 255, 255];
|
|
var blackRgb = [0, 0, 0];
|
|
var result = [];
|
|
var ctx = canvas.getContext('2d');
|
|
var frame = ctx.getImageData(from.x, from.y, this.size.x, this.size.y);
|
|
var data = frame.data;
|
|
var length = this.data.length;
|
|
while (length--) {
|
|
hsv[0] = this.data[length] * scale;
|
|
result = hsv[0] <= 0 ? whiteRgb : hsv[0] >= 360 ? blackRgb : /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["a"].bind()(hsv, rgb);
|
|
data[length * 4 + 0] = result[0];
|
|
data[length * 4 + 1] = result[1];
|
|
data[length * 4 + 2] = result[2];
|
|
data[length * 4 + 3] = 255;
|
|
}
|
|
ctx.putImageData(frame, from.x, from.y);
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = ImageWrapper;
|
|
|
|
/***/ },
|
|
/* 19 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* A specialized version of `_.reduce` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
*/
|
|
function arrayReduce(array, iteratee, accumulator, initAccum) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
if (initAccum && length) {
|
|
accumulator = array[++index];
|
|
}
|
|
while (++index < length) {
|
|
accumulator = iteratee(accumulator, array[index], index, array);
|
|
}
|
|
return accumulator;
|
|
}
|
|
|
|
module.e = arrayReduce;
|
|
|
|
|
|
/***/ },
|
|
/* 20 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var copyObjectWith = __webpack_require__(111);
|
|
|
|
/**
|
|
* Copies properties of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy properties from.
|
|
* @param {Array} props The property names to copy.
|
|
* @param {Object} [object={}] The object to copy properties to.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copyObject(source, props, object) {
|
|
return copyObjectWith(source, props, object);
|
|
}
|
|
|
|
module.e = copyObject;
|
|
|
|
|
|
/***/ },
|
|
/* 21 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Checks if `value` is a host object in IE < 9.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
|
|
*/
|
|
function isHostObject(value) {
|
|
// Many host objects are `Object` objects that can coerce to strings
|
|
// despite having improperly defined `toString` methods.
|
|
var result = false;
|
|
if (value != null && typeof value.toString != 'function') {
|
|
try {
|
|
result = !!(value + '');
|
|
} catch (e) {}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.e = isHostObject;
|
|
|
|
|
|
/***/ },
|
|
/* 22 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/** Used as references for various `Number` constants. */
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
/** Used to detect unsigned integer values. */
|
|
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like index.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|
*/
|
|
function isIndex(value, length) {
|
|
value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|
return value > -1 && value % 1 == 0 && value < length;
|
|
}
|
|
|
|
module.e = isIndex;
|
|
|
|
|
|
/***/ },
|
|
/* 23 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Checks if `value` is likely a prototype object.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|
*/
|
|
function isPrototype(value) {
|
|
var Ctor = value && value.constructor,
|
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
|
|
|
|
return value === proto;
|
|
}
|
|
|
|
module.e = isPrototype;
|
|
|
|
|
|
/***/ },
|
|
/* 24 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isArrayLikeObject = __webpack_require__(26);
|
|
|
|
/** `Object#toString` result references. */
|
|
var argsTag = '[object Arguments]';
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objectToString = objectProto.toString;
|
|
|
|
/** Built-in value references. */
|
|
var propertyIsEnumerable = objectProto.propertyIsEnumerable;
|
|
|
|
/**
|
|
* Checks if `value` is likely an `arguments` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArguments(function() { return arguments; }());
|
|
* // => true
|
|
*
|
|
* _.isArguments([1, 2, 3]);
|
|
* // => false
|
|
*/
|
|
function isArguments(value) {
|
|
// Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
|
|
return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
|
|
(!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
|
|
}
|
|
|
|
module.e = isArguments;
|
|
|
|
|
|
/***/ },
|
|
/* 25 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var getLength = __webpack_require__(115),
|
|
isFunction = __webpack_require__(16),
|
|
isLength = __webpack_require__(27);
|
|
|
|
/**
|
|
* Checks if `value` is array-like. A value is considered array-like if it's
|
|
* not a function and has a `value.length` that's an integer greater than or
|
|
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArrayLike([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArrayLike(document.body.children);
|
|
* // => true
|
|
*
|
|
* _.isArrayLike('abc');
|
|
* // => true
|
|
*
|
|
* _.isArrayLike(_.noop);
|
|
* // => false
|
|
*/
|
|
function isArrayLike(value) {
|
|
return value != null && isLength(getLength(value)) && !isFunction(value);
|
|
}
|
|
|
|
module.e = isArrayLike;
|
|
|
|
|
|
/***/ },
|
|
/* 26 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isArrayLike = __webpack_require__(25),
|
|
isObjectLike = __webpack_require__(7);
|
|
|
|
/**
|
|
* This method is like `_.isArrayLike` except that it also checks if `value`
|
|
* is an object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArrayLikeObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArrayLikeObject(document.body.children);
|
|
* // => true
|
|
*
|
|
* _.isArrayLikeObject('abc');
|
|
* // => false
|
|
*
|
|
* _.isArrayLikeObject(_.noop);
|
|
* // => false
|
|
*/
|
|
function isArrayLikeObject(value) {
|
|
return isObjectLike(value) && isArrayLike(value);
|
|
}
|
|
|
|
module.e = isArrayLikeObject;
|
|
|
|
|
|
/***/ },
|
|
/* 27 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/** Used as references for various `Number` constants. */
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like length.
|
|
*
|
|
* **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
* @example
|
|
*
|
|
* _.isLength(3);
|
|
* // => true
|
|
*
|
|
* _.isLength(Number.MIN_VALUE);
|
|
* // => false
|
|
*
|
|
* _.isLength(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isLength('3');
|
|
* // => false
|
|
*/
|
|
function isLength(value) {
|
|
return typeof value == 'number' &&
|
|
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
module.e = isLength;
|
|
|
|
|
|
/***/ },
|
|
/* 28 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseMerge = __webpack_require__(99),
|
|
createAssigner = __webpack_require__(113);
|
|
|
|
/**
|
|
* This method is like `_.assign` except that it recursively merges own and
|
|
* inherited enumerable properties of source objects into the destination
|
|
* object. Source properties that resolve to `undefined` are skipped if a
|
|
* destination value exists. Array and plain object properties are merged
|
|
* recursively.Other objects and value types are overridden by assignment.
|
|
* Source objects are applied from left to right. Subsequent sources
|
|
* overwrite property assignments of previous sources.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
|
|
* };
|
|
*
|
|
* var ages = {
|
|
* 'data': [{ 'age': 36 }, { 'age': 40 }]
|
|
* };
|
|
*
|
|
* _.merge(users, ages);
|
|
* // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
|
|
*/
|
|
var merge = createAssigner(function(object, source, srcIndex) {
|
|
baseMerge(object, source, srcIndex);
|
|
});
|
|
|
|
module.e = merge;
|
|
|
|
|
|
/***/ },
|
|
/* 29 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* http://www.codeproject.com/Tips/407172/Connected-Component-Labeling-and-Vectorization
|
|
*/
|
|
var Tracer = {
|
|
searchDirections: [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]],
|
|
create: function create(imageWrapper, labelWrapper) {
|
|
var imageData = imageWrapper.data,
|
|
labelData = labelWrapper.data,
|
|
searchDirections = this.searchDirections,
|
|
width = imageWrapper.size.x,
|
|
pos;
|
|
|
|
function _trace(current, color, label, edgelabel) {
|
|
var i, y, x;
|
|
|
|
for (i = 0; i < 7; i++) {
|
|
y = current.cy + searchDirections[current.dir][0];
|
|
x = current.cx + searchDirections[current.dir][1];
|
|
pos = y * width + x;
|
|
if (imageData[pos] === color && (labelData[pos] === 0 || labelData[pos] === label)) {
|
|
labelData[pos] = label;
|
|
current.cy = y;
|
|
current.cx = x;
|
|
return true;
|
|
} else {
|
|
if (labelData[pos] === 0) {
|
|
labelData[pos] = edgelabel;
|
|
}
|
|
current.dir = (current.dir + 1) % 8;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function vertex2D(x, y, dir) {
|
|
return {
|
|
dir: dir,
|
|
x: x,
|
|
y: y,
|
|
next: null,
|
|
prev: null
|
|
};
|
|
}
|
|
|
|
function _contourTracing(sy, sx, label, color, edgelabel) {
|
|
var Fv = null,
|
|
Cv,
|
|
P,
|
|
ldir,
|
|
current = {
|
|
cx: sx,
|
|
cy: sy,
|
|
dir: 0
|
|
};
|
|
|
|
if (_trace(current, color, label, edgelabel)) {
|
|
Fv = vertex2D(sx, sy, current.dir);
|
|
Cv = Fv;
|
|
ldir = current.dir;
|
|
P = vertex2D(current.cx, current.cy, 0);
|
|
P.prev = Cv;
|
|
Cv.next = P;
|
|
P.next = null;
|
|
Cv = P;
|
|
do {
|
|
current.dir = (current.dir + 6) % 8;
|
|
_trace(current, color, label, edgelabel);
|
|
if (ldir !== current.dir) {
|
|
Cv.dir = current.dir;
|
|
P = vertex2D(current.cx, current.cy, 0);
|
|
P.prev = Cv;
|
|
Cv.next = P;
|
|
P.next = null;
|
|
Cv = P;
|
|
} else {
|
|
Cv.dir = ldir;
|
|
Cv.x = current.cx;
|
|
Cv.y = current.cy;
|
|
}
|
|
ldir = current.dir;
|
|
} while (current.cx !== sx || current.cy !== sy);
|
|
Fv.prev = Cv.prev;
|
|
Cv.prev.next = Fv;
|
|
}
|
|
return Fv;
|
|
}
|
|
|
|
return {
|
|
trace: function trace(current, color, label, edgelabel) {
|
|
return _trace(current, color, label, edgelabel);
|
|
},
|
|
contourTracing: function contourTracing(sy, sx, label, color, edgelabel) {
|
|
return _contourTracing(sy, sx, label, color, edgelabel);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = Tracer;
|
|
|
|
/***/ },
|
|
/* 30 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__barcode_reader__ = __webpack_require__(5);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_array_helper__ = __webpack_require__(8);
|
|
|
|
|
|
|
|
function Code39Reader() {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
ALPHABETH_STRING: { value: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%" },
|
|
ALPHABET: { value: [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 45, 46, 32, 42, 36, 47, 43, 37] },
|
|
CHARACTER_ENCODINGS: { value: [0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x094, 0x0A8, 0x0A2, 0x08A, 0x02A] },
|
|
ASTERISK: { value: 0x094 },
|
|
FORMAT: { value: "code_39", writeable: false }
|
|
};
|
|
|
|
Code39Reader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].prototype, properties);
|
|
Code39Reader.prototype.constructor = Code39Reader;
|
|
|
|
Code39Reader.prototype._toCounters = function (start, counter) {
|
|
var self = this,
|
|
numCounters = counter.length,
|
|
end = self._row.length,
|
|
isWhite = !self._row[start],
|
|
i,
|
|
counterPos = 0;
|
|
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_array_helper__["a"].init(counter, 0);
|
|
|
|
for (i = start; i < end; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
counterPos++;
|
|
if (counterPos === numCounters) {
|
|
break;
|
|
} else {
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
}
|
|
|
|
return counter;
|
|
};
|
|
|
|
Code39Reader.prototype._decode = function () {
|
|
var self = this,
|
|
counters = [0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
result = [],
|
|
start = self._findStart(),
|
|
decodedChar,
|
|
lastStart,
|
|
pattern,
|
|
nextStart;
|
|
|
|
if (!start) {
|
|
return null;
|
|
}
|
|
nextStart = self._nextSet(self._row, start.end);
|
|
|
|
do {
|
|
counters = self._toCounters(nextStart, counters);
|
|
pattern = self._toPattern(counters);
|
|
if (pattern < 0) {
|
|
return null;
|
|
}
|
|
decodedChar = self._patternToChar(pattern);
|
|
if (decodedChar < 0) {
|
|
return null;
|
|
}
|
|
result.push(decodedChar);
|
|
lastStart = nextStart;
|
|
nextStart += /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_array_helper__["a"].sum(counters);
|
|
nextStart = self._nextSet(self._row, nextStart);
|
|
} while (decodedChar !== '*');
|
|
result.pop();
|
|
|
|
if (!result.length) {
|
|
return null;
|
|
}
|
|
|
|
if (!self._verifyTrailingWhitespace(lastStart, nextStart, counters)) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
code: result.join(""),
|
|
start: start.start,
|
|
end: nextStart,
|
|
startInfo: start,
|
|
decodedCodes: result
|
|
};
|
|
};
|
|
|
|
Code39Reader.prototype._verifyTrailingWhitespace = function (lastStart, nextStart, counters) {
|
|
var trailingWhitespaceEnd,
|
|
patternSize = /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_array_helper__["a"].sum(counters);
|
|
|
|
trailingWhitespaceEnd = nextStart - lastStart - patternSize;
|
|
if (trailingWhitespaceEnd * 3 >= patternSize) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
Code39Reader.prototype._patternToChar = function (pattern) {
|
|
var i,
|
|
self = this;
|
|
|
|
for (i = 0; i < self.CHARACTER_ENCODINGS.length; i++) {
|
|
if (self.CHARACTER_ENCODINGS[i] === pattern) {
|
|
return String.fromCharCode(self.ALPHABET[i]);
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
Code39Reader.prototype._findNextWidth = function (counters, current) {
|
|
var i,
|
|
minWidth = Number.MAX_VALUE;
|
|
|
|
for (i = 0; i < counters.length; i++) {
|
|
if (counters[i] < minWidth && counters[i] > current) {
|
|
minWidth = counters[i];
|
|
}
|
|
}
|
|
|
|
return minWidth;
|
|
};
|
|
|
|
Code39Reader.prototype._toPattern = function (counters) {
|
|
var numCounters = counters.length,
|
|
maxNarrowWidth = 0,
|
|
numWideBars = numCounters,
|
|
wideBarWidth = 0,
|
|
self = this,
|
|
pattern,
|
|
i;
|
|
|
|
while (numWideBars > 3) {
|
|
maxNarrowWidth = self._findNextWidth(counters, maxNarrowWidth);
|
|
numWideBars = 0;
|
|
pattern = 0;
|
|
for (i = 0; i < numCounters; i++) {
|
|
if (counters[i] > maxNarrowWidth) {
|
|
pattern |= 1 << numCounters - 1 - i;
|
|
numWideBars++;
|
|
wideBarWidth += counters[i];
|
|
}
|
|
}
|
|
|
|
if (numWideBars === 3) {
|
|
for (i = 0; i < numCounters && numWideBars > 0; i++) {
|
|
if (counters[i] > maxNarrowWidth) {
|
|
numWideBars--;
|
|
if (counters[i] * 2 >= wideBarWidth) {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
return pattern;
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
Code39Reader.prototype._findStart = function () {
|
|
var self = this,
|
|
offset = self._nextSet(self._row),
|
|
patternStart = offset,
|
|
counter = [0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
counterPos = 0,
|
|
isWhite = false,
|
|
i,
|
|
j,
|
|
whiteSpaceMustStart;
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
// find start pattern
|
|
if (self._toPattern(counter) === self.ASTERISK) {
|
|
whiteSpaceMustStart = Math.floor(Math.max(0, patternStart - (i - patternStart) / 4));
|
|
if (self._matchRange(whiteSpaceMustStart, patternStart, 0)) {
|
|
return {
|
|
start: patternStart,
|
|
end: i
|
|
};
|
|
}
|
|
}
|
|
|
|
patternStart += counter[0] + counter[1];
|
|
for (j = 0; j < 7; j++) {
|
|
counter[j] = counter[j + 2];
|
|
}
|
|
counter[7] = 0;
|
|
counter[8] = 0;
|
|
counterPos--;
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = Code39Reader;
|
|
|
|
/***/ },
|
|
/* 31 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = dot
|
|
|
|
/**
|
|
* Calculates the dot product of two vec2's
|
|
*
|
|
* @param {vec2} a the first operand
|
|
* @param {vec2} b the second operand
|
|
* @returns {Number} dot product of a and b
|
|
*/
|
|
function dot(a, b) {
|
|
return a[0] * b[0] + a[1] * b[1]
|
|
}
|
|
|
|
/***/ },
|
|
/* 32 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var stackClear = __webpack_require__(133),
|
|
stackDelete = __webpack_require__(134),
|
|
stackGet = __webpack_require__(135),
|
|
stackHas = __webpack_require__(136),
|
|
stackSet = __webpack_require__(137);
|
|
|
|
/**
|
|
* Creates a stack cache object to store key-value pairs.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [values] The values to cache.
|
|
*/
|
|
function Stack(values) {
|
|
var index = -1,
|
|
length = values ? values.length : 0;
|
|
|
|
this.clear();
|
|
while (++index < length) {
|
|
var entry = values[index];
|
|
this.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
|
|
// Add functions to the `Stack` cache.
|
|
Stack.prototype.clear = stackClear;
|
|
Stack.prototype['delete'] = stackDelete;
|
|
Stack.prototype.get = stackGet;
|
|
Stack.prototype.has = stackHas;
|
|
Stack.prototype.set = stackSet;
|
|
|
|
module.e = Stack;
|
|
|
|
|
|
/***/ },
|
|
/* 33 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* A specialized version of `_.forEach` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayEach(array, iteratee) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (iteratee(array[index], index, array) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
module.e = arrayEach;
|
|
|
|
|
|
/***/ },
|
|
/* 34 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var eq = __webpack_require__(15);
|
|
|
|
/**
|
|
* This function is like `assignValue` except that it doesn't assign
|
|
* `undefined` values.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {*} value The value to assign.
|
|
*/
|
|
function assignMergeValue(object, key, value) {
|
|
if ((value !== undefined && !eq(object[key], value)) ||
|
|
(typeof key == 'number' && value === undefined && !(key in object))) {
|
|
object[key] = value;
|
|
}
|
|
}
|
|
|
|
module.e = assignMergeValue;
|
|
|
|
|
|
/***/ },
|
|
/* 35 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var eq = __webpack_require__(15);
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {*} value The value to assign.
|
|
*/
|
|
function assignValue(object, key, value) {
|
|
var objValue = object[key];
|
|
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
|
|
(value === undefined && !(key in object))) {
|
|
object[key] = value;
|
|
}
|
|
}
|
|
|
|
module.e = assignValue;
|
|
|
|
|
|
/***/ },
|
|
/* 36 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assocIndexOf = __webpack_require__(11);
|
|
|
|
/** Used for built-in method references. */
|
|
var arrayProto = Array.prototype;
|
|
|
|
/** Built-in value references. */
|
|
var splice = arrayProto.splice;
|
|
|
|
/**
|
|
* Removes `key` and its value from the associative array.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to query.
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function assocDelete(array, key) {
|
|
var index = assocIndexOf(array, key);
|
|
if (index < 0) {
|
|
return false;
|
|
}
|
|
var lastIndex = array.length - 1;
|
|
if (index == lastIndex) {
|
|
array.pop();
|
|
} else {
|
|
splice.call(array, index, 1);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
module.e = assocDelete;
|
|
|
|
|
|
/***/ },
|
|
/* 37 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assocIndexOf = __webpack_require__(11);
|
|
|
|
/**
|
|
* Gets the associative array value for `key`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to query.
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function assocGet(array, key) {
|
|
var index = assocIndexOf(array, key);
|
|
return index < 0 ? undefined : array[index][1];
|
|
}
|
|
|
|
module.e = assocGet;
|
|
|
|
|
|
/***/ },
|
|
/* 38 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assocIndexOf = __webpack_require__(11);
|
|
|
|
/**
|
|
* Checks if an associative array value for `key` exists.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to query.
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function assocHas(array, key) {
|
|
return assocIndexOf(array, key) > -1;
|
|
}
|
|
|
|
module.e = assocHas;
|
|
|
|
|
|
/***/ },
|
|
/* 39 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assocIndexOf = __webpack_require__(11);
|
|
|
|
/**
|
|
* Sets the associative array `key` to `value`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
*/
|
|
function assocSet(array, key, value) {
|
|
var index = assocIndexOf(array, key);
|
|
if (index < 0) {
|
|
array.push([key, value]);
|
|
} else {
|
|
array[index][1] = value;
|
|
}
|
|
}
|
|
|
|
module.e = assocSet;
|
|
|
|
|
|
/***/ },
|
|
/* 40 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Uint8Array = __webpack_require__(84);
|
|
|
|
/**
|
|
* Creates a clone of `arrayBuffer`.
|
|
*
|
|
* @private
|
|
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
|
|
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
|
*/
|
|
function cloneArrayBuffer(arrayBuffer) {
|
|
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
|
|
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
|
|
return result;
|
|
}
|
|
|
|
module.e = cloneArrayBuffer;
|
|
|
|
|
|
/***/ },
|
|
/* 41 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Copies the values of `source` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} source The array to copy values from.
|
|
* @param {Array} [array=[]] The array to copy values to.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function copyArray(source, array) {
|
|
var index = -1,
|
|
length = source.length;
|
|
|
|
array || (array = Array(length));
|
|
while (++index < length) {
|
|
array[index] = source[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
module.e = copyArray;
|
|
|
|
|
|
/***/ },
|
|
/* 42 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var nativeCreate = __webpack_require__(14);
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Checks if a hash value for `key` exists.
|
|
*
|
|
* @private
|
|
* @param {Object} hash The hash to query.
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function hashHas(hash, key) {
|
|
return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
|
|
}
|
|
|
|
module.e = hashHas;
|
|
|
|
|
|
/***/ },
|
|
/* 43 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseTimes = __webpack_require__(103),
|
|
isArguments = __webpack_require__(24),
|
|
isArray = __webpack_require__(4),
|
|
isLength = __webpack_require__(27),
|
|
isString = __webpack_require__(142);
|
|
|
|
/**
|
|
* Creates an array of index keys for `object` values of arrays,
|
|
* `arguments` objects, and strings, otherwise `null` is returned.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array|null} Returns index keys, else `null`.
|
|
*/
|
|
function indexKeys(object) {
|
|
var length = object ? object.length : undefined;
|
|
if (isLength(length) &&
|
|
(isArray(object) || isString(object) || isArguments(object))) {
|
|
return baseTimes(length, String);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
module.e = indexKeys;
|
|
|
|
|
|
/***/ },
|
|
/* 44 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isLength = __webpack_require__(27),
|
|
isObjectLike = __webpack_require__(7);
|
|
|
|
/** `Object#toString` result references. */
|
|
var argsTag = '[object Arguments]',
|
|
arrayTag = '[object Array]',
|
|
boolTag = '[object Boolean]',
|
|
dateTag = '[object Date]',
|
|
errorTag = '[object Error]',
|
|
funcTag = '[object Function]',
|
|
mapTag = '[object Map]',
|
|
numberTag = '[object Number]',
|
|
objectTag = '[object Object]',
|
|
regexpTag = '[object RegExp]',
|
|
setTag = '[object Set]',
|
|
stringTag = '[object String]',
|
|
weakMapTag = '[object WeakMap]';
|
|
|
|
var arrayBufferTag = '[object ArrayBuffer]',
|
|
float32Tag = '[object Float32Array]',
|
|
float64Tag = '[object Float64Array]',
|
|
int8Tag = '[object Int8Array]',
|
|
int16Tag = '[object Int16Array]',
|
|
int32Tag = '[object Int32Array]',
|
|
uint8Tag = '[object Uint8Array]',
|
|
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
uint16Tag = '[object Uint16Array]',
|
|
uint32Tag = '[object Uint32Array]';
|
|
|
|
/** Used to identify `toStringTag` values of typed arrays. */
|
|
var typedArrayTags = {};
|
|
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
|
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
|
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
|
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
|
typedArrayTags[uint32Tag] = true;
|
|
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
|
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
|
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
|
|
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
|
|
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
|
|
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
|
|
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objectToString = objectProto.toString;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a typed array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isTypedArray(new Uint8Array);
|
|
* // => true
|
|
*
|
|
* _.isTypedArray([]);
|
|
* // => false
|
|
*/
|
|
function isTypedArray(value) {
|
|
return isObjectLike(value) &&
|
|
isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
|
|
}
|
|
|
|
module.e = isTypedArray;
|
|
|
|
|
|
/***/ },
|
|
/* 45 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseHas = __webpack_require__(96),
|
|
baseKeys = __webpack_require__(97),
|
|
indexKeys = __webpack_require__(43),
|
|
isArrayLike = __webpack_require__(25),
|
|
isIndex = __webpack_require__(22),
|
|
isPrototype = __webpack_require__(23);
|
|
|
|
/**
|
|
* Creates an array of the own enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects. See the
|
|
* [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
|
|
* for more details.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keys(new Foo);
|
|
* // => ['a', 'b'] (iteration order is not guaranteed)
|
|
*
|
|
* _.keys('hi');
|
|
* // => ['0', '1']
|
|
*/
|
|
function keys(object) {
|
|
var isProto = isPrototype(object);
|
|
if (!(isProto || isArrayLike(object))) {
|
|
return baseKeys(object);
|
|
}
|
|
var indexes = indexKeys(object),
|
|
skipIndexes = !!indexes,
|
|
result = indexes || [],
|
|
length = result.length;
|
|
|
|
for (var key in object) {
|
|
if (baseHas(object, key) &&
|
|
!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
|
|
!(isProto && key == 'constructor')) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.e = keys;
|
|
|
|
|
|
/***/ },
|
|
/* 46 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseKeysIn = __webpack_require__(98),
|
|
indexKeys = __webpack_require__(43),
|
|
isIndex = __webpack_require__(22),
|
|
isPrototype = __webpack_require__(23);
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keysIn(new Foo);
|
|
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
|
*/
|
|
function keysIn(object) {
|
|
var index = -1,
|
|
isProto = isPrototype(object),
|
|
props = baseKeysIn(object),
|
|
propsLength = props.length,
|
|
indexes = indexKeys(object),
|
|
skipIndexes = !!indexes,
|
|
result = indexes || [],
|
|
length = result.length;
|
|
|
|
while (++index < propsLength) {
|
|
var key = props[index];
|
|
if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
|
|
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.e = keysIn;
|
|
|
|
|
|
/***/ },
|
|
/* 47 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var apply = __webpack_require__(88),
|
|
toInteger = __webpack_require__(144);
|
|
|
|
/** Used as the `TypeError` message for "Functions" methods. */
|
|
var FUNC_ERROR_TEXT = 'Expected a function';
|
|
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
var nativeMax = Math.max;
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of the
|
|
* created function and arguments from `start` and beyond provided as an array.
|
|
*
|
|
* **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Function
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var say = _.rest(function(what, names) {
|
|
* return what + ' ' + _.initial(names).join(', ') +
|
|
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
|
* });
|
|
*
|
|
* say('hello', 'fred', 'barney', 'pebbles');
|
|
* // => 'hello fred, barney, & pebbles'
|
|
*/
|
|
function rest(func, start) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
|
|
return function() {
|
|
var args = arguments,
|
|
index = -1,
|
|
length = nativeMax(args.length - start, 0),
|
|
array = Array(length);
|
|
|
|
while (++index < length) {
|
|
array[index] = args[start + index];
|
|
}
|
|
switch (start) {
|
|
case 0: return func.call(this, array);
|
|
case 1: return func.call(this, args[0], array);
|
|
case 2: return func.call(this, args[0], args[1], array);
|
|
}
|
|
var otherArgs = Array(start + 1);
|
|
index = -1;
|
|
while (++index < start) {
|
|
otherArgs[index] = args[index];
|
|
}
|
|
otherArgs[start] = array;
|
|
return apply(func, this, otherArgs);
|
|
};
|
|
}
|
|
|
|
module.e = rest;
|
|
|
|
|
|
/***/ },
|
|
/* 48 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = function(module) {
|
|
if(!module.webpackPolyfill) {
|
|
module.deprecate = function() {};
|
|
module.paths = [];
|
|
// module.parent = undefined by default
|
|
module.children = [];
|
|
Object.defineProperty(module, "exports", {
|
|
enumerable: true,
|
|
configurable: false,
|
|
get: function() { return module.e; },
|
|
set: function(v) { return module.e = v; }
|
|
});
|
|
Object.defineProperty(module, "loaded", {
|
|
enumerable: true,
|
|
configurable: false,
|
|
get: function() { return module.l; }
|
|
});
|
|
Object.defineProperty(module, "id", {
|
|
enumerable: true,
|
|
configurable: false,
|
|
get: function() { return module.i; }
|
|
});
|
|
module.webpackPolyfill = 1;
|
|
}
|
|
return module;
|
|
}
|
|
|
|
|
|
/***/ },
|
|
/* 49 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_lodash_merge__ = __webpack_require__(28);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_lodash_merge___default = __WEBPACK_IMPORTED_MODULE_0_lodash_merge__ && __WEBPACK_IMPORTED_MODULE_0_lodash_merge__.__esModule ? function() { return __WEBPACK_IMPORTED_MODULE_0_lodash_merge__['default'] } : function() { return __WEBPACK_IMPORTED_MODULE_0_lodash_merge__; }
|
|
/* harmony import */ Object.defineProperty(__WEBPACK_IMPORTED_MODULE_0_lodash_merge___default, 'a', { get: __WEBPACK_IMPORTED_MODULE_0_lodash_merge___default });
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_typedefs__ = __webpack_require__(54);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_typedefs___default = __WEBPACK_IMPORTED_MODULE_1__common_typedefs__ && __WEBPACK_IMPORTED_MODULE_1__common_typedefs__.__esModule ? function() { return __WEBPACK_IMPORTED_MODULE_1__common_typedefs__['default'] } : function() { return __WEBPACK_IMPORTED_MODULE_1__common_typedefs__; }
|
|
/* harmony import */ Object.defineProperty(__WEBPACK_IMPORTED_MODULE_1__common_typedefs___default, 'a', { get: __WEBPACK_IMPORTED_MODULE_1__common_typedefs___default });
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_webrtc_adapter__ = __webpack_require__(147);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_webrtc_adapter___default = __WEBPACK_IMPORTED_MODULE_2_webrtc_adapter__ && __WEBPACK_IMPORTED_MODULE_2_webrtc_adapter__.__esModule ? function() { return __WEBPACK_IMPORTED_MODULE_2_webrtc_adapter__['default'] } : function() { return __WEBPACK_IMPORTED_MODULE_2_webrtc_adapter__; }
|
|
/* harmony import */ Object.defineProperty(__WEBPACK_IMPORTED_MODULE_2_webrtc_adapter___default, 'a', { get: __WEBPACK_IMPORTED_MODULE_2_webrtc_adapter___default });
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_image_wrapper__ = __webpack_require__(18);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__locator_barcode_locator__ = __webpack_require__(63);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__decoder_barcode_decoder__ = __webpack_require__(57);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__common_events__ = __webpack_require__(52);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__input_camera_access__ = __webpack_require__(59);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__common_image_debug__ = __webpack_require__(9);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__analytics_result_collector__ = __webpack_require__(50);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__config_config__ = __webpack_require__(56);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11_input_stream__ = __webpack_require__(62);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12_frame_grabber__ = __webpack_require__(60);
|
|
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
// eslint-disable-line no-unused-vars
|
|
// eslint-disable-line no-unused-vars
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var vec2 = {
|
|
clone: __webpack_require__(6)
|
|
};
|
|
|
|
var _inputStream,
|
|
_framegrabber,
|
|
_stopped,
|
|
_canvasContainer = {
|
|
ctx: {
|
|
image: null,
|
|
overlay: null
|
|
},
|
|
dom: {
|
|
image: null,
|
|
overlay: null
|
|
}
|
|
},
|
|
_inputImageWrapper,
|
|
_boxSize,
|
|
_decoder,
|
|
_workerPool = [],
|
|
_onUIThread = true,
|
|
_resultCollector,
|
|
_config = {};
|
|
|
|
function initializeData(imageWrapper) {
|
|
initBuffers(imageWrapper);
|
|
_decoder = /* harmony import */__WEBPACK_IMPORTED_MODULE_5__decoder_barcode_decoder__["a"].create(_config.decoder, _inputImageWrapper);
|
|
}
|
|
|
|
function initInputStream(cb) {
|
|
var video;
|
|
if (_config.inputStream.type === "VideoStream") {
|
|
video = document.createElement("video");
|
|
_inputStream = /* harmony import */__WEBPACK_IMPORTED_MODULE_11_input_stream__["a"].createVideoStream(video);
|
|
} else if (_config.inputStream.type === "ImageStream") {
|
|
_inputStream = /* harmony import */__WEBPACK_IMPORTED_MODULE_11_input_stream__["a"].createImageStream();
|
|
} else if (_config.inputStream.type === "LiveStream") {
|
|
var $viewport = getViewPort();
|
|
if ($viewport) {
|
|
video = $viewport.querySelector("video");
|
|
if (!video) {
|
|
video = document.createElement("video");
|
|
$viewport.appendChild(video);
|
|
}
|
|
}
|
|
_inputStream = /* harmony import */__WEBPACK_IMPORTED_MODULE_11_input_stream__["a"].createLiveStream(video);
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_7__input_camera_access__["a"].request(video, _config.inputStream.constraints).then(function () {
|
|
_inputStream.trigger("canrecord");
|
|
}).catch(function (err) {
|
|
return cb(err);
|
|
});
|
|
}
|
|
|
|
_inputStream.setAttribute("preload", "auto");
|
|
_inputStream.setAttribute("autoplay", true);
|
|
_inputStream.setInputStream(_config.inputStream);
|
|
_inputStream.addEventListener("canrecord", canRecord.bind(undefined, cb));
|
|
}
|
|
|
|
function getViewPort() {
|
|
var target = _config.inputStream.target;
|
|
// Check if target is already a DOM element
|
|
if (target && target.nodeName && target.nodeType === 1) {
|
|
return target;
|
|
} else {
|
|
// Use '#interactive.viewport' as a fallback selector (backwards compatibility)
|
|
var selector = typeof target === 'string' ? target : '#interactive.viewport';
|
|
return document.querySelector(selector);
|
|
}
|
|
}
|
|
|
|
function canRecord(cb) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_4__locator_barcode_locator__["a"].checkImageConstraints(_inputStream, _config.locator);
|
|
initCanvas(_config);
|
|
_framegrabber = /* harmony import */__WEBPACK_IMPORTED_MODULE_12_frame_grabber__["a"].create(_inputStream, _canvasContainer.dom.image);
|
|
|
|
adjustWorkerPool(_config.numOfWorkers, function () {
|
|
if (_config.numOfWorkers === 0) {
|
|
initializeData();
|
|
}
|
|
ready(cb);
|
|
});
|
|
}
|
|
|
|
function ready(cb) {
|
|
_inputStream.play();
|
|
cb();
|
|
}
|
|
|
|
function initCanvas() {
|
|
if (typeof document !== "undefined") {
|
|
var $viewport = getViewPort();
|
|
_canvasContainer.dom.image = document.querySelector("canvas.imgBuffer");
|
|
if (!_canvasContainer.dom.image) {
|
|
_canvasContainer.dom.image = document.createElement("canvas");
|
|
_canvasContainer.dom.image.className = "imgBuffer";
|
|
if ($viewport && _config.inputStream.type === "ImageStream") {
|
|
$viewport.appendChild(_canvasContainer.dom.image);
|
|
}
|
|
}
|
|
_canvasContainer.ctx.image = _canvasContainer.dom.image.getContext("2d");
|
|
_canvasContainer.dom.image.width = _inputStream.getCanvasSize().x;
|
|
_canvasContainer.dom.image.height = _inputStream.getCanvasSize().y;
|
|
|
|
_canvasContainer.dom.overlay = document.querySelector("canvas.drawingBuffer");
|
|
if (!_canvasContainer.dom.overlay) {
|
|
_canvasContainer.dom.overlay = document.createElement("canvas");
|
|
_canvasContainer.dom.overlay.className = "drawingBuffer";
|
|
if ($viewport) {
|
|
$viewport.appendChild(_canvasContainer.dom.overlay);
|
|
}
|
|
var clearFix = document.createElement("br");
|
|
clearFix.setAttribute("clear", "all");
|
|
if ($viewport) {
|
|
$viewport.appendChild(clearFix);
|
|
}
|
|
}
|
|
_canvasContainer.ctx.overlay = _canvasContainer.dom.overlay.getContext("2d");
|
|
_canvasContainer.dom.overlay.width = _inputStream.getCanvasSize().x;
|
|
_canvasContainer.dom.overlay.height = _inputStream.getCanvasSize().y;
|
|
}
|
|
}
|
|
|
|
function initBuffers(imageWrapper) {
|
|
if (imageWrapper) {
|
|
_inputImageWrapper = imageWrapper;
|
|
} else {
|
|
_inputImageWrapper = new /* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_wrapper__["a"]({
|
|
x: _inputStream.getWidth(),
|
|
y: _inputStream.getHeight()
|
|
});
|
|
}
|
|
|
|
if (true) {
|
|
console.log(_inputImageWrapper.size);
|
|
}
|
|
_boxSize = [vec2.clone([0, 0]), vec2.clone([0, _inputImageWrapper.size.y]), vec2.clone([_inputImageWrapper.size.x, _inputImageWrapper.size.y]), vec2.clone([_inputImageWrapper.size.x, 0])];
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_4__locator_barcode_locator__["a"].init(_inputImageWrapper, _config.locator);
|
|
}
|
|
|
|
function getBoundingBoxes() {
|
|
if (_config.locate) {
|
|
return /* harmony import */__WEBPACK_IMPORTED_MODULE_4__locator_barcode_locator__["a"].locate();
|
|
} else {
|
|
return [[vec2.clone(_boxSize[0]), vec2.clone(_boxSize[1]), vec2.clone(_boxSize[2]), vec2.clone(_boxSize[3])]];
|
|
}
|
|
}
|
|
|
|
function transformResult(result) {
|
|
var topRight = _inputStream.getTopRight(),
|
|
xOffset = topRight.x,
|
|
yOffset = topRight.y,
|
|
i;
|
|
|
|
if (xOffset === 0 && yOffset === 0) {
|
|
return;
|
|
}
|
|
|
|
if (result.barcodes) {
|
|
for (i = 0; i < result.barcodes.length; i++) {
|
|
transformResult(result.barcodes[i]);
|
|
}
|
|
}
|
|
|
|
if (result.line && result.line.length === 2) {
|
|
moveLine(result.line);
|
|
}
|
|
|
|
if (result.box) {
|
|
moveBox(result.box);
|
|
}
|
|
|
|
if (result.boxes && result.boxes.length > 0) {
|
|
for (i = 0; i < result.boxes.length; i++) {
|
|
moveBox(result.boxes[i]);
|
|
}
|
|
}
|
|
|
|
function moveBox(box) {
|
|
var corner = box.length;
|
|
|
|
while (corner--) {
|
|
box[corner][0] += xOffset;
|
|
box[corner][1] += yOffset;
|
|
}
|
|
}
|
|
|
|
function moveLine(line) {
|
|
line[0].x += xOffset;
|
|
line[0].y += yOffset;
|
|
line[1].x += xOffset;
|
|
line[1].y += yOffset;
|
|
}
|
|
}
|
|
|
|
function addResult(result, imageData) {
|
|
if (!imageData || !_resultCollector) {
|
|
return;
|
|
}
|
|
|
|
if (result.barcodes) {
|
|
result.barcodes.filter(function (barcode) {
|
|
return barcode.codeResult;
|
|
}).forEach(function (barcode) {
|
|
return addResult(barcode, imageData);
|
|
});
|
|
} else if (result.codeResult) {
|
|
_resultCollector.addResult(imageData, _inputStream.getCanvasSize(), result.codeResult);
|
|
}
|
|
}
|
|
|
|
function hasCodeResult(result) {
|
|
return result && (result.barcodes ? result.barcodes.some(function (barcode) {
|
|
return barcode.codeResult;
|
|
}) : result.codeResult);
|
|
}
|
|
|
|
function publishResult(result, imageData) {
|
|
var resultToPublish = result;
|
|
|
|
if (result && _onUIThread) {
|
|
transformResult(result);
|
|
addResult(result, imageData);
|
|
resultToPublish = result.barcodes || result;
|
|
}
|
|
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_6__common_events__["a"].publish("processed", resultToPublish);
|
|
if (hasCodeResult(result)) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_6__common_events__["a"].publish("detected", resultToPublish);
|
|
}
|
|
}
|
|
|
|
function locateAndDecode() {
|
|
var result, boxes;
|
|
|
|
boxes = getBoundingBoxes();
|
|
if (boxes) {
|
|
result = _decoder.decodeFromBoundingBoxes(boxes);
|
|
result = result || {};
|
|
result.boxes = boxes;
|
|
publishResult(result, _inputImageWrapper.data);
|
|
} else {
|
|
publishResult();
|
|
}
|
|
}
|
|
|
|
function update() {
|
|
var availableWorker;
|
|
|
|
if (_onUIThread) {
|
|
if (_workerPool.length > 0) {
|
|
availableWorker = _workerPool.filter(function (workerThread) {
|
|
return !workerThread.busy;
|
|
})[0];
|
|
if (availableWorker) {
|
|
_framegrabber.attachData(availableWorker.imageData);
|
|
} else {
|
|
return; // all workers are busy
|
|
}
|
|
} else {
|
|
_framegrabber.attachData(_inputImageWrapper.data);
|
|
}
|
|
if (_framegrabber.grab()) {
|
|
if (availableWorker) {
|
|
availableWorker.busy = true;
|
|
availableWorker.worker.postMessage({
|
|
cmd: 'process',
|
|
imageData: availableWorker.imageData
|
|
}, [availableWorker.imageData.buffer]);
|
|
} else {
|
|
locateAndDecode();
|
|
}
|
|
}
|
|
} else {
|
|
locateAndDecode();
|
|
}
|
|
}
|
|
|
|
function startContinuousUpdate() {
|
|
var next = null,
|
|
delay = 1000 / (_config.frequency || 60);
|
|
|
|
_stopped = false;
|
|
(function frame(timestamp) {
|
|
next = next || timestamp;
|
|
if (!_stopped) {
|
|
if (timestamp >= next) {
|
|
next += delay;
|
|
update();
|
|
}
|
|
window.requestAnimFrame(frame);
|
|
}
|
|
})(performance.now());
|
|
}
|
|
|
|
function _start() {
|
|
if (_onUIThread && _config.inputStream.type === "LiveStream") {
|
|
startContinuousUpdate();
|
|
} else {
|
|
update();
|
|
}
|
|
}
|
|
|
|
function initWorker(cb) {
|
|
var blobURL,
|
|
workerThread = {
|
|
worker: undefined,
|
|
imageData: new Uint8Array(_inputStream.getWidth() * _inputStream.getHeight()),
|
|
busy: true
|
|
};
|
|
|
|
blobURL = generateWorkerBlob();
|
|
workerThread.worker = new Worker(blobURL);
|
|
|
|
workerThread.worker.onmessage = function (e) {
|
|
if (e.data.event === 'initialized') {
|
|
URL.revokeObjectURL(blobURL);
|
|
workerThread.busy = false;
|
|
workerThread.imageData = new Uint8Array(e.data.imageData);
|
|
if (true) {
|
|
console.log("Worker initialized");
|
|
}
|
|
return cb(workerThread);
|
|
} else if (e.data.event === 'processed') {
|
|
workerThread.imageData = new Uint8Array(e.data.imageData);
|
|
workerThread.busy = false;
|
|
publishResult(e.data.result, workerThread.imageData);
|
|
} else if (e.data.event === 'error') {
|
|
if (true) {
|
|
console.log("Worker error: " + e.data.message);
|
|
}
|
|
}
|
|
};
|
|
|
|
workerThread.worker.postMessage({
|
|
cmd: 'init',
|
|
size: { x: _inputStream.getWidth(), y: _inputStream.getHeight() },
|
|
imageData: workerThread.imageData,
|
|
config: configForWorker(_config)
|
|
}, [workerThread.imageData.buffer]);
|
|
}
|
|
|
|
function configForWorker(config) {
|
|
return _extends({}, config, {
|
|
inputStream: _extends({}, config.inputStream, {
|
|
target: null
|
|
})
|
|
});
|
|
}
|
|
|
|
function workerInterface(factory) {
|
|
/* eslint-disable no-undef*/
|
|
if (factory) {
|
|
var Quagga = factory().default;
|
|
if (!Quagga) {
|
|
self.postMessage({ 'event': 'error', message: 'Quagga could not be created' });
|
|
return;
|
|
}
|
|
}
|
|
var imageWrapper;
|
|
|
|
self.onmessage = function (e) {
|
|
if (e.data.cmd === 'init') {
|
|
var config = e.data.config;
|
|
config.numOfWorkers = 0;
|
|
imageWrapper = new Quagga.ImageWrapper({
|
|
x: e.data.size.x,
|
|
y: e.data.size.y
|
|
}, new Uint8Array(e.data.imageData));
|
|
Quagga.init(config, ready, imageWrapper);
|
|
Quagga.onProcessed(onProcessed);
|
|
} else if (e.data.cmd === 'process') {
|
|
imageWrapper.data = new Uint8Array(e.data.imageData);
|
|
Quagga.start();
|
|
} else if (e.data.cmd === 'setReaders') {
|
|
Quagga.setReaders(e.data.readers);
|
|
}
|
|
};
|
|
|
|
function onProcessed(result) {
|
|
self.postMessage({
|
|
'event': 'processed',
|
|
imageData: imageWrapper.data,
|
|
result: result
|
|
}, [imageWrapper.data.buffer]);
|
|
}
|
|
|
|
function ready() {
|
|
// eslint-disable-line
|
|
self.postMessage({ 'event': 'initialized', imageData: imageWrapper.data }, [imageWrapper.data.buffer]);
|
|
}
|
|
|
|
/* eslint-enable */
|
|
}
|
|
|
|
function generateWorkerBlob() {
|
|
var blob, factorySource;
|
|
|
|
/* jshint ignore:start */
|
|
if (typeof __factorySource__ !== 'undefined') {
|
|
factorySource = __factorySource__; // eslint-disable-line no-undef
|
|
}
|
|
/* jshint ignore:end */
|
|
|
|
blob = new Blob(['(' + workerInterface.toString() + ')(' + factorySource + ');'], { type: 'text/javascript' });
|
|
|
|
return window.URL.createObjectURL(blob);
|
|
}
|
|
|
|
function _setReaders(readers) {
|
|
if (_decoder) {
|
|
_decoder.setReaders(readers);
|
|
} else if (_onUIThread && _workerPool.length > 0) {
|
|
_workerPool.forEach(function (workerThread) {
|
|
workerThread.worker.postMessage({ cmd: 'setReaders', readers: readers });
|
|
});
|
|
}
|
|
}
|
|
|
|
function adjustWorkerPool(capacity, cb) {
|
|
var increaseBy = capacity - _workerPool.length;
|
|
if (increaseBy === 0) {
|
|
return cb && cb();
|
|
}
|
|
if (increaseBy < 0) {
|
|
var workersToTerminate = _workerPool.slice(increaseBy);
|
|
workersToTerminate.forEach(function (workerThread) {
|
|
workerThread.worker.terminate();
|
|
if (true) {
|
|
console.log("Worker terminated!");
|
|
}
|
|
});
|
|
_workerPool = _workerPool.slice(0, increaseBy);
|
|
return cb && cb();
|
|
} else {
|
|
var workerInitialized = function workerInitialized(workerThread) {
|
|
_workerPool.push(workerThread);
|
|
if (_workerPool.length >= capacity) {
|
|
cb && cb();
|
|
}
|
|
};
|
|
|
|
for (var i = 0; i < increaseBy; i++) {
|
|
initWorker(workerInitialized);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* harmony default export */ exports["default"] = {
|
|
init: function init(config, cb, imageWrapper) {
|
|
_config = /* harmony import */__WEBPACK_IMPORTED_MODULE_0_lodash_merge___default.a.bind()({}, /* harmony import */__WEBPACK_IMPORTED_MODULE_10__config_config__["a"], config);
|
|
if (imageWrapper) {
|
|
_onUIThread = false;
|
|
initializeData(imageWrapper);
|
|
return cb();
|
|
} else {
|
|
initInputStream(cb);
|
|
}
|
|
},
|
|
start: function start() {
|
|
_start();
|
|
},
|
|
stop: function stop() {
|
|
_stopped = true;
|
|
adjustWorkerPool(0);
|
|
if (_config.inputStream.type === "LiveStream") {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_7__input_camera_access__["a"].release();
|
|
_inputStream.clearEventHandlers();
|
|
}
|
|
},
|
|
pause: function pause() {
|
|
_stopped = true;
|
|
},
|
|
onDetected: function onDetected(callback) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_6__common_events__["a"].subscribe("detected", callback);
|
|
},
|
|
offDetected: function offDetected(callback) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_6__common_events__["a"].unsubscribe("detected", callback);
|
|
},
|
|
onProcessed: function onProcessed(callback) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_6__common_events__["a"].subscribe("processed", callback);
|
|
},
|
|
offProcessed: function offProcessed(callback) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_6__common_events__["a"].unsubscribe("processed", callback);
|
|
},
|
|
setReaders: function setReaders(readers) {
|
|
_setReaders(readers);
|
|
},
|
|
registerResultCollector: function registerResultCollector(resultCollector) {
|
|
if (resultCollector && typeof resultCollector.addResult === 'function') {
|
|
_resultCollector = resultCollector;
|
|
}
|
|
},
|
|
canvas: _canvasContainer,
|
|
decodeSingle: function decodeSingle(config, resultCallback) {
|
|
var _this = this;
|
|
|
|
config = /* harmony import */__WEBPACK_IMPORTED_MODULE_0_lodash_merge___default.a.bind()({
|
|
inputStream: {
|
|
type: "ImageStream",
|
|
sequence: false,
|
|
size: 800,
|
|
src: config.src
|
|
},
|
|
numOfWorkers: true && config.debug ? 0 : 1,
|
|
locator: {
|
|
halfSample: false
|
|
}
|
|
}, config);
|
|
this.init(config, function () {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_6__common_events__["a"].once("processed", function (result) {
|
|
_this.stop();
|
|
resultCallback.call(null, result);
|
|
}, true);
|
|
_start();
|
|
});
|
|
},
|
|
ImageWrapper: /* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_wrapper__["a"],
|
|
ImageDebug: /* harmony import */__WEBPACK_IMPORTED_MODULE_8__common_image_debug__["a"],
|
|
ResultCollector: /* harmony import */__WEBPACK_IMPORTED_MODULE_9__analytics_result_collector__["a"]
|
|
};
|
|
|
|
/***/ },
|
|
/* 50 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common_image_debug__ = __webpack_require__(9);
|
|
|
|
|
|
function contains(codeResult, list) {
|
|
if (list) {
|
|
return list.some(function (item) {
|
|
return Object.keys(item).every(function (key) {
|
|
return item[key] === codeResult[key];
|
|
});
|
|
});
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function passesFilter(codeResult, filter) {
|
|
if (typeof filter === 'function') {
|
|
return filter(codeResult);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/* harmony default export */ exports["a"] = {
|
|
create: function create(config) {
|
|
var canvas = document.createElement("canvas"),
|
|
ctx = canvas.getContext("2d"),
|
|
results = [],
|
|
capacity = config.capacity || 20,
|
|
capture = config.capture === true;
|
|
|
|
function matchesConstraints(codeResult) {
|
|
return capacity && codeResult && !contains(codeResult, config.blacklist) && passesFilter(codeResult, config.filter);
|
|
}
|
|
|
|
return {
|
|
addResult: function addResult(data, imageSize, codeResult) {
|
|
var result = {};
|
|
|
|
if (matchesConstraints(codeResult)) {
|
|
capacity--;
|
|
result.codeResult = codeResult;
|
|
if (capture) {
|
|
canvas.width = imageSize.x;
|
|
canvas.height = imageSize.y;
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_debug__["a"].drawImage(data, imageSize, ctx);
|
|
result.frame = canvas.toDataURL();
|
|
}
|
|
results.push(result);
|
|
}
|
|
},
|
|
getResults: function getResults() {
|
|
return results;
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ },
|
|
/* 51 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var vec2 = {
|
|
clone: __webpack_require__(6),
|
|
dot: __webpack_require__(31)
|
|
};
|
|
/**
|
|
* Creates a cluster for grouping similar orientations of datapoints
|
|
*/
|
|
/* harmony default export */ exports["a"] = {
|
|
create: function create(point, threshold) {
|
|
var points = [],
|
|
center = {
|
|
rad: 0,
|
|
vec: vec2.clone([0, 0])
|
|
},
|
|
pointMap = {};
|
|
|
|
function init() {
|
|
_add(point);
|
|
updateCenter();
|
|
}
|
|
|
|
function _add(pointToAdd) {
|
|
pointMap[pointToAdd.id] = pointToAdd;
|
|
points.push(pointToAdd);
|
|
}
|
|
|
|
function updateCenter() {
|
|
var i,
|
|
sum = 0;
|
|
for (i = 0; i < points.length; i++) {
|
|
sum += points[i].rad;
|
|
}
|
|
center.rad = sum / points.length;
|
|
center.vec = vec2.clone([Math.cos(center.rad), Math.sin(center.rad)]);
|
|
}
|
|
|
|
init();
|
|
|
|
return {
|
|
add: function add(pointToAdd) {
|
|
if (!pointMap[pointToAdd.id]) {
|
|
_add(pointToAdd);
|
|
updateCenter();
|
|
}
|
|
},
|
|
fits: function fits(otherPoint) {
|
|
// check cosine similarity to center-angle
|
|
var similarity = Math.abs(vec2.dot(otherPoint.point.vec, center.vec));
|
|
if (similarity > threshold) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
getPoints: function getPoints() {
|
|
return points;
|
|
},
|
|
getCenter: function getCenter() {
|
|
return center;
|
|
}
|
|
};
|
|
},
|
|
createPoint: function createPoint(newPoint, id, property) {
|
|
return {
|
|
rad: newPoint[property],
|
|
point: newPoint,
|
|
id: id
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ },
|
|
/* 52 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony default export */ exports["a"] = function () {
|
|
var events = {};
|
|
|
|
function getEvent(eventName) {
|
|
if (!events[eventName]) {
|
|
events[eventName] = {
|
|
subscribers: []
|
|
};
|
|
}
|
|
return events[eventName];
|
|
}
|
|
|
|
function clearEvents() {
|
|
events = {};
|
|
}
|
|
|
|
function publishSubscription(subscription, data) {
|
|
if (subscription.async) {
|
|
setTimeout(function () {
|
|
subscription.callback(data);
|
|
}, 4);
|
|
} else {
|
|
subscription.callback(data);
|
|
}
|
|
}
|
|
|
|
function _subscribe(event, callback, async) {
|
|
var subscription;
|
|
|
|
if (typeof callback === "function") {
|
|
subscription = {
|
|
callback: callback,
|
|
async: async
|
|
};
|
|
} else {
|
|
subscription = callback;
|
|
if (!subscription.callback) {
|
|
throw "Callback was not specified on options";
|
|
}
|
|
}
|
|
|
|
getEvent(event).subscribers.push(subscription);
|
|
}
|
|
|
|
return {
|
|
subscribe: function subscribe(event, callback, async) {
|
|
return _subscribe(event, callback, async);
|
|
},
|
|
publish: function publish(eventName, data) {
|
|
var event = getEvent(eventName),
|
|
subscribers = event.subscribers;
|
|
|
|
event.subscribers = subscribers.filter(function (subscriber) {
|
|
publishSubscription(subscriber, data);
|
|
return !subscriber.once;
|
|
});
|
|
},
|
|
once: function once(event, callback, async) {
|
|
_subscribe(event, {
|
|
callback: callback,
|
|
async: async,
|
|
once: true
|
|
});
|
|
},
|
|
unsubscribe: function unsubscribe(eventName, callback) {
|
|
var event;
|
|
|
|
if (eventName) {
|
|
event = getEvent(eventName);
|
|
if (event && callback) {
|
|
event.subscribers = event.subscribers.filter(function (subscriber) {
|
|
return subscriber.callback !== callback;
|
|
});
|
|
} else {
|
|
event.subscribers = [];
|
|
}
|
|
} else {
|
|
clearEvents();
|
|
}
|
|
}
|
|
};
|
|
}();
|
|
|
|
/***/ },
|
|
/* 53 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Construct representing a part of another {ImageWrapper}. Shares data
|
|
* between the parent and the child.
|
|
* @param from {ImageRef} The position where to start the {SubImage} from. (top-left corner)
|
|
* @param size {ImageRef} The size of the resulting image
|
|
* @param I {ImageWrapper} The {ImageWrapper} to share from
|
|
* @returns {SubImage} A shared part of the original image
|
|
*/
|
|
function SubImage(from, size, I) {
|
|
if (!I) {
|
|
I = {
|
|
data: null,
|
|
size: size
|
|
};
|
|
}
|
|
this.data = I.data;
|
|
this.originalSize = I.size;
|
|
this.I = I;
|
|
|
|
this.from = from;
|
|
this.size = size;
|
|
}
|
|
|
|
/**
|
|
* Displays the {SubImage} in a given canvas
|
|
* @param canvas {Canvas} The canvas element to write to
|
|
* @param scale {Number} Scale which is applied to each pixel-value
|
|
*/
|
|
SubImage.prototype.show = function (canvas, scale) {
|
|
var ctx, frame, data, current, y, x, pixel;
|
|
|
|
if (!scale) {
|
|
scale = 1.0;
|
|
}
|
|
ctx = canvas.getContext('2d');
|
|
canvas.width = this.size.x;
|
|
canvas.height = this.size.y;
|
|
frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
data = frame.data;
|
|
current = 0;
|
|
for (y = 0; y < this.size.y; y++) {
|
|
for (x = 0; x < this.size.x; x++) {
|
|
pixel = y * this.size.x + x;
|
|
current = this.get(x, y) * scale;
|
|
data[pixel * 4 + 0] = current;
|
|
data[pixel * 4 + 1] = current;
|
|
data[pixel * 4 + 2] = current;
|
|
data[pixel * 4 + 3] = 255;
|
|
}
|
|
}
|
|
frame.data = data;
|
|
ctx.putImageData(frame, 0, 0);
|
|
};
|
|
|
|
/**
|
|
* Retrieves a given pixel position from the {SubImage}
|
|
* @param x {Number} The x-position
|
|
* @param y {Number} The y-position
|
|
* @returns {Number} The grayscale value at the pixel-position
|
|
*/
|
|
SubImage.prototype.get = function (x, y) {
|
|
return this.data[(this.from.y + y) * this.originalSize.x + this.from.x + x];
|
|
};
|
|
|
|
/**
|
|
* Updates the underlying data from a given {ImageWrapper}
|
|
* @param image {ImageWrapper} The updated image
|
|
*/
|
|
SubImage.prototype.updateData = function (image) {
|
|
this.originalSize = image.size;
|
|
this.data = image.data;
|
|
};
|
|
|
|
/**
|
|
* Updates the position of the shared area
|
|
* @param from {x,y} The new location
|
|
* @returns {SubImage} returns {this} for possible chaining
|
|
*/
|
|
SubImage.prototype.updateFrom = function (from) {
|
|
this.from = from;
|
|
return this;
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = SubImage;
|
|
|
|
/***/ },
|
|
/* 54 */
|
|
/***/ function(module, exports) {
|
|
|
|
/*
|
|
* typedefs.js
|
|
* Normalizes browser-specific prefixes
|
|
*/
|
|
|
|
if (typeof window !== 'undefined') {
|
|
window.requestAnimFrame = function () {
|
|
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function ( /* function FrameRequestCallback */callback) {
|
|
window.setTimeout(callback, 1000 / 60);
|
|
};
|
|
}();
|
|
}
|
|
Math.imul = Math.imul || function (a, b) {
|
|
var ah = a >>> 16 & 0xffff,
|
|
al = a & 0xffff,
|
|
bh = b >>> 16 & 0xffff,
|
|
bl = b & 0xffff;
|
|
// the shift by 0 fixes the sign on the high part
|
|
// the final |0 converts the unsigned value into a signed value
|
|
return al * bl + (ah * bl + al * bh << 16 >>> 0) | 0;
|
|
};
|
|
|
|
/***/ },
|
|
/* 55 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = {
|
|
inputStream: {
|
|
name: "Live",
|
|
type: "LiveStream",
|
|
constraints: {
|
|
width: 640,
|
|
height: 480,
|
|
// aspectRatio: 640/480, // optional
|
|
facingMode: "environment" },
|
|
// or user
|
|
// deviceId: "38745983457387598375983759834"
|
|
area: {
|
|
top: "0%",
|
|
right: "0%",
|
|
left: "0%",
|
|
bottom: "0%"
|
|
},
|
|
singleChannel: false // true: only the red color-channel is read
|
|
},
|
|
locate: true,
|
|
numOfWorkers: 0,
|
|
decoder: {
|
|
readers: ['code_128_reader'],
|
|
debug: {
|
|
drawBoundingBox: false,
|
|
showFrequency: false,
|
|
drawScanline: false,
|
|
showPattern: false
|
|
}
|
|
},
|
|
locator: {
|
|
halfSample: true,
|
|
patchSize: "medium", // x-small, small, medium, large, x-large
|
|
debug: {
|
|
showCanvas: false,
|
|
showPatches: false,
|
|
showFoundPatches: false,
|
|
showSkeleton: false,
|
|
showLabels: false,
|
|
showPatchLabels: false,
|
|
showRemainingPatchLabels: false,
|
|
boxFromPatches: {
|
|
showTransformed: false,
|
|
showTransformedBox: false,
|
|
showBB: false
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/***/ },
|
|
/* 56 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var config = void 0;
|
|
|
|
if (true) {
|
|
config = __webpack_require__(55);
|
|
} else if (ENV.node) {
|
|
config = require('./config.node.js');
|
|
} else {
|
|
config = require('./config.prod.js');
|
|
}
|
|
|
|
/* harmony default export */ exports["a"] = config;
|
|
|
|
/***/ },
|
|
/* 57 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__bresenham__ = __webpack_require__(58);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_image_debug__ = __webpack_require__(9);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__reader_code_128_reader__ = __webpack_require__(67);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__reader_ean_reader__ = __webpack_require__(10);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__reader_code_39_reader__ = __webpack_require__(30);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__reader_code_39_vin_reader__ = __webpack_require__(68);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__reader_codabar_reader__ = __webpack_require__(66);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__reader_upc_reader__ = __webpack_require__(72);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__reader_ean_8_reader__ = __webpack_require__(69);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__reader_upc_e_reader__ = __webpack_require__(71);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__reader_i2of5_reader__ = __webpack_require__(70);
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var READERS = {
|
|
code_128_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_2__reader_code_128_reader__["a"],
|
|
ean_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_3__reader_ean_reader__["a"],
|
|
ean_8_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_8__reader_ean_8_reader__["a"],
|
|
code_39_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_4__reader_code_39_reader__["a"],
|
|
code_39_vin_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_5__reader_code_39_vin_reader__["a"],
|
|
codabar_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_6__reader_codabar_reader__["a"],
|
|
upc_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_7__reader_upc_reader__["a"],
|
|
upc_e_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_9__reader_upc_e_reader__["a"],
|
|
i2of5_reader: /* harmony import */__WEBPACK_IMPORTED_MODULE_10__reader_i2of5_reader__["a"]
|
|
};
|
|
/* harmony default export */ exports["a"] = {
|
|
create: function create(config, inputImageWrapper) {
|
|
var _canvas = {
|
|
ctx: {
|
|
frequency: null,
|
|
pattern: null,
|
|
overlay: null
|
|
},
|
|
dom: {
|
|
frequency: null,
|
|
pattern: null,
|
|
overlay: null
|
|
}
|
|
},
|
|
_barcodeReaders = [];
|
|
|
|
initCanvas();
|
|
initReaders();
|
|
initConfig();
|
|
|
|
function initCanvas() {
|
|
if (true && typeof document !== 'undefined') {
|
|
var $debug = document.querySelector("#debug.detection");
|
|
_canvas.dom.frequency = document.querySelector("canvas.frequency");
|
|
if (!_canvas.dom.frequency) {
|
|
_canvas.dom.frequency = document.createElement("canvas");
|
|
_canvas.dom.frequency.className = "frequency";
|
|
if ($debug) {
|
|
$debug.appendChild(_canvas.dom.frequency);
|
|
}
|
|
}
|
|
_canvas.ctx.frequency = _canvas.dom.frequency.getContext("2d");
|
|
|
|
_canvas.dom.pattern = document.querySelector("canvas.patternBuffer");
|
|
if (!_canvas.dom.pattern) {
|
|
_canvas.dom.pattern = document.createElement("canvas");
|
|
_canvas.dom.pattern.className = "patternBuffer";
|
|
if ($debug) {
|
|
$debug.appendChild(_canvas.dom.pattern);
|
|
}
|
|
}
|
|
_canvas.ctx.pattern = _canvas.dom.pattern.getContext("2d");
|
|
|
|
_canvas.dom.overlay = document.querySelector("canvas.drawingBuffer");
|
|
if (_canvas.dom.overlay) {
|
|
_canvas.ctx.overlay = _canvas.dom.overlay.getContext("2d");
|
|
}
|
|
}
|
|
}
|
|
|
|
function initReaders() {
|
|
config.readers.forEach(function (readerConfig) {
|
|
var reader,
|
|
configuration = {};
|
|
|
|
if ((typeof readerConfig === 'undefined' ? 'undefined' : _typeof(readerConfig)) === 'object') {
|
|
reader = readerConfig.format;
|
|
configuration = readerConfig.config;
|
|
} else if (typeof readerConfig === 'string') {
|
|
reader = readerConfig;
|
|
}
|
|
if (true) {
|
|
console.log("Before registering reader: ", reader);
|
|
}
|
|
_barcodeReaders.push(new READERS[reader](configuration));
|
|
});
|
|
if (true) {
|
|
console.log("Registered Readers: " + _barcodeReaders.map(function (reader) {
|
|
return JSON.stringify({ format: reader.FORMAT, config: reader.config });
|
|
}).join(', '));
|
|
}
|
|
}
|
|
|
|
function initConfig() {
|
|
if (true && typeof document !== 'undefined') {
|
|
var i,
|
|
vis = [{
|
|
node: _canvas.dom.frequency,
|
|
prop: config.debug.showFrequency
|
|
}, {
|
|
node: _canvas.dom.pattern,
|
|
prop: config.debug.showPattern
|
|
}];
|
|
|
|
for (i = 0; i < vis.length; i++) {
|
|
if (vis[i].prop === true) {
|
|
vis[i].node.style.display = "block";
|
|
} else {
|
|
vis[i].node.style.display = "none";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* extend the line on both ends
|
|
* @param {Array} line
|
|
* @param {Number} angle
|
|
*/
|
|
function getExtendedLine(line, angle, ext) {
|
|
function extendLine(amount) {
|
|
var extension = {
|
|
y: amount * Math.sin(angle),
|
|
x: amount * Math.cos(angle)
|
|
};
|
|
|
|
line[0].y -= extension.y;
|
|
line[0].x -= extension.x;
|
|
line[1].y += extension.y;
|
|
line[1].x += extension.x;
|
|
}
|
|
|
|
// check if inside image
|
|
extendLine(ext);
|
|
while (ext > 1 && (!inputImageWrapper.inImageWithBorder(line[0], 0) || !inputImageWrapper.inImageWithBorder(line[1], 0))) {
|
|
ext -= Math.ceil(ext / 2);
|
|
extendLine(-ext);
|
|
}
|
|
return line;
|
|
}
|
|
|
|
function getLine(box) {
|
|
return [{
|
|
x: (box[1][0] - box[0][0]) / 2 + box[0][0],
|
|
y: (box[1][1] - box[0][1]) / 2 + box[0][1]
|
|
}, {
|
|
x: (box[3][0] - box[2][0]) / 2 + box[2][0],
|
|
y: (box[3][1] - box[2][1]) / 2 + box[2][1]
|
|
}];
|
|
}
|
|
|
|
function tryDecode(line) {
|
|
var result = null,
|
|
i,
|
|
barcodeLine = /* harmony import */__WEBPACK_IMPORTED_MODULE_0__bresenham__["a"].getBarcodeLine(inputImageWrapper, line[0], line[1]);
|
|
|
|
if (true && config.debug.showFrequency) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_image_debug__["a"].drawPath(line, { x: 'x', y: 'y' }, _canvas.ctx.overlay, { color: 'red', lineWidth: 3 });
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__bresenham__["a"].debug.printFrequency(barcodeLine.line, _canvas.dom.frequency);
|
|
}
|
|
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__bresenham__["a"].toBinaryLine(barcodeLine);
|
|
|
|
if (true && config.debug.showPattern) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__bresenham__["a"].debug.printPattern(barcodeLine.line, _canvas.dom.pattern);
|
|
}
|
|
|
|
for (i = 0; i < _barcodeReaders.length && result === null; i++) {
|
|
result = _barcodeReaders[i].decodePattern(barcodeLine.line);
|
|
}
|
|
if (result === null) {
|
|
return null;
|
|
}
|
|
return {
|
|
codeResult: result,
|
|
barcodeLine: barcodeLine
|
|
};
|
|
}
|
|
|
|
/**
|
|
* This method slices the given area apart and tries to detect a barcode-pattern
|
|
* for each slice. It returns the decoded barcode, or null if nothing was found
|
|
* @param {Array} box
|
|
* @param {Array} line
|
|
* @param {Number} lineAngle
|
|
*/
|
|
function tryDecodeBruteForce(box, line, lineAngle) {
|
|
var sideLength = Math.sqrt(Math.pow(box[1][0] - box[0][0], 2) + Math.pow(box[1][1] - box[0][1], 2)),
|
|
i,
|
|
slices = 16,
|
|
result = null,
|
|
dir,
|
|
extension,
|
|
xdir = Math.sin(lineAngle),
|
|
ydir = Math.cos(lineAngle);
|
|
|
|
for (i = 1; i < slices && result === null; i++) {
|
|
// move line perpendicular to angle
|
|
dir = sideLength / slices * i * (i % 2 === 0 ? -1 : 1);
|
|
extension = {
|
|
y: dir * xdir,
|
|
x: dir * ydir
|
|
};
|
|
line[0].y += extension.x;
|
|
line[0].x -= extension.y;
|
|
line[1].y += extension.x;
|
|
line[1].x -= extension.y;
|
|
|
|
result = tryDecode(line);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function getLineLength(line) {
|
|
return Math.sqrt(Math.pow(Math.abs(line[1].y - line[0].y), 2) + Math.pow(Math.abs(line[1].x - line[0].x), 2));
|
|
}
|
|
|
|
/**
|
|
* With the help of the configured readers (Code128 or EAN) this function tries to detect a
|
|
* valid barcode pattern within the given area.
|
|
* @param {Object} box The area to search in
|
|
* @returns {Object} the result {codeResult, line, angle, pattern, threshold}
|
|
*/
|
|
function _decodeFromBoundingBox(box) {
|
|
var line,
|
|
lineAngle,
|
|
ctx = _canvas.ctx.overlay,
|
|
result,
|
|
lineLength;
|
|
|
|
if (true) {
|
|
if (config.debug.drawBoundingBox && ctx) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_image_debug__["a"].drawPath(box, { x: 0, y: 1 }, ctx, { color: "blue", lineWidth: 2 });
|
|
}
|
|
}
|
|
|
|
line = getLine(box);
|
|
lineLength = getLineLength(line);
|
|
lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x);
|
|
line = getExtendedLine(line, lineAngle, Math.floor(lineLength * 0.1));
|
|
if (line === null) {
|
|
return null;
|
|
}
|
|
|
|
result = tryDecode(line);
|
|
if (result === null) {
|
|
result = tryDecodeBruteForce(box, line, lineAngle);
|
|
}
|
|
|
|
if (result === null) {
|
|
return null;
|
|
}
|
|
|
|
if (true && result && config.debug.drawScanline && ctx) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_image_debug__["a"].drawPath(line, { x: 'x', y: 'y' }, ctx, { color: 'red', lineWidth: 3 });
|
|
}
|
|
|
|
return {
|
|
codeResult: result.codeResult,
|
|
line: line,
|
|
angle: lineAngle,
|
|
pattern: result.barcodeLine.line,
|
|
threshold: result.barcodeLine.threshold
|
|
};
|
|
}
|
|
|
|
return {
|
|
decodeFromBoundingBox: function decodeFromBoundingBox(box) {
|
|
return _decodeFromBoundingBox(box);
|
|
},
|
|
decodeFromBoundingBoxes: function decodeFromBoundingBoxes(boxes) {
|
|
var i,
|
|
result,
|
|
barcodes = [],
|
|
multiple = config.multiple;
|
|
|
|
for (i = 0; i < boxes.length; i++) {
|
|
var box = boxes[i];
|
|
result = _decodeFromBoundingBox(box) || {};
|
|
result.box = box;
|
|
|
|
if (multiple) {
|
|
barcodes.push(result);
|
|
} else if (result.codeResult) {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
if (multiple) {
|
|
return {
|
|
barcodes: barcodes
|
|
};
|
|
}
|
|
},
|
|
setReaders: function setReaders(readers) {
|
|
config.readers = readers;
|
|
_barcodeReaders.length = 0;
|
|
initReaders();
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ },
|
|
/* 58 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__ = __webpack_require__(18);
|
|
|
|
|
|
var Bresenham = {};
|
|
|
|
var Slope = {
|
|
DIR: {
|
|
UP: 1,
|
|
DOWN: -1
|
|
}
|
|
};
|
|
/**
|
|
* Scans a line of the given image from point p1 to p2 and returns a result object containing
|
|
* gray-scale values (0-255) of the underlying pixels in addition to the min
|
|
* and max values.
|
|
* @param {Object} imageWrapper
|
|
* @param {Object} p1 The start point {x,y}
|
|
* @param {Object} p2 The end point {x,y}
|
|
* @returns {line, min, max}
|
|
*/
|
|
Bresenham.getBarcodeLine = function (imageWrapper, p1, p2) {
|
|
var x0 = p1.x | 0,
|
|
y0 = p1.y | 0,
|
|
x1 = p2.x | 0,
|
|
y1 = p2.y | 0,
|
|
steep = Math.abs(y1 - y0) > Math.abs(x1 - x0),
|
|
deltax,
|
|
deltay,
|
|
error,
|
|
ystep,
|
|
y,
|
|
tmp,
|
|
x,
|
|
line = [],
|
|
imageData = imageWrapper.data,
|
|
width = imageWrapper.size.x,
|
|
sum = 0,
|
|
val,
|
|
min = 255,
|
|
max = 0;
|
|
|
|
function read(a, b) {
|
|
val = imageData[b * width + a];
|
|
sum += val;
|
|
min = val < min ? val : min;
|
|
max = val > max ? val : max;
|
|
line.push(val);
|
|
}
|
|
|
|
if (steep) {
|
|
tmp = x0;
|
|
x0 = y0;
|
|
y0 = tmp;
|
|
|
|
tmp = x1;
|
|
x1 = y1;
|
|
y1 = tmp;
|
|
}
|
|
if (x0 > x1) {
|
|
tmp = x0;
|
|
x0 = x1;
|
|
x1 = tmp;
|
|
|
|
tmp = y0;
|
|
y0 = y1;
|
|
y1 = tmp;
|
|
}
|
|
deltax = x1 - x0;
|
|
deltay = Math.abs(y1 - y0);
|
|
error = deltax / 2 | 0;
|
|
y = y0;
|
|
ystep = y0 < y1 ? 1 : -1;
|
|
for (x = x0; x < x1; x++) {
|
|
if (steep) {
|
|
read(y, x);
|
|
} else {
|
|
read(x, y);
|
|
}
|
|
error = error - deltay;
|
|
if (error < 0) {
|
|
y = y + ystep;
|
|
error = error + deltax;
|
|
}
|
|
}
|
|
|
|
return {
|
|
line: line,
|
|
min: min,
|
|
max: max
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Converts the result from getBarcodeLine into a binary representation
|
|
* also considering the frequency and slope of the signal for more robust results
|
|
* @param {Object} result {line, min, max}
|
|
*/
|
|
Bresenham.toBinaryLine = function (result) {
|
|
var min = result.min,
|
|
max = result.max,
|
|
line = result.line,
|
|
slope,
|
|
slope2,
|
|
center = min + (max - min) / 2,
|
|
extrema = [],
|
|
currentDir,
|
|
dir,
|
|
threshold = (max - min) / 12,
|
|
rThreshold = -threshold,
|
|
i,
|
|
j;
|
|
|
|
// 1. find extrema
|
|
currentDir = line[0] > center ? Slope.DIR.UP : Slope.DIR.DOWN;
|
|
extrema.push({
|
|
pos: 0,
|
|
val: line[0]
|
|
});
|
|
for (i = 0; i < line.length - 2; i++) {
|
|
slope = line[i + 1] - line[i];
|
|
slope2 = line[i + 2] - line[i + 1];
|
|
if (slope + slope2 < rThreshold && line[i + 1] < center * 1.5) {
|
|
dir = Slope.DIR.DOWN;
|
|
} else if (slope + slope2 > threshold && line[i + 1] > center * 0.5) {
|
|
dir = Slope.DIR.UP;
|
|
} else {
|
|
dir = currentDir;
|
|
}
|
|
|
|
if (currentDir !== dir) {
|
|
extrema.push({
|
|
pos: i,
|
|
val: line[i]
|
|
});
|
|
currentDir = dir;
|
|
}
|
|
}
|
|
extrema.push({
|
|
pos: line.length,
|
|
val: line[line.length - 1]
|
|
});
|
|
|
|
for (j = extrema[0].pos; j < extrema[1].pos; j++) {
|
|
line[j] = line[j] > center ? 0 : 1;
|
|
}
|
|
|
|
// iterate over extrema and convert to binary based on avg between minmax
|
|
for (i = 1; i < extrema.length - 1; i++) {
|
|
if (extrema[i + 1].val > extrema[i].val) {
|
|
threshold = extrema[i].val + (extrema[i + 1].val - extrema[i].val) / 3 * 2 | 0;
|
|
} else {
|
|
threshold = extrema[i + 1].val + (extrema[i].val - extrema[i + 1].val) / 3 | 0;
|
|
}
|
|
|
|
for (j = extrema[i].pos; j < extrema[i + 1].pos; j++) {
|
|
line[j] = line[j] > threshold ? 0 : 1;
|
|
}
|
|
}
|
|
|
|
return {
|
|
line: line,
|
|
threshold: threshold
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Used for development only
|
|
*/
|
|
Bresenham.debug = {
|
|
printFrequency: function printFrequency(line, canvas) {
|
|
var i,
|
|
ctx = canvas.getContext("2d");
|
|
canvas.width = line.length;
|
|
canvas.height = 256;
|
|
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = "blue";
|
|
for (i = 0; i < line.length; i++) {
|
|
ctx.moveTo(i, 255);
|
|
ctx.lineTo(i, 255 - line[i]);
|
|
}
|
|
ctx.stroke();
|
|
ctx.closePath();
|
|
},
|
|
|
|
printPattern: function printPattern(line, canvas) {
|
|
var ctx = canvas.getContext("2d"),
|
|
i;
|
|
|
|
canvas.width = line.length;
|
|
ctx.fillColor = "black";
|
|
for (i = 0; i < line.length; i++) {
|
|
if (line[i] === 1) {
|
|
ctx.fillRect(i, 0, 1, 100);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = Bresenham;
|
|
|
|
/***/ },
|
|
/* 59 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_lodash_pick__ = __webpack_require__(143);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_lodash_pick___default = __WEBPACK_IMPORTED_MODULE_0_lodash_pick__ && __WEBPACK_IMPORTED_MODULE_0_lodash_pick__.__esModule ? function() { return __WEBPACK_IMPORTED_MODULE_0_lodash_pick__['default'] } : function() { return __WEBPACK_IMPORTED_MODULE_0_lodash_pick__; }
|
|
/* harmony import */ Object.defineProperty(__WEBPACK_IMPORTED_MODULE_0_lodash_pick___default, 'a', { get: __WEBPACK_IMPORTED_MODULE_0_lodash_pick___default });
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_lodash_merge__ = __webpack_require__(28);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_lodash_merge___default = __WEBPACK_IMPORTED_MODULE_1_lodash_merge__ && __WEBPACK_IMPORTED_MODULE_1_lodash_merge__.__esModule ? function() { return __WEBPACK_IMPORTED_MODULE_1_lodash_merge__['default'] } : function() { return __WEBPACK_IMPORTED_MODULE_1_lodash_merge__; }
|
|
/* harmony import */ Object.defineProperty(__WEBPACK_IMPORTED_MODULE_1_lodash_merge___default, 'a', { get: __WEBPACK_IMPORTED_MODULE_1_lodash_merge___default });
|
|
|
|
|
|
|
|
|
|
var streamRef, loadedDataHandler;
|
|
|
|
function waitForVideo(video) {
|
|
return new Promise(function (resolve, reject) {
|
|
var attempts = 10;
|
|
|
|
function checkVideo() {
|
|
if (attempts > 0) {
|
|
if (video.videoWidth > 0 && video.videoHeight > 0) {
|
|
if (true) {
|
|
console.log(video.videoWidth + "px x " + video.videoHeight + "px");
|
|
}
|
|
resolve();
|
|
} else {
|
|
window.setTimeout(checkVideo, 500);
|
|
}
|
|
} else {
|
|
reject('Unable to play video stream. Is webcam working?');
|
|
}
|
|
attempts--;
|
|
}
|
|
checkVideo();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Tries to attach the camera-stream to a given video-element
|
|
* and calls the callback function when the content is ready
|
|
* @param {Object} constraints
|
|
* @param {Object} video
|
|
*/
|
|
function initCamera(video, constraints) {
|
|
return navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
|
|
return new Promise(function (resolve, reject) {
|
|
streamRef = stream;
|
|
video.src = window.URL.createObjectURL(stream);
|
|
video.onloadedmetadata = function (e) {
|
|
video.play();
|
|
resolve();
|
|
};
|
|
});
|
|
}).then(waitForVideo.bind(null, video));
|
|
}
|
|
|
|
function deprecatedConstraints(videoConstraints) {
|
|
var normalized = /* harmony import */__WEBPACK_IMPORTED_MODULE_0_lodash_pick___default.a.bind()(videoConstraints, ["width", "height", "facingMode", "aspectRatio", "deviceId"]);
|
|
|
|
if (typeof videoConstraints["minAspectRatio"] !== 'undefined' && videoConstraints["minAspectRatio"] > 0) {
|
|
normalized["aspectRatio"] = videoConstraints["minAspectRatio"];
|
|
console.log("WARNING: Constraint 'minAspectRatio' is deprecated; Use 'aspectRatio' instead");
|
|
}
|
|
if (typeof videoConstraints["facing"] !== 'undefined') {
|
|
normalized["facingMode"] = videoConstraints["facing"];
|
|
console.log("WARNING: Constraint 'facing' is deprecated. Use 'facingMode' instead'");
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
function applyCameraFacing(facing, constraints) {
|
|
if (typeof constraints.video.deviceId !== 'undefined' || !facing) {
|
|
return Promise.resolve(constraints);
|
|
}
|
|
if (typeof MediaStreamTrack !== 'undefined' && typeof MediaStreamTrack.getSources !== 'undefined') {
|
|
return new Promise(function (resolve, reject) {
|
|
MediaStreamTrack.getSources(function (sourceInfos) {
|
|
var videoSource = sourceInfos.filter(function (sourceInfo) {
|
|
return sourceInfo.kind === "video" && sourceInfo.facing === facing;
|
|
})[0];
|
|
if (videoSource) {
|
|
return resolve(/* harmony import */__WEBPACK_IMPORTED_MODULE_1_lodash_merge___default.a.bind()({}, constraints, { video: { deviceId: videoSource.id } }));
|
|
}
|
|
return resolve(constraints);
|
|
});
|
|
});
|
|
}
|
|
return Promise.resolve(/* harmony import */__WEBPACK_IMPORTED_MODULE_1_lodash_merge___default.a.bind()({}, constraints, { video: { facingMode: facing } }));
|
|
}
|
|
|
|
function pickConstraints(videoConstraints) {
|
|
var constraints = {
|
|
audio: false,
|
|
video: deprecatedConstraints(videoConstraints)
|
|
};
|
|
return applyCameraFacing(constraints.video.facingMode, constraints);
|
|
}
|
|
|
|
/* harmony default export */ exports["a"] = {
|
|
request: function request(video, videoConstraints) {
|
|
return pickConstraints(videoConstraints).then(initCamera.bind(null, video));
|
|
},
|
|
release: function release() {
|
|
var tracks = streamRef && streamRef.getVideoTracks();
|
|
if (tracks && tracks.length) {
|
|
tracks[0].stop();
|
|
}
|
|
streamRef = null;
|
|
}
|
|
};
|
|
|
|
/***/ },
|
|
/* 60 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common_cv_utils__ = __webpack_require__(17);
|
|
|
|
|
|
var FrameGrabber = {};
|
|
|
|
FrameGrabber.create = function (inputStream, canvas) {
|
|
var _that = {},
|
|
_streamConfig = inputStream.getConfig(),
|
|
_video_size = /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_cv_utils__["f"].bind()(inputStream.getRealWidth(), inputStream.getRealHeight()),
|
|
_canvasSize = inputStream.getCanvasSize(),
|
|
_size = /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_cv_utils__["f"].bind()(inputStream.getWidth(), inputStream.getHeight()),
|
|
topRight = inputStream.getTopRight(),
|
|
_sx = topRight.x,
|
|
_sy = topRight.y,
|
|
_canvas,
|
|
_ctx = null,
|
|
_data = null;
|
|
|
|
_canvas = canvas ? canvas : document.createElement("canvas");
|
|
_canvas.width = _canvasSize.x;
|
|
_canvas.height = _canvasSize.y;
|
|
_ctx = _canvas.getContext("2d");
|
|
_data = new Uint8Array(_size.x * _size.y);
|
|
if (true) {
|
|
console.log("FrameGrabber", JSON.stringify({
|
|
size: _size,
|
|
topRight: topRight,
|
|
videoSize: _video_size,
|
|
canvasSize: _canvasSize
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Uses the given array as frame-buffer
|
|
*/
|
|
_that.attachData = function (data) {
|
|
_data = data;
|
|
};
|
|
|
|
/**
|
|
* Returns the used frame-buffer
|
|
*/
|
|
_that.getData = function () {
|
|
return _data;
|
|
};
|
|
|
|
/**
|
|
* Fetches a frame from the input-stream and puts into the frame-buffer.
|
|
* The image-data is converted to gray-scale and then half-sampled if configured.
|
|
*/
|
|
_that.grab = function () {
|
|
var doHalfSample = _streamConfig.halfSample,
|
|
frame = inputStream.getFrame(),
|
|
ctxData;
|
|
if (frame) {
|
|
_ctx.drawImage(frame, 0, 0, _canvasSize.x, _canvasSize.y);
|
|
ctxData = _ctx.getImageData(_sx, _sy, _size.x, _size.y).data;
|
|
if (doHalfSample) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_cv_utils__["i"].bind()(ctxData, _size, _data);
|
|
} else {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_cv_utils__["j"].bind()(ctxData, _data, _streamConfig);
|
|
}
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
_that.getSize = function () {
|
|
return _size;
|
|
};
|
|
|
|
return _that;
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = FrameGrabber;
|
|
|
|
/***/ },
|
|
/* 61 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var ImageLoader = {};
|
|
ImageLoader.load = function (directory, callback, offset, size, sequence) {
|
|
var htmlImagesSrcArray = new Array(size),
|
|
htmlImagesArray = new Array(htmlImagesSrcArray.length),
|
|
i,
|
|
img,
|
|
num;
|
|
|
|
if (sequence === false) {
|
|
htmlImagesSrcArray[0] = directory;
|
|
} else {
|
|
for (i = 0; i < htmlImagesSrcArray.length; i++) {
|
|
num = offset + i;
|
|
htmlImagesSrcArray[i] = directory + "image-" + ("00" + num).slice(-3) + ".jpg";
|
|
}
|
|
}
|
|
htmlImagesArray.notLoaded = [];
|
|
htmlImagesArray.addImage = function (image) {
|
|
htmlImagesArray.notLoaded.push(image);
|
|
};
|
|
htmlImagesArray.loaded = function (loadedImg) {
|
|
var notloadedImgs = htmlImagesArray.notLoaded;
|
|
for (var x = 0; x < notloadedImgs.length; x++) {
|
|
if (notloadedImgs[x] === loadedImg) {
|
|
notloadedImgs.splice(x, 1);
|
|
for (var y = 0; y < htmlImagesSrcArray.length; y++) {
|
|
var imgName = htmlImagesSrcArray[y].substr(htmlImagesSrcArray[y].lastIndexOf("/"));
|
|
if (loadedImg.src.lastIndexOf(imgName) !== -1) {
|
|
htmlImagesArray[y] = loadedImg;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (notloadedImgs.length === 0) {
|
|
if (true) {
|
|
console.log("Images loaded");
|
|
}
|
|
callback.apply(null, [htmlImagesArray]);
|
|
}
|
|
};
|
|
|
|
for (i = 0; i < htmlImagesSrcArray.length; i++) {
|
|
img = new Image();
|
|
htmlImagesArray.addImage(img);
|
|
addOnloadHandler(img, htmlImagesArray);
|
|
img.src = htmlImagesSrcArray[i];
|
|
}
|
|
};
|
|
|
|
function addOnloadHandler(img, htmlImagesArray) {
|
|
img.onload = function () {
|
|
htmlImagesArray.loaded(this);
|
|
};
|
|
}
|
|
|
|
/* harmony default export */ exports["a"] = ImageLoader;
|
|
|
|
/***/ },
|
|
/* 62 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__image_loader__ = __webpack_require__(61);
|
|
|
|
|
|
var InputStream = {};
|
|
InputStream.createVideoStream = function (video) {
|
|
var that = {},
|
|
_config = null,
|
|
_eventNames = ['canrecord', 'ended'],
|
|
_eventHandlers = {},
|
|
_calculatedWidth,
|
|
_calculatedHeight,
|
|
_topRight = { x: 0, y: 0 },
|
|
_canvasSize = { x: 0, y: 0 };
|
|
|
|
function initSize() {
|
|
var width = video.videoWidth,
|
|
height = video.videoHeight;
|
|
|
|
_calculatedWidth = _config.size ? width / height > 1 ? _config.size : Math.floor(width / height * _config.size) : width;
|
|
_calculatedHeight = _config.size ? width / height > 1 ? Math.floor(height / width * _config.size) : _config.size : height;
|
|
|
|
_canvasSize.x = _calculatedWidth;
|
|
_canvasSize.y = _calculatedHeight;
|
|
}
|
|
|
|
that.getRealWidth = function () {
|
|
return video.videoWidth;
|
|
};
|
|
|
|
that.getRealHeight = function () {
|
|
return video.videoHeight;
|
|
};
|
|
|
|
that.getWidth = function () {
|
|
return _calculatedWidth;
|
|
};
|
|
|
|
that.getHeight = function () {
|
|
return _calculatedHeight;
|
|
};
|
|
|
|
that.setWidth = function (width) {
|
|
_calculatedWidth = width;
|
|
};
|
|
|
|
that.setHeight = function (height) {
|
|
_calculatedHeight = height;
|
|
};
|
|
|
|
that.setInputStream = function (config) {
|
|
_config = config;
|
|
video.src = typeof config.src !== 'undefined' ? config.src : '';
|
|
};
|
|
|
|
that.ended = function () {
|
|
return video.ended;
|
|
};
|
|
|
|
that.getConfig = function () {
|
|
return _config;
|
|
};
|
|
|
|
that.setAttribute = function (name, value) {
|
|
video.setAttribute(name, value);
|
|
};
|
|
|
|
that.pause = function () {
|
|
video.pause();
|
|
};
|
|
|
|
that.play = function () {
|
|
video.play();
|
|
};
|
|
|
|
that.setCurrentTime = function (time) {
|
|
if (_config.type !== "LiveStream") {
|
|
video.currentTime = time;
|
|
}
|
|
};
|
|
|
|
that.addEventListener = function (event, f, bool) {
|
|
if (_eventNames.indexOf(event) !== -1) {
|
|
if (!_eventHandlers[event]) {
|
|
_eventHandlers[event] = [];
|
|
}
|
|
_eventHandlers[event].push(f);
|
|
} else {
|
|
video.addEventListener(event, f, bool);
|
|
}
|
|
};
|
|
|
|
that.clearEventHandlers = function () {
|
|
_eventNames.forEach(function (eventName) {
|
|
var handlers = _eventHandlers[eventName];
|
|
if (handlers && handlers.length > 0) {
|
|
handlers.forEach(function (handler) {
|
|
video.removeEventListener(eventName, handler);
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
that.trigger = function (eventName, args) {
|
|
var j,
|
|
handlers = _eventHandlers[eventName];
|
|
|
|
if (eventName === 'canrecord') {
|
|
initSize();
|
|
}
|
|
if (handlers && handlers.length > 0) {
|
|
for (j = 0; j < handlers.length; j++) {
|
|
handlers[j].apply(that, args);
|
|
}
|
|
}
|
|
};
|
|
|
|
that.setTopRight = function (topRight) {
|
|
_topRight.x = topRight.x;
|
|
_topRight.y = topRight.y;
|
|
};
|
|
|
|
that.getTopRight = function () {
|
|
return _topRight;
|
|
};
|
|
|
|
that.setCanvasSize = function (size) {
|
|
_canvasSize.x = size.x;
|
|
_canvasSize.y = size.y;
|
|
};
|
|
|
|
that.getCanvasSize = function () {
|
|
return _canvasSize;
|
|
};
|
|
|
|
that.getFrame = function () {
|
|
return video;
|
|
};
|
|
|
|
return that;
|
|
};
|
|
|
|
InputStream.createLiveStream = function (video) {
|
|
video.setAttribute("autoplay", true);
|
|
var that = InputStream.createVideoStream(video);
|
|
|
|
that.ended = function () {
|
|
return false;
|
|
};
|
|
|
|
return that;
|
|
};
|
|
|
|
InputStream.createImageStream = function () {
|
|
var that = {};
|
|
var _config = null;
|
|
|
|
var width = 0,
|
|
height = 0,
|
|
frameIdx = 0,
|
|
paused = true,
|
|
loaded = false,
|
|
imgArray = null,
|
|
size = 0,
|
|
offset = 1,
|
|
baseUrl = null,
|
|
ended = false,
|
|
calculatedWidth,
|
|
calculatedHeight,
|
|
_eventNames = ['canrecord', 'ended'],
|
|
_eventHandlers = {},
|
|
_topRight = { x: 0, y: 0 },
|
|
_canvasSize = { x: 0, y: 0 };
|
|
|
|
function loadImages() {
|
|
loaded = false;
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__image_loader__["a"].load(baseUrl, function (imgs) {
|
|
imgArray = imgs;
|
|
width = imgs[0].width;
|
|
height = imgs[0].height;
|
|
calculatedWidth = _config.size ? width / height > 1 ? _config.size : Math.floor(width / height * _config.size) : width;
|
|
calculatedHeight = _config.size ? width / height > 1 ? Math.floor(height / width * _config.size) : _config.size : height;
|
|
_canvasSize.x = calculatedWidth;
|
|
_canvasSize.y = calculatedHeight;
|
|
loaded = true;
|
|
frameIdx = 0;
|
|
setTimeout(function () {
|
|
publishEvent("canrecord", []);
|
|
}, 0);
|
|
}, offset, size, _config.sequence);
|
|
}
|
|
|
|
function publishEvent(eventName, args) {
|
|
var j,
|
|
handlers = _eventHandlers[eventName];
|
|
|
|
if (handlers && handlers.length > 0) {
|
|
for (j = 0; j < handlers.length; j++) {
|
|
handlers[j].apply(that, args);
|
|
}
|
|
}
|
|
}
|
|
|
|
that.trigger = publishEvent;
|
|
|
|
that.getWidth = function () {
|
|
return calculatedWidth;
|
|
};
|
|
|
|
that.getHeight = function () {
|
|
return calculatedHeight;
|
|
};
|
|
|
|
that.setWidth = function (newWidth) {
|
|
calculatedWidth = newWidth;
|
|
};
|
|
|
|
that.setHeight = function (newHeight) {
|
|
calculatedHeight = newHeight;
|
|
};
|
|
|
|
that.getRealWidth = function () {
|
|
return width;
|
|
};
|
|
|
|
that.getRealHeight = function () {
|
|
return height;
|
|
};
|
|
|
|
that.setInputStream = function (stream) {
|
|
_config = stream;
|
|
if (stream.sequence === false) {
|
|
baseUrl = stream.src;
|
|
size = 1;
|
|
} else {
|
|
baseUrl = stream.src;
|
|
size = stream.length;
|
|
}
|
|
loadImages();
|
|
};
|
|
|
|
that.ended = function () {
|
|
return ended;
|
|
};
|
|
|
|
that.setAttribute = function () {};
|
|
|
|
that.getConfig = function () {
|
|
return _config;
|
|
};
|
|
|
|
that.pause = function () {
|
|
paused = true;
|
|
};
|
|
|
|
that.play = function () {
|
|
paused = false;
|
|
};
|
|
|
|
that.setCurrentTime = function (time) {
|
|
frameIdx = time;
|
|
};
|
|
|
|
that.addEventListener = function (event, f) {
|
|
if (_eventNames.indexOf(event) !== -1) {
|
|
if (!_eventHandlers[event]) {
|
|
_eventHandlers[event] = [];
|
|
}
|
|
_eventHandlers[event].push(f);
|
|
}
|
|
};
|
|
|
|
that.setTopRight = function (topRight) {
|
|
_topRight.x = topRight.x;
|
|
_topRight.y = topRight.y;
|
|
};
|
|
|
|
that.getTopRight = function () {
|
|
return _topRight;
|
|
};
|
|
|
|
that.setCanvasSize = function (canvasSize) {
|
|
_canvasSize.x = canvasSize.x;
|
|
_canvasSize.y = canvasSize.y;
|
|
};
|
|
|
|
that.getCanvasSize = function () {
|
|
return _canvasSize;
|
|
};
|
|
|
|
that.getFrame = function () {
|
|
var frame;
|
|
|
|
if (!loaded) {
|
|
return null;
|
|
}
|
|
if (!paused) {
|
|
frame = imgArray[frameIdx];
|
|
if (frameIdx < size - 1) {
|
|
frameIdx++;
|
|
} else {
|
|
setTimeout(function () {
|
|
ended = true;
|
|
publishEvent("ended", []);
|
|
}, 0);
|
|
}
|
|
}
|
|
return frame;
|
|
};
|
|
|
|
return that;
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = InputStream;
|
|
|
|
/***/ },
|
|
/* 63 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(global) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__ = __webpack_require__(18);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_cv_utils__ = __webpack_require__(17);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_array_helper__ = __webpack_require__(8);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_image_debug__ = __webpack_require__(9);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__rasterizer__ = __webpack_require__(64);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__tracer__ = __webpack_require__(29);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__skeletonizer__ = __webpack_require__(65);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var vec2 = {
|
|
clone: __webpack_require__(6),
|
|
dot: __webpack_require__(31),
|
|
scale: __webpack_require__(76),
|
|
transformMat2: __webpack_require__(77)
|
|
};
|
|
var mat2 = {
|
|
copy: __webpack_require__(73),
|
|
create: __webpack_require__(74),
|
|
invert: __webpack_require__(75)
|
|
};
|
|
|
|
var _config,
|
|
_currentImageWrapper,
|
|
_skelImageWrapper,
|
|
_subImageWrapper,
|
|
_labelImageWrapper,
|
|
_patchGrid,
|
|
_patchLabelGrid,
|
|
_imageToPatchGrid,
|
|
_binaryImageWrapper,
|
|
_patchSize,
|
|
_canvasContainer = {
|
|
ctx: {
|
|
binary: null
|
|
},
|
|
dom: {
|
|
binary: null
|
|
}
|
|
},
|
|
_numPatches = { x: 0, y: 0 },
|
|
_inputImageWrapper,
|
|
_skeletonizer;
|
|
|
|
function initBuffers() {
|
|
var skeletonImageData;
|
|
|
|
if (_config.halfSample) {
|
|
_currentImageWrapper = new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__["a"]({
|
|
x: _inputImageWrapper.size.x / 2 | 0,
|
|
y: _inputImageWrapper.size.y / 2 | 0
|
|
});
|
|
} else {
|
|
_currentImageWrapper = _inputImageWrapper;
|
|
}
|
|
|
|
_patchSize = /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["b"].bind()(_config.patchSize, _currentImageWrapper.size);
|
|
|
|
_numPatches.x = _currentImageWrapper.size.x / _patchSize.x | 0;
|
|
_numPatches.y = _currentImageWrapper.size.y / _patchSize.y | 0;
|
|
|
|
_binaryImageWrapper = new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__["a"](_currentImageWrapper.size, undefined, Uint8Array, false);
|
|
|
|
_labelImageWrapper = new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__["a"](_patchSize, undefined, Array, true);
|
|
|
|
skeletonImageData = new ArrayBuffer(64 * 1024);
|
|
_subImageWrapper = new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__["a"](_patchSize, new Uint8Array(skeletonImageData, 0, _patchSize.x * _patchSize.y));
|
|
_skelImageWrapper = new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__["a"](_patchSize, new Uint8Array(skeletonImageData, _patchSize.x * _patchSize.y * 3, _patchSize.x * _patchSize.y), undefined, true);
|
|
_skeletonizer = /* harmony import */__WEBPACK_IMPORTED_MODULE_6__skeletonizer__["a"].bind()(typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : global, {
|
|
size: _patchSize.x
|
|
}, skeletonImageData);
|
|
|
|
_imageToPatchGrid = new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__["a"]({
|
|
x: _currentImageWrapper.size.x / _subImageWrapper.size.x | 0,
|
|
y: _currentImageWrapper.size.y / _subImageWrapper.size.y | 0
|
|
}, undefined, Array, true);
|
|
_patchGrid = new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__["a"](_imageToPatchGrid.size, undefined, undefined, true);
|
|
_patchLabelGrid = new /* harmony import */__WEBPACK_IMPORTED_MODULE_0__common_image_wrapper__["a"](_imageToPatchGrid.size, undefined, Int32Array, true);
|
|
}
|
|
|
|
function initCanvas() {
|
|
if (_config.useWorker || typeof document === 'undefined') {
|
|
return;
|
|
}
|
|
_canvasContainer.dom.binary = document.createElement("canvas");
|
|
_canvasContainer.dom.binary.className = "binaryBuffer";
|
|
if (true && _config.debug.showCanvas === true) {
|
|
document.querySelector("#debug").appendChild(_canvasContainer.dom.binary);
|
|
}
|
|
_canvasContainer.ctx.binary = _canvasContainer.dom.binary.getContext("2d");
|
|
_canvasContainer.dom.binary.width = _binaryImageWrapper.size.x;
|
|
_canvasContainer.dom.binary.height = _binaryImageWrapper.size.y;
|
|
}
|
|
|
|
/**
|
|
* Creates a bounding box which encloses all the given patches
|
|
* @returns {Array} The minimal bounding box
|
|
*/
|
|
function boxFromPatches(patches) {
|
|
var overAvg,
|
|
i,
|
|
j,
|
|
patch,
|
|
transMat,
|
|
minx = _binaryImageWrapper.size.x,
|
|
miny = _binaryImageWrapper.size.y,
|
|
maxx = -_binaryImageWrapper.size.x,
|
|
maxy = -_binaryImageWrapper.size.y,
|
|
box,
|
|
scale;
|
|
|
|
// draw all patches which are to be taken into consideration
|
|
overAvg = 0;
|
|
for (i = 0; i < patches.length; i++) {
|
|
patch = patches[i];
|
|
overAvg += patch.rad;
|
|
if (true && _config.debug.showPatches) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_debug__["a"].drawRect(patch.pos, _subImageWrapper.size, _canvasContainer.ctx.binary, { color: "red" });
|
|
}
|
|
}
|
|
|
|
overAvg /= patches.length;
|
|
overAvg = (overAvg * 180 / Math.PI + 90) % 180 - 90;
|
|
if (overAvg < 0) {
|
|
overAvg += 180;
|
|
}
|
|
|
|
overAvg = (180 - overAvg) * Math.PI / 180;
|
|
transMat = mat2.copy(mat2.create(), [Math.cos(overAvg), Math.sin(overAvg), -Math.sin(overAvg), Math.cos(overAvg)]);
|
|
|
|
// iterate over patches and rotate by angle
|
|
for (i = 0; i < patches.length; i++) {
|
|
patch = patches[i];
|
|
for (j = 0; j < 4; j++) {
|
|
vec2.transformMat2(patch.box[j], patch.box[j], transMat);
|
|
}
|
|
|
|
if (true && _config.debug.boxFromPatches.showTransformed) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_debug__["a"].drawPath(patch.box, { x: 0, y: 1 }, _canvasContainer.ctx.binary, { color: '#99ff00', lineWidth: 2 });
|
|
}
|
|
}
|
|
|
|
// find bounding box
|
|
for (i = 0; i < patches.length; i++) {
|
|
patch = patches[i];
|
|
for (j = 0; j < 4; j++) {
|
|
if (patch.box[j][0] < minx) {
|
|
minx = patch.box[j][0];
|
|
}
|
|
if (patch.box[j][0] > maxx) {
|
|
maxx = patch.box[j][0];
|
|
}
|
|
if (patch.box[j][1] < miny) {
|
|
miny = patch.box[j][1];
|
|
}
|
|
if (patch.box[j][1] > maxy) {
|
|
maxy = patch.box[j][1];
|
|
}
|
|
}
|
|
}
|
|
|
|
box = [[minx, miny], [maxx, miny], [maxx, maxy], [minx, maxy]];
|
|
|
|
if (true && _config.debug.boxFromPatches.showTransformedBox) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_debug__["a"].drawPath(box, { x: 0, y: 1 }, _canvasContainer.ctx.binary, { color: '#ff0000', lineWidth: 2 });
|
|
}
|
|
|
|
scale = _config.halfSample ? 2 : 1;
|
|
// reverse rotation;
|
|
transMat = mat2.invert(transMat, transMat);
|
|
for (j = 0; j < 4; j++) {
|
|
vec2.transformMat2(box[j], box[j], transMat);
|
|
}
|
|
|
|
if (true && _config.debug.boxFromPatches.showBB) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_debug__["a"].drawPath(box, { x: 0, y: 1 }, _canvasContainer.ctx.binary, { color: '#ff0000', lineWidth: 2 });
|
|
}
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
vec2.scale(box[j], box[j], scale);
|
|
}
|
|
|
|
return box;
|
|
}
|
|
|
|
/**
|
|
* Creates a binary image of the current image
|
|
*/
|
|
function binarizeImage() {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["c"].bind()(_currentImageWrapper, _binaryImageWrapper);
|
|
_binaryImageWrapper.zeroBorder();
|
|
if (true && _config.debug.showCanvas) {
|
|
_binaryImageWrapper.show(_canvasContainer.dom.binary, 255);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Iterate over the entire image
|
|
* extract patches
|
|
*/
|
|
function findPatches() {
|
|
var i,
|
|
j,
|
|
x,
|
|
y,
|
|
moments,
|
|
patchesFound = [],
|
|
rasterizer,
|
|
rasterResult,
|
|
patch;
|
|
for (i = 0; i < _numPatches.x; i++) {
|
|
for (j = 0; j < _numPatches.y; j++) {
|
|
x = _subImageWrapper.size.x * i;
|
|
y = _subImageWrapper.size.y * j;
|
|
|
|
// seperate parts
|
|
skeletonize(x, y);
|
|
|
|
// Rasterize, find individual bars
|
|
_skelImageWrapper.zeroBorder();
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_2__common_array_helper__["a"].init(_labelImageWrapper.data, 0);
|
|
rasterizer = /* harmony import */__WEBPACK_IMPORTED_MODULE_4__rasterizer__["a"].create(_skelImageWrapper, _labelImageWrapper);
|
|
rasterResult = rasterizer.rasterize(0);
|
|
|
|
if (true && _config.debug.showLabels) {
|
|
_labelImageWrapper.overlay(_canvasContainer.dom.binary, Math.floor(360 / rasterResult.count), { x: x, y: y });
|
|
}
|
|
|
|
// calculate moments from the skeletonized patch
|
|
moments = _labelImageWrapper.moments(rasterResult.count);
|
|
|
|
// extract eligible patches
|
|
patchesFound = patchesFound.concat(describePatch(moments, [i, j], x, y));
|
|
}
|
|
}
|
|
|
|
if (true && _config.debug.showFoundPatches) {
|
|
for (i = 0; i < patchesFound.length; i++) {
|
|
patch = patchesFound[i];
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_debug__["a"].drawRect(patch.pos, _subImageWrapper.size, _canvasContainer.ctx.binary, { color: "#99ff00", lineWidth: 2 });
|
|
}
|
|
}
|
|
|
|
return patchesFound;
|
|
}
|
|
|
|
/**
|
|
* Finds those connected areas which contain at least 6 patches
|
|
* and returns them ordered DESC by the number of contained patches
|
|
* @param {Number} maxLabel
|
|
*/
|
|
function findBiggestConnectedAreas(maxLabel) {
|
|
var i,
|
|
sum,
|
|
labelHist = [],
|
|
topLabels = [];
|
|
|
|
for (i = 0; i < maxLabel; i++) {
|
|
labelHist.push(0);
|
|
}
|
|
sum = _patchLabelGrid.data.length;
|
|
while (sum--) {
|
|
if (_patchLabelGrid.data[sum] > 0) {
|
|
labelHist[_patchLabelGrid.data[sum] - 1]++;
|
|
}
|
|
}
|
|
|
|
labelHist = labelHist.map(function (val, idx) {
|
|
return {
|
|
val: val,
|
|
label: idx + 1
|
|
};
|
|
});
|
|
|
|
labelHist.sort(function (a, b) {
|
|
return b.val - a.val;
|
|
});
|
|
|
|
// extract top areas with at least 6 patches present
|
|
topLabels = labelHist.filter(function (el) {
|
|
return el.val >= 5;
|
|
});
|
|
|
|
return topLabels;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
function findBoxes(topLabels, maxLabel) {
|
|
var i,
|
|
j,
|
|
sum,
|
|
patches = [],
|
|
patch,
|
|
box,
|
|
boxes = [],
|
|
hsv = [0, 1, 1],
|
|
rgb = [0, 0, 0];
|
|
|
|
for (i = 0; i < topLabels.length; i++) {
|
|
sum = _patchLabelGrid.data.length;
|
|
patches.length = 0;
|
|
while (sum--) {
|
|
if (_patchLabelGrid.data[sum] === topLabels[i].label) {
|
|
patch = _imageToPatchGrid.data[sum];
|
|
patches.push(patch);
|
|
}
|
|
}
|
|
box = boxFromPatches(patches);
|
|
if (box) {
|
|
boxes.push(box);
|
|
|
|
// draw patch-labels if requested
|
|
if (true && _config.debug.showRemainingPatchLabels) {
|
|
for (j = 0; j < patches.length; j++) {
|
|
patch = patches[j];
|
|
hsv[0] = topLabels[i].label / (maxLabel + 1) * 360;
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["a"].bind()(hsv, rgb);
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_debug__["a"].drawRect(patch.pos, _subImageWrapper.size, _canvasContainer.ctx.binary, { color: "rgb(" + rgb.join(",") + ")", lineWidth: 2 });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return boxes;
|
|
}
|
|
|
|
/**
|
|
* Find similar moments (via cluster)
|
|
* @param {Object} moments
|
|
*/
|
|
function similarMoments(moments) {
|
|
var clusters = /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["d"].bind()(moments, 0.90);
|
|
var topCluster = /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["e"].bind()(clusters, 1, function (e) {
|
|
return e.getPoints().length;
|
|
});
|
|
var points = [],
|
|
result = [];
|
|
if (topCluster.length === 1) {
|
|
points = topCluster[0].item.getPoints();
|
|
for (var i = 0; i < points.length; i++) {
|
|
result.push(points[i].point);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function skeletonize(x, y) {
|
|
_binaryImageWrapper.subImageAsCopy(_subImageWrapper, /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["f"].bind()(x, y));
|
|
_skeletonizer.skeletonize();
|
|
|
|
// Show skeleton if requested
|
|
if (true && _config.debug.showSkeleton) {
|
|
_skelImageWrapper.overlay(_canvasContainer.dom.binary, 360, /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["f"].bind()(x, y));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extracts and describes those patches which seem to contain a barcode pattern
|
|
* @param {Array} moments
|
|
* @param {Object} patchPos,
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
* @returns {Array} list of patches
|
|
*/
|
|
function describePatch(moments, patchPos, x, y) {
|
|
var k,
|
|
avg,
|
|
eligibleMoments = [],
|
|
matchingMoments,
|
|
patch,
|
|
patchesFound = [],
|
|
minComponentWeight = Math.ceil(_patchSize.x / 3);
|
|
|
|
if (moments.length >= 2) {
|
|
// only collect moments which's area covers at least minComponentWeight pixels.
|
|
for (k = 0; k < moments.length; k++) {
|
|
if (moments[k].m00 > minComponentWeight) {
|
|
eligibleMoments.push(moments[k]);
|
|
}
|
|
}
|
|
|
|
// if at least 2 moments are found which have at least minComponentWeights covered
|
|
if (eligibleMoments.length >= 2) {
|
|
matchingMoments = similarMoments(eligibleMoments);
|
|
avg = 0;
|
|
// determine the similarity of the moments
|
|
for (k = 0; k < matchingMoments.length; k++) {
|
|
avg += matchingMoments[k].rad;
|
|
}
|
|
|
|
// Only two of the moments are allowed not to fit into the equation
|
|
// add the patch to the set
|
|
if (matchingMoments.length > 1 && matchingMoments.length >= eligibleMoments.length / 4 * 3 && matchingMoments.length > moments.length / 4) {
|
|
avg /= matchingMoments.length;
|
|
patch = {
|
|
index: patchPos[1] * _numPatches.x + patchPos[0],
|
|
pos: {
|
|
x: x,
|
|
y: y
|
|
},
|
|
box: [vec2.clone([x, y]), vec2.clone([x + _subImageWrapper.size.x, y]), vec2.clone([x + _subImageWrapper.size.x, y + _subImageWrapper.size.y]), vec2.clone([x, y + _subImageWrapper.size.y])],
|
|
moments: matchingMoments,
|
|
rad: avg,
|
|
vec: vec2.clone([Math.cos(avg), Math.sin(avg)])
|
|
};
|
|
patchesFound.push(patch);
|
|
}
|
|
}
|
|
}
|
|
return patchesFound;
|
|
}
|
|
|
|
/**
|
|
* finds patches which are connected and share the same orientation
|
|
* @param {Object} patchesFound
|
|
*/
|
|
function rasterizeAngularSimilarity(patchesFound) {
|
|
var label = 0,
|
|
threshold = 0.95,
|
|
currIdx = 0,
|
|
j,
|
|
patch,
|
|
hsv = [0, 1, 1],
|
|
rgb = [0, 0, 0];
|
|
|
|
function notYetProcessed() {
|
|
var i;
|
|
for (i = 0; i < _patchLabelGrid.data.length; i++) {
|
|
if (_patchLabelGrid.data[i] === 0 && _patchGrid.data[i] === 1) {
|
|
return i;
|
|
}
|
|
}
|
|
return _patchLabelGrid.length;
|
|
}
|
|
|
|
function trace(currentIdx) {
|
|
var x,
|
|
y,
|
|
currentPatch,
|
|
idx,
|
|
dir,
|
|
current = {
|
|
x: currentIdx % _patchLabelGrid.size.x,
|
|
y: currentIdx / _patchLabelGrid.size.x | 0
|
|
},
|
|
similarity;
|
|
|
|
if (currentIdx < _patchLabelGrid.data.length) {
|
|
currentPatch = _imageToPatchGrid.data[currentIdx];
|
|
// assign label
|
|
_patchLabelGrid.data[currentIdx] = label;
|
|
for (dir = 0; dir < /* harmony import */__WEBPACK_IMPORTED_MODULE_5__tracer__["a"].searchDirections.length; dir++) {
|
|
y = current.y + /* harmony import */__WEBPACK_IMPORTED_MODULE_5__tracer__["a"].searchDirections[dir][0];
|
|
x = current.x + /* harmony import */__WEBPACK_IMPORTED_MODULE_5__tracer__["a"].searchDirections[dir][1];
|
|
idx = y * _patchLabelGrid.size.x + x;
|
|
|
|
// continue if patch empty
|
|
if (_patchGrid.data[idx] === 0) {
|
|
_patchLabelGrid.data[idx] = Number.MAX_VALUE;
|
|
continue;
|
|
}
|
|
|
|
if (_patchLabelGrid.data[idx] === 0) {
|
|
similarity = Math.abs(vec2.dot(_imageToPatchGrid.data[idx].vec, currentPatch.vec));
|
|
if (similarity > threshold) {
|
|
trace(idx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// prepare for finding the right patches
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_2__common_array_helper__["a"].init(_patchGrid.data, 0);
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_2__common_array_helper__["a"].init(_patchLabelGrid.data, 0);
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_2__common_array_helper__["a"].init(_imageToPatchGrid.data, null);
|
|
|
|
for (j = 0; j < patchesFound.length; j++) {
|
|
patch = patchesFound[j];
|
|
_imageToPatchGrid.data[patch.index] = patch;
|
|
_patchGrid.data[patch.index] = 1;
|
|
}
|
|
|
|
// rasterize the patches found to determine area
|
|
_patchGrid.zeroBorder();
|
|
|
|
while ((currIdx = notYetProcessed()) < _patchLabelGrid.data.length) {
|
|
label++;
|
|
trace(currIdx);
|
|
}
|
|
|
|
// draw patch-labels if requested
|
|
if (true && _config.debug.showPatchLabels) {
|
|
for (j = 0; j < _patchLabelGrid.data.length; j++) {
|
|
if (_patchLabelGrid.data[j] > 0 && _patchLabelGrid.data[j] <= label) {
|
|
patch = _imageToPatchGrid.data[j];
|
|
hsv[0] = _patchLabelGrid.data[j] / (label + 1) * 360;
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["a"].bind()(hsv, rgb);
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_3__common_image_debug__["a"].drawRect(patch.pos, _subImageWrapper.size, _canvasContainer.ctx.binary, { color: "rgb(" + rgb.join(",") + ")", lineWidth: 2 });
|
|
}
|
|
}
|
|
}
|
|
|
|
return label;
|
|
}
|
|
|
|
/* harmony default export */ exports["a"] = {
|
|
init: function init(inputImageWrapper, config) {
|
|
_config = config;
|
|
_inputImageWrapper = inputImageWrapper;
|
|
|
|
initBuffers();
|
|
initCanvas();
|
|
},
|
|
|
|
locate: function locate() {
|
|
var patchesFound, topLabels, boxes;
|
|
|
|
if (_config.halfSample) {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["g"].bind()(_inputImageWrapper, _currentImageWrapper);
|
|
}
|
|
|
|
binarizeImage();
|
|
patchesFound = findPatches();
|
|
// return unless 5% or more patches are found
|
|
if (patchesFound.length < _numPatches.x * _numPatches.y * 0.05) {
|
|
return null;
|
|
}
|
|
|
|
// rasterrize area by comparing angular similarity;
|
|
var maxLabel = rasterizeAngularSimilarity(patchesFound);
|
|
if (maxLabel < 1) {
|
|
return null;
|
|
}
|
|
|
|
// search for area with the most patches (biggest connected area)
|
|
topLabels = findBiggestConnectedAreas(maxLabel);
|
|
if (topLabels.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
boxes = findBoxes(topLabels, maxLabel);
|
|
return boxes;
|
|
},
|
|
|
|
checkImageConstraints: function checkImageConstraints(inputStream, config) {
|
|
var patchSize,
|
|
width = inputStream.getWidth(),
|
|
height = inputStream.getHeight(),
|
|
halfSample = config.halfSample ? 0.5 : 1,
|
|
size,
|
|
area;
|
|
|
|
// calculate width and height based on area
|
|
if (inputStream.getConfig().area) {
|
|
area = /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["h"].bind()(width, height, inputStream.getConfig().area);
|
|
inputStream.setTopRight({ x: area.sx, y: area.sy });
|
|
inputStream.setCanvasSize({ x: width, y: height });
|
|
width = area.sw;
|
|
height = area.sh;
|
|
}
|
|
|
|
size = {
|
|
x: Math.floor(width * halfSample),
|
|
y: Math.floor(height * halfSample)
|
|
};
|
|
|
|
patchSize = /* harmony import */__WEBPACK_IMPORTED_MODULE_1__common_cv_utils__["b"].bind()(config.patchSize, size);
|
|
if (true) {
|
|
console.log("Patch-Size: " + JSON.stringify(patchSize));
|
|
}
|
|
|
|
inputStream.setWidth(Math.floor(Math.floor(size.x / patchSize.x) * (1 / halfSample) * patchSize.x));
|
|
inputStream.setHeight(Math.floor(Math.floor(size.y / patchSize.y) * (1 / halfSample) * patchSize.y));
|
|
|
|
if (inputStream.getWidth() % patchSize.x === 0 && inputStream.getHeight() % patchSize.y === 0) {
|
|
return true;
|
|
}
|
|
|
|
throw new Error("Image dimensions do not comply with the current settings: Width (" + width + " )and height (" + height + ") must a multiple of " + patchSize.x);
|
|
}
|
|
};
|
|
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
|
|
|
|
/***/ },
|
|
/* 64 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__tracer__ = __webpack_require__(29);
|
|
|
|
|
|
/**
|
|
* http://www.codeproject.com/Tips/407172/Connected-Component-Labeling-and-Vectorization
|
|
*/
|
|
var Rasterizer = {
|
|
createContour2D: function createContour2D() {
|
|
return {
|
|
dir: null,
|
|
index: null,
|
|
firstVertex: null,
|
|
insideContours: null,
|
|
nextpeer: null,
|
|
prevpeer: null
|
|
};
|
|
},
|
|
CONTOUR_DIR: {
|
|
CW_DIR: 0,
|
|
CCW_DIR: 1,
|
|
UNKNOWN_DIR: 2
|
|
},
|
|
DIR: {
|
|
OUTSIDE_EDGE: -32767,
|
|
INSIDE_EDGE: -32766
|
|
},
|
|
create: function create(imageWrapper, labelWrapper) {
|
|
var imageData = imageWrapper.data,
|
|
labelData = labelWrapper.data,
|
|
width = imageWrapper.size.x,
|
|
height = imageWrapper.size.y,
|
|
tracer = /* harmony import */__WEBPACK_IMPORTED_MODULE_0__tracer__["a"].create(imageWrapper, labelWrapper);
|
|
|
|
return {
|
|
rasterize: function rasterize(depthlabel) {
|
|
var color,
|
|
bc,
|
|
lc,
|
|
labelindex,
|
|
cx,
|
|
cy,
|
|
colorMap = [],
|
|
vertex,
|
|
p,
|
|
cc,
|
|
sc,
|
|
pos,
|
|
connectedCount = 0,
|
|
i;
|
|
|
|
for (i = 0; i < 400; i++) {
|
|
colorMap[i] = 0;
|
|
}
|
|
|
|
colorMap[0] = imageData[0];
|
|
cc = null;
|
|
for (cy = 1; cy < height - 1; cy++) {
|
|
labelindex = 0;
|
|
bc = colorMap[0];
|
|
for (cx = 1; cx < width - 1; cx++) {
|
|
pos = cy * width + cx;
|
|
if (labelData[pos] === 0) {
|
|
color = imageData[pos];
|
|
if (color !== bc) {
|
|
if (labelindex === 0) {
|
|
lc = connectedCount + 1;
|
|
colorMap[lc] = color;
|
|
bc = color;
|
|
vertex = tracer.contourTracing(cy, cx, lc, color, Rasterizer.DIR.OUTSIDE_EDGE);
|
|
if (vertex !== null) {
|
|
connectedCount++;
|
|
labelindex = lc;
|
|
p = Rasterizer.createContour2D();
|
|
p.dir = Rasterizer.CONTOUR_DIR.CW_DIR;
|
|
p.index = labelindex;
|
|
p.firstVertex = vertex;
|
|
p.nextpeer = cc;
|
|
p.insideContours = null;
|
|
if (cc !== null) {
|
|
cc.prevpeer = p;
|
|
}
|
|
cc = p;
|
|
}
|
|
} else {
|
|
vertex = tracer.contourTracing(cy, cx, Rasterizer.DIR.INSIDE_EDGE, color, labelindex);
|
|
if (vertex !== null) {
|
|
p = Rasterizer.createContour2D();
|
|
p.firstVertex = vertex;
|
|
p.insideContours = null;
|
|
if (depthlabel === 0) {
|
|
p.dir = Rasterizer.CONTOUR_DIR.CCW_DIR;
|
|
} else {
|
|
p.dir = Rasterizer.CONTOUR_DIR.CW_DIR;
|
|
}
|
|
p.index = depthlabel;
|
|
sc = cc;
|
|
while (sc !== null && sc.index !== labelindex) {
|
|
sc = sc.nextpeer;
|
|
}
|
|
if (sc !== null) {
|
|
p.nextpeer = sc.insideContours;
|
|
if (sc.insideContours !== null) {
|
|
sc.insideContours.prevpeer = p;
|
|
}
|
|
sc.insideContours = p;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
labelData[pos] = labelindex;
|
|
}
|
|
} else if (labelData[pos] === Rasterizer.DIR.OUTSIDE_EDGE || labelData[pos] === Rasterizer.DIR.INSIDE_EDGE) {
|
|
labelindex = 0;
|
|
if (labelData[pos] === Rasterizer.DIR.INSIDE_EDGE) {
|
|
bc = imageData[pos];
|
|
} else {
|
|
bc = colorMap[0];
|
|
}
|
|
} else {
|
|
labelindex = labelData[pos];
|
|
bc = colorMap[labelindex];
|
|
}
|
|
}
|
|
}
|
|
sc = cc;
|
|
while (sc !== null) {
|
|
sc.index = depthlabel;
|
|
sc = sc.nextpeer;
|
|
}
|
|
return {
|
|
cc: cc,
|
|
count: connectedCount
|
|
};
|
|
},
|
|
debug: {
|
|
drawContour: function drawContour(canvas, firstContour) {
|
|
var ctx = canvas.getContext("2d"),
|
|
pq = firstContour,
|
|
iq,
|
|
q,
|
|
p;
|
|
|
|
ctx.strokeStyle = "red";
|
|
ctx.fillStyle = "red";
|
|
ctx.lineWidth = 1;
|
|
|
|
if (pq !== null) {
|
|
iq = pq.insideContours;
|
|
} else {
|
|
iq = null;
|
|
}
|
|
|
|
while (pq !== null) {
|
|
if (iq !== null) {
|
|
q = iq;
|
|
iq = iq.nextpeer;
|
|
} else {
|
|
q = pq;
|
|
pq = pq.nextpeer;
|
|
if (pq !== null) {
|
|
iq = pq.insideContours;
|
|
} else {
|
|
iq = null;
|
|
}
|
|
}
|
|
|
|
switch (q.dir) {
|
|
case Rasterizer.CONTOUR_DIR.CW_DIR:
|
|
ctx.strokeStyle = "red";
|
|
break;
|
|
case Rasterizer.CONTOUR_DIR.CCW_DIR:
|
|
ctx.strokeStyle = "blue";
|
|
break;
|
|
case Rasterizer.CONTOUR_DIR.UNKNOWN_DIR:
|
|
ctx.strokeStyle = "green";
|
|
break;
|
|
}
|
|
|
|
p = q.firstVertex;
|
|
ctx.beginPath();
|
|
ctx.moveTo(p.x, p.y);
|
|
do {
|
|
p = p.next;
|
|
ctx.lineTo(p.x, p.y);
|
|
} while (p !== q.firstVertex);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = Rasterizer;
|
|
|
|
/***/ },
|
|
/* 65 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* @preserve ASM BEGIN */
|
|
/* eslint-disable eqeqeq*/
|
|
function Skeletonizer(stdlib, foreign, buffer) {
|
|
"use asm";
|
|
|
|
var images = new stdlib.Uint8Array(buffer),
|
|
size = foreign.size | 0,
|
|
imul = stdlib.Math.imul;
|
|
|
|
function erode(inImagePtr, outImagePtr) {
|
|
inImagePtr = inImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var v = 0,
|
|
u = 0,
|
|
sum = 0,
|
|
yStart1 = 0,
|
|
yStart2 = 0,
|
|
xStart1 = 0,
|
|
xStart2 = 0,
|
|
offset = 0;
|
|
|
|
for (v = 1; (v | 0) < (size - 1 | 0); v = v + 1 | 0) {
|
|
offset = offset + size | 0;
|
|
for (u = 1; (u | 0) < (size - 1 | 0); u = u + 1 | 0) {
|
|
yStart1 = offset - size | 0;
|
|
yStart2 = offset + size | 0;
|
|
xStart1 = u - 1 | 0;
|
|
xStart2 = u + 1 | 0;
|
|
sum = (images[inImagePtr + yStart1 + xStart1 | 0] | 0) + (images[inImagePtr + yStart1 + xStart2 | 0] | 0) + (images[inImagePtr + offset + u | 0] | 0) + (images[inImagePtr + yStart2 + xStart1 | 0] | 0) + (images[inImagePtr + yStart2 + xStart2 | 0] | 0) | 0;
|
|
if ((sum | 0) == (5 | 0)) {
|
|
images[outImagePtr + offset + u | 0] = 1;
|
|
} else {
|
|
images[outImagePtr + offset + u | 0] = 0;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
function subtract(aImagePtr, bImagePtr, outImagePtr) {
|
|
aImagePtr = aImagePtr | 0;
|
|
bImagePtr = bImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
images[outImagePtr + length | 0] = (images[aImagePtr + length | 0] | 0) - (images[bImagePtr + length | 0] | 0) | 0;
|
|
}
|
|
}
|
|
|
|
function bitwiseOr(aImagePtr, bImagePtr, outImagePtr) {
|
|
aImagePtr = aImagePtr | 0;
|
|
bImagePtr = bImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
images[outImagePtr + length | 0] = images[aImagePtr + length | 0] | 0 | (images[bImagePtr + length | 0] | 0) | 0;
|
|
}
|
|
}
|
|
|
|
function countNonZero(imagePtr) {
|
|
imagePtr = imagePtr | 0;
|
|
|
|
var sum = 0,
|
|
length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
sum = (sum | 0) + (images[imagePtr + length | 0] | 0) | 0;
|
|
}
|
|
|
|
return sum | 0;
|
|
}
|
|
|
|
function init(imagePtr, value) {
|
|
imagePtr = imagePtr | 0;
|
|
value = value | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
images[imagePtr + length | 0] = value;
|
|
}
|
|
}
|
|
|
|
function dilate(inImagePtr, outImagePtr) {
|
|
inImagePtr = inImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var v = 0,
|
|
u = 0,
|
|
sum = 0,
|
|
yStart1 = 0,
|
|
yStart2 = 0,
|
|
xStart1 = 0,
|
|
xStart2 = 0,
|
|
offset = 0;
|
|
|
|
for (v = 1; (v | 0) < (size - 1 | 0); v = v + 1 | 0) {
|
|
offset = offset + size | 0;
|
|
for (u = 1; (u | 0) < (size - 1 | 0); u = u + 1 | 0) {
|
|
yStart1 = offset - size | 0;
|
|
yStart2 = offset + size | 0;
|
|
xStart1 = u - 1 | 0;
|
|
xStart2 = u + 1 | 0;
|
|
sum = (images[inImagePtr + yStart1 + xStart1 | 0] | 0) + (images[inImagePtr + yStart1 + xStart2 | 0] | 0) + (images[inImagePtr + offset + u | 0] | 0) + (images[inImagePtr + yStart2 + xStart1 | 0] | 0) + (images[inImagePtr + yStart2 + xStart2 | 0] | 0) | 0;
|
|
if ((sum | 0) > (0 | 0)) {
|
|
images[outImagePtr + offset + u | 0] = 1;
|
|
} else {
|
|
images[outImagePtr + offset + u | 0] = 0;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
function memcpy(srcImagePtr, dstImagePtr) {
|
|
srcImagePtr = srcImagePtr | 0;
|
|
dstImagePtr = dstImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = length - 1 | 0;
|
|
images[dstImagePtr + length | 0] = images[srcImagePtr + length | 0] | 0;
|
|
}
|
|
}
|
|
|
|
function zeroBorder(imagePtr) {
|
|
imagePtr = imagePtr | 0;
|
|
|
|
var x = 0,
|
|
y = 0;
|
|
|
|
for (x = 0; (x | 0) < (size - 1 | 0); x = x + 1 | 0) {
|
|
images[imagePtr + x | 0] = 0;
|
|
images[imagePtr + y | 0] = 0;
|
|
y = y + size - 1 | 0;
|
|
images[imagePtr + y | 0] = 0;
|
|
y = y + 1 | 0;
|
|
}
|
|
for (x = 0; (x | 0) < (size | 0); x = x + 1 | 0) {
|
|
images[imagePtr + y | 0] = 0;
|
|
y = y + 1 | 0;
|
|
}
|
|
}
|
|
|
|
function skeletonize() {
|
|
var subImagePtr = 0,
|
|
erodedImagePtr = 0,
|
|
tempImagePtr = 0,
|
|
skelImagePtr = 0,
|
|
sum = 0,
|
|
done = 0;
|
|
|
|
erodedImagePtr = imul(size, size) | 0;
|
|
tempImagePtr = erodedImagePtr + erodedImagePtr | 0;
|
|
skelImagePtr = tempImagePtr + erodedImagePtr | 0;
|
|
|
|
// init skel-image
|
|
init(skelImagePtr, 0);
|
|
zeroBorder(subImagePtr);
|
|
|
|
do {
|
|
erode(subImagePtr, erodedImagePtr);
|
|
dilate(erodedImagePtr, tempImagePtr);
|
|
subtract(subImagePtr, tempImagePtr, tempImagePtr);
|
|
bitwiseOr(skelImagePtr, tempImagePtr, skelImagePtr);
|
|
memcpy(erodedImagePtr, subImagePtr);
|
|
sum = countNonZero(subImagePtr) | 0;
|
|
done = (sum | 0) == 0 | 0;
|
|
} while (!done);
|
|
}
|
|
return {
|
|
skeletonize: skeletonize
|
|
};
|
|
}
|
|
/* @preserve ASM END */
|
|
/* harmony default export */ exports["a"] = Skeletonizer;
|
|
/* eslint-enable eqeqeq*/
|
|
|
|
/***/ },
|
|
/* 66 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__barcode_reader__ = __webpack_require__(5);
|
|
|
|
|
|
function CodabarReader() {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].call(this);
|
|
this._counters = [];
|
|
}
|
|
|
|
var properties = {
|
|
ALPHABETH_STRING: { value: "0123456789-$:/.+ABCD" },
|
|
ALPHABET: { value: [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 36, 58, 47, 46, 43, 65, 66, 67, 68] },
|
|
CHARACTER_ENCODINGS: { value: [0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, 0x00c, 0x018, 0x045, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E] },
|
|
START_END: { value: [0x01A, 0x029, 0x00B, 0x00E] },
|
|
MIN_ENCODED_CHARS: { value: 4 },
|
|
MAX_ACCEPTABLE: { value: 2.0 },
|
|
PADDING: { value: 1.5 },
|
|
FORMAT: { value: "codabar", writeable: false }
|
|
};
|
|
|
|
CodabarReader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].prototype, properties);
|
|
CodabarReader.prototype.constructor = CodabarReader;
|
|
|
|
CodabarReader.prototype._decode = function () {
|
|
var self = this,
|
|
result = [],
|
|
start,
|
|
decodedChar,
|
|
pattern,
|
|
nextStart,
|
|
end;
|
|
|
|
this._counters = self._fillCounters();
|
|
start = self._findStart();
|
|
if (!start) {
|
|
return null;
|
|
}
|
|
nextStart = start.startCounter;
|
|
|
|
do {
|
|
pattern = self._toPattern(nextStart);
|
|
if (pattern < 0) {
|
|
return null;
|
|
}
|
|
decodedChar = self._patternToChar(pattern);
|
|
if (decodedChar < 0) {
|
|
return null;
|
|
}
|
|
result.push(decodedChar);
|
|
nextStart += 8;
|
|
if (result.length > 1 && self._isStartEnd(pattern)) {
|
|
break;
|
|
}
|
|
} while (nextStart < self._counters.length);
|
|
|
|
// verify end
|
|
if (result.length - 2 < self.MIN_ENCODED_CHARS || !self._isStartEnd(pattern)) {
|
|
return null;
|
|
}
|
|
|
|
// verify end white space
|
|
if (!self._verifyWhitespace(start.startCounter, nextStart - 8)) {
|
|
return null;
|
|
}
|
|
|
|
if (!self._validateResult(result, start.startCounter)) {
|
|
return null;
|
|
}
|
|
|
|
nextStart = nextStart > self._counters.length ? self._counters.length : nextStart;
|
|
end = start.start + self._sumCounters(start.startCounter, nextStart - 8);
|
|
|
|
return {
|
|
code: result.join(""),
|
|
start: start.start,
|
|
end: end,
|
|
startInfo: start,
|
|
decodedCodes: result
|
|
};
|
|
};
|
|
|
|
CodabarReader.prototype._verifyWhitespace = function (startCounter, endCounter) {
|
|
if (startCounter - 1 <= 0 || this._counters[startCounter - 1] >= this._calculatePatternLength(startCounter) / 2.0) {
|
|
if (endCounter + 8 >= this._counters.length || this._counters[endCounter + 7] >= this._calculatePatternLength(endCounter) / 2.0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
CodabarReader.prototype._calculatePatternLength = function (offset) {
|
|
var i,
|
|
sum = 0;
|
|
|
|
for (i = offset; i < offset + 7; i++) {
|
|
sum += this._counters[i];
|
|
}
|
|
|
|
return sum;
|
|
};
|
|
|
|
CodabarReader.prototype._thresholdResultPattern = function (result, startCounter) {
|
|
var self = this,
|
|
categorization = {
|
|
space: {
|
|
narrow: { size: 0, counts: 0, min: 0, max: Number.MAX_VALUE },
|
|
wide: { size: 0, counts: 0, min: 0, max: Number.MAX_VALUE }
|
|
},
|
|
bar: {
|
|
narrow: { size: 0, counts: 0, min: 0, max: Number.MAX_VALUE },
|
|
wide: { size: 0, counts: 0, min: 0, max: Number.MAX_VALUE }
|
|
}
|
|
},
|
|
kind,
|
|
cat,
|
|
i,
|
|
j,
|
|
pos = startCounter,
|
|
pattern;
|
|
|
|
for (i = 0; i < result.length; i++) {
|
|
pattern = self._charToPattern(result[i]);
|
|
for (j = 6; j >= 0; j--) {
|
|
kind = (j & 1) === 2 ? categorization.bar : categorization.space;
|
|
cat = (pattern & 1) === 1 ? kind.wide : kind.narrow;
|
|
cat.size += self._counters[pos + j];
|
|
cat.counts++;
|
|
pattern >>= 1;
|
|
}
|
|
pos += 8;
|
|
}
|
|
|
|
["space", "bar"].forEach(function (key) {
|
|
var newkind = categorization[key];
|
|
newkind.wide.min = Math.floor((newkind.narrow.size / newkind.narrow.counts + newkind.wide.size / newkind.wide.counts) / 2);
|
|
newkind.narrow.max = Math.ceil(newkind.wide.min);
|
|
newkind.wide.max = Math.ceil((newkind.wide.size * self.MAX_ACCEPTABLE + self.PADDING) / newkind.wide.counts);
|
|
});
|
|
|
|
return categorization;
|
|
};
|
|
|
|
CodabarReader.prototype._charToPattern = function (char) {
|
|
var self = this,
|
|
charCode = char.charCodeAt(0),
|
|
i;
|
|
|
|
for (i = 0; i < self.ALPHABET.length; i++) {
|
|
if (self.ALPHABET[i] === charCode) {
|
|
return self.CHARACTER_ENCODINGS[i];
|
|
}
|
|
}
|
|
return 0x0;
|
|
};
|
|
|
|
CodabarReader.prototype._validateResult = function (result, startCounter) {
|
|
var self = this,
|
|
thresholds = self._thresholdResultPattern(result, startCounter),
|
|
i,
|
|
j,
|
|
kind,
|
|
cat,
|
|
size,
|
|
pos = startCounter,
|
|
pattern;
|
|
|
|
for (i = 0; i < result.length; i++) {
|
|
pattern = self._charToPattern(result[i]);
|
|
for (j = 6; j >= 0; j--) {
|
|
kind = (j & 1) === 0 ? thresholds.bar : thresholds.space;
|
|
cat = (pattern & 1) === 1 ? kind.wide : kind.narrow;
|
|
size = self._counters[pos + j];
|
|
if (size < cat.min || size > cat.max) {
|
|
return false;
|
|
}
|
|
pattern >>= 1;
|
|
}
|
|
pos += 8;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
CodabarReader.prototype._patternToChar = function (pattern) {
|
|
var i,
|
|
self = this;
|
|
|
|
for (i = 0; i < self.CHARACTER_ENCODINGS.length; i++) {
|
|
if (self.CHARACTER_ENCODINGS[i] === pattern) {
|
|
return String.fromCharCode(self.ALPHABET[i]);
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
CodabarReader.prototype._computeAlternatingThreshold = function (offset, end) {
|
|
var i,
|
|
min = Number.MAX_VALUE,
|
|
max = 0,
|
|
counter;
|
|
|
|
for (i = offset; i < end; i += 2) {
|
|
counter = this._counters[i];
|
|
if (counter > max) {
|
|
max = counter;
|
|
}
|
|
if (counter < min) {
|
|
min = counter;
|
|
}
|
|
}
|
|
|
|
return (min + max) / 2.0 | 0;
|
|
};
|
|
|
|
CodabarReader.prototype._toPattern = function (offset) {
|
|
var numCounters = 7,
|
|
end = offset + numCounters,
|
|
barThreshold,
|
|
spaceThreshold,
|
|
bitmask = 1 << numCounters - 1,
|
|
pattern = 0,
|
|
i,
|
|
threshold;
|
|
|
|
if (end > this._counters.length) {
|
|
return -1;
|
|
}
|
|
|
|
barThreshold = this._computeAlternatingThreshold(offset, end);
|
|
spaceThreshold = this._computeAlternatingThreshold(offset + 1, end);
|
|
|
|
for (i = 0; i < numCounters; i++) {
|
|
threshold = (i & 1) === 0 ? barThreshold : spaceThreshold;
|
|
if (this._counters[offset + i] > threshold) {
|
|
pattern |= bitmask;
|
|
}
|
|
bitmask >>= 1;
|
|
}
|
|
|
|
return pattern;
|
|
};
|
|
|
|
CodabarReader.prototype._isStartEnd = function (pattern) {
|
|
var i;
|
|
|
|
for (i = 0; i < this.START_END.length; i++) {
|
|
if (this.START_END[i] === pattern) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
CodabarReader.prototype._sumCounters = function (start, end) {
|
|
var i,
|
|
sum = 0;
|
|
|
|
for (i = start; i < end; i++) {
|
|
sum += this._counters[i];
|
|
}
|
|
return sum;
|
|
};
|
|
|
|
CodabarReader.prototype._findStart = function () {
|
|
var self = this,
|
|
i,
|
|
pattern,
|
|
start = self._nextUnset(self._row),
|
|
end;
|
|
|
|
for (i = 1; i < this._counters.length; i++) {
|
|
pattern = self._toPattern(i);
|
|
if (pattern !== -1 && self._isStartEnd(pattern)) {
|
|
// TODO: Look for whitespace ahead
|
|
start += self._sumCounters(0, i);
|
|
end = start + self._sumCounters(i, i + 8);
|
|
return {
|
|
start: start,
|
|
end: end,
|
|
startCounter: i,
|
|
endCounter: i + 8
|
|
};
|
|
}
|
|
}
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = CodabarReader;
|
|
|
|
/***/ },
|
|
/* 67 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__barcode_reader__ = __webpack_require__(5);
|
|
|
|
|
|
function Code128Reader() {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
CODE_SHIFT: { value: 98 },
|
|
CODE_C: { value: 99 },
|
|
CODE_B: { value: 100 },
|
|
CODE_A: { value: 101 },
|
|
START_CODE_A: { value: 103 },
|
|
START_CODE_B: { value: 104 },
|
|
START_CODE_C: { value: 105 },
|
|
STOP_CODE: { value: 106 },
|
|
MODULO: { value: 11 },
|
|
CODE_PATTERN: { value: [[2, 1, 2, 2, 2, 2], [2, 2, 2, 1, 2, 2], [2, 2, 2, 2, 2, 1], [1, 2, 1, 2, 2, 3], [1, 2, 1, 3, 2, 2], [1, 3, 1, 2, 2, 2], [1, 2, 2, 2, 1, 3], [1, 2, 2, 3, 1, 2], [1, 3, 2, 2, 1, 2], [2, 2, 1, 2, 1, 3], [2, 2, 1, 3, 1, 2], [2, 3, 1, 2, 1, 2], [1, 1, 2, 2, 3, 2], [1, 2, 2, 1, 3, 2], [1, 2, 2, 2, 3, 1], [1, 1, 3, 2, 2, 2], [1, 2, 3, 1, 2, 2], [1, 2, 3, 2, 2, 1], [2, 2, 3, 2, 1, 1], [2, 2, 1, 1, 3, 2], [2, 2, 1, 2, 3, 1], [2, 1, 3, 2, 1, 2], [2, 2, 3, 1, 1, 2], [3, 1, 2, 1, 3, 1], [3, 1, 1, 2, 2, 2], [3, 2, 1, 1, 2, 2], [3, 2, 1, 2, 2, 1], [3, 1, 2, 2, 1, 2], [3, 2, 2, 1, 1, 2], [3, 2, 2, 2, 1, 1], [2, 1, 2, 1, 2, 3], [2, 1, 2, 3, 2, 1], [2, 3, 2, 1, 2, 1], [1, 1, 1, 3, 2, 3], [1, 3, 1, 1, 2, 3], [1, 3, 1, 3, 2, 1], [1, 1, 2, 3, 1, 3], [1, 3, 2, 1, 1, 3], [1, 3, 2, 3, 1, 1], [2, 1, 1, 3, 1, 3], [2, 3, 1, 1, 1, 3], [2, 3, 1, 3, 1, 1], [1, 1, 2, 1, 3, 3], [1, 1, 2, 3, 3, 1], [1, 3, 2, 1, 3, 1], [1, 1, 3, 1, 2, 3], [1, 1, 3, 3, 2, 1], [1, 3, 3, 1, 2, 1], [3, 1, 3, 1, 2, 1], [2, 1, 1, 3, 3, 1], [2, 3, 1, 1, 3, 1], [2, 1, 3, 1, 1, 3], [2, 1, 3, 3, 1, 1], [2, 1, 3, 1, 3, 1], [3, 1, 1, 1, 2, 3], [3, 1, 1, 3, 2, 1], [3, 3, 1, 1, 2, 1], [3, 1, 2, 1, 1, 3], [3, 1, 2, 3, 1, 1], [3, 3, 2, 1, 1, 1], [3, 1, 4, 1, 1, 1], [2, 2, 1, 4, 1, 1], [4, 3, 1, 1, 1, 1], [1, 1, 1, 2, 2, 4], [1, 1, 1, 4, 2, 2], [1, 2, 1, 1, 2, 4], [1, 2, 1, 4, 2, 1], [1, 4, 1, 1, 2, 2], [1, 4, 1, 2, 2, 1], [1, 1, 2, 2, 1, 4], [1, 1, 2, 4, 1, 2], [1, 2, 2, 1, 1, 4], [1, 2, 2, 4, 1, 1], [1, 4, 2, 1, 1, 2], [1, 4, 2, 2, 1, 1], [2, 4, 1, 2, 1, 1], [2, 2, 1, 1, 1, 4], [4, 1, 3, 1, 1, 1], [2, 4, 1, 1, 1, 2], [1, 3, 4, 1, 1, 1], [1, 1, 1, 2, 4, 2], [1, 2, 1, 1, 4, 2], [1, 2, 1, 2, 4, 1], [1, 1, 4, 2, 1, 2], [1, 2, 4, 1, 1, 2], [1, 2, 4, 2, 1, 1], [4, 1, 1, 2, 1, 2], [4, 2, 1, 1, 1, 2], [4, 2, 1, 2, 1, 1], [2, 1, 2, 1, 4, 1], [2, 1, 4, 1, 2, 1], [4, 1, 2, 1, 2, 1], [1, 1, 1, 1, 4, 3], [1, 1, 1, 3, 4, 1], [1, 3, 1, 1, 4, 1], [1, 1, 4, 1, 1, 3], [1, 1, 4, 3, 1, 1], [4, 1, 1, 1, 1, 3], [4, 1, 1, 3, 1, 1], [1, 1, 3, 1, 4, 1], [1, 1, 4, 1, 3, 1], [3, 1, 1, 1, 4, 1], [4, 1, 1, 1, 3, 1], [2, 1, 1, 4, 1, 2], [2, 1, 1, 2, 1, 4], [2, 1, 1, 2, 3, 2], [2, 3, 3, 1, 1, 1, 2]] },
|
|
SINGLE_CODE_ERROR: { value: 0.64 },
|
|
AVG_CODE_ERROR: { value: 0.30 },
|
|
FORMAT: { value: "code_128", writeable: false },
|
|
MODULE_INDICES: { value: { bar: [0, 2, 4], space: [1, 3, 5] } }
|
|
};
|
|
|
|
Code128Reader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].prototype, properties);
|
|
Code128Reader.prototype.constructor = Code128Reader;
|
|
|
|
Code128Reader.prototype._decodeCode = function (start, correction) {
|
|
var counter = [0, 0, 0, 0, 0, 0],
|
|
i,
|
|
self = this,
|
|
offset = start,
|
|
isWhite = !self._row[offset],
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: start,
|
|
end: start,
|
|
correction: {
|
|
bar: 1,
|
|
space: 1
|
|
}
|
|
},
|
|
code,
|
|
error,
|
|
normalized;
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
normalized = self._normalize(counter, correction);
|
|
if (normalized) {
|
|
for (code = 0; code < self.CODE_PATTERN.length; code++) {
|
|
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
|
|
if (error < bestMatch.error) {
|
|
bestMatch.code = code;
|
|
bestMatch.error = error;
|
|
}
|
|
}
|
|
bestMatch.end = i;
|
|
if (bestMatch.code === -1) {
|
|
return null;
|
|
}
|
|
if (self.CODE_PATTERN[bestMatch.code]) {
|
|
bestMatch.correction.bar = calculateCorrection(self.CODE_PATTERN[bestMatch.code], normalized, this.MODULE_INDICES.bar);
|
|
bestMatch.correction.space = calculateCorrection(self.CODE_PATTERN[bestMatch.code], normalized, this.MODULE_INDICES.space);
|
|
}
|
|
return bestMatch;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
Code128Reader.prototype._correct = function (counter, correction) {
|
|
this._correctBars(counter, correction.bar, this.MODULE_INDICES.bar);
|
|
this._correctBars(counter, correction.space, this.MODULE_INDICES.space);
|
|
};
|
|
|
|
Code128Reader.prototype._findStart = function () {
|
|
var counter = [0, 0, 0, 0, 0, 0],
|
|
i,
|
|
self = this,
|
|
offset = self._nextSet(self._row),
|
|
isWhite = false,
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0,
|
|
end: 0,
|
|
correction: {
|
|
bar: 1,
|
|
space: 1
|
|
}
|
|
},
|
|
code,
|
|
error,
|
|
j,
|
|
sum,
|
|
normalized;
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
sum = 0;
|
|
for (j = 0; j < counter.length; j++) {
|
|
sum += counter[j];
|
|
}
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
for (code = self.START_CODE_A; code <= self.START_CODE_C; code++) {
|
|
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
|
|
if (error < bestMatch.error) {
|
|
bestMatch.code = code;
|
|
bestMatch.error = error;
|
|
}
|
|
}
|
|
if (bestMatch.error < self.AVG_CODE_ERROR) {
|
|
bestMatch.start = i - sum;
|
|
bestMatch.end = i;
|
|
bestMatch.correction.bar = calculateCorrection(self.CODE_PATTERN[code], normalized, [0, 2, 4]);
|
|
bestMatch.correction.space = calculateCorrection(self.CODE_PATTERN[code], normalized, [1, 3, 5]);
|
|
return bestMatch;
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
counter[j] = counter[j + 2];
|
|
}
|
|
counter[4] = 0;
|
|
counter[5] = 0;
|
|
counterPos--;
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
Code128Reader.prototype._decode = function () {
|
|
var self = this,
|
|
startInfo = self._findStart(),
|
|
code = null,
|
|
done = false,
|
|
result = [],
|
|
multiplier = 0,
|
|
checksum = 0,
|
|
codeset,
|
|
rawResult = [],
|
|
decodedCodes = [],
|
|
shiftNext = false,
|
|
unshift,
|
|
removeLastCharacter = true;
|
|
|
|
if (startInfo === null) {
|
|
return null;
|
|
}
|
|
code = {
|
|
code: startInfo.code,
|
|
start: startInfo.start,
|
|
end: startInfo.end,
|
|
correction: {
|
|
bar: startInfo.correction.bar,
|
|
space: startInfo.correction.space
|
|
}
|
|
};
|
|
decodedCodes.push(code);
|
|
checksum = code.code;
|
|
switch (code.code) {
|
|
case self.START_CODE_A:
|
|
codeset = self.CODE_A;
|
|
break;
|
|
case self.START_CODE_B:
|
|
codeset = self.CODE_B;
|
|
break;
|
|
case self.START_CODE_C:
|
|
codeset = self.CODE_C;
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
|
|
while (!done) {
|
|
unshift = shiftNext;
|
|
shiftNext = false;
|
|
code = self._decodeCode(code.end, code.correction);
|
|
if (code !== null) {
|
|
if (code.code !== self.STOP_CODE) {
|
|
removeLastCharacter = true;
|
|
}
|
|
|
|
if (code.code !== self.STOP_CODE) {
|
|
rawResult.push(code.code);
|
|
multiplier++;
|
|
checksum += multiplier * code.code;
|
|
}
|
|
decodedCodes.push(code);
|
|
|
|
switch (codeset) {
|
|
case self.CODE_A:
|
|
if (code.code < 64) {
|
|
result.push(String.fromCharCode(32 + code.code));
|
|
} else if (code.code < 96) {
|
|
result.push(String.fromCharCode(code.code - 64));
|
|
} else {
|
|
if (code.code !== self.STOP_CODE) {
|
|
removeLastCharacter = false;
|
|
}
|
|
switch (code.code) {
|
|
case self.CODE_SHIFT:
|
|
shiftNext = true;
|
|
codeset = self.CODE_B;
|
|
break;
|
|
case self.CODE_B:
|
|
codeset = self.CODE_B;
|
|
break;
|
|
case self.CODE_C:
|
|
codeset = self.CODE_C;
|
|
break;
|
|
case self.STOP_CODE:
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case self.CODE_B:
|
|
if (code.code < 96) {
|
|
result.push(String.fromCharCode(32 + code.code));
|
|
} else {
|
|
if (code.code !== self.STOP_CODE) {
|
|
removeLastCharacter = false;
|
|
}
|
|
switch (code.code) {
|
|
case self.CODE_SHIFT:
|
|
shiftNext = true;
|
|
codeset = self.CODE_A;
|
|
break;
|
|
case self.CODE_A:
|
|
codeset = self.CODE_A;
|
|
break;
|
|
case self.CODE_C:
|
|
codeset = self.CODE_C;
|
|
break;
|
|
case self.STOP_CODE:
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case self.CODE_C:
|
|
if (code.code < 100) {
|
|
result.push(code.code < 10 ? "0" + code.code : code.code);
|
|
} else {
|
|
if (code.code !== self.STOP_CODE) {
|
|
removeLastCharacter = false;
|
|
}
|
|
switch (code.code) {
|
|
case self.CODE_A:
|
|
codeset = self.CODE_A;
|
|
break;
|
|
case self.CODE_B:
|
|
codeset = self.CODE_B;
|
|
break;
|
|
case self.STOP_CODE:
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
done = true;
|
|
}
|
|
if (unshift) {
|
|
codeset = codeset === self.CODE_A ? self.CODE_B : self.CODE_A;
|
|
}
|
|
}
|
|
|
|
if (code === null) {
|
|
return null;
|
|
}
|
|
|
|
code.end = self._nextUnset(self._row, code.end);
|
|
if (!self._verifyTrailingWhitespace(code)) {
|
|
return null;
|
|
}
|
|
|
|
checksum -= multiplier * rawResult[rawResult.length - 1];
|
|
if (checksum % 103 !== rawResult[rawResult.length - 1]) {
|
|
return null;
|
|
}
|
|
|
|
if (!result.length) {
|
|
return null;
|
|
}
|
|
|
|
// remove last code from result (checksum)
|
|
if (removeLastCharacter) {
|
|
result.splice(result.length - 1, 1);
|
|
}
|
|
|
|
return {
|
|
code: result.join(""),
|
|
start: startInfo.start,
|
|
end: code.end,
|
|
codeset: codeset,
|
|
startInfo: startInfo,
|
|
decodedCodes: decodedCodes,
|
|
endInfo: code
|
|
};
|
|
};
|
|
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__barcode_reader__["a"].prototype._verifyTrailingWhitespace = function (endInfo) {
|
|
var self = this,
|
|
trailingWhitespaceEnd;
|
|
|
|
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start) / 2;
|
|
if (trailingWhitespaceEnd < self._row.length) {
|
|
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
|
|
return endInfo;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
function calculateCorrection(expected, normalized, indices) {
|
|
var length = indices.length,
|
|
sumNormalized = 0,
|
|
sumExpected = 0;
|
|
|
|
while (length--) {
|
|
sumExpected += expected[indices[length]];
|
|
sumNormalized += normalized[indices[length]];
|
|
}
|
|
return sumExpected / sumNormalized;
|
|
}
|
|
|
|
/* harmony default export */ exports["a"] = Code128Reader;
|
|
|
|
/***/ },
|
|
/* 68 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__code_39_reader__ = __webpack_require__(30);
|
|
|
|
|
|
function Code39VINReader() {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__code_39_reader__["a"].call(this);
|
|
}
|
|
|
|
var patterns = {
|
|
IOQ: /[IOQ]/g,
|
|
AZ09: /[A-Z0-9]{17}/
|
|
};
|
|
|
|
Code39VINReader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__code_39_reader__["a"].prototype);
|
|
Code39VINReader.prototype.constructor = Code39VINReader;
|
|
|
|
// Cribbed from:
|
|
// https://github.com/zxing/zxing/blob/master/core/src/main/java/com/google/zxing/client/result/VINResultParser.java
|
|
Code39VINReader.prototype._decode = function () {
|
|
var result = /* harmony import */__WEBPACK_IMPORTED_MODULE_0__code_39_reader__["a"].prototype._decode.apply(this);
|
|
if (!result) {
|
|
return null;
|
|
}
|
|
|
|
var code = result.code;
|
|
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
|
|
code = code.replace(patterns.IOQ, '');
|
|
|
|
if (!code.match(patterns.AZ09)) {
|
|
if (true) {
|
|
console.log('Failed AZ09 pattern code:', code);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
if (!this._checkChecksum(code)) {
|
|
return null;
|
|
}
|
|
|
|
result.code = code;
|
|
return result;
|
|
};
|
|
|
|
Code39VINReader.prototype._checkChecksum = function (code) {
|
|
// TODO
|
|
return !!code;
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = Code39VINReader;
|
|
|
|
/***/ },
|
|
/* 69 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ean_reader__ = __webpack_require__(10);
|
|
|
|
|
|
function EAN8Reader() {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
FORMAT: { value: "ean_8", writeable: false }
|
|
};
|
|
|
|
EAN8Reader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].prototype, properties);
|
|
EAN8Reader.prototype.constructor = EAN8Reader;
|
|
|
|
EAN8Reader.prototype._decodePayload = function (code, result, decodedCodes) {
|
|
var i,
|
|
self = this;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
code = self._decodeCode(code.end, self.CODE_G_START);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
result.push(code.code);
|
|
decodedCodes.push(code);
|
|
}
|
|
|
|
code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false);
|
|
if (code === null) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(code);
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
code = self._decodeCode(code.end, self.CODE_G_START);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(code);
|
|
result.push(code.code);
|
|
}
|
|
|
|
return code;
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = EAN8Reader;
|
|
|
|
/***/ },
|
|
/* 70 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_lodash_merge__ = __webpack_require__(28);
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_lodash_merge___default = __WEBPACK_IMPORTED_MODULE_0_lodash_merge__ && __WEBPACK_IMPORTED_MODULE_0_lodash_merge__.__esModule ? function() { return __WEBPACK_IMPORTED_MODULE_0_lodash_merge__['default'] } : function() { return __WEBPACK_IMPORTED_MODULE_0_lodash_merge__; }
|
|
/* harmony import */ Object.defineProperty(__WEBPACK_IMPORTED_MODULE_0_lodash_merge___default, 'a', { get: __WEBPACK_IMPORTED_MODULE_0_lodash_merge___default });
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__barcode_reader__ = __webpack_require__(5);
|
|
|
|
|
|
|
|
|
|
function I2of5Reader(opts) {
|
|
opts = /* harmony import */__WEBPACK_IMPORTED_MODULE_0_lodash_merge___default.a.bind()(getDefaulConfig(), opts);
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_1__barcode_reader__["a"].call(this, opts);
|
|
this.barSpaceRatio = [1, 1];
|
|
if (opts.normalizeBarSpaceWidth) {
|
|
this.SINGLE_CODE_ERROR = 0.38;
|
|
this.AVG_CODE_ERROR = 0.09;
|
|
}
|
|
}
|
|
|
|
function getDefaulConfig() {
|
|
var config = {};
|
|
|
|
Object.keys(I2of5Reader.CONFIG_KEYS).forEach(function (key) {
|
|
config[key] = I2of5Reader.CONFIG_KEYS[key].default;
|
|
});
|
|
return config;
|
|
}
|
|
|
|
var N = 1,
|
|
W = 3,
|
|
properties = {
|
|
MODULO: { value: 10 },
|
|
START_PATTERN: { value: [N * 2.5, N * 2.5, N * 2.5, N * 2.5] },
|
|
STOP_PATTERN: { value: [N * 2, N * 2, W * 2] },
|
|
CODE_PATTERN: { value: [[N, N, W, W, N], [W, N, N, N, W], [N, W, N, N, W], [W, W, N, N, N], [N, N, W, N, W], [W, N, W, N, N], [N, W, W, N, N], [N, N, N, W, W], [W, N, N, W, N], [N, W, N, W, N]] },
|
|
SINGLE_CODE_ERROR: { value: 0.78, writable: true },
|
|
AVG_CODE_ERROR: { value: 0.38, writable: true },
|
|
MAX_CORRECTION_FACTOR: { value: 5 },
|
|
FORMAT: { value: "i2of5" }
|
|
};
|
|
|
|
I2of5Reader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_1__barcode_reader__["a"].prototype, properties);
|
|
I2of5Reader.prototype.constructor = I2of5Reader;
|
|
|
|
I2of5Reader.prototype._matchPattern = function (counter, code) {
|
|
if (this.config.normalizeBarSpaceWidth) {
|
|
var i,
|
|
counterSum = [0, 0],
|
|
codeSum = [0, 0],
|
|
correction = [0, 0],
|
|
correctionRatio = this.MAX_CORRECTION_FACTOR,
|
|
correctionRatioInverse = 1 / correctionRatio;
|
|
|
|
for (i = 0; i < counter.length; i++) {
|
|
counterSum[i % 2] += counter[i];
|
|
codeSum[i % 2] += code[i];
|
|
}
|
|
correction[0] = codeSum[0] / counterSum[0];
|
|
correction[1] = codeSum[1] / counterSum[1];
|
|
|
|
correction[0] = Math.max(Math.min(correction[0], correctionRatio), correctionRatioInverse);
|
|
correction[1] = Math.max(Math.min(correction[1], correctionRatio), correctionRatioInverse);
|
|
this.barSpaceRatio = correction;
|
|
for (i = 0; i < counter.length; i++) {
|
|
counter[i] *= this.barSpaceRatio[i % 2];
|
|
}
|
|
}
|
|
return /* harmony import */__WEBPACK_IMPORTED_MODULE_1__barcode_reader__["a"].prototype._matchPattern.call(this, counter, code);
|
|
};
|
|
|
|
I2of5Reader.prototype._findPattern = function (pattern, offset, isWhite, tryHarder) {
|
|
var counter = [],
|
|
self = this,
|
|
i,
|
|
counterPos = 0,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0,
|
|
end: 0
|
|
},
|
|
error,
|
|
j,
|
|
sum,
|
|
normalized,
|
|
epsilon = self.AVG_CODE_ERROR;
|
|
|
|
isWhite = isWhite || false;
|
|
tryHarder = tryHarder || false;
|
|
|
|
if (!offset) {
|
|
offset = self._nextSet(self._row);
|
|
}
|
|
|
|
for (i = 0; i < pattern.length; i++) {
|
|
counter[i] = 0;
|
|
}
|
|
|
|
for (i = offset; i < self._row.length; i++) {
|
|
if (self._row[i] ^ isWhite) {
|
|
counter[counterPos]++;
|
|
} else {
|
|
if (counterPos === counter.length - 1) {
|
|
sum = 0;
|
|
for (j = 0; j < counter.length; j++) {
|
|
sum += counter[j];
|
|
}
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
error = self._matchPattern(normalized, pattern);
|
|
|
|
if (error < epsilon) {
|
|
bestMatch.error = error;
|
|
bestMatch.start = i - sum;
|
|
bestMatch.end = i;
|
|
return bestMatch;
|
|
}
|
|
}
|
|
if (tryHarder) {
|
|
for (j = 0; j < counter.length - 2; j++) {
|
|
counter[j] = counter[j + 2];
|
|
}
|
|
counter[counter.length - 2] = 0;
|
|
counter[counter.length - 1] = 0;
|
|
counterPos--;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
counterPos++;
|
|
}
|
|
counter[counterPos] = 1;
|
|
isWhite = !isWhite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
I2of5Reader.prototype._findStart = function () {
|
|
var self = this,
|
|
leadingWhitespaceStart,
|
|
offset = self._nextSet(self._row),
|
|
startInfo,
|
|
narrowBarWidth = 1;
|
|
|
|
while (!startInfo) {
|
|
startInfo = self._findPattern(self.START_PATTERN, offset, false, true);
|
|
if (!startInfo) {
|
|
return null;
|
|
}
|
|
narrowBarWidth = Math.floor((startInfo.end - startInfo.start) / 4);
|
|
leadingWhitespaceStart = startInfo.start - narrowBarWidth * 10;
|
|
if (leadingWhitespaceStart >= 0) {
|
|
if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) {
|
|
return startInfo;
|
|
}
|
|
}
|
|
offset = startInfo.end;
|
|
startInfo = null;
|
|
}
|
|
};
|
|
|
|
I2of5Reader.prototype._verifyTrailingWhitespace = function (endInfo) {
|
|
var self = this,
|
|
trailingWhitespaceEnd;
|
|
|
|
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start) / 2;
|
|
if (trailingWhitespaceEnd < self._row.length) {
|
|
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
|
|
return endInfo;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
I2of5Reader.prototype._findEnd = function () {
|
|
var self = this,
|
|
endInfo,
|
|
tmp;
|
|
|
|
self._row.reverse();
|
|
endInfo = self._findPattern(self.STOP_PATTERN);
|
|
self._row.reverse();
|
|
|
|
if (endInfo === null) {
|
|
return null;
|
|
}
|
|
|
|
// reverse numbers
|
|
tmp = endInfo.start;
|
|
endInfo.start = self._row.length - endInfo.end;
|
|
endInfo.end = self._row.length - tmp;
|
|
|
|
return endInfo !== null ? self._verifyTrailingWhitespace(endInfo) : null;
|
|
};
|
|
|
|
I2of5Reader.prototype._decodePair = function (counterPair) {
|
|
var i,
|
|
code,
|
|
codes = [],
|
|
self = this;
|
|
|
|
for (i = 0; i < counterPair.length; i++) {
|
|
code = self._decodeCode(counterPair[i]);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
codes.push(code);
|
|
}
|
|
return codes;
|
|
};
|
|
|
|
I2of5Reader.prototype._decodeCode = function (counter) {
|
|
var j,
|
|
self = this,
|
|
sum = 0,
|
|
normalized,
|
|
error,
|
|
epsilon = self.AVG_CODE_ERROR,
|
|
code,
|
|
bestMatch = {
|
|
error: Number.MAX_VALUE,
|
|
code: -1,
|
|
start: 0,
|
|
end: 0
|
|
};
|
|
|
|
for (j = 0; j < counter.length; j++) {
|
|
sum += counter[j];
|
|
}
|
|
normalized = self._normalize(counter);
|
|
if (normalized) {
|
|
for (code = 0; code < self.CODE_PATTERN.length; code++) {
|
|
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
|
|
if (error < bestMatch.error) {
|
|
bestMatch.code = code;
|
|
bestMatch.error = error;
|
|
}
|
|
}
|
|
if (bestMatch.error < epsilon) {
|
|
return bestMatch;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
I2of5Reader.prototype._decodePayload = function (counters, result, decodedCodes) {
|
|
var i,
|
|
self = this,
|
|
pos = 0,
|
|
counterLength = counters.length,
|
|
counterPair = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]],
|
|
codes;
|
|
|
|
while (pos < counterLength) {
|
|
for (i = 0; i < 5; i++) {
|
|
counterPair[0][i] = counters[pos] * this.barSpaceRatio[0];
|
|
counterPair[1][i] = counters[pos + 1] * this.barSpaceRatio[1];
|
|
pos += 2;
|
|
}
|
|
codes = self._decodePair(counterPair);
|
|
if (!codes) {
|
|
return null;
|
|
}
|
|
for (i = 0; i < codes.length; i++) {
|
|
result.push(codes[i].code + "");
|
|
decodedCodes.push(codes[i]);
|
|
}
|
|
}
|
|
return codes;
|
|
};
|
|
|
|
I2of5Reader.prototype._verifyCounterLength = function (counters) {
|
|
return counters.length % 10 === 0;
|
|
};
|
|
|
|
I2of5Reader.prototype._decode = function () {
|
|
var startInfo,
|
|
endInfo,
|
|
self = this,
|
|
code,
|
|
result = [],
|
|
decodedCodes = [],
|
|
counters;
|
|
|
|
startInfo = self._findStart();
|
|
if (!startInfo) {
|
|
return null;
|
|
}
|
|
decodedCodes.push(startInfo);
|
|
|
|
endInfo = self._findEnd();
|
|
if (!endInfo) {
|
|
return null;
|
|
}
|
|
|
|
counters = self._fillCounters(startInfo.end, endInfo.start, false);
|
|
if (!self._verifyCounterLength(counters)) {
|
|
return null;
|
|
}
|
|
code = self._decodePayload(counters, result, decodedCodes);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
if (result.length % 2 !== 0 || result.length < 6) {
|
|
return null;
|
|
}
|
|
|
|
decodedCodes.push(endInfo);
|
|
return {
|
|
code: result.join(""),
|
|
start: startInfo.start,
|
|
end: endInfo.end,
|
|
startInfo: startInfo,
|
|
decodedCodes: decodedCodes
|
|
};
|
|
};
|
|
|
|
I2of5Reader.CONFIG_KEYS = {
|
|
normalizeBarSpaceWidth: {
|
|
'type': 'boolean',
|
|
'default': false,
|
|
'description': 'If true, the reader tries to normalize the' + 'width-difference between bars and spaces'
|
|
}
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = I2of5Reader;
|
|
|
|
/***/ },
|
|
/* 71 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ean_reader__ = __webpack_require__(10);
|
|
|
|
|
|
function UPCEReader() {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
CODE_FREQUENCY: { value: [[56, 52, 50, 49, 44, 38, 35, 42, 41, 37], [7, 11, 13, 14, 19, 25, 28, 21, 22, 26]] },
|
|
STOP_PATTERN: { value: [1 / 6 * 7, 1 / 6 * 7, 1 / 6 * 7, 1 / 6 * 7, 1 / 6 * 7, 1 / 6 * 7] },
|
|
FORMAT: { value: "upc_e", writeable: false }
|
|
};
|
|
|
|
UPCEReader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].prototype, properties);
|
|
UPCEReader.prototype.constructor = UPCEReader;
|
|
|
|
UPCEReader.prototype._decodePayload = function (code, result, decodedCodes) {
|
|
var i,
|
|
self = this,
|
|
codeFrequency = 0x0;
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
code = self._decodeCode(code.end);
|
|
if (!code) {
|
|
return null;
|
|
}
|
|
if (code.code >= self.CODE_G_START) {
|
|
code.code = code.code - self.CODE_G_START;
|
|
codeFrequency |= 1 << 5 - i;
|
|
}
|
|
result.push(code.code);
|
|
decodedCodes.push(code);
|
|
}
|
|
if (!self._determineParity(codeFrequency, result)) {
|
|
return null;
|
|
}
|
|
|
|
return code;
|
|
};
|
|
|
|
UPCEReader.prototype._determineParity = function (codeFrequency, result) {
|
|
var i, nrSystem;
|
|
|
|
for (nrSystem = 0; nrSystem < this.CODE_FREQUENCY.length; nrSystem++) {
|
|
for (i = 0; i < this.CODE_FREQUENCY[nrSystem].length; i++) {
|
|
if (codeFrequency === this.CODE_FREQUENCY[nrSystem][i]) {
|
|
result.unshift(nrSystem);
|
|
result.push(i);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
UPCEReader.prototype._convertToUPCA = function (result) {
|
|
var upca = [result[0]],
|
|
lastDigit = result[result.length - 2];
|
|
|
|
if (lastDigit <= 2) {
|
|
upca = upca.concat(result.slice(1, 3)).concat([lastDigit, 0, 0, 0, 0]).concat(result.slice(3, 6));
|
|
} else if (lastDigit === 3) {
|
|
upca = upca.concat(result.slice(1, 4)).concat([0, 0, 0, 0, 0]).concat(result.slice(4, 6));
|
|
} else if (lastDigit === 4) {
|
|
upca = upca.concat(result.slice(1, 5)).concat([0, 0, 0, 0, 0, result[5]]);
|
|
} else {
|
|
upca = upca.concat(result.slice(1, 6)).concat([0, 0, 0, 0, lastDigit]);
|
|
}
|
|
|
|
upca.push(result[result.length - 1]);
|
|
return upca;
|
|
};
|
|
|
|
UPCEReader.prototype._checksum = function (result) {
|
|
return /* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].prototype._checksum.call(this, this._convertToUPCA(result));
|
|
};
|
|
|
|
UPCEReader.prototype._findEnd = function (offset, isWhite) {
|
|
isWhite = true;
|
|
return /* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].prototype._findEnd.call(this, offset, isWhite);
|
|
};
|
|
|
|
UPCEReader.prototype._verifyTrailingWhitespace = function (endInfo) {
|
|
var self = this,
|
|
trailingWhitespaceEnd;
|
|
|
|
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start) / 2;
|
|
if (trailingWhitespaceEnd < self._row.length) {
|
|
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
|
|
return endInfo;
|
|
}
|
|
}
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = UPCEReader;
|
|
|
|
/***/ },
|
|
/* 72 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ean_reader__ = __webpack_require__(10);
|
|
|
|
|
|
function UPCReader() {
|
|
/* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].call(this);
|
|
}
|
|
|
|
var properties = {
|
|
FORMAT: { value: "upc_a", writeable: false }
|
|
};
|
|
|
|
UPCReader.prototype = Object.create(/* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].prototype, properties);
|
|
UPCReader.prototype.constructor = UPCReader;
|
|
|
|
UPCReader.prototype._decode = function () {
|
|
var result = /* harmony import */__WEBPACK_IMPORTED_MODULE_0__ean_reader__["a"].prototype._decode.call(this);
|
|
|
|
if (result && result.code && result.code.length === 13 && result.code.charAt(0) === "0") {
|
|
result.code = result.code.substring(1);
|
|
return result;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
/* harmony default export */ exports["a"] = UPCReader;
|
|
|
|
/***/ },
|
|
/* 73 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = copy
|
|
|
|
/**
|
|
* Copy the values from one mat2 to another
|
|
*
|
|
* @alias mat2.copy
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the source matrix
|
|
* @returns {mat2} out
|
|
*/
|
|
function copy(out, a) {
|
|
out[0] = a[0]
|
|
out[1] = a[1]
|
|
out[2] = a[2]
|
|
out[3] = a[3]
|
|
return out
|
|
}
|
|
|
|
|
|
/***/ },
|
|
/* 74 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = create
|
|
|
|
/**
|
|
* Creates a new identity mat2
|
|
*
|
|
* @alias mat2.create
|
|
* @returns {mat2} a new 2x2 matrix
|
|
*/
|
|
function create() {
|
|
var out = new Float32Array(4)
|
|
out[0] = 1
|
|
out[1] = 0
|
|
out[2] = 0
|
|
out[3] = 1
|
|
return out
|
|
}
|
|
|
|
|
|
/***/ },
|
|
/* 75 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = invert
|
|
|
|
/**
|
|
* Inverts a mat2
|
|
*
|
|
* @alias mat2.invert
|
|
* @param {mat2} out the receiving matrix
|
|
* @param {mat2} a the source matrix
|
|
* @returns {mat2} out
|
|
*/
|
|
function invert(out, a) {
|
|
var a0 = a[0]
|
|
var a1 = a[1]
|
|
var a2 = a[2]
|
|
var a3 = a[3]
|
|
var det = a0 * a3 - a2 * a1
|
|
|
|
if (!det) return null
|
|
det = 1.0 / det
|
|
|
|
out[0] = a3 * det
|
|
out[1] = -a1 * det
|
|
out[2] = -a2 * det
|
|
out[3] = a0 * det
|
|
|
|
return out
|
|
}
|
|
|
|
|
|
/***/ },
|
|
/* 76 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = scale
|
|
|
|
/**
|
|
* Scales a vec2 by a scalar number
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the vector to scale
|
|
* @param {Number} b amount to scale the vector by
|
|
* @returns {vec2} out
|
|
*/
|
|
function scale(out, a, b) {
|
|
out[0] = a[0] * b
|
|
out[1] = a[1] * b
|
|
return out
|
|
}
|
|
|
|
/***/ },
|
|
/* 77 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = transformMat2
|
|
|
|
/**
|
|
* Transforms the vec2 with a mat2
|
|
*
|
|
* @param {vec2} out the receiving vector
|
|
* @param {vec2} a the vector to transform
|
|
* @param {mat2} m matrix to transform with
|
|
* @returns {vec2} out
|
|
*/
|
|
function transformMat2(out, a, m) {
|
|
var x = a[0],
|
|
y = a[1]
|
|
out[0] = m[0] * x + m[2] * y
|
|
out[1] = m[1] * x + m[3] * y
|
|
return out
|
|
}
|
|
|
|
/***/ },
|
|
/* 78 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = clone;
|
|
|
|
/**
|
|
* Creates a new vec3 initialized with values from an existing vector
|
|
*
|
|
* @param {vec3} a vector to clone
|
|
* @returns {vec3} a new 3D vector
|
|
*/
|
|
function clone(a) {
|
|
var out = new Float32Array(3)
|
|
out[0] = a[0]
|
|
out[1] = a[1]
|
|
out[2] = a[2]
|
|
return out
|
|
}
|
|
|
|
/***/ },
|
|
/* 79 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var nativeCreate = __webpack_require__(14);
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Creates an hash object.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @returns {Object} Returns the new hash object.
|
|
*/
|
|
function Hash() {}
|
|
|
|
// Avoid inheriting from `Object.prototype` when possible.
|
|
Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
|
|
|
|
module.e = Hash;
|
|
|
|
|
|
/***/ },
|
|
/* 80 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var mapClear = __webpack_require__(126),
|
|
mapDelete = __webpack_require__(127),
|
|
mapGet = __webpack_require__(128),
|
|
mapHas = __webpack_require__(129),
|
|
mapSet = __webpack_require__(130);
|
|
|
|
/**
|
|
* Creates a map cache object to store key-value pairs.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [values] The values to cache.
|
|
*/
|
|
function MapCache(values) {
|
|
var index = -1,
|
|
length = values ? values.length : 0;
|
|
|
|
this.clear();
|
|
while (++index < length) {
|
|
var entry = values[index];
|
|
this.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
|
|
// Add functions to the `MapCache`.
|
|
MapCache.prototype.clear = mapClear;
|
|
MapCache.prototype['delete'] = mapDelete;
|
|
MapCache.prototype.get = mapGet;
|
|
MapCache.prototype.has = mapHas;
|
|
MapCache.prototype.set = mapSet;
|
|
|
|
module.e = MapCache;
|
|
|
|
|
|
/***/ },
|
|
/* 81 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var root = __webpack_require__(1);
|
|
|
|
/** Built-in value references. */
|
|
var Reflect = root.Reflect;
|
|
|
|
module.e = Reflect;
|
|
|
|
|
|
/***/ },
|
|
/* 82 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var getNative = __webpack_require__(12),
|
|
root = __webpack_require__(1);
|
|
|
|
/* Built-in method references that are verified to be native. */
|
|
var Set = getNative(root, 'Set');
|
|
|
|
module.e = Set;
|
|
|
|
|
|
/***/ },
|
|
/* 83 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var root = __webpack_require__(1);
|
|
|
|
/** Built-in value references. */
|
|
var Symbol = root.Symbol;
|
|
|
|
module.e = Symbol;
|
|
|
|
|
|
/***/ },
|
|
/* 84 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var root = __webpack_require__(1);
|
|
|
|
/** Built-in value references. */
|
|
var Uint8Array = root.Uint8Array;
|
|
|
|
module.e = Uint8Array;
|
|
|
|
|
|
/***/ },
|
|
/* 85 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var getNative = __webpack_require__(12),
|
|
root = __webpack_require__(1);
|
|
|
|
/* Built-in method references that are verified to be native. */
|
|
var WeakMap = getNative(root, 'WeakMap');
|
|
|
|
module.e = WeakMap;
|
|
|
|
|
|
/***/ },
|
|
/* 86 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Adds the key-value `pair` to `map`.
|
|
*
|
|
* @private
|
|
* @param {Object} map The map to modify.
|
|
* @param {Array} pair The key-value pair to add.
|
|
* @returns {Object} Returns `map`.
|
|
*/
|
|
function addMapEntry(map, pair) {
|
|
// Don't return `Map#set` because it doesn't return the map instance in IE 11.
|
|
map.set(pair[0], pair[1]);
|
|
return map;
|
|
}
|
|
|
|
module.e = addMapEntry;
|
|
|
|
|
|
/***/ },
|
|
/* 87 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Adds `value` to `set`.
|
|
*
|
|
* @private
|
|
* @param {Object} set The set to modify.
|
|
* @param {*} value The value to add.
|
|
* @returns {Object} Returns `set`.
|
|
*/
|
|
function addSetEntry(set, value) {
|
|
set.add(value);
|
|
return set;
|
|
}
|
|
|
|
module.e = addSetEntry;
|
|
|
|
|
|
/***/ },
|
|
/* 88 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* A faster alternative to `Function#apply`, this function invokes `func`
|
|
* with the `this` binding of `thisArg` and the arguments of `args`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to invoke.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {...*} args The arguments to invoke `func` with.
|
|
* @returns {*} Returns the result of `func`.
|
|
*/
|
|
function apply(func, thisArg, args) {
|
|
var length = args.length;
|
|
switch (length) {
|
|
case 0: return func.call(thisArg);
|
|
case 1: return func.call(thisArg, args[0]);
|
|
case 2: return func.call(thisArg, args[0], args[1]);
|
|
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
|
}
|
|
return func.apply(thisArg, args);
|
|
}
|
|
|
|
module.e = apply;
|
|
|
|
|
|
/***/ },
|
|
/* 89 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Appends the elements of `values` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to append.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayPush(array, values) {
|
|
var index = -1,
|
|
length = values.length,
|
|
offset = array.length;
|
|
|
|
while (++index < length) {
|
|
array[offset + index] = values[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
module.e = arrayPush;
|
|
|
|
|
|
/***/ },
|
|
/* 90 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var copyObject = __webpack_require__(20),
|
|
keys = __webpack_require__(45);
|
|
|
|
/**
|
|
* The base implementation of `_.assign` without support for multiple sources
|
|
* or `customizer` functions.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseAssign(object, source) {
|
|
return object && copyObject(source, keys(source), object);
|
|
}
|
|
|
|
module.e = baseAssign;
|
|
|
|
|
|
/***/ },
|
|
/* 91 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Stack = __webpack_require__(32),
|
|
arrayEach = __webpack_require__(33),
|
|
assignValue = __webpack_require__(35),
|
|
baseAssign = __webpack_require__(90),
|
|
baseForOwn = __webpack_require__(95),
|
|
cloneBuffer = __webpack_require__(105),
|
|
copyArray = __webpack_require__(41),
|
|
copySymbols = __webpack_require__(112),
|
|
getTag = __webpack_require__(117),
|
|
initCloneArray = __webpack_require__(121),
|
|
initCloneByTag = __webpack_require__(122),
|
|
initCloneObject = __webpack_require__(123),
|
|
isArray = __webpack_require__(4),
|
|
isBuffer = __webpack_require__(139),
|
|
isHostObject = __webpack_require__(21),
|
|
isObject = __webpack_require__(2);
|
|
|
|
/** `Object#toString` result references. */
|
|
var argsTag = '[object Arguments]',
|
|
arrayTag = '[object Array]',
|
|
boolTag = '[object Boolean]',
|
|
dateTag = '[object Date]',
|
|
errorTag = '[object Error]',
|
|
funcTag = '[object Function]',
|
|
genTag = '[object GeneratorFunction]',
|
|
mapTag = '[object Map]',
|
|
numberTag = '[object Number]',
|
|
objectTag = '[object Object]',
|
|
regexpTag = '[object RegExp]',
|
|
setTag = '[object Set]',
|
|
stringTag = '[object String]',
|
|
symbolTag = '[object Symbol]',
|
|
weakMapTag = '[object WeakMap]';
|
|
|
|
var arrayBufferTag = '[object ArrayBuffer]',
|
|
float32Tag = '[object Float32Array]',
|
|
float64Tag = '[object Float64Array]',
|
|
int8Tag = '[object Int8Array]',
|
|
int16Tag = '[object Int16Array]',
|
|
int32Tag = '[object Int32Array]',
|
|
uint8Tag = '[object Uint8Array]',
|
|
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
uint16Tag = '[object Uint16Array]',
|
|
uint32Tag = '[object Uint32Array]';
|
|
|
|
/** Used to identify `toStringTag` values supported by `_.clone`. */
|
|
var cloneableTags = {};
|
|
cloneableTags[argsTag] = cloneableTags[arrayTag] =
|
|
cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
|
|
cloneableTags[dateTag] = cloneableTags[float32Tag] =
|
|
cloneableTags[float64Tag] = cloneableTags[int8Tag] =
|
|
cloneableTags[int16Tag] = cloneableTags[int32Tag] =
|
|
cloneableTags[mapTag] = cloneableTags[numberTag] =
|
|
cloneableTags[objectTag] = cloneableTags[regexpTag] =
|
|
cloneableTags[setTag] = cloneableTags[stringTag] =
|
|
cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
|
|
cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
|
|
cloneableTags[uint32Tag] = true;
|
|
cloneableTags[errorTag] = cloneableTags[funcTag] =
|
|
cloneableTags[weakMapTag] = false;
|
|
|
|
/**
|
|
* The base implementation of `_.clone` and `_.cloneDeep` which tracks
|
|
* traversed objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @param {boolean} [isFull] Specify a clone including symbols.
|
|
* @param {Function} [customizer] The function to customize cloning.
|
|
* @param {string} [key] The key of `value`.
|
|
* @param {Object} [object] The parent object of `value`.
|
|
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
|
|
* @returns {*} Returns the cloned value.
|
|
*/
|
|
function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
|
|
var result;
|
|
if (customizer) {
|
|
result = object ? customizer(value, key, object, stack) : customizer(value);
|
|
}
|
|
if (result !== undefined) {
|
|
return result;
|
|
}
|
|
if (!isObject(value)) {
|
|
return value;
|
|
}
|
|
var isArr = isArray(value);
|
|
if (isArr) {
|
|
result = initCloneArray(value);
|
|
if (!isDeep) {
|
|
return copyArray(value, result);
|
|
}
|
|
} else {
|
|
var tag = getTag(value),
|
|
isFunc = tag == funcTag || tag == genTag;
|
|
|
|
if (isBuffer(value)) {
|
|
return cloneBuffer(value, isDeep);
|
|
}
|
|
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
|
|
if (isHostObject(value)) {
|
|
return object ? value : {};
|
|
}
|
|
result = initCloneObject(isFunc ? {} : value);
|
|
if (!isDeep) {
|
|
result = baseAssign(result, value);
|
|
return isFull ? copySymbols(value, result) : result;
|
|
}
|
|
} else {
|
|
if (!cloneableTags[tag]) {
|
|
return object ? value : {};
|
|
}
|
|
result = initCloneByTag(value, tag, isDeep);
|
|
}
|
|
}
|
|
// Check for circular references and return its corresponding clone.
|
|
stack || (stack = new Stack);
|
|
var stacked = stack.get(value);
|
|
if (stacked) {
|
|
return stacked;
|
|
}
|
|
stack.set(value, result);
|
|
|
|
// Recursively populate clone (susceptible to call stack limits).
|
|
(isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
|
|
assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
|
|
});
|
|
return (isFull && !isArr) ? copySymbols(value, result) : result;
|
|
}
|
|
|
|
module.e = baseClone;
|
|
|
|
|
|
/***/ },
|
|
/* 92 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isObject = __webpack_require__(2);
|
|
|
|
/** Built-in value references. */
|
|
var objectCreate = Object.create;
|
|
|
|
/**
|
|
* The base implementation of `_.create` without support for assigning
|
|
* properties to the created object.
|
|
*
|
|
* @private
|
|
* @param {Object} prototype The object to inherit from.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function baseCreate(proto) {
|
|
return isObject(proto) ? objectCreate(proto) : {};
|
|
}
|
|
|
|
module.e = baseCreate;
|
|
|
|
|
|
/***/ },
|
|
/* 93 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var arrayPush = __webpack_require__(89),
|
|
isArguments = __webpack_require__(24),
|
|
isArray = __webpack_require__(4),
|
|
isArrayLikeObject = __webpack_require__(26);
|
|
|
|
/**
|
|
* The base implementation of `_.flatten` with support for restricting flattening.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to flatten.
|
|
* @param {number} depth The maximum recursion depth.
|
|
* @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
|
|
* @param {Array} [result=[]] The initial result value.
|
|
* @returns {Array} Returns the new flattened array.
|
|
*/
|
|
function baseFlatten(array, depth, isStrict, result) {
|
|
result || (result = []);
|
|
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (depth > 0 && isArrayLikeObject(value) &&
|
|
(isStrict || isArray(value) || isArguments(value))) {
|
|
if (depth > 1) {
|
|
// Recursively flatten arrays (susceptible to call stack limits).
|
|
baseFlatten(value, depth - 1, isStrict, result);
|
|
} else {
|
|
arrayPush(result, value);
|
|
}
|
|
} else if (!isStrict) {
|
|
result[result.length] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.e = baseFlatten;
|
|
|
|
|
|
/***/ },
|
|
/* 94 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var createBaseFor = __webpack_require__(114);
|
|
|
|
/**
|
|
* The base implementation of `baseForIn` and `baseForOwn` which iterates
|
|
* over `object` properties returned by `keysFunc` invoking `iteratee` for
|
|
* each property. Iteratee functions may exit iteration early by explicitly
|
|
* returning `false`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
var baseFor = createBaseFor();
|
|
|
|
module.e = baseFor;
|
|
|
|
|
|
/***/ },
|
|
/* 95 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseFor = __webpack_require__(94),
|
|
keys = __webpack_require__(45);
|
|
|
|
/**
|
|
* The base implementation of `_.forOwn` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseForOwn(object, iteratee) {
|
|
return object && baseFor(object, iteratee, keys);
|
|
}
|
|
|
|
module.e = baseForOwn;
|
|
|
|
|
|
/***/ },
|
|
/* 96 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/** Built-in value references. */
|
|
var getPrototypeOf = Object.getPrototypeOf;
|
|
|
|
/**
|
|
* The base implementation of `_.has` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} key The key to check.
|
|
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
|
*/
|
|
function baseHas(object, key) {
|
|
// Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
|
|
// that are composed entirely of index properties, return `false` for
|
|
// `hasOwnProperty` checks of them.
|
|
return hasOwnProperty.call(object, key) ||
|
|
(typeof object == 'object' && key in object && getPrototypeOf(object) === null);
|
|
}
|
|
|
|
module.e = baseHas;
|
|
|
|
|
|
/***/ },
|
|
/* 97 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
var nativeKeys = Object.keys;
|
|
|
|
/**
|
|
* The base implementation of `_.keys` which doesn't skip the constructor
|
|
* property of prototypes or treat sparse arrays as dense.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function baseKeys(object) {
|
|
return nativeKeys(Object(object));
|
|
}
|
|
|
|
module.e = baseKeys;
|
|
|
|
|
|
/***/ },
|
|
/* 98 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Reflect = __webpack_require__(81),
|
|
iteratorToArray = __webpack_require__(125);
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Built-in value references. */
|
|
var enumerate = Reflect ? Reflect.enumerate : undefined,
|
|
propertyIsEnumerable = objectProto.propertyIsEnumerable;
|
|
|
|
/**
|
|
* The base implementation of `_.keysIn` which doesn't skip the constructor
|
|
* property of prototypes or treat sparse arrays as dense.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function baseKeysIn(object) {
|
|
object = object == null ? object : Object(object);
|
|
|
|
var result = [];
|
|
for (var key in object) {
|
|
result.push(key);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Fallback for IE < 9 with es6-shim.
|
|
if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
|
|
baseKeysIn = function(object) {
|
|
return iteratorToArray(enumerate(object));
|
|
};
|
|
}
|
|
|
|
module.e = baseKeysIn;
|
|
|
|
|
|
/***/ },
|
|
/* 99 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Stack = __webpack_require__(32),
|
|
arrayEach = __webpack_require__(33),
|
|
assignMergeValue = __webpack_require__(34),
|
|
baseMergeDeep = __webpack_require__(100),
|
|
isArray = __webpack_require__(4),
|
|
isObject = __webpack_require__(2),
|
|
isTypedArray = __webpack_require__(44),
|
|
keysIn = __webpack_require__(46);
|
|
|
|
/**
|
|
* The base implementation of `_.merge` without support for multiple sources.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {number} srcIndex The index of `source`.
|
|
* @param {Function} [customizer] The function to customize merged values.
|
|
* @param {Object} [stack] Tracks traversed source values and their merged counterparts.
|
|
*/
|
|
function baseMerge(object, source, srcIndex, customizer, stack) {
|
|
if (object === source) {
|
|
return;
|
|
}
|
|
var props = (isArray(source) || isTypedArray(source))
|
|
? undefined
|
|
: keysIn(source);
|
|
|
|
arrayEach(props || source, function(srcValue, key) {
|
|
if (props) {
|
|
key = srcValue;
|
|
srcValue = source[key];
|
|
}
|
|
if (isObject(srcValue)) {
|
|
stack || (stack = new Stack);
|
|
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
|
|
}
|
|
else {
|
|
var newValue = customizer
|
|
? customizer(object[key], srcValue, (key + ''), object, source, stack)
|
|
: undefined;
|
|
|
|
if (newValue === undefined) {
|
|
newValue = srcValue;
|
|
}
|
|
assignMergeValue(object, key, newValue);
|
|
}
|
|
});
|
|
}
|
|
|
|
module.e = baseMerge;
|
|
|
|
|
|
/***/ },
|
|
/* 100 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assignMergeValue = __webpack_require__(34),
|
|
baseClone = __webpack_require__(91),
|
|
copyArray = __webpack_require__(41),
|
|
isArguments = __webpack_require__(24),
|
|
isArray = __webpack_require__(4),
|
|
isArrayLikeObject = __webpack_require__(26),
|
|
isFunction = __webpack_require__(16),
|
|
isObject = __webpack_require__(2),
|
|
isPlainObject = __webpack_require__(141),
|
|
isTypedArray = __webpack_require__(44),
|
|
toPlainObject = __webpack_require__(146);
|
|
|
|
/**
|
|
* A specialized version of `baseMerge` for arrays and objects which performs
|
|
* deep merges and tracks traversed objects enabling objects with circular
|
|
* references to be merged.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {string} key The key of the value to merge.
|
|
* @param {number} srcIndex The index of `source`.
|
|
* @param {Function} mergeFunc The function to merge values.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @param {Object} [stack] Tracks traversed source values and their merged counterparts.
|
|
*/
|
|
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
|
|
var objValue = object[key],
|
|
srcValue = source[key],
|
|
stacked = stack.get(srcValue);
|
|
|
|
if (stacked) {
|
|
assignMergeValue(object, key, stacked);
|
|
return;
|
|
}
|
|
var newValue = customizer
|
|
? customizer(objValue, srcValue, (key + ''), object, source, stack)
|
|
: undefined;
|
|
|
|
var isCommon = newValue === undefined;
|
|
|
|
if (isCommon) {
|
|
newValue = srcValue;
|
|
if (isArray(srcValue) || isTypedArray(srcValue)) {
|
|
if (isArray(objValue)) {
|
|
newValue = objValue;
|
|
}
|
|
else if (isArrayLikeObject(objValue)) {
|
|
newValue = copyArray(objValue);
|
|
}
|
|
else {
|
|
isCommon = false;
|
|
newValue = baseClone(srcValue, !customizer);
|
|
}
|
|
}
|
|
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
|
if (isArguments(objValue)) {
|
|
newValue = toPlainObject(objValue);
|
|
}
|
|
else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
|
|
isCommon = false;
|
|
newValue = baseClone(srcValue, !customizer);
|
|
}
|
|
else {
|
|
newValue = objValue;
|
|
}
|
|
}
|
|
else {
|
|
isCommon = false;
|
|
}
|
|
}
|
|
stack.set(srcValue, newValue);
|
|
|
|
if (isCommon) {
|
|
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
|
|
}
|
|
stack['delete'](srcValue);
|
|
assignMergeValue(object, key, newValue);
|
|
}
|
|
|
|
module.e = baseMergeDeep;
|
|
|
|
|
|
/***/ },
|
|
/* 101 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var arrayReduce = __webpack_require__(19);
|
|
|
|
/**
|
|
* The base implementation of `_.pick` without support for individual
|
|
* property names.
|
|
*
|
|
* @private
|
|
* @param {Object} object The source object.
|
|
* @param {string[]} props The property names to pick.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function basePick(object, props) {
|
|
object = Object(object);
|
|
return arrayReduce(props, function(result, key) {
|
|
if (key in object) {
|
|
result[key] = object[key];
|
|
}
|
|
return result;
|
|
}, {});
|
|
}
|
|
|
|
module.e = basePick;
|
|
|
|
|
|
/***/ },
|
|
/* 102 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* The base implementation of `_.property` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function baseProperty(key) {
|
|
return function(object) {
|
|
return object == null ? undefined : object[key];
|
|
};
|
|
}
|
|
|
|
module.e = baseProperty;
|
|
|
|
|
|
/***/ },
|
|
/* 103 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* The base implementation of `_.times` without support for iteratee shorthands
|
|
* or max array length checks.
|
|
*
|
|
* @private
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns the array of results.
|
|
*/
|
|
function baseTimes(n, iteratee) {
|
|
var index = -1,
|
|
result = Array(n);
|
|
|
|
while (++index < n) {
|
|
result[index] = iteratee(index);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.e = baseTimes;
|
|
|
|
|
|
/***/ },
|
|
/* 104 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Checks if `value` is a global object.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {null|Object} Returns `value` if it's a global object, else `null`.
|
|
*/
|
|
function checkGlobal(value) {
|
|
return (value && value.Object === Object) ? value : null;
|
|
}
|
|
|
|
module.e = checkGlobal;
|
|
|
|
|
|
/***/ },
|
|
/* 105 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Creates a clone of `buffer`.
|
|
*
|
|
* @private
|
|
* @param {Buffer} buffer The buffer to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Buffer} Returns the cloned buffer.
|
|
*/
|
|
function cloneBuffer(buffer, isDeep) {
|
|
if (isDeep) {
|
|
return buffer.slice();
|
|
}
|
|
var result = new buffer.constructor(buffer.length);
|
|
buffer.copy(result);
|
|
return result;
|
|
}
|
|
|
|
module.e = cloneBuffer;
|
|
|
|
|
|
/***/ },
|
|
/* 106 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var addMapEntry = __webpack_require__(86),
|
|
arrayReduce = __webpack_require__(19),
|
|
mapToArray = __webpack_require__(131);
|
|
|
|
/**
|
|
* Creates a clone of `map`.
|
|
*
|
|
* @private
|
|
* @param {Object} map The map to clone.
|
|
* @returns {Object} Returns the cloned map.
|
|
*/
|
|
function cloneMap(map) {
|
|
return arrayReduce(mapToArray(map), addMapEntry, new map.constructor);
|
|
}
|
|
|
|
module.e = cloneMap;
|
|
|
|
|
|
/***/ },
|
|
/* 107 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/** Used to match `RegExp` flags from their coerced string values. */
|
|
var reFlags = /\w*$/;
|
|
|
|
/**
|
|
* Creates a clone of `regexp`.
|
|
*
|
|
* @private
|
|
* @param {Object} regexp The regexp to clone.
|
|
* @returns {Object} Returns the cloned regexp.
|
|
*/
|
|
function cloneRegExp(regexp) {
|
|
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
|
|
result.lastIndex = regexp.lastIndex;
|
|
return result;
|
|
}
|
|
|
|
module.e = cloneRegExp;
|
|
|
|
|
|
/***/ },
|
|
/* 108 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var addSetEntry = __webpack_require__(87),
|
|
arrayReduce = __webpack_require__(19),
|
|
setToArray = __webpack_require__(132);
|
|
|
|
/**
|
|
* Creates a clone of `set`.
|
|
*
|
|
* @private
|
|
* @param {Object} set The set to clone.
|
|
* @returns {Object} Returns the cloned set.
|
|
*/
|
|
function cloneSet(set) {
|
|
return arrayReduce(setToArray(set), addSetEntry, new set.constructor);
|
|
}
|
|
|
|
module.e = cloneSet;
|
|
|
|
|
|
/***/ },
|
|
/* 109 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Symbol = __webpack_require__(83);
|
|
|
|
/** Used to convert symbols to primitives and strings. */
|
|
var symbolProto = Symbol ? Symbol.prototype : undefined,
|
|
symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
|
|
|
|
/**
|
|
* Creates a clone of the `symbol` object.
|
|
*
|
|
* @private
|
|
* @param {Object} symbol The symbol object to clone.
|
|
* @returns {Object} Returns the cloned symbol object.
|
|
*/
|
|
function cloneSymbol(symbol) {
|
|
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
|
|
}
|
|
|
|
module.e = cloneSymbol;
|
|
|
|
|
|
/***/ },
|
|
/* 110 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var cloneArrayBuffer = __webpack_require__(40);
|
|
|
|
/**
|
|
* Creates a clone of `typedArray`.
|
|
*
|
|
* @private
|
|
* @param {Object} typedArray The typed array to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Object} Returns the cloned typed array.
|
|
*/
|
|
function cloneTypedArray(typedArray, isDeep) {
|
|
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
|
|
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
|
}
|
|
|
|
module.e = cloneTypedArray;
|
|
|
|
|
|
/***/ },
|
|
/* 111 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assignValue = __webpack_require__(35);
|
|
|
|
/**
|
|
* This function is like `copyObject` except that it accepts a function to
|
|
* customize copied values.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy properties from.
|
|
* @param {Array} props The property names to copy.
|
|
* @param {Object} [object={}] The object to copy properties to.
|
|
* @param {Function} [customizer] The function to customize copied values.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copyObjectWith(source, props, object, customizer) {
|
|
object || (object = {});
|
|
|
|
var index = -1,
|
|
length = props.length;
|
|
|
|
while (++index < length) {
|
|
var key = props[index];
|
|
|
|
var newValue = customizer
|
|
? customizer(object[key], source[key], key, object, source)
|
|
: source[key];
|
|
|
|
assignValue(object, key, newValue);
|
|
}
|
|
return object;
|
|
}
|
|
|
|
module.e = copyObjectWith;
|
|
|
|
|
|
/***/ },
|
|
/* 112 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var copyObject = __webpack_require__(20),
|
|
getSymbols = __webpack_require__(116);
|
|
|
|
/**
|
|
* Copies own symbol properties of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy symbols from.
|
|
* @param {Object} [object={}] The object to copy symbols to.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copySymbols(source, object) {
|
|
return copyObject(source, getSymbols(source), object);
|
|
}
|
|
|
|
module.e = copySymbols;
|
|
|
|
|
|
/***/ },
|
|
/* 113 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isIterateeCall = __webpack_require__(124),
|
|
rest = __webpack_require__(47);
|
|
|
|
/**
|
|
* Creates a function like `_.assign`.
|
|
*
|
|
* @private
|
|
* @param {Function} assigner The function to assign values.
|
|
* @returns {Function} Returns the new assigner function.
|
|
*/
|
|
function createAssigner(assigner) {
|
|
return rest(function(object, sources) {
|
|
var index = -1,
|
|
length = sources.length,
|
|
customizer = length > 1 ? sources[length - 1] : undefined,
|
|
guard = length > 2 ? sources[2] : undefined;
|
|
|
|
customizer = typeof customizer == 'function'
|
|
? (length--, customizer)
|
|
: undefined;
|
|
|
|
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
customizer = length < 3 ? undefined : customizer;
|
|
length = 1;
|
|
}
|
|
object = Object(object);
|
|
while (++index < length) {
|
|
var source = sources[index];
|
|
if (source) {
|
|
assigner(object, source, index, customizer);
|
|
}
|
|
}
|
|
return object;
|
|
});
|
|
}
|
|
|
|
module.e = createAssigner;
|
|
|
|
|
|
/***/ },
|
|
/* 114 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Creates a base function for methods like `_.forIn`.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new base function.
|
|
*/
|
|
function createBaseFor(fromRight) {
|
|
return function(object, iteratee, keysFunc) {
|
|
var index = -1,
|
|
iterable = Object(object),
|
|
props = keysFunc(object),
|
|
length = props.length;
|
|
|
|
while (length--) {
|
|
var key = props[fromRight ? length : ++index];
|
|
if (iteratee(iterable[key], key, iterable) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return object;
|
|
};
|
|
}
|
|
|
|
module.e = createBaseFor;
|
|
|
|
|
|
/***/ },
|
|
/* 115 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseProperty = __webpack_require__(102);
|
|
|
|
/**
|
|
* Gets the "length" property value of `object`.
|
|
*
|
|
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
|
|
* that affects Safari on at least iOS 8.1-8.3 ARM64.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {*} Returns the "length" value.
|
|
*/
|
|
var getLength = baseProperty('length');
|
|
|
|
module.e = getLength;
|
|
|
|
|
|
/***/ },
|
|
/* 116 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/** Built-in value references. */
|
|
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
|
|
|
/**
|
|
* Creates an array of the own symbol properties of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of symbols.
|
|
*/
|
|
var getSymbols = getOwnPropertySymbols || function() {
|
|
return [];
|
|
};
|
|
|
|
module.e = getSymbols;
|
|
|
|
|
|
/***/ },
|
|
/* 117 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Map = __webpack_require__(3),
|
|
Set = __webpack_require__(82),
|
|
WeakMap = __webpack_require__(85);
|
|
|
|
/** `Object#toString` result references. */
|
|
var mapTag = '[object Map]',
|
|
objectTag = '[object Object]',
|
|
setTag = '[object Set]',
|
|
weakMapTag = '[object WeakMap]';
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to resolve the decompiled source of functions. */
|
|
var funcToString = Function.prototype.toString;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objectToString = objectProto.toString;
|
|
|
|
/** Used to detect maps, sets, and weakmaps. */
|
|
var mapCtorString = Map ? funcToString.call(Map) : '',
|
|
setCtorString = Set ? funcToString.call(Set) : '',
|
|
weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : '';
|
|
|
|
/**
|
|
* Gets the `toStringTag` of `value`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @returns {string} Returns the `toStringTag`.
|
|
*/
|
|
function getTag(value) {
|
|
return objectToString.call(value);
|
|
}
|
|
|
|
// Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps.
|
|
if ((Map && getTag(new Map) != mapTag) ||
|
|
(Set && getTag(new Set) != setTag) ||
|
|
(WeakMap && getTag(new WeakMap) != weakMapTag)) {
|
|
getTag = function(value) {
|
|
var result = objectToString.call(value),
|
|
Ctor = result == objectTag ? value.constructor : null,
|
|
ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
|
|
|
|
if (ctorString) {
|
|
switch (ctorString) {
|
|
case mapCtorString: return mapTag;
|
|
case setCtorString: return setTag;
|
|
case weakMapCtorString: return weakMapTag;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
module.e = getTag;
|
|
|
|
|
|
/***/ },
|
|
/* 118 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var hashHas = __webpack_require__(42);
|
|
|
|
/**
|
|
* Removes `key` and its value from the hash.
|
|
*
|
|
* @private
|
|
* @param {Object} hash The hash to modify.
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function hashDelete(hash, key) {
|
|
return hashHas(hash, key) && delete hash[key];
|
|
}
|
|
|
|
module.e = hashDelete;
|
|
|
|
|
|
/***/ },
|
|
/* 119 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var nativeCreate = __webpack_require__(14);
|
|
|
|
/** Used to stand-in for `undefined` hash values. */
|
|
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Gets the hash value for `key`.
|
|
*
|
|
* @private
|
|
* @param {Object} hash The hash to query.
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function hashGet(hash, key) {
|
|
if (nativeCreate) {
|
|
var result = hash[key];
|
|
return result === HASH_UNDEFINED ? undefined : result;
|
|
}
|
|
return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
|
|
}
|
|
|
|
module.e = hashGet;
|
|
|
|
|
|
/***/ },
|
|
/* 120 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var nativeCreate = __webpack_require__(14);
|
|
|
|
/** Used to stand-in for `undefined` hash values. */
|
|
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
|
|
|
/**
|
|
* Sets the hash `key` to `value`.
|
|
*
|
|
* @private
|
|
* @param {Object} hash The hash to modify.
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
*/
|
|
function hashSet(hash, key, value) {
|
|
hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
|
}
|
|
|
|
module.e = hashSet;
|
|
|
|
|
|
/***/ },
|
|
/* 121 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Initializes an array clone.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to clone.
|
|
* @returns {Array} Returns the initialized clone.
|
|
*/
|
|
function initCloneArray(array) {
|
|
var length = array.length,
|
|
result = array.constructor(length);
|
|
|
|
// Add properties assigned by `RegExp#exec`.
|
|
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
|
|
result.index = array.index;
|
|
result.input = array.input;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.e = initCloneArray;
|
|
|
|
|
|
/***/ },
|
|
/* 122 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var cloneArrayBuffer = __webpack_require__(40),
|
|
cloneMap = __webpack_require__(106),
|
|
cloneRegExp = __webpack_require__(107),
|
|
cloneSet = __webpack_require__(108),
|
|
cloneSymbol = __webpack_require__(109),
|
|
cloneTypedArray = __webpack_require__(110);
|
|
|
|
/** `Object#toString` result references. */
|
|
var boolTag = '[object Boolean]',
|
|
dateTag = '[object Date]',
|
|
mapTag = '[object Map]',
|
|
numberTag = '[object Number]',
|
|
regexpTag = '[object RegExp]',
|
|
setTag = '[object Set]',
|
|
stringTag = '[object String]',
|
|
symbolTag = '[object Symbol]';
|
|
|
|
var arrayBufferTag = '[object ArrayBuffer]',
|
|
float32Tag = '[object Float32Array]',
|
|
float64Tag = '[object Float64Array]',
|
|
int8Tag = '[object Int8Array]',
|
|
int16Tag = '[object Int16Array]',
|
|
int32Tag = '[object Int32Array]',
|
|
uint8Tag = '[object Uint8Array]',
|
|
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
uint16Tag = '[object Uint16Array]',
|
|
uint32Tag = '[object Uint32Array]';
|
|
|
|
/**
|
|
* Initializes an object clone based on its `toStringTag`.
|
|
*
|
|
* **Note:** This function only supports cloning values with tags of
|
|
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to clone.
|
|
* @param {string} tag The `toStringTag` of the object to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Object} Returns the initialized clone.
|
|
*/
|
|
function initCloneByTag(object, tag, isDeep) {
|
|
var Ctor = object.constructor;
|
|
switch (tag) {
|
|
case arrayBufferTag:
|
|
return cloneArrayBuffer(object);
|
|
|
|
case boolTag:
|
|
case dateTag:
|
|
return new Ctor(+object);
|
|
|
|
case float32Tag: case float64Tag:
|
|
case int8Tag: case int16Tag: case int32Tag:
|
|
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
|
return cloneTypedArray(object, isDeep);
|
|
|
|
case mapTag:
|
|
return cloneMap(object);
|
|
|
|
case numberTag:
|
|
case stringTag:
|
|
return new Ctor(object);
|
|
|
|
case regexpTag:
|
|
return cloneRegExp(object);
|
|
|
|
case setTag:
|
|
return cloneSet(object);
|
|
|
|
case symbolTag:
|
|
return cloneSymbol(object);
|
|
}
|
|
}
|
|
|
|
module.e = initCloneByTag;
|
|
|
|
|
|
/***/ },
|
|
/* 123 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseCreate = __webpack_require__(92),
|
|
isPrototype = __webpack_require__(23);
|
|
|
|
/** Built-in value references. */
|
|
var getPrototypeOf = Object.getPrototypeOf;
|
|
|
|
/**
|
|
* Initializes an object clone.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to clone.
|
|
* @returns {Object} Returns the initialized clone.
|
|
*/
|
|
function initCloneObject(object) {
|
|
return (typeof object.constructor == 'function' && !isPrototype(object))
|
|
? baseCreate(getPrototypeOf(object))
|
|
: {};
|
|
}
|
|
|
|
module.e = initCloneObject;
|
|
|
|
|
|
/***/ },
|
|
/* 124 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var eq = __webpack_require__(15),
|
|
isArrayLike = __webpack_require__(25),
|
|
isIndex = __webpack_require__(22),
|
|
isObject = __webpack_require__(2);
|
|
|
|
/**
|
|
* Checks if the given arguments are from an iteratee call.
|
|
*
|
|
* @private
|
|
* @param {*} value The potential iteratee value argument.
|
|
* @param {*} index The potential iteratee index or key argument.
|
|
* @param {*} object The potential iteratee object argument.
|
|
* @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
|
|
*/
|
|
function isIterateeCall(value, index, object) {
|
|
if (!isObject(object)) {
|
|
return false;
|
|
}
|
|
var type = typeof index;
|
|
if (type == 'number'
|
|
? (isArrayLike(object) && isIndex(index, object.length))
|
|
: (type == 'string' && index in object)) {
|
|
return eq(object[index], value);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
module.e = isIterateeCall;
|
|
|
|
|
|
/***/ },
|
|
/* 125 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Converts `iterator` to an array.
|
|
*
|
|
* @private
|
|
* @param {Object} iterator The iterator to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function iteratorToArray(iterator) {
|
|
var data,
|
|
result = [];
|
|
|
|
while (!(data = iterator.next()).done) {
|
|
result.push(data.value);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.e = iteratorToArray;
|
|
|
|
|
|
/***/ },
|
|
/* 126 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Hash = __webpack_require__(79),
|
|
Map = __webpack_require__(3);
|
|
|
|
/**
|
|
* Removes all key-value entries from the map.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf MapCache
|
|
*/
|
|
function mapClear() {
|
|
this.__data__ = {
|
|
'hash': new Hash,
|
|
'map': Map ? new Map : [],
|
|
'string': new Hash
|
|
};
|
|
}
|
|
|
|
module.e = mapClear;
|
|
|
|
|
|
/***/ },
|
|
/* 127 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Map = __webpack_require__(3),
|
|
assocDelete = __webpack_require__(36),
|
|
hashDelete = __webpack_require__(118),
|
|
isKeyable = __webpack_require__(13);
|
|
|
|
/**
|
|
* Removes `key` and its value from the map.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function mapDelete(key) {
|
|
var data = this.__data__;
|
|
if (isKeyable(key)) {
|
|
return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
|
|
}
|
|
return Map ? data.map['delete'](key) : assocDelete(data.map, key);
|
|
}
|
|
|
|
module.e = mapDelete;
|
|
|
|
|
|
/***/ },
|
|
/* 128 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Map = __webpack_require__(3),
|
|
assocGet = __webpack_require__(37),
|
|
hashGet = __webpack_require__(119),
|
|
isKeyable = __webpack_require__(13);
|
|
|
|
/**
|
|
* Gets the map value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function mapGet(key) {
|
|
var data = this.__data__;
|
|
if (isKeyable(key)) {
|
|
return hashGet(typeof key == 'string' ? data.string : data.hash, key);
|
|
}
|
|
return Map ? data.map.get(key) : assocGet(data.map, key);
|
|
}
|
|
|
|
module.e = mapGet;
|
|
|
|
|
|
/***/ },
|
|
/* 129 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Map = __webpack_require__(3),
|
|
assocHas = __webpack_require__(38),
|
|
hashHas = __webpack_require__(42),
|
|
isKeyable = __webpack_require__(13);
|
|
|
|
/**
|
|
* Checks if a map value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function mapHas(key) {
|
|
var data = this.__data__;
|
|
if (isKeyable(key)) {
|
|
return hashHas(typeof key == 'string' ? data.string : data.hash, key);
|
|
}
|
|
return Map ? data.map.has(key) : assocHas(data.map, key);
|
|
}
|
|
|
|
module.e = mapHas;
|
|
|
|
|
|
/***/ },
|
|
/* 130 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var Map = __webpack_require__(3),
|
|
assocSet = __webpack_require__(39),
|
|
hashSet = __webpack_require__(120),
|
|
isKeyable = __webpack_require__(13);
|
|
|
|
/**
|
|
* Sets the map `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the map cache object.
|
|
*/
|
|
function mapSet(key, value) {
|
|
var data = this.__data__;
|
|
if (isKeyable(key)) {
|
|
hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
|
|
} else if (Map) {
|
|
data.map.set(key, value);
|
|
} else {
|
|
assocSet(data.map, key, value);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
module.e = mapSet;
|
|
|
|
|
|
/***/ },
|
|
/* 131 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Converts `map` to an array.
|
|
*
|
|
* @private
|
|
* @param {Object} map The map to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function mapToArray(map) {
|
|
var index = -1,
|
|
result = Array(map.size);
|
|
|
|
map.forEach(function(value, key) {
|
|
result[++index] = [key, value];
|
|
});
|
|
return result;
|
|
}
|
|
|
|
module.e = mapToArray;
|
|
|
|
|
|
/***/ },
|
|
/* 132 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Converts `set` to an array.
|
|
*
|
|
* @private
|
|
* @param {Object} set The set to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function setToArray(set) {
|
|
var index = -1,
|
|
result = Array(set.size);
|
|
|
|
set.forEach(function(value) {
|
|
result[++index] = value;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
module.e = setToArray;
|
|
|
|
|
|
/***/ },
|
|
/* 133 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Removes all key-value entries from the stack.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf Stack
|
|
*/
|
|
function stackClear() {
|
|
this.__data__ = { 'array': [], 'map': null };
|
|
}
|
|
|
|
module.e = stackClear;
|
|
|
|
|
|
/***/ },
|
|
/* 134 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assocDelete = __webpack_require__(36);
|
|
|
|
/**
|
|
* Removes `key` and its value from the stack.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function stackDelete(key) {
|
|
var data = this.__data__,
|
|
array = data.array;
|
|
|
|
return array ? assocDelete(array, key) : data.map['delete'](key);
|
|
}
|
|
|
|
module.e = stackDelete;
|
|
|
|
|
|
/***/ },
|
|
/* 135 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assocGet = __webpack_require__(37);
|
|
|
|
/**
|
|
* Gets the stack value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function stackGet(key) {
|
|
var data = this.__data__,
|
|
array = data.array;
|
|
|
|
return array ? assocGet(array, key) : data.map.get(key);
|
|
}
|
|
|
|
module.e = stackGet;
|
|
|
|
|
|
/***/ },
|
|
/* 136 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var assocHas = __webpack_require__(38);
|
|
|
|
/**
|
|
* Checks if a stack value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function stackHas(key) {
|
|
var data = this.__data__,
|
|
array = data.array;
|
|
|
|
return array ? assocHas(array, key) : data.map.has(key);
|
|
}
|
|
|
|
module.e = stackHas;
|
|
|
|
|
|
/***/ },
|
|
/* 137 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var MapCache = __webpack_require__(80),
|
|
assocSet = __webpack_require__(39);
|
|
|
|
/** Used as the size to enable large array optimizations. */
|
|
var LARGE_ARRAY_SIZE = 200;
|
|
|
|
/**
|
|
* Sets the stack `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the stack cache object.
|
|
*/
|
|
function stackSet(key, value) {
|
|
var data = this.__data__,
|
|
array = data.array;
|
|
|
|
if (array) {
|
|
if (array.length < (LARGE_ARRAY_SIZE - 1)) {
|
|
assocSet(array, key, value);
|
|
} else {
|
|
data.array = null;
|
|
data.map = new MapCache(array);
|
|
}
|
|
}
|
|
var map = data.map;
|
|
if (map) {
|
|
map.set(key, value);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
module.e = stackSet;
|
|
|
|
|
|
/***/ },
|
|
/* 138 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* Creates a function that returns `value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {*} value The value to return from the new function.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var object = { 'user': 'fred' };
|
|
* var getter = _.constant(object);
|
|
*
|
|
* getter() === object;
|
|
* // => true
|
|
*/
|
|
function constant(value) {
|
|
return function() {
|
|
return value;
|
|
};
|
|
}
|
|
|
|
module.e = constant;
|
|
|
|
|
|
/***/ },
|
|
/* 139 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(module) {var constant = __webpack_require__(138),
|
|
root = __webpack_require__(1);
|
|
|
|
/** Used to determine if values are of the language type `Object`. */
|
|
var objectTypes = {
|
|
'function': true,
|
|
'object': true
|
|
};
|
|
|
|
/** Detect free variable `exports`. */
|
|
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
|
|
? exports
|
|
: undefined;
|
|
|
|
/** Detect free variable `module`. */
|
|
var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
|
|
? module
|
|
: undefined;
|
|
|
|
/** Detect the popular CommonJS extension `module.exports`. */
|
|
var moduleExports = (freeModule && freeModule.exports === freeExports)
|
|
? freeExports
|
|
: undefined;
|
|
|
|
/** Built-in value references. */
|
|
var Buffer = moduleExports ? root.Buffer : undefined;
|
|
|
|
/**
|
|
* Checks if `value` is a buffer.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isBuffer(new Buffer(2));
|
|
* // => true
|
|
*
|
|
* _.isBuffer(new Uint8Array(2));
|
|
* // => false
|
|
*/
|
|
var isBuffer = !Buffer ? constant(false) : function(value) {
|
|
return value instanceof Buffer;
|
|
};
|
|
|
|
module.e = isBuffer;
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(48)(module)))
|
|
|
|
/***/ },
|
|
/* 140 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isFunction = __webpack_require__(16),
|
|
isHostObject = __webpack_require__(21),
|
|
isObjectLike = __webpack_require__(7);
|
|
|
|
/** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
|
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|
|
|
/** Used to detect host constructors (Safari > 5). */
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to resolve the decompiled source of functions. */
|
|
var funcToString = Function.prototype.toString;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/** Used to detect if a method is native. */
|
|
var reIsNative = RegExp('^' +
|
|
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
);
|
|
|
|
/**
|
|
* Checks if `value` is a native function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a native function, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNative(Array.prototype.push);
|
|
* // => true
|
|
*
|
|
* _.isNative(_);
|
|
* // => false
|
|
*/
|
|
function isNative(value) {
|
|
if (value == null) {
|
|
return false;
|
|
}
|
|
if (isFunction(value)) {
|
|
return reIsNative.test(funcToString.call(value));
|
|
}
|
|
return isObjectLike(value) &&
|
|
(isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
|
|
}
|
|
|
|
module.e = isNative;
|
|
|
|
|
|
/***/ },
|
|
/* 141 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isHostObject = __webpack_require__(21),
|
|
isObjectLike = __webpack_require__(7);
|
|
|
|
/** `Object#toString` result references. */
|
|
var objectTag = '[object Object]';
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to resolve the decompiled source of functions. */
|
|
var funcToString = Function.prototype.toString;
|
|
|
|
/** Used to infer the `Object` constructor. */
|
|
var objectCtorString = funcToString.call(Object);
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objectToString = objectProto.toString;
|
|
|
|
/** Built-in value references. */
|
|
var getPrototypeOf = Object.getPrototypeOf;
|
|
|
|
/**
|
|
* Checks if `value` is a plain object, that is, an object created by the
|
|
* `Object` constructor or one with a `[[Prototype]]` of `null`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* }
|
|
*
|
|
* _.isPlainObject(new Foo);
|
|
* // => false
|
|
*
|
|
* _.isPlainObject([1, 2, 3]);
|
|
* // => false
|
|
*
|
|
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
|
* // => true
|
|
*
|
|
* _.isPlainObject(Object.create(null));
|
|
* // => true
|
|
*/
|
|
function isPlainObject(value) {
|
|
if (!isObjectLike(value) ||
|
|
objectToString.call(value) != objectTag || isHostObject(value)) {
|
|
return false;
|
|
}
|
|
var proto = getPrototypeOf(value);
|
|
if (proto === null) {
|
|
return true;
|
|
}
|
|
var Ctor = proto.constructor;
|
|
return (typeof Ctor == 'function' &&
|
|
Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
|
|
}
|
|
|
|
module.e = isPlainObject;
|
|
|
|
|
|
/***/ },
|
|
/* 142 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isArray = __webpack_require__(4),
|
|
isObjectLike = __webpack_require__(7);
|
|
|
|
/** `Object#toString` result references. */
|
|
var stringTag = '[object String]';
|
|
|
|
/** Used for built-in method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objectToString = objectProto.toString;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `String` primitive or object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isString('abc');
|
|
* // => true
|
|
*
|
|
* _.isString(1);
|
|
* // => false
|
|
*/
|
|
function isString(value) {
|
|
return typeof value == 'string' ||
|
|
(!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
|
|
}
|
|
|
|
module.e = isString;
|
|
|
|
|
|
/***/ },
|
|
/* 143 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var baseFlatten = __webpack_require__(93),
|
|
basePick = __webpack_require__(101),
|
|
rest = __webpack_require__(47);
|
|
|
|
/**
|
|
* Creates an object composed of the picked `object` properties.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {...(string|string[])} [props] The property names to pick, specified
|
|
* individually or in arrays.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.pick(object, ['a', 'c']);
|
|
* // => { 'a': 1, 'c': 3 }
|
|
*/
|
|
var pick = rest(function(object, props) {
|
|
return object == null ? {} : basePick(object, baseFlatten(props, 1));
|
|
});
|
|
|
|
module.e = pick;
|
|
|
|
|
|
/***/ },
|
|
/* 144 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var toNumber = __webpack_require__(145);
|
|
|
|
/** Used as references for various `Number` constants. */
|
|
var INFINITY = 1 / 0,
|
|
MAX_INTEGER = 1.7976931348623157e+308;
|
|
|
|
/**
|
|
* Converts `value` to an integer.
|
|
*
|
|
* **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.toInteger(3);
|
|
* // => 3
|
|
*
|
|
* _.toInteger(Number.MIN_VALUE);
|
|
* // => 0
|
|
*
|
|
* _.toInteger(Infinity);
|
|
* // => 1.7976931348623157e+308
|
|
*
|
|
* _.toInteger('3');
|
|
* // => 3
|
|
*/
|
|
function toInteger(value) {
|
|
if (!value) {
|
|
return value === 0 ? value : 0;
|
|
}
|
|
value = toNumber(value);
|
|
if (value === INFINITY || value === -INFINITY) {
|
|
var sign = (value < 0 ? -1 : 1);
|
|
return sign * MAX_INTEGER;
|
|
}
|
|
var remainder = value % 1;
|
|
return value === value ? (remainder ? value - remainder : value) : 0;
|
|
}
|
|
|
|
module.e = toInteger;
|
|
|
|
|
|
/***/ },
|
|
/* 145 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var isFunction = __webpack_require__(16),
|
|
isObject = __webpack_require__(2);
|
|
|
|
/** Used as references for various `Number` constants. */
|
|
var NAN = 0 / 0;
|
|
|
|
/** Used to match leading and trailing whitespace. */
|
|
var reTrim = /^\s+|\s+$/g;
|
|
|
|
/** Used to detect bad signed hexadecimal string values. */
|
|
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
|
|
|
/** Used to detect binary string values. */
|
|
var reIsBinary = /^0b[01]+$/i;
|
|
|
|
/** Used to detect octal string values. */
|
|
var reIsOctal = /^0o[0-7]+$/i;
|
|
|
|
/** Built-in method references without a dependency on `root`. */
|
|
var freeParseInt = parseInt;
|
|
|
|
/**
|
|
* Converts `value` to a number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to process.
|
|
* @returns {number} Returns the number.
|
|
* @example
|
|
*
|
|
* _.toNumber(3);
|
|
* // => 3
|
|
*
|
|
* _.toNumber(Number.MIN_VALUE);
|
|
* // => 5e-324
|
|
*
|
|
* _.toNumber(Infinity);
|
|
* // => Infinity
|
|
*
|
|
* _.toNumber('3');
|
|
* // => 3
|
|
*/
|
|
function toNumber(value) {
|
|
if (isObject(value)) {
|
|
var other = isFunction(value.valueOf) ? value.valueOf() : value;
|
|
value = isObject(other) ? (other + '') : other;
|
|
}
|
|
if (typeof value != 'string') {
|
|
return value === 0 ? value : +value;
|
|
}
|
|
value = value.replace(reTrim, '');
|
|
var isBinary = reIsBinary.test(value);
|
|
return (isBinary || reIsOctal.test(value))
|
|
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
|
: (reIsBadHex.test(value) ? NAN : +value);
|
|
}
|
|
|
|
module.e = toNumber;
|
|
|
|
|
|
/***/ },
|
|
/* 146 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var copyObject = __webpack_require__(20),
|
|
keysIn = __webpack_require__(46);
|
|
|
|
/**
|
|
* Converts `value` to a plain object flattening inherited enumerable
|
|
* properties of `value` to own properties of the plain object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {Object} Returns the converted plain object.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.assign({ 'a': 1 }, new Foo);
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*
|
|
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
|
|
* // => { 'a': 1, 'b': 2, 'c': 3 }
|
|
*/
|
|
function toPlainObject(value) {
|
|
return copyObject(value, keysIn(value));
|
|
}
|
|
|
|
module.e = toPlainObject;
|
|
|
|
|
|
/***/ },
|
|
/* 147 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree.
|
|
*/
|
|
'use strict';
|
|
|
|
// Shimming starts here.
|
|
(function() {
|
|
// Utils.
|
|
var logging = __webpack_require__(0).log;
|
|
var browserDetails = __webpack_require__(0).browserDetails;
|
|
// Export to the adapter global object visible in the browser.
|
|
module.e.browserDetails = browserDetails;
|
|
module.e.extractVersion = __webpack_require__(0).extractVersion;
|
|
module.e.disableLog = __webpack_require__(0).disableLog;
|
|
|
|
// Uncomment if you do not want any logging at all including the switch
|
|
// statement below. Can also be turned off in the browser via
|
|
// adapter.disableLog(true) but then logging from the switch statement below
|
|
// will still appear.
|
|
//require('./utils').disableLog(true);
|
|
|
|
// Browser shims.
|
|
var chromeShim = __webpack_require__(148) || null;
|
|
var edgeShim = __webpack_require__(151) || null;
|
|
var firefoxShim = __webpack_require__(152) || null;
|
|
|
|
// Shim browser if found.
|
|
switch (browserDetails.browser) {
|
|
case 'chrome':
|
|
if (!chromeShim || !chromeShim.shimPeerConnection) {
|
|
logging('Chrome shim is not included in this adapter release.');
|
|
return;
|
|
}
|
|
logging('adapter.js shimming chrome!');
|
|
// Export to the adapter global object visible in the browser.
|
|
module.e.browserShim = chromeShim;
|
|
|
|
chromeShim.shimGetUserMedia();
|
|
chromeShim.shimSourceObject();
|
|
chromeShim.shimPeerConnection();
|
|
chromeShim.shimOnTrack();
|
|
break;
|
|
case 'edge':
|
|
if (!edgeShim || !edgeShim.shimPeerConnection) {
|
|
logging('MS edge shim is not included in this adapter release.');
|
|
return;
|
|
}
|
|
logging('adapter.js shimming edge!');
|
|
// Export to the adapter global object visible in the browser.
|
|
module.e.browserShim = edgeShim;
|
|
|
|
edgeShim.shimPeerConnection();
|
|
break;
|
|
case 'firefox':
|
|
if (!firefoxShim || !firefoxShim.shimPeerConnection) {
|
|
logging('Firefox shim is not included in this adapter release.');
|
|
return;
|
|
}
|
|
logging('adapter.js shimming firefox!');
|
|
// Export to the adapter global object visible in the browser.
|
|
module.e.browserShim = firefoxShim;
|
|
|
|
firefoxShim.shimGetUserMedia();
|
|
firefoxShim.shimSourceObject();
|
|
firefoxShim.shimPeerConnection();
|
|
firefoxShim.shimOnTrack();
|
|
break;
|
|
default:
|
|
logging('Unsupported browser!');
|
|
}
|
|
})();
|
|
|
|
|
|
/***/ },
|
|
/* 148 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree.
|
|
*/
|
|
'use strict';
|
|
var logging = __webpack_require__(0).log;
|
|
var browserDetails = __webpack_require__(0).browserDetails;
|
|
|
|
var chromeShim = {
|
|
shimOnTrack: function() {
|
|
if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in
|
|
window.RTCPeerConnection.prototype)) {
|
|
Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {
|
|
get: function() { return this._ontrack; },
|
|
set: function(f) {
|
|
var self = this;
|
|
if (this._ontrack) {
|
|
this.removeEventListener('track', this._ontrack);
|
|
this.removeEventListener('addstream', this._ontrackpoly);
|
|
}
|
|
this.addEventListener('track', this._ontrack = f);
|
|
this.addEventListener('addstream', this._ontrackpoly = function(e) {
|
|
// onaddstream does not fire when a track is added to an existing stream.
|
|
// but stream.onaddtrack is implemented so we use that
|
|
e.stream.addEventListener('addtrack', function(te) {
|
|
var event = new Event('track');
|
|
event.track = te.track;
|
|
event.receiver = {track: te.track};
|
|
event.streams = [e.stream];
|
|
self.dispatchEvent(event);
|
|
});
|
|
e.stream.getTracks().forEach(function(track) {
|
|
var event = new Event('track');
|
|
event.track = track;
|
|
event.receiver = {track: track};
|
|
event.streams = [e.stream];
|
|
this.dispatchEvent(event);
|
|
}.bind(this));
|
|
}.bind(this));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
shimSourceObject: function() {
|
|
if (typeof window === 'object') {
|
|
if (window.HTMLMediaElement &&
|
|
!('srcObject' in window.HTMLMediaElement.prototype)) {
|
|
// Shim the srcObject property, once, when HTMLMediaElement is found.
|
|
Object.defineProperty(window.HTMLMediaElement.prototype, 'srcObject', {
|
|
get: function() {
|
|
return this._srcObject;
|
|
},
|
|
set: function(stream) {
|
|
var self = this;
|
|
// Use _srcObject as a private property for this shim
|
|
this._srcObject = stream;
|
|
if (this.src) {
|
|
URL.revokeObjectURL(this.src);
|
|
}
|
|
|
|
if (!stream) {
|
|
this.src = '';
|
|
return;
|
|
}
|
|
this.src = URL.createObjectURL(stream);
|
|
// We need to recreate the blob url when a track is added or removed.
|
|
// Doing it manually since we want to avoid a recursion.
|
|
stream.addEventListener('addtrack', function() {
|
|
if (self.src) {
|
|
URL.revokeObjectURL(self.src);
|
|
}
|
|
self.src = URL.createObjectURL(stream);
|
|
});
|
|
stream.addEventListener('removetrack', function() {
|
|
if (self.src) {
|
|
URL.revokeObjectURL(self.src);
|
|
}
|
|
self.src = URL.createObjectURL(stream);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
|
|
shimPeerConnection: function() {
|
|
// The RTCPeerConnection object.
|
|
window.RTCPeerConnection = function(pcConfig, pcConstraints) {
|
|
// Translate iceTransportPolicy to iceTransports,
|
|
// see https://code.google.com/p/webrtc/issues/detail?id=4869
|
|
logging('PeerConnection');
|
|
if (pcConfig && pcConfig.iceTransportPolicy) {
|
|
pcConfig.iceTransports = pcConfig.iceTransportPolicy;
|
|
}
|
|
|
|
var pc = new webkitRTCPeerConnection(pcConfig, pcConstraints); // jscs:ignore requireCapitalizedConstructors
|
|
var origGetStats = pc.getStats.bind(pc);
|
|
pc.getStats = function(selector, successCallback, errorCallback) { // jshint ignore: line
|
|
var self = this;
|
|
var args = arguments;
|
|
|
|
// If selector is a function then we are in the old style stats so just
|
|
// pass back the original getStats format to avoid breaking old users.
|
|
if (arguments.length > 0 && typeof selector === 'function') {
|
|
return origGetStats(selector, successCallback);
|
|
}
|
|
|
|
var fixChromeStats_ = function(response) {
|
|
var standardReport = {};
|
|
var reports = response.result();
|
|
reports.forEach(function(report) {
|
|
var standardStats = {
|
|
id: report.id,
|
|
timestamp: report.timestamp,
|
|
type: report.type
|
|
};
|
|
report.names().forEach(function(name) {
|
|
standardStats[name] = report.stat(name);
|
|
});
|
|
standardReport[standardStats.id] = standardStats;
|
|
});
|
|
|
|
return standardReport;
|
|
};
|
|
|
|
if (arguments.length >= 2) {
|
|
var successCallbackWrapper_ = function(response) {
|
|
args[1](fixChromeStats_(response));
|
|
};
|
|
|
|
return origGetStats.apply(this, [successCallbackWrapper_, arguments[0]]);
|
|
}
|
|
|
|
// promise-support
|
|
return new Promise(function(resolve, reject) {
|
|
if (args.length === 1 && selector === null) {
|
|
origGetStats.apply(self, [
|
|
function(response) {
|
|
resolve.apply(null, [fixChromeStats_(response)]);
|
|
}, reject]);
|
|
} else {
|
|
origGetStats.apply(self, [resolve, reject]);
|
|
}
|
|
});
|
|
};
|
|
|
|
return pc;
|
|
};
|
|
window.RTCPeerConnection.prototype = webkitRTCPeerConnection.prototype;
|
|
|
|
// wrap static methods. Currently just generateCertificate.
|
|
if (webkitRTCPeerConnection.generateCertificate) {
|
|
Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {
|
|
get: function() {
|
|
if (arguments.length) {
|
|
return webkitRTCPeerConnection.generateCertificate.apply(null,
|
|
arguments);
|
|
} else {
|
|
return webkitRTCPeerConnection.generateCertificate;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// add promise support
|
|
['createOffer', 'createAnswer'].forEach(function(method) {
|
|
var nativeMethod = webkitRTCPeerConnection.prototype[method];
|
|
webkitRTCPeerConnection.prototype[method] = function() {
|
|
var self = this;
|
|
if (arguments.length < 1 || (arguments.length === 1 &&
|
|
typeof(arguments[0]) === 'object')) {
|
|
var opts = arguments.length === 1 ? arguments[0] : undefined;
|
|
return new Promise(function(resolve, reject) {
|
|
nativeMethod.apply(self, [resolve, reject, opts]);
|
|
});
|
|
} else {
|
|
return nativeMethod.apply(this, arguments);
|
|
}
|
|
};
|
|
});
|
|
|
|
['setLocalDescription', 'setRemoteDescription',
|
|
'addIceCandidate'].forEach(function(method) {
|
|
var nativeMethod = webkitRTCPeerConnection.prototype[method];
|
|
webkitRTCPeerConnection.prototype[method] = function() {
|
|
var args = arguments;
|
|
var self = this;
|
|
return new Promise(function(resolve, reject) {
|
|
nativeMethod.apply(self, [args[0],
|
|
function() {
|
|
resolve();
|
|
if (args.length >= 2) {
|
|
args[1].apply(null, []);
|
|
}
|
|
},
|
|
function(err) {
|
|
reject(err);
|
|
if (args.length >= 3) {
|
|
args[2].apply(null, [err]);
|
|
}
|
|
}]
|
|
);
|
|
});
|
|
};
|
|
});
|
|
},
|
|
|
|
// Attach a media stream to an element.
|
|
attachMediaStream: function(element, stream) {
|
|
logging('DEPRECATED, attachMediaStream will soon be removed.');
|
|
if (browserDetails.version >= 43) {
|
|
element.srcObject = stream;
|
|
} else if (typeof element.src !== 'undefined') {
|
|
element.src = URL.createObjectURL(stream);
|
|
} else {
|
|
logging('Error attaching stream to element.');
|
|
}
|
|
},
|
|
|
|
reattachMediaStream: function(to, from) {
|
|
logging('DEPRECATED, reattachMediaStream will soon be removed.');
|
|
if (browserDetails.version >= 43) {
|
|
to.srcObject = from.srcObject;
|
|
} else {
|
|
to.src = from.src;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Expose public methods.
|
|
module.e = {
|
|
shimOnTrack: chromeShim.shimOnTrack,
|
|
shimSourceObject: chromeShim.shimSourceObject,
|
|
shimPeerConnection: chromeShim.shimPeerConnection,
|
|
shimGetUserMedia: __webpack_require__(149),
|
|
attachMediaStream: chromeShim.attachMediaStream,
|
|
reattachMediaStream: chromeShim.reattachMediaStream
|
|
};
|
|
|
|
|
|
/***/ },
|
|
/* 149 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree.
|
|
*/
|
|
'use strict';
|
|
var logging = __webpack_require__(0).log;
|
|
|
|
// Expose public methods.
|
|
module.e = function() {
|
|
var constraintsToChrome_ = function(c) {
|
|
if (typeof c !== 'object' || c.mandatory || c.optional) {
|
|
return c;
|
|
}
|
|
var cc = {};
|
|
Object.keys(c).forEach(function(key) {
|
|
if (key === 'require' || key === 'advanced' || key === 'mediaSource') {
|
|
return;
|
|
}
|
|
var r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]};
|
|
if (r.exact !== undefined && typeof r.exact === 'number') {
|
|
r.min = r.max = r.exact;
|
|
}
|
|
var oldname_ = function(prefix, name) {
|
|
if (prefix) {
|
|
return prefix + name.charAt(0).toUpperCase() + name.slice(1);
|
|
}
|
|
return (name === 'deviceId') ? 'sourceId' : name;
|
|
};
|
|
if (r.ideal !== undefined) {
|
|
cc.optional = cc.optional || [];
|
|
var oc = {};
|
|
if (typeof r.ideal === 'number') {
|
|
oc[oldname_('min', key)] = r.ideal;
|
|
cc.optional.push(oc);
|
|
oc = {};
|
|
oc[oldname_('max', key)] = r.ideal;
|
|
cc.optional.push(oc);
|
|
} else {
|
|
oc[oldname_('', key)] = r.ideal;
|
|
cc.optional.push(oc);
|
|
}
|
|
}
|
|
if (r.exact !== undefined && typeof r.exact !== 'number') {
|
|
cc.mandatory = cc.mandatory || {};
|
|
cc.mandatory[oldname_('', key)] = r.exact;
|
|
} else {
|
|
['min', 'max'].forEach(function(mix) {
|
|
if (r[mix] !== undefined) {
|
|
cc.mandatory = cc.mandatory || {};
|
|
cc.mandatory[oldname_(mix, key)] = r[mix];
|
|
}
|
|
});
|
|
}
|
|
});
|
|
if (c.advanced) {
|
|
cc.optional = (cc.optional || []).concat(c.advanced);
|
|
}
|
|
return cc;
|
|
};
|
|
|
|
var getUserMedia_ = function(constraints, onSuccess, onError) {
|
|
if (constraints.audio) {
|
|
constraints.audio = constraintsToChrome_(constraints.audio);
|
|
}
|
|
if (constraints.video) {
|
|
constraints.video = constraintsToChrome_(constraints.video);
|
|
}
|
|
logging('chrome: ' + JSON.stringify(constraints));
|
|
return navigator.webkitGetUserMedia(constraints, onSuccess, onError);
|
|
};
|
|
navigator.getUserMedia = getUserMedia_;
|
|
|
|
// Returns the result of getUserMedia as a Promise.
|
|
var getUserMediaPromise_ = function(constraints) {
|
|
return new Promise(function(resolve, reject) {
|
|
navigator.getUserMedia(constraints, resolve, reject);
|
|
});
|
|
}
|
|
|
|
if (!navigator.mediaDevices) {
|
|
navigator.mediaDevices = {getUserMedia: getUserMediaPromise_,
|
|
enumerateDevices: function() {
|
|
return new Promise(function(resolve) {
|
|
var kinds = {audio: 'audioinput', video: 'videoinput'};
|
|
return MediaStreamTrack.getSources(function(devices) {
|
|
resolve(devices.map(function(device) {
|
|
return {label: device.label,
|
|
kind: kinds[device.kind],
|
|
deviceId: device.id,
|
|
groupId: ''};
|
|
}));
|
|
});
|
|
});
|
|
}};
|
|
}
|
|
|
|
// A shim for getUserMedia method on the mediaDevices object.
|
|
// TODO(KaptenJansson) remove once implemented in Chrome stable.
|
|
if (!navigator.mediaDevices.getUserMedia) {
|
|
navigator.mediaDevices.getUserMedia = function(constraints) {
|
|
return getUserMediaPromise_(constraints);
|
|
};
|
|
} else {
|
|
// Even though Chrome 45 has navigator.mediaDevices and a getUserMedia
|
|
// function which returns a Promise, it does not accept spec-style
|
|
// constraints.
|
|
var origGetUserMedia = navigator.mediaDevices.getUserMedia.
|
|
bind(navigator.mediaDevices);
|
|
navigator.mediaDevices.getUserMedia = function(c) {
|
|
if (c) {
|
|
logging('spec: ' + JSON.stringify(c)); // whitespace for alignment
|
|
c.audio = constraintsToChrome_(c.audio);
|
|
c.video = constraintsToChrome_(c.video);
|
|
logging('chrome: ' + JSON.stringify(c));
|
|
}
|
|
return origGetUserMedia(c);
|
|
}.bind(this);
|
|
}
|
|
|
|
// Dummy devicechange event methods.
|
|
// TODO(KaptenJansson) remove once implemented in Chrome stable.
|
|
if (typeof navigator.mediaDevices.addEventListener === 'undefined') {
|
|
navigator.mediaDevices.addEventListener = function() {
|
|
logging('Dummy mediaDevices.addEventListener called.');
|
|
};
|
|
}
|
|
if (typeof navigator.mediaDevices.removeEventListener === 'undefined') {
|
|
navigator.mediaDevices.removeEventListener = function() {
|
|
logging('Dummy mediaDevices.removeEventListener called.');
|
|
};
|
|
}
|
|
};
|
|
|
|
|
|
/***/ },
|
|
/* 150 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree.
|
|
*/
|
|
'use strict';
|
|
|
|
// SDP helpers.
|
|
var SDPUtils = {};
|
|
|
|
// Generate an alphanumeric identifier for cname or mids.
|
|
// TODO: use UUIDs instead? https://gist.github.com/jed/982883
|
|
SDPUtils.generateIdentifier = function() {
|
|
return Math.random().toString(36).substr(2, 10);
|
|
};
|
|
|
|
// The RTCP CNAME used by all peerconnections from the same JS.
|
|
SDPUtils.localCName = SDPUtils.generateIdentifier();
|
|
|
|
|
|
// Splits SDP into lines, dealing with both CRLF and LF.
|
|
SDPUtils.splitLines = function(blob) {
|
|
return blob.trim().split('\n').map(function(line) {
|
|
return line.trim();
|
|
});
|
|
};
|
|
// Splits SDP into sessionpart and mediasections. Ensures CRLF.
|
|
SDPUtils.splitSections = function(blob) {
|
|
var parts = blob.split('\r\nm=');
|
|
return parts.map(function(part, index) {
|
|
return (index > 0 ? 'm=' + part : part).trim() + '\r\n';
|
|
});
|
|
};
|
|
|
|
// Returns lines that start with a certain prefix.
|
|
SDPUtils.matchPrefix = function(blob, prefix) {
|
|
return SDPUtils.splitLines(blob).filter(function(line) {
|
|
return line.indexOf(prefix) === 0;
|
|
});
|
|
};
|
|
|
|
// Parses an ICE candidate line. Sample input:
|
|
// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8 rport 55996"
|
|
SDPUtils.parseCandidate = function(line) {
|
|
var parts;
|
|
// Parse both variants.
|
|
if (line.indexOf('a=candidate:') === 0) {
|
|
parts = line.substring(12).split(' ');
|
|
} else {
|
|
parts = line.substring(10).split(' ');
|
|
}
|
|
|
|
var candidate = {
|
|
foundation: parts[0],
|
|
component: parts[1],
|
|
protocol: parts[2].toLowerCase(),
|
|
priority: parseInt(parts[3], 10),
|
|
ip: parts[4],
|
|
port: parseInt(parts[5], 10),
|
|
// skip parts[6] == 'typ'
|
|
type: parts[7]
|
|
};
|
|
|
|
for (var i = 8; i < parts.length; i += 2) {
|
|
switch (parts[i]) {
|
|
case 'raddr':
|
|
candidate.relatedAddress = parts[i + 1];
|
|
break;
|
|
case 'rport':
|
|
candidate.relatedPort = parseInt(parts[i + 1], 10);
|
|
break;
|
|
case 'tcptype':
|
|
candidate.tcpType = parts[i + 1];
|
|
break;
|
|
default: // Unknown extensions are silently ignored.
|
|
break;
|
|
}
|
|
}
|
|
return candidate;
|
|
};
|
|
|
|
// Translates a candidate object into SDP candidate attribute.
|
|
SDPUtils.writeCandidate = function(candidate) {
|
|
var sdp = [];
|
|
sdp.push(candidate.foundation);
|
|
sdp.push(candidate.component);
|
|
sdp.push(candidate.protocol.toUpperCase());
|
|
sdp.push(candidate.priority);
|
|
sdp.push(candidate.ip);
|
|
sdp.push(candidate.port);
|
|
|
|
var type = candidate.type;
|
|
sdp.push('typ');
|
|
sdp.push(type);
|
|
if (type !== 'host' && candidate.relatedAddress &&
|
|
candidate.relatedPort) {
|
|
sdp.push('raddr');
|
|
sdp.push(candidate.relatedAddress); // was: relAddr
|
|
sdp.push('rport');
|
|
sdp.push(candidate.relatedPort); // was: relPort
|
|
}
|
|
if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
|
|
sdp.push('tcptype');
|
|
sdp.push(candidate.tcpType);
|
|
}
|
|
return 'candidate:' + sdp.join(' ');
|
|
};
|
|
|
|
// Parses an rtpmap line, returns RTCRtpCoddecParameters. Sample input:
|
|
// a=rtpmap:111 opus/48000/2
|
|
SDPUtils.parseRtpMap = function(line) {
|
|
var parts = line.substr(9).split(' ');
|
|
var parsed = {
|
|
payloadType: parseInt(parts.shift(), 10) // was: id
|
|
};
|
|
|
|
parts = parts[0].split('/');
|
|
|
|
parsed.name = parts[0];
|
|
parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
|
|
parsed.numChannels = parts.length === 3 ? parseInt(parts[2], 10) : 1; // was: channels
|
|
return parsed;
|
|
};
|
|
|
|
// Generate an a=rtpmap line from RTCRtpCodecCapability or RTCRtpCodecParameters.
|
|
SDPUtils.writeRtpMap = function(codec) {
|
|
var pt = codec.payloadType;
|
|
if (codec.preferredPayloadType !== undefined) {
|
|
pt = codec.preferredPayloadType;
|
|
}
|
|
return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +
|
|
(codec.numChannels !== 1 ? '/' + codec.numChannels : '') + '\r\n';
|
|
};
|
|
|
|
// Parses an ftmp line, returns dictionary. Sample input:
|
|
// a=fmtp:96 vbr=on;cng=on
|
|
// Also deals with vbr=on; cng=on
|
|
SDPUtils.parseFmtp = function(line) {
|
|
var parsed = {};
|
|
var kv;
|
|
var parts = line.substr(line.indexOf(' ') + 1).split(';');
|
|
for (var j = 0; j < parts.length; j++) {
|
|
kv = parts[j].trim().split('=');
|
|
parsed[kv[0].trim()] = kv[1];
|
|
}
|
|
return parsed;
|
|
};
|
|
|
|
// Generates an a=ftmp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
|
|
SDPUtils.writeFtmp = function(codec) {
|
|
var line = '';
|
|
var pt = codec.payloadType;
|
|
if (codec.preferredPayloadType !== undefined) {
|
|
pt = codec.preferredPayloadType;
|
|
}
|
|
if (codec.parameters && codec.parameters.length) {
|
|
var params = [];
|
|
Object.keys(codec.parameters).forEach(function(param) {
|
|
params.push(param + '=' + codec.parameters[param]);
|
|
});
|
|
line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
|
|
}
|
|
return line;
|
|
};
|
|
|
|
// Parses an rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
|
|
// a=rtcp-fb:98 nack rpsi
|
|
SDPUtils.parseRtcpFb = function(line) {
|
|
var parts = line.substr(line.indexOf(' ') + 1).split(' ');
|
|
return {
|
|
type: parts.shift(),
|
|
parameter: parts.join(' ')
|
|
};
|
|
};
|
|
// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
|
|
SDPUtils.writeRtcpFb = function(codec) {
|
|
var lines = '';
|
|
var pt = codec.payloadType;
|
|
if (codec.preferredPayloadType !== undefined) {
|
|
pt = codec.preferredPayloadType;
|
|
}
|
|
if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
|
|
// FIXME: special handling for trr-int?
|
|
codec.rtcpFeedback.forEach(function(fb) {
|
|
lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + ' ' + fb.parameter +
|
|
'\r\n';
|
|
});
|
|
}
|
|
return lines;
|
|
};
|
|
|
|
// Parses an RFC 5576 ssrc media attribute. Sample input:
|
|
// a=ssrc:3735928559 cname:something
|
|
SDPUtils.parseSsrcMedia = function(line) {
|
|
var sp = line.indexOf(' ');
|
|
var parts = {
|
|
ssrc: line.substr(7, sp - 7),
|
|
};
|
|
var colon = line.indexOf(':', sp);
|
|
if (colon > -1) {
|
|
parts.attribute = line.substr(sp + 1, colon - sp - 1);
|
|
parts.value = line.substr(colon + 1);
|
|
} else {
|
|
parts.attribute = line.substr(sp + 1);
|
|
}
|
|
return parts;
|
|
};
|
|
|
|
// Extracts DTLS parameters from SDP media section or sessionpart.
|
|
// FIXME: for consistency with other functions this should only
|
|
// get the fingerprint line as input. See also getIceParameters.
|
|
SDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {
|
|
var lines = SDPUtils.splitLines(mediaSection);
|
|
lines = lines.concat(SDPUtils.splitLines(sessionpart)); // Search in session part, too.
|
|
var fpLine = lines.filter(function(line) {
|
|
return line.indexOf('a=fingerprint:') === 0;
|
|
})[0].substr(14);
|
|
// Note: a=setup line is ignored since we use the 'auto' role.
|
|
var dtlsParameters = {
|
|
role: 'auto',
|
|
fingerprints: [{
|
|
algorithm: fpLine.split(' ')[0],
|
|
value: fpLine.split(' ')[1]
|
|
}]
|
|
};
|
|
return dtlsParameters;
|
|
};
|
|
|
|
// Serializes DTLS parameters to SDP.
|
|
SDPUtils.writeDtlsParameters = function(params, setupType) {
|
|
var sdp = 'a=setup:' + setupType + '\r\n';
|
|
params.fingerprints.forEach(function(fp) {
|
|
sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
|
|
});
|
|
return sdp;
|
|
};
|
|
// Parses ICE information from SDP media section or sessionpart.
|
|
// FIXME: for consistency with other functions this should only
|
|
// get the ice-ufrag and ice-pwd lines as input.
|
|
SDPUtils.getIceParameters = function(mediaSection, sessionpart) {
|
|
var lines = SDPUtils.splitLines(mediaSection);
|
|
lines = lines.concat(SDPUtils.splitLines(sessionpart)); // Search in session part, too.
|
|
var iceParameters = {
|
|
usernameFragment: lines.filter(function(line) {
|
|
return line.indexOf('a=ice-ufrag:') === 0;
|
|
})[0].substr(12),
|
|
password: lines.filter(function(line) {
|
|
return line.indexOf('a=ice-pwd:') === 0;
|
|
})[0].substr(10)
|
|
};
|
|
return iceParameters;
|
|
};
|
|
|
|
// Serializes ICE parameters to SDP.
|
|
SDPUtils.writeIceParameters = function(params) {
|
|
return 'a=ice-ufrag:' + params.usernameFragment + '\r\n' +
|
|
'a=ice-pwd:' + params.password + '\r\n';
|
|
};
|
|
|
|
// Parses the SDP media section and returns RTCRtpParameters.
|
|
SDPUtils.parseRtpParameters = function(mediaSection) {
|
|
var description = {
|
|
codecs: [],
|
|
headerExtensions: [],
|
|
fecMechanisms: [],
|
|
rtcp: []
|
|
};
|
|
var lines = SDPUtils.splitLines(mediaSection);
|
|
var mline = lines[0].split(' ');
|
|
for (var i = 3; i < mline.length; i++) { // find all codecs from mline[3..]
|
|
var pt = mline[i];
|
|
var rtpmapline = SDPUtils.matchPrefix(
|
|
mediaSection, 'a=rtpmap:' + pt + ' ')[0];
|
|
if (rtpmapline) {
|
|
var codec = SDPUtils.parseRtpMap(rtpmapline);
|
|
var fmtps = SDPUtils.matchPrefix(
|
|
mediaSection, 'a=fmtp:' + pt + ' ');
|
|
// Only the first a=fmtp:<pt> is considered.
|
|
codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
|
|
codec.rtcpFeedback = SDPUtils.matchPrefix(
|
|
mediaSection, 'a=rtcp-fb:' + pt + ' ')
|
|
.map(SDPUtils.parseRtcpFb);
|
|
description.codecs.push(codec);
|
|
}
|
|
}
|
|
// FIXME: parse headerExtensions, fecMechanisms and rtcp.
|
|
return description;
|
|
};
|
|
|
|
// Generates parts of the SDP media section describing the capabilities / parameters.
|
|
SDPUtils.writeRtpDescription = function(kind, caps) {
|
|
var sdp = '';
|
|
|
|
// Build the mline.
|
|
sdp += 'm=' + kind + ' ';
|
|
sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
|
|
sdp += ' UDP/TLS/RTP/SAVPF ';
|
|
sdp += caps.codecs.map(function(codec) {
|
|
if (codec.preferredPayloadType !== undefined) {
|
|
return codec.preferredPayloadType;
|
|
}
|
|
return codec.payloadType;
|
|
}).join(' ') + '\r\n';
|
|
|
|
sdp += 'c=IN IP4 0.0.0.0\r\n';
|
|
sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n';
|
|
|
|
// Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
|
|
caps.codecs.forEach(function(codec) {
|
|
sdp += SDPUtils.writeRtpMap(codec);
|
|
sdp += SDPUtils.writeFtmp(codec);
|
|
sdp += SDPUtils.writeRtcpFb(codec);
|
|
});
|
|
// FIXME: add headerExtensions, fecMechanismş and rtcp.
|
|
sdp += 'a=rtcp-mux\r\n';
|
|
return sdp;
|
|
};
|
|
|
|
SDPUtils.writeSessionBoilerplate = function() {
|
|
// FIXME: sess-id should be an NTP timestamp.
|
|
return 'v=0\r\n' +
|
|
'o=thisisadapterortc 8169639915646943137 2 IN IP4 127.0.0.1\r\n' +
|
|
's=-\r\n' +
|
|
't=0 0\r\n';
|
|
};
|
|
|
|
SDPUtils.writeMediaSection = function(transceiver, caps, type, stream) {
|
|
var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps);
|
|
|
|
// Map ICE parameters (ufrag, pwd) to SDP.
|
|
sdp += SDPUtils.writeIceParameters(
|
|
transceiver.iceGatherer.getLocalParameters());
|
|
|
|
// Map DTLS parameters to SDP.
|
|
sdp += SDPUtils.writeDtlsParameters(
|
|
transceiver.dtlsTransport.getLocalParameters(),
|
|
type === 'offer' ? 'actpass' : 'active');
|
|
|
|
sdp += 'a=mid:' + transceiver.mid + '\r\n';
|
|
|
|
if (transceiver.rtpSender && transceiver.rtpReceiver) {
|
|
sdp += 'a=sendrecv\r\n';
|
|
} else if (transceiver.rtpSender) {
|
|
sdp += 'a=sendonly\r\n';
|
|
} else if (transceiver.rtpReceiver) {
|
|
sdp += 'a=recvonly\r\n';
|
|
} else {
|
|
sdp += 'a=inactive\r\n';
|
|
}
|
|
|
|
// FIXME: for RTX there might be multiple SSRCs. Not implemented in Edge yet.
|
|
if (transceiver.rtpSender) {
|
|
var msid = 'msid:' + stream.id + ' ' +
|
|
transceiver.rtpSender.track.id + '\r\n';
|
|
sdp += 'a=' + msid;
|
|
sdp += 'a=ssrc:' + transceiver.sendSsrc + ' ' + msid;
|
|
}
|
|
// FIXME: this should be written by writeRtpDescription.
|
|
sdp += 'a=ssrc:' + transceiver.sendSsrc + ' cname:' +
|
|
SDPUtils.localCName + '\r\n';
|
|
return sdp;
|
|
};
|
|
|
|
// Gets the direction from the mediaSection or the sessionpart.
|
|
SDPUtils.getDirection = function(mediaSection, sessionpart) {
|
|
// Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
|
|
var lines = SDPUtils.splitLines(mediaSection);
|
|
for (var i = 0; i < lines.length; i++) {
|
|
switch (lines[i]) {
|
|
case 'a=sendrecv':
|
|
case 'a=sendonly':
|
|
case 'a=recvonly':
|
|
case 'a=inactive':
|
|
return lines[i].substr(2);
|
|
}
|
|
}
|
|
if (sessionpart) {
|
|
return SDPUtils.getDirection(sessionpart);
|
|
}
|
|
return 'sendrecv';
|
|
};
|
|
|
|
// Expose public methods.
|
|
module.e = SDPUtils;
|
|
|
|
|
|
/***/ },
|
|
/* 151 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree.
|
|
*/
|
|
'use strict';
|
|
|
|
var SDPUtils = __webpack_require__(150);
|
|
var logging = __webpack_require__(0).log;
|
|
var browserDetails = __webpack_require__(0).browserDetails;
|
|
|
|
var edgeShim = {
|
|
shimPeerConnection: function() {
|
|
if (window.RTCIceGatherer) {
|
|
// ORTC defines an RTCIceCandidate object but no constructor.
|
|
// Not implemented in Edge.
|
|
if (!window.RTCIceCandidate) {
|
|
window.RTCIceCandidate = function(args) {
|
|
return args;
|
|
};
|
|
}
|
|
// ORTC does not have a session description object but
|
|
// other browsers (i.e. Chrome) that will support both PC and ORTC
|
|
// in the future might have this defined already.
|
|
if (!window.RTCSessionDescription) {
|
|
window.RTCSessionDescription = function(args) {
|
|
return args;
|
|
};
|
|
}
|
|
}
|
|
|
|
window.RTCPeerConnection = function(config) {
|
|
var self = this;
|
|
|
|
var _eventTarget = document.createDocumentFragment();
|
|
['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(
|
|
function(method) {
|
|
self[method] = _eventTarget[method].bind(_eventTarget);
|
|
});
|
|
|
|
this.onicecandidate = null;
|
|
this.onaddstream = null;
|
|
this.ontrack = null;
|
|
this.onremovestream = null;
|
|
this.onsignalingstatechange = null;
|
|
this.oniceconnectionstatechange = null;
|
|
this.onnegotiationneeded = null;
|
|
this.ondatachannel = null;
|
|
|
|
this.localStreams = [];
|
|
this.remoteStreams = [];
|
|
this.getLocalStreams = function() { return self.localStreams; };
|
|
this.getRemoteStreams = function() { return self.remoteStreams; };
|
|
|
|
this.localDescription = new RTCSessionDescription({
|
|
type: '',
|
|
sdp: ''
|
|
});
|
|
this.remoteDescription = new RTCSessionDescription({
|
|
type: '',
|
|
sdp: ''
|
|
});
|
|
this.signalingState = 'stable';
|
|
this.iceConnectionState = 'new';
|
|
this.iceGatheringState = 'new';
|
|
|
|
this.iceOptions = {
|
|
gatherPolicy: 'all',
|
|
iceServers: []
|
|
};
|
|
if (config && config.iceTransportPolicy) {
|
|
switch (config.iceTransportPolicy) {
|
|
case 'all':
|
|
case 'relay':
|
|
this.iceOptions.gatherPolicy = config.iceTransportPolicy;
|
|
break;
|
|
case 'none':
|
|
// FIXME: remove once implementation and spec have added this.
|
|
throw new TypeError('iceTransportPolicy "none" not supported');
|
|
}
|
|
}
|
|
if (config && config.iceServers) {
|
|
// Edge does not like
|
|
// 1) stun:
|
|
// 2) turn: that does not have all of turn:host:port?transport=udp
|
|
this.iceOptions.iceServers = config.iceServers.filter(function(server) {
|
|
if (server && server.urls) {
|
|
server.urls = server.urls.filter(function(url) {
|
|
return url.indexOf('transport=udp') !== -1;
|
|
})[0];
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
}
|
|
|
|
// per-track iceGathers, iceTransports, dtlsTransports, rtpSenders, ...
|
|
// everything that is needed to describe a SDP m-line.
|
|
this.transceivers = [];
|
|
|
|
// since the iceGatherer is currently created in createOffer but we
|
|
// must not emit candidates until after setLocalDescription we buffer
|
|
// them in this array.
|
|
this._localIceCandidatesBuffer = [];
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype._emitBufferedCandidates = function() {
|
|
var self = this;
|
|
var sections = SDPUtils.splitSections(self.localDescription.sdp);
|
|
// FIXME: need to apply ice candidates in a way which is async but in-order
|
|
this._localIceCandidatesBuffer.forEach(function(event) {
|
|
var end = !event.candidate || Object.keys(event.candidate).length == 0;
|
|
if (end) {
|
|
for (var j = 1; j < sections.length; j++) {
|
|
sections[j] += 'a=end-of-candidates\r\n';
|
|
}
|
|
} else {
|
|
sections[event.candidate.sdpMLineIndex + 1] +=
|
|
'a=' + event.candidate.candidate + '\r\n';
|
|
}
|
|
self.dispatchEvent(event);
|
|
if (self.onicecandidate !== null) {
|
|
self.onicecandidate(event);
|
|
}
|
|
if (!event.candidate) {
|
|
self.iceGatheringState = 'complete';
|
|
}
|
|
});
|
|
this._localIceCandidatesBuffer = [];
|
|
this.localDescription.sdp = sections.join('');
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.addStream = function(stream) {
|
|
// Clone is necessary for local demos mostly, attaching directly
|
|
// to two different senders does not work (build 10547).
|
|
this.localStreams.push(stream.clone());
|
|
this._maybeFireNegotiationNeeded();
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.removeStream = function(stream) {
|
|
var idx = this.localStreams.indexOf(stream);
|
|
if (idx > -1) {
|
|
this.localStreams.splice(idx, 1);
|
|
this._maybeFireNegotiationNeeded();
|
|
}
|
|
};
|
|
|
|
// Determines the intersection of local and remote capabilities.
|
|
window.RTCPeerConnection.prototype._getCommonCapabilities =
|
|
function(localCapabilities, remoteCapabilities) {
|
|
var commonCapabilities = {
|
|
codecs: [],
|
|
headerExtensions: [],
|
|
fecMechanisms: []
|
|
};
|
|
localCapabilities.codecs.forEach(function(lCodec) {
|
|
for (var i = 0; i < remoteCapabilities.codecs.length; i++) {
|
|
var rCodec = remoteCapabilities.codecs[i];
|
|
if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() &&
|
|
lCodec.clockRate === rCodec.clockRate &&
|
|
lCodec.numChannels === rCodec.numChannels) {
|
|
// push rCodec so we reply with offerer payload type
|
|
commonCapabilities.codecs.push(rCodec);
|
|
|
|
// FIXME: also need to determine intersection between
|
|
// .rtcpFeedback and .parameters
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
localCapabilities.headerExtensions.forEach(function(lHeaderExtension) {
|
|
for (var i = 0; i < remoteCapabilities.headerExtensions.length; i++) {
|
|
var rHeaderExtension = remoteCapabilities.headerExtensions[i];
|
|
if (lHeaderExtension.uri === rHeaderExtension.uri) {
|
|
commonCapabilities.headerExtensions.push(rHeaderExtension);
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
// FIXME: fecMechanisms
|
|
return commonCapabilities;
|
|
};
|
|
|
|
// Create ICE gatherer, ICE transport and DTLS transport.
|
|
window.RTCPeerConnection.prototype._createIceAndDtlsTransports =
|
|
function(mid, sdpMLineIndex) {
|
|
var self = this;
|
|
var iceGatherer = new RTCIceGatherer(self.iceOptions);
|
|
var iceTransport = new RTCIceTransport(iceGatherer);
|
|
iceGatherer.onlocalcandidate = function(evt) {
|
|
var event = new Event('icecandidate');
|
|
event.candidate = {sdpMid: mid, sdpMLineIndex: sdpMLineIndex};
|
|
|
|
var cand = evt.candidate;
|
|
var end = !cand || Object.keys(cand).length === 0;
|
|
// Edge emits an empty object for RTCIceCandidateComplete‥
|
|
if (end) {
|
|
// polyfill since RTCIceGatherer.state is not implemented in Edge 10547 yet.
|
|
if (iceGatherer.state === undefined) {
|
|
iceGatherer.state = 'completed';
|
|
}
|
|
|
|
// Emit a candidate with type endOfCandidates to make the samples work.
|
|
// Edge requires addIceCandidate with this empty candidate to start checking.
|
|
// The real solution is to signal end-of-candidates to the other side when
|
|
// getting the null candidate but some apps (like the samples) don't do that.
|
|
event.candidate.candidate =
|
|
'candidate:1 1 udp 1 0.0.0.0 9 typ endOfCandidates';
|
|
} else {
|
|
// RTCIceCandidate doesn't have a component, needs to be added
|
|
cand.component = iceTransport.component === 'RTCP' ? 2 : 1;
|
|
event.candidate.candidate = SDPUtils.writeCandidate(cand);
|
|
}
|
|
|
|
var complete = self.transceivers.every(function(transceiver) {
|
|
return transceiver.iceGatherer &&
|
|
transceiver.iceGatherer.state === 'completed';
|
|
});
|
|
// update .localDescription with candidate and (potentially) end-of-candidates.
|
|
// To make this harder, the gatherer might emit candidates before localdescription
|
|
// is set. To make things worse, gather.getLocalCandidates still errors in
|
|
// Edge 10547 when no candidates have been gathered yet.
|
|
if (self.localDescription && self.localDescription.type !== '') {
|
|
var sections = SDPUtils.splitSections(self.localDescription.sdp);
|
|
sections[sdpMLineIndex + 1] += (!end ? 'a=' + event.candidate.candidate :
|
|
'a=end-of-candidates') + '\r\n';
|
|
self.localDescription.sdp = sections.join('');
|
|
}
|
|
|
|
// Emit candidate if localDescription is set.
|
|
// Also emits null candidate when all gatherers are complete.
|
|
switch(self.iceGatheringState) {
|
|
case 'new':
|
|
self._localIceCandidatesBuffer.push(event);
|
|
if (complete) {
|
|
self._localIceCandidatesBuffer.push(new Event('icecandidate'));
|
|
}
|
|
break;
|
|
case 'gathering':
|
|
self._emitBufferedCandidates();
|
|
self.dispatchEvent(event);
|
|
if (self.onicecandidate !== null) {
|
|
self.onicecandidate(event);
|
|
}
|
|
if (complete) {
|
|
self.dispatchEvent(new Event('icecandidate'));
|
|
if (self.onicecandidate !== null) {
|
|
self.onicecandidate(new Event('icecandidate'));
|
|
}
|
|
self.iceGatheringState = 'complete';
|
|
}
|
|
break;
|
|
case 'complete':
|
|
// should not happen... currently!
|
|
break;
|
|
}
|
|
};
|
|
iceTransport.onicestatechange = function() {
|
|
self._updateConnectionState();
|
|
};
|
|
|
|
var dtlsTransport = new RTCDtlsTransport(iceTransport);
|
|
dtlsTransport.ondtlsstatechange = function() {
|
|
self._updateConnectionState();
|
|
};
|
|
dtlsTransport.onerror = function() {
|
|
// onerror does not set state to failed by itself.
|
|
dtlsTransport.state = 'failed';
|
|
self._updateConnectionState();
|
|
};
|
|
|
|
return {
|
|
iceGatherer: iceGatherer,
|
|
iceTransport: iceTransport,
|
|
dtlsTransport: dtlsTransport
|
|
};
|
|
};
|
|
|
|
// Start the RTP Sender and Receiver for a transceiver.
|
|
window.RTCPeerConnection.prototype._transceive = function(transceiver,
|
|
send, recv) {
|
|
var params = this._getCommonCapabilities(transceiver.localCapabilities,
|
|
transceiver.remoteCapabilities);
|
|
if (send && transceiver.rtpSender) {
|
|
params.encodings = [{
|
|
ssrc: transceiver.sendSsrc
|
|
}];
|
|
params.rtcp = {
|
|
cname: SDPUtils.localCName,
|
|
ssrc: transceiver.recvSsrc
|
|
};
|
|
transceiver.rtpSender.send(params);
|
|
}
|
|
if (recv && transceiver.rtpReceiver) {
|
|
params.encodings = [{
|
|
ssrc: transceiver.recvSsrc
|
|
}];
|
|
params.rtcp = {
|
|
cname: transceiver.cname,
|
|
ssrc: transceiver.sendSsrc
|
|
};
|
|
transceiver.rtpReceiver.receive(params);
|
|
}
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.setLocalDescription =
|
|
function(description) {
|
|
var self = this;
|
|
if (description.type === 'offer') {
|
|
if (!this._pendingOffer) {
|
|
} else {
|
|
this.transceivers = this._pendingOffer;
|
|
delete this._pendingOffer;
|
|
}
|
|
} else if (description.type === 'answer') {
|
|
var sections = SDPUtils.splitSections(self.remoteDescription.sdp);
|
|
var sessionpart = sections.shift();
|
|
sections.forEach(function(mediaSection, sdpMLineIndex) {
|
|
var transceiver = self.transceivers[sdpMLineIndex];
|
|
var iceGatherer = transceiver.iceGatherer;
|
|
var iceTransport = transceiver.iceTransport;
|
|
var dtlsTransport = transceiver.dtlsTransport;
|
|
var localCapabilities = transceiver.localCapabilities;
|
|
var remoteCapabilities = transceiver.remoteCapabilities;
|
|
var rejected = mediaSection.split('\n', 1)[0]
|
|
.split(' ', 2)[1] === '0';
|
|
|
|
if (!rejected) {
|
|
var remoteIceParameters = SDPUtils.getIceParameters(mediaSection,
|
|
sessionpart);
|
|
iceTransport.start(iceGatherer, remoteIceParameters, 'controlled');
|
|
|
|
var remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection,
|
|
sessionpart);
|
|
dtlsTransport.start(remoteDtlsParameters);
|
|
|
|
// Calculate intersection of capabilities.
|
|
var params = self._getCommonCapabilities(localCapabilities,
|
|
remoteCapabilities);
|
|
|
|
// Start the RTCRtpSender. The RTCRtpReceiver for this transceiver
|
|
// has already been started in setRemoteDescription.
|
|
self._transceive(transceiver,
|
|
params.codecs.length > 0,
|
|
false);
|
|
}
|
|
});
|
|
}
|
|
|
|
this.localDescription = {
|
|
type: description.type,
|
|
sdp: description.sdp
|
|
};
|
|
switch (description.type) {
|
|
case 'offer':
|
|
this._updateSignalingState('have-local-offer');
|
|
break;
|
|
case 'answer':
|
|
this._updateSignalingState('stable');
|
|
break;
|
|
default:
|
|
throw new TypeError('unsupported type "' + description.type + '"');
|
|
}
|
|
|
|
// If a success callback was provided, emit ICE candidates after it has been
|
|
// executed. Otherwise, emit callback after the Promise is resolved.
|
|
var hasCallback = arguments.length > 1 &&
|
|
typeof arguments[1] === 'function';
|
|
if (hasCallback) {
|
|
var cb = arguments[1];
|
|
window.setTimeout(function() {
|
|
cb();
|
|
if (self.iceGatheringState === 'new') {
|
|
self.iceGatheringState = 'gathering';
|
|
}
|
|
self._emitBufferedCandidates();
|
|
}, 0);
|
|
}
|
|
var p = Promise.resolve();
|
|
p.then(function() {
|
|
if (!hasCallback) {
|
|
if (self.iceGatheringState === 'new') {
|
|
self.iceGatheringState = 'gathering';
|
|
}
|
|
// Usually candidates will be emitted earlier.
|
|
window.setTimeout(self._emitBufferedCandidates.bind(self), 500);
|
|
}
|
|
});
|
|
return p;
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.setRemoteDescription =
|
|
function(description) {
|
|
var self = this;
|
|
var stream = new MediaStream();
|
|
var receiverList = [];
|
|
var sections = SDPUtils.splitSections(description.sdp);
|
|
var sessionpart = sections.shift();
|
|
sections.forEach(function(mediaSection, sdpMLineIndex) {
|
|
var lines = SDPUtils.splitLines(mediaSection);
|
|
var mline = lines[0].substr(2).split(' ');
|
|
var kind = mline[0];
|
|
var rejected = mline[1] === '0';
|
|
var direction = SDPUtils.getDirection(mediaSection, sessionpart);
|
|
|
|
var transceiver;
|
|
var iceGatherer;
|
|
var iceTransport;
|
|
var dtlsTransport;
|
|
var rtpSender;
|
|
var rtpReceiver;
|
|
var sendSsrc;
|
|
var recvSsrc;
|
|
var localCapabilities;
|
|
|
|
var track;
|
|
// FIXME: ensure the mediaSection has rtcp-mux set.
|
|
var remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection);
|
|
var remoteIceParameters;
|
|
var remoteDtlsParameters;
|
|
if (!rejected) {
|
|
remoteIceParameters = SDPUtils.getIceParameters(mediaSection,
|
|
sessionpart);
|
|
remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection,
|
|
sessionpart);
|
|
}
|
|
var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0].substr(6);
|
|
|
|
var cname;
|
|
// Gets the first SSRC. Note that with RTX there might be multiple SSRCs.
|
|
var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')
|
|
.map(function(line) {
|
|
return SDPUtils.parseSsrcMedia(line);
|
|
})
|
|
.filter(function(obj) {
|
|
return obj.attribute === 'cname';
|
|
})[0];
|
|
if (remoteSsrc) {
|
|
recvSsrc = parseInt(remoteSsrc.ssrc, 10);
|
|
cname = remoteSsrc.value;
|
|
}
|
|
|
|
if (description.type === 'offer') {
|
|
var transports = self._createIceAndDtlsTransports(mid, sdpMLineIndex);
|
|
|
|
localCapabilities = RTCRtpReceiver.getCapabilities(kind);
|
|
sendSsrc = (2 * sdpMLineIndex + 2) * 1001;
|
|
|
|
rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, kind);
|
|
|
|
track = rtpReceiver.track;
|
|
receiverList.push([track, rtpReceiver]);
|
|
// FIXME: not correct when there are multiple streams but that is
|
|
// not currently supported in this shim.
|
|
stream.addTrack(track);
|
|
|
|
// FIXME: look at direction.
|
|
if (self.localStreams.length > 0 &&
|
|
self.localStreams[0].getTracks().length >= sdpMLineIndex) {
|
|
// FIXME: actually more complicated, needs to match types etc
|
|
var localtrack = self.localStreams[0].getTracks()[sdpMLineIndex];
|
|
rtpSender = new RTCRtpSender(localtrack, transports.dtlsTransport);
|
|
}
|
|
|
|
self.transceivers[sdpMLineIndex] = {
|
|
iceGatherer: transports.iceGatherer,
|
|
iceTransport: transports.iceTransport,
|
|
dtlsTransport: transports.dtlsTransport,
|
|
localCapabilities: localCapabilities,
|
|
remoteCapabilities: remoteCapabilities,
|
|
rtpSender: rtpSender,
|
|
rtpReceiver: rtpReceiver,
|
|
kind: kind,
|
|
mid: mid,
|
|
cname: cname,
|
|
sendSsrc: sendSsrc,
|
|
recvSsrc: recvSsrc
|
|
};
|
|
// Start the RTCRtpReceiver now. The RTPSender is started in setLocalDescription.
|
|
self._transceive(self.transceivers[sdpMLineIndex],
|
|
false,
|
|
direction === 'sendrecv' || direction === 'sendonly');
|
|
} else if (description.type === 'answer' && !rejected) {
|
|
transceiver = self.transceivers[sdpMLineIndex];
|
|
iceGatherer = transceiver.iceGatherer;
|
|
iceTransport = transceiver.iceTransport;
|
|
dtlsTransport = transceiver.dtlsTransport;
|
|
rtpSender = transceiver.rtpSender;
|
|
rtpReceiver = transceiver.rtpReceiver;
|
|
sendSsrc = transceiver.sendSsrc;
|
|
//recvSsrc = transceiver.recvSsrc;
|
|
localCapabilities = transceiver.localCapabilities;
|
|
|
|
self.transceivers[sdpMLineIndex].recvSsrc = recvSsrc;
|
|
self.transceivers[sdpMLineIndex].remoteCapabilities =
|
|
remoteCapabilities;
|
|
self.transceivers[sdpMLineIndex].cname = cname;
|
|
|
|
iceTransport.start(iceGatherer, remoteIceParameters, 'controlling');
|
|
dtlsTransport.start(remoteDtlsParameters);
|
|
|
|
self._transceive(transceiver,
|
|
direction === 'sendrecv' || direction === 'recvonly',
|
|
direction === 'sendrecv' || direction === 'sendonly');
|
|
|
|
if (rtpReceiver &&
|
|
(direction === 'sendrecv' || direction === 'sendonly')) {
|
|
track = rtpReceiver.track;
|
|
receiverList.push([track, rtpReceiver]);
|
|
stream.addTrack(track);
|
|
} else {
|
|
// FIXME: actually the receiver should be created later.
|
|
delete transceiver.rtpReceiver;
|
|
}
|
|
}
|
|
});
|
|
|
|
this.remoteDescription = {
|
|
type: description.type,
|
|
sdp: description.sdp
|
|
};
|
|
switch (description.type) {
|
|
case 'offer':
|
|
this._updateSignalingState('have-remote-offer');
|
|
break;
|
|
case 'answer':
|
|
this._updateSignalingState('stable');
|
|
break;
|
|
default:
|
|
throw new TypeError('unsupported type "' + description.type + '"');
|
|
}
|
|
if (stream.getTracks().length) {
|
|
self.remoteStreams.push(stream);
|
|
window.setTimeout(function() {
|
|
var event = new Event('addstream');
|
|
event.stream = stream;
|
|
self.dispatchEvent(event);
|
|
if (self.onaddstream !== null) {
|
|
window.setTimeout(function() {
|
|
self.onaddstream(event);
|
|
}, 0);
|
|
}
|
|
|
|
receiverList.forEach(function(item) {
|
|
var track = item[0];
|
|
var receiver = item[1];
|
|
var event = new Event('track');
|
|
event.track = track;
|
|
event.receiver = receiver;
|
|
event.streams = [stream];
|
|
self.dispatchEvent(event);
|
|
if (self.ontrack !== null) {
|
|
window.setTimeout(function() {
|
|
self.ontrack(event);
|
|
}, 0);
|
|
}
|
|
});
|
|
}, 0);
|
|
}
|
|
if (arguments.length > 1 && typeof arguments[1] === 'function') {
|
|
window.setTimeout(arguments[1], 0);
|
|
}
|
|
return Promise.resolve();
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.close = function() {
|
|
this.transceivers.forEach(function(transceiver) {
|
|
/* not yet
|
|
if (transceiver.iceGatherer) {
|
|
transceiver.iceGatherer.close();
|
|
}
|
|
*/
|
|
if (transceiver.iceTransport) {
|
|
transceiver.iceTransport.stop();
|
|
}
|
|
if (transceiver.dtlsTransport) {
|
|
transceiver.dtlsTransport.stop();
|
|
}
|
|
if (transceiver.rtpSender) {
|
|
transceiver.rtpSender.stop();
|
|
}
|
|
if (transceiver.rtpReceiver) {
|
|
transceiver.rtpReceiver.stop();
|
|
}
|
|
});
|
|
// FIXME: clean up tracks, local streams, remote streams, etc
|
|
this._updateSignalingState('closed');
|
|
};
|
|
|
|
// Update the signaling state.
|
|
window.RTCPeerConnection.prototype._updateSignalingState =
|
|
function(newState) {
|
|
this.signalingState = newState;
|
|
var event = new Event('signalingstatechange');
|
|
this.dispatchEvent(event);
|
|
if (this.onsignalingstatechange !== null) {
|
|
this.onsignalingstatechange(event);
|
|
}
|
|
};
|
|
|
|
// Determine whether to fire the negotiationneeded event.
|
|
window.RTCPeerConnection.prototype._maybeFireNegotiationNeeded =
|
|
function() {
|
|
// Fire away (for now).
|
|
var event = new Event('negotiationneeded');
|
|
this.dispatchEvent(event);
|
|
if (this.onnegotiationneeded !== null) {
|
|
this.onnegotiationneeded(event);
|
|
}
|
|
};
|
|
|
|
// Update the connection state.
|
|
window.RTCPeerConnection.prototype._updateConnectionState =
|
|
function() {
|
|
var self = this;
|
|
var newState;
|
|
var states = {
|
|
'new': 0,
|
|
closed: 0,
|
|
connecting: 0,
|
|
checking: 0,
|
|
connected: 0,
|
|
completed: 0,
|
|
failed: 0
|
|
};
|
|
this.transceivers.forEach(function(transceiver) {
|
|
states[transceiver.iceTransport.state]++;
|
|
states[transceiver.dtlsTransport.state]++;
|
|
});
|
|
// ICETransport.completed and connected are the same for this purpose.
|
|
states['connected'] += states['completed'];
|
|
|
|
newState = 'new';
|
|
if (states['failed'] > 0) {
|
|
newState = 'failed';
|
|
} else if (states['connecting'] > 0 || states['checking'] > 0) {
|
|
newState = 'connecting';
|
|
} else if (states['disconnected'] > 0) {
|
|
newState = 'disconnected';
|
|
} else if (states['new'] > 0) {
|
|
newState = 'new';
|
|
} else if (states['connecting'] > 0 || states['completed'] > 0) {
|
|
newState = 'connected';
|
|
}
|
|
|
|
if (newState !== self.iceConnectionState) {
|
|
self.iceConnectionState = newState;
|
|
var event = new Event('iceconnectionstatechange');
|
|
this.dispatchEvent(event);
|
|
if (this.oniceconnectionstatechange !== null) {
|
|
this.oniceconnectionstatechange(event);
|
|
}
|
|
}
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.createOffer = function() {
|
|
var self = this;
|
|
if (this._pendingOffer) {
|
|
throw new Error('createOffer called while there is a pending offer.');
|
|
}
|
|
var offerOptions;
|
|
if (arguments.length === 1 && typeof arguments[0] !== 'function') {
|
|
offerOptions = arguments[0];
|
|
} else if (arguments.length === 3) {
|
|
offerOptions = arguments[2];
|
|
}
|
|
|
|
var tracks = [];
|
|
var numAudioTracks = 0;
|
|
var numVideoTracks = 0;
|
|
// Default to sendrecv.
|
|
if (this.localStreams.length) {
|
|
numAudioTracks = this.localStreams[0].getAudioTracks().length;
|
|
numVideoTracks = this.localStreams[0].getVideoTracks().length;
|
|
}
|
|
// Determine number of audio and video tracks we need to send/recv.
|
|
if (offerOptions) {
|
|
// Reject Chrome legacy constraints.
|
|
if (offerOptions.mandatory || offerOptions.optional) {
|
|
throw new TypeError(
|
|
'Legacy mandatory/optional constraints not supported.');
|
|
}
|
|
if (offerOptions.offerToReceiveAudio !== undefined) {
|
|
numAudioTracks = offerOptions.offerToReceiveAudio;
|
|
}
|
|
if (offerOptions.offerToReceiveVideo !== undefined) {
|
|
numVideoTracks = offerOptions.offerToReceiveVideo;
|
|
}
|
|
}
|
|
if (this.localStreams.length) {
|
|
// Push local streams.
|
|
this.localStreams[0].getTracks().forEach(function(track) {
|
|
tracks.push({
|
|
kind: track.kind,
|
|
track: track,
|
|
wantReceive: track.kind === 'audio' ?
|
|
numAudioTracks > 0 : numVideoTracks > 0
|
|
});
|
|
if (track.kind === 'audio') {
|
|
numAudioTracks--;
|
|
} else if (track.kind === 'video') {
|
|
numVideoTracks--;
|
|
}
|
|
});
|
|
}
|
|
// Create M-lines for recvonly streams.
|
|
while (numAudioTracks > 0 || numVideoTracks > 0) {
|
|
if (numAudioTracks > 0) {
|
|
tracks.push({
|
|
kind: 'audio',
|
|
wantReceive: true
|
|
});
|
|
numAudioTracks--;
|
|
}
|
|
if (numVideoTracks > 0) {
|
|
tracks.push({
|
|
kind: 'video',
|
|
wantReceive: true
|
|
});
|
|
numVideoTracks--;
|
|
}
|
|
}
|
|
|
|
var sdp = SDPUtils.writeSessionBoilerplate();
|
|
var transceivers = [];
|
|
tracks.forEach(function(mline, sdpMLineIndex) {
|
|
// For each track, create an ice gatherer, ice transport, dtls transport,
|
|
// potentially rtpsender and rtpreceiver.
|
|
var track = mline.track;
|
|
var kind = mline.kind;
|
|
var mid = SDPUtils.generateIdentifier();
|
|
|
|
var transports = self._createIceAndDtlsTransports(mid, sdpMLineIndex);
|
|
|
|
var localCapabilities = RTCRtpSender.getCapabilities(kind);
|
|
var rtpSender;
|
|
var rtpReceiver;
|
|
|
|
// generate an ssrc now, to be used later in rtpSender.send
|
|
var sendSsrc = (2 * sdpMLineIndex + 1) * 1001;
|
|
if (track) {
|
|
rtpSender = new RTCRtpSender(track, transports.dtlsTransport);
|
|
}
|
|
|
|
if (mline.wantReceive) {
|
|
rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, kind);
|
|
}
|
|
|
|
transceivers[sdpMLineIndex] = {
|
|
iceGatherer: transports.iceGatherer,
|
|
iceTransport: transports.iceTransport,
|
|
dtlsTransport: transports.dtlsTransport,
|
|
localCapabilities: localCapabilities,
|
|
remoteCapabilities: null,
|
|
rtpSender: rtpSender,
|
|
rtpReceiver: rtpReceiver,
|
|
kind: kind,
|
|
mid: mid,
|
|
sendSsrc: sendSsrc,
|
|
recvSsrc: null
|
|
};
|
|
var transceiver = transceivers[sdpMLineIndex];
|
|
sdp += SDPUtils.writeMediaSection(transceiver,
|
|
transceiver.localCapabilities, 'offer', self.localStreams[0]);
|
|
});
|
|
|
|
this._pendingOffer = transceivers;
|
|
var desc = new RTCSessionDescription({
|
|
type: 'offer',
|
|
sdp: sdp
|
|
});
|
|
if (arguments.length && typeof arguments[0] === 'function') {
|
|
window.setTimeout(arguments[0], 0, desc);
|
|
}
|
|
return Promise.resolve(desc);
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.createAnswer = function() {
|
|
var self = this;
|
|
var answerOptions;
|
|
if (arguments.length === 1 && typeof arguments[0] !== 'function') {
|
|
answerOptions = arguments[0];
|
|
} else if (arguments.length === 3) {
|
|
answerOptions = arguments[2];
|
|
}
|
|
|
|
var sdp = SDPUtils.writeSessionBoilerplate();
|
|
this.transceivers.forEach(function(transceiver) {
|
|
// Calculate intersection of capabilities.
|
|
var commonCapabilities = self._getCommonCapabilities(
|
|
transceiver.localCapabilities,
|
|
transceiver.remoteCapabilities);
|
|
|
|
sdp += SDPUtils.writeMediaSection(transceiver, commonCapabilities,
|
|
'answer', self.localStreams[0]);
|
|
});
|
|
|
|
var desc = new RTCSessionDescription({
|
|
type: 'answer',
|
|
sdp: sdp
|
|
});
|
|
if (arguments.length && typeof arguments[0] === 'function') {
|
|
window.setTimeout(arguments[0], 0, desc);
|
|
}
|
|
return Promise.resolve(desc);
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.addIceCandidate = function(candidate) {
|
|
var mLineIndex = candidate.sdpMLineIndex;
|
|
if (candidate.sdpMid) {
|
|
for (var i = 0; i < this.transceivers.length; i++) {
|
|
if (this.transceivers[i].mid === candidate.sdpMid) {
|
|
mLineIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
var transceiver = this.transceivers[mLineIndex];
|
|
if (transceiver) {
|
|
var cand = Object.keys(candidate.candidate).length > 0 ?
|
|
SDPUtils.parseCandidate(candidate.candidate) : {};
|
|
// Ignore Chrome's invalid candidates since Edge does not like them.
|
|
if (cand.protocol === 'tcp' && cand.port === 0) {
|
|
return;
|
|
}
|
|
// Ignore RTCP candidates, we assume RTCP-MUX.
|
|
if (cand.component !== '1') {
|
|
return;
|
|
}
|
|
// A dirty hack to make samples work.
|
|
if (cand.type === 'endOfCandidates') {
|
|
cand = {};
|
|
}
|
|
transceiver.iceTransport.addRemoteCandidate(cand);
|
|
|
|
// update the remoteDescription.
|
|
var sections = SDPUtils.splitSections(this.remoteDescription.sdp);
|
|
sections[mLineIndex + 1] += (cand.type ? candidate.candidate.trim()
|
|
: 'a=end-of-candidates') + '\r\n';
|
|
this.remoteDescription.sdp = sections.join('');
|
|
}
|
|
if (arguments.length > 1 && typeof arguments[1] === 'function') {
|
|
window.setTimeout(arguments[1], 0);
|
|
}
|
|
return Promise.resolve();
|
|
};
|
|
|
|
window.RTCPeerConnection.prototype.getStats = function() {
|
|
var promises = [];
|
|
this.transceivers.forEach(function(transceiver) {
|
|
['rtpSender', 'rtpReceiver', 'iceGatherer', 'iceTransport',
|
|
'dtlsTransport'].forEach(function(method) {
|
|
if (transceiver[method]) {
|
|
promises.push(transceiver[method].getStats());
|
|
}
|
|
});
|
|
});
|
|
var cb = arguments.length > 1 && typeof arguments[1] === 'function' &&
|
|
arguments[1];
|
|
return new Promise(function(resolve) {
|
|
var results = {};
|
|
Promise.all(promises).then(function(res) {
|
|
res.forEach(function(result) {
|
|
Object.keys(result).forEach(function(id) {
|
|
results[id] = result[id];
|
|
});
|
|
});
|
|
if (cb) {
|
|
window.setTimeout(cb, 0, results);
|
|
}
|
|
resolve(results);
|
|
});
|
|
});
|
|
};
|
|
},
|
|
|
|
// Attach a media stream to an element.
|
|
attachMediaStream: function(element, stream) {
|
|
logging('DEPRECATED, attachMediaStream will soon be removed.');
|
|
element.srcObject = stream;
|
|
},
|
|
|
|
reattachMediaStream: function(to, from) {
|
|
logging('DEPRECATED, reattachMediaStream will soon be removed.');
|
|
to.srcObject = from.srcObject;
|
|
}
|
|
}
|
|
|
|
// Expose public methods.
|
|
module.e = {
|
|
shimPeerConnection: edgeShim.shimPeerConnection,
|
|
attachMediaStream: edgeShim.attachMediaStream,
|
|
reattachMediaStream: edgeShim.reattachMediaStream
|
|
}
|
|
|
|
|
|
|
|
/***/ },
|
|
/* 152 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree.
|
|
*/
|
|
'use strict';
|
|
|
|
var logging = __webpack_require__(0).log;
|
|
var browserDetails = __webpack_require__(0).browserDetails;
|
|
|
|
var firefoxShim = {
|
|
shimOnTrack: function() {
|
|
if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in
|
|
window.RTCPeerConnection.prototype)) {
|
|
Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {
|
|
get: function() { return this._ontrack; },
|
|
set: function(f) {
|
|
var self = this;
|
|
if (this._ontrack) {
|
|
this.removeEventListener('track', this._ontrack);
|
|
this.removeEventListener('addstream', this._ontrackpoly);
|
|
}
|
|
this.addEventListener('track', this._ontrack = f);
|
|
this.addEventListener('addstream', this._ontrackpoly = function(e) {
|
|
e.stream.getTracks().forEach(function(track) {
|
|
var event = new Event('track');
|
|
event.track = track;
|
|
event.receiver = {track: track};
|
|
event.streams = [e.stream];
|
|
this.dispatchEvent(event);
|
|
}.bind(this));
|
|
}.bind(this));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
shimSourceObject: function() {
|
|
// Firefox has supported mozSrcObject since FF22, unprefixed in 42.
|
|
if (typeof window === 'object') {
|
|
if (window.HTMLMediaElement &&
|
|
!('srcObject' in window.HTMLMediaElement.prototype)) {
|
|
// Shim the srcObject property, once, when HTMLMediaElement is found.
|
|
Object.defineProperty(window.HTMLMediaElement.prototype, 'srcObject', {
|
|
get: function() {
|
|
return this.mozSrcObject;
|
|
},
|
|
set: function(stream) {
|
|
this.mozSrcObject = stream;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
|
|
shimPeerConnection: function() {
|
|
// The RTCPeerConnection object.
|
|
if (!window.RTCPeerConnection) {
|
|
window.RTCPeerConnection = function(pcConfig, pcConstraints) {
|
|
if (browserDetails.version < 38) {
|
|
// .urls is not supported in FF < 38.
|
|
// create RTCIceServers with a single url.
|
|
if (pcConfig && pcConfig.iceServers) {
|
|
var newIceServers = [];
|
|
for (var i = 0; i < pcConfig.iceServers.length; i++) {
|
|
var server = pcConfig.iceServers[i];
|
|
if (server.hasOwnProperty('urls')) {
|
|
for (var j = 0; j < server.urls.length; j++) {
|
|
var newServer = {
|
|
url: server.urls[j]
|
|
};
|
|
if (server.urls[j].indexOf('turn') === 0) {
|
|
newServer.username = server.username;
|
|
newServer.credential = server.credential;
|
|
}
|
|
newIceServers.push(newServer);
|
|
}
|
|
} else {
|
|
newIceServers.push(pcConfig.iceServers[i]);
|
|
}
|
|
}
|
|
pcConfig.iceServers = newIceServers;
|
|
}
|
|
}
|
|
return new mozRTCPeerConnection(pcConfig, pcConstraints); // jscs:ignore requireCapitalizedConstructors
|
|
};
|
|
window.RTCPeerConnection.prototype = mozRTCPeerConnection.prototype;
|
|
|
|
// wrap static methods. Currently just generateCertificate.
|
|
if (mozRTCPeerConnection.generateCertificate) {
|
|
Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {
|
|
get: function() {
|
|
if (arguments.length) {
|
|
return mozRTCPeerConnection.generateCertificate.apply(null,
|
|
arguments);
|
|
} else {
|
|
return mozRTCPeerConnection.generateCertificate;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
window.RTCSessionDescription = mozRTCSessionDescription;
|
|
window.RTCIceCandidate = mozRTCIceCandidate;
|
|
}
|
|
},
|
|
|
|
shimGetUserMedia: function() {
|
|
// getUserMedia constraints shim.
|
|
var getUserMedia_ = function(constraints, onSuccess, onError) {
|
|
var constraintsToFF37_ = function(c) {
|
|
if (typeof c !== 'object' || c.require) {
|
|
return c;
|
|
}
|
|
var require = [];
|
|
Object.keys(c).forEach(function(key) {
|
|
if (key === 'require' || key === 'advanced' || key === 'mediaSource') {
|
|
return;
|
|
}
|
|
var r = c[key] = (typeof c[key] === 'object') ?
|
|
c[key] : {ideal: c[key]};
|
|
if (r.min !== undefined ||
|
|
r.max !== undefined || r.exact !== undefined) {
|
|
require.push(key);
|
|
}
|
|
if (r.exact !== undefined) {
|
|
if (typeof r.exact === 'number') {
|
|
r. min = r.max = r.exact;
|
|
} else {
|
|
c[key] = r.exact;
|
|
}
|
|
delete r.exact;
|
|
}
|
|
if (r.ideal !== undefined) {
|
|
c.advanced = c.advanced || [];
|
|
var oc = {};
|
|
if (typeof r.ideal === 'number') {
|
|
oc[key] = {min: r.ideal, max: r.ideal};
|
|
} else {
|
|
oc[key] = r.ideal;
|
|
}
|
|
c.advanced.push(oc);
|
|
delete r.ideal;
|
|
if (!Object.keys(r).length) {
|
|
delete c[key];
|
|
}
|
|
}
|
|
});
|
|
if (require.length) {
|
|
c.require = require;
|
|
}
|
|
return c;
|
|
};
|
|
if (browserDetails.version < 38) {
|
|
logging('spec: ' + JSON.stringify(constraints));
|
|
if (constraints.audio) {
|
|
constraints.audio = constraintsToFF37_(constraints.audio);
|
|
}
|
|
if (constraints.video) {
|
|
constraints.video = constraintsToFF37_(constraints.video);
|
|
}
|
|
logging('ff37: ' + JSON.stringify(constraints));
|
|
}
|
|
return navigator.mozGetUserMedia(constraints, onSuccess, onError);
|
|
};
|
|
|
|
navigator.getUserMedia = getUserMedia_;
|
|
|
|
// Returns the result of getUserMedia as a Promise.
|
|
var getUserMediaPromise_ = function(constraints) {
|
|
return new Promise(function(resolve, reject) {
|
|
navigator.getUserMedia(constraints, resolve, reject);
|
|
});
|
|
}
|
|
|
|
// Shim for mediaDevices on older versions.
|
|
if (!navigator.mediaDevices) {
|
|
navigator.mediaDevices = {getUserMedia: getUserMediaPromise_,
|
|
addEventListener: function() { },
|
|
removeEventListener: function() { }
|
|
};
|
|
}
|
|
navigator.mediaDevices.enumerateDevices =
|
|
navigator.mediaDevices.enumerateDevices || function() {
|
|
return new Promise(function(resolve) {
|
|
var infos = [
|
|
{kind: 'audioinput', deviceId: 'default', label: '', groupId: ''},
|
|
{kind: 'videoinput', deviceId: 'default', label: '', groupId: ''}
|
|
];
|
|
resolve(infos);
|
|
});
|
|
};
|
|
|
|
if (browserDetails.version < 41) {
|
|
// Work around http://bugzil.la/1169665
|
|
var orgEnumerateDevices =
|
|
navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices);
|
|
navigator.mediaDevices.enumerateDevices = function() {
|
|
return orgEnumerateDevices().then(undefined, function(e) {
|
|
if (e.name === 'NotFoundError') {
|
|
return [];
|
|
}
|
|
throw e;
|
|
});
|
|
};
|
|
}
|
|
},
|
|
|
|
// Attach a media stream to an element.
|
|
attachMediaStream: function(element, stream) {
|
|
logging('DEPRECATED, attachMediaStream will soon be removed.');
|
|
element.srcObject = stream;
|
|
},
|
|
|
|
reattachMediaStream: function(to, from) {
|
|
logging('DEPRECATED, reattachMediaStream will soon be removed.');
|
|
to.srcObject = from.srcObject;
|
|
}
|
|
}
|
|
|
|
// Expose public methods.
|
|
module.e = {
|
|
shimOnTrack: firefoxShim.shimOnTrack,
|
|
shimSourceObject: firefoxShim.shimSourceObject,
|
|
shimPeerConnection: firefoxShim.shimPeerConnection,
|
|
shimGetUserMedia: __webpack_require__(153),
|
|
attachMediaStream: firefoxShim.attachMediaStream,
|
|
reattachMediaStream: firefoxShim.reattachMediaStream
|
|
}
|
|
|
|
|
|
/***/ },
|
|
/* 153 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree.
|
|
*/
|
|
'use strict';
|
|
|
|
var logging = __webpack_require__(0).log;
|
|
var browserDetails = __webpack_require__(0).browserDetails;
|
|
|
|
// Expose public methods.
|
|
module.e = function() {
|
|
// getUserMedia constraints shim.
|
|
var getUserMedia_ = function(constraints, onSuccess, onError) {
|
|
var constraintsToFF37_ = function(c) {
|
|
if (typeof c !== 'object' || c.require) {
|
|
return c;
|
|
}
|
|
var require = [];
|
|
Object.keys(c).forEach(function(key) {
|
|
if (key === 'require' || key === 'advanced' || key === 'mediaSource') {
|
|
return;
|
|
}
|
|
var r = c[key] = (typeof c[key] === 'object') ?
|
|
c[key] : {ideal: c[key]};
|
|
if (r.min !== undefined ||
|
|
r.max !== undefined || r.exact !== undefined) {
|
|
require.push(key);
|
|
}
|
|
if (r.exact !== undefined) {
|
|
if (typeof r.exact === 'number') {
|
|
r. min = r.max = r.exact;
|
|
} else {
|
|
c[key] = r.exact;
|
|
}
|
|
delete r.exact;
|
|
}
|
|
if (r.ideal !== undefined) {
|
|
c.advanced = c.advanced || [];
|
|
var oc = {};
|
|
if (typeof r.ideal === 'number') {
|
|
oc[key] = {min: r.ideal, max: r.ideal};
|
|
} else {
|
|
oc[key] = r.ideal;
|
|
}
|
|
c.advanced.push(oc);
|
|
delete r.ideal;
|
|
if (!Object.keys(r).length) {
|
|
delete c[key];
|
|
}
|
|
}
|
|
});
|
|
if (require.length) {
|
|
c.require = require;
|
|
}
|
|
return c;
|
|
};
|
|
if (browserDetails.version < 38) {
|
|
logging('spec: ' + JSON.stringify(constraints));
|
|
if (constraints.audio) {
|
|
constraints.audio = constraintsToFF37_(constraints.audio);
|
|
}
|
|
if (constraints.video) {
|
|
constraints.video = constraintsToFF37_(constraints.video);
|
|
}
|
|
logging('ff37: ' + JSON.stringify(constraints));
|
|
}
|
|
return navigator.mozGetUserMedia(constraints, onSuccess, onError);
|
|
};
|
|
|
|
navigator.getUserMedia = getUserMedia_;
|
|
|
|
// Returns the result of getUserMedia as a Promise.
|
|
var getUserMediaPromise_ = function(constraints) {
|
|
return new Promise(function(resolve, reject) {
|
|
navigator.getUserMedia(constraints, resolve, reject);
|
|
});
|
|
}
|
|
|
|
// Shim for mediaDevices on older versions.
|
|
if (!navigator.mediaDevices) {
|
|
navigator.mediaDevices = {getUserMedia: getUserMediaPromise_,
|
|
addEventListener: function() { },
|
|
removeEventListener: function() { }
|
|
};
|
|
}
|
|
navigator.mediaDevices.enumerateDevices =
|
|
navigator.mediaDevices.enumerateDevices || function() {
|
|
return new Promise(function(resolve) {
|
|
var infos = [
|
|
{kind: 'audioinput', deviceId: 'default', label: '', groupId: ''},
|
|
{kind: 'videoinput', deviceId: 'default', label: '', groupId: ''}
|
|
];
|
|
resolve(infos);
|
|
});
|
|
};
|
|
|
|
if (browserDetails.version < 41) {
|
|
// Work around http://bugzil.la/1169665
|
|
var orgEnumerateDevices =
|
|
navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices);
|
|
navigator.mediaDevices.enumerateDevices = function() {
|
|
return orgEnumerateDevices().then(undefined, function(e) {
|
|
if (e.name === 'NotFoundError') {
|
|
return [];
|
|
}
|
|
throw e;
|
|
});
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/***/ },
|
|
/* 154 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
module.e = __webpack_require__(49);
|
|
|
|
|
|
/***/ }
|
|
/******/ ])
|
|
});
|
|
;
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9teU1vZHVsZURlZmluaXRpb24iLCJ3ZWJwYWNrOi8vL3dlYnBhY2svYm9vdHN0cmFwIGZkZmZjY2ZhN2JkNTkyNzZiOTcxIiwid2VicGFjazovLy8uL34vd2VicnRjLWFkYXB0ZXIvc3JjL2pzL3V0aWxzLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19yb290LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2lzT2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19NYXAuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaXNBcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcmVhZGVyL2JhcmNvZGVfcmVhZGVyLmpzIiwid2VicGFjazovLy8uL34vZ2wtdmVjMi9jbG9uZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pc09iamVjdExpa2UuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbW1vbi9hcnJheV9oZWxwZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbW1vbi9pbWFnZV9kZWJ1Zy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcmVhZGVyL2Vhbl9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2Fzc29jSW5kZXhPZi5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fZ2V0TmF0aXZlLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19pc0tleWFibGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX25hdGl2ZUNyZWF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9lcS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pc0Z1bmN0aW9uLmpzIiwid2VicGFjazovLy8uL3NyYy9jb21tb24vY3ZfdXRpbHMuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbW1vbi9pbWFnZV93cmFwcGVyLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19hcnJheVJlZHVjZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fY29weU9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9faXNIb3N0T2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19pc0luZGV4LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19pc1Byb3RvdHlwZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pc0FyZ3VtZW50cy5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pc0FycmF5TGlrZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pc0FycmF5TGlrZU9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pc0xlbmd0aC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9tZXJnZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvbG9jYXRvci90cmFjZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JlYWRlci9jb2RlXzM5X3JlYWRlci5qcyIsIndlYnBhY2s6Ly8vLi9+L2dsLXZlYzIvZG90LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19TdGFjay5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYXJyYXlFYWNoLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19hc3NpZ25NZXJnZVZhbHVlLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19hc3NpZ25WYWx1ZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYXNzb2NEZWxldGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2Fzc29jR2V0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19hc3NvY0hhcy5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYXNzb2NTZXQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2Nsb25lQXJyYXlCdWZmZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2NvcHlBcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9faGFzaEhhcy5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9faW5kZXhLZXlzLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2lzVHlwZWRBcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9rZXlzLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL2tleXNJbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9yZXN0LmpzIiwid2VicGFjazovLy8od2VicGFjaykvYnVpbGRpbi9tb2R1bGUuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3F1YWdnYS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYW5hbHl0aWNzL3Jlc3VsdF9jb2xsZWN0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbW1vbi9jbHVzdGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9jb21tb24vZXZlbnRzLmpzIiwid2VicGFjazovLy8uL3NyYy9jb21tb24vc3ViSW1hZ2UuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbW1vbi90eXBlZGVmcy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29uZmlnL2NvbmZpZy5kZXYuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbmZpZy9jb25maWcuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2RlY29kZXIvYmFyY29kZV9kZWNvZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9kZWNvZGVyL2JyZXNlbmhhbS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5wdXQvY2FtZXJhX2FjY2Vzcy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5wdXQvZnJhbWVfZ3JhYmJlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5wdXQvaW1hZ2VfbG9hZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9pbnB1dC9pbnB1dF9zdHJlYW0uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2xvY2F0b3IvYmFyY29kZV9sb2NhdG9yLmpzIiwid2VicGFjazovLy8uL3NyYy9sb2NhdG9yL3Jhc3Rlcml6ZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2xvY2F0b3Ivc2tlbGV0b25pemVyLmpzIiwid2VicGFjazovLy8uL3NyYy9yZWFkZXIvY29kYWJhcl9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JlYWRlci9jb2RlXzEyOF9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JlYWRlci9jb2RlXzM5X3Zpbl9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JlYWRlci9lYW5fOF9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JlYWRlci9pMm9mNV9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JlYWRlci91cGNfZV9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JlYWRlci91cGNfcmVhZGVyLmpzIiwid2VicGFjazovLy8uL34vZ2wtbWF0Mi9jb3B5LmpzIiwid2VicGFjazovLy8uL34vZ2wtbWF0Mi9jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9nbC1tYXQyL2ludmVydC5qcyIsIndlYnBhY2s6Ly8vLi9+L2dsLXZlYzIvc2NhbGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9nbC12ZWMyL3RyYW5zZm9ybU1hdDIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9nbC12ZWMzL2Nsb25lLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19IYXNoLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19NYXBDYWNoZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fUmVmbGVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fU2V0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19TeW1ib2wuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX1VpbnQ4QXJyYXkuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX1dlYWtNYXAuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2FkZE1hcEVudHJ5LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19hZGRTZXRFbnRyeS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYXBwbHkuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2FycmF5UHVzaC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZUFzc2lnbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZUNsb25lLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19iYXNlQ3JlYXRlLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19iYXNlRmxhdHRlbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZUZvci5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZUZvck93bi5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZUhhcy5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZUtleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2Jhc2VLZXlzSW4uanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2Jhc2VNZXJnZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZU1lcmdlRGVlcC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZVBpY2suanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2Jhc2VQcm9wZXJ0eS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fYmFzZVRpbWVzLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19jaGVja0dsb2JhbC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fY2xvbmVCdWZmZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2Nsb25lTWFwLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19jbG9uZVJlZ0V4cC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fY2xvbmVTZXQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2Nsb25lU3ltYm9sLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19jbG9uZVR5cGVkQXJyYXkuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2NvcHlPYmplY3RXaXRoLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19jb3B5U3ltYm9scy5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fY3JlYXRlQXNzaWduZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2NyZWF0ZUJhc2VGb3IuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2dldExlbmd0aC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fZ2V0U3ltYm9scy5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fZ2V0VGFnLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19oYXNoRGVsZXRlLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19oYXNoR2V0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19oYXNoU2V0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19pbml0Q2xvbmVBcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9faW5pdENsb25lQnlUYWcuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2luaXRDbG9uZU9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9faXNJdGVyYXRlZUNhbGwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX2l0ZXJhdG9yVG9BcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fbWFwQ2xlYXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX21hcERlbGV0ZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fbWFwR2V0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19tYXBIYXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX21hcFNldC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fbWFwVG9BcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fc2V0VG9BcnJheS5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fc3RhY2tDbGVhci5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fc3RhY2tEZWxldGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvX3N0YWNrR2V0LmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL19zdGFja0hhcy5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9fc3RhY2tTZXQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvY29uc3RhbnQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaXNCdWZmZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaXNOYXRpdmUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9sb2Rhc2gvaXNQbGFpbk9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9pc1N0cmluZy5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC9waWNrLmpzIiwid2VicGFjazovLy8uL34vbG9kYXNoL3RvSW50ZWdlci5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC90b051bWJlci5qcyIsIndlYnBhY2s6Ly8vLi9+L2xvZGFzaC90b1BsYWluT2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2FkYXB0ZXJfY29yZS5qcyIsIndlYnBhY2s6Ly8vLi9+L3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9jaHJvbWUvY2hyb21lX3NoaW0uanMiLCJ3ZWJwYWNrOi8vLy4vfi93ZWJydGMtYWRhcHRlci9zcmMvanMvY2hyb21lL2dldHVzZXJtZWRpYS5qcyIsIndlYnBhY2s6Ly8vLi9+L3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9lZGdlL2VkZ2Vfc2RwLmpzIiwid2VicGFjazovLy8uL34vd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2VkZ2UvZWRnZV9zaGltLmpzIiwid2VicGFjazovLy8uL34vd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2ZpcmVmb3gvZmlyZWZveF9zaGltLmpzIiwid2VicGFjazovLy8uL34vd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2ZpcmVmb3gvZ2V0dXNlcm1lZGlhLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELE87QUNSQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDdkJBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLEVBQUU7QUFDYixjQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsT0FBTztBQUNsQixjQUFhLE1BQU07QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ3REQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsT0FBTztBQUNsQixjQUFhLE1BQU07QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQzNDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsRUFBRTtBQUNiLGNBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQzFEQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVyxFQUFFO0FBQ2IsY0FBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFhLFNBQVM7QUFDdEIsV0FBVTtBQUNWO0FBQ0EsY0FBYSxTQUFTO0FBQ3RCLFdBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFDOzs7Ozs7O0FDMUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBeUIsc0JBQXNCLEVBQUU7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBLGNBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxpQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBLGNBQWE7QUFDYixZQUFXO0FBQ1g7QUFDQSxRQUFPO0FBQ1A7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFhO0FBQ2I7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFFQUFvRTtBQUNwRTtBQUNBLHlFQUF3RTtBQUN4RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWE7QUFDYjtBQUNBLFlBQVc7O0FBRVg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFpQjtBQUNqQixZQUFXO0FBQ1g7QUFDQTtBQUNBLFVBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVztBQUNYLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxNQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWU7QUFDZjtBQUNBLFVBQVM7QUFDVDtBQUNBLE1BQUs7QUFDTCxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ2xQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF1RDtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7O0FBRUE7QUFD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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUF5QixxQkFBcUI7QUFDOUM7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF1QixzQ0FBc0M7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPOztBQUVQO0FBQ0Esd0JBQXVCLGdEQUFnRDtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPOztBQUVQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTJCOztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYTtBQUNiO0FBQ0E7QUFDQSxjQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYTtBQUNiOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBaUI7QUFDakI7QUFDQSxZQUFXO0FBQ1gsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBLFFBQU87QUFDUDtBQUNBLFFBQU87QUFDUDtBQUNBLFFBQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVztBQUNYO0FBQ0E7QUFDQSxZQUFXO0FBQ1g7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtB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Q0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDdE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBdUI7QUFDdkIsWUFBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EsK0JBQThCO0FBQzlCLHFDQUFvQyxFQUFFO0FBQ3RDLHdDQUF1QztBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTLGdFQUFnRTtBQUN6RSxVQUFTO0FBQ1Q7QUFDQTtBQUNBLE1BQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0EiLCJmaWxlIjoicXVhZ2dhLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShmYWN0b3J5LnRvU3RyaW5nKCkpLmRlZmF1bHQ7XG5cdGVsc2UgaWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKVxuXHRcdGV4cG9ydHNbXCJRdWFnZ2FcIl0gPSBmYWN0b3J5KGZhY3RvcnkudG9TdHJpbmcoKSkuZGVmYXVsdDtcblx0ZWxzZVxuXHRcdHJvb3RbXCJRdWFnZ2FcIl0gPSBmYWN0b3J5KGZhY3RvcnkudG9TdHJpbmcoKSkuZGVmYXVsdDtcbn0pKHRoaXMsIGZ1bmN0aW9uKF9fZmFjdG9yeVNvdXJjZV9fKSB7XG5yZXR1cm4gXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogd2VicGFjay9teU1vZHVsZURlZmluaXRpb25cbiAqKi8iLCIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZTtcblxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0ZToge30sXG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2VcbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZSwgbW9kdWxlLCBtb2R1bGUuZSwgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5lO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiL1wiO1xuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDE1NCk7XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiB3ZWJwYWNrL2Jvb3RzdHJhcCBmZGZmY2NmYTdiZDU5Mjc2Yjk3MVxuICoqLyIsIi8qXG4gKiAgQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBXZWJSVEMgcHJvamVjdCBhdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgc291cmNlXG4gKiAgdHJlZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nRGlzYWJsZWRfID0gZmFsc2U7XG5cbi8vIFV0aWxpdHkgbWV0aG9kcy5cbnZhciB1dGlscyA9IHtcbiAgZGlzYWJsZUxvZzogZnVuY3Rpb24oYm9vbCkge1xuICAgIGlmICh0eXBlb2YgYm9vbCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKCdBcmd1bWVudCB0eXBlOiAnICsgdHlwZW9mIGJvb2wgK1xuICAgICAgICAgICcuIFBsZWFzZSB1c2UgYSBib29sZWFuLicpO1xuICAgIH1cbiAgICBsb2dEaXNhYmxlZF8gPSBib29sO1xuICAgIHJldHVybiAoYm9vbCkgPyAnYWRhcHRlci5qcyBsb2dnaW5nIGRpc2FibGVkJyA6XG4gICAgICAgICdhZGFwdGVyLmpzIGxvZ2dpbmcgZW5hYmxlZCc7XG4gIH0sXG5cbiAgbG9nOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChsb2dEaXNhYmxlZF8pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc29sZS5sb2cuYXBwbHkoY29uc29sZSwgYXJndW1lbnRzKTtcbiAgICB9XG4gIH0sXG5cbiAgIC8qKlxuICAgKiBFeHRyYWN0IGJyb3dzZXIgdmVyc2lvbiBvdXQgb2YgdGhlIHByb3ZpZGVkIHVzZXIgYWdlbnQgc3RyaW5nLlxuICAgKiBAcGFyYW0geyFzdHJpbmd9IHVhc3RyaW5nIHVzZXJBZ2VudCBzdHJpbmcuXG4gICAqIEBwYXJhbSB7IXN0cmluZ30gZXhwciBSZWd1bGFyIGV4cHJlc3Npb24gdXNlZCBhcyBtYXRjaCBjcml0ZXJpYS5cbiAgICogQHBhcmFtIHshbnVtYmVyfSBwb3MgcG9zaXRpb24gaW4gdGhlIHZlcnNpb24gc3RyaW5nIHRvIGJlIHJldHVybmVkLlxuICAgKiBAcmV0dXJuIHshbnVtYmVyfSBicm93c2VyIHZlcnNpb24uXG4gICAqL1xuICBleHRyYWN0VmVyc2lvbjogZnVuY3Rpb24odWFzdHJpbmcsIGV4cHIsIHBvcykge1xuICAgIHZhciBtYXRjaCA9IHVhc3RyaW5nLm1hdGNoKGV4cHIpO1xuICAgIHJldHVybiBtYXRjaCAmJiBtYXRjaC5sZW5ndGggPj0gcG9zICYmIHBhcnNlSW50KG1hdGNoW3Bvc10sIDEwKTtcbiAgfSxcblxuICAvKipcbiAgICogQnJvd3NlciBkZXRlY3Rvci5cbiAgICogQHJldHVybiB7b2JqZWN0fSByZXN1bHQgY29udGFpbmluZyBicm93c2VyLCB2ZXJzaW9uIGFuZCBtaW5WZXJzaW9uXG4gICAqICAgICBwcm9wZXJ0aWVzLlxuICAgKi9cbiAgZGV0ZWN0QnJvd3NlcjogZnVuY3Rpb24oKSB7XG4gICAgLy8gUmV0dXJuZWQgcmVzdWx0IG9iamVjdC5cbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgcmVzdWx0LmJyb3dzZXIgPSBudWxsO1xuICAgIHJlc3VsdC52ZXJzaW9uID0gbnVsbDtcbiAgICByZXN1bHQubWluVmVyc2lvbiA9IG51bGw7XG5cbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgfHwgIXdpbmRvdy5uYXZpZ2F0b3IpIHtcbiAgICAgIHJlc3VsdC5icm93c2VyID0gJ05vdCBhIGJyb3dzZXIuJztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAvLyBGaXJlZm94LlxuICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnZmlyZWZveCc7XG4gICAgICByZXN1bHQudmVyc2lvbiA9IHRoaXMuZXh0cmFjdFZlcnNpb24obmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgICAgICAgICAvRmlyZWZveFxcLyhbMC05XSspXFwuLywgMSk7XG4gICAgICByZXN1bHQubWluVmVyc2lvbiA9IDMxO1xuICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLndlYmtpdEdldFVzZXJNZWRpYSAmJiB3aW5kb3cud2Via2l0UlRDUGVlckNvbm5lY3Rpb24pIHtcbiAgICAgIC8vIENocm9tZSwgQ2hyb21pdW0sIFdlYlZpZXcsIE9wZXJhIGFuZCBvdGhlciBXZWJLaXQgYnJvd3NlcnMuXG4gICAgICByZXN1bHQuYnJvd3NlciA9ICdjaHJvbWUnO1xuICAgICAgcmVzdWx0LnZlcnNpb24gPSB0aGlzLmV4dHJhY3RWZXJzaW9uKG5hdmlnYXRvci51c2VyQWdlbnQsXG4gICAgICAgICAgL0Nocm9tKGV8aXVtKVxcLyhbMC05XSspXFwuLywgMik7XG4gICAgICByZXN1bHQubWluVmVyc2lvbiA9IDM4O1xuICAgIH0gZWxzZSBpZihuYXZpZ2F0b3IubWVkaWFEZXZpY2VzICYmXG4gICAgICAgIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0VkZ2VcXC8oXFxkKykuKFxcZCspJC8pKSB7XG4gICAgICAvLyBFZGdlLlxuICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnZWRnZSc7XG4gICAgICByZXN1bHQudmVyc2lvbiA9IHRoaXMuZXh0cmFjdFZlcnNpb24obmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgICAgICAgICAvRWRnZVxcLyhcXGQrKS4oXFxkKykkLywgMik7XG4gICAgICByZXN1bHQubWluVmVyc2lvbiA9IDEwNTQ3O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQuYnJvd3NlciA9ICdOb3QgYSBzdXBwb3J0ZWQgYnJvd3Nlci4nO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyBXYXJuIGlmIHZlcnNpb24gaXMgbGVzcyB0aGFuIG1pblZlcnNpb24uXG4gICAgaWYgKHJlc3VsdC52ZXJzaW9uIDwgcmVzdWx0Lm1pblZlcnNpb24pIHtcbiAgICAgIHV0aWxzLmxvZygnQnJvd3NlcjogJyArIHJlc3VsdC5icm93c2VyICsgJyBWZXJzaW9uOiAnICsgcmVzdWx0LnZlcnNpb24gK1xuICAgICAgICAgICcgPCBtaW5pbXVtIHN1cHBvcnRlZCB2ZXJzaW9uOiAnICsgcmVzdWx0Lm1pblZlcnNpb24gK1xuICAgICAgICAgICdcXG4gc29tZSB0aGluZ3MgbWlnaHQgbm90IHdvcmshJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufTtcblxuLy8gRXhwb3J0LlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGxvZzogdXRpbHMubG9nLFxuICBkaXNhYmxlTG9nOiB1dGlscy5kaXNhYmxlTG9nLFxuICBicm93c2VyRGV0YWlsczogdXRpbHMuZGV0ZWN0QnJvd3NlcigpLFxuICBleHRyYWN0VmVyc2lvbjogdXRpbHMuZXh0cmFjdFZlcnNpb25cbn07XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi93ZWJydGMtYWRhcHRlci9zcmMvanMvdXRpbHMuanNcbiAqKiBtb2R1bGUgaWQgPSAwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgY2hlY2tHbG9iYWwgPSByZXF1aXJlKCcuL19jaGVja0dsb2JhbCcpO1xuXG4vKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbnZhciBvYmplY3RUeXBlcyA9IHtcbiAgJ2Z1bmN0aW9uJzogdHJ1ZSxcbiAgJ29iamVjdCc6IHRydWVcbn07XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG52YXIgZnJlZUV4cG9ydHMgPSAob2JqZWN0VHlwZXNbdHlwZW9mIGV4cG9ydHNdICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUpXG4gID8gZXhwb3J0c1xuICA6IHVuZGVmaW5lZDtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqL1xudmFyIGZyZWVNb2R1bGUgPSAob2JqZWN0VHlwZXNbdHlwZW9mIG1vZHVsZV0gJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUpXG4gID8gbW9kdWxlXG4gIDogdW5kZWZpbmVkO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAgZnJvbSBOb2RlLmpzLiAqL1xudmFyIGZyZWVHbG9iYWwgPSBjaGVja0dsb2JhbChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsKTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi9cbnZhciBmcmVlU2VsZiA9IGNoZWNrR2xvYmFsKG9iamVjdFR5cGVzW3R5cGVvZiBzZWxmXSAmJiBzZWxmKTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGB3aW5kb3dgLiAqL1xudmFyIGZyZWVXaW5kb3cgPSBjaGVja0dsb2JhbChvYmplY3RUeXBlc1t0eXBlb2Ygd2luZG93XSAmJiB3aW5kb3cpO1xuXG4vKiogRGV0ZWN0IGB0aGlzYCBhcyB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbnZhciB0aGlzR2xvYmFsID0gY2hlY2tHbG9iYWwob2JqZWN0VHlwZXNbdHlwZW9mIHRoaXNdICYmIHRoaXMpO1xuXG4vKipcbiAqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuXG4gKlxuICogVGhlIGB0aGlzYCB2YWx1ZSBpcyB1c2VkIGlmIGl0J3MgdGhlIGdsb2JhbCBvYmplY3QgdG8gYXZvaWQgR3JlYXNlbW9ua2V5J3NcbiAqIHJlc3RyaWN0ZWQgYHdpbmRvd2Agb2JqZWN0LCBvdGhlcndpc2UgdGhlIGB3aW5kb3dgIG9iamVjdCBpcyB1c2VkLlxuICovXG52YXIgcm9vdCA9IGZyZWVHbG9iYWwgfHxcbiAgKChmcmVlV2luZG93ICE9PSAodGhpc0dsb2JhbCAmJiB0aGlzR2xvYmFsLndpbmRvdykpICYmIGZyZWVXaW5kb3cpIHx8XG4gICAgZnJlZVNlbGYgfHwgdGhpc0dsb2JhbCB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJvb3Q7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX3Jvb3QuanNcbiAqKiBtb2R1bGUgaWQgPSAxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZSBbbGFuZ3VhZ2UgdHlwZV0oaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4OCkgb2YgYE9iamVjdGAuXG4gKiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2lzT2JqZWN0LmpzXG4gKiogbW9kdWxlIGlkID0gMlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBNYXAgPSBnZXROYXRpdmUocm9vdCwgJ01hcCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fTWFwLmpzXG4gKiogbW9kdWxlIGlkID0gM1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAdHlwZSB7RnVuY3Rpb259XG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXkoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNBcnJheSgnYWJjJyk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNBcnJheShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJyYXk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaXNBcnJheS5qc1xuICoqIG1vZHVsZSBpZCA9IDRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsImZ1bmN0aW9uIEJhcmNvZGVSZWFkZXIoY29uZmlnKSB7XHJcbiAgICB0aGlzLl9yb3cgPSBbXTtcclxuICAgIHRoaXMuY29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn1cclxuXHJcbkJhcmNvZGVSZWFkZXIucHJvdG90eXBlLl9uZXh0VW5zZXQgPSBmdW5jdGlvbihsaW5lLCBzdGFydCkge1xyXG4gICAgdmFyIGk7XHJcblxyXG4gICAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICBzdGFydCA9IDA7XHJcbiAgICB9XHJcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAoIWxpbmVbaV0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxpbmUubGVuZ3RoO1xyXG59O1xyXG5cclxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuX21hdGNoUGF0dGVybiA9IGZ1bmN0aW9uKGNvdW50ZXIsIGNvZGUpIHtcclxuICAgIHZhciBpLFxyXG4gICAgICAgIGVycm9yID0gMCxcclxuICAgICAgICBzaW5nbGVFcnJvciA9IDAsXHJcbiAgICAgICAgbW9kdWxvID0gdGhpcy5NT0RVTE8sXHJcbiAgICAgICAgbWF4U2luZ2xlRXJyb3IgPSB0aGlzLlNJTkdMRV9DT0RFX0VSUk9SIHx8IDE7XHJcblxyXG4gICAgZm9yIChpID0gMDsgaSA8IGNvdW50ZXIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBzaW5nbGVFcnJvciA9IE1hdGguYWJzKGNvZGVbaV0gLSBjb3VudGVyW2ldKTtcclxuICAgICAgICBpZiAoc2luZ2xlRXJyb3IgPiBtYXhTaW5nbGVFcnJvcikge1xyXG4gICAgICAgICAgICByZXR1cm4gTnVtYmVyLk1BWF9WQUxVRTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZXJyb3IgKz0gc2luZ2xlRXJyb3I7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZXJyb3IgLyBtb2R1bG87XHJcbn07XHJcblxyXG5CYXJjb2RlUmVhZGVyLnByb3RvdHlwZS5fbmV4dFNldCA9IGZ1bmN0aW9uKGxpbmUsIG9mZnNldCkge1xyXG4gICAgdmFyIGk7XHJcblxyXG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XHJcbiAgICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGxpbmVbaV0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxpbmUubGVuZ3RoO1xyXG59O1xyXG5cclxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuX25vcm1hbGl6ZSA9IGZ1bmN0aW9uKGNvdW50ZXIsIGNvcnJlY3Rpb24pIHtcclxuICAgIHZhciBpLFxyXG4gICAgICAgIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIHN1bSA9IDAsXHJcbiAgICAgICAgcmF0aW8sXHJcbiAgICAgICAgbnVtT25lcyA9IDAsXHJcbiAgICAgICAgbm9ybWFsaXplZCA9IG5ldyBBcnJheShjb3VudGVyLmxlbmd0aCksXHJcbiAgICAgICAgbm9ybSA9IDAsXHJcbiAgICAgICAgbW9kdWxvID0gc2VsZi5NT0RVTE87XHJcblxyXG4gICAgaWYgKGNvcnJlY3Rpb24pIHtcclxuICAgICAgICBzZWxmLl9jb3JyZWN0KGNvdW50ZXIsIGNvcnJlY3Rpb24pO1xyXG4gICAgfVxyXG4gICAgZm9yIChpID0gMDsgaSA8IGNvdW50ZXIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBzdW0gKz0gY291bnRlcltpXTtcclxuICAgIH1cclxuICAgIHJhdGlvID0gc3VtIC8gKG1vZHVsbyAtIG51bU9uZXMpO1xyXG4gICAgZm9yIChpID0gMDsgaSA8IGNvdW50ZXIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBub3JtID0gY291bnRlcltpXSA9PT0gMSA/IGNvdW50ZXJbaV0gOiBjb3VudGVyW2ldIC8gcmF0aW87XHJcbiAgICAgICAgbm9ybWFsaXplZFtpXSA9IG5vcm07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbm9ybWFsaXplZDtcclxufTtcclxuXHJcbkJhcmNvZGVSZWFkZXIucHJvdG90eXBlLl9jb3JyZWN0QmFycyA9IGZ1bmN0aW9uKGNvdW50ZXIsIGNvcnJlY3Rpb24sIGluZGljZXMpIHtcclxuICAgIHZhciBsZW5ndGggPSBpbmRpY2VzLmxlbmd0aCxcclxuICAgICAgICB0bXAgPSAwO1xyXG4gICAgd2hpbGUobGVuZ3RoLS0pIHtcclxuICAgICAgICB0bXAgPSBjb3VudGVyW2luZGljZXNbbGVuZ3RoXV0gKiAoMSAtICgoMSAtIGNvcnJlY3Rpb24pIC8gMikpO1xyXG4gICAgICAgIGlmICh0bXAgPiAxKSB7XHJcbiAgICAgICAgICAgIGNvdW50ZXJbaW5kaWNlc1tsZW5ndGhdXSA9IHRtcDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbkJhcmNvZGVSZWFkZXIucHJvdG90eXBlLl9tYXRjaFRyYWNlID0gZnVuY3Rpb24oY21wQ291bnRlciwgZXBzaWxvbikge1xyXG4gICAgdmFyIGNvdW50ZXIgPSBbXSxcclxuICAgICAgICBpLFxyXG4gICAgICAgIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIG9mZnNldCA9IHNlbGYuX25leHRTZXQoc2VsZi5fcm93KSxcclxuICAgICAgICBpc1doaXRlID0gIXNlbGYuX3Jvd1tvZmZzZXRdLFxyXG4gICAgICAgIGNvdW50ZXJQb3MgPSAwLFxyXG4gICAgICAgIGJlc3RNYXRjaCA9IHtcclxuICAgICAgICAgICAgZXJyb3I6IE51bWJlci5NQVhfVkFMVUUsXHJcbiAgICAgICAgICAgIGNvZGU6IC0xLFxyXG4gICAgICAgICAgICBzdGFydDogMFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZXJyb3I7XHJcblxyXG4gICAgaWYgKGNtcENvdW50ZXIpIHtcclxuICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGNtcENvdW50ZXIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY291bnRlci5wdXNoKDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKCBpID0gb2Zmc2V0OyBpIDwgc2VsZi5fcm93Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChzZWxmLl9yb3dbaV0gXiBpc1doaXRlKSB7XHJcbiAgICAgICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdKys7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY291bnRlclBvcyA9PT0gY291bnRlci5sZW5ndGggLSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBzZWxmLl9tYXRjaFBhdHRlcm4oY291bnRlciwgY21wQ291bnRlcik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA8IGVwc2lsb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLnN0YXJ0ID0gaSAtIG9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVuZCA9IGk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5jb3VudGVyID0gY291bnRlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJlc3RNYXRjaDtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MrKztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvdW50ZXJbY291bnRlclBvc10gPSAxO1xyXG4gICAgICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBjb3VudGVyLnB1c2goMCk7XHJcbiAgICAgICAgZm9yICggaSA9IG9mZnNldDsgaSA8IHNlbGYuX3Jvdy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5fcm93W2ldIF4gaXNXaGl0ZSkge1xyXG4gICAgICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSsrO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY291bnRlclBvcysrO1xyXG4gICAgICAgICAgICAgICAgY291bnRlci5wdXNoKDApO1xyXG4gICAgICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSA9IDE7XHJcbiAgICAgICAgICAgICAgICBpc1doaXRlID0gIWlzV2hpdGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaWYgY21wQ291bnRlciB3YXMgbm90IGdpdmVuXHJcbiAgICBiZXN0TWF0Y2guc3RhcnQgPSBvZmZzZXQ7XHJcbiAgICBiZXN0TWF0Y2guZW5kID0gc2VsZi5fcm93Lmxlbmd0aCAtIDE7XHJcbiAgICBiZXN0TWF0Y2guY291bnRlciA9IGNvdW50ZXI7XHJcbiAgICByZXR1cm4gYmVzdE1hdGNoO1xyXG59O1xyXG5cclxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuZGVjb2RlUGF0dGVybiA9IGZ1bmN0aW9uKHBhdHRlcm4pIHtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICByZXN1bHQ7XHJcblxyXG4gICAgc2VsZi5fcm93ID0gcGF0dGVybjtcclxuICAgIHJlc3VsdCA9IHNlbGYuX2RlY29kZSgpO1xyXG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xyXG4gICAgICAgIHNlbGYuX3Jvdy5yZXZlcnNlKCk7XHJcbiAgICAgICAgcmVzdWx0ID0gc2VsZi5fZGVjb2RlKCk7XHJcbiAgICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgICByZXN1bHQuZGlyZWN0aW9uID0gQmFyY29kZVJlYWRlci5ESVJFQ1RJT04uUkVWRVJTRTtcclxuICAgICAgICAgICAgcmVzdWx0LnN0YXJ0ID0gc2VsZi5fcm93Lmxlbmd0aCAtIHJlc3VsdC5zdGFydDtcclxuICAgICAgICAgICAgcmVzdWx0LmVuZCA9IHNlbGYuX3Jvdy5sZW5ndGggLSByZXN1bHQuZW5kO1xyXG4gICAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmVzdWx0LmRpcmVjdGlvbiA9IEJhcmNvZGVSZWFkZXIuRElSRUNUSU9OLkZPUldBUkQ7XHJcbiAgICB9XHJcbiAgICBpZiAocmVzdWx0KSB7XHJcbiAgICAgICAgcmVzdWx0LmZvcm1hdCA9IHNlbGYuRk9STUFUO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcbkJhcmNvZGVSZWFkZXIucHJvdG90eXBlLl9tYXRjaFJhbmdlID0gZnVuY3Rpb24oc3RhcnQsIGVuZCwgdmFsdWUpIHtcclxuICAgIHZhciBpO1xyXG5cclxuICAgIHN0YXJ0ID0gc3RhcnQgPCAwID8gMCA6IHN0YXJ0O1xyXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xyXG4gICAgICAgIGlmICh0aGlzLl9yb3dbaV0gIT09IHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufTtcclxuXHJcbkJhcmNvZGVSZWFkZXIucHJvdG90eXBlLl9maWxsQ291bnRlcnMgPSBmdW5jdGlvbihvZmZzZXQsIGVuZCwgaXNXaGl0ZSkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGNvdW50ZXJQb3MgPSAwLFxyXG4gICAgICAgIGksXHJcbiAgICAgICAgY291bnRlcnMgPSBbXTtcclxuXHJcbiAgICBpc1doaXRlID0gKHR5cGVvZiBpc1doaXRlICE9PSAndW5kZWZpbmVkJykgPyBpc1doaXRlIDogdHJ1ZTtcclxuICAgIG9mZnNldCA9ICh0eXBlb2Ygb2Zmc2V0ICE9PSAndW5kZWZpbmVkJykgPyBvZmZzZXQgOiBzZWxmLl9uZXh0VW5zZXQoc2VsZi5fcm93KTtcclxuICAgIGVuZCA9IGVuZCB8fCBzZWxmLl9yb3cubGVuZ3RoO1xyXG5cclxuICAgIGNvdW50ZXJzW2NvdW50ZXJQb3NdID0gMDtcclxuICAgIGZvciAoaSA9IG9mZnNldDsgaSA8IGVuZDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKHNlbGYuX3Jvd1tpXSBeIGlzV2hpdGUpIHtcclxuICAgICAgICAgICAgY291bnRlcnNbY291bnRlclBvc10rKztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb3VudGVyUG9zKys7XHJcbiAgICAgICAgICAgIGNvdW50ZXJzW2NvdW50ZXJQb3NdID0gMTtcclxuICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjb3VudGVycztcclxufTtcclxuXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShCYXJjb2RlUmVhZGVyLnByb3RvdHlwZSwgXCJGT1JNQVRcIiwge1xyXG4gICAgdmFsdWU6ICd1bmtub3duJyxcclxuICAgIHdyaXRlYWJsZTogZmFsc2VcclxufSk7XHJcblxyXG5CYXJjb2RlUmVhZGVyLkRJUkVDVElPTiA9IHtcclxuICAgIEZPUldBUkQ6IDEsXHJcbiAgICBSRVZFUlNFOiAtMVxyXG59O1xyXG5cclxuQmFyY29kZVJlYWRlci5FeGNlcHRpb24gPSB7XHJcbiAgICBTdGFydE5vdEZvdW5kRXhjZXB0aW9uOiBcIlN0YXJ0LUluZm8gd2FzIG5vdCBmb3VuZCFcIixcclxuICAgIENvZGVOb3RGb3VuZEV4Y2VwdGlvbjogXCJDb2RlIGNvdWxkIG5vdCBiZSBmb3VuZCFcIixcclxuICAgIFBhdHRlcm5Ob3RGb3VuZEV4Y2VwdGlvbjogXCJQYXR0ZXJuIGNvdWxkIG5vdCBiZSBmb3VuZCFcIlxyXG59O1xyXG5cclxuQmFyY29kZVJlYWRlci5DT05GSUdfS0VZUyA9IHt9O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQmFyY29kZVJlYWRlcjtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvcmVhZGVyL2JhcmNvZGVfcmVhZGVyLmpzXG4gKiovIiwibW9kdWxlLmV4cG9ydHMgPSBjbG9uZVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgdmVjMiBpbml0aWFsaXplZCB3aXRoIHZhbHVlcyBmcm9tIGFuIGV4aXN0aW5nIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7dmVjMn0gYSB2ZWN0b3IgdG8gY2xvbmVcbiAqIEByZXR1cm5zIHt2ZWMyfSBhIG5ldyAyRCB2ZWN0b3JcbiAqL1xuZnVuY3Rpb24gY2xvbmUoYSkge1xuICAgIHZhciBvdXQgPSBuZXcgRmxvYXQzMkFycmF5KDIpXG4gICAgb3V0WzBdID0gYVswXVxuICAgIG91dFsxXSA9IGFbMV1cbiAgICByZXR1cm4gb3V0XG59XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZ2wtdmVjMi9jbG9uZS5qc1xuICoqIG1vZHVsZSBpZCA9IDZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdExpa2U7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaXNPYmplY3RMaWtlLmpzXG4gKiogbW9kdWxlIGlkID0gN1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgaW5pdDogZnVuY3Rpb24oYXJyLCB2YWwpIHtcclxuICAgICAgICB2YXIgbCA9IGFyci5sZW5ndGg7XHJcbiAgICAgICAgd2hpbGUgKGwtLSkge1xyXG4gICAgICAgICAgICBhcnJbbF0gPSB2YWw7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNodWZmbGVzIHRoZSBjb250ZW50IG9mIGFuIGFycmF5XHJcbiAgICAgKiBAcmV0dXJuIHtBcnJheX0gdGhlIGFycmF5IGl0c2VsZiBzaHVmZmxlZFxyXG4gICAgICovXHJcbiAgICBzaHVmZmxlOiBmdW5jdGlvbihhcnIpIHtcclxuICAgICAgICB2YXIgaSA9IGFyci5sZW5ndGggLSAxLCBqLCB4O1xyXG4gICAgICAgIGZvciAoaTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgaiA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGkpO1xyXG4gICAgICAgICAgICB4ID0gYXJyW2ldO1xyXG4gICAgICAgICAgICBhcnJbaV0gPSBhcnJbal07XHJcbiAgICAgICAgICAgIGFycltqXSA9IHg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhcnI7XHJcbiAgICB9LFxyXG5cclxuICAgIHRvUG9pbnRMaXN0OiBmdW5jdGlvbihhcnIpIHtcclxuICAgICAgICB2YXIgaSwgaiwgcm93ID0gW10sIHJvd3MgPSBbXTtcclxuICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICByb3cgPSBbXTtcclxuICAgICAgICAgICAgZm9yICggaiA9IDA7IGogPCBhcnJbaV0ubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgIHJvd1tqXSA9IGFycltpXVtqXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByb3dzW2ldID0gXCJbXCIgKyByb3cuam9pbihcIixcIikgKyBcIl1cIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFwiW1wiICsgcm93cy5qb2luKFwiLFxcclxcblwiKSArIFwiXVwiO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIHJldHVybnMgdGhlIGVsZW1lbnRzIHdoaWNoJ3Mgc2NvcmUgaXMgYmlnZ2VyIHRoYW4gdGhlIHRocmVzaG9sZFxyXG4gICAgICogQHJldHVybiB7QXJyYXl9IHRoZSByZWR1Y2VkIGFycmF5XHJcbiAgICAgKi9cclxuICAgIHRocmVzaG9sZDogZnVuY3Rpb24oYXJyLCB0aHJlc2hvbGQsIHNjb3JlRnVuYykge1xyXG4gICAgICAgIHZhciBpLCBxdWV1ZSA9IFtdO1xyXG4gICAgICAgIGZvciAoIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChzY29yZUZ1bmMuYXBwbHkoYXJyLCBbYXJyW2ldXSkgPj0gdGhyZXNob2xkKSB7XHJcbiAgICAgICAgICAgICAgICBxdWV1ZS5wdXNoKGFycltpXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHF1ZXVlO1xyXG4gICAgfSxcclxuXHJcbiAgICBtYXhJbmRleDogZnVuY3Rpb24oYXJyKSB7XHJcbiAgICAgICAgdmFyIGksIG1heCA9IDA7XHJcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGFycltpXSA+IGFyclttYXhdKSB7XHJcbiAgICAgICAgICAgICAgICBtYXggPSBpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBtYXg7XHJcbiAgICB9LFxyXG5cclxuICAgIG1heDogZnVuY3Rpb24oYXJyKSB7XHJcbiAgICAgICAgdmFyIGksIG1heCA9IDA7XHJcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGFycltpXSA+IG1heCkge1xyXG4gICAgICAgICAgICAgICAgbWF4ID0gYXJyW2ldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBtYXg7XHJcbiAgICB9LFxyXG5cclxuICAgIHN1bTogZnVuY3Rpb24oYXJyKSB7XHJcbiAgICAgICAgdmFyIGxlbmd0aCA9IGFyci5sZW5ndGgsXHJcbiAgICAgICAgICAgIHN1bSA9IDA7XHJcblxyXG4gICAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xyXG4gICAgICAgICAgICBzdW0gKz0gYXJyW2xlbmd0aF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzdW07XHJcbiAgICB9XHJcbn07XHJcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2NvbW1vbi9hcnJheV9oZWxwZXIuanNcbiAqKi8iLCJleHBvcnQgZGVmYXVsdCB7XHJcbiAgICBkcmF3UmVjdDogZnVuY3Rpb24ocG9zLCBzaXplLCBjdHgsIHN0eWxlKXtcclxuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBzdHlsZS5jb2xvcjtcclxuICAgICAgICBjdHguZmlsbFN0eWxlID0gc3R5bGUuY29sb3I7XHJcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IDE7XHJcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICAgIGN0eC5zdHJva2VSZWN0KHBvcy54LCBwb3MueSwgc2l6ZS54LCBzaXplLnkpO1xyXG4gICAgfSxcclxuICAgIGRyYXdQYXRoOiBmdW5jdGlvbihwYXRoLCBkZWYsIGN0eCwgc3R5bGUpIHtcclxuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBzdHlsZS5jb2xvcjtcclxuICAgICAgICBjdHguZmlsbFN0eWxlID0gc3R5bGUuY29sb3I7XHJcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IHN0eWxlLmxpbmVXaWR0aDtcclxuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgY3R4Lm1vdmVUbyhwYXRoWzBdW2RlZi54XSwgcGF0aFswXVtkZWYueV0pO1xyXG4gICAgICAgIGZvciAodmFyIGogPSAxOyBqIDwgcGF0aC5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICBjdHgubGluZVRvKHBhdGhbal1bZGVmLnhdLCBwYXRoW2pdW2RlZi55XSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgICBjdHguc3Ryb2tlKCk7XHJcbiAgICB9LFxyXG4gICAgZHJhd0ltYWdlOiBmdW5jdGlvbihpbWFnZURhdGEsIHNpemUsIGN0eCkge1xyXG4gICAgICAgIHZhciBjYW52YXNEYXRhID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCBzaXplLngsIHNpemUueSksXHJcbiAgICAgICAgICAgIGRhdGEgPSBjYW52YXNEYXRhLmRhdGEsXHJcbiAgICAgICAgICAgIGltYWdlRGF0YVBvcyA9IGltYWdlRGF0YS5sZW5ndGgsXHJcbiAgICAgICAgICAgIGNhbnZhc0RhdGFQb3MgPSBkYXRhLmxlbmd0aCxcclxuICAgICAgICAgICAgdmFsdWU7XHJcblxyXG4gICAgICAgIGlmIChjYW52YXNEYXRhUG9zIC8gaW1hZ2VEYXRhUG9zICE9PSA0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgd2hpbGUgKGltYWdlRGF0YVBvcy0tKXtcclxuICAgICAgICAgICAgdmFsdWUgPSBpbWFnZURhdGFbaW1hZ2VEYXRhUG9zXTtcclxuICAgICAgICAgICAgZGF0YVstLWNhbnZhc0RhdGFQb3NdID0gMjU1O1xyXG4gICAgICAgICAgICBkYXRhWy0tY2FudmFzRGF0YVBvc10gPSB2YWx1ZTtcclxuICAgICAgICAgICAgZGF0YVstLWNhbnZhc0RhdGFQb3NdID0gdmFsdWU7XHJcbiAgICAgICAgICAgIGRhdGFbLS1jYW52YXNEYXRhUG9zXSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjdHgucHV0SW1hZ2VEYXRhKGNhbnZhc0RhdGEsIDAsIDApO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG59O1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9jb21tb24vaW1hZ2VfZGVidWcuanNcbiAqKi8iLCJpbXBvcnQgQmFyY29kZVJlYWRlciBmcm9tICcuL2JhcmNvZGVfcmVhZGVyJztcclxuXHJcbmZ1bmN0aW9uIEVBTlJlYWRlcihvcHRzKSB7XHJcbiAgICBCYXJjb2RlUmVhZGVyLmNhbGwodGhpcywgb3B0cyk7XHJcbn1cclxuXHJcbnZhciBwcm9wZXJ0aWVzID0ge1xyXG4gICAgQ09ERV9MX1NUQVJUOiB7dmFsdWU6IDB9LFxyXG4gICAgTU9EVUxPOiB7dmFsdWU6IDd9LFxyXG4gICAgQ09ERV9HX1NUQVJUOiB7dmFsdWU6IDEwfSxcclxuICAgIFNUQVJUX1BBVFRFUk46IHt2YWx1ZTogWzEgLyAzICogNywgMSAvIDMgKiA3LCAxIC8gMyAqIDddfSxcclxuICAgIFNUT1BfUEFUVEVSTjoge3ZhbHVlOiBbMSAvIDMgKiA3LCAxIC8gMyAqIDcsIDEgLyAzICogN119LFxyXG4gICAgTUlERExFX1BBVFRFUk46IHt2YWx1ZTogWzEgLyA1ICogNywgMSAvIDUgKiA3LCAxIC8gNSAqIDcsIDEgLyA1ICogNywgMSAvIDUgKiA3XX0sXHJcbiAgICBDT0RFX1BBVFRFUk46IHt2YWx1ZTogW1xyXG4gICAgICAgIFszLCAyLCAxLCAxXSxcclxuICAgICAgICBbMiwgMiwgMiwgMV0sXHJcbiAgICAgICAgWzIsIDEsIDIsIDJdLFxyXG4gICAgICAgIFsxLCA0LCAxLCAxXSxcclxuICAgICAgICBbMSwgMSwgMywgMl0sXHJcbiAgICAgICAgWzEsIDIsIDMsIDFdLFxyXG4gICAgICAgIFsxLCAxLCAxLCA0XSxcclxuICAgICAgICBbMSwgMywgMSwgMl0sXHJcbiAgICAgICAgWzEsIDIsIDEsIDNdLFxyXG4gICAgICAgIFszLCAxLCAxLCAyXSxcclxuICAgICAgICBbMSwgMSwgMiwgM10sXHJcbiAgICAgICAgWzEsIDIsIDIsIDJdLFxyXG4gICAgICAgIFsyLCAyLCAxLCAyXSxcclxuICAgICAgICBbMSwgMSwgNCwgMV0sXHJcbiAgICAgICAgWzIsIDMsIDEsIDFdLFxyXG4gICAgICAgIFsxLCAzLCAyLCAxXSxcclxuICAgICAgICBbNCwgMSwgMSwgMV0sXHJcbiAgICAgICAgWzIsIDEsIDMsIDFdLFxyXG4gICAgICAgIFszLCAxLCAyLCAxXSxcclxuICAgICAgICBbMiwgMSwgMSwgM11cclxuICAgIF19LFxyXG4gICAgQ09ERV9GUkVRVUVOQ1k6IHt2YWx1ZTogWzAsIDExLCAxMywgMTQsIDE5LCAyNSwgMjgsIDIxLCAyMiwgMjZdfSxcclxuICAgIFNJTkdMRV9DT0RFX0VSUk9SOiB7dmFsdWU6IDAuNjd9LFxyXG4gICAgQVZHX0NPREVfRVJST1I6IHt2YWx1ZTogMC4yN30sXHJcbiAgICBGT1JNQVQ6IHt2YWx1ZTogXCJlYW5fMTNcIiwgd3JpdGVhYmxlOiBmYWxzZX1cclxufTtcclxuXHJcbkVBTlJlYWRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhcmNvZGVSZWFkZXIucHJvdG90eXBlLCBwcm9wZXJ0aWVzKTtcclxuRUFOUmVhZGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEVBTlJlYWRlcjtcclxuXHJcbkVBTlJlYWRlci5wcm90b3R5cGUuX2RlY29kZUNvZGUgPSBmdW5jdGlvbihzdGFydCwgY29kZXJhbmdlKSB7XHJcbiAgICB2YXIgY291bnRlciA9IFswLCAwLCAwLCAwXSxcclxuICAgICAgICBpLFxyXG4gICAgICAgIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIG9mZnNldCA9IHN0YXJ0LFxyXG4gICAgICAgIGlzV2hpdGUgPSAhc2VsZi5fcm93W29mZnNldF0sXHJcbiAgICAgICAgY291bnRlclBvcyA9IDAsXHJcbiAgICAgICAgYmVzdE1hdGNoID0ge1xyXG4gICAgICAgICAgICBlcnJvcjogTnVtYmVyLk1BWF9WQUxVRSxcclxuICAgICAgICAgICAgY29kZTogLTEsXHJcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcclxuICAgICAgICAgICAgZW5kOiBzdGFydFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY29kZSxcclxuICAgICAgICBlcnJvcixcclxuICAgICAgICBub3JtYWxpemVkO1xyXG5cclxuICAgIGlmICghY29kZXJhbmdlKSB7XHJcbiAgICAgICAgY29kZXJhbmdlID0gc2VsZi5DT0RFX1BBVFRFUk4ubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAoIGkgPSBvZmZzZXQ7IGkgPCBzZWxmLl9yb3cubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAoc2VsZi5fcm93W2ldIF4gaXNXaGl0ZSkge1xyXG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdKys7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKGNvdW50ZXJQb3MgPT09IGNvdW50ZXIubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZCA9IHNlbGYuX25vcm1hbGl6ZShjb3VudGVyKTtcclxuICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb2RlID0gMDsgY29kZSA8IGNvZGVyYW5nZTsgY29kZSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gc2VsZi5fbWF0Y2hQYXR0ZXJuKG5vcm1hbGl6ZWQsIHNlbGYuQ09ERV9QQVRURVJOW2NvZGVdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yIDwgYmVzdE1hdGNoLmVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guY29kZSA9IGNvZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guZXJyb3IgPSBlcnJvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guZW5kID0gaTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYmVzdE1hdGNoLmVycm9yID4gc2VsZi5BVkdfQ09ERV9FUlJPUikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJlc3RNYXRjaDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MrKztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcclxuICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuRUFOUmVhZGVyLnByb3RvdHlwZS5fZmluZFBhdHRlcm4gPSBmdW5jdGlvbihwYXR0ZXJuLCBvZmZzZXQsIGlzV2hpdGUsIHRyeUhhcmRlciwgZXBzaWxvbikge1xyXG4gICAgdmFyIGNvdW50ZXIgPSBbXSxcclxuICAgICAgICBzZWxmID0gdGhpcyxcclxuICAgICAgICBpLFxyXG4gICAgICAgIGNvdW50ZXJQb3MgPSAwLFxyXG4gICAgICAgIGJlc3RNYXRjaCA9IHtcclxuICAgICAgICAgICAgZXJyb3I6IE51bWJlci5NQVhfVkFMVUUsXHJcbiAgICAgICAgICAgIGNvZGU6IC0xLFxyXG4gICAgICAgICAgICBzdGFydDogMCxcclxuICAgICAgICAgICAgZW5kOiAwXHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvcixcclxuICAgICAgICBqLFxyXG4gICAgICAgIHN1bSxcclxuICAgICAgICBub3JtYWxpemVkO1xyXG5cclxuICAgIGlmICghb2Zmc2V0KSB7XHJcbiAgICAgICAgb2Zmc2V0ID0gc2VsZi5fbmV4dFNldChzZWxmLl9yb3cpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpc1doaXRlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICBpc1doaXRlID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRyeUhhcmRlciA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgdHJ5SGFyZGVyID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIGVwc2lsb24gPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGVwc2lsb24gPSBzZWxmLkFWR19DT0RFX0VSUk9SO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAoIGkgPSAwOyBpIDwgcGF0dGVybi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvdW50ZXJbaV0gPSAwO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAoIGkgPSBvZmZzZXQ7IGkgPCBzZWxmLl9yb3cubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAoc2VsZi5fcm93W2ldIF4gaXNXaGl0ZSkge1xyXG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdKys7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKGNvdW50ZXJQb3MgPT09IGNvdW50ZXIubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICAgICAgc3VtID0gMDtcclxuICAgICAgICAgICAgICAgIGZvciAoIGogPSAwOyBqIDwgY291bnRlci5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHN1bSArPSBjb3VudGVyW2pdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZCA9IHNlbGYuX25vcm1hbGl6ZShjb3VudGVyKTtcclxuICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBzZWxmLl9tYXRjaFBhdHRlcm4obm9ybWFsaXplZCwgcGF0dGVybik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA8IGVwc2lsb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVycm9yID0gZXJyb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5zdGFydCA9IGkgLSBzdW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5lbmQgPSBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmVzdE1hdGNoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICh0cnlIYXJkZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKCBqID0gMDsgaiA8IGNvdW50ZXIubGVuZ3RoIC0gMjsgaisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXJbal0gPSBjb3VudGVyW2ogKyAyXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcltjb3VudGVyLmxlbmd0aCAtIDJdID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBjb3VudGVyW2NvdW50ZXIubGVuZ3RoIC0gMV0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MtLTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zKys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSA9IDE7XHJcbiAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbkVBTlJlYWRlci5wcm90b3R5cGUuX2ZpbmRTdGFydCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGxlYWRpbmdXaGl0ZXNwYWNlU3RhcnQsXHJcbiAgICAgICAgb2Zmc2V0ID0gc2VsZi5fbmV4dFNldChzZWxmLl9yb3cpLFxyXG4gICAgICAgIHN0YXJ0SW5mbztcclxuXHJcbiAgICB3aGlsZSAoIXN0YXJ0SW5mbykge1xyXG4gICAgICAgIHN0YXJ0SW5mbyA9IHNlbGYuX2ZpbmRQYXR0ZXJuKHNlbGYuU1RBUlRfUEFUVEVSTiwgb2Zmc2V0KTtcclxuICAgICAgICBpZiAoIXN0YXJ0SW5mbykge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGVhZGluZ1doaXRlc3BhY2VTdGFydCA9IHN0YXJ0SW5mby5zdGFydCAtIChzdGFydEluZm8uZW5kIC0gc3RhcnRJbmZvLnN0YXJ0KTtcclxuICAgICAgICBpZiAobGVhZGluZ1doaXRlc3BhY2VTdGFydCA+PSAwKSB7XHJcbiAgICAgICAgICAgIGlmIChzZWxmLl9tYXRjaFJhbmdlKGxlYWRpbmdXaGl0ZXNwYWNlU3RhcnQsIHN0YXJ0SW5mby5zdGFydCwgMCkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzdGFydEluZm87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ID0gc3RhcnRJbmZvLmVuZDtcclxuICAgICAgICBzdGFydEluZm8gPSBudWxsO1xyXG4gICAgfVxyXG59O1xyXG5cclxuRUFOUmVhZGVyLnByb3RvdHlwZS5fdmVyaWZ5VHJhaWxpbmdXaGl0ZXNwYWNlID0gZnVuY3Rpb24oZW5kSW5mbykge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIHRyYWlsaW5nV2hpdGVzcGFjZUVuZDtcclxuXHJcbiAgICB0cmFpbGluZ1doaXRlc3BhY2VFbmQgPSBlbmRJbmZvLmVuZCArIChlbmRJbmZvLmVuZCAtIGVuZEluZm8uc3RhcnQpO1xyXG4gICAgaWYgKHRyYWlsaW5nV2hpdGVzcGFjZUVuZCA8IHNlbGYuX3Jvdy5sZW5ndGgpIHtcclxuICAgICAgICBpZiAoc2VsZi5fbWF0Y2hSYW5nZShlbmRJbmZvLmVuZCwgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kLCAwKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZW5kSW5mbztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbkVBTlJlYWRlci5wcm90b3R5cGUuX2ZpbmRFbmQgPSBmdW5jdGlvbihvZmZzZXQsIGlzV2hpdGUpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBlbmRJbmZvID0gc2VsZi5fZmluZFBhdHRlcm4oc2VsZi5TVE9QX1BBVFRFUk4sIG9mZnNldCwgaXNXaGl0ZSwgZmFsc2UpO1xyXG5cclxuICAgIHJldHVybiBlbmRJbmZvICE9PSBudWxsID8gc2VsZi5fdmVyaWZ5VHJhaWxpbmdXaGl0ZXNwYWNlKGVuZEluZm8pIDogbnVsbDtcclxufTtcclxuXHJcbkVBTlJlYWRlci5wcm90b3R5cGUuX2NhbGN1bGF0ZUZpcnN0RGlnaXQgPSBmdW5jdGlvbihjb2RlRnJlcXVlbmN5KSB7XHJcbiAgICB2YXIgaSxcclxuICAgICAgICBzZWxmID0gdGhpcztcclxuXHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IHNlbGYuQ09ERV9GUkVRVUVOQ1kubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAoY29kZUZyZXF1ZW5jeSA9PT0gc2VsZi5DT0RFX0ZSRVFVRU5DWVtpXSkge1xyXG4gICAgICAgICAgICByZXR1cm4gaTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbkVBTlJlYWRlci5wcm90b3R5cGUuX2RlY29kZVBheWxvYWQgPSBmdW5jdGlvbihjb2RlLCByZXN1bHQsIGRlY29kZWRDb2Rlcykge1xyXG4gICAgdmFyIGksXHJcbiAgICAgICAgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY29kZUZyZXF1ZW5jeSA9IDB4MCxcclxuICAgICAgICBmaXJzdERpZ2l0O1xyXG5cclxuICAgIGZvciAoIGkgPSAwOyBpIDwgNjsgaSsrKSB7XHJcbiAgICAgICAgY29kZSA9IHNlbGYuX2RlY29kZUNvZGUoY29kZS5lbmQpO1xyXG4gICAgICAgIGlmICghY29kZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNvZGUuY29kZSA+PSBzZWxmLkNPREVfR19TVEFSVCkge1xyXG4gICAgICAgICAgICBjb2RlLmNvZGUgPSBjb2RlLmNvZGUgLSBzZWxmLkNPREVfR19TVEFSVDtcclxuICAgICAgICAgICAgY29kZUZyZXF1ZW5jeSB8PSAxIDw8ICg1IC0gaSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29kZUZyZXF1ZW5jeSB8PSAwIDw8ICg1IC0gaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlc3VsdC5wdXNoKGNvZGUuY29kZSk7XHJcbiAgICAgICAgZGVjb2RlZENvZGVzLnB1c2goY29kZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZmlyc3REaWdpdCA9IHNlbGYuX2NhbGN1bGF0ZUZpcnN0RGlnaXQoY29kZUZyZXF1ZW5jeSk7XHJcbiAgICBpZiAoZmlyc3REaWdpdCA9PT0gbnVsbCkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgcmVzdWx0LnVuc2hpZnQoZmlyc3REaWdpdCk7XHJcblxyXG4gICAgY29kZSA9IHNlbGYuX2ZpbmRQYXR0ZXJuKHNlbGYuTUlERExFX1BBVFRFUk4sIGNvZGUuZW5kLCB0cnVlLCBmYWxzZSk7XHJcbiAgICBpZiAoY29kZSA9PT0gbnVsbCkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgZGVjb2RlZENvZGVzLnB1c2goY29kZSk7XHJcblxyXG4gICAgZm9yICggaSA9IDA7IGkgPCA2OyBpKyspIHtcclxuICAgICAgICBjb2RlID0gc2VsZi5fZGVjb2RlQ29kZShjb2RlLmVuZCwgc2VsZi5DT0RFX0dfU1RBUlQpO1xyXG4gICAgICAgIGlmICghY29kZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZGVjb2RlZENvZGVzLnB1c2goY29kZSk7XHJcbiAgICAgICAgcmVzdWx0LnB1c2goY29kZS5jb2RlKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY29kZTtcclxufTtcclxuXHJcbkVBTlJlYWRlci5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHN0YXJ0SW5mbyxcclxuICAgICAgICBzZWxmID0gdGhpcyxcclxuICAgICAgICBjb2RlLFxyXG4gICAgICAgIHJlc3VsdCA9IFtdLFxyXG4gICAgICAgIGRlY29kZWRDb2RlcyA9IFtdO1xyXG5cclxuICAgIHN0YXJ0SW5mbyA9IHNlbGYuX2ZpbmRTdGFydCgpO1xyXG4gICAgaWYgKCFzdGFydEluZm8pIHtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIGNvZGUgPSB7XHJcbiAgICAgICAgY29kZTogc3RhcnRJbmZvLmNvZGUsXHJcbiAgICAgICAgc3RhcnQ6IHN0YXJ0SW5mby5zdGFydCxcclxuICAgICAgICBlbmQ6IHN0YXJ0SW5mby5lbmRcclxuICAgIH07XHJcbiAgICBkZWNvZGVkQ29kZXMucHVzaChjb2RlKTtcclxuICAgIGNvZGUgPSBzZWxmLl9kZWNvZGVQYXlsb2FkKGNvZGUsIHJlc3VsdCwgZGVjb2RlZENvZGVzKTtcclxuICAgIGlmICghY29kZSkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgY29kZSA9IHNlbGYuX2ZpbmRFbmQoY29kZS5lbmQsIGZhbHNlKTtcclxuICAgIGlmICghY29kZSl7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgZGVjb2RlZENvZGVzLnB1c2goY29kZSk7XHJcblxyXG4gICAgLy8gQ2hlY2tzdW1cclxuICAgIGlmICghc2VsZi5fY2hlY2tzdW0ocmVzdWx0KSkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgY29kZTogcmVzdWx0LmpvaW4oXCJcIiksXHJcbiAgICAgICAgc3RhcnQ6IHN0YXJ0SW5mby5zdGFydCxcclxuICAgICAgICBlbmQ6IGNvZGUuZW5kLFxyXG4gICAgICAgIGNvZGVzZXQ6IFwiXCIsXHJcbiAgICAgICAgc3RhcnRJbmZvOiBzdGFydEluZm8sXHJcbiAgICAgICAgZGVjb2RlZENvZGVzOiBkZWNvZGVkQ29kZXNcclxuICAgIH07XHJcbn07XHJcblxyXG5FQU5SZWFkZXIucHJvdG90eXBlLl9jaGVja3N1bSA9IGZ1bmN0aW9uKHJlc3VsdCkge1xyXG4gICAgdmFyIHN1bSA9IDAsIGk7XHJcblxyXG4gICAgZm9yICggaSA9IHJlc3VsdC5sZW5ndGggLSAyOyBpID49IDA7IGkgLT0gMikge1xyXG4gICAgICAgIHN1bSArPSByZXN1bHRbaV07XHJcbiAgICB9XHJcbiAgICBzdW0gKj0gMztcclxuICAgIGZvciAoIGkgPSByZXN1bHQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDIpIHtcclxuICAgICAgICBzdW0gKz0gcmVzdWx0W2ldO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN1bSAlIDEwID09PSAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgKEVBTlJlYWRlcik7XHJcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL3JlYWRlci9lYW5fcmVhZGVyLmpzXG4gKiovIiwidmFyIGVxID0gcmVxdWlyZSgnLi9lcScpO1xuXG4vKipcbiAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGBrZXlgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAqIG9mIGtleS12YWx1ZSBwYWlycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7Kn0ga2V5IFRoZSBrZXkgdG8gc2VhcmNoIGZvci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gKi9cbmZ1bmN0aW9uIGFzc29jSW5kZXhPZihhcnJheSwga2V5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChlcShhcnJheVtsZW5ndGhdWzBdLCBrZXkpKSB7XG4gICAgICByZXR1cm4gbGVuZ3RoO1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzb2NJbmRleE9mO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19hc3NvY0luZGV4T2YuanNcbiAqKiBtb2R1bGUgaWQgPSAxMVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGlzTmF0aXZlID0gcmVxdWlyZSgnLi9pc05hdGl2ZScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgdmFyIHZhbHVlID0gb2JqZWN0W2tleV07XG4gIHJldHVybiBpc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXROYXRpdmU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2dldE5hdGl2ZS5qc1xuICoqIG1vZHVsZSBpZCA9IDEyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciB1c2UgYXMgdW5pcXVlIG9iamVjdCBrZXkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXlhYmxlKHZhbHVlKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gdHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdib29sZWFuJyB8fFxuICAgICh0eXBlID09ICdzdHJpbmcnICYmIHZhbHVlICE9ICdfX3Byb3RvX18nKSB8fCB2YWx1ZSA9PSBudWxsO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzS2V5YWJsZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faXNLZXlhYmxlLmpzXG4gKiogbW9kdWxlIGlkID0gMTNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xudmFyIG5hdGl2ZUNyZWF0ZSA9IGdldE5hdGl2ZShPYmplY3QsICdjcmVhdGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuYXRpdmVDcmVhdGU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX25hdGl2ZUNyZWF0ZS5qc1xuICoqIG1vZHVsZSBpZCA9IDE0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIFBlcmZvcm1zIGEgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSBlcXVpdmFsZW50LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICogdmFyIG90aGVyID0geyAndXNlcic6ICdmcmVkJyB9O1xuICpcbiAqIF8uZXEob2JqZWN0LCBvYmplY3QpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEob2JqZWN0LCBvdGhlcik7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoJ2EnLCAnYScpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoTmFOLCBOYU4pO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBvdGhlciB8fCAodmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXE7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvZXEuanNcbiAqKiBtb2R1bGUgaWQgPSAxNVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgZ2VuVGFnID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYEZ1bmN0aW9uYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3JcbiAgLy8gaW4gU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgYW5kIHdlYWsgbWFwIGNvbnN0cnVjdG9ycyxcbiAgLy8gYW5kIFBoYW50b21KUyAxLjkgd2hpY2ggcmV0dXJucyAnZnVuY3Rpb24nIGZvciBgTm9kZUxpc3RgIGluc3RhbmNlcy5cbiAgdmFyIHRhZyA9IGlzT2JqZWN0KHZhbHVlKSA/IG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRnVuY3Rpb247XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaXNGdW5jdGlvbi5qc1xuICoqIG1vZHVsZSBpZCA9IDE2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJpbXBvcnQgQ2x1c3RlcjIgZnJvbSAnLi9jbHVzdGVyJztcclxuaW1wb3J0IEFycmF5SGVscGVyIGZyb20gJy4vYXJyYXlfaGVscGVyJztcclxuY29uc3QgdmVjMiA9IHtcclxuICAgIGNsb25lOiByZXF1aXJlKCdnbC12ZWMyL2Nsb25lJyksXHJcbn07XHJcbmNvbnN0IHZlYzMgPSB7XHJcbiAgICBjbG9uZTogcmVxdWlyZSgnZ2wtdmVjMy9jbG9uZScpLFxyXG59O1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB4IHgtY29vcmRpbmF0ZVxyXG4gKiBAcGFyYW0geSB5LWNvb3JkaW5hdGVcclxuICogQHJldHVybiBJbWFnZVJlZmVyZW5jZSB7eCx5fSBDb29yZGluYXRlXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaW1hZ2VSZWYoeCwgeSkge1xyXG4gICAgdmFyIHRoYXQgPSB7XHJcbiAgICAgICAgeDogeCxcclxuICAgICAgICB5OiB5LFxyXG4gICAgICAgIHRvVmVjMjogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB2ZWMyLmNsb25lKFt0aGlzLngsIHRoaXMueV0pO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdG9WZWMzOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHZlYzMuY2xvbmUoW3RoaXMueCwgdGhpcy55LCAxXSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICByb3VuZDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHRoaXMueCA9IHRoaXMueCA+IDAuMCA/IE1hdGguZmxvb3IodGhpcy54ICsgMC41KSA6IE1hdGguZmxvb3IodGhpcy54IC0gMC41KTtcclxuICAgICAgICAgICAgdGhpcy55ID0gdGhpcy55ID4gMC4wID8gTWF0aC5mbG9vcih0aGlzLnkgKyAwLjUpIDogTWF0aC5mbG9vcih0aGlzLnkgLSAwLjUpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIHRoYXQ7XHJcbn07XHJcblxyXG4vKipcclxuICogQ29tcHV0ZXMgYW4gaW50ZWdyYWwgaW1hZ2Ugb2YgYSBnaXZlbiBncmF5c2NhbGUgaW1hZ2UuXHJcbiAqIEBwYXJhbSBpbWFnZURhdGFDb250YWluZXIge0ltYWdlRGF0YUNvbnRhaW5lcn0gdGhlIGltYWdlIHRvIGJlIGludGVncmF0ZWRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlSW50ZWdyYWxJbWFnZTIoaW1hZ2VXcmFwcGVyLCBpbnRlZ3JhbFdyYXBwZXIpIHtcclxuICAgIHZhciBpbWFnZURhdGEgPSBpbWFnZVdyYXBwZXIuZGF0YTtcclxuICAgIHZhciB3aWR0aCA9IGltYWdlV3JhcHBlci5zaXplLng7XHJcbiAgICB2YXIgaGVpZ2h0ID0gaW1hZ2VXcmFwcGVyLnNpemUueTtcclxuICAgIHZhciBpbnRlZ3JhbEltYWdlRGF0YSA9IGludGVncmFsV3JhcHBlci5kYXRhO1xyXG4gICAgdmFyIHN1bSA9IDAsIHBvc0EgPSAwLCBwb3NCID0gMCwgcG9zQyA9IDAsIHBvc0QgPSAwLCB4LCB5O1xyXG5cclxuICAgIC8vIHN1bSB1cCBmaXJzdCBjb2x1bW5cclxuICAgIHBvc0IgPSB3aWR0aDtcclxuICAgIHN1bSA9IDA7XHJcbiAgICBmb3IgKCB5ID0gMTsgeSA8IGhlaWdodDsgeSsrKSB7XHJcbiAgICAgICAgc3VtICs9IGltYWdlRGF0YVtwb3NBXTtcclxuICAgICAgICBpbnRlZ3JhbEltYWdlRGF0YVtwb3NCXSArPSBzdW07XHJcbiAgICAgICAgcG9zQSArPSB3aWR0aDtcclxuICAgICAgICBwb3NCICs9IHdpZHRoO1xyXG4gICAgfVxyXG5cclxuICAgIHBvc0EgPSAwO1xyXG4gICAgcG9zQiA9IDE7XHJcbiAgICBzdW0gPSAwO1xyXG4gICAgZm9yICggeCA9IDE7IHggPCB3aWR0aDsgeCsrKSB7XHJcbiAgICAgICAgc3VtICs9IGltYWdlRGF0YVtwb3NBXTtcclxuICAgICAgICBpbnRlZ3JhbEltYWdlRGF0YVtwb3NCXSArPSBzdW07XHJcbiAgICAgICAgcG9zQSsrO1xyXG4gICAgICAgIHBvc0IrKztcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKCB5ID0gMTsgeSA8IGhlaWdodDsgeSsrKSB7XHJcbiAgICAgICAgcG9zQSA9IHkgKiB3aWR0aCArIDE7XHJcbiAgICAgICAgcG9zQiA9ICh5IC0gMSkgKiB3aWR0aCArIDE7XHJcbiAgICAgICAgcG9zQyA9IHkgKiB3aWR0aDtcclxuICAgICAgICBwb3NEID0gKHkgLSAxKSAqIHdpZHRoO1xyXG4gICAgICAgIGZvciAoIHggPSAxOyB4IDwgd2lkdGg7IHgrKykge1xyXG4gICAgICAgICAgICBpbnRlZ3JhbEltYWdlRGF0YVtwb3NBXSArPVxyXG4gICAgICAgICAgICAgICAgaW1hZ2VEYXRhW3Bvc0FdICsgaW50ZWdyYWxJbWFnZURhdGFbcG9zQl0gKyBpbnRlZ3JhbEltYWdlRGF0YVtwb3NDXSAtIGludGVncmFsSW1hZ2VEYXRhW3Bvc0RdO1xyXG4gICAgICAgICAgICBwb3NBKys7XHJcbiAgICAgICAgICAgIHBvc0IrKztcclxuICAgICAgICAgICAgcG9zQysrO1xyXG4gICAgICAgICAgICBwb3NEKys7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVJbnRlZ3JhbEltYWdlKGltYWdlV3JhcHBlciwgaW50ZWdyYWxXcmFwcGVyKSB7XHJcbiAgICB2YXIgaW1hZ2VEYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGE7XHJcbiAgICB2YXIgd2lkdGggPSBpbWFnZVdyYXBwZXIuc2l6ZS54O1xyXG4gICAgdmFyIGhlaWdodCA9IGltYWdlV3JhcHBlci5zaXplLnk7XHJcbiAgICB2YXIgaW50ZWdyYWxJbWFnZURhdGEgPSBpbnRlZ3JhbFdyYXBwZXIuZGF0YTtcclxuICAgIHZhciBzdW0gPSAwO1xyXG5cclxuICAgIC8vIHN1bSB1cCBmaXJzdCByb3dcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgd2lkdGg7IGkrKykge1xyXG4gICAgICAgIHN1bSArPSBpbWFnZURhdGFbaV07XHJcbiAgICAgICAgaW50ZWdyYWxJbWFnZURhdGFbaV0gPSBzdW07XHJcbiAgICB9XHJcblxyXG4gICAgZm9yICh2YXIgdiA9IDE7IHYgPCBoZWlnaHQ7IHYrKykge1xyXG4gICAgICAgIHN1bSA9IDA7XHJcbiAgICAgICAgZm9yICh2YXIgdSA9IDA7IHUgPCB3aWR0aDsgdSsrKSB7XHJcbiAgICAgICAgICAgIHN1bSArPSBpbWFnZURhdGFbdiAqIHdpZHRoICsgdV07XHJcbiAgICAgICAgICAgIGludGVncmFsSW1hZ2VEYXRhWygodikgKiB3aWR0aCkgKyB1XSA9IHN1bSArIGludGVncmFsSW1hZ2VEYXRhWyh2IC0gMSkgKiB3aWR0aCArIHVdO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB0aHJlc2hvbGRJbWFnZShpbWFnZVdyYXBwZXIsIHRocmVzaG9sZCwgdGFyZ2V0V3JhcHBlcikge1xyXG4gICAgaWYgKCF0YXJnZXRXcmFwcGVyKSB7XHJcbiAgICAgICAgdGFyZ2V0V3JhcHBlciA9IGltYWdlV3JhcHBlcjtcclxuICAgIH1cclxuICAgIHZhciBpbWFnZURhdGEgPSBpbWFnZVdyYXBwZXIuZGF0YSwgbGVuZ3RoID0gaW1hZ2VEYXRhLmxlbmd0aCwgdGFyZ2V0RGF0YSA9IHRhcmdldFdyYXBwZXIuZGF0YTtcclxuXHJcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcclxuICAgICAgICB0YXJnZXREYXRhW2xlbmd0aF0gPSBpbWFnZURhdGFbbGVuZ3RoXSA8IHRocmVzaG9sZCA/IDEgOiAwO1xyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVIaXN0b2dyYW0oaW1hZ2VXcmFwcGVyLCBiaXRzUGVyUGl4ZWwpIHtcclxuICAgIGlmICghYml0c1BlclBpeGVsKSB7XHJcbiAgICAgICAgYml0c1BlclBpeGVsID0gODtcclxuICAgIH1cclxuICAgIHZhciBpbWFnZURhdGEgPSBpbWFnZVdyYXBwZXIuZGF0YSxcclxuICAgICAgICBsZW5ndGggPSBpbWFnZURhdGEubGVuZ3RoLFxyXG4gICAgICAgIGJpdFNoaWZ0ID0gOCAtIGJpdHNQZXJQaXhlbCxcclxuICAgICAgICBidWNrZXRDbnQgPSAxIDw8IGJpdHNQZXJQaXhlbCxcclxuICAgICAgICBoaXN0ID0gbmV3IEludDMyQXJyYXkoYnVja2V0Q250KTtcclxuXHJcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcclxuICAgICAgICBoaXN0W2ltYWdlRGF0YVtsZW5ndGhdID4+IGJpdFNoaWZ0XSsrO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGhpc3Q7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2hhcnBlbkxpbmUobGluZSkge1xyXG4gICAgdmFyIGksXHJcbiAgICAgICAgbGVuZ3RoID0gbGluZS5sZW5ndGgsXHJcbiAgICAgICAgbGVmdCA9IGxpbmVbMF0sXHJcbiAgICAgICAgY2VudGVyID0gbGluZVsxXSxcclxuICAgICAgICByaWdodDtcclxuXHJcbiAgICBmb3IgKGkgPSAxOyBpIDwgbGVuZ3RoIC0gMTsgaSsrKSB7XHJcbiAgICAgICAgcmlnaHQgPSBsaW5lW2kgKyAxXTtcclxuICAgICAgICAvLyAgLTEgNCAtMSBrZXJuZWxcclxuICAgICAgICBsaW5lW2kgLSAxXSA9ICgoKGNlbnRlciAqIDIpIC0gbGVmdCAtIHJpZ2h0KSkgJiAyNTU7XHJcbiAgICAgICAgbGVmdCA9IGNlbnRlcjtcclxuICAgICAgICBjZW50ZXIgPSByaWdodDtcclxuICAgIH1cclxuICAgIHJldHVybiBsaW5lO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRldGVybWluZU90c3VUaHJlc2hvbGQoaW1hZ2VXcmFwcGVyLCBiaXRzUGVyUGl4ZWwpIHtcclxuICAgIGlmICghYml0c1BlclBpeGVsKSB7XHJcbiAgICAgICAgYml0c1BlclBpeGVsID0gODtcclxuICAgIH1cclxuICAgIHZhciBoaXN0LFxyXG4gICAgICAgIHRocmVzaG9sZCxcclxuICAgICAgICBiaXRTaGlmdCA9IDggLSBiaXRzUGVyUGl4ZWw7XHJcblxyXG4gICAgZnVuY3Rpb24gcHgoaW5pdCwgZW5kKSB7XHJcbiAgICAgICAgdmFyIHN1bSA9IDAsIGk7XHJcbiAgICAgICAgZm9yICggaSA9IGluaXQ7IGkgPD0gZW5kOyBpKyspIHtcclxuICAgICAgICAgICAgc3VtICs9IGhpc3RbaV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzdW07XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gbXgoaW5pdCwgZW5kKSB7XHJcbiAgICAgICAgdmFyIGksIHN1bSA9IDA7XHJcblxyXG4gICAgICAgIGZvciAoIGkgPSBpbml0OyBpIDw9IGVuZDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHN1bSArPSBpICogaGlzdFtpXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBzdW07XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gZGV0ZXJtaW5lVGhyZXNob2xkKCkge1xyXG4gICAgICAgIHZhciB2ZXQgPSBbMF0sIHAxLCBwMiwgcDEyLCBrLCBtMSwgbTIsIG0xMixcclxuICAgICAgICAgICAgbWF4ID0gKDEgPDwgYml0c1BlclBpeGVsKSAtIDE7XHJcblxyXG4gICAgICAgIGhpc3QgPSBjb21wdXRlSGlzdG9ncmFtKGltYWdlV3JhcHBlciwgYml0c1BlclBpeGVsKTtcclxuICAgICAgICBmb3IgKCBrID0gMTsgayA8IG1heDsgaysrKSB7XHJcbiAgICAgICAgICAgIHAxID0gcHgoMCwgayk7XHJcbiAgICAgICAgICAgIHAyID0gcHgoayArIDEsIG1heCk7XHJcbiAgICAgICAgICAgIHAxMiA9IHAxICogcDI7XHJcbiAgICAgICAgICAgIGlmIChwMTIgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHAxMiA9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbTEgPSBteCgwLCBrKSAqIHAyO1xyXG4gICAgICAgICAgICBtMiA9IG14KGsgKyAxLCBtYXgpICogcDE7XHJcbiAgICAgICAgICAgIG0xMiA9IG0xIC0gbTI7XHJcbiAgICAgICAgICAgIHZldFtrXSA9IG0xMiAqIG0xMiAvIHAxMjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIEFycmF5SGVscGVyLm1heEluZGV4KHZldCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhyZXNob2xkID0gZGV0ZXJtaW5lVGhyZXNob2xkKCk7XHJcbiAgICByZXR1cm4gdGhyZXNob2xkIDw8IGJpdFNoaWZ0O1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG90c3VUaHJlc2hvbGQoaW1hZ2VXcmFwcGVyLCB0YXJnZXRXcmFwcGVyKSB7XHJcbiAgICB2YXIgdGhyZXNob2xkID0gZGV0ZXJtaW5lT3RzdVRocmVzaG9sZChpbWFnZVdyYXBwZXIpO1xyXG5cclxuICAgIHRocmVzaG9sZEltYWdlKGltYWdlV3JhcHBlciwgdGhyZXNob2xkLCB0YXJnZXRXcmFwcGVyKTtcclxuICAgIHJldHVybiB0aHJlc2hvbGQ7XHJcbn07XHJcblxyXG4vLyBsb2NhbCB0aHJlc2hvbGRpbmdcclxuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVCaW5hcnlJbWFnZShpbWFnZVdyYXBwZXIsIGludGVncmFsV3JhcHBlciwgdGFyZ2V0V3JhcHBlcikge1xyXG4gICAgY29tcHV0ZUludGVncmFsSW1hZ2UoaW1hZ2VXcmFwcGVyLCBpbnRlZ3JhbFdyYXBwZXIpO1xyXG5cclxuICAgIGlmICghdGFyZ2V0V3JhcHBlcikge1xyXG4gICAgICAgIHRhcmdldFdyYXBwZXIgPSBpbWFnZVdyYXBwZXI7XHJcbiAgICB9XHJcbiAgICB2YXIgaW1hZ2VEYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGE7XHJcbiAgICB2YXIgdGFyZ2V0RGF0YSA9IHRhcmdldFdyYXBwZXIuZGF0YTtcclxuICAgIHZhciB3aWR0aCA9IGltYWdlV3JhcHBlci5zaXplLng7XHJcbiAgICB2YXIgaGVpZ2h0ID0gaW1hZ2VXcmFwcGVyLnNpemUueTtcclxuICAgIHZhciBpbnRlZ3JhbEltYWdlRGF0YSA9IGludGVncmFsV3JhcHBlci5kYXRhO1xyXG4gICAgdmFyIHN1bSA9IDAsIHYsIHUsIGtlcm5lbCA9IDMsIEEsIEIsIEMsIEQsIGF2Zywgc2l6ZSA9IChrZXJuZWwgKiAyICsgMSkgKiAoa2VybmVsICogMiArIDEpO1xyXG5cclxuICAgIC8vIGNsZWFyIG91dCB0b3AgJiBib3R0b20tYm9yZGVyXHJcbiAgICBmb3IgKCB2ID0gMDsgdiA8PSBrZXJuZWw7IHYrKykge1xyXG4gICAgICAgIGZvciAoIHUgPSAwOyB1IDwgd2lkdGg7IHUrKykge1xyXG4gICAgICAgICAgICB0YXJnZXREYXRhWygodikgKiB3aWR0aCkgKyB1XSA9IDA7XHJcbiAgICAgICAgICAgIHRhcmdldERhdGFbKCgoaGVpZ2h0IC0gMSkgLSB2KSAqIHdpZHRoKSArIHVdID0gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY2xlYXIgb3V0IGxlZnQgJiByaWdodCBib3JkZXJcclxuICAgIGZvciAoIHYgPSBrZXJuZWw7IHYgPCBoZWlnaHQgLSBrZXJuZWw7IHYrKykge1xyXG4gICAgICAgIGZvciAoIHUgPSAwOyB1IDw9IGtlcm5lbDsgdSsrKSB7XHJcbiAgICAgICAgICAgIHRhcmdldERhdGFbKCh2KSAqIHdpZHRoKSArIHVdID0gMDtcclxuICAgICAgICAgICAgdGFyZ2V0RGF0YVsoKHYpICogd2lkdGgpICsgKHdpZHRoIC0gMSAtIHUpXSA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZvciAoIHYgPSBrZXJuZWwgKyAxOyB2IDwgaGVpZ2h0IC0ga2VybmVsIC0gMTsgdisrKSB7XHJcbiAgICAgICAgZm9yICggdSA9IGtlcm5lbCArIDE7IHUgPCB3aWR0aCAtIGtlcm5lbDsgdSsrKSB7XHJcbiAgICAgICAgICAgIEEgPSBpbnRlZ3JhbEltYWdlRGF0YVsodiAtIGtlcm5lbCAtIDEpICogd2lkdGggKyAodSAtIGtlcm5lbCAtIDEpXTtcclxuICAgICAgICAgICAgQiA9IGludGVncmFsSW1hZ2VEYXRhWyh2IC0ga2VybmVsIC0gMSkgKiB3aWR0aCArICh1ICsga2VybmVsKV07XHJcbiAgICAgICAgICAgIEMgPSBpbnRlZ3JhbEltYWdlRGF0YVsodiArIGtlcm5lbCkgKiB3aWR0aCArICh1IC0ga2VybmVsIC0gMSldO1xyXG4gICAgICAgICAgICBEID0gaW50ZWdyYWxJbWFnZURhdGFbKHYgKyBrZXJuZWwpICogd2lkdGggKyAodSArIGtlcm5lbCldO1xyXG4gICAgICAgICAgICBzdW0gPSBEIC0gQyAtIEIgKyBBO1xyXG4gICAgICAgICAgICBhdmcgPSBzdW0gLyAoc2l6ZSk7XHJcbiAgICAgICAgICAgIHRhcmdldERhdGFbdiAqIHdpZHRoICsgdV0gPSBpbWFnZURhdGFbdiAqIHdpZHRoICsgdV0gPiAoYXZnICsgNSkgPyAwIDogMTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY2x1c3Rlcihwb2ludHMsIHRocmVzaG9sZCwgcHJvcGVydHkpIHtcclxuICAgIHZhciBpLCBrLCBjbHVzdGVyLCBwb2ludCwgY2x1c3RlcnMgPSBbXTtcclxuXHJcbiAgICBpZiAoIXByb3BlcnR5KSB7XHJcbiAgICAgICAgcHJvcGVydHkgPSBcInJhZFwiO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGFkZFRvQ2x1c3RlcihuZXdQb2ludCkge1xyXG4gICAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xyXG4gICAgICAgIGZvciAoIGsgPSAwOyBrIDwgY2x1c3RlcnMubGVuZ3RoOyBrKyspIHtcclxuICAgICAgICAgICAgY2x1c3RlciA9IGNsdXN0ZXJzW2tdO1xyXG4gICAgICAgICAgICBpZiAoY2x1c3Rlci5maXRzKG5ld1BvaW50KSkge1xyXG4gICAgICAgICAgICAgICAgY2x1c3Rlci5hZGQobmV3UG9pbnQpO1xyXG4gICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmb3VuZDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpdGVyYXRlIG92ZXIgZWFjaCBjbG91ZFxyXG4gICAgZm9yICggaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBwb2ludCA9IENsdXN0ZXIyLmNyZWF0ZVBvaW50KHBvaW50c1tpXSwgaSwgcHJvcGVydHkpO1xyXG4gICAgICAgIGlmICghYWRkVG9DbHVzdGVyKHBvaW50KSkge1xyXG4gICAgICAgICAgICBjbHVzdGVycy5wdXNoKENsdXN0ZXIyLmNyZWF0ZShwb2ludCwgdGhyZXNob2xkKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNsdXN0ZXJzO1xyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IFRyYWNlciA9IHtcclxuICAgIHRyYWNlOiBmdW5jdGlvbihwb2ludHMsIHZlYykge1xyXG4gICAgICAgIHZhciBpdGVyYXRpb24sIG1heEl0ZXJhdGlvbnMgPSAxMCwgdG9wID0gW10sIHJlc3VsdCA9IFtdLCBjZW50ZXJQb3MgPSAwLCBjdXJyZW50UG9zID0gMDtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gdHJhY2UoaWR4LCBmb3J3YXJkKSB7XHJcbiAgICAgICAgICAgIHZhciBmcm9tLCB0bywgdG9JZHgsIHByZWRpY3RlZFBvcywgdGhyZXNob2xkWCA9IDEsIHRocmVzaG9sZFkgPSBNYXRoLmFicyh2ZWNbMV0gLyAxMCksIGZvdW5kID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBtYXRjaChwb3MsIHByZWRpY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHBvcy54ID4gKHByZWRpY3RlZC54IC0gdGhyZXNob2xkWClcclxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgcG9zLnggPCAocHJlZGljdGVkLnggKyB0aHJlc2hvbGRYKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBwb3MueSA+IChwcmVkaWN0ZWQueSAtIHRocmVzaG9sZFkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIHBvcy55IDwgKHByZWRpY3RlZC55ICsgdGhyZXNob2xkWSkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBjaGVjayBpZiB0aGUgbmV4dCBpbmRleCBpcyB3aXRoaW4gdGhlIHZlYyBzcGVjaWZpY2F0aW9uc1xyXG4gICAgICAgICAgICAvLyBpZiBub3QsIGNoZWNrIGFzIGxvbmcgYXMgdGhlIHRocmVzaG9sZCBpcyBtZXRcclxuXHJcbiAgICAgICAgICAgIGZyb20gPSBwb2ludHNbaWR4XTtcclxuICAgICAgICAgICAgaWYgKGZvcndhcmQpIHtcclxuICAgICAgICAgICAgICAgIHByZWRpY3RlZFBvcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICB4OiBmcm9tLnggKyB2ZWNbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgeTogZnJvbS55ICsgdmVjWzFdXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcHJlZGljdGVkUG9zID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIHg6IGZyb20ueCAtIHZlY1swXSxcclxuICAgICAgICAgICAgICAgICAgICB5OiBmcm9tLnkgLSB2ZWNbMV1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRvSWR4ID0gZm9yd2FyZCA/IGlkeCArIDEgOiBpZHggLSAxO1xyXG4gICAgICAgICAgICB0byA9IHBvaW50c1t0b0lkeF07XHJcbiAgICAgICAgICAgIHdoaWxlICh0byAmJiAoIGZvdW5kID0gbWF0Y2godG8sIHByZWRpY3RlZFBvcykpICE9PSB0cnVlICYmIChNYXRoLmFicyh0by55IC0gZnJvbS55KSA8IHZlY1sxXSkpIHtcclxuICAgICAgICAgICAgICAgIHRvSWR4ID0gZm9yd2FyZCA/IHRvSWR4ICsgMSA6IHRvSWR4IC0gMTtcclxuICAgICAgICAgICAgICAgIHRvID0gcG9pbnRzW3RvSWR4XTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGZvdW5kID8gdG9JZHggOiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yICggaXRlcmF0aW9uID0gMDsgaXRlcmF0aW9uIDwgbWF4SXRlcmF0aW9uczsgaXRlcmF0aW9uKyspIHtcclxuICAgICAgICAgICAgLy8gcmFuZG9tbHkgc2VsZWN0IHBvaW50IHRvIHN0YXJ0IHdpdGhcclxuICAgICAgICAgICAgY2VudGVyUG9zID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcG9pbnRzLmxlbmd0aCk7XHJcblxyXG4gICAgICAgICAgICAvLyB0cmFjZSBmb3J3YXJkXHJcbiAgICAgICAgICAgIHRvcCA9IFtdO1xyXG4gICAgICAgICAgICBjdXJyZW50UG9zID0gY2VudGVyUG9zO1xyXG4gICAgICAgICAgICB0b3AucHVzaChwb2ludHNbY3VycmVudFBvc10pO1xyXG4gICAgICAgICAgICB3aGlsZSAoKCBjdXJyZW50UG9zID0gdHJhY2UoY3VycmVudFBvcywgdHJ1ZSkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0b3AucHVzaChwb2ludHNbY3VycmVudFBvc10pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChjZW50ZXJQb3MgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50UG9zID0gY2VudGVyUG9zO1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKCggY3VycmVudFBvcyA9IHRyYWNlKGN1cnJlbnRQb3MsIGZhbHNlKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB0b3AucHVzaChwb2ludHNbY3VycmVudFBvc10pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodG9wLmxlbmd0aCA+IHJlc3VsdC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRvcDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IERJTEFURSA9IDE7XHJcbmV4cG9ydCBjb25zdCBFUk9ERSA9IDI7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZGlsYXRlKGluSW1hZ2VXcmFwcGVyLCBvdXRJbWFnZVdyYXBwZXIpIHtcclxuICAgIHZhciB2LFxyXG4gICAgICAgIHUsXHJcbiAgICAgICAgaW5JbWFnZURhdGEgPSBpbkltYWdlV3JhcHBlci5kYXRhLFxyXG4gICAgICAgIG91dEltYWdlRGF0YSA9IG91dEltYWdlV3JhcHBlci5kYXRhLFxyXG4gICAgICAgIGhlaWdodCA9IGluSW1hZ2VXcmFwcGVyLnNpemUueSxcclxuICAgICAgICB3aWR0aCA9IGluSW1hZ2VXcmFwcGVyLnNpemUueCxcclxuICAgICAgICBzdW0sXHJcbiAgICAgICAgeVN0YXJ0MSxcclxuICAgICAgICB5U3RhcnQyLFxyXG4gICAgICAgIHhTdGFydDEsXHJcbiAgICAgICAgeFN0YXJ0MjtcclxuXHJcbiAgICBmb3IgKCB2ID0gMTsgdiA8IGhlaWdodCAtIDE7IHYrKykge1xyXG4gICAgICAgIGZvciAoIHUgPSAxOyB1IDwgd2lkdGggLSAxOyB1KyspIHtcclxuICAgICAgICAgICAgeVN0YXJ0MSA9IHYgLSAxO1xyXG4gICAgICAgICAgICB5U3RhcnQyID0gdiArIDE7XHJcbiAgICAgICAgICAgIHhTdGFydDEgPSB1IC0gMTtcclxuICAgICAgICAgICAgeFN0YXJ0MiA9IHUgKyAxO1xyXG4gICAgICAgICAgICBzdW0gPSBpbkltYWdlRGF0YVt5U3RhcnQxICogd2lkdGggKyB4U3RhcnQxXSArIGluSW1hZ2VEYXRhW3lTdGFydDEgKiB3aWR0aCArIHhTdGFydDJdICtcclxuICAgICAgICAgICAgaW5JbWFnZURhdGFbdiAqIHdpZHRoICsgdV0gK1xyXG4gICAgICAgICAgICBpbkltYWdlRGF0YVt5U3RhcnQyICogd2lkdGggKyB4U3RhcnQxXSArIGluSW1hZ2VEYXRhW3lTdGFydDIgKiB3aWR0aCArIHhTdGFydDJdO1xyXG4gICAgICAgICAgICBvdXRJbWFnZURhdGFbdiAqIHdpZHRoICsgdV0gPSBzdW0gPiAwID8gMSA6IDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGVyb2RlKGluSW1hZ2VXcmFwcGVyLCBvdXRJbWFnZVdyYXBwZXIpIHtcclxuICAgIHZhciB2LFxyXG4gICAgICAgIHUsXHJcbiAgICAgICAgaW5JbWFnZURhdGEgPSBpbkltYWdlV3JhcHBlci5kYXRhLFxyXG4gICAgICAgIG91dEltYWdlRGF0YSA9IG91dEltYWdlV3JhcHBlci5kYXRhLFxyXG4gICAgICAgIGhlaWdodCA9IGluSW1hZ2VXcmFwcGVyLnNpemUueSxcclxuICAgICAgICB3aWR0aCA9IGluSW1hZ2VXcmFwcGVyLnNpemUueCxcclxuICAgICAgICBzdW0sXHJcbiAgICAgICAgeVN0YXJ0MSxcclxuICAgICAgICB5U3RhcnQyLFxyXG4gICAgICAgIHhTdGFydDEsXHJcbiAgICAgICAgeFN0YXJ0MjtcclxuXHJcbiAgICBmb3IgKCB2ID0gMTsgdiA8IGhlaWdodCAtIDE7IHYrKykge1xyXG4gICAgICAgIGZvciAoIHUgPSAxOyB1IDwgd2lkdGggLSAxOyB1KyspIHtcclxuICAgICAgICAgICAgeVN0YXJ0MSA9IHYgLSAxO1xyXG4gICAgICAgICAgICB5U3RhcnQyID0gdiArIDE7XHJcbiAgICAgICAgICAgIHhTdGFydDEgPSB1IC0gMTtcclxuICAgICAgICAgICAgeFN0YXJ0MiA9IHUgKyAxO1xyXG4gICAgICAgICAgICBzdW0gPSBpbkltYWdlRGF0YVt5U3RhcnQxICogd2lkdGggKyB4U3RhcnQxXSArIGluSW1hZ2VEYXRhW3lTdGFydDEgKiB3aWR0aCArIHhTdGFydDJdICtcclxuICAgICAgICAgICAgaW5JbWFnZURhdGFbdiAqIHdpZHRoICsgdV0gK1xyXG4gICAgICAgICAgICBpbkltYWdlRGF0YVt5U3RhcnQyICogd2lkdGggKyB4U3RhcnQxXSArIGluSW1hZ2VEYXRhW3lTdGFydDIgKiB3aWR0aCArIHhTdGFydDJdO1xyXG4gICAgICAgICAgICBvdXRJbWFnZURhdGFbdiAqIHdpZHRoICsgdV0gPSBzdW0gPT09IDUgPyAxIDogMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc3VidHJhY3QoYUltYWdlV3JhcHBlciwgYkltYWdlV3JhcHBlciwgcmVzdWx0SW1hZ2VXcmFwcGVyKSB7XHJcbiAgICBpZiAoIXJlc3VsdEltYWdlV3JhcHBlcikge1xyXG4gICAgICAgIHJlc3VsdEltYWdlV3JhcHBlciA9IGFJbWFnZVdyYXBwZXI7XHJcbiAgICB9XHJcbiAgICB2YXIgbGVuZ3RoID0gYUltYWdlV3JhcHBlci5kYXRhLmxlbmd0aCxcclxuICAgICAgICBhSW1hZ2VEYXRhID0gYUltYWdlV3JhcHBlci5kYXRhLFxyXG4gICAgICAgIGJJbWFnZURhdGEgPSBiSW1hZ2VXcmFwcGVyLmRhdGEsXHJcbiAgICAgICAgY0ltYWdlRGF0YSA9IHJlc3VsdEltYWdlV3JhcHBlci5kYXRhO1xyXG5cclxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xyXG4gICAgICAgIGNJbWFnZURhdGFbbGVuZ3RoXSA9IGFJbWFnZURhdGFbbGVuZ3RoXSAtIGJJbWFnZURhdGFbbGVuZ3RoXTtcclxuICAgIH1cclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBiaXR3aXNlT3IoYUltYWdlV3JhcHBlciwgYkltYWdlV3JhcHBlciwgcmVzdWx0SW1hZ2VXcmFwcGVyKSB7XHJcbiAgICBpZiAoIXJlc3VsdEltYWdlV3JhcHBlcikge1xyXG4gICAgICAgIHJlc3VsdEltYWdlV3JhcHBlciA9IGFJbWFnZVdyYXBwZXI7XHJcbiAgICB9XHJcbiAgICB2YXIgbGVuZ3RoID0gYUltYWdlV3JhcHBlci5kYXRhLmxlbmd0aCxcclxuICAgICAgICBhSW1hZ2VEYXRhID0gYUltYWdlV3JhcHBlci5kYXRhLFxyXG4gICAgICAgIGJJbWFnZURhdGEgPSBiSW1hZ2VXcmFwcGVyLmRhdGEsXHJcbiAgICAgICAgY0ltYWdlRGF0YSA9IHJlc3VsdEltYWdlV3JhcHBlci5kYXRhO1xyXG5cclxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xyXG4gICAgICAgIGNJbWFnZURhdGFbbGVuZ3RoXSA9IGFJbWFnZURhdGFbbGVuZ3RoXSB8fCBiSW1hZ2VEYXRhW2xlbmd0aF07XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY291bnROb25aZXJvKGltYWdlV3JhcHBlcikge1xyXG4gICAgdmFyIGxlbmd0aCA9IGltYWdlV3JhcHBlci5kYXRhLmxlbmd0aCwgZGF0YSA9IGltYWdlV3JhcHBlci5kYXRhLCBzdW0gPSAwO1xyXG5cclxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xyXG4gICAgICAgIHN1bSArPSBkYXRhW2xlbmd0aF07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gc3VtO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHRvcEdlbmVyaWMobGlzdCwgdG9wLCBzY29yZUZ1bmMpIHtcclxuICAgIHZhciBpLCBtaW5JZHggPSAwLCBtaW4gPSAwLCBxdWV1ZSA9IFtdLCBzY29yZSwgaGl0LCBwb3M7XHJcblxyXG4gICAgZm9yICggaSA9IDA7IGkgPCB0b3A7IGkrKykge1xyXG4gICAgICAgIHF1ZXVlW2ldID0ge1xyXG4gICAgICAgICAgICBzY29yZTogMCxcclxuICAgICAgICAgICAgaXRlbTogbnVsbFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgZm9yICggaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgc2NvcmUgPSBzY29yZUZ1bmMuYXBwbHkodGhpcywgW2xpc3RbaV1dKTtcclxuICAgICAgICBpZiAoc2NvcmUgPiBtaW4pIHtcclxuICAgICAgICAgICAgaGl0ID0gcXVldWVbbWluSWR4XTtcclxuICAgICAgICAgICAgaGl0LnNjb3JlID0gc2NvcmU7XHJcbiAgICAgICAgICAgIGhpdC5pdGVtID0gbGlzdFtpXTtcclxuICAgICAgICAgICAgbWluID0gTnVtYmVyLk1BWF9WQUxVRTtcclxuICAgICAgICAgICAgZm9yICggcG9zID0gMDsgcG9zIDwgdG9wOyBwb3MrKykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlW3Bvc10uc2NvcmUgPCBtaW4pIHtcclxuICAgICAgICAgICAgICAgICAgICBtaW4gPSBxdWV1ZVtwb3NdLnNjb3JlO1xyXG4gICAgICAgICAgICAgICAgICAgIG1pbklkeCA9IHBvcztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcXVldWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ3JheUFycmF5RnJvbUltYWdlKGh0bWxJbWFnZSwgb2Zmc2V0WCwgY3R4LCBhcnJheSkge1xyXG4gICAgY3R4LmRyYXdJbWFnZShodG1sSW1hZ2UsIG9mZnNldFgsIDAsIGh0bWxJbWFnZS53aWR0aCwgaHRtbEltYWdlLmhlaWdodCk7XHJcbiAgICB2YXIgY3R4RGF0YSA9IGN0eC5nZXRJbWFnZURhdGEob2Zmc2V0WCwgMCwgaHRtbEltYWdlLndpZHRoLCBodG1sSW1hZ2UuaGVpZ2h0KS5kYXRhO1xyXG4gICAgY29tcHV0ZUdyYXkoY3R4RGF0YSwgYXJyYXkpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdyYXlBcnJheUZyb21Db250ZXh0KGN0eCwgc2l6ZSwgb2Zmc2V0LCBhcnJheSkge1xyXG4gICAgdmFyIGN0eERhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKG9mZnNldC54LCBvZmZzZXQueSwgc2l6ZS54LCBzaXplLnkpLmRhdGE7XHJcbiAgICBjb21wdXRlR3JheShjdHhEYXRhLCBhcnJheSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ3JheUFuZEhhbGZTYW1wbGVGcm9tQ2FudmFzRGF0YShjYW52YXNEYXRhLCBzaXplLCBvdXRBcnJheSkge1xyXG4gICAgdmFyIHRvcFJvd0lkeCA9IDA7XHJcbiAgICB2YXIgYm90dG9tUm93SWR4ID0gc2l6ZS54O1xyXG4gICAgdmFyIGVuZElkeCA9IE1hdGguZmxvb3IoY2FudmFzRGF0YS5sZW5ndGggLyA0KTtcclxuICAgIHZhciBvdXRXaWR0aCA9IHNpemUueCAvIDI7XHJcbiAgICB2YXIgb3V0SW1nSWR4ID0gMDtcclxuICAgIHZhciBpbldpZHRoID0gc2l6ZS54O1xyXG4gICAgdmFyIGk7XHJcblxyXG4gICAgd2hpbGUgKGJvdHRvbVJvd0lkeCA8IGVuZElkeCkge1xyXG4gICAgICAgIGZvciAoIGkgPSAwOyBpIDwgb3V0V2lkdGg7IGkrKykge1xyXG4gICAgICAgICAgICBvdXRBcnJheVtvdXRJbWdJZHhdID0gTWF0aC5mbG9vcigoXHJcbiAgICAgICAgICAgICAgICAoMC4yOTkgKiBjYW52YXNEYXRhW3RvcFJvd0lkeCAqIDQgKyAwXSArXHJcbiAgICAgICAgICAgICAgICAgMC41ODcgKiBjYW52YXNEYXRhW3RvcFJvd0lkeCAqIDQgKyAxXSArXHJcbiAgICAgICAgICAgICAgICAgMC4xMTQgKiBjYW52YXNEYXRhW3RvcFJvd0lkeCAqIDQgKyAyXSkgK1xyXG4gICAgICAgICAgICAgICAgKDAuMjk5ICogY2FudmFzRGF0YVsodG9wUm93SWR4ICsgMSkgKiA0ICsgMF0gK1xyXG4gICAgICAgICAgICAgICAgIDAuNTg3ICogY2FudmFzRGF0YVsodG9wUm93SWR4ICsgMSkgKiA0ICsgMV0gK1xyXG4gICAgICAgICAgICAgICAgIDAuMTE0ICogY2FudmFzRGF0YVsodG9wUm93SWR4ICsgMSkgKiA0ICsgMl0pICtcclxuICAgICAgICAgICAgICAgICgwLjI5OSAqIGNhbnZhc0RhdGFbKGJvdHRvbVJvd0lkeCkgKiA0ICsgMF0gK1xyXG4gICAgICAgICAgICAgICAgIDAuNTg3ICogY2FudmFzRGF0YVsoYm90dG9tUm93SWR4KSAqIDQgKyAxXSArXHJcbiAgICAgICAgICAgICAgICAgMC4xMTQgKiBjYW52YXNEYXRhWyhib3R0b21Sb3dJZHgpICogNCArIDJdKSArXHJcbiAgICAgICAgICAgICAgICAoMC4yOTkgKiBjYW52YXNEYXRhWyhib3R0b21Sb3dJZHggKyAxKSAqIDQgKyAwXSArXHJcbiAgICAgICAgICAgICAgICAgMC41ODcgKiBjYW52YXNEYXRhWyhib3R0b21Sb3dJZHggKyAxKSAqIDQgKyAxXSArXHJcbiAgICAgICAgICAgICAgICAgMC4xMTQgKiBjYW52YXNEYXRhWyhib3R0b21Sb3dJZHggKyAxKSAqIDQgKyAyXSkpIC8gNCk7XHJcbiAgICAgICAgICAgIG91dEltZ0lkeCsrO1xyXG4gICAgICAgICAgICB0b3BSb3dJZHggPSB0b3BSb3dJZHggKyAyO1xyXG4gICAgICAgICAgICBib3R0b21Sb3dJZHggPSBib3R0b21Sb3dJZHggKyAyO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0b3BSb3dJZHggPSB0b3BSb3dJZHggKyBpbldpZHRoO1xyXG4gICAgICAgIGJvdHRvbVJvd0lkeCA9IGJvdHRvbVJvd0lkeCArIGluV2lkdGg7XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZUdyYXkoaW1hZ2VEYXRhLCBvdXRBcnJheSwgY29uZmlnKSB7XHJcbiAgICB2YXIgbCA9IChpbWFnZURhdGEubGVuZ3RoIC8gNCkgfCAwLFxyXG4gICAgICAgIGksXHJcbiAgICAgICAgc2luZ2xlQ2hhbm5lbCA9IGNvbmZpZyAmJiBjb25maWcuc2luZ2xlQ2hhbm5lbCA9PT0gdHJ1ZTtcclxuXHJcbiAgICBpZiAoc2luZ2xlQ2hhbm5lbCkge1xyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgb3V0QXJyYXlbaV0gPSBpbWFnZURhdGFbaSAqIDQgKyAwXTtcclxuICAgICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgb3V0QXJyYXlbaV0gPSBNYXRoLmZsb29yKFxyXG4gICAgICAgICAgICAgICAgMC4yOTkgKiBpbWFnZURhdGFbaSAqIDQgKyAwXSArIDAuNTg3ICogaW1hZ2VEYXRhW2kgKiA0ICsgMV0gKyAwLjExNCAqIGltYWdlRGF0YVtpICogNCArIDJdKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbG9hZEltYWdlQXJyYXkoc3JjLCBjYWxsYmFjaywgY2FudmFzKSB7XHJcbiAgICBpZiAoIWNhbnZhcykge1xyXG4gICAgICAgIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xyXG4gICAgfVxyXG4gICAgdmFyIGltZyA9IG5ldyBJbWFnZSgpO1xyXG4gICAgaW1nLmNhbGxiYWNrID0gY2FsbGJhY2s7XHJcbiAgICBpbWcub25sb2FkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgY2FudmFzLndpZHRoID0gdGhpcy53aWR0aDtcclxuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XHJcbiAgICAgICAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xyXG4gICAgICAgIGN0eC5kcmF3SW1hZ2UodGhpcywgMCwgMCk7XHJcbiAgICAgICAgdmFyIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy53aWR0aCAqIHRoaXMuaGVpZ2h0KTtcclxuICAgICAgICBjdHguZHJhd0ltYWdlKHRoaXMsIDAsIDApO1xyXG4gICAgICAgIHZhciBkYXRhID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCkuZGF0YTtcclxuICAgICAgICBjb21wdXRlR3JheShkYXRhLCBhcnJheSk7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFjayhhcnJheSwge1xyXG4gICAgICAgICAgICB4OiB0aGlzLndpZHRoLFxyXG4gICAgICAgICAgICB5OiB0aGlzLmhlaWdodFxyXG4gICAgICAgIH0sIHRoaXMpO1xyXG4gICAgfTtcclxuICAgIGltZy5zcmMgPSBzcmM7XHJcbn07XHJcblxyXG4vKipcclxuICogQHBhcmFtIGluSW1nIHtJbWFnZVdyYXBwZXJ9IGlucHV0IGltYWdlIHRvIGJlIHNhbXBsZWRcclxuICogQHBhcmFtIG91dEltZyB7SW1hZ2VXcmFwcGVyfSB0byBiZSBzdG9yZWQgaW5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBoYWxmU2FtcGxlKGluSW1nV3JhcHBlciwgb3V0SW1nV3JhcHBlcikge1xyXG4gICAgdmFyIGluSW1nID0gaW5JbWdXcmFwcGVyLmRhdGE7XHJcbiAgICB2YXIgaW5XaWR0aCA9IGluSW1nV3JhcHBlci5zaXplLng7XHJcbiAgICB2YXIgb3V0SW1nID0gb3V0SW1nV3JhcHBlci5kYXRhO1xyXG4gICAgdmFyIHRvcFJvd0lkeCA9IDA7XHJcbiAgICB2YXIgYm90dG9tUm93SWR4ID0gaW5XaWR0aDtcclxuICAgIHZhciBlbmRJZHggPSBpbkltZy5sZW5ndGg7XHJcbiAgICB2YXIgb3V0V2lkdGggPSBpbldpZHRoIC8gMjtcclxuICAgIHZhciBvdXRJbWdJZHggPSAwO1xyXG4gICAgd2hpbGUgKGJvdHRvbVJvd0lkeCA8IGVuZElkeCkge1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3V0V2lkdGg7IGkrKykge1xyXG4gICAgICAgICAgICBvdXRJbWdbb3V0SW1nSWR4XSA9IE1hdGguZmxvb3IoXHJcbiAgICAgICAgICAgICAgICAoaW5JbWdbdG9wUm93SWR4XSArIGluSW1nW3RvcFJvd0lkeCArIDFdICsgaW5JbWdbYm90dG9tUm93SWR4XSArIGluSW1nW2JvdHRvbVJvd0lkeCArIDFdKSAvIDQpO1xyXG4gICAgICAgICAgICBvdXRJbWdJZHgrKztcclxuICAgICAgICAgICAgdG9wUm93SWR4ID0gdG9wUm93SWR4ICsgMjtcclxuICAgICAgICAgICAgYm90dG9tUm93SWR4ID0gYm90dG9tUm93SWR4ICsgMjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdG9wUm93SWR4ID0gdG9wUm93SWR4ICsgaW5XaWR0aDtcclxuICAgICAgICBib3R0b21Sb3dJZHggPSBib3R0b21Sb3dJZHggKyBpbldpZHRoO1xyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGhzdjJyZ2IoaHN2LCByZ2IpIHtcclxuICAgIHZhciBoID0gaHN2WzBdLFxyXG4gICAgICAgIHMgPSBoc3ZbMV0sXHJcbiAgICAgICAgdiA9IGhzdlsyXSxcclxuICAgICAgICBjID0gdiAqIHMsXHJcbiAgICAgICAgeCA9IGMgKiAoMSAtIE1hdGguYWJzKChoIC8gNjApICUgMiAtIDEpKSxcclxuICAgICAgICBtID0gdiAtIGMsXHJcbiAgICAgICAgciA9IDAsXHJcbiAgICAgICAgZyA9IDAsXHJcbiAgICAgICAgYiA9IDA7XHJcblxyXG4gICAgcmdiID0gcmdiIHx8IFswLCAwLCAwXTtcclxuXHJcbiAgICBpZiAoaCA8IDYwKSB7XHJcbiAgICAgICAgciA9IGM7XHJcbiAgICAgICAgZyA9IHg7XHJcbiAgICB9IGVsc2UgaWYgKGggPCAxMjApIHtcclxuICAgICAgICByID0geDtcclxuICAgICAgICBnID0gYztcclxuICAgIH0gZWxzZSBpZiAoaCA8IDE4MCkge1xyXG4gICAgICAgIGcgPSBjO1xyXG4gICAgICAgIGIgPSB4O1xyXG4gICAgfSBlbHNlIGlmIChoIDwgMjQwKSB7XHJcbiAgICAgICAgZyA9IHg7XHJcbiAgICAgICAgYiA9IGM7XHJcbiAgICB9IGVsc2UgaWYgKGggPCAzMDApIHtcclxuICAgICAgICByID0geDtcclxuICAgICAgICBiID0gYztcclxuICAgIH0gZWxzZSBpZiAoaCA8IDM2MCkge1xyXG4gICAgICAgIHIgPSBjO1xyXG4gICAgICAgIGIgPSB4O1xyXG4gICAgfVxyXG4gICAgcmdiWzBdID0gKChyICsgbSkgKiAyNTUpIHwgMDtcclxuICAgIHJnYlsxXSA9ICgoZyArIG0pICogMjU1KSB8IDA7XHJcbiAgICByZ2JbMl0gPSAoKGIgKyBtKSAqIDI1NSkgfCAwO1xyXG4gICAgcmV0dXJuIHJnYjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfY29tcHV0ZURpdmlzb3JzKG4pIHtcclxuICAgIHZhciBsYXJnZURpdmlzb3JzID0gW10sXHJcbiAgICAgICAgZGl2aXNvcnMgPSBbXSxcclxuICAgICAgICBpO1xyXG5cclxuICAgIGZvciAoaSA9IDE7IGkgPCBNYXRoLnNxcnQobikgKyAxOyBpKyspIHtcclxuICAgICAgICBpZiAobiAlIGkgPT09IDApIHtcclxuICAgICAgICAgICAgZGl2aXNvcnMucHVzaChpKTtcclxuICAgICAgICAgICAgaWYgKGkgIT09IG4gLyBpKSB7XHJcbiAgICAgICAgICAgICAgICBsYXJnZURpdmlzb3JzLnVuc2hpZnQoTWF0aC5mbG9vcihuIC8gaSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGRpdmlzb3JzLmNvbmNhdChsYXJnZURpdmlzb3JzKTtcclxufTtcclxuXHJcbmZ1bmN0aW9uIF9jb21wdXRlSW50ZXJzZWN0aW9uKGFycjEsIGFycjIpIHtcclxuICAgIHZhciBpID0gMCxcclxuICAgICAgICBqID0gMCxcclxuICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICB3aGlsZSAoaSA8IGFycjEubGVuZ3RoICYmIGogPCBhcnIyLmxlbmd0aCkge1xyXG4gICAgICAgIGlmIChhcnIxW2ldID09PSBhcnIyW2pdKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGFycjFbaV0pO1xyXG4gICAgICAgICAgICBpKys7XHJcbiAgICAgICAgICAgIGorKztcclxuICAgICAgICB9IGVsc2UgaWYgKGFycjFbaV0gPiBhcnIyW2pdKSB7XHJcbiAgICAgICAgICAgIGorKztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpKys7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVQYXRjaFNpemUocGF0Y2hTaXplLCBpbWdTaXplKSB7XHJcbiAgICB2YXIgZGl2aXNvcnNYID0gX2NvbXB1dGVEaXZpc29ycyhpbWdTaXplLngpLFxyXG4gICAgICAgIGRpdmlzb3JzWSA9IF9jb21wdXRlRGl2aXNvcnMoaW1nU2l6ZS55KSxcclxuICAgICAgICB3aWRlU2lkZSA9IE1hdGgubWF4KGltZ1NpemUueCwgaW1nU2l6ZS55KSxcclxuICAgICAgICBjb21tb24gPSBfY29tcHV0ZUludGVyc2VjdGlvbihkaXZpc29yc1gsIGRpdmlzb3JzWSksXHJcbiAgICAgICAgbnJPZlBhdGNoZXNMaXN0ID0gWzgsIDEwLCAxNSwgMjAsIDMyLCA2MCwgODBdLFxyXG4gICAgICAgIG5yT2ZQYXRjaGVzTWFwID0ge1xyXG4gICAgICAgICAgICBcIngtc21hbGxcIjogNSxcclxuICAgICAgICAgICAgXCJzbWFsbFwiOiA0LFxyXG4gICAgICAgICAgICBcIm1lZGl1bVwiOiAzLFxyXG4gICAgICAgICAgICBcImxhcmdlXCI6IDIsXHJcbiAgICAgICAgICAgIFwieC1sYXJnZVwiOiAxXHJcbiAgICAgICAgfSxcclxuICAgICAgICBuck9mUGF0Y2hlc0lkeCA9IG5yT2ZQYXRjaGVzTWFwW3BhdGNoU2l6ZV0gfHwgbnJPZlBhdGNoZXNNYXAubWVkaXVtLFxyXG4gICAgICAgIG5yT2ZQYXRjaGVzID0gbnJPZlBhdGNoZXNMaXN0W25yT2ZQYXRjaGVzSWR4XSxcclxuICAgICAgICBkZXNpcmVkUGF0Y2hTaXplID0gTWF0aC5mbG9vcih3aWRlU2lkZSAvIG5yT2ZQYXRjaGVzKSxcclxuICAgICAgICBvcHRpbWFsUGF0Y2hTaXplO1xyXG5cclxuICAgIGZ1bmN0aW9uIGZpbmRQYXRjaFNpemVGb3JEaXZpc29ycyhkaXZpc29ycykge1xyXG4gICAgICAgIHZhciBpID0gMCxcclxuICAgICAgICAgICAgZm91bmQgPSBkaXZpc29yc1tNYXRoLmZsb29yKGRpdmlzb3JzLmxlbmd0aCAvIDIpXTtcclxuXHJcbiAgICAgICAgd2hpbGUgKGkgPCAoZGl2aXNvcnMubGVuZ3RoIC0gMSkgJiYgZGl2aXNvcnNbaV0gPCBkZXNpcmVkUGF0Y2hTaXplKSB7XHJcbiAgICAgICAgICAgIGkrKztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGkgPiAwKSB7XHJcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkaXZpc29yc1tpXSAtIGRlc2lyZWRQYXRjaFNpemUpID4gTWF0aC5hYnMoZGl2aXNvcnNbaSAtIDFdIC0gZGVzaXJlZFBhdGNoU2l6ZSkpIHtcclxuICAgICAgICAgICAgICAgIGZvdW5kID0gZGl2aXNvcnNbaSAtIDFdO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZm91bmQgPSBkaXZpc29yc1tpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZGVzaXJlZFBhdGNoU2l6ZSAvIGZvdW5kIDwgbnJPZlBhdGNoZXNMaXN0W25yT2ZQYXRjaGVzSWR4ICsgMV0gLyBuck9mUGF0Y2hlc0xpc3RbbnJPZlBhdGNoZXNJZHhdICYmXHJcbiAgICAgICAgICAgIGRlc2lyZWRQYXRjaFNpemUgLyBmb3VuZCA+IG5yT2ZQYXRjaGVzTGlzdFtuck9mUGF0Y2hlc0lkeCAtIDFdIC8gbnJPZlBhdGNoZXNMaXN0W25yT2ZQYXRjaGVzSWR4XSApIHtcclxuICAgICAgICAgICAgcmV0dXJuIHt4OiBmb3VuZCwgeTogZm91bmR9O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBvcHRpbWFsUGF0Y2hTaXplID0gZmluZFBhdGNoU2l6ZUZvckRpdmlzb3JzKGNvbW1vbik7XHJcbiAgICBpZiAoIW9wdGltYWxQYXRjaFNpemUpIHtcclxuICAgICAgICBvcHRpbWFsUGF0Y2hTaXplID0gZmluZFBhdGNoU2l6ZUZvckRpdmlzb3JzKF9jb21wdXRlRGl2aXNvcnMod2lkZVNpZGUpKTtcclxuICAgICAgICBpZiAoIW9wdGltYWxQYXRjaFNpemUpIHtcclxuICAgICAgICAgICAgb3B0aW1hbFBhdGNoU2l6ZSA9IGZpbmRQYXRjaFNpemVGb3JEaXZpc29ycygoX2NvbXB1dGVEaXZpc29ycyhkZXNpcmVkUGF0Y2hTaXplICogbnJPZlBhdGNoZXMpKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG9wdGltYWxQYXRjaFNpemU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX3BhcnNlQ1NTRGltZW5zaW9uVmFsdWVzKHZhbHVlKSB7XHJcbiAgICB2YXIgZGltZW5zaW9uID0ge1xyXG4gICAgICAgIHZhbHVlOiBwYXJzZUZsb2F0KHZhbHVlKSxcclxuICAgICAgICB1bml0OiB2YWx1ZS5pbmRleE9mKFwiJVwiKSA9PT0gdmFsdWUubGVuZ3RoIC0gMSA/IFwiJVwiIDogXCIlXCJcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIGRpbWVuc2lvbjtcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBfZGltZW5zaW9uc0NvbnZlcnRlcnMgPSB7XHJcbiAgICB0b3A6IGZ1bmN0aW9uKGRpbWVuc2lvbiwgY29udGV4dCkge1xyXG4gICAgICAgIGlmIChkaW1lbnNpb24udW5pdCA9PT0gXCIlXCIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoY29udGV4dC5oZWlnaHQgKiAoZGltZW5zaW9uLnZhbHVlIC8gMTAwKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHJpZ2h0OiBmdW5jdGlvbihkaW1lbnNpb24sIGNvbnRleHQpIHtcclxuICAgICAgICBpZiAoZGltZW5zaW9uLnVuaXQgPT09IFwiJVwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKGNvbnRleHQud2lkdGggLSAoY29udGV4dC53aWR0aCAqIChkaW1lbnNpb24udmFsdWUgLyAxMDApKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIGJvdHRvbTogZnVuY3Rpb24oZGltZW5zaW9uLCBjb250ZXh0KSB7XHJcbiAgICAgICAgaWYgKGRpbWVuc2lvbi51bml0ID09PSBcIiVcIikge1xyXG4gICAgICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihjb250ZXh0LmhlaWdodCAtIChjb250ZXh0LmhlaWdodCAqIChkaW1lbnNpb24udmFsdWUgLyAxMDApKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIGxlZnQ6IGZ1bmN0aW9uKGRpbWVuc2lvbiwgY29udGV4dCkge1xyXG4gICAgICAgIGlmIChkaW1lbnNpb24udW5pdCA9PT0gXCIlXCIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoY29udGV4dC53aWR0aCAqIChkaW1lbnNpb24udmFsdWUgLyAxMDApKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZUltYWdlQXJlYShpbnB1dFdpZHRoLCBpbnB1dEhlaWdodCwgYXJlYSkge1xyXG4gICAgdmFyIGNvbnRleHQgPSB7d2lkdGg6IGlucHV0V2lkdGgsIGhlaWdodDogaW5wdXRIZWlnaHR9O1xyXG5cclxuICAgIHZhciBwYXJzZWRBcmVhID0gT2JqZWN0LmtleXMoYXJlYSkucmVkdWNlKGZ1bmN0aW9uKHJlc3VsdCwga2V5KSB7XHJcbiAgICAgICAgdmFyIHZhbHVlID0gYXJlYVtrZXldLFxyXG4gICAgICAgICAgICBwYXJzZWQgPSBfcGFyc2VDU1NEaW1lbnNpb25WYWx1ZXModmFsdWUpLFxyXG4gICAgICAgICAgICBjYWxjdWxhdGVkID0gX2RpbWVuc2lvbnNDb252ZXJ0ZXJzW2tleV0ocGFyc2VkLCBjb250ZXh0KTtcclxuXHJcbiAgICAgICAgcmVzdWx0W2tleV0gPSBjYWxjdWxhdGVkO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9LCB7fSk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBzeDogcGFyc2VkQXJlYS5sZWZ0LFxyXG4gICAgICAgIHN5OiBwYXJzZWRBcmVhLnRvcCxcclxuICAgICAgICBzdzogcGFyc2VkQXJlYS5yaWdodCAtIHBhcnNlZEFyZWEubGVmdCxcclxuICAgICAgICBzaDogcGFyc2VkQXJlYS5ib3R0b20gLSBwYXJzZWRBcmVhLnRvcFxyXG4gICAgfTtcclxufTtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvY29tbW9uL2N2X3V0aWxzLmpzXG4gKiovIiwiaW1wb3J0IFN1YkltYWdlIGZyb20gJy4vc3ViSW1hZ2UnO1xyXG5pbXBvcnQge2hzdjJyZ2J9IGZyb20gJy4uL2NvbW1vbi9jdl91dGlscyc7XHJcbmltcG9ydCBBcnJheUhlbHBlciBmcm9tICcuLi9jb21tb24vYXJyYXlfaGVscGVyJztcclxuY29uc3QgdmVjMiA9IHtcclxuICAgIGNsb25lOiByZXF1aXJlKCdnbC12ZWMyL2Nsb25lJyksXHJcbn07XHJcblxyXG4vKipcclxuICogUmVwcmVzZW50cyBhIGJhc2ljIGltYWdlIGNvbWJpbmluZyB0aGUgZGF0YSBhbmQgc2l6ZS5cclxuICogSW4gYWRkaXRpb24sIHNvbWUgbWV0aG9kcyBmb3IgbWFuaXB1bGF0aW9uIGFyZSBjb250YWluZWQuXHJcbiAqIEBwYXJhbSBzaXplIHt4LHl9IFRoZSBzaXplIG9mIHRoZSBpbWFnZSBpbiBwaXhlbFxyXG4gKiBAcGFyYW0gZGF0YSB7QXJyYXl9IElmIGdpdmVuLCBhIGZsYXQgYXJyYXkgY29udGFpbmluZyB0aGUgcGl4ZWwgZGF0YVxyXG4gKiBAcGFyYW0gQXJyYXlUeXBlIHtUeXBlfSBJZiBnaXZlbiwgdGhlIGRlc2lyZWQgRGF0YVR5cGUgb2YgdGhlIEFycmF5IChtYXkgYmUgdHlwZWQvbm9uLXR5cGVkKVxyXG4gKiBAcGFyYW0gaW5pdGlhbGl6ZSB7Qm9vbGVhbn0gSW5kaWNhdGluZyBpZiB0aGUgYXJyYXkgc2hvdWxkIGJlIGluaXRpYWxpemVkIG9uIGNyZWF0aW9uLlxyXG4gKiBAcmV0dXJucyB7SW1hZ2VXcmFwcGVyfVxyXG4gKi9cclxuZnVuY3Rpb24gSW1hZ2VXcmFwcGVyKHNpemUsIGRhdGEsIEFycmF5VHlwZSwgaW5pdGlhbGl6ZSkge1xyXG4gICAgaWYgKCFkYXRhKSB7XHJcbiAgICAgICAgaWYgKEFycmF5VHlwZSkge1xyXG4gICAgICAgICAgICB0aGlzLmRhdGEgPSBuZXcgQXJyYXlUeXBlKHNpemUueCAqIHNpemUueSk7XHJcbiAgICAgICAgICAgIGlmIChBcnJheVR5cGUgPT09IEFycmF5ICYmIGluaXRpYWxpemUpIHtcclxuICAgICAgICAgICAgICAgIEFycmF5SGVscGVyLmluaXQodGhpcy5kYXRhLCAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KHNpemUueCAqIHNpemUueSk7XHJcbiAgICAgICAgICAgIGlmIChVaW50OEFycmF5ID09PSBBcnJheSAmJiBpbml0aWFsaXplKSB7XHJcbiAgICAgICAgICAgICAgICBBcnJheUhlbHBlci5pbml0KHRoaXMuZGF0YSwgMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XHJcbiAgICB9XHJcbiAgICB0aGlzLnNpemUgPSBzaXplO1xyXG59XHJcblxyXG4vKipcclxuICogdGVzdHMgaWYgYSBwb3NpdGlvbiBpcyB3aXRoaW4gdGhlIGltYWdlIHdpdGggYSBnaXZlbiBvZmZzZXRcclxuICogQHBhcmFtIGltZ1JlZiB7eCwgeX0gVGhlIGxvY2F0aW9uIHRvIHRlc3RcclxuICogQHBhcmFtIGJvcmRlciBOdW1iZXIgdGhlIHBhZGRpbmcgdmFsdWUgaW4gcGl4ZWxcclxuICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgbG9jYXRpb24gaW5zaWRlIHRoZSBpbWFnZSdzIGJvcmRlciwgZmFsc2Ugb3RoZXJ3aXNlXHJcbiAqIEBzZWUgY3ZkL2ltYWdlLmhcclxuICovXHJcbkltYWdlV3JhcHBlci5wcm90b3R5cGUuaW5JbWFnZVdpdGhCb3JkZXIgPSBmdW5jdGlvbihpbWdSZWYsIGJvcmRlcikge1xyXG4gICAgcmV0dXJuIChpbWdSZWYueCA+PSBib3JkZXIpXHJcbiAgICAgICAgJiYgKGltZ1JlZi55ID49IGJvcmRlcilcclxuICAgICAgICAmJiAoaW1nUmVmLnggPCAodGhpcy5zaXplLnggLSBib3JkZXIpKVxyXG4gICAgICAgICYmIChpbWdSZWYueSA8ICh0aGlzLnNpemUueSAtIGJvcmRlcikpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFBlcmZvcm1zIGJpbGluZWFyIHNhbXBsaW5nXHJcbiAqIEBwYXJhbSBpbkltZyBJbWFnZSB0byBleHRyYWN0IHNhbXBsZSBmcm9tXHJcbiAqIEBwYXJhbSB4IHRoZSB4LWNvb3JkaW5hdGVcclxuICogQHBhcmFtIHkgdGhlIHktY29vcmRpbmF0ZVxyXG4gKiBAcmV0dXJucyB0aGUgc2FtcGxlZCB2YWx1ZVxyXG4gKiBAc2VlIGN2ZC92aXNpb24uaFxyXG4gKi9cclxuSW1hZ2VXcmFwcGVyLnNhbXBsZSA9IGZ1bmN0aW9uKGluSW1nLCB4LCB5KSB7XHJcbiAgICB2YXIgbHggPSBNYXRoLmZsb29yKHgpO1xyXG4gICAgdmFyIGx5ID0gTWF0aC5mbG9vcih5KTtcclxuICAgIHZhciB3ID0gaW5JbWcuc2l6ZS54O1xyXG4gICAgdmFyIGJhc2UgPSBseSAqIGluSW1nLnNpemUueCArIGx4O1xyXG4gICAgdmFyIGEgPSBpbkltZy5kYXRhW2Jhc2UgKyAwXTtcclxuICAgIHZhciBiID0gaW5JbWcuZGF0YVtiYXNlICsgMV07XHJcbiAgICB2YXIgYyA9IGluSW1nLmRhdGFbYmFzZSArIHddO1xyXG4gICAgdmFyIGQgPSBpbkltZy5kYXRhW2Jhc2UgKyB3ICsgMV07XHJcbiAgICB2YXIgZSA9IGEgLSBiO1xyXG4gICAgeCAtPSBseDtcclxuICAgIHkgLT0gbHk7XHJcblxyXG4gICAgdmFyIHJlc3VsdCA9IE1hdGguZmxvb3IoeCAqICh5ICogKGUgLSBjICsgZCkgLSBlKSArIHkgKiAoYyAtIGEpICsgYSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEluaXRpYWxpemVzIGEgZ2l2ZW4gYXJyYXkuIFNldHMgZWFjaCBlbGVtZW50IHRvIHplcm8uXHJcbiAqIEBwYXJhbSBhcnJheSB7QXJyYXl9IFRoZSBhcnJheSB0byBpbml0aWFsaXplXHJcbiAqL1xyXG5JbWFnZVdyYXBwZXIuY2xlYXJBcnJheSA9IGZ1bmN0aW9uKGFycmF5KSB7XHJcbiAgICB2YXIgbCA9IGFycmF5Lmxlbmd0aDtcclxuICAgIHdoaWxlIChsLS0pIHtcclxuICAgICAgICBhcnJheVtsXSA9IDA7XHJcbiAgICB9XHJcbn07XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyBhIHtTdWJJbWFnZX0gZnJvbSB0aGUgY3VycmVudCBpbWFnZSAoe3RoaXN9KS5cclxuICogQHBhcmFtIGZyb20ge0ltYWdlUmVmfSBUaGUgcG9zaXRpb24gd2hlcmUgdG8gc3RhcnQgdGhlIHtTdWJJbWFnZX0gZnJvbS4gKHRvcC1sZWZ0IGNvcm5lcilcclxuICogQHBhcmFtIHNpemUge0ltYWdlUmVmfSBUaGUgc2l6ZSBvZiB0aGUgcmVzdWx0aW5nIGltYWdlXHJcbiAqIEByZXR1cm5zIHtTdWJJbWFnZX0gQSBzaGFyZWQgcGFydCBvZiB0aGUgb3JpZ2luYWwgaW1hZ2VcclxuICovXHJcbkltYWdlV3JhcHBlci5wcm90b3R5cGUuc3ViSW1hZ2UgPSBmdW5jdGlvbihmcm9tLCBzaXplKSB7XHJcbiAgICByZXR1cm4gbmV3IFN1YkltYWdlKGZyb20sIHNpemUsIHRoaXMpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZXMgYW4ge0ltYWdlV3JhcHBlcikgYW5kIGNvcGllcyB0aGUgbmVlZGVkIHVuZGVybHlpbmcgaW1hZ2UtZGF0YSBhcmVhXHJcbiAqIEBwYXJhbSBpbWFnZVdyYXBwZXIge0ltYWdlV3JhcHBlcn0gVGhlIHRhcmdldCB7SW1hZ2VXcmFwcGVyfSB3aGVyZSB0aGUgZGF0YSBzaG91bGQgYmUgY29waWVkXHJcbiAqIEBwYXJhbSBmcm9tIHtJbWFnZVJlZn0gVGhlIGxvY2F0aW9uIHdoZXJlIHRvIGNvcHkgZnJvbSAodG9wLWxlZnQgbG9jYXRpb24pXHJcbiAqL1xyXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLnN1YkltYWdlQXNDb3B5ID0gZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBmcm9tKSB7XHJcbiAgICB2YXIgc2l6ZVkgPSBpbWFnZVdyYXBwZXIuc2l6ZS55LCBzaXplWCA9IGltYWdlV3JhcHBlci5zaXplLng7XHJcbiAgICB2YXIgeCwgeTtcclxuICAgIGZvciAoIHggPSAwOyB4IDwgc2l6ZVg7IHgrKykge1xyXG4gICAgICAgIGZvciAoIHkgPSAwOyB5IDwgc2l6ZVk7IHkrKykge1xyXG4gICAgICAgICAgICBpbWFnZVdyYXBwZXIuZGF0YVt5ICogc2l6ZVggKyB4XSA9IHRoaXMuZGF0YVsoZnJvbS55ICsgeSkgKiB0aGlzLnNpemUueCArIGZyb20ueCArIHhdO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbkltYWdlV3JhcHBlci5wcm90b3R5cGUuY29weVRvID0gZnVuY3Rpb24oaW1hZ2VXcmFwcGVyKSB7XHJcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5kYXRhLmxlbmd0aCwgc3JjRGF0YSA9IHRoaXMuZGF0YSwgZHN0RGF0YSA9IGltYWdlV3JhcHBlci5kYXRhO1xyXG5cclxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xyXG4gICAgICAgIGRzdERhdGFbbGVuZ3RoXSA9IHNyY0RhdGFbbGVuZ3RoXTtcclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXRyaWV2ZXMgYSBnaXZlbiBwaXhlbCBwb3NpdGlvbiBmcm9tIHRoZSBpbWFnZVxyXG4gKiBAcGFyYW0geCB7TnVtYmVyfSBUaGUgeC1wb3NpdGlvblxyXG4gKiBAcGFyYW0geSB7TnVtYmVyfSBUaGUgeS1wb3NpdGlvblxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgZ3JheXNjYWxlIHZhbHVlIGF0IHRoZSBwaXhlbC1wb3NpdGlvblxyXG4gKi9cclxuSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbih4LCB5KSB7XHJcbiAgICByZXR1cm4gdGhpcy5kYXRhW3kgKiB0aGlzLnNpemUueCArIHhdO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHJpZXZlcyBhIGdpdmVuIHBpeGVsIHBvc2l0aW9uIGZyb20gdGhlIGltYWdlXHJcbiAqIEBwYXJhbSB4IHtOdW1iZXJ9IFRoZSB4LXBvc2l0aW9uXHJcbiAqIEBwYXJhbSB5IHtOdW1iZXJ9IFRoZSB5LXBvc2l0aW9uXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBncmF5c2NhbGUgdmFsdWUgYXQgdGhlIHBpeGVsLXBvc2l0aW9uXHJcbiAqL1xyXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLmdldFNhZmUgPSBmdW5jdGlvbih4LCB5KSB7XHJcbiAgICB2YXIgaTtcclxuXHJcbiAgICBpZiAoIXRoaXMuaW5kZXhNYXBwaW5nKSB7XHJcbiAgICAgICAgdGhpcy5pbmRleE1hcHBpbmcgPSB7XHJcbiAgICAgICAgICAgIHg6IFtdLFxyXG4gICAgICAgICAgICB5OiBbXVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMuc2l6ZS54OyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy5pbmRleE1hcHBpbmcueFtpXSA9IGk7XHJcbiAgICAgICAgICAgIHRoaXMuaW5kZXhNYXBwaW5nLnhbaSArIHRoaXMuc2l6ZS54XSA9IGk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLnNpemUueTsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaW5kZXhNYXBwaW5nLnlbaV0gPSBpO1xyXG4gICAgICAgICAgICB0aGlzLmluZGV4TWFwcGluZy55W2kgKyB0aGlzLnNpemUueV0gPSBpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmRhdGFbKHRoaXMuaW5kZXhNYXBwaW5nLnlbeSArIHRoaXMuc2l6ZS55XSkgKiB0aGlzLnNpemUueCArIHRoaXMuaW5kZXhNYXBwaW5nLnhbeCArIHRoaXMuc2l6ZS54XV07XHJcbn07XHJcblxyXG4vKipcclxuICogU2V0cyBhIGdpdmVuIHBpeGVsIHBvc2l0aW9uIGluIHRoZSBpbWFnZVxyXG4gKiBAcGFyYW0geCB7TnVtYmVyfSBUaGUgeC1wb3NpdGlvblxyXG4gKiBAcGFyYW0geSB7TnVtYmVyfSBUaGUgeS1wb3NpdGlvblxyXG4gKiBAcGFyYW0gdmFsdWUge051bWJlcn0gVGhlIGdyYXlzY2FsZSB2YWx1ZSB0byBzZXRcclxuICogQHJldHVybnMge0ltYWdlV3JhcHBlcn0gVGhlIEltYWdlIGl0c2VsZiAoZm9yIHBvc3NpYmxlIGNoYWluaW5nKVxyXG4gKi9cclxuSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbih4LCB5LCB2YWx1ZSkge1xyXG4gICAgdGhpcy5kYXRhW3kgKiB0aGlzLnNpemUueCArIHhdID0gdmFsdWU7XHJcbiAgICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBTZXRzIHRoZSBib3JkZXIgb2YgdGhlIGltYWdlICgxIHBpeGVsKSB0byB6ZXJvXHJcbiAqL1xyXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLnplcm9Cb3JkZXIgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciBpLCB3aWR0aCA9IHRoaXMuc2l6ZS54LCBoZWlnaHQgPSB0aGlzLnNpemUueSwgZGF0YSA9IHRoaXMuZGF0YTtcclxuICAgIGZvciAoIGkgPSAwOyBpIDwgd2lkdGg7IGkrKykge1xyXG4gICAgICAgIGRhdGFbaV0gPSBkYXRhWyhoZWlnaHQgLSAxKSAqIHdpZHRoICsgaV0gPSAwO1xyXG4gICAgfVxyXG4gICAgZm9yICggaSA9IDE7IGkgPCBoZWlnaHQgLSAxOyBpKyspIHtcclxuICAgICAgICBkYXRhW2kgKiB3aWR0aF0gPSBkYXRhW2kgKiB3aWR0aCArICh3aWR0aCAtIDEpXSA9IDA7XHJcbiAgICB9XHJcbn07XHJcblxyXG4vKipcclxuICogSW52ZXJ0cyBhIGJpbmFyeSBpbWFnZSBpbiBwbGFjZVxyXG4gKi9cclxuSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS5pbnZlcnQgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciBkYXRhID0gdGhpcy5kYXRhLCBsZW5ndGggPSBkYXRhLmxlbmd0aDtcclxuXHJcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcclxuICAgICAgICBkYXRhW2xlbmd0aF0gPSBkYXRhW2xlbmd0aF0gPyAwIDogMTtcclxuICAgIH1cclxufTtcclxuXHJcbkltYWdlV3JhcHBlci5wcm90b3R5cGUuY29udm9sdmUgPSBmdW5jdGlvbihrZXJuZWwpIHtcclxuICAgIHZhciB4LCB5LCBreCwga3ksIGtTaXplID0gKGtlcm5lbC5sZW5ndGggLyAyKSB8IDAsIGFjY3UgPSAwO1xyXG4gICAgZm9yICggeSA9IDA7IHkgPCB0aGlzLnNpemUueTsgeSsrKSB7XHJcbiAgICAgICAgZm9yICggeCA9IDA7IHggPCB0aGlzLnNpemUueDsgeCsrKSB7XHJcbiAgICAgICAgICAgIGFjY3UgPSAwO1xyXG4gICAgICAgICAgICBmb3IgKCBreSA9IC1rU2l6ZTsga3kgPD0ga1NpemU7IGt5KyspIHtcclxuICAgICAgICAgICAgICAgIGZvciAoIGt4ID0gLWtTaXplOyBreCA8PSBrU2l6ZTsga3grKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGFjY3UgKz0ga2VybmVsW2t5ICsga1NpemVdW2t4ICsga1NpemVdICogdGhpcy5nZXRTYWZlKHggKyBreCwgeSArIGt5KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmRhdGFbeSAqIHRoaXMuc2l6ZS54ICsgeF0gPSBhY2N1O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbkltYWdlV3JhcHBlci5wcm90b3R5cGUubW9tZW50cyA9IGZ1bmN0aW9uKGxhYmVsY291bnQpIHtcclxuICAgIHZhciBkYXRhID0gdGhpcy5kYXRhLFxyXG4gICAgICAgIHgsXHJcbiAgICAgICAgeSxcclxuICAgICAgICBoZWlnaHQgPSB0aGlzLnNpemUueSxcclxuICAgICAgICB3aWR0aCA9IHRoaXMuc2l6ZS54LFxyXG4gICAgICAgIHZhbCxcclxuICAgICAgICB5c3EsXHJcbiAgICAgICAgbGFiZWxzdW0gPSBbXSxcclxuICAgICAgICBpLFxyXG4gICAgICAgIGxhYmVsLFxyXG4gICAgICAgIG11MTEsXHJcbiAgICAgICAgbXUwMixcclxuICAgICAgICBtdTIwLFxyXG4gICAgICAgIHhfLFxyXG4gICAgICAgIHlfLFxyXG4gICAgICAgIHRtcCxcclxuICAgICAgICByZXN1bHQgPSBbXSxcclxuICAgICAgICBQSSA9IE1hdGguUEksXHJcbiAgICAgICAgUElfNCA9IFBJIC8gNDtcclxuXHJcbiAgICBpZiAobGFiZWxjb3VudCA8PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IGxhYmVsY291bnQ7IGkrKykge1xyXG4gICAgICAgIGxhYmVsc3VtW2ldID0ge1xyXG4gICAgICAgICAgICBtMDA6IDAsXHJcbiAgICAgICAgICAgIG0wMTogMCxcclxuICAgICAgICAgICAgbTEwOiAwLFxyXG4gICAgICAgICAgICBtMTE6IDAsXHJcbiAgICAgICAgICAgIG0wMjogMCxcclxuICAgICAgICAgICAgbTIwOiAwLFxyXG4gICAgICAgICAgICB0aGV0YTogMCxcclxuICAgICAgICAgICAgcmFkOiAwXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7XHJcbiAgICAgICAgeXNxID0geSAqIHk7XHJcbiAgICAgICAgZm9yICggeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7XHJcbiAgICAgICAgICAgIHZhbCA9IGRhdGFbeSAqIHdpZHRoICsgeF07XHJcbiAgICAgICAgICAgIGlmICh2YWwgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBsYWJlbCA9IGxhYmVsc3VtW3ZhbCAtIDFdO1xyXG4gICAgICAgICAgICAgICAgbGFiZWwubTAwICs9IDE7XHJcbiAgICAgICAgICAgICAgICBsYWJlbC5tMDEgKz0geTtcclxuICAgICAgICAgICAgICAgIGxhYmVsLm0xMCArPSB4O1xyXG4gICAgICAgICAgICAgICAgbGFiZWwubTExICs9IHggKiB5O1xyXG4gICAgICAgICAgICAgICAgbGFiZWwubTAyICs9IHlzcTtcclxuICAgICAgICAgICAgICAgIGxhYmVsLm0yMCArPSB4ICogeDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IGxhYmVsY291bnQ7IGkrKykge1xyXG4gICAgICAgIGxhYmVsID0gbGFiZWxzdW1baV07XHJcbiAgICAgICAgaWYgKCFpc05hTihsYWJlbC5tMDApICYmIGxhYmVsLm0wMCAhPT0gMCkge1xyXG4gICAgICAgICAgICB4XyA9IGxhYmVsLm0xMCAvIGxhYmVsLm0wMDtcclxuICAgICAgICAgICAgeV8gPSBsYWJlbC5tMDEgLyBsYWJlbC5tMDA7XHJcbiAgICAgICAgICAgIG11MTEgPSBsYWJlbC5tMTEgLyBsYWJlbC5tMDAgLSB4XyAqIHlfO1xyXG4gICAgICAgICAgICBtdTAyID0gbGFiZWwubTAyIC8gbGFiZWwubTAwIC0geV8gKiB5XztcclxuICAgICAgICAgICAgbXUyMCA9IGxhYmVsLm0yMCAvIGxhYmVsLm0wMCAtIHhfICogeF87XHJcbiAgICAgICAgICAgIHRtcCA9IChtdTAyIC0gbXUyMCkgLyAoMiAqIG11MTEpO1xyXG4gICAgICAgICAgICB0bXAgPSAwLjUgKiBNYXRoLmF0YW4odG1wKSArIChtdTExID49IDAgPyBQSV80IDogLVBJXzQgKSArIFBJO1xyXG4gICAgICAgICAgICBsYWJlbC50aGV0YSA9ICh0bXAgKiAxODAgLyBQSSArIDkwKSAlIDE4MCAtIDkwO1xyXG4gICAgICAgICAgICBpZiAobGFiZWwudGhldGEgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICBsYWJlbC50aGV0YSArPSAxODA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbGFiZWwucmFkID0gdG1wID4gUEkgPyB0bXAgLSBQSSA6IHRtcDtcclxuICAgICAgICAgICAgbGFiZWwudmVjID0gdmVjMi5jbG9uZShbTWF0aC5jb3ModG1wKSwgTWF0aC5zaW4odG1wKV0pO1xyXG4gICAgICAgICAgICByZXN1bHQucHVzaChsYWJlbCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn07XHJcblxyXG4vKipcclxuICogRGlzcGxheXMgdGhlIHtJbWFnZVdyYXBwZXJ9IGluIGEgZ2l2ZW4gY2FudmFzXHJcbiAqIEBwYXJhbSBjYW52YXMge0NhbnZhc30gVGhlIGNhbnZhcyBlbGVtZW50IHRvIHdyaXRlIHRvXHJcbiAqIEBwYXJhbSBzY2FsZSB7TnVtYmVyfSBTY2FsZSB3aGljaCBpcyBhcHBsaWVkIHRvIGVhY2ggcGl4ZWwtdmFsdWVcclxuICovXHJcbkltYWdlV3JhcHBlci5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKGNhbnZhcywgc2NhbGUpIHtcclxuICAgIHZhciBjdHgsXHJcbiAgICAgICAgZnJhbWUsXHJcbiAgICAgICAgZGF0YSxcclxuICAgICAgICBjdXJyZW50LFxyXG4gICAgICAgIHBpeGVsLFxyXG4gICAgICAgIHgsXHJcbiAgICAgICAgeTtcclxuXHJcbiAgICBpZiAoIXNjYWxlKSB7XHJcbiAgICAgICAgc2NhbGUgPSAxLjA7XHJcbiAgICB9XHJcbiAgICBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgIGNhbnZhcy53aWR0aCA9IHRoaXMuc2l6ZS54O1xyXG4gICAgY2FudmFzLmhlaWdodCA9IHRoaXMuc2l6ZS55O1xyXG4gICAgZnJhbWUgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XHJcbiAgICBkYXRhID0gZnJhbWUuZGF0YTtcclxuICAgIGN1cnJlbnQgPSAwO1xyXG4gICAgZm9yICh5ID0gMDsgeSA8IHRoaXMuc2l6ZS55OyB5KyspIHtcclxuICAgICAgICBmb3IgKHggPSAwOyB4IDwgdGhpcy5zaXplLng7IHgrKykge1xyXG4gICAgICAgICAgICBwaXhlbCA9IHkgKiB0aGlzLnNpemUueCArIHg7XHJcbiAgICAgICAgICAgIGN1cnJlbnQgPSB0aGlzLmdldCh4LCB5KSAqIHNjYWxlO1xyXG4gICAgICAgICAgICBkYXRhW3BpeGVsICogNCArIDBdID0gY3VycmVudDtcclxuICAgICAgICAgICAgZGF0YVtwaXhlbCAqIDQgKyAxXSA9IGN1cnJlbnQ7XHJcbiAgICAgICAgICAgIGRhdGFbcGl4ZWwgKiA0ICsgMl0gPSBjdXJyZW50O1xyXG4gICAgICAgICAgICBkYXRhW3BpeGVsICogNCArIDNdID0gMjU1O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vZnJhbWUuZGF0YSA9IGRhdGE7XHJcbiAgICBjdHgucHV0SW1hZ2VEYXRhKGZyYW1lLCAwLCAwKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBEaXNwbGF5cyB0aGUge1N1YkltYWdlfSBpbiBhIGdpdmVuIGNhbnZhc1xyXG4gKiBAcGFyYW0gY2FudmFzIHtDYW52YXN9IFRoZSBjYW52YXMgZWxlbWVudCB0byB3cml0ZSB0b1xyXG4gKiBAcGFyYW0gc2NhbGUge051bWJlcn0gU2NhbGUgd2hpY2ggaXMgYXBwbGllZCB0byBlYWNoIHBpeGVsLXZhbHVlXHJcbiAqL1xyXG5JbWFnZVdyYXBwZXIucHJvdG90eXBlLm92ZXJsYXkgPSBmdW5jdGlvbihjYW52YXMsIHNjYWxlLCBmcm9tKSB7XHJcbiAgICBpZiAoIXNjYWxlIHx8IHNjYWxlIDwgMCB8fCBzY2FsZSA+IDM2MCkge1xyXG4gICAgICAgIHNjYWxlID0gMzYwO1xyXG4gICAgfVxyXG4gICAgdmFyIGhzdiA9IFswLCAxLCAxXTtcclxuICAgIHZhciByZ2IgPSBbMCwgMCwgMF07XHJcbiAgICB2YXIgd2hpdGVSZ2IgPSBbMjU1LCAyNTUsIDI1NV07XHJcbiAgICB2YXIgYmxhY2tSZ2IgPSBbMCwgMCwgMF07XHJcbiAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XHJcbiAgICB2YXIgZnJhbWUgPSBjdHguZ2V0SW1hZ2VEYXRhKGZyb20ueCwgZnJvbS55LCB0aGlzLnNpemUueCwgdGhpcy5zaXplLnkpO1xyXG4gICAgdmFyIGRhdGEgPSBmcmFtZS5kYXRhO1xyXG4gICAgdmFyIGxlbmd0aCA9IHRoaXMuZGF0YS5sZW5ndGg7XHJcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcclxuICAgICAgICBoc3ZbMF0gPSB0aGlzLmRhdGFbbGVuZ3RoXSAqIHNjYWxlO1xyXG4gICAgICAgIHJlc3VsdCA9IGhzdlswXSA8PSAwID8gd2hpdGVSZ2IgOiBoc3ZbMF0gPj0gMzYwID8gYmxhY2tSZ2IgOiBoc3YycmdiKGhzdiwgcmdiKTtcclxuICAgICAgICBkYXRhW2xlbmd0aCAqIDQgKyAwXSA9IHJlc3VsdFswXTtcclxuICAgICAgICBkYXRhW2xlbmd0aCAqIDQgKyAxXSA9IHJlc3VsdFsxXTtcclxuICAgICAgICBkYXRhW2xlbmd0aCAqIDQgKyAyXSA9IHJlc3VsdFsyXTtcclxuICAgICAgICBkYXRhW2xlbmd0aCAqIDQgKyAzXSA9IDI1NTtcclxuICAgIH1cclxuICAgIGN0eC5wdXRJbWFnZURhdGEoZnJhbWUsIGZyb20ueCwgZnJvbS55KTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IEltYWdlV3JhcHBlcjtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvY29tbW9uL2ltYWdlX3dyYXBwZXIuanNcbiAqKi8iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5yZWR1Y2VgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpbml0QWNjdW1dIFNwZWNpZnkgdXNpbmcgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YCBhcyB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gYXJyYXlSZWR1Y2UoYXJyYXksIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgaW5pdEFjY3VtKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIGlmIChpbml0QWNjdW0gJiYgbGVuZ3RoKSB7XG4gICAgYWNjdW11bGF0b3IgPSBhcnJheVsrK2luZGV4XTtcbiAgfVxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGFjY3VtdWxhdG9yID0gaXRlcmF0ZWUoYWNjdW11bGF0b3IsIGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgfVxuICByZXR1cm4gYWNjdW11bGF0b3I7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlSZWR1Y2U7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2FycmF5UmVkdWNlLmpzXG4gKiogbW9kdWxlIGlkID0gMTlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBjb3B5T2JqZWN0V2l0aCA9IHJlcXVpcmUoJy4vX2NvcHlPYmplY3RXaXRoJyk7XG5cbi8qKlxuICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBjb3B5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gY29weU9iamVjdChzb3VyY2UsIHByb3BzLCBvYmplY3QpIHtcbiAgcmV0dXJuIGNvcHlPYmplY3RXaXRoKHNvdXJjZSwgcHJvcHMsIG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29weU9iamVjdDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fY29weU9iamVjdC5qc1xuICoqIG1vZHVsZSBpZCA9IDIwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QgaW4gSUUgPCA5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNIb3N0T2JqZWN0KHZhbHVlKSB7XG4gIC8vIE1hbnkgaG9zdCBvYmplY3RzIGFyZSBgT2JqZWN0YCBvYmplY3RzIHRoYXQgY2FuIGNvZXJjZSB0byBzdHJpbmdzXG4gIC8vIGRlc3BpdGUgaGF2aW5nIGltcHJvcGVybHkgZGVmaW5lZCBgdG9TdHJpbmdgIG1ldGhvZHMuXG4gIHZhciByZXN1bHQgPSBmYWxzZTtcbiAgaWYgKHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gISEodmFsdWUgKyAnJyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSG9zdE9iamVjdDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faXNIb3N0T2JqZWN0LmpzXG4gKiogbW9kdWxlIGlkID0gMjFcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovXG52YXIgcmVJc1VpbnQgPSAvXig/OjB8WzEtOV1cXGQqKSQvO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHwgcmVJc1VpbnQudGVzdCh2YWx1ZSkpID8gK3ZhbHVlIDogLTE7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcbiAgcmV0dXJuIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGg7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faXNJbmRleC5qc1xuICoqIG1vZHVsZSBpZCA9IDIyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxpa2VseSBhIHByb3RvdHlwZSBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm90b3R5cGUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNQcm90b3R5cGUodmFsdWUpIHtcbiAgdmFyIEN0b3IgPSB2YWx1ZSAmJiB2YWx1ZS5jb25zdHJ1Y3RvcixcbiAgICAgIHByb3RvID0gKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUpIHx8IG9iamVjdFByb3RvO1xuXG4gIHJldHVybiB2YWx1ZSA9PT0gcHJvdG87XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQcm90b3R5cGU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2lzUHJvdG90eXBlLmpzXG4gKiogbW9kdWxlIGlkID0gMjNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc0FycmF5TGlrZU9iamVjdCA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2VPYmplY3QnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gIC8vIFNhZmFyaSA4LjEgaW5jb3JyZWN0bHkgbWFrZXMgYGFyZ3VtZW50cy5jYWxsZWVgIGVudW1lcmFibGUgaW4gc3RyaWN0IG1vZGUuXG4gIHJldHVybiBpc0FycmF5TGlrZU9iamVjdCh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgKCFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJykgfHwgb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gYXJnc1RhZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcmd1bWVudHM7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaXNBcmd1bWVudHMuanNcbiAqKiBtb2R1bGUgaWQgPSAyNFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGdldExlbmd0aCA9IHJlcXVpcmUoJy4vX2dldExlbmd0aCcpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgYXJyYXktbGlrZSBpZiBpdCdzXG4gKiBub3QgYSBmdW5jdGlvbiBhbmQgaGFzIGEgYHZhbHVlLmxlbmd0aGAgdGhhdCdzIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIG9yXG4gKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoJ2FiYycpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKGdldExlbmd0aCh2YWx1ZSkpICYmICFpc0Z1bmN0aW9uKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5TGlrZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pc0FycmF5TGlrZS5qc1xuICoqIG1vZHVsZSBpZCA9IDI1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzQXJyYXlMaWtlYCBleGNlcHQgdGhhdCBpdCBhbHNvIGNoZWNrcyBpZiBgdmFsdWVgXG4gKiBpcyBhbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LWxpa2Ugb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheUxpa2VPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlT2JqZWN0KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2VPYmplY3QoJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXlMaWtlT2JqZWN0KF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5TGlrZU9iamVjdCh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0FycmF5TGlrZSh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2VPYmplY3Q7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaXNBcnJheUxpa2VPYmplY3QuanNcbiAqKiBtb2R1bGUgaWQgPSAyNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBhcnJheS1saWtlIGxlbmd0aC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyBsb29zZWx5IGJhc2VkIG9uIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgbGVuZ3RoLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNMZW5ndGgoMyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0xlbmd0aChOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0xlbmd0aChJbmZpbml0eSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNMZW5ndGgoJzMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTGVuZ3RoKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiZcbiAgICB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMZW5ndGg7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaXNMZW5ndGguanNcbiAqKiBtb2R1bGUgaWQgPSAyN1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGJhc2VNZXJnZSA9IHJlcXVpcmUoJy4vX2Jhc2VNZXJnZScpLFxuICAgIGNyZWF0ZUFzc2lnbmVyID0gcmVxdWlyZSgnLi9fY3JlYXRlQXNzaWduZXInKTtcblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmFzc2lnbmAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgbWVyZ2VzIG93biBhbmRcbiAqIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2Ygc291cmNlIG9iamVjdHMgaW50byB0aGUgZGVzdGluYXRpb25cbiAqIG9iamVjdC4gU291cmNlIHByb3BlcnRpZXMgdGhhdCByZXNvbHZlIHRvIGB1bmRlZmluZWRgIGFyZSBza2lwcGVkIGlmIGFcbiAqIGRlc3RpbmF0aW9uIHZhbHVlIGV4aXN0cy4gQXJyYXkgYW5kIHBsYWluIG9iamVjdCBwcm9wZXJ0aWVzIGFyZSBtZXJnZWRcbiAqIHJlY3Vyc2l2ZWx5Lk90aGVyIG9iamVjdHMgYW5kIHZhbHVlIHR5cGVzIGFyZSBvdmVycmlkZGVuIGJ5IGFzc2lnbm1lbnQuXG4gKiBTb3VyY2Ugb2JqZWN0cyBhcmUgYXBwbGllZCBmcm9tIGxlZnQgdG8gcmlnaHQuIFN1YnNlcXVlbnQgc291cmNlc1xuICogb3ZlcndyaXRlIHByb3BlcnR5IGFzc2lnbm1lbnRzIG9mIHByZXZpb3VzIHNvdXJjZXMuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHVzZXJzID0ge1xuICogICAnZGF0YSc6IFt7ICd1c2VyJzogJ2Jhcm5leScgfSwgeyAndXNlcic6ICdmcmVkJyB9XVxuICogfTtcbiAqXG4gKiB2YXIgYWdlcyA9IHtcbiAqICAgJ2RhdGEnOiBbeyAnYWdlJzogMzYgfSwgeyAnYWdlJzogNDAgfV1cbiAqIH07XG4gKlxuICogXy5tZXJnZSh1c2VycywgYWdlcyk7XG4gKiAvLyA9PiB7ICdkYXRhJzogW3sgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH0sIHsgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9XSB9XG4gKi9cbnZhciBtZXJnZSA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCkge1xuICBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4KTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG1lcmdlO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL21lcmdlLmpzXG4gKiogbW9kdWxlIGlkID0gMjhcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxyXG4gKiBodHRwOi8vd3d3LmNvZGVwcm9qZWN0LmNvbS9UaXBzLzQwNzE3Mi9Db25uZWN0ZWQtQ29tcG9uZW50LUxhYmVsaW5nLWFuZC1WZWN0b3JpemF0aW9uXHJcbiAqL1xyXG52YXIgVHJhY2VyID0ge1xyXG4gICAgc2VhcmNoRGlyZWN0aW9uczogW1swLCAxXSwgWzEsIDFdLCBbMSwgMF0sIFsxLCAtMV0sIFswLCAtMV0sIFstMSwgLTFdLCBbLTEsIDBdLCBbLTEsIDFdXSxcclxuICAgIGNyZWF0ZTogZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBsYWJlbFdyYXBwZXIpIHtcclxuICAgICAgICB2YXIgaW1hZ2VEYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGEsXHJcbiAgICAgICAgICAgIGxhYmVsRGF0YSA9IGxhYmVsV3JhcHBlci5kYXRhLFxyXG4gICAgICAgICAgICBzZWFyY2hEaXJlY3Rpb25zID0gdGhpcy5zZWFyY2hEaXJlY3Rpb25zLFxyXG4gICAgICAgICAgICB3aWR0aCA9IGltYWdlV3JhcHBlci5zaXplLngsXHJcbiAgICAgICAgICAgIHBvcztcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gdHJhY2UoY3VycmVudCwgY29sb3IsIGxhYmVsLCBlZGdlbGFiZWwpIHtcclxuICAgICAgICAgICAgdmFyIGksXHJcbiAgICAgICAgICAgICAgICB5LFxyXG4gICAgICAgICAgICAgICAgeDtcclxuXHJcbiAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgNzsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB5ID0gY3VycmVudC5jeSArIHNlYXJjaERpcmVjdGlvbnNbY3VycmVudC5kaXJdWzBdO1xyXG4gICAgICAgICAgICAgICAgeCA9IGN1cnJlbnQuY3ggKyBzZWFyY2hEaXJlY3Rpb25zW2N1cnJlbnQuZGlyXVsxXTtcclxuICAgICAgICAgICAgICAgIHBvcyA9IHkgKiB3aWR0aCArIHg7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGltYWdlRGF0YVtwb3NdID09PSBjb2xvcikgJiYgKChsYWJlbERhdGFbcG9zXSA9PT0gMCkgfHwgKGxhYmVsRGF0YVtwb3NdID09PSBsYWJlbCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxEYXRhW3Bvc10gPSBsYWJlbDtcclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmN5ID0geTtcclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmN4ID0geDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhYmVsRGF0YVtwb3NdID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsRGF0YVtwb3NdID0gZWRnZWxhYmVsO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmRpciA9IChjdXJyZW50LmRpciArIDEpICUgODtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiB2ZXJ0ZXgyRCh4LCB5LCBkaXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGRpcjogZGlyLFxyXG4gICAgICAgICAgICAgICAgeDogeCxcclxuICAgICAgICAgICAgICAgIHk6IHksXHJcbiAgICAgICAgICAgICAgICBuZXh0OiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcHJldjogbnVsbFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gY29udG91clRyYWNpbmcoc3ksIHN4LCBsYWJlbCwgY29sb3IsIGVkZ2VsYWJlbCkge1xyXG4gICAgICAgICAgICB2YXIgRnYgPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgQ3YsXHJcbiAgICAgICAgICAgICAgICBQLFxyXG4gICAgICAgICAgICAgICAgbGRpcixcclxuICAgICAgICAgICAgICAgIGN1cnJlbnQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY3g6IHN4LFxyXG4gICAgICAgICAgICAgICAgICAgIGN5OiBzeSxcclxuICAgICAgICAgICAgICAgICAgICBkaXI6IDBcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBpZiAodHJhY2UoY3VycmVudCwgY29sb3IsIGxhYmVsLCBlZGdlbGFiZWwpKSB7XHJcbiAgICAgICAgICAgICAgICBGdiA9IHZlcnRleDJEKHN4LCBzeSwgY3VycmVudC5kaXIpO1xyXG4gICAgICAgICAgICAgICAgQ3YgPSBGdjtcclxuICAgICAgICAgICAgICAgIGxkaXIgPSBjdXJyZW50LmRpcjtcclxuICAgICAgICAgICAgICAgIFAgPSB2ZXJ0ZXgyRChjdXJyZW50LmN4LCBjdXJyZW50LmN5LCAwKTtcclxuICAgICAgICAgICAgICAgIFAucHJldiA9IEN2O1xyXG4gICAgICAgICAgICAgICAgQ3YubmV4dCA9IFA7XHJcbiAgICAgICAgICAgICAgICBQLm5leHQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgQ3YgPSBQO1xyXG4gICAgICAgICAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuZGlyID0gKGN1cnJlbnQuZGlyICsgNikgJSA4O1xyXG4gICAgICAgICAgICAgICAgICAgIHRyYWNlKGN1cnJlbnQsIGNvbG9yLCBsYWJlbCwgZWRnZWxhYmVsKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobGRpciAhPT0gY3VycmVudC5kaXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ3YuZGlyID0gY3VycmVudC5kaXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFAgPSB2ZXJ0ZXgyRChjdXJyZW50LmN4LCBjdXJyZW50LmN5LCAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgUC5wcmV2ID0gQ3Y7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEN2Lm5leHQgPSBQO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBQLm5leHQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDdiA9IFA7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ3YuZGlyID0gbGRpcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ3YueCA9IGN1cnJlbnQuY3g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEN2LnkgPSBjdXJyZW50LmN5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBsZGlyID0gY3VycmVudC5kaXI7XHJcbiAgICAgICAgICAgICAgICB9IHdoaWxlIChjdXJyZW50LmN4ICE9PSBzeCB8fCBjdXJyZW50LmN5ICE9PSBzeSk7XHJcbiAgICAgICAgICAgICAgICBGdi5wcmV2ID0gQ3YucHJldjtcclxuICAgICAgICAgICAgICAgIEN2LnByZXYubmV4dCA9IEZ2O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBGdjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHRyYWNlOiBmdW5jdGlvbihjdXJyZW50LCBjb2xvciwgbGFiZWwsIGVkZ2VsYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRyYWNlKGN1cnJlbnQsIGNvbG9yLCBsYWJlbCwgZWRnZWxhYmVsKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgY29udG91clRyYWNpbmc6IGZ1bmN0aW9uKHN5LCBzeCwgbGFiZWwsIGNvbG9yLCBlZGdlbGFiZWwpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjb250b3VyVHJhY2luZyhzeSwgc3gsIGxhYmVsLCBjb2xvciwgZWRnZWxhYmVsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCAoVHJhY2VyKTtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvbG9jYXRvci90cmFjZXIuanNcbiAqKi8iLCJpbXBvcnQgQmFyY29kZVJlYWRlciBmcm9tICcuL2JhcmNvZGVfcmVhZGVyJztcclxuaW1wb3J0IEFycmF5SGVscGVyIGZyb20gJy4uL2NvbW1vbi9hcnJheV9oZWxwZXInO1xyXG5cclxuZnVuY3Rpb24gQ29kZTM5UmVhZGVyKCkge1xyXG4gICAgQmFyY29kZVJlYWRlci5jYWxsKHRoaXMpO1xyXG59XHJcblxyXG52YXIgcHJvcGVydGllcyA9IHtcclxuICAgIEFMUEhBQkVUSF9TVFJJTkc6IHt2YWx1ZTogXCIwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotLiAqJC8rJVwifSxcclxuICAgIEFMUEhBQkVUOiB7dmFsdWU6IFs0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LFxyXG4gICAgICAgIDc5LCA4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDQ1LCA0NiwgMzIsIDQyLCAzNiwgNDcsIDQzLCAzN119LFxyXG4gICAgQ0hBUkFDVEVSX0VOQ09ESU5HUzoge3ZhbHVlOiBbMHgwMzQsIDB4MTIxLCAweDA2MSwgMHgxNjAsIDB4MDMxLCAweDEzMCwgMHgwNzAsIDB4MDI1LCAweDEyNCwgMHgwNjQsIDB4MTA5LCAweDA0OSxcclxuICAgICAgICAweDE0OCwgMHgwMTksIDB4MTE4LCAweDA1OCwgMHgwMEQsIDB4MTBDLCAweDA0QywgMHgwMUMsIDB4MTAzLCAweDA0MywgMHgxNDIsIDB4MDEzLCAweDExMiwgMHgwNTIsIDB4MDA3LCAweDEwNixcclxuICAgICAgICAweDA0NiwgMHgwMTYsIDB4MTgxLCAweDBDMSwgMHgxQzAsIDB4MDkxLCAweDE5MCwgMHgwRDAsIDB4MDg1LCAweDE4NCwgMHgwQzQsIDB4MDk0LCAweDBBOCwgMHgwQTIsIDB4MDhBLCAweDAyQVxyXG4gICAgXX0sXHJcbiAgICBBU1RFUklTSzoge3ZhbHVlOiAweDA5NH0sXHJcbiAgICBGT1JNQVQ6IHt2YWx1ZTogXCJjb2RlXzM5XCIsIHdyaXRlYWJsZTogZmFsc2V9XHJcbn07XHJcblxyXG5Db2RlMzlSZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShCYXJjb2RlUmVhZGVyLnByb3RvdHlwZSwgcHJvcGVydGllcyk7XHJcbkNvZGUzOVJlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDb2RlMzlSZWFkZXI7XHJcblxyXG5Db2RlMzlSZWFkZXIucHJvdG90eXBlLl90b0NvdW50ZXJzID0gZnVuY3Rpb24oc3RhcnQsIGNvdW50ZXIpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBudW1Db3VudGVycyA9IGNvdW50ZXIubGVuZ3RoLFxyXG4gICAgICAgIGVuZCA9IHNlbGYuX3Jvdy5sZW5ndGgsXHJcbiAgICAgICAgaXNXaGl0ZSA9ICFzZWxmLl9yb3dbc3RhcnRdLFxyXG4gICAgICAgIGksXHJcbiAgICAgICAgY291bnRlclBvcyA9IDA7XHJcblxyXG4gICAgQXJyYXlIZWxwZXIuaW5pdChjb3VudGVyLCAwKTtcclxuXHJcbiAgICBmb3IgKCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xyXG4gICAgICAgIGlmIChzZWxmLl9yb3dbaV0gXiBpc1doaXRlKSB7XHJcbiAgICAgICAgICAgIGNvdW50ZXJbY291bnRlclBvc10rKztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb3VudGVyUG9zKys7XHJcbiAgICAgICAgICAgIGlmIChjb3VudGVyUG9zID09PSBudW1Db3VudGVycykge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcclxuICAgICAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY291bnRlcjtcclxufTtcclxuXHJcbkNvZGUzOVJlYWRlci5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGNvdW50ZXJzID0gWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdLFxyXG4gICAgICAgIHJlc3VsdCA9IFtdLFxyXG4gICAgICAgIHN0YXJ0ID0gc2VsZi5fZmluZFN0YXJ0KCksXHJcbiAgICAgICAgZGVjb2RlZENoYXIsXHJcbiAgICAgICAgbGFzdFN0YXJ0LFxyXG4gICAgICAgIHBhdHRlcm4sXHJcbiAgICAgICAgbmV4dFN0YXJ0O1xyXG5cclxuICAgIGlmICghc3RhcnQpIHtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIG5leHRTdGFydCA9IHNlbGYuX25leHRTZXQoc2VsZi5fcm93LCBzdGFydC5lbmQpO1xyXG5cclxuICAgIGRvIHtcclxuICAgICAgICBjb3VudGVycyA9IHNlbGYuX3RvQ291bnRlcnMobmV4dFN0YXJ0LCBjb3VudGVycyk7XHJcbiAgICAgICAgcGF0dGVybiA9IHNlbGYuX3RvUGF0dGVybihjb3VudGVycyk7XHJcbiAgICAgICAgaWYgKHBhdHRlcm4gPCAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBkZWNvZGVkQ2hhciA9IHNlbGYuX3BhdHRlcm5Ub0NoYXIocGF0dGVybik7XHJcbiAgICAgICAgaWYgKGRlY29kZWRDaGFyIDwgMCl7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXN1bHQucHVzaChkZWNvZGVkQ2hhcik7XHJcbiAgICAgICAgbGFzdFN0YXJ0ID0gbmV4dFN0YXJ0O1xyXG4gICAgICAgIG5leHRTdGFydCArPSBBcnJheUhlbHBlci5zdW0oY291bnRlcnMpO1xyXG4gICAgICAgIG5leHRTdGFydCA9IHNlbGYuX25leHRTZXQoc2VsZi5fcm93LCBuZXh0U3RhcnQpO1xyXG4gICAgfSB3aGlsZSAoZGVjb2RlZENoYXIgIT09ICcqJyk7XHJcbiAgICByZXN1bHQucG9wKCk7XHJcblxyXG4gICAgaWYgKCFyZXN1bHQubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFzZWxmLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UobGFzdFN0YXJ0LCBuZXh0U3RhcnQsIGNvdW50ZXJzKSkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgY29kZTogcmVzdWx0LmpvaW4oXCJcIiksXHJcbiAgICAgICAgc3RhcnQ6IHN0YXJ0LnN0YXJ0LFxyXG4gICAgICAgIGVuZDogbmV4dFN0YXJ0LFxyXG4gICAgICAgIHN0YXJ0SW5mbzogc3RhcnQsXHJcbiAgICAgICAgZGVjb2RlZENvZGVzOiByZXN1bHRcclxuICAgIH07XHJcbn07XHJcblxyXG5Db2RlMzlSZWFkZXIucHJvdG90eXBlLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UgPSBmdW5jdGlvbihsYXN0U3RhcnQsIG5leHRTdGFydCwgY291bnRlcnMpIHtcclxuICAgIHZhciB0cmFpbGluZ1doaXRlc3BhY2VFbmQsXHJcbiAgICAgICAgcGF0dGVyblNpemUgPSBBcnJheUhlbHBlci5zdW0oY291bnRlcnMpO1xyXG5cclxuICAgIHRyYWlsaW5nV2hpdGVzcGFjZUVuZCA9IG5leHRTdGFydCAtIGxhc3RTdGFydCAtIHBhdHRlcm5TaXplO1xyXG4gICAgaWYgKCh0cmFpbGluZ1doaXRlc3BhY2VFbmQgKiAzKSA+PSBwYXR0ZXJuU2l6ZSkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxuQ29kZTM5UmVhZGVyLnByb3RvdHlwZS5fcGF0dGVyblRvQ2hhciA9IGZ1bmN0aW9uKHBhdHRlcm4pIHtcclxuICAgIHZhciBpLFxyXG4gICAgICAgIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIGZvciAoaSA9IDA7IGkgPCBzZWxmLkNIQVJBQ1RFUl9FTkNPRElOR1MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAoc2VsZi5DSEFSQUNURVJfRU5DT0RJTkdTW2ldID09PSBwYXR0ZXJuKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHNlbGYuQUxQSEFCRVRbaV0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiAtMTtcclxufTtcclxuXHJcbkNvZGUzOVJlYWRlci5wcm90b3R5cGUuX2ZpbmROZXh0V2lkdGggPSBmdW5jdGlvbihjb3VudGVycywgY3VycmVudCkge1xyXG4gICAgdmFyIGksXHJcbiAgICAgICAgbWluV2lkdGggPSBOdW1iZXIuTUFYX1ZBTFVFO1xyXG5cclxuICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudGVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChjb3VudGVyc1tpXSA8IG1pbldpZHRoICYmIGNvdW50ZXJzW2ldID4gY3VycmVudCkge1xyXG4gICAgICAgICAgICBtaW5XaWR0aCA9IGNvdW50ZXJzW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbWluV2lkdGg7XHJcbn07XHJcblxyXG5Db2RlMzlSZWFkZXIucHJvdG90eXBlLl90b1BhdHRlcm4gPSBmdW5jdGlvbihjb3VudGVycykge1xyXG4gICAgdmFyIG51bUNvdW50ZXJzID0gY291bnRlcnMubGVuZ3RoLFxyXG4gICAgICAgIG1heE5hcnJvd1dpZHRoID0gMCxcclxuICAgICAgICBudW1XaWRlQmFycyA9IG51bUNvdW50ZXJzLFxyXG4gICAgICAgIHdpZGVCYXJXaWR0aCA9IDAsXHJcbiAgICAgICAgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgcGF0dGVybixcclxuICAgICAgICBpO1xyXG5cclxuICAgIHdoaWxlIChudW1XaWRlQmFycyA+IDMpIHtcclxuICAgICAgICBtYXhOYXJyb3dXaWR0aCA9IHNlbGYuX2ZpbmROZXh0V2lkdGgoY291bnRlcnMsIG1heE5hcnJvd1dpZHRoKTtcclxuICAgICAgICBudW1XaWRlQmFycyA9IDA7XHJcbiAgICAgICAgcGF0dGVybiA9IDA7XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bUNvdW50ZXJzOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGNvdW50ZXJzW2ldID4gbWF4TmFycm93V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgIHBhdHRlcm4gfD0gMSA8PCAobnVtQ291bnRlcnMgLSAxIC0gaSk7XHJcbiAgICAgICAgICAgICAgICBudW1XaWRlQmFycysrO1xyXG4gICAgICAgICAgICAgICAgd2lkZUJhcldpZHRoICs9IGNvdW50ZXJzW2ldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobnVtV2lkZUJhcnMgPT09IDMpIHtcclxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bUNvdW50ZXJzICYmIG51bVdpZGVCYXJzID4gMDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY291bnRlcnNbaV0gPiBtYXhOYXJyb3dXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG51bVdpZGVCYXJzLS07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChjb3VudGVyc1tpXSAqIDIpID49IHdpZGVCYXJXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBwYXR0ZXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiAtMTtcclxufTtcclxuXHJcbkNvZGUzOVJlYWRlci5wcm90b3R5cGUuX2ZpbmRTdGFydCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIG9mZnNldCA9IHNlbGYuX25leHRTZXQoc2VsZi5fcm93KSxcclxuICAgICAgICBwYXR0ZXJuU3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgY291bnRlciA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXSxcclxuICAgICAgICBjb3VudGVyUG9zID0gMCxcclxuICAgICAgICBpc1doaXRlID0gZmFsc2UsXHJcbiAgICAgICAgaSxcclxuICAgICAgICBqLFxyXG4gICAgICAgIHdoaXRlU3BhY2VNdXN0U3RhcnQ7XHJcblxyXG4gICAgZm9yICggaSA9IG9mZnNldDsgaSA8IHNlbGYuX3Jvdy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChzZWxmLl9yb3dbaV0gXiBpc1doaXRlKSB7XHJcbiAgICAgICAgICAgIGNvdW50ZXJbY291bnRlclBvc10rKztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAoY291bnRlclBvcyA9PT0gY291bnRlci5sZW5ndGggLSAxKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBmaW5kIHN0YXJ0IHBhdHRlcm5cclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLl90b1BhdHRlcm4oY291bnRlcikgPT09IHNlbGYuQVNURVJJU0spIHtcclxuICAgICAgICAgICAgICAgICAgICB3aGl0ZVNwYWNlTXVzdFN0YXJ0ID0gTWF0aC5mbG9vcihNYXRoLm1heCgwLCBwYXR0ZXJuU3RhcnQgLSAoKGkgLSBwYXR0ZXJuU3RhcnQpIC8gNCkpKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5fbWF0Y2hSYW5nZSh3aGl0ZVNwYWNlTXVzdFN0YXJ0LCBwYXR0ZXJuU3RhcnQsIDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydDogcGF0dGVyblN0YXJ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHBhdHRlcm5TdGFydCArPSBjb3VudGVyWzBdICsgY291bnRlclsxXTtcclxuICAgICAgICAgICAgICAgIGZvciAoIGogPSAwOyBqIDwgNzsgaisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcltqXSA9IGNvdW50ZXJbaiArIDJdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY291bnRlcls3XSA9IDA7XHJcbiAgICAgICAgICAgICAgICBjb3VudGVyWzhdID0gMDtcclxuICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MtLTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MrKztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcclxuICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ29kZTM5UmVhZGVyO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9yZWFkZXIvY29kZV8zOV9yZWFkZXIuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGRvdFxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRvdCBwcm9kdWN0IG9mIHR3byB2ZWMyJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7dmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRvdCBwcm9kdWN0IG9mIGEgYW5kIGJcbiAqL1xuZnVuY3Rpb24gZG90KGEsIGIpIHtcbiAgICByZXR1cm4gYVswXSAqIGJbMF0gKyBhWzFdICogYlsxXVxufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2dsLXZlYzIvZG90LmpzXG4gKiogbW9kdWxlIGlkID0gMzFcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBzdGFja0NsZWFyID0gcmVxdWlyZSgnLi9fc3RhY2tDbGVhcicpLFxuICAgIHN0YWNrRGVsZXRlID0gcmVxdWlyZSgnLi9fc3RhY2tEZWxldGUnKSxcbiAgICBzdGFja0dldCA9IHJlcXVpcmUoJy4vX3N0YWNrR2V0JyksXG4gICAgc3RhY2tIYXMgPSByZXF1aXJlKCcuL19zdGFja0hhcycpLFxuICAgIHN0YWNrU2V0ID0gcmVxdWlyZSgnLi9fc3RhY2tTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgc3RhY2sgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGNhY2hlLlxuICovXG5mdW5jdGlvbiBTdGFjayh2YWx1ZXMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSB2YWx1ZXMgPyB2YWx1ZXMubGVuZ3RoIDogMDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gdmFsdWVzW2luZGV4XTtcbiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG59XG5cbi8vIEFkZCBmdW5jdGlvbnMgdG8gdGhlIGBTdGFja2AgY2FjaGUuXG5TdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyO1xuU3RhY2sucHJvdG90eXBlWydkZWxldGUnXSA9IHN0YWNrRGVsZXRlO1xuU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0O1xuU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzO1xuU3RhY2sucHJvdG90eXBlLnNldCA9IHN0YWNrU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0YWNrO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19TdGFjay5qc1xuICoqIG1vZHVsZSBpZCA9IDMyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUVhY2g7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2FycmF5RWFjaC5qc1xuICoqIG1vZHVsZSBpZCA9IDMzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgZXEgPSByZXF1aXJlKCcuL2VxJyk7XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBhc3NpZ25WYWx1ZWAgZXhjZXB0IHRoYXQgaXQgZG9lc24ndCBhc3NpZ25cbiAqIGB1bmRlZmluZWRgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICovXG5mdW5jdGlvbiBhc3NpZ25NZXJnZVZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICBpZiAoKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgIWVxKG9iamVjdFtrZXldLCB2YWx1ZSkpIHx8XG4gICAgICAodHlwZW9mIGtleSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFzc2lnbk1lcmdlVmFsdWU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Fzc2lnbk1lcmdlVmFsdWUuanNcbiAqKiBtb2R1bGUgaWQgPSAzNFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGVxID0gcmVxdWlyZSgnLi9lcScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEFzc2lnbnMgYHZhbHVlYCB0byBga2V5YCBvZiBgb2JqZWN0YCBpZiB0aGUgZXhpc3RpbmcgdmFsdWUgaXMgbm90IGVxdWl2YWxlbnRcbiAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAqL1xuZnVuY3Rpb24gYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldO1xuICBpZiAoIShoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSAmJiBlcShvYmpWYWx1ZSwgdmFsdWUpKSB8fFxuICAgICAgKHZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkpIHtcbiAgICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzaWduVmFsdWU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Fzc2lnblZhbHVlLmpzXG4gKiogbW9kdWxlIGlkID0gMzVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBhc3NvY2lhdGl2ZSBhcnJheS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGFzc29jRGVsZXRlKGFycmF5LCBrZXkpIHtcbiAgdmFyIGluZGV4ID0gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpO1xuICBpZiAoaW5kZXggPCAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBsYXN0SW5kZXggPSBhcnJheS5sZW5ndGggLSAxO1xuICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgYXJyYXkucG9wKCk7XG4gIH0gZWxzZSB7XG4gICAgc3BsaWNlLmNhbGwoYXJyYXksIGluZGV4LCAxKTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NvY0RlbGV0ZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYXNzb2NEZWxldGUuanNcbiAqKiBtb2R1bGUgaWQgPSAzNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGFzc29jSW5kZXhPZiA9IHJlcXVpcmUoJy4vX2Fzc29jSW5kZXhPZicpO1xuXG4vKipcbiAqIEdldHMgdGhlIGFzc29jaWF0aXZlIGFycmF5IHZhbHVlIGZvciBga2V5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGFzc29jR2V0KGFycmF5LCBrZXkpIHtcbiAgdmFyIGluZGV4ID0gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpO1xuICByZXR1cm4gaW5kZXggPCAwID8gdW5kZWZpbmVkIDogYXJyYXlbaW5kZXhdWzFdO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFzc29jR2V0O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19hc3NvY0dldC5qc1xuICoqIG1vZHVsZSBpZCA9IDM3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYXNzb2NJbmRleE9mID0gcmVxdWlyZSgnLi9fYXNzb2NJbmRleE9mJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGFuIGFzc29jaWF0aXZlIGFycmF5IHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBhc3NvY0hhcyhhcnJheSwga2V5KSB7XG4gIHJldHVybiBhc3NvY0luZGV4T2YoYXJyYXksIGtleSkgPiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NvY0hhcztcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYXNzb2NIYXMuanNcbiAqKiBtb2R1bGUgaWQgPSAzOFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGFzc29jSW5kZXhPZiA9IHJlcXVpcmUoJy4vX2Fzc29jSW5kZXhPZicpO1xuXG4vKipcbiAqIFNldHMgdGhlIGFzc29jaWF0aXZlIGFycmF5IGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAqL1xuZnVuY3Rpb24gYXNzb2NTZXQoYXJyYXksIGtleSwgdmFsdWUpIHtcbiAgdmFyIGluZGV4ID0gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpO1xuICBpZiAoaW5kZXggPCAwKSB7XG4gICAgYXJyYXkucHVzaChba2V5LCB2YWx1ZV0pO1xuICB9IGVsc2Uge1xuICAgIGFycmF5W2luZGV4XVsxXSA9IHZhbHVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzb2NTZXQ7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Fzc29jU2V0LmpzXG4gKiogbW9kdWxlIGlkID0gMzlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBVaW50OEFycmF5ID0gcmVxdWlyZSgnLi9fVWludDhBcnJheScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgYXJyYXlCdWZmZXJgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBhcnJheUJ1ZmZlciBUaGUgYXJyYXkgYnVmZmVyIHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5QnVmZmVyfSBSZXR1cm5zIHRoZSBjbG9uZWQgYXJyYXkgYnVmZmVyLlxuICovXG5mdW5jdGlvbiBjbG9uZUFycmF5QnVmZmVyKGFycmF5QnVmZmVyKSB7XG4gIHZhciByZXN1bHQgPSBuZXcgYXJyYXlCdWZmZXIuY29uc3RydWN0b3IoYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCk7XG4gIG5ldyBVaW50OEFycmF5KHJlc3VsdCkuc2V0KG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyKSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmVBcnJheUJ1ZmZlcjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fY2xvbmVBcnJheUJ1ZmZlci5qc1xuICoqIG1vZHVsZSBpZCA9IDQwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5QXJyYXk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2NvcHlBcnJheS5qc1xuICoqIG1vZHVsZSBpZCA9IDQxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgaGFzaCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gaGFzaCBUaGUgaGFzaCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBoYXNoSGFzKGhhc2gsIGtleSkge1xuICByZXR1cm4gbmF0aXZlQ3JlYXRlID8gaGFzaFtrZXldICE9PSB1bmRlZmluZWQgOiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGhhc2gsIGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaEhhcztcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faGFzaEhhcy5qc1xuICoqIG1vZHVsZSBpZCA9IDQyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYmFzZVRpbWVzID0gcmVxdWlyZSgnLi9fYmFzZVRpbWVzJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi9pc0xlbmd0aCcpLFxuICAgIGlzU3RyaW5nID0gcmVxdWlyZSgnLi9pc1N0cmluZycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgaW5kZXgga2V5cyBmb3IgYG9iamVjdGAgdmFsdWVzIG9mIGFycmF5cyxcbiAqIGBhcmd1bWVudHNgIG9iamVjdHMsIGFuZCBzdHJpbmdzLCBvdGhlcndpc2UgYG51bGxgIGlzIHJldHVybmVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl8bnVsbH0gUmV0dXJucyBpbmRleCBrZXlzLCBlbHNlIGBudWxsYC5cbiAqL1xuZnVuY3Rpb24gaW5kZXhLZXlzKG9iamVjdCkge1xuICB2YXIgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IHVuZGVmaW5lZDtcbiAgaWYgKGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNTdHJpbmcob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpKSkge1xuICAgIHJldHVybiBiYXNlVGltZXMobGVuZ3RoLCBTdHJpbmcpO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluZGV4S2V5cztcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faW5kZXhLZXlzLmpzXG4gKiogbW9kdWxlIGlkID0gNDNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIG9mIHR5cGVkIGFycmF5cy4gKi9cbnZhciB0eXBlZEFycmF5VGFncyA9IHt9O1xudHlwZWRBcnJheVRhZ3NbZmxvYXQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1tmbG9hdDY0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tpbnQ4VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2ludDE2VGFnXSA9XG50eXBlZEFycmF5VGFnc1tpbnQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50OFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbdWludDMyVGFnXSA9IHRydWU7XG50eXBlZEFycmF5VGFnc1thcmdzVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2FycmF5VGFnXSA9XG50eXBlZEFycmF5VGFnc1thcnJheUJ1ZmZlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tib29sVGFnXSA9XG50eXBlZEFycmF5VGFnc1tkYXRlVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Vycm9yVGFnXSA9XG50eXBlZEFycmF5VGFnc1tmdW5jVGFnXSA9IHR5cGVkQXJyYXlUYWdzW21hcFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbbnVtYmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW29iamVjdFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbcmVnZXhwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3NldFRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbc3RyaW5nVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3dlYWtNYXBUYWddID0gZmFsc2U7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmXG4gICAgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW29iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1R5cGVkQXJyYXk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaXNUeXBlZEFycmF5LmpzXG4gKiogbW9kdWxlIGlkID0gNDRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBiYXNlSGFzID0gcmVxdWlyZSgnLi9fYmFzZUhhcycpLFxuICAgIGJhc2VLZXlzID0gcmVxdWlyZSgnLi9fYmFzZUtleXMnKSxcbiAgICBpbmRleEtleXMgPSByZXF1aXJlKCcuL19pbmRleEtleXMnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9faXNJbmRleCcpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5rZXlzKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIF8ua2V5cygnaGknKTtcbiAqIC8vID0+IFsnMCcsICcxJ11cbiAqL1xuZnVuY3Rpb24ga2V5cyhvYmplY3QpIHtcbiAgdmFyIGlzUHJvdG8gPSBpc1Byb3RvdHlwZShvYmplY3QpO1xuICBpZiAoIShpc1Byb3RvIHx8IGlzQXJyYXlMaWtlKG9iamVjdCkpKSB7XG4gICAgcmV0dXJuIGJhc2VLZXlzKG9iamVjdCk7XG4gIH1cbiAgdmFyIGluZGV4ZXMgPSBpbmRleEtleXMob2JqZWN0KSxcbiAgICAgIHNraXBJbmRleGVzID0gISFpbmRleGVzLFxuICAgICAgcmVzdWx0ID0gaW5kZXhlcyB8fCBbXSxcbiAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgIGlmIChiYXNlSGFzKG9iamVjdCwga2V5KSAmJlxuICAgICAgICAhKHNraXBJbmRleGVzICYmIChrZXkgPT0gJ2xlbmd0aCcgfHwgaXNJbmRleChrZXksIGxlbmd0aCkpKSAmJlxuICAgICAgICAhKGlzUHJvdG8gJiYga2V5ID09ICdjb25zdHJ1Y3RvcicpKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXM7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gva2V5cy5qc1xuICoqIG1vZHVsZSBpZCA9IDQ1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYmFzZUtleXNJbiA9IHJlcXVpcmUoJy4vX2Jhc2VLZXlzSW4nKSxcbiAgICBpbmRleEtleXMgPSByZXF1aXJlKCcuL19pbmRleEtleXMnKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9faXNJbmRleCcpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXNJbihuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJywgJ2MnXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBrZXlzSW4ob2JqZWN0KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgaXNQcm90byA9IGlzUHJvdG90eXBlKG9iamVjdCksXG4gICAgICBwcm9wcyA9IGJhc2VLZXlzSW4ob2JqZWN0KSxcbiAgICAgIHByb3BzTGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgaW5kZXhlcyA9IGluZGV4S2V5cyhvYmplY3QpLFxuICAgICAgc2tpcEluZGV4ZXMgPSAhIWluZGV4ZXMsXG4gICAgICByZXN1bHQgPSBpbmRleGVzIHx8IFtdLFxuICAgICAgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBpZiAoIShza2lwSW5kZXhlcyAmJiAoa2V5ID09ICdsZW5ndGgnIHx8IGlzSW5kZXgoa2V5LCBsZW5ndGgpKSkgJiZcbiAgICAgICAgIShrZXkgPT0gJ2NvbnN0cnVjdG9yJyAmJiAoaXNQcm90byB8fCAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzSW47XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gva2V5c0luLmpzXG4gKiogbW9kdWxlIGlkID0gNDZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBhcHBseSA9IHJlcXVpcmUoJy4vX2FwcGx5JyksXG4gICAgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi90b0ludGVnZXInKTtcblxuLyoqIFVzZWQgYXMgdGhlIGBUeXBlRXJyb3JgIG1lc3NhZ2UgZm9yIFwiRnVuY3Rpb25zXCIgbWV0aG9kcy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAqIGNyZWF0ZWQgZnVuY3Rpb24gYW5kIGFyZ3VtZW50cyBmcm9tIGBzdGFydGAgYW5kIGJleW9uZCBwcm92aWRlZCBhcyBhbiBhcnJheS5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9tZG4uaW8vcmVzdF9wYXJhbWV0ZXJzKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD1mdW5jLmxlbmd0aC0xXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJlc3QgcGFyYW1ldGVyLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBzYXkgPSBfLnJlc3QoZnVuY3Rpb24od2hhdCwgbmFtZXMpIHtcbiAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICogICAgIChfLnNpemUobmFtZXMpID4gMSA/ICcsICYgJyA6ICcnKSArIF8ubGFzdChuYW1lcyk7XG4gKiB9KTtcbiAqXG4gKiBzYXkoJ2hlbGxvJywgJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnKTtcbiAqIC8vID0+ICdoZWxsbyBmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAqL1xuZnVuY3Rpb24gcmVzdChmdW5jLCBzdGFydCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiB0b0ludGVnZXIoc3RhcnQpLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgIGFycmF5ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBhcnJheVtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdO1xuICAgIH1cbiAgICBzd2l0Y2ggKHN0YXJ0KSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJyYXkpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFycmF5KTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzLCBhcmdzWzBdLCBhcmdzWzFdLCBhcnJheSk7XG4gICAgfVxuICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgIGluZGV4ID0gLTE7XG4gICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgIH1cbiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gYXJyYXk7XG4gICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIG90aGVyQXJncyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVzdDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9yZXN0LmpzXG4gKiogbW9kdWxlIGlkID0gNDdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obW9kdWxlKSB7XHJcblx0aWYoIW1vZHVsZS53ZWJwYWNrUG9seWZpbGwpIHtcclxuXHRcdG1vZHVsZS5kZXByZWNhdGUgPSBmdW5jdGlvbigpIHt9O1xyXG5cdFx0bW9kdWxlLnBhdGhzID0gW107XHJcblx0XHQvLyBtb2R1bGUucGFyZW50ID0gdW5kZWZpbmVkIGJ5IGRlZmF1bHRcclxuXHRcdG1vZHVsZS5jaGlsZHJlbiA9IFtdO1xyXG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZSwgXCJleHBvcnRzXCIsIHtcclxuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcclxuXHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcclxuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1vZHVsZS5lOyB9LFxyXG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKHYpIHsgcmV0dXJuIG1vZHVsZS5lID0gdjsgfVxyXG5cdFx0fSk7XHJcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLCBcImxvYWRlZFwiLCB7XHJcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXHJcblx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXHJcblx0XHRcdGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtb2R1bGUubDsgfVxyXG5cdFx0fSk7XHJcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLCBcImlkXCIsIHtcclxuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcclxuXHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcclxuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1vZHVsZS5pOyB9XHJcblx0XHR9KTtcclxuXHRcdG1vZHVsZS53ZWJwYWNrUG9seWZpbGwgPSAxO1xyXG5cdH1cclxuXHRyZXR1cm4gbW9kdWxlO1xyXG59XHJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogKHdlYnBhY2spL2J1aWxkaW4vbW9kdWxlLmpzXG4gKiogbW9kdWxlIGlkID0gNDhcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsImltcG9ydCBUeXBlRGVmcyBmcm9tICcuL2NvbW1vbi90eXBlZGVmcyc7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcclxuaW1wb3J0IFdlYnJ0Y0FkYXB0ZXIgZnJvbSAnd2VicnRjLWFkYXB0ZXInOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXHJcbmltcG9ydCBJbWFnZVdyYXBwZXIgZnJvbSAnLi9jb21tb24vaW1hZ2Vfd3JhcHBlcic7XHJcbmltcG9ydCBCYXJjb2RlTG9jYXRvciBmcm9tICcuL2xvY2F0b3IvYmFyY29kZV9sb2NhdG9yJztcclxuaW1wb3J0IEJhcmNvZGVEZWNvZGVyIGZyb20gJy4vZGVjb2Rlci9iYXJjb2RlX2RlY29kZXInO1xyXG5pbXBvcnQgRXZlbnRzIGZyb20gJy4vY29tbW9uL2V2ZW50cyc7XHJcbmltcG9ydCBDYW1lcmFBY2Nlc3MgZnJvbSAnLi9pbnB1dC9jYW1lcmFfYWNjZXNzJztcclxuaW1wb3J0IEltYWdlRGVidWcgZnJvbSAnLi9jb21tb24vaW1hZ2VfZGVidWcnO1xyXG5pbXBvcnQgUmVzdWx0Q29sbGVjdG9yIGZyb20gJy4vYW5hbHl0aWNzL3Jlc3VsdF9jb2xsZWN0b3InO1xyXG5pbXBvcnQgQ29uZmlnIGZyb20gJy4vY29uZmlnL2NvbmZpZyc7XHJcbmltcG9ydCBJbnB1dFN0cmVhbSBmcm9tICdpbnB1dF9zdHJlYW0nO1xyXG5pbXBvcnQgRnJhbWVHcmFiYmVyIGZyb20gJ2ZyYW1lX2dyYWJiZXInO1xyXG5pbXBvcnQge21lcmdlfSBmcm9tICdsb2Rhc2gnO1xyXG5jb25zdCB2ZWMyID0ge1xyXG4gICAgY2xvbmU6IHJlcXVpcmUoJ2dsLXZlYzIvY2xvbmUnKVxyXG59O1xyXG5cclxudmFyIF9pbnB1dFN0cmVhbSxcclxuICAgIF9mcmFtZWdyYWJiZXIsXHJcbiAgICBfc3RvcHBlZCxcclxuICAgIF9jYW52YXNDb250YWluZXIgPSB7XHJcbiAgICAgICAgY3R4OiB7XHJcbiAgICAgICAgICAgIGltYWdlOiBudWxsLFxyXG4gICAgICAgICAgICBvdmVybGF5OiBudWxsXHJcbiAgICAgICAgfSxcclxuICAgICAgICBkb206IHtcclxuICAgICAgICAgICAgaW1hZ2U6IG51bGwsXHJcbiAgICAgICAgICAgIG92ZXJsYXk6IG51bGxcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgX2lucHV0SW1hZ2VXcmFwcGVyLFxyXG4gICAgX2JveFNpemUsXHJcbiAgICBfZGVjb2RlcixcclxuICAgIF93b3JrZXJQb29sID0gW10sXHJcbiAgICBfb25VSVRocmVhZCA9IHRydWUsXHJcbiAgICBfcmVzdWx0Q29sbGVjdG9yLFxyXG4gICAgX2NvbmZpZyA9IHt9O1xyXG5cclxuZnVuY3Rpb24gaW5pdGlhbGl6ZURhdGEoaW1hZ2VXcmFwcGVyKSB7XHJcbiAgICBpbml0QnVmZmVycyhpbWFnZVdyYXBwZXIpO1xyXG4gICAgX2RlY29kZXIgPSBCYXJjb2RlRGVjb2Rlci5jcmVhdGUoX2NvbmZpZy5kZWNvZGVyLCBfaW5wdXRJbWFnZVdyYXBwZXIpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpbml0SW5wdXRTdHJlYW0oY2IpIHtcclxuICAgIHZhciB2aWRlbztcclxuICAgIGlmIChfY29uZmlnLmlucHV0U3RyZWFtLnR5cGUgPT09IFwiVmlkZW9TdHJlYW1cIikge1xyXG4gICAgICAgIHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInZpZGVvXCIpO1xyXG4gICAgICAgIF9pbnB1dFN0cmVhbSA9IElucHV0U3RyZWFtLmNyZWF0ZVZpZGVvU3RyZWFtKHZpZGVvKTtcclxuICAgIH0gZWxzZSBpZiAoX2NvbmZpZy5pbnB1dFN0cmVhbS50eXBlID09PSBcIkltYWdlU3RyZWFtXCIpIHtcclxuICAgICAgICBfaW5wdXRTdHJlYW0gPSBJbnB1dFN0cmVhbS5jcmVhdGVJbWFnZVN0cmVhbSgpO1xyXG4gICAgfSBlbHNlIGlmIChfY29uZmlnLmlucHV0U3RyZWFtLnR5cGUgPT09IFwiTGl2ZVN0cmVhbVwiKSB7XHJcbiAgICAgICAgdmFyICR2aWV3cG9ydCA9IGdldFZpZXdQb3J0KCk7XHJcbiAgICAgICAgaWYgKCR2aWV3cG9ydCkge1xyXG4gICAgICAgICAgICB2aWRlbyA9ICR2aWV3cG9ydC5xdWVyeVNlbGVjdG9yKFwidmlkZW9cIik7XHJcbiAgICAgICAgICAgIGlmICghdmlkZW8pIHtcclxuICAgICAgICAgICAgICAgIHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInZpZGVvXCIpO1xyXG4gICAgICAgICAgICAgICAgJHZpZXdwb3J0LmFwcGVuZENoaWxkKHZpZGVvKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBfaW5wdXRTdHJlYW0gPSBJbnB1dFN0cmVhbS5jcmVhdGVMaXZlU3RyZWFtKHZpZGVvKTtcclxuICAgICAgICBDYW1lcmFBY2Nlc3MucmVxdWVzdCh2aWRlbywgX2NvbmZpZy5pbnB1dFN0cmVhbS5jb25zdHJhaW50cylcclxuICAgICAgICAudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIF9pbnB1dFN0cmVhbS50cmlnZ2VyKFwiY2FucmVjb3JkXCIpO1xyXG4gICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIGNiKGVycik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgX2lucHV0U3RyZWFtLnNldEF0dHJpYnV0ZShcInByZWxvYWRcIiwgXCJhdXRvXCIpO1xyXG4gICAgX2lucHV0U3RyZWFtLnNldEF0dHJpYnV0ZShcImF1dG9wbGF5XCIsIHRydWUpO1xyXG4gICAgX2lucHV0U3RyZWFtLnNldElucHV0U3RyZWFtKF9jb25maWcuaW5wdXRTdHJlYW0pO1xyXG4gICAgX2lucHV0U3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXCJjYW5yZWNvcmRcIiwgY2FuUmVjb3JkLmJpbmQodW5kZWZpbmVkLCBjYikpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRWaWV3UG9ydCgpIHtcclxuICAgIHZhciB0YXJnZXQgPSBfY29uZmlnLmlucHV0U3RyZWFtLnRhcmdldDtcclxuICAgIC8vIENoZWNrIGlmIHRhcmdldCBpcyBhbHJlYWR5IGEgRE9NIGVsZW1lbnRcclxuICAgIGlmICh0YXJnZXQgJiYgdGFyZ2V0Lm5vZGVOYW1lICYmIHRhcmdldC5ub2RlVHlwZSA9PT0gMSkge1xyXG4gICAgICAgIHJldHVybiB0YXJnZXQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIFVzZSAnI2ludGVyYWN0aXZlLnZpZXdwb3J0JyBhcyBhIGZhbGxiYWNrIHNlbGVjdG9yIChiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSlcclxuICAgICAgICB2YXIgc2VsZWN0b3IgPSB0eXBlb2YgdGFyZ2V0ID09PSAnc3RyaW5nJyA/IHRhcmdldCA6ICcjaW50ZXJhY3RpdmUudmlld3BvcnQnO1xyXG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gY2FuUmVjb3JkKGNiKSB7XHJcbiAgICBCYXJjb2RlTG9jYXRvci5jaGVja0ltYWdlQ29uc3RyYWludHMoX2lucHV0U3RyZWFtLCBfY29uZmlnLmxvY2F0b3IpO1xyXG4gICAgaW5pdENhbnZhcyhfY29uZmlnKTtcclxuICAgIF9mcmFtZWdyYWJiZXIgPSBGcmFtZUdyYWJiZXIuY3JlYXRlKF9pbnB1dFN0cmVhbSwgX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UpO1xyXG5cclxuICAgIGFkanVzdFdvcmtlclBvb2woX2NvbmZpZy5udW1PZldvcmtlcnMsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGlmIChfY29uZmlnLm51bU9mV29ya2VycyA9PT0gMCkge1xyXG4gICAgICAgICAgICBpbml0aWFsaXplRGF0YSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZWFkeShjYik7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVhZHkoY2Ipe1xyXG4gICAgX2lucHV0U3RyZWFtLnBsYXkoKTtcclxuICAgIGNiKCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGluaXRDYW52YXMoKSB7XHJcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSBcInVuZGVmaW5lZFwiKSB7XHJcbiAgICAgICAgdmFyICR2aWV3cG9ydCA9IGdldFZpZXdQb3J0KCk7XHJcbiAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiY2FudmFzLmltZ0J1ZmZlclwiKTtcclxuICAgICAgICBpZiAoIV9jYW52YXNDb250YWluZXIuZG9tLmltYWdlKSB7XHJcbiAgICAgICAgICAgIF9jYW52YXNDb250YWluZXIuZG9tLmltYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcclxuICAgICAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5kb20uaW1hZ2UuY2xhc3NOYW1lID0gXCJpbWdCdWZmZXJcIjtcclxuICAgICAgICAgICAgaWYgKCR2aWV3cG9ydCAmJiBfY29uZmlnLmlucHV0U3RyZWFtLnR5cGUgPT09IFwiSW1hZ2VTdHJlYW1cIikge1xyXG4gICAgICAgICAgICAgICAgJHZpZXdwb3J0LmFwcGVuZENoaWxkKF9jYW52YXNDb250YWluZXIuZG9tLmltYWdlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBfY2FudmFzQ29udGFpbmVyLmN0eC5pbWFnZSA9IF9jYW52YXNDb250YWluZXIuZG9tLmltYWdlLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5pbWFnZS53aWR0aCA9IF9pbnB1dFN0cmVhbS5nZXRDYW52YXNTaXplKCkueDtcclxuICAgICAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5pbWFnZS5oZWlnaHQgPSBfaW5wdXRTdHJlYW0uZ2V0Q2FudmFzU2l6ZSgpLnk7XHJcblxyXG4gICAgICAgIF9jYW52YXNDb250YWluZXIuZG9tLm92ZXJsYXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiY2FudmFzLmRyYXdpbmdCdWZmZXJcIik7XHJcbiAgICAgICAgaWYgKCFfY2FudmFzQ29udGFpbmVyLmRvbS5vdmVybGF5KSB7XHJcbiAgICAgICAgICAgIF9jYW52YXNDb250YWluZXIuZG9tLm92ZXJsYXkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xyXG4gICAgICAgICAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5vdmVybGF5LmNsYXNzTmFtZSA9IFwiZHJhd2luZ0J1ZmZlclwiO1xyXG4gICAgICAgICAgICBpZiAoJHZpZXdwb3J0KSB7XHJcbiAgICAgICAgICAgICAgICAkdmlld3BvcnQuYXBwZW5kQ2hpbGQoX2NhbnZhc0NvbnRhaW5lci5kb20ub3ZlcmxheSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGNsZWFyRml4ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImJyXCIpO1xyXG4gICAgICAgICAgICBjbGVhckZpeC5zZXRBdHRyaWJ1dGUoXCJjbGVhclwiLCBcImFsbFwiKTtcclxuICAgICAgICAgICAgaWYgKCR2aWV3cG9ydCkge1xyXG4gICAgICAgICAgICAgICAgJHZpZXdwb3J0LmFwcGVuZENoaWxkKGNsZWFyRml4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBfY2FudmFzQ29udGFpbmVyLmN0eC5vdmVybGF5ID0gX2NhbnZhc0NvbnRhaW5lci5kb20ub3ZlcmxheS5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgICAgX2NhbnZhc0NvbnRhaW5lci5kb20ub3ZlcmxheS53aWR0aCA9IF9pbnB1dFN0cmVhbS5nZXRDYW52YXNTaXplKCkueDtcclxuICAgICAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5vdmVybGF5LmhlaWdodCA9IF9pbnB1dFN0cmVhbS5nZXRDYW52YXNTaXplKCkueTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gaW5pdEJ1ZmZlcnMoaW1hZ2VXcmFwcGVyKSB7XHJcbiAgICBpZiAoaW1hZ2VXcmFwcGVyKSB7XHJcbiAgICAgICAgX2lucHV0SW1hZ2VXcmFwcGVyID0gaW1hZ2VXcmFwcGVyO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBfaW5wdXRJbWFnZVdyYXBwZXIgPSBuZXcgSW1hZ2VXcmFwcGVyKHtcclxuICAgICAgICAgICAgeDogX2lucHV0U3RyZWFtLmdldFdpZHRoKCksXHJcbiAgICAgICAgICAgIHk6IF9pbnB1dFN0cmVhbS5nZXRIZWlnaHQoKVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQpIHtcclxuICAgICAgICBjb25zb2xlLmxvZyhfaW5wdXRJbWFnZVdyYXBwZXIuc2l6ZSk7XHJcbiAgICB9XHJcbiAgICBfYm94U2l6ZSA9IFtcclxuICAgICAgICB2ZWMyLmNsb25lKFswLCAwXSksXHJcbiAgICAgICAgdmVjMi5jbG9uZShbMCwgX2lucHV0SW1hZ2VXcmFwcGVyLnNpemUueV0pLFxyXG4gICAgICAgIHZlYzIuY2xvbmUoW19pbnB1dEltYWdlV3JhcHBlci5zaXplLngsIF9pbnB1dEltYWdlV3JhcHBlci5zaXplLnldKSxcclxuICAgICAgICB2ZWMyLmNsb25lKFtfaW5wdXRJbWFnZVdyYXBwZXIuc2l6ZS54LCAwXSlcclxuICAgIF07XHJcbiAgICBCYXJjb2RlTG9jYXRvci5pbml0KF9pbnB1dEltYWdlV3JhcHBlciwgX2NvbmZpZy5sb2NhdG9yKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0Qm91bmRpbmdCb3hlcygpIHtcclxuICAgIGlmIChfY29uZmlnLmxvY2F0ZSkge1xyXG4gICAgICAgIHJldHVybiBCYXJjb2RlTG9jYXRvci5sb2NhdGUoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIFtbXHJcbiAgICAgICAgICAgIHZlYzIuY2xvbmUoX2JveFNpemVbMF0pLFxyXG4gICAgICAgICAgICB2ZWMyLmNsb25lKF9ib3hTaXplWzFdKSxcclxuICAgICAgICAgICAgdmVjMi5jbG9uZShfYm94U2l6ZVsyXSksXHJcbiAgICAgICAgICAgIHZlYzIuY2xvbmUoX2JveFNpemVbM10pXV07XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRyYW5zZm9ybVJlc3VsdChyZXN1bHQpIHtcclxuICAgIHZhciB0b3BSaWdodCA9IF9pbnB1dFN0cmVhbS5nZXRUb3BSaWdodCgpLFxyXG4gICAgICAgIHhPZmZzZXQgPSB0b3BSaWdodC54LFxyXG4gICAgICAgIHlPZmZzZXQgPSB0b3BSaWdodC55LFxyXG4gICAgICAgIGk7XHJcblxyXG4gICAgaWYgKHhPZmZzZXQgPT09IDAgJiYgeU9mZnNldCA9PT0gMCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAocmVzdWx0LmJhcmNvZGVzKSB7XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHJlc3VsdC5iYXJjb2Rlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0cmFuc2Zvcm1SZXN1bHQocmVzdWx0LmJhcmNvZGVzW2ldKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHJlc3VsdC5saW5lICYmIHJlc3VsdC5saW5lLmxlbmd0aCA9PT0gMikge1xyXG4gICAgICAgIG1vdmVMaW5lKHJlc3VsdC5saW5lKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAocmVzdWx0LmJveCkge1xyXG4gICAgICAgIG1vdmVCb3gocmVzdWx0LmJveCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHJlc3VsdC5ib3hlcyAmJiByZXN1bHQuYm94ZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCByZXN1bHQuYm94ZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbW92ZUJveChyZXN1bHQuYm94ZXNbaV0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBtb3ZlQm94KGJveCkge1xyXG4gICAgICAgIHZhciBjb3JuZXIgPSBib3gubGVuZ3RoO1xyXG5cclxuICAgICAgICB3aGlsZSAoY29ybmVyLS0pIHtcclxuICAgICAgICAgICAgYm94W2Nvcm5lcl1bMF0gKz0geE9mZnNldDtcclxuICAgICAgICAgICAgYm94W2Nvcm5lcl1bMV0gKz0geU9mZnNldDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gbW92ZUxpbmUobGluZSkge1xyXG4gICAgICAgIGxpbmVbMF0ueCArPSB4T2Zmc2V0O1xyXG4gICAgICAgIGxpbmVbMF0ueSArPSB5T2Zmc2V0O1xyXG4gICAgICAgIGxpbmVbMV0ueCArPSB4T2Zmc2V0O1xyXG4gICAgICAgIGxpbmVbMV0ueSArPSB5T2Zmc2V0O1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRSZXN1bHQgKHJlc3VsdCwgaW1hZ2VEYXRhKSB7XHJcbiAgICBpZiAoIWltYWdlRGF0YSB8fCAhX3Jlc3VsdENvbGxlY3Rvcikge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAocmVzdWx0LmJhcmNvZGVzKSB7XHJcbiAgICAgICAgcmVzdWx0LmJhcmNvZGVzLmZpbHRlcihiYXJjb2RlID0+IGJhcmNvZGUuY29kZVJlc3VsdClcclxuICAgICAgICAgICAgLmZvckVhY2goYmFyY29kZSA9PiBhZGRSZXN1bHQoYmFyY29kZSwgaW1hZ2VEYXRhKSk7XHJcbiAgICB9IGVsc2UgaWYgKHJlc3VsdC5jb2RlUmVzdWx0KSB7XHJcbiAgICAgICAgX3Jlc3VsdENvbGxlY3Rvci5hZGRSZXN1bHQoaW1hZ2VEYXRhLCBfaW5wdXRTdHJlYW0uZ2V0Q2FudmFzU2l6ZSgpLCByZXN1bHQuY29kZVJlc3VsdCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhhc0NvZGVSZXN1bHQgKHJlc3VsdCkge1xyXG4gICAgcmV0dXJuIHJlc3VsdCAmJiAocmVzdWx0LmJhcmNvZGVzID9cclxuICAgICAgcmVzdWx0LmJhcmNvZGVzLnNvbWUoYmFyY29kZSA9PiBiYXJjb2RlLmNvZGVSZXN1bHQpIDpcclxuICAgICAgcmVzdWx0LmNvZGVSZXN1bHQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBwdWJsaXNoUmVzdWx0KHJlc3VsdCwgaW1hZ2VEYXRhKSB7XHJcbiAgICBsZXQgcmVzdWx0VG9QdWJsaXNoID0gcmVzdWx0O1xyXG5cclxuICAgIGlmIChyZXN1bHQgJiYgX29uVUlUaHJlYWQpIHtcclxuICAgICAgICB0cmFuc2Zvcm1SZXN1bHQocmVzdWx0KTtcclxuICAgICAgICBhZGRSZXN1bHQocmVzdWx0LCBpbWFnZURhdGEpO1xyXG4gICAgICAgIHJlc3VsdFRvUHVibGlzaCA9IHJlc3VsdC5iYXJjb2RlcyB8fCByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgRXZlbnRzLnB1Ymxpc2goXCJwcm9jZXNzZWRcIiwgcmVzdWx0VG9QdWJsaXNoKTtcclxuICAgIGlmIChoYXNDb2RlUmVzdWx0KHJlc3VsdCkpIHtcclxuICAgICAgICBFdmVudHMucHVibGlzaChcImRldGVjdGVkXCIsIHJlc3VsdFRvUHVibGlzaCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxvY2F0ZUFuZERlY29kZSgpIHtcclxuICAgIHZhciByZXN1bHQsXHJcbiAgICAgICAgYm94ZXM7XHJcblxyXG4gICAgYm94ZXMgPSBnZXRCb3VuZGluZ0JveGVzKCk7XHJcbiAgICBpZiAoYm94ZXMpIHtcclxuICAgICAgICByZXN1bHQgPSBfZGVjb2Rlci5kZWNvZGVGcm9tQm91bmRpbmdCb3hlcyhib3hlcyk7XHJcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0IHx8IHt9O1xyXG4gICAgICAgIHJlc3VsdC5ib3hlcyA9IGJveGVzO1xyXG4gICAgICAgIHB1Ymxpc2hSZXN1bHQocmVzdWx0LCBfaW5wdXRJbWFnZVdyYXBwZXIuZGF0YSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHB1Ymxpc2hSZXN1bHQoKTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdXBkYXRlKCkge1xyXG4gICAgdmFyIGF2YWlsYWJsZVdvcmtlcjtcclxuXHJcbiAgICBpZiAoX29uVUlUaHJlYWQpIHtcclxuICAgICAgICBpZiAoX3dvcmtlclBvb2wubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBhdmFpbGFibGVXb3JrZXIgPSBfd29ya2VyUG9vbC5maWx0ZXIoZnVuY3Rpb24od29ya2VyVGhyZWFkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gIXdvcmtlclRocmVhZC5idXN5O1xyXG4gICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgaWYgKGF2YWlsYWJsZVdvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgX2ZyYW1lZ3JhYmJlci5hdHRhY2hEYXRhKGF2YWlsYWJsZVdvcmtlci5pbWFnZURhdGEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBhbGwgd29ya2VycyBhcmUgYnVzeVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgX2ZyYW1lZ3JhYmJlci5hdHRhY2hEYXRhKF9pbnB1dEltYWdlV3JhcHBlci5kYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKF9mcmFtZWdyYWJiZXIuZ3JhYigpKSB7XHJcbiAgICAgICAgICAgIGlmIChhdmFpbGFibGVXb3JrZXIpIHtcclxuICAgICAgICAgICAgICAgIGF2YWlsYWJsZVdvcmtlci5idXN5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGF2YWlsYWJsZVdvcmtlci53b3JrZXIucG9zdE1lc3NhZ2Uoe1xyXG4gICAgICAgICAgICAgICAgICAgIGNtZDogJ3Byb2Nlc3MnLFxyXG4gICAgICAgICAgICAgICAgICAgIGltYWdlRGF0YTogYXZhaWxhYmxlV29ya2VyLmltYWdlRGF0YVxyXG4gICAgICAgICAgICAgICAgfSwgW2F2YWlsYWJsZVdvcmtlci5pbWFnZURhdGEuYnVmZmVyXSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsb2NhdGVBbmREZWNvZGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbG9jYXRlQW5kRGVjb2RlKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHN0YXJ0Q29udGludW91c1VwZGF0ZSgpIHtcclxuICAgIHZhciBuZXh0ID0gbnVsbCxcclxuICAgICAgICBkZWxheSA9IDEwMDAgLyAoX2NvbmZpZy5mcmVxdWVuY3kgfHwgNjApO1xyXG5cclxuICAgIF9zdG9wcGVkID0gZmFsc2U7XHJcbiAgICAoZnVuY3Rpb24gZnJhbWUodGltZXN0YW1wKSB7XHJcbiAgICAgICAgbmV4dCA9IG5leHQgfHwgdGltZXN0YW1wO1xyXG4gICAgICAgIGlmICghX3N0b3BwZWQpIHtcclxuICAgICAgICAgICAgaWYgKHRpbWVzdGFtcCA+PSBuZXh0KSB7XHJcbiAgICAgICAgICAgICAgICBuZXh0ICs9IGRlbGF5O1xyXG4gICAgICAgICAgICAgICAgdXBkYXRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltRnJhbWUoZnJhbWUpO1xyXG4gICAgICAgIH1cclxuICAgIH0ocGVyZm9ybWFuY2Uubm93KCkpKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc3RhcnQoKSB7XHJcbiAgICBpZiAoX29uVUlUaHJlYWQgJiYgX2NvbmZpZy5pbnB1dFN0cmVhbS50eXBlID09PSBcIkxpdmVTdHJlYW1cIikge1xyXG4gICAgICAgIHN0YXJ0Q29udGludW91c1VwZGF0ZSgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB1cGRhdGUoKTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gaW5pdFdvcmtlcihjYikge1xyXG4gICAgdmFyIGJsb2JVUkwsXHJcbiAgICAgICAgd29ya2VyVGhyZWFkID0ge1xyXG4gICAgICAgICAgICB3b3JrZXI6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgaW1hZ2VEYXRhOiBuZXcgVWludDhBcnJheShfaW5wdXRTdHJlYW0uZ2V0V2lkdGgoKSAqIF9pbnB1dFN0cmVhbS5nZXRIZWlnaHQoKSksXHJcbiAgICAgICAgICAgIGJ1c3k6IHRydWVcclxuICAgICAgICB9O1xyXG5cclxuICAgIGJsb2JVUkwgPSBnZW5lcmF0ZVdvcmtlckJsb2IoKTtcclxuICAgIHdvcmtlclRocmVhZC53b3JrZXIgPSBuZXcgV29ya2VyKGJsb2JVUkwpO1xyXG5cclxuICAgIHdvcmtlclRocmVhZC53b3JrZXIub25tZXNzYWdlID0gZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGlmIChlLmRhdGEuZXZlbnQgPT09ICdpbml0aWFsaXplZCcpIHtcclxuICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTChibG9iVVJMKTtcclxuICAgICAgICAgICAgd29ya2VyVGhyZWFkLmJ1c3kgPSBmYWxzZTtcclxuICAgICAgICAgICAgd29ya2VyVGhyZWFkLmltYWdlRGF0YSA9IG5ldyBVaW50OEFycmF5KGUuZGF0YS5pbWFnZURhdGEpO1xyXG4gICAgICAgICAgICBpZiAoRU5WLmRldmVsb3BtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIldvcmtlciBpbml0aWFsaXplZFwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gY2Iod29ya2VyVGhyZWFkKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGUuZGF0YS5ldmVudCA9PT0gJ3Byb2Nlc3NlZCcpIHtcclxuICAgICAgICAgICAgd29ya2VyVGhyZWFkLmltYWdlRGF0YSA9IG5ldyBVaW50OEFycmF5KGUuZGF0YS5pbWFnZURhdGEpO1xyXG4gICAgICAgICAgICB3b3JrZXJUaHJlYWQuYnVzeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICBwdWJsaXNoUmVzdWx0KGUuZGF0YS5yZXN1bHQsIHdvcmtlclRocmVhZC5pbWFnZURhdGEpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoZS5kYXRhLmV2ZW50ID09PSAnZXJyb3InKSB7XHJcbiAgICAgICAgICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiV29ya2VyIGVycm9yOiBcIiArIGUuZGF0YS5tZXNzYWdlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgd29ya2VyVGhyZWFkLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgY21kOiAnaW5pdCcsXHJcbiAgICAgICAgc2l6ZToge3g6IF9pbnB1dFN0cmVhbS5nZXRXaWR0aCgpLCB5OiBfaW5wdXRTdHJlYW0uZ2V0SGVpZ2h0KCl9LFxyXG4gICAgICAgIGltYWdlRGF0YTogd29ya2VyVGhyZWFkLmltYWdlRGF0YSxcclxuICAgICAgICBjb25maWc6IGNvbmZpZ0ZvcldvcmtlcihfY29uZmlnKVxyXG4gICAgfSwgW3dvcmtlclRocmVhZC5pbWFnZURhdGEuYnVmZmVyXSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNvbmZpZ0Zvcldvcmtlcihjb25maWcpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgLi4uY29uZmlnLFxyXG4gICAgICAgIGlucHV0U3RyZWFtOiB7XHJcbiAgICAgICAgICAgIC4uLmNvbmZpZy5pbnB1dFN0cmVhbSxcclxuICAgICAgICAgICAgdGFyZ2V0OiBudWxsXHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gd29ya2VySW50ZXJmYWNlKGZhY3RvcnkpIHtcclxuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmKi9cclxuICAgIGlmIChmYWN0b3J5KSB7XHJcbiAgICAgICAgdmFyIFF1YWdnYSA9IGZhY3RvcnkoKS5kZWZhdWx0O1xyXG4gICAgICAgIGlmICghUXVhZ2dhKSB7XHJcbiAgICAgICAgICAgIHNlbGYucG9zdE1lc3NhZ2UoeydldmVudCc6ICdlcnJvcicsIG1lc3NhZ2U6ICdRdWFnZ2EgY291bGQgbm90IGJlIGNyZWF0ZWQnfSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB2YXIgaW1hZ2VXcmFwcGVyO1xyXG5cclxuICAgIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGlmIChlLmRhdGEuY21kID09PSAnaW5pdCcpIHtcclxuICAgICAgICAgICAgdmFyIGNvbmZpZyA9IGUuZGF0YS5jb25maWc7XHJcbiAgICAgICAgICAgIGNvbmZpZy5udW1PZldvcmtlcnMgPSAwO1xyXG4gICAgICAgICAgICBpbWFnZVdyYXBwZXIgPSBuZXcgUXVhZ2dhLkltYWdlV3JhcHBlcih7XHJcbiAgICAgICAgICAgICAgICB4OiBlLmRhdGEuc2l6ZS54LFxyXG4gICAgICAgICAgICAgICAgeTogZS5kYXRhLnNpemUueVxyXG4gICAgICAgICAgICB9LCBuZXcgVWludDhBcnJheShlLmRhdGEuaW1hZ2VEYXRhKSk7XHJcbiAgICAgICAgICAgIFF1YWdnYS5pbml0KGNvbmZpZywgcmVhZHksIGltYWdlV3JhcHBlcik7XHJcbiAgICAgICAgICAgIFF1YWdnYS5vblByb2Nlc3NlZChvblByb2Nlc3NlZCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChlLmRhdGEuY21kID09PSAncHJvY2VzcycpIHtcclxuICAgICAgICAgICAgaW1hZ2VXcmFwcGVyLmRhdGEgPSBuZXcgVWludDhBcnJheShlLmRhdGEuaW1hZ2VEYXRhKTtcclxuICAgICAgICAgICAgUXVhZ2dhLnN0YXJ0KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChlLmRhdGEuY21kID09PSAnc2V0UmVhZGVycycpIHtcclxuICAgICAgICAgICAgUXVhZ2dhLnNldFJlYWRlcnMoZS5kYXRhLnJlYWRlcnMpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgZnVuY3Rpb24gb25Qcm9jZXNzZWQocmVzdWx0KSB7XHJcbiAgICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICdldmVudCc6ICdwcm9jZXNzZWQnLFxyXG4gICAgICAgICAgICBpbWFnZURhdGE6IGltYWdlV3JhcHBlci5kYXRhLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJlc3VsdFxyXG4gICAgICAgIH0sIFtpbWFnZVdyYXBwZXIuZGF0YS5idWZmZXJdKTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiByZWFkeSgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxyXG4gICAgICAgIHNlbGYucG9zdE1lc3NhZ2UoeydldmVudCc6ICdpbml0aWFsaXplZCcsIGltYWdlRGF0YTogaW1hZ2VXcmFwcGVyLmRhdGF9LCBbaW1hZ2VXcmFwcGVyLmRhdGEuYnVmZmVyXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyogZXNsaW50LWVuYWJsZSAqL1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZW5lcmF0ZVdvcmtlckJsb2IoKSB7XHJcbiAgICB2YXIgYmxvYixcclxuICAgICAgICBmYWN0b3J5U291cmNlO1xyXG5cclxuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuICAgIGlmICh0eXBlb2YgX19mYWN0b3J5U291cmNlX18gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgZmFjdG9yeVNvdXJjZSA9IF9fZmFjdG9yeVNvdXJjZV9fOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXHJcbiAgICB9XHJcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG5cclxuICAgIGJsb2IgPSBuZXcgQmxvYihbJygnICsgd29ya2VySW50ZXJmYWNlLnRvU3RyaW5nKCkgKyAnKSgnICsgZmFjdG9yeVNvdXJjZSArICcpOyddLFxyXG4gICAgICAgIHt0eXBlOiAndGV4dC9qYXZhc2NyaXB0J30pO1xyXG5cclxuICAgIHJldHVybiB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2V0UmVhZGVycyhyZWFkZXJzKSB7XHJcbiAgICBpZiAoX2RlY29kZXIpIHtcclxuICAgICAgICBfZGVjb2Rlci5zZXRSZWFkZXJzKHJlYWRlcnMpO1xyXG4gICAgfSBlbHNlIGlmIChfb25VSVRocmVhZCAmJiBfd29ya2VyUG9vbC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgX3dvcmtlclBvb2wuZm9yRWFjaChmdW5jdGlvbih3b3JrZXJUaHJlYWQpIHtcclxuICAgICAgICAgICAgd29ya2VyVGhyZWFkLndvcmtlci5wb3N0TWVzc2FnZSh7Y21kOiAnc2V0UmVhZGVycycsIHJlYWRlcnM6IHJlYWRlcnN9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gYWRqdXN0V29ya2VyUG9vbChjYXBhY2l0eSwgY2IpIHtcclxuICAgIGNvbnN0IGluY3JlYXNlQnkgPSBjYXBhY2l0eSAtIF93b3JrZXJQb29sLmxlbmd0aDtcclxuICAgIGlmIChpbmNyZWFzZUJ5ID09PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuIGNiICYmIGNiKCk7XHJcbiAgICB9XHJcbiAgICBpZiAoaW5jcmVhc2VCeSA8IDApIHtcclxuICAgICAgICBjb25zdCB3b3JrZXJzVG9UZXJtaW5hdGUgPSBfd29ya2VyUG9vbC5zbGljZShpbmNyZWFzZUJ5KTtcclxuICAgICAgICB3b3JrZXJzVG9UZXJtaW5hdGUuZm9yRWFjaChmdW5jdGlvbih3b3JrZXJUaHJlYWQpIHtcclxuICAgICAgICAgICAgd29ya2VyVGhyZWFkLndvcmtlci50ZXJtaW5hdGUoKTtcclxuICAgICAgICAgICAgaWYgKEVOVi5kZXZlbG9wbWVudCkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJXb3JrZXIgdGVybWluYXRlZCFcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBfd29ya2VyUG9vbCA9IF93b3JrZXJQb29sLnNsaWNlKDAsIGluY3JlYXNlQnkpO1xyXG4gICAgICAgIHJldHVybiBjYiAmJiBjYigpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluY3JlYXNlQnk7IGkrKykge1xyXG4gICAgICAgICAgICBpbml0V29ya2VyKHdvcmtlckluaXRpYWxpemVkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdvcmtlckluaXRpYWxpemVkKHdvcmtlclRocmVhZCkge1xyXG4gICAgICAgICAgICBfd29ya2VyUG9vbC5wdXNoKHdvcmtlclRocmVhZCk7XHJcbiAgICAgICAgICAgIGlmIChfd29ya2VyUG9vbC5sZW5ndGggPj0gY2FwYWNpdHkpe1xyXG4gICAgICAgICAgICAgICAgY2IgJiYgY2IoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgaW5pdDogZnVuY3Rpb24oY29uZmlnLCBjYiwgaW1hZ2VXcmFwcGVyKSB7XHJcbiAgICAgICAgX2NvbmZpZyA9IG1lcmdlKHt9LCBDb25maWcsIGNvbmZpZyk7XHJcbiAgICAgICAgaWYgKGltYWdlV3JhcHBlcikge1xyXG4gICAgICAgICAgICBfb25VSVRocmVhZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBpbml0aWFsaXplRGF0YShpbWFnZVdyYXBwZXIpO1xyXG4gICAgICAgICAgICByZXR1cm4gY2IoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpbml0SW5wdXRTdHJlYW0oY2IpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBzdGFydDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgc3RhcnQoKTtcclxuICAgIH0sXHJcbiAgICBzdG9wOiBmdW5jdGlvbigpIHtcclxuICAgICAgICBfc3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgYWRqdXN0V29ya2VyUG9vbCgwKTtcclxuICAgICAgICBpZiAoX2NvbmZpZy5pbnB1dFN0cmVhbS50eXBlID09PSBcIkxpdmVTdHJlYW1cIikge1xyXG4gICAgICAgICAgICBDYW1lcmFBY2Nlc3MucmVsZWFzZSgpO1xyXG4gICAgICAgICAgICBfaW5wdXRTdHJlYW0uY2xlYXJFdmVudEhhbmRsZXJzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHBhdXNlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICBfc3RvcHBlZCA9IHRydWU7XHJcbiAgICB9LFxyXG4gICAgb25EZXRlY3RlZDogZnVuY3Rpb24oY2FsbGJhY2spIHtcclxuICAgICAgICBFdmVudHMuc3Vic2NyaWJlKFwiZGV0ZWN0ZWRcIiwgY2FsbGJhY2spO1xyXG4gICAgfSxcclxuICAgIG9mZkRldGVjdGVkOiBmdW5jdGlvbihjYWxsYmFjaykge1xyXG4gICAgICAgIEV2ZW50cy51bnN1YnNjcmliZShcImRldGVjdGVkXCIsIGNhbGxiYWNrKTtcclxuICAgIH0sXHJcbiAgICBvblByb2Nlc3NlZDogZnVuY3Rpb24oY2FsbGJhY2spIHtcclxuICAgICAgICBFdmVudHMuc3Vic2NyaWJlKFwicHJvY2Vzc2VkXCIsIGNhbGxiYWNrKTtcclxuICAgIH0sXHJcbiAgICBvZmZQcm9jZXNzZWQ6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgRXZlbnRzLnVuc3Vic2NyaWJlKFwicHJvY2Vzc2VkXCIsIGNhbGxiYWNrKTtcclxuICAgIH0sXHJcbiAgICBzZXRSZWFkZXJzOiBmdW5jdGlvbihyZWFkZXJzKSB7XHJcbiAgICAgICAgc2V0UmVhZGVycyhyZWFkZXJzKTtcclxuICAgIH0sXHJcbiAgICByZWdpc3RlclJlc3VsdENvbGxlY3RvcjogZnVuY3Rpb24ocmVzdWx0Q29sbGVjdG9yKSB7XHJcbiAgICAgICAgaWYgKHJlc3VsdENvbGxlY3RvciAmJiB0eXBlb2YgcmVzdWx0Q29sbGVjdG9yLmFkZFJlc3VsdCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICBfcmVzdWx0Q29sbGVjdG9yID0gcmVzdWx0Q29sbGVjdG9yO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBjYW52YXM6IF9jYW52YXNDb250YWluZXIsXHJcbiAgICBkZWNvZGVTaW5nbGU6IGZ1bmN0aW9uKGNvbmZpZywgcmVzdWx0Q2FsbGJhY2spIHtcclxuICAgICAgICBjb25maWcgPSBtZXJnZSh7XHJcbiAgICAgICAgICAgIGlucHV0U3RyZWFtOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBcIkltYWdlU3RyZWFtXCIsXHJcbiAgICAgICAgICAgICAgICBzZXF1ZW5jZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBzaXplOiA4MDAsXHJcbiAgICAgICAgICAgICAgICBzcmM6IGNvbmZpZy5zcmNcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbnVtT2ZXb3JrZXJzOiAoRU5WLmRldmVsb3BtZW50ICYmIGNvbmZpZy5kZWJ1ZykgPyAwIDogMSxcclxuICAgICAgICAgICAgbG9jYXRvcjoge1xyXG4gICAgICAgICAgICAgICAgaGFsZlNhbXBsZTogZmFsc2VcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIGNvbmZpZyk7XHJcbiAgICAgICAgdGhpcy5pbml0KGNvbmZpZywgKCkgPT4ge1xyXG4gICAgICAgICAgICBFdmVudHMub25jZShcInByb2Nlc3NlZFwiLCAocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3AoKTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdENhbGxiYWNrLmNhbGwobnVsbCwgcmVzdWx0KTtcclxuICAgICAgICAgICAgfSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHN0YXJ0KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9LFxyXG4gICAgSW1hZ2VXcmFwcGVyOiBJbWFnZVdyYXBwZXIsXHJcbiAgICBJbWFnZURlYnVnOiBJbWFnZURlYnVnLFxyXG4gICAgUmVzdWx0Q29sbGVjdG9yOiBSZXN1bHRDb2xsZWN0b3JcclxufTtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvcXVhZ2dhLmpzXG4gKiovIiwiaW1wb3J0IEltYWdlRGVidWcgZnJvbSAnLi4vY29tbW9uL2ltYWdlX2RlYnVnJztcclxuXHJcbmZ1bmN0aW9uIGNvbnRhaW5zKGNvZGVSZXN1bHQsIGxpc3QpIHtcclxuICAgIGlmIChsaXN0KSB7XHJcbiAgICAgICAgcmV0dXJuIGxpc3Quc29tZShmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoaXRlbSkuZXZlcnkoZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW1ba2V5XSA9PT0gY29kZVJlc3VsdFtrZXldO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gcGFzc2VzRmlsdGVyKGNvZGVSZXN1bHQsIGZpbHRlcikge1xyXG4gICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICByZXR1cm4gZmlsdGVyKGNvZGVSZXN1bHQpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIGNyZWF0ZTogZnVuY3Rpb24oY29uZmlnKSB7XHJcbiAgICAgICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIiksXHJcbiAgICAgICAgICAgIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIiksXHJcbiAgICAgICAgICAgIHJlc3VsdHMgPSBbXSxcclxuICAgICAgICAgICAgY2FwYWNpdHkgPSBjb25maWcuY2FwYWNpdHkgfHwgMjAsXHJcbiAgICAgICAgICAgIGNhcHR1cmUgPSBjb25maWcuY2FwdHVyZSA9PT0gdHJ1ZTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gbWF0Y2hlc0NvbnN0cmFpbnRzKGNvZGVSZXN1bHQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNhcGFjaXR5XHJcbiAgICAgICAgICAgICAgICAmJiBjb2RlUmVzdWx0XHJcbiAgICAgICAgICAgICAgICAmJiAhY29udGFpbnMoY29kZVJlc3VsdCwgY29uZmlnLmJsYWNrbGlzdClcclxuICAgICAgICAgICAgICAgICYmIHBhc3Nlc0ZpbHRlcihjb2RlUmVzdWx0LCBjb25maWcuZmlsdGVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGFkZFJlc3VsdDogZnVuY3Rpb24oZGF0YSwgaW1hZ2VTaXplLCBjb2RlUmVzdWx0KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoZXNDb25zdHJhaW50cyhjb2RlUmVzdWx0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhcGFjaXR5LS07XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmNvZGVSZXN1bHQgPSBjb2RlUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjYXB0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IGltYWdlU2l6ZS54O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaW1hZ2VTaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd0ltYWdlKGRhdGEsIGltYWdlU2l6ZSwgY3R4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmZyYW1lID0gY2FudmFzLnRvRGF0YVVSTCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2gocmVzdWx0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZ2V0UmVzdWx0czogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn07XHJcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2FuYWx5dGljcy9yZXN1bHRfY29sbGVjdG9yLmpzXG4gKiovIiwiY29uc3QgdmVjMiA9IHtcclxuICAgIGNsb25lOiByZXF1aXJlKCdnbC12ZWMyL2Nsb25lJyksXHJcbiAgICBkb3Q6IHJlcXVpcmUoJ2dsLXZlYzIvZG90JylcclxufVxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgY2x1c3RlciBmb3IgZ3JvdXBpbmcgc2ltaWxhciBvcmllbnRhdGlvbnMgb2YgZGF0YXBvaW50c1xyXG4gICAgICovXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIGNyZWF0ZTogZnVuY3Rpb24ocG9pbnQsIHRocmVzaG9sZCkge1xyXG4gICAgICAgIHZhciBwb2ludHMgPSBbXSxcclxuICAgICAgICAgICAgY2VudGVyID0ge1xyXG4gICAgICAgICAgICAgICAgcmFkOiAwLFxyXG4gICAgICAgICAgICAgICAgdmVjOiB2ZWMyLmNsb25lKFswLCAwXSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcG9pbnRNYXAgPSB7fTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gaW5pdCgpIHtcclxuICAgICAgICAgICAgYWRkKHBvaW50KTtcclxuICAgICAgICAgICAgdXBkYXRlQ2VudGVyKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBhZGQocG9pbnRUb0FkZCkge1xyXG4gICAgICAgICAgICBwb2ludE1hcFtwb2ludFRvQWRkLmlkXSA9IHBvaW50VG9BZGQ7XHJcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHBvaW50VG9BZGQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gdXBkYXRlQ2VudGVyKCkge1xyXG4gICAgICAgICAgICB2YXIgaSwgc3VtID0gMDtcclxuICAgICAgICAgICAgZm9yICggaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHN1bSArPSBwb2ludHNbaV0ucmFkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNlbnRlci5yYWQgPSBzdW0gLyBwb2ludHMubGVuZ3RoO1xyXG4gICAgICAgICAgICBjZW50ZXIudmVjID0gdmVjMi5jbG9uZShbTWF0aC5jb3MoY2VudGVyLnJhZCksIE1hdGguc2luKGNlbnRlci5yYWQpXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbml0KCk7XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGFkZDogZnVuY3Rpb24ocG9pbnRUb0FkZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFwb2ludE1hcFtwb2ludFRvQWRkLmlkXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZChwb2ludFRvQWRkKTtcclxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVDZW50ZXIoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZml0czogZnVuY3Rpb24ob3RoZXJQb2ludCkge1xyXG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgY29zaW5lIHNpbWlsYXJpdHkgdG8gY2VudGVyLWFuZ2xlXHJcbiAgICAgICAgICAgICAgICB2YXIgc2ltaWxhcml0eSA9IE1hdGguYWJzKHZlYzIuZG90KG90aGVyUG9pbnQucG9pbnQudmVjLCBjZW50ZXIudmVjKSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2ltaWxhcml0eSA+IHRocmVzaG9sZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBnZXRQb2ludHM6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvaW50cztcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZ2V0Q2VudGVyOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjZW50ZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgfSxcclxuICAgIGNyZWF0ZVBvaW50OiBmdW5jdGlvbihuZXdQb2ludCwgaWQsIHByb3BlcnR5KSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgcmFkOiBuZXdQb2ludFtwcm9wZXJ0eV0sXHJcbiAgICAgICAgICAgIHBvaW50OiBuZXdQb2ludCxcclxuICAgICAgICAgICAgaWQ6IGlkXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufTtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvY29tbW9uL2NsdXN0ZXIuanNcbiAqKi8iLCJleHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgZXZlbnRzID0ge307XHJcblxyXG4gICAgZnVuY3Rpb24gZ2V0RXZlbnQoZXZlbnROYW1lKSB7XHJcbiAgICAgICAgaWYgKCFldmVudHNbZXZlbnROYW1lXSkge1xyXG4gICAgICAgICAgICBldmVudHNbZXZlbnROYW1lXSA9IHtcclxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXJzOiBbXVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZXZlbnRzW2V2ZW50TmFtZV07XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gY2xlYXJFdmVudHMoKXtcclxuICAgICAgICBldmVudHMgPSB7fTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBwdWJsaXNoU3Vic2NyaXB0aW9uKHN1YnNjcmlwdGlvbiwgZGF0YSkge1xyXG4gICAgICAgIGlmIChzdWJzY3JpcHRpb24uYXN5bmMpIHtcclxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi5jYWxsYmFjayhkYXRhKTtcclxuICAgICAgICAgICAgfSwgNCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc3Vic2NyaXB0aW9uLmNhbGxiYWNrKGRhdGEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBzdWJzY3JpYmUoZXZlbnQsIGNhbGxiYWNrLCBhc3luYykge1xyXG4gICAgICAgIHZhciBzdWJzY3JpcHRpb247XHJcblxyXG4gICAgICAgIGlmICggdHlwZW9mIGNhbGxiYWNrID09PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICAgICAgc3Vic2NyaXB0aW9uID0ge1xyXG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLFxyXG4gICAgICAgICAgICAgICAgYXN5bmM6IGFzeW5jXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc3Vic2NyaXB0aW9uID0gY2FsbGJhY2s7XHJcbiAgICAgICAgICAgIGlmICghc3Vic2NyaXB0aW9uLmNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBcIkNhbGxiYWNrIHdhcyBub3Qgc3BlY2lmaWVkIG9uIG9wdGlvbnNcIjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZ2V0RXZlbnQoZXZlbnQpLnN1YnNjcmliZXJzLnB1c2goc3Vic2NyaXB0aW9uKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHN1YnNjcmliZTogZnVuY3Rpb24oZXZlbnQsIGNhbGxiYWNrLCBhc3luYykge1xyXG4gICAgICAgICAgICByZXR1cm4gc3Vic2NyaWJlKGV2ZW50LCBjYWxsYmFjaywgYXN5bmMpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgcHVibGlzaDogZnVuY3Rpb24oZXZlbnROYW1lLCBkYXRhKSB7XHJcbiAgICAgICAgICAgIHZhciBldmVudCA9IGdldEV2ZW50KGV2ZW50TmFtZSksXHJcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVycyA9IGV2ZW50LnN1YnNjcmliZXJzO1xyXG5cclxuICAgICAgICAgICAgZXZlbnQuc3Vic2NyaWJlcnMgPSBzdWJzY3JpYmVycy5maWx0ZXIoZnVuY3Rpb24oc3Vic2NyaWJlcikge1xyXG4gICAgICAgICAgICAgICAgcHVibGlzaFN1YnNjcmlwdGlvbihzdWJzY3JpYmVyLCBkYXRhKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiAhc3Vic2NyaWJlci5vbmNlO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIG9uY2U6IGZ1bmN0aW9uKGV2ZW50LCBjYWxsYmFjaywgYXN5bmMpIHtcclxuICAgICAgICAgICAgc3Vic2NyaWJlKGV2ZW50LCB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogY2FsbGJhY2ssXHJcbiAgICAgICAgICAgICAgICBhc3luYzogYXN5bmMsXHJcbiAgICAgICAgICAgICAgICBvbmNlOiB0cnVlXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdW5zdWJzY3JpYmU6IGZ1bmN0aW9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgdmFyIGV2ZW50O1xyXG5cclxuICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgZXZlbnQgPSBnZXRFdmVudChldmVudE5hbWUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50ICYmIGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3Vic2NyaWJlcnMgPSBldmVudC5zdWJzY3JpYmVycy5maWx0ZXIoZnVuY3Rpb24oc3Vic2NyaWJlcil7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJzY3JpYmVyLmNhbGxiYWNrICE9PSBjYWxsYmFjaztcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3Vic2NyaWJlcnMgPSBbXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNsZWFyRXZlbnRzKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59KSgpO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9jb21tb24vZXZlbnRzLmpzXG4gKiovIiwiLyoqXHJcbiAqIENvbnN0cnVjdCByZXByZXNlbnRpbmcgYSBwYXJ0IG9mIGFub3RoZXIge0ltYWdlV3JhcHBlcn0uIFNoYXJlcyBkYXRhXHJcbiAqIGJldHdlZW4gdGhlIHBhcmVudCBhbmQgdGhlIGNoaWxkLlxyXG4gKiBAcGFyYW0gZnJvbSB7SW1hZ2VSZWZ9IFRoZSBwb3NpdGlvbiB3aGVyZSB0byBzdGFydCB0aGUge1N1YkltYWdlfSBmcm9tLiAodG9wLWxlZnQgY29ybmVyKVxyXG4gKiBAcGFyYW0gc2l6ZSB7SW1hZ2VSZWZ9IFRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgaW1hZ2VcclxuICogQHBhcmFtIEkge0ltYWdlV3JhcHBlcn0gVGhlIHtJbWFnZVdyYXBwZXJ9IHRvIHNoYXJlIGZyb21cclxuICogQHJldHVybnMge1N1YkltYWdlfSBBIHNoYXJlZCBwYXJ0IG9mIHRoZSBvcmlnaW5hbCBpbWFnZVxyXG4gKi9cclxuZnVuY3Rpb24gU3ViSW1hZ2UoZnJvbSwgc2l6ZSwgSSkge1xyXG4gICAgaWYgKCFJKSB7XHJcbiAgICAgICAgSSA9IHtcclxuICAgICAgICAgICAgZGF0YTogbnVsbCxcclxuICAgICAgICAgICAgc2l6ZTogc2l6ZVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICB0aGlzLmRhdGEgPSBJLmRhdGE7XHJcbiAgICB0aGlzLm9yaWdpbmFsU2l6ZSA9IEkuc2l6ZTtcclxuICAgIHRoaXMuSSA9IEk7XHJcblxyXG4gICAgdGhpcy5mcm9tID0gZnJvbTtcclxuICAgIHRoaXMuc2l6ZSA9IHNpemU7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBEaXNwbGF5cyB0aGUge1N1YkltYWdlfSBpbiBhIGdpdmVuIGNhbnZhc1xyXG4gKiBAcGFyYW0gY2FudmFzIHtDYW52YXN9IFRoZSBjYW52YXMgZWxlbWVudCB0byB3cml0ZSB0b1xyXG4gKiBAcGFyYW0gc2NhbGUge051bWJlcn0gU2NhbGUgd2hpY2ggaXMgYXBwbGllZCB0byBlYWNoIHBpeGVsLXZhbHVlXHJcbiAqL1xyXG5TdWJJbWFnZS5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKGNhbnZhcywgc2NhbGUpIHtcclxuICAgIHZhciBjdHgsXHJcbiAgICAgICAgZnJhbWUsXHJcbiAgICAgICAgZGF0YSxcclxuICAgICAgICBjdXJyZW50LFxyXG4gICAgICAgIHksXHJcbiAgICAgICAgeCxcclxuICAgICAgICBwaXhlbDtcclxuXHJcbiAgICBpZiAoIXNjYWxlKSB7XHJcbiAgICAgICAgc2NhbGUgPSAxLjA7XHJcbiAgICB9XHJcbiAgICBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgIGNhbnZhcy53aWR0aCA9IHRoaXMuc2l6ZS54O1xyXG4gICAgY2FudmFzLmhlaWdodCA9IHRoaXMuc2l6ZS55O1xyXG4gICAgZnJhbWUgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XHJcbiAgICBkYXRhID0gZnJhbWUuZGF0YTtcclxuICAgIGN1cnJlbnQgPSAwO1xyXG4gICAgZm9yICh5ID0gMDsgeSA8IHRoaXMuc2l6ZS55OyB5KyspIHtcclxuICAgICAgICBmb3IgKHggPSAwOyB4IDwgdGhpcy5zaXplLng7IHgrKykge1xyXG4gICAgICAgICAgICBwaXhlbCA9IHkgKiB0aGlzLnNpemUueCArIHg7XHJcbiAgICAgICAgICAgIGN1cnJlbnQgPSB0aGlzLmdldCh4LCB5KSAqIHNjYWxlO1xyXG4gICAgICAgICAgICBkYXRhW3BpeGVsICogNCArIDBdID0gY3VycmVudDtcclxuICAgICAgICAgICAgZGF0YVtwaXhlbCAqIDQgKyAxXSA9IGN1cnJlbnQ7XHJcbiAgICAgICAgICAgIGRhdGFbcGl4ZWwgKiA0ICsgMl0gPSBjdXJyZW50O1xyXG4gICAgICAgICAgICBkYXRhW3BpeGVsICogNCArIDNdID0gMjU1O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGZyYW1lLmRhdGEgPSBkYXRhO1xyXG4gICAgY3R4LnB1dEltYWdlRGF0YShmcmFtZSwgMCwgMCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0cmlldmVzIGEgZ2l2ZW4gcGl4ZWwgcG9zaXRpb24gZnJvbSB0aGUge1N1YkltYWdlfVxyXG4gKiBAcGFyYW0geCB7TnVtYmVyfSBUaGUgeC1wb3NpdGlvblxyXG4gKiBAcGFyYW0geSB7TnVtYmVyfSBUaGUgeS1wb3NpdGlvblxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgZ3JheXNjYWxlIHZhbHVlIGF0IHRoZSBwaXhlbC1wb3NpdGlvblxyXG4gKi9cclxuU3ViSW1hZ2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHgsIHkpIHtcclxuICAgIHJldHVybiB0aGlzLmRhdGFbKHRoaXMuZnJvbS55ICsgeSkgKiB0aGlzLm9yaWdpbmFsU2l6ZS54ICsgdGhpcy5mcm9tLnggKyB4XTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBVcGRhdGVzIHRoZSB1bmRlcmx5aW5nIGRhdGEgZnJvbSBhIGdpdmVuIHtJbWFnZVdyYXBwZXJ9XHJcbiAqIEBwYXJhbSBpbWFnZSB7SW1hZ2VXcmFwcGVyfSBUaGUgdXBkYXRlZCBpbWFnZVxyXG4gKi9cclxuU3ViSW1hZ2UucHJvdG90eXBlLnVwZGF0ZURhdGEgPSBmdW5jdGlvbihpbWFnZSkge1xyXG4gICAgdGhpcy5vcmlnaW5hbFNpemUgPSBpbWFnZS5zaXplO1xyXG4gICAgdGhpcy5kYXRhID0gaW1hZ2UuZGF0YTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBVcGRhdGVzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc2hhcmVkIGFyZWFcclxuICogQHBhcmFtIGZyb20ge3gseX0gVGhlIG5ldyBsb2NhdGlvblxyXG4gKiBAcmV0dXJucyB7U3ViSW1hZ2V9IHJldHVybnMge3RoaXN9IGZvciBwb3NzaWJsZSBjaGFpbmluZ1xyXG4gKi9cclxuU3ViSW1hZ2UucHJvdG90eXBlLnVwZGF0ZUZyb20gPSBmdW5jdGlvbihmcm9tKSB7XHJcbiAgICB0aGlzLmZyb20gPSBmcm9tO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCAoU3ViSW1hZ2UpO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9jb21tb24vc3ViSW1hZ2UuanNcbiAqKi8iLCIvKlxyXG4gKiB0eXBlZGVmcy5qc1xyXG4gKiBOb3JtYWxpemVzIGJyb3dzZXItc3BlY2lmaWMgcHJlZml4ZXNcclxuICovXHJcblxyXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbUZyYW1lID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxyXG4gICAgICAgICAgICB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XHJcbiAgICAgICAgICAgIHdpbmRvdy5tb3pSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgICAgICAgd2luZG93Lm9SZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgICAgICAgd2luZG93Lm1zUmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uICgvKiBmdW5jdGlvbiBGcmFtZVJlcXVlc3RDYWxsYmFjayAqLyBjYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICB9KSgpO1xyXG59XHJcbk1hdGguaW11bCA9IE1hdGguaW11bCB8fCBmdW5jdGlvbihhLCBiKSB7XHJcbiAgICB2YXIgYWggPSAoYSA+Pj4gMTYpICYgMHhmZmZmLFxyXG4gICAgICAgIGFsID0gYSAmIDB4ZmZmZixcclxuICAgICAgICBiaCA9IChiID4+PiAxNikgJiAweGZmZmYsXHJcbiAgICAgICAgYmwgPSBiICYgMHhmZmZmO1xyXG4gICAgLy8gdGhlIHNoaWZ0IGJ5IDAgZml4ZXMgdGhlIHNpZ24gb24gdGhlIGhpZ2ggcGFydFxyXG4gICAgLy8gdGhlIGZpbmFsIHwwIGNvbnZlcnRzIHRoZSB1bnNpZ25lZCB2YWx1ZSBpbnRvIGEgc2lnbmVkIHZhbHVlXHJcbiAgICByZXR1cm4gKChhbCAqIGJsKSArICgoKGFoICogYmwgKyBhbCAqIGJoKSA8PCAxNikgPj4+IDApIHwgMCk7XHJcbn07XHJcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2NvbW1vbi90eXBlZGVmcy5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0ge1xyXG4gICAgaW5wdXRTdHJlYW06IHtcclxuICAgICAgICBuYW1lOiBcIkxpdmVcIixcclxuICAgICAgICB0eXBlOiBcIkxpdmVTdHJlYW1cIixcclxuICAgICAgICBjb25zdHJhaW50czoge1xyXG4gICAgICAgICAgICB3aWR0aDogNjQwLFxyXG4gICAgICAgICAgICBoZWlnaHQ6IDQ4MCxcclxuICAgICAgICAgICAgLy8gYXNwZWN0UmF0aW86IDY0MC80ODAsIC8vIG9wdGlvbmFsXHJcbiAgICAgICAgICAgIGZhY2luZ01vZGU6IFwiZW52aXJvbm1lbnRcIiwgLy8gb3IgdXNlclxyXG4gICAgICAgICAgICAvLyBkZXZpY2VJZDogXCIzODc0NTk4MzQ1NzM4NzU5ODM3NTk4Mzc1OTgzNFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICBhcmVhOiB7XHJcbiAgICAgICAgICAgIHRvcDogXCIwJVwiLFxyXG4gICAgICAgICAgICByaWdodDogXCIwJVwiLFxyXG4gICAgICAgICAgICBsZWZ0OiBcIjAlXCIsXHJcbiAgICAgICAgICAgIGJvdHRvbTogXCIwJVwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICBzaW5nbGVDaGFubmVsOiBmYWxzZSAvLyB0cnVlOiBvbmx5IHRoZSByZWQgY29sb3ItY2hhbm5lbCBpcyByZWFkXHJcbiAgICB9LFxyXG4gICAgbG9jYXRlOiB0cnVlLFxyXG4gICAgbnVtT2ZXb3JrZXJzOiAwLFxyXG4gICAgZGVjb2Rlcjoge1xyXG4gICAgICAgIHJlYWRlcnM6IFtcclxuICAgICAgICAgICAgJ2NvZGVfMTI4X3JlYWRlcidcclxuICAgICAgICBdLFxyXG4gICAgICAgIGRlYnVnOiB7XHJcbiAgICAgICAgICAgIGRyYXdCb3VuZGluZ0JveDogZmFsc2UsXHJcbiAgICAgICAgICAgIHNob3dGcmVxdWVuY3k6IGZhbHNlLFxyXG4gICAgICAgICAgICBkcmF3U2NhbmxpbmU6IGZhbHNlLFxyXG4gICAgICAgICAgICBzaG93UGF0dGVybjogZmFsc2VcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgbG9jYXRvcjoge1xyXG4gICAgICAgIGhhbGZTYW1wbGU6IHRydWUsXHJcbiAgICAgICAgcGF0Y2hTaXplOiBcIm1lZGl1bVwiLCAvLyB4LXNtYWxsLCBzbWFsbCwgbWVkaXVtLCBsYXJnZSwgeC1sYXJnZVxyXG4gICAgICAgIGRlYnVnOiB7XHJcbiAgICAgICAgICAgIHNob3dDYW52YXM6IGZhbHNlLFxyXG4gICAgICAgICAgICBzaG93UGF0Y2hlczogZmFsc2UsXHJcbiAgICAgICAgICAgIHNob3dGb3VuZFBhdGNoZXM6IGZhbHNlLFxyXG4gICAgICAgICAgICBzaG93U2tlbGV0b246IGZhbHNlLFxyXG4gICAgICAgICAgICBzaG93TGFiZWxzOiBmYWxzZSxcclxuICAgICAgICAgICAgc2hvd1BhdGNoTGFiZWxzOiBmYWxzZSxcclxuICAgICAgICAgICAgc2hvd1JlbWFpbmluZ1BhdGNoTGFiZWxzOiBmYWxzZSxcclxuICAgICAgICAgICAgYm94RnJvbVBhdGNoZXM6IHtcclxuICAgICAgICAgICAgICAgIHNob3dUcmFuc2Zvcm1lZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBzaG93VHJhbnNmb3JtZWRCb3g6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgc2hvd0JCOiBmYWxzZVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9jb25maWcvY29uZmlnLmRldi5qc1xuICoqLyIsImxldCBjb25maWc7XHJcblxyXG5pZiAoRU5WLmRldmVsb3BtZW50KXtcclxuICAgIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnLmRldi5qcycpO1xyXG59IGVsc2UgaWYgKEVOVi5ub2RlKSB7XHJcbiAgICBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZy5ub2RlLmpzJyk7XHJcbn0gZWxzZSB7XHJcbiAgICBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZy5wcm9kLmpzJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNvbmZpZztcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvY29uZmlnL2NvbmZpZy5qc1xuICoqLyIsImltcG9ydCBCcmVzZW5oYW0gZnJvbSAnLi9icmVzZW5oYW0nO1xyXG5pbXBvcnQgSW1hZ2VEZWJ1ZyBmcm9tICcuLi9jb21tb24vaW1hZ2VfZGVidWcnO1xyXG5pbXBvcnQgQ29kZTEyOFJlYWRlciBmcm9tICcuLi9yZWFkZXIvY29kZV8xMjhfcmVhZGVyJztcclxuaW1wb3J0IEVBTlJlYWRlciBmcm9tICcuLi9yZWFkZXIvZWFuX3JlYWRlcic7XHJcbmltcG9ydCBDb2RlMzlSZWFkZXIgZnJvbSAnLi4vcmVhZGVyL2NvZGVfMzlfcmVhZGVyJztcclxuaW1wb3J0IENvZGUzOVZJTlJlYWRlciBmcm9tICcuLi9yZWFkZXIvY29kZV8zOV92aW5fcmVhZGVyJztcclxuaW1wb3J0IENvZGFiYXJSZWFkZXIgZnJvbSAnLi4vcmVhZGVyL2NvZGFiYXJfcmVhZGVyJztcclxuaW1wb3J0IFVQQ1JlYWRlciBmcm9tICcuLi9yZWFkZXIvdXBjX3JlYWRlcic7XHJcbmltcG9ydCBFQU44UmVhZGVyIGZyb20gJy4uL3JlYWRlci9lYW5fOF9yZWFkZXInO1xyXG5pbXBvcnQgVVBDRVJlYWRlciBmcm9tICcuLi9yZWFkZXIvdXBjX2VfcmVhZGVyJztcclxuaW1wb3J0IEkyb2Y1UmVhZGVyIGZyb20gJy4uL3JlYWRlci9pMm9mNV9yZWFkZXInO1xyXG5cclxuY29uc3QgUkVBREVSUyA9IHtcclxuICAgIGNvZGVfMTI4X3JlYWRlcjogQ29kZTEyOFJlYWRlcixcclxuICAgIGVhbl9yZWFkZXI6IEVBTlJlYWRlcixcclxuICAgIGVhbl84X3JlYWRlcjogRUFOOFJlYWRlcixcclxuICAgIGNvZGVfMzlfcmVhZGVyOiBDb2RlMzlSZWFkZXIsXHJcbiAgICBjb2RlXzM5X3Zpbl9yZWFkZXI6IENvZGUzOVZJTlJlYWRlcixcclxuICAgIGNvZGFiYXJfcmVhZGVyOiBDb2RhYmFyUmVhZGVyLFxyXG4gICAgdXBjX3JlYWRlcjogVVBDUmVhZGVyLFxyXG4gICAgdXBjX2VfcmVhZGVyOiBVUENFUmVhZGVyLFxyXG4gICAgaTJvZjVfcmVhZGVyOiBJMm9mNVJlYWRlclxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgICBjcmVhdGU6IGZ1bmN0aW9uKGNvbmZpZywgaW5wdXRJbWFnZVdyYXBwZXIpIHtcclxuICAgICAgICB2YXIgX2NhbnZhcyA9IHtcclxuICAgICAgICAgICAgICAgIGN0eDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGZyZXF1ZW5jeTogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXk6IG51bGxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBkb206IHtcclxuICAgICAgICAgICAgICAgICAgICBmcmVxdWVuY3k6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgcGF0dGVybjogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5OiBudWxsXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIF9iYXJjb2RlUmVhZGVycyA9IFtdO1xyXG5cclxuICAgICAgICBpbml0Q2FudmFzKCk7XHJcbiAgICAgICAgaW5pdFJlYWRlcnMoKTtcclxuICAgICAgICBpbml0Q29uZmlnKCk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGluaXRDYW52YXMoKSB7XHJcbiAgICAgICAgICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICAgICAgdmFyICRkZWJ1ZyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjZGVidWcuZGV0ZWN0aW9uXCIpO1xyXG4gICAgICAgICAgICAgICAgX2NhbnZhcy5kb20uZnJlcXVlbmN5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImNhbnZhcy5mcmVxdWVuY3lcIik7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV9jYW52YXMuZG9tLmZyZXF1ZW5jeSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF9jYW52YXMuZG9tLmZyZXF1ZW5jeSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgX2NhbnZhcy5kb20uZnJlcXVlbmN5LmNsYXNzTmFtZSA9IFwiZnJlcXVlbmN5XCI7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCRkZWJ1Zykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAkZGVidWcuYXBwZW5kQ2hpbGQoX2NhbnZhcy5kb20uZnJlcXVlbmN5KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBfY2FudmFzLmN0eC5mcmVxdWVuY3kgPSBfY2FudmFzLmRvbS5mcmVxdWVuY3kuZ2V0Q29udGV4dChcIjJkXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIF9jYW52YXMuZG9tLnBhdHRlcm4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiY2FudmFzLnBhdHRlcm5CdWZmZXJcIik7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV9jYW52YXMuZG9tLnBhdHRlcm4pIHtcclxuICAgICAgICAgICAgICAgICAgICBfY2FudmFzLmRvbS5wYXR0ZXJuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcclxuICAgICAgICAgICAgICAgICAgICBfY2FudmFzLmRvbS5wYXR0ZXJuLmNsYXNzTmFtZSA9IFwicGF0dGVybkJ1ZmZlclwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgkZGVidWcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJGRlYnVnLmFwcGVuZENoaWxkKF9jYW52YXMuZG9tLnBhdHRlcm4pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIF9jYW52YXMuY3R4LnBhdHRlcm4gPSBfY2FudmFzLmRvbS5wYXR0ZXJuLmdldENvbnRleHQoXCIyZFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICBfY2FudmFzLmRvbS5vdmVybGF5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImNhbnZhcy5kcmF3aW5nQnVmZmVyXCIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKF9jYW52YXMuZG9tLm92ZXJsYXkpIHtcclxuICAgICAgICAgICAgICAgICAgICBfY2FudmFzLmN0eC5vdmVybGF5ID0gX2NhbnZhcy5kb20ub3ZlcmxheS5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGluaXRSZWFkZXJzKCkge1xyXG4gICAgICAgICAgICBjb25maWcucmVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKHJlYWRlckNvbmZpZykge1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlYWRlcixcclxuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZWFkZXJDb25maWcgPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gcmVhZGVyQ29uZmlnLmZvcm1hdDtcclxuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uID0gcmVhZGVyQ29uZmlnLmNvbmZpZztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlYWRlckNvbmZpZyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSByZWFkZXJDb25maWc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoRU5WLmRldmVsb3BtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJCZWZvcmUgcmVnaXN0ZXJpbmcgcmVhZGVyOiBcIiwgcmVhZGVyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIF9iYXJjb2RlUmVhZGVycy5wdXNoKG5ldyBSRUFERVJTW3JlYWRlcl0oY29uZmlndXJhdGlvbikpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgaWYgKEVOVi5kZXZlbG9wbWVudCkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJSZWdpc3RlcmVkIFJlYWRlcnM6IFwiICsgX2JhcmNvZGVSZWFkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgocmVhZGVyKSA9PiBKU09OLnN0cmluZ2lmeSh7Zm9ybWF0OiByZWFkZXIuRk9STUFULCBjb25maWc6IHJlYWRlci5jb25maWd9KSlcclxuICAgICAgICAgICAgICAgICAgICAuam9pbignLCAnKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGluaXRDb25maWcoKSB7XHJcbiAgICAgICAgICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGksXHJcbiAgICAgICAgICAgICAgICAgICAgdmlzID0gW3tcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogX2NhbnZhcy5kb20uZnJlcXVlbmN5LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wOiBjb25maWcuZGVidWcuc2hvd0ZyZXF1ZW5jeVxyXG4gICAgICAgICAgICAgICAgICAgIH0sIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogX2NhbnZhcy5kb20ucGF0dGVybixcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcDogY29uZmlnLmRlYnVnLnNob3dQYXR0ZXJuXHJcbiAgICAgICAgICAgICAgICAgICAgfV07XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHZpcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2aXNbaV0ucHJvcCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aXNbaV0ubm9kZS5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpc1tpXS5ub2RlLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGV4dGVuZCB0aGUgbGluZSBvbiBib3RoIGVuZHNcclxuICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBsaW5lXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGFuZ2xlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gZ2V0RXh0ZW5kZWRMaW5lKGxpbmUsIGFuZ2xlLCBleHQpIHtcclxuICAgICAgICAgICAgZnVuY3Rpb24gZXh0ZW5kTGluZShhbW91bnQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBleHRlbnNpb24gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeTogYW1vdW50ICogTWF0aC5zaW4oYW5nbGUpLFxyXG4gICAgICAgICAgICAgICAgICAgIHg6IGFtb3VudCAqIE1hdGguY29zKGFuZ2xlKVxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBsaW5lWzBdLnkgLT0gZXh0ZW5zaW9uLnk7XHJcbiAgICAgICAgICAgICAgICBsaW5lWzBdLnggLT0gZXh0ZW5zaW9uLng7XHJcbiAgICAgICAgICAgICAgICBsaW5lWzFdLnkgKz0gZXh0ZW5zaW9uLnk7XHJcbiAgICAgICAgICAgICAgICBsaW5lWzFdLnggKz0gZXh0ZW5zaW9uLng7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGluc2lkZSBpbWFnZVxyXG4gICAgICAgICAgICBleHRlbmRMaW5lKGV4dCk7XHJcbiAgICAgICAgICAgIHdoaWxlIChleHQgPiAxICYmICghaW5wdXRJbWFnZVdyYXBwZXIuaW5JbWFnZVdpdGhCb3JkZXIobGluZVswXSwgMClcclxuICAgICAgICAgICAgICAgICAgICB8fCAhaW5wdXRJbWFnZVdyYXBwZXIuaW5JbWFnZVdpdGhCb3JkZXIobGluZVsxXSwgMCkpKSB7XHJcbiAgICAgICAgICAgICAgICBleHQgLT0gTWF0aC5jZWlsKGV4dCAvIDIpO1xyXG4gICAgICAgICAgICAgICAgZXh0ZW5kTGluZSgtZXh0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gbGluZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGdldExpbmUoYm94KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbe1xyXG4gICAgICAgICAgICAgICAgeDogKGJveFsxXVswXSAtIGJveFswXVswXSkgLyAyICsgYm94WzBdWzBdLFxyXG4gICAgICAgICAgICAgICAgeTogKGJveFsxXVsxXSAtIGJveFswXVsxXSkgLyAyICsgYm94WzBdWzFdXHJcbiAgICAgICAgICAgIH0sIHtcclxuICAgICAgICAgICAgICAgIHg6IChib3hbM11bMF0gLSBib3hbMl1bMF0pIC8gMiArIGJveFsyXVswXSxcclxuICAgICAgICAgICAgICAgIHk6IChib3hbM11bMV0gLSBib3hbMl1bMV0pIC8gMiArIGJveFsyXVsxXVxyXG4gICAgICAgICAgICB9XTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHRyeURlY29kZShsaW5lKSB7XHJcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgICAgIGJhcmNvZGVMaW5lID0gQnJlc2VuaGFtLmdldEJhcmNvZGVMaW5lKGlucHV0SW1hZ2VXcmFwcGVyLCBsaW5lWzBdLCBsaW5lWzFdKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQgJiYgY29uZmlnLmRlYnVnLnNob3dGcmVxdWVuY3kpIHtcclxuICAgICAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1BhdGgobGluZSwge3g6ICd4JywgeTogJ3knfSwgX2NhbnZhcy5jdHgub3ZlcmxheSwge2NvbG9yOiAncmVkJywgbGluZVdpZHRoOiAzfSk7XHJcbiAgICAgICAgICAgICAgICBCcmVzZW5oYW0uZGVidWcucHJpbnRGcmVxdWVuY3koYmFyY29kZUxpbmUubGluZSwgX2NhbnZhcy5kb20uZnJlcXVlbmN5KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgQnJlc2VuaGFtLnRvQmluYXJ5TGluZShiYXJjb2RlTGluZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoRU5WLmRldmVsb3BtZW50ICYmIGNvbmZpZy5kZWJ1Zy5zaG93UGF0dGVybikge1xyXG4gICAgICAgICAgICAgICAgQnJlc2VuaGFtLmRlYnVnLnByaW50UGF0dGVybihiYXJjb2RlTGluZS5saW5lLCBfY2FudmFzLmRvbS5wYXR0ZXJuKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm9yICggaSA9IDA7IGkgPCBfYmFyY29kZVJlYWRlcnMubGVuZ3RoICYmIHJlc3VsdCA9PT0gbnVsbDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBfYmFyY29kZVJlYWRlcnNbaV0uZGVjb2RlUGF0dGVybihiYXJjb2RlTGluZS5saW5lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKXtcclxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBjb2RlUmVzdWx0OiByZXN1bHQsXHJcbiAgICAgICAgICAgICAgICBiYXJjb2RlTGluZTogYmFyY29kZUxpbmVcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoaXMgbWV0aG9kIHNsaWNlcyB0aGUgZ2l2ZW4gYXJlYSBhcGFydCBhbmQgdHJpZXMgdG8gZGV0ZWN0IGEgYmFyY29kZS1wYXR0ZXJuXHJcbiAgICAgICAgICogZm9yIGVhY2ggc2xpY2UuIEl0IHJldHVybnMgdGhlIGRlY29kZWQgYmFyY29kZSwgb3IgbnVsbCBpZiBub3RoaW5nIHdhcyBmb3VuZFxyXG4gICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGJveFxyXG4gICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGxpbmVcclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gbGluZUFuZ2xlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gdHJ5RGVjb2RlQnJ1dGVGb3JjZShib3gsIGxpbmUsIGxpbmVBbmdsZSkge1xyXG4gICAgICAgICAgICB2YXIgc2lkZUxlbmd0aCA9IE1hdGguc3FydChNYXRoLnBvdyhib3hbMV1bMF0gLSBib3hbMF1bMF0sIDIpICsgTWF0aC5wb3coKGJveFsxXVsxXSAtIGJveFswXVsxXSksIDIpKSxcclxuICAgICAgICAgICAgICAgIGksXHJcbiAgICAgICAgICAgICAgICBzbGljZXMgPSAxNixcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IG51bGwsXHJcbiAgICAgICAgICAgICAgICBkaXIsXHJcbiAgICAgICAgICAgICAgICBleHRlbnNpb24sXHJcbiAgICAgICAgICAgICAgICB4ZGlyID0gTWF0aC5zaW4obGluZUFuZ2xlKSxcclxuICAgICAgICAgICAgICAgIHlkaXIgPSBNYXRoLmNvcyhsaW5lQW5nbGUpO1xyXG5cclxuICAgICAgICAgICAgZm9yICggaSA9IDE7IGkgPCBzbGljZXMgJiYgcmVzdWx0ID09PSBudWxsOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIC8vIG1vdmUgbGluZSBwZXJwZW5kaWN1bGFyIHRvIGFuZ2xlXHJcbiAgICAgICAgICAgICAgICBkaXIgPSBzaWRlTGVuZ3RoIC8gc2xpY2VzICogaSAqIChpICUgMiA9PT0gMCA/IC0xIDogMSk7XHJcbiAgICAgICAgICAgICAgICBleHRlbnNpb24gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeTogZGlyICogeGRpcixcclxuICAgICAgICAgICAgICAgICAgICB4OiBkaXIgKiB5ZGlyXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgbGluZVswXS55ICs9IGV4dGVuc2lvbi54O1xyXG4gICAgICAgICAgICAgICAgbGluZVswXS54IC09IGV4dGVuc2lvbi55O1xyXG4gICAgICAgICAgICAgICAgbGluZVsxXS55ICs9IGV4dGVuc2lvbi54O1xyXG4gICAgICAgICAgICAgICAgbGluZVsxXS54IC09IGV4dGVuc2lvbi55O1xyXG5cclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRyeURlY29kZShsaW5lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gZ2V0TGluZUxlbmd0aChsaW5lKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnNxcnQoXHJcbiAgICAgICAgICAgICAgICBNYXRoLnBvdyhNYXRoLmFicyhsaW5lWzFdLnkgLSBsaW5lWzBdLnkpLCAyKSArXHJcbiAgICAgICAgICAgICAgICBNYXRoLnBvdyhNYXRoLmFicyhsaW5lWzFdLnggLSBsaW5lWzBdLngpLCAyKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXaXRoIHRoZSBoZWxwIG9mIHRoZSBjb25maWd1cmVkIHJlYWRlcnMgKENvZGUxMjggb3IgRUFOKSB0aGlzIGZ1bmN0aW9uIHRyaWVzIHRvIGRldGVjdCBhXHJcbiAgICAgICAgICogdmFsaWQgYmFyY29kZSBwYXR0ZXJuIHdpdGhpbiB0aGUgZ2l2ZW4gYXJlYS5cclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gYm94IFRoZSBhcmVhIHRvIHNlYXJjaCBpblxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9IHRoZSByZXN1bHQge2NvZGVSZXN1bHQsIGxpbmUsIGFuZ2xlLCBwYXR0ZXJuLCB0aHJlc2hvbGR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gZGVjb2RlRnJvbUJvdW5kaW5nQm94KGJveCkge1xyXG4gICAgICAgICAgICB2YXIgbGluZSxcclxuICAgICAgICAgICAgICAgIGxpbmVBbmdsZSxcclxuICAgICAgICAgICAgICAgIGN0eCA9IF9jYW52YXMuY3R4Lm92ZXJsYXksXHJcbiAgICAgICAgICAgICAgICByZXN1bHQsXHJcbiAgICAgICAgICAgICAgICBsaW5lTGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgaWYgKEVOVi5kZXZlbG9wbWVudCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5kZWJ1Zy5kcmF3Qm91bmRpbmdCb3ggJiYgY3R4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgSW1hZ2VEZWJ1Zy5kcmF3UGF0aChib3gsIHt4OiAwLCB5OiAxfSwgY3R4LCB7Y29sb3I6IFwiYmx1ZVwiLCBsaW5lV2lkdGg6IDJ9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGluZSA9IGdldExpbmUoYm94KTtcclxuICAgICAgICAgICAgbGluZUxlbmd0aCA9IGdldExpbmVMZW5ndGgobGluZSk7XHJcbiAgICAgICAgICAgIGxpbmVBbmdsZSA9IE1hdGguYXRhbjIobGluZVsxXS55IC0gbGluZVswXS55LCBsaW5lWzFdLnggLSBsaW5lWzBdLngpO1xyXG4gICAgICAgICAgICBsaW5lID0gZ2V0RXh0ZW5kZWRMaW5lKGxpbmUsIGxpbmVBbmdsZSwgTWF0aC5mbG9vcihsaW5lTGVuZ3RoICogMC4xKSk7XHJcbiAgICAgICAgICAgIGlmIChsaW5lID09PSBudWxsKXtcclxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXN1bHQgPSB0cnlEZWNvZGUobGluZSk7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRyeURlY29kZUJydXRlRm9yY2UoYm94LCBsaW5lLCBsaW5lQW5nbGUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKEVOVi5kZXZlbG9wbWVudCAmJiByZXN1bHQgJiYgY29uZmlnLmRlYnVnLmRyYXdTY2FubGluZSAmJiBjdHgpIHtcclxuICAgICAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1BhdGgobGluZSwge3g6ICd4JywgeTogJ3knfSwgY3R4LCB7Y29sb3I6ICdyZWQnLCBsaW5lV2lkdGg6IDN9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGNvZGVSZXN1bHQ6IHJlc3VsdC5jb2RlUmVzdWx0LFxyXG4gICAgICAgICAgICAgICAgbGluZTogbGluZSxcclxuICAgICAgICAgICAgICAgIGFuZ2xlOiBsaW5lQW5nbGUsXHJcbiAgICAgICAgICAgICAgICBwYXR0ZXJuOiByZXN1bHQuYmFyY29kZUxpbmUubGluZSxcclxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogcmVzdWx0LmJhcmNvZGVMaW5lLnRocmVzaG9sZFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgZGVjb2RlRnJvbUJvdW5kaW5nQm94OiBmdW5jdGlvbihib3gpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkZWNvZGVGcm9tQm91bmRpbmdCb3goYm94KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZGVjb2RlRnJvbUJvdW5kaW5nQm94ZXM6IGZ1bmN0aW9uKGJveGVzKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgaSwgcmVzdWx0LFxyXG4gICAgICAgICAgICAgICAgICAgIGJhcmNvZGVzID0gW10sXHJcbiAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUgPSBjb25maWcubXVsdGlwbGU7XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yICggaSA9IDA7IGkgPCBib3hlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJveCA9IGJveGVzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlY29kZUZyb21Cb3VuZGluZ0JveChib3gpIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5ib3ggPSBib3g7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChtdWx0aXBsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYXJjb2Rlcy5wdXNoKHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuY29kZVJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAobXVsdGlwbGUpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYXJjb2Rlc1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHNldFJlYWRlcnM6IGZ1bmN0aW9uKHJlYWRlcnMpIHtcclxuICAgICAgICAgICAgICAgIGNvbmZpZy5yZWFkZXJzID0gcmVhZGVycztcclxuICAgICAgICAgICAgICAgIF9iYXJjb2RlUmVhZGVycy5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgICAgICAgaW5pdFJlYWRlcnMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn07XHJcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2RlY29kZXIvYmFyY29kZV9kZWNvZGVyLmpzXG4gKiovIiwiaW1wb3J0IEltYWdlV3JhcHBlciBmcm9tICcuLi9jb21tb24vaW1hZ2Vfd3JhcHBlcic7XHJcblxyXG52YXIgQnJlc2VuaGFtID0ge307XHJcblxyXG52YXIgU2xvcGUgPSB7XHJcbiAgICBESVI6IHtcclxuICAgICAgICBVUDogMSxcclxuICAgICAgICBET1dOOiAtMVxyXG4gICAgfVxyXG59O1xyXG4vKipcclxuICogU2NhbnMgYSBsaW5lIG9mIHRoZSBnaXZlbiBpbWFnZSBmcm9tIHBvaW50IHAxIHRvIHAyIGFuZCByZXR1cm5zIGEgcmVzdWx0IG9iamVjdCBjb250YWluaW5nXHJcbiAqIGdyYXktc2NhbGUgdmFsdWVzICgwLTI1NSkgb2YgdGhlIHVuZGVybHlpbmcgcGl4ZWxzIGluIGFkZGl0aW9uIHRvIHRoZSBtaW5cclxuICogYW5kIG1heCB2YWx1ZXMuXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBpbWFnZVdyYXBwZXJcclxuICogQHBhcmFtIHtPYmplY3R9IHAxIFRoZSBzdGFydCBwb2ludCB7eCx5fVxyXG4gKiBAcGFyYW0ge09iamVjdH0gcDIgVGhlIGVuZCBwb2ludCB7eCx5fVxyXG4gKiBAcmV0dXJucyB7bGluZSwgbWluLCBtYXh9XHJcbiAqL1xyXG5CcmVzZW5oYW0uZ2V0QmFyY29kZUxpbmUgPSBmdW5jdGlvbihpbWFnZVdyYXBwZXIsIHAxLCBwMikge1xyXG4gICAgdmFyIHgwID0gcDEueCB8IDAsXHJcbiAgICAgICAgeTAgPSBwMS55IHwgMCxcclxuICAgICAgICB4MSA9IHAyLnggfCAwLFxyXG4gICAgICAgIHkxID0gcDIueSB8IDAsXHJcbiAgICAgICAgc3RlZXAgPSBNYXRoLmFicyh5MSAtIHkwKSA+IE1hdGguYWJzKHgxIC0geDApLFxyXG4gICAgICAgIGRlbHRheCxcclxuICAgICAgICBkZWx0YXksXHJcbiAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgeXN0ZXAsXHJcbiAgICAgICAgeSxcclxuICAgICAgICB0bXAsXHJcbiAgICAgICAgeCxcclxuICAgICAgICBsaW5lID0gW10sXHJcbiAgICAgICAgaW1hZ2VEYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGEsXHJcbiAgICAgICAgd2lkdGggPSBpbWFnZVdyYXBwZXIuc2l6ZS54LFxyXG4gICAgICAgIHN1bSA9IDAsXHJcbiAgICAgICAgdmFsLFxyXG4gICAgICAgIG1pbiA9IDI1NSxcclxuICAgICAgICBtYXggPSAwO1xyXG5cclxuICAgIGZ1bmN0aW9uIHJlYWQoYSwgYikge1xyXG4gICAgICAgIHZhbCA9IGltYWdlRGF0YVtiICogd2lkdGggKyBhXTtcclxuICAgICAgICBzdW0gKz0gdmFsO1xyXG4gICAgICAgIG1pbiA9IHZhbCA8IG1pbiA/IHZhbCA6IG1pbjtcclxuICAgICAgICBtYXggPSB2YWwgPiBtYXggPyB2YWwgOiBtYXg7XHJcbiAgICAgICAgbGluZS5wdXNoKHZhbCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHN0ZWVwKSB7XHJcbiAgICAgICAgdG1wID0geDA7XHJcbiAgICAgICAgeDAgPSB5MDtcclxuICAgICAgICB5MCA9IHRtcDtcclxuXHJcbiAgICAgICAgdG1wID0geDE7XHJcbiAgICAgICAgeDEgPSB5MTtcclxuICAgICAgICB5MSA9IHRtcDtcclxuICAgIH1cclxuICAgIGlmICh4MCA+IHgxKSB7XHJcbiAgICAgICAgdG1wID0geDA7XHJcbiAgICAgICAgeDAgPSB4MTtcclxuICAgICAgICB4MSA9IHRtcDtcclxuXHJcbiAgICAgICAgdG1wID0geTA7XHJcbiAgICAgICAgeTAgPSB5MTtcclxuICAgICAgICB5MSA9IHRtcDtcclxuICAgIH1cclxuICAgIGRlbHRheCA9IHgxIC0geDA7XHJcbiAgICBkZWx0YXkgPSBNYXRoLmFicyh5MSAtIHkwKTtcclxuICAgIGVycm9yID0gKGRlbHRheCAvIDIpIHwgMDtcclxuICAgIHkgPSB5MDtcclxuICAgIHlzdGVwID0geTAgPCB5MSA/IDEgOiAtMTtcclxuICAgIGZvciAoIHggPSB4MDsgeCA8IHgxOyB4KyspIHtcclxuICAgICAgICBpZiAoc3RlZXApe1xyXG4gICAgICAgICAgICByZWFkKHksIHgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJlYWQoeCwgeSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVycm9yID0gZXJyb3IgLSBkZWx0YXk7XHJcbiAgICAgICAgaWYgKGVycm9yIDwgMCkge1xyXG4gICAgICAgICAgICB5ID0geSArIHlzdGVwO1xyXG4gICAgICAgICAgICBlcnJvciA9IGVycm9yICsgZGVsdGF4O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGxpbmU6IGxpbmUsXHJcbiAgICAgICAgbWluOiBtaW4sXHJcbiAgICAgICAgbWF4OiBtYXhcclxuICAgIH07XHJcbn07XHJcblxyXG4vKipcclxuICogQ29udmVydHMgdGhlIHJlc3VsdCBmcm9tIGdldEJhcmNvZGVMaW5lIGludG8gYSBiaW5hcnkgcmVwcmVzZW50YXRpb25cclxuICogYWxzbyBjb25zaWRlcmluZyB0aGUgZnJlcXVlbmN5IGFuZCBzbG9wZSBvZiB0aGUgc2lnbmFsIGZvciBtb3JlIHJvYnVzdCByZXN1bHRzXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSByZXN1bHQge2xpbmUsIG1pbiwgbWF4fVxyXG4gKi9cclxuQnJlc2VuaGFtLnRvQmluYXJ5TGluZSA9IGZ1bmN0aW9uKHJlc3VsdCkge1xyXG4gICAgdmFyIG1pbiA9IHJlc3VsdC5taW4sXHJcbiAgICAgICAgbWF4ID0gcmVzdWx0Lm1heCxcclxuICAgICAgICBsaW5lID0gcmVzdWx0LmxpbmUsXHJcbiAgICAgICAgc2xvcGUsXHJcbiAgICAgICAgc2xvcGUyLFxyXG4gICAgICAgIGNlbnRlciA9IG1pbiArIChtYXggLSBtaW4pIC8gMixcclxuICAgICAgICBleHRyZW1hID0gW10sXHJcbiAgICAgICAgY3VycmVudERpcixcclxuICAgICAgICBkaXIsXHJcbiAgICAgICAgdGhyZXNob2xkID0gKG1heCAtIG1pbikgLyAxMixcclxuICAgICAgICByVGhyZXNob2xkID0gLXRocmVzaG9sZCxcclxuICAgICAgICBpLFxyXG4gICAgICAgIGo7XHJcblxyXG4gICAgLy8gMS4gZmluZCBleHRyZW1hXHJcbiAgICBjdXJyZW50RGlyID0gbGluZVswXSA+IGNlbnRlciA/IFNsb3BlLkRJUi5VUCA6IFNsb3BlLkRJUi5ET1dOO1xyXG4gICAgZXh0cmVtYS5wdXNoKHtcclxuICAgICAgICBwb3M6IDAsXHJcbiAgICAgICAgdmFsOiBsaW5lWzBdXHJcbiAgICB9KTtcclxuICAgIGZvciAoIGkgPSAwOyBpIDwgbGluZS5sZW5ndGggLSAyOyBpKyspIHtcclxuICAgICAgICBzbG9wZSA9IChsaW5lW2kgKyAxXSAtIGxpbmVbaV0pO1xyXG4gICAgICAgIHNsb3BlMiA9IChsaW5lW2kgKyAyXSAtIGxpbmVbaSArIDFdKTtcclxuICAgICAgICBpZiAoKHNsb3BlICsgc2xvcGUyKSA8IHJUaHJlc2hvbGQgJiYgbGluZVtpICsgMV0gPCAoY2VudGVyICogMS41KSkge1xyXG4gICAgICAgICAgICBkaXIgPSBTbG9wZS5ESVIuRE9XTjtcclxuICAgICAgICB9IGVsc2UgaWYgKChzbG9wZSArIHNsb3BlMikgPiB0aHJlc2hvbGQgJiYgbGluZVtpICsgMV0gPiAoY2VudGVyICogMC41KSkge1xyXG4gICAgICAgICAgICBkaXIgPSBTbG9wZS5ESVIuVVA7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZGlyID0gY3VycmVudERpcjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjdXJyZW50RGlyICE9PSBkaXIpIHtcclxuICAgICAgICAgICAgZXh0cmVtYS5wdXNoKHtcclxuICAgICAgICAgICAgICAgIHBvczogaSxcclxuICAgICAgICAgICAgICAgIHZhbDogbGluZVtpXVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgY3VycmVudERpciA9IGRpcjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBleHRyZW1hLnB1c2goe1xyXG4gICAgICAgIHBvczogbGluZS5sZW5ndGgsXHJcbiAgICAgICAgdmFsOiBsaW5lW2xpbmUubGVuZ3RoIC0gMV1cclxuICAgIH0pO1xyXG5cclxuICAgIGZvciAoIGogPSBleHRyZW1hWzBdLnBvczsgaiA8IGV4dHJlbWFbMV0ucG9zOyBqKyspIHtcclxuICAgICAgICBsaW5lW2pdID0gbGluZVtqXSA+IGNlbnRlciA/IDAgOiAxO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGl0ZXJhdGUgb3ZlciBleHRyZW1hIGFuZCBjb252ZXJ0IHRvIGJpbmFyeSBiYXNlZCBvbiBhdmcgYmV0d2VlbiBtaW5tYXhcclxuICAgIGZvciAoIGkgPSAxOyBpIDwgZXh0cmVtYS5sZW5ndGggLSAxOyBpKyspIHtcclxuICAgICAgICBpZiAoZXh0cmVtYVtpICsgMV0udmFsID4gZXh0cmVtYVtpXS52YWwpIHtcclxuICAgICAgICAgICAgdGhyZXNob2xkID0gKGV4dHJlbWFbaV0udmFsICsgKChleHRyZW1hW2kgKyAxXS52YWwgLSBleHRyZW1hW2ldLnZhbCkgLyAzKSAqIDIpIHwgMDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJlc2hvbGQgPSAoZXh0cmVtYVtpICsgMV0udmFsICsgKChleHRyZW1hW2ldLnZhbCAtIGV4dHJlbWFbaSArIDFdLnZhbCkgLyAzKSkgfCAwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yICggaiA9IGV4dHJlbWFbaV0ucG9zOyBqIDwgZXh0cmVtYVtpICsgMV0ucG9zOyBqKyspIHtcclxuICAgICAgICAgICAgbGluZVtqXSA9IGxpbmVbal0gPiB0aHJlc2hvbGQgPyAwIDogMTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBsaW5lOiBsaW5lLFxyXG4gICAgICAgIHRocmVzaG9sZDogdGhyZXNob2xkXHJcbiAgICB9O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFVzZWQgZm9yIGRldmVsb3BtZW50IG9ubHlcclxuICovXHJcbkJyZXNlbmhhbS5kZWJ1ZyA9IHtcclxuICAgIHByaW50RnJlcXVlbmN5OiBmdW5jdGlvbihsaW5lLCBjYW52YXMpIHtcclxuICAgICAgICB2YXIgaSxcclxuICAgICAgICAgICAgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgICBjYW52YXMud2lkdGggPSBsaW5lLmxlbmd0aDtcclxuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gMjU2O1xyXG5cclxuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gXCJibHVlXCI7XHJcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGN0eC5tb3ZlVG8oaSwgMjU1KTtcclxuICAgICAgICAgICAgY3R4LmxpbmVUbyhpLCAyNTUgLSBsaW5lW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgIH0sXHJcblxyXG4gICAgcHJpbnRQYXR0ZXJuOiBmdW5jdGlvbihsaW5lLCBjYW52YXMpIHtcclxuICAgICAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKSwgaTtcclxuXHJcbiAgICAgICAgY2FudmFzLndpZHRoID0gbGluZS5sZW5ndGg7XHJcbiAgICAgICAgY3R4LmZpbGxDb2xvciA9IFwiYmxhY2tcIjtcclxuICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGxpbmVbaV0gPT09IDEpIHtcclxuICAgICAgICAgICAgICAgIGN0eC5maWxsUmVjdChpLCAwLCAxLCAxMDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQnJlc2VuaGFtO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9kZWNvZGVyL2JyZXNlbmhhbS5qc1xuICoqLyIsImltcG9ydCB7bWVyZ2UsIHBpY2t9IGZyb20gJ2xvZGFzaCc7XHJcblxyXG52YXIgc3RyZWFtUmVmLFxyXG4gICAgbG9hZGVkRGF0YUhhbmRsZXI7XHJcblxyXG5mdW5jdGlvbiB3YWl0Rm9yVmlkZW8odmlkZW8pIHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgbGV0IGF0dGVtcHRzID0gMTA7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGNoZWNrVmlkZW8oKSB7XHJcbiAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+IDApIHtcclxuICAgICAgICAgICAgICAgIGlmICh2aWRlby52aWRlb1dpZHRoID4gMCAmJiB2aWRlby52aWRlb0hlaWdodCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoRU5WLmRldmVsb3BtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHZpZGVvLnZpZGVvV2lkdGggKyBcInB4IHggXCIgKyB2aWRlby52aWRlb0hlaWdodCArIFwicHhcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoY2hlY2tWaWRlbywgNTAwKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJlamVjdCgnVW5hYmxlIHRvIHBsYXkgdmlkZW8gc3RyZWFtLiBJcyB3ZWJjYW0gd29ya2luZz8nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBhdHRlbXB0cy0tO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjaGVja1ZpZGVvKCk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRyaWVzIHRvIGF0dGFjaCB0aGUgY2FtZXJhLXN0cmVhbSB0byBhIGdpdmVuIHZpZGVvLWVsZW1lbnRcclxuICogYW5kIGNhbGxzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIHRoZSBjb250ZW50IGlzIHJlYWR5XHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25zdHJhaW50c1xyXG4gKiBAcGFyYW0ge09iamVjdH0gdmlkZW9cclxuICovXHJcbmZ1bmN0aW9uIGluaXRDYW1lcmEodmlkZW8sIGNvbnN0cmFpbnRzKSB7XHJcbiAgICByZXR1cm4gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHMpXHJcbiAgICAudGhlbigoc3RyZWFtKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgc3RyZWFtUmVmID0gc3RyZWFtO1xyXG4gICAgICAgICAgICB2aWRlby5zcmMgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChzdHJlYW0pO1xyXG4gICAgICAgICAgICB2aWRlby5vbmxvYWRlZG1ldGFkYXRhID0gKGUpID0+IHtcclxuICAgICAgICAgICAgICAgIHZpZGVvLnBsYXkoKTtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9KTtcclxuICAgIH0pXHJcbiAgICAudGhlbih3YWl0Rm9yVmlkZW8uYmluZChudWxsLCB2aWRlbykpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBkZXByZWNhdGVkQ29uc3RyYWludHModmlkZW9Db25zdHJhaW50cykge1xyXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IHBpY2sodmlkZW9Db25zdHJhaW50cywgW1wid2lkdGhcIiwgXCJoZWlnaHRcIiwgXCJmYWNpbmdNb2RlXCIsXHJcbiAgICAgICAgICAgIFwiYXNwZWN0UmF0aW9cIiwgXCJkZXZpY2VJZFwiXSk7XHJcblxyXG4gICAgaWYgKHR5cGVvZiB2aWRlb0NvbnN0cmFpbnRzW1wibWluQXNwZWN0UmF0aW9cIl0gIT09ICd1bmRlZmluZWQnICYmXHJcbiAgICAgICAgICAgIHZpZGVvQ29uc3RyYWludHNbXCJtaW5Bc3BlY3RSYXRpb1wiXSA+IDApIHtcclxuICAgICAgICBub3JtYWxpemVkW1wiYXNwZWN0UmF0aW9cIl0gPSB2aWRlb0NvbnN0cmFpbnRzW1wibWluQXNwZWN0UmF0aW9cIl07XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJXQVJOSU5HOiBDb25zdHJhaW50ICdtaW5Bc3BlY3RSYXRpbycgaXMgZGVwcmVjYXRlZDsgVXNlICdhc3BlY3RSYXRpbycgaW5zdGVhZFwiKTtcclxuICAgIH1cclxuICAgIGlmICh0eXBlb2YgdmlkZW9Db25zdHJhaW50c1tcImZhY2luZ1wiXSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICBub3JtYWxpemVkW1wiZmFjaW5nTW9kZVwiXSA9IHZpZGVvQ29uc3RyYWludHNbXCJmYWNpbmdcIl07XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJXQVJOSU5HOiBDb25zdHJhaW50ICdmYWNpbmcnIGlzIGRlcHJlY2F0ZWQuIFVzZSAnZmFjaW5nTW9kZScgaW5zdGVhZCdcIik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbm9ybWFsaXplZDtcclxufVxyXG5cclxuZnVuY3Rpb24gYXBwbHlDYW1lcmFGYWNpbmcoZmFjaW5nLCBjb25zdHJhaW50cykge1xyXG4gICAgaWYgKHR5cGVvZiBjb25zdHJhaW50cy52aWRlby5kZXZpY2VJZCAhPT0gJ3VuZGVmaW5lZCcgfHwgIWZhY2luZyl7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShjb25zdHJhaW50cyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJlxyXG4gICAgICAgICAgICB0eXBlb2YgTWVkaWFTdHJlYW1UcmFjay5nZXRTb3VyY2VzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIE1lZGlhU3RyZWFtVHJhY2suZ2V0U291cmNlcygoc291cmNlSW5mb3MpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlID0gc291cmNlSW5mb3MuZmlsdGVyKChzb3VyY2VJbmZvKSA9PiAoXHJcbiAgICAgICAgICAgICAgICAgICAgc291cmNlSW5mby5raW5kID09PSBcInZpZGVvXCIgJiYgc291cmNlSW5mby5mYWNpbmcgPT09IGZhY2luZ1xyXG4gICAgICAgICAgICAgICAgKSlbMF07XHJcbiAgICAgICAgICAgICAgICBpZiAodmlkZW9Tb3VyY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShtZXJnZSh7fSwgY29uc3RyYWludHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHt2aWRlbzoge2RldmljZUlkOiB2aWRlb1NvdXJjZS5pZH19KSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShjb25zdHJhaW50cyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShtZXJnZSh7fSwgY29uc3RyYWludHMsIHt2aWRlbzoge2ZhY2luZ01vZGU6IGZhY2luZ319KSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHBpY2tDb25zdHJhaW50cyh2aWRlb0NvbnN0cmFpbnRzKSB7XHJcbiAgICBjb25zdCBjb25zdHJhaW50cyA9IHtcclxuICAgICAgICBhdWRpbzogZmFsc2UsXHJcbiAgICAgICAgdmlkZW86IGRlcHJlY2F0ZWRDb25zdHJhaW50cyh2aWRlb0NvbnN0cmFpbnRzKVxyXG4gICAgfTtcclxuICAgIHJldHVybiBhcHBseUNhbWVyYUZhY2luZyhjb25zdHJhaW50cy52aWRlby5mYWNpbmdNb2RlLCBjb25zdHJhaW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIHJlcXVlc3Q6IGZ1bmN0aW9uKHZpZGVvLCB2aWRlb0NvbnN0cmFpbnRzKSB7XHJcbiAgICAgICAgcmV0dXJuIHBpY2tDb25zdHJhaW50cyh2aWRlb0NvbnN0cmFpbnRzKVxyXG4gICAgICAgICAgICAudGhlbihpbml0Q2FtZXJhLmJpbmQobnVsbCwgdmlkZW8pKTtcclxuICAgIH0sXHJcbiAgICByZWxlYXNlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgdHJhY2tzID0gc3RyZWFtUmVmICYmIHN0cmVhbVJlZi5nZXRWaWRlb1RyYWNrcygpO1xyXG4gICAgICAgIGlmICh0cmFja3MgJiYgdHJhY2tzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0cmFja3NbMF0uc3RvcCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzdHJlYW1SZWYgPSBudWxsO1xyXG4gICAgfVxyXG59O1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9pbnB1dC9jYW1lcmFfYWNjZXNzLmpzXG4gKiovIiwiaW1wb3J0IHtcclxuICAgIGltYWdlUmVmLFxyXG4gICAgZ3JheUFuZEhhbGZTYW1wbGVGcm9tQ2FudmFzRGF0YSxcclxuICAgIGNvbXB1dGVHcmF5XHJcbn0gZnJvbSAnLi4vY29tbW9uL2N2X3V0aWxzJztcclxuXHJcbnZhciBGcmFtZUdyYWJiZXIgPSB7fTtcclxuXHJcbkZyYW1lR3JhYmJlci5jcmVhdGUgPSBmdW5jdGlvbihpbnB1dFN0cmVhbSwgY2FudmFzKSB7XHJcbiAgICB2YXIgX3RoYXQgPSB7fSxcclxuICAgICAgICBfc3RyZWFtQ29uZmlnID0gaW5wdXRTdHJlYW0uZ2V0Q29uZmlnKCksXHJcbiAgICAgICAgX3ZpZGVvX3NpemUgPSBpbWFnZVJlZihpbnB1dFN0cmVhbS5nZXRSZWFsV2lkdGgoKSwgaW5wdXRTdHJlYW0uZ2V0UmVhbEhlaWdodCgpKSxcclxuICAgICAgICBfY2FudmFzU2l6ZSA9IGlucHV0U3RyZWFtLmdldENhbnZhc1NpemUoKSxcclxuICAgICAgICBfc2l6ZSA9IGltYWdlUmVmKGlucHV0U3RyZWFtLmdldFdpZHRoKCksIGlucHV0U3RyZWFtLmdldEhlaWdodCgpKSxcclxuICAgICAgICB0b3BSaWdodCA9IGlucHV0U3RyZWFtLmdldFRvcFJpZ2h0KCksXHJcbiAgICAgICAgX3N4ID0gdG9wUmlnaHQueCxcclxuICAgICAgICBfc3kgPSB0b3BSaWdodC55LFxyXG4gICAgICAgIF9jYW52YXMsXHJcbiAgICAgICAgX2N0eCA9IG51bGwsXHJcbiAgICAgICAgX2RhdGEgPSBudWxsO1xyXG5cclxuICAgIF9jYW52YXMgPSBjYW52YXMgPyBjYW52YXMgOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xyXG4gICAgX2NhbnZhcy53aWR0aCA9IF9jYW52YXNTaXplLng7XHJcbiAgICBfY2FudmFzLmhlaWdodCA9IF9jYW52YXNTaXplLnk7XHJcbiAgICBfY3R4ID0gX2NhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICBfZGF0YSA9IG5ldyBVaW50OEFycmF5KF9zaXplLnggKiBfc2l6ZS55KTtcclxuICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQpIHtcclxuICAgICAgICBjb25zb2xlLmxvZyhcIkZyYW1lR3JhYmJlclwiLCBKU09OLnN0cmluZ2lmeSh7XHJcbiAgICAgICAgICAgIHNpemU6IF9zaXplLFxyXG4gICAgICAgICAgICB0b3BSaWdodDogdG9wUmlnaHQsXHJcbiAgICAgICAgICAgIHZpZGVvU2l6ZTogX3ZpZGVvX3NpemUsXHJcbiAgICAgICAgICAgIGNhbnZhc1NpemU6IF9jYW52YXNTaXplXHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVXNlcyB0aGUgZ2l2ZW4gYXJyYXkgYXMgZnJhbWUtYnVmZmVyXHJcbiAgICAgKi9cclxuICAgIF90aGF0LmF0dGFjaERhdGEgPSBmdW5jdGlvbihkYXRhKSB7XHJcbiAgICAgICAgX2RhdGEgPSBkYXRhO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHVzZWQgZnJhbWUtYnVmZmVyXHJcbiAgICAgKi9cclxuICAgIF90aGF0LmdldERhdGEgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gX2RhdGE7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmV0Y2hlcyBhIGZyYW1lIGZyb20gdGhlIGlucHV0LXN0cmVhbSBhbmQgcHV0cyBpbnRvIHRoZSBmcmFtZS1idWZmZXIuXHJcbiAgICAgKiBUaGUgaW1hZ2UtZGF0YSBpcyBjb252ZXJ0ZWQgdG8gZ3JheS1zY2FsZSBhbmQgdGhlbiBoYWxmLXNhbXBsZWQgaWYgY29uZmlndXJlZC5cclxuICAgICAqL1xyXG4gICAgX3RoYXQuZ3JhYiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHZhciBkb0hhbGZTYW1wbGUgPSBfc3RyZWFtQ29uZmlnLmhhbGZTYW1wbGUsXHJcbiAgICAgICAgICAgIGZyYW1lID0gaW5wdXRTdHJlYW0uZ2V0RnJhbWUoKSxcclxuICAgICAgICAgICAgY3R4RGF0YTtcclxuICAgICAgICBpZiAoZnJhbWUpIHtcclxuICAgICAgICAgICAgX2N0eC5kcmF3SW1hZ2UoZnJhbWUsIDAsIDAsIF9jYW52YXNTaXplLngsIF9jYW52YXNTaXplLnkpO1xyXG4gICAgICAgICAgICBjdHhEYXRhID0gX2N0eC5nZXRJbWFnZURhdGEoX3N4LCBfc3ksIF9zaXplLngsIF9zaXplLnkpLmRhdGE7XHJcbiAgICAgICAgICAgIGlmIChkb0hhbGZTYW1wbGUpe1xyXG4gICAgICAgICAgICAgICAgZ3JheUFuZEhhbGZTYW1wbGVGcm9tQ2FudmFzRGF0YShjdHhEYXRhLCBfc2l6ZSwgX2RhdGEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29tcHV0ZUdyYXkoY3R4RGF0YSwgX2RhdGEsIF9zdHJlYW1Db25maWcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIF90aGF0LmdldFNpemUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gX3NpemU7XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiBfdGhhdDtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IEZyYW1lR3JhYmJlcjtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvaW5wdXQvZnJhbWVfZ3JhYmJlci5qc1xuICoqLyIsInZhciBJbWFnZUxvYWRlciA9IHt9O1xyXG5JbWFnZUxvYWRlci5sb2FkID0gZnVuY3Rpb24oZGlyZWN0b3J5LCBjYWxsYmFjaywgb2Zmc2V0LCBzaXplLCBzZXF1ZW5jZSkge1xyXG4gICAgdmFyIGh0bWxJbWFnZXNTcmNBcnJheSA9IG5ldyBBcnJheShzaXplKSxcclxuICAgICAgICBodG1sSW1hZ2VzQXJyYXkgPSBuZXcgQXJyYXkoaHRtbEltYWdlc1NyY0FycmF5Lmxlbmd0aCksXHJcbiAgICAgICAgaSxcclxuICAgICAgICBpbWcsXHJcbiAgICAgICAgbnVtO1xyXG5cclxuICAgIGlmIChzZXF1ZW5jZSA9PT0gZmFsc2UpIHtcclxuICAgICAgICBodG1sSW1hZ2VzU3JjQXJyYXlbMF0gPSBkaXJlY3Rvcnk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGZvciAoIGkgPSAwOyBpIDwgaHRtbEltYWdlc1NyY0FycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIG51bSA9IChvZmZzZXQgKyBpKTtcclxuICAgICAgICAgICAgaHRtbEltYWdlc1NyY0FycmF5W2ldID0gZGlyZWN0b3J5ICsgXCJpbWFnZS1cIiArIChcIjAwXCIgKyBudW0pLnNsaWNlKC0zKSArIFwiLmpwZ1wiO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGh0bWxJbWFnZXNBcnJheS5ub3RMb2FkZWQgPSBbXTtcclxuICAgIGh0bWxJbWFnZXNBcnJheS5hZGRJbWFnZSA9IGZ1bmN0aW9uKGltYWdlKSB7XHJcbiAgICAgICAgaHRtbEltYWdlc0FycmF5Lm5vdExvYWRlZC5wdXNoKGltYWdlKTtcclxuICAgIH07XHJcbiAgICBodG1sSW1hZ2VzQXJyYXkubG9hZGVkID0gZnVuY3Rpb24obG9hZGVkSW1nKSB7XHJcbiAgICAgICAgdmFyIG5vdGxvYWRlZEltZ3MgPSBodG1sSW1hZ2VzQXJyYXkubm90TG9hZGVkO1xyXG4gICAgICAgIGZvciAodmFyIHggPSAwOyB4IDwgbm90bG9hZGVkSW1ncy5sZW5ndGg7IHgrKykge1xyXG4gICAgICAgICAgICBpZiAobm90bG9hZGVkSW1nc1t4XSA9PT0gbG9hZGVkSW1nKSB7XHJcbiAgICAgICAgICAgICAgICBub3Rsb2FkZWRJbWdzLnNwbGljZSh4LCAxKTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIHkgPSAwOyB5IDwgaHRtbEltYWdlc1NyY0FycmF5Lmxlbmd0aDsgeSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGltZ05hbWUgPSBodG1sSW1hZ2VzU3JjQXJyYXlbeV0uc3Vic3RyKGh0bWxJbWFnZXNTcmNBcnJheVt5XS5sYXN0SW5kZXhPZihcIi9cIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkZWRJbWcuc3JjLmxhc3RJbmRleE9mKGltZ05hbWUpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBodG1sSW1hZ2VzQXJyYXlbeV0gPSBsb2FkZWRJbWc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChub3Rsb2FkZWRJbWdzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICBpZiAoRU5WLmRldmVsb3BtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkltYWdlcyBsb2FkZWRcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgW2h0bWxJbWFnZXNBcnJheV0pO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgZm9yICggaSA9IDA7IGkgPCBodG1sSW1hZ2VzU3JjQXJyYXkubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpbWcgPSBuZXcgSW1hZ2UoKTtcclxuICAgICAgICBodG1sSW1hZ2VzQXJyYXkuYWRkSW1hZ2UoaW1nKTtcclxuICAgICAgICBhZGRPbmxvYWRIYW5kbGVyKGltZywgaHRtbEltYWdlc0FycmF5KTtcclxuICAgICAgICBpbWcuc3JjID0gaHRtbEltYWdlc1NyY0FycmF5W2ldO1xyXG4gICAgfVxyXG59O1xyXG5cclxuZnVuY3Rpb24gYWRkT25sb2FkSGFuZGxlcihpbWcsIGh0bWxJbWFnZXNBcnJheSkge1xyXG4gICAgaW1nLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGh0bWxJbWFnZXNBcnJheS5sb2FkZWQodGhpcyk7XHJcbiAgICB9O1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCAoSW1hZ2VMb2FkZXIpO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9pbnB1dC9pbWFnZV9sb2FkZXIuanNcbiAqKi8iLCJpbXBvcnQgSW1hZ2VMb2FkZXIgZnJvbSAnLi9pbWFnZV9sb2FkZXInO1xyXG5cclxudmFyIElucHV0U3RyZWFtID0ge307XHJcbklucHV0U3RyZWFtLmNyZWF0ZVZpZGVvU3RyZWFtID0gZnVuY3Rpb24odmlkZW8pIHtcclxuICAgIHZhciB0aGF0ID0ge30sXHJcbiAgICAgICAgX2NvbmZpZyA9IG51bGwsXHJcbiAgICAgICAgX2V2ZW50TmFtZXMgPSBbJ2NhbnJlY29yZCcsICdlbmRlZCddLFxyXG4gICAgICAgIF9ldmVudEhhbmRsZXJzID0ge30sXHJcbiAgICAgICAgX2NhbGN1bGF0ZWRXaWR0aCxcclxuICAgICAgICBfY2FsY3VsYXRlZEhlaWdodCxcclxuICAgICAgICBfdG9wUmlnaHQgPSB7eDogMCwgeTogMH0sXHJcbiAgICAgICAgX2NhbnZhc1NpemUgPSB7eDogMCwgeTogMH07XHJcblxyXG4gICAgZnVuY3Rpb24gaW5pdFNpemUoKSB7XHJcbiAgICAgICAgdmFyIHdpZHRoID0gdmlkZW8udmlkZW9XaWR0aCxcclxuICAgICAgICAgICAgaGVpZ2h0ID0gdmlkZW8udmlkZW9IZWlnaHQ7XHJcblxyXG4gICAgICAgIF9jYWxjdWxhdGVkV2lkdGggPVxyXG4gICAgICAgICAgICBfY29uZmlnLnNpemUgPyB3aWR0aCAvIGhlaWdodCA+IDEgPyBfY29uZmlnLnNpemUgOiBNYXRoLmZsb29yKCh3aWR0aCAvIGhlaWdodCkgKiBfY29uZmlnLnNpemUpIDogd2lkdGg7XHJcbiAgICAgICAgX2NhbGN1bGF0ZWRIZWlnaHQgPVxyXG4gICAgICAgICAgICBfY29uZmlnLnNpemUgPyB3aWR0aCAvIGhlaWdodCA+IDEgPyBNYXRoLmZsb29yKChoZWlnaHQgLyB3aWR0aCkgKiBfY29uZmlnLnNpemUpIDogX2NvbmZpZy5zaXplIDogaGVpZ2h0O1xyXG5cclxuICAgICAgICBfY2FudmFzU2l6ZS54ID0gX2NhbGN1bGF0ZWRXaWR0aDtcclxuICAgICAgICBfY2FudmFzU2l6ZS55ID0gX2NhbGN1bGF0ZWRIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgdGhhdC5nZXRSZWFsV2lkdGggPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdmlkZW8udmlkZW9XaWR0aDtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5nZXRSZWFsSGVpZ2h0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHZpZGVvLnZpZGVvSGVpZ2h0O1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LmdldFdpZHRoID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIF9jYWxjdWxhdGVkV2lkdGg7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuZ2V0SGVpZ2h0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIF9jYWxjdWxhdGVkSGVpZ2h0O1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LnNldFdpZHRoID0gZnVuY3Rpb24od2lkdGgpIHtcclxuICAgICAgICBfY2FsY3VsYXRlZFdpZHRoID0gd2lkdGg7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuc2V0SGVpZ2h0ID0gZnVuY3Rpb24oaGVpZ2h0KSB7XHJcbiAgICAgICAgX2NhbGN1bGF0ZWRIZWlnaHQgPSBoZWlnaHQ7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuc2V0SW5wdXRTdHJlYW0gPSBmdW5jdGlvbihjb25maWcpIHtcclxuICAgICAgICBfY29uZmlnID0gY29uZmlnO1xyXG4gICAgICAgIHZpZGVvLnNyYyA9ICh0eXBlb2YgY29uZmlnLnNyYyAhPT0gJ3VuZGVmaW5lZCcpID8gY29uZmlnLnNyYyA6ICcnO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LmVuZGVkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHZpZGVvLmVuZGVkO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LmdldENvbmZpZyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBfY29uZmlnO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LnNldEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XHJcbiAgICAgICAgdmlkZW8uc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5wYXVzZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHZpZGVvLnBhdXNlKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQucGxheSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHZpZGVvLnBsYXkoKTtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5zZXRDdXJyZW50VGltZSA9IGZ1bmN0aW9uKHRpbWUpIHtcclxuICAgICAgICBpZiAoX2NvbmZpZy50eXBlICE9PSBcIkxpdmVTdHJlYW1cIikge1xyXG4gICAgICAgICAgICB2aWRlby5jdXJyZW50VGltZSA9IHRpbWU7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbihldmVudCwgZiwgYm9vbCkge1xyXG4gICAgICAgIGlmIChfZXZlbnROYW1lcy5pbmRleE9mKGV2ZW50KSAhPT0gLTEpIHtcclxuICAgICAgICAgICAgaWYgKCFfZXZlbnRIYW5kbGVyc1tldmVudF0pIHtcclxuICAgICAgICAgICAgICAgIF9ldmVudEhhbmRsZXJzW2V2ZW50XSA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF9ldmVudEhhbmRsZXJzW2V2ZW50XS5wdXNoKGYpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGYsIGJvb2wpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5jbGVhckV2ZW50SGFuZGxlcnMgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBfZXZlbnROYW1lcy5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50TmFtZSkge1xyXG4gICAgICAgICAgICB2YXIgaGFuZGxlcnMgPSBfZXZlbnRIYW5kbGVyc1tldmVudE5hbWVdO1xyXG4gICAgICAgICAgICBpZiAoaGFuZGxlcnMgJiYgaGFuZGxlcnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgaGFuZGxlcnMuZm9yRWFjaChmdW5jdGlvbihoYW5kbGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC50cmlnZ2VyID0gZnVuY3Rpb24oZXZlbnROYW1lLCBhcmdzKSB7XHJcbiAgICAgICAgdmFyIGosXHJcbiAgICAgICAgICAgIGhhbmRsZXJzID0gX2V2ZW50SGFuZGxlcnNbZXZlbnROYW1lXTtcclxuXHJcbiAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ2NhbnJlY29yZCcpIHtcclxuICAgICAgICAgICAgaW5pdFNpemUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGhhbmRsZXJzICYmIGhhbmRsZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgZm9yICggaiA9IDA7IGogPCBoYW5kbGVycy5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICAgICAgaGFuZGxlcnNbal0uYXBwbHkodGhhdCwgYXJncyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuc2V0VG9wUmlnaHQgPSBmdW5jdGlvbih0b3BSaWdodCkge1xyXG4gICAgICAgIF90b3BSaWdodC54ID0gdG9wUmlnaHQueDtcclxuICAgICAgICBfdG9wUmlnaHQueSA9IHRvcFJpZ2h0Lnk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuZ2V0VG9wUmlnaHQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gX3RvcFJpZ2h0O1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LnNldENhbnZhc1NpemUgPSBmdW5jdGlvbihzaXplKSB7XHJcbiAgICAgICAgX2NhbnZhc1NpemUueCA9IHNpemUueDtcclxuICAgICAgICBfY2FudmFzU2l6ZS55ID0gc2l6ZS55O1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LmdldENhbnZhc1NpemUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gX2NhbnZhc1NpemU7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuZ2V0RnJhbWUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdmlkZW87XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiB0aGF0O1xyXG59O1xyXG5cclxuSW5wdXRTdHJlYW0uY3JlYXRlTGl2ZVN0cmVhbSA9IGZ1bmN0aW9uKHZpZGVvKSB7XHJcbiAgICB2aWRlby5zZXRBdHRyaWJ1dGUoXCJhdXRvcGxheVwiLCB0cnVlKTtcclxuICAgIHZhciB0aGF0ID0gSW5wdXRTdHJlYW0uY3JlYXRlVmlkZW9TdHJlYW0odmlkZW8pO1xyXG5cclxuICAgIHRoYXQuZW5kZWQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiB0aGF0O1xyXG59O1xyXG5cclxuSW5wdXRTdHJlYW0uY3JlYXRlSW1hZ2VTdHJlYW0gPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciB0aGF0ID0ge307XHJcbiAgICB2YXIgX2NvbmZpZyA9IG51bGw7XHJcblxyXG4gICAgdmFyIHdpZHRoID0gMCxcclxuICAgICAgICBoZWlnaHQgPSAwLFxyXG4gICAgICAgIGZyYW1lSWR4ID0gMCxcclxuICAgICAgICBwYXVzZWQgPSB0cnVlLFxyXG4gICAgICAgIGxvYWRlZCA9IGZhbHNlLFxyXG4gICAgICAgIGltZ0FycmF5ID0gbnVsbCxcclxuICAgICAgICBzaXplID0gMCxcclxuICAgICAgICBvZmZzZXQgPSAxLFxyXG4gICAgICAgIGJhc2VVcmwgPSBudWxsLFxyXG4gICAgICAgIGVuZGVkID0gZmFsc2UsXHJcbiAgICAgICAgY2FsY3VsYXRlZFdpZHRoLFxyXG4gICAgICAgIGNhbGN1bGF0ZWRIZWlnaHQsXHJcbiAgICAgICAgX2V2ZW50TmFtZXMgPSBbJ2NhbnJlY29yZCcsICdlbmRlZCddLFxyXG4gICAgICAgIF9ldmVudEhhbmRsZXJzID0ge30sXHJcbiAgICAgICAgX3RvcFJpZ2h0ID0ge3g6IDAsIHk6IDB9LFxyXG4gICAgICAgIF9jYW52YXNTaXplID0ge3g6IDAsIHk6IDB9O1xyXG5cclxuICAgIGZ1bmN0aW9uIGxvYWRJbWFnZXMoKSB7XHJcbiAgICAgICAgbG9hZGVkID0gZmFsc2U7XHJcbiAgICAgICAgSW1hZ2VMb2FkZXIubG9hZChiYXNlVXJsLCBmdW5jdGlvbihpbWdzKSB7XHJcbiAgICAgICAgICAgIGltZ0FycmF5ID0gaW1ncztcclxuICAgICAgICAgICAgd2lkdGggPSBpbWdzWzBdLndpZHRoO1xyXG4gICAgICAgICAgICBoZWlnaHQgPSBpbWdzWzBdLmhlaWdodDtcclxuICAgICAgICAgICAgY2FsY3VsYXRlZFdpZHRoID1cclxuICAgICAgICAgICAgICAgIF9jb25maWcuc2l6ZSA/IHdpZHRoIC8gaGVpZ2h0ID4gMSA/IF9jb25maWcuc2l6ZSA6IE1hdGguZmxvb3IoKHdpZHRoIC8gaGVpZ2h0KSAqIF9jb25maWcuc2l6ZSkgOiB3aWR0aDtcclxuICAgICAgICAgICAgY2FsY3VsYXRlZEhlaWdodCA9XHJcbiAgICAgICAgICAgICAgICBfY29uZmlnLnNpemUgPyB3aWR0aCAvIGhlaWdodCA+IDEgPyBNYXRoLmZsb29yKChoZWlnaHQgLyB3aWR0aCkgKiBfY29uZmlnLnNpemUpIDogX2NvbmZpZy5zaXplIDogaGVpZ2h0O1xyXG4gICAgICAgICAgICBfY2FudmFzU2l6ZS54ID0gY2FsY3VsYXRlZFdpZHRoO1xyXG4gICAgICAgICAgICBfY2FudmFzU2l6ZS55ID0gY2FsY3VsYXRlZEhlaWdodDtcclxuICAgICAgICAgICAgbG9hZGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgZnJhbWVJZHggPSAwO1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgcHVibGlzaEV2ZW50KFwiY2FucmVjb3JkXCIsIFtdKTtcclxuICAgICAgICAgICAgfSwgMCk7XHJcbiAgICAgICAgfSwgb2Zmc2V0LCBzaXplLCBfY29uZmlnLnNlcXVlbmNlKTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBwdWJsaXNoRXZlbnQoZXZlbnROYW1lLCBhcmdzKSB7XHJcbiAgICAgICAgdmFyIGosXHJcbiAgICAgICAgICAgIGhhbmRsZXJzID0gX2V2ZW50SGFuZGxlcnNbZXZlbnROYW1lXTtcclxuXHJcbiAgICAgICAgaWYgKGhhbmRsZXJzICYmIGhhbmRsZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgZm9yICggaiA9IDA7IGogPCBoYW5kbGVycy5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICAgICAgaGFuZGxlcnNbal0uYXBwbHkodGhhdCwgYXJncyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxuICAgIHRoYXQudHJpZ2dlciA9IHB1Ymxpc2hFdmVudDtcclxuXHJcbiAgICB0aGF0LmdldFdpZHRoID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIGNhbGN1bGF0ZWRXaWR0aDtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5nZXRIZWlnaHQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gY2FsY3VsYXRlZEhlaWdodDtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5zZXRXaWR0aCA9IGZ1bmN0aW9uKG5ld1dpZHRoKSB7XHJcbiAgICAgICAgY2FsY3VsYXRlZFdpZHRoID0gbmV3V2lkdGg7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuc2V0SGVpZ2h0ID0gZnVuY3Rpb24obmV3SGVpZ2h0KSB7XHJcbiAgICAgICAgY2FsY3VsYXRlZEhlaWdodCA9IG5ld0hlaWdodDtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5nZXRSZWFsV2lkdGggPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gd2lkdGg7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuZ2V0UmVhbEhlaWdodCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBoZWlnaHQ7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuc2V0SW5wdXRTdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcclxuICAgICAgICBfY29uZmlnID0gc3RyZWFtO1xyXG4gICAgICAgIGlmIChzdHJlYW0uc2VxdWVuY2UgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGJhc2VVcmwgPSBzdHJlYW0uc3JjO1xyXG4gICAgICAgICAgICBzaXplID0gMTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYXNlVXJsID0gc3RyZWFtLnNyYztcclxuICAgICAgICAgICAgc2l6ZSA9IHN0cmVhbS5sZW5ndGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxvYWRJbWFnZXMoKTtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5lbmRlZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBlbmRlZDtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5zZXRBdHRyaWJ1dGUgPSBmdW5jdGlvbigpIHt9O1xyXG5cclxuICAgIHRoYXQuZ2V0Q29uZmlnID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIF9jb25maWc7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQucGF1c2UgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBwYXVzZWQgPSB0cnVlO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LnBsYXkgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBwYXVzZWQgPSBmYWxzZTtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5zZXRDdXJyZW50VGltZSA9IGZ1bmN0aW9uKHRpbWUpIHtcclxuICAgICAgICBmcmFtZUlkeCA9IHRpbWU7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoYXQuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmKSB7XHJcbiAgICAgICAgaWYgKF9ldmVudE5hbWVzLmluZGV4T2YoZXZlbnQpICE9PSAtMSkge1xyXG4gICAgICAgICAgICBpZiAoIV9ldmVudEhhbmRsZXJzW2V2ZW50XSkge1xyXG4gICAgICAgICAgICAgICAgX2V2ZW50SGFuZGxlcnNbZXZlbnRdID0gW107XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX2V2ZW50SGFuZGxlcnNbZXZlbnRdLnB1c2goZik7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LnNldFRvcFJpZ2h0ID0gZnVuY3Rpb24odG9wUmlnaHQpIHtcclxuICAgICAgICBfdG9wUmlnaHQueCA9IHRvcFJpZ2h0Lng7XHJcbiAgICAgICAgX3RvcFJpZ2h0LnkgPSB0b3BSaWdodC55O1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LmdldFRvcFJpZ2h0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIF90b3BSaWdodDtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5zZXRDYW52YXNTaXplID0gZnVuY3Rpb24oY2FudmFzU2l6ZSkge1xyXG4gICAgICAgIF9jYW52YXNTaXplLnggPSBjYW52YXNTaXplLng7XHJcbiAgICAgICAgX2NhbnZhc1NpemUueSA9IGNhbnZhc1NpemUueTtcclxuICAgIH07XHJcblxyXG4gICAgdGhhdC5nZXRDYW52YXNTaXplID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIF9jYW52YXNTaXplO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGF0LmdldEZyYW1lID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdmFyIGZyYW1lO1xyXG5cclxuICAgICAgICBpZiAoIWxvYWRlZCl7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXBhdXNlZCkge1xyXG4gICAgICAgICAgICBmcmFtZSA9IGltZ0FycmF5W2ZyYW1lSWR4XTtcclxuICAgICAgICAgICAgaWYgKGZyYW1lSWR4IDwgKHNpemUgLSAxKSkge1xyXG4gICAgICAgICAgICAgICAgZnJhbWVJZHgrKztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5kZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hFdmVudChcImVuZGVkXCIsIFtdKTtcclxuICAgICAgICAgICAgICAgIH0sIDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmcmFtZTtcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIHRoYXQ7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBJbnB1dFN0cmVhbTtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvaW5wdXQvaW5wdXRfc3RyZWFtLmpzXG4gKiovIiwiaW1wb3J0IEltYWdlV3JhcHBlciBmcm9tICcuLi9jb21tb24vaW1hZ2Vfd3JhcHBlcic7XHJcbmltcG9ydCB7XHJcbiAgICBjYWxjdWxhdGVQYXRjaFNpemUsXHJcbiAgICBvdHN1VGhyZXNob2xkLFxyXG4gICAgaHN2MnJnYixcclxuICAgIGNsdXN0ZXIsXHJcbiAgICB0b3BHZW5lcmljLFxyXG4gICAgaW1hZ2VSZWYsXHJcbiAgICBoYWxmU2FtcGxlLFxyXG4gICAgY29tcHV0ZUltYWdlQXJlYVxyXG59IGZyb20gJy4uL2NvbW1vbi9jdl91dGlscyc7XHJcbmltcG9ydCBBcnJheUhlbHBlciBmcm9tICcuLi9jb21tb24vYXJyYXlfaGVscGVyJztcclxuaW1wb3J0IEltYWdlRGVidWcgZnJvbSAnLi4vY29tbW9uL2ltYWdlX2RlYnVnJztcclxuaW1wb3J0IFJhc3Rlcml6ZXIgZnJvbSAnLi9yYXN0ZXJpemVyJztcclxuaW1wb3J0IFRyYWNlciBmcm9tICcuL3RyYWNlcic7XHJcbmltcG9ydCBza2VsZXRvbml6ZXIgZnJvbSAnLi9za2VsZXRvbml6ZXInO1xyXG5jb25zdCB2ZWMyID0ge1xyXG4gICAgY2xvbmU6IHJlcXVpcmUoJ2dsLXZlYzIvY2xvbmUnKSxcclxuICAgIGRvdDogIHJlcXVpcmUoJ2dsLXZlYzIvZG90JyksXHJcbiAgICBzY2FsZTogcmVxdWlyZSgnZ2wtdmVjMi9zY2FsZScpLFxyXG4gICAgdHJhbnNmb3JtTWF0MjogcmVxdWlyZSgnZ2wtdmVjMi90cmFuc2Zvcm1NYXQyJylcclxufTtcclxuY29uc3QgbWF0MiA9IHtcclxuICAgIGNvcHk6IHJlcXVpcmUoJ2dsLW1hdDIvY29weScpLFxyXG4gICAgY3JlYXRlOiByZXF1aXJlKCdnbC1tYXQyL2NyZWF0ZScpLFxyXG4gICAgaW52ZXJ0OiByZXF1aXJlKCdnbC1tYXQyL2ludmVydCcpXHJcbn1cclxuXHJcbnZhciBfY29uZmlnLFxyXG4gICAgX2N1cnJlbnRJbWFnZVdyYXBwZXIsXHJcbiAgICBfc2tlbEltYWdlV3JhcHBlcixcclxuICAgIF9zdWJJbWFnZVdyYXBwZXIsXHJcbiAgICBfbGFiZWxJbWFnZVdyYXBwZXIsXHJcbiAgICBfcGF0Y2hHcmlkLFxyXG4gICAgX3BhdGNoTGFiZWxHcmlkLFxyXG4gICAgX2ltYWdlVG9QYXRjaEdyaWQsXHJcbiAgICBfYmluYXJ5SW1hZ2VXcmFwcGVyLFxyXG4gICAgX3BhdGNoU2l6ZSxcclxuICAgIF9jYW52YXNDb250YWluZXIgPSB7XHJcbiAgICAgICAgY3R4OiB7XHJcbiAgICAgICAgICAgIGJpbmFyeTogbnVsbFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZG9tOiB7XHJcbiAgICAgICAgICAgIGJpbmFyeTogbnVsbFxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBfbnVtUGF0Y2hlcyA9IHt4OiAwLCB5OiAwfSxcclxuICAgIF9pbnB1dEltYWdlV3JhcHBlcixcclxuICAgIF9za2VsZXRvbml6ZXI7XHJcblxyXG5mdW5jdGlvbiBpbml0QnVmZmVycygpIHtcclxuICAgIHZhciBza2VsZXRvbkltYWdlRGF0YTtcclxuXHJcbiAgICBpZiAoX2NvbmZpZy5oYWxmU2FtcGxlKSB7XHJcbiAgICAgICAgX2N1cnJlbnRJbWFnZVdyYXBwZXIgPSBuZXcgSW1hZ2VXcmFwcGVyKHtcclxuICAgICAgICAgICAgeDogX2lucHV0SW1hZ2VXcmFwcGVyLnNpemUueCAvIDIgfCAwLFxyXG4gICAgICAgICAgICB5OiBfaW5wdXRJbWFnZVdyYXBwZXIuc2l6ZS55IC8gMiB8IDBcclxuICAgICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2N1cnJlbnRJbWFnZVdyYXBwZXIgPSBfaW5wdXRJbWFnZVdyYXBwZXI7XHJcbiAgICB9XHJcblxyXG4gICAgX3BhdGNoU2l6ZSA9IGNhbGN1bGF0ZVBhdGNoU2l6ZShfY29uZmlnLnBhdGNoU2l6ZSwgX2N1cnJlbnRJbWFnZVdyYXBwZXIuc2l6ZSk7XHJcblxyXG4gICAgX251bVBhdGNoZXMueCA9IF9jdXJyZW50SW1hZ2VXcmFwcGVyLnNpemUueCAvIF9wYXRjaFNpemUueCB8IDA7XHJcbiAgICBfbnVtUGF0Y2hlcy55ID0gX2N1cnJlbnRJbWFnZVdyYXBwZXIuc2l6ZS55IC8gX3BhdGNoU2l6ZS55IHwgMDtcclxuXHJcbiAgICBfYmluYXJ5SW1hZ2VXcmFwcGVyID0gbmV3IEltYWdlV3JhcHBlcihfY3VycmVudEltYWdlV3JhcHBlci5zaXplLCB1bmRlZmluZWQsIFVpbnQ4QXJyYXksIGZhbHNlKTtcclxuXHJcbiAgICBfbGFiZWxJbWFnZVdyYXBwZXIgPSBuZXcgSW1hZ2VXcmFwcGVyKF9wYXRjaFNpemUsIHVuZGVmaW5lZCwgQXJyYXksIHRydWUpO1xyXG5cclxuICAgIHNrZWxldG9uSW1hZ2VEYXRhID0gbmV3IEFycmF5QnVmZmVyKDY0ICogMTAyNCk7XHJcbiAgICBfc3ViSW1hZ2VXcmFwcGVyID0gbmV3IEltYWdlV3JhcHBlcihfcGF0Y2hTaXplLFxyXG4gICAgICAgIG5ldyBVaW50OEFycmF5KHNrZWxldG9uSW1hZ2VEYXRhLCAwLCBfcGF0Y2hTaXplLnggKiBfcGF0Y2hTaXplLnkpKTtcclxuICAgIF9za2VsSW1hZ2VXcmFwcGVyID0gbmV3IEltYWdlV3JhcHBlcihfcGF0Y2hTaXplLFxyXG4gICAgICAgIG5ldyBVaW50OEFycmF5KHNrZWxldG9uSW1hZ2VEYXRhLCBfcGF0Y2hTaXplLnggKiBfcGF0Y2hTaXplLnkgKiAzLCBfcGF0Y2hTaXplLnggKiBfcGF0Y2hTaXplLnkpLFxyXG4gICAgICAgIHVuZGVmaW5lZCwgdHJ1ZSk7XHJcbiAgICBfc2tlbGV0b25pemVyID0gc2tlbGV0b25pemVyKCh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgPyB3aW5kb3cgOiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnKSA/IHNlbGYgOiBnbG9iYWwsIHtcclxuICAgICAgICBzaXplOiBfcGF0Y2hTaXplLnhcclxuICAgIH0sIHNrZWxldG9uSW1hZ2VEYXRhKTtcclxuXHJcbiAgICBfaW1hZ2VUb1BhdGNoR3JpZCA9IG5ldyBJbWFnZVdyYXBwZXIoe1xyXG4gICAgICAgIHg6IChfY3VycmVudEltYWdlV3JhcHBlci5zaXplLnggLyBfc3ViSW1hZ2VXcmFwcGVyLnNpemUueCkgfCAwLFxyXG4gICAgICAgIHk6IChfY3VycmVudEltYWdlV3JhcHBlci5zaXplLnkgLyBfc3ViSW1hZ2VXcmFwcGVyLnNpemUueSkgfCAwXHJcbiAgICB9LCB1bmRlZmluZWQsIEFycmF5LCB0cnVlKTtcclxuICAgIF9wYXRjaEdyaWQgPSBuZXcgSW1hZ2VXcmFwcGVyKF9pbWFnZVRvUGF0Y2hHcmlkLnNpemUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0cnVlKTtcclxuICAgIF9wYXRjaExhYmVsR3JpZCA9IG5ldyBJbWFnZVdyYXBwZXIoX2ltYWdlVG9QYXRjaEdyaWQuc2l6ZSwgdW5kZWZpbmVkLCBJbnQzMkFycmF5LCB0cnVlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaW5pdENhbnZhcygpIHtcclxuICAgIGlmIChfY29uZmlnLnVzZVdvcmtlciB8fCB0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgX2NhbnZhc0NvbnRhaW5lci5kb20uYmluYXJ5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcclxuICAgIF9jYW52YXNDb250YWluZXIuZG9tLmJpbmFyeS5jbGFzc05hbWUgPSBcImJpbmFyeUJ1ZmZlclwiO1xyXG4gICAgaWYgKEVOVi5kZXZlbG9wbWVudCAmJiBfY29uZmlnLmRlYnVnLnNob3dDYW52YXMgPT09IHRydWUpIHtcclxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2RlYnVnXCIpLmFwcGVuZENoaWxkKF9jYW52YXNDb250YWluZXIuZG9tLmJpbmFyeSk7XHJcbiAgICB9XHJcbiAgICBfY2FudmFzQ29udGFpbmVyLmN0eC5iaW5hcnkgPSBfY2FudmFzQ29udGFpbmVyLmRvbS5iaW5hcnkuZ2V0Q29udGV4dChcIjJkXCIpO1xyXG4gICAgX2NhbnZhc0NvbnRhaW5lci5kb20uYmluYXJ5LndpZHRoID0gX2JpbmFyeUltYWdlV3JhcHBlci5zaXplLng7XHJcbiAgICBfY2FudmFzQ29udGFpbmVyLmRvbS5iaW5hcnkuaGVpZ2h0ID0gX2JpbmFyeUltYWdlV3JhcHBlci5zaXplLnk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgYm91bmRpbmcgYm94IHdoaWNoIGVuY2xvc2VzIGFsbCB0aGUgZ2l2ZW4gcGF0Y2hlc1xyXG4gKiBAcmV0dXJucyB7QXJyYXl9IFRoZSBtaW5pbWFsIGJvdW5kaW5nIGJveFxyXG4gKi9cclxuZnVuY3Rpb24gYm94RnJvbVBhdGNoZXMocGF0Y2hlcykge1xyXG4gICAgdmFyIG92ZXJBdmcsXHJcbiAgICAgICAgaSxcclxuICAgICAgICBqLFxyXG4gICAgICAgIHBhdGNoLFxyXG4gICAgICAgIHRyYW5zTWF0LFxyXG4gICAgICAgIG1pbnggPVxyXG4gICAgICAgIF9iaW5hcnlJbWFnZVdyYXBwZXIuc2l6ZS54LFxyXG4gICAgICAgIG1pbnkgPSBfYmluYXJ5SW1hZ2VXcmFwcGVyLnNpemUueSxcclxuICAgICAgICBtYXh4ID0gLV9iaW5hcnlJbWFnZVdyYXBwZXIuc2l6ZS54LFxyXG4gICAgICAgIG1heHkgPSAtX2JpbmFyeUltYWdlV3JhcHBlci5zaXplLnksXHJcbiAgICAgICAgYm94LFxyXG4gICAgICAgIHNjYWxlO1xyXG5cclxuICAgIC8vIGRyYXcgYWxsIHBhdGNoZXMgd2hpY2ggYXJlIHRvIGJlIHRha2VuIGludG8gY29uc2lkZXJhdGlvblxyXG4gICAgb3ZlckF2ZyA9IDA7XHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IHBhdGNoZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBwYXRjaCA9IHBhdGNoZXNbaV07XHJcbiAgICAgICAgb3ZlckF2ZyArPSBwYXRjaC5yYWQ7XHJcbiAgICAgICAgaWYgKEVOVi5kZXZlbG9wbWVudCAmJiBfY29uZmlnLmRlYnVnLnNob3dQYXRjaGVzKSB7XHJcbiAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1JlY3QocGF0Y2gucG9zLCBfc3ViSW1hZ2VXcmFwcGVyLnNpemUsIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSwge2NvbG9yOiBcInJlZFwifSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG92ZXJBdmcgLz0gcGF0Y2hlcy5sZW5ndGg7XHJcbiAgICBvdmVyQXZnID0gKG92ZXJBdmcgKiAxODAgLyBNYXRoLlBJICsgOTApICUgMTgwIC0gOTA7XHJcbiAgICBpZiAob3ZlckF2ZyA8IDApIHtcclxuICAgICAgICBvdmVyQXZnICs9IDE4MDtcclxuICAgIH1cclxuXHJcbiAgICBvdmVyQXZnID0gKDE4MCAtIG92ZXJBdmcpICogTWF0aC5QSSAvIDE4MDtcclxuICAgIHRyYW5zTWF0ID0gbWF0Mi5jb3B5KG1hdDIuY3JlYXRlKCksIFtNYXRoLmNvcyhvdmVyQXZnKSwgTWF0aC5zaW4ob3ZlckF2ZyksIC1NYXRoLnNpbihvdmVyQXZnKSwgTWF0aC5jb3Mob3ZlckF2ZyldKTtcclxuXHJcbiAgICAvLyBpdGVyYXRlIG92ZXIgcGF0Y2hlcyBhbmQgcm90YXRlIGJ5IGFuZ2xlXHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IHBhdGNoZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBwYXRjaCA9IHBhdGNoZXNbaV07XHJcbiAgICAgICAgZm9yICggaiA9IDA7IGogPCA0OyBqKyspIHtcclxuICAgICAgICAgICAgdmVjMi50cmFuc2Zvcm1NYXQyKHBhdGNoLmJveFtqXSwgcGF0Y2guYm94W2pdLCB0cmFuc01hdCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoRU5WLmRldmVsb3BtZW50ICYmIF9jb25maWcuZGVidWcuYm94RnJvbVBhdGNoZXMuc2hvd1RyYW5zZm9ybWVkKSB7XHJcbiAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1BhdGgocGF0Y2guYm94LCB7eDogMCwgeTogMX0sIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSwge2NvbG9yOiAnIzk5ZmYwMCcsIGxpbmVXaWR0aDogMn0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBmaW5kIGJvdW5kaW5nIGJveFxyXG4gICAgZm9yICggaSA9IDA7IGkgPCBwYXRjaGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgcGF0Y2ggPSBwYXRjaGVzW2ldO1xyXG4gICAgICAgIGZvciAoIGogPSAwOyBqIDwgNDsgaisrKSB7XHJcbiAgICAgICAgICAgIGlmIChwYXRjaC5ib3hbal1bMF0gPCBtaW54KSB7XHJcbiAgICAgICAgICAgICAgICBtaW54ID0gcGF0Y2guYm94W2pdWzBdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwYXRjaC5ib3hbal1bMF0gPiBtYXh4KSB7XHJcbiAgICAgICAgICAgICAgICBtYXh4ID0gcGF0Y2guYm94W2pdWzBdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwYXRjaC5ib3hbal1bMV0gPCBtaW55KSB7XHJcbiAgICAgICAgICAgICAgICBtaW55ID0gcGF0Y2guYm94W2pdWzFdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwYXRjaC5ib3hbal1bMV0gPiBtYXh5KSB7XHJcbiAgICAgICAgICAgICAgICBtYXh5ID0gcGF0Y2guYm94W2pdWzFdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGJveCA9IFtbbWlueCwgbWlueV0sIFttYXh4LCBtaW55XSwgW21heHgsIG1heHldLCBbbWlueCwgbWF4eV1dO1xyXG5cclxuICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQgJiYgX2NvbmZpZy5kZWJ1Zy5ib3hGcm9tUGF0Y2hlcy5zaG93VHJhbnNmb3JtZWRCb3gpIHtcclxuICAgICAgICBJbWFnZURlYnVnLmRyYXdQYXRoKGJveCwge3g6IDAsIHk6IDF9LCBfY2FudmFzQ29udGFpbmVyLmN0eC5iaW5hcnksIHtjb2xvcjogJyNmZjAwMDAnLCBsaW5lV2lkdGg6IDJ9KTtcclxuICAgIH1cclxuXHJcbiAgICBzY2FsZSA9IF9jb25maWcuaGFsZlNhbXBsZSA/IDIgOiAxO1xyXG4gICAgLy8gcmV2ZXJzZSByb3RhdGlvbjtcclxuICAgIHRyYW5zTWF0ID0gbWF0Mi5pbnZlcnQodHJhbnNNYXQsIHRyYW5zTWF0KTtcclxuICAgIGZvciAoIGogPSAwOyBqIDwgNDsgaisrKSB7XHJcbiAgICAgICAgdmVjMi50cmFuc2Zvcm1NYXQyKGJveFtqXSwgYm94W2pdLCB0cmFuc01hdCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKEVOVi5kZXZlbG9wbWVudCAmJiBfY29uZmlnLmRlYnVnLmJveEZyb21QYXRjaGVzLnNob3dCQikge1xyXG4gICAgICAgIEltYWdlRGVidWcuZHJhd1BhdGgoYm94LCB7eDogMCwgeTogMX0sIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSwge2NvbG9yOiAnI2ZmMDAwMCcsIGxpbmVXaWR0aDogMn0pO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAoIGogPSAwOyBqIDwgNDsgaisrKSB7XHJcbiAgICAgICAgdmVjMi5zY2FsZShib3hbal0sIGJveFtqXSwgc2NhbGUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBib3g7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgYmluYXJ5IGltYWdlIG9mIHRoZSBjdXJyZW50IGltYWdlXHJcbiAqL1xyXG5mdW5jdGlvbiBiaW5hcml6ZUltYWdlKCkge1xyXG4gICAgb3RzdVRocmVzaG9sZChfY3VycmVudEltYWdlV3JhcHBlciwgX2JpbmFyeUltYWdlV3JhcHBlcik7XHJcbiAgICBfYmluYXJ5SW1hZ2VXcmFwcGVyLnplcm9Cb3JkZXIoKTtcclxuICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQgJiYgX2NvbmZpZy5kZWJ1Zy5zaG93Q2FudmFzKSB7XHJcbiAgICAgICAgX2JpbmFyeUltYWdlV3JhcHBlci5zaG93KF9jYW52YXNDb250YWluZXIuZG9tLmJpbmFyeSwgMjU1KTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEl0ZXJhdGUgb3ZlciB0aGUgZW50aXJlIGltYWdlXHJcbiAqIGV4dHJhY3QgcGF0Y2hlc1xyXG4gKi9cclxuZnVuY3Rpb24gZmluZFBhdGNoZXMoKSB7XHJcbiAgICB2YXIgaSxcclxuICAgICAgICBqLFxyXG4gICAgICAgIHgsXHJcbiAgICAgICAgeSxcclxuICAgICAgICBtb21lbnRzLFxyXG4gICAgICAgIHBhdGNoZXNGb3VuZCA9IFtdLFxyXG4gICAgICAgIHJhc3Rlcml6ZXIsXHJcbiAgICAgICAgcmFzdGVyUmVzdWx0LFxyXG4gICAgICAgIHBhdGNoO1xyXG4gICAgZm9yIChpID0gMDsgaSA8IF9udW1QYXRjaGVzLng7IGkrKykge1xyXG4gICAgICAgIGZvciAoaiA9IDA7IGogPCBfbnVtUGF0Y2hlcy55OyBqKyspIHtcclxuICAgICAgICAgICAgeCA9IF9zdWJJbWFnZVdyYXBwZXIuc2l6ZS54ICogaTtcclxuICAgICAgICAgICAgeSA9IF9zdWJJbWFnZVdyYXBwZXIuc2l6ZS55ICogajtcclxuXHJcbiAgICAgICAgICAgIC8vIHNlcGVyYXRlIHBhcnRzXHJcbiAgICAgICAgICAgIHNrZWxldG9uaXplKHgsIHkpO1xyXG5cclxuICAgICAgICAgICAgLy8gUmFzdGVyaXplLCBmaW5kIGluZGl2aWR1YWwgYmFyc1xyXG4gICAgICAgICAgICBfc2tlbEltYWdlV3JhcHBlci56ZXJvQm9yZGVyKCk7XHJcbiAgICAgICAgICAgIEFycmF5SGVscGVyLmluaXQoX2xhYmVsSW1hZ2VXcmFwcGVyLmRhdGEsIDApO1xyXG4gICAgICAgICAgICByYXN0ZXJpemVyID0gUmFzdGVyaXplci5jcmVhdGUoX3NrZWxJbWFnZVdyYXBwZXIsIF9sYWJlbEltYWdlV3JhcHBlcik7XHJcbiAgICAgICAgICAgIHJhc3RlclJlc3VsdCA9IHJhc3Rlcml6ZXIucmFzdGVyaXplKDApO1xyXG5cclxuICAgICAgICAgICAgaWYgKEVOVi5kZXZlbG9wbWVudCAmJiBfY29uZmlnLmRlYnVnLnNob3dMYWJlbHMpIHtcclxuICAgICAgICAgICAgICAgIF9sYWJlbEltYWdlV3JhcHBlci5vdmVybGF5KF9jYW52YXNDb250YWluZXIuZG9tLmJpbmFyeSwgTWF0aC5mbG9vcigzNjAgLyByYXN0ZXJSZXN1bHQuY291bnQpLFxyXG4gICAgICAgICAgICAgICAgICAgIHt4OiB4LCB5OiB5fSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBtb21lbnRzIGZyb20gdGhlIHNrZWxldG9uaXplZCBwYXRjaFxyXG4gICAgICAgICAgICBtb21lbnRzID0gX2xhYmVsSW1hZ2VXcmFwcGVyLm1vbWVudHMocmFzdGVyUmVzdWx0LmNvdW50KTtcclxuXHJcbiAgICAgICAgICAgIC8vIGV4dHJhY3QgZWxpZ2libGUgcGF0Y2hlc1xyXG4gICAgICAgICAgICBwYXRjaGVzRm91bmQgPSBwYXRjaGVzRm91bmQuY29uY2F0KGRlc2NyaWJlUGF0Y2gobW9tZW50cywgW2ksIGpdLCB4LCB5KSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQgJiYgX2NvbmZpZy5kZWJ1Zy5zaG93Rm91bmRQYXRjaGVzKSB7XHJcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBwYXRjaGVzRm91bmQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgcGF0Y2ggPSBwYXRjaGVzRm91bmRbaV07XHJcbiAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1JlY3QocGF0Y2gucG9zLCBfc3ViSW1hZ2VXcmFwcGVyLnNpemUsIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSxcclxuICAgICAgICAgICAgICAgIHtjb2xvcjogXCIjOTlmZjAwXCIsIGxpbmVXaWR0aDogMn0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcGF0Y2hlc0ZvdW5kO1xyXG59XHJcblxyXG4vKipcclxuICogRmluZHMgdGhvc2UgY29ubmVjdGVkIGFyZWFzIHdoaWNoIGNvbnRhaW4gYXQgbGVhc3QgNiBwYXRjaGVzXHJcbiAqIGFuZCByZXR1cm5zIHRoZW0gb3JkZXJlZCBERVNDIGJ5IHRoZSBudW1iZXIgb2YgY29udGFpbmVkIHBhdGNoZXNcclxuICogQHBhcmFtIHtOdW1iZXJ9IG1heExhYmVsXHJcbiAqL1xyXG5mdW5jdGlvbiBmaW5kQmlnZ2VzdENvbm5lY3RlZEFyZWFzKG1heExhYmVsKXtcclxuICAgIHZhciBpLFxyXG4gICAgICAgIHN1bSxcclxuICAgICAgICBsYWJlbEhpc3QgPSBbXSxcclxuICAgICAgICB0b3BMYWJlbHMgPSBbXTtcclxuXHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IG1heExhYmVsOyBpKyspIHtcclxuICAgICAgICBsYWJlbEhpc3QucHVzaCgwKTtcclxuICAgIH1cclxuICAgIHN1bSA9IF9wYXRjaExhYmVsR3JpZC5kYXRhLmxlbmd0aDtcclxuICAgIHdoaWxlIChzdW0tLSkge1xyXG4gICAgICAgIGlmIChfcGF0Y2hMYWJlbEdyaWQuZGF0YVtzdW1dID4gMCkge1xyXG4gICAgICAgICAgICBsYWJlbEhpc3RbX3BhdGNoTGFiZWxHcmlkLmRhdGFbc3VtXSAtIDFdKys7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGxhYmVsSGlzdCA9IGxhYmVsSGlzdC5tYXAoZnVuY3Rpb24odmFsLCBpZHgpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2YWw6IHZhbCxcclxuICAgICAgICAgICAgbGFiZWw6IGlkeCArIDFcclxuICAgICAgICB9O1xyXG4gICAgfSk7XHJcblxyXG4gICAgbGFiZWxIaXN0LnNvcnQoZnVuY3Rpb24oYSwgYikge1xyXG4gICAgICAgIHJldHVybiBiLnZhbCAtIGEudmFsO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gZXh0cmFjdCB0b3AgYXJlYXMgd2l0aCBhdCBsZWFzdCA2IHBhdGNoZXMgcHJlc2VudFxyXG4gICAgdG9wTGFiZWxzID0gbGFiZWxIaXN0LmZpbHRlcihmdW5jdGlvbihlbCkge1xyXG4gICAgICAgIHJldHVybiBlbC52YWwgPj0gNTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB0b3BMYWJlbHM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKlxyXG4gKi9cclxuZnVuY3Rpb24gZmluZEJveGVzKHRvcExhYmVscywgbWF4TGFiZWwpIHtcclxuICAgIHZhciBpLFxyXG4gICAgICAgIGosXHJcbiAgICAgICAgc3VtLFxyXG4gICAgICAgIHBhdGNoZXMgPSBbXSxcclxuICAgICAgICBwYXRjaCxcclxuICAgICAgICBib3gsXHJcbiAgICAgICAgYm94ZXMgPSBbXSxcclxuICAgICAgICBoc3YgPSBbMCwgMSwgMV0sXHJcbiAgICAgICAgcmdiID0gWzAsIDAsIDBdO1xyXG5cclxuICAgIGZvciAoIGkgPSAwOyBpIDwgdG9wTGFiZWxzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgc3VtID0gX3BhdGNoTGFiZWxHcmlkLmRhdGEubGVuZ3RoO1xyXG4gICAgICAgIHBhdGNoZXMubGVuZ3RoID0gMDtcclxuICAgICAgICB3aGlsZSAoc3VtLS0pIHtcclxuICAgICAgICAgICAgaWYgKF9wYXRjaExhYmVsR3JpZC5kYXRhW3N1bV0gPT09IHRvcExhYmVsc1tpXS5sYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgcGF0Y2ggPSBfaW1hZ2VUb1BhdGNoR3JpZC5kYXRhW3N1bV07XHJcbiAgICAgICAgICAgICAgICBwYXRjaGVzLnB1c2gocGF0Y2gpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJveCA9IGJveEZyb21QYXRjaGVzKHBhdGNoZXMpO1xyXG4gICAgICAgIGlmIChib3gpIHtcclxuICAgICAgICAgICAgYm94ZXMucHVzaChib3gpO1xyXG5cclxuICAgICAgICAgICAgLy8gZHJhdyBwYXRjaC1sYWJlbHMgaWYgcmVxdWVzdGVkXHJcbiAgICAgICAgICAgIGlmIChFTlYuZGV2ZWxvcG1lbnQgJiYgX2NvbmZpZy5kZWJ1Zy5zaG93UmVtYWluaW5nUGF0Y2hMYWJlbHMpIHtcclxuICAgICAgICAgICAgICAgIGZvciAoIGogPSAwOyBqIDwgcGF0Y2hlcy5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhdGNoID0gcGF0Y2hlc1tqXTtcclxuICAgICAgICAgICAgICAgICAgICBoc3ZbMF0gPSAodG9wTGFiZWxzW2ldLmxhYmVsIC8gKG1heExhYmVsICsgMSkpICogMzYwO1xyXG4gICAgICAgICAgICAgICAgICAgIGhzdjJyZ2IoaHN2LCByZ2IpO1xyXG4gICAgICAgICAgICAgICAgICAgIEltYWdlRGVidWcuZHJhd1JlY3QocGF0Y2gucG9zLCBfc3ViSW1hZ2VXcmFwcGVyLnNpemUsIF9jYW52YXNDb250YWluZXIuY3R4LmJpbmFyeSxcclxuICAgICAgICAgICAgICAgICAgICAgICAge2NvbG9yOiBcInJnYihcIiArIHJnYi5qb2luKFwiLFwiKSArIFwiKVwiLCBsaW5lV2lkdGg6IDJ9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBib3hlcztcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbmQgc2ltaWxhciBtb21lbnRzICh2aWEgY2x1c3RlcilcclxuICogQHBhcmFtIHtPYmplY3R9IG1vbWVudHNcclxuICovXHJcbmZ1bmN0aW9uIHNpbWlsYXJNb21lbnRzKG1vbWVudHMpIHtcclxuICAgIHZhciBjbHVzdGVycyA9IGNsdXN0ZXIobW9tZW50cywgMC45MCk7XHJcbiAgICB2YXIgdG9wQ2x1c3RlciA9IHRvcEdlbmVyaWMoY2x1c3RlcnMsIDEsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICByZXR1cm4gZS5nZXRQb2ludHMoKS5sZW5ndGg7XHJcbiAgICB9KTtcclxuICAgIHZhciBwb2ludHMgPSBbXSwgcmVzdWx0ID0gW107XHJcbiAgICBpZiAodG9wQ2x1c3Rlci5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICBwb2ludHMgPSB0b3BDbHVzdGVyWzBdLml0ZW0uZ2V0UG9pbnRzKCk7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgcmVzdWx0LnB1c2gocG9pbnRzW2ldLnBvaW50KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBza2VsZXRvbml6ZSh4LCB5KSB7XHJcbiAgICBfYmluYXJ5SW1hZ2VXcmFwcGVyLnN1YkltYWdlQXNDb3B5KF9zdWJJbWFnZVdyYXBwZXIsIGltYWdlUmVmKHgsIHkpKTtcclxuICAgIF9za2VsZXRvbml6ZXIuc2tlbGV0b25pemUoKTtcclxuXHJcbiAgICAvLyBTaG93IHNrZWxldG9uIGlmIHJlcXVlc3RlZFxyXG4gICAgaWYgKEVOVi5kZXZlbG9wbWVudCAmJiBfY29uZmlnLmRlYnVnLnNob3dTa2VsZXRvbikge1xyXG4gICAgICAgIF9za2VsSW1hZ2VXcmFwcGVyLm92ZXJsYXkoX2NhbnZhc0NvbnRhaW5lci5kb20uYmluYXJ5LCAzNjAsIGltYWdlUmVmKHgsIHkpKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEV4dHJhY3RzIGFuZCBkZXNjcmliZXMgdGhvc2UgcGF0Y2hlcyB3aGljaCBzZWVtIHRvIGNvbnRhaW4gYSBiYXJjb2RlIHBhdHRlcm5cclxuICogQHBhcmFtIHtBcnJheX0gbW9tZW50c1xyXG4gKiBAcGFyYW0ge09iamVjdH0gcGF0Y2hQb3MsXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB4XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB5XHJcbiAqIEByZXR1cm5zIHtBcnJheX0gbGlzdCBvZiBwYXRjaGVzXHJcbiAqL1xyXG5mdW5jdGlvbiBkZXNjcmliZVBhdGNoKG1vbWVudHMsIHBhdGNoUG9zLCB4LCB5KSB7XHJcbiAgICB2YXIgayxcclxuICAgICAgICBhdmcsXHJcbiAgICAgICAgZWxpZ2libGVNb21lbnRzID0gW10sXHJcbiAgICAgICAgbWF0Y2hpbmdNb21lbnRzLFxyXG4gICAgICAgIHBhdGNoLFxyXG4gICAgICAgIHBhdGNoZXNGb3VuZCA9IFtdLFxyXG4gICAgICAgIG1pbkNvbXBvbmVudFdlaWdodCA9IE1hdGguY2VpbChfcGF0Y2hTaXplLnggLyAzKTtcclxuXHJcbiAgICBpZiAobW9tZW50cy5sZW5ndGggPj0gMikge1xyXG4gICAgICAgIC8vIG9ubHkgY29sbGVjdCBtb21lbnRzIHdoaWNoJ3MgYXJlYSBjb3ZlcnMgYXQgbGVhc3QgbWluQ29tcG9uZW50V2VpZ2h0IHBpeGVscy5cclxuICAgICAgICBmb3IgKCBrID0gMDsgayA8IG1vbWVudHMubGVuZ3RoOyBrKyspIHtcclxuICAgICAgICAgICAgaWYgKG1vbWVudHNba10ubTAwID4gbWluQ29tcG9uZW50V2VpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICBlbGlnaWJsZU1vbWVudHMucHVzaChtb21lbnRzW2tdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gaWYgYXQgbGVhc3QgMiBtb21lbnRzIGFyZSBmb3VuZCB3aGljaCBoYXZlIGF0IGxlYXN0IG1pbkNvbXBvbmVudFdlaWdodHMgY292ZXJlZFxyXG4gICAgICAgIGlmIChlbGlnaWJsZU1vbWVudHMubGVuZ3RoID49IDIpIHtcclxuICAgICAgICAgICAgbWF0Y2hpbmdNb21lbnRzID0gc2ltaWxhck1vbWVudHMoZWxpZ2libGVNb21lbnRzKTtcclxuICAgICAgICAgICAgYXZnID0gMDtcclxuICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIHRoZSBzaW1pbGFyaXR5IG9mIHRoZSBtb21lbnRzXHJcbiAgICAgICAgICAgIGZvciAoIGsgPSAwOyBrIDwgbWF0Y2hpbmdNb21lbnRzLmxlbmd0aDsgaysrKSB7XHJcbiAgICAgICAgICAgICAgICBhdmcgKz0gbWF0Y2hpbmdNb21lbnRzW2tdLnJhZDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gT25seSB0d28gb2YgdGhlIG1vbWVudHMgYXJlIGFsbG93ZWQgbm90IHRvIGZpdCBpbnRvIHRoZSBlcXVhdGlvblxyXG4gICAgICAgICAgICAvLyBhZGQgdGhlIHBhdGNoIHRvIHRoZSBzZXRcclxuICAgICAgICAgICAgaWYgKG1hdGNoaW5nTW9tZW50cy5sZW5ndGggPiAxXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgbWF0Y2hpbmdNb21lbnRzLmxlbmd0aCA+PSAoZWxpZ2libGVNb21lbnRzLmxlbmd0aCAvIDQpICogM1xyXG4gICAgICAgICAgICAgICAgICAgICYmIG1hdGNoaW5nTW9tZW50cy5sZW5ndGggPiBtb21lbnRzLmxlbmd0aCAvIDQpIHtcclxuICAgICAgICAgICAgICAgIGF2ZyAvPSBtYXRjaGluZ01vbWVudHMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgcGF0Y2ggPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHBhdGNoUG9zWzFdICogX251bVBhdGNoZXMueCArIHBhdGNoUG9zWzBdLFxyXG4gICAgICAgICAgICAgICAgICAgIHBvczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiB4LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiB5XHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBib3g6IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmVjMi5jbG9uZShbeCwgeV0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWMyLmNsb25lKFt4ICsgX3N1YkltYWdlV3JhcHBlci5zaXplLngsIHldKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmVjMi5jbG9uZShbeCArIF9zdWJJbWFnZVdyYXBwZXIuc2l6ZS54LCB5ICsgX3N1YkltYWdlV3JhcHBlci5zaXplLnldKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmVjMi5jbG9uZShbeCwgeSArIF9zdWJJbWFnZVdyYXBwZXIuc2l6ZS55XSlcclxuICAgICAgICAgICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICAgICAgICAgIG1vbWVudHM6IG1hdGNoaW5nTW9tZW50cyxcclxuICAgICAgICAgICAgICAgICAgICByYWQ6IGF2ZyxcclxuICAgICAgICAgICAgICAgICAgICB2ZWM6IHZlYzIuY2xvbmUoW01hdGguY29zKGF2ZyksIE1hdGguc2luKGF2ZyldKVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHBhdGNoZXNGb3VuZC5wdXNoKHBhdGNoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBwYXRjaGVzRm91bmQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBmaW5kcyBwYXRjaGVzIHdoaWNoIGFyZSBjb25uZWN0ZWQgYW5kIHNoYXJlIHRoZSBzYW1lIG9yaWVudGF0aW9uXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYXRjaGVzRm91bmRcclxuICovXHJcbmZ1bmN0aW9uIHJhc3Rlcml6ZUFuZ3VsYXJTaW1pbGFyaXR5KHBhdGNoZXNGb3VuZCkge1xyXG4gICAgdmFyIGxhYmVsID0gMCxcclxuICAgICAgICB0aHJlc2hvbGQgPSAwLjk1LFxyXG4gICAgICAgIGN1cnJJZHggPSAwLFxyXG4gICAgICAgIGosXHJcbiAgICAgICAgcGF0Y2gsXHJcbiAgICAgICAgaHN2ID0gWzAsIDEsIDFdLFxyXG4gICAgICAgIHJnYiA9IFswLCAwLCAwXTtcclxuXHJcbiAgICBmdW5jdGlvbiBub3RZZXRQcm9jZXNzZWQoKSB7XHJcbiAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgZm9yICggaSA9IDA7IGkgPCBfcGF0Y2hMYWJlbEdyaWQuZGF0YS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoX3BhdGNoTGFiZWxHcmlkLmRhdGFbaV0gPT09IDAgJiYgX3BhdGNoR3JpZC5kYXRhW2ldID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gX3BhdGNoTGFiZWxHcmlkLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiB0cmFjZShjdXJyZW50SWR4KSB7XHJcbiAgICAgICAgdmFyIHgsXHJcbiAgICAgICAgICAgIHksXHJcbiAgICAgICAgICAgIGN1cnJlbnRQYXRjaCxcclxuICAgICAgICAgICAgaWR4LFxyXG4gICAgICAgICAgICBkaXIsXHJcbiAgICAgICAgICAgIGN1cnJlbnQgPSB7XHJcbiAgICAgICAgICAgICAgICB4OiBjdXJyZW50SWR4ICUgX3BhdGNoTGFiZWxHcmlkLnNpemUueCxcclxuICAgICAgICAgICAgICAgIHk6IChjdXJyZW50SWR4IC8gX3BhdGNoTGFiZWxHcmlkLnNpemUueCkgfCAwXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHNpbWlsYXJpdHk7XHJcblxyXG4gICAgICAgIGlmIChjdXJyZW50SWR4IDwgX3BhdGNoTGFiZWxHcmlkLmRhdGEubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGN1cnJlbnRQYXRjaCA9IF9pbWFnZVRvUGF0Y2hHcmlkLmRhdGFbY3VycmVudElkeF07XHJcbiAgICAgICAgICAgIC8vIGFzc2lnbiBsYWJlbFxyXG4gICAgICAgICAgICBfcGF0Y2hMYWJlbEdyaWQuZGF0YVtjdXJyZW50SWR4XSA9IGxhYmVsO1xyXG4gICAgICAgICAgICBmb3IgKCBkaXIgPSAwOyBkaXIgPCBUcmFjZXIuc2VhcmNoRGlyZWN0aW9ucy5sZW5ndGg7IGRpcisrKSB7XHJcbiAgICAgICAgICAgICAgICB5ID0gY3VycmVudC55ICsgVHJhY2VyLnNlYXJjaERpcmVjdGlvbnNbZGlyXVswXTtcclxuICAgICAgICAgICAgICAgIHggPSBjdXJyZW50LnggKyBUcmFjZXIuc2VhcmNoRGlyZWN0aW9uc1tkaXJdWzFdO1xyXG4gICAgICAgICAgICAgICAgaWR4ID0geSAqIF9wYXRjaExhYmVsR3JpZC5zaXplLnggKyB4O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIGlmIHBhdGNoIGVtcHR5XHJcbiAgICAgICAgICAgICAgICBpZiAoX3BhdGNoR3JpZC5kYXRhW2lkeF0gPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBfcGF0Y2hMYWJlbEdyaWQuZGF0YVtpZHhdID0gTnVtYmVyLk1BWF9WQUxVRTtcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoX3BhdGNoTGFiZWxHcmlkLmRhdGFbaWR4XSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNpbWlsYXJpdHkgPSBNYXRoLmFicyh2ZWMyLmRvdChfaW1hZ2VUb1BhdGNoR3JpZC5kYXRhW2lkeF0udmVjLCBjdXJyZW50UGF0Y2gudmVjKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpbWlsYXJpdHkgPiB0aHJlc2hvbGQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2UoaWR4KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcHJlcGFyZSBmb3IgZmluZGluZyB0aGUgcmlnaHQgcGF0Y2hlc1xyXG4gICAgQXJyYXlIZWxwZXIuaW5pdChfcGF0Y2hHcmlkLmRhdGEsIDApO1xyXG4gICAgQXJyYXlIZWxwZXIuaW5pdChfcGF0Y2hMYWJlbEdyaWQuZGF0YSwgMCk7XHJcbiAgICBBcnJheUhlbHBlci5pbml0KF9pbWFnZVRvUGF0Y2hHcmlkLmRhdGEsIG51bGwpO1xyXG5cclxuICAgIGZvciAoIGogPSAwOyBqIDwgcGF0Y2hlc0ZvdW5kLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgcGF0Y2ggPSBwYXRjaGVzRm91bmRbal07XHJcbiAgICAgICAgX2ltYWdlVG9QYXRjaEdyaWQuZGF0YVtwYXRjaC5pbmRleF0gPSBwYXRjaDtcclxuICAgICAgICBfcGF0Y2hHcmlkLmRhdGFbcGF0Y2guaW5kZXhdID0gMTtcclxuICAgIH1cclxuXHJcbiAgICAvLyByYXN0ZXJpemUgdGhlIHBhdGNoZXMgZm91bmQgdG8gZGV0ZXJtaW5lIGFyZWFcclxuICAgIF9wYXRjaEdyaWQuemVyb0JvcmRlcigpO1xyXG5cclxuICAgIHdoaWxlICgoIGN1cnJJZHggPSBub3RZZXRQcm9jZXNzZWQoKSkgPCBfcGF0Y2hMYWJlbEdyaWQuZGF0YS5sZW5ndGgpIHtcclxuICAgICAgICBsYWJlbCsrO1xyXG4gICAgICAgIHRyYWNlKGN1cnJJZHgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGRyYXcgcGF0Y2gtbGFiZWxzIGlmIHJlcXVlc3RlZFxyXG4gICAgaWYgKEVOVi5kZXZlbG9wbWVudCAmJiBfY29uZmlnLmRlYnVnLnNob3dQYXRjaExhYmVscykge1xyXG4gICAgICAgIGZvciAoIGogPSAwOyBqIDwgX3BhdGNoTGFiZWxHcmlkLmRhdGEubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgaWYgKF9wYXRjaExhYmVsR3JpZC5kYXRhW2pdID4gMCAmJiBfcGF0Y2hMYWJlbEdyaWQuZGF0YVtqXSA8PSBsYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgcGF0Y2ggPSBfaW1hZ2VUb1BhdGNoR3JpZC5kYXRhW2pdO1xyXG4gICAgICAgICAgICAgICAgaHN2WzBdID0gKF9wYXRjaExhYmVsR3JpZC5kYXRhW2pdIC8gKGxhYmVsICsgMSkpICogMzYwO1xyXG4gICAgICAgICAgICAgICAgaHN2MnJnYihoc3YsIHJnYik7XHJcbiAgICAgICAgICAgICAgICBJbWFnZURlYnVnLmRyYXdSZWN0KHBhdGNoLnBvcywgX3N1YkltYWdlV3JhcHBlci5zaXplLCBfY2FudmFzQ29udGFpbmVyLmN0eC5iaW5hcnksXHJcbiAgICAgICAgICAgICAgICAgICAge2NvbG9yOiBcInJnYihcIiArIHJnYi5qb2luKFwiLFwiKSArIFwiKVwiLCBsaW5lV2lkdGg6IDJ9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbGFiZWw7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIGluaXQ6IGZ1bmN0aW9uKGlucHV0SW1hZ2VXcmFwcGVyLCBjb25maWcpIHtcclxuICAgICAgICBfY29uZmlnID0gY29uZmlnO1xyXG4gICAgICAgIF9pbnB1dEltYWdlV3JhcHBlciA9IGlucHV0SW1hZ2VXcmFwcGVyO1xyXG5cclxuICAgICAgICBpbml0QnVmZmVycygpO1xyXG4gICAgICAgIGluaXRDYW52YXMoKTtcclxuICAgIH0sXHJcblxyXG4gICAgbG9jYXRlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgcGF0Y2hlc0ZvdW5kLFxyXG4gICAgICAgICAgICB0b3BMYWJlbHMsXHJcbiAgICAgICAgICAgIGJveGVzO1xyXG5cclxuICAgICAgICBpZiAoX2NvbmZpZy5oYWxmU2FtcGxlKSB7XHJcbiAgICAgICAgICAgIGhhbGZTYW1wbGUoX2lucHV0SW1hZ2VXcmFwcGVyLCBfY3VycmVudEltYWdlV3JhcHBlcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBiaW5hcml6ZUltYWdlKCk7XHJcbiAgICAgICAgcGF0Y2hlc0ZvdW5kID0gZmluZFBhdGNoZXMoKTtcclxuICAgICAgICAvLyByZXR1cm4gdW5sZXNzIDUlIG9yIG1vcmUgcGF0Y2hlcyBhcmUgZm91bmRcclxuICAgICAgICBpZiAocGF0Y2hlc0ZvdW5kLmxlbmd0aCA8IF9udW1QYXRjaGVzLnggKiBfbnVtUGF0Y2hlcy55ICogMC4wNSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHJhc3RlcnJpemUgYXJlYSBieSBjb21wYXJpbmcgYW5ndWxhciBzaW1pbGFyaXR5O1xyXG4gICAgICAgIHZhciBtYXhMYWJlbCA9IHJhc3Rlcml6ZUFuZ3VsYXJTaW1pbGFyaXR5KHBhdGNoZXNGb3VuZCk7XHJcbiAgICAgICAgaWYgKG1heExhYmVsIDwgMSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHNlYXJjaCBmb3IgYXJlYSB3aXRoIHRoZSBtb3N0IHBhdGNoZXMgKGJpZ2dlc3QgY29ubmVjdGVkIGFyZWEpXHJcbiAgICAgICAgdG9wTGFiZWxzID0gZmluZEJpZ2dlc3RDb25uZWN0ZWRBcmVhcyhtYXhMYWJlbCk7XHJcbiAgICAgICAgaWYgKHRvcExhYmVscy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBib3hlcyA9IGZpbmRCb3hlcyh0b3BMYWJlbHMsIG1heExhYmVsKTtcclxuICAgICAgICByZXR1cm4gYm94ZXM7XHJcbiAgICB9LFxyXG5cclxuICAgIGNoZWNrSW1hZ2VDb25zdHJhaW50czogZnVuY3Rpb24oaW5wdXRTdHJlYW0sIGNvbmZpZykge1xyXG4gICAgICAgIHZhciBwYXRjaFNpemUsXHJcbiAgICAgICAgICAgIHdpZHRoID0gaW5wdXRTdHJlYW0uZ2V0V2lkdGgoKSxcclxuICAgICAgICAgICAgaGVpZ2h0ID0gaW5wdXRTdHJlYW0uZ2V0SGVpZ2h0KCksXHJcbiAgICAgICAgICAgIGhhbGZTYW1wbGUgPSBjb25maWcuaGFsZlNhbXBsZSA/IDAuNSA6IDEsXHJcbiAgICAgICAgICAgIHNpemUsXHJcbiAgICAgICAgICAgIGFyZWE7XHJcblxyXG4gICAgICAgIC8vIGNhbGN1bGF0ZSB3aWR0aCBhbmQgaGVpZ2h0IGJhc2VkIG9uIGFyZWFcclxuICAgICAgICBpZiAoaW5wdXRTdHJlYW0uZ2V0Q29uZmlnKCkuYXJlYSkge1xyXG4gICAgICAgICAgICBhcmVhID0gY29tcHV0ZUltYWdlQXJlYSh3aWR0aCwgaGVpZ2h0LCBpbnB1dFN0cmVhbS5nZXRDb25maWcoKS5hcmVhKTtcclxuICAgICAgICAgICAgaW5wdXRTdHJlYW0uc2V0VG9wUmlnaHQoe3g6IGFyZWEuc3gsIHk6IGFyZWEuc3l9KTtcclxuICAgICAgICAgICAgaW5wdXRTdHJlYW0uc2V0Q2FudmFzU2l6ZSh7eDogd2lkdGgsIHk6IGhlaWdodH0pO1xyXG4gICAgICAgICAgICB3aWR0aCA9IGFyZWEuc3c7XHJcbiAgICAgICAgICAgIGhlaWdodCA9IGFyZWEuc2g7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzaXplID0ge1xyXG4gICAgICAgICAgICB4OiBNYXRoLmZsb29yKHdpZHRoICogaGFsZlNhbXBsZSksXHJcbiAgICAgICAgICAgIHk6IE1hdGguZmxvb3IoaGVpZ2h0ICogaGFsZlNhbXBsZSlcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBwYXRjaFNpemUgPSBjYWxjdWxhdGVQYXRjaFNpemUoY29uZmlnLnBhdGNoU2l6ZSwgc2l6ZSk7XHJcbiAgICAgICAgaWYgKEVOVi5kZXZlbG9wbWVudCkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIlBhdGNoLVNpemU6IFwiICsgSlNPTi5zdHJpbmdpZnkocGF0Y2hTaXplKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbnB1dFN0cmVhbS5zZXRXaWR0aChNYXRoLmZsb29yKE1hdGguZmxvb3Ioc2l6ZS54IC8gcGF0Y2hTaXplLngpICogKDEgLyBoYWxmU2FtcGxlKSAqIHBhdGNoU2l6ZS54KSk7XHJcbiAgICAgICAgaW5wdXRTdHJlYW0uc2V0SGVpZ2h0KE1hdGguZmxvb3IoTWF0aC5mbG9vcihzaXplLnkgLyBwYXRjaFNpemUueSkgKiAoMSAvIGhhbGZTYW1wbGUpICogcGF0Y2hTaXplLnkpKTtcclxuXHJcbiAgICAgICAgaWYgKChpbnB1dFN0cmVhbS5nZXRXaWR0aCgpICUgcGF0Y2hTaXplLngpID09PSAwICYmIChpbnB1dFN0cmVhbS5nZXRIZWlnaHQoKSAlIHBhdGNoU2l6ZS55KSA9PT0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkltYWdlIGRpbWVuc2lvbnMgZG8gbm90IGNvbXBseSB3aXRoIHRoZSBjdXJyZW50IHNldHRpbmdzOiBXaWR0aCAoXCIgK1xyXG4gICAgICAgICAgICB3aWR0aCArIFwiIClhbmQgaGVpZ2h0IChcIiArIGhlaWdodCArXHJcbiAgICAgICAgICAgIFwiKSBtdXN0IGEgbXVsdGlwbGUgb2YgXCIgKyBwYXRjaFNpemUueCk7XHJcbiAgICB9XHJcbn07XHJcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2xvY2F0b3IvYmFyY29kZV9sb2NhdG9yLmpzXG4gKiovIiwiaW1wb3J0IFRyYWNlciBmcm9tICcuL3RyYWNlcic7XHJcblxyXG4vKipcclxuICogaHR0cDovL3d3dy5jb2RlcHJvamVjdC5jb20vVGlwcy80MDcxNzIvQ29ubmVjdGVkLUNvbXBvbmVudC1MYWJlbGluZy1hbmQtVmVjdG9yaXphdGlvblxyXG4gKi9cclxudmFyIFJhc3Rlcml6ZXIgPSB7XHJcbiAgICBjcmVhdGVDb250b3VyMkQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGRpcjogbnVsbCxcclxuICAgICAgICAgICAgaW5kZXg6IG51bGwsXHJcbiAgICAgICAgICAgIGZpcnN0VmVydGV4OiBudWxsLFxyXG4gICAgICAgICAgICBpbnNpZGVDb250b3VyczogbnVsbCxcclxuICAgICAgICAgICAgbmV4dHBlZXI6IG51bGwsXHJcbiAgICAgICAgICAgIHByZXZwZWVyOiBudWxsXHJcbiAgICAgICAgfTtcclxuICAgIH0sXHJcbiAgICBDT05UT1VSX0RJUjoge1xyXG4gICAgICAgIENXX0RJUjogMCxcclxuICAgICAgICBDQ1dfRElSOiAxLFxyXG4gICAgICAgIFVOS05PV05fRElSOiAyXHJcbiAgICB9LFxyXG4gICAgRElSOiB7XHJcbiAgICAgICAgT1VUU0lERV9FREdFOiAtMzI3NjcsXHJcbiAgICAgICAgSU5TSURFX0VER0U6IC0zMjc2NlxyXG4gICAgfSxcclxuICAgIGNyZWF0ZTogZnVuY3Rpb24oaW1hZ2VXcmFwcGVyLCBsYWJlbFdyYXBwZXIpIHtcclxuICAgICAgICB2YXIgaW1hZ2VEYXRhID0gaW1hZ2VXcmFwcGVyLmRhdGEsXHJcbiAgICAgICAgICAgIGxhYmVsRGF0YSA9IGxhYmVsV3JhcHBlci5kYXRhLFxyXG4gICAgICAgICAgICB3aWR0aCA9IGltYWdlV3JhcHBlci5zaXplLngsXHJcbiAgICAgICAgICAgIGhlaWdodCA9IGltYWdlV3JhcHBlci5zaXplLnksXHJcbiAgICAgICAgICAgIHRyYWNlciA9IFRyYWNlci5jcmVhdGUoaW1hZ2VXcmFwcGVyLCBsYWJlbFdyYXBwZXIpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICByYXN0ZXJpemU6IGZ1bmN0aW9uKGRlcHRobGFiZWwpIHtcclxuICAgICAgICAgICAgICAgIHZhciBjb2xvcixcclxuICAgICAgICAgICAgICAgICAgICBiYyxcclxuICAgICAgICAgICAgICAgICAgICBsYyxcclxuICAgICAgICAgICAgICAgICAgICBsYWJlbGluZGV4LFxyXG4gICAgICAgICAgICAgICAgICAgIGN4LFxyXG4gICAgICAgICAgICAgICAgICAgIGN5LFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yTWFwID0gW10sXHJcbiAgICAgICAgICAgICAgICAgICAgdmVydGV4LFxyXG4gICAgICAgICAgICAgICAgICAgIHAsXHJcbiAgICAgICAgICAgICAgICAgICAgY2MsXHJcbiAgICAgICAgICAgICAgICAgICAgc2MsXHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3RlZENvdW50ID0gMCxcclxuICAgICAgICAgICAgICAgICAgICBpO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgNDAwOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjb2xvck1hcFtpXSA9IDA7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29sb3JNYXBbMF0gPSBpbWFnZURhdGFbMF07XHJcbiAgICAgICAgICAgICAgICBjYyA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBmb3IgKCBjeSA9IDE7IGN5IDwgaGVpZ2h0IC0gMTsgY3krKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsaW5kZXggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGJjID0gY29sb3JNYXBbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICggY3ggPSAxOyBjeCA8IHdpZHRoIC0gMTsgY3grKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MgPSBjeSAqIHdpZHRoICsgY3g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYWJlbERhdGFbcG9zXSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBpbWFnZURhdGFbcG9zXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xvciAhPT0gYmMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGFiZWxpbmRleCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYyA9IGNvbm5lY3RlZENvdW50ICsgMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JNYXBbbGNdID0gY29sb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJjID0gY29sb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRleCA9IHRyYWNlci5jb250b3VyVHJhY2luZyhjeSwgY3gsIGxjLCBjb2xvciwgUmFzdGVyaXplci5ESVIuT1VUU0lERV9FREdFKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZlcnRleCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGVkQ291bnQrKztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsaW5kZXggPSBsYztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAgPSBSYXN0ZXJpemVyLmNyZWF0ZUNvbnRvdXIyRCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcC5kaXIgPSBSYXN0ZXJpemVyLkNPTlRPVVJfRElSLkNXX0RJUjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuaW5kZXggPSBsYWJlbGluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcC5maXJzdFZlcnRleCA9IHZlcnRleDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAubmV4dHBlZXIgPSBjYztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuaW5zaWRlQ29udG91cnMgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNjICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2MucHJldnBlZXIgPSBwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2MgPSBwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVydGV4ID0gdHJhY2VyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29udG91clRyYWNpbmcoY3ksIGN4LCBSYXN0ZXJpemVyLkRJUi5JTlNJREVfRURHRSwgY29sb3IsIGxhYmVsaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmVydGV4ICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwID0gUmFzdGVyaXplci5jcmVhdGVDb250b3VyMkQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuZmlyc3RWZXJ0ZXggPSB2ZXJ0ZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmluc2lkZUNvbnRvdXJzID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXB0aGxhYmVsID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcC5kaXIgPSBSYXN0ZXJpemVyLkNPTlRPVVJfRElSLkNDV19ESVI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuZGlyID0gUmFzdGVyaXplci5DT05UT1VSX0RJUi5DV19ESVI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmluZGV4ID0gZGVwdGhsYWJlbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjID0gY2M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKHNjICE9PSBudWxsKSAmJiBzYy5pbmRleCAhPT0gbGFiZWxpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjID0gc2MubmV4dHBlZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2MgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLm5leHRwZWVyID0gc2MuaW5zaWRlQ29udG91cnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjLmluc2lkZUNvbnRvdXJzICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjLmluc2lkZUNvbnRvdXJzLnByZXZwZWVyID0gcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2MuaW5zaWRlQ29udG91cnMgPSBwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbERhdGFbcG9zXSA9IGxhYmVsaW5kZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobGFiZWxEYXRhW3Bvc10gPT09IFJhc3Rlcml6ZXIuRElSLk9VVFNJREVfRURHRVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGxhYmVsRGF0YVtwb3NdID09PSBSYXN0ZXJpemVyLkRJUi5JTlNJREVfRURHRSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxpbmRleCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGFiZWxEYXRhW3Bvc10gPT09IFJhc3Rlcml6ZXIuRElSLklOU0lERV9FREdFKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmMgPSBpbWFnZURhdGFbcG9zXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmMgPSBjb2xvck1hcFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsaW5kZXggPSBsYWJlbERhdGFbcG9zXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJjID0gY29sb3JNYXBbbGFiZWxpbmRleF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBzYyA9IGNjO1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKHNjICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2MuaW5kZXggPSBkZXB0aGxhYmVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHNjID0gc2MubmV4dHBlZXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNjOiBjYyxcclxuICAgICAgICAgICAgICAgICAgICBjb3VudDogY29ubmVjdGVkQ291bnRcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGRlYnVnOiB7XHJcbiAgICAgICAgICAgICAgICBkcmF3Q29udG91cjogZnVuY3Rpb24oY2FudmFzLCBmaXJzdENvbnRvdXIpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHEgPSBmaXJzdENvbnRvdXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlxLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBxLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBcInJlZFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBcInJlZFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGN0eC5saW5lV2lkdGggPSAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocHEgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXEgPSBwcS5pbnNpZGVDb250b3VycztcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpcSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAocHEgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlxICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxID0gaXE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcSA9IGlxLm5leHRwZWVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcSA9IHBxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHEgPSBwcS5uZXh0cGVlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlxID0gcHEuaW5zaWRlQ29udG91cnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlxID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChxLmRpcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFJhc3Rlcml6ZXIuQ09OVE9VUl9ESVIuQ1dfRElSOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gXCJyZWRcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFJhc3Rlcml6ZXIuQ09OVE9VUl9ESVIuQ0NXX0RJUjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IFwiYmx1ZVwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUmFzdGVyaXplci5DT05UT1VSX0RJUi5VTktOT1dOX0RJUjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IFwiZ3JlZW5cIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwID0gcS5maXJzdFZlcnRleDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjdHgubW92ZVRvKHAueCwgcC55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcCA9IHAubmV4dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5saW5lVG8ocC54LCBwLnkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IHdoaWxlIChwICE9PSBxLmZpcnN0VmVydGV4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBSYXN0ZXJpemVyO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9sb2NhdG9yL3Jhc3Rlcml6ZXIuanNcbiAqKi8iLCIvKiBAcHJlc2VydmUgQVNNIEJFR0lOICovXHJcbi8qIGVzbGludC1kaXNhYmxlIGVxZXFlcSovXHJcbmZ1bmN0aW9uIFNrZWxldG9uaXplcihzdGRsaWIsIGZvcmVpZ24sIGJ1ZmZlcikge1xyXG4gICAgXCJ1c2UgYXNtXCI7XHJcblxyXG4gICAgdmFyIGltYWdlcyA9IG5ldyBzdGRsaWIuVWludDhBcnJheShidWZmZXIpLFxyXG4gICAgICAgIHNpemUgPSBmb3JlaWduLnNpemUgfCAwLFxyXG4gICAgICAgIGltdWwgPSBzdGRsaWIuTWF0aC5pbXVsO1xyXG5cclxuICAgIGZ1bmN0aW9uIGVyb2RlKGluSW1hZ2VQdHIsIG91dEltYWdlUHRyKSB7XHJcbiAgICAgICAgaW5JbWFnZVB0ciA9IGluSW1hZ2VQdHIgfCAwO1xyXG4gICAgICAgIG91dEltYWdlUHRyID0gb3V0SW1hZ2VQdHIgfCAwO1xyXG5cclxuICAgICAgICB2YXIgdiA9IDAsXHJcbiAgICAgICAgICAgIHUgPSAwLFxyXG4gICAgICAgICAgICBzdW0gPSAwLFxyXG4gICAgICAgICAgICB5U3RhcnQxID0gMCxcclxuICAgICAgICAgICAgeVN0YXJ0MiA9IDAsXHJcbiAgICAgICAgICAgIHhTdGFydDEgPSAwLFxyXG4gICAgICAgICAgICB4U3RhcnQyID0gMCxcclxuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuXHJcbiAgICAgICAgZm9yICggdiA9IDE7ICh2IHwgMCkgPCAoKHNpemUgLSAxKSB8IDApOyB2ID0gKHYgKyAxKSB8IDApIHtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gKG9mZnNldCArIHNpemUpIHwgMDtcclxuICAgICAgICAgICAgZm9yICggdSA9IDE7ICh1IHwgMCkgPCAoKHNpemUgLSAxKSB8IDApOyB1ID0gKHUgKyAxKSB8IDApIHtcclxuICAgICAgICAgICAgICAgIHlTdGFydDEgPSAob2Zmc2V0IC0gc2l6ZSkgfCAwO1xyXG4gICAgICAgICAgICAgICAgeVN0YXJ0MiA9IChvZmZzZXQgKyBzaXplKSB8IDA7XHJcbiAgICAgICAgICAgICAgICB4U3RhcnQxID0gKHUgLSAxKSB8IDA7XHJcbiAgICAgICAgICAgICAgICB4U3RhcnQyID0gKHUgKyAxKSB8IDA7XHJcbiAgICAgICAgICAgICAgICBzdW0gPSAoKGltYWdlc1soaW5JbWFnZVB0ciArIHlTdGFydDEgKyB4U3RhcnQxKSB8IDBdIHwgMClcclxuICAgICAgICAgICAgICAgICAgICArIChpbWFnZXNbKGluSW1hZ2VQdHIgKyB5U3RhcnQxICsgeFN0YXJ0MikgfCAwXSB8IDApXHJcbiAgICAgICAgICAgICAgICAgICAgKyAoaW1hZ2VzWyhpbkltYWdlUHRyICsgb2Zmc2V0ICsgdSkgfCAwXSB8IDApXHJcbiAgICAgICAgICAgICAgICAgICAgKyAoaW1hZ2VzWyhpbkltYWdlUHRyICsgeVN0YXJ0MiArIHhTdGFydDEpIHwgMF0gfCAwKVxyXG4gICAgICAgICAgICAgICAgICAgICsgKGltYWdlc1soaW5JbWFnZVB0ciArIHlTdGFydDIgKyB4U3RhcnQyKSB8IDBdIHwgMCkpIHwgMDtcclxuICAgICAgICAgICAgICAgIGlmICgoc3VtIHwgMCkgPT0gKDUgfCAwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGltYWdlc1sob3V0SW1hZ2VQdHIgKyBvZmZzZXQgKyB1KSB8IDBdID0gMTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW1hZ2VzWyhvdXRJbWFnZVB0ciArIG9mZnNldCArIHUpIHwgMF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBzdWJ0cmFjdChhSW1hZ2VQdHIsIGJJbWFnZVB0ciwgb3V0SW1hZ2VQdHIpIHtcclxuICAgICAgICBhSW1hZ2VQdHIgPSBhSW1hZ2VQdHIgfCAwO1xyXG4gICAgICAgIGJJbWFnZVB0ciA9IGJJbWFnZVB0ciB8IDA7XHJcbiAgICAgICAgb3V0SW1hZ2VQdHIgPSBvdXRJbWFnZVB0ciB8IDA7XHJcblxyXG4gICAgICAgIHZhciBsZW5ndGggPSAwO1xyXG5cclxuICAgICAgICBsZW5ndGggPSBpbXVsKHNpemUsIHNpemUpIHwgMDtcclxuXHJcbiAgICAgICAgd2hpbGUgKChsZW5ndGggfCAwKSA+IDApIHtcclxuICAgICAgICAgICAgbGVuZ3RoID0gKGxlbmd0aCAtIDEpIHwgMDtcclxuICAgICAgICAgICAgaW1hZ2VzWyhvdXRJbWFnZVB0ciArIGxlbmd0aCkgfCAwXSA9XHJcbiAgICAgICAgICAgICAgICAoKGltYWdlc1soYUltYWdlUHRyICsgbGVuZ3RoKSB8IDBdIHwgMCkgLSAoaW1hZ2VzWyhiSW1hZ2VQdHIgKyBsZW5ndGgpIHwgMF0gfCAwKSkgfCAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBiaXR3aXNlT3IoYUltYWdlUHRyLCBiSW1hZ2VQdHIsIG91dEltYWdlUHRyKSB7XHJcbiAgICAgICAgYUltYWdlUHRyID0gYUltYWdlUHRyIHwgMDtcclxuICAgICAgICBiSW1hZ2VQdHIgPSBiSW1hZ2VQdHIgfCAwO1xyXG4gICAgICAgIG91dEltYWdlUHRyID0gb3V0SW1hZ2VQdHIgfCAwO1xyXG5cclxuICAgICAgICB2YXIgbGVuZ3RoID0gMDtcclxuXHJcbiAgICAgICAgbGVuZ3RoID0gaW11bChzaXplLCBzaXplKSB8IDA7XHJcblxyXG4gICAgICAgIHdoaWxlICgobGVuZ3RoIHwgMCkgPiAwKSB7XHJcbiAgICAgICAgICAgIGxlbmd0aCA9IChsZW5ndGggLSAxKSB8IDA7XHJcbiAgICAgICAgICAgIGltYWdlc1sob3V0SW1hZ2VQdHIgKyBsZW5ndGgpIHwgMF0gPVxyXG4gICAgICAgICAgICAgICAgKChpbWFnZXNbKGFJbWFnZVB0ciArIGxlbmd0aCkgfCAwXSB8IDApIHwgKGltYWdlc1soYkltYWdlUHRyICsgbGVuZ3RoKSB8IDBdIHwgMCkpIHwgMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gY291bnROb25aZXJvKGltYWdlUHRyKSB7XHJcbiAgICAgICAgaW1hZ2VQdHIgPSBpbWFnZVB0ciB8IDA7XHJcblxyXG4gICAgICAgIHZhciBzdW0gPSAwLFxyXG4gICAgICAgICAgICBsZW5ndGggPSAwO1xyXG5cclxuICAgICAgICBsZW5ndGggPSBpbXVsKHNpemUsIHNpemUpIHwgMDtcclxuXHJcbiAgICAgICAgd2hpbGUgKChsZW5ndGggfCAwKSA+IDApIHtcclxuICAgICAgICAgICAgbGVuZ3RoID0gKGxlbmd0aCAtIDEpIHwgMDtcclxuICAgICAgICAgICAgc3VtID0gKChzdW0gfCAwKSArIChpbWFnZXNbKGltYWdlUHRyICsgbGVuZ3RoKSB8IDBdIHwgMCkpIHwgMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiAoc3VtIHwgMCk7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gaW5pdChpbWFnZVB0ciwgdmFsdWUpIHtcclxuICAgICAgICBpbWFnZVB0ciA9IGltYWdlUHRyIHwgMDtcclxuICAgICAgICB2YWx1ZSA9IHZhbHVlIHwgMDtcclxuXHJcbiAgICAgICAgdmFyIGxlbmd0aCA9IDA7XHJcblxyXG4gICAgICAgIGxlbmd0aCA9IGltdWwoc2l6ZSwgc2l6ZSkgfCAwO1xyXG5cclxuICAgICAgICB3aGlsZSAoKGxlbmd0aCB8IDApID4gMCkge1xyXG4gICAgICAgICAgICBsZW5ndGggPSAobGVuZ3RoIC0gMSkgfCAwO1xyXG4gICAgICAgICAgICBpbWFnZXNbKGltYWdlUHRyICsgbGVuZ3RoKSB8IDBdID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGRpbGF0ZShpbkltYWdlUHRyLCBvdXRJbWFnZVB0cikge1xyXG4gICAgICAgIGluSW1hZ2VQdHIgPSBpbkltYWdlUHRyIHwgMDtcclxuICAgICAgICBvdXRJbWFnZVB0ciA9IG91dEltYWdlUHRyIHwgMDtcclxuXHJcbiAgICAgICAgdmFyIHYgPSAwLFxyXG4gICAgICAgICAgICB1ID0gMCxcclxuICAgICAgICAgICAgc3VtID0gMCxcclxuICAgICAgICAgICAgeVN0YXJ0MSA9IDAsXHJcbiAgICAgICAgICAgIHlTdGFydDIgPSAwLFxyXG4gICAgICAgICAgICB4U3RhcnQxID0gMCxcclxuICAgICAgICAgICAgeFN0YXJ0MiA9IDAsXHJcbiAgICAgICAgICAgIG9mZnNldCA9IDA7XHJcblxyXG4gICAgICAgIGZvciAoIHYgPSAxOyAodiB8IDApIDwgKChzaXplIC0gMSkgfCAwKTsgdiA9ICh2ICsgMSkgfCAwKSB7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IChvZmZzZXQgKyBzaXplKSB8IDA7XHJcbiAgICAgICAgICAgIGZvciAoIHUgPSAxOyAodSB8IDApIDwgKChzaXplIC0gMSkgfCAwKTsgdSA9ICh1ICsgMSkgfCAwKSB7XHJcbiAgICAgICAgICAgICAgICB5U3RhcnQxID0gKG9mZnNldCAtIHNpemUpIHwgMDtcclxuICAgICAgICAgICAgICAgIHlTdGFydDIgPSAob2Zmc2V0ICsgc2l6ZSkgfCAwO1xyXG4gICAgICAgICAgICAgICAgeFN0YXJ0MSA9ICh1IC0gMSkgfCAwO1xyXG4gICAgICAgICAgICAgICAgeFN0YXJ0MiA9ICh1ICsgMSkgfCAwO1xyXG4gICAgICAgICAgICAgICAgc3VtID0gKChpbWFnZXNbKGluSW1hZ2VQdHIgKyB5U3RhcnQxICsgeFN0YXJ0MSkgfCAwXSB8IDApXHJcbiAgICAgICAgICAgICAgICAgICAgKyAoaW1hZ2VzWyhpbkltYWdlUHRyICsgeVN0YXJ0MSArIHhTdGFydDIpIHwgMF0gfCAwKVxyXG4gICAgICAgICAgICAgICAgICAgICsgKGltYWdlc1soaW5JbWFnZVB0ciArIG9mZnNldCArIHUpIHwgMF0gfCAwKVxyXG4gICAgICAgICAgICAgICAgICAgICsgKGltYWdlc1soaW5JbWFnZVB0ciArIHlTdGFydDIgKyB4U3RhcnQxKSB8IDBdIHwgMClcclxuICAgICAgICAgICAgICAgICAgICArIChpbWFnZXNbKGluSW1hZ2VQdHIgKyB5U3RhcnQyICsgeFN0YXJ0MikgfCAwXSB8IDApKSB8IDA7XHJcbiAgICAgICAgICAgICAgICBpZiAoKHN1bSB8IDApID4gKDAgfCAwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGltYWdlc1sob3V0SW1hZ2VQdHIgKyBvZmZzZXQgKyB1KSB8IDBdID0gMTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW1hZ2VzWyhvdXRJbWFnZVB0ciArIG9mZnNldCArIHUpIHwgMF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBtZW1jcHkoc3JjSW1hZ2VQdHIsIGRzdEltYWdlUHRyKSB7XHJcbiAgICAgICAgc3JjSW1hZ2VQdHIgPSBzcmNJbWFnZVB0ciB8IDA7XHJcbiAgICAgICAgZHN0SW1hZ2VQdHIgPSBkc3RJbWFnZVB0ciB8IDA7XHJcblxyXG4gICAgICAgIHZhciBsZW5ndGggPSAwO1xyXG5cclxuICAgICAgICBsZW5ndGggPSBpbXVsKHNpemUsIHNpemUpIHwgMDtcclxuXHJcbiAgICAgICAgd2hpbGUgKChsZW5ndGggfCAwKSA+IDApIHtcclxuICAgICAgICAgICAgbGVuZ3RoID0gKGxlbmd0aCAtIDEpIHwgMDtcclxuICAgICAgICAgICAgaW1hZ2VzWyhkc3RJbWFnZVB0ciArIGxlbmd0aCkgfCAwXSA9IChpbWFnZXNbKHNyY0ltYWdlUHRyICsgbGVuZ3RoKSB8IDBdIHwgMCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHplcm9Cb3JkZXIoaW1hZ2VQdHIpIHtcclxuICAgICAgICBpbWFnZVB0ciA9IGltYWdlUHRyIHwgMDtcclxuXHJcbiAgICAgICAgdmFyIHggPSAwLFxyXG4gICAgICAgICAgICB5ID0gMDtcclxuXHJcbiAgICAgICAgZm9yICggeCA9IDA7ICh4IHwgMCkgPCAoKHNpemUgLSAxKSB8IDApOyB4ID0gKHggKyAxKSB8IDApIHtcclxuICAgICAgICAgICAgaW1hZ2VzWyhpbWFnZVB0ciArIHgpIHwgMF0gPSAwO1xyXG4gICAgICAgICAgICBpbWFnZXNbKGltYWdlUHRyICsgeSkgfCAwXSA9IDA7XHJcbiAgICAgICAgICAgIHkgPSAoKHkgKyBzaXplKSAtIDEpIHwgMDtcclxuICAgICAgICAgICAgaW1hZ2VzWyhpbWFnZVB0ciArIHkpIHwgMF0gPSAwO1xyXG4gICAgICAgICAgICB5ID0gKHkgKyAxKSB8IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoIHggPSAwOyAoeCB8IDApIDwgKHNpemUgfCAwKTsgeCA9ICh4ICsgMSkgfCAwKSB7XHJcbiAgICAgICAgICAgIGltYWdlc1soaW1hZ2VQdHIgKyB5KSB8IDBdID0gMDtcclxuICAgICAgICAgICAgeSA9ICh5ICsgMSkgfCAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBza2VsZXRvbml6ZSgpIHtcclxuICAgICAgICB2YXIgc3ViSW1hZ2VQdHIgPSAwLFxyXG4gICAgICAgICAgICBlcm9kZWRJbWFnZVB0ciA9IDAsXHJcbiAgICAgICAgICAgIHRlbXBJbWFnZVB0ciA9IDAsXHJcbiAgICAgICAgICAgIHNrZWxJbWFnZVB0ciA9IDAsXHJcbiAgICAgICAgICAgIHN1bSA9IDAsXHJcbiAgICAgICAgICAgIGRvbmUgPSAwO1xyXG5cclxuICAgICAgICBlcm9kZWRJbWFnZVB0ciA9IGltdWwoc2l6ZSwgc2l6ZSkgfCAwO1xyXG4gICAgICAgIHRlbXBJbWFnZVB0ciA9IChlcm9kZWRJbWFnZVB0ciArIGVyb2RlZEltYWdlUHRyKSB8IDA7XHJcbiAgICAgICAgc2tlbEltYWdlUHRyID0gKHRlbXBJbWFnZVB0ciArIGVyb2RlZEltYWdlUHRyKSB8IDA7XHJcblxyXG4gICAgICAgIC8vIGluaXQgc2tlbC1pbWFnZVxyXG4gICAgICAgIGluaXQoc2tlbEltYWdlUHRyLCAwKTtcclxuICAgICAgICB6ZXJvQm9yZGVyKHN1YkltYWdlUHRyKTtcclxuXHJcbiAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICBlcm9kZShzdWJJbWFnZVB0ciwgZXJvZGVkSW1hZ2VQdHIpO1xyXG4gICAgICAgICAgICBkaWxhdGUoZXJvZGVkSW1hZ2VQdHIsIHRlbXBJbWFnZVB0cik7XHJcbiAgICAgICAgICAgIHN1YnRyYWN0KHN1YkltYWdlUHRyLCB0ZW1wSW1hZ2VQdHIsIHRlbXBJbWFnZVB0cik7XHJcbiAgICAgICAgICAgIGJpdHdpc2VPcihza2VsSW1hZ2VQdHIsIHRlbXBJbWFnZVB0ciwgc2tlbEltYWdlUHRyKTtcclxuICAgICAgICAgICAgbWVtY3B5KGVyb2RlZEltYWdlUHRyLCBzdWJJbWFnZVB0cik7XHJcbiAgICAgICAgICAgIHN1bSA9IGNvdW50Tm9uWmVybyhzdWJJbWFnZVB0cikgfCAwO1xyXG4gICAgICAgICAgICBkb25lID0gKChzdW0gfCAwKSA9PSAwIHwgMCk7XHJcbiAgICAgICAgfSB3aGlsZSAoIWRvbmUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBza2VsZXRvbml6ZTogc2tlbGV0b25pemVcclxuICAgIH07XHJcbn1cclxuLyogQHByZXNlcnZlIEFTTSBFTkQgKi9cclxuZXhwb3J0IGRlZmF1bHQgU2tlbGV0b25pemVyO1xyXG4vKiBlc2xpbnQtZW5hYmxlIGVxZXFlcSovXHJcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL2xvY2F0b3Ivc2tlbGV0b25pemVyLmpzXG4gKiovIiwiaW1wb3J0IEJhcmNvZGVSZWFkZXIgZnJvbSAnLi9iYXJjb2RlX3JlYWRlcic7XHJcblxyXG5mdW5jdGlvbiBDb2RhYmFyUmVhZGVyKCkge1xyXG4gICAgQmFyY29kZVJlYWRlci5jYWxsKHRoaXMpO1xyXG4gICAgdGhpcy5fY291bnRlcnMgPSBbXTtcclxufVxyXG5cclxudmFyIHByb3BlcnRpZXMgPSB7XHJcbiAgICBBTFBIQUJFVEhfU1RSSU5HOiB7dmFsdWU6IFwiMDEyMzQ1Njc4OS0kOi8uK0FCQ0RcIn0sXHJcbiAgICBBTFBIQUJFVDoge3ZhbHVlOiBbNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDQ1LCAzNiwgNTgsIDQ3LCA0NiwgNDMsIDY1LCA2NiwgNjcsIDY4XX0sXHJcbiAgICBDSEFSQUNURVJfRU5DT0RJTkdTOiB7dmFsdWU6IFsweDAwMywgMHgwMDYsIDB4MDA5LCAweDA2MCwgMHgwMTIsIDB4MDQyLCAweDAyMSwgMHgwMjQsIDB4MDMwLCAweDA0OCwgMHgwMGMsIDB4MDE4LFxyXG4gICAgICAgIDB4MDQ1LCAweDA1MSwgMHgwNTQsIDB4MDE1LCAweDAxQSwgMHgwMjksIDB4MDBCLCAweDAwRV19LFxyXG4gICAgU1RBUlRfRU5EOiB7dmFsdWU6IFsweDAxQSwgMHgwMjksIDB4MDBCLCAweDAwRV19LFxyXG4gICAgTUlOX0VOQ09ERURfQ0hBUlM6IHt2YWx1ZTogNH0sXHJcbiAgICBNQVhfQUNDRVBUQUJMRToge3ZhbHVlOiAyLjB9LFxyXG4gICAgUEFERElORzoge3ZhbHVlOiAxLjV9LFxyXG4gICAgRk9STUFUOiB7dmFsdWU6IFwiY29kYWJhclwiLCB3cml0ZWFibGU6IGZhbHNlfVxyXG59O1xyXG5cclxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhcmNvZGVSZWFkZXIucHJvdG90eXBlLCBwcm9wZXJ0aWVzKTtcclxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDb2RhYmFyUmVhZGVyO1xyXG5cclxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIHJlc3VsdCA9IFtdLFxyXG4gICAgICAgIHN0YXJ0LFxyXG4gICAgICAgIGRlY29kZWRDaGFyLFxyXG4gICAgICAgIHBhdHRlcm4sXHJcbiAgICAgICAgbmV4dFN0YXJ0LFxyXG4gICAgICAgIGVuZDtcclxuXHJcbiAgICB0aGlzLl9jb3VudGVycyA9IHNlbGYuX2ZpbGxDb3VudGVycygpO1xyXG4gICAgc3RhcnQgPSBzZWxmLl9maW5kU3RhcnQoKTtcclxuICAgIGlmICghc3RhcnQpIHtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIG5leHRTdGFydCA9IHN0YXJ0LnN0YXJ0Q291bnRlcjtcclxuXHJcbiAgICBkbyB7XHJcbiAgICAgICAgcGF0dGVybiA9IHNlbGYuX3RvUGF0dGVybihuZXh0U3RhcnQpO1xyXG4gICAgICAgIGlmIChwYXR0ZXJuIDwgMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZGVjb2RlZENoYXIgPSBzZWxmLl9wYXR0ZXJuVG9DaGFyKHBhdHRlcm4pO1xyXG4gICAgICAgIGlmIChkZWNvZGVkQ2hhciA8IDApe1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVzdWx0LnB1c2goZGVjb2RlZENoYXIpO1xyXG4gICAgICAgIG5leHRTdGFydCArPSA4O1xyXG4gICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID4gMSAmJiBzZWxmLl9pc1N0YXJ0RW5kKHBhdHRlcm4pKSB7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH0gd2hpbGUgKG5leHRTdGFydCA8IHNlbGYuX2NvdW50ZXJzLmxlbmd0aCk7XHJcblxyXG4gICAgLy8gdmVyaWZ5IGVuZFxyXG4gICAgaWYgKChyZXN1bHQubGVuZ3RoIC0gMikgPCBzZWxmLk1JTl9FTkNPREVEX0NIQVJTIHx8ICFzZWxmLl9pc1N0YXJ0RW5kKHBhdHRlcm4pKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gdmVyaWZ5IGVuZCB3aGl0ZSBzcGFjZVxyXG4gICAgaWYgKCFzZWxmLl92ZXJpZnlXaGl0ZXNwYWNlKHN0YXJ0LnN0YXJ0Q291bnRlciwgbmV4dFN0YXJ0IC0gOCkpe1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghc2VsZi5fdmFsaWRhdGVSZXN1bHQocmVzdWx0LCBzdGFydC5zdGFydENvdW50ZXIpKXtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBuZXh0U3RhcnQgPSBuZXh0U3RhcnQgPiBzZWxmLl9jb3VudGVycy5sZW5ndGggPyBzZWxmLl9jb3VudGVycy5sZW5ndGggOiBuZXh0U3RhcnQ7XHJcbiAgICBlbmQgPSBzdGFydC5zdGFydCArIHNlbGYuX3N1bUNvdW50ZXJzKHN0YXJ0LnN0YXJ0Q291bnRlciwgbmV4dFN0YXJ0IC0gOCk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBjb2RlOiByZXN1bHQuam9pbihcIlwiKSxcclxuICAgICAgICBzdGFydDogc3RhcnQuc3RhcnQsXHJcbiAgICAgICAgZW5kOiBlbmQsXHJcbiAgICAgICAgc3RhcnRJbmZvOiBzdGFydCxcclxuICAgICAgICBkZWNvZGVkQ29kZXM6IHJlc3VsdFxyXG4gICAgfTtcclxufTtcclxuXHJcbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl92ZXJpZnlXaGl0ZXNwYWNlID0gZnVuY3Rpb24oc3RhcnRDb3VudGVyLCBlbmRDb3VudGVyKSB7XHJcbiAgICBpZiAoKHN0YXJ0Q291bnRlciAtIDEgPD0gMClcclxuICAgICAgICAgICAgfHwgdGhpcy5fY291bnRlcnNbc3RhcnRDb3VudGVyIC0gMV0gPj0gKHRoaXMuX2NhbGN1bGF0ZVBhdHRlcm5MZW5ndGgoc3RhcnRDb3VudGVyKSAvIDIuMCkpIHtcclxuICAgICAgICBpZiAoKGVuZENvdW50ZXIgKyA4ID49IHRoaXMuX2NvdW50ZXJzLmxlbmd0aClcclxuICAgICAgICAgICAgICAgIHx8IHRoaXMuX2NvdW50ZXJzW2VuZENvdW50ZXIgKyA3XSA+PSAodGhpcy5fY2FsY3VsYXRlUGF0dGVybkxlbmd0aChlbmRDb3VudGVyKSAvIDIuMCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX2NhbGN1bGF0ZVBhdHRlcm5MZW5ndGggPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgIHZhciBpLFxyXG4gICAgICAgIHN1bSA9IDA7XHJcblxyXG4gICAgZm9yIChpID0gb2Zmc2V0OyBpIDwgb2Zmc2V0ICsgNzsgaSsrKSB7XHJcbiAgICAgICAgc3VtICs9IHRoaXMuX2NvdW50ZXJzW2ldO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzdW07XHJcbn07XHJcblxyXG5Db2RhYmFyUmVhZGVyLnByb3RvdHlwZS5fdGhyZXNob2xkUmVzdWx0UGF0dGVybiA9IGZ1bmN0aW9uKHJlc3VsdCwgc3RhcnRDb3VudGVyKXtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBjYXRlZ29yaXphdGlvbiA9IHtcclxuICAgICAgICAgICAgc3BhY2U6IHtcclxuICAgICAgICAgICAgICAgIG5hcnJvdzogeyBzaXplOiAwLCBjb3VudHM6IDAsIG1pbjogMCwgbWF4OiBOdW1iZXIuTUFYX1ZBTFVFfSxcclxuICAgICAgICAgICAgICAgIHdpZGU6IHtzaXplOiAwLCBjb3VudHM6IDAsIG1pbjogMCwgbWF4OiBOdW1iZXIuTUFYX1ZBTFVFfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBiYXI6IHtcclxuICAgICAgICAgICAgICAgIG5hcnJvdzogeyBzaXplOiAwLCBjb3VudHM6IDAsIG1pbjogMCwgbWF4OiBOdW1iZXIuTUFYX1ZBTFVFfSxcclxuICAgICAgICAgICAgICAgIHdpZGU6IHsgc2l6ZTogMCwgY291bnRzOiAwLCBtaW46IDAsIG1heDogTnVtYmVyLk1BWF9WQUxVRX1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAga2luZCxcclxuICAgICAgICBjYXQsXHJcbiAgICAgICAgaSxcclxuICAgICAgICBqLFxyXG4gICAgICAgIHBvcyA9IHN0YXJ0Q291bnRlcixcclxuICAgICAgICBwYXR0ZXJuO1xyXG5cclxuICAgIGZvciAoaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspe1xyXG4gICAgICAgIHBhdHRlcm4gPSBzZWxmLl9jaGFyVG9QYXR0ZXJuKHJlc3VsdFtpXSk7XHJcbiAgICAgICAgZm9yIChqID0gNjsgaiA+PSAwOyBqLS0pIHtcclxuICAgICAgICAgICAga2luZCA9IChqICYgMSkgPT09IDIgPyBjYXRlZ29yaXphdGlvbi5iYXIgOiBjYXRlZ29yaXphdGlvbi5zcGFjZTtcclxuICAgICAgICAgICAgY2F0ID0gKHBhdHRlcm4gJiAxKSA9PT0gMSA/IGtpbmQud2lkZSA6IGtpbmQubmFycm93O1xyXG4gICAgICAgICAgICBjYXQuc2l6ZSArPSBzZWxmLl9jb3VudGVyc1twb3MgKyBqXTtcclxuICAgICAgICAgICAgY2F0LmNvdW50cysrO1xyXG4gICAgICAgICAgICBwYXR0ZXJuID4+PSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwb3MgKz0gODtcclxuICAgIH1cclxuXHJcbiAgICBbXCJzcGFjZVwiLCBcImJhclwiXS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xyXG4gICAgICAgIHZhciBuZXdraW5kID0gY2F0ZWdvcml6YXRpb25ba2V5XTtcclxuICAgICAgICBuZXdraW5kLndpZGUubWluID1cclxuICAgICAgICAgICAgTWF0aC5mbG9vcigobmV3a2luZC5uYXJyb3cuc2l6ZSAvIG5ld2tpbmQubmFycm93LmNvdW50cyArIG5ld2tpbmQud2lkZS5zaXplIC8gbmV3a2luZC53aWRlLmNvdW50cykgLyAyKTtcclxuICAgICAgICBuZXdraW5kLm5hcnJvdy5tYXggPSBNYXRoLmNlaWwobmV3a2luZC53aWRlLm1pbik7XHJcbiAgICAgICAgbmV3a2luZC53aWRlLm1heCA9IE1hdGguY2VpbCgobmV3a2luZC53aWRlLnNpemUgKiBzZWxmLk1BWF9BQ0NFUFRBQkxFICsgc2VsZi5QQURESU5HKSAvIG5ld2tpbmQud2lkZS5jb3VudHMpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIGNhdGVnb3JpemF0aW9uO1xyXG59O1xyXG5cclxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX2NoYXJUb1BhdHRlcm4gPSBmdW5jdGlvbihjaGFyKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY2hhckNvZGUgPSBjaGFyLmNoYXJDb2RlQXQoMCksXHJcbiAgICAgICAgaTtcclxuXHJcbiAgICBmb3IgKGkgPSAwOyBpIDwgc2VsZi5BTFBIQUJFVC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChzZWxmLkFMUEhBQkVUW2ldID09PSBjaGFyQ29kZSl7XHJcbiAgICAgICAgICAgIHJldHVybiBzZWxmLkNIQVJBQ1RFUl9FTkNPRElOR1NbaV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIDB4MDtcclxufTtcclxuXHJcbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl92YWxpZGF0ZVJlc3VsdCA9IGZ1bmN0aW9uKHJlc3VsdCwgc3RhcnRDb3VudGVyKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgdGhyZXNob2xkcyA9IHNlbGYuX3RocmVzaG9sZFJlc3VsdFBhdHRlcm4ocmVzdWx0LCBzdGFydENvdW50ZXIpLFxyXG4gICAgICAgIGksXHJcbiAgICAgICAgaixcclxuICAgICAgICBraW5kLFxyXG4gICAgICAgIGNhdCxcclxuICAgICAgICBzaXplLFxyXG4gICAgICAgIHBvcyA9IHN0YXJ0Q291bnRlcixcclxuICAgICAgICBwYXR0ZXJuO1xyXG5cclxuICAgIGZvciAoaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBwYXR0ZXJuID0gc2VsZi5fY2hhclRvUGF0dGVybihyZXN1bHRbaV0pO1xyXG4gICAgICAgIGZvciAoaiA9IDY7IGogPj0gMDsgai0tKSB7XHJcbiAgICAgICAgICAgIGtpbmQgPSAoaiAmIDEpID09PSAwID8gdGhyZXNob2xkcy5iYXIgOiB0aHJlc2hvbGRzLnNwYWNlO1xyXG4gICAgICAgICAgICBjYXQgPSAocGF0dGVybiAmIDEpID09PSAxID8ga2luZC53aWRlIDoga2luZC5uYXJyb3c7XHJcbiAgICAgICAgICAgIHNpemUgPSBzZWxmLl9jb3VudGVyc1twb3MgKyBqXTtcclxuICAgICAgICAgICAgaWYgKHNpemUgPCBjYXQubWluIHx8IHNpemUgPiBjYXQubWF4KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGF0dGVybiA+Pj0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcG9zICs9IDg7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufTtcclxuXHJcbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl9wYXR0ZXJuVG9DaGFyID0gZnVuY3Rpb24ocGF0dGVybikge1xyXG4gICAgdmFyIGksXHJcbiAgICAgICAgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgZm9yIChpID0gMDsgaSA8IHNlbGYuQ0hBUkFDVEVSX0VOQ09ESU5HUy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChzZWxmLkNIQVJBQ1RFUl9FTkNPRElOR1NbaV0gPT09IHBhdHRlcm4pIHtcclxuICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoc2VsZi5BTFBIQUJFVFtpXSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIC0xO1xyXG59O1xyXG5cclxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX2NvbXB1dGVBbHRlcm5hdGluZ1RocmVzaG9sZCA9IGZ1bmN0aW9uKG9mZnNldCwgZW5kKSB7XHJcbiAgICB2YXIgaSxcclxuICAgICAgICBtaW4gPSBOdW1iZXIuTUFYX1ZBTFVFLFxyXG4gICAgICAgIG1heCA9IDAsXHJcbiAgICAgICAgY291bnRlcjtcclxuXHJcbiAgICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBlbmQ7IGkgKz0gMil7XHJcbiAgICAgICAgY291bnRlciA9IHRoaXMuX2NvdW50ZXJzW2ldO1xyXG4gICAgICAgIGlmIChjb3VudGVyID4gbWF4KSB7XHJcbiAgICAgICAgICAgIG1heCA9IGNvdW50ZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjb3VudGVyIDwgbWluKSB7XHJcbiAgICAgICAgICAgIG1pbiA9IGNvdW50ZXI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAoKG1pbiArIG1heCkgLyAyLjApIHwgMDtcclxufTtcclxuXHJcbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl90b1BhdHRlcm4gPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgIHZhciBudW1Db3VudGVycyA9IDcsXHJcbiAgICAgICAgZW5kID0gb2Zmc2V0ICsgbnVtQ291bnRlcnMsXHJcbiAgICAgICAgYmFyVGhyZXNob2xkLFxyXG4gICAgICAgIHNwYWNlVGhyZXNob2xkLFxyXG4gICAgICAgIGJpdG1hc2sgPSAxIDw8IChudW1Db3VudGVycyAtIDEpLFxyXG4gICAgICAgIHBhdHRlcm4gPSAwLFxyXG4gICAgICAgIGksXHJcbiAgICAgICAgdGhyZXNob2xkO1xyXG5cclxuICAgIGlmIChlbmQgPiB0aGlzLl9jb3VudGVycy5sZW5ndGgpIHtcclxuICAgICAgICByZXR1cm4gLTE7XHJcbiAgICB9XHJcblxyXG4gICAgYmFyVGhyZXNob2xkID0gdGhpcy5fY29tcHV0ZUFsdGVybmF0aW5nVGhyZXNob2xkKG9mZnNldCwgZW5kKTtcclxuICAgIHNwYWNlVGhyZXNob2xkID0gdGhpcy5fY29tcHV0ZUFsdGVybmF0aW5nVGhyZXNob2xkKG9mZnNldCArIDEsIGVuZCk7XHJcblxyXG4gICAgZm9yIChpID0gMDsgaSA8IG51bUNvdW50ZXJzOyBpKyspe1xyXG4gICAgICAgIHRocmVzaG9sZCA9IChpICYgMSkgPT09IDAgPyBiYXJUaHJlc2hvbGQgOiBzcGFjZVRocmVzaG9sZDtcclxuICAgICAgICBpZiAodGhpcy5fY291bnRlcnNbb2Zmc2V0ICsgaV0gPiB0aHJlc2hvbGQpIHtcclxuICAgICAgICAgICAgcGF0dGVybiB8PSBiaXRtYXNrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBiaXRtYXNrID4+PSAxO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwYXR0ZXJuO1xyXG59O1xyXG5cclxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX2lzU3RhcnRFbmQgPSBmdW5jdGlvbihwYXR0ZXJuKSB7XHJcbiAgICB2YXIgaTtcclxuXHJcbiAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5TVEFSVF9FTkQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAodGhpcy5TVEFSVF9FTkRbaV0gPT09IHBhdHRlcm4pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxuQ29kYWJhclJlYWRlci5wcm90b3R5cGUuX3N1bUNvdW50ZXJzID0gZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xyXG4gICAgdmFyIGksXHJcbiAgICAgICAgc3VtID0gMDtcclxuXHJcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XHJcbiAgICAgICAgc3VtICs9IHRoaXMuX2NvdW50ZXJzW2ldO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN1bTtcclxufTtcclxuXHJcbkNvZGFiYXJSZWFkZXIucHJvdG90eXBlLl9maW5kU3RhcnQgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBpLFxyXG4gICAgICAgIHBhdHRlcm4sXHJcbiAgICAgICAgc3RhcnQgPSBzZWxmLl9uZXh0VW5zZXQoc2VsZi5fcm93KSxcclxuICAgICAgICBlbmQ7XHJcblxyXG4gICAgZm9yIChpID0gMTsgaSA8IHRoaXMuX2NvdW50ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgcGF0dGVybiA9IHNlbGYuX3RvUGF0dGVybihpKTtcclxuICAgICAgICBpZiAocGF0dGVybiAhPT0gLTEgJiYgc2VsZi5faXNTdGFydEVuZChwYXR0ZXJuKSkge1xyXG4gICAgICAgICAgICAvLyBUT0RPOiBMb29rIGZvciB3aGl0ZXNwYWNlIGFoZWFkXHJcbiAgICAgICAgICAgIHN0YXJ0ICs9IHNlbGYuX3N1bUNvdW50ZXJzKDAsIGkpO1xyXG4gICAgICAgICAgICBlbmQgPSBzdGFydCArIHNlbGYuX3N1bUNvdW50ZXJzKGksIGkgKyA4KTtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcclxuICAgICAgICAgICAgICAgIGVuZDogZW5kLFxyXG4gICAgICAgICAgICAgICAgc3RhcnRDb3VudGVyOiBpLFxyXG4gICAgICAgICAgICAgICAgZW5kQ291bnRlcjogaSArIDhcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDb2RhYmFyUmVhZGVyO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9yZWFkZXIvY29kYWJhcl9yZWFkZXIuanNcbiAqKi8iLCJpbXBvcnQgQmFyY29kZVJlYWRlciBmcm9tICcuL2JhcmNvZGVfcmVhZGVyJztcclxuXHJcbmZ1bmN0aW9uIENvZGUxMjhSZWFkZXIoKSB7XHJcbiAgICBCYXJjb2RlUmVhZGVyLmNhbGwodGhpcyk7XHJcbn1cclxuXHJcbnZhciBwcm9wZXJ0aWVzID0ge1xyXG4gICAgQ09ERV9TSElGVDoge3ZhbHVlOiA5OH0sXHJcbiAgICBDT0RFX0M6IHt2YWx1ZTogOTl9LFxyXG4gICAgQ09ERV9COiB7dmFsdWU6IDEwMH0sXHJcbiAgICBDT0RFX0E6IHt2YWx1ZTogMTAxfSxcclxuICAgIFNUQVJUX0NPREVfQToge3ZhbHVlOiAxMDN9LFxyXG4gICAgU1RBUlRfQ09ERV9COiB7dmFsdWU6IDEwNH0sXHJcbiAgICBTVEFSVF9DT0RFX0M6IHt2YWx1ZTogMTA1fSxcclxuICAgIFNUT1BfQ09ERToge3ZhbHVlOiAxMDZ9LFxyXG4gICAgTU9EVUxPOiB7dmFsdWU6IDExfSxcclxuICAgIENPREVfUEFUVEVSTjoge3ZhbHVlOiBbXHJcbiAgICAgICAgWzIsIDEsIDIsIDIsIDIsIDJdLFxyXG4gICAgICAgIFsyLCAyLCAyLCAxLCAyLCAyXSxcclxuICAgICAgICBbMiwgMiwgMiwgMiwgMiwgMV0sXHJcbiAgICAgICAgWzEsIDIsIDEsIDIsIDIsIDNdLFxyXG4gICAgICAgIFsxLCAyLCAxLCAzLCAyLCAyXSxcclxuICAgICAgICBbMSwgMywgMSwgMiwgMiwgMl0sXHJcbiAgICAgICAgWzEsIDIsIDIsIDIsIDEsIDNdLFxyXG4gICAgICAgIFsxLCAyLCAyLCAzLCAxLCAyXSxcclxuICAgICAgICBbMSwgMywgMiwgMiwgMSwgMl0sXHJcbiAgICAgICAgWzIsIDIsIDEsIDIsIDEsIDNdLFxyXG4gICAgICAgIFsyLCAyLCAxLCAzLCAxLCAyXSxcclxuICAgICAgICBbMiwgMywgMSwgMiwgMSwgMl0sXHJcbiAgICAgICAgWzEsIDEsIDIsIDIsIDMsIDJdLFxyXG4gICAgICAgIFsxLCAyLCAyLCAxLCAzLCAyXSxcclxuICAgICAgICBbMSwgMiwgMiwgMiwgMywgMV0sXHJcbiAgICAgICAgWzEsIDEsIDMsIDIsIDIsIDJdLFxyXG4gICAgICAgIFsxLCAyLCAzLCAxLCAyLCAyXSxcclxuICAgICAgICBbMSwgMiwgMywgMiwgMiwgMV0sXHJcbiAgICAgICAgWzIsIDIsIDMsIDIsIDEsIDFdLFxyXG4gICAgICAgIFsyLCAyLCAxLCAxLCAzLCAyXSxcclxuICAgICAgICBbMiwgMiwgMSwgMiwgMywgMV0sXHJcbiAgICAgICAgWzIsIDEsIDMsIDIsIDEsIDJdLFxyXG4gICAgICAgIFsyLCAyLCAzLCAxLCAxLCAyXSxcclxuICAgICAgICBbMywgMSwgMiwgMSwgMywgMV0sXHJcbiAgICAgICAgWzMsIDEsIDEsIDIsIDIsIDJdLFxyXG4gICAgICAgIFszLCAyLCAxLCAxLCAyLCAyXSxcclxuICAgICAgICBbMywgMiwgMSwgMiwgMiwgMV0sXHJcbiAgICAgICAgWzMsIDEsIDIsIDIsIDEsIDJdLFxyXG4gICAgICAgIFszLCAyLCAyLCAxLCAxLCAyXSxcclxuICAgICAgICBbMywgMiwgMiwgMiwgMSwgMV0sXHJcbiAgICAgICAgWzIsIDEsIDIsIDEsIDIsIDNdLFxyXG4gICAgICAgIFsyLCAxLCAyLCAzLCAyLCAxXSxcclxuICAgICAgICBbMiwgMywgMiwgMSwgMiwgMV0sXHJcbiAgICAgICAgWzEsIDEsIDEsIDMsIDIsIDNdLFxyXG4gICAgICAgIFsxLCAzLCAxLCAxLCAyLCAzXSxcclxuICAgICAgICBbMSwgMywgMSwgMywgMiwgMV0sXHJcbiAgICAgICAgWzEsIDEsIDIsIDMsIDEsIDNdLFxyXG4gICAgICAgIFsxLCAzLCAyLCAxLCAxLCAzXSxcclxuICAgICAgICBbMSwgMywgMiwgMywgMSwgMV0sXHJcbiAgICAgICAgWzIsIDEsIDEsIDMsIDEsIDNdLFxyXG4gICAgICAgIFsyLCAzLCAxLCAxLCAxLCAzXSxcclxuICAgICAgICBbMiwgMywgMSwgMywgMSwgMV0sXHJcbiAgICAgICAgWzEsIDEsIDIsIDEsIDMsIDNdLFxyXG4gICAgICAgIFsxLCAxLCAyLCAzLCAzLCAxXSxcclxuICAgICAgICBbMSwgMywgMiwgMSwgMywgMV0sXHJcbiAgICAgICAgWzEsIDEsIDMsIDEsIDIsIDNdLFxyXG4gICAgICAgIFsxLCAxLCAzLCAzLCAyLCAxXSxcclxuICAgICAgICBbMSwgMywgMywgMSwgMiwgMV0sXHJcbiAgICAgICAgWzMsIDEsIDMsIDEsIDIsIDFdLFxyXG4gICAgICAgIFsyLCAxLCAxLCAzLCAzLCAxXSxcclxuICAgICAgICBbMiwgMywgMSwgMSwgMywgMV0sXHJcbiAgICAgICAgWzIsIDEsIDMsIDEsIDEsIDNdLFxyXG4gICAgICAgIFsyLCAxLCAzLCAzLCAxLCAxXSxcclxuICAgICAgICBbMiwgMSwgMywgMSwgMywgMV0sXHJcbiAgICAgICAgWzMsIDEsIDEsIDEsIDIsIDNdLFxyXG4gICAgICAgIFszLCAxLCAxLCAzLCAyLCAxXSxcclxuICAgICAgICBbMywgMywgMSwgMSwgMiwgMV0sXHJcbiAgICAgICAgWzMsIDEsIDIsIDEsIDEsIDNdLFxyXG4gICAgICAgIFszLCAxLCAyLCAzLCAxLCAxXSxcclxuICAgICAgICBbMywgMywgMiwgMSwgMSwgMV0sXHJcbiAgICAgICAgWzMsIDEsIDQsIDEsIDEsIDFdLFxyXG4gICAgICAgIFsyLCAyLCAxLCA0LCAxLCAxXSxcclxuICAgICAgICBbNCwgMywgMSwgMSwgMSwgMV0sXHJcbiAgICAgICAgWzEsIDEsIDEsIDIsIDIsIDRdLFxyXG4gICAgICAgIFsxLCAxLCAxLCA0LCAyLCAyXSxcclxuICAgICAgICBbMSwgMiwgMSwgMSwgMiwgNF0sXHJcbiAgICAgICAgWzEsIDIsIDEsIDQsIDIsIDFdLFxyXG4gICAgICAgIFsxLCA0LCAxLCAxLCAyLCAyXSxcclxuICAgICAgICBbMSwgNCwgMSwgMiwgMiwgMV0sXHJcbiAgICAgICAgWzEsIDEsIDIsIDIsIDEsIDRdLFxyXG4gICAgICAgIFsxLCAxLCAyLCA0LCAxLCAyXSxcclxuICAgICAgICBbMSwgMiwgMiwgMSwgMSwgNF0sXHJcbiAgICAgICAgWzEsIDIsIDIsIDQsIDEsIDFdLFxyXG4gICAgICAgIFsxLCA0LCAyLCAxLCAxLCAyXSxcclxuICAgICAgICBbMSwgNCwgMiwgMiwgMSwgMV0sXHJcbiAgICAgICAgWzIsIDQsIDEsIDIsIDEsIDFdLFxyXG4gICAgICAgIFsyLCAyLCAxLCAxLCAxLCA0XSxcclxuICAgICAgICBbNCwgMSwgMywgMSwgMSwgMV0sXHJcbiAgICAgICAgWzIsIDQsIDEsIDEsIDEsIDJdLFxyXG4gICAgICAgIFsxLCAzLCA0LCAxLCAxLCAxXSxcclxuICAgICAgICBbMSwgMSwgMSwgMiwgNCwgMl0sXHJcbiAgICAgICAgWzEsIDIsIDEsIDEsIDQsIDJdLFxyXG4gICAgICAgIFsxLCAyLCAxLCAyLCA0LCAxXSxcclxuICAgICAgICBbMSwgMSwgNCwgMiwgMSwgMl0sXHJcbiAgICAgICAgWzEsIDIsIDQsIDEsIDEsIDJdLFxyXG4gICAgICAgIFsxLCAyLCA0LCAyLCAxLCAxXSxcclxuICAgICAgICBbNCwgMSwgMSwgMiwgMSwgMl0sXHJcbiAgICAgICAgWzQsIDIsIDEsIDEsIDEsIDJdLFxyXG4gICAgICAgIFs0LCAyLCAxLCAyLCAxLCAxXSxcclxuICAgICAgICBbMiwgMSwgMiwgMSwgNCwgMV0sXHJcbiAgICAgICAgWzIsIDEsIDQsIDEsIDIsIDFdLFxyXG4gICAgICAgIFs0LCAxLCAyLCAxLCAyLCAxXSxcclxuICAgICAgICBbMSwgMSwgMSwgMSwgNCwgM10sXHJcbiAgICAgICAgWzEsIDEsIDEsIDMsIDQsIDFdLFxyXG4gICAgICAgIFsxLCAzLCAxLCAxLCA0LCAxXSxcclxuICAgICAgICBbMSwgMSwgNCwgMSwgMSwgM10sXHJcbiAgICAgICAgWzEsIDEsIDQsIDMsIDEsIDFdLFxyXG4gICAgICAgIFs0LCAxLCAxLCAxLCAxLCAzXSxcclxuICAgICAgICBbNCwgMSwgMSwgMywgMSwgMV0sXHJcbiAgICAgICAgWzEsIDEsIDMsIDEsIDQsIDFdLFxyXG4gICAgICAgIFsxLCAxLCA0LCAxLCAzLCAxXSxcclxuICAgICAgICBbMywgMSwgMSwgMSwgNCwgMV0sXHJcbiAgICAgICAgWzQsIDEsIDEsIDEsIDMsIDFdLFxyXG4gICAgICAgIFsyLCAxLCAxLCA0LCAxLCAyXSxcclxuICAgICAgICBbMiwgMSwgMSwgMiwgMSwgNF0sXHJcbiAgICAgICAgWzIsIDEsIDEsIDIsIDMsIDJdLFxyXG4gICAgICAgIFsyLCAzLCAzLCAxLCAxLCAxLCAyXVxyXG4gICAgXX0sXHJcbiAgICBTSU5HTEVfQ09ERV9FUlJPUjoge3ZhbHVlOiAwLjY0fSxcclxuICAgIEFWR19DT0RFX0VSUk9SOiB7dmFsdWU6IDAuMzB9LFxyXG4gICAgRk9STUFUOiB7dmFsdWU6IFwiY29kZV8xMjhcIiwgd3JpdGVhYmxlOiBmYWxzZX0sXHJcbiAgICBNT0RVTEVfSU5ESUNFUzoge3ZhbHVlOiB7YmFyOiBbMCwgMiwgNF0sIHNwYWNlOiBbMSwgMywgNV19fVxyXG59O1xyXG5cclxuQ29kZTEyOFJlYWRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhcmNvZGVSZWFkZXIucHJvdG90eXBlLCBwcm9wZXJ0aWVzKTtcclxuQ29kZTEyOFJlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDb2RlMTI4UmVhZGVyO1xyXG5cclxuQ29kZTEyOFJlYWRlci5wcm90b3R5cGUuX2RlY29kZUNvZGUgPSBmdW5jdGlvbihzdGFydCwgY29ycmVjdGlvbikge1xyXG4gICAgdmFyIGNvdW50ZXIgPSBbMCwgMCwgMCwgMCwgMCwgMF0sXHJcbiAgICAgICAgaSxcclxuICAgICAgICBzZWxmID0gdGhpcyxcclxuICAgICAgICBvZmZzZXQgPSBzdGFydCxcclxuICAgICAgICBpc1doaXRlID0gIXNlbGYuX3Jvd1tvZmZzZXRdLFxyXG4gICAgICAgIGNvdW50ZXJQb3MgPSAwLFxyXG4gICAgICAgIGJlc3RNYXRjaCA9IHtcclxuICAgICAgICAgICAgZXJyb3I6IE51bWJlci5NQVhfVkFMVUUsXHJcbiAgICAgICAgICAgIGNvZGU6IC0xLFxyXG4gICAgICAgICAgICBzdGFydDogc3RhcnQsXHJcbiAgICAgICAgICAgIGVuZDogc3RhcnQsXHJcbiAgICAgICAgICAgIGNvcnJlY3Rpb246IHtcclxuICAgICAgICAgICAgICAgIGJhcjogMSxcclxuICAgICAgICAgICAgICAgIHNwYWNlOiAxXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIGNvZGUsXHJcbiAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgbm9ybWFsaXplZDtcclxuXHJcbiAgICBmb3IgKCBpID0gb2Zmc2V0OyBpIDwgc2VsZi5fcm93Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKHNlbGYuX3Jvd1tpXSBeIGlzV2hpdGUpIHtcclxuICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSsrO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChjb3VudGVyUG9zID09PSBjb3VudGVyLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBzZWxmLl9ub3JtYWxpemUoY291bnRlciwgY29ycmVjdGlvbik7XHJcbiAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29kZSA9IDA7IGNvZGUgPCBzZWxmLkNPREVfUEFUVEVSTi5sZW5ndGg7IGNvZGUrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHNlbGYuX21hdGNoUGF0dGVybihub3JtYWxpemVkLCBzZWxmLkNPREVfUEFUVEVSTltjb2RlXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA8IGJlc3RNYXRjaC5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmNvZGUgPSBjb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVycm9yID0gZXJyb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmVzdE1hdGNoLmVuZCA9IGk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJlc3RNYXRjaC5jb2RlID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuQ09ERV9QQVRURVJOW2Jlc3RNYXRjaC5jb2RlXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guY29ycmVjdGlvbi5iYXIgPSBjYWxjdWxhdGVDb3JyZWN0aW9uKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5DT0RFX1BBVFRFUk5bYmVzdE1hdGNoLmNvZGVdLCBub3JtYWxpemVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5NT0RVTEVfSU5ESUNFUy5iYXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guY29ycmVjdGlvbi5zcGFjZSA9IGNhbGN1bGF0ZUNvcnJlY3Rpb24oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLkNPREVfUEFUVEVSTltiZXN0TWF0Y2guY29kZV0sIG5vcm1hbGl6ZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLk1PRFVMRV9JTkRJQ0VTLnNwYWNlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJlc3RNYXRjaDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MrKztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb3VudGVyW2NvdW50ZXJQb3NdID0gMTtcclxuICAgICAgICAgICAgaXNXaGl0ZSA9ICFpc1doaXRlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuQ29kZTEyOFJlYWRlci5wcm90b3R5cGUuX2NvcnJlY3QgPSBmdW5jdGlvbihjb3VudGVyLCBjb3JyZWN0aW9uKSB7XHJcbiAgICB0aGlzLl9jb3JyZWN0QmFycyhjb3VudGVyLCBjb3JyZWN0aW9uLmJhciwgdGhpcy5NT0RVTEVfSU5ESUNFUy5iYXIpO1xyXG4gICAgdGhpcy5fY29ycmVjdEJhcnMoY291bnRlciwgY29ycmVjdGlvbi5zcGFjZSwgdGhpcy5NT0RVTEVfSU5ESUNFUy5zcGFjZSk7XHJcbn07XHJcblxyXG5Db2RlMTI4UmVhZGVyLnByb3RvdHlwZS5fZmluZFN0YXJ0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgY291bnRlciA9IFswLCAwLCAwLCAwLCAwLCAwXSxcclxuICAgICAgICBpLFxyXG4gICAgICAgIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIG9mZnNldCA9IHNlbGYuX25leHRTZXQoc2VsZi5fcm93KSxcclxuICAgICAgICBpc1doaXRlID0gZmFsc2UsXHJcbiAgICAgICAgY291bnRlclBvcyA9IDAsXHJcbiAgICAgICAgYmVzdE1hdGNoID0ge1xyXG4gICAgICAgICAgICBlcnJvcjogTnVtYmVyLk1BWF9WQUxVRSxcclxuICAgICAgICAgICAgY29kZTogLTEsXHJcbiAgICAgICAgICAgIHN0YXJ0OiAwLFxyXG4gICAgICAgICAgICBlbmQ6IDAsXHJcbiAgICAgICAgICAgIGNvcnJlY3Rpb246IHtcclxuICAgICAgICAgICAgICAgIGJhcjogMSxcclxuICAgICAgICAgICAgICAgIHNwYWNlOiAxXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIGNvZGUsXHJcbiAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgaixcclxuICAgICAgICBzdW0sXHJcbiAgICAgICAgbm9ybWFsaXplZDtcclxuXHJcbiAgICBmb3IgKCBpID0gb2Zmc2V0OyBpIDwgc2VsZi5fcm93Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKHNlbGYuX3Jvd1tpXSBeIGlzV2hpdGUpIHtcclxuICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSsrO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChjb3VudGVyUG9zID09PSBjb3VudGVyLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgIHN1bSA9IDA7XHJcbiAgICAgICAgICAgICAgICBmb3IgKCBqID0gMDsgaiA8IGNvdW50ZXIubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBzdW0gKz0gY291bnRlcltqXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBzZWxmLl9ub3JtYWxpemUoY291bnRlcik7XHJcbiAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29kZSA9IHNlbGYuU1RBUlRfQ09ERV9BOyBjb2RlIDw9IHNlbGYuU1RBUlRfQ09ERV9DOyBjb2RlKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBzZWxmLl9tYXRjaFBhdHRlcm4obm9ybWFsaXplZCwgc2VsZi5DT0RFX1BBVFRFUk5bY29kZV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgPCBiZXN0TWF0Y2guZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5jb2RlID0gY29kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5lcnJvciA9IGVycm9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChiZXN0TWF0Y2guZXJyb3IgPCBzZWxmLkFWR19DT0RFX0VSUk9SKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5zdGFydCA9IGkgLSBzdW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5lbmQgPSBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guY29ycmVjdGlvbi5iYXIgPSBjYWxjdWxhdGVDb3JyZWN0aW9uKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5DT0RFX1BBVFRFUk5bY29kZV0sIG5vcm1hbGl6ZWQsIFswLCAyLCA0XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5jb3JyZWN0aW9uLnNwYWNlID0gY2FsY3VsYXRlQ29ycmVjdGlvbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuQ09ERV9QQVRURVJOW2NvZGVdLCBub3JtYWxpemVkLCBbMSwgMywgNV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmVzdE1hdGNoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKCBqID0gMDsgaiA8IDQ7IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJbal0gPSBjb3VudGVyW2ogKyAyXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvdW50ZXJbNF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgY291bnRlcls1XSA9IDA7XHJcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zLS07XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zKys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSA9IDE7XHJcbiAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbkNvZGUxMjhSZWFkZXIucHJvdG90eXBlLl9kZWNvZGUgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBzdGFydEluZm8gPSBzZWxmLl9maW5kU3RhcnQoKSxcclxuICAgICAgICBjb2RlID0gbnVsbCxcclxuICAgICAgICBkb25lID0gZmFsc2UsXHJcbiAgICAgICAgcmVzdWx0ID0gW10sXHJcbiAgICAgICAgbXVsdGlwbGllciA9IDAsXHJcbiAgICAgICAgY2hlY2tzdW0gPSAwLFxyXG4gICAgICAgIGNvZGVzZXQsXHJcbiAgICAgICAgcmF3UmVzdWx0ID0gW10sXHJcbiAgICAgICAgZGVjb2RlZENvZGVzID0gW10sXHJcbiAgICAgICAgc2hpZnROZXh0ID0gZmFsc2UsXHJcbiAgICAgICAgdW5zaGlmdCxcclxuICAgICAgICByZW1vdmVMYXN0Q2hhcmFjdGVyID0gdHJ1ZTtcclxuXHJcbiAgICBpZiAoc3RhcnRJbmZvID09PSBudWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICBjb2RlID0ge1xyXG4gICAgICAgIGNvZGU6IHN0YXJ0SW5mby5jb2RlLFxyXG4gICAgICAgIHN0YXJ0OiBzdGFydEluZm8uc3RhcnQsXHJcbiAgICAgICAgZW5kOiBzdGFydEluZm8uZW5kLFxyXG4gICAgICAgIGNvcnJlY3Rpb246IHtcclxuICAgICAgICAgICAgYmFyOiBzdGFydEluZm8uY29ycmVjdGlvbi5iYXIsXHJcbiAgICAgICAgICAgIHNwYWNlOiBzdGFydEluZm8uY29ycmVjdGlvbi5zcGFjZVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBkZWNvZGVkQ29kZXMucHVzaChjb2RlKTtcclxuICAgIGNoZWNrc3VtID0gY29kZS5jb2RlO1xyXG4gICAgc3dpdGNoIChjb2RlLmNvZGUpIHtcclxuICAgIGNhc2Ugc2VsZi5TVEFSVF9DT0RFX0E6XHJcbiAgICAgICAgY29kZXNldCA9IHNlbGYuQ09ERV9BO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSBzZWxmLlNUQVJUX0NPREVfQjpcclxuICAgICAgICBjb2Rlc2V0ID0gc2VsZi5DT0RFX0I7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICBjYXNlIHNlbGYuU1RBUlRfQ09ERV9DOlxyXG4gICAgICAgIGNvZGVzZXQgPSBzZWxmLkNPREVfQztcclxuICAgICAgICBicmVhaztcclxuICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgd2hpbGUgKCFkb25lKSB7XHJcbiAgICAgICAgdW5zaGlmdCA9IHNoaWZ0TmV4dDtcclxuICAgICAgICBzaGlmdE5leHQgPSBmYWxzZTtcclxuICAgICAgICBjb2RlID0gc2VsZi5fZGVjb2RlQ29kZShjb2RlLmVuZCwgY29kZS5jb3JyZWN0aW9uKTtcclxuICAgICAgICBpZiAoY29kZSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBpZiAoY29kZS5jb2RlICE9PSBzZWxmLlNUT1BfQ09ERSkge1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlTGFzdENoYXJhY3RlciA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChjb2RlLmNvZGUgIT09IHNlbGYuU1RPUF9DT0RFKSB7XHJcbiAgICAgICAgICAgICAgICByYXdSZXN1bHQucHVzaChjb2RlLmNvZGUpO1xyXG4gICAgICAgICAgICAgICAgbXVsdGlwbGllcisrO1xyXG4gICAgICAgICAgICAgICAgY2hlY2tzdW0gKz0gbXVsdGlwbGllciAqIGNvZGUuY29kZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWNvZGVkQ29kZXMucHVzaChjb2RlKTtcclxuXHJcbiAgICAgICAgICAgIHN3aXRjaCAoY29kZXNldCkge1xyXG4gICAgICAgICAgICBjYXNlIHNlbGYuQ09ERV9BOlxyXG4gICAgICAgICAgICAgICAgaWYgKGNvZGUuY29kZSA8IDY0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSgzMiArIGNvZGUuY29kZSkpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb2RlLmNvZGUgPCA5Nikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZS5jb2RlIC0gNjQpKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvZGUuY29kZSAhPT0gc2VsZi5TVE9QX0NPREUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlTGFzdENoYXJhY3RlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvZGUuY29kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2Ugc2VsZi5DT0RFX1NISUZUOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaGlmdE5leHQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2Rlc2V0ID0gc2VsZi5DT0RFX0I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2Ugc2VsZi5DT0RFX0I6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVzZXQgPSBzZWxmLkNPREVfQjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLkNPREVfQzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZXNldCA9IHNlbGYuQ09ERV9DO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuU1RPUF9DT0RFOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2Ugc2VsZi5DT0RFX0I6XHJcbiAgICAgICAgICAgICAgICBpZiAoY29kZS5jb2RlIDwgOTYpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKDMyICsgY29kZS5jb2RlKSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2RlLmNvZGUgIT09IHNlbGYuU1RPUF9DT0RFKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUxhc3RDaGFyYWN0ZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb2RlLmNvZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuQ09ERV9TSElGVDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2hpZnROZXh0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZXNldCA9IHNlbGYuQ09ERV9BO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuQ09ERV9BOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2Rlc2V0ID0gc2VsZi5DT0RFX0E7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2Ugc2VsZi5DT0RFX0M6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVzZXQgPSBzZWxmLkNPREVfQztcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLlNUT1BfQ09ERTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIHNlbGYuQ09ERV9DOlxyXG4gICAgICAgICAgICAgICAgaWYgKGNvZGUuY29kZSA8IDEwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGNvZGUuY29kZSA8IDEwID8gXCIwXCIgKyBjb2RlLmNvZGUgOiBjb2RlLmNvZGUpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29kZS5jb2RlICE9PSBzZWxmLlNUT1BfQ09ERSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVMYXN0Q2hhcmFjdGVyID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY29kZS5jb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLkNPREVfQTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZXNldCA9IHNlbGYuQ09ERV9BO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuQ09ERV9COlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2Rlc2V0ID0gc2VsZi5DT0RFX0I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2Ugc2VsZi5TVE9QX0NPREU6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodW5zaGlmdCkge1xyXG4gICAgICAgICAgICBjb2Rlc2V0ID0gY29kZXNldCA9PT0gc2VsZi5DT0RFX0EgPyBzZWxmLkNPREVfQiA6IHNlbGYuQ09ERV9BO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29kZSA9PT0gbnVsbCkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGNvZGUuZW5kID0gc2VsZi5fbmV4dFVuc2V0KHNlbGYuX3JvdywgY29kZS5lbmQpO1xyXG4gICAgaWYgKCFzZWxmLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UoY29kZSkpe1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGNoZWNrc3VtIC09IG11bHRpcGxpZXIgKiByYXdSZXN1bHRbcmF3UmVzdWx0Lmxlbmd0aCAtIDFdO1xyXG4gICAgaWYgKGNoZWNrc3VtICUgMTAzICE9PSByYXdSZXN1bHRbcmF3UmVzdWx0Lmxlbmd0aCAtIDFdKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFyZXN1bHQubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmVtb3ZlIGxhc3QgY29kZSBmcm9tIHJlc3VsdCAoY2hlY2tzdW0pXHJcbiAgICBpZiAocmVtb3ZlTGFzdENoYXJhY3Rlcikge1xyXG4gICAgICAgIHJlc3VsdC5zcGxpY2UocmVzdWx0Lmxlbmd0aCAtIDEsIDEpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGNvZGU6IHJlc3VsdC5qb2luKFwiXCIpLFxyXG4gICAgICAgIHN0YXJ0OiBzdGFydEluZm8uc3RhcnQsXHJcbiAgICAgICAgZW5kOiBjb2RlLmVuZCxcclxuICAgICAgICBjb2Rlc2V0OiBjb2Rlc2V0LFxyXG4gICAgICAgIHN0YXJ0SW5mbzogc3RhcnRJbmZvLFxyXG4gICAgICAgIGRlY29kZWRDb2RlczogZGVjb2RlZENvZGVzLFxyXG4gICAgICAgIGVuZEluZm86IGNvZGVcclxuICAgIH07XHJcbn07XHJcblxyXG5cclxuQmFyY29kZVJlYWRlci5wcm90b3R5cGUuX3ZlcmlmeVRyYWlsaW5nV2hpdGVzcGFjZSA9IGZ1bmN0aW9uKGVuZEluZm8pIHtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICB0cmFpbGluZ1doaXRlc3BhY2VFbmQ7XHJcblxyXG4gICAgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kID0gZW5kSW5mby5lbmQgKyAoKGVuZEluZm8uZW5kIC0gZW5kSW5mby5zdGFydCkgLyAyKTtcclxuICAgIGlmICh0cmFpbGluZ1doaXRlc3BhY2VFbmQgPCBzZWxmLl9yb3cubGVuZ3RoKSB7XHJcbiAgICAgICAgaWYgKHNlbGYuX21hdGNoUmFuZ2UoZW5kSW5mby5lbmQsIHRyYWlsaW5nV2hpdGVzcGFjZUVuZCwgMCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGVuZEluZm87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbn07XHJcblxyXG5mdW5jdGlvbiBjYWxjdWxhdGVDb3JyZWN0aW9uKGV4cGVjdGVkLCBub3JtYWxpemVkLCBpbmRpY2VzKSB7XHJcbiAgICB2YXIgbGVuZ3RoID0gaW5kaWNlcy5sZW5ndGgsXHJcbiAgICAgICAgc3VtTm9ybWFsaXplZCA9IDAsXHJcbiAgICAgICAgc3VtRXhwZWN0ZWQgPSAwO1xyXG5cclxuICAgIHdoaWxlKGxlbmd0aC0tKSB7XHJcbiAgICAgICAgc3VtRXhwZWN0ZWQgKz0gZXhwZWN0ZWRbaW5kaWNlc1tsZW5ndGhdXTtcclxuICAgICAgICBzdW1Ob3JtYWxpemVkICs9IG5vcm1hbGl6ZWRbaW5kaWNlc1tsZW5ndGhdXTtcclxuICAgIH1cclxuICAgIHJldHVybiBzdW1FeHBlY3RlZC9zdW1Ob3JtYWxpemVkO1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDb2RlMTI4UmVhZGVyO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9yZWFkZXIvY29kZV8xMjhfcmVhZGVyLmpzXG4gKiovIiwiaW1wb3J0IENvZGUzOVJlYWRlciBmcm9tICcuL2NvZGVfMzlfcmVhZGVyJztcclxuXHJcbmZ1bmN0aW9uIENvZGUzOVZJTlJlYWRlcigpIHtcclxuICAgIENvZGUzOVJlYWRlci5jYWxsKHRoaXMpO1xyXG59XHJcblxyXG52YXIgcGF0dGVybnMgPSB7XHJcbiAgICBJT1E6IC9bSU9RXS9nLFxyXG4gICAgQVowOTogL1tBLVowLTldezE3fS9cclxufTtcclxuXHJcbkNvZGUzOVZJTlJlYWRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKENvZGUzOVJlYWRlci5wcm90b3R5cGUpO1xyXG5Db2RlMzlWSU5SZWFkZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQ29kZTM5VklOUmVhZGVyO1xyXG5cclxuLy8gQ3JpYmJlZCBmcm9tOlxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20venhpbmcvenhpbmcvYmxvYi9tYXN0ZXIvY29yZS9zcmMvbWFpbi9qYXZhL2NvbS9nb29nbGUvenhpbmcvY2xpZW50L3Jlc3VsdC9WSU5SZXN1bHRQYXJzZXIuamF2YVxyXG5Db2RlMzlWSU5SZWFkZXIucHJvdG90eXBlLl9kZWNvZGUgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciByZXN1bHQgPSBDb2RlMzlSZWFkZXIucHJvdG90eXBlLl9kZWNvZGUuYXBwbHkodGhpcyk7XHJcbiAgICBpZiAoIXJlc3VsdCkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBjb2RlID0gcmVzdWx0LmNvZGU7XHJcblxyXG4gICAgaWYgKCFjb2RlKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgY29kZSA9IGNvZGUucmVwbGFjZShwYXR0ZXJucy5JT1EsICcnKTtcclxuXHJcbiAgICBpZiAoIWNvZGUubWF0Y2gocGF0dGVybnMuQVowOSkpIHtcclxuICAgICAgICBpZiAoRU5WLmRldmVsb3BtZW50KSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdGYWlsZWQgQVowOSBwYXR0ZXJuIGNvZGU6JywgY29kZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy5fY2hlY2tDaGVja3N1bShjb2RlKSkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHJlc3VsdC5jb2RlID0gY29kZTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn07XHJcblxyXG5Db2RlMzlWSU5SZWFkZXIucHJvdG90eXBlLl9jaGVja0NoZWNrc3VtID0gZnVuY3Rpb24oY29kZSkge1xyXG4gICAgLy8gVE9ET1xyXG4gICAgcmV0dXJuICEhY29kZTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IENvZGUzOVZJTlJlYWRlcjtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvcmVhZGVyL2NvZGVfMzlfdmluX3JlYWRlci5qc1xuICoqLyIsImltcG9ydCBFQU5SZWFkZXIgZnJvbSAnLi9lYW5fcmVhZGVyJztcclxuXHJcbmZ1bmN0aW9uIEVBTjhSZWFkZXIoKSB7XHJcbiAgICBFQU5SZWFkZXIuY2FsbCh0aGlzKTtcclxufVxyXG5cclxudmFyIHByb3BlcnRpZXMgPSB7XHJcbiAgICBGT1JNQVQ6IHt2YWx1ZTogXCJlYW5fOFwiLCB3cml0ZWFibGU6IGZhbHNlfVxyXG59O1xyXG5cclxuRUFOOFJlYWRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVBTlJlYWRlci5wcm90b3R5cGUsIHByb3BlcnRpZXMpO1xyXG5FQU44UmVhZGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEVBTjhSZWFkZXI7XHJcblxyXG5FQU44UmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlUGF5bG9hZCA9IGZ1bmN0aW9uKGNvZGUsIHJlc3VsdCwgZGVjb2RlZENvZGVzKSB7XHJcbiAgICB2YXIgaSxcclxuICAgICAgICBzZWxmID0gdGhpcztcclxuXHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IDQ7IGkrKykge1xyXG4gICAgICAgIGNvZGUgPSBzZWxmLl9kZWNvZGVDb2RlKGNvZGUuZW5kLCBzZWxmLkNPREVfR19TVEFSVCk7XHJcbiAgICAgICAgaWYgKCFjb2RlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXN1bHQucHVzaChjb2RlLmNvZGUpO1xyXG4gICAgICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvZGUgPSBzZWxmLl9maW5kUGF0dGVybihzZWxmLk1JRERMRV9QQVRURVJOLCBjb2RlLmVuZCwgdHJ1ZSwgZmFsc2UpO1xyXG4gICAgaWYgKGNvZGUgPT09IG51bGwpIHtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xyXG5cclxuICAgIGZvciAoIGkgPSAwOyBpIDwgNDsgaSsrKSB7XHJcbiAgICAgICAgY29kZSA9IHNlbGYuX2RlY29kZUNvZGUoY29kZS5lbmQsIHNlbGYuQ09ERV9HX1NUQVJUKTtcclxuICAgICAgICBpZiAoIWNvZGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xyXG4gICAgICAgIHJlc3VsdC5wdXNoKGNvZGUuY29kZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNvZGU7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBFQU44UmVhZGVyO1xyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3NyYy9yZWFkZXIvZWFuXzhfcmVhZGVyLmpzXG4gKiovIiwiaW1wb3J0IEJhcmNvZGVSZWFkZXIgZnJvbSAnLi9iYXJjb2RlX3JlYWRlcic7XHJcbmltcG9ydCB7bWVyZ2V9IGZyb20gJ2xvZGFzaCc7XHJcblxyXG5mdW5jdGlvbiBJMm9mNVJlYWRlcihvcHRzKSB7XHJcbiAgICBvcHRzID0gbWVyZ2UoZ2V0RGVmYXVsQ29uZmlnKCksIG9wdHMpO1xyXG4gICAgQmFyY29kZVJlYWRlci5jYWxsKHRoaXMsIG9wdHMpO1xyXG4gICAgdGhpcy5iYXJTcGFjZVJhdGlvID0gWzEsIDFdO1xyXG4gICAgaWYgKG9wdHMubm9ybWFsaXplQmFyU3BhY2VXaWR0aCkge1xyXG4gICAgICAgIHRoaXMuU0lOR0xFX0NPREVfRVJST1IgPSAwLjM4O1xyXG4gICAgICAgIHRoaXMuQVZHX0NPREVfRVJST1IgPSAwLjA5O1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBnZXREZWZhdWxDb25maWcoKSB7XHJcbiAgICB2YXIgY29uZmlnID0ge307XHJcblxyXG4gICAgT2JqZWN0LmtleXMoSTJvZjVSZWFkZXIuQ09ORklHX0tFWVMpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XHJcbiAgICAgICAgY29uZmlnW2tleV0gPSBJMm9mNVJlYWRlci5DT05GSUdfS0VZU1trZXldLmRlZmF1bHQ7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBjb25maWc7XHJcbn1cclxuXHJcbnZhciBOID0gMSxcclxuICAgIFcgPSAzLFxyXG4gICAgcHJvcGVydGllcyA9IHtcclxuICAgICAgICBNT0RVTE86IHt2YWx1ZTogMTB9LFxyXG4gICAgICAgIFNUQVJUX1BBVFRFUk46IHt2YWx1ZTogW04gKiAyLjUsIE4gKiAyLjUsIE4gKiAyLjUsIE4gKiAyLjVdfSxcclxuICAgICAgICBTVE9QX1BBVFRFUk46IHt2YWx1ZTogW04gKiAyLCBOICogMiwgVyAqIDJdfSxcclxuICAgICAgICBDT0RFX1BBVFRFUk46IHt2YWx1ZTogW1xyXG4gICAgICAgICAgICBbTiwgTiwgVywgVywgTl0sXHJcbiAgICAgICAgICAgIFtXLCBOLCBOLCBOLCBXXSxcclxuICAgICAgICAgICAgW04sIFcsIE4sIE4sIFddLFxyXG4gICAgICAgICAgICBbVywgVywgTiwgTiwgTl0sXHJcbiAgICAgICAgICAgIFtOLCBOLCBXLCBOLCBXXSxcclxuICAgICAgICAgICAgW1csIE4sIFcsIE4sIE5dLFxyXG4gICAgICAgICAgICBbTiwgVywgVywgTiwgTl0sXHJcbiAgICAgICAgICAgIFtOLCBOLCBOLCBXLCBXXSxcclxuICAgICAgICAgICAgW1csIE4sIE4sIFcsIE5dLFxyXG4gICAgICAgICAgICBbTiwgVywgTiwgVywgTl1cclxuICAgICAgICBdfSxcclxuICAgICAgICBTSU5HTEVfQ09ERV9FUlJPUjoge3ZhbHVlOiAwLjc4LCB3cml0YWJsZTogdHJ1ZX0sXHJcbiAgICAgICAgQVZHX0NPREVfRVJST1I6IHt2YWx1ZTogMC4zOCwgd3JpdGFibGU6IHRydWV9LFxyXG4gICAgICAgIE1BWF9DT1JSRUNUSU9OX0ZBQ1RPUjoge3ZhbHVlOiA1fSxcclxuICAgICAgICBGT1JNQVQ6IHt2YWx1ZTogXCJpMm9mNVwifVxyXG4gICAgfTtcclxuXHJcbkkyb2Y1UmVhZGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQmFyY29kZVJlYWRlci5wcm90b3R5cGUsIHByb3BlcnRpZXMpO1xyXG5JMm9mNVJlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBJMm9mNVJlYWRlcjtcclxuXHJcbkkyb2Y1UmVhZGVyLnByb3RvdHlwZS5fbWF0Y2hQYXR0ZXJuID0gZnVuY3Rpb24oY291bnRlciwgY29kZSkge1xyXG4gICAgaWYgKHRoaXMuY29uZmlnLm5vcm1hbGl6ZUJhclNwYWNlV2lkdGgpIHtcclxuICAgICAgICB2YXIgaSxcclxuICAgICAgICAgICAgY291bnRlclN1bSA9IFswLCAwXSxcclxuICAgICAgICAgICAgY29kZVN1bSA9IFswLCAwXSxcclxuICAgICAgICAgICAgY29ycmVjdGlvbiA9IFswLCAwXSxcclxuICAgICAgICAgICAgY29ycmVjdGlvblJhdGlvID0gdGhpcy5NQVhfQ09SUkVDVElPTl9GQUNUT1IsXHJcbiAgICAgICAgICAgIGNvcnJlY3Rpb25SYXRpb0ludmVyc2UgPSAxIC8gY29ycmVjdGlvblJhdGlvO1xyXG5cclxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnRlci5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb3VudGVyU3VtW2kgJSAyXSArPSBjb3VudGVyW2ldO1xyXG4gICAgICAgICAgICBjb2RlU3VtW2kgJSAyXSArPSBjb2RlW2ldO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb3JyZWN0aW9uWzBdID0gY29kZVN1bVswXSAvIGNvdW50ZXJTdW1bMF07XHJcbiAgICAgICAgY29ycmVjdGlvblsxXSA9IGNvZGVTdW1bMV0gLyBjb3VudGVyU3VtWzFdO1xyXG5cclxuICAgICAgICBjb3JyZWN0aW9uWzBdID0gTWF0aC5tYXgoTWF0aC5taW4oY29ycmVjdGlvblswXSwgY29ycmVjdGlvblJhdGlvKSwgY29ycmVjdGlvblJhdGlvSW52ZXJzZSk7XHJcbiAgICAgICAgY29ycmVjdGlvblsxXSA9IE1hdGgubWF4KE1hdGgubWluKGNvcnJlY3Rpb25bMV0sIGNvcnJlY3Rpb25SYXRpbyksIGNvcnJlY3Rpb25SYXRpb0ludmVyc2UpO1xyXG4gICAgICAgIHRoaXMuYmFyU3BhY2VSYXRpbyA9IGNvcnJlY3Rpb247XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50ZXIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY291bnRlcltpXSAqPSB0aGlzLmJhclNwYWNlUmF0aW9baSAlIDJdO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBCYXJjb2RlUmVhZGVyLnByb3RvdHlwZS5fbWF0Y2hQYXR0ZXJuLmNhbGwodGhpcywgY291bnRlciwgY29kZSk7XHJcbn07XHJcblxyXG5JMm9mNVJlYWRlci5wcm90b3R5cGUuX2ZpbmRQYXR0ZXJuID0gZnVuY3Rpb24ocGF0dGVybiwgb2Zmc2V0LCBpc1doaXRlLCB0cnlIYXJkZXIpIHtcclxuICAgIHZhciBjb3VudGVyID0gW10sXHJcbiAgICAgICAgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgaSxcclxuICAgICAgICBjb3VudGVyUG9zID0gMCxcclxuICAgICAgICBiZXN0TWF0Y2ggPSB7XHJcbiAgICAgICAgICAgIGVycm9yOiBOdW1iZXIuTUFYX1ZBTFVFLFxyXG4gICAgICAgICAgICBjb2RlOiAtMSxcclxuICAgICAgICAgICAgc3RhcnQ6IDAsXHJcbiAgICAgICAgICAgIGVuZDogMFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgaixcclxuICAgICAgICBzdW0sXHJcbiAgICAgICAgbm9ybWFsaXplZCxcclxuICAgICAgICBlcHNpbG9uID0gc2VsZi5BVkdfQ09ERV9FUlJPUjtcclxuXHJcbiAgICBpc1doaXRlID0gaXNXaGl0ZSB8fCBmYWxzZTtcclxuICAgIHRyeUhhcmRlciA9IHRyeUhhcmRlciB8fCBmYWxzZTtcclxuXHJcbiAgICBpZiAoIW9mZnNldCkge1xyXG4gICAgICAgIG9mZnNldCA9IHNlbGYuX25leHRTZXQoc2VsZi5fcm93KTtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IHBhdHRlcm4ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb3VudGVyW2ldID0gMDtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKCBpID0gb2Zmc2V0OyBpIDwgc2VsZi5fcm93Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKHNlbGYuX3Jvd1tpXSBeIGlzV2hpdGUpIHtcclxuICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSsrO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChjb3VudGVyUG9zID09PSBjb3VudGVyLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgIHN1bSA9IDA7XHJcbiAgICAgICAgICAgICAgICBmb3IgKCBqID0gMDsgaiA8IGNvdW50ZXIubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBzdW0gKz0gY291bnRlcltqXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBzZWxmLl9ub3JtYWxpemUoY291bnRlcik7XHJcbiAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gc2VsZi5fbWF0Y2hQYXR0ZXJuKG5vcm1hbGl6ZWQsIHBhdHRlcm4pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgPCBlcHNpbG9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5lcnJvciA9IGVycm9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guc3RhcnQgPSBpIC0gc3VtO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiZXN0TWF0Y2guZW5kID0gaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJlc3RNYXRjaDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodHJ5SGFyZGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGNvdW50ZXIubGVuZ3RoIC0gMjsgaisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXJbal0gPSBjb3VudGVyW2ogKyAyXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcltjb3VudGVyLmxlbmd0aCAtIDJdID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBjb3VudGVyW2NvdW50ZXIubGVuZ3RoIC0gMV0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXJQb3MtLTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb3VudGVyUG9zKys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY291bnRlcltjb3VudGVyUG9zXSA9IDE7XHJcbiAgICAgICAgICAgIGlzV2hpdGUgPSAhaXNXaGl0ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbkkyb2Y1UmVhZGVyLnByb3RvdHlwZS5fZmluZFN0YXJ0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgbGVhZGluZ1doaXRlc3BhY2VTdGFydCxcclxuICAgICAgICBvZmZzZXQgPSBzZWxmLl9uZXh0U2V0KHNlbGYuX3JvdyksXHJcbiAgICAgICAgc3RhcnRJbmZvLFxyXG4gICAgICAgIG5hcnJvd0JhcldpZHRoID0gMTtcclxuXHJcbiAgICB3aGlsZSAoIXN0YXJ0SW5mbykge1xyXG4gICAgICAgIHN0YXJ0SW5mbyA9IHNlbGYuX2ZpbmRQYXR0ZXJuKHNlbGYuU1RBUlRfUEFUVEVSTiwgb2Zmc2V0LCBmYWxzZSwgdHJ1ZSk7XHJcbiAgICAgICAgaWYgKCFzdGFydEluZm8pIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG5hcnJvd0JhcldpZHRoID0gTWF0aC5mbG9vcigoc3RhcnRJbmZvLmVuZCAtIHN0YXJ0SW5mby5zdGFydCkgLyA0KTtcclxuICAgICAgICBsZWFkaW5nV2hpdGVzcGFjZVN0YXJ0ID0gc3RhcnRJbmZvLnN0YXJ0IC0gbmFycm93QmFyV2lkdGggKiAxMDtcclxuICAgICAgICBpZiAobGVhZGluZ1doaXRlc3BhY2VTdGFydCA+PSAwKSB7XHJcbiAgICAgICAgICAgIGlmIChzZWxmLl9tYXRjaFJhbmdlKGxlYWRpbmdXaGl0ZXNwYWNlU3RhcnQsIHN0YXJ0SW5mby5zdGFydCwgMCkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzdGFydEluZm87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ID0gc3RhcnRJbmZvLmVuZDtcclxuICAgICAgICBzdGFydEluZm8gPSBudWxsO1xyXG4gICAgfVxyXG59O1xyXG5cclxuSTJvZjVSZWFkZXIucHJvdG90eXBlLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UgPSBmdW5jdGlvbihlbmRJbmZvKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kO1xyXG5cclxuICAgIHRyYWlsaW5nV2hpdGVzcGFjZUVuZCA9IGVuZEluZm8uZW5kICsgKChlbmRJbmZvLmVuZCAtIGVuZEluZm8uc3RhcnQpIC8gMik7XHJcbiAgICBpZiAodHJhaWxpbmdXaGl0ZXNwYWNlRW5kIDwgc2VsZi5fcm93Lmxlbmd0aCkge1xyXG4gICAgICAgIGlmIChzZWxmLl9tYXRjaFJhbmdlKGVuZEluZm8uZW5kLCB0cmFpbGluZ1doaXRlc3BhY2VFbmQsIDApKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbmRJbmZvO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuSTJvZjVSZWFkZXIucHJvdG90eXBlLl9maW5kRW5kID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgZW5kSW5mbyxcclxuICAgICAgICB0bXA7XHJcblxyXG4gICAgc2VsZi5fcm93LnJldmVyc2UoKTtcclxuICAgIGVuZEluZm8gPSBzZWxmLl9maW5kUGF0dGVybihzZWxmLlNUT1BfUEFUVEVSTik7XHJcbiAgICBzZWxmLl9yb3cucmV2ZXJzZSgpO1xyXG5cclxuICAgIGlmIChlbmRJbmZvID09PSBudWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmV2ZXJzZSBudW1iZXJzXHJcbiAgICB0bXAgPSBlbmRJbmZvLnN0YXJ0O1xyXG4gICAgZW5kSW5mby5zdGFydCA9IHNlbGYuX3Jvdy5sZW5ndGggLSBlbmRJbmZvLmVuZDtcclxuICAgIGVuZEluZm8uZW5kID0gc2VsZi5fcm93Lmxlbmd0aCAtIHRtcDtcclxuXHJcbiAgICByZXR1cm4gZW5kSW5mbyAhPT0gbnVsbCA/IHNlbGYuX3ZlcmlmeVRyYWlsaW5nV2hpdGVzcGFjZShlbmRJbmZvKSA6IG51bGw7XHJcbn07XHJcblxyXG5JMm9mNVJlYWRlci5wcm90b3R5cGUuX2RlY29kZVBhaXIgPSBmdW5jdGlvbihjb3VudGVyUGFpcikge1xyXG4gICAgdmFyIGksXHJcbiAgICAgICAgY29kZSxcclxuICAgICAgICBjb2RlcyA9IFtdLFxyXG4gICAgICAgIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudGVyUGFpci5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvZGUgPSBzZWxmLl9kZWNvZGVDb2RlKGNvdW50ZXJQYWlyW2ldKTtcclxuICAgICAgICBpZiAoIWNvZGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvZGVzLnB1c2goY29kZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY29kZXM7XHJcbn07XHJcblxyXG5JMm9mNVJlYWRlci5wcm90b3R5cGUuX2RlY29kZUNvZGUgPSBmdW5jdGlvbihjb3VudGVyKSB7XHJcbiAgICB2YXIgaixcclxuICAgICAgICBzZWxmID0gdGhpcyxcclxuICAgICAgICBzdW0gPSAwLFxyXG4gICAgICAgIG5vcm1hbGl6ZWQsXHJcbiAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgZXBzaWxvbiA9IHNlbGYuQVZHX0NPREVfRVJST1IsXHJcbiAgICAgICAgY29kZSxcclxuICAgICAgICBiZXN0TWF0Y2ggPSB7XHJcbiAgICAgICAgICAgIGVycm9yOiBOdW1iZXIuTUFYX1ZBTFVFLFxyXG4gICAgICAgICAgICBjb2RlOiAtMSxcclxuICAgICAgICAgICAgc3RhcnQ6IDAsXHJcbiAgICAgICAgICAgIGVuZDogMFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgZm9yICggaiA9IDA7IGogPCBjb3VudGVyLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgc3VtICs9IGNvdW50ZXJbal07XHJcbiAgICB9XHJcbiAgICBub3JtYWxpemVkID0gc2VsZi5fbm9ybWFsaXplKGNvdW50ZXIpO1xyXG4gICAgaWYgKG5vcm1hbGl6ZWQpIHtcclxuICAgICAgICBmb3IgKGNvZGUgPSAwOyBjb2RlIDwgc2VsZi5DT0RFX1BBVFRFUk4ubGVuZ3RoOyBjb2RlKyspIHtcclxuICAgICAgICAgICAgZXJyb3IgPSBzZWxmLl9tYXRjaFBhdHRlcm4obm9ybWFsaXplZCwgc2VsZi5DT0RFX1BBVFRFUk5bY29kZV0pO1xyXG4gICAgICAgICAgICBpZiAoZXJyb3IgPCBiZXN0TWF0Y2guZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5jb2RlID0gY29kZTtcclxuICAgICAgICAgICAgICAgIGJlc3RNYXRjaC5lcnJvciA9IGVycm9yO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChiZXN0TWF0Y2guZXJyb3IgPCBlcHNpbG9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBiZXN0TWF0Y2g7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbn07XHJcblxyXG5JMm9mNVJlYWRlci5wcm90b3R5cGUuX2RlY29kZVBheWxvYWQgPSBmdW5jdGlvbihjb3VudGVycywgcmVzdWx0LCBkZWNvZGVkQ29kZXMpIHtcclxuICAgIHZhciBpLFxyXG4gICAgICAgIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIHBvcyA9IDAsXHJcbiAgICAgICAgY291bnRlckxlbmd0aCA9IGNvdW50ZXJzLmxlbmd0aCxcclxuICAgICAgICBjb3VudGVyUGFpciA9IFtbMCwgMCwgMCwgMCwgMF0sIFswLCAwLCAwLCAwLCAwXV0sXHJcbiAgICAgICAgY29kZXM7XHJcblxyXG4gICAgd2hpbGUgKHBvcyA8IGNvdW50ZXJMZW5ndGgpIHtcclxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNTsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvdW50ZXJQYWlyWzBdW2ldID0gY291bnRlcnNbcG9zXSAqIHRoaXMuYmFyU3BhY2VSYXRpb1swXTtcclxuICAgICAgICAgICAgY291bnRlclBhaXJbMV1baV0gPSBjb3VudGVyc1twb3MgKyAxXSAqIHRoaXMuYmFyU3BhY2VSYXRpb1sxXTtcclxuICAgICAgICAgICAgcG9zICs9IDI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvZGVzID0gc2VsZi5fZGVjb2RlUGFpcihjb3VudGVyUGFpcik7XHJcbiAgICAgICAgaWYgKCFjb2Rlcykge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvZGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGNvZGVzW2ldLmNvZGUgKyBcIlwiKTtcclxuICAgICAgICAgICAgZGVjb2RlZENvZGVzLnB1c2goY29kZXNbaV0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjb2RlcztcclxufTtcclxuXHJcbkkyb2Y1UmVhZGVyLnByb3RvdHlwZS5fdmVyaWZ5Q291bnRlckxlbmd0aCA9IGZ1bmN0aW9uKGNvdW50ZXJzKSB7XHJcbiAgICByZXR1cm4gKGNvdW50ZXJzLmxlbmd0aCAlIDEwID09PSAwKTtcclxufTtcclxuXHJcbkkyb2Y1UmVhZGVyLnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgc3RhcnRJbmZvLFxyXG4gICAgICAgIGVuZEluZm8sXHJcbiAgICAgICAgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY29kZSxcclxuICAgICAgICByZXN1bHQgPSBbXSxcclxuICAgICAgICBkZWNvZGVkQ29kZXMgPSBbXSxcclxuICAgICAgICBjb3VudGVycztcclxuXHJcbiAgICBzdGFydEluZm8gPSBzZWxmLl9maW5kU3RhcnQoKTtcclxuICAgIGlmICghc3RhcnRJbmZvKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICBkZWNvZGVkQ29kZXMucHVzaChzdGFydEluZm8pO1xyXG5cclxuICAgIGVuZEluZm8gPSBzZWxmLl9maW5kRW5kKCk7XHJcbiAgICBpZiAoIWVuZEluZm8pIHtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBjb3VudGVycyA9IHNlbGYuX2ZpbGxDb3VudGVycyhzdGFydEluZm8uZW5kLCBlbmRJbmZvLnN0YXJ0LCBmYWxzZSk7XHJcbiAgICBpZiAoIXNlbGYuX3ZlcmlmeUNvdW50ZXJMZW5ndGgoY291bnRlcnMpKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICBjb2RlID0gc2VsZi5fZGVjb2RlUGF5bG9hZChjb3VudGVycywgcmVzdWx0LCBkZWNvZGVkQ29kZXMpO1xyXG4gICAgaWYgKCFjb2RlKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICBpZiAocmVzdWx0Lmxlbmd0aCAlIDIgIT09IDAgfHxcclxuICAgICAgICAgICAgcmVzdWx0Lmxlbmd0aCA8IDYpIHtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBkZWNvZGVkQ29kZXMucHVzaChlbmRJbmZvKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgY29kZTogcmVzdWx0LmpvaW4oXCJcIiksXHJcbiAgICAgICAgc3RhcnQ6IHN0YXJ0SW5mby5zdGFydCxcclxuICAgICAgICBlbmQ6IGVuZEluZm8uZW5kLFxyXG4gICAgICAgIHN0YXJ0SW5mbzogc3RhcnRJbmZvLFxyXG4gICAgICAgIGRlY29kZWRDb2RlczogZGVjb2RlZENvZGVzXHJcbiAgICB9O1xyXG59O1xyXG5cclxuSTJvZjVSZWFkZXIuQ09ORklHX0tFWVMgPSB7XHJcbiAgICBub3JtYWxpemVCYXJTcGFjZVdpZHRoOiB7XHJcbiAgICAgICAgJ3R5cGUnOiAnYm9vbGVhbicsXHJcbiAgICAgICAgJ2RlZmF1bHQnOiBmYWxzZSxcclxuICAgICAgICAnZGVzY3JpcHRpb24nOiAnSWYgdHJ1ZSwgdGhlIHJlYWRlciB0cmllcyB0byBub3JtYWxpemUgdGhlJyArXHJcbiAgICAgICAgJ3dpZHRoLWRpZmZlcmVuY2UgYmV0d2VlbiBiYXJzIGFuZCBzcGFjZXMnXHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBJMm9mNVJlYWRlcjtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvcmVhZGVyL2kyb2Y1X3JlYWRlci5qc1xuICoqLyIsImltcG9ydCBFQU5SZWFkZXIgZnJvbSAnLi9lYW5fcmVhZGVyJztcclxuXHJcbmZ1bmN0aW9uIFVQQ0VSZWFkZXIoKSB7XHJcbiAgICBFQU5SZWFkZXIuY2FsbCh0aGlzKTtcclxufVxyXG5cclxudmFyIHByb3BlcnRpZXMgPSB7XHJcbiAgICBDT0RFX0ZSRVFVRU5DWToge3ZhbHVlOiBbXHJcbiAgICAgICAgWyA1NiwgNTIsIDUwLCA0OSwgNDQsIDM4LCAzNSwgNDIsIDQxLCAzNyBdLFxyXG4gICAgICAgIFs3LCAxMSwgMTMsIDE0LCAxOSwgMjUsIDI4LCAyMSwgMjIsIDI2XV19LFxyXG4gICAgU1RPUF9QQVRURVJOOiB7IHZhbHVlOiBbMSAvIDYgKiA3LCAxIC8gNiAqIDcsIDEgLyA2ICogNywgMSAvIDYgKiA3LCAxIC8gNiAqIDcsIDEgLyA2ICogN119LFxyXG4gICAgRk9STUFUOiB7dmFsdWU6IFwidXBjX2VcIiwgd3JpdGVhYmxlOiBmYWxzZX1cclxufTtcclxuXHJcblVQQ0VSZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFQU5SZWFkZXIucHJvdG90eXBlLCBwcm9wZXJ0aWVzKTtcclxuVVBDRVJlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBVUENFUmVhZGVyO1xyXG5cclxuVVBDRVJlYWRlci5wcm90b3R5cGUuX2RlY29kZVBheWxvYWQgPSBmdW5jdGlvbihjb2RlLCByZXN1bHQsIGRlY29kZWRDb2Rlcykge1xyXG4gICAgdmFyIGksXHJcbiAgICAgICAgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY29kZUZyZXF1ZW5jeSA9IDB4MDtcclxuXHJcbiAgICBmb3IgKCBpID0gMDsgaSA8IDY7IGkrKykge1xyXG4gICAgICAgIGNvZGUgPSBzZWxmLl9kZWNvZGVDb2RlKGNvZGUuZW5kKTtcclxuICAgICAgICBpZiAoIWNvZGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjb2RlLmNvZGUgPj0gc2VsZi5DT0RFX0dfU1RBUlQpIHtcclxuICAgICAgICAgICAgY29kZS5jb2RlID0gY29kZS5jb2RlIC0gc2VsZi5DT0RFX0dfU1RBUlQ7XHJcbiAgICAgICAgICAgIGNvZGVGcmVxdWVuY3kgfD0gMSA8PCAoNSAtIGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXN1bHQucHVzaChjb2RlLmNvZGUpO1xyXG4gICAgICAgIGRlY29kZWRDb2Rlcy5wdXNoKGNvZGUpO1xyXG4gICAgfVxyXG4gICAgaWYgKCFzZWxmLl9kZXRlcm1pbmVQYXJpdHkoY29kZUZyZXF1ZW5jeSwgcmVzdWx0KSkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjb2RlO1xyXG59O1xyXG5cclxuVVBDRVJlYWRlci5wcm90b3R5cGUuX2RldGVybWluZVBhcml0eSA9IGZ1bmN0aW9uKGNvZGVGcmVxdWVuY3ksIHJlc3VsdCkge1xyXG4gICAgdmFyIGksXHJcbiAgICAgICAgbnJTeXN0ZW07XHJcblxyXG4gICAgZm9yIChuclN5c3RlbSA9IDA7IG5yU3lzdGVtIDwgdGhpcy5DT0RFX0ZSRVFVRU5DWS5sZW5ndGg7IG5yU3lzdGVtKyspe1xyXG4gICAgICAgIGZvciAoIGkgPSAwOyBpIDwgdGhpcy5DT0RFX0ZSRVFVRU5DWVtuclN5c3RlbV0ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGNvZGVGcmVxdWVuY3kgPT09IHRoaXMuQ09ERV9GUkVRVUVOQ1lbbnJTeXN0ZW1dW2ldKSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQudW5zaGlmdChuclN5c3RlbSk7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChpKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxuVVBDRVJlYWRlci5wcm90b3R5cGUuX2NvbnZlcnRUb1VQQ0EgPSBmdW5jdGlvbihyZXN1bHQpIHtcclxuICAgIHZhciB1cGNhID0gW3Jlc3VsdFswXV0sXHJcbiAgICAgICAgbGFzdERpZ2l0ID0gcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAyXTtcclxuXHJcbiAgICBpZiAobGFzdERpZ2l0IDw9IDIpIHtcclxuICAgICAgICB1cGNhID0gdXBjYS5jb25jYXQocmVzdWx0LnNsaWNlKDEsIDMpKVxyXG4gICAgICAgICAgICAuY29uY2F0KFtsYXN0RGlnaXQsIDAsIDAsIDAsIDBdKVxyXG4gICAgICAgICAgICAuY29uY2F0KHJlc3VsdC5zbGljZSgzLCA2KSk7XHJcbiAgICB9IGVsc2UgaWYgKGxhc3REaWdpdCA9PT0gMykge1xyXG4gICAgICAgIHVwY2EgPSB1cGNhLmNvbmNhdChyZXN1bHQuc2xpY2UoMSwgNCkpXHJcbiAgICAgICAgICAgIC5jb25jYXQoWzAsIDAsIDAsIDAsIDBdKVxyXG4gICAgICAgICAgICAuY29uY2F0KHJlc3VsdC5zbGljZSg0LCA2KSk7XHJcbiAgICB9IGVsc2UgaWYgKGxhc3REaWdpdCA9PT0gNCkge1xyXG4gICAgICAgIHVwY2EgPSB1cGNhLmNvbmNhdChyZXN1bHQuc2xpY2UoMSwgNSkpXHJcbiAgICAgICAgICAgIC5jb25jYXQoWzAsIDAsIDAsIDAsIDAsIHJlc3VsdFs1XV0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB1cGNhID0gdXBjYS5jb25jYXQocmVzdWx0LnNsaWNlKDEsIDYpKVxyXG4gICAgICAgICAgICAuY29uY2F0KFswLCAwLCAwLCAwLCBsYXN0RGlnaXRdKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGNhLnB1c2gocmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXSk7XHJcbiAgICByZXR1cm4gdXBjYTtcclxufTtcclxuXHJcblVQQ0VSZWFkZXIucHJvdG90eXBlLl9jaGVja3N1bSA9IGZ1bmN0aW9uKHJlc3VsdCkge1xyXG4gICAgcmV0dXJuIEVBTlJlYWRlci5wcm90b3R5cGUuX2NoZWNrc3VtLmNhbGwodGhpcywgdGhpcy5fY29udmVydFRvVVBDQShyZXN1bHQpKTtcclxufTtcclxuXHJcblVQQ0VSZWFkZXIucHJvdG90eXBlLl9maW5kRW5kID0gZnVuY3Rpb24ob2Zmc2V0LCBpc1doaXRlKSB7XHJcbiAgICBpc1doaXRlID0gdHJ1ZTtcclxuICAgIHJldHVybiBFQU5SZWFkZXIucHJvdG90eXBlLl9maW5kRW5kLmNhbGwodGhpcywgb2Zmc2V0LCBpc1doaXRlKTtcclxufTtcclxuXHJcblVQQ0VSZWFkZXIucHJvdG90eXBlLl92ZXJpZnlUcmFpbGluZ1doaXRlc3BhY2UgPSBmdW5jdGlvbihlbmRJbmZvKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgdHJhaWxpbmdXaGl0ZXNwYWNlRW5kO1xyXG5cclxuICAgIHRyYWlsaW5nV2hpdGVzcGFjZUVuZCA9IGVuZEluZm8uZW5kICsgKChlbmRJbmZvLmVuZCAtIGVuZEluZm8uc3RhcnQpIC8gMik7XHJcbiAgICBpZiAodHJhaWxpbmdXaGl0ZXNwYWNlRW5kIDwgc2VsZi5fcm93Lmxlbmd0aCkge1xyXG4gICAgICAgIGlmIChzZWxmLl9tYXRjaFJhbmdlKGVuZEluZm8uZW5kLCB0cmFpbGluZ1doaXRlc3BhY2VFbmQsIDApKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbmRJbmZvO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFVQQ0VSZWFkZXI7XHJcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vc3JjL3JlYWRlci91cGNfZV9yZWFkZXIuanNcbiAqKi8iLCJpbXBvcnQgRUFOUmVhZGVyIGZyb20gJy4vZWFuX3JlYWRlcic7XHJcblxyXG5mdW5jdGlvbiBVUENSZWFkZXIoKSB7XHJcbiAgICBFQU5SZWFkZXIuY2FsbCh0aGlzKTtcclxufVxyXG5cclxudmFyIHByb3BlcnRpZXMgPSB7XHJcbiAgICBGT1JNQVQ6IHt2YWx1ZTogXCJ1cGNfYVwiLCB3cml0ZWFibGU6IGZhbHNlfVxyXG59O1xyXG5cclxuVVBDUmVhZGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRUFOUmVhZGVyLnByb3RvdHlwZSwgcHJvcGVydGllcyk7XHJcblVQQ1JlYWRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBVUENSZWFkZXI7XHJcblxyXG5VUENSZWFkZXIucHJvdG90eXBlLl9kZWNvZGUgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciByZXN1bHQgPSBFQU5SZWFkZXIucHJvdG90eXBlLl9kZWNvZGUuY2FsbCh0aGlzKTtcclxuXHJcbiAgICBpZiAocmVzdWx0ICYmIHJlc3VsdC5jb2RlICYmIHJlc3VsdC5jb2RlLmxlbmd0aCA9PT0gMTMgJiYgcmVzdWx0LmNvZGUuY2hhckF0KDApID09PSBcIjBcIikge1xyXG4gICAgICAgIHJlc3VsdC5jb2RlID0gcmVzdWx0LmNvZGUuc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFVQQ1JlYWRlcjtcclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9zcmMvcmVhZGVyL3VwY19yZWFkZXIuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGNvcHlcblxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgbWF0MiB0byBhbm90aGVyXG4gKlxuICogQGFsaWFzIG1hdDIuY29weVxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7bWF0Mn0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDJ9IG91dFxuICovXG5mdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdXG4gIG91dFsxXSA9IGFbMV1cbiAgb3V0WzJdID0gYVsyXVxuICBvdXRbM10gPSBhWzNdXG4gIHJldHVybiBvdXRcbn1cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2dsLW1hdDIvY29weS5qc1xuICoqIG1vZHVsZSBpZCA9IDczXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgbWF0MlxuICpcbiAqIEBhbGlhcyBtYXQyLmNyZWF0ZVxuICogQHJldHVybnMge21hdDJ9IGEgbmV3IDJ4MiBtYXRyaXhcbiAqL1xuZnVuY3Rpb24gY3JlYXRlKCkge1xuICB2YXIgb3V0ID0gbmV3IEZsb2F0MzJBcnJheSg0KVxuICBvdXRbMF0gPSAxXG4gIG91dFsxXSA9IDBcbiAgb3V0WzJdID0gMFxuICBvdXRbM10gPSAxXG4gIHJldHVybiBvdXRcbn1cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2dsLW1hdDIvY3JlYXRlLmpzXG4gKiogbW9kdWxlIGlkID0gNzRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIm1vZHVsZS5leHBvcnRzID0gaW52ZXJ0XG5cbi8qKlxuICogSW52ZXJ0cyBhIG1hdDJcbiAqXG4gKiBAYWxpYXMgbWF0Mi5pbnZlcnRcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge21hdDJ9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xuZnVuY3Rpb24gaW52ZXJ0KG91dCwgYSkge1xuICB2YXIgYTAgPSBhWzBdXG4gIHZhciBhMSA9IGFbMV1cbiAgdmFyIGEyID0gYVsyXVxuICB2YXIgYTMgPSBhWzNdXG4gIHZhciBkZXQgPSBhMCAqIGEzIC0gYTIgKiBhMVxuXG4gIGlmICghZGV0KSByZXR1cm4gbnVsbFxuICBkZXQgPSAxLjAgLyBkZXRcblxuICBvdXRbMF0gPSAgYTMgKiBkZXRcbiAgb3V0WzFdID0gLWExICogZGV0XG4gIG91dFsyXSA9IC1hMiAqIGRldFxuICBvdXRbM10gPSAgYTAgKiBkZXRcblxuICByZXR1cm4gb3V0XG59XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9nbC1tYXQyL2ludmVydC5qc1xuICoqIG1vZHVsZSBpZCA9IDc1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IHNjYWxlXG5cbi8qKlxuICogU2NhbGVzIGEgdmVjMiBieSBhIHNjYWxhciBudW1iZXJcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHt2ZWMyfSBhIHRoZSB2ZWN0b3IgdG8gc2NhbGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgdmVjdG9yIGJ5XG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cbmZ1bmN0aW9uIHNjYWxlKG91dCwgYSwgYikge1xuICAgIG91dFswXSA9IGFbMF0gKiBiXG4gICAgb3V0WzFdID0gYVsxXSAqIGJcbiAgICByZXR1cm4gb3V0XG59XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZ2wtdmVjMi9zY2FsZS5qc1xuICoqIG1vZHVsZSBpZCA9IDc2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IHRyYW5zZm9ybU1hdDJcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWMyIHdpdGggYSBtYXQyXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxuICogQHBhcmFtIHttYXQyfSBtIG1hdHJpeCB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm1NYXQyKG91dCwgYSwgbSkge1xuICAgIHZhciB4ID0gYVswXSxcbiAgICAgICAgeSA9IGFbMV1cbiAgICBvdXRbMF0gPSBtWzBdICogeCArIG1bMl0gKiB5XG4gICAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzNdICogeVxuICAgIHJldHVybiBvdXRcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9nbC12ZWMyL3RyYW5zZm9ybU1hdDIuanNcbiAqKiBtb2R1bGUgaWQgPSA3N1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwibW9kdWxlLmV4cG9ydHMgPSBjbG9uZTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHZlYzMgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyB2ZWN0b3JcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IGEgdmVjdG9yIHRvIGNsb25lXG4gKiBAcmV0dXJucyB7dmVjM30gYSBuZXcgM0QgdmVjdG9yXG4gKi9cbmZ1bmN0aW9uIGNsb25lKGEpIHtcbiAgICB2YXIgb3V0ID0gbmV3IEZsb2F0MzJBcnJheSgzKVxuICAgIG91dFswXSA9IGFbMF1cbiAgICBvdXRbMV0gPSBhWzFdXG4gICAgb3V0WzJdID0gYVsyXVxuICAgIHJldHVybiBvdXRcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9nbC12ZWMzL2Nsb25lLmpzXG4gKiogbW9kdWxlIGlkID0gNzhcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBuYXRpdmVDcmVhdGUgPSByZXF1aXJlKCcuL19uYXRpdmVDcmVhdGUnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGhhc2ggb2JqZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBoYXNoIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gSGFzaCgpIHt9XG5cbi8vIEF2b2lkIGluaGVyaXRpbmcgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAgd2hlbiBwb3NzaWJsZS5cbkhhc2gucHJvdG90eXBlID0gbmF0aXZlQ3JlYXRlID8gbmF0aXZlQ3JlYXRlKG51bGwpIDogb2JqZWN0UHJvdG87XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fSGFzaC5qc1xuICoqIG1vZHVsZSBpZCA9IDc5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgbWFwQ2xlYXIgPSByZXF1aXJlKCcuL19tYXBDbGVhcicpLFxuICAgIG1hcERlbGV0ZSA9IHJlcXVpcmUoJy4vX21hcERlbGV0ZScpLFxuICAgIG1hcEdldCA9IHJlcXVpcmUoJy4vX21hcEdldCcpLFxuICAgIG1hcEhhcyA9IHJlcXVpcmUoJy4vX21hcEhhcycpLFxuICAgIG1hcFNldCA9IHJlcXVpcmUoJy4vX21hcFNldCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXAgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGNhY2hlLlxuICovXG5mdW5jdGlvbiBNYXBDYWNoZSh2YWx1ZXMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSB2YWx1ZXMgPyB2YWx1ZXMubGVuZ3RoIDogMDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gdmFsdWVzW2luZGV4XTtcbiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG59XG5cbi8vIEFkZCBmdW5jdGlvbnMgdG8gdGhlIGBNYXBDYWNoZWAuXG5NYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDbGVhcjtcbk1hcENhY2hlLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBtYXBEZWxldGU7XG5NYXBDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbWFwR2V0O1xuTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcEhhcztcbk1hcENhY2hlLnByb3RvdHlwZS5zZXQgPSBtYXBTZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gTWFwQ2FjaGU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX01hcENhY2hlLmpzXG4gKiogbW9kdWxlIGlkID0gODBcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBSZWZsZWN0ID0gcm9vdC5SZWZsZWN0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlZmxlY3Q7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX1JlZmxlY3QuanNcbiAqKiBtb2R1bGUgaWQgPSA4MVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBTZXQgPSBnZXROYXRpdmUocm9vdCwgJ1NldCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNldDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fU2V0LmpzXG4gKiogbW9kdWxlIGlkID0gODJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBTeW1ib2wgPSByb290LlN5bWJvbDtcblxubW9kdWxlLmV4cG9ydHMgPSBTeW1ib2w7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX1N5bWJvbC5qc1xuICoqIG1vZHVsZSBpZCA9IDgzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgVWludDhBcnJheSA9IHJvb3QuVWludDhBcnJheTtcblxubW9kdWxlLmV4cG9ydHMgPSBVaW50OEFycmF5O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19VaW50OEFycmF5LmpzXG4gKiogbW9kdWxlIGlkID0gODRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgV2Vha01hcCA9IGdldE5hdGl2ZShyb290LCAnV2Vha01hcCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYWtNYXA7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX1dlYWtNYXAuanNcbiAqKiBtb2R1bGUgaWQgPSA4NVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBBZGRzIHRoZSBrZXktdmFsdWUgYHBhaXJgIHRvIGBtYXBgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gbWFwIFRoZSBtYXAgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtBcnJheX0gcGFpciBUaGUga2V5LXZhbHVlIHBhaXIgdG8gYWRkLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgbWFwYC5cbiAqL1xuZnVuY3Rpb24gYWRkTWFwRW50cnkobWFwLCBwYWlyKSB7XG4gIC8vIERvbid0IHJldHVybiBgTWFwI3NldGAgYmVjYXVzZSBpdCBkb2Vzbid0IHJldHVybiB0aGUgbWFwIGluc3RhbmNlIGluIElFIDExLlxuICBtYXAuc2V0KHBhaXJbMF0sIHBhaXJbMV0pO1xuICByZXR1cm4gbWFwO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFkZE1hcEVudHJ5O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19hZGRNYXBFbnRyeS5qc1xuICoqIG1vZHVsZSBpZCA9IDg2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIEFkZHMgYHZhbHVlYCB0byBgc2V0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFkZC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYHNldGAuXG4gKi9cbmZ1bmN0aW9uIGFkZFNldEVudHJ5KHNldCwgdmFsdWUpIHtcbiAgc2V0LmFkZCh2YWx1ZSk7XG4gIHJldHVybiBzZXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYWRkU2V0RW50cnk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2FkZFNldEVudHJ5LmpzXG4gKiogbW9kdWxlIGlkID0gODdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxuICogQSBmYXN0ZXIgYWx0ZXJuYXRpdmUgdG8gYEZ1bmN0aW9uI2FwcGx5YCwgdGhpcyBmdW5jdGlvbiBpbnZva2VzIGBmdW5jYFxuICogd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYXJndW1lbnRzIG9mIGBhcmdzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0gey4uLip9IGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgYGZ1bmNgIHdpdGguXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzdWx0IG9mIGBmdW5jYC5cbiAqL1xuZnVuY3Rpb24gYXBwbHkoZnVuYywgdGhpc0FyZywgYXJncykge1xuICB2YXIgbGVuZ3RoID0gYXJncy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuZ3RoKSB7XG4gICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcpO1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhcmdzWzBdKTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICB9XG4gIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFwcGx5O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19hcHBseS5qc1xuICoqIG1vZHVsZSBpZCA9IDg4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIEFwcGVuZHMgdGhlIGVsZW1lbnRzIG9mIGB2YWx1ZXNgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBhcHBlbmQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlQdXNoKGFycmF5LCB2YWx1ZXMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgb2Zmc2V0ID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgYXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gdmFsdWVzW2luZGV4XTtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlQdXNoO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19hcnJheVB1c2guanNcbiAqKiBtb2R1bGUgaWQgPSA4OVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmFzc2lnbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gKiBvciBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUFzc2lnbihvYmplY3QsIHNvdXJjZSkge1xuICByZXR1cm4gb2JqZWN0ICYmIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzKHNvdXJjZSksIG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUFzc2lnbjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYmFzZUFzc2lnbi5qc1xuICoqIG1vZHVsZSBpZCA9IDkwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vX2FycmF5RWFjaCcpLFxuICAgIGFzc2lnblZhbHVlID0gcmVxdWlyZSgnLi9fYXNzaWduVmFsdWUnKSxcbiAgICBiYXNlQXNzaWduID0gcmVxdWlyZSgnLi9fYmFzZUFzc2lnbicpLFxuICAgIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL19iYXNlRm9yT3duJyksXG4gICAgY2xvbmVCdWZmZXIgPSByZXF1aXJlKCcuL19jbG9uZUJ1ZmZlcicpLFxuICAgIGNvcHlBcnJheSA9IHJlcXVpcmUoJy4vX2NvcHlBcnJheScpLFxuICAgIGNvcHlTeW1ib2xzID0gcmVxdWlyZSgnLi9fY29weVN5bWJvbHMnKSxcbiAgICBnZXRUYWcgPSByZXF1aXJlKCcuL19nZXRUYWcnKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vX2luaXRDbG9uZUFycmF5JyksXG4gICAgaW5pdENsb25lQnlUYWcgPSByZXF1aXJlKCcuL19pbml0Q2xvbmVCeVRhZycpLFxuICAgIGluaXRDbG9uZU9iamVjdCA9IHJlcXVpcmUoJy4vX2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL19pc0hvc3RPYmplY3QnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIHN1cHBvcnRlZCBieSBgXy5jbG9uZWAuICovXG52YXIgY2xvbmVhYmxlVGFncyA9IHt9O1xuY2xvbmVhYmxlVGFnc1thcmdzVGFnXSA9IGNsb25lYWJsZVRhZ3NbYXJyYXlUYWddID1cbmNsb25lYWJsZVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gY2xvbmVhYmxlVGFnc1tib29sVGFnXSA9XG5jbG9uZWFibGVUYWdzW2RhdGVUYWddID0gY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9XG5jbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQ4VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9IGNsb25lYWJsZVRhZ3NbaW50MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9IGNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9XG5jbG9uZWFibGVUYWdzW29iamVjdFRhZ10gPSBjbG9uZWFibGVUYWdzW3JlZ2V4cFRhZ10gPVxuY2xvbmVhYmxlVGFnc1tzZXRUYWddID0gY2xvbmVhYmxlVGFnc1tzdHJpbmdUYWddID1cbmNsb25lYWJsZVRhZ3Nbc3ltYm9sVGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhUYWddID1cbmNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDE2VGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbmNsb25lYWJsZVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgYW5kIGBfLmNsb25lRGVlcGAgd2hpY2ggdHJhY2tzXG4gKiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNGdWxsXSBTcGVjaWZ5IGEgY2xvbmUgaW5jbHVkaW5nIHN5bWJvbHMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgcGFyZW50IG9iamVjdCBvZiBgdmFsdWVgLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGFuZCB0aGVpciBjbG9uZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgaXNGdWxsLCBjdXN0b21pemVyLCBrZXksIG9iamVjdCwgc3RhY2spIHtcbiAgdmFyIHJlc3VsdDtcbiAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICByZXN1bHQgPSBvYmplY3QgPyBjdXN0b21pemVyKHZhbHVlLCBrZXksIG9iamVjdCwgc3RhY2spIDogY3VzdG9taXplcih2YWx1ZSk7XG4gIH1cbiAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgaWYgKGlzQXJyKSB7XG4gICAgcmVzdWx0ID0gaW5pdENsb25lQXJyYXkodmFsdWUpO1xuICAgIGlmICghaXNEZWVwKSB7XG4gICAgICByZXR1cm4gY29weUFycmF5KHZhbHVlLCByZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKSxcbiAgICAgICAgaXNGdW5jID0gdGFnID09IGZ1bmNUYWcgfHwgdGFnID09IGdlblRhZztcblxuICAgIGlmIChpc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjbG9uZUJ1ZmZlcih2YWx1ZSwgaXNEZWVwKTtcbiAgICB9XG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgaWYgKGlzSG9zdE9iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVPYmplY3QoaXNGdW5jID8ge30gOiB2YWx1ZSk7XG4gICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICByZXN1bHQgPSBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gaXNGdWxsID8gY29weVN5bWJvbHModmFsdWUsIHJlc3VsdCkgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghY2xvbmVhYmxlVGFnc1t0YWddKSB7XG4gICAgICAgIHJldHVybiBvYmplY3QgPyB2YWx1ZSA6IHt9O1xuICAgICAgfVxuICAgICAgcmVzdWx0ID0gaW5pdENsb25lQnlUYWcodmFsdWUsIHRhZywgaXNEZWVwKTtcbiAgICB9XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgYW5kIHJldHVybiBpdHMgY29ycmVzcG9uZGluZyBjbG9uZS5cbiAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgdmFyIHN0YWNrZWQgPSBzdGFjay5nZXQodmFsdWUpO1xuICBpZiAoc3RhY2tlZCkge1xuICAgIHJldHVybiBzdGFja2VkO1xuICB9XG4gIHN0YWNrLnNldCh2YWx1ZSwgcmVzdWx0KTtcblxuICAvLyBSZWN1cnNpdmVseSBwb3B1bGF0ZSBjbG9uZSAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAoaXNBcnIgPyBhcnJheUVhY2ggOiBiYXNlRm9yT3duKSh2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgIGFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCBiYXNlQ2xvbmUoc3ViVmFsdWUsIGlzRGVlcCwgaXNGdWxsLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFjaykpO1xuICB9KTtcbiAgcmV0dXJuIChpc0Z1bGwgJiYgIWlzQXJyKSA/IGNvcHlTeW1ib2xzKHZhbHVlLCByZXN1bHQpIDogcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDbG9uZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYmFzZUNsb25lLmpzXG4gKiogbW9kdWxlIGlkID0gOTFcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jcmVhdGVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXNzaWduaW5nXG4gKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvdHlwZSBUaGUgb2JqZWN0IHRvIGluaGVyaXQgZnJvbS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGJhc2VDcmVhdGUocHJvdG8pIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHByb3RvKSA/IG9iamVjdENyZWF0ZShwcm90bykgOiB7fTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19iYXNlQ3JlYXRlLmpzXG4gKiogbW9kdWxlIGlkID0gOTJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBhcnJheVB1c2ggPSByZXF1aXJlKCcuL19hcnJheVB1c2gnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2VPYmplY3QgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmxhdHRlbmAgd2l0aCBzdXBwb3J0IGZvciByZXN0cmljdGluZyBmbGF0dGVuaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkZXB0aCBUaGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGguXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc1N0cmljdF0gUmVzdHJpY3QgZmxhdHRlbmluZyB0byBhcnJheXMtbGlrZSBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdD1bXV0gVGhlIGluaXRpYWwgcmVzdWx0IHZhbHVlLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlRmxhdHRlbihhcnJheSwgZGVwdGgsIGlzU3RyaWN0LCByZXN1bHQpIHtcbiAgcmVzdWx0IHx8IChyZXN1bHQgPSBbXSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgaWYgKGRlcHRoID4gMCAmJiBpc0FycmF5TGlrZU9iamVjdCh2YWx1ZSkgJiZcbiAgICAgICAgKGlzU3RyaWN0IHx8IGlzQXJyYXkodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSkpIHtcbiAgICAgIGlmIChkZXB0aCA+IDEpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgZmxhdHRlbiBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgYmFzZUZsYXR0ZW4odmFsdWUsIGRlcHRoIC0gMSwgaXNTdHJpY3QsIHJlc3VsdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhcnJheVB1c2gocmVzdWx0LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghaXNTdHJpY3QpIHtcbiAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGbGF0dGVuO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19iYXNlRmxhdHRlbi5qc1xuICoqIG1vZHVsZSBpZCA9IDkzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgY3JlYXRlQmFzZUZvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUJhc2VGb3InKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYmFzZUZvckluYCBhbmQgYGJhc2VGb3JPd25gIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBvYmplY3RgIHByb3BlcnRpZXMgcmV0dXJuZWQgYnkgYGtleXNGdW5jYCBpbnZva2luZyBgaXRlcmF0ZWVgIGZvclxuICogZWFjaCBwcm9wZXJ0eS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5XG4gKiByZXR1cm5pbmcgYGZhbHNlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xudmFyIGJhc2VGb3IgPSBjcmVhdGVCYXNlRm9yKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZvcjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYmFzZUZvci5qc1xuICoqIG1vZHVsZSBpZCA9IDk0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vX2Jhc2VGb3InKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgYmFzZUZvcihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9yT3duO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19iYXNlRm9yT3duLmpzXG4gKiogbW9kdWxlIGlkID0gOTVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIGdldFByb3RvdHlwZU9mID0gT2JqZWN0LmdldFByb3RvdHlwZU9mO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmhhc2Agd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30ga2V5IFRoZSBrZXkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VIYXMob2JqZWN0LCBrZXkpIHtcbiAgLy8gQXZvaWQgYSBidWcgaW4gSUUgMTAtMTEgd2hlcmUgb2JqZWN0cyB3aXRoIGEgW1tQcm90b3R5cGVdXSBvZiBgbnVsbGAsXG4gIC8vIHRoYXQgYXJlIGNvbXBvc2VkIGVudGlyZWx5IG9mIGluZGV4IHByb3BlcnRpZXMsIHJldHVybiBgZmFsc2VgIGZvclxuICAvLyBgaGFzT3duUHJvcGVydHlgIGNoZWNrcyBvZiB0aGVtLlxuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgfHxcbiAgICAodHlwZW9mIG9iamVjdCA9PSAnb2JqZWN0JyAmJiBrZXkgaW4gb2JqZWN0ICYmIGdldFByb3RvdHlwZU9mKG9iamVjdCkgPT09IG51bGwpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VIYXM7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Jhc2VIYXMuanNcbiAqKiBtb2R1bGUgaWQgPSA5NlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZUtleXMgPSBPYmplY3Qua2V5cztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzYCB3aGljaCBkb2Vzbid0IHNraXAgdGhlIGNvbnN0cnVjdG9yXG4gKiBwcm9wZXJ0eSBvZiBwcm90b3R5cGVzIG9yIHRyZWF0IHNwYXJzZSBhcnJheXMgYXMgZGVuc2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VLZXlzKG9iamVjdCkge1xuICByZXR1cm4gbmF0aXZlS2V5cyhPYmplY3Qob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUtleXM7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Jhc2VLZXlzLmpzXG4gKiogbW9kdWxlIGlkID0gOTdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBSZWZsZWN0ID0gcmVxdWlyZSgnLi9fUmVmbGVjdCcpLFxuICAgIGl0ZXJhdG9yVG9BcnJheSA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9yVG9BcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBlbnVtZXJhdGUgPSBSZWZsZWN0ID8gUmVmbGVjdC5lbnVtZXJhdGUgOiB1bmRlZmluZWQsXG4gICAgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzSW5gIHdoaWNoIGRvZXNuJ3Qgc2tpcCB0aGUgY29uc3RydWN0b3JcbiAqIHByb3BlcnR5IG9mIHByb3RvdHlwZXMgb3IgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gYmFzZUtleXNJbihvYmplY3QpIHtcbiAgb2JqZWN0ID0gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBPYmplY3Qob2JqZWN0KTtcblxuICB2YXIgcmVzdWx0ID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICByZXN1bHQucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIEZhbGxiYWNrIGZvciBJRSA8IDkgd2l0aCBlczYtc2hpbS5cbmlmIChlbnVtZXJhdGUgJiYgIXByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoeyAndmFsdWVPZic6IDEgfSwgJ3ZhbHVlT2YnKSkge1xuICBiYXNlS2V5c0luID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIGl0ZXJhdG9yVG9BcnJheShlbnVtZXJhdGUob2JqZWN0KSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUtleXNJbjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYmFzZUtleXNJbi5qc1xuICoqIG1vZHVsZSBpZCA9IDk4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vX2FycmF5RWFjaCcpLFxuICAgIGFzc2lnbk1lcmdlVmFsdWUgPSByZXF1aXJlKCcuL19hc3NpZ25NZXJnZVZhbHVlJyksXG4gICAgYmFzZU1lcmdlRGVlcCA9IHJlcXVpcmUoJy4vX2Jhc2VNZXJnZURlZXAnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgaXNUeXBlZEFycmF5ID0gcmVxdWlyZSgnLi9pc1R5cGVkQXJyYXknKSxcbiAgICBrZXlzSW4gPSByZXF1aXJlKCcuL2tleXNJbicpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1lcmdlYCB3aXRob3V0IHN1cHBvcnQgZm9yIG11bHRpcGxlIHNvdXJjZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcGFyYW0ge251bWJlcn0gc3JjSW5kZXggVGhlIGluZGV4IG9mIGBzb3VyY2VgLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgbWVyZ2VkIHZhbHVlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIHZhbHVlcyBhbmQgdGhlaXIgbWVyZ2VkIGNvdW50ZXJwYXJ0cy5cbiAqL1xuZnVuY3Rpb24gYmFzZU1lcmdlKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplciwgc3RhY2spIHtcbiAgaWYgKG9iamVjdCA9PT0gc291cmNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBwcm9wcyA9IChpc0FycmF5KHNvdXJjZSkgfHwgaXNUeXBlZEFycmF5KHNvdXJjZSkpXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IGtleXNJbihzb3VyY2UpO1xuXG4gIGFycmF5RWFjaChwcm9wcyB8fCBzb3VyY2UsIGZ1bmN0aW9uKHNyY1ZhbHVlLCBrZXkpIHtcbiAgICBpZiAocHJvcHMpIHtcbiAgICAgIGtleSA9IHNyY1ZhbHVlO1xuICAgICAgc3JjVmFsdWUgPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gICAgaWYgKGlzT2JqZWN0KHNyY1ZhbHVlKSkge1xuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIGJhc2VNZXJnZSwgY3VzdG9taXplciwgc3RhY2spO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHZhciBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXJcbiAgICAgICAgPyBjdXN0b21pemVyKG9iamVjdFtrZXldLCBzcmNWYWx1ZSwgKGtleSArICcnKSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKVxuICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbmV3VmFsdWUgPSBzcmNWYWx1ZTtcbiAgICAgIH1cbiAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNZXJnZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYmFzZU1lcmdlLmpzXG4gKiogbW9kdWxlIGlkID0gOTlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBhc3NpZ25NZXJnZVZhbHVlID0gcmVxdWlyZSgnLi9fYXNzaWduTWVyZ2VWYWx1ZScpLFxuICAgIGJhc2VDbG9uZSA9IHJlcXVpcmUoJy4vX2Jhc2VDbG9uZScpLFxuICAgIGNvcHlBcnJheSA9IHJlcXVpcmUoJy4vX2NvcHlBcnJheScpLFxuICAgIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0FycmF5TGlrZU9iamVjdCA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2VPYmplY3QnKSxcbiAgICBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgaXNQbGFpbk9iamVjdCA9IHJlcXVpcmUoJy4vaXNQbGFpbk9iamVjdCcpLFxuICAgIGlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vaXNUeXBlZEFycmF5JyksXG4gICAgdG9QbGFpbk9iamVjdCA9IHJlcXVpcmUoJy4vdG9QbGFpbk9iamVjdCcpO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZU1lcmdlYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zXG4gKiBkZWVwIG1lcmdlcyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICogcmVmZXJlbmNlcyB0byBiZSBtZXJnZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIG1lcmdlLlxuICogQHBhcmFtIHtudW1iZXJ9IHNyY0luZGV4IFRoZSBpbmRleCBvZiBgc291cmNlYC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1lcmdlRnVuYyBUaGUgZnVuY3Rpb24gdG8gbWVyZ2UgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2UgdmFsdWVzIGFuZCB0aGVpciBtZXJnZWQgY291bnRlcnBhcnRzLlxuICovXG5mdW5jdGlvbiBiYXNlTWVyZ2VEZWVwKG9iamVjdCwgc291cmNlLCBrZXksIHNyY0luZGV4LCBtZXJnZUZ1bmMsIGN1c3RvbWl6ZXIsIHN0YWNrKSB7XG4gIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgc3JjVmFsdWUgPSBzb3VyY2Vba2V5XSxcbiAgICAgIHN0YWNrZWQgPSBzdGFjay5nZXQoc3JjVmFsdWUpO1xuXG4gIGlmIChzdGFja2VkKSB7XG4gICAgYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgc3RhY2tlZCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXJcbiAgICA/IGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlLCAoa2V5ICsgJycpLCBvYmplY3QsIHNvdXJjZSwgc3RhY2spXG4gICAgOiB1bmRlZmluZWQ7XG5cbiAgdmFyIGlzQ29tbW9uID0gbmV3VmFsdWUgPT09IHVuZGVmaW5lZDtcblxuICBpZiAoaXNDb21tb24pIHtcbiAgICBuZXdWYWx1ZSA9IHNyY1ZhbHVlO1xuICAgIGlmIChpc0FycmF5KHNyY1ZhbHVlKSB8fCBpc1R5cGVkQXJyYXkoc3JjVmFsdWUpKSB7XG4gICAgICBpZiAoaXNBcnJheShvYmpWYWx1ZSkpIHtcbiAgICAgICAgbmV3VmFsdWUgPSBvYmpWYWx1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KG9ialZhbHVlKSkge1xuICAgICAgICBuZXdWYWx1ZSA9IGNvcHlBcnJheShvYmpWYWx1ZSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgbmV3VmFsdWUgPSBiYXNlQ2xvbmUoc3JjVmFsdWUsICFjdXN0b21pemVyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAoaXNQbGFpbk9iamVjdChzcmNWYWx1ZSkgfHwgaXNBcmd1bWVudHMoc3JjVmFsdWUpKSB7XG4gICAgICBpZiAoaXNBcmd1bWVudHMob2JqVmFsdWUpKSB7XG4gICAgICAgIG5ld1ZhbHVlID0gdG9QbGFpbk9iamVjdChvYmpWYWx1ZSk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmICghaXNPYmplY3Qob2JqVmFsdWUpIHx8IChzcmNJbmRleCAmJiBpc0Z1bmN0aW9uKG9ialZhbHVlKSkpIHtcbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgbmV3VmFsdWUgPSBiYXNlQ2xvbmUoc3JjVmFsdWUsICFjdXN0b21pemVyKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBuZXdWYWx1ZSA9IG9ialZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIHN0YWNrLnNldChzcmNWYWx1ZSwgbmV3VmFsdWUpO1xuXG4gIGlmIChpc0NvbW1vbikge1xuICAgIC8vIFJlY3Vyc2l2ZWx5IG1lcmdlIG9iamVjdHMgYW5kIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgIG1lcmdlRnVuYyhuZXdWYWx1ZSwgc3JjVmFsdWUsIHNyY0luZGV4LCBjdXN0b21pemVyLCBzdGFjayk7XG4gIH1cbiAgc3RhY2tbJ2RlbGV0ZSddKHNyY1ZhbHVlKTtcbiAgYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgbmV3VmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNZXJnZURlZXA7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Jhc2VNZXJnZURlZXAuanNcbiAqKiBtb2R1bGUgaWQgPSAxMDBcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBhcnJheVJlZHVjZSA9IHJlcXVpcmUoJy4vX2FycmF5UmVkdWNlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucGlja2Agd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsXG4gKiBwcm9wZXJ0eSBuYW1lcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBwaWNrLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gYmFzZVBpY2sob2JqZWN0LCBwcm9wcykge1xuICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgcmV0dXJuIGFycmF5UmVkdWNlKHByb3BzLCBmdW5jdGlvbihyZXN1bHQsIGtleSkge1xuICAgIGlmIChrZXkgaW4gb2JqZWN0KSB7XG4gICAgICByZXN1bHRba2V5XSA9IG9iamVjdFtrZXldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LCB7fSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVBpY2s7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Jhc2VQaWNrLmpzXG4gKiogbW9kdWxlIGlkID0gMTAxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYmFzZVByb3BlcnR5LmpzXG4gKiogbW9kdWxlIGlkID0gMTAyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRpbWVzYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHNcbiAqIG9yIG1heCBhcnJheSBsZW5ndGggY2hlY2tzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAqL1xuZnVuY3Rpb24gYmFzZVRpbWVzKG4sIGl0ZXJhdGVlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobik7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBuKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGluZGV4KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUaW1lcztcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fYmFzZVRpbWVzLmpzXG4gKiogbW9kdWxlIGlkID0gMTAzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgZ2xvYmFsIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7bnVsbHxPYmplY3R9IFJldHVybnMgYHZhbHVlYCBpZiBpdCdzIGEgZ2xvYmFsIG9iamVjdCwgZWxzZSBgbnVsbGAuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrR2xvYmFsKHZhbHVlKSB7XG4gIHJldHVybiAodmFsdWUgJiYgdmFsdWUuT2JqZWN0ID09PSBPYmplY3QpID8gdmFsdWUgOiBudWxsO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNoZWNrR2xvYmFsO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19jaGVja0dsb2JhbC5qc1xuICoqIG1vZHVsZSBpZCA9IDEwNFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgIGBidWZmZXJgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyIFRoZSBidWZmZXIgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHJldHVybnMge0J1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGJ1ZmZlci5cbiAqL1xuZnVuY3Rpb24gY2xvbmVCdWZmZXIoYnVmZmVyLCBpc0RlZXApIHtcbiAgaWYgKGlzRGVlcCkge1xuICAgIHJldHVybiBidWZmZXIuc2xpY2UoKTtcbiAgfVxuICB2YXIgcmVzdWx0ID0gbmV3IGJ1ZmZlci5jb25zdHJ1Y3RvcihidWZmZXIubGVuZ3RoKTtcbiAgYnVmZmVyLmNvcHkocmVzdWx0KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZUJ1ZmZlcjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fY2xvbmVCdWZmZXIuanNcbiAqKiBtb2R1bGUgaWQgPSAxMDVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBhZGRNYXBFbnRyeSA9IHJlcXVpcmUoJy4vX2FkZE1hcEVudHJ5JyksXG4gICAgYXJyYXlSZWR1Y2UgPSByZXF1aXJlKCcuL19hcnJheVJlZHVjZScpLFxuICAgIG1hcFRvQXJyYXkgPSByZXF1aXJlKCcuL19tYXBUb0FycmF5Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIGBtYXBgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gbWFwIFRoZSBtYXAgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgbWFwLlxuICovXG5mdW5jdGlvbiBjbG9uZU1hcChtYXApIHtcbiAgcmV0dXJuIGFycmF5UmVkdWNlKG1hcFRvQXJyYXkobWFwKSwgYWRkTWFwRW50cnksIG5ldyBtYXAuY29uc3RydWN0b3IpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lTWFwO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19jbG9uZU1hcC5qc1xuICoqIG1vZHVsZSBpZCA9IDEwNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGAgZmxhZ3MgZnJvbSB0aGVpciBjb2VyY2VkIHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVGbGFncyA9IC9cXHcqJC87XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIGByZWdleHBgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gcmVnZXhwIFRoZSByZWdleHAgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgcmVnZXhwLlxuICovXG5mdW5jdGlvbiBjbG9uZVJlZ0V4cChyZWdleHApIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyByZWdleHAuY29uc3RydWN0b3IocmVnZXhwLnNvdXJjZSwgcmVGbGFncy5leGVjKHJlZ2V4cCkpO1xuICByZXN1bHQubGFzdEluZGV4ID0gcmVnZXhwLmxhc3RJbmRleDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZVJlZ0V4cDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fY2xvbmVSZWdFeHAuanNcbiAqKiBtb2R1bGUgaWQgPSAxMDdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBhZGRTZXRFbnRyeSA9IHJlcXVpcmUoJy4vX2FkZFNldEVudHJ5JyksXG4gICAgYXJyYXlSZWR1Y2UgPSByZXF1aXJlKCcuL19hcnJheVJlZHVjZScpLFxuICAgIHNldFRvQXJyYXkgPSByZXF1aXJlKCcuL19zZXRUb0FycmF5Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIGBzZXRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc2V0IFRoZSBzZXQgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgc2V0LlxuICovXG5mdW5jdGlvbiBjbG9uZVNldChzZXQpIHtcbiAgcmV0dXJuIGFycmF5UmVkdWNlKHNldFRvQXJyYXkoc2V0KSwgYWRkU2V0RW50cnksIG5ldyBzZXQuY29uc3RydWN0b3IpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lU2V0O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19jbG9uZVNldC5qc1xuICoqIG1vZHVsZSBpZCA9IDEwOFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbnZhciBzeW1ib2xQcm90byA9IFN5bWJvbCA/IFN5bWJvbC5wcm90b3R5cGUgOiB1bmRlZmluZWQsXG4gICAgc3ltYm9sVmFsdWVPZiA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udmFsdWVPZiA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGBzeW1ib2xgIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN5bWJvbCBUaGUgc3ltYm9sIG9iamVjdCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBzeW1ib2wgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBjbG9uZVN5bWJvbChzeW1ib2wpIHtcbiAgcmV0dXJuIHN5bWJvbFZhbHVlT2YgPyBPYmplY3Qoc3ltYm9sVmFsdWVPZi5jYWxsKHN5bWJvbCkpIDoge307XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmVTeW1ib2w7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Nsb25lU3ltYm9sLmpzXG4gKiogbW9kdWxlIGlkID0gMTA5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgY2xvbmVBcnJheUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2Nsb25lQXJyYXlCdWZmZXInKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHR5cGVkQXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gdHlwZWRBcnJheSBUaGUgdHlwZWQgYXJyYXkgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHR5cGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBjbG9uZVR5cGVkQXJyYXkodHlwZWRBcnJheSwgaXNEZWVwKSB7XG4gIHZhciBidWZmZXIgPSBpc0RlZXAgPyBjbG9uZUFycmF5QnVmZmVyKHR5cGVkQXJyYXkuYnVmZmVyKSA6IHR5cGVkQXJyYXkuYnVmZmVyO1xuICByZXR1cm4gbmV3IHR5cGVkQXJyYXkuY29uc3RydWN0b3IoYnVmZmVyLCB0eXBlZEFycmF5LmJ5dGVPZmZzZXQsIHR5cGVkQXJyYXkubGVuZ3RoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZVR5cGVkQXJyYXk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2Nsb25lVHlwZWRBcnJheS5qc1xuICoqIG1vZHVsZSBpZCA9IDExMFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGFzc2lnblZhbHVlID0gcmVxdWlyZSgnLi9fYXNzaWduVmFsdWUnKTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvcHlPYmplY3RgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYSBmdW5jdGlvbiB0b1xuICogY3VzdG9taXplIGNvcGllZCB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBjb3B5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29waWVkIHZhbHVlcy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlPYmplY3RXaXRoKHNvdXJjZSwgcHJvcHMsIG9iamVjdCwgY3VzdG9taXplcikge1xuICBvYmplY3QgfHwgKG9iamVjdCA9IHt9KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG5cbiAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICA/IGN1c3RvbWl6ZXIob2JqZWN0W2tleV0sIHNvdXJjZVtrZXldLCBrZXksIG9iamVjdCwgc291cmNlKVxuICAgICAgOiBzb3VyY2Vba2V5XTtcblxuICAgIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5T2JqZWN0V2l0aDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fY29weU9iamVjdFdpdGguanNcbiAqKiBtb2R1bGUgaWQgPSAxMTFcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBjb3B5T2JqZWN0ID0gcmVxdWlyZSgnLi9fY29weU9iamVjdCcpLFxuICAgIGdldFN5bWJvbHMgPSByZXF1aXJlKCcuL19nZXRTeW1ib2xzJyk7XG5cbi8qKlxuICogQ29waWVzIG93biBzeW1ib2wgcHJvcGVydGllcyBvZiBgc291cmNlYCB0byBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IHRvIGNvcHkgc3ltYm9scyBmcm9tLlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIHRvLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gY29weVN5bWJvbHMoc291cmNlLCBvYmplY3QpIHtcbiAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzKHNvdXJjZSksIG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29weVN5bWJvbHM7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2NvcHlTeW1ib2xzLmpzXG4gKiogbW9kdWxlIGlkID0gMTEyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuL19pc0l0ZXJhdGVlQ2FsbCcpLFxuICAgIHJlc3QgPSByZXF1aXJlKCcuL3Jlc3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5hc3NpZ25gLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBhc3NpZ25lciBUaGUgZnVuY3Rpb24gdG8gYXNzaWduIHZhbHVlcy5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFzc2lnbmVyIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVBc3NpZ25lcihhc3NpZ25lcikge1xuICByZXR1cm4gcmVzdChmdW5jdGlvbihvYmplY3QsIHNvdXJjZXMpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gc291cmNlcy5sZW5ndGgsXG4gICAgICAgIGN1c3RvbWl6ZXIgPSBsZW5ndGggPiAxID8gc291cmNlc1tsZW5ndGggLSAxXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZ3VhcmQgPSBsZW5ndGggPiAyID8gc291cmNlc1syXSA6IHVuZGVmaW5lZDtcblxuICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nXG4gICAgICA/IChsZW5ndGgtLSwgY3VzdG9taXplcilcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHNvdXJjZXNbMF0sIHNvdXJjZXNbMV0sIGd1YXJkKSkge1xuICAgICAgY3VzdG9taXplciA9IGxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiBjdXN0b21pemVyO1xuICAgICAgbGVuZ3RoID0gMTtcbiAgICB9XG4gICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzW2luZGV4XTtcbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgYXNzaWduZXIob2JqZWN0LCBzb3VyY2UsIGluZGV4LCBjdXN0b21pemVyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQXNzaWduZXI7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2NyZWF0ZUFzc2lnbmVyLmpzXG4gKiogbW9kdWxlIGlkID0gMTEzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIENyZWF0ZXMgYSBiYXNlIGZ1bmN0aW9uIGZvciBtZXRob2RzIGxpa2UgYF8uZm9ySW5gLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBpdGVyYWJsZSA9IE9iamVjdChvYmplY3QpLFxuICAgICAgICBwcm9wcyA9IGtleXNGdW5jKG9iamVjdCksXG4gICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgdmFyIGtleSA9IHByb3BzW2Zyb21SaWdodCA/IGxlbmd0aCA6ICsraW5kZXhdO1xuICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2tleV0sIGtleSwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRm9yO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19jcmVhdGVCYXNlRm9yLmpzXG4gKiogbW9kdWxlIGlkID0gMTE0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fYmFzZVByb3BlcnR5Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSB2YWx1ZSBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGF2b2lkIGEgW0pJVCBidWddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNDI3OTIpXG4gKiB0aGF0IGFmZmVjdHMgU2FmYXJpIG9uIGF0IGxlYXN0IGlPUyA4LjEtOC4zIEFSTTY0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgXCJsZW5ndGhcIiB2YWx1ZS5cbiAqL1xudmFyIGdldExlbmd0aCA9IGJhc2VQcm9wZXJ0eSgnbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TGVuZ3RoO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19nZXRMZW5ndGguanNcbiAqKiBtb2R1bGUgaWQgPSAxMTVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIGdldE93blByb3BlcnR5U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIHN5bWJvbCBwcm9wZXJ0aWVzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHN5bWJvbHMuXG4gKi9cbnZhciBnZXRTeW1ib2xzID0gZ2V0T3duUHJvcGVydHlTeW1ib2xzIHx8IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gW107XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFN5bWJvbHM7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX2dldFN5bWJvbHMuanNcbiAqKiBtb2R1bGUgaWQgPSAxMTZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBTZXQgPSByZXF1aXJlKCcuL19TZXQnKSxcbiAgICBXZWFrTWFwID0gcmVxdWlyZSgnLi9fV2Vha01hcCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZ1bmNUb1N0cmluZyA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IG1hcHMsIHNldHMsIGFuZCB3ZWFrbWFwcy4gKi9cbnZhciBtYXBDdG9yU3RyaW5nID0gTWFwID8gZnVuY1RvU3RyaW5nLmNhbGwoTWFwKSA6ICcnLFxuICAgIHNldEN0b3JTdHJpbmcgPSBTZXQgPyBmdW5jVG9TdHJpbmcuY2FsbChTZXQpIDogJycsXG4gICAgd2Vha01hcEN0b3JTdHJpbmcgPSBXZWFrTWFwID8gZnVuY1RvU3RyaW5nLmNhbGwoV2Vha01hcCkgOiAnJztcblxuLyoqXG4gKiBHZXRzIHRoZSBgdG9TdHJpbmdUYWdgIG9mIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgYHRvU3RyaW5nVGFnYC5cbiAqL1xuZnVuY3Rpb24gZ2V0VGFnKHZhbHVlKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbn1cblxuLy8gRmFsbGJhY2sgZm9yIElFIDExIHByb3ZpZGluZyBgdG9TdHJpbmdUYWdgIHZhbHVlcyBmb3IgbWFwcywgc2V0cywgYW5kIHdlYWttYXBzLlxuaWYgKChNYXAgJiYgZ2V0VGFnKG5ldyBNYXApICE9IG1hcFRhZykgfHxcbiAgICAoU2V0ICYmIGdldFRhZyhuZXcgU2V0KSAhPSBzZXRUYWcpIHx8XG4gICAgKFdlYWtNYXAgJiYgZ2V0VGFnKG5ldyBXZWFrTWFwKSAhPSB3ZWFrTWFwVGFnKSkge1xuICBnZXRUYWcgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciByZXN1bHQgPSBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKSxcbiAgICAgICAgQ3RvciA9IHJlc3VsdCA9PSBvYmplY3RUYWcgPyB2YWx1ZS5jb25zdHJ1Y3RvciA6IG51bGwsXG4gICAgICAgIGN0b3JTdHJpbmcgPSB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nID8gZnVuY1RvU3RyaW5nLmNhbGwoQ3RvcikgOiAnJztcblxuICAgIGlmIChjdG9yU3RyaW5nKSB7XG4gICAgICBzd2l0Y2ggKGN0b3JTdHJpbmcpIHtcbiAgICAgICAgY2FzZSBtYXBDdG9yU3RyaW5nOiByZXR1cm4gbWFwVGFnO1xuICAgICAgICBjYXNlIHNldEN0b3JTdHJpbmc6IHJldHVybiBzZXRUYWc7XG4gICAgICAgIGNhc2Ugd2Vha01hcEN0b3JTdHJpbmc6IHJldHVybiB3ZWFrTWFwVGFnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFRhZztcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fZ2V0VGFnLmpzXG4gKiogbW9kdWxlIGlkID0gMTE3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaGFzaEhhcyA9IHJlcXVpcmUoJy4vX2hhc2hIYXMnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgaGFzaC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGhhc2ggVGhlIGhhc2ggdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGhhc2hEZWxldGUoaGFzaCwga2V5KSB7XG4gIHJldHVybiBoYXNoSGFzKGhhc2gsIGtleSkgJiYgZGVsZXRlIGhhc2hba2V5XTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoRGVsZXRlO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19oYXNoRGVsZXRlLmpzXG4gKiogbW9kdWxlIGlkID0gMTE4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbnZhciBIQVNIX1VOREVGSU5FRCA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBHZXRzIHRoZSBoYXNoIHZhbHVlIGZvciBga2V5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGhhc2ggVGhlIGhhc2ggdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gaGFzaEdldChoYXNoLCBrZXkpIHtcbiAgaWYgKG5hdGl2ZUNyZWF0ZSkge1xuICAgIHZhciByZXN1bHQgPSBoYXNoW2tleV07XG4gICAgcmV0dXJuIHJlc3VsdCA9PT0gSEFTSF9VTkRFRklORUQgPyB1bmRlZmluZWQgOiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaGFzaCwga2V5KSA/IGhhc2hba2V5XSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoR2V0O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19oYXNoR2V0LmpzXG4gKiogbW9kdWxlIGlkID0gMTE5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbnZhciBIQVNIX1VOREVGSU5FRCA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJztcblxuLyoqXG4gKiBTZXRzIHRoZSBoYXNoIGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYXNoIFRoZSBoYXNoIHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICovXG5mdW5jdGlvbiBoYXNoU2V0KGhhc2gsIGtleSwgdmFsdWUpIHtcbiAgaGFzaFtrZXldID0gKG5hdGl2ZUNyZWF0ZSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkKSA/IEhBU0hfVU5ERUZJTkVEIDogdmFsdWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaFNldDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faGFzaFNldC5qc1xuICoqIG1vZHVsZSBpZCA9IDEyMFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IGFycmF5LmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgLy8gQWRkIHByb3BlcnRpZXMgYXNzaWduZWQgYnkgYFJlZ0V4cCNleGVjYC5cbiAgaWYgKGxlbmd0aCAmJiB0eXBlb2YgYXJyYXlbMF0gPT0gJ3N0cmluZycgJiYgaGFzT3duUHJvcGVydHkuY2FsbChhcnJheSwgJ2luZGV4JykpIHtcbiAgICByZXN1bHQuaW5kZXggPSBhcnJheS5pbmRleDtcbiAgICByZXN1bHQuaW5wdXQgPSBhcnJheS5pbnB1dDtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluaXRDbG9uZUFycmF5O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19pbml0Q2xvbmVBcnJheS5qc1xuICoqIG1vZHVsZSBpZCA9IDEyMVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGNsb25lQXJyYXlCdWZmZXIgPSByZXF1aXJlKCcuL19jbG9uZUFycmF5QnVmZmVyJyksXG4gICAgY2xvbmVNYXAgPSByZXF1aXJlKCcuL19jbG9uZU1hcCcpLFxuICAgIGNsb25lUmVnRXhwID0gcmVxdWlyZSgnLi9fY2xvbmVSZWdFeHAnKSxcbiAgICBjbG9uZVNldCA9IHJlcXVpcmUoJy4vX2Nsb25lU2V0JyksXG4gICAgY2xvbmVTeW1ib2wgPSByZXF1aXJlKCcuL19jbG9uZVN5bWJvbCcpLFxuICAgIGNsb25lVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vX2Nsb25lVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nO1xuXG52YXIgYXJyYXlCdWZmZXJUYWcgPSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGNsb25lQXJyYXlCdWZmZXIob2JqZWN0KTtcblxuICAgIGNhc2UgYm9vbFRhZzpcbiAgICBjYXNlIGRhdGVUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3IoK29iamVjdCk7XG5cbiAgICBjYXNlIGZsb2F0MzJUYWc6IGNhc2UgZmxvYXQ2NFRhZzpcbiAgICBjYXNlIGludDhUYWc6IGNhc2UgaW50MTZUYWc6IGNhc2UgaW50MzJUYWc6XG4gICAgY2FzZSB1aW50OFRhZzogY2FzZSB1aW50OENsYW1wZWRUYWc6IGNhc2UgdWludDE2VGFnOiBjYXNlIHVpbnQzMlRhZzpcbiAgICAgIHJldHVybiBjbG9uZVR5cGVkQXJyYXkob2JqZWN0LCBpc0RlZXApO1xuXG4gICAgY2FzZSBtYXBUYWc6XG4gICAgICByZXR1cm4gY2xvbmVNYXAob2JqZWN0KTtcblxuICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKG9iamVjdCk7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICAgIHJldHVybiBjbG9uZVJlZ0V4cChvYmplY3QpO1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICByZXR1cm4gY2xvbmVTZXQob2JqZWN0KTtcblxuICAgIGNhc2Ugc3ltYm9sVGFnOlxuICAgICAgcmV0dXJuIGNsb25lU3ltYm9sKG9iamVjdCk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVCeVRhZztcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faW5pdENsb25lQnlUYWcuanNcbiAqKiBtb2R1bGUgaWQgPSAxMjJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9fYmFzZUNyZWF0ZScpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgZ2V0UHJvdG90eXBlT2YgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNQcm90b3R5cGUob2JqZWN0KSlcbiAgICA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlT2Yob2JqZWN0KSlcbiAgICA6IHt9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluaXRDbG9uZU9iamVjdDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faW5pdENsb25lT2JqZWN0LmpzXG4gKiogbW9kdWxlIGlkID0gMTIzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgZXEgPSByZXF1aXJlKCcuL2VxJyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vX2lzSW5kZXgnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgdmFsdWUgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IGluZGV4IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgaW5kZXggb3Iga2V5IGFyZ3VtZW50LlxuICogQHBhcmFtIHsqfSBvYmplY3QgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBvYmplY3QgYXJndW1lbnQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzSXRlcmF0ZWVDYWxsKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7XG4gIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgdHlwZSA9IHR5cGVvZiBpbmRleDtcbiAgaWYgKHR5cGUgPT0gJ251bWJlcidcbiAgICAgID8gKGlzQXJyYXlMaWtlKG9iamVjdCkgJiYgaXNJbmRleChpbmRleCwgb2JqZWN0Lmxlbmd0aCkpXG4gICAgICA6ICh0eXBlID09ICdzdHJpbmcnICYmIGluZGV4IGluIG9iamVjdCkpIHtcbiAgICByZXR1cm4gZXEob2JqZWN0W2luZGV4XSwgdmFsdWUpO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0l0ZXJhdGVlQ2FsbDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faXNJdGVyYXRlZUNhbGwuanNcbiAqKiBtb2R1bGUgaWQgPSAxMjRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxuICogQ29udmVydHMgYGl0ZXJhdG9yYCB0byBhbiBhcnJheS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGl0ZXJhdG9yIFRoZSBpdGVyYXRvciB0byBjb252ZXJ0LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGl0ZXJhdG9yVG9BcnJheShpdGVyYXRvcikge1xuICB2YXIgZGF0YSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICghKGRhdGEgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICByZXN1bHQucHVzaChkYXRhLnZhbHVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGl0ZXJhdG9yVG9BcnJheTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9faXRlcmF0b3JUb0FycmF5LmpzXG4gKiogbW9kdWxlIGlkID0gMTI1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgSGFzaCA9IHJlcXVpcmUoJy4vX0hhc2gnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBtYXAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGNsZWFyXG4gKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAqL1xuZnVuY3Rpb24gbWFwQ2xlYXIoKSB7XG4gIHRoaXMuX19kYXRhX18gPSB7XG4gICAgJ2hhc2gnOiBuZXcgSGFzaCxcbiAgICAnbWFwJzogTWFwID8gbmV3IE1hcCA6IFtdLFxuICAgICdzdHJpbmcnOiBuZXcgSGFzaFxuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcENsZWFyO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19tYXBDbGVhci5qc1xuICoqIG1vZHVsZSBpZCA9IDEyNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIE1hcCA9IHJlcXVpcmUoJy4vX01hcCcpLFxuICAgIGFzc29jRGVsZXRlID0gcmVxdWlyZSgnLi9fYXNzb2NEZWxldGUnKSxcbiAgICBoYXNoRGVsZXRlID0gcmVxdWlyZSgnLi9faGFzaERlbGV0ZScpLFxuICAgIGlzS2V5YWJsZSA9IHJlcXVpcmUoJy4vX2lzS2V5YWJsZScpO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gbWFwRGVsZXRlKGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIGlmIChpc0tleWFibGUoa2V5KSkge1xuICAgIHJldHVybiBoYXNoRGVsZXRlKHR5cGVvZiBrZXkgPT0gJ3N0cmluZycgPyBkYXRhLnN0cmluZyA6IGRhdGEuaGFzaCwga2V5KTtcbiAgfVxuICByZXR1cm4gTWFwID8gZGF0YS5tYXBbJ2RlbGV0ZSddKGtleSkgOiBhc3NvY0RlbGV0ZShkYXRhLm1hcCwga2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBEZWxldGU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX21hcERlbGV0ZS5qc1xuICoqIG1vZHVsZSBpZCA9IDEyN1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIE1hcCA9IHJlcXVpcmUoJy4vX01hcCcpLFxuICAgIGFzc29jR2V0ID0gcmVxdWlyZSgnLi9fYXNzb2NHZXQnKSxcbiAgICBoYXNoR2V0ID0gcmVxdWlyZSgnLi9faGFzaEdldCcpLFxuICAgIGlzS2V5YWJsZSA9IHJlcXVpcmUoJy4vX2lzS2V5YWJsZScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG1hcCB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbWFwR2V0KGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIGlmIChpc0tleWFibGUoa2V5KSkge1xuICAgIHJldHVybiBoYXNoR2V0KHR5cGVvZiBrZXkgPT0gJ3N0cmluZycgPyBkYXRhLnN0cmluZyA6IGRhdGEuaGFzaCwga2V5KTtcbiAgfVxuICByZXR1cm4gTWFwID8gZGF0YS5tYXAuZ2V0KGtleSkgOiBhc3NvY0dldChkYXRhLm1hcCwga2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBHZXQ7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX21hcEdldC5qc1xuICoqIG1vZHVsZSBpZCA9IDEyOFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIE1hcCA9IHJlcXVpcmUoJy4vX01hcCcpLFxuICAgIGFzc29jSGFzID0gcmVxdWlyZSgnLi9fYXNzb2NIYXMnKSxcbiAgICBoYXNoSGFzID0gcmVxdWlyZSgnLi9faGFzaEhhcycpLFxuICAgIGlzS2V5YWJsZSA9IHJlcXVpcmUoJy4vX2lzS2V5YWJsZScpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBhIG1hcCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIG1hcEhhcyhrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAoaXNLZXlhYmxlKGtleSkpIHtcbiAgICByZXR1cm4gaGFzaEhhcyh0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gZGF0YS5zdHJpbmcgOiBkYXRhLmhhc2gsIGtleSk7XG4gIH1cbiAgcmV0dXJuIE1hcCA/IGRhdGEubWFwLmhhcyhrZXkpIDogYXNzb2NIYXMoZGF0YS5tYXAsIGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwSGFzO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19tYXBIYXMuanNcbiAqKiBtb2R1bGUgaWQgPSAxMjlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBhc3NvY1NldCA9IHJlcXVpcmUoJy4vX2Fzc29jU2V0JyksXG4gICAgaGFzaFNldCA9IHJlcXVpcmUoJy4vX2hhc2hTZXQnKSxcbiAgICBpc0tleWFibGUgPSByZXF1aXJlKCcuL19pc0tleWFibGUnKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBtYXAgYGtleWAgdG8gYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgc2V0XG4gKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbWFwIGNhY2hlIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gbWFwU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAoaXNLZXlhYmxlKGtleSkpIHtcbiAgICBoYXNoU2V0KHR5cGVvZiBrZXkgPT0gJ3N0cmluZycgPyBkYXRhLnN0cmluZyA6IGRhdGEuaGFzaCwga2V5LCB2YWx1ZSk7XG4gIH0gZWxzZSBpZiAoTWFwKSB7XG4gICAgZGF0YS5tYXAuc2V0KGtleSwgdmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIGFzc29jU2V0KGRhdGEubWFwLCBrZXksIHZhbHVlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBTZXQ7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX21hcFNldC5qc1xuICoqIG1vZHVsZSBpZCA9IDEzMFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBDb252ZXJ0cyBgbWFwYCB0byBhbiBhcnJheS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gbWFwVG9BcnJheShtYXApIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBBcnJheShtYXAuc2l6ZSk7XG5cbiAgbWFwLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgIHJlc3VsdFsrK2luZGV4XSA9IFtrZXksIHZhbHVlXTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwVG9BcnJheTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fbWFwVG9BcnJheS5qc1xuICoqIG1vZHVsZSBpZCA9IDEzMVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBDb252ZXJ0cyBgc2V0YCB0byBhbiBhcnJheS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gc2V0VG9BcnJheShzZXQpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7XG5cbiAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0VG9BcnJheTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fc2V0VG9BcnJheS5qc1xuICoqIG1vZHVsZSBpZCA9IDEzMlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBzdGFjay5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBTdGFja1xuICovXG5mdW5jdGlvbiBzdGFja0NsZWFyKCkge1xuICB0aGlzLl9fZGF0YV9fID0geyAnYXJyYXknOiBbXSwgJ21hcCc6IG51bGwgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0NsZWFyO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19zdGFja0NsZWFyLmpzXG4gKiogbW9kdWxlIGlkID0gMTMzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYXNzb2NEZWxldGUgPSByZXF1aXJlKCcuL19hc3NvY0RlbGV0ZScpO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBzdGFjay5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZGVsZXRlXG4gKiBAbWVtYmVyT2YgU3RhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBzdGFja0RlbGV0ZShrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLFxuICAgICAgYXJyYXkgPSBkYXRhLmFycmF5O1xuXG4gIHJldHVybiBhcnJheSA/IGFzc29jRGVsZXRlKGFycmF5LCBrZXkpIDogZGF0YS5tYXBbJ2RlbGV0ZSddKGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RhY2tEZWxldGU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX3N0YWNrRGVsZXRlLmpzXG4gKiogbW9kdWxlIGlkID0gMTM0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYXNzb2NHZXQgPSByZXF1aXJlKCcuL19hc3NvY0dldCcpO1xuXG4vKipcbiAqIEdldHMgdGhlIHN0YWNrIHZhbHVlIGZvciBga2V5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZ2V0XG4gKiBAbWVtYmVyT2YgU3RhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICovXG5mdW5jdGlvbiBzdGFja0dldChrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLFxuICAgICAgYXJyYXkgPSBkYXRhLmFycmF5O1xuXG4gIHJldHVybiBhcnJheSA/IGFzc29jR2V0KGFycmF5LCBrZXkpIDogZGF0YS5tYXAuZ2V0KGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RhY2tHZXQ7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvX3N0YWNrR2V0LmpzXG4gKiogbW9kdWxlIGlkID0gMTM1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgYXNzb2NIYXMgPSByZXF1aXJlKCcuL19hc3NvY0hhcycpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBhIHN0YWNrIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGhhc1xuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc3RhY2tIYXMoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIGFycmF5ID0gZGF0YS5hcnJheTtcblxuICByZXR1cm4gYXJyYXkgPyBhc3NvY0hhcyhhcnJheSwga2V5KSA6IGRhdGEubWFwLmhhcyhrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrSGFzO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL19zdGFja0hhcy5qc1xuICoqIG1vZHVsZSBpZCA9IDEzNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIE1hcENhY2hlID0gcmVxdWlyZSgnLi9fTWFwQ2FjaGUnKSxcbiAgICBhc3NvY1NldCA9IHJlcXVpcmUoJy4vX2Fzc29jU2V0Jyk7XG5cbi8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqL1xudmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7XG5cbi8qKlxuICogU2V0cyB0aGUgc3RhY2sgYGtleWAgdG8gYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgc2V0XG4gKiBAbWVtYmVyT2YgU3RhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgc3RhY2sgY2FjaGUgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBzdGFja1NldChrZXksIHZhbHVlKSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIGFycmF5ID0gZGF0YS5hcnJheTtcblxuICBpZiAoYXJyYXkpIHtcbiAgICBpZiAoYXJyYXkubGVuZ3RoIDwgKExBUkdFX0FSUkFZX1NJWkUgLSAxKSkge1xuICAgICAgYXNzb2NTZXQoYXJyYXksIGtleSwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkYXRhLmFycmF5ID0gbnVsbDtcbiAgICAgIGRhdGEubWFwID0gbmV3IE1hcENhY2hlKGFycmF5KTtcbiAgICB9XG4gIH1cbiAgdmFyIG1hcCA9IGRhdGEubWFwO1xuICBpZiAobWFwKSB7XG4gICAgbWFwLnNldChrZXksIHZhbHVlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja1NldDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9fc3RhY2tTZXQuanNcbiAqKiBtb2R1bGUgaWQgPSAxMzdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgdmFsdWVgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgVXRpbFxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcmV0dXJuIGZyb20gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICogdmFyIGdldHRlciA9IF8uY29uc3RhbnQob2JqZWN0KTtcbiAqXG4gKiBnZXR0ZXIoKSA9PT0gb2JqZWN0O1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBjb25zdGFudCh2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbnN0YW50O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2NvbnN0YW50LmpzXG4gKiogbW9kdWxlIGlkID0gMTM4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgY29uc3RhbnQgPSByZXF1aXJlKCcuL2NvbnN0YW50JyksXG4gICAgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZXJtaW5lIGlmIHZhbHVlcyBhcmUgb2YgdGhlIGxhbmd1YWdlIHR5cGUgYE9iamVjdGAuICovXG52YXIgb2JqZWN0VHlwZXMgPSB7XG4gICdmdW5jdGlvbic6IHRydWUsXG4gICdvYmplY3QnOiB0cnVlXG59O1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xudmFyIGZyZWVFeHBvcnRzID0gKG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlKVxuICA/IGV4cG9ydHNcbiAgOiB1bmRlZmluZWQ7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbnZhciBmcmVlTW9kdWxlID0gKG9iamVjdFR5cGVzW3R5cGVvZiBtb2R1bGVdICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlKVxuICA/IG1vZHVsZVxuICA6IHVuZGVmaW5lZDtcblxuLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi9cbnZhciBtb2R1bGVFeHBvcnRzID0gKGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cylcbiAgPyBmcmVlRXhwb3J0c1xuICA6IHVuZGVmaW5lZDtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyA/IHJvb3QuQnVmZmVyIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJ1ZmZlciwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQnVmZmVyKG5ldyBCdWZmZXIoMikpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNCdWZmZXIobmV3IFVpbnQ4QXJyYXkoMikpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzQnVmZmVyID0gIUJ1ZmZlciA/IGNvbnN0YW50KGZhbHNlKSA6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIEJ1ZmZlcjtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNCdWZmZXI7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvaXNCdWZmZXIuanNcbiAqKiBtb2R1bGUgaWQgPSAxMzlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi9faXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGAgW3N5bnRheCBjaGFyYWN0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1wYXR0ZXJucykuICovXG52YXIgcmVSZWdFeHBDaGFyID0gL1tcXFxcXiQuKis/KClbXFxde318XS9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSA+IDUpLiAqL1xudmFyIHJlSXNIb3N0Q3RvciA9IC9eXFxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXFxdJC87XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmdW5jVG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmdW5jVG9TdHJpbmcuY2FsbChoYXNPd25Qcm9wZXJ0eSkucmVwbGFjZShyZVJlZ0V4cENoYXIsICdcXFxcJCYnKVxuICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbik7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24uXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNOYXRpdmUoQXJyYXkucHJvdG90eXBlLnB1c2gpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNOYXRpdmUoXyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc05hdGl2ZSh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICByZXR1cm4gcmVJc05hdGl2ZS50ZXN0KGZ1bmNUb1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiZcbiAgICAoaXNIb3N0T2JqZWN0KHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3IpLnRlc3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTmF0aXZlO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbG9kYXNoL2lzTmF0aXZlLmpzXG4gKiogbW9kdWxlIGlkID0gMTQwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi9faXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byByZXNvbHZlIHRoZSBkZWNvbXBpbGVkIHNvdXJjZSBvZiBmdW5jdGlvbnMuICovXG52YXIgZnVuY1RvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBpbmZlciB0aGUgYE9iamVjdGAgY29uc3RydWN0b3IuICovXG52YXIgb2JqZWN0Q3RvclN0cmluZyA9IGZ1bmNUb1N0cmluZy5jYWxsKE9iamVjdCk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIGdldFByb3RvdHlwZU9mID0gT2JqZWN0LmdldFByb3RvdHlwZU9mO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCB0aGF0IGlzLCBhbiBvYmplY3QgY3JlYXRlZCBieSB0aGVcbiAqIGBPYmplY3RgIGNvbnN0cnVjdG9yIG9yIG9uZSB3aXRoIGEgYFtbUHJvdG90eXBlXV1gIG9mIGBudWxsYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwbGFpbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogfVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdChuZXcgRm9vKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdCh7ICd4JzogMCwgJ3knOiAwIH0pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdChPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICBpZiAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgfHxcbiAgICAgIG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpICE9IG9iamVjdFRhZyB8fCBpc0hvc3RPYmplY3QodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBwcm90byA9IGdldFByb3RvdHlwZU9mKHZhbHVlKTtcbiAgaWYgKHByb3RvID09PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdmFyIEN0b3IgPSBwcm90by5jb25zdHJ1Y3RvcjtcbiAgcmV0dXJuICh0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmXG4gICAgQ3RvciBpbnN0YW5jZW9mIEN0b3IgJiYgZnVuY1RvU3RyaW5nLmNhbGwoQ3RvcikgPT0gb2JqZWN0Q3RvclN0cmluZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQbGFpbk9iamVjdDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pc1BsYWluT2JqZWN0LmpzXG4gKiogbW9kdWxlIGlkID0gMTQxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N0cmluZygnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N0cmluZygxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHxcbiAgICAoIWlzQXJyYXkodmFsdWUpICYmIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmluZztcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC9pc1N0cmluZy5qc1xuICoqIG1vZHVsZSBpZCA9IDE0MlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGJhc2VGbGF0dGVuID0gcmVxdWlyZSgnLi9fYmFzZUZsYXR0ZW4nKSxcbiAgICBiYXNlUGljayA9IHJlcXVpcmUoJy4vX2Jhc2VQaWNrJyksXG4gICAgcmVzdCA9IHJlcXVpcmUoJy4vcmVzdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBwaWNrZWQgYG9iamVjdGAgcHJvcGVydGllcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IFtwcm9wc10gVGhlIHByb3BlcnR5IG5hbWVzIHRvIHBpY2ssIHNwZWNpZmllZFxuICogIGluZGl2aWR1YWxseSBvciBpbiBhcnJheXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAqXG4gKiBfLnBpY2sob2JqZWN0LCBbJ2EnLCAnYyddKTtcbiAqIC8vID0+IHsgJ2EnOiAxLCAnYyc6IDMgfVxuICovXG52YXIgcGljayA9IHJlc3QoZnVuY3Rpb24ob2JqZWN0LCBwcm9wcykge1xuICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB7fSA6IGJhc2VQaWNrKG9iamVjdCwgYmFzZUZsYXR0ZW4ocHJvcHMsIDEpKTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHBpY2s7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvcGljay5qc1xuICoqIG1vZHVsZSBpZCA9IDE0M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIHRvTnVtYmVyID0gcmVxdWlyZSgnLi90b051bWJlcicpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBJTkZJTklUWSA9IDEgLyAwLFxuICAgIE1BWF9JTlRFR0VSID0gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDg7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBpbnRlZ2VyLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIGxvb3NlbHkgYmFzZWQgb24gW2BUb0ludGVnZXJgXShodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9pbnRlZ2VyKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0ludGVnZXIoMyk7XG4gKiAvLyA9PiAzXG4gKlxuICogXy50b0ludGVnZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gKiAvLyA9PiAwXG4gKlxuICogXy50b0ludGVnZXIoSW5maW5pdHkpO1xuICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDhcbiAqXG4gKiBfLnRvSW50ZWdlcignMycpO1xuICogLy8gPT4gM1xuICovXG5mdW5jdGlvbiB0b0ludGVnZXIodmFsdWUpIHtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gMCA/IHZhbHVlIDogMDtcbiAgfVxuICB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgaWYgKHZhbHVlID09PSBJTkZJTklUWSB8fCB2YWx1ZSA9PT0gLUlORklOSVRZKSB7XG4gICAgdmFyIHNpZ24gPSAodmFsdWUgPCAwID8gLTEgOiAxKTtcbiAgICByZXR1cm4gc2lnbiAqIE1BWF9JTlRFR0VSO1xuICB9XG4gIHZhciByZW1haW5kZXIgPSB2YWx1ZSAlIDE7XG4gIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgPyAocmVtYWluZGVyID8gdmFsdWUgLSByZW1haW5kZXIgOiB2YWx1ZSkgOiAwO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvSW50ZWdlcjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC90b0ludGVnZXIuanNcbiAqKiBtb2R1bGUgaWQgPSAxNDRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE5BTiA9IDAgLyAwO1xuXG4vKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLiAqL1xudmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG52YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBudW1iZXIuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udG9OdW1iZXIoMyk7XG4gKiAvLyA9PiAzXG4gKlxuICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICogLy8gPT4gSW5maW5pdHlcbiAqXG4gKiBfLnRvTnVtYmVyKCczJyk7XG4gKiAvLyA9PiAzXG4gKi9cbmZ1bmN0aW9uIHRvTnVtYmVyKHZhbHVlKSB7XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICB2YXIgb3RoZXIgPSBpc0Z1bmN0aW9uKHZhbHVlLnZhbHVlT2YpID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7XG4gICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gIH1cbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b051bWJlcjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2xvZGFzaC90b051bWJlci5qc1xuICoqIG1vZHVsZSBpZCA9IDE0NVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgcGxhaW4gb2JqZWN0IGZsYXR0ZW5pbmcgaW5oZXJpdGVkIGVudW1lcmFibGVcbiAqIHByb3BlcnRpZXMgb2YgYHZhbHVlYCB0byBvd24gcHJvcGVydGllcyBvZiB0aGUgcGxhaW4gb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBwbGFpbiBvYmplY3QuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8uYXNzaWduKHsgJ2EnOiAxIH0sIG5ldyBGb28pO1xuICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gKlxuICogXy5hc3NpZ24oeyAnYSc6IDEgfSwgXy50b1BsYWluT2JqZWN0KG5ldyBGb28pKTtcbiAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9XG4gKi9cbmZ1bmN0aW9uIHRvUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIGNvcHlPYmplY3QodmFsdWUsIGtleXNJbih2YWx1ZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvUGxhaW5PYmplY3Q7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9sb2Rhc2gvdG9QbGFpbk9iamVjdC5qc1xuICoqIG1vZHVsZSBpZCA9IDE0NlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbi8vIFNoaW1taW5nIHN0YXJ0cyBoZXJlLlxuKGZ1bmN0aW9uKCkge1xuICAvLyBVdGlscy5cbiAgdmFyIGxvZ2dpbmcgPSByZXF1aXJlKCcuL3V0aWxzJykubG9nO1xuICB2YXIgYnJvd3NlckRldGFpbHMgPSByZXF1aXJlKCcuL3V0aWxzJykuYnJvd3NlckRldGFpbHM7XG4gIC8vIEV4cG9ydCB0byB0aGUgYWRhcHRlciBnbG9iYWwgb2JqZWN0IHZpc2libGUgaW4gdGhlIGJyb3dzZXIuXG4gIG1vZHVsZS5leHBvcnRzLmJyb3dzZXJEZXRhaWxzID0gYnJvd3NlckRldGFpbHM7XG4gIG1vZHVsZS5leHBvcnRzLmV4dHJhY3RWZXJzaW9uID0gcmVxdWlyZSgnLi91dGlscycpLmV4dHJhY3RWZXJzaW9uO1xuICBtb2R1bGUuZXhwb3J0cy5kaXNhYmxlTG9nID0gcmVxdWlyZSgnLi91dGlscycpLmRpc2FibGVMb2c7XG5cbiAgLy8gVW5jb21tZW50IGlmIHlvdSBkbyBub3Qgd2FudCBhbnkgbG9nZ2luZyBhdCBhbGwgaW5jbHVkaW5nIHRoZSBzd2l0Y2hcbiAgLy8gc3RhdGVtZW50IGJlbG93LiBDYW4gYWxzbyBiZSB0dXJuZWQgb2ZmIGluIHRoZSBicm93c2VyIHZpYVxuICAvLyBhZGFwdGVyLmRpc2FibGVMb2codHJ1ZSkgYnV0IHRoZW4gbG9nZ2luZyBmcm9tIHRoZSBzd2l0Y2ggc3RhdGVtZW50IGJlbG93XG4gIC8vIHdpbGwgc3RpbGwgYXBwZWFyLlxuICAvL3JlcXVpcmUoJy4vdXRpbHMnKS5kaXNhYmxlTG9nKHRydWUpO1xuXG4gIC8vIEJyb3dzZXIgc2hpbXMuXG4gIHZhciBjaHJvbWVTaGltID0gcmVxdWlyZSgnLi9jaHJvbWUvY2hyb21lX3NoaW0nKSB8fCBudWxsO1xuICB2YXIgZWRnZVNoaW0gPSByZXF1aXJlKCcuL2VkZ2UvZWRnZV9zaGltJykgfHwgbnVsbDtcbiAgdmFyIGZpcmVmb3hTaGltID0gcmVxdWlyZSgnLi9maXJlZm94L2ZpcmVmb3hfc2hpbScpIHx8IG51bGw7XG5cbiAgLy8gU2hpbSBicm93c2VyIGlmIGZvdW5kLlxuICBzd2l0Y2ggKGJyb3dzZXJEZXRhaWxzLmJyb3dzZXIpIHtcbiAgICBjYXNlICdjaHJvbWUnOlxuICAgICAgaWYgKCFjaHJvbWVTaGltIHx8ICFjaHJvbWVTaGltLnNoaW1QZWVyQ29ubmVjdGlvbikge1xuICAgICAgICBsb2dnaW5nKCdDaHJvbWUgc2hpbSBpcyBub3QgaW5jbHVkZWQgaW4gdGhpcyBhZGFwdGVyIHJlbGVhc2UuJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxvZ2dpbmcoJ2FkYXB0ZXIuanMgc2hpbW1pbmcgY2hyb21lIScpO1xuICAgICAgLy8gRXhwb3J0IHRvIHRoZSBhZGFwdGVyIGdsb2JhbCBvYmplY3QgdmlzaWJsZSBpbiB0aGUgYnJvd3Nlci5cbiAgICAgIG1vZHVsZS5leHBvcnRzLmJyb3dzZXJTaGltID0gY2hyb21lU2hpbTtcblxuICAgICAgY2hyb21lU2hpbS5zaGltR2V0VXNlck1lZGlhKCk7XG4gICAgICBjaHJvbWVTaGltLnNoaW1Tb3VyY2VPYmplY3QoKTtcbiAgICAgIGNocm9tZVNoaW0uc2hpbVBlZXJDb25uZWN0aW9uKCk7XG4gICAgICBjaHJvbWVTaGltLnNoaW1PblRyYWNrKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdlZGdlJzpcbiAgICAgIGlmICghZWRnZVNoaW0gfHwgIWVkZ2VTaGltLnNoaW1QZWVyQ29ubmVjdGlvbikge1xuICAgICAgICBsb2dnaW5nKCdNUyBlZGdlIHNoaW0gaXMgbm90IGluY2x1ZGVkIGluIHRoaXMgYWRhcHRlciByZWxlYXNlLicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2dnaW5nKCdhZGFwdGVyLmpzIHNoaW1taW5nIGVkZ2UhJyk7XG4gICAgICAvLyBFeHBvcnQgdG8gdGhlIGFkYXB0ZXIgZ2xvYmFsIG9iamVjdCB2aXNpYmxlIGluIHRoZSBicm93c2VyLlxuICAgICAgbW9kdWxlLmV4cG9ydHMuYnJvd3NlclNoaW0gPSBlZGdlU2hpbTtcblxuICAgICAgZWRnZVNoaW0uc2hpbVBlZXJDb25uZWN0aW9uKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdmaXJlZm94JzpcbiAgICAgIGlmICghZmlyZWZveFNoaW0gfHwgIWZpcmVmb3hTaGltLnNoaW1QZWVyQ29ubmVjdGlvbikge1xuICAgICAgICBsb2dnaW5nKCdGaXJlZm94IHNoaW0gaXMgbm90IGluY2x1ZGVkIGluIHRoaXMgYWRhcHRlciByZWxlYXNlLicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2dnaW5nKCdhZGFwdGVyLmpzIHNoaW1taW5nIGZpcmVmb3ghJyk7XG4gICAgICAvLyBFeHBvcnQgdG8gdGhlIGFkYXB0ZXIgZ2xvYmFsIG9iamVjdCB2aXNpYmxlIGluIHRoZSBicm93c2VyLlxuICAgICAgbW9kdWxlLmV4cG9ydHMuYnJvd3NlclNoaW0gPSBmaXJlZm94U2hpbTtcblxuICAgICAgZmlyZWZveFNoaW0uc2hpbUdldFVzZXJNZWRpYSgpO1xuICAgICAgZmlyZWZveFNoaW0uc2hpbVNvdXJjZU9iamVjdCgpO1xuICAgICAgZmlyZWZveFNoaW0uc2hpbVBlZXJDb25uZWN0aW9uKCk7XG4gICAgICBmaXJlZm94U2hpbS5zaGltT25UcmFjaygpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGxvZ2dpbmcoJ1Vuc3VwcG9ydGVkIGJyb3dzZXIhJyk7XG4gIH1cbn0pKCk7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi93ZWJydGMtYWRhcHRlci9zcmMvanMvYWRhcHRlcl9jb3JlLmpzXG4gKiogbW9kdWxlIGlkID0gMTQ3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbid1c2Ugc3RyaWN0JztcbnZhciBsb2dnaW5nID0gcmVxdWlyZSgnLi4vdXRpbHMuanMnKS5sb2c7XG52YXIgYnJvd3NlckRldGFpbHMgPSByZXF1aXJlKCcuLi91dGlscy5qcycpLmJyb3dzZXJEZXRhaWxzO1xuXG52YXIgY2hyb21lU2hpbSA9IHtcbiAgc2hpbU9uVHJhY2s6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyAmJiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gJiYgISgnb250cmFjaycgaW5cbiAgICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLCAnb250cmFjaycsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMuX29udHJhY2s7IH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24oZikge1xuICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICBpZiAodGhpcy5fb250cmFjaykge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFjaycsIHRoaXMuX29udHJhY2spO1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdhZGRzdHJlYW0nLCB0aGlzLl9vbnRyYWNrcG9seSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcigndHJhY2snLCB0aGlzLl9vbnRyYWNrID0gZik7XG4gICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdhZGRzdHJlYW0nLCB0aGlzLl9vbnRyYWNrcG9seSA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIC8vIG9uYWRkc3RyZWFtIGRvZXMgbm90IGZpcmUgd2hlbiBhIHRyYWNrIGlzIGFkZGVkIHRvIGFuIGV4aXN0aW5nIHN0cmVhbS5cbiAgICAgICAgICAgIC8vIGJ1dCBzdHJlYW0ub25hZGR0cmFjayBpcyBpbXBsZW1lbnRlZCBzbyB3ZSB1c2UgdGhhdFxuICAgICAgICAgICAgZS5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWRkdHJhY2snLCBmdW5jdGlvbih0ZSkge1xuICAgICAgICAgICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ3RyYWNrJyk7XG4gICAgICAgICAgICAgIGV2ZW50LnRyYWNrID0gdGUudHJhY2s7XG4gICAgICAgICAgICAgIGV2ZW50LnJlY2VpdmVyID0ge3RyYWNrOiB0ZS50cmFja307XG4gICAgICAgICAgICAgIGV2ZW50LnN0cmVhbXMgPSBbZS5zdHJlYW1dO1xuICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBlLnN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrKSB7XG4gICAgICAgICAgICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgndHJhY2snKTtcbiAgICAgICAgICAgICAgZXZlbnQudHJhY2sgPSB0cmFjaztcbiAgICAgICAgICAgICAgZXZlbnQucmVjZWl2ZXIgPSB7dHJhY2s6IHRyYWNrfTtcbiAgICAgICAgICAgICAgZXZlbnQuc3RyZWFtcyA9IFtlLnN0cmVhbV07XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcblxuICBzaGltU291cmNlT2JqZWN0OiBmdW5jdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudCAmJlxuICAgICAgICAhKCdzcmNPYmplY3QnIGluIHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSkpIHtcbiAgICAgICAgLy8gU2hpbSB0aGUgc3JjT2JqZWN0IHByb3BlcnR5LCBvbmNlLCB3aGVuIEhUTUxNZWRpYUVsZW1lbnQgaXMgZm91bmQuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUsICdzcmNPYmplY3QnLCB7XG4gICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zcmNPYmplY3Q7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgLy8gVXNlIF9zcmNPYmplY3QgYXMgYSBwcml2YXRlIHByb3BlcnR5IGZvciB0aGlzIHNoaW1cbiAgICAgICAgICAgIHRoaXMuX3NyY09iamVjdCA9IHN0cmVhbTtcbiAgICAgICAgICAgIGlmICh0aGlzLnNyYykge1xuICAgICAgICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHRoaXMuc3JjKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFzdHJlYW0pIHtcbiAgICAgICAgICAgICAgdGhpcy5zcmMgPSAnJztcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zcmMgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKHN0cmVhbSk7XG4gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIHJlY3JlYXRlIHRoZSBibG9iIHVybCB3aGVuIGEgdHJhY2sgaXMgYWRkZWQgb3IgcmVtb3ZlZC5cbiAgICAgICAgICAgIC8vIERvaW5nIGl0IG1hbnVhbGx5IHNpbmNlIHdlIHdhbnQgdG8gYXZvaWQgYSByZWN1cnNpb24uXG4gICAgICAgICAgICBzdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWRkdHJhY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgaWYgKHNlbGYuc3JjKSB7XG4gICAgICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTChzZWxmLnNyYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc2VsZi5zcmMgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKHN0cmVhbSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCdyZW1vdmV0cmFjaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICBpZiAoc2VsZi5zcmMpIHtcbiAgICAgICAgICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHNlbGYuc3JjKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzZWxmLnNyYyA9IFVSTC5jcmVhdGVPYmplY3RVUkwoc3RyZWFtKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHNoaW1QZWVyQ29ubmVjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgLy8gVGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdC5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gPSBmdW5jdGlvbihwY0NvbmZpZywgcGNDb25zdHJhaW50cykge1xuICAgICAgLy8gVHJhbnNsYXRlIGljZVRyYW5zcG9ydFBvbGljeSB0byBpY2VUcmFuc3BvcnRzLFxuICAgICAgLy8gc2VlIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3Avd2VicnRjL2lzc3Vlcy9kZXRhaWw/aWQ9NDg2OVxuICAgICAgbG9nZ2luZygnUGVlckNvbm5lY3Rpb24nKTtcbiAgICAgIGlmIChwY0NvbmZpZyAmJiBwY0NvbmZpZy5pY2VUcmFuc3BvcnRQb2xpY3kpIHtcbiAgICAgICAgcGNDb25maWcuaWNlVHJhbnNwb3J0cyA9IHBjQ29uZmlnLmljZVRyYW5zcG9ydFBvbGljeTtcbiAgICAgIH1cblxuICAgICAgdmFyIHBjID0gbmV3IHdlYmtpdFJUQ1BlZXJDb25uZWN0aW9uKHBjQ29uZmlnLCBwY0NvbnN0cmFpbnRzKTsgLy8ganNjczppZ25vcmUgcmVxdWlyZUNhcGl0YWxpemVkQ29uc3RydWN0b3JzXG4gICAgICB2YXIgb3JpZ0dldFN0YXRzID0gcGMuZ2V0U3RhdHMuYmluZChwYyk7XG4gICAgICBwYy5nZXRTdGF0cyA9IGZ1bmN0aW9uKHNlbGVjdG9yLCBzdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spIHsgLy8ganNoaW50IGlnbm9yZTogbGluZVxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgICAgIC8vIElmIHNlbGVjdG9yIGlzIGEgZnVuY3Rpb24gdGhlbiB3ZSBhcmUgaW4gdGhlIG9sZCBzdHlsZSBzdGF0cyBzbyBqdXN0XG4gICAgICAgIC8vIHBhc3MgYmFjayB0aGUgb3JpZ2luYWwgZ2V0U3RhdHMgZm9ybWF0IHRvIGF2b2lkIGJyZWFraW5nIG9sZCB1c2Vycy5cbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHJldHVybiBvcmlnR2V0U3RhdHMoc2VsZWN0b3IsIHN1Y2Nlc3NDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZml4Q2hyb21lU3RhdHNfID0gZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICAgICAgICB2YXIgc3RhbmRhcmRSZXBvcnQgPSB7fTtcbiAgICAgICAgICB2YXIgcmVwb3J0cyA9IHJlc3BvbnNlLnJlc3VsdCgpO1xuICAgICAgICAgIHJlcG9ydHMuZm9yRWFjaChmdW5jdGlvbihyZXBvcnQpIHtcbiAgICAgICAgICAgIHZhciBzdGFuZGFyZFN0YXRzID0ge1xuICAgICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgICB0aW1lc3RhbXA6IHJlcG9ydC50aW1lc3RhbXAsXG4gICAgICAgICAgICAgIHR5cGU6IHJlcG9ydC50eXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVwb3J0Lm5hbWVzKCkuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgICAgICAgIHN0YW5kYXJkU3RhdHNbbmFtZV0gPSByZXBvcnQuc3RhdChuYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhbmRhcmRSZXBvcnRbc3RhbmRhcmRTdGF0cy5pZF0gPSBzdGFuZGFyZFN0YXRzO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICB2YXIgc3VjY2Vzc0NhbGxiYWNrV3JhcHBlcl8gPSBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgICAgICAgICAgYXJnc1sxXShmaXhDaHJvbWVTdGF0c18ocmVzcG9uc2UpKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmV0dXJuIG9yaWdHZXRTdGF0cy5hcHBseSh0aGlzLCBbc3VjY2Vzc0NhbGxiYWNrV3JhcHBlcl8sIGFyZ3VtZW50c1swXV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcHJvbWlzZS1zdXBwb3J0XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgc2VsZWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIG9yaWdHZXRTdGF0cy5hcHBseShzZWxmLCBbXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmUuYXBwbHkobnVsbCwgW2ZpeENocm9tZVN0YXRzXyhyZXNwb25zZSldKTtcbiAgICAgICAgICAgICAgICB9LCByZWplY3RdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3JpZ0dldFN0YXRzLmFwcGx5KHNlbGYsIFtyZXNvbHZlLCByZWplY3RdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHBjO1xuICAgIH07XG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSA9IHdlYmtpdFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZTtcblxuICAgIC8vIHdyYXAgc3RhdGljIG1ldGhvZHMuIEN1cnJlbnRseSBqdXN0IGdlbmVyYXRlQ2VydGlmaWNhdGUuXG4gICAgaWYgKHdlYmtpdFJUQ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGUpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24sICdnZW5lcmF0ZUNlcnRpZmljYXRlJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gd2Via2l0UlRDUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZS5hcHBseShudWxsLFxuICAgICAgICAgICAgICAgIGFyZ3VtZW50cyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB3ZWJraXRSVENQZWVyQ29ubmVjdGlvbi5nZW5lcmF0ZUNlcnRpZmljYXRlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gYWRkIHByb21pc2Ugc3VwcG9ydFxuICAgIFsnY3JlYXRlT2ZmZXInLCAnY3JlYXRlQW5zd2VyJ10uZm9yRWFjaChmdW5jdGlvbihtZXRob2QpIHtcbiAgICAgIHZhciBuYXRpdmVNZXRob2QgPSB3ZWJraXRSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbbWV0aG9kXTtcbiAgICAgIHdlYmtpdFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAxIHx8IChhcmd1bWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICB0eXBlb2YoYXJndW1lbnRzWzBdKSA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgdmFyIG9wdHMgPSBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkO1xuICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIG5hdGl2ZU1ldGhvZC5hcHBseShzZWxmLCBbcmVzb2x2ZSwgcmVqZWN0LCBvcHRzXSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5hdGl2ZU1ldGhvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgWydzZXRMb2NhbERlc2NyaXB0aW9uJywgJ3NldFJlbW90ZURlc2NyaXB0aW9uJyxcbiAgICAgICAgJ2FkZEljZUNhbmRpZGF0ZSddLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICB2YXIgbmF0aXZlTWV0aG9kID0gd2Via2l0UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF07XG4gICAgICB3ZWJraXRSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgbmF0aXZlTWV0aG9kLmFwcGx5KHNlbGYsIFthcmdzWzBdLFxuICAgICAgICAgICAgICBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgICAgICAgIGFyZ3NbMV0uYXBwbHkobnVsbCwgW10pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID49IDMpIHtcbiAgICAgICAgICAgICAgICAgIGFyZ3NbMl0uYXBwbHkobnVsbCwgW2Vycl0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfV1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfSxcblxuICAvLyBBdHRhY2ggYSBtZWRpYSBzdHJlYW0gdG8gYW4gZWxlbWVudC5cbiAgYXR0YWNoTWVkaWFTdHJlYW06IGZ1bmN0aW9uKGVsZW1lbnQsIHN0cmVhbSkge1xuICAgIGxvZ2dpbmcoJ0RFUFJFQ0FURUQsIGF0dGFjaE1lZGlhU3RyZWFtIHdpbGwgc29vbiBiZSByZW1vdmVkLicpO1xuICAgIGlmIChicm93c2VyRGV0YWlscy52ZXJzaW9uID49IDQzKSB7XG4gICAgICBlbGVtZW50LnNyY09iamVjdCA9IHN0cmVhbTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbGVtZW50LnNyYyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGVsZW1lbnQuc3JjID0gVVJMLmNyZWF0ZU9iamVjdFVSTChzdHJlYW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnaW5nKCdFcnJvciBhdHRhY2hpbmcgc3RyZWFtIHRvIGVsZW1lbnQuJyk7XG4gICAgfVxuICB9LFxuXG4gIHJlYXR0YWNoTWVkaWFTdHJlYW06IGZ1bmN0aW9uKHRvLCBmcm9tKSB7XG4gICAgbG9nZ2luZygnREVQUkVDQVRFRCwgcmVhdHRhY2hNZWRpYVN0cmVhbSB3aWxsIHNvb24gYmUgcmVtb3ZlZC4nKTtcbiAgICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA+PSA0Mykge1xuICAgICAgdG8uc3JjT2JqZWN0ID0gZnJvbS5zcmNPYmplY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRvLnNyYyA9IGZyb20uc3JjO1xuICAgIH1cbiAgfVxufVxuXG5cbi8vIEV4cG9zZSBwdWJsaWMgbWV0aG9kcy5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzaGltT25UcmFjazogY2hyb21lU2hpbS5zaGltT25UcmFjayxcbiAgc2hpbVNvdXJjZU9iamVjdDogY2hyb21lU2hpbS5zaGltU291cmNlT2JqZWN0LFxuICBzaGltUGVlckNvbm5lY3Rpb246IGNocm9tZVNoaW0uc2hpbVBlZXJDb25uZWN0aW9uLFxuICBzaGltR2V0VXNlck1lZGlhOiByZXF1aXJlKCcuL2dldHVzZXJtZWRpYScpLFxuICBhdHRhY2hNZWRpYVN0cmVhbTogY2hyb21lU2hpbS5hdHRhY2hNZWRpYVN0cmVhbSxcbiAgcmVhdHRhY2hNZWRpYVN0cmVhbTogY2hyb21lU2hpbS5yZWF0dGFjaE1lZGlhU3RyZWFtXG59O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2Nocm9tZS9jaHJvbWVfc2hpbS5qc1xuICoqIG1vZHVsZSBpZCA9IDE0OFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7XG52YXIgbG9nZ2luZyA9IHJlcXVpcmUoJy4uL3V0aWxzLmpzJykubG9nO1xuXG4vLyBFeHBvc2UgcHVibGljIG1ldGhvZHMuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29uc3RyYWludHNUb0Nocm9tZV8gPSBmdW5jdGlvbihjKSB7XG4gICAgaWYgKHR5cGVvZiBjICE9PSAnb2JqZWN0JyB8fCBjLm1hbmRhdG9yeSB8fCBjLm9wdGlvbmFsKSB7XG4gICAgICByZXR1cm4gYztcbiAgICB9XG4gICAgdmFyIGNjID0ge307XG4gICAgT2JqZWN0LmtleXMoYykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgIGlmIChrZXkgPT09ICdyZXF1aXJlJyB8fCBrZXkgPT09ICdhZHZhbmNlZCcgfHwga2V5ID09PSAnbWVkaWFTb3VyY2UnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciByID0gKHR5cGVvZiBjW2tleV0gPT09ICdvYmplY3QnKSA/IGNba2V5XSA6IHtpZGVhbDogY1trZXldfTtcbiAgICAgIGlmIChyLmV4YWN0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHIuZXhhY3QgPT09ICdudW1iZXInKSB7XG4gICAgICAgIHIubWluID0gci5tYXggPSByLmV4YWN0O1xuICAgICAgfVxuICAgICAgdmFyIG9sZG5hbWVfID0gZnVuY3Rpb24ocHJlZml4LCBuYW1lKSB7XG4gICAgICAgIGlmIChwcmVmaXgpIHtcbiAgICAgICAgICByZXR1cm4gcHJlZml4ICsgbmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChuYW1lID09PSAnZGV2aWNlSWQnKSA/ICdzb3VyY2VJZCcgOiBuYW1lO1xuICAgICAgfTtcbiAgICAgIGlmIChyLmlkZWFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2Mub3B0aW9uYWwgPSBjYy5vcHRpb25hbCB8fCBbXTtcbiAgICAgICAgdmFyIG9jID0ge307XG4gICAgICAgIGlmICh0eXBlb2Ygci5pZGVhbCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBvY1tvbGRuYW1lXygnbWluJywga2V5KV0gPSByLmlkZWFsO1xuICAgICAgICAgIGNjLm9wdGlvbmFsLnB1c2gob2MpO1xuICAgICAgICAgIG9jID0ge307XG4gICAgICAgICAgb2Nbb2xkbmFtZV8oJ21heCcsIGtleSldID0gci5pZGVhbDtcbiAgICAgICAgICBjYy5vcHRpb25hbC5wdXNoKG9jKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvY1tvbGRuYW1lXygnJywga2V5KV0gPSByLmlkZWFsO1xuICAgICAgICAgIGNjLm9wdGlvbmFsLnB1c2gob2MpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoci5leGFjdCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiByLmV4YWN0ICE9PSAnbnVtYmVyJykge1xuICAgICAgICBjYy5tYW5kYXRvcnkgPSBjYy5tYW5kYXRvcnkgfHwge307XG4gICAgICAgIGNjLm1hbmRhdG9yeVtvbGRuYW1lXygnJywga2V5KV0gPSByLmV4YWN0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgWydtaW4nLCAnbWF4J10uZm9yRWFjaChmdW5jdGlvbihtaXgpIHtcbiAgICAgICAgICBpZiAoclttaXhdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNjLm1hbmRhdG9yeSA9IGNjLm1hbmRhdG9yeSB8fCB7fTtcbiAgICAgICAgICAgIGNjLm1hbmRhdG9yeVtvbGRuYW1lXyhtaXgsIGtleSldID0gclttaXhdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGMuYWR2YW5jZWQpIHtcbiAgICAgIGNjLm9wdGlvbmFsID0gKGNjLm9wdGlvbmFsIHx8IFtdKS5jb25jYXQoYy5hZHZhbmNlZCk7XG4gICAgfVxuICAgIHJldHVybiBjYztcbiAgfTtcblxuICB2YXIgZ2V0VXNlck1lZGlhXyA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzLCBvblN1Y2Nlc3MsIG9uRXJyb3IpIHtcbiAgICBpZiAoY29uc3RyYWludHMuYXVkaW8pIHtcbiAgICAgIGNvbnN0cmFpbnRzLmF1ZGlvID0gY29uc3RyYWludHNUb0Nocm9tZV8oY29uc3RyYWludHMuYXVkaW8pO1xuICAgIH1cbiAgICBpZiAoY29uc3RyYWludHMudmlkZW8pIHtcbiAgICAgIGNvbnN0cmFpbnRzLnZpZGVvID0gY29uc3RyYWludHNUb0Nocm9tZV8oY29uc3RyYWludHMudmlkZW8pO1xuICAgIH1cbiAgICBsb2dnaW5nKCdjaHJvbWU6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuICAgIHJldHVybiBuYXZpZ2F0b3Iud2Via2l0R2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzLCBvblN1Y2Nlc3MsIG9uRXJyb3IpO1xuICB9O1xuICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhID0gZ2V0VXNlck1lZGlhXztcblxuICAvLyBSZXR1cm5zIHRoZSByZXN1bHQgb2YgZ2V0VXNlck1lZGlhIGFzIGEgUHJvbWlzZS5cbiAgdmFyIGdldFVzZXJNZWRpYVByb21pc2VfID0gZnVuY3Rpb24oY29uc3RyYWludHMpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzLCByZXNvbHZlLCByZWplY3QpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKCFuYXZpZ2F0b3IubWVkaWFEZXZpY2VzKSB7XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcyA9IHtnZXRVc2VyTWVkaWE6IGdldFVzZXJNZWRpYVByb21pc2VfLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnVtZXJhdGVEZXZpY2VzOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7XG4gICAgICAgIHZhciBraW5kcyA9IHthdWRpbzogJ2F1ZGlvaW5wdXQnLCB2aWRlbzogJ3ZpZGVvaW5wdXQnfTtcbiAgICAgICAgcmV0dXJuIE1lZGlhU3RyZWFtVHJhY2suZ2V0U291cmNlcyhmdW5jdGlvbihkZXZpY2VzKSB7XG4gICAgICAgICAgcmVzb2x2ZShkZXZpY2VzLm1hcChmdW5jdGlvbihkZXZpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB7bGFiZWw6IGRldmljZS5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAga2luZDoga2luZHNbZGV2aWNlLmtpbmRdLFxuICAgICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlLmlkLFxuICAgICAgICAgICAgICAgICAgICBncm91cElkOiAnJ307XG4gICAgICAgICAgfSkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH19O1xuICB9XG5cbiAgLy8gQSBzaGltIGZvciBnZXRVc2VyTWVkaWEgbWV0aG9kIG9uIHRoZSBtZWRpYURldmljZXMgb2JqZWN0LlxuICAvLyBUT0RPKEthcHRlbkphbnNzb24pIHJlbW92ZSBvbmNlIGltcGxlbWVudGVkIGluIENocm9tZSBzdGFibGUuXG4gIGlmICghbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzKSB7XG4gICAgICByZXR1cm4gZ2V0VXNlck1lZGlhUHJvbWlzZV8oY29uc3RyYWludHMpO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgLy8gRXZlbiB0aG91Z2ggQ2hyb21lIDQ1IGhhcyBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzIGFuZCBhIGdldFVzZXJNZWRpYVxuICAgIC8vIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYSBQcm9taXNlLCBpdCBkb2VzIG5vdCBhY2NlcHQgc3BlYy1zdHlsZVxuICAgIC8vIGNvbnN0cmFpbnRzLlxuICAgIHZhciBvcmlnR2V0VXNlck1lZGlhID0gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEuXG4gICAgICAgIGJpbmQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyk7XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEgPSBmdW5jdGlvbihjKSB7XG4gICAgICBpZiAoYykge1xuICAgICAgICBsb2dnaW5nKCdzcGVjOiAgICcgKyBKU09OLnN0cmluZ2lmeShjKSk7IC8vIHdoaXRlc3BhY2UgZm9yIGFsaWdubWVudFxuICAgICAgICBjLmF1ZGlvID0gY29uc3RyYWludHNUb0Nocm9tZV8oYy5hdWRpbyk7XG4gICAgICAgIGMudmlkZW8gPSBjb25zdHJhaW50c1RvQ2hyb21lXyhjLnZpZGVvKTtcbiAgICAgICAgbG9nZ2luZygnY2hyb21lOiAnICsgSlNPTi5zdHJpbmdpZnkoYykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9yaWdHZXRVc2VyTWVkaWEoYyk7XG4gICAgfS5iaW5kKHRoaXMpO1xuICB9XG5cbiAgLy8gRHVtbXkgZGV2aWNlY2hhbmdlIGV2ZW50IG1ldGhvZHMuXG4gIC8vIFRPRE8oS2FwdGVuSmFuc3NvbikgcmVtb3ZlIG9uY2UgaW1wbGVtZW50ZWQgaW4gQ2hyb21lIHN0YWJsZS5cbiAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmFkZEV2ZW50TGlzdGVuZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oKSB7XG4gICAgICBsb2dnaW5nKCdEdW1teSBtZWRpYURldmljZXMuYWRkRXZlbnRMaXN0ZW5lciBjYWxsZWQuJyk7XG4gICAgfTtcbiAgfVxuICBpZiAodHlwZW9mIG5hdmlnYXRvci5tZWRpYURldmljZXMucmVtb3ZlRXZlbnRMaXN0ZW5lciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIGxvZ2dpbmcoJ0R1bW15IG1lZGlhRGV2aWNlcy5yZW1vdmVFdmVudExpc3RlbmVyIGNhbGxlZC4nKTtcbiAgICB9O1xuICB9XG59O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2Nocm9tZS9nZXR1c2VybWVkaWEuanNcbiAqKiBtb2R1bGUgaWQgPSAxNDlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qXG4gKiAgQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBXZWJSVEMgcHJvamVjdCBhdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgc291cmNlXG4gKiAgdHJlZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBTRFAgaGVscGVycy5cbnZhciBTRFBVdGlscyA9IHt9O1xuXG4vLyBHZW5lcmF0ZSBhbiBhbHBoYW51bWVyaWMgaWRlbnRpZmllciBmb3IgY25hbWUgb3IgbWlkcy5cbi8vIFRPRE86IHVzZSBVVUlEcyBpbnN0ZWFkPyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9qZWQvOTgyODgzXG5TRFBVdGlscy5nZW5lcmF0ZUlkZW50aWZpZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCAxMCk7XG59O1xuXG4vLyBUaGUgUlRDUCBDTkFNRSB1c2VkIGJ5IGFsbCBwZWVyY29ubmVjdGlvbnMgZnJvbSB0aGUgc2FtZSBKUy5cblNEUFV0aWxzLmxvY2FsQ05hbWUgPSBTRFBVdGlscy5nZW5lcmF0ZUlkZW50aWZpZXIoKTtcblxuXG4vLyBTcGxpdHMgU0RQIGludG8gbGluZXMsIGRlYWxpbmcgd2l0aCBib3RoIENSTEYgYW5kIExGLlxuU0RQVXRpbHMuc3BsaXRMaW5lcyA9IGZ1bmN0aW9uKGJsb2IpIHtcbiAgcmV0dXJuIGJsb2IudHJpbSgpLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgIHJldHVybiBsaW5lLnRyaW0oKTtcbiAgfSk7XG59O1xuLy8gU3BsaXRzIFNEUCBpbnRvIHNlc3Npb25wYXJ0IGFuZCBtZWRpYXNlY3Rpb25zLiBFbnN1cmVzIENSTEYuXG5TRFBVdGlscy5zcGxpdFNlY3Rpb25zID0gZnVuY3Rpb24oYmxvYikge1xuICB2YXIgcGFydHMgPSBibG9iLnNwbGl0KCdcXHJcXG5tPScpO1xuICByZXR1cm4gcGFydHMubWFwKGZ1bmN0aW9uKHBhcnQsIGluZGV4KSB7XG4gICAgcmV0dXJuIChpbmRleCA+IDAgPyAnbT0nICsgcGFydCA6IHBhcnQpLnRyaW0oKSArICdcXHJcXG4nO1xuICB9KTtcbn07XG5cbi8vIFJldHVybnMgbGluZXMgdGhhdCBzdGFydCB3aXRoIGEgY2VydGFpbiBwcmVmaXguXG5TRFBVdGlscy5tYXRjaFByZWZpeCA9IGZ1bmN0aW9uKGJsb2IsIHByZWZpeCkge1xuICByZXR1cm4gU0RQVXRpbHMuc3BsaXRMaW5lcyhibG9iKS5maWx0ZXIoZnVuY3Rpb24obGluZSkge1xuICAgIHJldHVybiBsaW5lLmluZGV4T2YocHJlZml4KSA9PT0gMDtcbiAgfSk7XG59O1xuXG4vLyBQYXJzZXMgYW4gSUNFIGNhbmRpZGF0ZSBsaW5lLiBTYW1wbGUgaW5wdXQ6XG4vLyBjYW5kaWRhdGU6NzAyNzg2MzUwIDIgdWRwIDQxODE5OTAyIDguOC44LjggNjA3NjkgdHlwIHJlbGF5IHJhZGRyIDguOC44LjggcnBvcnQgNTU5OTZcIlxuU0RQVXRpbHMucGFyc2VDYW5kaWRhdGUgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJ0cztcbiAgLy8gUGFyc2UgYm90aCB2YXJpYW50cy5cbiAgaWYgKGxpbmUuaW5kZXhPZignYT1jYW5kaWRhdGU6JykgPT09IDApIHtcbiAgICBwYXJ0cyA9IGxpbmUuc3Vic3RyaW5nKDEyKS5zcGxpdCgnICcpO1xuICB9IGVsc2Uge1xuICAgIHBhcnRzID0gbGluZS5zdWJzdHJpbmcoMTApLnNwbGl0KCcgJyk7XG4gIH1cblxuICB2YXIgY2FuZGlkYXRlID0ge1xuICAgIGZvdW5kYXRpb246IHBhcnRzWzBdLFxuICAgIGNvbXBvbmVudDogcGFydHNbMV0sXG4gICAgcHJvdG9jb2w6IHBhcnRzWzJdLnRvTG93ZXJDYXNlKCksXG4gICAgcHJpb3JpdHk6IHBhcnNlSW50KHBhcnRzWzNdLCAxMCksXG4gICAgaXA6IHBhcnRzWzRdLFxuICAgIHBvcnQ6IHBhcnNlSW50KHBhcnRzWzVdLCAxMCksXG4gICAgLy8gc2tpcCBwYXJ0c1s2XSA9PSAndHlwJ1xuICAgIHR5cGU6IHBhcnRzWzddXG4gIH07XG5cbiAgZm9yICh2YXIgaSA9IDg7IGkgPCBwYXJ0cy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHN3aXRjaCAocGFydHNbaV0pIHtcbiAgICAgIGNhc2UgJ3JhZGRyJzpcbiAgICAgICAgY2FuZGlkYXRlLnJlbGF0ZWRBZGRyZXNzID0gcGFydHNbaSArIDFdO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3Jwb3J0JzpcbiAgICAgICAgY2FuZGlkYXRlLnJlbGF0ZWRQb3J0ID0gcGFyc2VJbnQocGFydHNbaSArIDFdLCAxMCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndGNwdHlwZSc6XG4gICAgICAgIGNhbmRpZGF0ZS50Y3BUeXBlID0gcGFydHNbaSArIDFdO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6IC8vIFVua25vd24gZXh0ZW5zaW9ucyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBjYW5kaWRhdGU7XG59O1xuXG4vLyBUcmFuc2xhdGVzIGEgY2FuZGlkYXRlIG9iamVjdCBpbnRvIFNEUCBjYW5kaWRhdGUgYXR0cmlidXRlLlxuU0RQVXRpbHMud3JpdGVDYW5kaWRhdGUgPSBmdW5jdGlvbihjYW5kaWRhdGUpIHtcbiAgdmFyIHNkcCA9IFtdO1xuICBzZHAucHVzaChjYW5kaWRhdGUuZm91bmRhdGlvbik7XG4gIHNkcC5wdXNoKGNhbmRpZGF0ZS5jb21wb25lbnQpO1xuICBzZHAucHVzaChjYW5kaWRhdGUucHJvdG9jb2wudG9VcHBlckNhc2UoKSk7XG4gIHNkcC5wdXNoKGNhbmRpZGF0ZS5wcmlvcml0eSk7XG4gIHNkcC5wdXNoKGNhbmRpZGF0ZS5pcCk7XG4gIHNkcC5wdXNoKGNhbmRpZGF0ZS5wb3J0KTtcblxuICB2YXIgdHlwZSA9IGNhbmRpZGF0ZS50eXBlO1xuICBzZHAucHVzaCgndHlwJyk7XG4gIHNkcC5wdXNoKHR5cGUpO1xuICBpZiAodHlwZSAhPT0gJ2hvc3QnICYmIGNhbmRpZGF0ZS5yZWxhdGVkQWRkcmVzcyAmJlxuICAgICAgY2FuZGlkYXRlLnJlbGF0ZWRQb3J0KSB7XG4gICAgc2RwLnB1c2goJ3JhZGRyJyk7XG4gICAgc2RwLnB1c2goY2FuZGlkYXRlLnJlbGF0ZWRBZGRyZXNzKTsgLy8gd2FzOiByZWxBZGRyXG4gICAgc2RwLnB1c2goJ3Jwb3J0Jyk7XG4gICAgc2RwLnB1c2goY2FuZGlkYXRlLnJlbGF0ZWRQb3J0KTsgLy8gd2FzOiByZWxQb3J0XG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS50Y3BUeXBlICYmIGNhbmRpZGF0ZS5wcm90b2NvbC50b0xvd2VyQ2FzZSgpID09PSAndGNwJykge1xuICAgIHNkcC5wdXNoKCd0Y3B0eXBlJyk7XG4gICAgc2RwLnB1c2goY2FuZGlkYXRlLnRjcFR5cGUpO1xuICB9XG4gIHJldHVybiAnY2FuZGlkYXRlOicgKyBzZHAuam9pbignICcpO1xufTtcblxuLy8gUGFyc2VzIGFuIHJ0cG1hcCBsaW5lLCByZXR1cm5zIFJUQ1J0cENvZGRlY1BhcmFtZXRlcnMuIFNhbXBsZSBpbnB1dDpcbi8vIGE9cnRwbWFwOjExMSBvcHVzLzQ4MDAwLzJcblNEUFV0aWxzLnBhcnNlUnRwTWFwID0gZnVuY3Rpb24obGluZSkge1xuICB2YXIgcGFydHMgPSBsaW5lLnN1YnN0cig5KS5zcGxpdCgnICcpO1xuICB2YXIgcGFyc2VkID0ge1xuICAgIHBheWxvYWRUeXBlOiBwYXJzZUludChwYXJ0cy5zaGlmdCgpLCAxMCkgLy8gd2FzOiBpZFxuICB9O1xuXG4gIHBhcnRzID0gcGFydHNbMF0uc3BsaXQoJy8nKTtcblxuICBwYXJzZWQubmFtZSA9IHBhcnRzWzBdO1xuICBwYXJzZWQuY2xvY2tSYXRlID0gcGFyc2VJbnQocGFydHNbMV0sIDEwKTsgLy8gd2FzOiBjbG9ja3JhdGVcbiAgcGFyc2VkLm51bUNoYW5uZWxzID0gcGFydHMubGVuZ3RoID09PSAzID8gcGFyc2VJbnQocGFydHNbMl0sIDEwKSA6IDE7IC8vIHdhczogY2hhbm5lbHNcbiAgcmV0dXJuIHBhcnNlZDtcbn07XG5cbi8vIEdlbmVyYXRlIGFuIGE9cnRwbWFwIGxpbmUgZnJvbSBSVENSdHBDb2RlY0NhcGFiaWxpdHkgb3IgUlRDUnRwQ29kZWNQYXJhbWV0ZXJzLlxuU0RQVXRpbHMud3JpdGVSdHBNYXAgPSBmdW5jdGlvbihjb2RlYykge1xuICB2YXIgcHQgPSBjb2RlYy5wYXlsb2FkVHlwZTtcbiAgaWYgKGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICBwdCA9IGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlO1xuICB9XG4gIHJldHVybiAnYT1ydHBtYXA6JyArIHB0ICsgJyAnICsgY29kZWMubmFtZSArICcvJyArIGNvZGVjLmNsb2NrUmF0ZSArXG4gICAgICAoY29kZWMubnVtQ2hhbm5lbHMgIT09IDEgPyAnLycgKyBjb2RlYy5udW1DaGFubmVscyA6ICcnKSArICdcXHJcXG4nO1xufTtcblxuLy8gUGFyc2VzIGFuIGZ0bXAgbGluZSwgcmV0dXJucyBkaWN0aW9uYXJ5LiBTYW1wbGUgaW5wdXQ6XG4vLyBhPWZtdHA6OTYgdmJyPW9uO2NuZz1vblxuLy8gQWxzbyBkZWFscyB3aXRoIHZicj1vbjsgY25nPW9uXG5TRFBVdGlscy5wYXJzZUZtdHAgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJzZWQgPSB7fTtcbiAgdmFyIGt2O1xuICB2YXIgcGFydHMgPSBsaW5lLnN1YnN0cihsaW5lLmluZGV4T2YoJyAnKSArIDEpLnNwbGl0KCc7Jyk7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICBrdiA9IHBhcnRzW2pdLnRyaW0oKS5zcGxpdCgnPScpO1xuICAgIHBhcnNlZFtrdlswXS50cmltKCldID0ga3ZbMV07XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn07XG5cbi8vIEdlbmVyYXRlcyBhbiBhPWZ0bXAgbGluZSBmcm9tIFJUQ1J0cENvZGVjQ2FwYWJpbGl0eSBvciBSVENSdHBDb2RlY1BhcmFtZXRlcnMuXG5TRFBVdGlscy53cml0ZUZ0bXAgPSBmdW5jdGlvbihjb2RlYykge1xuICB2YXIgbGluZSA9ICcnO1xuICB2YXIgcHQgPSBjb2RlYy5wYXlsb2FkVHlwZTtcbiAgaWYgKGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICBwdCA9IGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlO1xuICB9XG4gIGlmIChjb2RlYy5wYXJhbWV0ZXJzICYmIGNvZGVjLnBhcmFtZXRlcnMubGVuZ3RoKSB7XG4gICAgdmFyIHBhcmFtcyA9IFtdO1xuICAgIE9iamVjdC5rZXlzKGNvZGVjLnBhcmFtZXRlcnMpLmZvckVhY2goZnVuY3Rpb24ocGFyYW0pIHtcbiAgICAgIHBhcmFtcy5wdXNoKHBhcmFtICsgJz0nICsgY29kZWMucGFyYW1ldGVyc1twYXJhbV0pO1xuICAgIH0pO1xuICAgIGxpbmUgKz0gJ2E9Zm10cDonICsgcHQgKyAnICcgKyBwYXJhbXMuam9pbignOycpICsgJ1xcclxcbic7XG4gIH1cbiAgcmV0dXJuIGxpbmU7XG59O1xuXG4vLyBQYXJzZXMgYW4gcnRjcC1mYiBsaW5lLCByZXR1cm5zIFJUQ1BSdGNwRmVlZGJhY2sgb2JqZWN0LiBTYW1wbGUgaW5wdXQ6XG4vLyBhPXJ0Y3AtZmI6OTggbmFjayBycHNpXG5TRFBVdGlscy5wYXJzZVJ0Y3BGYiA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgdmFyIHBhcnRzID0gbGluZS5zdWJzdHIobGluZS5pbmRleE9mKCcgJykgKyAxKS5zcGxpdCgnICcpO1xuICByZXR1cm4ge1xuICAgIHR5cGU6IHBhcnRzLnNoaWZ0KCksXG4gICAgcGFyYW1ldGVyOiBwYXJ0cy5qb2luKCcgJylcbiAgfTtcbn07XG4vLyBHZW5lcmF0ZSBhPXJ0Y3AtZmIgbGluZXMgZnJvbSBSVENSdHBDb2RlY0NhcGFiaWxpdHkgb3IgUlRDUnRwQ29kZWNQYXJhbWV0ZXJzLlxuU0RQVXRpbHMud3JpdGVSdGNwRmIgPSBmdW5jdGlvbihjb2RlYykge1xuICB2YXIgbGluZXMgPSAnJztcbiAgdmFyIHB0ID0gY29kZWMucGF5bG9hZFR5cGU7XG4gIGlmIChjb2RlYy5wcmVmZXJyZWRQYXlsb2FkVHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcHQgPSBjb2RlYy5wcmVmZXJyZWRQYXlsb2FkVHlwZTtcbiAgfVxuICBpZiAoY29kZWMucnRjcEZlZWRiYWNrICYmIGNvZGVjLnJ0Y3BGZWVkYmFjay5sZW5ndGgpIHtcbiAgICAvLyBGSVhNRTogc3BlY2lhbCBoYW5kbGluZyBmb3IgdHJyLWludD9cbiAgICBjb2RlYy5ydGNwRmVlZGJhY2suZm9yRWFjaChmdW5jdGlvbihmYikge1xuICAgICAgbGluZXMgKz0gJ2E9cnRjcC1mYjonICsgcHQgKyAnICcgKyBmYi50eXBlICsgJyAnICsgZmIucGFyYW1ldGVyICtcbiAgICAgICAgICAnXFxyXFxuJztcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gbGluZXM7XG59O1xuXG4vLyBQYXJzZXMgYW4gUkZDIDU1NzYgc3NyYyBtZWRpYSBhdHRyaWJ1dGUuIFNhbXBsZSBpbnB1dDpcbi8vIGE9c3NyYzozNzM1OTI4NTU5IGNuYW1lOnNvbWV0aGluZ1xuU0RQVXRpbHMucGFyc2VTc3JjTWVkaWEgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBzcCA9IGxpbmUuaW5kZXhPZignICcpO1xuICB2YXIgcGFydHMgPSB7XG4gICAgc3NyYzogbGluZS5zdWJzdHIoNywgc3AgLSA3KSxcbiAgfTtcbiAgdmFyIGNvbG9uID0gbGluZS5pbmRleE9mKCc6Jywgc3ApO1xuICBpZiAoY29sb24gPiAtMSkge1xuICAgIHBhcnRzLmF0dHJpYnV0ZSA9IGxpbmUuc3Vic3RyKHNwICsgMSwgY29sb24gLSBzcCAtIDEpO1xuICAgIHBhcnRzLnZhbHVlID0gbGluZS5zdWJzdHIoY29sb24gKyAxKTtcbiAgfSBlbHNlIHtcbiAgICBwYXJ0cy5hdHRyaWJ1dGUgPSBsaW5lLnN1YnN0cihzcCArIDEpO1xuICB9XG4gIHJldHVybiBwYXJ0cztcbn07XG5cbi8vIEV4dHJhY3RzIERUTFMgcGFyYW1ldGVycyBmcm9tIFNEUCBtZWRpYSBzZWN0aW9uIG9yIHNlc3Npb25wYXJ0LlxuLy8gRklYTUU6IGZvciBjb25zaXN0ZW5jeSB3aXRoIG90aGVyIGZ1bmN0aW9ucyB0aGlzIHNob3VsZCBvbmx5XG4vLyAgIGdldCB0aGUgZmluZ2VycHJpbnQgbGluZSBhcyBpbnB1dC4gU2VlIGFsc28gZ2V0SWNlUGFyYW1ldGVycy5cblNEUFV0aWxzLmdldER0bHNQYXJhbWV0ZXJzID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uLCBzZXNzaW9ucGFydCkge1xuICB2YXIgbGluZXMgPSBTRFBVdGlscy5zcGxpdExpbmVzKG1lZGlhU2VjdGlvbik7XG4gIGxpbmVzID0gbGluZXMuY29uY2F0KFNEUFV0aWxzLnNwbGl0TGluZXMoc2Vzc2lvbnBhcnQpKTsgLy8gU2VhcmNoIGluIHNlc3Npb24gcGFydCwgdG9vLlxuICB2YXIgZnBMaW5lID0gbGluZXMuZmlsdGVyKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICByZXR1cm4gbGluZS5pbmRleE9mKCdhPWZpbmdlcnByaW50OicpID09PSAwO1xuICB9KVswXS5zdWJzdHIoMTQpO1xuICAvLyBOb3RlOiBhPXNldHVwIGxpbmUgaXMgaWdub3JlZCBzaW5jZSB3ZSB1c2UgdGhlICdhdXRvJyByb2xlLlxuICB2YXIgZHRsc1BhcmFtZXRlcnMgPSB7XG4gICAgcm9sZTogJ2F1dG8nLFxuICAgIGZpbmdlcnByaW50czogW3tcbiAgICAgIGFsZ29yaXRobTogZnBMaW5lLnNwbGl0KCcgJylbMF0sXG4gICAgICB2YWx1ZTogZnBMaW5lLnNwbGl0KCcgJylbMV1cbiAgICB9XVxuICB9O1xuICByZXR1cm4gZHRsc1BhcmFtZXRlcnM7XG59O1xuXG4vLyBTZXJpYWxpemVzIERUTFMgcGFyYW1ldGVycyB0byBTRFAuXG5TRFBVdGlscy53cml0ZUR0bHNQYXJhbWV0ZXJzID0gZnVuY3Rpb24ocGFyYW1zLCBzZXR1cFR5cGUpIHtcbiAgdmFyIHNkcCA9ICdhPXNldHVwOicgKyBzZXR1cFR5cGUgKyAnXFxyXFxuJztcbiAgcGFyYW1zLmZpbmdlcnByaW50cy5mb3JFYWNoKGZ1bmN0aW9uKGZwKSB7XG4gICAgc2RwICs9ICdhPWZpbmdlcnByaW50OicgKyBmcC5hbGdvcml0aG0gKyAnICcgKyBmcC52YWx1ZSArICdcXHJcXG4nO1xuICB9KTtcbiAgcmV0dXJuIHNkcDtcbn07XG4vLyBQYXJzZXMgSUNFIGluZm9ybWF0aW9uIGZyb20gU0RQIG1lZGlhIHNlY3Rpb24gb3Igc2Vzc2lvbnBhcnQuXG4vLyBGSVhNRTogZm9yIGNvbnNpc3RlbmN5IHdpdGggb3RoZXIgZnVuY3Rpb25zIHRoaXMgc2hvdWxkIG9ubHlcbi8vICAgZ2V0IHRoZSBpY2UtdWZyYWcgYW5kIGljZS1wd2QgbGluZXMgYXMgaW5wdXQuXG5TRFBVdGlscy5nZXRJY2VQYXJhbWV0ZXJzID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uLCBzZXNzaW9ucGFydCkge1xuICB2YXIgbGluZXMgPSBTRFBVdGlscy5zcGxpdExpbmVzKG1lZGlhU2VjdGlvbik7XG4gIGxpbmVzID0gbGluZXMuY29uY2F0KFNEUFV0aWxzLnNwbGl0TGluZXMoc2Vzc2lvbnBhcnQpKTsgLy8gU2VhcmNoIGluIHNlc3Npb24gcGFydCwgdG9vLlxuICB2YXIgaWNlUGFyYW1ldGVycyA9IHtcbiAgICB1c2VybmFtZUZyYWdtZW50OiBsaW5lcy5maWx0ZXIoZnVuY3Rpb24obGluZSkge1xuICAgICAgcmV0dXJuIGxpbmUuaW5kZXhPZignYT1pY2UtdWZyYWc6JykgPT09IDA7XG4gICAgfSlbMF0uc3Vic3RyKDEyKSxcbiAgICBwYXNzd29yZDogbGluZXMuZmlsdGVyKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIHJldHVybiBsaW5lLmluZGV4T2YoJ2E9aWNlLXB3ZDonKSA9PT0gMDtcbiAgICB9KVswXS5zdWJzdHIoMTApXG4gIH07XG4gIHJldHVybiBpY2VQYXJhbWV0ZXJzO1xufTtcblxuLy8gU2VyaWFsaXplcyBJQ0UgcGFyYW1ldGVycyB0byBTRFAuXG5TRFBVdGlscy53cml0ZUljZVBhcmFtZXRlcnMgPSBmdW5jdGlvbihwYXJhbXMpIHtcbiAgcmV0dXJuICdhPWljZS11ZnJhZzonICsgcGFyYW1zLnVzZXJuYW1lRnJhZ21lbnQgKyAnXFxyXFxuJyArXG4gICAgICAnYT1pY2UtcHdkOicgKyBwYXJhbXMucGFzc3dvcmQgKyAnXFxyXFxuJztcbn07XG5cbi8vIFBhcnNlcyB0aGUgU0RQIG1lZGlhIHNlY3Rpb24gYW5kIHJldHVybnMgUlRDUnRwUGFyYW1ldGVycy5cblNEUFV0aWxzLnBhcnNlUnRwUGFyYW1ldGVycyA9IGZ1bmN0aW9uKG1lZGlhU2VjdGlvbikge1xuICB2YXIgZGVzY3JpcHRpb24gPSB7XG4gICAgY29kZWNzOiBbXSxcbiAgICBoZWFkZXJFeHRlbnNpb25zOiBbXSxcbiAgICBmZWNNZWNoYW5pc21zOiBbXSxcbiAgICBydGNwOiBbXVxuICB9O1xuICB2YXIgbGluZXMgPSBTRFBVdGlscy5zcGxpdExpbmVzKG1lZGlhU2VjdGlvbik7XG4gIHZhciBtbGluZSA9IGxpbmVzWzBdLnNwbGl0KCcgJyk7XG4gIGZvciAodmFyIGkgPSAzOyBpIDwgbWxpbmUubGVuZ3RoOyBpKyspIHsgLy8gZmluZCBhbGwgY29kZWNzIGZyb20gbWxpbmVbMy4uXVxuICAgIHZhciBwdCA9IG1saW5lW2ldO1xuICAgIHZhciBydHBtYXBsaW5lID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgoXG4gICAgICAgIG1lZGlhU2VjdGlvbiwgJ2E9cnRwbWFwOicgKyBwdCArICcgJylbMF07XG4gICAgaWYgKHJ0cG1hcGxpbmUpIHtcbiAgICAgIHZhciBjb2RlYyA9IFNEUFV0aWxzLnBhcnNlUnRwTWFwKHJ0cG1hcGxpbmUpO1xuICAgICAgdmFyIGZtdHBzID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgoXG4gICAgICAgICAgbWVkaWFTZWN0aW9uLCAnYT1mbXRwOicgKyBwdCArICcgJyk7XG4gICAgICAvLyBPbmx5IHRoZSBmaXJzdCBhPWZtdHA6PHB0PiBpcyBjb25zaWRlcmVkLlxuICAgICAgY29kZWMucGFyYW1ldGVycyA9IGZtdHBzLmxlbmd0aCA/IFNEUFV0aWxzLnBhcnNlRm10cChmbXRwc1swXSkgOiB7fTtcbiAgICAgIGNvZGVjLnJ0Y3BGZWVkYmFjayA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KFxuICAgICAgICAgIG1lZGlhU2VjdGlvbiwgJ2E9cnRjcC1mYjonICsgcHQgKyAnICcpXG4gICAgICAgIC5tYXAoU0RQVXRpbHMucGFyc2VSdGNwRmIpO1xuICAgICAgZGVzY3JpcHRpb24uY29kZWNzLnB1c2goY29kZWMpO1xuICAgIH1cbiAgfVxuICAvLyBGSVhNRTogcGFyc2UgaGVhZGVyRXh0ZW5zaW9ucywgZmVjTWVjaGFuaXNtcyBhbmQgcnRjcC5cbiAgcmV0dXJuIGRlc2NyaXB0aW9uO1xufTtcblxuLy8gR2VuZXJhdGVzIHBhcnRzIG9mIHRoZSBTRFAgbWVkaWEgc2VjdGlvbiBkZXNjcmliaW5nIHRoZSBjYXBhYmlsaXRpZXMgLyBwYXJhbWV0ZXJzLlxuU0RQVXRpbHMud3JpdGVSdHBEZXNjcmlwdGlvbiA9IGZ1bmN0aW9uKGtpbmQsIGNhcHMpIHtcbiAgdmFyIHNkcCA9ICcnO1xuXG4gIC8vIEJ1aWxkIHRoZSBtbGluZS5cbiAgc2RwICs9ICdtPScgKyBraW5kICsgJyAnO1xuICBzZHAgKz0gY2Fwcy5jb2RlY3MubGVuZ3RoID4gMCA/ICc5JyA6ICcwJzsgLy8gcmVqZWN0IGlmIG5vIGNvZGVjcy5cbiAgc2RwICs9ICcgVURQL1RMUy9SVFAvU0FWUEYgJztcbiAgc2RwICs9IGNhcHMuY29kZWNzLm1hcChmdW5jdGlvbihjb2RlYykge1xuICAgIGlmIChjb2RlYy5wcmVmZXJyZWRQYXlsb2FkVHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gY29kZWMucHJlZmVycmVkUGF5bG9hZFR5cGU7XG4gICAgfVxuICAgIHJldHVybiBjb2RlYy5wYXlsb2FkVHlwZTtcbiAgfSkuam9pbignICcpICsgJ1xcclxcbic7XG5cbiAgc2RwICs9ICdjPUlOIElQNCAwLjAuMC4wXFxyXFxuJztcbiAgc2RwICs9ICdhPXJ0Y3A6OSBJTiBJUDQgMC4wLjAuMFxcclxcbic7XG5cbiAgLy8gQWRkIGE9cnRwbWFwIGxpbmVzIGZvciBlYWNoIGNvZGVjLiBBbHNvIGZtdHAgYW5kIHJ0Y3AtZmIuXG4gIGNhcHMuY29kZWNzLmZvckVhY2goZnVuY3Rpb24oY29kZWMpIHtcbiAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVSdHBNYXAoY29kZWMpO1xuICAgIHNkcCArPSBTRFBVdGlscy53cml0ZUZ0bXAoY29kZWMpO1xuICAgIHNkcCArPSBTRFBVdGlscy53cml0ZVJ0Y3BGYihjb2RlYyk7XG4gIH0pO1xuICAvLyBGSVhNRTogYWRkIGhlYWRlckV4dGVuc2lvbnMsIGZlY01lY2hhbmlzbcWfIGFuZCBydGNwLlxuICBzZHAgKz0gJ2E9cnRjcC1tdXhcXHJcXG4nO1xuICByZXR1cm4gc2RwO1xufTtcblxuU0RQVXRpbHMud3JpdGVTZXNzaW9uQm9pbGVycGxhdGUgPSBmdW5jdGlvbigpIHtcbiAgLy8gRklYTUU6IHNlc3MtaWQgc2hvdWxkIGJlIGFuIE5UUCB0aW1lc3RhbXAuXG4gIHJldHVybiAndj0wXFxyXFxuJyArXG4gICAgICAnbz10aGlzaXNhZGFwdGVyb3J0YyA4MTY5NjM5OTE1NjQ2OTQzMTM3IDIgSU4gSVA0IDEyNy4wLjAuMVxcclxcbicgK1xuICAgICAgJ3M9LVxcclxcbicgK1xuICAgICAgJ3Q9MCAwXFxyXFxuJztcbn07XG5cblNEUFV0aWxzLndyaXRlTWVkaWFTZWN0aW9uID0gZnVuY3Rpb24odHJhbnNjZWl2ZXIsIGNhcHMsIHR5cGUsIHN0cmVhbSkge1xuICB2YXIgc2RwID0gU0RQVXRpbHMud3JpdGVSdHBEZXNjcmlwdGlvbih0cmFuc2NlaXZlci5raW5kLCBjYXBzKTtcblxuICAvLyBNYXAgSUNFIHBhcmFtZXRlcnMgKHVmcmFnLCBwd2QpIHRvIFNEUC5cbiAgc2RwICs9IFNEUFV0aWxzLndyaXRlSWNlUGFyYW1ldGVycyhcbiAgICAgIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyLmdldExvY2FsUGFyYW1ldGVycygpKTtcblxuICAvLyBNYXAgRFRMUyBwYXJhbWV0ZXJzIHRvIFNEUC5cbiAgc2RwICs9IFNEUFV0aWxzLndyaXRlRHRsc1BhcmFtZXRlcnMoXG4gICAgICB0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0LmdldExvY2FsUGFyYW1ldGVycygpLFxuICAgICAgdHlwZSA9PT0gJ29mZmVyJyA/ICdhY3RwYXNzJyA6ICdhY3RpdmUnKTtcblxuICBzZHAgKz0gJ2E9bWlkOicgKyB0cmFuc2NlaXZlci5taWQgKyAnXFxyXFxuJztcblxuICBpZiAodHJhbnNjZWl2ZXIucnRwU2VuZGVyICYmIHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyKSB7XG4gICAgc2RwICs9ICdhPXNlbmRyZWN2XFxyXFxuJztcbiAgfSBlbHNlIGlmICh0cmFuc2NlaXZlci5ydHBTZW5kZXIpIHtcbiAgICBzZHAgKz0gJ2E9c2VuZG9ubHlcXHJcXG4nO1xuICB9IGVsc2UgaWYgKHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyKSB7XG4gICAgc2RwICs9ICdhPXJlY3Zvbmx5XFxyXFxuJztcbiAgfSBlbHNlIHtcbiAgICBzZHAgKz0gJ2E9aW5hY3RpdmVcXHJcXG4nO1xuICB9XG5cbiAgLy8gRklYTUU6IGZvciBSVFggdGhlcmUgbWlnaHQgYmUgbXVsdGlwbGUgU1NSQ3MuIE5vdCBpbXBsZW1lbnRlZCBpbiBFZGdlIHlldC5cbiAgaWYgKHRyYW5zY2VpdmVyLnJ0cFNlbmRlcikge1xuICAgIHZhciBtc2lkID0gJ21zaWQ6JyArIHN0cmVhbS5pZCArICcgJyArXG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0cFNlbmRlci50cmFjay5pZCArICdcXHJcXG4nO1xuICAgIHNkcCArPSAnYT0nICsgbXNpZDtcbiAgICBzZHAgKz0gJ2E9c3NyYzonICsgdHJhbnNjZWl2ZXIuc2VuZFNzcmMgKyAnICcgKyBtc2lkO1xuICB9XG4gIC8vIEZJWE1FOiB0aGlzIHNob3VsZCBiZSB3cml0dGVuIGJ5IHdyaXRlUnRwRGVzY3JpcHRpb24uXG4gIHNkcCArPSAnYT1zc3JjOicgKyB0cmFuc2NlaXZlci5zZW5kU3NyYyArICcgY25hbWU6JyArXG4gICAgICBTRFBVdGlscy5sb2NhbENOYW1lICsgJ1xcclxcbic7XG4gIHJldHVybiBzZHA7XG59O1xuXG4vLyBHZXRzIHRoZSBkaXJlY3Rpb24gZnJvbSB0aGUgbWVkaWFTZWN0aW9uIG9yIHRoZSBzZXNzaW9ucGFydC5cblNEUFV0aWxzLmdldERpcmVjdGlvbiA9IGZ1bmN0aW9uKG1lZGlhU2VjdGlvbiwgc2Vzc2lvbnBhcnQpIHtcbiAgLy8gTG9vayBmb3Igc2VuZHJlY3YsIHNlbmRvbmx5LCByZWN2b25seSwgaW5hY3RpdmUsIGRlZmF1bHQgdG8gc2VuZHJlY3YuXG4gIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIHN3aXRjaCAobGluZXNbaV0pIHtcbiAgICAgIGNhc2UgJ2E9c2VuZHJlY3YnOlxuICAgICAgY2FzZSAnYT1zZW5kb25seSc6XG4gICAgICBjYXNlICdhPXJlY3Zvbmx5JzpcbiAgICAgIGNhc2UgJ2E9aW5hY3RpdmUnOlxuICAgICAgICByZXR1cm4gbGluZXNbaV0uc3Vic3RyKDIpO1xuICAgIH1cbiAgfVxuICBpZiAoc2Vzc2lvbnBhcnQpIHtcbiAgICByZXR1cm4gU0RQVXRpbHMuZ2V0RGlyZWN0aW9uKHNlc3Npb25wYXJ0KTtcbiAgfVxuICByZXR1cm4gJ3NlbmRyZWN2Jztcbn07XG5cbi8vIEV4cG9zZSBwdWJsaWMgbWV0aG9kcy5cbm1vZHVsZS5leHBvcnRzID0gU0RQVXRpbHM7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi93ZWJydGMtYWRhcHRlci9zcmMvanMvZWRnZS9lZGdlX3NkcC5qc1xuICoqIG1vZHVsZSBpZCA9IDE1MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBTRFBVdGlscyA9IHJlcXVpcmUoJy4vZWRnZV9zZHAnKTtcbnZhciBsb2dnaW5nID0gcmVxdWlyZSgnLi4vdXRpbHMnKS5sb2c7XG52YXIgYnJvd3NlckRldGFpbHMgPSByZXF1aXJlKCcuLi91dGlscycpLmJyb3dzZXJEZXRhaWxzO1xuXG52YXIgZWRnZVNoaW0gPSB7XG4gIHNoaW1QZWVyQ29ubmVjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHdpbmRvdy5SVENJY2VHYXRoZXJlcikge1xuICAgICAgLy8gT1JUQyBkZWZpbmVzIGFuIFJUQ0ljZUNhbmRpZGF0ZSBvYmplY3QgYnV0IG5vIGNvbnN0cnVjdG9yLlxuICAgICAgLy8gTm90IGltcGxlbWVudGVkIGluIEVkZ2UuXG4gICAgICBpZiAoIXdpbmRvdy5SVENJY2VDYW5kaWRhdGUpIHtcbiAgICAgICAgd2luZG93LlJUQ0ljZUNhbmRpZGF0ZSA9IGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgICByZXR1cm4gYXJncztcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIC8vIE9SVEMgZG9lcyBub3QgaGF2ZSBhIHNlc3Npb24gZGVzY3JpcHRpb24gb2JqZWN0IGJ1dFxuICAgICAgLy8gb3RoZXIgYnJvd3NlcnMgKGkuZS4gQ2hyb21lKSB0aGF0IHdpbGwgc3VwcG9ydCBib3RoIFBDIGFuZCBPUlRDXG4gICAgICAvLyBpbiB0aGUgZnV0dXJlIG1pZ2h0IGhhdmUgdGhpcyBkZWZpbmVkIGFscmVhZHkuXG4gICAgICBpZiAoIXdpbmRvdy5SVENTZXNzaW9uRGVzY3JpcHRpb24pIHtcbiAgICAgICAgd2luZG93LlJUQ1Nlc3Npb25EZXNjcmlwdGlvbiA9IGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgICByZXR1cm4gYXJncztcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gPSBmdW5jdGlvbihjb25maWcpIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgdmFyIF9ldmVudFRhcmdldCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgIFsnYWRkRXZlbnRMaXN0ZW5lcicsICdyZW1vdmVFdmVudExpc3RlbmVyJywgJ2Rpc3BhdGNoRXZlbnQnXS5mb3JFYWNoKFxuICAgICAgICAgIGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgICBzZWxmW21ldGhvZF0gPSBfZXZlbnRUYXJnZXRbbWV0aG9kXS5iaW5kKF9ldmVudFRhcmdldCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5vbmljZWNhbmRpZGF0ZSA9IG51bGw7XG4gICAgICB0aGlzLm9uYWRkc3RyZWFtID0gbnVsbDtcbiAgICAgIHRoaXMub250cmFjayA9IG51bGw7XG4gICAgICB0aGlzLm9ucmVtb3Zlc3RyZWFtID0gbnVsbDtcbiAgICAgIHRoaXMub25zaWduYWxpbmdzdGF0ZWNoYW5nZSA9IG51bGw7XG4gICAgICB0aGlzLm9uaWNlY29ubmVjdGlvbnN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgIHRoaXMub25uZWdvdGlhdGlvbm5lZWRlZCA9IG51bGw7XG4gICAgICB0aGlzLm9uZGF0YWNoYW5uZWwgPSBudWxsO1xuXG4gICAgICB0aGlzLmxvY2FsU3RyZWFtcyA9IFtdO1xuICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zID0gW107XG4gICAgICB0aGlzLmdldExvY2FsU3RyZWFtcyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gc2VsZi5sb2NhbFN0cmVhbXM7IH07XG4gICAgICB0aGlzLmdldFJlbW90ZVN0cmVhbXMgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHNlbGYucmVtb3RlU3RyZWFtczsgfTtcblxuICAgICAgdGhpcy5sb2NhbERlc2NyaXB0aW9uID0gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICAgIHR5cGU6ICcnLFxuICAgICAgICBzZHA6ICcnXG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVtb3RlRGVzY3JpcHRpb24gPSBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgICAgdHlwZTogJycsXG4gICAgICAgIHNkcDogJydcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zaWduYWxpbmdTdGF0ZSA9ICdzdGFibGUnO1xuICAgICAgdGhpcy5pY2VDb25uZWN0aW9uU3RhdGUgPSAnbmV3JztcbiAgICAgIHRoaXMuaWNlR2F0aGVyaW5nU3RhdGUgPSAnbmV3JztcblxuICAgICAgdGhpcy5pY2VPcHRpb25zID0ge1xuICAgICAgICBnYXRoZXJQb2xpY3k6ICdhbGwnLFxuICAgICAgICBpY2VTZXJ2ZXJzOiBbXVxuICAgICAgfTtcbiAgICAgIGlmIChjb25maWcgJiYgY29uZmlnLmljZVRyYW5zcG9ydFBvbGljeSkge1xuICAgICAgICBzd2l0Y2ggKGNvbmZpZy5pY2VUcmFuc3BvcnRQb2xpY3kpIHtcbiAgICAgICAgICBjYXNlICdhbGwnOlxuICAgICAgICAgIGNhc2UgJ3JlbGF5JzpcbiAgICAgICAgICAgIHRoaXMuaWNlT3B0aW9ucy5nYXRoZXJQb2xpY3kgPSBjb25maWcuaWNlVHJhbnNwb3J0UG9saWN5O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnbm9uZSc6XG4gICAgICAgICAgICAvLyBGSVhNRTogcmVtb3ZlIG9uY2UgaW1wbGVtZW50YXRpb24gYW5kIHNwZWMgaGF2ZSBhZGRlZCB0aGlzLlxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaWNlVHJhbnNwb3J0UG9saWN5IFwibm9uZVwiIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGNvbmZpZyAmJiBjb25maWcuaWNlU2VydmVycykge1xuICAgICAgICAvLyBFZGdlIGRvZXMgbm90IGxpa2VcbiAgICAgICAgLy8gMSkgc3R1bjpcbiAgICAgICAgLy8gMikgdHVybjogdGhhdCBkb2VzIG5vdCBoYXZlIGFsbCBvZiB0dXJuOmhvc3Q6cG9ydD90cmFuc3BvcnQ9dWRwXG4gICAgICAgIHRoaXMuaWNlT3B0aW9ucy5pY2VTZXJ2ZXJzID0gY29uZmlnLmljZVNlcnZlcnMuZmlsdGVyKGZ1bmN0aW9uKHNlcnZlcikge1xuICAgICAgICAgIGlmIChzZXJ2ZXIgJiYgc2VydmVyLnVybHMpIHtcbiAgICAgICAgICAgIHNlcnZlci51cmxzID0gc2VydmVyLnVybHMuZmlsdGVyKGZ1bmN0aW9uKHVybCkge1xuICAgICAgICAgICAgICByZXR1cm4gdXJsLmluZGV4T2YoJ3RyYW5zcG9ydD11ZHAnKSAhPT0gLTE7XG4gICAgICAgICAgICB9KVswXTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBwZXItdHJhY2sgaWNlR2F0aGVycywgaWNlVHJhbnNwb3J0cywgZHRsc1RyYW5zcG9ydHMsIHJ0cFNlbmRlcnMsIC4uLlxuICAgICAgLy8gZXZlcnl0aGluZyB0aGF0IGlzIG5lZWRlZCB0byBkZXNjcmliZSBhIFNEUCBtLWxpbmUuXG4gICAgICB0aGlzLnRyYW5zY2VpdmVycyA9IFtdO1xuXG4gICAgICAvLyBzaW5jZSB0aGUgaWNlR2F0aGVyZXIgaXMgY3VycmVudGx5IGNyZWF0ZWQgaW4gY3JlYXRlT2ZmZXIgYnV0IHdlXG4gICAgICAvLyBtdXN0IG5vdCBlbWl0IGNhbmRpZGF0ZXMgdW50aWwgYWZ0ZXIgc2V0TG9jYWxEZXNjcmlwdGlvbiB3ZSBidWZmZXJcbiAgICAgIC8vIHRoZW0gaW4gdGhpcyBhcnJheS5cbiAgICAgIHRoaXMuX2xvY2FsSWNlQ2FuZGlkYXRlc0J1ZmZlciA9IFtdO1xuICAgIH07XG5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLl9lbWl0QnVmZmVyZWRDYW5kaWRhdGVzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICB2YXIgc2VjdGlvbnMgPSBTRFBVdGlscy5zcGxpdFNlY3Rpb25zKHNlbGYubG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgLy8gRklYTUU6IG5lZWQgdG8gYXBwbHkgaWNlIGNhbmRpZGF0ZXMgaW4gYSB3YXkgd2hpY2ggaXMgYXN5bmMgYnV0IGluLW9yZGVyXG4gICAgICB0aGlzLl9sb2NhbEljZUNhbmRpZGF0ZXNCdWZmZXIuZm9yRWFjaChmdW5jdGlvbihldmVudCkge1xuICAgICAgICB2YXIgZW5kID0gIWV2ZW50LmNhbmRpZGF0ZSB8fCBPYmplY3Qua2V5cyhldmVudC5jYW5kaWRhdGUpLmxlbmd0aCA9PSAwO1xuICAgICAgICBpZiAoZW5kKSB7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IDE7IGogPCBzZWN0aW9ucy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgc2VjdGlvbnNbal0gKz0gJ2E9ZW5kLW9mLWNhbmRpZGF0ZXNcXHJcXG4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZWN0aW9uc1tldmVudC5jYW5kaWRhdGUuc2RwTUxpbmVJbmRleCArIDFdICs9XG4gICAgICAgICAgICAgICdhPScgKyBldmVudC5jYW5kaWRhdGUuY2FuZGlkYXRlICsgJ1xcclxcbic7XG4gICAgICAgIH1cbiAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgaWYgKHNlbGYub25pY2VjYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICBzZWxmLm9uaWNlY2FuZGlkYXRlKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWV2ZW50LmNhbmRpZGF0ZSkge1xuICAgICAgICAgIHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUgPSAnY29tcGxldGUnO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuX2xvY2FsSWNlQ2FuZGlkYXRlc0J1ZmZlciA9IFtdO1xuICAgICAgdGhpcy5sb2NhbERlc2NyaXB0aW9uLnNkcCA9IHNlY3Rpb25zLmpvaW4oJycpO1xuICAgIH07XG5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZFN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgLy8gQ2xvbmUgaXMgbmVjZXNzYXJ5IGZvciBsb2NhbCBkZW1vcyBtb3N0bHksIGF0dGFjaGluZyBkaXJlY3RseVxuICAgICAgLy8gdG8gdHdvIGRpZmZlcmVudCBzZW5kZXJzIGRvZXMgbm90IHdvcmsgKGJ1aWxkIDEwNTQ3KS5cbiAgICAgIHRoaXMubG9jYWxTdHJlYW1zLnB1c2goc3RyZWFtLmNsb25lKCkpO1xuICAgICAgdGhpcy5fbWF5YmVGaXJlTmVnb3RpYXRpb25OZWVkZWQoKTtcbiAgICB9O1xuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVTdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgIHZhciBpZHggPSB0aGlzLmxvY2FsU3RyZWFtcy5pbmRleE9mKHN0cmVhbSk7XG4gICAgICBpZiAoaWR4ID4gLTEpIHtcbiAgICAgICAgdGhpcy5sb2NhbFN0cmVhbXMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgIHRoaXMuX21heWJlRmlyZU5lZ290aWF0aW9uTmVlZGVkKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIERldGVybWluZXMgdGhlIGludGVyc2VjdGlvbiBvZiBsb2NhbCBhbmQgcmVtb3RlIGNhcGFiaWxpdGllcy5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLl9nZXRDb21tb25DYXBhYmlsaXRpZXMgPVxuICAgICAgICBmdW5jdGlvbihsb2NhbENhcGFiaWxpdGllcywgcmVtb3RlQ2FwYWJpbGl0aWVzKSB7XG4gICAgICB2YXIgY29tbW9uQ2FwYWJpbGl0aWVzID0ge1xuICAgICAgICBjb2RlY3M6IFtdLFxuICAgICAgICBoZWFkZXJFeHRlbnNpb25zOiBbXSxcbiAgICAgICAgZmVjTWVjaGFuaXNtczogW11cbiAgICAgIH07XG4gICAgICBsb2NhbENhcGFiaWxpdGllcy5jb2RlY3MuZm9yRWFjaChmdW5jdGlvbihsQ29kZWMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZW1vdGVDYXBhYmlsaXRpZXMuY29kZWNzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHJDb2RlYyA9IHJlbW90ZUNhcGFiaWxpdGllcy5jb2RlY3NbaV07XG4gICAgICAgICAgaWYgKGxDb2RlYy5uYW1lLnRvTG93ZXJDYXNlKCkgPT09IHJDb2RlYy5uYW1lLnRvTG93ZXJDYXNlKCkgJiZcbiAgICAgICAgICAgICAgbENvZGVjLmNsb2NrUmF0ZSA9PT0gckNvZGVjLmNsb2NrUmF0ZSAmJlxuICAgICAgICAgICAgICBsQ29kZWMubnVtQ2hhbm5lbHMgPT09IHJDb2RlYy5udW1DaGFubmVscykge1xuICAgICAgICAgICAgLy8gcHVzaCByQ29kZWMgc28gd2UgcmVwbHkgd2l0aCBvZmZlcmVyIHBheWxvYWQgdHlwZVxuICAgICAgICAgICAgY29tbW9uQ2FwYWJpbGl0aWVzLmNvZGVjcy5wdXNoKHJDb2RlYyk7XG5cbiAgICAgICAgICAgIC8vIEZJWE1FOiBhbHNvIG5lZWQgdG8gZGV0ZXJtaW5lIGludGVyc2VjdGlvbiBiZXR3ZWVuXG4gICAgICAgICAgICAvLyAucnRjcEZlZWRiYWNrIGFuZCAucGFyYW1ldGVyc1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgbG9jYWxDYXBhYmlsaXRpZXMuaGVhZGVyRXh0ZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uKGxIZWFkZXJFeHRlbnNpb24pIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZW1vdGVDYXBhYmlsaXRpZXMuaGVhZGVyRXh0ZW5zaW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBySGVhZGVyRXh0ZW5zaW9uID0gcmVtb3RlQ2FwYWJpbGl0aWVzLmhlYWRlckV4dGVuc2lvbnNbaV07XG4gICAgICAgICAgaWYgKGxIZWFkZXJFeHRlbnNpb24udXJpID09PSBySGVhZGVyRXh0ZW5zaW9uLnVyaSkge1xuICAgICAgICAgICAgY29tbW9uQ2FwYWJpbGl0aWVzLmhlYWRlckV4dGVuc2lvbnMucHVzaChySGVhZGVyRXh0ZW5zaW9uKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIEZJWE1FOiBmZWNNZWNoYW5pc21zXG4gICAgICByZXR1cm4gY29tbW9uQ2FwYWJpbGl0aWVzO1xuICAgIH07XG5cbiAgICAvLyBDcmVhdGUgSUNFIGdhdGhlcmVyLCBJQ0UgdHJhbnNwb3J0IGFuZCBEVExTIHRyYW5zcG9ydC5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLl9jcmVhdGVJY2VBbmREdGxzVHJhbnNwb3J0cyA9XG4gICAgICAgIGZ1bmN0aW9uKG1pZCwgc2RwTUxpbmVJbmRleCkge1xuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgdmFyIGljZUdhdGhlcmVyID0gbmV3IFJUQ0ljZUdhdGhlcmVyKHNlbGYuaWNlT3B0aW9ucyk7XG4gICAgICB2YXIgaWNlVHJhbnNwb3J0ID0gbmV3IFJUQ0ljZVRyYW5zcG9ydChpY2VHYXRoZXJlcik7XG4gICAgICBpY2VHYXRoZXJlci5vbmxvY2FsY2FuZGlkYXRlID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgnaWNlY2FuZGlkYXRlJyk7XG4gICAgICAgIGV2ZW50LmNhbmRpZGF0ZSA9IHtzZHBNaWQ6IG1pZCwgc2RwTUxpbmVJbmRleDogc2RwTUxpbmVJbmRleH07XG5cbiAgICAgICAgdmFyIGNhbmQgPSBldnQuY2FuZGlkYXRlO1xuICAgICAgICB2YXIgZW5kID0gIWNhbmQgfHwgT2JqZWN0LmtleXMoY2FuZCkubGVuZ3RoID09PSAwO1xuICAgICAgICAvLyBFZGdlIGVtaXRzIGFuIGVtcHR5IG9iamVjdCBmb3IgUlRDSWNlQ2FuZGlkYXRlQ29tcGxldGXigKVcbiAgICAgICAgaWYgKGVuZCkge1xuICAgICAgICAgIC8vIHBvbHlmaWxsIHNpbmNlIFJUQ0ljZUdhdGhlcmVyLnN0YXRlIGlzIG5vdCBpbXBsZW1lbnRlZCBpbiBFZGdlIDEwNTQ3IHlldC5cbiAgICAgICAgICBpZiAoaWNlR2F0aGVyZXIuc3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWNlR2F0aGVyZXIuc3RhdGUgPSAnY29tcGxldGVkJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBFbWl0IGEgY2FuZGlkYXRlIHdpdGggdHlwZSBlbmRPZkNhbmRpZGF0ZXMgdG8gbWFrZSB0aGUgc2FtcGxlcyB3b3JrLlxuICAgICAgICAgIC8vIEVkZ2UgcmVxdWlyZXMgYWRkSWNlQ2FuZGlkYXRlIHdpdGggdGhpcyBlbXB0eSBjYW5kaWRhdGUgdG8gc3RhcnQgY2hlY2tpbmcuXG4gICAgICAgICAgLy8gVGhlIHJlYWwgc29sdXRpb24gaXMgdG8gc2lnbmFsIGVuZC1vZi1jYW5kaWRhdGVzIHRvIHRoZSBvdGhlciBzaWRlIHdoZW5cbiAgICAgICAgICAvLyBnZXR0aW5nIHRoZSBudWxsIGNhbmRpZGF0ZSBidXQgc29tZSBhcHBzIChsaWtlIHRoZSBzYW1wbGVzKSBkb24ndCBkbyB0aGF0LlxuICAgICAgICAgIGV2ZW50LmNhbmRpZGF0ZS5jYW5kaWRhdGUgPVxuICAgICAgICAgICAgICAnY2FuZGlkYXRlOjEgMSB1ZHAgMSAwLjAuMC4wIDkgdHlwIGVuZE9mQ2FuZGlkYXRlcyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUlRDSWNlQ2FuZGlkYXRlIGRvZXNuJ3QgaGF2ZSBhIGNvbXBvbmVudCwgbmVlZHMgdG8gYmUgYWRkZWRcbiAgICAgICAgICBjYW5kLmNvbXBvbmVudCA9IGljZVRyYW5zcG9ydC5jb21wb25lbnQgPT09ICdSVENQJyA/IDIgOiAxO1xuICAgICAgICAgIGV2ZW50LmNhbmRpZGF0ZS5jYW5kaWRhdGUgPSBTRFBVdGlscy53cml0ZUNhbmRpZGF0ZShjYW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjb21wbGV0ZSA9IHNlbGYudHJhbnNjZWl2ZXJzLmV2ZXJ5KGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICAgICAgcmV0dXJuIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyICYmXG4gICAgICAgICAgICAgIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyLnN0YXRlID09PSAnY29tcGxldGVkJztcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHVwZGF0ZSAubG9jYWxEZXNjcmlwdGlvbiB3aXRoIGNhbmRpZGF0ZSBhbmQgKHBvdGVudGlhbGx5KSBlbmQtb2YtY2FuZGlkYXRlcy5cbiAgICAgICAgLy8gICAgIFRvIG1ha2UgdGhpcyBoYXJkZXIsIHRoZSBnYXRoZXJlciBtaWdodCBlbWl0IGNhbmRpZGF0ZXMgYmVmb3JlIGxvY2FsZGVzY3JpcHRpb25cbiAgICAgICAgLy8gICAgIGlzIHNldC4gVG8gbWFrZSB0aGluZ3Mgd29yc2UsIGdhdGhlci5nZXRMb2NhbENhbmRpZGF0ZXMgc3RpbGwgZXJyb3JzIGluXG4gICAgICAgIC8vICAgICBFZGdlIDEwNTQ3IHdoZW4gbm8gY2FuZGlkYXRlcyBoYXZlIGJlZW4gZ2F0aGVyZWQgeWV0LlxuICAgICAgICBpZiAoc2VsZi5sb2NhbERlc2NyaXB0aW9uICYmIHNlbGYubG9jYWxEZXNjcmlwdGlvbi50eXBlICE9PSAnJykge1xuICAgICAgICAgIHZhciBzZWN0aW9ucyA9IFNEUFV0aWxzLnNwbGl0U2VjdGlvbnMoc2VsZi5sb2NhbERlc2NyaXB0aW9uLnNkcCk7XG4gICAgICAgICAgc2VjdGlvbnNbc2RwTUxpbmVJbmRleCArIDFdICs9ICghZW5kID8gJ2E9JyArIGV2ZW50LmNhbmRpZGF0ZS5jYW5kaWRhdGUgOlxuICAgICAgICAgICAgICAnYT1lbmQtb2YtY2FuZGlkYXRlcycpICsgJ1xcclxcbic7XG4gICAgICAgICAgc2VsZi5sb2NhbERlc2NyaXB0aW9uLnNkcCA9IHNlY3Rpb25zLmpvaW4oJycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRW1pdCBjYW5kaWRhdGUgaWYgbG9jYWxEZXNjcmlwdGlvbiBpcyBzZXQuXG4gICAgICAgIC8vIEFsc28gZW1pdHMgbnVsbCBjYW5kaWRhdGUgd2hlbiBhbGwgZ2F0aGVyZXJzIGFyZSBjb21wbGV0ZS5cbiAgICAgICAgc3dpdGNoKHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUpIHtcbiAgICAgICAgY2FzZSAnbmV3JzpcbiAgICAgICAgICBzZWxmLl9sb2NhbEljZUNhbmRpZGF0ZXNCdWZmZXIucHVzaChldmVudCk7XG4gICAgICAgICAgaWYgKGNvbXBsZXRlKSB7XG4gICAgICAgICAgICBzZWxmLl9sb2NhbEljZUNhbmRpZGF0ZXNCdWZmZXIucHVzaChuZXcgRXZlbnQoJ2ljZWNhbmRpZGF0ZScpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2dhdGhlcmluZyc6XG4gICAgICAgICAgc2VsZi5fZW1pdEJ1ZmZlcmVkQ2FuZGlkYXRlcygpO1xuICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgaWYgKHNlbGYub25pY2VjYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHNlbGYub25pY2VjYW5kaWRhdGUoZXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY29tcGxldGUpIHtcbiAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2ljZWNhbmRpZGF0ZScpKTtcbiAgICAgICAgICAgIGlmIChzZWxmLm9uaWNlY2FuZGlkYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHNlbGYub25pY2VjYW5kaWRhdGUobmV3IEV2ZW50KCdpY2VjYW5kaWRhdGUnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLmljZUdhdGhlcmluZ1N0YXRlID0gJ2NvbXBsZXRlJztcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2NvbXBsZXRlJzpcbiAgICAgICAgICAvLyBzaG91bGQgbm90IGhhcHBlbi4uLiBjdXJyZW50bHkhXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBpY2VUcmFuc3BvcnQub25pY2VzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBzZWxmLl91cGRhdGVDb25uZWN0aW9uU3RhdGUoKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBkdGxzVHJhbnNwb3J0ID0gbmV3IFJUQ0R0bHNUcmFuc3BvcnQoaWNlVHJhbnNwb3J0KTtcbiAgICAgIGR0bHNUcmFuc3BvcnQub25kdGxzc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgc2VsZi5fdXBkYXRlQ29ubmVjdGlvblN0YXRlKCk7XG4gICAgICB9O1xuICAgICAgZHRsc1RyYW5zcG9ydC5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIG9uZXJyb3IgZG9lcyBub3Qgc2V0IHN0YXRlIHRvIGZhaWxlZCBieSBpdHNlbGYuXG4gICAgICAgIGR0bHNUcmFuc3BvcnQuc3RhdGUgPSAnZmFpbGVkJztcbiAgICAgICAgc2VsZi5fdXBkYXRlQ29ubmVjdGlvblN0YXRlKCk7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBpY2VHYXRoZXJlcjogaWNlR2F0aGVyZXIsXG4gICAgICAgIGljZVRyYW5zcG9ydDogaWNlVHJhbnNwb3J0LFxuICAgICAgICBkdGxzVHJhbnNwb3J0OiBkdGxzVHJhbnNwb3J0XG4gICAgICB9O1xuICAgIH07XG5cbiAgICAvLyBTdGFydCB0aGUgUlRQIFNlbmRlciBhbmQgUmVjZWl2ZXIgZm9yIGEgdHJhbnNjZWl2ZXIuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fdHJhbnNjZWl2ZSA9IGZ1bmN0aW9uKHRyYW5zY2VpdmVyLFxuICAgICAgICBzZW5kLCByZWN2KSB7XG4gICAgICB2YXIgcGFyYW1zID0gdGhpcy5fZ2V0Q29tbW9uQ2FwYWJpbGl0aWVzKHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgIHRyYW5zY2VpdmVyLnJlbW90ZUNhcGFiaWxpdGllcyk7XG4gICAgICBpZiAoc2VuZCAmJiB0cmFuc2NlaXZlci5ydHBTZW5kZXIpIHtcbiAgICAgICAgcGFyYW1zLmVuY29kaW5ncyA9IFt7XG4gICAgICAgICAgc3NyYzogdHJhbnNjZWl2ZXIuc2VuZFNzcmNcbiAgICAgICAgfV07XG4gICAgICAgIHBhcmFtcy5ydGNwID0ge1xuICAgICAgICAgIGNuYW1lOiBTRFBVdGlscy5sb2NhbENOYW1lLFxuICAgICAgICAgIHNzcmM6IHRyYW5zY2VpdmVyLnJlY3ZTc3JjXG4gICAgICAgIH07XG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0cFNlbmRlci5zZW5kKHBhcmFtcyk7XG4gICAgICB9XG4gICAgICBpZiAocmVjdiAmJiB0cmFuc2NlaXZlci5ydHBSZWNlaXZlcikge1xuICAgICAgICBwYXJhbXMuZW5jb2RpbmdzID0gW3tcbiAgICAgICAgICBzc3JjOiB0cmFuc2NlaXZlci5yZWN2U3NyY1xuICAgICAgICB9XTtcbiAgICAgICAgcGFyYW1zLnJ0Y3AgPSB7XG4gICAgICAgICAgY25hbWU6IHRyYW5zY2VpdmVyLmNuYW1lLFxuICAgICAgICAgIHNzcmM6IHRyYW5zY2VpdmVyLnNlbmRTc3JjXG4gICAgICAgIH07XG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyLnJlY2VpdmUocGFyYW1zKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5zZXRMb2NhbERlc2NyaXB0aW9uID1cbiAgICAgICAgZnVuY3Rpb24oZGVzY3JpcHRpb24pIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIGlmIChkZXNjcmlwdGlvbi50eXBlID09PSAnb2ZmZXInKSB7XG4gICAgICAgIGlmICghdGhpcy5fcGVuZGluZ09mZmVyKSB7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy50cmFuc2NlaXZlcnMgPSB0aGlzLl9wZW5kaW5nT2ZmZXI7XG4gICAgICAgICAgZGVsZXRlIHRoaXMuX3BlbmRpbmdPZmZlcjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChkZXNjcmlwdGlvbi50eXBlID09PSAnYW5zd2VyJykge1xuICAgICAgICB2YXIgc2VjdGlvbnMgPSBTRFBVdGlscy5zcGxpdFNlY3Rpb25zKHNlbGYucmVtb3RlRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgdmFyIHNlc3Npb25wYXJ0ID0gc2VjdGlvbnMuc2hpZnQoKTtcbiAgICAgICAgc2VjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgICAgICB2YXIgdHJhbnNjZWl2ZXIgPSBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XTtcbiAgICAgICAgICB2YXIgaWNlR2F0aGVyZXIgPSB0cmFuc2NlaXZlci5pY2VHYXRoZXJlcjtcbiAgICAgICAgICB2YXIgaWNlVHJhbnNwb3J0ID0gdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0O1xuICAgICAgICAgIHZhciBkdGxzVHJhbnNwb3J0ID0gdHJhbnNjZWl2ZXIuZHRsc1RyYW5zcG9ydDtcbiAgICAgICAgICB2YXIgbG9jYWxDYXBhYmlsaXRpZXMgPSB0cmFuc2NlaXZlci5sb2NhbENhcGFiaWxpdGllcztcbiAgICAgICAgICB2YXIgcmVtb3RlQ2FwYWJpbGl0aWVzID0gdHJhbnNjZWl2ZXIucmVtb3RlQ2FwYWJpbGl0aWVzO1xuICAgICAgICAgIHZhciByZWplY3RlZCA9IG1lZGlhU2VjdGlvbi5zcGxpdCgnXFxuJywgMSlbMF1cbiAgICAgICAgICAgICAgLnNwbGl0KCcgJywgMilbMV0gPT09ICcwJztcblxuICAgICAgICAgIGlmICghcmVqZWN0ZWQpIHtcbiAgICAgICAgICAgIHZhciByZW1vdGVJY2VQYXJhbWV0ZXJzID0gU0RQVXRpbHMuZ2V0SWNlUGFyYW1ldGVycyhtZWRpYVNlY3Rpb24sXG4gICAgICAgICAgICAgICAgc2Vzc2lvbnBhcnQpO1xuICAgICAgICAgICAgaWNlVHJhbnNwb3J0LnN0YXJ0KGljZUdhdGhlcmVyLCByZW1vdGVJY2VQYXJhbWV0ZXJzLCAnY29udHJvbGxlZCcpO1xuXG4gICAgICAgICAgICB2YXIgcmVtb3RlRHRsc1BhcmFtZXRlcnMgPSBTRFBVdGlscy5nZXREdGxzUGFyYW1ldGVycyhtZWRpYVNlY3Rpb24sXG4gICAgICAgICAgICAgIHNlc3Npb25wYXJ0KTtcbiAgICAgICAgICAgIGR0bHNUcmFuc3BvcnQuc3RhcnQocmVtb3RlRHRsc1BhcmFtZXRlcnMpO1xuXG4gICAgICAgICAgICAvLyBDYWxjdWxhdGUgaW50ZXJzZWN0aW9uIG9mIGNhcGFiaWxpdGllcy5cbiAgICAgICAgICAgIHZhciBwYXJhbXMgPSBzZWxmLl9nZXRDb21tb25DYXBhYmlsaXRpZXMobG9jYWxDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICAgICAgcmVtb3RlQ2FwYWJpbGl0aWVzKTtcblxuICAgICAgICAgICAgLy8gU3RhcnQgdGhlIFJUQ1J0cFNlbmRlci4gVGhlIFJUQ1J0cFJlY2VpdmVyIGZvciB0aGlzIHRyYW5zY2VpdmVyXG4gICAgICAgICAgICAvLyBoYXMgYWxyZWFkeSBiZWVuIHN0YXJ0ZWQgaW4gc2V0UmVtb3RlRGVzY3JpcHRpb24uXG4gICAgICAgICAgICBzZWxmLl90cmFuc2NlaXZlKHRyYW5zY2VpdmVyLFxuICAgICAgICAgICAgICAgIHBhcmFtcy5jb2RlY3MubGVuZ3RoID4gMCxcbiAgICAgICAgICAgICAgICBmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sb2NhbERlc2NyaXB0aW9uID0ge1xuICAgICAgICB0eXBlOiBkZXNjcmlwdGlvbi50eXBlLFxuICAgICAgICBzZHA6IGRlc2NyaXB0aW9uLnNkcFxuICAgICAgfTtcbiAgICAgIHN3aXRjaCAoZGVzY3JpcHRpb24udHlwZSkge1xuICAgICAgICBjYXNlICdvZmZlcic6XG4gICAgICAgICAgdGhpcy5fdXBkYXRlU2lnbmFsaW5nU3RhdGUoJ2hhdmUtbG9jYWwtb2ZmZXInKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYW5zd2VyJzpcbiAgICAgICAgICB0aGlzLl91cGRhdGVTaWduYWxpbmdTdGF0ZSgnc3RhYmxlJyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndW5zdXBwb3J0ZWQgdHlwZSBcIicgKyBkZXNjcmlwdGlvbi50eXBlICsgJ1wiJyk7XG4gICAgICB9XG5cbiAgICAgIC8vIElmIGEgc3VjY2VzcyBjYWxsYmFjayB3YXMgcHJvdmlkZWQsIGVtaXQgSUNFIGNhbmRpZGF0ZXMgYWZ0ZXIgaXQgaGFzIGJlZW5cbiAgICAgIC8vIGV4ZWN1dGVkLiBPdGhlcndpc2UsIGVtaXQgY2FsbGJhY2sgYWZ0ZXIgdGhlIFByb21pc2UgaXMgcmVzb2x2ZWQuXG4gICAgICB2YXIgaGFzQ2FsbGJhY2sgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJlxuICAgICAgICB0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nO1xuICAgICAgaWYgKGhhc0NhbGxiYWNrKSB7XG4gICAgICAgIHZhciBjYiA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY2IoKTtcbiAgICAgICAgICBpZiAoc2VsZi5pY2VHYXRoZXJpbmdTdGF0ZSA9PT0gJ25ldycpIHtcbiAgICAgICAgICAgIHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUgPSAnZ2F0aGVyaW5nJztcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VsZi5fZW1pdEJ1ZmZlcmVkQ2FuZGlkYXRlcygpO1xuICAgICAgICB9LCAwKTtcbiAgICAgIH1cbiAgICAgIHZhciBwID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICBwLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICghaGFzQ2FsbGJhY2spIHtcbiAgICAgICAgICBpZiAoc2VsZi5pY2VHYXRoZXJpbmdTdGF0ZSA9PT0gJ25ldycpIHtcbiAgICAgICAgICAgIHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUgPSAnZ2F0aGVyaW5nJztcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVXN1YWxseSBjYW5kaWRhdGVzIHdpbGwgYmUgZW1pdHRlZCBlYXJsaWVyLlxuICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KHNlbGYuX2VtaXRCdWZmZXJlZENhbmRpZGF0ZXMuYmluZChzZWxmKSwgNTAwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcDtcbiAgICB9O1xuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5zZXRSZW1vdGVEZXNjcmlwdGlvbiA9XG4gICAgICAgIGZ1bmN0aW9uKGRlc2NyaXB0aW9uKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICB2YXIgc3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICB2YXIgcmVjZWl2ZXJMaXN0ID0gW107XG4gICAgICB2YXIgc2VjdGlvbnMgPSBTRFBVdGlscy5zcGxpdFNlY3Rpb25zKGRlc2NyaXB0aW9uLnNkcCk7XG4gICAgICB2YXIgc2Vzc2lvbnBhcnQgPSBzZWN0aW9ucy5zaGlmdCgpO1xuICAgICAgc2VjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgICAgdmFyIGxpbmVzID0gU0RQVXRpbHMuc3BsaXRMaW5lcyhtZWRpYVNlY3Rpb24pO1xuICAgICAgICB2YXIgbWxpbmUgPSBsaW5lc1swXS5zdWJzdHIoMikuc3BsaXQoJyAnKTtcbiAgICAgICAgdmFyIGtpbmQgPSBtbGluZVswXTtcbiAgICAgICAgdmFyIHJlamVjdGVkID0gbWxpbmVbMV0gPT09ICcwJztcbiAgICAgICAgdmFyIGRpcmVjdGlvbiA9IFNEUFV0aWxzLmdldERpcmVjdGlvbihtZWRpYVNlY3Rpb24sIHNlc3Npb25wYXJ0KTtcblxuICAgICAgICB2YXIgdHJhbnNjZWl2ZXI7XG4gICAgICAgIHZhciBpY2VHYXRoZXJlcjtcbiAgICAgICAgdmFyIGljZVRyYW5zcG9ydDtcbiAgICAgICAgdmFyIGR0bHNUcmFuc3BvcnQ7XG4gICAgICAgIHZhciBydHBTZW5kZXI7XG4gICAgICAgIHZhciBydHBSZWNlaXZlcjtcbiAgICAgICAgdmFyIHNlbmRTc3JjO1xuICAgICAgICB2YXIgcmVjdlNzcmM7XG4gICAgICAgIHZhciBsb2NhbENhcGFiaWxpdGllcztcblxuICAgICAgICB2YXIgdHJhY2s7XG4gICAgICAgIC8vIEZJWE1FOiBlbnN1cmUgdGhlIG1lZGlhU2VjdGlvbiBoYXMgcnRjcC1tdXggc2V0LlxuICAgICAgICB2YXIgcmVtb3RlQ2FwYWJpbGl0aWVzID0gU0RQVXRpbHMucGFyc2VSdHBQYXJhbWV0ZXJzKG1lZGlhU2VjdGlvbik7XG4gICAgICAgIHZhciByZW1vdGVJY2VQYXJhbWV0ZXJzO1xuICAgICAgICB2YXIgcmVtb3RlRHRsc1BhcmFtZXRlcnM7XG4gICAgICAgIGlmICghcmVqZWN0ZWQpIHtcbiAgICAgICAgICByZW1vdGVJY2VQYXJhbWV0ZXJzID0gU0RQVXRpbHMuZ2V0SWNlUGFyYW1ldGVycyhtZWRpYVNlY3Rpb24sXG4gICAgICAgICAgICAgIHNlc3Npb25wYXJ0KTtcbiAgICAgICAgICByZW1vdGVEdGxzUGFyYW1ldGVycyA9IFNEUFV0aWxzLmdldER0bHNQYXJhbWV0ZXJzKG1lZGlhU2VjdGlvbixcbiAgICAgICAgICAgICAgc2Vzc2lvbnBhcnQpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtaWQgPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdhPW1pZDonKVswXS5zdWJzdHIoNik7XG5cbiAgICAgICAgdmFyIGNuYW1lO1xuICAgICAgICAvLyBHZXRzIHRoZSBmaXJzdCBTU1JDLiBOb3RlIHRoYXQgd2l0aCBSVFggdGhlcmUgbWlnaHQgYmUgbXVsdGlwbGUgU1NSQ3MuXG4gICAgICAgIHZhciByZW1vdGVTc3JjID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1zc3JjOicpXG4gICAgICAgICAgICAubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIFNEUFV0aWxzLnBhcnNlU3NyY01lZGlhKGxpbmUpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24ob2JqKSB7XG4gICAgICAgICAgICAgIHJldHVybiBvYmouYXR0cmlidXRlID09PSAnY25hbWUnO1xuICAgICAgICAgICAgfSlbMF07XG4gICAgICAgIGlmIChyZW1vdGVTc3JjKSB7XG4gICAgICAgICAgcmVjdlNzcmMgPSBwYXJzZUludChyZW1vdGVTc3JjLnNzcmMsIDEwKTtcbiAgICAgICAgICBjbmFtZSA9IHJlbW90ZVNzcmMudmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGVzY3JpcHRpb24udHlwZSA9PT0gJ29mZmVyJykge1xuICAgICAgICAgIHZhciB0cmFuc3BvcnRzID0gc2VsZi5fY3JlYXRlSWNlQW5kRHRsc1RyYW5zcG9ydHMobWlkLCBzZHBNTGluZUluZGV4KTtcblxuICAgICAgICAgIGxvY2FsQ2FwYWJpbGl0aWVzID0gUlRDUnRwUmVjZWl2ZXIuZ2V0Q2FwYWJpbGl0aWVzKGtpbmQpO1xuICAgICAgICAgIHNlbmRTc3JjID0gKDIgKiBzZHBNTGluZUluZGV4ICsgMikgKiAxMDAxO1xuXG4gICAgICAgICAgcnRwUmVjZWl2ZXIgPSBuZXcgUlRDUnRwUmVjZWl2ZXIodHJhbnNwb3J0cy5kdGxzVHJhbnNwb3J0LCBraW5kKTtcblxuICAgICAgICAgIHRyYWNrID0gcnRwUmVjZWl2ZXIudHJhY2s7XG4gICAgICAgICAgcmVjZWl2ZXJMaXN0LnB1c2goW3RyYWNrLCBydHBSZWNlaXZlcl0pO1xuICAgICAgICAgIC8vIEZJWE1FOiBub3QgY29ycmVjdCB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBzdHJlYW1zIGJ1dCB0aGF0IGlzXG4gICAgICAgICAgLy8gbm90IGN1cnJlbnRseSBzdXBwb3J0ZWQgaW4gdGhpcyBzaGltLlxuICAgICAgICAgIHN0cmVhbS5hZGRUcmFjayh0cmFjayk7XG5cbiAgICAgICAgICAvLyBGSVhNRTogbG9vayBhdCBkaXJlY3Rpb24uXG4gICAgICAgICAgaWYgKHNlbGYubG9jYWxTdHJlYW1zLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgc2VsZi5sb2NhbFN0cmVhbXNbMF0uZ2V0VHJhY2tzKCkubGVuZ3RoID49IHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgICAgICAgIC8vIEZJWE1FOiBhY3R1YWxseSBtb3JlIGNvbXBsaWNhdGVkLCBuZWVkcyB0byBtYXRjaCB0eXBlcyBldGNcbiAgICAgICAgICAgIHZhciBsb2NhbHRyYWNrID0gc2VsZi5sb2NhbFN0cmVhbXNbMF0uZ2V0VHJhY2tzKClbc2RwTUxpbmVJbmRleF07XG4gICAgICAgICAgICBydHBTZW5kZXIgPSBuZXcgUlRDUnRwU2VuZGVyKGxvY2FsdHJhY2ssIHRyYW5zcG9ydHMuZHRsc1RyYW5zcG9ydCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0gPSB7XG4gICAgICAgICAgICBpY2VHYXRoZXJlcjogdHJhbnNwb3J0cy5pY2VHYXRoZXJlcixcbiAgICAgICAgICAgIGljZVRyYW5zcG9ydDogdHJhbnNwb3J0cy5pY2VUcmFuc3BvcnQsXG4gICAgICAgICAgICBkdGxzVHJhbnNwb3J0OiB0cmFuc3BvcnRzLmR0bHNUcmFuc3BvcnQsXG4gICAgICAgICAgICBsb2NhbENhcGFiaWxpdGllczogbG9jYWxDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICByZW1vdGVDYXBhYmlsaXRpZXM6IHJlbW90ZUNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIHJ0cFNlbmRlcjogcnRwU2VuZGVyLFxuICAgICAgICAgICAgcnRwUmVjZWl2ZXI6IHJ0cFJlY2VpdmVyLFxuICAgICAgICAgICAga2luZDoga2luZCxcbiAgICAgICAgICAgIG1pZDogbWlkLFxuICAgICAgICAgICAgY25hbWU6IGNuYW1lLFxuICAgICAgICAgICAgc2VuZFNzcmM6IHNlbmRTc3JjLFxuICAgICAgICAgICAgcmVjdlNzcmM6IHJlY3ZTc3JjXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyBTdGFydCB0aGUgUlRDUnRwUmVjZWl2ZXIgbm93LiBUaGUgUlRQU2VuZGVyIGlzIHN0YXJ0ZWQgaW4gc2V0TG9jYWxEZXNjcmlwdGlvbi5cbiAgICAgICAgICBzZWxmLl90cmFuc2NlaXZlKHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLFxuICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlbmRvbmx5Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGVzY3JpcHRpb24udHlwZSA9PT0gJ2Fuc3dlcicgJiYgIXJlamVjdGVkKSB7XG4gICAgICAgICAgdHJhbnNjZWl2ZXIgPSBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XTtcbiAgICAgICAgICBpY2VHYXRoZXJlciA9IHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyO1xuICAgICAgICAgIGljZVRyYW5zcG9ydCA9IHRyYW5zY2VpdmVyLmljZVRyYW5zcG9ydDtcbiAgICAgICAgICBkdGxzVHJhbnNwb3J0ID0gdHJhbnNjZWl2ZXIuZHRsc1RyYW5zcG9ydDtcbiAgICAgICAgICBydHBTZW5kZXIgPSB0cmFuc2NlaXZlci5ydHBTZW5kZXI7XG4gICAgICAgICAgcnRwUmVjZWl2ZXIgPSB0cmFuc2NlaXZlci5ydHBSZWNlaXZlcjtcbiAgICAgICAgICBzZW5kU3NyYyA9IHRyYW5zY2VpdmVyLnNlbmRTc3JjO1xuICAgICAgICAgIC8vcmVjdlNzcmMgPSB0cmFuc2NlaXZlci5yZWN2U3NyYztcbiAgICAgICAgICBsb2NhbENhcGFiaWxpdGllcyA9IHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzO1xuXG4gICAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0ucmVjdlNzcmMgPSByZWN2U3NyYztcbiAgICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5yZW1vdGVDYXBhYmlsaXRpZXMgPVxuICAgICAgICAgICAgICByZW1vdGVDYXBhYmlsaXRpZXM7XG4gICAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uY25hbWUgPSBjbmFtZTtcblxuICAgICAgICAgIGljZVRyYW5zcG9ydC5zdGFydChpY2VHYXRoZXJlciwgcmVtb3RlSWNlUGFyYW1ldGVycywgJ2NvbnRyb2xsaW5nJyk7XG4gICAgICAgICAgZHRsc1RyYW5zcG9ydC5zdGFydChyZW1vdGVEdGxzUGFyYW1ldGVycyk7XG5cbiAgICAgICAgICBzZWxmLl90cmFuc2NlaXZlKHRyYW5zY2VpdmVyLFxuICAgICAgICAgICAgICBkaXJlY3Rpb24gPT09ICdzZW5kcmVjdicgfHwgZGlyZWN0aW9uID09PSAncmVjdm9ubHknLFxuICAgICAgICAgICAgICBkaXJlY3Rpb24gPT09ICdzZW5kcmVjdicgfHwgZGlyZWN0aW9uID09PSAnc2VuZG9ubHknKTtcblxuICAgICAgICAgIGlmIChydHBSZWNlaXZlciAmJlxuICAgICAgICAgICAgICAoZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlbmRvbmx5JykpIHtcbiAgICAgICAgICAgIHRyYWNrID0gcnRwUmVjZWl2ZXIudHJhY2s7XG4gICAgICAgICAgICByZWNlaXZlckxpc3QucHVzaChbdHJhY2ssIHJ0cFJlY2VpdmVyXSk7XG4gICAgICAgICAgICBzdHJlYW0uYWRkVHJhY2sodHJhY2spO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBGSVhNRTogYWN0dWFsbHkgdGhlIHJlY2VpdmVyIHNob3VsZCBiZSBjcmVhdGVkIGxhdGVyLlxuICAgICAgICAgICAgZGVsZXRlIHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMucmVtb3RlRGVzY3JpcHRpb24gPSB7XG4gICAgICAgICAgdHlwZTogZGVzY3JpcHRpb24udHlwZSxcbiAgICAgICAgICBzZHA6IGRlc2NyaXB0aW9uLnNkcFxuICAgICAgfTtcbiAgICAgIHN3aXRjaCAoZGVzY3JpcHRpb24udHlwZSkge1xuICAgICAgICBjYXNlICdvZmZlcic6XG4gICAgICAgICAgdGhpcy5fdXBkYXRlU2lnbmFsaW5nU3RhdGUoJ2hhdmUtcmVtb3RlLW9mZmVyJyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2Fuc3dlcic6XG4gICAgICAgICAgdGhpcy5fdXBkYXRlU2lnbmFsaW5nU3RhdGUoJ3N0YWJsZScpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3Vuc3VwcG9ydGVkIHR5cGUgXCInICsgZGVzY3JpcHRpb24udHlwZSArICdcIicpO1xuICAgICAgfVxuICAgICAgaWYgKHN0cmVhbS5nZXRUcmFja3MoKS5sZW5ndGgpIHtcbiAgICAgICAgc2VsZi5yZW1vdGVTdHJlYW1zLnB1c2goc3RyZWFtKTtcbiAgICAgICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCdhZGRzdHJlYW0nKTtcbiAgICAgICAgICBldmVudC5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICBpZiAoc2VsZi5vbmFkZHN0cmVhbSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHNlbGYub25hZGRzdHJlYW0oZXZlbnQpO1xuICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVjZWl2ZXJMaXN0LmZvckVhY2goZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICAgICAgdmFyIHRyYWNrID0gaXRlbVswXTtcbiAgICAgICAgICAgIHZhciByZWNlaXZlciA9IGl0ZW1bMV07XG4gICAgICAgICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ3RyYWNrJyk7XG4gICAgICAgICAgICBldmVudC50cmFjayA9IHRyYWNrO1xuICAgICAgICAgICAgZXZlbnQucmVjZWl2ZXIgPSByZWNlaXZlcjtcbiAgICAgICAgICAgIGV2ZW50LnN0cmVhbXMgPSBbc3RyZWFtXTtcbiAgICAgICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICBpZiAoc2VsZi5vbnRyYWNrICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICBzZWxmLm9udHJhY2soZXZlbnQpO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9LCAwKTtcbiAgICAgIH1cbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KGFyZ3VtZW50c1sxXSwgMCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfTtcblxuICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMudHJhbnNjZWl2ZXJzLmZvckVhY2goZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgICAgLyogbm90IHlldFxuICAgICAgICBpZiAodHJhbnNjZWl2ZXIuaWNlR2F0aGVyZXIpIHtcbiAgICAgICAgICB0cmFuc2NlaXZlci5pY2VHYXRoZXJlci5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICAgICovXG4gICAgICAgIGlmICh0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQpIHtcbiAgICAgICAgICB0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQuc3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0KSB7XG4gICAgICAgICAgdHJhbnNjZWl2ZXIuZHRsc1RyYW5zcG9ydC5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRyYW5zY2VpdmVyLnJ0cFNlbmRlcikge1xuICAgICAgICAgIHRyYW5zY2VpdmVyLnJ0cFNlbmRlci5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyKSB7XG4gICAgICAgICAgdHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIuc3RvcCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIEZJWE1FOiBjbGVhbiB1cCB0cmFja3MsIGxvY2FsIHN0cmVhbXMsIHJlbW90ZSBzdHJlYW1zLCBldGNcbiAgICAgIHRoaXMuX3VwZGF0ZVNpZ25hbGluZ1N0YXRlKCdjbG9zZWQnKTtcbiAgICB9O1xuXG4gICAgLy8gVXBkYXRlIHRoZSBzaWduYWxpbmcgc3RhdGUuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fdXBkYXRlU2lnbmFsaW5nU3RhdGUgPVxuICAgICAgICBmdW5jdGlvbihuZXdTdGF0ZSkge1xuICAgICAgdGhpcy5zaWduYWxpbmdTdGF0ZSA9IG5ld1N0YXRlO1xuICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCdzaWduYWxpbmdzdGF0ZWNoYW5nZScpO1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgIGlmICh0aGlzLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5vbnNpZ25hbGluZ3N0YXRlY2hhbmdlKGV2ZW50KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gRGV0ZXJtaW5lIHdoZXRoZXIgdG8gZmlyZSB0aGUgbmVnb3RpYXRpb25uZWVkZWQgZXZlbnQuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fbWF5YmVGaXJlTmVnb3RpYXRpb25OZWVkZWQgPVxuICAgICAgICBmdW5jdGlvbigpIHtcbiAgICAgIC8vIEZpcmUgYXdheSAoZm9yIG5vdykuXG4gICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ25lZ290aWF0aW9ubmVlZGVkJyk7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgaWYgKHRoaXMub25uZWdvdGlhdGlvbm5lZWRlZCAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLm9ubmVnb3RpYXRpb25uZWVkZWQoZXZlbnQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBVcGRhdGUgdGhlIGNvbm5lY3Rpb24gc3RhdGUuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fdXBkYXRlQ29ubmVjdGlvblN0YXRlID1cbiAgICAgICAgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICB2YXIgbmV3U3RhdGU7XG4gICAgICB2YXIgc3RhdGVzID0ge1xuICAgICAgICAnbmV3JzogMCxcbiAgICAgICAgY2xvc2VkOiAwLFxuICAgICAgICBjb25uZWN0aW5nOiAwLFxuICAgICAgICBjaGVja2luZzogMCxcbiAgICAgICAgY29ubmVjdGVkOiAwLFxuICAgICAgICBjb21wbGV0ZWQ6IDAsXG4gICAgICAgIGZhaWxlZDogMFxuICAgICAgfTtcbiAgICAgIHRoaXMudHJhbnNjZWl2ZXJzLmZvckVhY2goZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgICAgc3RhdGVzW3RyYW5zY2VpdmVyLmljZVRyYW5zcG9ydC5zdGF0ZV0rKztcbiAgICAgICAgc3RhdGVzW3RyYW5zY2VpdmVyLmR0bHNUcmFuc3BvcnQuc3RhdGVdKys7XG4gICAgICB9KTtcbiAgICAgIC8vIElDRVRyYW5zcG9ydC5jb21wbGV0ZWQgYW5kIGNvbm5lY3RlZCBhcmUgdGhlIHNhbWUgZm9yIHRoaXMgcHVycG9zZS5cbiAgICAgIHN0YXRlc1snY29ubmVjdGVkJ10gKz0gc3RhdGVzWydjb21wbGV0ZWQnXTtcblxuICAgICAgbmV3U3RhdGUgPSAnbmV3JztcbiAgICAgIGlmIChzdGF0ZXNbJ2ZhaWxlZCddID4gMCkge1xuICAgICAgICBuZXdTdGF0ZSA9ICdmYWlsZWQnO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZXNbJ2Nvbm5lY3RpbmcnXSA+IDAgfHwgc3RhdGVzWydjaGVja2luZyddID4gMCkge1xuICAgICAgICBuZXdTdGF0ZSA9ICdjb25uZWN0aW5nJztcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGVzWydkaXNjb25uZWN0ZWQnXSA+IDApIHtcbiAgICAgICAgbmV3U3RhdGUgPSAnZGlzY29ubmVjdGVkJztcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGVzWyduZXcnXSA+IDApIHtcbiAgICAgICAgbmV3U3RhdGUgPSAnbmV3JztcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGVzWydjb25uZWN0aW5nJ10gPiAwIHx8IHN0YXRlc1snY29tcGxldGVkJ10gPiAwKSB7XG4gICAgICAgIG5ld1N0YXRlID0gJ2Nvbm5lY3RlZCc7XG4gICAgICB9XG5cbiAgICAgIGlmIChuZXdTdGF0ZSAhPT0gc2VsZi5pY2VDb25uZWN0aW9uU3RhdGUpIHtcbiAgICAgICAgc2VsZi5pY2VDb25uZWN0aW9uU3RhdGUgPSBuZXdTdGF0ZTtcbiAgICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCdpY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2UnKTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgaWYgKHRoaXMub25pY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2UgIT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLm9uaWNlY29ubmVjdGlvbnN0YXRlY2hhbmdlKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZU9mZmVyID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICBpZiAodGhpcy5fcGVuZGluZ09mZmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY3JlYXRlT2ZmZXIgY2FsbGVkIHdoaWxlIHRoZXJlIGlzIGEgcGVuZGluZyBvZmZlci4nKTtcbiAgICAgIH1cbiAgICAgIHZhciBvZmZlck9wdGlvbnM7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgYXJndW1lbnRzWzBdICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIG9mZmVyT3B0aW9ucyA9IGFyZ3VtZW50c1swXTtcbiAgICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgICBvZmZlck9wdGlvbnMgPSBhcmd1bWVudHNbMl07XG4gICAgICB9XG5cbiAgICAgIHZhciB0cmFja3MgPSBbXTtcbiAgICAgIHZhciBudW1BdWRpb1RyYWNrcyA9IDA7XG4gICAgICB2YXIgbnVtVmlkZW9UcmFja3MgPSAwO1xuICAgICAgLy8gRGVmYXVsdCB0byBzZW5kcmVjdi5cbiAgICAgIGlmICh0aGlzLmxvY2FsU3RyZWFtcy5sZW5ndGgpIHtcbiAgICAgICAgbnVtQXVkaW9UcmFja3MgPSB0aGlzLmxvY2FsU3RyZWFtc1swXS5nZXRBdWRpb1RyYWNrcygpLmxlbmd0aDtcbiAgICAgICAgbnVtVmlkZW9UcmFja3MgPSB0aGlzLmxvY2FsU3RyZWFtc1swXS5nZXRWaWRlb1RyYWNrcygpLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIC8vIERldGVybWluZSBudW1iZXIgb2YgYXVkaW8gYW5kIHZpZGVvIHRyYWNrcyB3ZSBuZWVkIHRvIHNlbmQvcmVjdi5cbiAgICAgIGlmIChvZmZlck9wdGlvbnMpIHtcbiAgICAgICAgLy8gUmVqZWN0IENocm9tZSBsZWdhY3kgY29uc3RyYWludHMuXG4gICAgICAgIGlmIChvZmZlck9wdGlvbnMubWFuZGF0b3J5IHx8IG9mZmVyT3B0aW9ucy5vcHRpb25hbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICdMZWdhY3kgbWFuZGF0b3J5L29wdGlvbmFsIGNvbnN0cmFpbnRzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9mZmVyT3B0aW9ucy5vZmZlclRvUmVjZWl2ZUF1ZGlvICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBudW1BdWRpb1RyYWNrcyA9IG9mZmVyT3B0aW9ucy5vZmZlclRvUmVjZWl2ZUF1ZGlvO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvZmZlck9wdGlvbnMub2ZmZXJUb1JlY2VpdmVWaWRlbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbnVtVmlkZW9UcmFja3MgPSBvZmZlck9wdGlvbnMub2ZmZXJUb1JlY2VpdmVWaWRlbztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMubG9jYWxTdHJlYW1zLmxlbmd0aCkge1xuICAgICAgICAvLyBQdXNoIGxvY2FsIHN0cmVhbXMuXG4gICAgICAgIHRoaXMubG9jYWxTdHJlYW1zWzBdLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odHJhY2spIHtcbiAgICAgICAgICB0cmFja3MucHVzaCh7XG4gICAgICAgICAgICBraW5kOiB0cmFjay5raW5kLFxuICAgICAgICAgICAgdHJhY2s6IHRyYWNrLFxuICAgICAgICAgICAgd2FudFJlY2VpdmU6IHRyYWNrLmtpbmQgPT09ICdhdWRpbycgP1xuICAgICAgICAgICAgICAgIG51bUF1ZGlvVHJhY2tzID4gMCA6IG51bVZpZGVvVHJhY2tzID4gMFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmICh0cmFjay5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgICBudW1BdWRpb1RyYWNrcy0tO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgbnVtVmlkZW9UcmFja3MtLTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgLy8gQ3JlYXRlIE0tbGluZXMgZm9yIHJlY3Zvbmx5IHN0cmVhbXMuXG4gICAgICB3aGlsZSAobnVtQXVkaW9UcmFja3MgPiAwIHx8IG51bVZpZGVvVHJhY2tzID4gMCkge1xuICAgICAgICBpZiAobnVtQXVkaW9UcmFja3MgPiAwKSB7XG4gICAgICAgICAgdHJhY2tzLnB1c2goe1xuICAgICAgICAgICAga2luZDogJ2F1ZGlvJyxcbiAgICAgICAgICAgIHdhbnRSZWNlaXZlOiB0cnVlXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgbnVtQXVkaW9UcmFja3MtLTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobnVtVmlkZW9UcmFja3MgPiAwKSB7XG4gICAgICAgICAgdHJhY2tzLnB1c2goe1xuICAgICAgICAgICAga2luZDogJ3ZpZGVvJyxcbiAgICAgICAgICAgIHdhbnRSZWNlaXZlOiB0cnVlXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgbnVtVmlkZW9UcmFja3MtLTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgc2RwID0gU0RQVXRpbHMud3JpdGVTZXNzaW9uQm9pbGVycGxhdGUoKTtcbiAgICAgIHZhciB0cmFuc2NlaXZlcnMgPSBbXTtcbiAgICAgIHRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKG1saW5lLCBzZHBNTGluZUluZGV4KSB7XG4gICAgICAgIC8vIEZvciBlYWNoIHRyYWNrLCBjcmVhdGUgYW4gaWNlIGdhdGhlcmVyLCBpY2UgdHJhbnNwb3J0LCBkdGxzIHRyYW5zcG9ydCxcbiAgICAgICAgLy8gcG90ZW50aWFsbHkgcnRwc2VuZGVyIGFuZCBydHByZWNlaXZlci5cbiAgICAgICAgdmFyIHRyYWNrID0gbWxpbmUudHJhY2s7XG4gICAgICAgIHZhciBraW5kID0gbWxpbmUua2luZDtcbiAgICAgICAgdmFyIG1pZCA9IFNEUFV0aWxzLmdlbmVyYXRlSWRlbnRpZmllcigpO1xuXG4gICAgICAgIHZhciB0cmFuc3BvcnRzID0gc2VsZi5fY3JlYXRlSWNlQW5kRHRsc1RyYW5zcG9ydHMobWlkLCBzZHBNTGluZUluZGV4KTtcblxuICAgICAgICB2YXIgbG9jYWxDYXBhYmlsaXRpZXMgPSBSVENSdHBTZW5kZXIuZ2V0Q2FwYWJpbGl0aWVzKGtpbmQpO1xuICAgICAgICB2YXIgcnRwU2VuZGVyO1xuICAgICAgICB2YXIgcnRwUmVjZWl2ZXI7XG5cbiAgICAgICAgLy8gZ2VuZXJhdGUgYW4gc3NyYyBub3csIHRvIGJlIHVzZWQgbGF0ZXIgaW4gcnRwU2VuZGVyLnNlbmRcbiAgICAgICAgdmFyIHNlbmRTc3JjID0gKDIgKiBzZHBNTGluZUluZGV4ICsgMSkgKiAxMDAxO1xuICAgICAgICBpZiAodHJhY2spIHtcbiAgICAgICAgICBydHBTZW5kZXIgPSBuZXcgUlRDUnRwU2VuZGVyKHRyYWNrLCB0cmFuc3BvcnRzLmR0bHNUcmFuc3BvcnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1saW5lLndhbnRSZWNlaXZlKSB7XG4gICAgICAgICAgcnRwUmVjZWl2ZXIgPSBuZXcgUlRDUnRwUmVjZWl2ZXIodHJhbnNwb3J0cy5kdGxzVHJhbnNwb3J0LCBraW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XSA9IHtcbiAgICAgICAgICBpY2VHYXRoZXJlcjogdHJhbnNwb3J0cy5pY2VHYXRoZXJlcixcbiAgICAgICAgICBpY2VUcmFuc3BvcnQ6IHRyYW5zcG9ydHMuaWNlVHJhbnNwb3J0LFxuICAgICAgICAgIGR0bHNUcmFuc3BvcnQ6IHRyYW5zcG9ydHMuZHRsc1RyYW5zcG9ydCxcbiAgICAgICAgICBsb2NhbENhcGFiaWxpdGllczogbG9jYWxDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgcmVtb3RlQ2FwYWJpbGl0aWVzOiBudWxsLFxuICAgICAgICAgIHJ0cFNlbmRlcjogcnRwU2VuZGVyLFxuICAgICAgICAgIHJ0cFJlY2VpdmVyOiBydHBSZWNlaXZlcixcbiAgICAgICAgICBraW5kOiBraW5kLFxuICAgICAgICAgIG1pZDogbWlkLFxuICAgICAgICAgIHNlbmRTc3JjOiBzZW5kU3NyYyxcbiAgICAgICAgICByZWN2U3NyYzogbnVsbFxuICAgICAgICB9O1xuICAgICAgICB2YXIgdHJhbnNjZWl2ZXIgPSB0cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF07XG4gICAgICAgIHNkcCArPSBTRFBVdGlscy53cml0ZU1lZGlhU2VjdGlvbih0cmFuc2NlaXZlcixcbiAgICAgICAgICAgIHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzLCAnb2ZmZXInLCBzZWxmLmxvY2FsU3RyZWFtc1swXSk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5fcGVuZGluZ09mZmVyID0gdHJhbnNjZWl2ZXJzO1xuICAgICAgdmFyIGRlc2MgPSBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgICAgdHlwZTogJ29mZmVyJyxcbiAgICAgICAgc2RwOiBzZHBcbiAgICAgIH0pO1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggJiYgdHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB3aW5kb3cuc2V0VGltZW91dChhcmd1bWVudHNbMF0sIDAsIGRlc2MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShkZXNjKTtcbiAgICB9O1xuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5jcmVhdGVBbnN3ZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIHZhciBhbnN3ZXJPcHRpb25zO1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3VtZW50c1swXSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBhbnN3ZXJPcHRpb25zID0gYXJndW1lbnRzWzBdO1xuICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICAgIGFuc3dlck9wdGlvbnMgPSBhcmd1bWVudHNbMl07XG4gICAgICB9XG5cbiAgICAgIHZhciBzZHAgPSBTRFBVdGlscy53cml0ZVNlc3Npb25Cb2lsZXJwbGF0ZSgpO1xuICAgICAgdGhpcy50cmFuc2NlaXZlcnMuZm9yRWFjaChmdW5jdGlvbih0cmFuc2NlaXZlcikge1xuICAgICAgICAvLyBDYWxjdWxhdGUgaW50ZXJzZWN0aW9uIG9mIGNhcGFiaWxpdGllcy5cbiAgICAgICAgdmFyIGNvbW1vbkNhcGFiaWxpdGllcyA9IHNlbGYuX2dldENvbW1vbkNhcGFiaWxpdGllcyhcbiAgICAgICAgICAgIHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgdHJhbnNjZWl2ZXIucmVtb3RlQ2FwYWJpbGl0aWVzKTtcblxuICAgICAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVNZWRpYVNlY3Rpb24odHJhbnNjZWl2ZXIsIGNvbW1vbkNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgICdhbnN3ZXInLCBzZWxmLmxvY2FsU3RyZWFtc1swXSk7XG4gICAgICB9KTtcblxuICAgICAgdmFyIGRlc2MgPSBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgIHNkcDogc2RwXG4gICAgICB9KTtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICYmIHR5cGVvZiBhcmd1bWVudHNbMF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgd2luZG93LnNldFRpbWVvdXQoYXJndW1lbnRzWzBdLCAwLCBkZXNjKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGVzYyk7XG4gICAgfTtcblxuICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkSWNlQ2FuZGlkYXRlID0gZnVuY3Rpb24oY2FuZGlkYXRlKSB7XG4gICAgICB2YXIgbUxpbmVJbmRleCA9IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4O1xuICAgICAgaWYgKGNhbmRpZGF0ZS5zZHBNaWQpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnRyYW5zY2VpdmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmICh0aGlzLnRyYW5zY2VpdmVyc1tpXS5taWQgPT09IGNhbmRpZGF0ZS5zZHBNaWQpIHtcbiAgICAgICAgICAgIG1MaW5lSW5kZXggPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YXIgdHJhbnNjZWl2ZXIgPSB0aGlzLnRyYW5zY2VpdmVyc1ttTGluZUluZGV4XTtcbiAgICAgIGlmICh0cmFuc2NlaXZlcikge1xuICAgICAgICB2YXIgY2FuZCA9IE9iamVjdC5rZXlzKGNhbmRpZGF0ZS5jYW5kaWRhdGUpLmxlbmd0aCA+IDAgP1xuICAgICAgICAgICAgU0RQVXRpbHMucGFyc2VDYW5kaWRhdGUoY2FuZGlkYXRlLmNhbmRpZGF0ZSkgOiB7fTtcbiAgICAgICAgLy8gSWdub3JlIENocm9tZSdzIGludmFsaWQgY2FuZGlkYXRlcyBzaW5jZSBFZGdlIGRvZXMgbm90IGxpa2UgdGhlbS5cbiAgICAgICAgaWYgKGNhbmQucHJvdG9jb2wgPT09ICd0Y3AnICYmIGNhbmQucG9ydCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZ25vcmUgUlRDUCBjYW5kaWRhdGVzLCB3ZSBhc3N1bWUgUlRDUC1NVVguXG4gICAgICAgIGlmIChjYW5kLmNvbXBvbmVudCAhPT0gJzEnKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIEEgZGlydHkgaGFjayB0byBtYWtlIHNhbXBsZXMgd29yay5cbiAgICAgICAgaWYgKGNhbmQudHlwZSA9PT0gJ2VuZE9mQ2FuZGlkYXRlcycpIHtcbiAgICAgICAgICBjYW5kID0ge307XG4gICAgICAgIH1cbiAgICAgICAgdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0LmFkZFJlbW90ZUNhbmRpZGF0ZShjYW5kKTtcblxuICAgICAgICAvLyB1cGRhdGUgdGhlIHJlbW90ZURlc2NyaXB0aW9uLlxuICAgICAgICB2YXIgc2VjdGlvbnMgPSBTRFBVdGlscy5zcGxpdFNlY3Rpb25zKHRoaXMucmVtb3RlRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgc2VjdGlvbnNbbUxpbmVJbmRleCArIDFdICs9IChjYW5kLnR5cGUgPyBjYW5kaWRhdGUuY2FuZGlkYXRlLnRyaW0oKVxuICAgICAgICAgICAgOiAnYT1lbmQtb2YtY2FuZGlkYXRlcycpICsgJ1xcclxcbic7XG4gICAgICAgIHRoaXMucmVtb3RlRGVzY3JpcHRpb24uc2RwID0gc2VjdGlvbnMuam9pbignJyk7XG4gICAgICB9XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgdHlwZW9mIGFyZ3VtZW50c1sxXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB3aW5kb3cuc2V0VGltZW91dChhcmd1bWVudHNbMV0sIDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH07XG5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFN0YXRzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcHJvbWlzZXMgPSBbXTtcbiAgICAgIHRoaXMudHJhbnNjZWl2ZXJzLmZvckVhY2goZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgICAgWydydHBTZW5kZXInLCAncnRwUmVjZWl2ZXInLCAnaWNlR2F0aGVyZXInLCAnaWNlVHJhbnNwb3J0JyxcbiAgICAgICAgICAgICdkdGxzVHJhbnNwb3J0J10uZm9yRWFjaChmdW5jdGlvbihtZXRob2QpIHtcbiAgICAgICAgICBpZiAodHJhbnNjZWl2ZXJbbWV0aG9kXSkge1xuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0cmFuc2NlaXZlclttZXRob2RdLmdldFN0YXRzKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHZhciBjYiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIHR5cGVvZiBhcmd1bWVudHNbMV0gPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgICBhcmd1bWVudHNbMV07XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgICB2YXIgcmVzdWx0cyA9IHt9O1xuICAgICAgICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihmdW5jdGlvbihyZXMpIHtcbiAgICAgICAgICByZXMuZm9yRWFjaChmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHJlc3VsdCkuZm9yRWFjaChmdW5jdGlvbihpZCkge1xuICAgICAgICAgICAgICByZXN1bHRzW2lkXSA9IHJlc3VsdFtpZF07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAoY2IpIHtcbiAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KGNiLCAwLCByZXN1bHRzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShyZXN1bHRzKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9O1xuICB9LFxuXG4gIC8vIEF0dGFjaCBhIG1lZGlhIHN0cmVhbSB0byBhbiBlbGVtZW50LlxuICBhdHRhY2hNZWRpYVN0cmVhbTogZnVuY3Rpb24oZWxlbWVudCwgc3RyZWFtKSB7XG4gICAgbG9nZ2luZygnREVQUkVDQVRFRCwgYXR0YWNoTWVkaWFTdHJlYW0gd2lsbCBzb29uIGJlIHJlbW92ZWQuJyk7XG4gICAgZWxlbWVudC5zcmNPYmplY3QgPSBzdHJlYW07XG4gIH0sXG5cbiAgcmVhdHRhY2hNZWRpYVN0cmVhbTogZnVuY3Rpb24odG8sIGZyb20pIHtcbiAgICBsb2dnaW5nKCdERVBSRUNBVEVELCByZWF0dGFjaE1lZGlhU3RyZWFtIHdpbGwgc29vbiBiZSByZW1vdmVkLicpO1xuICAgIHRvLnNyY09iamVjdCA9IGZyb20uc3JjT2JqZWN0O1xuICB9XG59XG5cbi8vIEV4cG9zZSBwdWJsaWMgbWV0aG9kcy5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzaGltUGVlckNvbm5lY3Rpb246IGVkZ2VTaGltLnNoaW1QZWVyQ29ubmVjdGlvbixcbiAgYXR0YWNoTWVkaWFTdHJlYW06IGVkZ2VTaGltLmF0dGFjaE1lZGlhU3RyZWFtLFxuICByZWF0dGFjaE1lZGlhU3RyZWFtOiBlZGdlU2hpbS5yZWF0dGFjaE1lZGlhU3RyZWFtXG59XG5cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9lZGdlL2VkZ2Vfc2hpbS5qc1xuICoqIG1vZHVsZSBpZCA9IDE1MVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBsb2dnaW5nID0gcmVxdWlyZSgnLi4vdXRpbHMnKS5sb2c7XG52YXIgYnJvd3NlckRldGFpbHMgPSByZXF1aXJlKCcuLi91dGlscycpLmJyb3dzZXJEZXRhaWxzO1xuXG52YXIgZmlyZWZveFNoaW0gPSB7XG4gIHNoaW1PblRyYWNrOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcgJiYgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uICYmICEoJ29udHJhY2snIGluXG4gICAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUpKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSwgJ29udHJhY2snLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLl9vbnRyYWNrOyB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uKGYpIHtcbiAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgaWYgKHRoaXMuX29udHJhY2spIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhY2snLCB0aGlzLl9vbnRyYWNrKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWRkc3RyZWFtJywgdGhpcy5fb250cmFja3BvbHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ3RyYWNrJywgdGhpcy5fb250cmFjayA9IGYpO1xuICAgICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignYWRkc3RyZWFtJywgdGhpcy5fb250cmFja3BvbHkgPSBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBlLnN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrKSB7XG4gICAgICAgICAgICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgndHJhY2snKTtcbiAgICAgICAgICAgICAgZXZlbnQudHJhY2sgPSB0cmFjaztcbiAgICAgICAgICAgICAgZXZlbnQucmVjZWl2ZXIgPSB7dHJhY2s6IHRyYWNrfTtcbiAgICAgICAgICAgICAgZXZlbnQuc3RyZWFtcyA9IFtlLnN0cmVhbV07XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcblxuICBzaGltU291cmNlT2JqZWN0OiBmdW5jdGlvbigpIHtcbiAgICAvLyBGaXJlZm94IGhhcyBzdXBwb3J0ZWQgbW96U3JjT2JqZWN0IHNpbmNlIEZGMjIsIHVucHJlZml4ZWQgaW4gNDIuXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAod2luZG93LkhUTUxNZWRpYUVsZW1lbnQgJiZcbiAgICAgICAgISgnc3JjT2JqZWN0JyBpbiB3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUpKSB7XG4gICAgICAgIC8vIFNoaW0gdGhlIHNyY09iamVjdCBwcm9wZXJ0eSwgb25jZSwgd2hlbiBIVE1MTWVkaWFFbGVtZW50IGlzIGZvdW5kLlxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlLCAnc3JjT2JqZWN0Jywge1xuICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5tb3pTcmNPYmplY3Q7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5tb3pTcmNPYmplY3QgPSBzdHJlYW07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgc2hpbVBlZXJDb25uZWN0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAvLyBUaGUgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0LlxuICAgIGlmICghd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uKSB7XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gPSBmdW5jdGlvbihwY0NvbmZpZywgcGNDb25zdHJhaW50cykge1xuICAgICAgICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDM4KSB7XG4gICAgICAgICAgLy8gLnVybHMgaXMgbm90IHN1cHBvcnRlZCBpbiBGRiA8IDM4LlxuICAgICAgICAgIC8vIGNyZWF0ZSBSVENJY2VTZXJ2ZXJzIHdpdGggYSBzaW5nbGUgdXJsLlxuICAgICAgICAgIGlmIChwY0NvbmZpZyAmJiBwY0NvbmZpZy5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICB2YXIgbmV3SWNlU2VydmVycyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwY0NvbmZpZy5pY2VTZXJ2ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgIHZhciBzZXJ2ZXIgPSBwY0NvbmZpZy5pY2VTZXJ2ZXJzW2ldO1xuICAgICAgICAgICAgICBpZiAoc2VydmVyLmhhc093blByb3BlcnR5KCd1cmxzJykpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHNlcnZlci51cmxzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgbmV3U2VydmVyID0ge1xuICAgICAgICAgICAgICAgICAgICB1cmw6IHNlcnZlci51cmxzW2pdXG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgaWYgKHNlcnZlci51cmxzW2pdLmluZGV4T2YoJ3R1cm4nKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBuZXdTZXJ2ZXIudXNlcm5hbWUgPSBzZXJ2ZXIudXNlcm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIG5ld1NlcnZlci5jcmVkZW50aWFsID0gc2VydmVyLmNyZWRlbnRpYWw7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBuZXdJY2VTZXJ2ZXJzLnB1c2gobmV3U2VydmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV3SWNlU2VydmVycy5wdXNoKHBjQ29uZmlnLmljZVNlcnZlcnNbaV0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwY0NvbmZpZy5pY2VTZXJ2ZXJzID0gbmV3SWNlU2VydmVycztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBtb3pSVENQZWVyQ29ubmVjdGlvbihwY0NvbmZpZywgcGNDb25zdHJhaW50cyk7IC8vIGpzY3M6aWdub3JlIHJlcXVpcmVDYXBpdGFsaXplZENvbnN0cnVjdG9yc1xuICAgICAgfTtcbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUgPSBtb3pSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGU7XG5cbiAgICAgIC8vIHdyYXAgc3RhdGljIG1ldGhvZHMuIEN1cnJlbnRseSBqdXN0IGdlbmVyYXRlQ2VydGlmaWNhdGUuXG4gICAgICBpZiAobW96UlRDUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLCAnZ2VuZXJhdGVDZXJ0aWZpY2F0ZScsIHtcbiAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG1velJUQ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGUuYXBwbHkobnVsbCxcbiAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gbW96UlRDUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB3aW5kb3cuUlRDU2Vzc2lvbkRlc2NyaXB0aW9uID0gbW96UlRDU2Vzc2lvbkRlc2NyaXB0aW9uO1xuICAgICAgd2luZG93LlJUQ0ljZUNhbmRpZGF0ZSA9IG1velJUQ0ljZUNhbmRpZGF0ZTtcbiAgICB9XG4gIH0sXG5cbiAgc2hpbUdldFVzZXJNZWRpYTogZnVuY3Rpb24oKSB7XG4gICAgLy8gZ2V0VXNlck1lZGlhIGNvbnN0cmFpbnRzIHNoaW0uXG4gICAgdmFyIGdldFVzZXJNZWRpYV8gPSBmdW5jdGlvbihjb25zdHJhaW50cywgb25TdWNjZXNzLCBvbkVycm9yKSB7XG4gICAgICB2YXIgY29uc3RyYWludHNUb0ZGMzdfID0gZnVuY3Rpb24oYykge1xuICAgICAgICBpZiAodHlwZW9mIGMgIT09ICdvYmplY3QnIHx8IGMucmVxdWlyZSkge1xuICAgICAgICAgIHJldHVybiBjO1xuICAgICAgICB9XG4gICAgICAgIHZhciByZXF1aXJlID0gW107XG4gICAgICAgIE9iamVjdC5rZXlzKGMpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlcXVpcmUnIHx8IGtleSA9PT0gJ2FkdmFuY2VkJyB8fCBrZXkgPT09ICdtZWRpYVNvdXJjZScpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIHIgPSBjW2tleV0gPSAodHlwZW9mIGNba2V5XSA9PT0gJ29iamVjdCcpID9cbiAgICAgICAgICAgICAgY1trZXldIDoge2lkZWFsOiBjW2tleV19O1xuICAgICAgICAgIGlmIChyLm1pbiAhPT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgIHIubWF4ICE9PSB1bmRlZmluZWQgfHwgci5leGFjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXF1aXJlLnB1c2goa2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHIuZXhhY3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiByLmV4YWN0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICByLiBtaW4gPSByLm1heCA9IHIuZXhhY3Q7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjW2tleV0gPSByLmV4YWN0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIHIuZXhhY3Q7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyLmlkZWFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGMuYWR2YW5jZWQgPSBjLmFkdmFuY2VkIHx8IFtdO1xuICAgICAgICAgICAgdmFyIG9jID0ge307XG4gICAgICAgICAgICBpZiAodHlwZW9mIHIuaWRlYWwgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgIG9jW2tleV0gPSB7bWluOiByLmlkZWFsLCBtYXg6IHIuaWRlYWx9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgb2Nba2V5XSA9IHIuaWRlYWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjLmFkdmFuY2VkLnB1c2gob2MpO1xuICAgICAgICAgICAgZGVsZXRlIHIuaWRlYWw7XG4gICAgICAgICAgICBpZiAoIU9iamVjdC5rZXlzKHIpLmxlbmd0aCkge1xuICAgICAgICAgICAgICBkZWxldGUgY1trZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXF1aXJlLmxlbmd0aCkge1xuICAgICAgICAgIGMucmVxdWlyZSA9IHJlcXVpcmU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGM7XG4gICAgICB9O1xuICAgICAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCAzOCkge1xuICAgICAgICBsb2dnaW5nKCdzcGVjOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcbiAgICAgICAgaWYgKGNvbnN0cmFpbnRzLmF1ZGlvKSB7XG4gICAgICAgICAgY29uc3RyYWludHMuYXVkaW8gPSBjb25zdHJhaW50c1RvRkYzN18oY29uc3RyYWludHMuYXVkaW8pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25zdHJhaW50cy52aWRlbykge1xuICAgICAgICAgIGNvbnN0cmFpbnRzLnZpZGVvID0gY29uc3RyYWludHNUb0ZGMzdfKGNvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnaW5nKCdmZjM3OiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzLCBvblN1Y2Nlc3MsIG9uRXJyb3IpO1xuICAgIH07XG5cbiAgICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhID0gZ2V0VXNlck1lZGlhXztcblxuICAgIC8vIFJldHVybnMgdGhlIHJlc3VsdCBvZiBnZXRVc2VyTWVkaWEgYXMgYSBQcm9taXNlLlxuICAgIHZhciBnZXRVc2VyTWVkaWFQcm9taXNlXyA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXRVc2VyTWVkaWEoY29uc3RyYWludHMsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBTaGltIGZvciBtZWRpYURldmljZXMgb24gb2xkZXIgdmVyc2lvbnMuXG4gICAgaWYgKCFuYXZpZ2F0b3IubWVkaWFEZXZpY2VzKSB7XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzID0ge2dldFVzZXJNZWRpYTogZ2V0VXNlck1lZGlhUHJvbWlzZV8sXG4gICAgICAgIGFkZEV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKCkgeyB9LFxuICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyOiBmdW5jdGlvbigpIHsgfVxuICAgICAgfTtcbiAgICB9XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzID1cbiAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzIHx8IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcbiAgICAgICAgdmFyIGluZm9zID0gW1xuICAgICAgICAgIHtraW5kOiAnYXVkaW9pbnB1dCcsIGRldmljZUlkOiAnZGVmYXVsdCcsIGxhYmVsOiAnJywgZ3JvdXBJZDogJyd9LFxuICAgICAgICAgIHtraW5kOiAndmlkZW9pbnB1dCcsIGRldmljZUlkOiAnZGVmYXVsdCcsIGxhYmVsOiAnJywgZ3JvdXBJZDogJyd9XG4gICAgICAgIF07XG4gICAgICAgIHJlc29sdmUoaW5mb3MpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGlmIChicm93c2VyRGV0YWlscy52ZXJzaW9uIDwgNDEpIHtcbiAgICAgIC8vIFdvcmsgYXJvdW5kIGh0dHA6Ly9idWd6aWwubGEvMTE2OTY2NVxuICAgICAgdmFyIG9yZ0VudW1lcmF0ZURldmljZXMgPVxuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcy5iaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO1xuICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBvcmdFbnVtZXJhdGVEZXZpY2VzKCkudGhlbih1bmRlZmluZWQsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICBpZiAoZS5uYW1lID09PSAnTm90Rm91bmRFcnJvcicpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSxcblxuICAvLyBBdHRhY2ggYSBtZWRpYSBzdHJlYW0gdG8gYW4gZWxlbWVudC5cbiAgYXR0YWNoTWVkaWFTdHJlYW06IGZ1bmN0aW9uKGVsZW1lbnQsIHN0cmVhbSkge1xuICAgIGxvZ2dpbmcoJ0RFUFJFQ0FURUQsIGF0dGFjaE1lZGlhU3RyZWFtIHdpbGwgc29vbiBiZSByZW1vdmVkLicpO1xuICAgIGVsZW1lbnQuc3JjT2JqZWN0ID0gc3RyZWFtO1xuICB9LFxuXG4gIHJlYXR0YWNoTWVkaWFTdHJlYW06IGZ1bmN0aW9uKHRvLCBmcm9tKSB7XG4gICAgbG9nZ2luZygnREVQUkVDQVRFRCwgcmVhdHRhY2hNZWRpYVN0cmVhbSB3aWxsIHNvb24gYmUgcmVtb3ZlZC4nKTtcbiAgICB0by5zcmNPYmplY3QgPSBmcm9tLnNyY09iamVjdDtcbiAgfVxufVxuXG4vLyBFeHBvc2UgcHVibGljIG1ldGhvZHMuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2hpbU9uVHJhY2s6IGZpcmVmb3hTaGltLnNoaW1PblRyYWNrLFxuICBzaGltU291cmNlT2JqZWN0OiBmaXJlZm94U2hpbS5zaGltU291cmNlT2JqZWN0LFxuICBzaGltUGVlckNvbm5lY3Rpb246IGZpcmVmb3hTaGltLnNoaW1QZWVyQ29ubmVjdGlvbixcbiAgc2hpbUdldFVzZXJNZWRpYTogcmVxdWlyZSgnLi9nZXR1c2VybWVkaWEnKSxcbiAgYXR0YWNoTWVkaWFTdHJlYW06IGZpcmVmb3hTaGltLmF0dGFjaE1lZGlhU3RyZWFtLFxuICByZWF0dGFjaE1lZGlhU3RyZWFtOiBmaXJlZm94U2hpbS5yZWF0dGFjaE1lZGlhU3RyZWFtXG59XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi93ZWJydGMtYWRhcHRlci9zcmMvanMvZmlyZWZveC9maXJlZm94X3NoaW0uanNcbiAqKiBtb2R1bGUgaWQgPSAxNTJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qXG4gKiAgQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBXZWJSVEMgcHJvamVjdCBhdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgc291cmNlXG4gKiAgdHJlZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nZ2luZyA9IHJlcXVpcmUoJy4uL3V0aWxzJykubG9nO1xudmFyIGJyb3dzZXJEZXRhaWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKS5icm93c2VyRGV0YWlscztcblxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzLlxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbiAgLy8gZ2V0VXNlck1lZGlhIGNvbnN0cmFpbnRzIHNoaW0uXG4gIHZhciBnZXRVc2VyTWVkaWFfID0gZnVuY3Rpb24oY29uc3RyYWludHMsIG9uU3VjY2Vzcywgb25FcnJvcikge1xuICAgIHZhciBjb25zdHJhaW50c1RvRkYzN18gPSBmdW5jdGlvbihjKSB7XG4gICAgICBpZiAodHlwZW9mIGMgIT09ICdvYmplY3QnIHx8IGMucmVxdWlyZSkge1xuICAgICAgICByZXR1cm4gYztcbiAgICAgIH1cbiAgICAgIHZhciByZXF1aXJlID0gW107XG4gICAgICBPYmplY3Qua2V5cyhjKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoa2V5ID09PSAncmVxdWlyZScgfHwga2V5ID09PSAnYWR2YW5jZWQnIHx8IGtleSA9PT0gJ21lZGlhU291cmNlJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgciA9IGNba2V5XSA9ICh0eXBlb2YgY1trZXldID09PSAnb2JqZWN0JykgP1xuICAgICAgICAgICAgY1trZXldIDoge2lkZWFsOiBjW2tleV19O1xuICAgICAgICBpZiAoci5taW4gIT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICAgci5tYXggIT09IHVuZGVmaW5lZCB8fCByLmV4YWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXF1aXJlLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoci5leGFjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiByLmV4YWN0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgci4gbWluID0gci5tYXggPSByLmV4YWN0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjW2tleV0gPSByLmV4YWN0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWxldGUgci5leGFjdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoci5pZGVhbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgYy5hZHZhbmNlZCA9IGMuYWR2YW5jZWQgfHwgW107XG4gICAgICAgICAgdmFyIG9jID0ge307XG4gICAgICAgICAgaWYgKHR5cGVvZiByLmlkZWFsID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgb2Nba2V5XSA9IHttaW46IHIuaWRlYWwsIG1heDogci5pZGVhbH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9jW2tleV0gPSByLmlkZWFsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjLmFkdmFuY2VkLnB1c2gob2MpO1xuICAgICAgICAgIGRlbGV0ZSByLmlkZWFsO1xuICAgICAgICAgIGlmICghT2JqZWN0LmtleXMocikubGVuZ3RoKSB7XG4gICAgICAgICAgICBkZWxldGUgY1trZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAocmVxdWlyZS5sZW5ndGgpIHtcbiAgICAgICAgYy5yZXF1aXJlID0gcmVxdWlyZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjO1xuICAgIH07XG4gICAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCAzOCkge1xuICAgICAgbG9nZ2luZygnc3BlYzogJyArIEpTT04uc3RyaW5naWZ5KGNvbnN0cmFpbnRzKSk7XG4gICAgICBpZiAoY29uc3RyYWludHMuYXVkaW8pIHtcbiAgICAgICAgY29uc3RyYWludHMuYXVkaW8gPSBjb25zdHJhaW50c1RvRkYzN18oY29uc3RyYWludHMuYXVkaW8pO1xuICAgICAgfVxuICAgICAgaWYgKGNvbnN0cmFpbnRzLnZpZGVvKSB7XG4gICAgICAgIGNvbnN0cmFpbnRzLnZpZGVvID0gY29uc3RyYWludHNUb0ZGMzdfKGNvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgIH1cbiAgICAgIGxvZ2dpbmcoJ2ZmMzc6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuICAgIH1cbiAgICByZXR1cm4gbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYShjb25zdHJhaW50cywgb25TdWNjZXNzLCBvbkVycm9yKTtcbiAgfTtcblxuICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhID0gZ2V0VXNlck1lZGlhXztcblxuICAvLyBSZXR1cm5zIHRoZSByZXN1bHQgb2YgZ2V0VXNlck1lZGlhIGFzIGEgUHJvbWlzZS5cbiAgdmFyIGdldFVzZXJNZWRpYVByb21pc2VfID0gZnVuY3Rpb24oY29uc3RyYWludHMpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzLCByZXNvbHZlLCByZWplY3QpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gU2hpbSBmb3IgbWVkaWFEZXZpY2VzIG9uIG9sZGVyIHZlcnNpb25zLlxuICBpZiAoIW5hdmlnYXRvci5tZWRpYURldmljZXMpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzID0ge2dldFVzZXJNZWRpYTogZ2V0VXNlck1lZGlhUHJvbWlzZV8sXG4gICAgICBhZGRFdmVudExpc3RlbmVyOiBmdW5jdGlvbigpIHsgfSxcbiAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKCkgeyB9XG4gICAgfTtcbiAgfVxuICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMgPVxuICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzIHx8IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7XG4gICAgICB2YXIgaW5mb3MgPSBbXG4gICAgICAgIHtraW5kOiAnYXVkaW9pbnB1dCcsIGRldmljZUlkOiAnZGVmYXVsdCcsIGxhYmVsOiAnJywgZ3JvdXBJZDogJyd9LFxuICAgICAgICB7a2luZDogJ3ZpZGVvaW5wdXQnLCBkZXZpY2VJZDogJ2RlZmF1bHQnLCBsYWJlbDogJycsIGdyb3VwSWQ6ICcnfVxuICAgICAgXTtcbiAgICAgIHJlc29sdmUoaW5mb3MpO1xuICAgIH0pO1xuICB9O1xuXG4gIGlmIChicm93c2VyRGV0YWlscy52ZXJzaW9uIDwgNDEpIHtcbiAgICAvLyBXb3JrIGFyb3VuZCBodHRwOi8vYnVnemlsLmxhLzExNjk2NjVcbiAgICB2YXIgb3JnRW51bWVyYXRlRGV2aWNlcyA9XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcy5iaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO1xuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIG9yZ0VudW1lcmF0ZURldmljZXMoKS50aGVuKHVuZGVmaW5lZCwgZnVuY3Rpb24oZSkge1xuICAgICAgICBpZiAoZS5uYW1lID09PSAnTm90Rm91bmRFcnJvcicpIHtcbiAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cbn1cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9maXJlZm94L2dldHVzZXJtZWRpYS5qc1xuICoqIG1vZHVsZSBpZCA9IDE1M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIl0sInNvdXJjZVJvb3QiOiIifQ== |