js-immutables
Version:
A small library to handle immutable data.
314 lines (305 loc) • 58 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.jsMessages = {}));
}(this, (function (exports) { 'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
}
function update(state, sndArg) {
if (typeof sndArg === 'string') {
return update(state).path(sndArg);
}
else if (typeof sndArg === 'function') {
var select = function () {
var path = [];
for (var _i = 0; _i < arguments.length; _i++) {
path[_i] = arguments[_i];
}
return createHandler(state, path, ObjectUpdaterImpl, ArrayUpdaterImpl);
};
return performUpdates(state, Array.from(sndArg(select)));
}
return createHandler(state, [], ObjectModifierImpl, ArrayModifierImpl);
}
var ObjectModifierImpl = (function () {
function ObjectModifierImpl(state, path) {
this._state = state;
this._path = path;
}
ObjectModifierImpl.prototype.path = function () {
var keys = [];
for (var _i = 0; _i < arguments.length; _i++) {
keys[_i] = arguments[_i];
}
return createHandler(this._state, __spreadArrays(this._path, keys), ObjectModifierImpl, ArrayModifierImpl);
};
ObjectModifierImpl.prototype.map = function (key, mapper) {
return performUpdate(this._state, this._path, ObjectOps.map(key, mapper));
};
ObjectModifierImpl.prototype.set = function (key, newValue) {
return performUpdate(this._state, this._path, ObjectOps.set(key, newValue));
};
return ObjectModifierImpl;
}());
var ArrayModifierImpl = (function () {
function ArrayModifierImpl(state, path) {
this._state = state;
this._path = path;
}
ArrayModifierImpl.prototype.path = function () {
var keys = [];
for (var _i = 0; _i < arguments.length; _i++) {
keys[_i] = arguments[_i];
}
return createHandler(this._state, __spreadArrays(this._path, keys), ObjectModifierImpl, ArrayModifierImpl);
};
ArrayModifierImpl.prototype.push = function (item) {
return performUpdate(this._state, this._path, ArrayOps.push(item));
};
ArrayModifierImpl.prototype.map = function (mapper) {
return performUpdate(this._state, this._path, ArrayOps.map(mapper));
};
ArrayModifierImpl.prototype.mapFirst = function (pred, mapper) {
return performUpdate(this._state, this._path, ArrayOps.mapFirst(pred, mapper));
};
ArrayModifierImpl.prototype.pop = function () {
return performUpdate(this._state, this._path, ArrayOps.pop());
};
ArrayModifierImpl.prototype.filter = function (pred) {
return performUpdate(this._state, this._path, ArrayOps.filter(pred));
};
ArrayModifierImpl.prototype.remove = function (pred) {
return performUpdate(this._state, this._path, ArrayOps.remove(pred));
};
ArrayModifierImpl.prototype.removeFirst = function (pred) {
return performUpdate(this._state, this._path, ArrayOps.removeFirst(pred));
};
ArrayModifierImpl.prototype.removeLast = function (pred) {
return performUpdate(this._state, this._path, ArrayOps.removeLast(pred));
};
ArrayModifierImpl.prototype.clear = function () {
return performUpdate(this._state, this._path, ArrayOps.clear());
};
return ArrayModifierImpl;
}());
var ObjectUpdaterImpl = (function () {
function ObjectUpdaterImpl(state, path) {
this._state = state;
this._path = path;
}
ObjectUpdaterImpl.prototype.select = function (keys) {
return createHandler(this._state, __spreadArrays(this._path, keys), ObjectUpdaterImpl, ArrayUpdaterImpl);
};
ObjectUpdaterImpl.prototype.map = function (key, mapper) {
return createUpdate(this._path, ObjectOps.map(key, mapper));
};
ObjectUpdaterImpl.prototype.set = function (key, newValue) {
return createUpdate(this._path, ObjectOps.set(key, newValue));
};
return ObjectUpdaterImpl;
}());
var ArrayUpdaterImpl = (function () {
function ArrayUpdaterImpl(state, path) {
this._state = state;
this._path = path;
}
ArrayUpdaterImpl.prototype.select = function (keys) {
return createHandler(this._state, __spreadArrays(this._path, keys), ObjectUpdaterImpl, ArrayUpdaterImpl);
};
ArrayUpdaterImpl.prototype.push = function (newItem) {
return createUpdate(this._path, ArrayOps.push(newItem));
};
ArrayUpdaterImpl.prototype.pop = function () {
return createUpdate(this._path, ArrayOps.pop());
};
ArrayUpdaterImpl.prototype.map = function (mapper) {
return createUpdate(this._path, ArrayOps.map(mapper));
};
ArrayUpdaterImpl.prototype.mapFirst = function (pred, mapper) {
return createUpdate(this._path, ArrayOps.mapFirst(pred, mapper));
};
ArrayUpdaterImpl.prototype.filter = function (pred) {
return createUpdate(this._path, ArrayOps.filter(pred));
};
ArrayUpdaterImpl.prototype.remove = function (pred) {
return createUpdate(this._path, ArrayOps.remove(pred));
};
ArrayUpdaterImpl.prototype.removeFirst = function (pred) {
return createUpdate(this._path, ArrayOps.removeFirst(pred));
};
ArrayUpdaterImpl.prototype.removeLast = function (pred) {
return createUpdate(this._path, ArrayOps.removeLast(pred));
};
ArrayUpdaterImpl.prototype.clear = function () {
return createUpdate(this._path, ArrayOps.clear());
};
return ArrayUpdaterImpl;
}());
var ObjectOps = {
set: function (key, newValue) {
return function (obj) {
var _a;
return (__assign(__assign({}, obj), (_a = {}, _a[key] = newValue, _a)));
};
},
map: function (key, mapper) {
return function (obj) {
var _a;
return (__assign(__assign({}, obj), (_a = {}, _a[key] = mapper(obj[key]), _a)));
};
}
};
var ArrayOps = {
push: function (newItem) {
return function (arr) { return __spreadArrays(arr, [newItem]); };
},
pop: function () {
return function (arr) {
var ret = __spreadArrays(arr);
ret.pop();
return ret;
};
},
map: function (mapper) {
return function (arr) { return arr.map(mapper); };
},
mapFirst: function (pred, mapper) {
return function (arr) {
var matchIdx = arr.findIndex(pred);
return matchIdx === -1
? arr
: arr.slice(0, matchIdx).concat(mapper(arr[matchIdx], matchIdx), arr.slice(matchIdx + 1));
};
},
filter: function (pred) {
return function (arr) { return arr.filter(pred); };
},
remove: function (pred) {
return function (arr) { return arr.filter(function (value, idx) { return !pred(value, idx); }); };
},
removeFirst: function (pred) {
return function (arr) {
var idx = arr.findIndex(pred);
return idx === -1
? arr
: idx === 0
? arr.slice(1)
: arr.slice(0, idx).concat(arr.slice(idx + 1));
};
},
removeLast: function (pred) {
return function (arr) {
for (var idx = arr.length - 1; idx >= 0; --idx) {
if (pred(arr[idx], idx)) {
return idx === 0
? arr.slice(1)
: arr.slice(0, idx).concat(arr.slice(idx + 1));
}
}
return arr;
};
},
clear: function () {
return function (arr) { return []; };
}
};
function createHandler(base, path, ObjectHandlerClass, ArrayHandlerClass) {
var ret = null;
if (base) {
var current = base;
for (var i = 0; i < path.length; ++i) {
var key = path[i];
current = current[key];
if (!current) {
break;
}
}
if (Array.isArray(current)) {
ret = new ArrayHandlerClass(base, path);
}
else if (current && typeof current === 'object') {
ret = new ObjectHandlerClass(base, path);
}
}
return ret;
}
function createUpdate(path, mapper) {
return {
path: path,
mapper: mapper
};
}
function performUpdates(state, updates) {
var state2 = shallowCopy(state);
var modifiedPaths = updates.length > 1 ? {} : null;
updates.forEach(function (_a) {
var path = _a.path, mapper = _a.mapper;
var pathAsString = '';
var substate = state2;
var parent = null;
path.forEach(function (key, idx) {
pathAsString = idx === 0 ? key : '@' + key;
if (!modifiedPaths || !hasOwnProp(modifiedPaths, pathAsString)) {
substate[key] = shallowCopy(substate[key]);
if (modifiedPaths) {
modifiedPaths[pathAsString] = true;
}
}
parent = substate;
substate = substate[key];
});
if (parent) {
parent[path[path.length - 1]] = mapper(substate);
}
else {
state2 = mapper(substate);
}
});
return state2;
}
function performUpdate(state, path, mapper) {
return performUpdates(state, [{ path: path, mapper: mapper }]);
}
function shallowCopy(it) {
if (Array.isArray(it)) {
return __spreadArrays(it);
}
else if (it && typeof it === 'object') {
return __assign({}, it);
}
return it;
}
function hasOwnProp(obj, propName) {
return Object.prototype.hasOwnProperty.call(obj, propName);
}
exports.update = update;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianMtaW1tdXRhYmxlcy51bWQuZGV2ZWxvcG1lbnQuanMiLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanMiLCIuLi9zcmMvbWFpbi9hcGkvdXBkYXRlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlXHJcbnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXHJcbkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcblxyXG5USElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRURcclxuV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSxcclxuTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC5cclxuXHJcblNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9uc1xyXG5hbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIGV4cG9ydHMpIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKCFleHBvcnRzLmhhc093blByb3BlcnR5KHApKSBleHBvcnRzW3BdID0gbVtwXTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSByZXN1bHRba10gPSBtb2Rba107XHJcbiAgICByZXN1bHQuZGVmYXVsdCA9IG1vZDtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcbiIsImV4cG9ydCBkZWZhdWx0IHVwZGF0ZVxuXG5mdW5jdGlvbiB1cGRhdGU8UyBleHRlbmRzIFN0YXRlPihzdGF0ZTogUyk6IE1vZGlmaWVyVHlwZTxTLCBTLCBTPlxuZnVuY3Rpb24gdXBkYXRlPFMgZXh0ZW5kcyBBcnJTdGF0ZTxWPiwgVj4oc3RhdGU6IFMsIGlkeDogbnVtYmVyKTogTW9kaWZpZXJUeXBlPFMsIFYsIFY+IFxuZnVuY3Rpb24gdXBkYXRlPFMgZXh0ZW5kcyBPYmpTdGF0ZSwgSyBleHRlbmRzIGtleW9mIFM+KHN0YXRlOiBTLCBrZXk6IEspOiBNb2RpZmllclR5cGU8UywgU1tLXSwgU1tLXT4gXG5mdW5jdGlvbiB1cGRhdGU8UyBleHRlbmRzIFN0YXRlPihzdGF0ZTogUywgZ2V0VXBkYXRlczogKHNlbGVjdDogVXBkYXRlU2VsZWN0b3I8UywgUz4pID0+IFVwZGF0ZTxTLCBhbnk+W10pOiBTIFxuZnVuY3Rpb24gdXBkYXRlPFMgZXh0ZW5kcyBTdGF0ZT4oc3RhdGU6IFMsIGdlbmVyYXRlVXBkYXRlczogKHNlbGVjdDogVXBkYXRlU2VsZWN0b3I8UywgUz4pID0+IEdlbmVyYXRvcjxVcGRhdGU8UywgYW55Pj4pOiBTIFxuXG5mdW5jdGlvbiB1cGRhdGU8UyBleHRlbmRzIFN0YXRlPihzdGF0ZTogUywgc25kQXJnPzogYW55KTogYW55IHtcbiAgaWYgKHR5cGVvZiBzbmRBcmcgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHVwZGF0ZShzdGF0ZSkucGF0aChzbmRBcmcgYXMga2V5b2YgUylcbiAgfSBlbHNlIGlmICh0eXBlb2Ygc25kQXJnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3Qgc2VsZWN0ID0gKC4uLnBhdGg6IHN0cmluZ1tdKSA9PiB7XG4gICAgICByZXR1cm4gY3JlYXRlSGFuZGxlcihzdGF0ZSwgcGF0aCwgT2JqZWN0VXBkYXRlckltcGwsIEFycmF5VXBkYXRlckltcGwpXG4gICAgfVxuXG4gICAgcmV0dXJuIHBlcmZvcm1VcGRhdGVzKHN0YXRlLCBBcnJheS5mcm9tKHNuZEFyZyhzZWxlY3QpKSlcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVIYW5kbGVyKHN0YXRlLCBbXSwgT2JqZWN0TW9kaWZpZXJJbXBsLCBBcnJheU1vZGlmaWVySW1wbClcbn1cblxuLy8gLS0tIG1vZGlmaWNhdGlvbiAodHlwZXMpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG50eXBlIE1vZGlmaWVyVHlwZTxTIGV4dGVuZHMgU3RhdGUsIEIgZXh0ZW5kcyBPYmosIFQ+ID1cbiAgSWZOZXZlclRoZW5OdWxsPFQgZXh0ZW5kcyAoaW5mZXIgVilbXSA/IEFycmF5TW9kaWZpZXI8UywgQiwgVj4gOiBuZXZlclxuICAgIHwgVCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPyBPYmplY3RNb2RpZmllcjxTLCBCLCBUPiA6IG5ldmVyPlxuXG50eXBlIE1vZGlmeVNlbGVjdG9yPFMgZXh0ZW5kcyBTdGF0ZSwgQiBleHRlbmRzIE9iaj4gPSB7XG4gIDxLMSBleHRlbmRzIGtleW9mIEI+KGsxOiBLMSk6IE1vZGlmaWVyVHlwZTxTLCBCLCBCW0sxXT4sXG4gIDxLMSBleHRlbmRzIGtleW9mIEIsIEsyIGV4dGVuZHMga2V5b2YgQltLMV0+KGsxOiBLMSwgazI6IEsyKTogTW9kaWZpZXJUeXBlPFMsIEIsIEJbSzFdW0syXT4sXG4gIDxLMSBleHRlbmRzIGtleW9mIEIsIEsyIGV4dGVuZHMga2V5b2YgQltLMV0sIEszIGV4dGVuZHMga2V5b2YgQltLMV1bSzJdPihrMTogSzEsIGsyOiBLMiwgazM6IEszKTogTW9kaWZpZXJUeXBlPFMsIEIsIEJbSzFdW0syXVtLM10+LFxuICA8SzEgZXh0ZW5kcyBrZXlvZiBCLCBLMiBleHRlbmRzIGtleW9mIEJbSzFdLCBLMyBleHRlbmRzIGtleW9mIEJbSzFdW0syXSwgSzQgZXh0ZW5kcyBrZXlvZiBCW0sxXVtLMl1bSzNdPihrMTogSzEsIGsyOiBLMiwgazM6IEszLCBrNDogSzQpOiBNb2RpZmllclR5cGU8UywgQiwgQltLMV1bSzJdW0szXVtLNF0+LFxuICA8SzEgZXh0ZW5kcyBrZXlvZiBCLCBLMiBleHRlbmRzIGtleW9mIEJbSzFdLCBLMyBleHRlbmRzIGtleW9mIEJbSzFdW0syXSwgSzQgZXh0ZW5kcyBrZXlvZiBCW0sxXVtLMl1bSzNdLCBLNSBleHRlbmRzIGtleW9mIEJbSzFdW0syXVtLM11bSzRdPihrMTogSzEsIGsyOiBLMiwgazM6IEszLCBrNDogSzQsIGs1OiBLNSk6IE1vZGlmaWVyVHlwZTxTLCBCLCBCW0sxXVtLMl1bSzNdW0s0XVtLNV0+LFxufVxuXG50eXBlIE9iamVjdE1vZGlmaWVyPFMgZXh0ZW5kcyBTdGF0ZSwgQiBleHRlbmRzIE9iaiwgVCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4+ID0ge1xuICBwYXRoOiBNb2RpZnlTZWxlY3RvcjxTLCBCPixcbiAgc2V0PEsgZXh0ZW5kcyBrZXlvZiBUPihrZXk6IEssIHZhbHVlOiBUW0tdKTogU1xuICBtYXA8SyBleHRlbmRzIGtleW9mIFQ+KGtleTogSywgbWFwcGVyOiAodmFsdWU6IFRbS10pID0+IFRbS10pOiBTXG59XG5cbnR5cGUgQXJyYXlNb2RpZmllcjxTIGV4dGVuZHMgU3RhdGUsIEIgZXh0ZW5kcyBTdGF0ZSwgVj4gPSB7XG4gIHBhdGg6IE1vZGlmeVNlbGVjdG9yPFMsIEI+LFxuICBwdXNoKGl0ZW06IFYpOiBTLFxuICBwb3AoKTogUyxcbiAgbWFwKG1hcHBlcjogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PlYpOiBTLFxuICBtYXBGaXJzdChwcmVkOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4sIG1hcHBlcjogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PlYpOiBTLFxuICBmaWx0ZXIocHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuKTogUyxcbiAgcmVtb3ZlKHByZWQ6IChpdGVtOiBWLCBpZHg6IG51bWJlcikgPT4gYm9vbGVhbik6IFMsXG4gIHJlbW92ZUZpcnN0KHByZWQ6IChpdGVtOiBWLCBpZHg6IG51bWJlcikgPT4gYm9vbGVhbik6IFMsXG4gIHJlbW92ZUxhc3QocHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuKTogUyxcbiAgY2xlYXIoKTogU1xufVxuXG4vLyAtLS0gbW9kaWZpY2F0aW9ucyAoaW1wbCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmNsYXNzIE9iamVjdE1vZGlmaWVySW1wbDxTIGV4dGVuZHMgU3RhdGUsIFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gIF9zdGF0ZTogU1xuICBfcGF0aDogc3RyaW5nW11cblxuICBjb25zdHJ1Y3RvcihzdGF0ZTogUywgcGF0aDogc3RyaW5nW10pIHtcbiAgICB0aGlzLl9zdGF0ZSA9IHN0YXRlXG4gICAgdGhpcy5fcGF0aCA9IHBhdGhcbiAgfVxuXG4gIHBhdGgoLi4ua2V5czogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gY3JlYXRlSGFuZGxlcih0aGlzLl9zdGF0ZSwgWy4uLnRoaXMuX3BhdGgsIC4uLmtleXMgXSwgT2JqZWN0TW9kaWZpZXJJbXBsLCBBcnJheU1vZGlmaWVySW1wbClcbiAgfVxuXG4gIG1hcChrZXk6IGtleW9mIFQsIG1hcHBlcjogKHZhbHVlOiBUKSA9PiBUKTogUyB7XG4gICAgcmV0dXJuIHBlcmZvcm1VcGRhdGUodGhpcy5fc3RhdGUsIHRoaXMuX3BhdGgsIE9iamVjdE9wcy5tYXAoa2V5LCBtYXBwZXIpKSBcbiAgfVxuXG4gIHNldChrZXk6IGtleW9mIFQsIG5ld1ZhbHVlOiBUKSB7XG4gICAgcmV0dXJuIHBlcmZvcm1VcGRhdGUodGhpcy5fc3RhdGUsIHRoaXMuX3BhdGgsIE9iamVjdE9wcy5zZXQoa2V5LCBuZXdWYWx1ZSkpIFxuICB9XG59XG5cbmNsYXNzIEFycmF5TW9kaWZpZXJJbXBsPFMgZXh0ZW5kcyBTdGF0ZSwgQiBleHRlbmRzIE9iaiwgVj4gaW1wbGVtZW50cyBBcnJheU1vZGlmaWVyPFMsIEIsIFY+IHtcbiAgX3N0YXRlOiBTXG4gIF9wYXRoOiBzdHJpbmdbXVxuXG4gIGNvbnN0cnVjdG9yKHN0YXRlOiBTLCBwYXRoOiBzdHJpbmdbXSkge1xuICAgIHRoaXMuX3N0YXRlID0gc3RhdGVcbiAgICB0aGlzLl9wYXRoID0gcGF0aFxuICB9XG5cbiAgcGF0aCguLi5rZXlzOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiBjcmVhdGVIYW5kbGVyKHRoaXMuX3N0YXRlLCBbLi4udGhpcy5fcGF0aCwgLi4ua2V5cyBdLCBPYmplY3RNb2RpZmllckltcGwsIEFycmF5TW9kaWZpZXJJbXBsKVxuICB9XG5cbiAgcHVzaChpdGVtOiBWKSB7XG4gICAgcmV0dXJuIHBlcmZvcm1VcGRhdGUodGhpcy5fc3RhdGUsIHRoaXMuX3BhdGgsIEFycmF5T3BzLnB1c2goaXRlbSkpXG4gIH1cbiAgXG4gIG1hcChtYXBwZXI6IChpdGVtOiBWLCBpZHg6IG51bWJlcikgPT4gVikge1xuICAgIHJldHVybiBwZXJmb3JtVXBkYXRlKHRoaXMuX3N0YXRlLCB0aGlzLl9wYXRoLCBBcnJheU9wcy5tYXAobWFwcGVyKSlcbiAgfVxuXG4gIG1hcEZpcnN0KFxuICAgIHByZWQ6IChpdGVtOiBWLCBpZHg6IG51bWJlcikgPT4gYm9vbGVhbixcbiAgICBtYXBwZXI6IChpdGVtOiBWLCBpZHg6IG51bWJlcikgPT5WXG4gICkge1xuICAgIHJldHVybiBwZXJmb3JtVXBkYXRlKHRoaXMuX3N0YXRlLCB0aGlzLl9wYXRoLCBBcnJheU9wcy5tYXBGaXJzdChwcmVkLCBtYXBwZXIpKVxuICB9XG5cbiAgcG9wKCkge1xuICAgIHJldHVybiBwZXJmb3JtVXBkYXRlKHRoaXMuX3N0YXRlLCB0aGlzLl9wYXRoLCBBcnJheU9wcy5wb3AoKSlcbiAgfVxuXG4gIGZpbHRlcihwcmVkOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gcGVyZm9ybVVwZGF0ZSh0aGlzLl9zdGF0ZSwgdGhpcy5fcGF0aCwgQXJyYXlPcHMuZmlsdGVyKHByZWQpKVxuICB9XG5cbiAgcmVtb3ZlKHByZWQ6IChpdGVtOiBWLCBpZHg6IG51bWJlcikgPT4gYm9vbGVhbikge1xuICAgIHJldHVybiBwZXJmb3JtVXBkYXRlKHRoaXMuX3N0YXRlLCB0aGlzLl9wYXRoLCBBcnJheU9wcy5yZW1vdmUocHJlZCkpXG4gIH1cblxuICByZW1vdmVGaXJzdChwcmVkOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gcGVyZm9ybVVwZGF0ZSh0aGlzLl9zdGF0ZSwgdGhpcy5fcGF0aCwgQXJyYXlPcHMucmVtb3ZlRmlyc3QocHJlZCkpXG4gIH1cblxuICByZW1vdmVMYXN0KHByZWQ6IChpdGVtOiBWLCBpZHg6IG51bWJlcikgPT4gYm9vbGVhbikge1xuICAgIHJldHVybiBwZXJmb3JtVXBkYXRlKHRoaXMuX3N0YXRlLCB0aGlzLl9wYXRoLCBBcnJheU9wcy5yZW1vdmVMYXN0KHByZWQpKVxuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgcmV0dXJuIHBlcmZvcm1VcGRhdGUodGhpcy5fc3RhdGUsIHRoaXMuX3BhdGgsIEFycmF5T3BzLmNsZWFyKCkpXG4gIH1cbn1cblxuLy8gLS0tIHVwZGF0ZXMgKHR5cGVzKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG50eXBlIFVwZGF0ZXJUeXBlPFMgZXh0ZW5kcyBTdGF0ZSwgQiBleHRlbmRzIFN0YXRlLCBUPiA9XG4gIElmTmV2ZXJUaGVuTnVsbDxUIGV4dGVuZHMgKGluZmVyIFYpW10gPyBBcnJheVVwZGF0ZXI8UywgQiwgVj4gOiBuZXZlclxuICAgIHwgVCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPyBPYmplY3RVcGRhdGVyPFMsIEIsIFQ+IDogbmV2ZXI+XG5cbnR5cGUgT2JqZWN0VXBkYXRlcjxTIGV4dGVuZHMgU3RhdGUsIEIgZXh0ZW5kcyBPYmosIFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+PiA9IHtcbiAgc2VsZWN0OiBVcGRhdGVTZWxlY3RvcjxTLCBCPixcbiAgc2V0PEsgZXh0ZW5kcyBrZXlvZiBUPihrZXk6IEssIHZhbHVlOiBUW0tdKTogVXBkYXRlPFMsIFQ+IFxuICBtYXA8SyBleHRlbmRzIGtleW9mIFQ+KGtleTogSywgbWFwcGVyOiAodmFsdWU6IFRbS10pID0+IFRbS10pOiBVcGRhdGU8UywgVD5cbn1cblxudHlwZSBBcnJheVVwZGF0ZXI8UyBleHRlbmRzIFN0YXRlLCBCIGV4dGVuZHMgU3RhdGUsIFY+ID0ge1xuICBzZWxlY3Q6IFVwZGF0ZVNlbGVjdG9yPFMsIEI+LFxuICBwdXNoKHZhbHVlOiBWKTogVXBkYXRlPFMsIFZbXT4sXG4gIHBvcCh2YWx1ZTogVik6IFVwZGF0ZTxTLCBWW10+LFxuICBtYXAobWFwcGVyOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+Vik6IFVwZGF0ZTxTLCBWW10+LFxuICBtYXBGaXJzdChwcmVkOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4sIG1hcHBlcjogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PlYpOiBVcGRhdGU8UywgVltdPixcbiAgZmlsdGVyKHByZWQ6IChpdGVtOiBWKSA9PiBib29sZWFuKTogVXBkYXRlPFMsIFZbXT4sXG4gIHJlbW92ZShwcmVkOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4pOiBVcGRhdGU8UywgVltdPixcbiAgcmVtb3ZlRmlyc3QocHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuKTogVXBkYXRlPFMsIFZbXT4sXG4gIHJlbW92ZUxhc3QocHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuKTogVXBkYXRlPFMsIFZbXT4sXG4gIGNsZWFyKCk6IFVwZGF0ZTxTLCBWW10+XG59XG5cbnR5cGUgVXBkYXRlU2VsZWN0b3I8UyBleHRlbmRzIFN0YXRlLCBCIGV4dGVuZHMgT2JqPiA9IHtcbiAgPEsxIGV4dGVuZHMga2V5b2YgQj4oazE6IEsxKTogVXBkYXRlclR5cGU8UywgQiwgQltLMV0+LFxuICA8SzEgZXh0ZW5kcyBrZXlvZiBCLCBLMiBleHRlbmRzIGtleW9mIEJbSzFdPihrMTogSzEsIGsyOiBLMik6IFVwZGF0ZXJUeXBlPFMsIEIsIEJbSzFdW0syXT4sXG4gIDxLMSBleHRlbmRzIGtleW9mIEIsIEsyIGV4dGVuZHMga2V5b2YgQltLMV0sIEszIGV4dGVuZHMga2V5b2YgQltLMV1bSzJdPihrMTogSzEsIGsyOiBLMiwgazM6IEszKTogVXBkYXRlclR5cGU8UywgQiwgQltLMV1bSzJdW0szXT4sXG4gIDxLMSBleHRlbmRzIGtleW9mIEIsIEsyIGV4dGVuZHMga2V5b2YgQltLMV0sIEszIGV4dGVuZHMga2V5b2YgQltLMV1bSzJdLCBLNCBleHRlbmRzIGtleW9mIEJbSzFdW0syXVtLM10+KGsxOiBLMSwgazI6IEsyLCBrMzogSzMsIGs0OiBLNCk6IFVwZGF0ZXJUeXBlPFMsIEIsIEJbSzFdW0syXVtLM11bSzRdPixcbiAgPEsxIGV4dGVuZHMga2V5b2YgQiwgSzIgZXh0ZW5kcyBrZXlvZiBCW0sxXSwgSzMgZXh0ZW5kcyBrZXlvZiBCW0sxXVtLMl0sIEs0IGV4dGVuZHMga2V5b2YgQltLMV1bSzJdW0szXSwgSzUgZXh0ZW5kcyBrZXlvZiBCW0sxXVtLMl1bSzNdW0s0XT4oazE6IEsxLCBrMjogSzIsIGszOiBLMywgazQ6IEs0LCBrNTogSzUpOiBVcGRhdGVyVHlwZTxTLCBCLCBCW0sxXVtLMl1bSzNdW0s0XVtLNV0+LFxufVxuXG50eXBlIFVwZGF0ZTxTIGV4dGVuZHMgU3RhdGUsIFQ+ID0ge1xuICBwYXRoOiBzdHJpbmdbXSxcbiAgbWFwcGVyOiAodmFsdWU6IFQpID0+IFQgXG59XG5cbi8vIC0tLSB1cGRhdGVzIChpbXBsKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY2xhc3MgT2JqZWN0VXBkYXRlckltcGw8UyBleHRlbmRzIFN0YXRlLCBCIGV4dGVuZHMgT2JqLCBUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pj4gaW1wbGVtZW50cyBPYmplY3RVcGRhdGVyPFMsIEIsIFQ+IHtcbiAgcHJpdmF0ZSBfc3RhdGU6IFNcbiAgcHJpdmF0ZSBfcGF0aDogc3RyaW5nW11cblxuICBjb25zdHJ1Y3RvcihzdGF0ZTogUywgcGF0aDogc3RyaW5nW10pIHtcbiAgICB0aGlzLl9zdGF0ZSA9IHN0YXRlXG4gICAgdGhpcy5fcGF0aCA9IHBhdGhcbiAgfVxuXG4gIHNlbGVjdChrZXlzOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiBjcmVhdGVIYW5kbGVyKHRoaXMuX3N0YXRlLCBbLi4udGhpcy5fcGF0aCwgLi4ua2V5c10sIE9iamVjdFVwZGF0ZXJJbXBsLCBBcnJheVVwZGF0ZXJJbXBsKVxuICB9XG5cbiAgbWFwPEsgZXh0ZW5kcyBrZXlvZiBUPihrZXk6IEssIG1hcHBlcjogKHZhbHVlOiBUW0tdKSA9PiBUW0tdKTogVXBkYXRlPFMsIFQ+IHtcbiAgICByZXR1cm4gY3JlYXRlVXBkYXRlKHRoaXMuX3BhdGgsIE9iamVjdE9wcy5tYXAoa2V5LCBtYXBwZXIpKVxuICB9XG5cbiAgc2V0PEsgZXh0ZW5kcyBrZXlvZiBUPihrZXk6IEssIG5ld1ZhbHVlOiBUW0tdKTogVXBkYXRlPFMsIFQ+IHtcbiAgICByZXR1cm4gY3JlYXRlVXBkYXRlKHRoaXMuX3BhdGgsIE9iamVjdE9wcy5zZXQoa2V5LCBuZXdWYWx1ZSkpXG4gIH1cbn1cblxuY2xhc3MgQXJyYXlVcGRhdGVySW1wbDxTIGV4dGVuZHMgU3RhdGUsIEIgZXh0ZW5kcyBWW10sIFY+IGltcGxlbWVudHMgQXJyYXlVcGRhdGVyPFMsIEIsIFY+IHtcbiAgcHJpdmF0ZSBfc3RhdGU6IFNcbiAgcHJpdmF0ZSBfcGF0aDogc3RyaW5nW11cblxuICBjb25zdHJ1Y3RvcihzdGF0ZTogUywgcGF0aDogc3RyaW5nW10pIHtcbiAgICB0aGlzLl9zdGF0ZSA9IHN0YXRlXG4gICAgdGhpcy5fcGF0aCA9IHBhdGhcbiAgfVxuICBcbiAgc2VsZWN0KGtleXM6IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhhbmRsZXIodGhpcy5fc3RhdGUsIFsuLi50aGlzLl9wYXRoLCAuLi5rZXlzXSwgT2JqZWN0VXBkYXRlckltcGwsIEFycmF5VXBkYXRlckltcGwpXG4gIH1cblxuICBwdXNoKG5ld0l0ZW06IFYpOiBVcGRhdGU8UywgVltdPiB7XG4gICAgcmV0dXJuIGNyZWF0ZVVwZGF0ZSh0aGlzLl9wYXRoLCBBcnJheU9wcy5wdXNoKG5ld0l0ZW0pKVxuICB9XG4gIFxuICBwb3AoKTogVXBkYXRlPFMsIFZbXT4ge1xuICAgIHJldHVybiBjcmVhdGVVcGRhdGUodGhpcy5fcGF0aCwgQXJyYXlPcHMucG9wKCkpXG4gIH1cblxuICBtYXAobWFwcGVyOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IFYpIHtcbiAgICByZXR1cm4gY3JlYXRlVXBkYXRlKHRoaXMuX3BhdGgsIEFycmF5T3BzLm1hcChtYXBwZXIpKVxuICB9XG5cbiAgbWFwRmlyc3QoXG4gICAgcHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuLFxuICAgIG1hcHBlcjogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PlZcbiAgKSB7XG4gICAgcmV0dXJuIGNyZWF0ZVVwZGF0ZSh0aGlzLl9wYXRoLCBBcnJheU9wcy5tYXBGaXJzdChwcmVkLCBtYXBwZXIpKVxuICB9XG5cbiAgZmlsdGVyKHByZWQ6IChpdGVtOiBWKSA9PiBib29sZWFuKSB7XG4gICAgcmV0dXJuIGNyZWF0ZVVwZGF0ZSh0aGlzLl9wYXRoLCBBcnJheU9wcy5maWx0ZXIocHJlZCkpXG4gIH1cblxuICByZW1vdmUocHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuKSB7XG4gICAgcmV0dXJuIGNyZWF0ZVVwZGF0ZSh0aGlzLl9wYXRoLCBBcnJheU9wcy5yZW1vdmUocHJlZCkpXG4gIH1cblxuICByZW1vdmVGaXJzdChwcmVkOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gY3JlYXRlVXBkYXRlKHRoaXMuX3BhdGgsIEFycmF5T3BzLnJlbW92ZUZpcnN0KHByZWQpKVxuICB9XG4gXG4gIHJlbW92ZUxhc3QocHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuKSB7XG4gICAgcmV0dXJuIGNyZWF0ZVVwZGF0ZSh0aGlzLl9wYXRoLCBBcnJheU9wcy5yZW1vdmVMYXN0KHByZWQpKVxuICB9XG5cbiAgY2xlYXIoKTogVXBkYXRlPFMsIFZbXT4ge1xuICAgIHJldHVybiBjcmVhdGVVcGRhdGUodGhpcy5fcGF0aCwgQXJyYXlPcHMuY2xlYXIoKSlcbiAgfVxufVxuXG4vLyAtLS0gc2hhcmVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbnR5cGUgT2JqID0gUmVjb3JkPHN0cmluZywgYW55PlxudHlwZSBPYmpTdGF0ZSA9IFJlY29yZDxzdHJpbmcsIGFueT5cbnR5cGUgQXJyU3RhdGU8ViA9IGFueT4gPSBWW11cbnR5cGUgU3RhdGUgPSBPYmpTdGF0ZSB8IEFyclN0YXRlXG5cbnR5cGUgSWZOZXZlclRoZW5OdWxsPFQ+ID0gVCBleHRlbmRzIG5ldmVyID8gbnVsbCA6IFRcblxuLy8gLS0tIHNoYXJlZCBvcGVyYXRpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5jb25zdCBPYmplY3RPcHMgPSB7XG4gIHNldDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiwgSyBleHRlbmRzIGtleW9mIFQ+KGtleTogSywgbmV3VmFsdWU6IFRbS10pOiAob2JqOiBUKSA9PiBUIHtcbiAgICByZXR1cm4gKG9iajogVCkgPT4gKHsgLi4ub2JqLCBba2V5XTogbmV3VmFsdWUgfSlcbiAgfSxcbiAgXG4gIG1hcDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiwgSyBleHRlbmRzIGtleW9mIFQ+KGtleTogSywgbWFwcGVyOiAodmFsdWU6IFRbS10pID0+IFRbS10pOiAob2JqOiBUKSA9PiBUIHtcbiAgICByZXR1cm4gKG9iajogVCkgPT4gKHsgLi4ub2JqLCBba2V5XTogbWFwcGVyKG9ialtrZXldKSB9KVxuICB9XG59XG5cbmNvbnN0IEFycmF5T3BzID0ge1xuICBwdXNoPFY+KG5ld0l0ZW06IFYpOiAoYXJyOiBWW10pID0+IFZbXSB7XG4gICAgcmV0dXJuIChhcnI6IFZbXSkgPT4gWy4uLmFyciwgbmV3SXRlbV1cbiAgfSxcbiAgXG4gIHBvcDxWPigpOiAoYXJyOiBWW10pID0+IFZbXSB7XG4gICAgcmV0dXJuIChhcnI6IFZbXSkgPT4ge1xuICAgICAgY29uc3QgcmV0ID0gWy4uLmFycl1cbiAgICAgIHJldC5wb3AoKVxuICAgICAgcmV0dXJuIHJldFxuICAgIH1cbiAgfSxcblxuICBtYXA8Vj4obWFwcGVyOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IFYpOiAoYXJyOiBWW10pID0+IFZbXSB7XG4gICAgcmV0dXJuIChhcnI6IFZbXSkgPT4gYXJyLm1hcChtYXBwZXIpXG4gIH0sXG5cbiAgbWFwRmlyc3Q8Vj4oXG4gICAgcHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuLFxuICAgIG1hcHBlcjogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBWXG4gICkge1xuICAgIHJldHVybiAoYXJyOiBWW10pID0+IHtcbiAgICAgIGNvbnN0IG1hdGNoSWR4ID0gYXJyLmZpbmRJbmRleChwcmVkKVxuXG4gICAgICByZXR1cm4gbWF0Y2hJZHggPT09IC0xXG4gICAgICAgID8gYXJyXG4gICAgICAgIDogYXJyLnNsaWNlKDAsIG1hdGNoSWR4KS5jb25jYXQobWFwcGVyKGFyclttYXRjaElkeF0sIG1hdGNoSWR4KSwgYXJyLnNsaWNlKG1hdGNoSWR4ICsgMSkpXG4gICAgfVxuICB9LFxuXG4gIGZpbHRlcjxWPihwcmVkOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4pOiAoYXJyOiBWW10pID0+IFZbXSB7XG4gICAgcmV0dXJuIChhcnI6IFZbXSkgPT4gYXJyLmZpbHRlcihwcmVkKVxuICB9LFxuXG4gIHJlbW92ZTxWPihwcmVkOiAoaXRlbTogViwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4pOiAoYXJyOiBWW10pID0+IFZbXSB7XG4gICAgcmV0dXJuIChhcnI6IFZbXSkgPT4gYXJyLmZpbHRlcigodmFsdWUsIGlkeCkgPT4gIXByZWQodmFsdWUsIGlkeCkpXG4gIH0sXG5cbiAgcmVtb3ZlRmlyc3Q8Vj4ocHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuKTogKGFycjogVltdKSA9PiBWW10ge1xuICAgIHJldHVybiAoYXJyOiBWW10pID0+IHtcbiAgICAgIGNvbnN0IGlkeCA9IGFyci5maW5kSW5kZXgocHJlZClcblxuICAgICAgcmV0dXJuIGlkeCA9PT0gLTFcbiAgICAgICAgPyBhcnJcbiAgICAgICAgOiBpZHggPT09IDBcbiAgICAgICAgICA/IGFyci5zbGljZSgxKVxuICAgICAgICAgIDogYXJyLnNsaWNlKDAsIGlkeCkuY29uY2F0KGFyci5zbGljZShpZHggKyAxKSlcbiAgICB9XG4gIH0sXG4gXG4gIHJlbW92ZUxhc3Q8Vj4ocHJlZDogKGl0ZW06IFYsIGlkeDogbnVtYmVyKSA9PiBib29sZWFuKTogKGFycjogVltdKSA9PiBWW10ge1xuICAgIHJldHVybiAoYXJyOiBWW10pID0+IHtcbiAgICAgIGZvciAobGV0IGlkeCA9IGFyci5sZW5ndGggLSAxOyBpZHggPj0gMDsgLS1pZHgpIHtcbiAgICAgICAgaWYgKHByZWQoYXJyW2lkeF0sIGlkeCkpIHtcbiAgICAgICAgICByZXR1cm4gaWR4ID09PSAwXG4gICAgICAgICAgICA/IGFyci5zbGljZSgxKVxuICAgICAgICAgICAgOiBhcnIuc2xpY2UoMCwgaWR4KS5jb25jYXQoYXJyLnNsaWNlKGlkeCArIDEpKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhcnJcbiAgICB9XG4gIH0sXG5cbiAgY2xlYXI8Vj4oKTogKGFycjogVltdKSA9PiBWW10ge1xuICAgIHJldHVybiAoYXJyOiBWW10pID0+IFtdXG4gIH1cbn1cblxuLy8gLS0tIHNoYXJlZCBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5mdW5jdGlvbiBjcmVhdGVIYW5kbGVyKGJhc2U6IGFueSwgcGF0aDogYW55W10sIE9iamVjdEhhbmRsZXJDbGFzczogYW55LCBBcnJheUhhbmRsZXJDbGFzczogYW55KTogYW55IHtcbiAgbGV0IHJldCA9IG51bGxcblxuICBpZiAoYmFzZSkge1xuICAgIGxldCBjdXJyZW50ID0gYmFzZVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgKytpKSB7XG4gICAgICBjb25zdCBrZXkgPSBwYXRoW2ldXG4gICAgICBjdXJyZW50ID0gY3VycmVudFtrZXldXG5cbiAgICAgIGlmICghY3VycmVudCkge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KGN1cnJlbnQpKSB7XG4gICAgICByZXQgPSBuZXcgQXJyYXlIYW5kbGVyQ2xhc3MoYmFzZSwgcGF0aClcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnQgJiYgdHlwZW9mIGN1cnJlbnQgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXQgPSBuZXcgT2JqZWN0SGFuZGxlckNsYXNzKGJhc2UsIHBhdGgpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBjcmVhdGVVcGRhdGU8UyBleHRlbmRzIFN0YXRlLCBUPihcbiAgcGF0aDogc3RyaW5nW10sXG4gIG1hcHBlcjogKHZhbHVlOiBUKSA9PiBUXG4pOiBVcGRhdGU8UywgVD4ge1xuICByZXR1cm4geyBcbiAgICBwYXRoLFxuICAgIG1hcHBlclxuICB9XG59XG5cbmZ1bmN0aW9uIHBlcmZvcm1VcGRhdGVzPFMgZXh0ZW5kcyBTdGF0ZT4oXG4gIHN0YXRlOiBTLFxuICB1cGRhdGVzOiB7IHBhdGg6IHN0cmluZ1tdLCBtYXBwZXI6IDxUPih2YWx1ZTogVCkgPT4gVCB9W11cbik6IFMge1xuICBsZXQgc3RhdGUyID0gc2hhbGxvd0NvcHkoc3RhdGUpXG4gIFxuICBsZXQgbW9kaWZpZWRQYXRoczogUmVjb3JkPHN0cmluZywgYm9vbGVhbj4gfCBudWxsID1cbiAgICB1cGRhdGVzLmxlbmd0aCA+IDEgPyB7fSA6IG51bGxcblxuICB1cGRhdGVzLmZvckVhY2goKHsgcGF0aCwgbWFwcGVyIH0pID0+IHtcbiAgICBsZXQgcGF0aEFzU3RyaW5nID0gJydcbiAgICBsZXQgc3Vic3RhdGU6IGFueSA9IHN0YXRlMlxuICAgIGxldCBwYXJlbnQgPSBudWxsXG5cbiAgICBwYXRoLmZvckVhY2goKGtleSwgaWR4KSA9PiB7XG4gICAgICBwYXRoQXNTdHJpbmcgPSBpZHggPT09IDAgPyBrZXkgOiAnQCcgKyBrZXlcblxuICAgICAgaWYgKCFtb2RpZmllZFBhdGhzIHx8ICFoYXNPd25Qcm9wKG1vZGlmaWVkUGF0aHMsIHBhdGhBc1N0cmluZykpIHtcbiAgICAgICAgc3Vic3RhdGVba2V5XSA9IHNoYWxsb3dDb3B5KHN1YnN0YXRlW2tleV0pXG4gICAgICAgIFxuICAgICAgICBpZiAobW9kaWZpZWRQYXRocykge1xuICAgICAgICAgIG1vZGlmaWVkUGF0aHNbcGF0aEFzU3RyaW5nXSA9IHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwYXJlbnQgPSBzdWJzdGF0ZVxuICAgICAgc3Vic3RhdGUgPSBzdWJzdGF0ZVtrZXldXG4gICAgfSlcbiBcbiAgICBpZiAocGFyZW50KSB7XG4gICAgICAocGFyZW50IGFzIGFueSlbcGF0aFtwYXRoLmxlbmd0aCAtIDFdXSA9IG1hcHBlcihzdWJzdGF0ZSlcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUyID0gbWFwcGVyKHN1YnN0YXRlKVxuICAgIH1cbiAgfSlcblxuICByZXR1cm4gc3RhdGUyIGFzIFNcbn1cblxuZnVuY3Rpb24gcGVyZm9ybVVwZGF0ZTxTIGV4dGVuZHMgU3RhdGU+KFxuICBzdGF0ZTogUyxcbiAgcGF0aDogc3RyaW5nW10sXG4gIG1hcHBlcjogKHZhbHVlOiBhbnkpID0+IGFueVxuKTogUyB7XG4gIHJldHVybiBwZXJmb3JtVXBkYXRlcyhzdGF0ZSwgW3sgcGF0aCwgbWFwcGVyIH1dKVxufVxuXG5mdW5jdGlvbiBzaGFsbG93Q29weTxUPihpdDogVCk6IFQge1xuICBpZiAoQXJyYXkuaXNBcnJheShpdCkpIHtcbiAgICByZXR1cm4gWy4uLml0XSBhcyBhbnkgYXMgVFxuICB9IGVsc2UgaWYgKGl0ICYmIHR5cGVvZiBpdCA9PT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4geyAuLi5pdCB9XG4gIH1cblxuICByZXR1cm4gaXRcbn1cblxuZnVuY3Rpb24gaGFzT3duUHJvcChvYmo6IGFueSwgcHJvcE5hbWU6IHN0cmluZykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcE5hbWUpXG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBQUE7SUFDQTtJQUNBO0lBQ0E7SUFDQTtBQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7QUFDQTtJQUNBO0lBQ0E7SUFDQTtBQWVBO0lBQ08sSUFBSSxRQUFRLEdBQUcsV0FBVztJQUNqQyxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLFNBQVMsUUFBUSxDQUFDLENBQUMsRUFBRTtJQUNyRCxRQUFRLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0lBQzdELFlBQVksQ0FBQyxHQUFHLFNB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